From 6dfab64262ea5816c761042192c84e498a3177ab Mon Sep 17 00:00:00 2001 From: jhh Date: Wed, 12 Feb 2020 18:20:06 -0600 Subject: tosca compliant op policy support + vcpe test Tosca Compliant and Toscal Legacy Operational policies are both supported for backwards compatibility. vCPE usecase junits to support 2 equivalent policies, one tosca compliant and the other one legacy. Issue-ID: POLICY-2360 Signed-off-by: jhh Change-Id: Iafbfc92bbec42e6a3fe4ceb4a9a17c85e636ea14 Signed-off-by: jhh --- .../src/main/resources/META-INF/kmodule.xml | 4 +- .../src/main/resources/usecases.drl | 6 +- .../org/onap/policy/controlloop/UsecasesBase.java | 10 +- .../java/org/onap/policy/controlloop/VcpeTest.java | 44 ++- .../test/resources/vcpe/tosca-compliant-vcpe.json | 37 ++ .../src/test/resources/vcpe/tosca-legacy-vcpe.json | 9 + .../src/test/resources/vcpe/tosca-vcpe.json | 9 - controlloop/common/domains/pom.xml | 89 +++++ .../drools/models/domain/legacy/LegacyPolicy.java | 40 ++ .../models/domain/legacy/LegacyProperties.java | 41 +++ .../models/domain/operational/ActorOperation.java | 59 +++ .../models/domain/operational/Operation.java | 104 ++++++ .../domain/operational/OperationalPolicy.java | 40 ++ .../domain/operational/OperationalProperties.java | 69 ++++ .../domain/operational/OperationalTarget.java | 48 +++ ...icies.controlloop.Operational-1.0.0.schema.json | 91 +++++ ...oop.operational.common.Drools-1.0.0.schema.json | 327 +++++++++++++++++ .../domain/operational/OperationalPolicyTest.java | 170 +++++++++ .../src/test/resources/tosca-legacy-vcpe.json | 9 + controlloop/common/eventmanager/pom.xml | 402 +++++++++++---------- .../controlloop/drl/legacy/ControlLoopParams.java | 3 +- .../eventmanager/ControlLoopEventManager.java | 46 ++- .../processor/ControlLoopProcessor.java | 109 +++++- .../policy/controlloop/utils/ControlLoopUtils.java | 32 +- .../drl/legacy/ControlLoopParamsTest.java | 26 +- .../eventmanager/ControlLoopEventManagerTest.java | 120 +++--- .../processor/ControlLoopProcessorTest.java | 34 +- .../controlloop/utils/ControlLoopUtilsTest.java | 20 +- .../resources/tosca-policy-compliant-vcpe.json | 37 ++ .../test/resources/tosca-policy-legacy-vcpe.json | 9 + .../tosca-policy-operational-restart.json | 9 - .../server/restful/RestControlLoopManager.java | 113 ------ .../server/restful/RestControlLoopManagerTest.java | 23 +- .../common/feature-controlloop-usecases/pom.xml | 10 +- controlloop/common/pom.xml | 3 +- 35 files changed, 1674 insertions(+), 528 deletions(-) create mode 100644 controlloop/common/controller-usecases/src/test/resources/vcpe/tosca-compliant-vcpe.json create mode 100644 controlloop/common/controller-usecases/src/test/resources/vcpe/tosca-legacy-vcpe.json delete mode 100644 controlloop/common/controller-usecases/src/test/resources/vcpe/tosca-vcpe.json create mode 100644 controlloop/common/domains/pom.xml create mode 100644 controlloop/common/domains/src/main/java/org/onap/policy/drools/models/domain/legacy/LegacyPolicy.java create mode 100644 controlloop/common/domains/src/main/java/org/onap/policy/drools/models/domain/legacy/LegacyProperties.java create mode 100644 controlloop/common/domains/src/main/java/org/onap/policy/drools/models/domain/operational/ActorOperation.java create mode 100644 controlloop/common/domains/src/main/java/org/onap/policy/drools/models/domain/operational/Operation.java create mode 100644 controlloop/common/domains/src/main/java/org/onap/policy/drools/models/domain/operational/OperationalPolicy.java create mode 100644 controlloop/common/domains/src/main/java/org/onap/policy/drools/models/domain/operational/OperationalProperties.java create mode 100644 controlloop/common/domains/src/main/java/org/onap/policy/drools/models/domain/operational/OperationalTarget.java create mode 100644 controlloop/common/domains/src/main/resources/schemas/onap.policies.controlloop.Operational-1.0.0.schema.json create mode 100644 controlloop/common/domains/src/main/resources/schemas/onap.policies.controlloop.operational.common.Drools-1.0.0.schema.json create mode 100644 controlloop/common/domains/src/test/java/org/onap/policy/drools/models/domain/operational/OperationalPolicyTest.java create mode 100644 controlloop/common/domains/src/test/resources/tosca-legacy-vcpe.json create mode 100644 controlloop/common/eventmanager/src/test/resources/tosca-policy-compliant-vcpe.json create mode 100644 controlloop/common/eventmanager/src/test/resources/tosca-policy-legacy-vcpe.json delete mode 100644 controlloop/common/eventmanager/src/test/resources/tosca-policy-operational-restart.json (limited to 'controlloop') diff --git a/controlloop/common/controller-usecases/src/main/resources/META-INF/kmodule.xml b/controlloop/common/controller-usecases/src/main/resources/META-INF/kmodule.xml index 4fe7da112..e1a23863a 100644 --- a/controlloop/common/controller-usecases/src/main/resources/META-INF/kmodule.xml +++ b/controlloop/common/controller-usecases/src/main/resources/META-INF/kmodule.xml @@ -19,7 +19,9 @@ ============LICENSE_END========================================================= --> - + + diff --git a/controlloop/common/controller-usecases/src/main/resources/usecases.drl b/controlloop/common/controller-usecases/src/main/resources/usecases.drl index e070b0219..3fe2cddbf 100644 --- a/controlloop/common/controller-usecases/src/main/resources/usecases.drl +++ b/controlloop/common/controller-usecases/src/main/resources/usecases.drl @@ -108,8 +108,8 @@ rule "INSERT.PARAMS" then Logger logger = LoggerFactory.getLogger(drools.getRule().getPackage()); - logger.info("{}: {} : YAML=[{}]", $params.getClosedLoopControlName(), $params.getPolicyName() + "." - + drools.getRule().getName(), $params.getControlLoopYaml()); + logger.info("{}: {} : TOSCA-POLICY=[{}]", $params.getClosedLoopControlName(), $params.getPolicyName() + "." + + drools.getRule().getName(), $params.getToscaPolicy()); end /* @@ -200,7 +200,7 @@ rule "EVENT" // Determine if EventManager can actively process the event // (i.e. syntax, is_closed_loop_disabled checks etc.) // - VirtualControlLoopNotification notification = manager.activate($params.getControlLoopYaml(), $event); + VirtualControlLoopNotification notification = manager.activate($params.getToscaPolicy(), $event); notification.setFrom("pdp-0001-controller=controlloop"); // Engine.getInstanceName() notification.setPolicyName($params.getPolicyName() + "." + drools.getRule().getName()); notification.setPolicyScope($params.getPolicyScope()); diff --git a/controlloop/common/controller-usecases/src/test/java/org/onap/policy/controlloop/UsecasesBase.java b/controlloop/common/controller-usecases/src/test/java/org/onap/policy/controlloop/UsecasesBase.java index 1fe6ace44..618963a70 100644 --- a/controlloop/common/controller-usecases/src/test/java/org/onap/policy/controlloop/UsecasesBase.java +++ b/controlloop/common/controller-usecases/src/test/java/org/onap/policy/controlloop/UsecasesBase.java @@ -146,7 +146,7 @@ public abstract class UsecasesBase { return usecases .getDrools() .facts(USECASES, ControlLoopParams.class).stream() - .filter((params) -> params.getControlLoopYaml() == policy.getProperties().get("content")) + .filter((params) -> params.getToscaPolicy() == policy) .findFirst() .get(); } @@ -178,7 +178,7 @@ public abstract class UsecasesBase { usecases .getDrools() .facts(USECASES, ControlLoopParams.class).stream() - .filter((params) -> params.getControlLoopYaml() == policy.getProperties().get("content")) + .filter((params) -> params.getToscaPolicy() == policy) .count()); return policy; @@ -209,18 +209,18 @@ public abstract class UsecasesBase { usecases .getDrools() .facts(USECASES, ControlLoopParams.class).stream() - .filter((params) -> params.getControlLoopYaml() == policy.getProperties().get("content")) + .filter((params) -> params.getPolicyName() == policy.getName()) .count()); } /** * Prepare a PDP-D to test the Use Cases. */ - protected static void preparePdpD() throws IOException, InterruptedException, CoderException { + protected static void preparePdpD() throws IOException { KieUtils.installArtifact( Paths.get("src/main/resources/META-INF/kmodule.xml").toFile(), Paths.get("src/test/resources/usecases.pom").toFile(), - "src/main/resources/onap.policies.controlloop.Operational/org/onap/policy/controlloop/", + "src/main/resources/org/onap/policy/controlloop/", Collections.singletonList(Paths.get("src/main/resources/usecases.drl").toFile())); repo.setConfigurationDir("src/test/resources/config"); diff --git a/controlloop/common/controller-usecases/src/test/java/org/onap/policy/controlloop/VcpeTest.java b/controlloop/common/controller-usecases/src/test/java/org/onap/policy/controlloop/VcpeTest.java index 8690f1a0a..1d9d0dd26 100644 --- a/controlloop/common/controller-usecases/src/test/java/org/onap/policy/controlloop/VcpeTest.java +++ b/controlloop/common/controller-usecases/src/test/java/org/onap/policy/controlloop/VcpeTest.java @@ -42,7 +42,8 @@ public class VcpeTest extends UsecasesBase { /** * VCPE Tosca Policy File. */ - private static final String TOSCA_POLICY_VCPE = "src/test/resources/vcpe/tosca-vcpe.json"; + private static final String TOSCA_LEGACY_POLICY_VCPE = "src/test/resources/vcpe/tosca-legacy-vcpe.json"; + private static final String TOSCA_COMPLIANT_POLICY_VCPE = "src/test/resources/vcpe/tosca-compliant-vcpe.json"; /* * VCPE Use case Messages. @@ -86,7 +87,6 @@ public class VcpeTest extends UsecasesBase { /** * Sunny day scenario for the VCPE use case. */ - @Test public void sunnyDay() throws IOException { /* Inject an ONSET event over the DCAE topic */ @@ -121,13 +121,41 @@ public class VcpeTest extends UsecasesBase { waitForFinalSuccess(policy, policyClMgt); } + /** + * Sunny Day with Legacy Tosca Policy. + */ + @Test + public void sunnyDayLegacy() throws InterruptedException, CoderException, IOException { + assertEquals(0, usecases.getDrools().factCount(USECASES)); + policy = setupPolicy(TOSCA_LEGACY_POLICY_VCPE); + assertEquals(2, usecases.getDrools().factCount(USECASES)); + + sunnyDay(); + } + + /** + * Sunny Day with Tosca Compliant Policy. + */ + @Test + public void sunnyDayCompliant() throws InterruptedException, CoderException, IOException { + assertEquals(0, usecases.getDrools().factCount(USECASES)); + policy = setupPolicy(TOSCA_COMPLIANT_POLICY_VCPE); + assertEquals(2, usecases.getDrools().factCount(USECASES)); + + sunnyDay(); + } + /** * An ONSET flood prevention test that injects a few ONSETs at once. * It attempts to simulate the flooding behavior of the DCAE TCA microservice. * TCA could blast tenths or hundreds of ONSETs within sub-second intervals. */ @Test - public void onsetFloodPrevention() throws IOException { + public void onsetFloodPrevention() throws IOException, InterruptedException, CoderException { + assertEquals(0, usecases.getDrools().factCount(USECASES)); + policy = setupPolicy(TOSCA_LEGACY_POLICY_VCPE); + assertEquals(2, usecases.getDrools().factCount(USECASES)); + injectOnTopic(DCAE_TOPIC, Paths.get(ONSET_1)); injectOnTopic(DCAE_TOPIC, Paths.get(ONSET_2)); injectOnTopic(DCAE_TOPIC, Paths.get(ONSET_3)); @@ -168,16 +196,6 @@ public class VcpeTest extends UsecasesBase { } } - /** - * Install Policy. - */ - @Before - public void installPolicy() throws IOException, CoderException, InterruptedException { - assertEquals(0, usecases.getDrools().factCount(USECASES)); - policy = setupPolicy(TOSCA_POLICY_VCPE); - assertEquals(2, usecases.getDrools().factCount(USECASES)); - } - /** * Uninstall Policy. */ diff --git a/controlloop/common/controller-usecases/src/test/resources/vcpe/tosca-compliant-vcpe.json b/controlloop/common/controller-usecases/src/test/resources/vcpe/tosca-compliant-vcpe.json new file mode 100644 index 000000000..c01f6898c --- /dev/null +++ b/controlloop/common/controller-usecases/src/test/resources/vcpe/tosca-compliant-vcpe.json @@ -0,0 +1,37 @@ +{ + "type": "onap.policies.controlloop.operational.common.Drools", + "type_version": "1.0.0", + "version": "1.0.0", + "name": "operational.restart", + "metadata": { + "policy-id": "operational.restart" + }, + "properties": { + "id": "ControlLoop-vCPE-48f0c2c3-a172-4192-9ae3-052274181b6e", + "timeout": 3600, + "abatement": false, + "trigger": "unique-policy-id-1-restart", + "operations": [ + { + "id": "unique-policy-id-1-restart", + "description": "Restart the VM", + "operation": { + "actor": "APPC", + "operation": "Restart", + "target": { + "type": "VM" + } + }, + "timeout": 1200, + "retries": 3, + "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" + } + ], + "controllerName": "usecases" + } +} \ No newline at end of file diff --git a/controlloop/common/controller-usecases/src/test/resources/vcpe/tosca-legacy-vcpe.json b/controlloop/common/controller-usecases/src/test/resources/vcpe/tosca-legacy-vcpe.json new file mode 100644 index 000000000..f42c07da9 --- /dev/null +++ b/controlloop/common/controller-usecases/src/test/resources/vcpe/tosca-legacy-vcpe.json @@ -0,0 +1,9 @@ +{ + "type": "onap.policies.controlloop.Operational", + "type_version": "1.0.0", + "properties": { + "content": "controlLoop%3A%0A%20%20version%3A%202.0.0%0A%20%20controlLoopName%3A%20ControlLoop-vCPE-48f0c2c3-a172-4192-9ae3-052274181b6e%0A%20%20trigger_policy%3A%20unique-policy-id-1-restart%0A%20%20timeout%3A%203600%0A%20%20abatement%3A%20false%0A%20%0Apolicies%3A%0A%20%20-%20id%3A%20unique-policy-id-1-restart%0A%20%20%20%20name%3A%20Restart%20the%20VM%0A%20%20%20%20description%3A%0A%20%20%20%20actor%3A%20APPC%0A%20%20%20%20recipe%3A%20Restart%0A%20%20%20%20target%3A%0A%20%20%20%20%20%20type%3A%20VM%0A%20%20%20%20retry%3A%203%0A%20%20%20%20timeout%3A%201200%0A%20%20%20%20success%3A%20final_success%0A%20%20%20%20failure%3A%20final_failure%0A%20%20%20%20failure_timeout%3A%20final_failure_timeout%0A%20%20%20%20failure_retries%3A%20final_failure_retries%0A%20%20%20%20failure_exception%3A%20final_failure_exception%0A%20%20%20%20failure_guard%3A%20final_failure_guard" + }, + "name": "vcpe", + "version": "1.0.0" +} \ No newline at end of file diff --git a/controlloop/common/controller-usecases/src/test/resources/vcpe/tosca-vcpe.json b/controlloop/common/controller-usecases/src/test/resources/vcpe/tosca-vcpe.json deleted file mode 100644 index f42c07da9..000000000 --- a/controlloop/common/controller-usecases/src/test/resources/vcpe/tosca-vcpe.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "type": "onap.policies.controlloop.Operational", - "type_version": "1.0.0", - "properties": { - "content": "controlLoop%3A%0A%20%20version%3A%202.0.0%0A%20%20controlLoopName%3A%20ControlLoop-vCPE-48f0c2c3-a172-4192-9ae3-052274181b6e%0A%20%20trigger_policy%3A%20unique-policy-id-1-restart%0A%20%20timeout%3A%203600%0A%20%20abatement%3A%20false%0A%20%0Apolicies%3A%0A%20%20-%20id%3A%20unique-policy-id-1-restart%0A%20%20%20%20name%3A%20Restart%20the%20VM%0A%20%20%20%20description%3A%0A%20%20%20%20actor%3A%20APPC%0A%20%20%20%20recipe%3A%20Restart%0A%20%20%20%20target%3A%0A%20%20%20%20%20%20type%3A%20VM%0A%20%20%20%20retry%3A%203%0A%20%20%20%20timeout%3A%201200%0A%20%20%20%20success%3A%20final_success%0A%20%20%20%20failure%3A%20final_failure%0A%20%20%20%20failure_timeout%3A%20final_failure_timeout%0A%20%20%20%20failure_retries%3A%20final_failure_retries%0A%20%20%20%20failure_exception%3A%20final_failure_exception%0A%20%20%20%20failure_guard%3A%20final_failure_guard" - }, - "name": "vcpe", - "version": "1.0.0" -} \ No newline at end of file diff --git a/controlloop/common/domains/pom.xml b/controlloop/common/domains/pom.xml new file mode 100644 index 000000000..c278cb577 --- /dev/null +++ b/controlloop/common/domains/pom.xml @@ -0,0 +1,89 @@ + + + 4.0.0 + + + org.onap.policy.drools-applications.controlloop.common + drools-applications-common + 1.6.0-SNAPSHOT + + + domains + + + + junit + junit + test + + + + org.onap.policy.drools-pdp + policy-management + ${version.policy.drools-pdp} + provided + + + + org.assertj + assertj-core + test + + + + + + + maven-checkstyle-plugin + + + onap-java-style + + check + + process-sources + + onap-checkstyle/onap-java-style.xml + ${project.build.sourceDirectory} + true + true + true + + + true + warning + + + + + + org.onap.oparent + checkstyle + ${oparent.version} + compile + + + + + + diff --git a/controlloop/common/domains/src/main/java/org/onap/policy/drools/models/domain/legacy/LegacyPolicy.java b/controlloop/common/domains/src/main/java/org/onap/policy/drools/models/domain/legacy/LegacyPolicy.java new file mode 100644 index 000000000..6f33ec43a --- /dev/null +++ b/controlloop/common/domains/src/main/java/org/onap/policy/drools/models/domain/legacy/LegacyPolicy.java @@ -0,0 +1,40 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP + * ================================================================================ + * Copyright (C) 2020 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.drools.models.domain.legacy; + +import java.io.Serializable; +import lombok.Data; +import lombok.experimental.SuperBuilder; +import org.onap.policy.drools.domain.models.DroolsPolicy; + + +/** + * Operational Domain Policy. + */ + +@Data +@SuperBuilder +public class LegacyPolicy extends DroolsPolicy implements Serializable { + private static final long serialVersionUID = 4100092564657497713L; + + private LegacyProperties properties; + +} diff --git a/controlloop/common/domains/src/main/java/org/onap/policy/drools/models/domain/legacy/LegacyProperties.java b/controlloop/common/domains/src/main/java/org/onap/policy/drools/models/domain/legacy/LegacyProperties.java new file mode 100644 index 000000000..7d07f85bd --- /dev/null +++ b/controlloop/common/domains/src/main/java/org/onap/policy/drools/models/domain/legacy/LegacyProperties.java @@ -0,0 +1,41 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP + * ================================================================================ + * Copyright (C) 2020 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.drools.models.domain.legacy; + +import java.io.Serializable; +import lombok.Builder; +import lombok.Data; + + +/** + * Legacy Operational Policy Properties. + */ + +@Data +@Builder +public class LegacyProperties implements Serializable { + private static final long serialVersionUID = 2455300363502597721L; + + /** + * Content (Operational Policy URL encoded yaml). + */ + private String content; +} diff --git a/controlloop/common/domains/src/main/java/org/onap/policy/drools/models/domain/operational/ActorOperation.java b/controlloop/common/domains/src/main/java/org/onap/policy/drools/models/domain/operational/ActorOperation.java new file mode 100644 index 000000000..0f159275d --- /dev/null +++ b/controlloop/common/domains/src/main/java/org/onap/policy/drools/models/domain/operational/ActorOperation.java @@ -0,0 +1,59 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP + * ================================================================================ + * Copyright (C) 2020 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.drools.models.domain.operational; + +import java.io.Serializable; +import java.util.HashMap; +import java.util.Map; +import lombok.Builder; +import lombok.Data; + + +/** + * Actor Operation. + */ + +@Data +@Builder +public class ActorOperation implements Serializable { + private static final long serialVersionUID = -534488831693359530L; + + /** + * Actor. + */ + private String actor; + + /** + * Operation Name. + */ + private String operation; + + /** + * Target. + */ + private OperationalTarget target; + + /** + * Payload. + */ + @Builder.Default + private Map payload = new HashMap<>(); +} diff --git a/controlloop/common/domains/src/main/java/org/onap/policy/drools/models/domain/operational/Operation.java b/controlloop/common/domains/src/main/java/org/onap/policy/drools/models/domain/operational/Operation.java new file mode 100644 index 000000000..68eec88fb --- /dev/null +++ b/controlloop/common/domains/src/main/java/org/onap/policy/drools/models/domain/operational/Operation.java @@ -0,0 +1,104 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP + * ================================================================================ + * Copyright (C) 2020 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.drools.models.domain.operational; + +import com.google.gson.annotations.SerializedName; +import java.io.Serializable; +import lombok.Builder; +import lombok.Data; + +/** + * Policy Operation. + */ + +@Data +@Builder +public class Operation implements Serializable { + private static final long serialVersionUID = 6175229119078195110L; + + /** + * Operation Identifier. + */ + private String id; + + /** + * Description. + */ + private String description; + + /** + * Actor Operation. + */ + @SerializedName("operation") + private ActorOperation actorOperation; + + /** + * Operation Timeout in seconds. + */ + @Builder.Default + private int timeout = 10; + + /** + * Number of Retries. + */ + @Builder.Default + private int retries = 0; + + /** + * Success Treatment. + */ + @Builder.Default + private String success = "final_success"; + + /** + * Failure Treatment. + */ + @Builder.Default + private String failure = "final_failure"; + + /** + * Failure Timeout Treatment. + */ + @SerializedName("failure_timeout") + @Builder.Default + private String failureTimeout = "final_failure_timeout"; + + /** + * Failure Retry Treatment. + */ + @SerializedName("failure_retries") + @Builder.Default + private String failureRetries = "final_failure_retries"; + + /** + * Failure Exception Treatment. + */ + @SerializedName("failure_exception") + @Builder.Default + private String failureException = "final_failure_exception"; + + /** + * Failure Guard Treatment. + */ + @SerializedName("failure_guard") + @Builder.Default + private String failureGuard = "final_failure_guard"; +} diff --git a/controlloop/common/domains/src/main/java/org/onap/policy/drools/models/domain/operational/OperationalPolicy.java b/controlloop/common/domains/src/main/java/org/onap/policy/drools/models/domain/operational/OperationalPolicy.java new file mode 100644 index 000000000..e746d33e6 --- /dev/null +++ b/controlloop/common/domains/src/main/java/org/onap/policy/drools/models/domain/operational/OperationalPolicy.java @@ -0,0 +1,40 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP + * ================================================================================ + * Copyright (C) 2020 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.drools.models.domain.operational; + +import java.io.Serializable; +import lombok.Data; +import lombok.experimental.SuperBuilder; +import org.onap.policy.drools.domain.models.DroolsPolicy; + + +/** + * Operational Domain Policy. + */ + +@Data +@SuperBuilder +public class OperationalPolicy extends DroolsPolicy implements Serializable { + private static final long serialVersionUID = 4100092564657497713L; + + private OperationalProperties properties; + +} diff --git a/controlloop/common/domains/src/main/java/org/onap/policy/drools/models/domain/operational/OperationalProperties.java b/controlloop/common/domains/src/main/java/org/onap/policy/drools/models/domain/operational/OperationalProperties.java new file mode 100644 index 000000000..a1563168c --- /dev/null +++ b/controlloop/common/domains/src/main/java/org/onap/policy/drools/models/domain/operational/OperationalProperties.java @@ -0,0 +1,69 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP + * ================================================================================ + * Copyright (C) 2020 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.drools.models.domain.operational; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.List; +import lombok.Builder; +import lombok.Data; + + +/** + * Operational Policy Properties. + */ + +@Data +@Builder +public class OperationalProperties implements Serializable { + private static final long serialVersionUID = 2455300363502597721L; + + /** + * Control Loop Name. + */ + private String id; + + /** + * Timeout in seconds. + */ + private int timeout = 30; + + /** + * Abatement. + */ + private boolean abatement = false; + + /** + * Trigger Operation. + */ + private String trigger; + + /** + * Operations. + */ + @Builder.Default + private List operations = new ArrayList<>(); + + /** + * Controller Name. + */ + private String controllerName; +} diff --git a/controlloop/common/domains/src/main/java/org/onap/policy/drools/models/domain/operational/OperationalTarget.java b/controlloop/common/domains/src/main/java/org/onap/policy/drools/models/domain/operational/OperationalTarget.java new file mode 100644 index 000000000..9e570ba7d --- /dev/null +++ b/controlloop/common/domains/src/main/java/org/onap/policy/drools/models/domain/operational/OperationalTarget.java @@ -0,0 +1,48 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP + * ================================================================================ + * Copyright (C) 2020 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.drools.models.domain.operational; + +import com.google.gson.annotations.SerializedName; +import java.io.Serializable; +import lombok.Builder; +import lombok.Data; + + +/** + * Operational Target. + */ + +@Data +@Builder +public class OperationalTarget implements Serializable { + private static final long serialVersionUID = -3557887855401250181L; + + /** + * Target Type. + */ + private String type; + + /** + * Resource ID. + */ + @SerializedName("resourceID") + private String resourceId; +} diff --git a/controlloop/common/domains/src/main/resources/schemas/onap.policies.controlloop.Operational-1.0.0.schema.json b/controlloop/common/domains/src/main/resources/schemas/onap.policies.controlloop.Operational-1.0.0.schema.json new file mode 100644 index 000000000..801859beb --- /dev/null +++ b/controlloop/common/domains/src/main/resources/schemas/onap.policies.controlloop.Operational-1.0.0.schema.json @@ -0,0 +1,91 @@ +{ + "definitions": {}, + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "http://www.onap.org/policy/models/schemas/onap.policies.controlloop.Operational.schema.json", + "type": "object", + "title": "Root Schema for legacy onap.policies.controlloop.Operational policy type domain policies", + "required": [ + "type", + "type_version", + "name", + "version", + "properties" + ], + "properties": { + "type": { + "$id": "#/properties/type", + "type": "string", + "title": "Policy Type", + "default": "onap.policies.controlloop.Operational", + "examples": [ + "onap.policies.controlloop.Operational" + ], + "pattern": "^(.+)$" + }, + "type_version": { + "$id": "#/properties/type_version", + "type": "string", + "title": "Policy Type Version", + "examples": [ + "1.0.0" + ], + "pattern": "^(.+)$" + }, + "version": { + "$id": "#/properties/version", + "type": "string", + "title": "Version", + "examples": [ + "1.0.0" + ], + "pattern": "^(.+)$" + }, + "name": { + "$id": "#/properties/name", + "type": "string", + "title": "Name", + "examples": [ + "example" + ], + "pattern": "^(.+)$" + }, + "metadata": { + "$id": "#/properties/metadata", + "type": "object", + "title": "Metadata", + "required": [ + "policy-id" + ], + "properties": { + "policy-id": { + "$id": "#/properties/metadata/properties/policy-id", + "type": "string", + "title": "Policy Name", + "examples": [ + "example" + ], + "pattern": "^(.+)$" + } + } + }, + "properties": { + "$id": "#/properties/properties", + "type": "object", + "title": "Properties", + "required": [ + "content" + ], + "properties": { + "content": { + "$id": "#/properties/properties/properties/content", + "type": "string", + "title": "Legacy policy in yaml format", + "examples": [ + "controlLoop%3A%0A%20%20version%3A%202.0.0%0A%20%20controlLoopName%3A%20ControlLoop-vCPEv2-48f0c2c3-a172-4192-9ae3-052274181b6e%0A%20%20trigger_policy%3A%20unique-policy-id-1-restart%0A%20%20timeout%3A%203600%0A%20%20abatement%3A%20true%0A%20%0Apolicies%3A%0A%20%20-%20id%3A%20unique-policy-id-1-restart%0A%20%20%20%20name%3A%20Restart%20the%20VM%0A%20%20%20%20description%3A%0A%20%20%20%20actor%3A%20APPC%0A%20%20%20%20recipe%3A%20Restart%0A%20%20%20%20target%3A%0A%20%20%20%20%20%20type%3A%20VM%0A%20%20%20%20retry%3A%203%0A%20%20%20%20timeout%3A%201200%0A%20%20%20%20success%3A%20final_success%0A%20%20%20%20failure%3A%20final_failure%0A%20%20%20%20failure_timeout%3A%20final_failure_timeout%0A%20%20%20%20failure_retries%3A%20final_failure_retries%0A%20%20%20%20failure_exception%3A%20final_failure_exception%0A%20%20%20%20failure_guard%3A%20final_failure_guard" + ], + "pattern": "^(.+)$" + } + } + } + } +} diff --git a/controlloop/common/domains/src/main/resources/schemas/onap.policies.controlloop.operational.common.Drools-1.0.0.schema.json b/controlloop/common/domains/src/main/resources/schemas/onap.policies.controlloop.operational.common.Drools-1.0.0.schema.json new file mode 100644 index 000000000..e3569f122 --- /dev/null +++ b/controlloop/common/domains/src/main/resources/schemas/onap.policies.controlloop.operational.common.Drools-1.0.0.schema.json @@ -0,0 +1,327 @@ +{ + "definitions": {}, + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "http://www.onap.org/policy/models/schemas/onap.policies.controlloop.operational.common.Drools.schema.json", + "type": "object", + "title": "The Root Schema", + "required": [ + "type", + "type_version", + "version", + "metadata", + "properties" + ], + "properties": { + "type": { + "$id": "#/properties/type", + "type": "string", + "title": "Policy Type", + "default": "onap.policies.controlloop.operational.common.Drools", + "examples": [ + "onap.policies.controlloop.operational.common.Drools" + ], + "pattern": "^(.+)$" + }, + "type_version": { + "$id": "#/properties/type_version", + "type": "string", + "title": "Policy Type Version", + "default": "1.0.0", + "examples": [ + "1.0.0" + ], + "pattern": "^(.+)$" + }, + "name": { + "$id": "#/properties/name", + "type": "string", + "title": "Policy Name", + "default": "", + "examples": [ + "example" + ], + "pattern": "^(.*)$" + }, + "version": { + "$id": "#/properties/version", + "type": "string", + "title": "Policy Version", + "default": "1.0.0", + "examples": [ + "1.0.0" + ], + "pattern": "^(.+)$" + }, + "metadata": { + "$id": "#/properties/metadata", + "type": "object", + "title": "Metadata", + "required": [ + "policy-id" + ], + "properties": { + "policy-id": { + "$id": "#/properties/metadata/properties/policy-id", + "type": "string", + "title": "Policy ID", + "examples": [ + "operational.restart" + ], + "pattern": "^(.+)$" + } + } + }, + "properties": { + "$id": "#/properties/properties", + "type": "object", + "title": "Properties", + "required": [ + "id", + "timeout", + "abatement", + "trigger", + "operations", + "controllerName" + ], + "properties": { + "id": { + "$id": "#/properties/properties/properties/id", + "type": "string", + "title": "Control Loop Name", + "examples": [ + "ControlLoop-vCPE-48f0c2c3-a172-4192-9ae3-052274181b6e" + ], + "pattern": "^(.+)$" + }, + "timeout": { + "$id": "#/properties/properties/properties/timeout", + "type": "integer", + "title": "Timeout in seconds", + "minimum": 1, + "default": 30, + "examples": [ + 3600 + ] + }, + "abatement": { + "$id": "#/properties/properties/properties/abatement", + "type": "boolean", + "title": "Abatement", + "default": false, + "examples": [ + true + ] + }, + "trigger": { + "$id": "#/properties/properties/properties/trigger", + "type": "string", + "title": "Trigger Operation", + "examples": [ + "unique-policy-id-1-restart" + ], + "pattern": "^(.+)$" + }, + "operations": { + "$id": "#/properties/properties/properties/operations", + "type": "array", + "title": "Operations", + "items": { + "$id": "#/properties/properties/properties/operations/items", + "type": "object", + "title": "Items", + "uniqueItems": true, + "required": [ + "id", + "operation", + "timeout", + "retries", + "success", + "failure" + ], + "properties": { + "id": { + "$id": "#/properties/properties/properties/operations/items/properties/id", + "type": "string", + "title": "Operation Identifier", + "examples": [ + "unique-policy-id-1-restart" + ], + "pattern": "^(.+)$" + }, + "description": { + "$id": "#/properties/properties/properties/operations/items/properties/description", + "type": "string", + "title": "Description", + "examples": [ + "Restart the VM" + ], + "pattern": "^(.+)$" + }, + "operation": { + "$id": "#/properties/properties/properties/operations/items/properties/operation", + "type": "object", + "title": "Operation", + "required": [ + "actor", + "operation", + "target" + ], + "properties": { + "actor": { + "$id": "#/properties/properties/properties/operations/items/properties/operation/properties/actor", + "type": "string", + "title": "Actor", + "examples": [ + "APPC" + ], + "pattern": "^(.+)$" + }, + "operation": { + "$id": "#/properties/properties/properties/operations/items/properties/operation/properties/operation", + "type": "string", + "title": "Operation Name", + "examples": [ + "Restart" + ], + "pattern": "^(.+)$" + }, + "target": { + "$id": "#/properties/properties/properties/operations/items/properties/operation/properties/target", + "type": "object", + "title": "Target", + "required": [ + "type" + ], + "properties": { + "type": { + "$id": "#/properties/properties/properties/operations/items/properties/operation/properties/target/properties/type", + "type": "string", + "title": "Target Type", + "examples": [ + "VNF" + ], + "pattern": "^(.+)$" + }, + "resourceID": { + "$id": "#/properties/properties/properties/operations/items/properties/operation/properties/target/properties/resourceID", + "type": "string", + "title": "Resource ID", + "examples": [ + "Eace933104d443b496b8.nodes.heat.vpg" + ], + "pattern": "^(.+)$" + } + } + }, + "payload": { + "$id": "#/properties/properties/properties/operations/items/properties/operation/properties/payload", + "type": "object", + "title": "Payload", + "additionalProperties": { + "type": "string" + } + } + } + }, + "timeout": { + "$id": "#/properties/properties/properties/operations/items/properties/timeout", + "type": "integer", + "title": "Operation Timeout in seconds", + "default": 10, + "minimum": 1, + "examples": [ + 1200 + ] + }, + "retries": { + "$id": "#/properties/properties/properties/operations/items/properties/retries", + "type": "integer", + "title": "Number of Retries", + "default": 0, + "examples": [ + 3 + ] + }, + "success": { + "$id": "#/properties/properties/properties/operations/items/properties/success", + "type": "string", + "title": "Success Treatment", + "default": "final_success", + "examples": [ + "final_success", + "unique-policy-id-2" + ], + "pattern": "^(.+)$" + }, + "failure": { + "$id": "#/properties/properties/properties/operations/items/properties/failure", + "type": "string", + "title": "Failure Treatment", + "default": "final_failure", + "examples": [ + "final_failure", + "unique-policy-id-2" + ], + "pattern": "^(.+)$" + }, + "failure_timeout": { + "$id": "#/properties/properties/properties/operations/items/properties/failure_timeout", + "type": "string", + "title": "Failure Timeout Treatment", + "default": "final_failure_timeout", + "examples": [ + "final_failure_timeout", + "unique-policy-id-2" + ], + "pattern": "^(.+)$" + }, + "failure_retries": { + "$id": "#/properties/properties/properties/operations/items/properties/failure_retries", + "type": "string", + "title": "Failure Retry Treatment", + "default": "final_failure_retries", + "examples": [ + "final_failure_retries", + "unique-policy-id-2" + ], + "pattern": "^(.+)$" + }, + "failure_exception": { + "$id": "#/properties/properties/properties/operations/items/properties/failure_exception", + "type": "string", + "title": "Failure Exception Treatment", + "default": "", + "examples": [ + "final_failure_exception", + "unique-policy-id-2" + ], + "pattern": "^(.+)$" + }, + "failure_guard": { + "$id": "#/properties/properties/properties/operations/items/properties/failure_guard", + "type": "string", + "title": "Failure Guard Treatment", + "default": "final_failure_guard", + "examples": [ + "final_failure_guard", + "unique-policy-id-2" + ], + "pattern": "^(.+)$" + } + } + } + }, + "controllerName": { + "$id": "#/properties/properties/properties/controllerName", + "type": "string", + "title": "Controller Name", + "default": "", + "examples": [ + "usecases" + ], + "pattern": "^(.+)$" + } + } + } + } +} \ No newline at end of file diff --git a/controlloop/common/domains/src/test/java/org/onap/policy/drools/models/domain/operational/OperationalPolicyTest.java b/controlloop/common/domains/src/test/java/org/onap/policy/drools/models/domain/operational/OperationalPolicyTest.java new file mode 100644 index 000000000..bab22d9ba --- /dev/null +++ b/controlloop/common/domains/src/test/java/org/onap/policy/drools/models/domain/operational/OperationalPolicyTest.java @@ -0,0 +1,170 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP + * ================================================================================ + * Copyright (C) 2020 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.drools.models.domain.operational; + +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + +import com.openpojo.reflection.PojoClass; +import com.openpojo.reflection.filters.FilterChain; +import com.openpojo.reflection.filters.FilterClassName; +import com.openpojo.reflection.filters.FilterNonConcrete; +import com.openpojo.reflection.impl.PojoClassFactory; +import com.openpojo.validation.Validator; +import com.openpojo.validation.ValidatorBuilder; +import com.openpojo.validation.test.impl.GetterTester; +import com.openpojo.validation.test.impl.SetterTester; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.util.List; +import org.junit.Before; +import org.junit.Test; +import org.onap.policy.common.utils.coder.CoderException; +import org.onap.policy.common.utils.coder.StandardCoder; +import org.onap.policy.common.utils.resources.ResourceUtils; +import org.onap.policy.drools.domain.models.DroolsPolicy; +import org.onap.policy.drools.domain.models.Metadata; +import org.onap.policy.drools.policies.DomainMaker; +import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicy; +import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicyTypeIdentifier; +import org.onap.policy.models.tosca.authorative.concepts.ToscaServiceTemplate; + +public class OperationalPolicyTest { + // Policy Types + private static final String OPERATIONAL_DROOLS_POLICY_TYPE = "onap.policies.controlloop.operational.common.Drools"; + private static final String OPERATIONAL_LEGACY_POLICY_TYPE = "onap.policies.controlloop.Operational"; + + // Operational vCPE Policies + private static final String OP_POLICY_NAME_VCPE = "operational.restart"; + private static final String VCPE_OPERATIONAL_DROOLS_POLICY_JSON = + "policies/vCPE.policy.operational.input.tosca.json"; + public static final String VCPE_OPERATIONAL_LEGACY_POLICY_JSON = "src/test/resources/tosca-legacy-vcpe.json"; + + private DomainMaker domainMaker; + private StandardCoder nonValCoder; + + @Before + public void setUp() { + domainMaker = new DomainMaker(); + nonValCoder = new StandardCoder(); + } + + + @Test + public void testToscaCompliantOperationalPolicyType() throws CoderException { + String rawVcpeToscaPolicy = getExamplesPolicyString(VCPE_OPERATIONAL_DROOLS_POLICY_JSON, OP_POLICY_NAME_VCPE); + + // valid "known" policy type with implicit schema + assertTrue(domainMaker + .isConformant( + new ToscaPolicyTypeIdentifier(OPERATIONAL_DROOLS_POLICY_TYPE, "1.0.0"), rawVcpeToscaPolicy)); + + OperationalPolicy policy = domainMaker.convertTo( + new ToscaPolicyTypeIdentifier("OPERATIONAL_LEGACY_POLICY_TYPE", "1.0.0"), + rawVcpeToscaPolicy, OperationalPolicy.class); + + assertNotNull(policy); + } + + @Test + public void testToscaLegacyOperationalPolicyType() throws CoderException, IOException { + String rawVcpeToscaPolicy = getJsonFromFile(VCPE_OPERATIONAL_LEGACY_POLICY_JSON); + + // valid "known" policy type with implicit schema + assertTrue(domainMaker + .isConformant( + new ToscaPolicyTypeIdentifier(OPERATIONAL_LEGACY_POLICY_TYPE, "1.0.0"), rawVcpeToscaPolicy)); + } + + @Test + public void testOperationalCompliantModel() { + // @formatter:off + OperationalPolicy policy = + OperationalPolicy.builder() + .metadata(Metadata.builder().policyId(OP_POLICY_NAME_VCPE).build()) + .name(OP_POLICY_NAME_VCPE) + .type(OPERATIONAL_DROOLS_POLICY_TYPE) + .typeVersion("1.0.0") + .version("1.0.0") + .properties( + OperationalProperties.builder() + .id("ControlLoop-vCPE-48f0c2c3-a172-4192-9ae3-052274181b6e") + .abatement(true) + .trigger("unique-policy-id-1-restart") + .operations( + List.of(Operation.builder() + .id("unique-policy-id-1-restart") + .description("Restart the VM") + .timeout(60) + .retries(3) + .actorOperation(ActorOperation.builder() + .operation("Restart") + .actor("APPC") + .target(OperationalTarget.builder().type("VNF").build()) + .build()) + .build())) + .controllerName("usecases") + .build()) + .build(); + // @formatter:on + + assertNotNull(policy); + } + + @Test + public void testPackage() { + /* validate model pojos */ + List pojoClasses = + PojoClassFactory + .getPojoClassesRecursively("org.onap.policy.drools.models.domain.operational", + new FilterChain(new FilterNonConcrete(), + new FilterClassName(DroolsPolicy.class.getName()))); + + Validator validator = ValidatorBuilder.create() + .with(new SetterTester(), new GetterTester()).build(); + validator.validate(pojoClasses); + } + + private String getJsonFromFile(String filePath) throws IOException { + return new String(Files.readAllBytes(Paths.get(filePath))); + } + + private String getJsonFromResource(String resourcePath) { + return ResourceUtils.getResourceAsString(resourcePath); + } + + private String getPolicyFromFileString(String filePath, String policyName) throws CoderException, IOException { + String policyJson = getJsonFromFile(filePath); + ToscaServiceTemplate serviceTemplate = new StandardCoder().decode(policyJson, ToscaServiceTemplate.class); + return nonValCoder.encode(serviceTemplate.getToscaTopologyTemplate().getPolicies().get(0).get(policyName)); + } + + private ToscaPolicy getExamplesPolicy(String resourcePath, String policyName) throws CoderException { + String policyJson = getJsonFromResource(resourcePath); + ToscaServiceTemplate serviceTemplate = new StandardCoder().decode(policyJson, ToscaServiceTemplate.class); + return serviceTemplate.getToscaTopologyTemplate().getPolicies().get(0).get(policyName); + } + + private String getExamplesPolicyString(String resourcePath, String policyName) throws CoderException { + return nonValCoder.encode(getExamplesPolicy(resourcePath, policyName)); + } +} \ No newline at end of file diff --git a/controlloop/common/domains/src/test/resources/tosca-legacy-vcpe.json b/controlloop/common/domains/src/test/resources/tosca-legacy-vcpe.json new file mode 100644 index 000000000..98e8bb8ff --- /dev/null +++ b/controlloop/common/domains/src/test/resources/tosca-legacy-vcpe.json @@ -0,0 +1,9 @@ +{ + "type": "onap.policies.controlloop.Operational", + "type_version": "1.0.0", + "properties": { + "content": "controlLoop%3A%0A%20%20version%3A%202.0.0%0A%20%20controlLoopName%3A%20ControlLoop-vCPE-48f0c2c3-a172-4192-9ae3-052274181b6e%0A%20%20trigger_policy%3A%20unique-policy-id-1-restart%0A%20%20timeout%3A%203600%0A%20%20abatement%3A%20true%0A%20%0Apolicies%3A%0A%20%20-%20id%3A%20unique-policy-id-1-restart%0A%20%20%20%20name%3A%20Restart%20the%20VM%0A%20%20%20%20description%3A%0A%20%20%20%20actor%3A%20APPC%0A%20%20%20%20recipe%3A%20Restart%0A%20%20%20%20target%3A%0A%20%20%20%20%20%20type%3A%20VM%0A%20%20%20%20retry%3A%203%0A%20%20%20%20timeout%3A%201200%0A%20%20%20%20success%3A%20final_success%0A%20%20%20%20failure%3A%20final_failure%0A%20%20%20%20failure_timeout%3A%20final_failure_timeout%0A%20%20%20%20failure_retries%3A%20final_failure_retries%0A%20%20%20%20failure_exception%3A%20final_failure_exception%0A%20%20%20%20failure_guard%3A%20final_failure_guard" + }, + "name": "operational.restart", + "version": "1.0.0" +} diff --git a/controlloop/common/eventmanager/pom.xml b/controlloop/common/eventmanager/pom.xml index 7b3985551..23ac4a227 100644 --- a/controlloop/common/eventmanager/pom.xml +++ b/controlloop/common/eventmanager/pom.xml @@ -20,207 +20,213 @@ ============LICENSE_END========================================================= --> - - 4.0.0 + + 4.0.0 - - org.onap.policy.drools-applications.controlloop.common - drools-applications-common - 1.6.0-SNAPSHOT - + + org.onap.policy.drools-applications.controlloop.common + drools-applications-common + 1.6.0-SNAPSHOT + - eventmanager + eventmanager - - - org.eclipse.persistence - org.eclipse.persistence.jpa - provided - - - commons-io - commons-io - 2.5 - provided - - - org.onap.policy.models.policy-models-interactions.model-actors - actorServiceProvider - ${policy.models.version} - provided - - - org.onap.policy.models.policy-models-interactions.model-actors - actor.sdnr - ${policy.models.version} - provided - - - org.onap.policy.models.policy-models-interactions.model-actors - actor.appc - ${policy.models.version} - provided - - - org.onap.policy.models.policy-models-interactions.model-actors - actor.so - ${policy.models.version} - provided - - - org.onap.policy.models.policy-models-interactions.model-actors - actor.vfc - ${policy.models.version} - provided - - - org.onap.policy.models.policy-models-interactions.model-actors - actor.sdnc - ${policy.models.version} - provided - - - org.onap.policy.models.policy-models-interactions.model-actors - actor.appclcm - ${policy.models.version} - provided - - - org.onap.policy.models.policy-models-interactions.model-actors - actor.cds - ${policy.models.version} - provided - - - org.onap.policy.drools-applications.controlloop.common - database - ${project.version} - - - org.onap.policy.drools-applications.controlloop.common - guard - ${project.version} - provided - - - org.onap.policy.models.policy-models-interactions.model-impl - events - ${policy.models.version} - provided - - - org.onap.policy.models.policy-models-interactions.model-impl - sdnr - ${policy.models.version} - provided - - - org.onap.policy.models.policy-models-interactions.model-impl - appc - ${policy.models.version} - provided - - - org.onap.policy.models.policy-models-interactions.model-impl - vfc - ${policy.models.version} - provided - - - org.onap.policy.models.policy-models-interactions.model-impl - sdnc - ${policy.models.version} - provided - - - org.onap.policy.models.policy-models-interactions.model-impl - appclcm - ${policy.models.version} - provided - - - org.onap.policy.models.policy-models-interactions.model-impl - cds - ${policy.models.version} - provided - - - org.onap.ccsdk.cds.components - proto-definition - - - junit - junit - test - - - org.powermock - powermock-api-mockito2 - test - - - org.assertj - assertj-core - test - - - com.google.code.gson - gson - provided - - - org.onap.policy.models.policy-models-interactions.model-impl - sdc - ${policy.models.version} - provided - - - org.onap.policy.models.policy-models-interactions.model-impl - aai - ${policy.models.version} - provided - - - org.onap.policy.models.policy-models-interactions.model-impl - so - ${policy.models.version} - provided - - - org.apache.httpcomponents - httpclient - provided - - - org.onap.policy.common - policy-endpoints - ${version.policy.common} - provided - - - org.onap.policy.drools-pdp - policy-management - ${version.policy.drools-pdp} - provided - - - org.onap.policy.common - utils-test - ${version.policy.common} - test - - - org.onap.policy.models.policy-models-interactions - simulators - ${policy.models.version} - test - - - com.h2database - h2 - test - - + + + org.eclipse.persistence + org.eclipse.persistence.jpa + provided + + + commons-io + commons-io + 2.5 + provided + + + org.onap.policy.models.policy-models-interactions.model-actors + actorServiceProvider + ${policy.models.version} + provided + + + org.onap.policy.models.policy-models-interactions.model-actors + actor.sdnr + ${policy.models.version} + provided + + + org.onap.policy.models.policy-models-interactions.model-actors + actor.appc + ${policy.models.version} + provided + + + org.onap.policy.models.policy-models-interactions.model-actors + actor.so + ${policy.models.version} + provided + + + org.onap.policy.models.policy-models-interactions.model-actors + actor.vfc + ${policy.models.version} + provided + + + org.onap.policy.models.policy-models-interactions.model-actors + actor.sdnc + ${policy.models.version} + provided + + + org.onap.policy.models.policy-models-interactions.model-actors + actor.appclcm + ${policy.models.version} + provided + + + org.onap.policy.models.policy-models-interactions.model-actors + actor.cds + ${policy.models.version} + provided + + + org.onap.policy.drools-applications.controlloop.common + database + ${project.version} + + + org.onap.policy.drools-applications.controlloop.common + guard + ${project.version} + provided + + + org.onap.policy.models.policy-models-interactions.model-impl + events + ${policy.models.version} + provided + + + org.onap.policy.models.policy-models-interactions.model-impl + sdnr + ${policy.models.version} + provided + + + org.onap.policy.models.policy-models-interactions.model-impl + appc + ${policy.models.version} + provided + + + org.onap.policy.models.policy-models-interactions.model-impl + vfc + ${policy.models.version} + provided + + + org.onap.policy.models.policy-models-interactions.model-impl + sdnc + ${policy.models.version} + provided + + + org.onap.policy.models.policy-models-interactions.model-impl + appclcm + ${policy.models.version} + provided + + + org.onap.policy.models.policy-models-interactions.model-impl + cds + ${policy.models.version} + provided + + + org.onap.ccsdk.cds.components + proto-definition + + + junit + junit + test + + + org.powermock + powermock-api-mockito2 + test + + + org.assertj + assertj-core + test + + + com.google.code.gson + gson + provided + + + org.onap.policy.models.policy-models-interactions.model-impl + sdc + ${policy.models.version} + provided + + + org.onap.policy.models.policy-models-interactions.model-impl + aai + ${policy.models.version} + provided + + + org.onap.policy.models.policy-models-interactions.model-impl + so + ${policy.models.version} + provided + + + org.apache.httpcomponents + httpclient + provided + + + org.onap.policy.common + policy-endpoints + ${version.policy.common} + provided + + + org.onap.policy.drools-pdp + policy-management + ${version.policy.drools-pdp} + provided + + + org.onap.policy.common + utils-test + ${version.policy.common} + test + + + org.onap.policy.models.policy-models-interactions + simulators + ${policy.models.version} + test + + + com.h2database + h2 + test + + + org.onap.policy.drools-applications.controlloop.common + domains + 1.6.0-SNAPSHOT + + diff --git a/controlloop/common/eventmanager/src/main/java/org/onap/policy/controlloop/drl/legacy/ControlLoopParams.java b/controlloop/common/eventmanager/src/main/java/org/onap/policy/controlloop/drl/legacy/ControlLoopParams.java index 6e24e26bf..769a6d971 100644 --- a/controlloop/common/eventmanager/src/main/java/org/onap/policy/controlloop/drl/legacy/ControlLoopParams.java +++ b/controlloop/common/eventmanager/src/main/java/org/onap/policy/controlloop/drl/legacy/ControlLoopParams.java @@ -23,6 +23,7 @@ package org.onap.policy.controlloop.drl.legacy; import java.io.Serializable; import lombok.Data; import lombok.NoArgsConstructor; +import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicy; @Data @NoArgsConstructor @@ -31,8 +32,8 @@ public class ControlLoopParams implements Serializable { private static final long serialVersionUID = 970755684770982776L; private String closedLoopControlName; - private String controlLoopYaml; private String policyName; private String policyScope; private String policyVersion; + private ToscaPolicy toscaPolicy; } diff --git a/controlloop/common/eventmanager/src/main/java/org/onap/policy/controlloop/eventmanager/ControlLoopEventManager.java b/controlloop/common/eventmanager/src/main/java/org/onap/policy/controlloop/eventmanager/ControlLoopEventManager.java index f297a8f6b..6e88ce982 100644 --- a/controlloop/common/eventmanager/src/main/java/org/onap/policy/controlloop/eventmanager/ControlLoopEventManager.java +++ b/controlloop/common/eventmanager/src/main/java/org/onap/policy/controlloop/eventmanager/ControlLoopEventManager.java @@ -55,6 +55,7 @@ import org.onap.policy.drools.core.lock.LockImpl; import org.onap.policy.drools.core.lock.LockState; import org.onap.policy.drools.system.PolicyEngineConstants; import org.onap.policy.drools.utils.Pair; +import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicy; import org.onap.policy.rest.RestManager; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -234,19 +235,7 @@ public class ControlLoopEventManager implements Serializable { return notification; } - // - // At this point we are good to go with this event - // - this.onset = event; - this.numOnsets = 1; - // - // - // Set ourselves as active - // - this.isActivated = true; - - notification.setNotification(ControlLoopNotificationType.ACTIVE); - return notification; + return postActivate(event, notification); } /** @@ -287,6 +276,34 @@ public class ControlLoopEventManager implements Serializable { return rejectNotification(event, e.getMessage()); } + return postActivate(event, notification); + } + + /** + * Activate a control loop event. + * + * @param toscaPolicy the tosca policy + * @param event the event + * @return the VirtualControlLoopNotification + */ + public VirtualControlLoopNotification activate(ToscaPolicy toscaPolicy, VirtualControlLoopEvent event) { + VirtualControlLoopNotification notification = preActivationChecks(event); + if (notification.getNotification() == ControlLoopNotificationType.REJECTED) { + return notification; + } + + try { + this.processor = new ControlLoopProcessor(toscaPolicy); + } catch (ControlLoopException e) { + logger.error("{}: activate from Tosca Policy threw: ", this, e); + return rejectNotification(event, e.getMessage()); + } + + return postActivate(event, notification); + } + + private VirtualControlLoopNotification postActivate( + VirtualControlLoopEvent event, VirtualControlLoopNotification notification) { // // At this point we are good to go with this event // @@ -298,9 +315,6 @@ public class ControlLoopEventManager implements Serializable { // this.isActivated = true; - // - // - // notification.setNotification(ControlLoopNotificationType.ACTIVE); return notification; } diff --git a/controlloop/common/eventmanager/src/main/java/org/onap/policy/controlloop/processor/ControlLoopProcessor.java b/controlloop/common/eventmanager/src/main/java/org/onap/policy/controlloop/processor/ControlLoopProcessor.java index ac684fcda..4cff616a0 100644 --- a/controlloop/common/eventmanager/src/main/java/org/onap/policy/controlloop/processor/ControlLoopProcessor.java +++ b/controlloop/common/eventmanager/src/main/java/org/onap/policy/controlloop/processor/ControlLoopProcessor.java @@ -1,8 +1,8 @@ /*- * ============LICENSE_START======================================================= - * controlloop processor + * ONAP * ================================================================================ - * Copyright (C) 2017-2018 AT&T Intellectual Property. All rights reserved. + * Copyright (C) 2017-2020 AT&T Intellectual Property. All rights reserved. * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -21,22 +21,41 @@ package org.onap.policy.controlloop.processor; import java.io.Serializable; +import java.io.UnsupportedEncodingException; +import java.net.URLDecoder; +import java.util.stream.Collectors; +import lombok.Getter; +import org.onap.policy.common.utils.coder.CoderException; import org.onap.policy.controlloop.ControlLoopException; +import org.onap.policy.controlloop.drl.legacy.ControlLoopParams; import org.onap.policy.controlloop.policy.ControlLoop; import org.onap.policy.controlloop.policy.ControlLoopPolicy; import org.onap.policy.controlloop.policy.FinalResult; import org.onap.policy.controlloop.policy.Policy; +import org.onap.policy.controlloop.policy.PolicyParam; import org.onap.policy.controlloop.policy.PolicyResult; +import org.onap.policy.controlloop.policy.Target; +import org.onap.policy.controlloop.policy.TargetType; +import org.onap.policy.drools.domain.models.DroolsPolicy; +import org.onap.policy.drools.models.domain.legacy.LegacyPolicy; +import org.onap.policy.drools.models.domain.operational.OperationalPolicy; +import org.onap.policy.drools.system.PolicyEngineConstants; +import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicy; import org.yaml.snakeyaml.Yaml; import org.yaml.snakeyaml.constructor.CustomClassLoaderConstructor; public class ControlLoopProcessor implements Serializable { private static final long serialVersionUID = 1L; - - private final String yaml; + private final ControlLoopPolicy policy; private String currentNestedPolicyId = null; + @Getter + private ToscaPolicy toscaOpPolicy; + + @Getter + private DroolsPolicy domainOpPolicy; + /** * Construct an instance from yaml. * @@ -44,11 +63,10 @@ public class ControlLoopProcessor implements Serializable { * @throws ControlLoopException if an error occurs */ public ControlLoopProcessor(String yaml) throws ControlLoopException { - this.yaml = yaml; try { final Yaml y = new Yaml(new CustomClassLoaderConstructor(ControlLoopPolicy.class, ControlLoopPolicy.class.getClassLoader())); - final Object obj = y.load(this.yaml); + final Object obj = y.load(yaml); this.policy = (ControlLoopPolicy) obj; this.currentNestedPolicyId = this.policy.getControlLoop().getTrigger_policy(); @@ -60,6 +78,85 @@ public class ControlLoopProcessor implements Serializable { } } + /** + * Create an instance from a Tosca Policy. + */ + public ControlLoopProcessor(ToscaPolicy toscaPolicy) throws ControlLoopException { + try { + // TODO: automate policy type to models mapping + this.policy = + ("onap.policies.controlloop.Operational".equals(toscaPolicy.getType())) + ? buildPolicyFromToscaLegacy(toscaPolicy) + : buildPolicyFromToscaCompliant(toscaPolicy); + + this.currentNestedPolicyId = this.policy.getControlLoop().getTrigger_policy(); + this.toscaOpPolicy = toscaPolicy; + } catch (RuntimeException | CoderException | UnsupportedEncodingException e) { + throw new ControlLoopException(e); + } + } + + protected ControlLoopPolicy buildPolicyFromToscaLegacy(ToscaPolicy policy) + throws UnsupportedEncodingException, CoderException { + LegacyPolicy legacyPolicy = + PolicyEngineConstants.getManager().getDomainMaker().convertTo(policy, LegacyPolicy.class); + this.domainOpPolicy = legacyPolicy; + String decodedPolicy = URLDecoder.decode(legacyPolicy.getProperties().getContent(), "UTF-8"); + return new Yaml( + new CustomClassLoaderConstructor( + ControlLoopPolicy.class, ControlLoopPolicy.class.getClassLoader())).load(decodedPolicy); + } + + protected ControlLoopPolicy buildPolicyFromToscaCompliant(ToscaPolicy policy) throws CoderException { + OperationalPolicy domainPolicy = + PolicyEngineConstants.getManager().getDomainMaker().convertTo(policy, OperationalPolicy.class); + + ControlLoopPolicy backwardsCompatiblePolicy = new ControlLoopPolicy(); + + // @formatter:off + backwardsCompatiblePolicy.setPolicies( + domainPolicy.getProperties().getOperations().stream().map(operation -> new Policy( + PolicyParam.builder() + .id(operation.getId()) + .name(operation.getActorOperation().getOperation()) + .description(operation.getDescription()) + .actor(operation.getActorOperation().getActor()) + .payload(operation.getActorOperation().getPayload()) + .recipe(operation.getActorOperation().getOperation()) + .retries(operation.getRetries()) + .timeout(operation.getTimeout()) + .target(new Target(TargetType.valueOf(operation.getActorOperation().getTarget().getType()), + operation.getActorOperation().getTarget().getResourceId())).build())) + .collect(Collectors.toList())); + // @formatter:on + + ControlLoop controlLoop = new ControlLoop(); + controlLoop.setAbatement(domainPolicy.getProperties().isAbatement()); + controlLoop.setControlLoopName(domainPolicy.getProperties().getId()); + controlLoop.setTimeout(domainPolicy.getProperties().getTimeout()); + controlLoop.setTrigger_policy(domainPolicy.getProperties().getTrigger()); + controlLoop.setVersion(domainPolicy.getVersion()); + + backwardsCompatiblePolicy.setControlLoop(controlLoop); + this.domainOpPolicy = domainPolicy; + return backwardsCompatiblePolicy; + } + + /** + * Get ControlLoopParams. + */ + public ControlLoopParams getControlLoopParams() { + ControlLoopParams controlLoopParams = new ControlLoopParams(); + + controlLoopParams.setClosedLoopControlName(this.getControlLoop().getControlLoopName()); + controlLoopParams.setPolicyScope(domainOpPolicy.getType() + ":" + domainOpPolicy.getTypeVersion()); + controlLoopParams.setPolicyName(domainOpPolicy.getName()); + controlLoopParams.setPolicyVersion(domainOpPolicy.getVersion()); + controlLoopParams.setToscaPolicy(toscaOpPolicy); + + return controlLoopParams; + } + public ControlLoop getControlLoop() { return this.policy.getControlLoop(); } diff --git a/controlloop/common/eventmanager/src/main/java/org/onap/policy/controlloop/utils/ControlLoopUtils.java b/controlloop/common/eventmanager/src/main/java/org/onap/policy/controlloop/utils/ControlLoopUtils.java index cfa4b3d3b..b5d95fed7 100644 --- a/controlloop/common/eventmanager/src/main/java/org/onap/policy/controlloop/utils/ControlLoopUtils.java +++ b/controlloop/common/eventmanager/src/main/java/org/onap/policy/controlloop/utils/ControlLoopUtils.java @@ -18,9 +18,6 @@ package org.onap.policy.controlloop.utils; -import java.io.UnsupportedEncodingException; -import java.net.URLDecoder; -import org.apache.commons.lang3.StringUtils; import org.onap.policy.controlloop.ControlLoopException; import org.onap.policy.controlloop.drl.legacy.ControlLoopParams; import org.onap.policy.controlloop.processor.ControlLoopProcessor; @@ -34,7 +31,6 @@ import org.slf4j.LoggerFactory; public class ControlLoopUtils { public static final Logger logger = LoggerFactory.getLogger(ControlLoopUtils.class); - public static final String TOSCA_POLICY_PROPERTY_CONTENT = "content"; private ControlLoopUtils() { super(); @@ -45,35 +41,11 @@ public class ControlLoopUtils { */ public static ControlLoopParams toControlLoopParams(ToscaPolicy policy) { - // TODO: ControlLoopParams class should be moved to this repo and take Tosca Policy in a constructor. - /* No exceptions are thrown to keep the DRL simpler */ try { - if (policy == null || policy.getProperties() == null - || policy.getProperties().get(TOSCA_POLICY_PROPERTY_CONTENT) == null) { - logger.error("Invalid Policy: {}", policy); - return null; - } - - String encodedPolicy = policy.getProperties().get(TOSCA_POLICY_PROPERTY_CONTENT).toString(); - String decodedPolicy = URLDecoder.decode(encodedPolicy, "UTF-8"); - - ControlLoopProcessor controlLoopProcessor = new ControlLoopProcessor(decodedPolicy); - if (controlLoopProcessor.getControlLoop() == null - || StringUtils.isEmpty(controlLoopProcessor.getControlLoop().getControlLoopName())) { - return null; - } - - ControlLoopParams controlLoopParams = new ControlLoopParams(); - controlLoopParams.setClosedLoopControlName(controlLoopProcessor.getControlLoop().getControlLoopName()); - controlLoopParams.setControlLoopYaml(encodedPolicy); - controlLoopParams.setPolicyScope(policy.getType() + ":" + policy.getTypeVersion()); - controlLoopParams.setPolicyName(policy.getName()); - controlLoopParams.setPolicyVersion(policy.getVersion()); - - return controlLoopParams; - } catch (ControlLoopException | RuntimeException | UnsupportedEncodingException e) { + return new ControlLoopProcessor(policy).getControlLoopParams(); + } catch (ControlLoopException | RuntimeException e) { logger.error("Invalid Policy because of {}: {}", e.getMessage(), policy, e); return null; } diff --git a/controlloop/common/eventmanager/src/test/java/org/onap/policy/controlloop/drl/legacy/ControlLoopParamsTest.java b/controlloop/common/eventmanager/src/test/java/org/onap/policy/controlloop/drl/legacy/ControlLoopParamsTest.java index 7bb2c5c96..f636e08f6 100644 --- a/controlloop/common/eventmanager/src/test/java/org/onap/policy/controlloop/drl/legacy/ControlLoopParamsTest.java +++ b/controlloop/common/eventmanager/src/test/java/org/onap/policy/controlloop/drl/legacy/ControlLoopParamsTest.java @@ -22,6 +22,12 @@ package org.onap.policy.controlloop.drl.legacy; import static org.junit.Assert.assertEquals; +import com.openpojo.reflection.PojoClass; +import com.openpojo.reflection.impl.PojoClassFactory; +import com.openpojo.validation.Validator; +import com.openpojo.validation.ValidatorBuilder; +import com.openpojo.validation.test.impl.GetterTester; +import com.openpojo.validation.test.impl.SetterTester; import org.junit.Before; import org.junit.Test; @@ -30,7 +36,6 @@ public class ControlLoopParamsTest { private static final String POLICY_NAME = "m"; private static final String POLICY_SCOPE = "s"; private static final String POLICY_VERSION = "v"; - private static final String CONTROL_LOOP_YAML = "y"; private ControlLoopParams clp = new ControlLoopParams(); @@ -43,17 +48,19 @@ public class ControlLoopParamsTest { clp.setPolicyName(POLICY_NAME); clp.setPolicyScope(POLICY_SCOPE); clp.setPolicyVersion(POLICY_VERSION); - clp.setControlLoopYaml(CONTROL_LOOP_YAML); } @Test - public void getClosedLoopControlName() { - assertEquals(CONTROL_LOOP_NAME, clp.getClosedLoopControlName()); + public void testPojo() { + PojoClass controlLoopParams = PojoClassFactory.getPojoClass(ControlLoopParams.class); + Validator validator = ValidatorBuilder.create() + .with(new SetterTester(), new GetterTester()).build(); + validator.validate(controlLoopParams); } @Test - public void getControlLoopYaml() { - assertEquals(CONTROL_LOOP_YAML, clp.getControlLoopYaml()); + public void getClosedLoopControlName() { + assertEquals(CONTROL_LOOP_NAME, clp.getClosedLoopControlName()); } @Test @@ -77,12 +84,6 @@ public class ControlLoopParamsTest { assertEquals(CONTROL_LOOP_NAME.toUpperCase(), clp.getClosedLoopControlName()); } - @Test - public void setControlLoopYaml() { - clp.setControlLoopYaml(CONTROL_LOOP_YAML.toUpperCase()); - assertEquals(CONTROL_LOOP_YAML.toUpperCase(), clp.getControlLoopYaml()); - } - @Test public void setPolicyName() { clp.setPolicyName(POLICY_NAME.toUpperCase()); @@ -108,7 +109,6 @@ public class ControlLoopParamsTest { other.setPolicyName(POLICY_NAME); other.setPolicyScope(POLICY_SCOPE); other.setPolicyVersion(POLICY_VERSION); - other.setControlLoopYaml(CONTROL_LOOP_YAML); assertEquals(clp, other); assertEquals(clp.hashCode(), other.hashCode()); diff --git a/controlloop/common/eventmanager/src/test/java/org/onap/policy/controlloop/eventmanager/ControlLoopEventManagerTest.java b/controlloop/common/eventmanager/src/test/java/org/onap/policy/controlloop/eventmanager/ControlLoopEventManagerTest.java index 21b082c82..266ad1ac9 100644 --- a/controlloop/common/eventmanager/src/test/java/org/onap/policy/controlloop/eventmanager/ControlLoopEventManagerTest.java +++ b/controlloop/common/eventmanager/src/test/java/org/onap/policy/controlloop/eventmanager/ControlLoopEventManagerTest.java @@ -1,8 +1,8 @@ /*- * ============LICENSE_START======================================================= - * unit test + * ONAP * ================================================================================ - * Copyright (C) 2017-2019 AT&T Intellectual Property. All rights reserved. + * Copyright (C) 2017-2020 AT&T Intellectual Property. All rights reserved. * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -39,11 +39,14 @@ import java.io.IOException; import java.io.InputStream; import java.io.Serializable; import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Paths; import java.time.Instant; import java.util.HashMap; import java.util.Map; import java.util.UUID; import org.apache.commons.io.IOUtils; +import org.jetbrains.annotations.NotNull; import org.junit.AfterClass; import org.junit.Before; import org.junit.BeforeClass; @@ -51,6 +54,8 @@ import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; import org.onap.policy.common.endpoints.http.server.HttpServletServerFactoryInstance; +import org.onap.policy.common.utils.coder.CoderException; +import org.onap.policy.common.utils.coder.StandardCoder; import org.onap.policy.common.utils.io.Serializer; import org.onap.policy.controlloop.ControlLoopEventStatus; import org.onap.policy.controlloop.ControlLoopException; @@ -64,6 +69,7 @@ import org.onap.policy.drools.core.lock.Lock; import org.onap.policy.drools.core.lock.LockCallback; import org.onap.policy.drools.system.PolicyEngineConstants; import org.onap.policy.drools.utils.Pair; +import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicy; import org.powermock.reflect.Whitebox; public class ControlLoopEventManagerTest { @@ -160,16 +166,7 @@ public class ControlLoopEventManagerTest { @Test public void testAlreadyActivated() { - UUID requestId = UUID.randomUUID(); - VirtualControlLoopEvent event = new VirtualControlLoopEvent(); - event.setClosedLoopControlName(TWO_ONSET_TEST); - event.setRequestId(requestId); - event.setTarget(VNF_ID); - event.setClosedLoopAlarmStart(Instant.now()); - event.setClosedLoopEventStatus(ControlLoopEventStatus.ONSET); - event.setAai(new HashMap<>()); - event.getAai().put(VNF_NAME, ONSET_ONE); - event.setTargetType(ControlLoopTargetType.VNF); + VirtualControlLoopEvent event = getOnsetEvent(); ControlLoopEventManager manager = makeManager(event); manager.setActivated(true); @@ -178,23 +175,13 @@ public class ControlLoopEventManagerTest { } @Test - public void testActivationYaml() throws IOException { - - UUID requestId = UUID.randomUUID(); - VirtualControlLoopEvent event = new VirtualControlLoopEvent(); - event.setClosedLoopControlName(TWO_ONSET_TEST); - event.setRequestId(requestId); - event.setTarget(VNF_ID); - event.setClosedLoopAlarmStart(Instant.now()); - event.setClosedLoopEventStatus(ControlLoopEventStatus.ONSET); - event.setAai(new HashMap<>()); - event.getAai().put(VNF_NAME, ONSET_ONE); - event.setTargetType(ControlLoopTargetType.VNF); + public void testActivationYaml() throws IOException, CoderException { + VirtualControlLoopEvent event = getOnsetEvent(); ControlLoopEventManager manager = makeManager(event); // Null YAML should fail - VirtualControlLoopNotification notificationNull = manager.activate(null, event); + VirtualControlLoopNotification notificationNull = manager.activate((String) null, event); assertNotNull(notificationNull); assertEquals(ControlLoopNotificationType.REJECTED, notificationNull.getNotification()); @@ -225,18 +212,33 @@ public class ControlLoopEventManagerTest { assertEquals(ControlLoopNotificationType.REJECTED, notificationActive.getNotification()); } + @Test + public void testActivateToscaLegacy() throws IOException, CoderException { + String policy = + new String(Files.readAllBytes(Paths.get("src/test/resources/tosca-policy-legacy-vcpe.json"))); + ToscaPolicy toscaPolicy = new StandardCoder().decode(policy, ToscaPolicy.class); + + VirtualControlLoopEvent event = getOnsetEvent(); + ControlLoopEventManager manager = makeManager(event); + + // trigger a reject by passing the wrong policy type + toscaPolicy.setType("onap.policies.controlloop.operational.common.Drools"); + VirtualControlLoopNotification notification = manager.activate(toscaPolicy, event); + assertEquals(ControlLoopNotificationType.REJECTED, notification.getNotification()); + + // place back correct policy type + toscaPolicy.setType("onap.policies.controlloop.Operational"); + notification = manager.activate(toscaPolicy, event); + assertEquals(ControlLoopNotificationType.ACTIVE, notification.getNotification()); + + // another activate should fail + notification = manager.activate(toscaPolicy, event); + assertEquals(ControlLoopNotificationType.REJECTED, notification.getNotification()); + } + @Test public void testControlLoopFinal() throws Exception { - UUID requestId = UUID.randomUUID(); - VirtualControlLoopEvent event = new VirtualControlLoopEvent(); - event.setClosedLoopControlName(TWO_ONSET_TEST); - event.setRequestId(requestId); - event.setTarget(VNF_ID); - event.setClosedLoopAlarmStart(Instant.now()); - event.setClosedLoopEventStatus(ControlLoopEventStatus.ONSET); - event.setAai(new HashMap<>()); - event.getAai().put(VNF_NAME, ONSET_ONE); - event.setTargetType(ControlLoopTargetType.VNF); + VirtualControlLoopEvent event = getOnsetEvent(); ControlLoopEventManager manager = makeManager(event); ControlLoopEventManager manager2 = manager; @@ -293,6 +295,21 @@ public class ControlLoopEventManagerTest { assertEquals(ControlLoopNotificationType.FINAL_FAILURE, clfNotification.getNotification()); } + @NotNull + private VirtualControlLoopEvent getOnsetEvent() { + UUID requestId = UUID.randomUUID(); + VirtualControlLoopEvent event = new VirtualControlLoopEvent(); + event.setClosedLoopControlName(TWO_ONSET_TEST); + event.setRequestId(requestId); + event.setTarget(VNF_ID); + event.setClosedLoopAlarmStart(Instant.now()); + event.setClosedLoopEventStatus(ControlLoopEventStatus.ONSET); + event.setAai(new HashMap<>()); + event.getAai().put(VNF_NAME, ONSET_ONE); + event.setTargetType(ControlLoopTargetType.VNF); + return event; + } + @Test public void testProcessControlLoop() throws Exception { UUID requestId = UUID.randomUUID(); @@ -633,16 +650,7 @@ public class ControlLoopEventManagerTest { @Test public void testControlLoopTimeout() throws IOException { - UUID requestId = UUID.randomUUID(); - VirtualControlLoopEvent onsetEvent = new VirtualControlLoopEvent(); - onsetEvent.setClosedLoopControlName(TWO_ONSET_TEST); - onsetEvent.setRequestId(requestId); - onsetEvent.setTarget(VNF_ID); - onsetEvent.setClosedLoopAlarmStart(Instant.now()); - onsetEvent.setClosedLoopEventStatus(ControlLoopEventStatus.ONSET); - onsetEvent.setAai(new HashMap<>()); - onsetEvent.getAai().put(VNF_NAME, ONSET_ONE); - onsetEvent.setTargetType(ControlLoopTargetType.VNF); + VirtualControlLoopEvent onsetEvent = getOnsetEvent(); ControlLoopEventManager manager = makeManager(onsetEvent); assertTrue(0 == manager.getControlLoopTimeout(null)); @@ -660,16 +668,7 @@ public class ControlLoopEventManagerTest { @Test public void testControlLoopTimeout_ZeroTimeout() throws IOException { - UUID requestId = UUID.randomUUID(); - VirtualControlLoopEvent onsetEvent = new VirtualControlLoopEvent(); - onsetEvent.setClosedLoopControlName(TWO_ONSET_TEST); - onsetEvent.setRequestId(requestId); - onsetEvent.setTarget(VNF_ID); - onsetEvent.setClosedLoopAlarmStart(Instant.now()); - onsetEvent.setClosedLoopEventStatus(ControlLoopEventStatus.ONSET); - onsetEvent.setAai(new HashMap<>()); - onsetEvent.getAai().put(VNF_NAME, ONSET_ONE); - onsetEvent.setTargetType(ControlLoopTargetType.VNF); + VirtualControlLoopEvent onsetEvent = getOnsetEvent(); ControlLoopEventManager manager = makeManager(onsetEvent); @@ -686,16 +685,7 @@ public class ControlLoopEventManagerTest { @Test public void testControlLoopTimeout_NullTimeout() throws IOException { - UUID requestId = UUID.randomUUID(); - VirtualControlLoopEvent onsetEvent = new VirtualControlLoopEvent(); - onsetEvent.setClosedLoopControlName(TWO_ONSET_TEST); - onsetEvent.setRequestId(requestId); - onsetEvent.setTarget(VNF_ID); - onsetEvent.setClosedLoopAlarmStart(Instant.now()); - onsetEvent.setClosedLoopEventStatus(ControlLoopEventStatus.ONSET); - onsetEvent.setAai(new HashMap<>()); - onsetEvent.getAai().put(VNF_NAME, ONSET_ONE); - onsetEvent.setTargetType(ControlLoopTargetType.VNF); + VirtualControlLoopEvent onsetEvent = getOnsetEvent(); ControlLoopEventManager manager = makeManager(onsetEvent); diff --git a/controlloop/common/eventmanager/src/test/java/org/onap/policy/controlloop/processor/ControlLoopProcessorTest.java b/controlloop/common/eventmanager/src/test/java/org/onap/policy/controlloop/processor/ControlLoopProcessorTest.java index 84fe44914..f76c0060c 100644 --- a/controlloop/common/eventmanager/src/test/java/org/onap/policy/controlloop/processor/ControlLoopProcessorTest.java +++ b/controlloop/common/eventmanager/src/test/java/org/onap/policy/controlloop/processor/ControlLoopProcessorTest.java @@ -1,8 +1,8 @@ /*- * ============LICENSE_START======================================================= - * unit test + * ONAP * ================================================================================ - * Copyright (C) 2017-2019 AT&T Intellectual Property. All rights reserved. + * Copyright (C) 2017-2020 AT&T Intellectual Property. All rights reserved. * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -29,12 +29,17 @@ import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Paths; import org.apache.commons.io.IOUtils; import org.junit.Test; +import org.onap.policy.common.utils.coder.CoderException; +import org.onap.policy.common.utils.coder.StandardCoder; import org.onap.policy.controlloop.ControlLoopException; import org.onap.policy.controlloop.policy.FinalResult; import org.onap.policy.controlloop.policy.Policy; import org.onap.policy.controlloop.policy.PolicyResult; +import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicy; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -49,6 +54,31 @@ public class ControlLoopProcessorTest { this.testFailure(yamlString); } + @Test + public void testControlLoopFromToscaLegacy() throws IOException, CoderException, ControlLoopException { + String policy = + new String(Files.readAllBytes(Paths.get("src/test/resources/tosca-policy-legacy-vcpe.json"))); + assertNotNull( + new ControlLoopProcessor(new StandardCoder().decode(policy, ToscaPolicy.class)).getCurrentPolicy()); + } + + @Test + public void testControlLoopFromToscaCompliant() throws IOException, CoderException, ControlLoopException { + String policy = + new String(Files.readAllBytes(Paths.get("src/test/resources/tosca-policy-compliant-vcpe.json"))); + assertNotNull( + new ControlLoopProcessor(new StandardCoder().decode(policy, ToscaPolicy.class)).getCurrentPolicy()); + } + + @Test + public void testControlLoopFromToscaCompliantBad() throws IOException, CoderException, ControlLoopException { + String policy = + new String(Files.readAllBytes(Paths.get("src/test/resources/tosca-policy-compliant-vcpe.json"))); + ToscaPolicy toscaPolicy = new StandardCoder().decode(policy, ToscaPolicy.class); + toscaPolicy.setType("onap.policies.controlloop.Operational"); + assertThatThrownBy(() -> new ControlLoopProcessor(toscaPolicy)).hasCauseInstanceOf(CoderException.class); + } + @Test public void testControlLoopProcessorBadYaml() throws IOException { InputStream is = new FileInputStream(new File("src/test/resources/string.yaml")); diff --git a/controlloop/common/eventmanager/src/test/java/org/onap/policy/controlloop/utils/ControlLoopUtilsTest.java b/controlloop/common/eventmanager/src/test/java/org/onap/policy/controlloop/utils/ControlLoopUtilsTest.java index 2c26517cd..2e4811475 100644 --- a/controlloop/common/eventmanager/src/test/java/org/onap/policy/controlloop/utils/ControlLoopUtilsTest.java +++ b/controlloop/common/eventmanager/src/test/java/org/onap/policy/controlloop/utils/ControlLoopUtilsTest.java @@ -19,12 +19,10 @@ package org.onap.policy.controlloop.utils; import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertSame; import java.nio.file.Files; import java.nio.file.Paths; -import java.util.Map; import org.junit.Test; import org.onap.policy.common.utils.coder.StandardCoder; import org.onap.policy.controlloop.drl.legacy.ControlLoopParams; @@ -35,22 +33,14 @@ public class ControlLoopUtilsTest { @Test public void testToControlLoopParams() throws Exception { String policy = - new String(Files.readAllBytes(Paths.get("src/test/resources/tosca-policy-operational-restart.json"))); - + new String(Files.readAllBytes(Paths.get("src/test/resources/tosca-policy-legacy-vcpe.json"))); ToscaPolicy toscaPolicy = new StandardCoder().decode(policy, ToscaPolicy.class); + ControlLoopParams params = ControlLoopUtils.toControlLoopParams(toscaPolicy); - assertNotNull(params); - assertNotNull(params.getClosedLoopControlName()); - assertEquals(toscaPolicy.getProperties().get("content"), params.getControlLoopYaml()); + assertEquals("ControlLoop-vCPE-48f0c2c3-a172-4192-9ae3-052274181b6e", params.getClosedLoopControlName()); assertEquals(toscaPolicy.getName(), params.getPolicyName()); assertEquals(toscaPolicy.getVersion(), params.getPolicyVersion()); assertEquals(toscaPolicy.getType() + ":" + toscaPolicy.getVersion(), params.getPolicyScope()); - - assertNull(ControlLoopUtils.toControlLoopParams(null)); - - Map properties = toscaPolicy.getProperties(); - toscaPolicy.setProperties(null); - assertNull(ControlLoopUtils.toControlLoopParams(toscaPolicy)); - toscaPolicy.setProperties(properties); + assertSame(toscaPolicy, params.getToscaPolicy()); } } \ No newline at end of file diff --git a/controlloop/common/eventmanager/src/test/resources/tosca-policy-compliant-vcpe.json b/controlloop/common/eventmanager/src/test/resources/tosca-policy-compliant-vcpe.json new file mode 100644 index 000000000..c01f6898c --- /dev/null +++ b/controlloop/common/eventmanager/src/test/resources/tosca-policy-compliant-vcpe.json @@ -0,0 +1,37 @@ +{ + "type": "onap.policies.controlloop.operational.common.Drools", + "type_version": "1.0.0", + "version": "1.0.0", + "name": "operational.restart", + "metadata": { + "policy-id": "operational.restart" + }, + "properties": { + "id": "ControlLoop-vCPE-48f0c2c3-a172-4192-9ae3-052274181b6e", + "timeout": 3600, + "abatement": false, + "trigger": "unique-policy-id-1-restart", + "operations": [ + { + "id": "unique-policy-id-1-restart", + "description": "Restart the VM", + "operation": { + "actor": "APPC", + "operation": "Restart", + "target": { + "type": "VM" + } + }, + "timeout": 1200, + "retries": 3, + "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" + } + ], + "controllerName": "usecases" + } +} \ No newline at end of file diff --git a/controlloop/common/eventmanager/src/test/resources/tosca-policy-legacy-vcpe.json b/controlloop/common/eventmanager/src/test/resources/tosca-policy-legacy-vcpe.json new file mode 100644 index 000000000..fd7c718db --- /dev/null +++ b/controlloop/common/eventmanager/src/test/resources/tosca-policy-legacy-vcpe.json @@ -0,0 +1,9 @@ +{ + "type": "onap.policies.controlloop.Operational", + "type_version": "1.0.0", + "properties": { + "content": "controlLoop%3A%0D%0A++version%3A+2.0.0%0D%0A++controlLoopName%3A+ControlLoop-vCPE-48f0c2c3-a172-4192-9ae3-052274181b6e%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+APPC%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" + }, + "name": "operational.restart", + "version": "1.0.0" +} diff --git a/controlloop/common/eventmanager/src/test/resources/tosca-policy-operational-restart.json b/controlloop/common/eventmanager/src/test/resources/tosca-policy-operational-restart.json deleted file mode 100644 index fd7c718db..000000000 --- a/controlloop/common/eventmanager/src/test/resources/tosca-policy-operational-restart.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "type": "onap.policies.controlloop.Operational", - "type_version": "1.0.0", - "properties": { - "content": "controlLoop%3A%0D%0A++version%3A+2.0.0%0D%0A++controlLoopName%3A+ControlLoop-vCPE-48f0c2c3-a172-4192-9ae3-052274181b6e%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+APPC%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" - }, - "name": "operational.restart", - "version": "1.0.0" -} diff --git a/controlloop/common/feature-controlloop-management/src/main/java/org/onap/policy/drools/server/restful/RestControlLoopManager.java b/controlloop/common/feature-controlloop-management/src/main/java/org/onap/policy/drools/server/restful/RestControlLoopManager.java index ff53d5201..35aabe424 100644 --- a/controlloop/common/feature-controlloop-management/src/main/java/org/onap/policy/drools/server/restful/RestControlLoopManager.java +++ b/controlloop/common/feature-controlloop-management/src/main/java/org/onap/policy/drools/server/restful/RestControlLoopManager.java @@ -25,15 +25,11 @@ import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiParam; import io.swagger.annotations.ApiResponse; import io.swagger.annotations.ApiResponses; -import java.io.UnsupportedEncodingException; -import java.net.URLDecoder; -import java.net.URLEncoder; import java.util.List; import java.util.UUID; import java.util.stream.Collectors; import javax.ws.rs.Consumes; import javax.ws.rs.GET; -import javax.ws.rs.PUT; import javax.ws.rs.Path; import javax.ws.rs.PathParam; import javax.ws.rs.Produces; @@ -41,13 +37,9 @@ import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; import javax.ws.rs.core.Response.Status; import org.onap.policy.aai.AaiManager; -import org.onap.policy.controlloop.ControlLoopException; import org.onap.policy.controlloop.drl.legacy.ControlLoopParams; import org.onap.policy.controlloop.eventmanager.ControlLoopEventManager; -import org.onap.policy.controlloop.processor.ControlLoopProcessor; import org.onap.policy.drools.apps.controlloop.feature.management.ControlLoopManagementFeature; -import org.onap.policy.drools.controller.DroolsController; -import org.onap.policy.drools.system.PolicyControllerConstants; import org.onap.policy.drools.system.PolicyEngineConstants; import org.onap.policy.rest.RestManager; import org.slf4j.Logger; @@ -122,111 +114,6 @@ public class RestControlLoopManager { } } - /** - * GET operational policy. - * - * @param controllerName controller name. - * @param sessionName session name. - * @param controlLoopName control loop name. - * @return operational policy. - */ - @GET - @Path("engine/controllers/{controller}/drools/facts/{session}/controlloops/{controlLoopName}/policy") - @Produces(MediaType.TEXT_PLAIN) - @ApiOperation( value = "Operational Policy", notes = "The policy is in yaml format") - @ApiResponses(value = {@ApiResponse(code = 404, message = "The Control Loop cannot be found"), - @ApiResponse(code = 500, message = "The Control Loop has invalid data")}) - public Response policy( - @ApiParam(value = "Policy Controller Name", required = true) @PathParam("controller") String controllerName, - @ApiParam(value = "Drools Session Name", required = true) @PathParam("session") String sessionName, - @ApiParam(value = "Control Loop Name", required = true) @PathParam("controlLoopName") String controlLoopName) { - - try { - ControlLoopParams controlLoopParams = - ControlLoopManagementFeature.controlLoops(controllerName, sessionName) - .filter(c -> c.getClosedLoopControlName().equals(controlLoopName)) - .findFirst() - .orElse(null); - - if (controlLoopParams == null || controlLoopParams.getControlLoopYaml() == null) { - return Response.status(Response.Status.NOT_FOUND).entity("Policy not found").build(); - } - - return Response.status(Status.OK) - .entity(URLDecoder.decode(controlLoopParams.getControlLoopYaml(), "UTF-8")).build(); - } catch (IllegalArgumentException e) { - logger.error("{}", e); - return Response.status(Response.Status.NOT_FOUND).entity(e.getMessage()).build(); - } catch (UnsupportedEncodingException e) { - logger.error("{}", e); - return Response.status(Status.INTERNAL_SERVER_ERROR).entity("Unreadable Policy").build(); - } - } - - /** - * PUT an Operational Policy. - * - * @param controllerName controller name. - * @param sessionName session name. - * @param controlLoopName control loop name. - * @param policy operational policy. - * - * @return operational policy. - */ - - @PUT - @Path("engine/controllers/{controller}/drools/facts/{session}/controlloops/{controlLoopName}/policy") - @Consumes(MediaType.TEXT_PLAIN) - @ApiOperation( value = "Add Operational Policy", notes = "The Operational Policy should be syntactically correct") - @ApiResponses(value = {@ApiResponse(code = 404, message = "The Control Loop cannot be found"), - @ApiResponse(code = 409, message = "The Control Loop exists"), - @ApiResponse(code = 412, message = "The Control Loop Name must be matched in the URL"), - @ApiResponse(code = 406, message = "The Operational Policy is invalid")}) - public Response opOffer( - @ApiParam(value = "Policy Controller Name", required = true) @PathParam("controller") String controllerName, - @ApiParam(value = "Drools Session Name", required = true) @PathParam("session") String sessionName, - @ApiParam(value = "Control Loop Name", required = true) @PathParam("controlLoopName") String controlLoopName, - @ApiParam(value = "Operational Policy", required = true) String policy) { - - try { - ControlLoopParams controlLoop = - ControlLoopManagementFeature.controlLoop(controllerName, sessionName, controlLoopName); - - if (controlLoop != null) { - return Response.status(Status.CONFLICT).entity(controlLoop).build(); - } - - /* validation */ - - ControlLoopProcessor controlLoopProcessor = new ControlLoopProcessor(policy); - - if (!controlLoopName.equals(controlLoopProcessor.getControlLoop().getControlLoopName())) { - return Response.status(Status.PRECONDITION_FAILED) - .entity("Control Loop Name in URL does not match the Operational Policy") - .build(); - } - - DroolsController controller = PolicyControllerConstants.getFactory().get(controllerName).getDrools(); - - controlLoop = new ControlLoopParams(); - controlLoop.setPolicyScope(controller.getGroupId()); - controlLoop.setPolicyName(controller.getArtifactId()); - controlLoop.setPolicyVersion(controller.getVersion()); - controlLoop.setClosedLoopControlName(controlLoopName); - controlLoop.setControlLoopYaml(URLEncoder.encode(policy, "UTF-8")); - - controller.getContainer().insertAll(controlLoop); - return Response.status(Status.OK).entity(controlLoop).build(); - - } catch (IllegalArgumentException i) { - logger.error("{}", i); - return Response.status(Response.Status.NOT_FOUND).entity(i).build(); - } catch (ControlLoopException | UnsupportedEncodingException e) { - logger.error("{}", e); - return Response.status(Status.NOT_ACCEPTABLE).entity(e).build(); - } - } - /** * AAI Custom Query. * diff --git a/controlloop/common/feature-controlloop-management/src/test/java/org/onap/policy/drools/server/restful/RestControlLoopManagerTest.java b/controlloop/common/feature-controlloop-management/src/test/java/org/onap/policy/drools/server/restful/RestControlLoopManagerTest.java index c2a9e536f..7fad4468d 100644 --- a/controlloop/common/feature-controlloop-management/src/test/java/org/onap/policy/drools/server/restful/RestControlLoopManagerTest.java +++ b/controlloop/common/feature-controlloop-management/src/test/java/org/onap/policy/drools/server/restful/RestControlLoopManagerTest.java @@ -2,7 +2,7 @@ * ============LICENSE_START======================================================= * ONAP * ================================================================================ - * Copyright (C) 2018-2019 AT&T Intellectual Property. All rights reserved. + * Copyright (C) 2018-2020 AT&T Intellectual Property. All rights reserved. * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -28,11 +28,9 @@ import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; -import java.util.Collections; import java.util.Properties; import java.util.concurrent.Callable; import java.util.concurrent.TimeUnit; -import javax.ws.rs.client.Entity; import javax.ws.rs.core.Response.Status; import org.junit.AfterClass; import org.junit.BeforeClass; @@ -179,25 +177,6 @@ public class RestControlLoopManagerTest { assertEquals(Status.NOT_FOUND.getStatusCode(), HttpClientFactoryInstance.getClientFactory() .get(CONTROLLER).get(URL_CONTEXT_PATH_CONTROLLOOP_POLICY).getStatus()); - - String policyFromFile = new String(Files.readAllBytes(Paths.get(POLICY))); - HttpClientFactoryInstance.getClientFactory().get(CONTROLLER).put( - URL_CONTEXT_PATH_CONTROLLOOP_POLICY, Entity.text(policyFromFile), - Collections.emptyMap()); - - assertEquals(Status.OK.getStatusCode(), HttpClientFactoryInstance.getClientFactory() - .get(CONTROLLER).get(URL_CONTEXT_PATH_CONTROLLOOP_POLICY).getStatus()); - - String policyFromPdpD = HttpClientFactoryInstance.getClientFactory().get(CONTROLLER) - .get(URL_CONTEXT_PATH_CONTROLLOOP_POLICY).readEntity(String.class); - - assertEquals(policyFromFile, policyFromPdpD); - - assertEquals(Status.CONFLICT.getStatusCode(), - HttpClientFactoryInstance.getClientFactory().get(CONTROLLER) - .put(URL_CONTEXT_PATH_CONTROLLOOP_POLICY, Entity.text(policyFromFile), - Collections.emptyMap()) - .getStatus()); } /** diff --git a/controlloop/common/feature-controlloop-usecases/pom.xml b/controlloop/common/feature-controlloop-usecases/pom.xml index 6e40e1bda..1e17d98a1 100644 --- a/controlloop/common/feature-controlloop-usecases/pom.xml +++ b/controlloop/common/feature-controlloop-usecases/pom.xml @@ -2,7 +2,7 @@ ============LICENSE_START======================================================= ONAP ================================================================================ - Copyright (C) 2018-2019 AT&T Intellectual Property. All rights reserved. + Copyright (C) 2018-2020 AT&T Intellectual Property. All rights reserved. Modifications Copyright (C) 2020 Bell Canada. ================================================================================ Licensed under the Apache License, Version 2.0 (the "License"); @@ -34,17 +34,15 @@ Load Experimental Usecases Control Loop Use Cases Controller as a feature. - - 1.8 - 1.8 - - src/main/feature true + + src/main/resources + diff --git a/controlloop/common/pom.xml b/controlloop/common/pom.xml index 3ef03b11d..a50e3d449 100644 --- a/controlloop/common/pom.xml +++ b/controlloop/common/pom.xml @@ -2,7 +2,7 @@ ============LICENSE_START======================================================= Drools PDP Application Common Models ================================================================================ - Copyright (C) 2017, 2019 AT&T Intellectual Property. All rights reserved. + Copyright (C) 2017, 2019-2020 AT&T Intellectual Property. All rights reserved. Modifications Copyright (C) 2020 Bell Canada. ================================================================================ Licensed under the Apache License, Version 2.0 (the "License"); @@ -37,6 +37,7 @@ guard coordination eventmanager + domains controller-usecases feature-controlloop-utils feature-controlloop-trans -- cgit 1.2.3-korg