Added tests & temporary removed RelationQueryDynamicSourceConfiguration from interface
This commit is contained in:
		
							parent
							
								
									909497703a
								
							
						
					
					
						commit
						2cb05c9d2b
					
				@ -26,7 +26,6 @@ import com.fasterxml.jackson.annotation.JsonTypeInfo;
 | 
				
			|||||||
        property = "type"
 | 
					        property = "type"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
@JsonSubTypes({
 | 
					@JsonSubTypes({
 | 
				
			||||||
        @JsonSubTypes.Type(value = RelationQueryDynamicSourceConfiguration.class, name = "RELATION_QUERY"),
 | 
					 | 
				
			||||||
        @JsonSubTypes.Type(value = RelationPathQueryDynamicSourceConfiguration.class, name = "RELATION_PATH_QUERY")
 | 
					        @JsonSubTypes.Type(value = RelationPathQueryDynamicSourceConfiguration.class, name = "RELATION_PATH_QUERY")
 | 
				
			||||||
})
 | 
					})
 | 
				
			||||||
@JsonIgnoreProperties(ignoreUnknown = true)
 | 
					@JsonIgnoreProperties(ignoreUnknown = true)
 | 
				
			||||||
 | 
				
			|||||||
@ -0,0 +1,126 @@
 | 
				
			|||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Copyright © 2016-2025 The Thingsboard Authors
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Licensed under the Apache License, Version 2.0 (the "License");
 | 
				
			||||||
 | 
					 * you may not use this file except in compliance with the License.
 | 
				
			||||||
 | 
					 * You may obtain a copy of the License at
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 *     http://www.apache.org/licenses/LICENSE-2.0
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Unless required by applicable law or agreed to in writing, software
 | 
				
			||||||
 | 
					 * distributed under the License is distributed on an "AS IS" BASIS,
 | 
				
			||||||
 | 
					 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
				
			||||||
 | 
					 * See the License for the specific language governing permissions and
 | 
				
			||||||
 | 
					 * limitations under the License.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					package org.thingsboard.server.common.data.cf.configuration;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import org.junit.jupiter.api.Test;
 | 
				
			||||||
 | 
					import org.junit.jupiter.api.extension.ExtendWith;
 | 
				
			||||||
 | 
					import org.junit.jupiter.params.ParameterizedTest;
 | 
				
			||||||
 | 
					import org.junit.jupiter.params.provider.NullAndEmptySource;
 | 
				
			||||||
 | 
					import org.mockito.junit.jupiter.MockitoExtension;
 | 
				
			||||||
 | 
					import org.thingsboard.server.common.data.id.EntityId;
 | 
				
			||||||
 | 
					import org.thingsboard.server.common.data.relation.EntityRelation;
 | 
				
			||||||
 | 
					import org.thingsboard.server.common.data.relation.EntitySearchDirection;
 | 
				
			||||||
 | 
					import org.thingsboard.server.common.data.relation.RelationPathLevel;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import java.util.ArrayList;
 | 
				
			||||||
 | 
					import java.util.List;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import static org.assertj.core.api.Assertions.assertThat;
 | 
				
			||||||
 | 
					import static org.assertj.core.api.Assertions.assertThatCode;
 | 
				
			||||||
 | 
					import static org.assertj.core.api.Assertions.assertThatThrownBy;
 | 
				
			||||||
 | 
					import static org.mockito.Mockito.mock;
 | 
				
			||||||
 | 
					import static org.mockito.Mockito.verify;
 | 
				
			||||||
 | 
					import static org.mockito.Mockito.when;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@ExtendWith(MockitoExtension.class)
 | 
				
			||||||
 | 
					public class RelationPathQueryDynamicSourceConfigurationTest {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @Test
 | 
				
			||||||
 | 
					    void typeShouldBeRelationQuery() {
 | 
				
			||||||
 | 
					        var cfg = new RelationPathQueryDynamicSourceConfiguration();
 | 
				
			||||||
 | 
					        assertThat(cfg.getType()).isEqualTo(CFArgumentDynamicSourceType.RELATION_PATH_QUERY);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @ParameterizedTest
 | 
				
			||||||
 | 
					    @NullAndEmptySource
 | 
				
			||||||
 | 
					    void validateShouldThrowWhenLevelsIsNull(List<RelationPathLevel> levels) {
 | 
				
			||||||
 | 
					        var cfg = new RelationPathQueryDynamicSourceConfiguration();
 | 
				
			||||||
 | 
					        cfg.setLevels(levels);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        assertThatThrownBy(cfg::validate)
 | 
				
			||||||
 | 
					                .isInstanceOf(IllegalArgumentException.class)
 | 
				
			||||||
 | 
					                .hasMessage("At least one relation level must be specified!");
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @Test
 | 
				
			||||||
 | 
					    void validateShouldCallValidateForPathLevels() {
 | 
				
			||||||
 | 
					        List<RelationPathLevel> levels = new ArrayList<>();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        RelationPathLevel lvl1 = mock(RelationPathLevel.class);
 | 
				
			||||||
 | 
					        RelationPathLevel lvl2 = mock(RelationPathLevel.class);
 | 
				
			||||||
 | 
					        levels.add(lvl1);
 | 
				
			||||||
 | 
					        levels.add(lvl2);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        var cfg = new RelationPathQueryDynamicSourceConfiguration();
 | 
				
			||||||
 | 
					        cfg.setLevels(levels);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        assertThatCode(cfg::validate).doesNotThrowAnyException();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        verify(lvl1).validate();
 | 
				
			||||||
 | 
					        verify(lvl2).validate();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @Test
 | 
				
			||||||
 | 
					    void resolveEntityIds_whenDirectionFROM_thenReturnsToIds() {
 | 
				
			||||||
 | 
					        List<RelationPathLevel> levels = new ArrayList<>();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        RelationPathLevel lvl1 = mock(RelationPathLevel.class);
 | 
				
			||||||
 | 
					        RelationPathLevel lvl2 = mock(RelationPathLevel.class);
 | 
				
			||||||
 | 
					        levels.add(lvl1);
 | 
				
			||||||
 | 
					        levels.add(lvl2);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        when(lvl2.direction()).thenReturn(EntitySearchDirection.FROM);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        EntityRelation rel1 = mock(EntityRelation.class);
 | 
				
			||||||
 | 
					        EntityRelation rel2 = mock(EntityRelation.class);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        when(rel1.getTo()).thenReturn(mock(EntityId.class));
 | 
				
			||||||
 | 
					        when(rel2.getTo()).thenReturn(mock(EntityId.class));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        var cfg = new RelationPathQueryDynamicSourceConfiguration();
 | 
				
			||||||
 | 
					        cfg.setLevels(levels);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        var out = cfg.resolveEntityIds(List.of(rel1, rel2));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        assertThat(out).containsExactly(rel1.getTo(), rel2.getTo());
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @Test
 | 
				
			||||||
 | 
					    void resolveEntityIds_whenDirectionTO_thenReturnsFromIds() {
 | 
				
			||||||
 | 
					        List<RelationPathLevel> levels = new ArrayList<>();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        RelationPathLevel lvl1 = mock(RelationPathLevel.class);
 | 
				
			||||||
 | 
					        RelationPathLevel lvl2 = mock(RelationPathLevel.class);
 | 
				
			||||||
 | 
					        levels.add(lvl1);
 | 
				
			||||||
 | 
					        levels.add(lvl2);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        when(lvl2.direction()).thenReturn(EntitySearchDirection.TO);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        EntityRelation rel1 = mock(EntityRelation.class);
 | 
				
			||||||
 | 
					        EntityRelation rel2 = mock(EntityRelation.class);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        when(rel1.getFrom()).thenReturn(mock(EntityId.class));
 | 
				
			||||||
 | 
					        when(rel2.getFrom()).thenReturn(mock(EntityId.class));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        var cfg = new RelationPathQueryDynamicSourceConfiguration();
 | 
				
			||||||
 | 
					        cfg.setLevels(levels);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        var out = cfg.resolveEntityIds(List.of(rel1, rel2));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        assertThat(out).containsExactly(rel1.getFrom(), rel2.getFrom());
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -123,9 +123,8 @@ public class RelationQueryDynamicSourceConfigurationTest {
 | 
				
			|||||||
                .hasMessage("Relation query dynamic source configuration relation type must be specified!");
 | 
					                .hasMessage("Relation query dynamic source configuration relation type must be specified!");
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @ParameterizedTest
 | 
					    @Test
 | 
				
			||||||
    @NullAndEmptySource
 | 
					    void isSimpleRelationTrueWhenLevelIsOneAndEntityTypesEmptyOrNull() {
 | 
				
			||||||
    void isSimpleRelationTrueWhenLevelIsOneAndEntityTypesEmptyOrNull(List<EntityType> entityTypes) {
 | 
					 | 
				
			||||||
        var cfg = new RelationQueryDynamicSourceConfiguration();
 | 
					        var cfg = new RelationQueryDynamicSourceConfiguration();
 | 
				
			||||||
        cfg.setMaxLevel(1);
 | 
					        cfg.setMaxLevel(1);
 | 
				
			||||||
        assertThat(cfg.isSimpleRelation()).isTrue();
 | 
					        assertThat(cfg.isSimpleRelation()).isTrue();
 | 
				
			||||||
@ -138,9 +137,8 @@ public class RelationQueryDynamicSourceConfigurationTest {
 | 
				
			|||||||
        assertThat(cfg.isSimpleRelation()).isFalse();
 | 
					        assertThat(cfg.isSimpleRelation()).isFalse();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @ParameterizedTest
 | 
					    @Test
 | 
				
			||||||
    @NullAndEmptySource
 | 
					    void toEntityRelationsQueryShouldThrowForSimpleRelation() {
 | 
				
			||||||
    void toEntityRelationsQueryShouldThrowForSimpleRelation(List<EntityType> entityTypes) {
 | 
					 | 
				
			||||||
        var cfg = new RelationQueryDynamicSourceConfiguration();
 | 
					        var cfg = new RelationQueryDynamicSourceConfiguration();
 | 
				
			||||||
        cfg.setMaxLevel(1);
 | 
					        cfg.setMaxLevel(1);
 | 
				
			||||||
        cfg.setFetchLastLevelOnly(false);
 | 
					        cfg.setFetchLastLevelOnly(false);
 | 
				
			||||||
@ -177,7 +175,7 @@ public class RelationQueryDynamicSourceConfigurationTest {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @Test
 | 
					    @Test
 | 
				
			||||||
    void resolveEntityIdsFromDirectionFROMReturnsToIds() {
 | 
					    void resolveEntityIds_whenDirectionFROM_thenReturnsToIds() {
 | 
				
			||||||
        when(rel1.getTo()).thenReturn(mock(EntityId.class));
 | 
					        when(rel1.getTo()).thenReturn(mock(EntityId.class));
 | 
				
			||||||
        when(rel2.getTo()).thenReturn(mock(EntityId.class));
 | 
					        when(rel2.getTo()).thenReturn(mock(EntityId.class));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -190,7 +188,7 @@ public class RelationQueryDynamicSourceConfigurationTest {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @Test
 | 
					    @Test
 | 
				
			||||||
    void resolveEntityIdsFromDirectionTOReturnsFromIds() {
 | 
					    void resolveEntityIds_whenDirectionTO_thenReturnsFromIds() {
 | 
				
			||||||
        when(rel1.getFrom()).thenReturn(mock(EntityId.class));
 | 
					        when(rel1.getFrom()).thenReturn(mock(EntityId.class));
 | 
				
			||||||
        when(rel2.getFrom()).thenReturn(mock(EntityId.class));
 | 
					        when(rel2.getFrom()).thenReturn(mock(EntityId.class));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -28,9 +28,11 @@ import org.thingsboard.server.common.data.EntityType;
 | 
				
			|||||||
import org.thingsboard.server.common.data.id.AssetId;
 | 
					import org.thingsboard.server.common.data.id.AssetId;
 | 
				
			||||||
import org.thingsboard.server.common.data.id.DeviceId;
 | 
					import org.thingsboard.server.common.data.id.DeviceId;
 | 
				
			||||||
import org.thingsboard.server.common.data.relation.EntityRelation;
 | 
					import org.thingsboard.server.common.data.relation.EntityRelation;
 | 
				
			||||||
 | 
					import org.thingsboard.server.common.data.relation.EntityRelationPathQuery;
 | 
				
			||||||
import org.thingsboard.server.common.data.relation.EntityRelationsQuery;
 | 
					import org.thingsboard.server.common.data.relation.EntityRelationsQuery;
 | 
				
			||||||
import org.thingsboard.server.common.data.relation.EntitySearchDirection;
 | 
					import org.thingsboard.server.common.data.relation.EntitySearchDirection;
 | 
				
			||||||
import org.thingsboard.server.common.data.relation.RelationEntityTypeFilter;
 | 
					import org.thingsboard.server.common.data.relation.RelationEntityTypeFilter;
 | 
				
			||||||
 | 
					import org.thingsboard.server.common.data.relation.RelationPathLevel;
 | 
				
			||||||
import org.thingsboard.server.common.data.relation.RelationTypeGroup;
 | 
					import org.thingsboard.server.common.data.relation.RelationTypeGroup;
 | 
				
			||||||
import org.thingsboard.server.common.data.relation.RelationsSearchParameters;
 | 
					import org.thingsboard.server.common.data.relation.RelationsSearchParameters;
 | 
				
			||||||
import org.thingsboard.server.dao.exception.DataValidationException;
 | 
					import org.thingsboard.server.dao.exception.DataValidationException;
 | 
				
			||||||
@ -42,6 +44,8 @@ import java.util.LinkedList;
 | 
				
			|||||||
import java.util.List;
 | 
					import java.util.List;
 | 
				
			||||||
import java.util.concurrent.ExecutionException;
 | 
					import java.util.concurrent.ExecutionException;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import static org.assertj.core.api.Assertions.assertThat;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@DaoSqlTest
 | 
					@DaoSqlTest
 | 
				
			||||||
public class RelationServiceTest extends AbstractServiceTest {
 | 
					public class RelationServiceTest extends AbstractServiceTest {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -348,14 +352,14 @@ public class RelationServiceTest extends AbstractServiceTest {
 | 
				
			|||||||
        query.setFilters(Collections.singletonList(new RelationEntityTypeFilter(EntityRelation.CONTAINS_TYPE, Collections.singletonList(EntityType.ASSET))));
 | 
					        query.setFilters(Collections.singletonList(new RelationEntityTypeFilter(EntityRelation.CONTAINS_TYPE, Collections.singletonList(EntityType.ASSET))));
 | 
				
			||||||
        List<EntityRelation> relations = relationService.findByQuery(SYSTEM_TENANT_ID, query).get();
 | 
					        List<EntityRelation> relations = relationService.findByQuery(SYSTEM_TENANT_ID, query).get();
 | 
				
			||||||
        Assert.assertEquals(expected.size(), relations.size());
 | 
					        Assert.assertEquals(expected.size(), relations.size());
 | 
				
			||||||
        for(EntityRelation r : expected){
 | 
					        for (EntityRelation r : expected) {
 | 
				
			||||||
            Assert.assertTrue(relations.contains(r));
 | 
					            Assert.assertTrue(relations.contains(r));
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        //Test from cache
 | 
					        //Test from cache
 | 
				
			||||||
        relations = relationService.findByQuery(SYSTEM_TENANT_ID, query).get();
 | 
					        relations = relationService.findByQuery(SYSTEM_TENANT_ID, query).get();
 | 
				
			||||||
        Assert.assertEquals(expected.size(), relations.size());
 | 
					        Assert.assertEquals(expected.size(), relations.size());
 | 
				
			||||||
        for(EntityRelation r : expected){
 | 
					        for (EntityRelation r : expected) {
 | 
				
			||||||
            Assert.assertTrue(relations.contains(r));
 | 
					            Assert.assertTrue(relations.contains(r));
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@ -623,6 +627,51 @@ public class RelationServiceTest extends AbstractServiceTest {
 | 
				
			|||||||
        Assert.assertTrue(relations.contains(relationF));
 | 
					        Assert.assertTrue(relations.contains(relationF));
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @Test
 | 
				
			||||||
 | 
					    public void testFindByPathQuery() throws Exception {
 | 
				
			||||||
 | 
					        /*
 | 
				
			||||||
 | 
					        A
 | 
				
			||||||
 | 
					        └──[firstLevel, TO]→ B
 | 
				
			||||||
 | 
					            └──[secondLevel, TO]→ C
 | 
				
			||||||
 | 
					                ├──[thirdLevel, FROM]→ D
 | 
				
			||||||
 | 
					                ├──[thirdLevel, FROM]→ E
 | 
				
			||||||
 | 
					                └──[thirdLevel, FROM]→ F
 | 
				
			||||||
 | 
					        */
 | 
				
			||||||
 | 
					        // rootEntity
 | 
				
			||||||
 | 
					        AssetId assetA = new AssetId(Uuids.timeBased());
 | 
				
			||||||
 | 
					        // firstLevelEntity
 | 
				
			||||||
 | 
					        AssetId assetB = new AssetId(Uuids.timeBased());
 | 
				
			||||||
 | 
					        // secondLevelEntity
 | 
				
			||||||
 | 
					        AssetId assetC = new AssetId(Uuids.timeBased());
 | 
				
			||||||
 | 
					        // thirdLevelEntities
 | 
				
			||||||
 | 
					        AssetId assetD = new AssetId(Uuids.timeBased());
 | 
				
			||||||
 | 
					        AssetId assetE = new AssetId(Uuids.timeBased());
 | 
				
			||||||
 | 
					        AssetId assetF = new AssetId(Uuids.timeBased());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        EntityRelation firstLevelRelation = new EntityRelation(assetB, assetA, "firstLevel");
 | 
				
			||||||
 | 
					        EntityRelation secondLevelRelation = new EntityRelation(assetC, assetB, "secondLevel");
 | 
				
			||||||
 | 
					        EntityRelation thirdLevelRelation1 = new EntityRelation(assetC, assetD, "thirdLevel");
 | 
				
			||||||
 | 
					        EntityRelation thirdLevelRelation2 = new EntityRelation(assetC, assetE, "thirdLevel");
 | 
				
			||||||
 | 
					        EntityRelation thirdLevelRelation3 = new EntityRelation(assetC, assetF, "thirdLevel");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        firstLevelRelation = saveRelation(firstLevelRelation);
 | 
				
			||||||
 | 
					        secondLevelRelation = saveRelation(secondLevelRelation);
 | 
				
			||||||
 | 
					        thirdLevelRelation1 = saveRelation(thirdLevelRelation1);
 | 
				
			||||||
 | 
					        thirdLevelRelation2 = saveRelation(thirdLevelRelation2);
 | 
				
			||||||
 | 
					        thirdLevelRelation3 = saveRelation(thirdLevelRelation3);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        List<EntityRelation> expectedRelations = List.of(thirdLevelRelation1, thirdLevelRelation2, thirdLevelRelation3);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        EntityRelationPathQuery relationPathQuery = new EntityRelationPathQuery(assetA, List.of(
 | 
				
			||||||
 | 
					                new RelationPathLevel(EntitySearchDirection.TO, "firstLevel"),
 | 
				
			||||||
 | 
					                new RelationPathLevel(EntitySearchDirection.TO, "secondLevel"),
 | 
				
			||||||
 | 
					                new RelationPathLevel(EntitySearchDirection.FROM, "thirdLevel")
 | 
				
			||||||
 | 
					        ));
 | 
				
			||||||
 | 
					        List<EntityRelation> entityRelations = relationService.findByRelationPathQueryAsync(tenantId, relationPathQuery).get();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        assertThat(expectedRelations).containsExactlyInAnyOrderElementsOf(entityRelations);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @Test
 | 
					    @Test
 | 
				
			||||||
    public void testFindByQueryLargeHierarchyFetchAllWithUnlimLvl() throws Exception {
 | 
					    public void testFindByQueryLargeHierarchyFetchAllWithUnlimLvl() throws Exception {
 | 
				
			||||||
        AssetId rootAsset = new AssetId(Uuids.timeBased());
 | 
					        AssetId rootAsset = new AssetId(Uuids.timeBased());
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user