From 776b69ebd28440f84a890b1d4170af77ca5974ff Mon Sep 17 00:00:00 2001 From: Saravanan A Date: Fri, 5 Apr 2019 20:45:44 +0530 Subject: Code changes done for OOF SON use case Added a new control loop for SON ANR changes Introducing control loop response flow using DCAE_CL_RSP topic Change-Id: I81d0e92ce2f5c489596ad70d7b523cab0d8436ce Issue-ID: POLICY-1463 Signed-off-by: Saravanan A Signed-off-by: Pamela Dragosh --- .../actor/sdnr/SdnrActorServiceProvider.java | 49 ++- .../actor/sdnr/SdnrActorServiceProviderTest.java | 38 +- .../eventmanager/ControlLoopOperationManager.java | 23 +- .../src/main/feature/bin/create-cl-usecases | 9 + .../src/main/feature/bin/push-policies-usecases | 13 + .../feature/config/usecases-controller.properties | 7 +- .../policy/controlloop/ControlLoopResponse.java | 142 +++++++ .../controlloop/ControlLoopResponseTest.java | 65 +++ .../sdnr/src/main/resources/definitions.yaml | 1 + .../controlloop/compiler/ControlLoopCompiler.java | 2 +- .../controlloop/policy/ControlLoopPolicyTest.java | 5 + .../v2.0.0/policy_ONAP_UseCase_vSONH.yaml | 39 ++ .../config/__artifactId__-controller.properties | 8 +- .../config/__artifactId__-controller.rest.json | 6 +- .../src/main/config/vSONH.anr.onset | 18 + .../src/main/config/vSONH.anr.sdnr.success | 23 ++ .../archetype-resources/src/main/config/vSONH.yml | 38 ++ .../META-INF/maven/archetype-metadata.xml | 18 + .../main/resources/__closedLoopControlName__.drl | 4 + .../policy/template/demo/VsonhControlLoopTest.java | 443 +++++++++++++++++++++ .../resources/yaml/policy_ControlLoop_vSONH.yaml | 38 ++ 21 files changed, 969 insertions(+), 20 deletions(-) create mode 100644 controlloop/common/model-impl/events/src/main/java/org/onap/policy/controlloop/ControlLoopResponse.java create mode 100644 controlloop/common/model-impl/events/src/test/java/org/onap/policy/controlloop/ControlLoopResponseTest.java create mode 100644 controlloop/common/policy-yaml/src/test/resources/v2.0.0/policy_ONAP_UseCase_vSONH.yaml create mode 100644 controlloop/templates/archetype-cl-amsterdam/src/main/resources/archetype-resources/src/main/config/vSONH.anr.onset create mode 100644 controlloop/templates/archetype-cl-amsterdam/src/main/resources/archetype-resources/src/main/config/vSONH.anr.sdnr.success create mode 100644 controlloop/templates/archetype-cl-amsterdam/src/main/resources/archetype-resources/src/main/config/vSONH.yml create mode 100644 controlloop/templates/template.demo/src/test/java/org/onap/policy/template/demo/VsonhControlLoopTest.java create mode 100644 controlloop/templates/template.demo/src/test/resources/yaml/policy_ControlLoop_vSONH.yaml diff --git a/controlloop/common/actors/actor.sdnr/src/main/java/org/onap/policy/controlloop/actor/sdnr/SdnrActorServiceProvider.java b/controlloop/common/actors/actor.sdnr/src/main/java/org/onap/policy/controlloop/actor/sdnr/SdnrActorServiceProvider.java index 406870208..d6ec1d219 100644 --- a/controlloop/common/actors/actor.sdnr/src/main/java/org/onap/policy/controlloop/actor/sdnr/SdnrActorServiceProvider.java +++ b/controlloop/common/actors/actor.sdnr/src/main/java/org/onap/policy/controlloop/actor/sdnr/SdnrActorServiceProvider.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. @@ -27,6 +27,7 @@ import java.util.Collections; import java.util.List; import org.onap.policy.controlloop.ControlLoopOperation; +import org.onap.policy.controlloop.ControlLoopResponse; import org.onap.policy.controlloop.VirtualControlLoopEvent; import org.onap.policy.controlloop.actorserviceprovider.spi.Actor; import org.onap.policy.controlloop.policy.Policy; @@ -68,6 +69,7 @@ public class SdnrActorServiceProvider implements Actor { // Strings for recipes private static final String RECIPE_MODIFY = "ModifyConfig"; + private static final String RECIPE_MODIFY_ANR = "ModifyConfigANR"; /* To be used in future releases when pci ModifyConfig is used */ private static final String SDNR_REQUEST_PARAMS = "request-parameters"; @@ -102,7 +104,7 @@ public class SdnrActorServiceProvider implements Actor { /** * Constructs an SDNR request conforming to the pci API. The actual request is * constructed and then placed in a wrapper object used to send through DMAAP. - * + * * @param onset * the event that is reporting the alert for policy to perform an * action @@ -160,11 +162,11 @@ public class SdnrActorServiceProvider implements Actor { /** * Parses the operation attempt using the subRequestId of SDNR response. - * + * * @param subRequestId * the sub id used to send to SDNR, Policy sets this using the * operation attempt - * + * * @return the current operation attempt */ public static Integer parseOperationAttempt(String subRequestId) { @@ -182,11 +184,11 @@ public class SdnrActorServiceProvider implements Actor { * Processes the SDNR pci response sent from SDNR. Determines if the SDNR * operation was successful/unsuccessful and maps this to the corresponding * Policy result. - * + * * @param dmaapResponse * the dmaap wrapper message that contains the actual SDNR reponse * inside the body field - * + * * @return an key-value pair that contains the Policy result and SDNR response * message */ @@ -252,4 +254,37 @@ public class SdnrActorServiceProvider implements Actor { } return new SdnrActorServiceProvider.Pair<>(result, message); } + + /** + * Converts the SDNR response to ControlLoopResponse object. + * + * @param dmaapResponse + * the dmaap wrapper message that contains the actual SDNR reponse + * inside the body field + * + * @return a ControlLoopResponse object to send to DCAE_CL_RSP topic + */ + public static ControlLoopResponse getControlLoopResponse(PciResponseWrapper dmaapResponse, + VirtualControlLoopEvent event) { + + logger.info("SDNR getClosedLoopResponse called : {} {}", dmaapResponse, event); + + /* The actual SDNR response is inside the wrapper's body field. */ + PciResponse sdnrResponse = dmaapResponse.getBody(); + + /* The ControlLoop response determined from the SDNR Response and input event. */ + ControlLoopResponse clRsp = new ControlLoopResponse(); + clRsp.setPayload(sdnrResponse.getPayload()); + clRsp.setFrom("SDNR"); + clRsp.setTarget("DCAE"); + clRsp.setClosedLoopControlName(event.getClosedLoopControlName()); + clRsp.setPolicyName(event.getPolicyName()); + clRsp.setPolicyVersion(event.getPolicyVersion()); + clRsp.setRequestId(event.getRequestId()); + clRsp.setVersion(event.getVersion()); + logger.info("SDNR getClosedLoopResponse clRsp : {}", clRsp); + + return clRsp; + } + } diff --git a/controlloop/common/actors/actor.sdnr/src/test/java/org/onap/policy/controlloop/actor/sdnr/SdnrActorServiceProviderTest.java b/controlloop/common/actors/actor.sdnr/src/test/java/org/onap/policy/controlloop/actor/sdnr/SdnrActorServiceProviderTest.java index 030bb9ec4..ac302565c 100644 --- a/controlloop/common/actors/actor.sdnr/src/test/java/org/onap/policy/controlloop/actor/sdnr/SdnrActorServiceProviderTest.java +++ b/controlloop/common/actors/actor.sdnr/src/test/java/org/onap/policy/controlloop/actor/sdnr/SdnrActorServiceProviderTest.java @@ -6,9 +6,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. @@ -22,28 +22,24 @@ package org.onap.policy.controlloop.actor.sdnr; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; import java.time.Instant; import java.util.HashMap; import java.util.UUID; -import org.junit.AfterClass; -import org.junit.BeforeClass; import org.junit.Test; -import org.onap.policy.common.endpoints.http.server.HttpServletServer; import org.onap.policy.controlloop.ControlLoopEventStatus; import org.onap.policy.controlloop.ControlLoopOperation; +import org.onap.policy.controlloop.ControlLoopResponse; import org.onap.policy.controlloop.ControlLoopTargetType; import org.onap.policy.controlloop.VirtualControlLoopEvent; import org.onap.policy.controlloop.policy.Policy; import org.onap.policy.controlloop.policy.Target; import org.onap.policy.controlloop.policy.TargetType; -import org.onap.policy.drools.system.PolicyEngine; import org.onap.policy.sdnr.PciRequest; import org.onap.policy.sdnr.PciResponse; +import org.onap.policy.sdnr.PciResponseWrapper; import org.onap.policy.sdnr.util.Serialization; -import org.onap.policy.simulators.Util; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -92,6 +88,32 @@ public class SdnrActorServiceProviderTest { policy.setPayload(null); policy.setRetry(2); policy.setTimeout(300); + + } + + @Test + public void getControlLoopResponseTest() { + PciRequest sdnrRequest; + sdnrRequest = SdnrActorServiceProvider.constructRequest(onsetEvent, operation, policy).getBody(); + PciResponse sdnrResponse = new PciResponse(sdnrRequest); + sdnrResponse.getStatus().setCode(200); + sdnrResponse.getStatus().setValue("SDNR success"); + sdnrResponse.setPayload("sdnr payload "); + /* Print out request as json to make sure serialization works */ + String jsonResponse = Serialization.gsonPretty.toJson(sdnrResponse); + logger.info(jsonResponse); + PciResponseWrapper pciResponseWrapper = new PciResponseWrapper(); + pciResponseWrapper.setBody(sdnrResponse); + + ControlLoopResponse clRsp = SdnrActorServiceProvider.getControlLoopResponse(pciResponseWrapper, onsetEvent); + assertEquals(clRsp.getClosedLoopControlName(), onsetEvent.getClosedLoopControlName()); + assertEquals(clRsp.getRequestId(), onsetEvent.getRequestId()); + assertEquals(clRsp.getPolicyName(), onsetEvent.getPolicyName()); + assertEquals(clRsp.getPolicyVersion(), onsetEvent.getPolicyVersion()); + assertEquals(clRsp.getVersion(), onsetEvent.getVersion()); + assertEquals(clRsp.getFrom(), "SDNR"); + assertEquals(clRsp.getTarget(), "DCAE"); + assertEquals(clRsp.getPayload(), sdnrResponse.getPayload()); } @Test diff --git a/controlloop/common/eventmanager/src/main/java/org/onap/policy/controlloop/eventmanager/ControlLoopOperationManager.java b/controlloop/common/eventmanager/src/main/java/org/onap/policy/controlloop/eventmanager/ControlLoopOperationManager.java index 1234a8ae1..8b7b15909 100644 --- a/controlloop/common/eventmanager/src/main/java/org/onap/policy/controlloop/eventmanager/ControlLoopOperationManager.java +++ b/controlloop/common/eventmanager/src/main/java/org/onap/policy/controlloop/eventmanager/ControlLoopOperationManager.java @@ -39,6 +39,7 @@ import org.onap.policy.appclcm.LcmResponseWrapper; import org.onap.policy.controlloop.ControlLoopEvent; import org.onap.policy.controlloop.ControlLoopException; import org.onap.policy.controlloop.ControlLoopOperation; +import org.onap.policy.controlloop.ControlLoopResponse; import org.onap.policy.controlloop.VirtualControlLoopEvent; import org.onap.policy.controlloop.actor.appc.AppcActorServiceProvider; import org.onap.policy.controlloop.actor.appclcm.AppcLcmActorServiceProvider; @@ -299,7 +300,7 @@ public class ControlLoopOperationManager implements Serializable { return operationRequest; case "SDNR": /* - * If the recipe is ModifyConfig, a SDNR request is constructed. + * If the recipe is ModifyConfig or ModifyConfigANR, a SDNR request is constructed. */ this.currentOperation = operation; this.operationRequest = SdnrActorServiceProvider.constructRequest((VirtualControlLoopEvent) onset, @@ -985,4 +986,24 @@ public class ControlLoopOperationManager implements Serializable { // this.currentOperation = null; } + + /** + * Construct a ControlLoopResponse object from actor response and input event. + * + * @param response the response from actor + * @param event the input event + * + * @return a ControlLoopResponse + */ + public ControlLoopResponse getControlLoopResponse(Object response, VirtualControlLoopEvent event) { + if (response instanceof PciResponseWrapper) { + // + // Cast SDNR response and handle it + // + return SdnrActorServiceProvider.getControlLoopResponse((PciResponseWrapper) response, event); + } else { + return null; + } + } + } diff --git a/controlloop/common/feature-controlloop-management/src/main/feature/bin/create-cl-usecases b/controlloop/common/feature-controlloop-management/src/main/feature/bin/create-cl-usecases index 99843aa10..44fde3245 100644 --- a/controlloop/common/feature-controlloop-management/src/main/feature/bin/create-cl-usecases +++ b/controlloop/common/feature-controlloop-management/src/main/feature/bin/create-cl-usecases @@ -60,6 +60,12 @@ VPCI_CONTROL_LOOP_NAME="ControlLoop-vPCI-fb41f388-a5f2-11e8-98d0-529269fb1459" VPCI_POLICY_NAME="vpci" VPCI_CONTROL_LOOP_YAML="controlLoop%3A%0D%0A++version%3A+3.0.0%0D%0A++controlLoopName%3A+ControlLoop-vPCI-fb41f388-a5f2-11e8-98d0-529269fb1459%0D%0A++trigger_policy%3A+unique-policy-id-123-modifyconfig%0D%0A++timeout%3A+1200%0D%0A++abatement%3A+false%0D%0A+%0D%0Apolicies%3A%0D%0A++-+id%3A+unique-policy-id-123-modifyconfig%0D%0A++++name%3A+modify+PCI+config%0D%0A++++description%3A%0D%0A++++actor%3A+SDNR%0D%0A++++recipe%3A+ModifyConfig%0D%0A++++target%3A%0D%0A++++++%23+These+fields+are+not+used%0D%0A++++++resourceID%3A+Eace933104d443b496b8.nodes.heat.vpg%0D%0A++++++type%3A+VNF%0D%0A++++retry%3A+0%0D%0A++++timeout%3A+300%0D%0A++++success%3A+final_success%0D%0A++++failure%3A+final_failure%0D%0A++++failure_timeout%3A+final_failure_timeout%0D%0A++++failure_retries%3A+final_failure_retries%0D%0A++++failure_exception%3A+final_failure_exception%0D%0A++++failure_guard%3A+final_failure_guard" +# vSONH Policy Parameters +VSONH_CONTROL_LOOP_NAME="ControlLoop-vSONH-7d4baf04-8875-4d1f-946d-06b874048b61" +VSONH_POLICY_NAME="vsonh" +VSONH_CONTROL_LOOP_YAML="controlLoop%3A%0D%0A++version%3A+4.0.0%0D%0A++controlLoopName%3A+ControlLoop-vSONH-7d4baf04-8875-4d1f-946d-06b874048b61%0D%0A++trigger_policy%3A+unique-policy-id-456-modifyconfig%0D%0A++timeout%3A+1200%0D%0A++abatement%3A+false%0D%0A+%0D%0Apolicies%3A%0D%0A++-+id%3A+unique-policy-id-456-modifyconfig%0D%0A++++name%3A+modify+ANR+config%0D%0A++++description%3A%0D%0A++++actor%3A+SDNR%0D%0A++++recipe%3A+ModifyConfigANR%0D%0A++++target%3A%0D%0A++++++%23+These+fields+are+not+used%0D%0A++++++resourceID%3A+Eace933104d443b496b8.nodes.heat.vpg%0D%0A++++++type%3A+VNF%0D%0A++++retry%3A+0%0D%0A++++timeout%3A+300%0D%0A++++success%3A+final_success%0D%0A++++failure%3A+final_failure%0D%0A++++failure_timeout%3A+final_failure_timeout%0D%0A++++failure_retries%3A+final_failure_retries%0D%0A++++failure_exception%3A+final_failure_exception%0D%0A++++failure_guard%3A+final_failure_guard" + + # CCVPN Policy Parameters CCVPN_CONTROL_LOOP_NAME="ControlLoop-CCVPN-2179b738-fd36-4843-a71a-a8c24c70c66b" CCVPN_POLICY_NAME="ccvpn" @@ -310,6 +316,9 @@ mvn archetype:generate \ -DvpciClosedLoopControlName="${VPCI_CONTROL_LOOP_NAME}" \ -DvpciPolicyName="${VPCI_POLICY_NAME}" \ -DvpciControlLoopYaml="${VPCI_CONTROL_LOOP_YAML}" \ + -DvsonhClosedLoopControlName="${VSONH_CONTROL_LOOP_NAME}" \ + -DvsonhPolicyName="${VSONH_POLICY_NAME}" \ + -DvsonhControlLoopYaml="${VSONH_CONTROL_LOOP_YAML}" \ -DccvpnClosedLoopControlName="${CCVPN_CONTROL_LOOP_NAME}" \ -DccvpnPolicyName="${CCVPN_POLICY_NAME}" \ -DccvpnControlLoopYaml="${CCVPN_CONTROL_LOOP_YAML}" \ diff --git a/controlloop/common/feature-controlloop-management/src/main/feature/bin/push-policies-usecases b/controlloop/common/feature-controlloop-management/src/main/feature/bin/push-policies-usecases index 307d7825a..69e221da9 100644 --- a/controlloop/common/feature-controlloop-management/src/main/feature/bin/push-policies-usecases +++ b/controlloop/common/feature-controlloop-management/src/main/feature/bin/push-policies-usecases @@ -124,6 +124,19 @@ curl -k --silent --user @1b3rt:31nst31n -X PUT --header 'Content-Type: text/plai "policyVersion": "1.2.0" }' "https://localhost:9696/policy/pdp/engine/topics/sources/ueb/${BRMSGW_TOPIC}/events" | python -m json.tool +sleep 2 + +echo +echo "Inserting vSONH Policy..." +curl -k --silent --user @1b3rt:31nst31n -X PUT --header 'Content-Type: text/plain' -d '{ + "closedLoopControlName": "ControlLoop-vSONH-7d4baf04-8875-4d1f-946d-06b874048b61", + "controlLoopYaml": "controlLoop%3A%0D%0A++version%3A+3.0.0%0D%0A++controlLoopName%3A+ControlLoop-vSONH-7d4baf04-8875-4d1f-946d-06b874048b61%0D%0A++trigger_policy%3A+unique-policy-id-456-modifyconfig%0D%0A++timeout%3A+1200%0D%0A++abatement%3A+false%0D%0A+%0D%0Apolicies%3A%0D%0A++-+id%3A+unique-policy-id-456-modifyconfig%0D%0A++++name%3A+modify+ANR+config%0D%0A++++description%3A%0D%0A++++actor%3A+SDNR%0D%0A++++recipe%3A+ModifyConfigANR%0D%0A++++target%3A%0D%0A++++++%23+These+fields+are+not+used%0D%0A++++++resourceID%3A+Eace933104d443b496b8.nodes.heat.vpg%0D%0A++++++type%3A+VNF%0D%0A++++retry%3A+0%0D%0A++++timeout%3A+300%0D%0A++++success%3A+final_success%0D%0A++++failure%3A+final_failure%0D%0A++++failure_timeout%3A+final_failure_timeout%0D%0A++++failure_retries%3A+final_failure_retries%0D%0A++++failure_exception%3A+final_failure_exception%0D%0A++++failure_guard%3A+final_failure_guard", + "policyName": "vsonh", + "policyScope": "DCAE", + "policyVersion": "1.2.0" +}' "https://localhost:9696/policy/pdp/engine/topics/sources/ueb/${BRMSGW_TOPIC}/events" | python -m json.tool + + sleep 2 echo diff --git a/controlloop/common/feature-controlloop-usecases/src/main/feature/config/usecases-controller.properties b/controlloop/common/feature-controlloop-usecases/src/main/feature/config/usecases-controller.properties index e54289ec6..3035e1061 100644 --- a/controlloop/common/feature-controlloop-usecases/src/main/feature/config/usecases-controller.properties +++ b/controlloop/common/feature-controlloop-usecases/src/main/feature/config/usecases-controller.properties @@ -48,7 +48,7 @@ dmaap.source.topics.APPC-LCM-WRITE.events.org.onap.policy.appclcm.LcmResponseWra dmaap.source.topics.APPC-LCM-WRITE.events.custom.gson=org.onap.policy.appclcm.util.Serialization,gson dmaap.source.topics.APPC-LCM-WRITE.https=true -dmaap.sink.topics=APPC-CL,APPC-LCM-READ,POLICY-CL-MGT,SDNR-CL +dmaap.sink.topics=APPC-CL,APPC-LCM-READ,POLICY-CL-MGT,SDNR-CL,DCAE_CL_RSP dmaap.sink.topics.APPC-CL.servers=${env:DMAAP_SERVERS} dmaap.sink.topics.APPC-CL.events=org.onap.policy.appc.Request @@ -74,6 +74,11 @@ dmaap.sink.topics.SDNR-CL.events=org.onap.policy.sdnr.PciRequestWrapper dmaap.sink.topics.SDNR-CL.events.custom.gson=org.onap.policy.sdnr.util.Serialization,gson dmaap.sink.topics.SDNR-CL.https=true +dmaap.sink.topics.DCAE_CL_RSP.servers=${env:DMAAP_SERVERS} +dmaap.sink.topics.DCAE_CL_RSP.events=org.onap.policy.controlloop.ControlLoopResponse +dmaap.sink.topics.DCAE_CL_RSP.events.custom.gson=org.onap.policy.controlloop.util.Serialization,gsonPretty +dmaap.sink.topics.DCAE_CL_RSP.https=true + dmaap.source.topics.SDNR-CL-RSP.servers=${env:DMAAP_SERVERS} dmaap.source.topics.SDNR-CL-RSP.events=org.onap.policy.sdnr.PciResponseWrapper dmaap.source.topics.SDNR-CL-RSP.events.org.onap.policy.sdnr.PciResponseWrapper.filter=[?($.type == 'response')] diff --git a/controlloop/common/model-impl/events/src/main/java/org/onap/policy/controlloop/ControlLoopResponse.java b/controlloop/common/model-impl/events/src/main/java/org/onap/policy/controlloop/ControlLoopResponse.java new file mode 100644 index 000000000..483aaacfa --- /dev/null +++ b/controlloop/common/model-impl/events/src/main/java/org/onap/policy/controlloop/ControlLoopResponse.java @@ -0,0 +1,142 @@ +/*- + * ============LICENSE_START======================================================= + * controlloop + * ================================================================================ + * Copyright (C) 2019 Wipro Limited 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.onap.policy.controlloop; + +import com.google.gson.annotations.SerializedName; + +import java.io.Serializable; +import java.util.UUID; + +public class ControlLoopResponse implements Serializable { + + private static final long serialVersionUID = 2391252138583119195L; + + @SerializedName("closedLoopControlName") + private String closedLoopControlName; + + @SerializedName("version") + private String version = "1.0.0"; + + @SerializedName("requestID") + private UUID requestId; + + @SerializedName("target") + private String target; + + @SerializedName("from") + private String from; + + @SerializedName("policyName") + private String policyName; + + @SerializedName("policyVersion") + private String policyVersion; + + @SerializedName("payload") + private String payload; + + public ControlLoopResponse() { + + } + + /** + * Construct an instace from an existing instance. + * + * @param response + * the existing instance + */ + public ControlLoopResponse(ControlLoopResponse response) { + if (response == null) { + return; + } + this.closedLoopControlName = response.closedLoopControlName; + this.requestId = response.requestId; + this.target = response.target; + this.from = response.from; + this.policyName = response.policyName; + this.policyVersion = response.policyVersion; + this.payload = response.payload; + } + + public String getClosedLoopControlName() { + return closedLoopControlName; + } + + public void setClosedLoopControlName(String closedLoopControlName) { + this.closedLoopControlName = closedLoopControlName; + } + + public String getVersion() { + return version; + } + + public void setVersion(String version) { + this.version = version; + } + + public UUID getRequestId() { + return requestId; + } + + public void setRequestId(UUID requestId) { + this.requestId = requestId; + } + + public String getTarget() { + return target; + } + + public void setTarget(String target) { + this.target = target; + } + + public String getFrom() { + return from; + } + + public void setFrom(String from) { + this.from = from; + } + + public String getPolicyName() { + return policyName; + } + + public void setPolicyName(String policyName) { + this.policyName = policyName; + } + + public String getPolicyVersion() { + return policyVersion; + } + + public void setPolicyVersion(String policyVersion) { + this.policyVersion = policyVersion; + } + + public String getPayload() { + return payload; + } + + public void setPayload(String payload) { + this.payload = payload; + } +} diff --git a/controlloop/common/model-impl/events/src/test/java/org/onap/policy/controlloop/ControlLoopResponseTest.java b/controlloop/common/model-impl/events/src/test/java/org/onap/policy/controlloop/ControlLoopResponseTest.java new file mode 100644 index 000000000..3bab0aef4 --- /dev/null +++ b/controlloop/common/model-impl/events/src/test/java/org/onap/policy/controlloop/ControlLoopResponseTest.java @@ -0,0 +1,65 @@ +/*- + * ============LICENSE_START======================================================= + * controlloop + * ================================================================================ + * Copyright (C) 2019 Wipro Limited 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.onap.policy.controlloop; + +import static org.junit.Assert.assertEquals; + +import java.util.UUID; +import org.junit.Test; + +public class ControlLoopResponseTest { + + @Test + public void test() { + ControlLoopResponse rsp = new ControlLoopResponse(); + + assertEquals("1.0.0", rsp.getVersion()); + + rsp = new ControlLoopResponse(null); + assertEquals("1.0.0", rsp.getVersion()); + + rsp.setClosedLoopControlName("name"); + assertEquals("name", rsp.getClosedLoopControlName()); + + rsp.setFrom("from"); + assertEquals("from", rsp.getFrom()); + + rsp.setPayload("payload"); + assertEquals("payload", rsp.getPayload()); + + rsp.setPolicyName("policyname"); + assertEquals("policyname", rsp.getPolicyName()); + + rsp.setPolicyVersion("1"); + assertEquals("1", rsp.getPolicyVersion()); + + UUID id = UUID.randomUUID(); + rsp.setRequestId(id); + assertEquals(id, rsp.getRequestId()); + + rsp.setTarget("target"); + assertEquals("target", rsp.getTarget()); + + rsp.setVersion("foo"); + assertEquals("foo", rsp.getVersion()); + + } +} diff --git a/controlloop/common/model-impl/sdnr/src/main/resources/definitions.yaml b/controlloop/common/model-impl/sdnr/src/main/resources/definitions.yaml index c128ab483..19c91e50d 100644 --- a/controlloop/common/model-impl/sdnr/src/main/resources/definitions.yaml +++ b/controlloop/common/model-impl/sdnr/src/main/resources/definitions.yaml @@ -55,6 +55,7 @@ Request: - LiveUpgrade - Migrate - ModifyConfig + - ModifyConfigANR - Query - Rebuild - Reconfigure diff --git a/controlloop/common/policy-yaml/src/main/java/org/onap/policy/controlloop/compiler/ControlLoopCompiler.java b/controlloop/common/policy-yaml/src/main/java/org/onap/policy/controlloop/compiler/ControlLoopCompiler.java index d3d8a0272..b98cb0bb4 100644 --- a/controlloop/common/policy-yaml/src/main/java/org/onap/policy/controlloop/compiler/ControlLoopCompiler.java +++ b/controlloop/common/policy-yaml/src/main/java/org/onap/policy/controlloop/compiler/ControlLoopCompiler.java @@ -430,7 +430,7 @@ public class ControlLoopCompiler implements Serializable { ImmutableMap> recipes = new ImmutableMap.Builder>() .put("APPC", ImmutableList.of("Restart", "Rebuild", "Migrate", "ModifyConfig")) .put("SDNC", ImmutableList.of("Reroute")) - .put("SDNR", ImmutableList.of("ModifyConfig")) + .put("SDNR", ImmutableList.of("ModifyConfig", "ModifyConfigANR")) .put("SO", ImmutableList.of("VF Module Create", "VF Module Delete")) .put("VFC", ImmutableList.of("Restart")) .build(); diff --git a/controlloop/common/policy-yaml/src/test/java/org/onap/policy/controlloop/policy/ControlLoopPolicyTest.java b/controlloop/common/policy-yaml/src/test/java/org/onap/policy/controlloop/policy/ControlLoopPolicyTest.java index 00c70052e..109a365a8 100644 --- a/controlloop/common/policy-yaml/src/test/java/org/onap/policy/controlloop/policy/ControlLoopPolicyTest.java +++ b/controlloop/common/policy-yaml/src/test/java/org/onap/policy/controlloop/policy/ControlLoopPolicyTest.java @@ -79,6 +79,11 @@ public class ControlLoopPolicyTest { this.test("src/test/resources/v2.0.0/policy_ONAP_UseCase_vPCI.yaml"); } + @Test + public void testvsonh() { + this.test("src/test/resources/v2.0.0/policy_ONAP_UseCase_vSONH.yaml"); + } + @Test public void testvolte() { this.test("src/test/resources/v2.0.0/policy_ONAP_UseCase_VOLTE.yaml"); diff --git a/controlloop/common/policy-yaml/src/test/resources/v2.0.0/policy_ONAP_UseCase_vSONH.yaml b/controlloop/common/policy-yaml/src/test/resources/v2.0.0/policy_ONAP_UseCase_vSONH.yaml new file mode 100644 index 000000000..3f965a967 --- /dev/null +++ b/controlloop/common/policy-yaml/src/test/resources/v2.0.0/policy_ONAP_UseCase_vSONH.yaml @@ -0,0 +1,39 @@ +# Copyright 2019 Wipro Limited 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. +controlLoop: + version: 3.0.0 + controlLoopName: ControlLoop-vSONH-7d4baf04-8875-4d1f-946d-06b874048b61 + trigger_policy: unique-policy-id-456-modifyconfig + timeout: 1200 + abatement: false + +policies: + - id: unique-policy-id-456-modifyconfig + name: modify ANR config + description: + actor: SDNR + recipe: ModifyConfigANR + target: + # These fields are not used + resourceID: Eace933104d443b496b8.nodes.heat.vpg + type: VNF + retry: 0 + timeout: 300 + success: final_success + failure: final_failure + failure_timeout: final_failure_timeout + failure_retries: final_failure_retries + failure_exception: final_failure_exception + failure_guard: final_failure_guard + diff --git a/controlloop/templates/archetype-cl-amsterdam/src/main/resources/archetype-resources/src/main/config/__artifactId__-controller.properties b/controlloop/templates/archetype-cl-amsterdam/src/main/resources/archetype-resources/src/main/config/__artifactId__-controller.properties index 4799c6567..cc95d5530 100644 --- a/controlloop/templates/archetype-cl-amsterdam/src/main/resources/archetype-resources/src/main/config/__artifactId__-controller.properties +++ b/controlloop/templates/archetype-cl-amsterdam/src/main/resources/archetype-resources/src/main/config/__artifactId__-controller.properties @@ -54,7 +54,7 @@ dmaap.source.topics.SDNR-CL-RSP.events.org.onap.policy.sdnr.PciResponseWrapper.f dmaap.source.topics.SDNR-CL-RSP.events.custom.gson=org.onap.policy.sdnr.util.Serialization,gson dmaap.source.topics.SDNR-CL-RSP.https=true -noop.sink.topics=APPC-CL,APPC-LCM-READ,POLICY-CL-MGT,SDNR-CL +noop.sink.topics=APPC-CL,APPC-LCM-READ,POLICY-CL-MGT,SDNR-CL,DCAE_CL_RSP noop.sink.topics.APPC-CL.servers=${dmaapServers} noop.sink.topics.APPC-CL.apiKey= @@ -80,6 +80,12 @@ noop.sink.topics.SDNR-CL.apiSecret= noop.sink.topics.SDNR-CL.events=org.onap.policy.sdnr.PciRequestWrapper noop.sink.topics.SDNR-CL.events.custom.gson=org.onap.policy.sdnr.util.Serialization,gson +noop.sink.topics.DCAE_CL_RSP.servers=${dmaapServers} +noop.sink.topics.DCAE_CL_RSP.apiKey= +noop.sink.topics.DCAE_CL_RSP.apiSecret= +noop.sink.topics.DCAE_CL_RSP.events=org.onap.policy.controlloop.ControlLoopResponse +noop.sink.topics.DCAE_CL_RSP.events.custom.gson=org.onap.policy.controlloop.util.Serialization,gsonPretty + rules.groupId=${groupId} rules.artifactId=${artifactId} rules.version=${version} diff --git a/controlloop/templates/archetype-cl-amsterdam/src/main/resources/archetype-resources/src/main/config/__artifactId__-controller.rest.json b/controlloop/templates/archetype-cl-amsterdam/src/main/resources/archetype-resources/src/main/config/__artifactId__-controller.rest.json index 8f6d39d88..0dda5d41b 100644 --- a/controlloop/templates/archetype-cl-amsterdam/src/main/resources/archetype-resources/src/main/config/__artifactId__-controller.rest.json +++ b/controlloop/templates/archetype-cl-amsterdam/src/main/resources/archetype-resources/src/main/config/__artifactId__-controller.rest.json @@ -23,7 +23,7 @@ "ueb.source.topics.SDNR-CL-RSP.events.org.onap.policy.sdnr.PciResponseWrapper.filter": "[?($.type == 'response')]", "ueb.source.topics.SDNR-CL-RSP.events.custom.gson": "org.onap.policy.sdnr.util.Serialization,gson", - "noop.sink.topics": "APPC-CL,APPC-LCM-READ,POLICY-CL-MGT,SDNR-CL", + "noop.sink.topics": "APPC-CL,APPC-LCM-READ,POLICY-CL-MGT,SDNR-CL,DCAE_CL_RSP", "noop.sink.topics.APPC-CL.servers": "${dmaapServers}", "noop.sink.topics.APPC-CL.events": "org.onap.policy.appc.Request", @@ -41,6 +41,10 @@ "noop.sink.topics.SDNR-CL.events": "org.onap.policy.sdnr.PciRequestWrapper", "noop.sink.topics.SDNR-CL.events.custom.gson": "org.onap.policy.sdnr.util.Serialization,gson", + "noop.sink.topics.DCAE_CL_RSP.servers": "${dmaapServers}", + "noop.sink.topics.DCAE_CL_RSP.events": "org.onap.policy.controlloop.ControlLoopResponse", + "noop.sink.topics.DCAE_CL_RSP.events.custom.gson": "org.onap.policy.controlloop.util.Serialization,gson", + "rules.groupId": "${groupId}", "rules.artifactId": "${artifactId}", "rules.version": "${version}" diff --git a/controlloop/templates/archetype-cl-amsterdam/src/main/resources/archetype-resources/src/main/config/vSONH.anr.onset b/controlloop/templates/archetype-cl-amsterdam/src/main/resources/archetype-resources/src/main/config/vSONH.anr.onset new file mode 100644 index 000000000..7636c2ade --- /dev/null +++ b/controlloop/templates/archetype-cl-amsterdam/src/main/resources/archetype-resources/src/main/config/vSONH.anr.onset @@ -0,0 +1,18 @@ +{ + "closedLoopControlName": "ControlLoop-vSONH-7d4baf04-8875-4d1f-946d-06b874048b61", + "closedLoopAlarmStart": 1510187409180, + "closedLoopEventClient": "microservice.SONH", + "closedLoopEventStatus": "ONSET", + "requestID": "722ee65a-8afd-48df-bf57-c152ae45bacc", + "target_type": "VNF", + "target": "generic-vnf.vnf-id", + "AAI": { + "generic-vnf.is-closed-loop-disabled": "false", + "generic-vnf.prov-status": "ACTIVE", + "generic-vnf.vnf-id": "notused" + }, + "from": "SONHMS", + "version": "1.0.2", + "Action": "ModifyConfigANR", + "payload": "{ \"Configurations\":[ { \"data\":{ \"FAPService\":{ \"alias\":\"Cell1\", \"CellConfig\":{ \"LTE\":{ \"RAN\":{ \"Common\":{ \"CellIdentity\":\"1\" }, \"NeighborListInUse\" : { \"LTECellNumberOfEntries\" : \"1\" , \"LTECell\" : [{ \"PLMNID\" :\"plmnid1\", \"CID\":\"Chn0001\", \"PhyCellID\":\"3\", \"PNFName\":\"ncserver01\", \"Blacklisted\":\"false\"}] } } } } } } } ] }" +} diff --git a/controlloop/templates/archetype-cl-amsterdam/src/main/resources/archetype-resources/src/main/config/vSONH.anr.sdnr.success b/controlloop/templates/archetype-cl-amsterdam/src/main/resources/archetype-resources/src/main/config/vSONH.anr.sdnr.success new file mode 100644 index 000000000..c814a7459 --- /dev/null +++ b/controlloop/templates/archetype-cl-amsterdam/src/main/resources/archetype-resources/src/main/config/vSONH.anr.sdnr.success @@ -0,0 +1,23 @@ +{ + "body": { + "output": { + "CommonHeader": { + "TimeStamp": "2018-09-10T07:10:05.614Z", + "APIver": "1.0", + "RequestID": "722ee65a-8afd-48df-bf57-c152ae45bacc", + "SubRequestID": "1", + "RequestTrack": [], + "Flags": [] + }, + "Status": { + "Code": 200, + "Value": "SUCCESS" + }, + "Payload": "{ \"Configurations\":[ { \"Status\": { \"Code\": 200, \"Value\": \"SUCCESS\" }, \"data\":{ \"FAPService\":{ \"alias\":\"Cell1\", \"CellConfig\":{ \"LTE\":{ \"RAN\":{ \"Common\":{ \"CellIdentity\":\"1\" }, \"NeighborListInUse\" : { \"LTECellNumberOfEntries\" : \"1\" , \"LTECell\" : [{ \"PLMNID\" :\"plmnid1\", \"CID\":\"Chn0001\", \"PhyCellID\":\"3\", \"PNFName\":\"ncserver01\", \"Blacklisted\":\"false\"}] } } } } } } } ] }" + } + }, + "version": "1.0", + "rpc-name": "ModifyConfigANR", + "correlation-id": "722ee65a-8afd-48df-bf57-c152ae45bacc-1", + "type": "response" +} diff --git a/controlloop/templates/archetype-cl-amsterdam/src/main/resources/archetype-resources/src/main/config/vSONH.yml b/controlloop/templates/archetype-cl-amsterdam/src/main/resources/archetype-resources/src/main/config/vSONH.yml new file mode 100644 index 000000000..07790226a --- /dev/null +++ b/controlloop/templates/archetype-cl-amsterdam/src/main/resources/archetype-resources/src/main/config/vSONH.yml @@ -0,0 +1,38 @@ +# Copyright 2019 Wipro Limited 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. +controlLoop: + version: 3.0.0 + controlLoopName: ${closedLoopControlName} + trigger_policy: unique-policy-id-123-modifyconfig + timeout: 1200 + abatement: false + +policies: + - id: unique-policy-id-456-modifyconfig + name: modify ANR config + description: + actor: SDNR + recipe: ModifyConfigANR + target: + # These fields are not used + resourceID: Eace933104d443b496b8.nodes.heat.vpg + type: VNF + retry: 0 + timeout: 300 + success: final_success + failure: final_failure + failure_timeout: final_failure_timeout + failure_retries: final_failure_retries + failure_exception: final_failure_exception + failure_guard: final_failure_guard diff --git a/controlloop/templates/archetype-cl-usecases/src/main/resources/META-INF/maven/archetype-metadata.xml b/controlloop/templates/archetype-cl-usecases/src/main/resources/META-INF/maven/archetype-metadata.xml index 7a870a8ba..07f1b5590 100644 --- a/controlloop/templates/archetype-cl-usecases/src/main/resources/META-INF/maven/archetype-metadata.xml +++ b/controlloop/templates/archetype-cl-usecases/src/main/resources/META-INF/maven/archetype-metadata.xml @@ -81,6 +81,24 @@ controlLoop%3A%0D%0A++version%3A+2.0.0%0D%0A++controlLoopName%3A+ControlLoop-CCVPN-2179b738-fd36-4843-a71a-a8c24c70c22b%0D%0A++trigger_policy%3A+unique-policy-id-16-BandwidthOnDemand%0D%0A++timeout%3A+3600%0D%0A++abatement%3A+false%0D%0A%0D%0Apolicies%3A%0D%0A++-+id%3A+unique-policy-id-16-BandwidthOnDemand%0D%0A++++name%3A+CCVPNBandwidthOnDemand%0D%0A++++description%3A%0D%0A++++actor%3A+SDNC%0D%0A++++recipe%3A+BandwidthOnDemand%0D%0A++++target%3A%0D%0A++++++type%3A+VM%0D%0A++++retry%3A+3%0D%0A++++timeout%3A+1200%0D%0A++++success%3A+final_success%0D%0A++++failure%3A+final_failure%0D%0A++++failure_timeout%3A+final_failure_timeout%0D%0A++++failure_retries%3A+final_failure_retries%0D%0A++++failure_exception%3A+final_failure_exception%0D%0A++++failure_guard%3A+final_failure_guard + + ControlLoop-vPCI-fb41f388-a5f2-11e8-98d0-529269fb1459 + + + VPCI + + + controlLoop%3A%0D%0A++version%3A+3.0.0%0D%0A++controlLoopName%3A+ControlLoop-vPCI-fb41f388-a5f2-11e8-98d0-529269fb1459%0D%0A++trigger_policy%3A+unique-policy-id-123-modifyconfig%0D%0A++timeout%3A+1200%0D%0A++abatement%3A+false%0D%0A+%0D%0Apolicies%3A%0D%0A++-+id%3A+unique-policy-id-123-modifyconfig%0D%0A++++name%3A+modify+PCI+config%0D%0A++++description%3A%0D%0A++++actor%3A+SDNR%0D%0A++++recipe%3A+ModifyConfig%0D%0A++++target%3A%0D%0A++++++%23+These+fields+are+not+used%0D%0A++++++resourceID%3A+Eace933104d443b496b8.nodes.heat.vpg%0D%0A++++++type%3A+VNF%0D%0A++++retry%3A+0%0D%0A++++timeout%3A+300%0D%0A++++success%3A+final_success%0D%0A++++failure%3A+final_failure%0D%0A++++failure_timeout%3A+final_failure_timeout%0D%0A++++failure_retries%3A+final_failure_retries%0D%0A++++failure_exception%3A+final_failure_exception%0D%0A++++failure_guard%3A+final_failure_guard + + + ControlLoop-vSONH-7d4baf04-8875-4d1f-946d-06b874048b61 + + + VSONH + + + controlLoop%3A%0D%0A++version%3A+4.0.0%0D%0A++controlLoopName%3A+ControlLoop-vSONH-7d4baf04-8875-4d1f-946d-06b874048b61%0D%0A++trigger_policy%3A+unique-policy-id-456-modifyconfig%0D%0A++timeout%3A+1200%0D%0A++abatement%3A+false%0D%0A+%0D%0Apolicies%3A%0D%0A++-+id%3A+unique-policy-id-456-modifyconfig%0D%0A++++name%3A+modify+ANR+config%0D%0A++++description%3A%0D%0A++++actor%3A+SDNR%0D%0A++++recipe%3A+ModifyConfigANR%0D%0A++++target%3A%0D%0A++++++%23+These+fields+are+not+used%0D%0A++++++resourceID%3A+Eace933104d443b496b8.nodes.heat.vpg%0D%0A++++++type%3A+VNF%0D%0A++++retry%3A+0%0D%0A++++timeout%3A+300%0D%0A++++success%3A+final_success%0D%0A++++failure%3A+final_failure%0D%0A++++failure_timeout%3A+final_failure_timeout%0D%0A++++failure_retries%3A+final_failure_retries%0D%0A++++failure_exception%3A+final_failure_exception%0D%0A++++failure_guard%3A+final_failure_guard + DCAE diff --git a/controlloop/templates/archetype-cl-usecases/src/main/resources/archetype-resources/src/main/resources/__closedLoopControlName__.drl b/controlloop/templates/archetype-cl-usecases/src/main/resources/archetype-resources/src/main/resources/__closedLoopControlName__.drl index 93bc63ea7..77edee1e7 100644 --- a/controlloop/templates/archetype-cl-usecases/src/main/resources/archetype-resources/src/main/resources/__closedLoopControlName__.drl +++ b/controlloop/templates/archetype-cl-usecases/src/main/resources/archetype-resources/src/main/resources/__closedLoopControlName__.drl @@ -26,6 +26,7 @@ import org.onap.policy.controlloop.VirtualControlLoopNotification; import org.onap.policy.controlloop.ControlLoopEventStatus; import org.onap.policy.controlloop.ControlLoopNotificationType; import org.onap.policy.controlloop.ControlLoopLogger; +import org.onap.policy.controlloop.ControlLoopResponse; import org.onap.policy.controlloop.policy.PolicyResult; import org.onap.policy.controlloop.policy.ControlLoopPolicy; import org.onap.policy.controlloop.policy.Policy; @@ -1488,6 +1489,9 @@ rule "SDNR.RESPONSE" notification.setNotification(ControlLoopNotificationType.OPERATION_FAILURE); } PolicyEngine.manager.deliver("POLICY-CL-MGT", notification); + + ControlLoopResponse clResponse = $operation.getControlLoopResponse($response, $event); + PolicyEngine.manager.deliver("DCAE_CL_RSP", clResponse); // // Ensure the operation is complete // diff --git a/controlloop/templates/template.demo/src/test/java/org/onap/policy/template/demo/VsonhControlLoopTest.java b/controlloop/templates/template.demo/src/test/java/org/onap/policy/template/demo/VsonhControlLoopTest.java new file mode 100644 index 000000000..871755db9 --- /dev/null +++ b/controlloop/templates/template.demo/src/test/java/org/onap/policy/template/demo/VsonhControlLoopTest.java @@ -0,0 +1,443 @@ +/*- + * ============LICENSE_START======================================================= + * demo + * ================================================================================ + * Copyright (C) 2019 Wipro Limited 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.onap.policy.template.demo; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import java.io.IOException; +import java.net.URLEncoder; +import java.time.Instant; +import java.util.HashMap; +import java.util.List; +import java.util.Properties; +import java.util.UUID; + +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.Test; +import org.kie.api.runtime.KieSession; +import org.kie.api.runtime.rule.FactHandle; +import org.onap.policy.common.endpoints.event.comm.Topic.CommInfrastructure; +import org.onap.policy.common.endpoints.event.comm.TopicEndpoint; +import org.onap.policy.common.endpoints.event.comm.TopicListener; +import org.onap.policy.common.endpoints.event.comm.TopicSink; +import org.onap.policy.common.endpoints.http.server.HttpServletServer; +import org.onap.policy.common.endpoints.properties.PolicyEndPointProperties; +import org.onap.policy.controlloop.ControlLoopEventStatus; +import org.onap.policy.controlloop.ControlLoopNotificationType; +import org.onap.policy.controlloop.ControlLoopTargetType; +import org.onap.policy.controlloop.VirtualControlLoopEvent; +import org.onap.policy.controlloop.VirtualControlLoopNotification; +import org.onap.policy.controlloop.policy.ControlLoopPolicy; +import org.onap.policy.drools.protocol.coders.EventProtocolCoder; +import org.onap.policy.drools.protocol.coders.EventProtocolParams; +import org.onap.policy.drools.protocol.coders.JsonProtocolFilter; +import org.onap.policy.drools.system.PolicyController; +import org.onap.policy.drools.system.PolicyEngine; +import org.onap.policy.drools.utils.logging.LoggerUtil; +import org.onap.policy.sdnr.PciRequest; +import org.onap.policy.sdnr.PciRequestWrapper; +import org.onap.policy.sdnr.PciResponse; +import org.onap.policy.sdnr.PciResponseWrapper; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class VsonhControlLoopTest implements TopicListener { + + private static final Logger logger = LoggerFactory.getLogger(VsonhControlLoopTest.class); + + private static List noopTopics; + + private static KieSession kieSession; + private static SupportUtil.Pair pair; + private UUID requestId; + + static { + /* Set environment properties */ + SupportUtil.setAaiProps(); + SupportUtil.setGuardProps(); + SupportUtil.setPuProp(); + LoggerUtil.setLevel(LoggerUtil.ROOT_LOGGER, "DEBUG"); + } + + /** + * Setup the simulator. + */ + @BeforeClass + public static void setUpSimulator() { + PolicyEngine.manager.configure(new Properties()); + assertTrue(PolicyEngine.manager.start()); + Properties noopSinkProperties = new Properties(); + noopSinkProperties.put(PolicyEndPointProperties.PROPERTY_NOOP_SINK_TOPICS, "SDNR-CL,POLICY-CL-MGT"); + noopSinkProperties.put("noop.sink.topics.SDNR-CL.events", "org.onap.policy.sdnr.PciRequestWrapper"); + noopSinkProperties.put("noop.sink.topics.SDNR-CL.events.custom.gson", + "org.onap.policy.sdnr.util.Serialization,gson"); + noopSinkProperties.put("noop.sink.topics.POLICY-CL-MGT.events", + "org.onap.policy.controlloop.VirtualControlLoopNotification"); + noopSinkProperties.put("noop.sink.topics.POLICY-CL-MGT.events.custom.gson", + "org.onap.policy.controlloop.util.Serialization,gsonPretty"); + noopTopics = TopicEndpoint.manager.addTopicSinks(noopSinkProperties); + + EventProtocolCoder.manager.addEncoder(EventProtocolParams.builder() + .groupId("junit.groupId") + .artifactId("junit.artifactId") + .topic("POLICY-CL-MGT") + .eventClass("org.onap.policy.controlloop.VirtualControlLoopNotification") + .protocolFilter(new JsonProtocolFilter()) + .modelClassLoaderHash(1111)); + EventProtocolCoder.manager.addEncoder(EventProtocolParams.builder() + .groupId("junit.groupId") + .artifactId("junit.artifactId") + .topic("SDNR-CL") + .eventClass("org.onap.policy.sdnr.PciRequestWrapper") + .protocolFilter(new JsonProtocolFilter()) + .modelClassLoaderHash(1111)); + try { + SupportUtil.buildAaiSim(); + SupportUtil.buildGuardSim(); + } catch (Exception e) { + fail(e.getMessage()); + } + /* + * Start the kie session + */ + try { + kieSession = startSession( + "../archetype-cl-amsterdam/src/main/resources/archetype-resources" + + "/src/main/resources/__closedLoopControlName__.drl", + "src/test/resources/yaml/policy_ControlLoop_vSONH.yaml", "type=operational", "CL_vSONH", "v4.0.0"); + } catch (IOException e) { + e.printStackTrace(); + logger.debug("Could not create kieSession"); + fail("Could not create kieSession"); + } + } + + /** + * Tear down the simulator. + */ + @AfterClass + public static void tearDownSimulator() { + /* + * Gracefully shut down the kie session + */ + kieSession.dispose(); + + PolicyEngine.manager.stop(); + HttpServletServer.factory.destroy(); + PolicyController.factory.shutdown(); + TopicEndpoint.manager.shutdown(); + } + + @Test + public void successTest() { + + /* + * Allows the PolicyEngine to callback to this object to notify that there is an + * event ready to be pulled from the queue + */ + for (TopicSink sink : noopTopics) { + assertTrue(sink.start()); + sink.register(this); + } + + /* + * Create a unique requestId + */ + requestId = UUID.randomUUID(); + + /* + * Simulate an onset event the policy engine will receive from DCAE to kick off + * processing through the rules + */ + sendEvent(pair.first, requestId, ControlLoopEventStatus.ONSET, true); + + kieSession.fireUntilHalt(); + + // allow object clean-up + kieSession.fireAllRules(); + + /* + * The only fact in memory should be Params + */ + assertEquals(1, kieSession.getFactCount()); + + /* + * Print what's left in memory + */ + dumpFacts(kieSession); + + } + + @Test + public void aaiGetFailTest() { + + /* + * Allows the PolicyEngine to callback to this object to notify that there is an + * event ready to be pulled from the queue + */ + for (TopicSink sink : noopTopics) { + assertTrue(sink.start()); + sink.register(this); + } + + /* + * Create a unique requestId + */ + requestId = UUID.randomUUID(); + + /* + * Simulate an onset event the policy engine will receive from DCAE to kick off + * processing through the rules + */ + sendEvent(pair.first, requestId, ControlLoopEventStatus.ONSET, false); + + kieSession.fireUntilHalt(); + + // allow object clean-up + kieSession.fireAllRules(); + + /* + * The only fact in memory should be Params + */ + assertEquals(1, kieSession.getFactCount()); + + /* + * Print what's left in memory + */ + dumpFacts(kieSession); + + } + + /** + * This method will start a kie session and instantiate the Policy Engine. + * + * @param droolsTemplate + * the DRL rules file + * @param yamlFile + * the yaml file containing the policies + * @param policyScope + * scope for policy + * @param policyName + * name of the policy + * @param policyVersion + * version of the policy + * @return the kieSession to be used to insert facts + * @throws IOException + * IO exception + */ + private static KieSession startSession(String droolsTemplate, String yamlFile, String policyScope, + String policyName, String policyVersion) throws IOException { + + /* + * Load policies from yaml + */ + pair = SupportUtil.loadYaml(yamlFile); + assertNotNull(pair); + assertNotNull(pair.first); + assertNotNull(pair.first.getControlLoop()); + assertNotNull(pair.first.getControlLoop().getControlLoopName()); + assertTrue(pair.first.getControlLoop().getControlLoopName().length() > 0); + + /* + * Construct a kie session + */ + final KieSession kieSession = SupportUtil.buildContainer(droolsTemplate, + pair.first.getControlLoop().getControlLoopName(), policyScope, policyName, policyVersion, + URLEncoder.encode(pair.second, "UTF-8")); + + /* + * Retrieve the Policy Engine + */ + + logger.debug("======controlloop======"); + logger.debug(((ControlLoopPolicy) pair.first).toString()); + logger.debug("======policies======"); + logger.debug(URLEncoder.encode(pair.second, "UTF-8")); + logger.debug("============"); + + return kieSession; + } + + /* + * (non-Javadoc) + * + * @see + * org.onap.policy.drools.PolicyEngineListener#newEventNotification(java.lang. + * String) + */ + @Override + public void onTopicEvent(CommInfrastructure commType, String topic, String event) { + logger.debug("\n============ onTopicEvent!!! ===========\n"); + logger.debug("topic: {}, event: {}", topic, event); + /* + * Pull the object that was sent out to DMAAP and make sure it is a + * ControlLoopNoticiation of type active + */ + Object obj = null; + if ("POLICY-CL-MGT".equals(topic)) { + obj = org.onap.policy.controlloop.util.Serialization.gsonJunit.fromJson(event, + org.onap.policy.controlloop.VirtualControlLoopNotification.class); + } else if ("SDNR-CL".equals(topic)) { + obj = org.onap.policy.sdnr.util.Serialization.gsonJunit.fromJson(event, + org.onap.policy.sdnr.PciRequestWrapper.class); + } + assertNotNull(obj); + if (obj instanceof VirtualControlLoopNotification) { + VirtualControlLoopNotification notification = (VirtualControlLoopNotification) obj; + String policyName = notification.getPolicyName(); + logger.debug("Rule Fired: {}", policyName); + if (policyName.endsWith("EVENT")) { + assertEquals(ControlLoopNotificationType.ACTIVE, notification.getNotification()); + } else if (policyName.endsWith("GUARD_NOT_YET_QUERIED")) { + assertEquals(ControlLoopNotificationType.OPERATION, notification.getNotification()); + assertNotNull(notification.getMessage()); + assertTrue(notification.getMessage().startsWith("Sending guard query")); + } else if (policyName.endsWith("GUARD.RESPONSE")) { + assertEquals(ControlLoopNotificationType.OPERATION, notification.getNotification()); + assertNotNull(notification.getMessage()); + assertTrue(notification.getMessage().toLowerCase().endsWith("permit")); + } else if (policyName.endsWith("GUARD_PERMITTED")) { + assertEquals(ControlLoopNotificationType.OPERATION, notification.getNotification()); + assertNotNull(notification.getMessage()); + assertTrue(notification.getMessage().startsWith("actor=SDNR")); + } else if (policyName.endsWith("OPERATION.TIMEOUT")) { + kieSession.halt(); + logger.debug("The operation timed out"); + fail("Operation Timed Out"); + } else if (policyName.endsWith("SDNR.RESPONSE")) { + assertEquals(ControlLoopNotificationType.OPERATION_SUCCESS, notification.getNotification()); + assertNotNull(notification.getMessage()); + assertTrue(notification.getMessage().startsWith("actor=SDNR")); + } else if (policyName.endsWith("EVENT.MANAGER")) { + if ("getFail".equals(notification.getAai().get("generic-vnf.vnf-id"))) { + assertEquals(ControlLoopNotificationType.FINAL_FAILURE, notification.getNotification()); + kieSession.halt(); + } else { + assertEquals(ControlLoopNotificationType.FINAL_SUCCESS, notification.getNotification()); + kieSession.halt(); + } + } else if (policyName.endsWith("EVENT.MANAGER.TIMEOUT")) { + kieSession.halt(); + logger.debug("The control loop timed out"); + fail("Control Loop Timed Out"); + } + } else if (obj instanceof PciRequestWrapper) { + /* + * The request should be of type PciRequestWrapper and the subrequestid should + * be 1 + */ + PciRequestWrapper dmaapRequest = (PciRequestWrapper) obj; + PciRequest pciRequest = dmaapRequest.getBody(); + assertEquals("1", pciRequest.getCommonHeader().getSubRequestId()); + + logger.debug("\n============ SDNR received the request!!! ===========\n"); + logger.debug("\n============ dmaapRequest ===========\n {} ", dmaapRequest); + logger.debug("\n============ pciRequest ===========\n {}", pciRequest); + + /* + * Simulate a success response from SDNR and insert the response into the + * working memory + */ + PciResponse pciResponse = new PciResponse(pciRequest); + pciResponse.getStatus().setCode(200); + pciResponse.getStatus().setValue("SUCCESS"); + StringBuilder sb = new StringBuilder(); + sb.append("{ \"Configurations\":[ { \"Status\": { \"Code\": 200, \"Value\":" + + " \"SUCCESS\" }, \"data\":{ \"FAPService\":{ \"alias\":" + + "\"Network1\", \"CellConfig\":{ \"LTE\":{ \"RAN\":{ \"Common\":" + + "{ \"CellIdentity\":\"1\" }, \"NeighborListInUse\" : " + + "{ \"LTECellNumberOfEntries\" : \"1\" , \"LTECell\" : " + + "[ { \"PLMNID\" :\"plmnid1\", \"CID\":\"Chn0001\", \"PhyCellID\":" + + "\"3\", \"PNFName\":\"ncserver01\", \"Blacklisted\":\"false\" " + + "} ] } } } } } } } ] }"); + + pciResponse.setPayload(sb.toString()); + PciResponseWrapper dmaapResponse = new PciResponseWrapper(); + dmaapResponse.setBody(pciResponse); + dmaapResponse.setType("response"); + logger.debug("\n============ SDNR sending response!!! ===========\n"); + logger.debug("\n============ dmaapResponse ===========\n {}", dmaapResponse); + logger.debug("\n============ pciResponse ===========\n {}", pciResponse); + kieSession.insert(dmaapResponse); + } + } + + /** + * This method is used to simulate event messages from DCAE that start the + * control loop (onset message). + * + * @param policy + * the controlLoopName comes from the policy + * @param requestId + * the requestId for this event + * @param status + * could be onset + */ + protected void sendEvent(ControlLoopPolicy policy, UUID requestId, ControlLoopEventStatus status, + boolean isEnriched) { + VirtualControlLoopEvent event = new VirtualControlLoopEvent(); + event.setClosedLoopControlName(policy.getControlLoop().getControlLoopName()); + event.setRequestId(requestId); + event.setTarget("generic-vnf.vnf-id"); + event.setTargetType(ControlLoopTargetType.VNF); + event.setClosedLoopAlarmStart(Instant.now()); + event.setAai(new HashMap<>()); + if (isEnriched) { + event.getAai().put("generic-vnf.is-closed-loop-disabled", "false"); + event.getAai().put("generic-vnf.prov-status", "ACTIVE"); + event.getAai().put("generic-vnf.vnf-id", "notused"); + } else { + event.getAai().put("generic-vnf.vnf-id", "getFail"); + } + event.setClosedLoopEventStatus(status); + StringBuilder sb = new StringBuilder(); + sb.append("{ \"Configurations\":[ { \"data\":{ \"FAPService\":" + + " { \"alias\":\"Cell1\", \"CellConfig\":{ \"LTE\":{ \"RAN\":{ \"Common\":" + + "{ \"CellIdentity\":\"1\" }, \"NeighborListInUse\" : " + + "{ \"LTECellNumberOfEntries\" : \"1\" , \"LTECell\" : " + + "[ { \"PLMNID\" :\"plmnid1\", \"CID\":\"Chn0001\", \"PhyCellID\":" + + "\"3\", \"PNFName\":\"ncserver01\", \"Blacklisted\":\"false\" " + + "} ] } } } } } } } ] }"); + + event.setPayload(sb.toString()); + logger.debug("\n============ Policy receiving ONSET event !!! ===========\n"); + logger.debug("\n============ event ===========\n {}", event); + kieSession.insert(event); + } + + /** + * This method will dump all the facts in the working memory. + * + * @param kieSession + * the session containing the facts + */ + public void dumpFacts(KieSession kieSession) { + logger.debug("Fact Count: {}", kieSession.getFactCount()); + for (FactHandle handle : kieSession.getFactHandles()) { + logger.debug("FACT: {}", handle); + } + } + +} diff --git a/controlloop/templates/template.demo/src/test/resources/yaml/policy_ControlLoop_vSONH.yaml b/controlloop/templates/template.demo/src/test/resources/yaml/policy_ControlLoop_vSONH.yaml new file mode 100644 index 000000000..4cdf8ff40 --- /dev/null +++ b/controlloop/templates/template.demo/src/test/resources/yaml/policy_ControlLoop_vSONH.yaml @@ -0,0 +1,38 @@ +# Copyright 2019 Wipro Limited 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. +controlLoop: + version: 3.0.0 + controlLoopName: ControlLoop-vSONH-7d4baf04-8875-4d1f-946d-06b874048b61 + trigger_policy: unique-policy-id-456-modifyconfig + timeout: 1200 + abatement: false + +policies: + - id: unique-policy-id-456-modifyconfig + name: modify ANR config + description: + actor: SDNR + recipe: ModifyConfigANR + target: + # These fields are not used + resourceID: Eace933104d443b496b8.nodes.heat.vpg + type: VNF + retry: 0 + timeout: 300 + success: final_success + failure: final_failure + failure_timeout: final_failure_timeout + failure_retries: final_failure_retries + failure_exception: final_failure_exception + failure_guard: final_failure_guard -- cgit 1.2.3-korg