Disable locking during deployment 36/122736/6
authordavsad <david.sadlier@est.tech>
Fri, 16 Jul 2021 08:44:22 +0000 (09:44 +0100)
committerMichael Morris <michael.morris@est.tech>
Thu, 5 Aug 2021 07:35:41 +0000 (07:35 +0000)
Issue-ID: SDC-3643
Signed-off-by: davsad <david.sadlier@est.tech>
Change-Id: I1a04c253d70bf5aebf33bba7b2b9f83bd559ae64

catalog-be/src/main/java/org/openecomp/sdc/be/servlets/LockServlet.java [new file with mode: 0644]
catalog-be/src/main/resources/scripts/sdcBePy/common/sdcBeProxy.py
catalog-be/src/main/resources/scripts/sdcBePy/tosca/imports/run.py
catalog-be/src/test/java/org/openecomp/sdc/be/servlets/LockServletTest.java [new file with mode: 0644]
catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/IGraphLockOperation.java
catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/GraphLockOperation.java

diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/LockServlet.java b/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/LockServlet.java
new file mode 100644 (file)
index 0000000..7319f7c
--- /dev/null
@@ -0,0 +1,96 @@
+/*
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2021 Nordix Foundation
+ *  ================================================================================
+ *  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.
+ *
+ *  SPDX-License-Identifier: Apache-2.0
+ *  ============LICENSE_END=========================================================
+ */
+package org.openecomp.sdc.be.servlets;
+
+import java.util.Arrays;
+
+import javax.inject.Inject;
+import javax.servlet.http.HttpServletRequest;
+import javax.ws.rs.Consumes;
+import javax.ws.rs.HeaderParam;
+import javax.ws.rs.POST;
+import javax.ws.rs.Path;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+
+import org.openecomp.sdc.be.components.impl.aaf.AafPermission;
+import org.openecomp.sdc.be.components.impl.aaf.PermissionAllowed;
+import org.openecomp.sdc.be.components.validation.UserValidations;
+import org.openecomp.sdc.be.impl.ComponentsUtils;
+import org.openecomp.sdc.be.model.operations.api.IGraphLockOperation;
+import org.openecomp.sdc.be.user.Role;
+import org.openecomp.sdc.be.user.UserBusinessLogic;
+import org.openecomp.sdc.common.log.enums.EcompLoggerErrorCode;
+import org.openecomp.sdc.common.log.wrappers.Logger;
+import org.springframework.stereotype.Controller;
+
+import com.jcabi.aspects.Loggable;
+
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.Parameter;
+import io.swagger.v3.oas.annotations.media.Content;
+import io.swagger.v3.oas.annotations.media.Schema;
+import io.swagger.v3.oas.annotations.responses.ApiResponse;
+import io.swagger.v3.oas.annotations.servers.Server;
+import io.swagger.v3.oas.annotations.tags.Tag;
+
+
+@Loggable(prepend = true, value = Loggable.DEBUG, trim = false)
+@Path("/v1/catalog")
+@Tag(name = "SDCE-2 APIs")
+@Server(url = "/sdc2/rest")
+@Controller
+public class LockServlet extends BeGenericServlet {
+
+    private static final Logger log = Logger.getLogger(LockServlet.class);
+    private final UserValidations userValidations;
+    private final IGraphLockOperation graphLockOperation;
+
+    @Inject
+    public LockServlet(final UserBusinessLogic userBusinessLogic, final ComponentsUtils componentsUtils,
+            final UserValidations userValidations, IGraphLockOperation graphLockOperation) {
+        super(userBusinessLogic, componentsUtils);
+        this.userValidations = userValidations;
+        this.graphLockOperation = graphLockOperation;
+    }
+
+    @POST
+    @Path("/lock")
+    @Consumes(MediaType.APPLICATION_JSON)
+    @Produces(MediaType.APPLICATION_JSON)
+    @PermissionAllowed(AafPermission.PermNames.INTERNAL_ALL_VALUE)
+    @Operation(description = "Toggle disable locking", method = "POST", responses = {
+        @ApiResponse(content = @Content(schema = @Schema(implementation = Response.class))),
+        @ApiResponse(responseCode = "200", description = "Disable locking successfully updated"),
+        @ApiResponse(responseCode = "500", description = "Update disable locking failed")
+    })
+    public Response toggleDisableLocking(@Context final HttpServletRequest request, @HeaderParam("USER_ID") String userId,
+            @Parameter(description = "Disable Locking") boolean disable) {
+        log.info("User {} attempting to set disable locking with value {}", userId, disable);
+        userValidations.validateUserRole(userValidations.validateUserExists(userId), Arrays.asList(Role.DESIGNER, Role.ADMIN));
+        try {
+            return Response.ok().entity(graphLockOperation.disableLocking(disable)).build();
+        } catch (final Exception e) {
+            log.error(EcompLoggerErrorCode.BUSINESS_PROCESS_ERROR, LockServlet.class.getName(), "Failed to set disable locking", e);
+            return Response.serverError().build();
+        }
+    }
+}
\ No newline at end of file
index f2bef53..0c71a38 100755 (executable)
@@ -49,6 +49,9 @@ class SdcBeProxy:
             'consumerPassword': password
         }))
 
+    def disable_locking(self, disable):
+        return self.con.post("/sdc2/rest/v1/catalog/lock", disable)
+
     def get_normatives(self):
         return self.con.get("/sdc2/rest/v1/screen", with_buffer=True)
 
index 067f110..1df54ca 100644 (file)
@@ -17,22 +17,27 @@ def main(sdc_be_proxy, update_version):
     # base_file_location = os.getcwd() + "/../../../import/tosca/"
     base_file_location = os.getcwd() + os.path.sep
     logger.debug("working directory =" + base_file_location)
-
-    model_import_manager = ModelImportManager(Path(base_file_location) / 'models', ModelClient(sdc_be_proxy))
+    if sdc_be_proxy.disable_locking("true") != 200:
+        raise RuntimeError("Failed to disable locking")
     try:
-        model_import_manager.create_models()
+        model_import_manager = ModelImportManager(Path(base_file_location) / 'models', ModelClient(sdc_be_proxy))
+        try:
+            model_import_manager.create_models()
+        except Exception as ex:
+            logger.log("An error has occurred while uploading the models: ", str(ex))
+            raise ex
+        process_element_list(normativeElementsList.get_normative_element_candidate_list(base_file_location), sdc_be_proxy)
+        process_type_list(normativeTypesList.get_normative_type_candidate_list(base_file_location), sdc_be_proxy, update_version)
+        process_element_list(normativeElementsList.get_normative_element_with_metadata_list(base_file_location), sdc_be_proxy)
     except Exception as ex:
-        logger.log("An error has occurred while uploading the models: ", str(ex))
+        logger.log("An error has occurred while uploading elements and types: ", str(ex))
         raise ex
-
-    process_element_list(normativeElementsList.get_normative_element_candidate_list(base_file_location), sdc_be_proxy)
-    process_type_list(normativeTypesList.get_normative_type_candidate_list(base_file_location), sdc_be_proxy, update_version)
-    process_element_list(normativeElementsList.get_normative_element_with_metadata_list(base_file_location), sdc_be_proxy)
-
+    finally:
+        if sdc_be_proxy.disable_locking("false") != 200:
+            raise RuntimeError("Failed to enable locking")
     logger.log("Script end ->", "All normatives imported successfully!")
     logger.print_and_exit(0, None)
 
-
 def run():
     sdc_be_proxy, update_version = parse_and_create_proxy()
     main(sdc_be_proxy, update_version)
diff --git a/catalog-be/src/test/java/org/openecomp/sdc/be/servlets/LockServletTest.java b/catalog-be/src/test/java/org/openecomp/sdc/be/servlets/LockServletTest.java
new file mode 100644 (file)
index 0000000..c2fb235
--- /dev/null
@@ -0,0 +1,121 @@
+/*
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2021 Nordix Foundation
+ *  ================================================================================
+ *  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.
+ *
+ *  SPDX-License-Identifier: Apache-2.0
+ *  ============LICENSE_END=========================================================
+ */
+package org.openecomp.sdc.be.servlets;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.ws.rs.client.Entity;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response.Status;
+
+import org.glassfish.hk2.utilities.binding.AbstractBinder;
+import org.glassfish.jersey.server.ResourceConfig;
+import org.glassfish.jersey.test.JerseyTest;
+import org.glassfish.jersey.test.TestProperties;
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.openecomp.sdc.be.components.validation.UserValidations;
+import org.openecomp.sdc.be.config.ConfigurationManager;
+import org.openecomp.sdc.be.config.SpringConfig;
+import org.openecomp.sdc.be.impl.ComponentsUtils;
+import org.openecomp.sdc.be.model.operations.api.IGraphLockOperation;
+import org.openecomp.sdc.be.user.UserBusinessLogic;
+import org.openecomp.sdc.common.api.ConfigurationSource;
+import org.openecomp.sdc.common.api.Constants;
+import org.openecomp.sdc.common.impl.ExternalConfiguration;
+import org.openecomp.sdc.common.impl.FSConfigurationSource;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.annotation.AnnotationConfigApplicationContext;
+
+class LockServletTest extends JerseyTest {
+
+    @Mock
+    private HttpServletRequest request;
+    @Mock
+    private UserBusinessLogic userBusinessLogic;
+    @Mock
+    private ComponentsUtils componentsUtils;
+    @Mock
+    private IGraphLockOperation graphLockOperation;
+    @Mock
+    private UserValidations userValidations;
+
+    private static final String postUrl = "/v1/catalog/lock";
+    private static final String USER_ID = "cs0008";
+
+    @BeforeEach
+    void init() throws Exception {
+        super.setUp();
+        initConfig();
+    }
+
+    @AfterEach
+    void destory() throws Exception {
+        super.tearDown();
+    }
+
+    private void initConfig() {
+        final String appConfigDir = "src/test/resources/config/catalog-be";
+        final ConfigurationSource configurationSource = new FSConfigurationSource(ExternalConfiguration.getChangeListener(), appConfigDir);
+        final ConfigurationManager configurationManager = new ConfigurationManager(configurationSource);
+        final org.openecomp.sdc.be.config.Configuration configuration = new org.openecomp.sdc.be.config.Configuration();
+        configuration.setJanusGraphInMemoryGraph(true);
+        configurationManager.setConfiguration(configuration);
+        ExternalConfiguration.setAppName("catalog-be");
+    }
+
+    @Override
+    protected ResourceConfig configure() {
+        MockitoAnnotations.openMocks(this);
+        forceSet(TestProperties.CONTAINER_PORT, "0");
+        final ApplicationContext context = new AnnotationConfigApplicationContext(SpringConfig.class);
+        return new ResourceConfig(LockServlet.class)
+            .register(new AbstractBinder() {
+                @Override
+                protected void configure() {
+                    bind(request).to(HttpServletRequest.class);
+                    bind(userBusinessLogic).to(UserBusinessLogic.class);
+                    bind(componentsUtils).to(ComponentsUtils.class);
+                    bind(graphLockOperation).to(IGraphLockOperation.class);
+                    bind(userValidations).to(UserValidations.class);
+                }
+            })
+            .property("contextConfig", context);
+    }
+
+    @Test
+    void disableLockTest() {
+        assertEquals(Status.OK.getStatusCode(), postDisableLock(true));
+        assertEquals(Status.OK.getStatusCode(), postDisableLock(false));
+        assertEquals(Status.OK.getStatusCode(), postDisableLock("true"));
+        assertEquals(Status.OK.getStatusCode(), postDisableLock("false"));
+        assertEquals(Status.BAD_REQUEST.getStatusCode(), postDisableLock("true1"));
+        assertEquals(Status.BAD_REQUEST.getStatusCode(), postDisableLock(null));
+    }
+
+    private int postDisableLock(Object disable) {
+        return target(postUrl).request(MediaType.APPLICATION_JSON)
+                .header(Constants.USER_ID_HEADER, USER_ID)
+                .post(Entity.json(disable)).getStatus();
+    }
+}
\ No newline at end of file
index 2128816..3e41527 100644 (file)
@@ -30,4 +30,6 @@ public interface IGraphLockOperation {
     StorageOperationStatus lockComponentByName(String name, NodeTypeEnum nodeType);
 
     StorageOperationStatus unlockComponentByName(String name, String componentId, NodeTypeEnum nodeType);
+
+    boolean disableLocking(final boolean disable);
 }
index 0106cd3..bc49c8a 100644 (file)
@@ -27,17 +27,17 @@ import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
 import org.openecomp.sdc.common.log.wrappers.Logger;
 import org.springframework.stereotype.Component;
 
+import lombok.NoArgsConstructor;
+
 @Component("graph-lock-operation")
+@NoArgsConstructor
 public class GraphLockOperation implements IGraphLockOperation {
 
     private static final Logger log = Logger.getLogger(GraphLockOperation.class.getName());
+    private boolean disable = false;
     @javax.annotation.Resource
     private JanusGraphGenericDao janusGraphGenericDao;
 
-    public GraphLockOperation() {
-        super();
-    }
-
     /*
      * (non-Javadoc)
      *
@@ -48,7 +48,7 @@ public class GraphLockOperation implements IGraphLockOperation {
         log.info("lock resource with id {}", componentId);
         JanusGraphOperationStatus lockElementStatus = null;
         try {
-            lockElementStatus = janusGraphGenericDao.lockElement(componentId, nodeType);
+            lockElementStatus = disable ? JanusGraphOperationStatus.OK : janusGraphGenericDao.lockElement(componentId, nodeType);
         } catch (Exception e) {
             lockElementStatus = JanusGraphOperationStatus.ALREADY_LOCKED;
         }
@@ -62,13 +62,13 @@ public class GraphLockOperation implements IGraphLockOperation {
      */
     @Override
     public StorageOperationStatus unlockComponent(String componentId, NodeTypeEnum nodeType) {
-        JanusGraphOperationStatus lockElementStatus = janusGraphGenericDao.releaseElement(componentId, nodeType);
+        JanusGraphOperationStatus lockElementStatus = disable ? JanusGraphOperationStatus.OK : janusGraphGenericDao.releaseElement(componentId, nodeType);
         return DaoStatusConverter.convertJanusGraphStatusToStorageStatus(lockElementStatus);
     }
 
     @Override
     public StorageOperationStatus unlockComponentByName(String name, String componentId, NodeTypeEnum nodeType) {
-        JanusGraphOperationStatus lockElementStatus = janusGraphGenericDao.releaseElement(name, nodeType);
+        JanusGraphOperationStatus lockElementStatus = disable ? JanusGraphOperationStatus.OK : janusGraphGenericDao.releaseElement(name, nodeType);
         return DaoStatusConverter.convertJanusGraphStatusToStorageStatus(lockElementStatus);
     }
 
@@ -77,10 +77,17 @@ public class GraphLockOperation implements IGraphLockOperation {
         log.info("lock resource with name {}", name);
         JanusGraphOperationStatus lockElementStatus = null;
         try {
-            lockElementStatus = janusGraphGenericDao.lockElement(name, nodeType);
+            lockElementStatus = disable ? JanusGraphOperationStatus.OK : janusGraphGenericDao.lockElement(name, nodeType);
         } catch (Exception e) {
             lockElementStatus = JanusGraphOperationStatus.ALREADY_LOCKED;
         }
         return DaoStatusConverter.convertJanusGraphStatusToStorageStatus(lockElementStatus);
     }
+
+    @Override
+    public boolean disableLocking(boolean disable) {
+        log.info("Toggling disable locking from {} to {}", this.disable, disable);
+        this.disable = disable;
+        return this.disable;
+    }
 }