diff options
17 files changed, 698 insertions, 0 deletions
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 980799171..5abfca47b 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 @@ -356,6 +356,11 @@ public class ControlLoopOperationManager implements Serializable { // Cast VFC response and handle it // return onResponse((VFCResponse) response); + } else if (response instanceof SdncResponse) { + // + // Cast SDNC response and handle it + // + return onResponse((SdncResponse) response); } else { return null; } @@ -583,6 +588,36 @@ public class ControlLoopOperationManager implements Serializable { } /** + * This method handles operation responses from SDNC. + * + * @param sdncResponse the VFC response + * @return The result of the response handling + */ + private PolicyResult onResponse(SdncResponse sdncResponse) { + if ("200".equals(sdncResponse.getResponseOutput().getResponseCode())) { + // + // Consider it as success + // + this.completeOperation(this.attempts, " Success", PolicyResult.SUCCESS); + if (this.policyResult != null && this.policyResult.equals(PolicyResult.FAILURE_TIMEOUT)) { + return null; + } + return PolicyResult.SUCCESS; + } else { + // + // Consider it as failure + // + this.completeOperation(this.attempts, " Failed", PolicyResult.FAILURE); + if (this.policyResult != null && this.policyResult.equals(PolicyResult.FAILURE_TIMEOUT)) { + return null; + } + // increment operation attempts for retries + this.attempts += 1; + return PolicyResult.FAILURE; + } + } + + /** * Get the operation timeout. * * @return the timeout diff --git a/controlloop/common/simulators/pom.xml b/controlloop/common/simulators/pom.xml index 3eabd6391..5259890ca 100644 --- a/controlloop/common/simulators/pom.xml +++ b/controlloop/common/simulators/pom.xml @@ -68,5 +68,10 @@ <artifactId>gson</artifactId> <scope>provided</scope> </dependency> + <dependency> + <groupId>org.onap.policy.drools-applications.controlloop.common.model-impl</groupId> + <artifactId>sdnc</artifactId> + <version>${project.version}</version> + </dependency> </dependencies> </project> diff --git a/controlloop/common/simulators/src/main/java/org/onap/policy/simulators/SdncSimulatorJaxRs.java b/controlloop/common/simulators/src/main/java/org/onap/policy/simulators/SdncSimulatorJaxRs.java new file mode 100644 index 000000000..47bdf01ed --- /dev/null +++ b/controlloop/common/simulators/src/main/java/org/onap/policy/simulators/SdncSimulatorJaxRs.java @@ -0,0 +1,58 @@ +/*- + * ============LICENSE_START======================================================= + * simulators + * ================================================================================ + * Copyright (C) 2018 Huawei. 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.simulators; + +import java.util.UUID; +import javax.ws.rs.Consumes; +import javax.ws.rs.POST; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; +import javax.ws.rs.core.MediaType; + + +import org.onap.policy.sdnc.SdncResponse; +import org.onap.policy.sdnc.SdncResponseOutput; +import org.onap.policy.sdnc.util.Serialization; + + +@Path("/restconf/operations/") +public class SdncSimulatorJaxRs { + + /** + * SDNC post query. + * + * @return the response + */ + @POST + @Path("/GENERIC-RESOURCE-API:network-topology-operation") + @Consumes(MediaType.APPLICATION_JSON) + @Produces("application/json") + public String sdncPostQuery() { + final SdncResponse response = new SdncResponse(); + response.setRequestId(UUID.randomUUID().toString()); + SdncResponseOutput responseOutput = new SdncResponseOutput(); + responseOutput.setResponseCode("200"); + responseOutput.setAckFinalIndicator("Y"); + responseOutput.setSvcRequestId(UUID.randomUUID().toString()); + response.setResponseOutput(responseOutput); + return Serialization.gsonPretty.toJson(response); + } +} diff --git a/controlloop/common/simulators/src/main/java/org/onap/policy/simulators/Util.java b/controlloop/common/simulators/src/main/java/org/onap/policy/simulators/Util.java index 16ae615af..1de77638b 100644 --- a/controlloop/common/simulators/src/main/java/org/onap/policy/simulators/Util.java +++ b/controlloop/common/simulators/src/main/java/org/onap/policy/simulators/Util.java @@ -30,11 +30,13 @@ public class Util { public static final String SOSIM_SERVER_NAME = "soSim"; public static final String VFCSIM_SERVER_NAME = "vfcSim"; public static final String GUARDSIM_SERVER_NAME = "guardSim"; + public static final String SDNCSIM_SERVER_NAME = "sdncSim"; public static final int AAISIM_SERVER_PORT = 6666; public static final int SOSIM_SERVER_PORT = 6667; public static final int VFCSIM_SERVER_PORT = 6668; public static final int GUARDSIM_SERVER_PORT = 6669; + public static final int SDNCSIM_SERVER_PORT = 6670; private static final String CANNOT_CONNECT = "cannot connect to port "; private static final String LOCALHOST = "localhost"; @@ -62,6 +64,25 @@ public class Util { } /** + * Build an SDNC simulator. + * + * @return the simulator + * @throws InterruptedException if a thread is interrupted + * @throws IOException if an IO errror occurs + */ + public static HttpServletServer buildSdncSim() throws InterruptedException, IOException { + final HttpServletServer testServer = + HttpServletServer.factory.build(SDNCSIM_SERVER_NAME, LOCALHOST, SDNCSIM_SERVER_PORT, "/", false, true); + testServer.addServletClass("/*", SdncSimulatorJaxRs.class.getName()); + testServer.waitedStart(5000); + if (!NetworkUtil.isTcpPortOpen(LOCALHOST, testServer.getPort(), 5, 10000L)) { + throw new IllegalStateException(CANNOT_CONNECT + testServer.getPort()); + } + return testServer; + } + + + /** * Build an SO simulator. * * @return the simulator diff --git a/controlloop/packages/basex-controlloop/src/files/bin/create-cl-casablanca b/controlloop/packages/basex-controlloop/src/files/bin/create-cl-casablanca index 68395bc88..8b2045488 100644 --- a/controlloop/packages/basex-controlloop/src/files/bin/create-cl-casablanca +++ b/controlloop/packages/basex-controlloop/src/files/bin/create-cl-casablanca @@ -59,6 +59,14 @@ 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" +# CCVPN Policy Parameters +CCVPN_CONTROL_LOOP_NAME="ControlLoop-CCVPN-2179b738-fd36-4843-a71a-a8c24c70c66b" +CCVPN_POLICY_NAME="ccvpn" +CCVPN_CONTROL_LOOP_YAML="controlLoop%3A%0D%0A++version%3A+2.0.0%0D%0A++controlLoopName%3A+ControlLoop-CCVPN-2179b738-fd36-4843-a71a-a8c24c70c66b%0D%0A++trigger_policy%3A+unique-policy-id-16-Reroute%0D%0A++t +imeout%3A+3600%0D%0A++abatement%3A+false%0D%0A+%0D%0Apolicies%3A%0D%0A++-+id%3A+unique-policy-id-16-Reroute%0D%0A++++name%3A+Connectivity Reroute%0D%0A++++description%3A%0D%0A++++actor%3A+SDNC%0D%0A++++reci +pe%3A+Reroute%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_fail +ure_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" + # Generic Scope and Version POLICY_SCOPE="casablanca" POLICY_VERSION="v0.0.1" @@ -95,6 +103,10 @@ read -e -i "${VPCI_CONTROL_LOOP_NAME}" -p "VPCI Control Loop Name> " VPCI_CONTRO read -e -i "${VPCI_POLICY_NAME}" -p "VPCI Policy Name> " VPCI_POLICY_NAME read -e -i "${VPCI_CONTROL_LOOP_YAML}" -p "VPCI Control Loop Yaml> " VPCI_CONTROL_LOOP_YAML +read -e -i "${CCVPN_CONTROL_LOOP_NAME}" -p "CCVPN Control Loop Name> " CCVPN_CONTROL_LOOP_NAME +read -e -i "${CCVPN_POLICY_NAME}" -p "CCVPN Policy Name> " CCVPN_POLICY_NAME +read -e -i "${CCVPN_CONTROL_LOOP_YAML}" -p "CCVPN Control Loop Yaml> " CCVPN_CONTROL_LOOP_YAML + read -e -i "${POLICY_SCOPE}" -p "Generic Policy Scope> " POLICY_SCOPE read -e -i "${POLICY_VERSION}" -p "Generic Policy Version> " POLICY_VERSION @@ -133,6 +145,10 @@ if [ -z "${VPCI_CONTROL_LOOP_NAME}" ]; then echo "Aborting: VPCI Control Loop Na if [ -z "${VPCI_POLICY_NAME}" ]; then echo "Aborting: VPCI Policy Name not provided"; exit 1; fi if [ -z "${VPCI_CONTROL_LOOP_YAML}" ]; then echo "Aborting: VPCI Control Loop Yaml not provided"; exit 1; fi +if [ -z "${CCVPN_CONTROL_LOOP_NAME}" ]; then echo "Aborting: CCVPN Control Loop Name not provided"; exit 1; fi +if [ -z "${CCVPN_POLICY_NAME}" ]; then echo "Aborting: CCVPN Policy Name not provided"; exit 1; fi +if [ -z "${CCVPN_CONTROL_LOOP_YAML}" ]; then echo "Aborting: CCVPN Control Loop Yaml not provided"; exit 1; fi + if [ -z "${POLICY_SCOPE}" ]; then echo "Aborting: Template Policy Scope not provided"; exit 1; fi if [ -z "${POLICY_VERSION}" ]; then echo "Aborting: Template Policy Version not provided"; exit 1; fi @@ -179,6 +195,10 @@ echo "VPCI Drools Fact Generation: VPCI Control Loop Control Name: ${VPCI_CONTRO echo "VPCI Drools Fact Generation: VPCI Control Loop Policy Name: ${VPCI_POLICY_NAME}" echo "VPCI Drools Fact Generation: VPCI Control Loop Yaml: ${VPCI_CONTROL_LOOP_YAML}" echo +echo "CCVPN Drools Fact Generation: CCVPN Control Loop Control Name: ${CCVPN_CONTROL_LOOP_NAME}" +echo "CCVPN Drools Fact Generation: CCVPN Control Loop Policy Name: ${CCVPN_POLICY_NAME}" +echo "CCVPN Drools Fact Generation: CCVPN Control Loop Yaml: ${CCVPN_CONTROL_LOOP_YAML}" +echo echo "Generic Drools Fact: Control Loop Policy Scope: ${POLICY_SCOPE}" echo "Generic: Control Loop Policy Version: ${POLICY_VERSION}" echo @@ -272,6 +292,9 @@ mvn archetype:generate \ -DvpciClosedLoopControlName="${VPCI_CONTROL_LOOP_NAME}" \ -DvpciPolicyName="${VPCI_POLICY_NAME}" \ -DvpciControlLoopYaml="${VPCI_CONTROL_LOOP_YAML}" \ + -DccvpnClosedLoopControlName="${CCVPN_CONTROL_LOOP_NAME}" \ + -DccvpnPolicyName="${CCVPN_POLICY_NAME}" \ + -DccvpnControlLoopYaml="${CCVPN_CONTROL_LOOP_YAML}" \ -DpolicyScope="${POLICY_SCOPE}" \ -DpolicyVersion="${POLICY_VERSION}" \ -DbrmsgwTopic="${BRMSGW_TOPIC}" \ diff --git a/controlloop/packages/basex-controlloop/src/files/bin/push-policies-casablanca b/controlloop/packages/basex-controlloop/src/files/bin/push-policies-casablanca index b09ea800f..d8140c0a5 100644 --- a/controlloop/packages/basex-controlloop/src/files/bin/push-policies-casablanca +++ b/controlloop/packages/basex-controlloop/src/files/bin/push-policies-casablanca @@ -125,7 +125,17 @@ curl -k --silent --user @1b3rt:31nst31n -X PUT --header 'Content-Type: text/plai sleep 2 +echo +echo "Inserting CCVPN Policy..." +curl -k --silent --user @1b3rt:31nst31n -X PUT --header 'Content-Type: text/plain' -d '{ + "closedLoopControlName": "ControlLoop-CCVPN-2179b738-fd36-4843-a71a-a8c24c70c66b", + "controlLoopYaml": "controlLoop%3A%0D%0A++version%3A+2.0.0%0D%0A++controlLoopName%3A+ControlLoop-CCVPN-2179b738-fd36-4843-a71a-a8c24c70c66b%0D%0A++trigger_policy%3A+unique-policy-id-16-Reroute%0D%0A++timeout%3A+3600%0D%0A++abatement%3A+false%0D%0A+%0D%0Apolicies%3A%0D%0A++-+id%3A+unique-policy-id-16-Reroute%0D%0A++++name%3A+Connectivity Reroute%0D%0A++++description%3A%0D%0A++++actor%3A+SDNC%0D%0A++++recipe%3A+Reroute%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", + "policyName": "ccvpn", + "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 echo "Policy insertions completed." diff --git a/controlloop/templates/archetype-cl-amsterdam/src/main/resources/archetype-resources/src/main/config/CCVPN.yaml b/controlloop/templates/archetype-cl-amsterdam/src/main/resources/archetype-resources/src/main/config/CCVPN.yaml new file mode 100644 index 000000000..b5b37b0eb --- /dev/null +++ b/controlloop/templates/archetype-cl-amsterdam/src/main/resources/archetype-resources/src/main/config/CCVPN.yaml @@ -0,0 +1,36 @@ +# Copyright (C) 2018 Huawei. 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: 2.0.0 + controlLoopName: ${ccvpnClosedLoopControlName} + trigger_policy: unique-policy-id-16-Reroute + timeout: 3600 + abatement: false + +policies: + - id: unique-policy-id-16-Reroute + name: Connectivity Reroute + description: + actor: SDNC + recipe: Reroute + target: + type: VM + retry: 3 + timeout: 1200 + 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/dcae.ccvpn.onset.json b/controlloop/templates/archetype-cl-amsterdam/src/main/resources/archetype-resources/src/main/config/dcae.ccvpn.onset.json new file mode 100644 index 000000000..474911e74 --- /dev/null +++ b/controlloop/templates/archetype-cl-amsterdam/src/main/resources/archetype-resources/src/main/config/dcae.ccvpn.onset.json @@ -0,0 +1,21 @@ +{ + "closedLoopEventClient": "DCAE.HolmesInstance", + "policyVersion": "1.0.0.5", + "policyName": "CCVPN", + "policyScope": "service=SOTNService,type=SampleType,closedLoopControlName=CL-CCVPN-d925ed73-8231-4d02-9545-db4e101f88f8", + "target_type": "VM", + "AAI": { + "vserver.vserver-name" : "TBD", + "globalSubscriberId" : "e151059a-d924-4629-845f-264db19e50b4", + "serviceType" : "SOTN", + "service-information.service-instance-id" : "service-instance-id-example-1", + "network-information. network-id " : "id" + }, + "closedLoopAlarmStart": 1484677482204798, + "closedLoopEventStatus": "ONSET", + "closedLoopControlName": "${ccvpnClosedLoopControlName}", + "version": "1.0.2", + "target": "vserver.vserver-name", + "requestID": "97964e10-686e-4790-8c45-bdfa61df770f", + "from": "DCAE" +} diff --git a/controlloop/templates/archetype-cl-amsterdam/src/main/resources/archetype-resources/src/main/resources/__closedLoopControlName__.drl b/controlloop/templates/archetype-cl-amsterdam/src/main/resources/archetype-resources/src/main/resources/__closedLoopControlName__.drl index 48cfab24c..cac512eac 100644 --- a/controlloop/templates/archetype-cl-amsterdam/src/main/resources/archetype-resources/src/main/resources/__closedLoopControlName__.drl +++ b/controlloop/templates/archetype-cl-amsterdam/src/main/resources/archetype-resources/src/main/resources/__closedLoopControlName__.drl @@ -618,6 +618,11 @@ rule "${policyName}.EVENT.MANAGER.OPERATION.LOCKED.GUARD_PERMITTED" retract($operation); modify($manager) {finishOperation($operation)}; } + else if ("sdnc".equalsIgnoreCase($operation.policy.getActor())) { + retract($opTimer); + retract($operation); + modify($manager) {finishOperation($operation)}; + } } } catch (Exception e) { diff --git a/controlloop/templates/archetype-cl-casablanca/src/main/resources/META-INF/maven/archetype-metadata.xml b/controlloop/templates/archetype-cl-casablanca/src/main/resources/META-INF/maven/archetype-metadata.xml index 4ef410083..a96989acd 100644 --- a/controlloop/templates/archetype-cl-casablanca/src/main/resources/META-INF/maven/archetype-metadata.xml +++ b/controlloop/templates/archetype-cl-casablanca/src/main/resources/META-INF/maven/archetype-metadata.xml @@ -61,6 +61,15 @@ <requiredProperty key="volteControlLoopYaml"> <defaultValue>controlLoop%3A%0D%0A++version%3A+2.0.0%0D%0A++controlLoopName%3A+ControlLoop-VOLTE-2179b738-fd36-4843-a71a-a8c24c70c55b%0D%0A++trigger_policy%3A+unique-policy-id-1-restart%0D%0A++timeout%3A+3600%0D%0A++abatement%3A+false%0D%0A+%0D%0Apolicies%3A%0D%0A++-+id%3A+unique-policy-id-1-restart%0D%0A++++name%3A+Restart+the+VM%0D%0A++++description%3A%0D%0A++++actor%3A+VFC%0D%0A++++recipe%3A+Restart%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</defaultValue> </requiredProperty> + <requiredProperty key="ccvpnClosedLoopControlName"> + <defaultValue>ControlLoop-CCVPN-2179b738-fd36-4843-a71a-a8c24c70c66b</defaultValue> + </requiredProperty> + <requiredProperty key="ccvpnPolicyName"> + <defaultValue>CCVPN</defaultValue> + </requiredProperty> + <requiredProperty key="ccvpnControlLoopYaml"> + <defaultValue>controlLoop%3A%0D%0A++version%3A+2.0.0%0D%0A++controlLoopName%3A+ControlLoop-CCVPN-2179b738-fd36-4843-a71a-a8c24c70c66b%0D%0A++trigger_policy%3A+unique-policy-id-16-Reroute%0D%0A++timeout%3A+3600%0D%0A++abatement%3A+false%0D%0A+%0D%0Apolicies%3A%0D%0A++-+id%3A+unique-policy-id-16-Reroute%0D%0A++++name%3A+Connectivity Reroute%0D%0A++++description%3A%0D%0A++++actor%3A+SDNC%0D%0A++++recipe%3A+Reroute%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</defaultValue> + </requiredProperty> <requiredProperty key="policyScope"> <defaultValue>DCAE</defaultValue> </requiredProperty> diff --git a/controlloop/templates/archetype-cl-casablanca/src/main/resources/archetype-resources/src/main/config/CCVPN.yaml b/controlloop/templates/archetype-cl-casablanca/src/main/resources/archetype-resources/src/main/config/CCVPN.yaml new file mode 100644 index 000000000..b5b37b0eb --- /dev/null +++ b/controlloop/templates/archetype-cl-casablanca/src/main/resources/archetype-resources/src/main/config/CCVPN.yaml @@ -0,0 +1,36 @@ +# Copyright (C) 2018 Huawei. 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: 2.0.0 + controlLoopName: ${ccvpnClosedLoopControlName} + trigger_policy: unique-policy-id-16-Reroute + timeout: 3600 + abatement: false + +policies: + - id: unique-policy-id-16-Reroute + name: Connectivity Reroute + description: + actor: SDNC + recipe: Reroute + target: + type: VM + retry: 3 + timeout: 1200 + 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-casablanca/src/main/resources/archetype-resources/src/main/config/ccvpn.brmsgw.params.json b/controlloop/templates/archetype-cl-casablanca/src/main/resources/archetype-resources/src/main/config/ccvpn.brmsgw.params.json new file mode 100644 index 000000000..5feeecd9e --- /dev/null +++ b/controlloop/templates/archetype-cl-casablanca/src/main/resources/archetype-resources/src/main/config/ccvpn.brmsgw.params.json @@ -0,0 +1,7 @@ +{ + "closedLoopControlName": "${ccvpnClosedLoopControlName}", + "controlLoopYaml": "${ccvpnControlLoopYaml}", + "policyName": "${ccvpnPolicyName}", + "policyScope": "${policyScope}", + "policyVersion": "${policyVersion}" +}
\ No newline at end of file diff --git a/controlloop/templates/archetype-cl-casablanca/src/main/resources/archetype-resources/src/main/config/dcae.ccvpn.onset.json b/controlloop/templates/archetype-cl-casablanca/src/main/resources/archetype-resources/src/main/config/dcae.ccvpn.onset.json new file mode 100644 index 000000000..474911e74 --- /dev/null +++ b/controlloop/templates/archetype-cl-casablanca/src/main/resources/archetype-resources/src/main/config/dcae.ccvpn.onset.json @@ -0,0 +1,21 @@ +{ + "closedLoopEventClient": "DCAE.HolmesInstance", + "policyVersion": "1.0.0.5", + "policyName": "CCVPN", + "policyScope": "service=SOTNService,type=SampleType,closedLoopControlName=CL-CCVPN-d925ed73-8231-4d02-9545-db4e101f88f8", + "target_type": "VM", + "AAI": { + "vserver.vserver-name" : "TBD", + "globalSubscriberId" : "e151059a-d924-4629-845f-264db19e50b4", + "serviceType" : "SOTN", + "service-information.service-instance-id" : "service-instance-id-example-1", + "network-information. network-id " : "id" + }, + "closedLoopAlarmStart": 1484677482204798, + "closedLoopEventStatus": "ONSET", + "closedLoopControlName": "${ccvpnClosedLoopControlName}", + "version": "1.0.2", + "target": "vserver.vserver-name", + "requestID": "97964e10-686e-4790-8c45-bdfa61df770f", + "from": "DCAE" +} diff --git a/controlloop/templates/archetype-cl-casablanca/src/main/resources/archetype-resources/src/main/resources/__closedLoopControlName__.drl b/controlloop/templates/archetype-cl-casablanca/src/main/resources/archetype-resources/src/main/resources/__closedLoopControlName__.drl index 11855d47d..f2aa7ef16 100644 --- a/controlloop/templates/archetype-cl-casablanca/src/main/resources/archetype-resources/src/main/resources/__closedLoopControlName__.drl +++ b/controlloop/templates/archetype-cl-casablanca/src/main/resources/archetype-resources/src/main/resources/__closedLoopControlName__.drl @@ -579,6 +579,11 @@ rule "EVENT.MANAGER.OPERATION.LOCKED.GUARD_PERMITTED" retract($operation); modify($manager) {finishOperation($operation)}; } + else if ("sdnc".equalsIgnoreCase($operation.policy.getActor())) { + retract($opTimer); + retract($operation); + modify($manager) {finishOperation($operation)}; + } } } catch (Exception e) { diff --git a/controlloop/templates/template.demo/src/test/java/org/onap/policy/template/demo/CcvpnControlLoopTest.java b/controlloop/templates/template.demo/src/test/java/org/onap/policy/template/demo/CcvpnControlLoopTest.java new file mode 100644 index 000000000..1da3ff70c --- /dev/null +++ b/controlloop/templates/template.demo/src/test/java/org/onap/policy/template/demo/CcvpnControlLoopTest.java @@ -0,0 +1,356 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2018 Huawei. 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.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.sdnc.SdncRequest; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class CcvpnControlLoopTest implements TopicListener { + + private static final Logger logger = LoggerFactory.getLogger(CcvpnControlLoopTest.class); + + private static List<? extends TopicSink> noopTopics; + + private static KieSession kieSession; + private static Util.Pair<ControlLoopPolicy, String> pair; + + static { + /* Set environment properties */ + Util.setAaiProps(); + Util.setSdncProps(); + LoggerUtil.setLevel(LoggerUtil.ROOT_LOGGER, "INFO"); + } + + /** + * 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, "POLICY-CL-MGT"); + 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("junit.groupId", "junit.artifactId", "POLICY-CL-MGT", + "org.onap.policy.controlloop.VirtualControlLoopNotification", new JsonProtocolFilter(), + null, null,1111); + + try { + Util.buildAaiSim(); + Util.buildSdncSim(); + } 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_CCVPN.yaml", "type=operational", "Connectivity Reroute", + "2.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() throws IOException { + + /* + * 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); + } + + /* + * Simulate an onset event the policy engine will receive from DCAE to kick off processing + * through the rules + */ + sendEvent(pair.first); + + kieSession.fireUntilHalt(); + + /* + * The only fact in memory should be Params + */ + assertEquals(1, kieSession.getFactCount()); + + /* + * Print what's left in memory + */ + dumpFacts(kieSession); + } + + @Test + public void nullRequestTest() throws IOException { + + /* + * 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); + } + + /* + * Simulate an onset event the policy engine will receive from DCAE to kick off processing + * through the rules + */ + + VirtualControlLoopEvent event = new VirtualControlLoopEvent(); + event.setClosedLoopControlName(pair.first.getControlLoop().getControlLoopName()); + event.setRequestId(UUID.randomUUID()); + event.setClosedLoopEventClient("DCAE.HolmesInstance"); + event.setTargetType(ControlLoopTargetType.VM); + event.setTarget("vserver.vserver-name"); + event.setFrom("DCAE"); + event.setClosedLoopAlarmStart(Instant.now()); + event.setAai(new HashMap<String, String>()); + event.getAai().put("vserver.vserver-name", "nullRequest"); + event.setClosedLoopEventStatus(ControlLoopEventStatus.ONSET); + kieSession.insert(event); + + kieSession.fireUntilHalt(); + + /* + * 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 = Util.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 = Util.buildContainer(droolsTemplate, + pair.first.getControlLoop().getControlLoopName(), + policyScope, policyName, policyVersion, URLEncoder.encode(pair.second, "UTF-8")); + + /* + * Retrieve the Policy Engine + */ + + logger.debug("============"); + 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) { + /* + * 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, + VirtualControlLoopNotification.class); + } + assertNotNull(obj); + if (obj instanceof VirtualControlLoopNotification) { + VirtualControlLoopNotification notification = (VirtualControlLoopNotification) obj; + String policyName = notification.getPolicyName(); + if (policyName.endsWith("EVENT")) { + logger.debug("Rule Fired: " + notification.getPolicyName()); + assertTrue(ControlLoopNotificationType.ACTIVE.equals(notification.getNotification())); + } else if (policyName.endsWith("GUARD_NOT_YET_QUERIED")) { + logger.debug("Rule Fired: " + notification.getPolicyName()); + assertTrue(ControlLoopNotificationType.OPERATION.equals(notification.getNotification())); + assertNotNull(notification.getMessage()); + assertTrue(notification.getMessage().startsWith("Sending guard query")); + } else if (policyName.endsWith("GUARD.RESPONSE")) { + logger.debug("Rule Fired: " + notification.getPolicyName()); + assertTrue(ControlLoopNotificationType.OPERATION.equals(notification.getNotification())); + assertNotNull(notification.getMessage()); + assertTrue(notification.getMessage().toLowerCase().endsWith("permit")); + } else if (policyName.endsWith("GUARD_PERMITTED")) { + logger.debug("Rule Fired: " + notification.getPolicyName()); + assertTrue(ControlLoopNotificationType.OPERATION.equals(notification.getNotification())); + assertNotNull(notification.getMessage()); + assertTrue(notification.getMessage().startsWith("actor=SDNC")); + } else if (policyName.endsWith("OPERATION.TIMEOUT")) { + logger.debug("Rule Fired: " + notification.getPolicyName()); + kieSession.halt(); + logger.debug("The operation timed out"); + fail("Operation Timed Out"); + } else if (policyName.endsWith("SDNC.RESPONSE")) { + logger.debug("Rule Fired: " + notification.getPolicyName()); + assertTrue(ControlLoopNotificationType.OPERATION_SUCCESS.equals(notification.getNotification())); + assertNotNull(notification.getMessage()); + assertTrue(notification.getMessage().startsWith("actor=SDNC")); + } else if (policyName.endsWith("EVENT.MANAGER")) { + logger.debug("Rule Fired: " + notification.getPolicyName()); + if ("nullRequest".equals(notification.getAai().get("vserver.vserver-name"))) { + assertEquals(ControlLoopNotificationType.FINAL_FAILURE, notification.getNotification()); + } else { + assertEquals(ControlLoopNotificationType.FINAL_SUCCESS, notification.getNotification()); + } + kieSession.halt(); + } else if (policyName.endsWith("EVENT.MANAGER.TIMEOUT")) { + logger.debug("Rule Fired: " + notification.getPolicyName()); + kieSession.halt(); + logger.debug("The control loop timed out"); + fail("Control Loop Timed Out"); + } + } else if (obj instanceof SdncRequest) { + logger.debug("\n============ SDNC received the request!!! ===========\n"); + } + } + + /** + * This method is used to simulate event messages from DCAE that start the control loop (onset + * message) or end the control loop (abatement message). + * + * @param policy the controlLoopName comes from the policy + */ + protected void sendEvent(ControlLoopPolicy policy) { + VirtualControlLoopEvent event = new VirtualControlLoopEvent(); + event.setClosedLoopControlName(policy.getControlLoop().getControlLoopName()); + event.setRequestId(UUID.randomUUID()); + event.setClosedLoopEventClient("DCAE.HolmesInstance"); + event.setTargetType(ControlLoopTargetType.VM); + event.setTarget("vserver.vserver-name"); + event.setFrom("DCAE"); + event.setClosedLoopAlarmStart(Instant.now()); + event.setAai(new HashMap<String, String>()); + event.getAai().put("vserver.vserver-name", "TBD"); + event.getAai().put("globalSubscriberId", "e151059a-d924-4629-845f-264db19e50b4"); + event.getAai().put("serviceType", "SOTN"); + event.getAai().put("service-instance.service-instance-id", "service-instance-id-example-1"); + event.getAai().put("network-information.network-id", "id"); + event.setClosedLoopEventStatus(ControlLoopEventStatus.ONSET); + kieSession.insert(event); + } + + /** + * Dumps the kie session facts. + * + * @param kieSession input session + */ + public static 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/java/org/onap/policy/template/demo/Util.java b/controlloop/templates/template.demo/src/test/java/org/onap/policy/template/demo/Util.java index 4ec51772f..575068086 100644 --- a/controlloop/templates/template.demo/src/test/java/org/onap/policy/template/demo/Util.java +++ b/controlloop/templates/template.demo/src/test/java/org/onap/policy/template/demo/Util.java @@ -137,6 +137,10 @@ public final class Util { return org.onap.policy.simulators.Util.buildGuardSim(); } + public static HttpServletServer buildSdncSim() throws InterruptedException, IOException { + return org.onap.policy.simulators.Util.buildSdncSim(); + } + private static String generatePolicy(String ruleContents, String closedLoopControlName, String policyScope, @@ -293,6 +297,15 @@ public final class Util { } /** + * Set the SDNC properties. + */ + public static void setSdncProps() { + PolicyEngine.manager.setEnvironmentProperty("sdnc.url", "http://localhost:6670/restconf/operations"); + PolicyEngine.manager.setEnvironmentProperty("sdnc.username", "sdnc"); + PolicyEngine.manager.setEnvironmentProperty("sdnc.password", "sdnc"); + } + + /** * Set the Guard properties. */ public static void setGuardProps() { diff --git a/controlloop/templates/template.demo/src/test/resources/yaml/policy_ControlLoop_CCVPN.yaml b/controlloop/templates/template.demo/src/test/resources/yaml/policy_ControlLoop_CCVPN.yaml new file mode 100644 index 000000000..176c1dc0e --- /dev/null +++ b/controlloop/templates/template.demo/src/test/resources/yaml/policy_ControlLoop_CCVPN.yaml @@ -0,0 +1,37 @@ +# Copyright (C) 2018 Huawei. 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: 2.0.0 + controlLoopName: ControlLoop-CCVPN-2179b738-fd36-4843-a71a-a8c24c70c66b + trigger_policy: unique-policy-id-16-Reroute + timeout: 3600 + abatement: false + +policies: + - id: unique-policy-id-16-Reroute + name: Connectivity Reroute + description: + actor: SDNC + recipe: Reroute + target: + type: VM + retry: 3 + timeout: 1200 + 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 + |