Work around potential NullPointerExceptions in ToscaElementLifecycleOperation

- Rewrite of `checkinToscaELement`
- Extracted methods from `checkinToscaELement`

Issue-ID: SDC-2964
Signed-off-by: Chris Andre <chris.andre@yoppworks.com>
Change-Id: I99d2c5aaa73b955ef5aa60eeb7644bb47ac12bd6
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsonjanusgraph/operations/ToscaElementLifecycleOperation.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsonjanusgraph/operations/ToscaElementLifecycleOperation.java
index 6ae99ae..273d500 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsonjanusgraph/operations/ToscaElementLifecycleOperation.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsonjanusgraph/operations/ToscaElementLifecycleOperation.java
@@ -38,7 +38,6 @@
 import org.openecomp.sdc.be.dao.jsongraph.types.VertexTypeEnum;
 import org.openecomp.sdc.be.dao.jsongraph.utils.IdBuilderUtils;
 import org.openecomp.sdc.be.dao.jsongraph.utils.JsonParserUtils;
-import org.openecomp.sdc.be.dao.neo4j.GraphEdgeLabels;
 import org.openecomp.sdc.be.datatypes.elements.*;
 import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum;
 import org.openecomp.sdc.be.datatypes.enums.GraphPropertyEnum;
@@ -85,34 +84,53 @@
      * @param ownerId
      * @return
      */
-    public Either<ToscaElement, StorageOperationStatus> checkinToscaELement(LifecycleStateEnum currState, String toscaElementId, String modifierId, String ownerId) {
-        Either<GraphVertex, StorageOperationStatus> updateResult = null;
-        Either<ToscaElement, StorageOperationStatus> result = null;
-        Map<String, GraphVertex> vertices = null;
-        ToscaElementOperation operation;
+    public Either<ToscaElement, StorageOperationStatus> checkinToscaELement(LifecycleStateEnum currState,
+        String toscaElementId, String modifierId, String ownerId) {
         try {
-            Either<Map<String, GraphVertex>, JanusGraphOperationStatus> getVerticesRes = janusGraphDao
-                .getVerticesByUniqueIdAndParseFlag(prepareParametersToGetVerticesForCheckin(toscaElementId, modifierId, ownerId));
-            if (getVerticesRes.isRight()) {
-                CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, FAILED_TO_GET_VERTICES, toscaElementId);
-                updateResult = Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(getVerticesRes.right().value()));
-            } else {
-                vertices = getVerticesRes.left().value();
-                updateResult = checkinToscaELement(currState, vertices.get(toscaElementId), vertices.get(ownerId), vertices.get(modifierId), LifecycleStateEnum.NOT_CERTIFIED_CHECKIN);
-            }
-            if (updateResult.isLeft()) {
-                operation = getToscaElementOperation(vertices.get(toscaElementId).getLabel());
-                result = operation.getToscaElement(updateResult.left().value().getUniqueId());
-                if (result.isRight()) {
-                    CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to get updated tosca element {}. Status is {}", toscaElementId, result.right().value());
-                }
-            } else {
-                result = Either.right(updateResult.right().value());
-            }
+            return janusGraphDao
+                .getVerticesByUniqueIdAndParseFlag(
+                    prepareParametersToGetVerticesForCheckin(toscaElementId, modifierId, ownerId))
+                .right().map(status -> handleFailureToPrepareParameters(status, toscaElementId))
+                .left().bind(
+                    verticesMap ->
+                        checkinToscaELement(
+                            currState,
+                            verticesMap.get(toscaElementId),
+                            verticesMap.get(ownerId),
+                            verticesMap.get(modifierId),
+                            LifecycleStateEnum.NOT_CERTIFIED_CHECKIN
+                        ).left().bind(checkinResult -> {
+                            //We retrieve the operation
+                            ToscaElementOperation operation =
+                                getToscaElementOperation(verticesMap.get(toscaElementId).getLabel());
+
+                            //We retrieve the ToscaElement from the operation
+                            return getToscaElementFromOperation(operation, checkinResult.getUniqueId(), toscaElementId);
+                        })
+                );
         } catch (Exception e) {
-            CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Exception occured during checkin of tosca element {}. {} ", toscaElementId, e.getMessage());
+            CommonUtility.addRecordToLog(
+                log, LogLevelEnum.DEBUG, "Exception occurred during checkin of tosca element {}. {} ", toscaElementId,
+                e.getMessage());
+            return Either.right(StorageOperationStatus.GENERAL_ERROR);
         }
-        return result;
+    }
+
+    static StorageOperationStatus handleFailureToPrepareParameters(final JanusGraphOperationStatus status, final String toscaElementId) {
+        CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, FAILED_TO_GET_VERTICES, toscaElementId);
+        return DaoStatusConverter.convertJanusGraphStatusToStorageStatus(status);
+    }
+
+    static Either<ToscaElement, StorageOperationStatus> getToscaElementFromOperation(final ToscaElementOperation operation,
+        final String uniqueId, final String toscaElementId) {
+        return operation.getToscaElement(uniqueId)
+            .right().map(status -> {
+                //We log a potential error we got while retrieving the ToscaElement
+                CommonUtility
+                    .addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to get updated tosca element {}. Status is {}",
+                        toscaElementId, status);
+                return status;
+            });
     }
 
     /**
diff --git a/catalog-model/src/test/java/org/openecomp/sdc/be/model/jsonjanusgraph/operations/ToscaElementLifecycleOperationTest.java b/catalog-model/src/test/java/org/openecomp/sdc/be/model/jsonjanusgraph/operations/ToscaElementLifecycleOperationTest.java
new file mode 100644
index 0000000..a459166
--- /dev/null
+++ b/catalog-model/src/test/java/org/openecomp/sdc/be/model/jsonjanusgraph/operations/ToscaElementLifecycleOperationTest.java
@@ -0,0 +1,208 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * SDC
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * 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.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.sdc.be.model.jsonjanusgraph.operations;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import fj.data.Either;
+import java.util.HashMap;
+import java.util.Map;
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.Test;
+import org.openecomp.sdc.be.dao.janusgraph.JanusGraphOperationStatus;
+import org.openecomp.sdc.be.dao.jsongraph.GraphVertex;
+import org.openecomp.sdc.be.dao.jsongraph.types.JsonParseFlagEnum;
+import org.openecomp.sdc.be.model.ComponentParametersView;
+import org.openecomp.sdc.be.model.jsonjanusgraph.datamodel.ToscaElement;
+import org.openecomp.sdc.be.model.jsonjanusgraph.datamodel.ToscaElementTypeEnum;
+import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
+
+public class ToscaElementLifecycleOperationTest {
+
+    @Test
+    @DisplayName("handleFailureToGetVertices - Golden Path")
+    public void handleFailureToGetVertices_GoldenPath() {
+        //Given
+        Map<JanusGraphOperationStatus, StorageOperationStatus> map = getStatusMap();
+
+        for (JanusGraphOperationStatus janusStatus : map.keySet()) {
+            //When
+            StorageOperationStatus result = ToscaElementLifecycleOperation
+                .handleFailureToPrepareParameters(janusStatus, "testToscaElementId");
+
+            //Then
+            assertEquals(map.get(janusStatus), result);
+        }
+    }
+
+    @Test
+    @DisplayName("handleFailureToGetVertices - Null `toscaElementId`")
+    public void handleFailureToGetVertices_NullToscaElementId() {
+        //Given
+        Map<JanusGraphOperationStatus, StorageOperationStatus> map = getStatusMap();
+
+        for (JanusGraphOperationStatus janusStatus : map.keySet()) {
+            //When
+            StorageOperationStatus result = ToscaElementLifecycleOperation
+                .handleFailureToPrepareParameters(janusStatus, "testToscaElementId");
+
+            //Then
+            assertEquals(map.get(janusStatus), result);
+        }
+    }
+
+    @Test
+    @DisplayName("handleFailureToGetVertices - Null `janusGraphOperationStatus`")
+    public void handleFailureToGetVertices_NullJanusGraphOperationStatus() {
+        //Given
+        JanusGraphOperationStatus status = null;
+
+        //When
+        StorageOperationStatus result = ToscaElementLifecycleOperation
+            .handleFailureToPrepareParameters(status, "testToscaElementId");
+
+        //Then
+        assertEquals(StorageOperationStatus.GENERAL_ERROR, result);
+    }
+
+    @Test
+    @DisplayName("getToscaElementFromOperation - should call `operation.getToscaElement`")
+    public void getToscaElementFromOperation_GoldenPath() {
+        //Given
+        String uniqueId = "uniqueId";
+        String toscaElementId = "toscaElementId";
+
+        Either<ToscaElement, StorageOperationStatus> expectedLeftResult = Either.left(
+            new ToscaElement(ToscaElementTypeEnum.NODE_TYPE) {
+            }
+        );
+        ToscaElementOperation leftResultOperation = getPseudoToscaOperation(expectedLeftResult);
+
+        //When
+        Either<ToscaElement, StorageOperationStatus> leftResult = ToscaElementLifecycleOperation
+            .getToscaElementFromOperation(leftResultOperation, uniqueId, toscaElementId);
+
+        //Then
+        assertTrue(leftResult.isLeft());
+        assertEquals(expectedLeftResult, leftResult);
+
+        //Given
+        Either<ToscaElement, StorageOperationStatus> expectedRightResult = Either
+            .right(StorageOperationStatus.GENERAL_ERROR);
+        ToscaElementOperation rightResultOperation = getPseudoToscaOperation(expectedRightResult);
+
+        //When
+        Either<ToscaElement, StorageOperationStatus> rightResult = ToscaElementLifecycleOperation
+            .getToscaElementFromOperation(rightResultOperation, uniqueId, toscaElementId);
+
+        //Then
+        assertTrue(rightResult.isRight());
+        assertEquals(expectedRightResult, rightResult);
+    }
+
+    ToscaElementOperation getPseudoToscaOperation(
+        Either<ToscaElement, StorageOperationStatus> expectedResult) {
+        return new ToscaElementOperation() {
+            @Override
+            public Either<ToscaElement, StorageOperationStatus> getToscaElement(String uniqueId,
+                ComponentParametersView componentParametersView) {
+                return expectedResult;
+            }
+
+            @Override
+            public <T extends ToscaElement> Either<T, StorageOperationStatus> getToscaElement(
+                GraphVertex toscaElementVertex, ComponentParametersView componentParametersView) {
+                return null;
+            }
+
+            @Override
+            public <T extends ToscaElement> Either<T, StorageOperationStatus> deleteToscaElement(
+                GraphVertex toscaElementVertex) {
+                return null;
+            }
+
+            @Override
+            public <T extends ToscaElement> Either<T, StorageOperationStatus> createToscaElement(
+                ToscaElement toscaElement) {
+                return null;
+            }
+
+            @Override
+            protected <T extends ToscaElement> JanusGraphOperationStatus setCategoriesFromGraph(
+                GraphVertex vertexComponent, T toscaElement) {
+                return null;
+            }
+
+            @Override
+            protected <T extends ToscaElement> JanusGraphOperationStatus setCapabilitiesFromGraph(
+                GraphVertex componentV, T toscaElement) {
+                return null;
+            }
+
+            @Override
+            protected <T extends ToscaElement> JanusGraphOperationStatus setRequirementsFromGraph(
+                GraphVertex componentV, T toscaElement) {
+                return null;
+            }
+
+            @Override
+            protected <T extends ToscaElement> StorageOperationStatus validateCategories(T toscaElementToUpdate,
+                GraphVertex elementV) {
+                return null;
+            }
+
+            @Override
+            protected <T extends ToscaElement> StorageOperationStatus updateDerived(T toscaElementToUpdate,
+                GraphVertex updateElementV) {
+                return null;
+            }
+
+            @Override
+            public <T extends ToscaElement> void fillToscaElementVertexData(GraphVertex elementV,
+                T toscaElementToUpdate, JsonParseFlagEnum flag) {
+
+            }
+        };
+    }
+
+    Map<JanusGraphOperationStatus, StorageOperationStatus> getStatusMap() {
+        Map<JanusGraphOperationStatus, StorageOperationStatus> map = new HashMap<>();
+        map.put(JanusGraphOperationStatus.OK, StorageOperationStatus.OK);
+        map.put(JanusGraphOperationStatus.NOT_CONNECTED, StorageOperationStatus.CONNECTION_FAILURE);
+        map.put(JanusGraphOperationStatus.NOT_FOUND, StorageOperationStatus.NOT_FOUND);
+        map.put(JanusGraphOperationStatus.NOT_CREATED, StorageOperationStatus.SCHEMA_ERROR);
+        map.put(JanusGraphOperationStatus.INDEX_CANNOT_BE_CHANGED, StorageOperationStatus.SCHEMA_ERROR);
+        map.put(JanusGraphOperationStatus.MISSING_UNIQUE_ID, StorageOperationStatus.BAD_REQUEST);
+        map.put(JanusGraphOperationStatus.ALREADY_LOCKED, StorageOperationStatus.FAILED_TO_LOCK_ELEMENT);
+        map.put(JanusGraphOperationStatus.JANUSGRAPH_SCHEMA_VIOLATION, StorageOperationStatus.SCHEMA_VIOLATION);
+        map.put(JanusGraphOperationStatus.INVALID_ID, StorageOperationStatus.INVALID_ID);
+        map.put(JanusGraphOperationStatus.MATCH_NOT_FOUND, StorageOperationStatus.MATCH_NOT_FOUND);
+        map.put(JanusGraphOperationStatus.ILLEGAL_ARGUMENT, StorageOperationStatus.BAD_REQUEST);
+        map.put(JanusGraphOperationStatus.ALREADY_EXIST, StorageOperationStatus.ENTITY_ALREADY_EXISTS);
+        map.put(JanusGraphOperationStatus.PROPERTY_NAME_ALREADY_EXISTS,
+            StorageOperationStatus.PROPERTY_NAME_ALREADY_EXISTS);
+        map.put(JanusGraphOperationStatus.INVALID_PROPERTY, StorageOperationStatus.INVALID_PROPERTY);
+        map.put(JanusGraphOperationStatus.INVALID_QUERY, StorageOperationStatus.GENERAL_ERROR);
+
+        return map;
+    }
+}