diff options
20 files changed, 509 insertions, 114 deletions
diff --git a/adapters/mso-openstack-adapters/src/main/java/org/onap/so/adapters/audit/AuditStackService.java b/adapters/mso-openstack-adapters/src/main/java/org/onap/so/adapters/audit/AuditStackService.java index 3508810e04..57d31bf308 100644 --- a/adapters/mso-openstack-adapters/src/main/java/org/onap/so/adapters/audit/AuditStackService.java +++ b/adapters/mso-openstack-adapters/src/main/java/org/onap/so/adapters/audit/AuditStackService.java @@ -50,23 +50,32 @@ public class AuditStackService { private AuditDeleteStackService auditDeleteStack; @PostConstruct - public void auditAddAAIInventory() { - String auth = ""; - try { - auth = CryptoUtils.decrypt(env.getRequiredProperty("mso.auth"), env.getRequiredProperty("mso.msoKey")); - } catch (IllegalStateException | GeneralSecurityException e) { - logger.error("Error Decrypting Password", e); + public void auditAddAAIInventory() throws Exception { + for (int i = 0; i < getMaxClients(); i++) { + ExternalTaskClient client = createExternalTaskClient(); + client.subscribe("InventoryAddAudit").lockDuration(60000).handler(auditCreateStack::executeExternalTask) + .open(); } - ClientRequestInterceptor interceptor = - new BasicAuthProvider(env.getRequiredProperty("mso.config.cadi.aafId"), auth); + } + + @PostConstruct + public void auditDeleteAAIInventory() throws Exception { + for (int i = 0; i < getMaxClients(); i++) { + ExternalTaskClient client = createExternalTaskClient(); + client.subscribe("InventoryDeleteAudit").lockDuration(60000).handler(auditDeleteStack::executeExternalTask) + .open(); + } + } + + protected ExternalTaskClient createExternalTaskClient() throws Exception { + ClientRequestInterceptor interceptor = createClientRequestInterceptor(); ExternalTaskClient client = ExternalTaskClient.create() .baseUrl(env.getRequiredProperty("mso.workflow.endpoint")).maxTasks(1).addInterceptor(interceptor) - .asyncResponseTimeout(120000).backoffStrategy(new ExponentialBackoffStrategy(0, 0, 0)).build(); - client.subscribe("InventoryAddAudit").lockDuration(60000).handler(auditCreateStack::executeExternalTask).open(); + .asyncResponseTimeout(120000).backoffStrategy(new ExponentialBackoffStrategy(10000, 2, 120000)).build(); + return client; } - @PostConstruct - public void auditDeleteAAIInventory() { + protected ClientRequestInterceptor createClientRequestInterceptor() { String auth = ""; try { auth = CryptoUtils.decrypt(env.getRequiredProperty("mso.auth"), env.getRequiredProperty("mso.msoKey")); @@ -75,11 +84,12 @@ public class AuditStackService { } ClientRequestInterceptor interceptor = new BasicAuthProvider(env.getRequiredProperty("mso.config.cadi.aafId"), auth); - ExternalTaskClient client = ExternalTaskClient.create() - .baseUrl(env.getRequiredProperty("mso.workflow.endpoint")).maxTasks(1).addInterceptor(interceptor) - .asyncResponseTimeout(120000).backoffStrategy(new ExponentialBackoffStrategy(0, 0, 0)).build(); - client.subscribe("InventoryDeleteAudit").lockDuration(60000).handler(auditDeleteStack::executeExternalTask) - .open(); + return interceptor; + } + + protected int getMaxClients() { + return Integer.parseInt(env.getProperty("workflow.topics.maxClients", "10")); } + } diff --git a/adapters/mso-openstack-adapters/src/main/resources/application.yaml b/adapters/mso-openstack-adapters/src/main/resources/application.yaml index 1982961ae7..470bb31b19 100644 --- a/adapters/mso-openstack-adapters/src/main/resources/application.yaml +++ b/adapters/mso-openstack-adapters/src/main/resources/application.yaml @@ -4,7 +4,7 @@ server: port: 8080 tomcat: - max-threads: 50 + max-threads: 75 mso: logPath: ./logs/openstack diff --git a/adapters/mso-openstack-adapters/src/test/java/org/onap/so/adapters/audit/AuditStackServiceTest.java b/adapters/mso-openstack-adapters/src/test/java/org/onap/so/adapters/audit/AuditStackServiceTest.java new file mode 100644 index 0000000000..2eb8d8ef39 --- /dev/null +++ b/adapters/mso-openstack-adapters/src/test/java/org/onap/so/adapters/audit/AuditStackServiceTest.java @@ -0,0 +1,71 @@ +package org.onap.so.adapters.audit; + +import static com.shazam.shazamcrest.MatcherAssert.assertThat; +import static com.shazam.shazamcrest.matcher.Matchers.sameBeanAs; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import org.camunda.bpm.client.ExternalTaskClient; +import org.camunda.bpm.client.interceptor.ClientRequestInterceptor; +import org.camunda.bpm.client.interceptor.auth.BasicAuthProvider; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.mockito.Spy; +import org.mockito.junit.MockitoJUnitRunner; +import org.onap.so.utils.CryptoUtils; +import org.springframework.core.env.Environment; + +@RunWith(MockitoJUnitRunner.class) +public class AuditStackServiceTest { + + @Spy + @InjectMocks + AuditStackService auditStackService; + + @Mock + Environment mockEnvironment; + + + @Before + public void before() { + Mockito.doReturn("5").when(mockEnvironment).getProperty("workflow.topics.maxClients", "10"); + Mockito.doReturn("6B466C603A260F3655DBF91E53CE54667041C01406D10E8CAF9CC24D8FA5388D06F90BFE4C852052B436") + .when(mockEnvironment).getRequiredProperty("mso.auth"); + Mockito.doReturn("07a7159d3bf51a0e53be7a8f89699be7").when(mockEnvironment).getRequiredProperty("mso.msoKey"); + Mockito.doReturn("something").when(mockEnvironment).getRequiredProperty("mso.config.cadi.aafId"); + Mockito.doReturn("host.com").when(mockEnvironment).getRequiredProperty("mso.workflow.endpoint"); + } + + @Test + public void testGetMaxClients() throws Exception { + int actual = auditStackService.getMaxClients(); + assertEquals(5, actual); + } + + @Test + public void testCreateClientRequestInterceptor() throws Exception { + String auth = CryptoUtils.decrypt( + "6B466C603A260F3655DBF91E53CE54667041C01406D10E8CAF9CC24D8FA5388D06F90BFE4C852052B436", + "07a7159d3bf51a0e53be7a8f89699be7"); + ClientRequestInterceptor expected = new BasicAuthProvider("something", auth); + ClientRequestInterceptor actual = auditStackService.createClientRequestInterceptor(); + assertThat(actual, sameBeanAs(expected)); + + } + + @Test + public void testCreateExternalTaskClient() throws Exception { + String auth = CryptoUtils.decrypt( + "6B466C603A260F3655DBF91E53CE54667041C01406D10E8CAF9CC24D8FA5388D06F90BFE4C852052B436", + "07a7159d3bf51a0e53be7a8f89699be7"); + ClientRequestInterceptor inter = new BasicAuthProvider("something", auth); + Mockito.doReturn(inter).when(auditStackService).createClientRequestInterceptor(); + ExternalTaskClient actual = auditStackService.createExternalTaskClient(); + assertNotNull(actual); + Mockito.verify(auditStackService, Mockito.times(1)).createClientRequestInterceptor(); + + } +} diff --git a/bpmn/MSOCommonBPMN/src/main/java/org/onap/so/bpmn/servicedecomposition/tasks/ExecuteBuildingBlockRainyDay.java b/bpmn/MSOCommonBPMN/src/main/java/org/onap/so/bpmn/servicedecomposition/tasks/ExecuteBuildingBlockRainyDay.java index 0a7a75c89b..122e71851f 100644 --- a/bpmn/MSOCommonBPMN/src/main/java/org/onap/so/bpmn/servicedecomposition/tasks/ExecuteBuildingBlockRainyDay.java +++ b/bpmn/MSOCommonBPMN/src/main/java/org/onap/so/bpmn/servicedecomposition/tasks/ExecuteBuildingBlockRainyDay.java @@ -9,9 +9,9 @@ * 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. @@ -81,14 +81,13 @@ public class ExecuteBuildingBlockRainyDay { String serviceType = ASTERISK; boolean aLaCarte = (boolean) execution.getVariable("aLaCarte"); boolean suppressRollback = (boolean) execution.getVariable("suppressRollback"); - String handlingCode = ""; WorkflowException workflowException = (WorkflowException) execution.getVariable("WorkflowException"); - try { - // Extract error data to be returned to WorkflowAction + if (workflowException != null) { execution.setVariable("WorkflowExceptionErrorMessage", workflowException.getErrorMessage()); - } catch (Exception e) { - logger.error("No WorkflowException Found", e); + } else { + logger.debug("WorkflowException is null, unable to set WorkflowExceptionErrorMessage"); } + String handlingCode = ""; if (suppressRollback) { handlingCode = "Abort"; diff --git a/bpmn/MSOCommonBPMN/src/main/java/org/onap/so/client/exception/ExceptionBuilder.java b/bpmn/MSOCommonBPMN/src/main/java/org/onap/so/client/exception/ExceptionBuilder.java index b69ab151c4..dabfc81e1f 100644 --- a/bpmn/MSOCommonBPMN/src/main/java/org/onap/so/client/exception/ExceptionBuilder.java +++ b/bpmn/MSOCommonBPMN/src/main/java/org/onap/so/client/exception/ExceptionBuilder.java @@ -152,7 +152,7 @@ public class ExceptionBuilder { .getProcessDefinition(execution.getProcessDefinitionId()).getKey(); } - public void processAuditException(DelegateExecutionImpl execution) { + public void processAuditException(DelegateExecutionImpl execution, boolean flowShouldContinue) { logger.info("Building a WorkflowException for Subflow"); StringBuilder errorMessage = new StringBuilder(); @@ -203,11 +203,15 @@ public class ExceptionBuilder { errorMessage.append( "Recommendation - Wait for nightly RO Audit to run and fix the data issue and resume vf-module creation in VID. If problem persists then report problem to AIC/RO Ops."); - WorkflowException exception = new WorkflowException(processKey, 400, errorMessage.toString()); - execution.setVariable("WorkflowException", exception); - execution.setVariable("WorkflowExceptionErrorMessage", errorMessage); - logger.info("Outgoing WorkflowException is {}", exception); - logger.info("Throwing MSOWorkflowException"); - throw new BpmnError("AAIInventoryFailure"); + if (flowShouldContinue) { + execution.setVariable("StatusMessage", errorMessage.toString()); + } else { + WorkflowException exception = new WorkflowException(processKey, 400, errorMessage.toString()); + execution.setVariable("WorkflowException", exception); + execution.setVariable("WorkflowExceptionErrorMessage", errorMessage.toString()); + logger.info("Outgoing WorkflowException is {}", exception); + logger.info("Throwing MSOWorkflowException"); + throw new BpmnError("AAIInventoryFailure"); + } } } diff --git a/bpmn/MSOCommonBPMN/src/test/java/org/onap/so/client/exception/ExceptionBuilderTest.java b/bpmn/MSOCommonBPMN/src/test/java/org/onap/so/client/exception/ExceptionBuilderTest.java index 4ade9dbe32..549f16b6f6 100644 --- a/bpmn/MSOCommonBPMN/src/test/java/org/onap/so/client/exception/ExceptionBuilderTest.java +++ b/bpmn/MSOCommonBPMN/src/test/java/org/onap/so/client/exception/ExceptionBuilderTest.java @@ -22,6 +22,7 @@ package org.onap.so.client.exception; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.fail; import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.when; import org.camunda.bpm.engine.delegate.BpmnError; @@ -131,7 +132,7 @@ public class ExceptionBuilderTest extends BaseTest { public void processAuditExceptionTest() { try { Mockito.doReturn(extractPojosForBB).when(exceptionBuilder).getExtractPojosForBB(); - exceptionBuilder.processAuditException((DelegateExecutionImpl) execution); + exceptionBuilder.processAuditException((DelegateExecutionImpl) execution, false); } catch (BpmnError bpmnException) { assertEquals("AAIInventoryFailure", bpmnException.getErrorCode()); WorkflowException we = execution.getVariable("WorkflowException"); @@ -142,4 +143,19 @@ public class ExceptionBuilderTest extends BaseTest { } } + @Test + public void processAuditExceptionContinueTest() { + try { + Mockito.doReturn(extractPojosForBB).when(exceptionBuilder).getExtractPojosForBB(); + exceptionBuilder.processAuditException((DelegateExecutionImpl) execution, true); + String sm = execution.getVariable("StatusMessage"); + assertNotNull(sm); + assertEquals( + "create VF-Module testVfModuleId1 failed due to incomplete A&AI vserver inventory population after stack testStackName was successfully created in cloud region testLcpCloudRegionId. MSO Audit indicates that AIC RO did not create vserver testVServerId in AAI. Recommendation - Wait for nightly RO Audit to run and fix the data issue and resume vf-module creation in VID. If problem persists then report problem to AIC/RO Ops.", + sm); + } catch (BpmnError bpmnException) { + fail(); + } + } + } diff --git a/bpmn/so-bpmn-building-blocks/src/main/resources/subprocess/BuildingBlock/ActivateVfModuleBB.bpmn b/bpmn/so-bpmn-building-blocks/src/main/resources/subprocess/BuildingBlock/ActivateVfModuleBB.bpmn index 435d85d032..ff37874978 100644 --- a/bpmn/so-bpmn-building-blocks/src/main/resources/subprocess/BuildingBlock/ActivateVfModuleBB.bpmn +++ b/bpmn/so-bpmn-building-blocks/src/main/resources/subprocess/BuildingBlock/ActivateVfModuleBB.bpmn @@ -69,7 +69,7 @@ </bpmn:endEvent> <bpmn:sequenceFlow id="SequenceFlow_19gbhlj" sourceRef="catchInventoryException" targetRef="processAuditException" /> <bpmn:sequenceFlow id="SequenceFlow_0l4jzc5" sourceRef="processAuditException" targetRef="EndEvent_067jv1n" /> - <bpmn:serviceTask id="processAuditException" name="Proccess Error" camunda:expression="${ExceptionBuilder.processAuditException(InjectExecution.execute(execution, execution.getVariable("gBuildingBlockExecution")))}"> + <bpmn:serviceTask id="processAuditException" name="Proccess Error" camunda:expression="${ExceptionBuilder.processAuditException(InjectExecution.execute(execution, execution.getVariable("gBuildingBlockExecution")), false)}"> <bpmn:incoming>SequenceFlow_19gbhlj</bpmn:incoming> <bpmn:outgoing>SequenceFlow_0l4jzc5</bpmn:outgoing> </bpmn:serviceTask> diff --git a/bpmn/so-bpmn-building-blocks/src/main/resources/subprocess/BuildingBlock/DeleteVfModuleBB.bpmn b/bpmn/so-bpmn-building-blocks/src/main/resources/subprocess/BuildingBlock/DeleteVfModuleBB.bpmn index 41c3966626..b774c052cc 100644 --- a/bpmn/so-bpmn-building-blocks/src/main/resources/subprocess/BuildingBlock/DeleteVfModuleBB.bpmn +++ b/bpmn/so-bpmn-building-blocks/src/main/resources/subprocess/BuildingBlock/DeleteVfModuleBB.bpmn @@ -109,19 +109,19 @@ <bpmn:outgoing>SequenceFlow_1ut7n32</bpmn:outgoing> </bpmn:exclusiveGateway> <bpmn:subProcess id="SubProcess_0grvkj2" name="Audit Exception Sub Process" triggeredByEvent="true"> - <bpmn:startEvent id="StartEvent_1euiddy"> - <bpmn:outgoing>SequenceFlow_0xuodpy</bpmn:outgoing> - <bpmn:errorEventDefinition errorRef="Error_0jjnve8" /> - </bpmn:startEvent> <bpmn:endEvent id="EndEvent_1gzq57j"> <bpmn:incoming>SequenceFlow_1fhst92</bpmn:incoming> </bpmn:endEvent> - <bpmn:serviceTask id="ServiceTask_1isbxvo" name="Proccess Error" camunda:expression="${ExceptionBuilder.processAuditException(InjectExecution.execute(execution, execution.getVariable("gBuildingBlockExecution")))}"> + <bpmn:serviceTask id="ServiceTask_1isbxvo" name="Proccess Error" camunda:expression="${ExceptionBuilder.processAuditException(InjectExecution.execute(execution, execution.getVariable("gBuildingBlockExecution")), true)}"> <bpmn:incoming>SequenceFlow_0xuodpy</bpmn:incoming> <bpmn:outgoing>SequenceFlow_1fhst92</bpmn:outgoing> </bpmn:serviceTask> <bpmn:sequenceFlow id="SequenceFlow_0xuodpy" sourceRef="StartEvent_1euiddy" targetRef="ServiceTask_1isbxvo" /> <bpmn:sequenceFlow id="SequenceFlow_1fhst92" sourceRef="ServiceTask_1isbxvo" targetRef="EndEvent_1gzq57j" /> + <bpmn:startEvent id="StartEvent_1euiddy" isInterrupting="false"> + <bpmn:outgoing>SequenceFlow_0xuodpy</bpmn:outgoing> + <bpmn:escalationEventDefinition escalationRef="Escalation_130je8j" camunda:escalationCodeVariable="test" /> + </bpmn:startEvent> </bpmn:subProcess> <bpmn:sequenceFlow id="SequenceFlow_179btn2" sourceRef="aaiCatch" targetRef="DeleteNetworkPolicies" /> <bpmn:intermediateThrowEvent id="aaiThrow" name="Update AAI"> @@ -132,26 +132,29 @@ <bpmn:outgoing>SequenceFlow_179btn2</bpmn:outgoing> <bpmn:linkEventDefinition name="AAI" /> </bpmn:intermediateCatchEvent> - <bpmn:exclusiveGateway id="auditSuccessfulCheck" name="Audit Successful?" default="SequenceFlow_17cd9e2"> - <bpmn:incoming>SequenceFlow_0qfmmgt</bpmn:incoming> - <bpmn:outgoing>SequenceFlow_17cd9e2</bpmn:outgoing> - <bpmn:outgoing>SequenceFlow_1gdyk9j</bpmn:outgoing> - </bpmn:exclusiveGateway> - <bpmn:sequenceFlow id="SequenceFlow_17cd9e2" name="Yes" sourceRef="auditSuccessfulCheck" targetRef="ExclusiveGateway_1pydilb" /> + <bpmn:sequenceFlow id="SequenceFlow_17cd9e2" name="Yes/No" sourceRef="auditSuccessfulCheck" targetRef="ExclusiveGateway_1pydilb"> + <bpmn:conditionExpression xsi:type="bpmn:tFormalExpression"><![CDATA[${execution.getVariable("auditIsSuccessful") == false || execution.getVariable("auditIsSuccessful") == true}]]></bpmn:conditionExpression> + </bpmn:sequenceFlow> <bpmn:sequenceFlow id="SequenceFlow_1gdyk9j" name="No" sourceRef="auditSuccessfulCheck" targetRef="EndEvent_0b0ocu0"> <bpmn:conditionExpression xsi:type="bpmn:tFormalExpression"><![CDATA[${execution.getVariable("auditIsSuccessful") == false}]]></bpmn:conditionExpression> </bpmn:sequenceFlow> - <bpmn:endEvent id="EndEvent_0b0ocu0"> - <bpmn:incoming>SequenceFlow_1gdyk9j</bpmn:incoming> - <bpmn:errorEventDefinition errorRef="Error_0jjnve8" /> - </bpmn:endEvent> <bpmn:inclusiveGateway id="ExclusiveGateway_1yvh16a"> <bpmn:incoming>SequenceFlow_02lpx87</bpmn:incoming> <bpmn:incoming>SequenceFlow_1ut7n32</bpmn:incoming> <bpmn:outgoing>SequenceFlow_14bu4ys</bpmn:outgoing> </bpmn:inclusiveGateway> + <bpmn:inclusiveGateway id="auditSuccessfulCheck" name="Audit Successful?"> + <bpmn:incoming>SequenceFlow_0qfmmgt</bpmn:incoming> + <bpmn:outgoing>SequenceFlow_17cd9e2</bpmn:outgoing> + <bpmn:outgoing>SequenceFlow_1gdyk9j</bpmn:outgoing> + </bpmn:inclusiveGateway> + <bpmn:endEvent id="EndEvent_0b0ocu0"> + <bpmn:incoming>SequenceFlow_1gdyk9j</bpmn:incoming> + <bpmn:escalationEventDefinition escalationRef="Escalation_130je8j" /> + </bpmn:endEvent> </bpmn:process> <bpmn:error id="Error_0jjnve8" name="Error_3k24na6" errorCode="AAIInventoryFailure" /> + <bpmn:escalation id="Escalation_130je8j" name="audit" escalationCode="audit1" /> <bpmndi:BPMNDiagram id="BPMNDiagram_1"> <bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="DeleteVfModuleBB"> <bpmndi:BPMNShape id="_BPMNShape_StartEvent_2" bpmnElement="DeleteVfModuleBB_Start"> @@ -375,12 +378,6 @@ <bpmndi:BPMNShape id="SubProcess_0grvkj2_di" bpmnElement="SubProcess_0grvkj2" isExpanded="true"> <dc:Bounds x="231" y="642" width="350" height="200" /> </bpmndi:BPMNShape> - <bpmndi:BPMNShape id="StartEvent_1euiddy_di" bpmnElement="StartEvent_1euiddy"> - <dc:Bounds x="262" y="725" width="36" height="36" /> - <bpmndi:BPMNLabel> - <dc:Bounds x="189" y="765" width="90" height="12" /> - </bpmndi:BPMNLabel> - </bpmndi:BPMNShape> <bpmndi:BPMNShape id="EndEvent_1gzq57j_di" bpmnElement="EndEvent_1gzq57j"> <dc:Bounds x="510" y="725" width="36" height="36" /> <bpmndi:BPMNLabel> @@ -394,7 +391,7 @@ <di:waypoint xsi:type="dc:Point" x="298" y="743" /> <di:waypoint xsi:type="dc:Point" x="353" y="743" /> <bpmndi:BPMNLabel> - <dc:Bounds x="237" y="722" width="90" height="12" /> + <dc:Bounds x="280.5" y="722" width="90" height="12" /> </bpmndi:BPMNLabel> </bpmndi:BPMNEdge> <bpmndi:BPMNEdge id="SequenceFlow_1fhst92_di" bpmnElement="SequenceFlow_1fhst92"> @@ -423,39 +420,45 @@ <dc:Bounds x="150" y="530" width="55" height="12" /> </bpmndi:BPMNLabel> </bpmndi:BPMNShape> - <bpmndi:BPMNShape id="ExclusiveGateway_187bfld_di" bpmnElement="auditSuccessfulCheck" isMarkerVisible="true"> - <dc:Bounds x="779.6431784107947" y="108" width="50" height="50" /> - <bpmndi:BPMNLabel> - <dc:Bounds x="775" y="162" width="60" height="24" /> - </bpmndi:BPMNLabel> - </bpmndi:BPMNShape> <bpmndi:BPMNEdge id="SequenceFlow_17cd9e2_di" bpmnElement="SequenceFlow_17cd9e2"> <di:waypoint xsi:type="dc:Point" x="830" y="133" /> <di:waypoint xsi:type="dc:Point" x="868" y="133" /> <di:waypoint xsi:type="dc:Point" x="868" y="174" /> <bpmndi:BPMNLabel> - <dc:Bounds x="838" y="114" width="19" height="12" /> + <dc:Bounds x="830" y="114" width="36" height="12" /> </bpmndi:BPMNLabel> </bpmndi:BPMNEdge> <bpmndi:BPMNEdge id="SequenceFlow_1gdyk9j_di" bpmnElement="SequenceFlow_1gdyk9j"> <di:waypoint xsi:type="dc:Point" x="805" y="108" /> <di:waypoint xsi:type="dc:Point" x="805" y="56" /> <bpmndi:BPMNLabel> - <dc:Bounds x="812" y="77.49056603773585" width="14" height="12" /> + <dc:Bounds x="812" y="77" width="14" height="12" /> </bpmndi:BPMNLabel> </bpmndi:BPMNEdge> - <bpmndi:BPMNShape id="EndEvent_1wydovd_di" bpmnElement="EndEvent_0b0ocu0"> - <dc:Bounds x="787" y="20" width="36" height="36" /> - <bpmndi:BPMNLabel> - <dc:Bounds x="805" y="59.13043478260869" width="0" height="12" /> - </bpmndi:BPMNLabel> - </bpmndi:BPMNShape> <bpmndi:BPMNShape id="InclusiveGateway_0cjvlht_di" bpmnElement="ExclusiveGateway_1yvh16a"> <dc:Bounds x="900" y="259" width="50" height="50" /> <bpmndi:BPMNLabel> <dc:Bounds x="879" y="312" width="0" height="12" /> </bpmndi:BPMNLabel> </bpmndi:BPMNShape> + <bpmndi:BPMNShape id="InclusiveGateway_0i6rdd1_di" bpmnElement="auditSuccessfulCheck"> + <dc:Bounds x="780" y="108" width="50" height="50" /> + <bpmndi:BPMNLabel> + <dc:Bounds x="775" y="162" width="60" height="24" /> + </bpmndi:BPMNLabel> + </bpmndi:BPMNShape> + <bpmndi:BPMNShape id="StartEvent_04qhoba_di" bpmnElement="StartEvent_1euiddy"> + <dc:Bounds x="262" y="725" width="36" height="36" /> + <bpmndi:BPMNLabel> + <dc:Bounds x="189" y="765" width="0" height="12" /> + </bpmndi:BPMNLabel> + </bpmndi:BPMNShape> + <bpmndi:BPMNShape id="EndEvent_1onxfk1_di" bpmnElement="EndEvent_0b0ocu0"> + <dc:Bounds x="787" y="20" width="36" height="36" /> + <bpmndi:BPMNLabel> + <dc:Bounds x="760" y="59" width="0" height="12" /> + </bpmndi:BPMNLabel> + </bpmndi:BPMNShape> </bpmndi:BPMNPlane> </bpmndi:BPMNDiagram> </bpmn:definitions> diff --git a/bpmn/so-bpmn-building-blocks/src/main/resources/subprocess/BuildingBlock/ExecuteBuildingBlock.bpmn b/bpmn/so-bpmn-building-blocks/src/main/resources/subprocess/BuildingBlock/ExecuteBuildingBlock.bpmn index 83363d48ba..0a6a7731ce 100644 --- a/bpmn/so-bpmn-building-blocks/src/main/resources/subprocess/BuildingBlock/ExecuteBuildingBlock.bpmn +++ b/bpmn/so-bpmn-building-blocks/src/main/resources/subprocess/BuildingBlock/ExecuteBuildingBlock.bpmn @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8"?> -<bpmn:definitions xmlns:bpmn="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:di="http://www.omg.org/spec/DD/20100524/DI" xmlns:dc="http://www.omg.org/spec/DD/20100524/DC" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:camunda="http://camunda.org/schema/1.0/bpmn" id="Definitions_1" targetNamespace="http://bpmn.io/schema/bpmn" exporter="Camunda Modeler" exporterVersion="1.7.2"> +<bpmn:definitions xmlns:bpmn="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:di="http://www.omg.org/spec/DD/20100524/DI" xmlns:dc="http://www.omg.org/spec/DD/20100524/DC" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:camunda="http://camunda.org/schema/1.0/bpmn" id="Definitions_1" targetNamespace="http://bpmn.io/schema/bpmn" exporter="Camunda Modeler" exporterVersion="1.10.0"> <bpmn:process id="ExecuteBuildingBlock" name="ExecuteBuildingBlock" isExecutable="true"> <bpmn:startEvent id="Start_ExecuteBuildingBlock" name="start"> <bpmn:outgoing>SequenceFlow_0rq4c5r</bpmn:outgoing> @@ -10,6 +10,7 @@ <camunda:out source="WorkflowException" target="WorkflowException" /> <camunda:in source="mso-request-id" target="mso-request-id" /> <camunda:out source="WorkflowExceptionErrorMessage" target="WorkflowExceptionErrorMessage" /> + <camunda:out source="StatusMessage" target="StatusMessage" /> </bpmn:extensionElements> <bpmn:incoming>SequenceFlow_19wuics</bpmn:incoming> <bpmn:outgoing>SequenceFlow_01h9qmz</bpmn:outgoing> diff --git a/bpmn/so-bpmn-building-blocks/src/main/resources/subprocess/BuildingBlock/WorkflowActionBB.bpmn b/bpmn/so-bpmn-building-blocks/src/main/resources/subprocess/BuildingBlock/WorkflowActionBB.bpmn index 76ca2a89cc..35b77d9189 100644 --- a/bpmn/so-bpmn-building-blocks/src/main/resources/subprocess/BuildingBlock/WorkflowActionBB.bpmn +++ b/bpmn/so-bpmn-building-blocks/src/main/resources/subprocess/BuildingBlock/WorkflowActionBB.bpmn @@ -22,6 +22,7 @@ <camunda:out source="orchestrationStatusValidationResult" target="orchestrationStatusValidationResult" /> <camunda:out source="RetryDuration" target="RetryDuration" /> <camunda:in source="suppressRollback" target="suppressRollback" /> + <camunda:out source="StatusMessage" target="StatusMessage" /> </bpmn:extensionElements> <bpmn:incoming>SequenceFlow_0mew9im</bpmn:incoming> <bpmn:outgoing>SequenceFlow_1hsqed1</bpmn:outgoing> diff --git a/bpmn/so-bpmn-building-blocks/src/test/java/org/onap/so/bpmn/infrastructure/bpmn/subprocess/DeleteVfModuleBBTest.java b/bpmn/so-bpmn-building-blocks/src/test/java/org/onap/so/bpmn/infrastructure/bpmn/subprocess/DeleteVfModuleBBTest.java index e88df73f39..d9166c9138 100644 --- a/bpmn/so-bpmn-building-blocks/src/test/java/org/onap/so/bpmn/infrastructure/bpmn/subprocess/DeleteVfModuleBBTest.java +++ b/bpmn/so-bpmn-building-blocks/src/test/java/org/onap/so/bpmn/infrastructure/bpmn/subprocess/DeleteVfModuleBBTest.java @@ -37,6 +37,7 @@ public class DeleteVfModuleBBTest extends BaseBPMNTest { @Before public void before() { variables.put("auditInventoryNeeded", true); + variables.put("auditIsSuccessful", true); } @Test diff --git a/bpmn/so-bpmn-tasks/src/main/java/org/onap/so/bpmn/infrastructure/workflow/tasks/WorkflowActionBBFailure.java b/bpmn/so-bpmn-tasks/src/main/java/org/onap/so/bpmn/infrastructure/workflow/tasks/WorkflowActionBBFailure.java index 4fc4d85b97..5f357f5478 100644 --- a/bpmn/so-bpmn-tasks/src/main/java/org/onap/so/bpmn/infrastructure/workflow/tasks/WorkflowActionBBFailure.java +++ b/bpmn/so-bpmn-tasks/src/main/java/org/onap/so/bpmn/infrastructure/workflow/tasks/WorkflowActionBBFailure.java @@ -20,6 +20,7 @@ package org.onap.so.bpmn.infrastructure.workflow.tasks; +import java.sql.Timestamp; import java.util.Optional; import org.camunda.bpm.engine.delegate.BpmnError; import org.camunda.bpm.engine.delegate.DelegateExecution; @@ -53,6 +54,10 @@ public class WorkflowActionBBFailure { errorMsg = "Failed to determine error message"; } request.setStatusMessage(errorMsg); + request.setProgress(Long.valueOf(100)); + request.setRequestStatus("FAILED"); + request.setLastModifiedBy("CamundaBPMN"); + request.setEndTime(new Timestamp(System.currentTimeMillis())); requestDbclient.updateInfraActiveRequests(request); } catch (Exception e) { logger.error( @@ -113,6 +118,7 @@ public class WorkflowActionBBFailure { request.setProgress(Long.valueOf(100)); request.setRequestStatus("FAILED"); request.setLastModifiedBy("CamundaBPMN"); + request.setEndTime(new Timestamp(System.currentTimeMillis())); requestDbclient.updateInfraActiveRequests(request); } catch (Exception e) { workflowAction.buildAndThrowException(execution, "Error Updating Request Database", e); diff --git a/bpmn/so-bpmn-tasks/src/main/java/org/onap/so/bpmn/infrastructure/workflow/tasks/WorkflowActionBBTasks.java b/bpmn/so-bpmn-tasks/src/main/java/org/onap/so/bpmn/infrastructure/workflow/tasks/WorkflowActionBBTasks.java index f0a102dfeb..753a050c03 100644 --- a/bpmn/so-bpmn-tasks/src/main/java/org/onap/so/bpmn/infrastructure/workflow/tasks/WorkflowActionBBTasks.java +++ b/bpmn/so-bpmn-tasks/src/main/java/org/onap/so/bpmn/infrastructure/workflow/tasks/WorkflowActionBBTasks.java @@ -7,9 +7,9 @@ * 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. @@ -227,11 +227,16 @@ public class WorkflowActionBBTasks { final String action = (String) execution.getVariable(G_ACTION); final boolean aLaCarte = (boolean) execution.getVariable(G_ALACARTE); final String resourceName = (String) execution.getVariable("resourceName"); + String statusMessage = (String) execution.getVariable("StatusMessage"); String macroAction = ""; - if (aLaCarte) { - macroAction = "ALaCarte-" + resourceName + "-" + action + " request was executed correctly."; + if (statusMessage == null) { + if (aLaCarte) { + macroAction = "ALaCarte-" + resourceName + "-" + action + " request was executed correctly."; + } else { + macroAction = "Macro-" + resourceName + "-" + action + " request was executed correctly."; + } } else { - macroAction = "Macro-" + resourceName + "-" + action + " request was executed correctly."; + macroAction = statusMessage; } execution.setVariable("finalStatusMessage", macroAction); Timestamp endTime = new Timestamp(System.currentTimeMillis()); diff --git a/bpmn/so-bpmn-tasks/src/test/java/org/onap/so/bpmn/infrastructure/workflow/tasks/WorkflowActionBBFailureTest.java b/bpmn/so-bpmn-tasks/src/test/java/org/onap/so/bpmn/infrastructure/workflow/tasks/WorkflowActionBBFailureTest.java index a6ce88f164..52a2cf7223 100644 --- a/bpmn/so-bpmn-tasks/src/test/java/org/onap/so/bpmn/infrastructure/workflow/tasks/WorkflowActionBBFailureTest.java +++ b/bpmn/so-bpmn-tasks/src/test/java/org/onap/so/bpmn/infrastructure/workflow/tasks/WorkflowActionBBFailureTest.java @@ -23,11 +23,14 @@ package org.onap.so.bpmn.infrastructure.workflow.tasks; import static org.junit.Assert.assertEquals; import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.ArgumentMatchers.isA; +import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.doNothing; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.when; +import java.sql.Timestamp; import org.camunda.bpm.engine.delegate.DelegateExecution; import org.camunda.bpm.extension.mockito.delegate.DelegateExecutionFake; +import org.junit.After; import org.junit.Before; import org.junit.Rule; import org.junit.Test; @@ -84,6 +87,7 @@ public class WorkflowActionBBFailureTest extends BaseTaskTest { Mockito.verify(reqMock, Mockito.times(1)).setRequestStatus("FAILED"); Mockito.verify(reqMock, Mockito.times(1)).setProgress(Long.valueOf(100)); Mockito.verify(reqMock, Mockito.times(1)).setLastModifiedBy("CamundaBPMN"); + Mockito.verify(reqMock, Mockito.times(1)).setEndTime(any(Timestamp.class)); } @Test @@ -142,4 +146,20 @@ public class WorkflowActionBBFailureTest extends BaseTaskTest { String errorMsg = (String) execution.getVariable("ErrorMessage"); assertEquals("error in test case", errorMsg); } + + @Test + public void updateRequestErrorStatusMessageTest() { + String reqId = "reqId123"; + execution.setVariable("mso-request-id", reqId); + WorkflowException we = new WorkflowException("WorkflowAction", 1231, "Error Case"); + execution.setVariable("WorkflowException", we); + + doReturn(reqMock).when(requestsDbClient).getInfraActiveRequestbyRequestId(reqId); + workflowActionBBFailure.updateRequestErrorStatusMessage(execution); + Mockito.verify(reqMock, Mockito.times(1)).setStatusMessage("Error Case"); + Mockito.verify(reqMock, Mockito.times(1)).setRequestStatus("FAILED"); + Mockito.verify(reqMock, Mockito.times(1)).setProgress(Long.valueOf(100)); + Mockito.verify(reqMock, Mockito.times(1)).setLastModifiedBy("CamundaBPMN"); + Mockito.verify(reqMock, Mockito.times(1)).setEndTime(any(Timestamp.class)); + } } diff --git a/common/src/main/java/org/onap/so/serviceinstancebeans/RequestParameters.java b/common/src/main/java/org/onap/so/serviceinstancebeans/RequestParameters.java index 1df2c10411..9fceed1641 100644 --- a/common/src/main/java/org/onap/so/serviceinstancebeans/RequestParameters.java +++ b/common/src/main/java/org/onap/so/serviceinstancebeans/RequestParameters.java @@ -20,11 +20,11 @@ package org.onap.so.serviceinstancebeans; -import java.beans.Transient; import java.io.Serializable; import java.util.ArrayList; import java.util.List; import java.util.Map; +import org.apache.commons.lang3.builder.ToStringBuilder; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonInclude.Include; import com.fasterxml.jackson.annotation.JsonProperty; @@ -52,9 +52,21 @@ public class RequestParameters implements Serializable { private Boolean cascadeDelete; @JsonProperty("testApi") private String testApi; // usePreload would always be true for Update + @JsonProperty("retainAssignments") + private Boolean retainAssignments; // usePreload would always be true for Update @JsonProperty("rebuildVolumeGroups") private Boolean rebuildVolumeGroups; + @Override + public String toString() { + return new ToStringBuilder(this).append("subscriptionServiceType", subscriptionServiceType) + .append("userParams", userParams).append("aLaCarte", aLaCarte).append("payload", payload) + .append("usePreload", usePreload).append("autoBuildVfModules", autoBuildVfModules) + .append("cascadeDelete", cascadeDelete).append("testApi", testApi) + .append("retainAssignments", retainAssignments).append("rebuildVolumeGroups", rebuildVolumeGroups) + .toString(); + } + public String getSubscriptionServiceType() { return subscriptionServiceType; } @@ -150,11 +162,13 @@ public class RequestParameters implements Serializable { this.rebuildVolumeGroups = rebuildVolumeGroups; } - @Override - public String toString() { - return "RequestParameters [subscriptionServiceType=" + subscriptionServiceType + ", userParams=" + userParams - + ", aLaCarte=" + aLaCarte + ", testApi= " + testApi + ", autoBuildVfModules=" + autoBuildVfModules - + ", usePreload=" + usePreload + ", rebuildVolumeGroups=" + rebuildVolumeGroups + ", payload=" + payload - + "]"; + public Boolean getRetainAssignments() { + return retainAssignments; + } + + public void setRetainAssignments(Boolean retainAssignments) { + this.retainAssignments = retainAssignments; } + + } diff --git a/mso-api-handlers/mso-api-handler-infra/src/main/java/org/onap/so/apihandlerinfra/Action.java b/mso-api-handlers/mso-api-handler-infra/src/main/java/org/onap/so/apihandlerinfra/Action.java index 77dbff9ebb..974d025ff2 100644 --- a/mso-api-handlers/mso-api-handler-infra/src/main/java/org/onap/so/apihandlerinfra/Action.java +++ b/mso-api-handlers/mso-api-handler-infra/src/main/java/org/onap/so/apihandlerinfra/Action.java @@ -20,9 +20,7 @@ package org.onap.so.apihandlerinfra; -/* - * Enum for Status values returned by API Handler to Tail-F - */ + public enum Action implements Actions { - createInstance, updateInstance, deleteInstance, configureInstance, replaceInstance, activateInstance, deactivateInstance, enablePort, disablePort, addRelationships, removeRelationships, inPlaceSoftwareUpdate, applyUpdatedConfig, completeTask, assignInstance, unassignInstance, compareModel, scaleInstance, deactivateAndCloudDelete, scaleOut, recreateInstance, addMembers, removeMembers + createInstance, updateInstance, deleteInstance, configureInstance, replaceInstance, replaceInstanceRetainAssignments, activateInstance, deactivateInstance, enablePort, disablePort, addRelationships, removeRelationships, inPlaceSoftwareUpdate, applyUpdatedConfig, completeTask, assignInstance, unassignInstance, compareModel, scaleInstance, deactivateAndCloudDelete, scaleOut, recreateInstance, addMembers, removeMembers } diff --git a/mso-api-handlers/mso-api-handler-infra/src/main/java/org/onap/so/apihandlerinfra/ServiceInstances.java b/mso-api-handlers/mso-api-handler-infra/src/main/java/org/onap/so/apihandlerinfra/ServiceInstances.java index 7c8d24742d..45319de5e8 100644 --- a/mso-api-handlers/mso-api-handler-infra/src/main/java/org/onap/so/apihandlerinfra/ServiceInstances.java +++ b/mso-api-handlers/mso-api-handler-infra/src/main/java/org/onap/so/apihandlerinfra/ServiceInstances.java @@ -23,12 +23,24 @@ package org.onap.so.apihandlerinfra; -import com.fasterxml.jackson.core.JsonParseException; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.JsonMappingException; -import com.fasterxml.jackson.databind.ObjectMapper; -import io.swagger.annotations.Api; -import io.swagger.annotations.ApiOperation; +import java.io.IOException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import javax.transaction.Transactional; +import javax.ws.rs.Consumes; +import javax.ws.rs.DELETE; +import javax.ws.rs.POST; +import javax.ws.rs.PUT; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; +import javax.ws.rs.Produces; +import javax.ws.rs.container.ContainerRequestContext; +import javax.ws.rs.core.Context; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; import org.apache.commons.lang.StringUtils; import org.apache.http.HttpStatus; import org.onap.so.apihandler.common.CommonConstants; @@ -74,24 +86,12 @@ import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.core.env.Environment; import org.springframework.stereotype.Component; -import javax.transaction.Transactional; -import javax.ws.rs.Consumes; -import javax.ws.rs.DELETE; -import javax.ws.rs.POST; -import javax.ws.rs.PUT; -import javax.ws.rs.Path; -import javax.ws.rs.PathParam; -import javax.ws.rs.Produces; -import javax.ws.rs.container.ContainerRequestContext; -import javax.ws.rs.core.Context; -import javax.ws.rs.core.MediaType; -import javax.ws.rs.core.Response; -import java.io.IOException; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Optional; +import com.fasterxml.jackson.core.JsonParseException; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.JsonMappingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; @Component @Path("/onap/so/infra/serviceInstantiation") @@ -766,6 +766,7 @@ public class ServiceInstances { String apiVersion = version.substring(1); sir = requestHandlerUtils.convertJsonToServiceInstanceRequest(requestJSON, action, requestId, requestUri); + action = handleReplaceInstance(action, sir); String requestScope = requestHandlerUtils.deriveRequestScope(action, sir, requestUri); InfraActiveRequests currentActiveReq = msoRequest.createRequestObject(sir, action, requestId, Status.IN_PROGRESS, requestJSON, requestScope); @@ -939,6 +940,20 @@ public class ServiceInstances { recipeLookupResult.getOrchestrationURI(), requestScope); } + /** + * @param action + * @param sir + * @return + */ + protected Actions handleReplaceInstance(Actions action, ServiceInstancesRequest sir) { + if (action != null && action.equals(Action.replaceInstance) + && sir.getRequestDetails().getRequestParameters().getRetainAssignments() != null + && sir.getRequestDetails().getRequestParameters().getRetainAssignments()) { + action = Action.replaceInstanceRetainAssignments; + } + return action; + } + public Response deleteInstanceGroups(Actions action, HashMap<String, String> instanceIdMap, String version, String requestId, String requestUri, ContainerRequestContext requestContext) throws ApiException { String instanceGroupId = instanceIdMap.get(CommonConstants.INSTANCE_GROUP_INSTANCE_ID); diff --git a/mso-api-handlers/mso-api-handler-infra/src/test/java/org/onap/so/apihandlerinfra/ServiceInstancesTest.java b/mso-api-handlers/mso-api-handler-infra/src/test/java/org/onap/so/apihandlerinfra/ServiceInstancesTest.java index db6273dc4a..ea43a54e69 100644 --- a/mso-api-handlers/mso-api-handler-infra/src/test/java/org/onap/so/apihandlerinfra/ServiceInstancesTest.java +++ b/mso-api-handlers/mso-api-handler-infra/src/test/java/org/onap/so/apihandlerinfra/ServiceInstancesTest.java @@ -28,11 +28,14 @@ import static com.github.tomakehurst.wiremock.client.WireMock.urlMatching; import static com.github.tomakehurst.wiremock.client.WireMock.urlPathEqualTo; import static com.shazam.shazamcrest.matcher.Matchers.sameBeanAs; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; import static org.junit.Assert.assertThat; import static org.junit.Assert.assertTrue; import static org.onap.so.logger.HttpHeadersConstants.ONAP_REQUEST_ID; import static org.onap.so.logger.HttpHeadersConstants.REQUESTOR_ID; +import static org.onap.so.logger.HttpHeadersConstants.TRANSACTION_ID; import static org.onap.so.logger.MdcConstants.CLIENT_ID; import static org.onap.so.logger.MdcConstants.ENDTIME; import static org.onap.so.logger.MdcConstants.INVOCATION_ID; @@ -41,7 +44,6 @@ import static org.onap.so.logger.MdcConstants.RESPONSECODE; import static org.onap.so.logger.MdcConstants.RESPONSEDESC; import static org.onap.so.logger.MdcConstants.SERVICE_NAME; import static org.onap.so.logger.MdcConstants.STATUSCODE; -import static org.onap.so.logger.HttpHeadersConstants.TRANSACTION_ID; import java.io.File; import java.io.IOException; import java.net.MalformedURLException; @@ -57,12 +59,17 @@ import org.junit.Before; import org.junit.Test; import org.mockito.Mockito; import org.onap.logging.ref.slf4j.ONAPLogConstants; +import org.onap.so.apihandlerinfra.exceptions.ContactCamundaException; +import org.onap.so.apihandlerinfra.exceptions.RequestDbFailureException; import org.onap.so.db.catalog.beans.Service; import org.onap.so.db.catalog.beans.ServiceRecipe; import org.onap.so.db.request.beans.InfraActiveRequests; import org.onap.so.logger.HttpHeadersConstants; import org.onap.so.serviceinstancebeans.CloudConfiguration; +import org.onap.so.serviceinstancebeans.ModelInfo; +import org.onap.so.serviceinstancebeans.RequestDetails; import org.onap.so.serviceinstancebeans.RequestError; +import org.onap.so.serviceinstancebeans.RequestInfo; import org.onap.so.serviceinstancebeans.RequestParameters; import org.onap.so.serviceinstancebeans.RequestReferences; import org.onap.so.serviceinstancebeans.ServiceInstancesRequest; @@ -75,7 +82,6 @@ import org.springframework.http.HttpMethod; import org.springframework.http.ResponseEntity; import org.springframework.util.ResourceUtils; import org.springframework.web.util.UriComponentsBuilder; -import com.fasterxml.jackson.annotation.JsonInclude.Include; import com.fasterxml.jackson.core.JsonParseException; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.DeserializationFeature; @@ -93,6 +99,9 @@ public class ServiceInstancesTest extends BaseTest { @Autowired private ServiceInstances servInstances; + @Autowired + private RequestHandlerUtils requestHandlerUtils; + @Value("${wiremock.server.port}") private String wiremockPort; @@ -2748,5 +2757,194 @@ public class ServiceInstancesTest extends BaseTest { "No valid modelCustomizationId for networkResourceCustomization lookup is specified"); } + @Test + public void setServiceTypeTestALaCarte() throws JsonProcessingException { + String requestScope = ModelType.service.toString(); + Boolean aLaCarteFlag = true; + ServiceInstancesRequest sir = new ServiceInstancesRequest(); + RequestDetails requestDetails = new RequestDetails(); + RequestInfo requestInfo = new RequestInfo(); + requestInfo.setSource("VID"); + requestDetails.setRequestInfo(requestInfo); + sir.setRequestDetails(requestDetails); + Service defaultService = new Service(); + defaultService.setServiceType("testServiceTypeALaCarte"); + + wireMockServer.stubFor(get(urlMatching(".*/service/search/.*")) + .willReturn(aResponse().withHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON) + .withBody(mapper.writeValueAsString(defaultService)).withStatus(HttpStatus.SC_OK))); + + String serviceType = requestHandlerUtils.getServiceType(requestScope, sir, aLaCarteFlag); + assertEquals(serviceType, "testServiceTypeALaCarte"); + } + + @Test + public void setServiceTypeTest() throws JsonProcessingException { + String requestScope = ModelType.service.toString(); + Boolean aLaCarteFlag = false; + ServiceInstancesRequest sir = new ServiceInstancesRequest(); + RequestDetails requestDetails = new RequestDetails(); + RequestInfo requestInfo = new RequestInfo(); + ModelInfo modelInfo = new ModelInfo(); + modelInfo.setModelVersionId("0dd91181-49da-446b-b839-cd959a96f04a"); + requestInfo.setSource("VID"); + requestDetails.setModelInfo(modelInfo); + requestDetails.setRequestInfo(requestInfo); + sir.setRequestDetails(requestDetails); + Service defaultService = new Service(); + defaultService.setServiceType("testServiceType"); + + wireMockServer.stubFor(get(urlMatching(".*/service/0dd91181-49da-446b-b839-cd959a96f04a")) + .willReturn(aResponse().withHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON) + .withBody(mapper.writeValueAsString(defaultService)).withStatus(HttpStatus.SC_OK))); + + String serviceType = requestHandlerUtils.getServiceType(requestScope, sir, aLaCarteFlag); + assertEquals(serviceType, "testServiceType"); + } + + @Test + public void setServiceTypeTestDefault() throws JsonProcessingException { + String requestScope = ModelType.service.toString(); + Boolean aLaCarteFlag = false; + ServiceInstancesRequest sir = new ServiceInstancesRequest(); + RequestDetails requestDetails = new RequestDetails(); + RequestInfo requestInfo = new RequestInfo(); + ModelInfo modelInfo = new ModelInfo(); + modelInfo.setModelVersionId("0dd91181-49da-446b-b839-cd959a96f04a"); + requestInfo.setSource("VID"); + requestDetails.setModelInfo(modelInfo); + requestDetails.setRequestInfo(requestInfo); + sir.setRequestDetails(requestDetails); + Service defaultService = new Service(); + defaultService.setServiceType("testServiceType"); + + wireMockServer.stubFor(get(urlMatching(".*/service/0dd91181-49da-446b-b839-cd959a96f04a")) + .willReturn(aResponse().withHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON) + .withStatus(HttpStatus.SC_NOT_FOUND))); + wireMockServer.stubFor(get(urlMatching(".*/service/search/.*")) + .willReturn(aResponse().withHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON) + .withBody(mapper.writeValueAsString(defaultService)).withStatus(HttpStatus.SC_OK))); + + String serviceType = requestHandlerUtils.getServiceType(requestScope, sir, aLaCarteFlag); + assertEquals(serviceType, "testServiceType"); + } + + @Test + public void setServiceTypeTestNetwork() throws JsonProcessingException { + String requestScope = ModelType.network.toString(); + Boolean aLaCarteFlag = null; + ServiceInstancesRequest sir = new ServiceInstancesRequest(); + RequestDetails requestDetails = new RequestDetails(); + RequestInfo requestInfo = new RequestInfo(); + ModelInfo modelInfo = new ModelInfo(); + modelInfo.setModelName("networkModelName"); + requestInfo.setSource("VID"); + requestDetails.setModelInfo(modelInfo); + requestDetails.setRequestInfo(requestInfo); + sir.setRequestDetails(requestDetails); + + String serviceType = requestHandlerUtils.getServiceType(requestScope, sir, aLaCarteFlag); + assertEquals(serviceType, "networkModelName"); + } + + @Test + public void setServiceInstanceIdInstanceGroupTest() throws JsonParseException, JsonMappingException, IOException { + String requestScope = "instanceGroup"; + ServiceInstancesRequest sir = + mapper.readValue(inputStream("/CreateInstanceGroup.json"), ServiceInstancesRequest.class); + assertEquals("ddcbbf3d-f2c1-4ca0-8852-76a807285efc", + requestHandlerUtils.setServiceInstanceId(requestScope, sir)); + } + + @Test + public void setServiceInstanceIdTest() { + String requestScope = "vnf"; + ServiceInstancesRequest sir = new ServiceInstancesRequest(); + sir.setServiceInstanceId("f0a35706-efc4-4e27-80ea-a995d7a2a40f"); + assertEquals("f0a35706-efc4-4e27-80ea-a995d7a2a40f", + requestHandlerUtils.setServiceInstanceId(requestScope, sir)); + } + + @Test + public void setServiceInstanceIdReturnNullTest() { + String requestScope = "vnf"; + ServiceInstancesRequest sir = new ServiceInstancesRequest(); + assertNull(requestHandlerUtils.setServiceInstanceId(requestScope, sir)); + } + + @Test + public void camundaHistoryCheckTest() throws ContactCamundaException, RequestDbFailureException { + wireMockServer.stubFor(get( + ("/sobpmnengine/history/process-instance?variables=mso-request-id_eq_f0a35706-efc4-4e27-80ea-a995d7a2a40f")) + .willReturn(aResponse().withHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON) + .withBodyFile("Camunda/HistoryCheckResponse.json") + .withStatus(org.apache.http.HttpStatus.SC_OK))); + + InfraActiveRequests duplicateRecord = new InfraActiveRequests(); + duplicateRecord.setRequestId("f0a35706-efc4-4e27-80ea-a995d7a2a40f"); + boolean inProgress = false; + inProgress = requestHandlerUtils.camundaHistoryCheck(duplicateRecord, null); + assertTrue(inProgress); + } + + @Test + public void camundaHistoryCheckNoneFoundTest() throws ContactCamundaException, RequestDbFailureException { + wireMockServer.stubFor(get( + ("/sobpmnengine/history/process-instance?variables=mso-request-id_eq_f0a35706-efc4-4e27-80ea-a995d7a2a40f")) + .willReturn(aResponse().withHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON) + .withBody("[]").withStatus(org.apache.http.HttpStatus.SC_OK))); + InfraActiveRequests duplicateRecord = new InfraActiveRequests(); + duplicateRecord.setRequestId("f0a35706-efc4-4e27-80ea-a995d7a2a40f"); + boolean inProgress = false; + inProgress = requestHandlerUtils.camundaHistoryCheck(duplicateRecord, null); + assertFalse(inProgress); + } + + @Test + public void camundaHistoryCheckNotInProgressTest() throws ContactCamundaException, RequestDbFailureException { + wireMockServer.stubFor(get( + ("/sobpmnengine/history/process-instance?variables=mso-request-id_eq_f0a35706-efc4-4e27-80ea-a995d7a2a40f")) + .willReturn(aResponse().withHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON) + .withBodyFile("Camunda/HistoryCheckResponseCompleted.json") + .withStatus(org.apache.http.HttpStatus.SC_OK))); + + InfraActiveRequests duplicateRecord = new InfraActiveRequests(); + duplicateRecord.setRequestId("f0a35706-efc4-4e27-80ea-a995d7a2a40f"); + boolean inProgress = false; + inProgress = requestHandlerUtils.camundaHistoryCheck(duplicateRecord, null); + assertFalse(inProgress); + } + + @Test + public void setCamundaHeadersTest() throws ContactCamundaException, RequestDbFailureException { + String encryptedAuth = "015E7ACF706C6BBF85F2079378BDD2896E226E09D13DC2784BA309E27D59AB9FAD3A5E039DF0BB8408"; // user:password + String key = "07a7159d3bf51a0e53be7a8f89699be7"; + HttpHeaders headers = requestHandlerUtils.setCamundaHeaders(encryptedAuth, key); + List<org.springframework.http.MediaType> acceptedType = headers.getAccept(); + String expectedAcceptedType = "application/json"; + assertEquals(expectedAcceptedType, acceptedType.get(0).toString()); + String basicAuth = headers.getFirst(HttpHeaders.AUTHORIZATION); + String expectedBasicAuth = "Basic dXNlcjpwYXNzd29yZA=="; + assertEquals(expectedBasicAuth, basicAuth); + } + + @Test + public void handleReplaceInstance_Test() throws JsonParseException, JsonMappingException, IOException { + String replaceVfModule = inputStream("/ReplaceVfModule.json"); + ObjectMapper mapper = new ObjectMapper(); + ServiceInstancesRequest sir = mapper.readValue(replaceVfModule, ServiceInstancesRequest.class); + Actions action = servInstances.handleReplaceInstance(Action.replaceInstance, sir); + assertEquals(Action.replaceInstance, action); + } + + @Test + public void handleReplaceInstance_retainAssignments_Test() + throws JsonParseException, JsonMappingException, IOException { + String replaceVfModule = inputStream("/ReplaceVfModuleRetainAssignments.json"); + ObjectMapper mapper = new ObjectMapper(); + ServiceInstancesRequest sir = mapper.readValue(replaceVfModule, ServiceInstancesRequest.class); + Actions action = servInstances.handleReplaceInstance(Action.replaceInstance, sir); + assertEquals(Action.replaceInstanceRetainAssignments, action); + } } diff --git a/mso-api-handlers/mso-api-handler-infra/src/test/resources/ServiceInstanceTest/ReplaceVfModuleRetainAssignments.json b/mso-api-handlers/mso-api-handler-infra/src/test/resources/ServiceInstanceTest/ReplaceVfModuleRetainAssignments.json new file mode 100644 index 0000000000..166f7ccce8 --- /dev/null +++ b/mso-api-handlers/mso-api-handler-infra/src/test/resources/ServiceInstanceTest/ReplaceVfModuleRetainAssignments.json @@ -0,0 +1,33 @@ +{ + "requestDetails": { + "requestInfo": { + "source": "VID", + "requestorId": "xxxxxx", + "instanceName": "testService60" + }, + "requestParameters": { + "aLaCarte": true, + "autoBuildVfModules": false, + "retainAssignments": true, + "subscriptionServiceType": "test" + }, + "cloudConfiguration": { + "lcpCloudRegionId": "mdt1", + "tenantId": "88a6ca3ee0394ade9403f075db23167e" + }, + "modelInfo":{ + "modelInvariantId": "f7ce78bb-423b-11e7-93f8-0050569a7968", + "modelVersion":"2", + "modelVersionId":"78ca26d0-246d-11e7-93ae-92361f002671", + "modelType":"vfModule", + "modelName":"serviceModel", + "modelCustomizationId": "a7f1d08e-b02d-11e6-80f5-76304dec7eb7" + }, + "subscriberInfo": { + "globalSubscriberId": "MSO_1610_dev", + "subscriberName": "MSO_1610_dev" + } + } +} + +
\ No newline at end of file diff --git a/mso-catalog-db/src/main/java/org/onap/so/db/catalog/data/repository/RainyDayHandlerStatusRepository.java b/mso-catalog-db/src/main/java/org/onap/so/db/catalog/data/repository/RainyDayHandlerStatusRepository.java index 91ae10236b..6819657b78 100644 --- a/mso-catalog-db/src/main/java/org/onap/so/db/catalog/data/repository/RainyDayHandlerStatusRepository.java +++ b/mso-catalog-db/src/main/java/org/onap/so/db/catalog/data/repository/RainyDayHandlerStatusRepository.java @@ -32,7 +32,7 @@ public interface RainyDayHandlerStatusRepository extends JpaRepository<RainyDayH @Query(value = "SELECT * FROM rainy_day_handler_macro WHERE (FLOW_NAME = :flowName ) AND SERVICE_TYPE IN (:serviceType ,'*') " + " AND VNF_TYPE IN ( :vnfType , '*') AND ERROR_CODE IN (:errorCode ,'*') AND WORK_STEP IN (:workStep , '*' ) " + " AND ( :errorMessage REGEXP rainy_day_handler_macro.REG_EX_ERROR_MESSAGE OR REG_EX_ERROR_MESSAGE = '*') " - + " ORDER BY CASE WHEN 'asdf' REGEXP REG_EX_ERROR_MESSAGE THEN 0 WHEN ERROR_CODE != '*' THEN 1 WHEN VNF_TYPE != '*' THEN 2 WHEN SERVICE_TYPE != '*' THEN 3 ELSE 4 END LIMIT 1;", + + " ORDER BY CASE WHEN :errorMessage REGEXP REG_EX_ERROR_MESSAGE THEN 0 WHEN ERROR_CODE != '*' THEN 1 WHEN VNF_TYPE != '*' THEN 2 WHEN SERVICE_TYPE != '*' THEN 3 ELSE 4 END LIMIT 1;", nativeQuery = true) RainyDayHandlerStatus findRainyDayHandler(@Param("flowName") String flowName, @Param("serviceType") String serviceType, @Param("vnfType") String vnfType, |