ATLAS-4652: fix to address potential NPE in AtlasAttributeDef.isSoftReferenced()
diff --git a/intg/src/main/java/org/apache/atlas/model/typedef/AtlasStructDef.java b/intg/src/main/java/org/apache/atlas/model/typedef/AtlasStructDef.java
index a621fb0..bef850c 100644
--- a/intg/src/main/java/org/apache/atlas/model/typedef/AtlasStructDef.java
+++ b/intg/src/main/java/org/apache/atlas/model/typedef/AtlasStructDef.java
@@ -515,9 +515,9 @@
@JsonIgnore
public boolean isSoftReferenced() {
- return this.options != null &&
- getOptions().containsKey(AtlasAttributeDef.ATTRDEF_OPTION_SOFT_REFERENCE) &&
- getOptions().get(AtlasAttributeDef.ATTRDEF_OPTION_SOFT_REFERENCE).equals(STRING_TRUE);
+ String val = getOption(AtlasAttributeDef.ATTRDEF_OPTION_SOFT_REFERENCE);
+
+ return val != null && Boolean.valueOf(val);
}
@JsonIgnore
diff --git a/intg/src/main/java/org/apache/atlas/utils/AtlasStringUtil.java b/intg/src/main/java/org/apache/atlas/utils/AtlasStringUtil.java
new file mode 100644
index 0000000..11a4399
--- /dev/null
+++ b/intg/src/main/java/org/apache/atlas/utils/AtlasStringUtil.java
@@ -0,0 +1,43 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.apache.atlas.utils;
+
+import java.util.Map;
+import java.util.Objects;
+
+public class AtlasStringUtil {
+ public static boolean hasOption(Map<String, String> options, String optionName) {
+ return options != null && options.containsKey(optionName);
+ }
+
+ public static String getOption(Map<String, String> options, String optionName) {
+ return options != null ? options.get(optionName) : null;
+ }
+
+ public static boolean getBooleanOption(Map<String, String> options, String optionName) {
+ return options != null && Boolean.parseBoolean(options.get(optionName));
+ }
+
+ public static boolean getBooleanOption(Map<String, String> options, String optionName, boolean defaultValue) {
+ return (options != null && options.containsKey(optionName)) ? Boolean.parseBoolean(options.get(optionName)) : defaultValue;
+ }
+
+ public static boolean optionEquals(Map<String, String> options, String optionName, String value) {
+ return Objects.equals(options != null ? options.get(optionName) : null, value);
+ }
+}
diff --git a/intg/src/test/java/org/apache/atlas/utils/AtlasStringUtilTest.java b/intg/src/test/java/org/apache/atlas/utils/AtlasStringUtilTest.java
new file mode 100644
index 0000000..da77645
--- /dev/null
+++ b/intg/src/test/java/org/apache/atlas/utils/AtlasStringUtilTest.java
@@ -0,0 +1,127 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * 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.apache.atlas.utils;
+
+import org.testng.annotations.Test;
+
+import java.util.Collections;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertFalse;
+import static org.testng.Assert.assertNotEquals;
+import static org.testng.Assert.assertNull;
+import static org.testng.Assert.assertTrue;
+
+public class AtlasStringUtilTest {
+ @Test
+ public void testGetOption() {
+ // null options
+ assertNull(AtlasStringUtil.getOption(null, "opt"));
+
+ // null optionName
+ assertNull(AtlasStringUtil.getOption(Collections.emptyMap(), null));
+
+ // explicit null value for the option
+ assertNull(AtlasStringUtil.getOption(Collections.singletonMap("opt", null), null));
+
+ // option not present
+ assertNull(AtlasStringUtil.getOption(Collections.emptyMap(), "opt"));
+ assertNull(AtlasStringUtil.getOption(Collections.singletonMap("opt", "val"), "opt1"));
+
+ // option present
+ assertEquals(AtlasStringUtil.getOption(Collections.singletonMap("opt", "val"), "opt"), "val");
+ assertNotEquals(AtlasStringUtil.getOption(Collections.singletonMap("opt", "val"), "opt"), "val1");
+ }
+
+ @Test
+ public void testGetBooleanOption() {
+ // null options
+ assertFalse(AtlasStringUtil.getBooleanOption(null, "opt"));
+
+ // null optionName
+ assertFalse(AtlasStringUtil.getBooleanOption(Collections.emptyMap(), null));
+
+ // explicit null value for the option
+ assertFalse(AtlasStringUtil.getBooleanOption(Collections.singletonMap("opt", null), "opt"));
+
+ // option not present
+ assertFalse(AtlasStringUtil.getBooleanOption(Collections.emptyMap(), "opt"));
+ assertFalse(AtlasStringUtil.getBooleanOption(Collections.singletonMap("opt", "val"), "opt1"));
+
+ // invalid value for the option
+ assertFalse(AtlasStringUtil.getBooleanOption(Collections.singletonMap("opt", "val"), "opt"));
+
+ // option present
+ assertFalse(AtlasStringUtil.getBooleanOption(Collections.singletonMap("opt", "false"), "opt"));
+ assertTrue(AtlasStringUtil.getBooleanOption(Collections.singletonMap("opt", "true"), "opt"));
+ assertTrue(AtlasStringUtil.getBooleanOption(Collections.singletonMap("opt", "TRUE"), "opt"));
+ }
+
+ @Test
+ public void testGetBooleanOptionWithDefault() {
+ // null options
+ assertTrue(AtlasStringUtil.getBooleanOption(null, "opt", true));
+ assertFalse(AtlasStringUtil.getBooleanOption(null, "opt", false));
+
+ // null optionName
+ assertTrue(AtlasStringUtil.getBooleanOption(Collections.emptyMap(), null, true));
+ assertFalse(AtlasStringUtil.getBooleanOption(Collections.emptyMap(), null, false));
+
+ // explicit null value for the option
+ assertFalse(AtlasStringUtil.getBooleanOption(Collections.singletonMap("opt", null), "opt", false));
+ assertFalse(AtlasStringUtil.getBooleanOption(Collections.singletonMap("opt", null), "opt", true));
+
+ // option not present
+ assertTrue(AtlasStringUtil.getBooleanOption(Collections.emptyMap(), "opt", true));
+ assertFalse(AtlasStringUtil.getBooleanOption(Collections.emptyMap(), "opt", false));
+ assertTrue(AtlasStringUtil.getBooleanOption(Collections.singletonMap("opt", "val"), "opt1", true));
+ assertFalse(AtlasStringUtil.getBooleanOption(Collections.singletonMap("opt", "val"), "opt1", false));
+
+ // invalid value for the option
+ assertFalse(AtlasStringUtil.getBooleanOption(Collections.singletonMap("opt", "val"), "opt", true));
+ assertFalse(AtlasStringUtil.getBooleanOption(Collections.singletonMap("opt", "val"), "opt", false));
+
+ // valid value for the option
+ assertFalse(AtlasStringUtil.getBooleanOption(Collections.singletonMap("opt", "false"), "opt", true));
+ assertTrue(AtlasStringUtil.getBooleanOption(Collections.singletonMap("opt", "true"), "opt", true));
+ assertTrue(AtlasStringUtil.getBooleanOption(Collections.singletonMap("opt", "TRUE"), "opt", true));
+ assertTrue(AtlasStringUtil.getBooleanOption(Collections.singletonMap("opt", "true"), "opt", false));
+ assertTrue(AtlasStringUtil.getBooleanOption(Collections.singletonMap("opt", "TRUE"), "opt", false));
+ }
+
+ @Test
+ public void testOptionEquals() {
+ // null options
+ assertTrue(AtlasStringUtil.optionEquals(null, "opt", null));
+ assertFalse(AtlasStringUtil.optionEquals(null, "opt", "val"));
+
+ // null optionName
+ assertTrue(AtlasStringUtil.optionEquals(Collections.emptyMap(), null, null));
+
+ // explicit null value for the option
+ assertTrue(AtlasStringUtil.optionEquals(Collections.singletonMap("opt", null), "opt", null));
+
+ // option not present
+ assertTrue(AtlasStringUtil.optionEquals(Collections.emptyMap(), "opt", null));
+ assertTrue(AtlasStringUtil.optionEquals(Collections.singletonMap("opt", "val"), "opt1", null));
+
+ // option present
+ assertTrue(AtlasStringUtil.optionEquals(Collections.singletonMap("opt", "val"), "opt", "val"));
+ assertFalse(AtlasStringUtil.optionEquals(Collections.singletonMap("opt", "val"), "opt", "val1"));
+ }
+}
diff --git a/repository/src/main/java/org/apache/atlas/repository/impexp/ImportService.java b/repository/src/main/java/org/apache/atlas/repository/impexp/ImportService.java
index 1d29bf8..ad4672d 100644
--- a/repository/src/main/java/org/apache/atlas/repository/impexp/ImportService.java
+++ b/repository/src/main/java/org/apache/atlas/repository/impexp/ImportService.java
@@ -34,6 +34,7 @@
import org.apache.atlas.store.AtlasTypeDefStore;
import org.apache.atlas.type.AtlasType;
import org.apache.atlas.type.AtlasTypeRegistry;
+import org.apache.atlas.utils.AtlasStringUtil;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.MapUtils;
import org.apache.commons.lang3.StringUtils;
@@ -106,10 +107,10 @@
RequestContext.get().setImportInProgress(true);
- String transforms = MapUtils.isNotEmpty(request.getOptions()) ? request.getOptions().get(TRANSFORMS_KEY) : null;
+ String transforms = AtlasStringUtil.getOption(request.getOptions(), TRANSFORMS_KEY);
setImportTransform(source, transforms);
- String transformers = MapUtils.isNotEmpty(request.getOptions()) ? request.getOptions().get(TRANSFORMERS_KEY) : null;
+ String transformers = AtlasStringUtil.getOption(request.getOptions(), TRANSFORMERS_KEY);
setEntityTransformerHandlers(source, transformers);
startTimestamp = System.currentTimeMillis();
@@ -254,9 +255,8 @@
private EntityImportStream createZipSource(AtlasImportRequest request, InputStream inputStream, String configuredTemporaryDirectory) throws AtlasBaseException {
try {
- if (isMigrationMode(request) || (request.getOptions().containsKey(AtlasImportRequest.OPTION_KEY_FORMAT) &&
- request.getOptions().get(AtlasImportRequest.OPTION_KEY_FORMAT).equals(AtlasImportRequest.OPTION_KEY_FORMAT_ZIP_DIRECT))) {
- LOG.info("ZipSource Format: ZipDirect: Size: {}", request.getOptions().get("size"));
+ if (isMigrationMode(request) || AtlasStringUtil.optionEquals(request.getOptions(), AtlasImportRequest.OPTION_KEY_FORMAT, AtlasImportRequest.OPTION_KEY_FORMAT_ZIP_DIRECT)) {
+ LOG.info("ZipSource Format: ZipDirect: Size: {}", AtlasStringUtil.getOption(request.getOptions(), "size"));
return getZipDirectEntityImportStream(request, inputStream);
}
@@ -294,6 +294,6 @@
}
private boolean isMigrationMode(AtlasImportRequest request) {
- return request.getOptions().containsKey(AtlasImportRequest.OPTION_KEY_MIGRATION);
+ return AtlasStringUtil.hasOption(request.getOptions(), AtlasImportRequest.OPTION_KEY_MIGRATION);
}
}
diff --git a/repository/src/main/java/org/apache/atlas/repository/store/graph/v2/BulkImporterImpl.java b/repository/src/main/java/org/apache/atlas/repository/store/graph/v2/BulkImporterImpl.java
index 8e17fd4..0d3e911 100644
--- a/repository/src/main/java/org/apache/atlas/repository/store/graph/v2/BulkImporterImpl.java
+++ b/repository/src/main/java/org/apache/atlas/repository/store/graph/v2/BulkImporterImpl.java
@@ -36,6 +36,7 @@
import org.apache.atlas.type.AtlasEntityType;
import org.apache.atlas.type.AtlasTypeRegistry;
import org.apache.atlas.type.Constants;
+import org.apache.atlas.utils.AtlasStringUtil;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -66,8 +67,7 @@
public EntityMutationResponse bulkImport(EntityImportStream entityStream, AtlasImportResult importResult) throws AtlasBaseException {
ImportStrategy importStrategy = null;
- if (importResult.getRequest().getOptions() != null &&
- importResult.getRequest().getOptions().containsKey(AtlasImportRequest.OPTION_KEY_MIGRATION)) {
+ if (AtlasStringUtil.hasOption(importResult.getRequest().getOptions(), AtlasImportRequest.OPTION_KEY_MIGRATION)) {
importStrategy = new MigrationImport(this.atlasGraph, new AtlasGraphProvider(), this.typeRegistry);
} else {
importStrategy = new RegularImport(this.atlasGraph, this.entityStore, this.typeRegistry);
diff --git a/repository/src/main/java/org/apache/atlas/repository/store/graph/v2/bulkimport/MigrationImport.java b/repository/src/main/java/org/apache/atlas/repository/store/graph/v2/bulkimport/MigrationImport.java
index d6f23d6..f8c9218 100644
--- a/repository/src/main/java/org/apache/atlas/repository/store/graph/v2/bulkimport/MigrationImport.java
+++ b/repository/src/main/java/org/apache/atlas/repository/store/graph/v2/bulkimport/MigrationImport.java
@@ -39,6 +39,7 @@
import org.apache.atlas.repository.store.graph.v2.bulkimport.pc.EntityConsumerBuilder;
import org.apache.atlas.repository.store.graph.v2.bulkimport.pc.EntityCreationManager;
import org.apache.atlas.type.AtlasTypeRegistry;
+import org.apache.atlas.utils.AtlasStringUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -89,7 +90,7 @@
private DataMigrationStatusService createMigrationStatusService(AtlasImportResult importResult) {
DataMigrationStatusService dataMigrationStatusService = new DataMigrationStatusService();
- dataMigrationStatusService.init(importResult.getRequest().getOptions().get(AtlasImportRequest.OPTION_KEY_MIGRATION_FILE_NAME));
+ dataMigrationStatusService.init(AtlasStringUtil.getOption(importResult.getRequest().getOptions(), AtlasImportRequest.OPTION_KEY_MIGRATION_FILE_NAME));
return dataMigrationStatusService;
}