ATLAS-4225 : Support for Chinese character in Atlas entities
Signed-off-by: Pinal Shah <pinal.shah@freestoneinfotech.com>
diff --git a/intg/src/main/java/org/apache/atlas/type/AtlasStructType.java b/intg/src/main/java/org/apache/atlas/type/AtlasStructType.java
index 591b316..ffbe9e7 100644
--- a/intg/src/main/java/org/apache/atlas/type/AtlasStructType.java
+++ b/intg/src/main/java/org/apache/atlas/type/AtlasStructType.java
@@ -1075,17 +1075,30 @@
}
public static boolean hastokenizeChar(String value) {
- if (value != null) {
+ if (StringUtils.isNotEmpty(value)) {
for (int i = 0; i < value.length(); i++) {
if (hastokenizeChar(value, i)) {
return true;
+ } else if (hasCJKChar(value,i)) {
+ return true;
}
}
}
-
return false;
}
+ private static boolean hasCJKChar(String value,int i){
+ char ch = value.charAt(i);
+ Character.UnicodeBlock block = Character.UnicodeBlock.of(ch);
+
+ if (Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS.equals(block) ||
+ Character.UnicodeBlock.CJK_COMPATIBILITY_IDEOGRAPHS.equals(block) ||
+ Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS_EXTENSION_A.equals(block) ||
+ Character.UnicodeBlock.HIRAGANA.equals(block)) {
+ return true;
+ }
+ return false;
+ }
private static boolean hastokenizeChar(String value, int i) {
char c = value.charAt(i);
diff --git a/intg/src/test/java/org/apache/atlas/type/TestAtlasStructType.java b/intg/src/test/java/org/apache/atlas/type/TestAtlasStructType.java
index f117fb3..f292f00 100644
--- a/intg/src/test/java/org/apache/atlas/type/TestAtlasStructType.java
+++ b/intg/src/test/java/org/apache/atlas/type/TestAtlasStructType.java
@@ -49,6 +49,8 @@
private final AtlasStructType structType;
private final List<Object> validValues;
private final List<Object> invalidValues;
+ private final List<String> tokenizedValue;
+ private final List<String> nonTokenizedValue;
{
AtlasAttributeDef multiValuedAttribMinMax = new AtlasAttributeDef();
@@ -126,6 +128,31 @@
invalidValues.add(new HashSet()); // incorrect datatype
invalidValues.add(new ArrayList()); // incorrect datatype
invalidValues.add(new String[] {}); // incorrect datatype
+
+ tokenizedValue = new ArrayList<>();
+
+ tokenizedValue.add("test[data"); //added special char [
+ tokenizedValue.add("test]data"); //added special char ]
+ tokenizedValue.add("狗"); //single char chinese data
+ tokenizedValue.add("数据"); //mutiple char chinese data
+ tokenizedValue.add("test data"); //english words with space
+ tokenizedValue.add("testdata "); //space after testdata
+ tokenizedValue.add("私は日本語を話します"); //japanese word
+ tokenizedValue.add("元帳"); //japanese ledger char
+ tokenizedValue.add("mydata&"); //added special char &
+ tokenizedValue.add("test.1data");
+ tokenizedValue.add("test:1data");
+
+ nonTokenizedValue = new ArrayList<>();
+
+ nonTokenizedValue.add("test.data");
+ nonTokenizedValue.add("test:data");
+ nonTokenizedValue.add("test_data");
+ nonTokenizedValue.add("test:");
+ nonTokenizedValue.add("test.");
+ nonTokenizedValue.add("test_");
+ nonTokenizedValue.add("レシート");
+ nonTokenizedValue.add("test");
}
@Test
@@ -199,6 +226,16 @@
}
}
+ @Test
+ public void testTokenizeChar() {
+ for (String valid : tokenizedValue) {
+ assertTrue(AtlasStructType.AtlasAttribute.hastokenizeChar(valid));
+ }
+ for (String invalid : nonTokenizedValue) {
+ assertFalse(AtlasStructType.AtlasAttribute.hastokenizeChar(invalid));
+ }
+ }
+
private static AtlasStructType getStructType(AtlasStructDef structDef) {
try {
return new AtlasStructType(structDef, ModelTestUtil.getTypesRegistry());
diff --git a/repository/src/main/java/org/apache/atlas/discovery/EntityDiscoveryService.java b/repository/src/main/java/org/apache/atlas/discovery/EntityDiscoveryService.java
index 9be6517..dc3acf6 100644
--- a/repository/src/main/java/org/apache/atlas/discovery/EntityDiscoveryService.java
+++ b/repository/src/main/java/org/apache/atlas/discovery/EntityDiscoveryService.java
@@ -466,6 +466,16 @@
@Override
@GraphTransaction
public AtlasSearchResult searchWithParameters(SearchParameters searchParameters) throws AtlasBaseException {
+ String query = searchParameters.getQuery();
+
+ if (StringUtils.isNotEmpty(query)) {
+
+ String modifiedString = StringUtils.strip(query, "*");
+
+ if (AtlasStructType.AtlasAttribute.hastokenizeChar(modifiedString)) {
+ searchParameters.setQuery(modifiedString);
+ }
+ }
return searchWithSearchContext(new SearchContext(searchParameters, typeRegistry, graph, indexer.getVertexIndexKeys()));
}
diff --git a/repository/src/main/java/org/apache/atlas/repository/store/graph/v2/EntityGraphMapper.java b/repository/src/main/java/org/apache/atlas/repository/store/graph/v2/EntityGraphMapper.java
index 01b88eb..77ab99a 100644
--- a/repository/src/main/java/org/apache/atlas/repository/store/graph/v2/EntityGraphMapper.java
+++ b/repository/src/main/java/org/apache/atlas/repository/store/graph/v2/EntityGraphMapper.java
@@ -142,8 +142,8 @@
private static final String CUSTOM_ATTRIBUTE_KEY_SPECIAL_PREFIX = AtlasConfiguration.CUSTOM_ATTRIBUTE_KEY_SPECIAL_PREFIX.getString();
private static final String CLASSIFICATION_NAME_DELIMITER = "|";
- private static final Pattern CUSTOM_ATTRIBUTE_KEY_REGEX = Pattern.compile("^[a-zA-Z0-9_-]*$");
- private static final Pattern LABEL_REGEX = Pattern.compile("^[a-zA-Z0-9_-]*$");
+ private static final Pattern CUSTOM_ATTRIBUTE_KEY_REGEX = Pattern.compile("^[\u2E80-\u2FD5\u3190-\u319f\u3400-\u4DBF\u4E00-\u9FCC\uF900-\uFAADa-zA-Z0-9_-]*$");
+ private static final Pattern LABEL_REGEX = Pattern.compile("^[\u2E80-\u2FD5\u3190-\u319f\u3400-\u4DBF\u4E00-\u9FCC\uF900-\uFAADa-zA-Z0-9_-]*$");
private static final int CUSTOM_ATTRIBUTE_KEY_MAX_LENGTH = AtlasConfiguration.CUSTOM_ATTRIBUTE_KEY_MAX_LENGTH.getInt();
private static final int CUSTOM_ATTRIBUTE_VALUE_MAX_LENGTH = AtlasConfiguration.CUSTOM_ATTRIBUTE_VALUE_MAX_LENGTH.getInt();
diff --git a/repository/src/test/java/org/apache/atlas/BasicTestSetup.java b/repository/src/test/java/org/apache/atlas/BasicTestSetup.java
index 593f8c1..88ca39c 100644
--- a/repository/src/test/java/org/apache/atlas/BasicTestSetup.java
+++ b/repository/src/test/java/org/apache/atlas/BasicTestSetup.java
@@ -56,6 +56,7 @@
private static final String STORAGE_DESC_TYPE = "hive_storagedesc";
private static final String VIEW_TYPE = "hive_process";
protected static final String DATASET_SUBTYPE = "Asset";
+ protected static final String HDFS_PATH = "hdfs_path";
//Classification type //
public static final String DIMENSION_CLASSIFICATION = "Dimension";
@@ -94,6 +95,7 @@
protected void setupTestData() {
loadBaseModels();
loadHiveDataset();
+ loadFsDataset();
loadEmployeeDataset();
assignGlossary();
}
@@ -148,6 +150,18 @@
}
}
+ protected void loadFsDataset() {
+ if (!baseLoaded) {
+ loadBaseModels();
+ }
+
+ try {
+ loadModelFromJson("1000-Hadoop/1020-fs_model.json", typeDefStore, typeRegistry);
+ } catch (IOException | AtlasBaseException e) {
+ fail("Fs model setup is required for test to run!");
+ }
+ }
+
protected void loadEmployeeDataset() {
if (!baseLoaded) {
loadBaseModels();
@@ -342,7 +356,8 @@
new AtlasClassificationDef(PII_CLASSIFICATION, "PII Classification", "1.0"),
new AtlasClassificationDef(METRIC_CLASSIFICATION, "Metric Classification", "1.0"),
new AtlasClassificationDef(ETL_CLASSIFICATION, "ETL Classification", "1.0"),
- new AtlasClassificationDef(JDBC_CLASSIFICATION, "JdbcAccess Classification", "1.0"),
+ new AtlasClassificationDef(JDBC_CLASSIFICATION, "JdbcAccess Classification", "1.0",
+ Arrays.asList(new AtlasStructDef.AtlasAttributeDef("attr1","string"))),
new AtlasClassificationDef(LOGDATA_CLASSIFICATION, "LogData Classification", "1.0"),
new AtlasClassificationDef(DIMENSIONAL_CLASSIFICATION,"Dimensional Classification", "1.0" ,
Arrays.asList(new AtlasStructDef.AtlasAttributeDef("attr1","string"))));
@@ -759,4 +774,24 @@
}
return entities;
}
+
+ public void addLabels(){
+
+ for(AtlasEntityHeader entity : hiveEntities.getCreatedEntities()) {
+
+ if (entity.getTypeName().equals(HIVE_TABLE_TYPE)){
+ Set<String> labels = new HashSet<>();
+ labels.add("你好");
+
+ try {
+ entityStore.setLabels(entity.getGuid(), labels);
+
+ } catch (AtlasBaseException e) {
+ fail("Failed to add Labels for Chinese characters to entity");
+ }
+ break;
+ }
+ }
+
+ }
}
diff --git a/repository/src/test/java/org/apache/atlas/discovery/AtlasDiscoveryServiceTest.java b/repository/src/test/java/org/apache/atlas/discovery/AtlasDiscoveryServiceTest.java
index 282a3fd..fb94aae 100644
--- a/repository/src/test/java/org/apache/atlas/discovery/AtlasDiscoveryServiceTest.java
+++ b/repository/src/test/java/org/apache/atlas/discovery/AtlasDiscoveryServiceTest.java
@@ -42,6 +42,7 @@
import org.testng.annotations.*;
import javax.inject.Inject;
+import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
@@ -69,6 +70,7 @@
createDimensionalTaggedEntity("sales");
createSpecialCharTestEntities();
setupRelationshipTestData();
+ createJapaneseEntityWithDescription();
}
/* TermSearchProcessor(TSP),
@@ -1047,6 +1049,78 @@
assertEquals(sr.getRelations().size(), 4);
}
+ @Test
+ public void cjkCharQuickSearch() throws AtlasBaseException {
+ addLabels();
+ String searchValue = "你";
+ int expected = 1;
+
+ QuickSearchParameters params = new QuickSearchParameters();
+ params.setQuery(searchValue);
+ params.setLimit(5);
+ params.setOffset(0);
+
+ AtlasQuickSearchResult searchResult = discoveryService.quickSearch(params);
+ assertSearchResult(searchResult.getSearchResults(), expected, searchValue);
+ }
+
+ @Test(dependsOnMethods = "cjkCharQuickSearch")
+ public void cjkCharBasicSearch() throws AtlasBaseException {
+ String searchValue = "你好";
+ int expected = 1;
+
+ SearchParameters params = new SearchParameters();
+ params.setQuery(searchValue);
+ params.setLimit(5);
+ params.setOffset(0);
+
+ AtlasSearchResult searchResult = discoveryService.searchWithParameters(params);
+ assertSearchResult(searchResult, expected, searchValue);
+ }
+
+ @Test
+ public void japaneseReceiptStarSearch() throws AtlasBaseException {
+ String searchValue = "レシート";
+ int expected = 1;
+
+ SearchParameters params = new SearchParameters();
+ params.setQuery(searchValue);
+ params.setTypeName(HDFS_PATH);
+ params.setLimit(5);
+ params.setOffset(0);
+
+ AtlasSearchResult searchResult = discoveryService.searchWithParameters(params);
+ assertSearchResult(searchResult, expected, searchValue);
+ }
+
+ @Test
+ public void japaneseLedgerSearch() throws AtlasBaseException {
+ String searchValue = "元帳";
+ int expected = 2;
+
+ SearchParameters params = new SearchParameters();
+ params.setQuery(searchValue);
+ params.setLimit(5);
+ params.setOffset(0);
+
+ AtlasSearchResult searchResult = discoveryService.searchWithParameters(params);
+ assertSearchResult(searchResult, expected, searchValue);
+ }
+
+ @Test
+ public void japaneseLedgerStarSearch() throws AtlasBaseException {
+ String searchValue = "の台*";
+ int expected = 1;
+
+ SearchParameters params = new SearchParameters();
+ params.setQuery(searchValue);
+ params.setLimit(5);
+ params.setOffset(0);
+
+ AtlasSearchResult searchResult = discoveryService.searchWithParameters(params);
+ assertSearchResult(searchResult, expected, searchValue);
+ }
+
private String gethiveTableSalesFactGuid() throws AtlasBaseException {
if (salesFactGuid == null) {
SearchParameters params = new SearchParameters();
@@ -1105,6 +1179,21 @@
entityStore.addClassification(Arrays.asList(guid), new AtlasClassification(DIMENSIONAL_CLASSIFICATION, attr));
}
+ private void createJapaneseEntityWithDescription() throws AtlasBaseException {
+ AtlasEntity entity = new AtlasEntity(HDFS_PATH);
+ entity.setAttribute("name", "元帳");
+ entity.setAttribute(AtlasClient.REFERENCEABLE_ATTRIBUTE_NAME, "レシート");
+ entity.setAttribute("path", "レシート");
+
+ entityStore.createOrUpdate(new AtlasEntityStream(new AtlasEntity.AtlasEntitiesWithExtInfo(entity)), false);
+
+ AtlasEntity entity2 = new AtlasEntity(HDFS_PATH);
+ entity2.setAttribute("name", "cjk");
+ entity2.setAttribute(AtlasClient.REFERENCEABLE_ATTRIBUTE_NAME, "の台帳");
+ entity2.setAttribute("path", "cjk");
+
+ entityStore.createOrUpdate(new AtlasEntityStream(new AtlasEntity.AtlasEntitiesWithExtInfo(entity2)), false);
+ }
private void assertSearchProcessorWithoutMarker(SearchParameters params, int expected) throws AtlasBaseException {
assertSearchProcessor(params, expected, false);
diff --git a/repository/src/test/java/org/apache/atlas/discovery/ClassificationSearchProcessorTest.java b/repository/src/test/java/org/apache/atlas/discovery/ClassificationSearchProcessorTest.java
index 121dca9..c69302a 100644
--- a/repository/src/test/java/org/apache/atlas/discovery/ClassificationSearchProcessorTest.java
+++ b/repository/src/test/java/org/apache/atlas/discovery/ClassificationSearchProcessorTest.java
@@ -64,6 +64,8 @@
private int dimensionTagEntities = 10;
private String dimensionTagDeleteGuid;
private String dimensionalTagGuid;
+ private String CJKGUID1;
+ private String CJKGUID2;
@BeforeClass
public void setup() throws Exception {
@@ -72,6 +74,8 @@
setupTestData();
createDimensionTaggedEntityAndDelete();
createDimensionalTaggedEntityWithAttr();
+ createChineseEntityWithClassificationSingleChar();
+ createChineseEntityWithClassificationMultipleChar();
}
@Test(priority = -1)
@@ -356,6 +360,360 @@
}
+ private void createChineseEntityWithClassificationSingleChar() throws AtlasBaseException {
+ AtlasEntity entityToDelete = new AtlasEntity(HDFS_PATH);
+ entityToDelete.setAttribute("name", "h1");
+ entityToDelete.setAttribute(AtlasClient.REFERENCEABLE_ATTRIBUTE_NAME, "h1qualified");
+ entityToDelete.setAttribute("path", "h1");
+
+ List<AtlasClassification> cls = new ArrayList<>();
+ cls.add(new AtlasClassification(JDBC_CLASSIFICATION, new HashMap<String, Object>() {{
+ put("attr1", "狗");
+ }}));
+ entityToDelete.setClassifications(cls);
+
+ //create entity
+ final EntityMutationResponse response = entityStore.createOrUpdate(new AtlasEntityStream(new AtlasEntity.AtlasEntitiesWithExtInfo(entityToDelete)), false);
+ AtlasEntityHeader entityHeader = response.getCreatedEntities().get(0);
+ CJKGUID1 = entityHeader.getGuid();
+
+ }
+
+ private void createChineseEntityWithClassificationMultipleChar() throws AtlasBaseException {
+ AtlasEntity entityToDelete = new AtlasEntity(HDFS_PATH);
+ entityToDelete.setAttribute("name", "h2");
+ entityToDelete.setAttribute(AtlasClient.REFERENCEABLE_ATTRIBUTE_NAME, "h2qualified");
+ entityToDelete.setAttribute("path", "h2");
+
+
+ List<AtlasClassification> cls = new ArrayList<>();
+ cls.add(new AtlasClassification(JDBC_CLASSIFICATION, new HashMap<String, Object>() {{
+ put("attr1", "数据");
+ }}));
+ entityToDelete.setClassifications(cls);
+
+ //create entity
+ final EntityMutationResponse response = entityStore.createOrUpdate(new AtlasEntityStream(new AtlasEntity.AtlasEntitiesWithExtInfo(entityToDelete)), false);
+ AtlasEntityHeader entityHeader = response.getCreatedEntities().get(0);
+ CJKGUID2 = entityHeader.getGuid();
+
+ }
+
+ //Equals with single char
+ @Test
+ public void searchJapaneseChineseByTagEquals() throws AtlasBaseException {
+ SearchParameters params = new SearchParameters();
+ params.setClassification(JDBC_CLASSIFICATION);
+ FilterCriteria filterCriteria = getSingleFilterCondition("attr1", Operator.EQ, "狗");
+ params.setTagFilters(filterCriteria);
+ params.setLimit(20);
+
+ SearchContext context = new SearchContext(params, typeRegistry, graph, indexer.getVertexIndexKeys());
+ ClassificationSearchProcessor processor = new ClassificationSearchProcessor(context);
+ List<AtlasVertex> vertices = processor.execute();
+
+ Assert.assertTrue(CollectionUtils.isNotEmpty(vertices));
+ assertEquals(vertices.size(), 1);
+ List<String> guids = vertices.stream().map(g -> {
+ try {
+ return entityRetriever.toAtlasEntityHeader(g).getGuid();
+ } catch (AtlasBaseException e) {
+ fail("Failure in mapping vertex to AtlasEntityHeader");
+ }
+ return "";
+ }).collect(Collectors.toList());
+ Assert.assertTrue(guids.contains(CJKGUID1));
+
+ }
+
+ //NEQ with single char
+ @Test
+ public void searchJapaneseChineseByTagNotEquals() throws AtlasBaseException {
+ SearchParameters params = new SearchParameters();
+ params.setClassification(JDBC_CLASSIFICATION);
+ FilterCriteria filterCriteria = getSingleFilterCondition("attr1", Operator.NEQ, "狗");
+ params.setTagFilters(filterCriteria);
+ params.setLimit(20);
+
+ SearchContext context = new SearchContext(params, typeRegistry, graph, indexer.getVertexIndexKeys());
+ ClassificationSearchProcessor processor = new ClassificationSearchProcessor(context);
+ List<AtlasVertex> vertices = processor.execute();
+
+ Assert.assertTrue(CollectionUtils.isNotEmpty(vertices));
+ assertEquals(vertices.size(), 1);
+ List<String> guids = vertices.stream().map(g -> {
+ try {
+ return entityRetriever.toAtlasEntityHeader(g).getGuid();
+ } catch (AtlasBaseException e) {
+ fail("Failure in mapping vertex to AtlasEntityHeader");
+ }
+ return "";
+ }).collect(Collectors.toList());
+ Assert.assertTrue(guids.contains(CJKGUID2));
+
+ }
+
+ //Contains with single char
+ @Test
+ public void searchJapaneseChineseByTagContains() throws AtlasBaseException {
+ SearchParameters params = new SearchParameters();
+ params.setClassification(JDBC_CLASSIFICATION);
+ FilterCriteria filterCriteria = getSingleFilterCondition("attr1", Operator.CONTAINS, "狗");
+ params.setTagFilters(filterCriteria);
+ params.setLimit(20);
+
+ SearchContext context = new SearchContext(params, typeRegistry, graph, indexer.getVertexIndexKeys());
+ ClassificationSearchProcessor processor = new ClassificationSearchProcessor(context);
+ List<AtlasVertex> vertices = processor.execute();
+
+ Assert.assertTrue(CollectionUtils.isNotEmpty(vertices));
+ assertEquals(vertices.size(), 1);
+ List<String> guids = vertices.stream().map(g -> {
+ try {
+ return entityRetriever.toAtlasEntityHeader(g).getGuid();
+ } catch (AtlasBaseException e) {
+ fail("Failure in mapping vertex to AtlasEntityHeader");
+ }
+ return "";
+ }).collect(Collectors.toList());
+ Assert.assertTrue(guids.contains(CJKGUID1));
+
+ }
+
+ //Begins with single char
+ @Test
+ public void searchJapaneseChineseByTagBeginswith() throws AtlasBaseException {
+ SearchParameters params = new SearchParameters();
+ params.setClassification(JDBC_CLASSIFICATION);
+ FilterCriteria filterCriteria = getSingleFilterCondition("attr1", Operator.STARTS_WITH, "狗");
+ params.setTagFilters(filterCriteria);
+ params.setLimit(20);
+
+ SearchContext context = new SearchContext(params, typeRegistry, graph, indexer.getVertexIndexKeys());
+ ClassificationSearchProcessor processor = new ClassificationSearchProcessor(context);
+ List<AtlasVertex> vertices = processor.execute();
+
+ Assert.assertTrue(CollectionUtils.isNotEmpty(vertices));
+ assertEquals(vertices.size(), 1);
+ List<String> guids = vertices.stream().map(g -> {
+ try {
+ return entityRetriever.toAtlasEntityHeader(g).getGuid();
+ } catch (AtlasBaseException e) {
+ fail("Failure in mapping vertex to AtlasEntityHeader");
+ }
+ return "";
+ }).collect(Collectors.toList());
+ Assert.assertTrue(guids.contains(CJKGUID1));
+
+ }
+
+ //ENDS with single char
+ @Test
+ public void searchJapaneseChineseByTagEndsWith() throws AtlasBaseException {
+ SearchParameters params = new SearchParameters();
+ params.setClassification(JDBC_CLASSIFICATION);
+ FilterCriteria filterCriteria = getSingleFilterCondition("attr1", Operator.ENDS_WITH, "狗");
+ params.setTagFilters(filterCriteria);
+ params.setLimit(20);
+
+ SearchContext context = new SearchContext(params, typeRegistry, graph, indexer.getVertexIndexKeys());
+ ClassificationSearchProcessor processor = new ClassificationSearchProcessor(context);
+ List<AtlasVertex> vertices = processor.execute();
+
+ Assert.assertTrue(CollectionUtils.isNotEmpty(vertices));
+ assertEquals(vertices.size(), 1);
+ List<String> guids = vertices.stream().map(g -> {
+ try {
+ return entityRetriever.toAtlasEntityHeader(g).getGuid();
+ } catch (AtlasBaseException e) {
+ fail("Failure in mapping vertex to AtlasEntityHeader");
+ }
+ return "";
+ }).collect(Collectors.toList());
+ Assert.assertTrue(guids.contains(CJKGUID1));
+
+ }
+
+ //ISNULL check
+ @Test
+ public void searchJapaneseChineseByTagISNULL() throws AtlasBaseException {
+ SearchParameters params = new SearchParameters();
+ params.setClassification(JDBC_CLASSIFICATION);
+ FilterCriteria filterCriteria = getSingleFilterCondition("attr1", Operator.IS_NULL, "");
+ params.setTagFilters(filterCriteria);
+ params.setLimit(20);
+
+ SearchContext context = new SearchContext(params, typeRegistry, graph, indexer.getVertexIndexKeys());
+ ClassificationSearchProcessor processor = new ClassificationSearchProcessor(context);
+ List<AtlasVertex> vertices = processor.execute();
+
+ Assert.assertTrue(CollectionUtils.isNotEmpty(vertices));
+ assertEquals(vertices.size(), 2); //customer_dim_view, product_dim_view entities
+ }
+
+ //ISNOT NULL CHECK
+ @Test
+ public void searchJapaneseChineseByTagISNOTNULL() throws AtlasBaseException {
+ SearchParameters params = new SearchParameters();
+ params.setClassification(JDBC_CLASSIFICATION);
+ FilterCriteria filterCriteria = getSingleFilterCondition("attr1", Operator.NOT_NULL, "狗");
+ params.setTagFilters(filterCriteria);
+ params.setLimit(20);
+
+ SearchContext context = new SearchContext(params, typeRegistry, graph, indexer.getVertexIndexKeys());
+ ClassificationSearchProcessor processor = new ClassificationSearchProcessor(context);
+ List<AtlasVertex> vertices = processor.execute();
+
+ Assert.assertTrue(CollectionUtils.isNotEmpty(vertices));
+ assertEquals(vertices.size(), 2);
+ List<String> guids = vertices.stream().map(g -> {
+ try {
+ return entityRetriever.toAtlasEntityHeader(g).getGuid();
+ } catch (AtlasBaseException e) {
+ fail("Failure in mapping vertex to AtlasEntityHeader");
+ }
+ return "";
+ }).collect(Collectors.toList());
+ Assert.assertTrue(guids.contains(CJKGUID1));
+
+ }
+
+ //Equals with Multiple char
+ @Test
+ public void searchJapaneseChineseByTagEqualsMultiple() throws AtlasBaseException {
+ SearchParameters params = new SearchParameters();
+ params.setClassification(JDBC_CLASSIFICATION);
+ FilterCriteria filterCriteria = getSingleFilterCondition("attr1", Operator.EQ, "数据");
+ params.setTagFilters(filterCriteria);
+ params.setLimit(20);
+
+ SearchContext context = new SearchContext(params, typeRegistry, graph, indexer.getVertexIndexKeys());
+ ClassificationSearchProcessor processor = new ClassificationSearchProcessor(context);
+ List<AtlasVertex> vertices = processor.execute();
+
+ Assert.assertTrue(CollectionUtils.isNotEmpty(vertices));
+ assertEquals(vertices.size(), 1);
+ List<String> guids = vertices.stream().map(g -> {
+ try {
+ return entityRetriever.toAtlasEntityHeader(g).getGuid();
+ } catch (AtlasBaseException e) {
+ fail("Failure in mapping vertex to AtlasEntityHeader");
+ }
+ return "";
+ }).collect(Collectors.toList());
+ Assert.assertTrue(guids.contains(CJKGUID2));
+
+ }
+
+ //NEQ with Multiple char
+ @Test
+ public void searchJapaneseChineseByTagNotEqualsMultiple() throws AtlasBaseException {
+ SearchParameters params = new SearchParameters();
+ params.setClassification(JDBC_CLASSIFICATION);
+ FilterCriteria filterCriteria = getSingleFilterCondition("attr1", Operator.NEQ, "数据");
+ params.setTagFilters(filterCriteria);
+ params.setLimit(20);
+
+ SearchContext context = new SearchContext(params, typeRegistry, graph, indexer.getVertexIndexKeys());
+ ClassificationSearchProcessor processor = new ClassificationSearchProcessor(context);
+ List<AtlasVertex> vertices = processor.execute();
+
+ Assert.assertTrue(CollectionUtils.isNotEmpty(vertices));
+ assertEquals(vertices.size(), 1);
+ List<String> guids = vertices.stream().map(g -> {
+ try {
+ return entityRetriever.toAtlasEntityHeader(g).getGuid();
+ } catch (AtlasBaseException e) {
+ fail("Failure in mapping vertex to AtlasEntityHeader");
+ }
+ return "";
+ }).collect(Collectors.toList());
+ Assert.assertTrue(guids.contains(CJKGUID1));
+
+ }
+
+ //Contains with Multiple char
+ @Test
+ public void searchJapaneseChineseByTagContainsMultiple() throws AtlasBaseException {
+ SearchParameters params = new SearchParameters();
+ params.setClassification(JDBC_CLASSIFICATION);
+ FilterCriteria filterCriteria = getSingleFilterCondition("attr1", Operator.CONTAINS, "数据");
+ params.setTagFilters(filterCriteria);
+ params.setLimit(20);
+
+ SearchContext context = new SearchContext(params, typeRegistry, graph, indexer.getVertexIndexKeys());
+ ClassificationSearchProcessor processor = new ClassificationSearchProcessor(context);
+ List<AtlasVertex> vertices = processor.execute();
+
+ Assert.assertTrue(CollectionUtils.isNotEmpty(vertices));
+ assertEquals(vertices.size(), 1);
+ List<String> guids = vertices.stream().map(g -> {
+ try {
+ return entityRetriever.toAtlasEntityHeader(g).getGuid();
+ } catch (AtlasBaseException e) {
+ fail("Failure in mapping vertex to AtlasEntityHeader");
+ }
+ return "";
+ }).collect(Collectors.toList());
+ Assert.assertTrue(guids.contains(CJKGUID2));
+
+ }
+
+ //Begins with Multiple char
+ @Test
+ public void searchJapaneseChineseByTagBeginsWithMultiple() throws AtlasBaseException {
+ SearchParameters params = new SearchParameters();
+ params.setClassification(JDBC_CLASSIFICATION);
+ FilterCriteria filterCriteria = getSingleFilterCondition("attr1", Operator.STARTS_WITH, "数据");
+ params.setTagFilters(filterCriteria);
+ params.setLimit(20);
+
+ SearchContext context = new SearchContext(params, typeRegistry, graph, indexer.getVertexIndexKeys());
+ ClassificationSearchProcessor processor = new ClassificationSearchProcessor(context);
+ List<AtlasVertex> vertices = processor.execute();
+
+ Assert.assertTrue(CollectionUtils.isNotEmpty(vertices));
+ assertEquals(vertices.size(), 1);
+ List<String> guids = vertices.stream().map(g -> {
+ try {
+ return entityRetriever.toAtlasEntityHeader(g).getGuid();
+ } catch (AtlasBaseException e) {
+ fail("Failure in mapping vertex to AtlasEntityHeader");
+ }
+ return "";
+ }).collect(Collectors.toList());
+ Assert.assertTrue(guids.contains(CJKGUID2));
+
+ }
+
+ //ENDS with single char
+ @Test
+ public void searchJapaneseChineseByTagEndsWithMultiple() throws AtlasBaseException {
+ SearchParameters params = new SearchParameters();
+ params.setClassification(JDBC_CLASSIFICATION);
+ FilterCriteria filterCriteria = getSingleFilterCondition("attr1", Operator.ENDS_WITH, "数据");
+ params.setTagFilters(filterCriteria);
+ params.setLimit(20);
+
+ SearchContext context = new SearchContext(params, typeRegistry, graph, indexer.getVertexIndexKeys());
+ ClassificationSearchProcessor processor = new ClassificationSearchProcessor(context);
+ List<AtlasVertex> vertices = processor.execute();
+
+ Assert.assertTrue(CollectionUtils.isNotEmpty(vertices));
+ assertEquals(vertices.size(), 1);
+ List<String> guids = vertices.stream().map(g -> {
+ try {
+ return entityRetriever.toAtlasEntityHeader(g).getGuid();
+ } catch (AtlasBaseException e) {
+ fail("Failure in mapping vertex to AtlasEntityHeader");
+ }
+ return "";
+ }).collect(Collectors.toList());
+ Assert.assertTrue(guids.contains(CJKGUID2));
+
+ }
+
+
@AfterClass
public void teardown() throws Exception {
AtlasGraphProvider.cleanup();
diff --git a/repository/src/test/java/org/apache/atlas/discovery/EntitySearchProcessorTest.java b/repository/src/test/java/org/apache/atlas/discovery/EntitySearchProcessorTest.java
index 3f9e74d..a4edb09 100644
--- a/repository/src/test/java/org/apache/atlas/discovery/EntitySearchProcessorTest.java
+++ b/repository/src/test/java/org/apache/atlas/discovery/EntitySearchProcessorTest.java
@@ -18,18 +18,25 @@
package org.apache.atlas.discovery;
import com.google.common.collect.Sets;
+import org.apache.atlas.AtlasClient;
import org.apache.atlas.BasicTestSetup;
import org.apache.atlas.SortOrder;
import org.apache.atlas.TestModules;
import org.apache.atlas.exception.AtlasBaseException;
import org.apache.atlas.model.discovery.SearchParameters;
+import org.apache.atlas.model.instance.AtlasClassification;
+import org.apache.atlas.model.instance.AtlasEntity;
+import org.apache.atlas.model.instance.AtlasEntityHeader;
+import org.apache.atlas.model.instance.EntityMutationResponse;
import org.apache.atlas.repository.Constants;
import org.apache.atlas.repository.graph.AtlasGraphProvider;
import org.apache.atlas.repository.graph.GraphBackedSearchIndexer;
import org.apache.atlas.repository.graphdb.AtlasGraph;
import org.apache.atlas.repository.graphdb.AtlasVertex;
+import org.apache.atlas.repository.store.graph.v2.AtlasEntityStream;
import org.apache.atlas.repository.store.graph.v2.EntityGraphRetriever;
import org.apache.atlas.type.AtlasTypeRegistry;
+import org.testng.Assert;
import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Guice;
@@ -40,6 +47,7 @@
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
+import java.util.HashMap;
import java.util.List;
import java.util.Calendar;
import java.util.GregorianCalendar;
@@ -50,6 +58,7 @@
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertTrue;
+import static org.testng.Assert.fail;
@Guice(modules = TestModules.TestOnlyModule.class)
public class EntitySearchProcessorTest extends BasicTestSetup {
@@ -65,11 +74,17 @@
@Inject
private EntityGraphRetriever entityRetriever;
+ private String CJKGUID1;
+
+ private String CJKGUID2;
+
@BeforeClass
public void setup() throws Exception {
super.initialize();
setupTestData();
+ createJapaneseEntityWithDescription();
+ createChineseEntityWithDescription();
}
@Inject
@@ -630,8 +645,172 @@
List b =v2.stream().map(v3 -> v3.getProperty(Constants.GUID_PROPERTY_KEY, String.class)).collect(Collectors.toList());
assertTrue(!a.stream().anyMatch(element -> b.contains(element)));
+ }
+ //Description EQUALS chinese multiple char
+ @Test
+ public void searchChineseDescription() throws AtlasBaseException {
+ SearchParameters params = new SearchParameters();
+ params.setTypeName(HDFS_PATH);
+ SearchParameters.FilterCriteria filterCriteria = getSingleFilterCondition("path", SearchParameters.Operator.EQ, "我说中文");
+ filterCriteria.getCriterion();
+ params.setEntityFilters(filterCriteria);
+ params.setLimit(20);
+ SearchContext context = new SearchContext(params, typeRegistry, graph, indexer.getVertexIndexKeys());
+
+ EntitySearchProcessor processor = new EntitySearchProcessor(context);//
+ List<AtlasVertex> vertices = processor.execute();
+
+ assertEquals(vertices.size(), 1);
+ List<String> guids = vertices.stream().map(g -> {
+ try {
+ return entityRetriever.toAtlasEntityHeader(g).getGuid();
+ } catch (AtlasBaseException e) {
+ fail("Failure in mapping vertex to AtlasEntityHeader");
+ }
+ return "";
+ }).collect(Collectors.toList());
+ Assert.assertTrue(guids.contains(CJKGUID2));
+ }
+
+ //Description contains chinese multiple char
+ @Test
+ public void searchChineseDescriptionCONTAINS() throws AtlasBaseException {
+ SearchParameters params = new SearchParameters();
+ params.setTypeName(HDFS_PATH);
+ SearchParameters.FilterCriteria filterCriteria = getSingleFilterCondition("path", SearchParameters.Operator.CONTAINS, "我说中文");
+ filterCriteria.getCriterion();
+ params.setEntityFilters(filterCriteria);
+ params.setLimit(20);
+
+ SearchContext context = new SearchContext(params, typeRegistry, graph, indexer.getVertexIndexKeys());
+
+ EntitySearchProcessor processor = new EntitySearchProcessor(context);//
+ List<AtlasVertex> vertices = processor.execute();
+
+ assertEquals(vertices.size(), 1);
+ List<String> guids = vertices.stream().map(g -> {
+ try {
+ return entityRetriever.toAtlasEntityHeader(g).getGuid();
+ } catch (AtlasBaseException e) {
+ fail("Failure in mapping vertex to AtlasEntityHeader");
+ }
+ return "";
+ }).collect(Collectors.toList());
+ Assert.assertTrue(guids.contains(CJKGUID2));
+ }
+
+ //Description contains japanese
+ @Test
+ public void searchJapaneseDescription() throws AtlasBaseException {
+ SearchParameters params = new SearchParameters();
+ params.setTypeName(HDFS_PATH);
+ SearchParameters.FilterCriteria filterCriteria = getSingleFilterCondition("path", SearchParameters.Operator.EQ, "私は日本語を話します");
+ filterCriteria.getCriterion();
+ params.setEntityFilters(filterCriteria);
+ params.setLimit(20);
+
+ SearchContext context = new SearchContext(params, typeRegistry, graph, indexer.getVertexIndexKeys());
+
+ EntitySearchProcessor processor = new EntitySearchProcessor(context);//
+ List<AtlasVertex> vertices = processor.execute();
+
+ assertEquals(vertices.size(), 1);
+ List<String> guids = vertices.stream().map(g -> {
+ try {
+ return entityRetriever.toAtlasEntityHeader(g).getGuid();
+ } catch (AtlasBaseException e) {
+ fail("Failure in mapping vertex to AtlasEntityHeader");
+ }
+ return "";
+ }).collect(Collectors.toList());
+ Assert.assertTrue(guids.contains(CJKGUID1));
+ }
+
+ @Test
+ public void searchWithQualifiedNameEQ() throws AtlasBaseException {
+ SearchParameters params = new SearchParameters();
+ params.setTypeName(HDFS_PATH);
+ SearchParameters.FilterCriteria filterCriteria = getSingleFilterCondition("qualifiedName", SearchParameters.Operator.EQ, "h3qualified");
+ filterCriteria.getCriterion();
+ params.setEntityFilters(filterCriteria);
+ params.setLimit(20);
+
+ SearchContext context = new SearchContext(params, typeRegistry, graph, indexer.getVertexIndexKeys());
+
+ EntitySearchProcessor processor = new EntitySearchProcessor(context);//
+ List<AtlasVertex> vertices = processor.execute();
+
+ assertEquals(vertices.size(), 1);
+ List<String> guids = vertices.stream().map(g -> {
+ try {
+ return entityRetriever.toAtlasEntityHeader(g).getGuid();
+ } catch (AtlasBaseException e) {
+ fail("Failure in mapping vertex to AtlasEntityHeader");
+ }
+ return "";
+ }).collect(Collectors.toList());
+ Assert.assertTrue(guids.contains(CJKGUID1));
+ }
+
+ @Test
+ public void searchWithNameBeginswith() throws AtlasBaseException {
+ SearchParameters params = new SearchParameters();
+ params.setTypeName(HDFS_PATH);
+ SearchParameters.FilterCriteria filterCriteria = getSingleFilterCondition("name", SearchParameters.Operator.STARTS_WITH, "hdfs");
+ filterCriteria.getCriterion();
+ params.setEntityFilters(filterCriteria);
+ params.setLimit(20);
+
+ SearchContext context = new SearchContext(params, typeRegistry, graph, indexer.getVertexIndexKeys());
+
+ EntitySearchProcessor processor = new EntitySearchProcessor(context);//
+ List<AtlasVertex> vertices = processor.execute();
+
+ assertEquals(vertices.size(), 1);
+ List<String> guids = vertices.stream().map(g -> {
+ try {
+ return entityRetriever.toAtlasEntityHeader(g).getGuid();
+ } catch (AtlasBaseException e) {
+ fail("Failure in mapping vertex to AtlasEntityHeader");
+ }
+ return "";
+ }).collect(Collectors.toList());
+
+ Assert.assertTrue(guids.contains(CJKGUID2));
+
+ }
+
+ private void createJapaneseEntityWithDescription() throws AtlasBaseException {
+ AtlasEntity entity = new AtlasEntity(HDFS_PATH);
+ entity.setAttribute("name", "h3");
+ entity.setAttribute(AtlasClient.REFERENCEABLE_ATTRIBUTE_NAME, "h3qualified");
+ entity.setAttribute("path", "私は日本語を話します");
+
+ List<AtlasClassification> cls = new ArrayList<>();
+ cls.add(new AtlasClassification(JDBC_CLASSIFICATION, new HashMap<String, Object>() {{
+ put("attr1", "attr1");
+ }}));
+ entity.setClassifications(cls);
+
+ //create entity
+ final EntityMutationResponse response = entityStore.createOrUpdate(new AtlasEntityStream(new AtlasEntity.AtlasEntitiesWithExtInfo(entity)), false);
+ AtlasEntityHeader entityHeader = response.getCreatedEntities().get(0);
+ CJKGUID1 = entityHeader.getGuid();
+
+ }
+
+ private void createChineseEntityWithDescription() throws AtlasBaseException {
+ AtlasEntity entity = new AtlasEntity(HDFS_PATH);
+ entity.setAttribute("name", "hdfs_chinese_test");
+ entity.setAttribute(AtlasClient.REFERENCEABLE_ATTRIBUTE_NAME, "hdfs_chinese_test_qualified");
+ entity.setAttribute("path", "我说中文");
+
+ //create entity
+ final EntityMutationResponse response = entityStore.createOrUpdate(new AtlasEntityStream(new AtlasEntity.AtlasEntitiesWithExtInfo(entity)), false);
+ AtlasEntityHeader entityHeader = response.getCreatedEntities().get(0);
+ CJKGUID2 = entityHeader.getGuid();
}
}
diff --git a/repository/src/test/java/org/apache/atlas/discovery/FreeTextSearchProcessorTest.java b/repository/src/test/java/org/apache/atlas/discovery/FreeTextSearchProcessorTest.java
index d7825a0..567b1f7 100644
--- a/repository/src/test/java/org/apache/atlas/discovery/FreeTextSearchProcessorTest.java
+++ b/repository/src/test/java/org/apache/atlas/discovery/FreeTextSearchProcessorTest.java
@@ -18,31 +18,43 @@
package org.apache.atlas.discovery;
import com.google.common.collect.Sets;
+import org.apache.atlas.AtlasClient;
import org.apache.atlas.BasicTestSetup;
import org.apache.atlas.SortOrder;
import org.apache.atlas.TestModules;
import org.apache.atlas.exception.AtlasBaseException;
import org.apache.atlas.model.discovery.SearchParameters;
+import org.apache.atlas.model.instance.AtlasClassification;
+import org.apache.atlas.model.instance.AtlasEntity;
+import org.apache.atlas.model.instance.AtlasEntityHeader;
+import org.apache.atlas.model.instance.EntityMutationResponse;
import org.apache.atlas.repository.graph.AtlasGraphProvider;
import org.apache.atlas.repository.graphdb.AtlasGraph;
import org.apache.atlas.repository.graphdb.AtlasVertex;
+import org.apache.atlas.repository.store.graph.v2.AtlasEntityStream;
import org.apache.atlas.repository.store.graph.v2.AtlasGraphUtilsV2;
import org.apache.atlas.repository.store.graph.v2.EntityGraphRetriever;
import org.apache.atlas.type.AtlasEntityType;
import org.apache.atlas.type.AtlasTypeRegistry;
+import org.apache.commons.collections.CollectionUtils;
+import org.testng.Assert;
import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Guice;
import org.testng.annotations.Test;
import javax.inject.Inject;
+import java.util.ArrayList;
import java.util.Collections;
+import java.util.HashMap;
import java.util.List;
+import java.util.stream.Collectors;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertNotEquals;
import static org.testng.Assert.assertFalse;
import static org.testng.Assert.assertNotNull;
+import static org.testng.Assert.fail;
@Guice(modules = TestModules.TestOnlyModule.class)
public class FreeTextSearchProcessorTest extends BasicTestSetup {
@@ -56,11 +68,14 @@
@Inject
private EntityGraphRetriever entityRetriever;
+ private String entityGUID;
+
@BeforeClass
public void setup() throws Exception {
super.initialize();
setupTestData();
+ createEntityWithQualifiedName();
}
@Test
@@ -162,6 +177,103 @@
}
}
+ @Test
+ public void searchQualifiedName() throws AtlasBaseException {
+ SearchParameters params = new SearchParameters();
+ params.setQuery("h1qualified*");
+ params.setExcludeDeletedEntities(true);
+ params.setLimit(500);
+ params.setOffset(0);
+
+ SearchContext context = new SearchContext(params, typeRegistry, graph, Collections.<String>emptySet());
+ FreeTextSearchProcessor processor = new FreeTextSearchProcessor(context);
+ List<AtlasVertex> vertices = processor.execute();
+
+ Assert.assertTrue(CollectionUtils.isNotEmpty(vertices));
+ assertEquals(vertices.size(), 1);
+
+ List<String> guids = vertices.stream().map(g -> {
+ try {
+ return entityRetriever.toAtlasEntityHeader(g).getGuid();
+ } catch (AtlasBaseException e) {
+ fail("Failure in mapping vertex to AtlasEntityHeader");
+ }
+ return "";
+ }).collect(Collectors.toList());
+
+ Assert.assertTrue(guids.contains(entityGUID));
+
+ }
+
+ @Test
+ public void searchName() throws AtlasBaseException {
+ SearchParameters params = new SearchParameters();
+ params.setQuery("h1Name*");
+ params.setExcludeDeletedEntities(true);
+ params.setLimit(500);
+ params.setOffset(0);
+
+ SearchContext context = new SearchContext(params, typeRegistry, graph, Collections.<String>emptySet());
+ FreeTextSearchProcessor processor = new FreeTextSearchProcessor(context);
+ List<AtlasVertex> vertices = processor.execute();
+
+ Assert.assertTrue(CollectionUtils.isNotEmpty(vertices));
+ assertEquals(vertices.size(), 1);
+
+ List<String> guids = vertices.stream().map(g -> {
+ try {
+ return entityRetriever.toAtlasEntityHeader(g).getGuid();
+ } catch (AtlasBaseException e) {
+ fail("Failure in mapping vertex to AtlasEntityHeader");
+ }
+ return "";
+ }).collect(Collectors.toList());
+
+ Assert.assertTrue(guids.contains(entityGUID));
+
+ }
+
+ @Test
+ public void searchNameWithStar() throws AtlasBaseException {
+ SearchParameters params = new SearchParameters();
+ params.setQuery("*h1*");
+ params.setExcludeDeletedEntities(true);
+ params.setLimit(500);
+ params.setOffset(0);
+
+ SearchContext context = new SearchContext(params, typeRegistry, graph, Collections.<String>emptySet());
+ FreeTextSearchProcessor processor = new FreeTextSearchProcessor(context);
+ List<AtlasVertex> vertices = processor.execute();
+
+ Assert.assertTrue(CollectionUtils.isNotEmpty(vertices));
+ assertEquals(vertices.size(), 1);
+
+ List<String> guids = vertices.stream().map(g -> {
+ try {
+ return entityRetriever.toAtlasEntityHeader(g).getGuid();
+ } catch (AtlasBaseException e) {
+ fail("Failure in mapping vertex to AtlasEntityHeader");
+ }
+ return "";
+ }).collect(Collectors.toList());
+
+ Assert.assertTrue(guids.contains(entityGUID));
+
+ }
+
+ private void createEntityWithQualifiedName() throws AtlasBaseException {
+ AtlasEntity entityToDelete = new AtlasEntity(HDFS_PATH);
+ entityToDelete.setAttribute("name", "h1NameHDFS");
+ entityToDelete.setAttribute(AtlasClient.REFERENCEABLE_ATTRIBUTE_NAME, "h1qualifiedNameHDFS");
+ entityToDelete.setAttribute("path", "h1PathHDFS");
+
+ //create entity
+ final EntityMutationResponse response = entityStore.createOrUpdate(new AtlasEntityStream(new AtlasEntity.AtlasEntitiesWithExtInfo(entityToDelete)), false);
+ AtlasEntityHeader entityHeader = response.getCreatedEntities().get(0);
+ entityGUID = entityHeader.getGuid();
+
+ }
+
@AfterClass
public void teardown() throws Exception {
AtlasGraphProvider.cleanup();
diff --git a/repository/src/test/java/org/apache/atlas/repository/store/graph/v2/AtlasEntityStoreV2Test.java b/repository/src/test/java/org/apache/atlas/repository/store/graph/v2/AtlasEntityStoreV2Test.java
index 1489b27..7b5cba5 100644
--- a/repository/src/test/java/org/apache/atlas/repository/store/graph/v2/AtlasEntityStoreV2Test.java
+++ b/repository/src/test/java/org/apache/atlas/repository/store/graph/v2/AtlasEntityStoreV2Test.java
@@ -1434,4 +1434,33 @@
fail("The BusinessMetadata Attribute should have been assigned " +e);
}
}
+
+
+ @Test(dependsOnMethods = "deleteLabelsToEntity")
+ public void testCJKaddLabel() {
+
+ Set<String> labels = new HashSet();
+ labels.add("国家");
+ try {
+ AtlasEntity tblEntity = getEntityFromStore(tblEntityGuid);
+ int count = tblEntity.getLabels().size();
+ entityStore.setLabels(tblEntityGuid, labels);
+ tblEntity = getEntityFromStore(tblEntityGuid);
+ assertEquals(tblEntity.getLabels().size(), count + 1);
+ } catch (Exception e) {
+ LOG.error("An error occurred : " + e);
+ }
+ }
+
+ @Test()
+ public void addCJKCustomAttributes() throws Exception {
+
+ AtlasEntity tblEntity = getEntityFromStore(tblEntityGuid);
+ Map<String, String> customAttributes = new HashMap<>();
+ customAttributes.put("国家", "国家");
+ tblEntity.setCustomAttributes(customAttributes);
+ entityStore.createOrUpdate(new AtlasEntityStream(tblEntity), false);
+ tblEntity = getEntityFromStore(tblEntityGuid);
+ assertEquals(customAttributes, tblEntity.getCustomAttributes());
+ }
}
\ No newline at end of file