From c1f79cd311ad62d3adb374921b8c3d303db5add6 Mon Sep 17 00:00:00 2001 From: Jim Hahn Date: Sat, 22 Feb 2020 17:11:20 -0500 Subject: Add frankfurt rules for Actor redesign Note: VcpeTest and VfwTest are not included, as they depend on updates to the APPC and APPC-LCM Actors. Added feature-controlloop-frankfurt. Added HTTP client property files to feature-controlloop-management. Updates per review comments: - pom changes - simplify FrankfurtBase - rename event-svc-http.properties - change "usescases" to "frankfurt" - use blanks for CDS property defaults - trailing spaces in http-client files - add https property to http-client files Added newlines to config files that appear to be missing them (based on feedback from gerrit). Issue-ID: POLICY-2385 Signed-off-by: Jim Hahn Change-Id: Ib4a4d75461c734ae47309e41dc9d099e8815d55d --- .../src/main/resources/META-INF/kmodule.xml | 27 + .../src/main/resources/frankfurt.drl | 348 +++++++++++++ .../org/onap/policy/controlloop/FrankfurtBase.java | 558 +++++++++++++++++++++ .../java/org/onap/policy/controlloop/VlbTest.java | 152 ++++++ .../test/resources/config/event-manager.properties | 70 +++ .../config/frankfurt-controller.properties | 65 +++ .../config/frankfurt-http-client.properties | 52 ++ .../src/test/resources/frankfurt.pom | 30 ++ .../test/resources/vcpe/tosca-compliant-vcpe.json | 37 ++ .../src/test/resources/vcpe/tosca-legacy-vcpe.json | 9 + .../src/test/resources/vcpe/vcpe.appc.success.json | 22 + .../src/test/resources/vcpe/vcpe.onset.1.json | 16 + .../src/test/resources/vcpe/vcpe.onset.2.json | 16 + .../src/test/resources/vcpe/vcpe.onset.3.json | 17 + .../test/resources/vfw/tosca-compliant-vfw.json | 40 ++ .../src/test/resources/vfw/tosca-vfw.json | 9 + .../src/test/resources/vfw/vfw.appc.success.json | 17 + .../src/test/resources/vfw/vfw.onset.json | 17 + .../test/resources/vlb/tosca-compliant-vlb.json | 48 ++ .../src/test/resources/vlb/tosca-vlb.json | 9 + .../src/test/resources/vlb/vlb.onset.json | 16 + 21 files changed, 1575 insertions(+) create mode 100644 controlloop/common/controller-frankfurt/src/main/resources/META-INF/kmodule.xml create mode 100644 controlloop/common/controller-frankfurt/src/main/resources/frankfurt.drl create mode 100644 controlloop/common/controller-frankfurt/src/test/java/org/onap/policy/controlloop/FrankfurtBase.java create mode 100644 controlloop/common/controller-frankfurt/src/test/java/org/onap/policy/controlloop/VlbTest.java create mode 100644 controlloop/common/controller-frankfurt/src/test/resources/config/event-manager.properties create mode 100644 controlloop/common/controller-frankfurt/src/test/resources/config/frankfurt-controller.properties create mode 100644 controlloop/common/controller-frankfurt/src/test/resources/config/frankfurt-http-client.properties create mode 100644 controlloop/common/controller-frankfurt/src/test/resources/frankfurt.pom create mode 100644 controlloop/common/controller-frankfurt/src/test/resources/vcpe/tosca-compliant-vcpe.json create mode 100644 controlloop/common/controller-frankfurt/src/test/resources/vcpe/tosca-legacy-vcpe.json create mode 100644 controlloop/common/controller-frankfurt/src/test/resources/vcpe/vcpe.appc.success.json create mode 100644 controlloop/common/controller-frankfurt/src/test/resources/vcpe/vcpe.onset.1.json create mode 100644 controlloop/common/controller-frankfurt/src/test/resources/vcpe/vcpe.onset.2.json create mode 100644 controlloop/common/controller-frankfurt/src/test/resources/vcpe/vcpe.onset.3.json create mode 100644 controlloop/common/controller-frankfurt/src/test/resources/vfw/tosca-compliant-vfw.json create mode 100644 controlloop/common/controller-frankfurt/src/test/resources/vfw/tosca-vfw.json create mode 100644 controlloop/common/controller-frankfurt/src/test/resources/vfw/vfw.appc.success.json create mode 100644 controlloop/common/controller-frankfurt/src/test/resources/vfw/vfw.onset.json create mode 100644 controlloop/common/controller-frankfurt/src/test/resources/vlb/tosca-compliant-vlb.json create mode 100644 controlloop/common/controller-frankfurt/src/test/resources/vlb/tosca-vlb.json create mode 100644 controlloop/common/controller-frankfurt/src/test/resources/vlb/vlb.onset.json (limited to 'controlloop/common/controller-frankfurt/src') diff --git a/controlloop/common/controller-frankfurt/src/main/resources/META-INF/kmodule.xml b/controlloop/common/controller-frankfurt/src/main/resources/META-INF/kmodule.xml new file mode 100644 index 000000000..b5e4e3f0e --- /dev/null +++ b/controlloop/common/controller-frankfurt/src/main/resources/META-INF/kmodule.xml @@ -0,0 +1,27 @@ + + + + + + + + diff --git a/controlloop/common/controller-frankfurt/src/main/resources/frankfurt.drl b/controlloop/common/controller-frankfurt/src/main/resources/frankfurt.drl new file mode 100644 index 000000000..00c4f5f10 --- /dev/null +++ b/controlloop/common/controller-frankfurt/src/main/resources/frankfurt.drl @@ -0,0 +1,348 @@ +/* + * ============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.controlloop; + +import org.onap.policy.controlloop.drl.legacy.ControlLoopParams; +import org.onap.policy.controlloop.CanonicalOnset; +import org.onap.policy.controlloop.VirtualControlLoopEvent; +import org.onap.policy.controlloop.VirtualControlLoopNotification; +import org.onap.policy.controlloop.ControlLoopNotificationType; +import org.onap.policy.controlloop.policy.Policy; +import org.onap.policy.controlloop.eventmanager.ControlLoopEventManager2; +import org.onap.policy.controlloop.eventmanager.ControlLoopEventManager2.NewEventStatus; +import org.onap.policy.controlloop.eventmanager.ControlLoopOperationManager2; +import org.onap.policy.controlloop.utils.ControlLoopUtils; +import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicy; + +import org.slf4j.LoggerFactory; +import org.slf4j.Logger; + +import org.onap.policy.drools.system.PolicyEngineConstants; + +/* +* +* Called when the ControlLoopParams object has been inserted into working memory from the BRMSGW. +* +*/ +rule "INSERT.PARAMS" + when + $params : ControlLoopParams() + then + + Logger logger = LoggerFactory.getLogger(drools.getRule().getPackage()); + logger.info("{}: {} : TOSCA-POLICY=[{}]", $params.getClosedLoopControlName(), $params.getPolicyName() + "." + + drools.getRule().getName(), $params.getToscaPolicy()); +end + +/* +* +* Called when a Tosca Policy is present. +* +*/ +rule "NEW.TOSCA.POLICY" + when + $policy : ToscaPolicy() + then + + Logger logger = LoggerFactory.getLogger(drools.getRule().getPackage()); + logger.info("{}: [{}|{}|{}|{}]: CONTENT: {}", drools.getRule().getName(), + $policy.getType(), $policy.getTypeVersion(), $policy.getName(), + $policy.getVersion(), $policy); + + ControlLoopParams params = ControlLoopUtils.toControlLoopParams($policy); + if (params != null) { + insert(params); + } +end + +/* + * Remove Control Loop Parameters. + */ +rule "REMOVE.PARAMS" + when + $params : ControlLoopParams( $policyName : getPolicyName(), $policyVersion : getPolicyVersion() ) + not ( ToscaPolicy( getName() == $policyName, getVersion() == $policyVersion ) ) + then + + Logger logger = LoggerFactory.getLogger(drools.getRule().getPackage()); + logger.info("{}: [{}|{}|{}]", drools.getRule().getName(), + $params.getPolicyScope(), $params.getPolicyName(), $params.getPolicyVersion()); + + retract($params); +end + +/* +* +* This rule responds to DCAE Events where there is no manager yet. Either it is +* the first ONSET, or a subsequent badly formed Event (i.e. Syntax error, or is-closed-loop-disabled) +* +*/ +rule "EVENT" + when + $params : ControlLoopParams( $clName : getClosedLoopControlName() ) + $event : CanonicalOnset( closedLoopControlName == $clName ) + not ( ControlLoopEventManager2( closedLoopControlName == $event.getClosedLoopControlName(), + requestId == $event.getRequestId() ) ) + then + + Logger logger = LoggerFactory.getLogger(drools.getRule().getPackage()); + logger.info("{}: {}.{}: event={}", + $clName, $params.getPolicyName(), drools.getRule().getName(), + $event); + // + // Retract the event from memory; it will be managed by the manager for now on + // + retract($event); + + VirtualControlLoopNotification notification; + + try { + // + // Check the event, because we need it to not be null when + // we create the ControlLoopEventManager2. The ControlLoopEventManager2 + // will do extra syntax checking as well as check if the closed loop is disabled. + // + if ($event.getRequestId() == null) { + notification = new VirtualControlLoopNotification($event); + notification.setNotification(ControlLoopNotificationType.REJECTED); + notification.setFrom("policy"); + notification.setMessage("Missing requestId"); + notification.setPolicyName($params.getPolicyName() + "." + drools.getRule().getName()); + notification.setPolicyScope($params.getPolicyScope()); + notification.setPolicyVersion($params.getPolicyVersion()); + + } else { + ControlLoopEventManager2 manager = new ControlLoopEventManager2($params, $event, drools.getWorkingMemory()); + insert(manager); + try { + manager.start(); + } catch(Exception e) { + retract(manager); + throw e; + } + notification = manager.makeNotification(); + notification.setNotification(ControlLoopNotificationType.ACTIVE); + notification.setPolicyName($params.getPolicyName() + "." + drools.getRule().getName()); + } + } catch (Exception e) { + logger.warn("{}: {}.{}", $clName, $params.getPolicyName(), drools.getRule().getName(), e); + notification = new VirtualControlLoopNotification($event); + notification.setNotification(ControlLoopNotificationType.REJECTED); + notification.setMessage("Exception occurred: " + e.getMessage()); + notification.setPolicyName($params.getPolicyName() + "." + drools.getRule().getName()); + notification.setPolicyScope($params.getPolicyScope()); + notification.setPolicyVersion($params.getPolicyVersion()); + } + // + // Generate notification + // + try { + PolicyEngineConstants.getManager().deliver("POLICY-CL-MGT", notification); + + } catch(RuntimeException e) { + logger.warn("{}: {}.{}: event={} exception generating notification", + $clName, $params.getPolicyName(), drools.getRule().getName(), + $event, e); + } +end + +/* +* +* This rule happens when we get a subsequent event. +* +*/ +rule "EVENT.MANAGER.NEW.EVENT" + when + $event : VirtualControlLoopEvent( ) + $manager : ControlLoopEventManager2( closedLoopControlName == $event.getClosedLoopControlName(), + requestId == $event.getRequestId() ) + then + + Logger logger = LoggerFactory.getLogger(drools.getRule().getPackage()); + logger.info("{}: {}.{}: event={} manager={}", + $manager.getClosedLoopControlName(), $manager.getPolicyName(), drools.getRule().getName(), + $event, $manager); + // + // Remove the event from memory + // + retract($event); + + // + // Check what kind of event this is + // + switch($manager.onNewEvent($event)) { + case SYNTAX_ERROR: + // + // Ignore any bad syntax events + // + logger.warn("{}: {}.{}: syntax error", + $manager.getClosedLoopControlName(), $manager.getPolicyName(), drools.getRule().getName()); + break; + + case FIRST_ABATEMENT: + case SUBSEQUENT_ABATEMENT: + // + // TODO: handle the abatement. Currently, it's just discarded. + // + break; + + case FIRST_ONSET: + case SUBSEQUENT_ONSET: + default: + // + // We don't care about subsequent onsets + // + logger.warn("{}: {}.{}: subsequent onset", + $manager.getClosedLoopControlName(), $manager.getPolicyName(), drools.getRule().getName()); + break; + } +end + +/* +* +* Step completed +* +*/ +rule "EVENT.MANAGER.PROCESSING" + when + $manager : ControlLoopEventManager2( isUpdated(), isActive(), $notification : getNotification() ) + then + + Logger logger = LoggerFactory.getLogger(drools.getRule().getPackage()); + logger.info("{}: {}.{}: manager={}", + $manager.getClosedLoopControlName(), $manager.getPolicyName(), drools.getRule().getName(), + $manager); + // + // Generate notification + // + try { + $notification.setPolicyName($manager.getPolicyName() + "." + drools.getRule().getName()); + PolicyEngineConstants.getManager().deliver("POLICY-CL-MGT", $notification); + + } catch(RuntimeException e) { + logger.warn("{}: {}.{}: manager={} exception generating notification", + $manager.getClosedLoopControlName(), $manager.getPolicyName(), drools.getRule().getName(), + $manager, e); + } + // + // Discard this message and wait for the next response. + // + $manager.nextStep(); + update($manager); +end + +/* +* +* Final step completed +* +*/ +rule "EVENT.MANAGER.FINAL" + when + $manager : ControlLoopEventManager2( !isActive(), $notification : getNotification() ) + then + + Logger logger = LoggerFactory.getLogger(drools.getRule().getPackage()); + logger.info("{}: {}.{}: manager={}", + $manager.getClosedLoopControlName(), $manager.getPolicyName(), drools.getRule().getName(), + $manager); + // + // Generate notification + // + try { + $notification.setPolicyName($manager.getPolicyName() + "." + drools.getRule().getName()); + PolicyEngineConstants.getManager().deliver("POLICY-CL-MGT", $notification); + + } catch(RuntimeException e) { + logger.warn("{}: {}.{}: manager={} exception generating notification", + $manager.getClosedLoopControlName(), $manager.getPolicyName(), drools.getRule().getName(), + $manager, e); + } + // + // Retract and destroy the manager + // + retract($manager); + $manager.destroy(); +end + +/* +* +* This rule will clean up any rogue events where there is no +* ControlLoopParams object corresponding to the onset event. +* +*/ +rule "EVENT.CLEANUP" + salience -1 + when + $event : VirtualControlLoopEvent( $clName: closedLoopControlName ) + then + + Logger logger = LoggerFactory.getLogger(drools.getRule().getPackage()); + logger.info("{}: {}", $clName, drools.getRule().getName()); + logger.debug("{}: {}: orphan event={}", + $clName, drools.getRule().getName(), $event); + // + // Retract the event + // + retract($event); +end + +/* +* +* At this point, it appears that if we prevent the rules from getting messages from +* topics, then that will also prevent the actors from getting them. So the following +* rules are here just to discard those messages. +* +* These have a higher salience so the objects are removed before the "FINAL" message +* is processed, so that the junit test can assume things are done once they see the +* "FINAL" message. Otherwise, tests might fail sporadically. +* +*/ +rule "APPC.Response.CLEANUP" + salience 1 + when + $msg : org.onap.policy.appc.Response( ) + then + retract($msg); +end + +rule "APPC.Request.CLEANUP" + salience 1 + when + $msg : org.onap.policy.appc.Request( ) + then + retract($msg); +end + +rule "APPC-LCM.Response.CLEANUP" + salience 1 + when + $msg : org.onap.policy.appclcm.AppcLcmDmaapWrapper( ) + then + retract($msg); +end + +rule "SDNR.Response.CLEANUP" + salience 1 + when + $msg : org.onap.policy.sdnr.PciResponseWrapper( ) + then + retract($msg); +end diff --git a/controlloop/common/controller-frankfurt/src/test/java/org/onap/policy/controlloop/FrankfurtBase.java b/controlloop/common/controller-frankfurt/src/test/java/org/onap/policy/controlloop/FrankfurtBase.java new file mode 100644 index 000000000..6e3380ee4 --- /dev/null +++ b/controlloop/common/controller-frankfurt/src/test/java/org/onap/policy/controlloop/FrankfurtBase.java @@ -0,0 +1,558 @@ +/*- + * ============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.controlloop; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.awaitility.Awaitility.await; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.Collections; +import java.util.LinkedList; +import java.util.Properties; +import java.util.Queue; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; +import lombok.Getter; +import org.apache.commons.io.IOUtils; +import org.apache.commons.lang3.StringUtils; +import org.kie.api.event.rule.AfterMatchFiredEvent; +import org.kie.api.event.rule.BeforeMatchFiredEvent; +import org.kie.api.event.rule.DefaultAgendaEventListener; +import org.kie.api.event.rule.DefaultRuleRuntimeEventListener; +import org.kie.api.event.rule.MatchCancelledEvent; +import org.kie.api.event.rule.MatchCreatedEvent; +import org.kie.api.event.rule.ObjectDeletedEvent; +import org.kie.api.event.rule.ObjectInsertedEvent; +import org.kie.api.event.rule.ObjectUpdatedEvent; +import org.kie.api.event.rule.RuleRuntimeEventListener; +import org.kie.api.runtime.KieSession; +import org.onap.policy.common.endpoints.event.comm.Topic; +import org.onap.policy.common.endpoints.event.comm.Topic.CommInfrastructure; +import org.onap.policy.common.endpoints.event.comm.TopicEndpointManager; +import org.onap.policy.common.endpoints.event.comm.TopicListener; +import org.onap.policy.common.endpoints.http.client.HttpClientConfigException; +import org.onap.policy.common.endpoints.http.client.HttpClientFactoryInstance; +import org.onap.policy.common.endpoints.http.server.HttpServletServerFactoryInstance; +import org.onap.policy.common.utils.coder.Coder; +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.controlloop.drl.legacy.ControlLoopParams; +import org.onap.policy.drools.persistence.SystemPersistence; +import org.onap.policy.drools.persistence.SystemPersistenceConstants; +import org.onap.policy.drools.protocol.coders.EventProtocolCoderConstants; +import org.onap.policy.drools.system.PolicyController; +import org.onap.policy.drools.system.PolicyControllerConstants; +import org.onap.policy.drools.system.PolicyEngine; +import org.onap.policy.drools.system.PolicyEngineConstants; +import org.onap.policy.drools.util.KieUtils; +import org.onap.policy.drools.utils.logging.LoggerUtil; +import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicy; +import org.onap.policy.models.tosca.authorative.concepts.ToscaServiceTemplate; +import org.onap.policy.simulators.Util; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Use Cases Tests Framework. + */ +public abstract class FrankfurtBase { + + private static final Logger logger = LoggerFactory.getLogger(FrankfurtBase.class); + private static final StandardCoder coder = new StandardCoder(); + + /** + * PDP-D Engine. + */ + protected static final PolicyEngine pdpD = PolicyEngineConstants.getManager(); + + /** + * PDP-D Configuration Repository. + */ + protected static final SystemPersistence repo = SystemPersistenceConstants.getManager(); + + /** + * Frankfurt controller and session name. + */ + protected static final String CONTROLLER_NAME = "frankfurt"; + + /** + * Frankfurt controller. + */ + protected static PolicyController controller; + + /* + * Canonical Topic Names. + */ + protected static final String DCAE_TOPIC = "DCAE_TOPIC"; + protected static final String APPC_LCM_WRITE_TOPIC = "APPC-LCM-WRITE"; + protected static final String POLICY_CL_MGT_TOPIC = "POLICY-CL-MGT"; + protected static final String APPC_LCM_READ_TOPIC = "APPC-LCM-READ"; + protected static final String APPC_CL_TOPIC = "APPC-CL"; + + protected static void initConfigDir() { + SystemPersistenceConstants.getManager().setConfigurationDir("src/test/resources/config"); + } + + /** + * Sets up overall logging. + */ + protected static void setupLogging() { + LoggerUtil.setLevel(LoggerUtil.ROOT_LOGGER, "WARN"); + LoggerUtil.setLevel("org.eclipse.jetty", "WARN"); + LoggerUtil.setLevel("org.onap.policy.controlloop", "INFO"); + LoggerUtil.setLevel("network", "INFO"); + } + + /** + * Sets up Drools Logging for events of interest. + */ + protected static void setupDroolsLogging() { + KieSession session = PolicyControllerConstants.getFactory().get(CONTROLLER_NAME).getDrools().getContainer() + .getPolicySession(CONTROLLER_NAME).getKieSession(); + + session.addEventListener(new RuleListenerLogger()); + session.addEventListener(new AgendaListenerLogger()); + } + + /** + * Sets up Http Clients specified in the property file. + */ + protected static void setUpHttpClients() { + try { + HttpClientFactoryInstance.getClientFactory().build( + SystemPersistenceConstants.getManager().getHttpClientProperties("frankfurt")); + } catch (HttpClientConfigException e) { + throw new IllegalArgumentException("cannot initialize HTTP clients", e); + } + } + + /** + * Sets up Simulators for use case testing. + */ + protected static void setupSimulators() throws InterruptedException { + Util.buildAaiSim(); + Util.buildSoSim(); + Util.buildVfcSim(); + Util.buildGuardSim(); + Util.buildSdncSim(); + } + + /** + * Returns the runtime Control Loop Parameters associated with a Tosca Policy. + */ + protected ControlLoopParams clParameters(ToscaPolicy policy) { + return controller.getDrools().facts(CONTROLLER_NAME, ControlLoopParams.class).stream() + .filter((params) -> params.getToscaPolicy() == policy).findFirst().get(); + } + + protected ToscaPolicy getPolicyFromResource(String resourcePath, String policyName) throws CoderException { + String policyJson = ResourceUtils.getResourceAsString(resourcePath); + ToscaServiceTemplate serviceTemplate = coder.decode(policyJson, ToscaServiceTemplate.class); + ToscaPolicy policy = serviceTemplate.getToscaTopologyTemplate().getPolicies().get(0).get(policyName); + assertNotNull(policy); + + /* + * name and version are used within a drl. api component and drools core will + * ensure that these are populated. + */ + if (StringUtils.isBlank(policy.getName())) { + policy.setName(policyName); + } + + if (StringUtils.isBlank(policy.getVersion())) { + policy.setVersion(policy.getTypeVersion()); + } + + return serviceTemplate.getToscaTopologyTemplate().getPolicies().get(0).get(policyName); + } + + protected ToscaPolicy getPolicyFromFile(String policyPath) throws IOException, CoderException { + String rawPolicy = new String(Files.readAllBytes(Paths.get(policyPath))); + return coder.decode(rawPolicy, ToscaPolicy.class); + } + + private ToscaPolicy setupPolicy(ToscaPolicy policy) throws InterruptedException { + final KieObjectExpectedCallback policyTracker = new KieObjectInsertedExpectedCallback<>(policy); + final KieObjectExpectedCallback paramsTracker = + new KieClassInsertedExpectedCallback<>(ControlLoopParams.class); + + controller.getDrools().offer(policy); + + assertTrue(policyTracker.isNotified()); + assertTrue(paramsTracker.isNotified()); + + assertEquals(1, controller.getDrools().facts(CONTROLLER_NAME, ToscaPolicy.class).stream() + .filter((anotherPolicy) -> anotherPolicy == policy).count()); + + assertEquals(1, controller.getDrools().facts(CONTROLLER_NAME, ControlLoopParams.class).stream() + .filter((params) -> params.getToscaPolicy() == policy).count()); + return policy; + } + + /** + * Installs a policy from policy/models (examples) repo. + */ + protected ToscaPolicy setupPolicyFromResource(String resourcePath, String policyName) + throws CoderException, InterruptedException { + return setupPolicy(getPolicyFromResource(resourcePath, policyName)); + } + + + /** + * Installs a given policy. + */ + protected ToscaPolicy setupPolicyFromFile(String policyPath) + throws IOException, CoderException, InterruptedException { + return setupPolicy(getPolicyFromFile(policyPath)); + } + + /** + * Deletes a policy. + */ + protected void deletePolicy(ToscaPolicy policy) throws InterruptedException { + ControlLoopParams clParams = clParameters(policy); + assertNotNull(clParams); + + final KieObjectExpectedCallback policyTracker = new KieObjectDeletedExpectedCallback<>(policy); + final KieObjectExpectedCallback clParamsTracker = new KieObjectDeletedExpectedCallback<>(clParams); + + controller.getDrools().delete(CONTROLLER_NAME, policy); + assertTrue(policyTracker.isNotified()); + assertTrue(clParamsTracker.isNotified()); + + assertEquals(0, controller.getDrools().facts(CONTROLLER_NAME, ToscaPolicy.class).stream() + .filter((anotherPolicy) -> anotherPolicy == policy).count()); + + assertEquals(0, controller.getDrools().facts(CONTROLLER_NAME, ControlLoopParams.class).stream() + .filter((params) -> params.getPolicyName() == policy.getName()).count()); + } + + /** + * Prepare a PDP-D to test the Use Cases. + */ + protected static void preparePdpD() throws IOException { + KieUtils.installArtifact(Paths.get("src/main/resources/META-INF/kmodule.xml").toFile(), + Paths.get("src/test/resources/frankfurt.pom").toFile(), + "src/main/resources/org/onap/policy/controlloop/", + Collections.singletonList(Paths.get("src/main/resources/frankfurt.drl").toFile())); + + repo.setConfigurationDir("src/test/resources/config"); + pdpD.configure(new Properties()); + + controller = pdpD.createPolicyController(CONTROLLER_NAME, repo.getControllerProperties(CONTROLLER_NAME)); + pdpD.start(); + + setupDroolsLogging(); + } + + /** + * Stop PDP-D. + */ + protected static void stopPdpD() { + PolicyControllerConstants.getFactory().shutdown(CONTROLLER_NAME); + pdpD.stop(); + } + + /** + * Stops the http clients. + */ + protected static void stopHttpClients() { + HttpClientFactoryInstance.getClientFactory().destroy(); + } + + /** + * Stop Simulators. + */ + protected static void stopSimulators() { + HttpServletServerFactoryInstance.getServerFactory().destroy(); + } + + /** + * Creates a Topic Sink Callback tracker. + */ + protected TopicCallback createTopicSinkCallback(String topicName, Class clazz) { + return new TopicCallback<>(TopicEndpointManager.getManager().getNoopTopicSink(topicName), clazz); + } + + /** + * Creates a Topic Sink Callback tracker. + */ + protected TopicCallback createTopicSinkCallbackPlain(String topicName, Class clazz, Coder coder) { + return new TopicCallbackCoder<>(TopicEndpointManager.getManager().getNoopTopicSink(topicName), clazz, coder); + } + + /** + * Creates a Topic Source Callback tracker. + */ + protected TopicCallback createTopicSourceCallback(String topicName, Class clazz) { + return new TopicCallback<>(TopicEndpointManager.getManager().getNoopTopicSource(topicName), clazz); + } + + /** + * Injects a message on a Topic Source. + */ + protected void injectOnTopic(String topicName, Path onsetPath) throws IOException { + TopicEndpointManager.getManager().getNoopTopicSource(topicName) + .offer(new String(Files.readAllBytes(onsetPath))); + } + + /** + * Injects a message on a Topic Source, with the given substitution.. + */ + protected void injectOnTopic(String topicName, Path path, String newText) throws IOException { + String text = IOUtils.toString(path.toUri(), StandardCharsets.UTF_8); + text = text.replace("${replaceMe}", newText); + TopicEndpointManager.getManager().getNoopTopicSource(topicName).offer(text); + } + + /** + * Waits for LOCK acquisition and getting a Permit from PDP-X to proceed. + */ + protected void waitForLockAndPermit(ToscaPolicy policy, TopicCallback policyClMgt) { + String policyName = policy.getIdentifier().getName(); + + // TODO register a topic listener instead of using await() ? + + await().until(() -> !policyClMgt.getMessages().isEmpty()); + VirtualControlLoopNotification notif = policyClMgt.getMessages().remove(); + assertEquals(ControlLoopNotificationType.ACTIVE, notif.getNotification()); + assertEquals(policyName + ".EVENT", notif.getPolicyName()); + + await().until(() -> !policyClMgt.getMessages().isEmpty()); + notif = policyClMgt.getMessages().remove(); + assertEquals(ControlLoopNotificationType.OPERATION, notif.getNotification()); + assertEquals(policyName + ".EVENT.MANAGER.PROCESSING", notif.getPolicyName()); + assertThat(notif.getMessage()).startsWith("Sending guard query"); + + await().until(() -> !policyClMgt.getMessages().isEmpty()); + notif = policyClMgt.getMessages().remove(); + assertEquals(ControlLoopNotificationType.OPERATION, notif.getNotification()); + assertEquals(policyName + ".EVENT.MANAGER.PROCESSING", notif.getPolicyName()); + assertThat(notif.getMessage()).startsWith("Guard result").endsWith("Permit"); + } + + /** + * Waits for a FINAL SUCCESS transaction notification. + */ + protected void waitForFinalSuccess(ToscaPolicy policy, TopicCallback policyClMgt) { + await().until(() -> !policyClMgt.getMessages().isEmpty()); + assertEquals(ControlLoopNotificationType.FINAL_SUCCESS, policyClMgt.getMessages().peek().getNotification()); + assertEquals(policy.getIdentifier().getName() + ".EVENT.MANAGER.FINAL", + policyClMgt.getMessages().remove().getPolicyName()); + } + + /** + * Logs Modifications to Working Memory. + */ + static class RuleListenerLogger implements RuleRuntimeEventListener { + @Override + public void objectInserted(ObjectInsertedEvent event) { + String ruleName = (event.getRule() != null) ? event.getRule().getName() : "null"; + logger.info("RULE {}: inserted {}", ruleName, event.getObject()); + } + + @Override + public void objectUpdated(ObjectUpdatedEvent event) { + String ruleName = (event.getRule() != null) ? event.getRule().getName() : "null"; + logger.info("RULE {}: updated {}", ruleName, event.getObject()); + + } + + @Override + public void objectDeleted(ObjectDeletedEvent event) { + String ruleName = (event.getRule() != null) ? event.getRule().getName() : "null"; + logger.info("RULE {}: deleted {}", ruleName, event.getOldObject()); + } + } + + /** + * Logs Rule Matches. + */ + static class AgendaListenerLogger extends DefaultAgendaEventListener { + @Override + public void matchCreated(MatchCreatedEvent event) { + logger.info("RULE {}: match created", event.getMatch().getRule().getName()); + } + + @Override + public void matchCancelled(MatchCancelledEvent event) { + logger.info("RULE {}: match cancelled", event.getMatch().getRule().getName()); + } + + @Override + public void beforeMatchFired(BeforeMatchFiredEvent event) { + logger.info("RULE {}: before match fired", event.getMatch().getRule().getName()); + } + + @Override + public void afterMatchFired(AfterMatchFiredEvent event) { + logger.info("RULE {}: after match fired", event.getMatch().getRule().getName()); + } + } + + /** + * Base Class to track Working Memory updates for objects of type T. + */ + abstract class KieObjectExpectedCallback extends DefaultRuleRuntimeEventListener { + protected T subject; + + protected CountDownLatch countDownLatch = new CountDownLatch(1); + + public KieObjectExpectedCallback(T affected) { + subject = affected; + register(); + } + + public boolean isNotified() throws InterruptedException { + return countDownLatch.await(9L, TimeUnit.SECONDS); + } + + protected void callbacked() { + unregister(); + countDownLatch.countDown(); + } + + public KieObjectExpectedCallback register() { + controller.getDrools().getContainer().getPolicySession(CONTROLLER_NAME).getKieSession() + .addEventListener(this); + return this; + } + + public KieObjectExpectedCallback unregister() { + controller.getDrools().getContainer().getPolicySession(CONTROLLER_NAME).getKieSession() + .removeEventListener(this); + return this; + } + } + + /** + * Tracks inserts in Working Memory for an object of type T. + */ + class KieObjectInsertedExpectedCallback extends KieObjectExpectedCallback { + public KieObjectInsertedExpectedCallback(T affected) { + super(affected); + } + + @Override + public void objectInserted(ObjectInsertedEvent event) { + if (subject == event.getObject()) { + callbacked(); + } + } + } + + /** + * Tracks deletes in Working Memory of an object of type T. + */ + class KieObjectDeletedExpectedCallback extends KieObjectExpectedCallback { + public KieObjectDeletedExpectedCallback(T affected) { + super(affected); + } + + @Override + public void objectDeleted(ObjectDeletedEvent event) { + if (subject == event.getOldObject()) { + callbacked(); + } + } + } + + /** + * Tracks inserts in Working Memory for any object of class T. + */ + class KieClassInsertedExpectedCallback extends KieObjectInsertedExpectedCallback { + + public KieClassInsertedExpectedCallback(T affected) { + super(affected); + } + + public void objectInserted(ObjectInsertedEvent event) { + if (subject == event.getObject().getClass()) { + callbacked(); + } + } + } + + /** + * Tracks callbacks from topics. + */ + class TopicCallback implements TopicListener { + protected final Topic topic; + protected final Class expectedClass; + + @Getter + protected Queue messages = new LinkedList<>(); + + public TopicCallback(Topic topic, Class expectedClass) { + this.topic = topic; + this.expectedClass = expectedClass; + this.topic.register(this); + } + + public TopicCallback register() { + this.topic.register(this); + return this; + } + + public TopicCallback unregister() { + this.topic.unregister(this); + return this; + } + + @Override + @SuppressWarnings("unchecked") + public void onTopicEvent(CommInfrastructure comm, String topic, String event) { + try { + messages.add((T) EventProtocolCoderConstants.getManager().decode(controller.getDrools().getGroupId(), + controller.getDrools().getArtifactId(), topic, event)); + } catch (Exception e) { + logger.warn("invalid mapping in topic {} for event {}", topic, event, e); + } + } + } + + class TopicCallbackCoder extends TopicCallback { + private final Coder coder; + + public TopicCallbackCoder(Topic topic, Class expectedClass, Coder coder) { + super(topic, expectedClass); + this.coder = coder; + } + + @Override + public void onTopicEvent(CommInfrastructure comm, String topic, String event) { + try { + messages.add((T) coder.decode(event, expectedClass)); + } catch (Exception e) { + logger.warn("invalid mapping in topic {} for event {}", topic, event, e); + } + } + + } +} diff --git a/controlloop/common/controller-frankfurt/src/test/java/org/onap/policy/controlloop/VlbTest.java b/controlloop/common/controller-frankfurt/src/test/java/org/onap/policy/controlloop/VlbTest.java new file mode 100644 index 000000000..4e5a6e3c7 --- /dev/null +++ b/controlloop/common/controller-frankfurt/src/test/java/org/onap/policy/controlloop/VlbTest.java @@ -0,0 +1,152 @@ +/*- + * ============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.controlloop; + +import static org.awaitility.Awaitility.await; +import static org.junit.Assert.assertEquals; + +import java.io.IOException; +import java.nio.file.Paths; +import org.junit.After; +import org.junit.AfterClass; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; +import org.onap.policy.common.utils.coder.CoderException; +import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicy; + +/** + * VLB Use Case Tests. + */ +public class VlbTest extends FrankfurtBase { + + /** + * VLB Tosca Policy File. + */ + private static final String TOSCA_LEGACY_POLICY_VLB = "src/test/resources/vlb/tosca-vlb.json"; + private static final String TOSCA_COMPLIANT_POLICY_VLB = "src/test/resources/vlb/tosca-compliant-vlb.json"; + + /* + * VLB Use case Messages. + */ + private static final String ONSET = "src/test/resources/vlb/vlb.onset.json"; + + /* + * Topic trackers used by the VLB use case. + */ + private TopicCallback policyClMgt; + + /* + * VLB Tosca Policy. + */ + private ToscaPolicy policy; + + /** + * Prepare PDP-D Framework for testing. + */ + @BeforeClass + public static void prepareResouces() throws InterruptedException, IOException { + initConfigDir(); + setupLogging(); + preparePdpD(); + setUpHttpClients(); + setupSimulators(); + } + + /** + * Take down the resources used by the test framework. + */ + @AfterClass + public static void takeDownResources() { + stopPdpD(); + stopSimulators(); + } + + /** + * Observe Topics. + */ + @Before + public void topicsRegistration() { + policyClMgt = createTopicSinkCallback(POLICY_CL_MGT_TOPIC, VirtualControlLoopNotification.class); + } + + /** + * Unregister Topic Callbacks and uninstall the policy. + */ + @After + public void topicsUnregistration() throws InterruptedException { + if (policyClMgt != null) { + policyClMgt.unregister(); + } + + // uninstall the policy + assertEquals(2, controller.getDrools().factCount(CONTROLLER_NAME)); + if (policy != null) { + deletePolicy(policy); + } + assertEquals(0, controller.getDrools().factCount(CONTROLLER_NAME)); + } + + /** + * Sunny Day with Legacy Tosca Policy. + */ + @Test + public void sunnyDayLegacy() throws InterruptedException, CoderException, IOException { + assertEquals(0, controller.getDrools().factCount(CONTROLLER_NAME)); + policy = setupPolicyFromFile(TOSCA_LEGACY_POLICY_VLB); + assertEquals(2, controller.getDrools().factCount(CONTROLLER_NAME)); + + sunnyDay(); + } + + /** + * Sunny Day with Tosca Compliant Policy. + */ + @Test + public void sunnyDayCompliant() throws InterruptedException, CoderException, IOException { + assertEquals(0, controller.getDrools().factCount(CONTROLLER_NAME)); + policy = setupPolicyFromFile(TOSCA_COMPLIANT_POLICY_VLB); + assertEquals(2, controller.getDrools().factCount(CONTROLLER_NAME)); + + sunnyDay(); + } + + /** + * Sunny day scenario for the VCPE use case. + */ + private void sunnyDay() throws IOException { + + /* Inject an ONSET event over the DCAE topic */ + injectOnTopic(DCAE_TOPIC, Paths.get(ONSET)); + + /* Wait to acquire a LOCK and a PDP-X PERMIT */ + waitForLockAndPermit(policy, policyClMgt); + + /* Ensure that the VLB SO Operation was successfully completed */ + + await().until(() -> !policyClMgt.getMessages().isEmpty()); + assertEquals(ControlLoopNotificationType.OPERATION_SUCCESS, + policyClMgt.getMessages().remove().getNotification()); + + /* --- VLB Transaction Completed --- */ + waitForFinalSuccess(policy, policyClMgt); + } +} diff --git a/controlloop/common/controller-frankfurt/src/test/resources/config/event-manager.properties b/controlloop/common/controller-frankfurt/src/test/resources/config/event-manager.properties new file mode 100644 index 000000000..7416d0480 --- /dev/null +++ b/controlloop/common/controller-frankfurt/src/test/resources/config/event-manager.properties @@ -0,0 +1,70 @@ +# +# ============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======================================================== +# + +# DB parameters +operation.history.url=jdbc:h2:mem:Frankfurt +operation.history.userName=sa +operation.history.password= + +# Actor parameters +# +# Note: every operation must have at least one entry, otherwise it will not be +# configured and started. Thus some of them have a "placeholder" property. +# + +actor.service.GUARD.disabled=true +actor.service.GUARD.clientName=GUARD +actor.service.GUARD.operations.Decision.path=decision + +actor.service.AAI.clientName=AAI +actor.service.AAI.operations.CustomQuery.path=aai/v16/query +actor.service.AAI.operations.Tenant.path=aai/v16/search/nodes-query + +actor.service.APPC.sinkTopic=APPC-LCM-READ +actor.service.APPC.sourceTopic=APPC-LCM-WRITE +actor.service.APPC.operations.ConfigModify.placeholder= +actor.service.APPC.operations.Migrate.placeholder= +actor.service.APPC.operations.Restart.placeholder= +actor.service.APPC.operations.Rebuild.placeholder= + +# legacy APPC - must specify sink and source for each operation +actor.service.APPC.operations.ModifyConfig.sinkTopic=APPC-CL +actor.service.APPC.operations.ModifyConfig.sourceTopic=APPC-CL + +actor.service.CDS.clientName=CDS +actor.service.CDS.grpcHost=localhost +actor.service.CDS.grpcPort=7878 +actor.service.CDS.grpcUsername=grpc-username +actor.service.CDS.grpcPassword=grpc-password +actor.service.CDS.grpcTimeout=10 +actor.service.CDS.operations.xxx.yyy= + +actor.service.SDNC.clientName=SDNC +actor.service.SDNC.operations.xxx.yyy= + +actor.service.SO.clientName=SO +actor.service.SO.pathGet=orchestrationRequests/v5/ +actor.service.SO.maxGets=20 +actor.service.SO.waitSecGet=20 +actor.service.SO.operations.VF\ Module\ Create.path=serviceInstantiation/v7/serviceInstances +actor.service.SO.operations.VF\ Module\ Delete.path=serviceInstances/v7 + +actor.service.VFC.clientName=VFC +actor.service.VFC.operations.xxx.yyy= diff --git a/controlloop/common/controller-frankfurt/src/test/resources/config/frankfurt-controller.properties b/controlloop/common/controller-frankfurt/src/test/resources/config/frankfurt-controller.properties new file mode 100644 index 000000000..694f66e61 --- /dev/null +++ b/controlloop/common/controller-frankfurt/src/test/resources/config/frankfurt-controller.properties @@ -0,0 +1,65 @@ +# +# ============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========================================================= +# + +controller.name=frankfurt + +rules.groupId=org.onap.policy.controlloop +rules.artifactId=frankfurt +rules.version=1.0.0 + +noop.source.topics=DCAE_TOPIC,APPC-CL,APPC-LCM-WRITE,SDNR-CL-RSP,POLICY-CL-MGT,APPC-LCM-READ,SDNR-CL,DCAE_CL_RSP + +noop.source.topics.DCAE_TOPIC.events=\ + org.onap.policy.controlloop.CanonicalOnset,org.onap.policy.controlloop.CanonicalAbated +noop.source.topics.DCAE_TOPIC.events.org.onap.policy.controlloop.CanonicalOnset.filter=\ + [?($.closedLoopEventStatus == 'ONSET')] +noop.source.topics.DCAE_TOPIC.events.org.onap.policy.controlloop.CanonicalAbated.filter=\ + [?($.closedLoopEventStatus == 'ABATED')] +noop.source.topics.DCAE_TOPIC.events.custom.gson=org.onap.policy.controlloop.util.Serialization,gson + +noop.source.topics.APPC-CL.events=org.onap.policy.appc.Response,org.onap.policy.appc.Request +noop.source.topics.APPC-CL.events.org.onap.policy.appc.Response.filter=[?($.CommonHeader && $.Status)] +noop.source.topics.APPC-CL.events.org.onap.policy.appc.Request.filter=[?($.CommonHeader && $.Action)] +noop.source.topics.APPC-CL.events.custom.gson=org.onap.policy.appc.util.Serialization,gsonPretty + +noop.source.topics.APPC-LCM-WRITE.events=org.onap.policy.appclcm.AppcLcmDmaapWrapper +noop.source.topics.APPC-LCM-WRITE.events.org.onap.policy.appclcm.AppcLcmDmaapWrapper.filter=[?($.type == 'response')] +noop.source.topics.APPC-LCM-WRITE.events.custom.gson=org.onap.policy.appclcm.util.Serialization,gson + +noop.source.topics.SDNR-CL-RSP.events=org.onap.policy.sdnr.PciResponseWrapper +noop.source.topics.SDNR-CL-RSP.events.org.onap.policy.sdnr.PciResponseWrapper.filter=[?($.type == 'response')] +noop.source.topics.SDNR-CL-RSP.events.custom.gson=org.onap.policy.sdnr.util.Serialization,gson + +noop.source.topics.POLICY-CL-MGT.events=org.onap.policy.controlloop.VirtualControlLoopNotification +noop.source.topics.POLICY-CL-MGT.events.custom.gson=org.onap.policy.controlloop.util.Serialization,gsonPretty + +noop.source.topics.APPC-LCM-READ.events=org.onap.policy.appclcm.AppcLcmDmaapWrapper +noop.source.topics.APPC-LCM-READ.events.custom.gson=org.onap.policy.appclcm.util.Serialization,gson + +noop.source.topics.SDNR-CL.events=org.onap.policy.sdnr.PciRequestWrapper +noop.source.topics.SDNR-CL.events.custom.gson=org.onap.policy.sdnr.util.Serialization,gson + +noop.source.topics.DCAE_CL_RSP.events=org.onap.policy.controlloop.ControlLoopResponse +noop.source.topics.DCAE_CL_RSP.events.custom.gson=org.onap.policy.controlloop.util.Serialization,gsonPretty + +noop.sink.topics=APPC-CL,APPC-LCM-READ,POLICY-CL-MGT,SDNR-CL,DCAE_CL_RSP + +noop.sink.topics.POLICY-CL-MGT.events=org.onap.policy.controlloop.VirtualControlLoopNotification +noop.sink.topics.POLICY-CL-MGT.events.custom.gson=org.onap.policy.controlloop.util.Serialization,gsonPretty diff --git a/controlloop/common/controller-frankfurt/src/test/resources/config/frankfurt-http-client.properties b/controlloop/common/controller-frankfurt/src/test/resources/config/frankfurt-http-client.properties new file mode 100644 index 000000000..bb3a1a02b --- /dev/null +++ b/controlloop/common/controller-frankfurt/src/test/resources/config/frankfurt-http-client.properties @@ -0,0 +1,52 @@ +# +# ============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========================================================= +# + +http.client.services=GUARD,AAI,SDNC,SO,VFC + +http.client.services.GUARD.managed=true +http.client.services.GUARD.host=localhost +http.client.services.GUARD.port=6669 +http.client.services.GUARD.username=pdpx +http.client.services.GUARD.password=pdpx +http.client.services.GUARD.contextUriPath=policy/pdpx/v1 + +http.client.services.AAI.managed=true +http.client.services.AAI.host=localhost +http.client.services.AAI.port=6666 +http.client.services.AAI.contextUriPath= + +http.client.services.SDNC.managed=true +http.client.services.SDNC.host=localhost +http.client.services.SDNC.port=6665 +http.client.services.SDNC.username=sdnc +http.client.services.SDNC.password=sdnc +http.client.services.SDNC.contextUriPath= + +http.client.services.SO.managed=true +http.client.services.SO.host=localhost +http.client.services.SO.port=6667 +http.client.services.SO.contextUriPath= + +http.client.services.VFC.managed=true +http.client.services.VFC.host=localhost +http.client.services.VFC.port=6668 +http.client.services.VFC.username=VFC +http.client.services.VFC.password=VFC +http.client.services.VFC.contextUriPath=api/nslcm/v1 diff --git a/controlloop/common/controller-frankfurt/src/test/resources/frankfurt.pom b/controlloop/common/controller-frankfurt/src/test/resources/frankfurt.pom new file mode 100644 index 000000000..707e59c9e --- /dev/null +++ b/controlloop/common/controller-frankfurt/src/test/resources/frankfurt.pom @@ -0,0 +1,30 @@ + + + + + + 4.0.0 + + org.onap.policy.controlloop + frankfurt + 1.0.0 + diff --git a/controlloop/common/controller-frankfurt/src/test/resources/vcpe/tosca-compliant-vcpe.json b/controlloop/common/controller-frankfurt/src/test/resources/vcpe/tosca-compliant-vcpe.json new file mode 100644 index 000000000..b876446dd --- /dev/null +++ b/controlloop/common/controller-frankfurt/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": { + "targetType": "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": "frankfurt" + } +} \ No newline at end of file diff --git a/controlloop/common/controller-frankfurt/src/test/resources/vcpe/tosca-legacy-vcpe.json b/controlloop/common/controller-frankfurt/src/test/resources/vcpe/tosca-legacy-vcpe.json new file mode 100644 index 000000000..f42c07da9 --- /dev/null +++ b/controlloop/common/controller-frankfurt/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-frankfurt/src/test/resources/vcpe/vcpe.appc.success.json b/controlloop/common/controller-frankfurt/src/test/resources/vcpe/vcpe.appc.success.json new file mode 100644 index 000000000..331021798 --- /dev/null +++ b/controlloop/common/controller-frankfurt/src/test/resources/vcpe/vcpe.appc.success.json @@ -0,0 +1,22 @@ +{ + "body": { + "output": { + "common-header": { + "timestamp": "2017-08-25T21:06:23.037Z", + "api-ver": "5.00", + "originator-id": "664be3d2-6c12-4f4b-a3e7-c349acced200", + "request-id": "664be3d2-6c12-4f4b-a3e7-c349acced200", + "sub-request-id": "${replaceMe}", + "flags": {} + }, + "status": { + "code": 400, + "message": "Restart Successful" + } + } + }, + "version": "2.0", + "rpc-name": "restart", + "correlation-id": "664be3d2-6c12-4f4b-a3e7-c349acced200-1", + "type": "response" +} diff --git a/controlloop/common/controller-frankfurt/src/test/resources/vcpe/vcpe.onset.1.json b/controlloop/common/controller-frankfurt/src/test/resources/vcpe/vcpe.onset.1.json new file mode 100644 index 000000000..d08ee47cd --- /dev/null +++ b/controlloop/common/controller-frankfurt/src/test/resources/vcpe/vcpe.onset.1.json @@ -0,0 +1,16 @@ +{ + "closedLoopControlName": "ControlLoop-vCPE-48f0c2c3-a172-4192-9ae3-052274181b6e", + "closedLoopAlarmStart": 1463679805324, + "closedLoopEventClient": "DCAE_INSTANCE_ID.dcae-tca", + "closedLoopEventStatus": "ONSET", + "requestID": "664be3d2-6c12-4f4b-a3e7-c349acced200", + "target_type": "VNF", + "target": "generic-vnf.vnf-id", + "AAI": { + "vserver.is-closed-loop-disabled": "false", + "vserver.prov-status": "ACTIVE", + "generic-vnf.vnf-id": "vCPE_Infrastructure_vGMUX_demo_app" + }, + "from": "DCAE", + "version": "1.0.2" +} \ No newline at end of file diff --git a/controlloop/common/controller-frankfurt/src/test/resources/vcpe/vcpe.onset.2.json b/controlloop/common/controller-frankfurt/src/test/resources/vcpe/vcpe.onset.2.json new file mode 100644 index 000000000..b8c76514e --- /dev/null +++ b/controlloop/common/controller-frankfurt/src/test/resources/vcpe/vcpe.onset.2.json @@ -0,0 +1,16 @@ +{ + "closedLoopControlName": "ControlLoop-vCPE-48f0c2c3-a172-4192-9ae3-052274181b6e", + "closedLoopAlarmStart": 1463679805324, + "closedLoopEventClient": "DCAE_INSTANCE_ID.dcae-tca", + "closedLoopEventStatus": "ONSET", + "requestID": "8cf3cd05-1218-4224-931b-601494ffe55b", + "target_type": "VNF", + "target": "generic-vnf.vnf-id", + "AAI": { + "vserver.is-closed-loop-disabled": "false", + "vserver.prov-status": "ACTIVE", + "generic-vnf.vnf-id": "vCPE_Infrastructure_vGMUX_demo_app" + }, + "from": "DCAE", + "version": "1.0.2" +} \ No newline at end of file diff --git a/controlloop/common/controller-frankfurt/src/test/resources/vcpe/vcpe.onset.3.json b/controlloop/common/controller-frankfurt/src/test/resources/vcpe/vcpe.onset.3.json new file mode 100644 index 000000000..40f29b3cf --- /dev/null +++ b/controlloop/common/controller-frankfurt/src/test/resources/vcpe/vcpe.onset.3.json @@ -0,0 +1,17 @@ +{ + "closedLoopControlName": "ControlLoop-vCPE-48f0c2c3-a172-4192-9ae3-052274181b6e", + "closedLoopAlarmStart": 1570722876324905, + "closedLoopAlarmEnd": 1570722876324999, + "closedLoopEventClient": "DCAE_INSTANCE_ID.dcae-tca", + "closedLoopEventStatus": "ONSET", + "requestID": "8cf3cd05-1218-4224-931b-601494ffe55b", + "target_type": "VNF", + "target": "generic-vnf.vnf-id", + "AAI": { + "vserver.is-closed-loop-disabled": "false", + "vserver.prov-status": "ACTIVE", + "generic-vnf.vnf-id": "vCPE_Infrastructure_vGMUX_demo_app" + }, + "from": "DCAE", + "version": "1.0.2" +} \ No newline at end of file diff --git a/controlloop/common/controller-frankfurt/src/test/resources/vfw/tosca-compliant-vfw.json b/controlloop/common/controller-frankfurt/src/test/resources/vfw/tosca-compliant-vfw.json new file mode 100644 index 000000000..47cb09d45 --- /dev/null +++ b/controlloop/common/controller-frankfurt/src/test/resources/vfw/tosca-compliant-vfw.json @@ -0,0 +1,40 @@ +{ + "type": "onap.policies.controlloop.operational.common.Drools", + "type_version": "1.0.0", + "name": "operational.modifyconfig", + "version": "1.0.0", + "metadata": { + "policy-id": "operational.modifyconfig" + }, + "properties": { + "id": "ControlLoop-vFirewall-d0a1dfc6-94f5-4fd4-a5b5-4630b438850a", + "timeout": 60, + "abatement": false, + "trigger": "unique-policy-id-1-modifyConfig", + "operations": [ + { + "id": "unique-policy-id-1-modifyConfig", + "description": "Modify the packet generator", + "operation": { + "actor": "APPC", + "operation": "ModifyConfig", + "target": { + "targetType": "VNF", + "entityIds": { + "resourceID": "bbb3cefd-01c8-413c-9bdd-2b92f9ca3d38" + } + } + }, + "timeout": 300, + "retries": 0, + "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": "frankfurt" + } +} diff --git a/controlloop/common/controller-frankfurt/src/test/resources/vfw/tosca-vfw.json b/controlloop/common/controller-frankfurt/src/test/resources/vfw/tosca-vfw.json new file mode 100644 index 000000000..5d1e35277 --- /dev/null +++ b/controlloop/common/controller-frankfurt/src/test/resources/vfw/tosca-vfw.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-vFirewall-d0a1dfc6-94f5-4fd4-a5b5-4630b438850a%0A%20%20services%3A%0A%20%20%20%20-%20serviceInvariantUUID%3A%20f6937c86-584c-47ae-ad29-8d41d6f0cc7c%0A%20%20%20%20%20%20serviceUUID%3A%207be584e2-0bb2-4126-adaf-ced2c77ca0b3%0A%20%20%20%20%20%20serviceName%3A%20Service_Ete_Name7ba1fbde-6187-464a-a62d-d9dd25bdf4e8%0A%20%20trigger_policy%3A%20unique-policy-id-1-modifyConfig%0A%20%20timeout%3A%2060%0A%20%20abatement%3A%20false%0A%20%0Apolicies%3A%0A%20%20-%20id%3A%20unique-policy-id-1-modifyConfig%0A%20%20%20%20name%3A%20modify%20packet%20gen%20config%0A%20%20%20%20description%3A%0A%20%20%20%20actor%3A%20APPC%0A%20%20%20%20recipe%3A%20ModifyConfig%0A%20%20%20%20target%3A%0A%20%20%20%20%20%20resourceID%3A%20bbb3cefd-01c8-413c-9bdd-2b92f9ca3d38%0A%20%20%20%20%20%20type%3A%20VNF%0A%20%20%20%20retry%3A%200%0A%20%20%20%20timeout%3A%2030%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": "vfw", + "version": "1.0.0" +} \ No newline at end of file diff --git a/controlloop/common/controller-frankfurt/src/test/resources/vfw/vfw.appc.success.json b/controlloop/common/controller-frankfurt/src/test/resources/vfw/vfw.appc.success.json new file mode 100644 index 000000000..d7e6ec3b9 --- /dev/null +++ b/controlloop/common/controller-frankfurt/src/test/resources/vfw/vfw.appc.success.json @@ -0,0 +1,17 @@ +{ + "CommonHeader": { + "TimeStamp": 1506051879001, + "APIver": "1.01", + "RequestID": "c7c6a4aa-bb61-4a15-b831-ba1472dd4a65", + "SubRequestID": "${replaceMe}", + "RequestTrack": [], + "Flags": [] + }, + "Status": { + "Code": 400, + "Value": "SUCCESS" + }, + "Payload": { + "generic-vnf.vnf-id": "jimmy-test-vnf2" + } +} \ No newline at end of file diff --git a/controlloop/common/controller-frankfurt/src/test/resources/vfw/vfw.onset.json b/controlloop/common/controller-frankfurt/src/test/resources/vfw/vfw.onset.json new file mode 100644 index 000000000..7782867a1 --- /dev/null +++ b/controlloop/common/controller-frankfurt/src/test/resources/vfw/vfw.onset.json @@ -0,0 +1,17 @@ +{ + "closedLoopControlName": "ControlLoop-vFirewall-d0a1dfc6-94f5-4fd4-a5b5-4630b438850a", + "closedLoopAlarmStart": 1463679805324, + "closedLoopEventClient": "microservice.stringmatcher", + "closedLoopEventStatus": "ONSET", + "requestID": "c7c6a4aa-bb61-4a15-b831-ba1472dd4a65", + "target_type": "VNF", + "target": "generic-vnf.vnf-name", + "AAI": { + "vserver.is-closed-loop-disabled": "false", + "vserver.prov-status": "ACTIVE", + "generic-vnf.vnf-name": "fw0002vm002fw002", + "vserver.vserver-name": "OzVServer" + }, + "from": "DCAE", + "version": "1.0.2" +} diff --git a/controlloop/common/controller-frankfurt/src/test/resources/vlb/tosca-compliant-vlb.json b/controlloop/common/controller-frankfurt/src/test/resources/vlb/tosca-compliant-vlb.json new file mode 100644 index 000000000..aeb22bb0b --- /dev/null +++ b/controlloop/common/controller-frankfurt/src/test/resources/vlb/tosca-compliant-vlb.json @@ -0,0 +1,48 @@ +{ + "type": "onap.policies.controlloop.operational.common.Drools", + "type_version": "1.0.0", + "name": "operational.scaleout", + "version": "1.0.0", + "metadata": { + "policy-id": "operational.scaleout" + }, + "properties": { + "id": "ControlLoop-vDNS-6f37f56d-a87d-4b85-b6a9-cc953cf779b3", + "timeout": 1200, + "abatement": false, + "trigger": "unique-policy-id-1-scale-up", + "operations": [ + { + "id": "unique-policy-id-1-scale-up", + "description": "Create a new VF Module", + "operation": { + "actor": "SO", + "operation": "VF Module Create", + "target": { + "targetType": "VFMODULE", + "entityIds": { + "modelInvariantId": "e6130d03-56f1-4b0a-9a1d-e1b2ebc30e0e", + "modelVersionId": "94b18b1d-cc91-4f43-911a-e6348665f292", + "modelName": "VfwclVfwsnkBbefb8ce2bde..base_vfw..module-0", + "modelVersion": 1, + "modelCustomizationId": "47958575-138f-452a-8c8d-d89b595f8164" + } + }, + "payload": { + "requestParameters": "{\"usePreload\":true,\"userParams\":[]}", + "configurationParameters": "[{\"ip-addr\":\"$.vf-module-topology.vf-module-parameters.param[9]\",\"oam-ip-addr\":\"$.vf-module-topology.vf-module-parameters.param[16]\",\"enabled\":\"$.vf-module-topology.vf-module-parameters.param[23]\"}]" + } + }, + "timeout": 1200, + "retries": 0, + "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": "frankfurt" + } +} diff --git a/controlloop/common/controller-frankfurt/src/test/resources/vlb/tosca-vlb.json b/controlloop/common/controller-frankfurt/src/test/resources/vlb/tosca-vlb.json new file mode 100644 index 000000000..5147d9922 --- /dev/null +++ b/controlloop/common/controller-frankfurt/src/test/resources/vlb/tosca-vlb.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-vDNS-6f37f56d-a87d-4b85-b6a9-cc953cf779b3%0A%20%20services%3A%0A%20%20%20%20-%20serviceName%3A%20d4738992-6497-4dca-9db9%0A%20%20%20%20%20%20serviceInvariantUUID%3A%20dc112d6e-7e73-4777-9c6f-1a7fb5fd1b6f%0A%20%20%20%20%20%20serviceUUID%3A%202eea06c6-e1d3-4c3a-b9c4-478c506eeedf%0A%20%20trigger_policy%3A%20unique-policy-id-1-scale-up%0A%20%20timeout%3A%2060%0A%0Apolicies%3A%0A%20%20-%20id%3A%20unique-policy-id-1-scale-up%0A%20%20%20%20name%3A%20Create%20a%20new%20VF%20Module%0A%20%20%20%20description%3A%0A%20%20%20%20actor%3A%20SO%0A%20%20%20%20recipe%3A%20VF%20Module%20Create%0A%20%20%20%20target%3A%0A%20%20%20%20%20%20type%3A%20VFMODULE%0A%20%20%20%20%20%20modelInvariantId%3A%20e6130d03-56f1-4b0a-9a1d-e1b2ebc30e0e%0A%20%20%20%20%20%20modelVersionId%3A%2094b18b1d-cc91-4f43-911a-e6348665f292%0A%20%20%20%20%20%20modelName%3A%20VfwclVfwsnkBbefb8ce2bde..base_vfw..module-0%0A%20%20%20%20%20%20modelVersion%3A%201%0A%20%20%20%20%20%20modelCustomizationId%3A%2047958575-138f-452a-8c8d-d89b595f8164%0A%20%20%20%20payload%3A%0A%20%20%20%20%20%20requestParameters%3A%20%27%7B%22usePreload%22%3Atrue%2C%22userParams%22%3A%5B%5D%7D%27%0A%20%20%20%20%20%20configurationParameters%3A%20%27%5B%7B%22ip-addr%22%3A%22%24.vf-module-topology.vf-module-parameters.param%5B9%5D%22%2C%22oam-ip-addr%22%3A%22%24.vf-module-topology.vf-module-parameters.param%5B16%5D%22%2C%22enabled%22%3A%22%24.vf-module-topology.vf-module-parameters.param%5B23%5D%22%7D%5D%27%0A%20%20%20%20retry%3A%200%0A%20%20%20%20timeout%3A%2030%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%0A" + }, + "name": "vlb", + "version": "1.0.0" +} \ No newline at end of file diff --git a/controlloop/common/controller-frankfurt/src/test/resources/vlb/vlb.onset.json b/controlloop/common/controller-frankfurt/src/test/resources/vlb/vlb.onset.json new file mode 100644 index 000000000..3360c0abb --- /dev/null +++ b/controlloop/common/controller-frankfurt/src/test/resources/vlb/vlb.onset.json @@ -0,0 +1,16 @@ +{ + "closedLoopControlName": "ControlLoop-vDNS-6f37f56d-a87d-4b85-b6a9-cc953cf779b3", + "closedLoopAlarmStart": 1484677482204798, + "closedLoopEventClient": "DCAE_INSTANCE_ID.dcae-tca", + "closedLoopEventStatus": "ONSET", + "requestID": "e4f95e0c-a013-4530-8e59-c5c5f9e539b6", + "target_type": "VNF", + "target": "vserver.vserver-name", + "AAI": { + "vserver.is-closed-loop-disabled": "false", + "vserver.prov-status": "ACTIVE", + "vserver.vserver-name": "OzVServer" + }, + "from": "DCAE", + "version": "1.0.2" +} \ No newline at end of file -- cgit 1.2.3-korg