diff options
author | daniel <dc443y@att.com> | 2017-10-04 10:09:37 -0500 |
---|---|---|
committer | daniel <dc443y@att.com> | 2017-10-05 15:41:22 -0500 |
commit | 1c2dcbb8e38fe1e3f3271dade73a7b3a7c3a64b5 (patch) | |
tree | 7c4bc5438a3bf61d28cfdf3b18a9d7c4c233f0d1 /controlloop/templates | |
parent | 9f789fa6c2d9d58685c1e20eaf3216f45deee5e7 (diff) |
Fix JUnit Race Conditions
This fix now implements the observer pattern for the
PolicyEngineJUnitImpl so that the test cases can be
notified when an event is available to be pulled.
This eliminates the need to sleep the thread for
some arbitrary time to let the rules process events.
Issue-ID: POLICY-291
Change-Id: I884c959c20b95a1b58f357602099d8a01c8d2e3c
Signed-off-by: Daniel Cruz <dc443y@att.com>
Diffstat (limited to 'controlloop/templates')
9 files changed, 452 insertions, 1210 deletions
diff --git a/controlloop/templates/template.demo/src/test/java/org/onap/policy/template/demo/TestSO.java b/controlloop/templates/template.demo/src/test/java/org/onap/policy/template/demo/TestSO.java deleted file mode 100644 index 3946de2ee..000000000 --- a/controlloop/templates/template.demo/src/test/java/org/onap/policy/template/demo/TestSO.java +++ /dev/null @@ -1,425 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * demo - * ================================================================================ - * Copyright (C) 2017 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.template.demo; - -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; - -import java.io.IOException; -import java.net.URLEncoder; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.time.Instant; -import java.util.HashMap; -import java.util.UUID; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import org.junit.AfterClass; -import org.junit.BeforeClass; -import org.junit.Test; -import org.kie.api.KieServices; -import org.kie.api.builder.KieBuilder; -import org.kie.api.builder.KieFileSystem; -import org.kie.api.builder.Message; -import org.kie.api.builder.ReleaseId; -import org.kie.api.builder.Results; -import org.kie.api.builder.model.KieModuleModel; -import org.kie.api.runtime.KieContainer; -import org.kie.api.runtime.KieSession; -import org.kie.api.runtime.rule.FactHandle; -import org.onap.policy.controlloop.ControlLoopEventStatus; -import org.onap.policy.controlloop.ControlLoopLogger; -import org.onap.policy.controlloop.ControlLoopTargetType; -import org.onap.policy.controlloop.VirtualControlLoopEvent; -import org.onap.policy.controlloop.impl.ControlLoopLoggerStdOutImpl; -import org.onap.policy.controlloop.policy.ControlLoopPolicy; -import org.onap.policy.drools.http.server.HttpServletServer; -import org.onap.policy.drools.impl.PolicyEngineJUnitImpl; -import org.onap.policy.so.util.Serialization; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - - -public class TestSO { - - private static final Logger log = LoggerFactory.getLogger(TestSO.class); - - static{ - /* Set environment properties */ - Util.setAAIProps(); - Util.setSOProps(); - Util.setPUProp(); - } - - @BeforeClass - public static void setUpSimulator() { - try { - Util.buildAaiSim(); - Util.buildSoSim(); - Util.buildGuardSim(); - } catch (Exception e) { - fail(e.getMessage()); - } - } - - @AfterClass - public static void tearDownSimulator() { - HttpServletServer.factory.destroy(); - } - - @Test - public void testvDNS() throws IOException { - - final String yaml = "src/test/resources/yaml/policy_ControlLoop_SO-test.yaml"; - - // - // Pull info from the yaml - // - final Util.Pair<ControlLoopPolicy, String> pair = Util.loadYaml(yaml); - assertNotNull(pair); - assertNotNull(pair.a); - assertNotNull(pair.a.getControlLoop()); - assertNotNull(pair.a.getControlLoop().getControlLoopName()); - assertTrue(pair.a.getControlLoop().getControlLoopName().length() > 0); - - // - // Build a container - // - final String closedLoopControlName = pair.a.getControlLoop().getControlLoopName(); - final KieSession kieSession = buildContainer("src/main/resources/ControlLoop_Template_xacml_guard.drl", - closedLoopControlName, - "type=operational", - "myVDNSDemoPolicy", - "v1.0", - "SO", - "POLICY-CL-MGT", - "APPC-CL", - URLEncoder.encode(pair.b, "UTF-8") - ); - - log.debug("============ PRINTING YAML ============"); - log.debug(URLEncoder.encode(pair.b, "UTF-8")); - log.debug("================ DONE ================="); - - // - // Insert our globals - // - final ControlLoopLogger logger = new ControlLoopLoggerStdOutImpl(); - kieSession.setGlobal("Logger", logger); - final PolicyEngineJUnitImpl engine = new PolicyEngineJUnitImpl(); - kieSession.setGlobal("Engine", engine); - - // - // Initial fire of rules - // - kieSession.fireAllRules(); - // - // Kick a thread that starts testing - // - new Thread(new Runnable() { - - @Override - public void run() { - - log.debug("\n************ Starting vDNS Test *************\n"); - - // - // Generate an invalid DCAE Event with requestID=null - // - VirtualControlLoopEvent invalidEvent = new VirtualControlLoopEvent(); - invalidEvent.closedLoopControlName = closedLoopControlName; - invalidEvent.requestID = null; - invalidEvent.closedLoopEventClient = "tca.instance00001"; - invalidEvent.target_type = ControlLoopTargetType.VNF; - invalidEvent.target = "generic-vnf.vnf-id"; - invalidEvent.from = "DCAE"; - invalidEvent.closedLoopAlarmStart = Instant.now(); - invalidEvent.AAI = new HashMap<String, String>(); - invalidEvent.AAI.put("vserver.vserver-name", "vserver-name-16102016-aai3255-data-11-1"); - invalidEvent.closedLoopEventStatus = ControlLoopEventStatus.ONSET; - - log.debug("-------- Sending Invalid ONSET --------"); - log.debug(Serialization.gsonPretty.toJson(invalidEvent)); - - // - // Insert invalid DCAE Event into memory - // - kieSession.insert(invalidEvent); - try { - Thread.sleep(500); - } catch (InterruptedException e) { - } - // - // Generate first DCAE ONSET Event - // - VirtualControlLoopEvent onsetEvent = new VirtualControlLoopEvent(); - onsetEvent.closedLoopControlName = closedLoopControlName; - onsetEvent.requestID = UUID.randomUUID(); - onsetEvent.closedLoopEventClient = "tca.instance00001"; - onsetEvent.target_type = ControlLoopTargetType.VNF; - onsetEvent.target = "VNF_NAME"; - onsetEvent.from = "DCAE"; - onsetEvent.closedLoopAlarmStart = Instant.now(); - onsetEvent.AAI = new HashMap<String, String>(); - onsetEvent.AAI.put("vserver.vserver-name", "vserver-name-16102016-aai3255-data-11-1"); - onsetEvent.AAI.put("vserver.is-closed-loop-disabled", "false"); - onsetEvent.closedLoopEventStatus = ControlLoopEventStatus.ONSET; - - log.debug("-------- Sending Valid ONSET --------"); - log.debug(Serialization.gsonPretty.toJson(onsetEvent)); - - // - // Insert first DCAE ONSET Event into memory - // - kieSession.insert(onsetEvent); - // - // We have test for subsequent ONSET Events in testvFirewall() - // So no need to test it again here - // - try { - Thread.sleep(10000); - } catch (InterruptedException e) { - } - // - // Test is finished, so stop the kieSession - // - kieSession.halt(); - } - // - }).start(); - // - // Start firing rules - // - kieSession.fireUntilHalt(); - // - // Dump working memory - // - dumpFacts(kieSession); - - // - // See if there is anything left in memory, there SHOULD only be - // a params fact. - // - // assertEquals("There should only be 1 Fact left in memory.", 1, kieSession.getFactCount()); - if (kieSession.getFactCount() != 1L) { - log.error("FACT count mismatch: 1 expected but there are {}", kieSession.getFactCount()); - } - for (FactHandle handle : kieSession.getFactHandles()) { - Object fact = kieSession.getObject(handle); - // assertEquals("Non-Param Fact left in working memory", "org.onap.policy.controlloop.Params", fact.getClass().getName()); - log.info("Working Memory FACT: {}", fact.getClass().getName()); - } - - } - - public static void dumpFacts(KieSession kieSession) { - log.debug("Fact Count: " + kieSession.getFactCount()); - for (FactHandle handle : kieSession.getFactHandles()) { - log.debug("FACT: " + handle); - } - } - - public static KieSession buildContainer(String droolsTemplate, - String closedLoopControlName, - String policyScope, - String policyName, - String policyVersion, - String actor, - String notificationTopic, - String appcTopic, - String yamlSpecification) throws IOException { - // - // Get our Drools Kie factory - // - KieServices ks = KieServices.Factory.get(); - - KieModuleModel kModule = ks.newKieModuleModel(); - - log.debug("KMODULE:" + System.lineSeparator() + kModule.toXML()); - - // - // Generate our drools rule from our template - // - KieFileSystem kfs = ks.newKieFileSystem(); - - kfs.writeKModuleXML(kModule.toXML()); - { - Path rule = Paths.get(droolsTemplate); - String ruleTemplate = new String(Files.readAllBytes(rule)); - String drlContents = generatePolicy(ruleTemplate, - closedLoopControlName, - policyScope, - policyName, - policyVersion, - actor, - notificationTopic, - appcTopic, - yamlSpecification - ); - - kfs.write("src/main/resources/" + policyName + ".drl", ks.getResources().newByteArrayResource(drlContents.getBytes())); - } - // - // Compile the rule - // - KieBuilder builder = ks.newKieBuilder(kfs).buildAll(); - Results results = builder.getResults(); - if (results.hasMessages(Message.Level.ERROR)) { - for (Message msg : results.getMessages()) { - System.err.println(msg.toString()); - } - throw new RuntimeException("Drools Rule has Errors"); - } - for (Message msg : results.getMessages()) { - log.debug(msg.toString()); - } - // - // Create our kie Session and container - // - ReleaseId releaseId = ks.getRepository().getDefaultReleaseId(); - log.debug("ReleaseId: " + releaseId); - KieContainer kContainer = ks.newKieContainer(releaseId); - - return kContainer.newKieSession(); - } - public static String generatePolicy(String ruleContents, - String closedLoopControlName, - String policyScope, - String policyName, - String policyVersion, - String actor, - String notificationTopic, - String appcTopic, - String controlLoopYaml) { - - Pattern p = Pattern.compile("\\$\\{closedLoopControlName\\}"); - Matcher m = p.matcher(ruleContents); - ruleContents = m.replaceAll(closedLoopControlName); - - p = Pattern.compile("\\$\\{policyScope\\}"); - m = p.matcher(ruleContents); - ruleContents = m.replaceAll(policyScope); - - p = Pattern.compile("\\$\\{policyName\\}"); - m = p.matcher(ruleContents); - ruleContents = m.replaceAll(policyName); - - p = Pattern.compile("\\$\\{policyVersion\\}"); - m = p.matcher(ruleContents); - ruleContents = m.replaceAll(policyVersion); - - p = Pattern.compile("\\$\\{actor\\}"); - m = p.matcher(ruleContents); - ruleContents = m.replaceAll(actor); - -// p = Pattern.compile("\\$\\{aaiURL\\}"); -// m = p.matcher(ruleContents); -// if (aaiURL == null) { -// ruleContents = m.replaceAll("null"); -// } else { -// ruleContents = m.replaceAll(aaiURL); -// } -// -// p = Pattern.compile("\\$\\{aaiUsername\\}"); -// m = p.matcher(ruleContents); -// if (aaiUsername == null) { -// ruleContents = m.replaceAll("null"); -// } else { -// ruleContents = m.replaceAll(aaiUsername); -// } -// -// p = Pattern.compile("\\$\\{aaiPassword\\}"); -// m = p.matcher(ruleContents); -// if (aaiPassword == null) { -// ruleContents = m.replaceAll("null"); -// } else { -// ruleContents = m.replaceAll(aaiPassword); -// } -// -// p = Pattern.compile("\\$\\{msoURL\\}"); -// m = p.matcher(ruleContents); -// if (msoURL == null) { -// ruleContents = m.replaceAll("null"); -// } else { -// ruleContents = m.replaceAll(msoURL); -// } -// -// p = Pattern.compile("\\$\\{msoUsername\\}"); -// m = p.matcher(ruleContents); -// if (msoUsername == null) { -// ruleContents = m.replaceAll("null"); -// } else { -// ruleContents = m.replaceAll(msoUsername); -// } -// -// p = Pattern.compile("\\$\\{msoPassword\\}"); -// m = p.matcher(ruleContents); -// if (msoPassword == null) { -// ruleContents = m.replaceAll("null"); -// } else { -// ruleContents = m.replaceAll(msoPassword); -// } -// -// p = Pattern.compile("\\$\\{aaiNamedQueryUUID\\}"); -// m = p.matcher(ruleContents); -// if (aaiNamedQueryUUID == null) { -// ruleContents = m.replaceAll("null"); -// } else { -// ruleContents = m.replaceAll(aaiNamedQueryUUID); -// } -// -// p = Pattern.compile("\\$\\{aaiPatternMatch\\}"); -// m = p.matcher(ruleContents); -// if (aaiPatternMatch == 1) { -// ruleContents = m.replaceAll("1"); -// } else { -// ruleContents = m.replaceAll("0"); -// } - - p = Pattern.compile("\\$\\{notificationTopic\\}"); - m = p.matcher(ruleContents); - if (notificationTopic == null) { - ruleContents = m.replaceAll("null"); - } else { - ruleContents = m.replaceAll(notificationTopic); - } - - p = Pattern.compile("\\$\\{appcTopic\\}"); - m = p.matcher(ruleContents); - if (appcTopic == null) { - ruleContents = m.replaceAll("null"); - } else { - ruleContents = m.replaceAll(appcTopic); - } - - p = Pattern.compile("\\$\\{controlLoopYaml\\}"); - m = p.matcher(ruleContents); - ruleContents = m.replaceAll(controlLoopYaml); - - log.debug(ruleContents); - - return ruleContents; - } - -} diff --git a/controlloop/templates/template.demo/src/test/java/org/onap/policy/template/demo/VCPEControlLoopTest.java b/controlloop/templates/template.demo/src/test/java/org/onap/policy/template/demo/VCPEControlLoopTest.java index ad44de2fe..4dc6b806f 100644 --- a/controlloop/templates/template.demo/src/test/java/org/onap/policy/template/demo/VCPEControlLoopTest.java +++ b/controlloop/templates/template.demo/src/test/java/org/onap/policy/template/demo/VCPEControlLoopTest.java @@ -42,20 +42,20 @@ import org.onap.policy.controlloop.ControlLoopNotificationType; import org.onap.policy.controlloop.VirtualControlLoopEvent; import org.onap.policy.controlloop.VirtualControlLoopNotification; import org.onap.policy.controlloop.policy.ControlLoopPolicy; -import org.onap.policy.controlloop.policy.TargetType; +import org.onap.policy.drools.PolicyEngineListener; import org.onap.policy.drools.http.server.HttpServletServer; import org.onap.policy.drools.impl.PolicyEngineJUnitImpl; -import org.onap.policy.guard.PolicyGuard; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -public class VCPEControlLoopTest { +public class VCPEControlLoopTest implements PolicyEngineListener { private static final Logger logger = LoggerFactory.getLogger(VCPEControlLoopTest.class); private KieSession kieSession; private Util.Pair<ControlLoopPolicy, String> pair; - private PolicyEngineJUnitImpl engine; + private PolicyEngineJUnitImpl engine; + private UUID requestID; static { /* Set environment properties */ @@ -81,16 +81,15 @@ public class VCPEControlLoopTest { @Test public void successTest() { - /* * Start the kie session */ try { kieSession = startSession("src/main/resources/ControlLoop_Template_xacml_guard.drl", "src/test/resources/yaml/policy_ControlLoop_vCPE.yaml", - "service=ServiceTest;resource=ResourceTest;type=operational", + "service=ServiceDemo;resource=Res1Demo;type=operational", "CL_vCPE", - "org.onap.closed_loop.ServiceTest:VNFS:1.0.0"); + "org.onap.closed_loop.ServiceDemo:VNFS:1.0.0"); } catch (IOException e) { e.printStackTrace(); logger.debug("Could not create kieSession"); @@ -98,245 +97,30 @@ public class VCPEControlLoopTest { } /* - * Create a thread to continuously fire rules - * until main thread calls halt - */ - new Thread( new Runnable() { - @Override - public void run() { - kieSession.fireUntilHalt(); - } - } ).start(); - - /* - * Create a unique requestId and a unique trigger source + * Allows the PolicyEngine to callback to this object to + * notify that there is an event ready to be pulled + * from the queue */ - UUID requestID = UUID.randomUUID(); - String triggerSourceName = "foobartriggersource36"; + engine.addListener(this); /* - * This will be the object returned from the PolicyEngine + * Create a unique requestId */ - Object obj = null; + requestID = UUID.randomUUID(); /* * Simulate an onset event the policy engine will * receive from DCAE to kick off processing through - * the rules. - */ - try { - sendOnset(pair.a, requestID, triggerSourceName); - } catch (InterruptedException e) { - e.printStackTrace(); - logger.debug("Unable to send onset event"); - fail("Unable to send onset event"); - } - - /* - * Pull the object that was sent out to DMAAP and make - * sure it is a ControlLoopNoticiation of type active - */ - obj = engine.subscribe("UEB", "POLICY-CL-MGT"); - assertNotNull(obj); - assertTrue(obj instanceof VirtualControlLoopNotification); - assertTrue(((VirtualControlLoopNotification)obj).notification.equals(ControlLoopNotificationType.ACTIVE)); - - /* - * Give the control loop time to acquire a lock - */ - try { - Thread.sleep(4000); - } catch (InterruptedException e) { - e.printStackTrace(); - logger.debug("An interrupt Exception was thrown"); - fail("An interrupt Exception was thrown"); - } - - /* - * The fact should be ready to query guard now to see - * if a ModifyConfig recipe is allowed - */ - obj = engine.subscribe("UEB", "POLICY-CL-MGT"); - assertNotNull(obj); - logger.debug("\n\n####################### GOING TO QUERY GUARD about Restart!!!!!!"); - logger.debug("Rule: {} Message {}", ((VirtualControlLoopNotification)obj).policyName, ((VirtualControlLoopNotification)obj).message); - - /* - * Make sure the object is an instance of a ControlLoopNotification - * and is of type operation + * the rules */ - assertTrue(obj instanceof VirtualControlLoopNotification); - assertTrue(((VirtualControlLoopNotification)obj).notification.equals(ControlLoopNotificationType.OPERATION)); - - try { - Thread.sleep(4000); - } catch (InterruptedException e) { - e.printStackTrace(); - logger.debug("An interrupt Exception was thrown"); - fail("An interrupt Exception was thrown"); - } - - /* - * The guard response should be received at this point - */ - obj = engine.subscribe("UEB", "POLICY-CL-MGT"); - assertNotNull(obj); - logger.debug("Rule: {} Message {}", ((VirtualControlLoopNotification)obj).policyName, ((VirtualControlLoopNotification)obj).message); - - /* - * The object should be a ControlLoopNotification with type operation - */ - assertTrue(obj instanceof VirtualControlLoopNotification); - assertTrue(((VirtualControlLoopNotification)obj).notification.equals(ControlLoopNotificationType.OPERATION)); - - /* - * See if Guard permits this action, if it does - * not then the test should fail - */ - if (((VirtualControlLoopNotification)obj).message.contains("PERMIT")) { - - /* - * A notification should be sent out of the Policy - * Engine at this point, it will be of type operation - */ - obj = engine.subscribe("UEB", "POLICY-CL-MGT"); - assertNotNull(obj); - logger.debug("Rule: {} Message {}", ((VirtualControlLoopNotification)obj).policyName, ((VirtualControlLoopNotification)obj).message); - - /* A notification should be sent out of the Policy - * Engine at this point, it will be of type operation - */ - assertTrue(obj instanceof VirtualControlLoopNotification); - assertTrue(((VirtualControlLoopNotification)obj).notification.equals(ControlLoopNotificationType.OPERATION)); - - try { - Thread.sleep(1000); - } catch (InterruptedException e) { - e.printStackTrace(); - logger.debug("An interrupt Exception was thrown"); - fail("An interrupt Exception was thrown"); - } - - /* - * Obtain the request sent from the Policy Engine - */ - obj = engine.subscribe("UEB", "APPC-LCM-READ"); - assertNotNull(obj); - - /* - * The request should be of type LCMRequestWrapper - * and the subrequestid should be 1 - */ - assertTrue(obj instanceof LCMRequestWrapper); - LCMRequestWrapper dmaapRequest = (LCMRequestWrapper) obj; - LCMRequest appcRequest = dmaapRequest.getBody(); - assertTrue(appcRequest.getCommonHeader().getSubRequestId().equals("1")); - - logger.debug("\n============ APPC received the request!!! ===========\n"); - - /* - * Give some time for processing - */ - try { - Thread.sleep(1000); - } catch (InterruptedException e) { - e.printStackTrace(); - logger.debug("An interrupt Exception was thrown"); - fail("An interrupt Exception was thrown"); - } - - /* - * Simulate a success response from APPC and insert - * the response into the working memory - */ - LCMResponseWrapper dmaapResponse = new LCMResponseWrapper(); - LCMResponse appcResponse = new LCMResponse(appcRequest); - appcResponse.getStatus().setCode(400); - appcResponse.getStatus().setMessage("AppC success"); - dmaapResponse.setBody(appcResponse); - kieSession.insert(dmaapResponse); - - /* - * Give time for processing - */ - try { - Thread.sleep(10000); - } catch (InterruptedException e) { - e.printStackTrace(); - logger.debug("An interrupt Exception was thrown"); - fail("An interrupt Exception was thrown"); - } - - /* - * Make sure the next notification is delivered - */ - obj = engine.subscribe("UEB", "POLICY-CL-MGT"); - assertNotNull(obj); - logger.debug("Rule: {} Message {}", ((VirtualControlLoopNotification)obj).policyName, ((VirtualControlLoopNotification)obj).message); - - /* - * The ControlLoopNotification should be - * an OPERATION_SUCCESS - */ - assertTrue(obj instanceof VirtualControlLoopNotification); - assertTrue(((VirtualControlLoopNotification)obj).notification.equals(ControlLoopNotificationType.OPERATION_SUCCESS)); - - /* - * Now simulate the abatement sent from DCAE - */ - try { - sendAbatement(pair.a, requestID, triggerSourceName); - } catch (InterruptedException e1) { - e1.printStackTrace(); - logger.debug("Abatement could not be sent"); - fail("Abatement could not be sent"); - } - - /* - * Give time to finish processing - */ - try { - Thread.sleep(20000); - } catch (InterruptedException e) { - e.printStackTrace(); - logger.debug("An interrupt Exception was thrown"); - fail("An interrupt Exception was thrown"); - } - - /* - * This should be the final notification from the Policy Engine - */ - obj = engine.subscribe("UEB", "POLICY-CL-MGT"); - assertNotNull(obj); - logger.debug("Rule: {} Message {}", ((VirtualControlLoopNotification)obj).policyName, ((VirtualControlLoopNotification)obj).message); - - /* - * The ControlLoopNotification should be of type FINAL_SUCCESS - */ - assertTrue(obj instanceof VirtualControlLoopNotification); - assertTrue(((VirtualControlLoopNotification)obj).notification.equals(ControlLoopNotificationType.FINAL_SUCCESS)); - - /* - * One final check to make sure the lock is released - */ - assertFalse(PolicyGuard.isLocked(TargetType.VNF, triggerSourceName, requestID)); - } - else { - fail("Operation Denied by Guard"); - } + sendEvent(pair.a, requestID, ControlLoopEventStatus.ONSET); - /* - * This will stop the thread that is firing the rules - */ - kieSession.halt(); + kieSession.fireUntilHalt(); /* * The only fact in memory should be Params */ - //assertEquals(1, kieSession.getFactCount()); - if (kieSession.getFactCount() != 1L) { - logger.error("FACT count mismatch: 1 expected but there are {}", kieSession.getFactCount()); - } + assertEquals(1, kieSession.getFactCount()); /* * Print what's left in memory @@ -404,47 +188,109 @@ public class VCPEControlLoopTest { return kieSession; } - /** - * This method is used to simulate event messages from DCAE - * that start the control loop (onset message). - * - * @param policy the controlLoopName comes from the policy - * @param requestID the requestId for this event - * @param triggerSourceName - * @throws InterruptedException + /* + * (non-Javadoc) + * @see org.onap.policy.drools.PolicyEngineListener#newEventNotification(java.lang.String) */ - protected void sendOnset(ControlLoopPolicy policy, UUID requestID, String triggerSourceName) throws InterruptedException { - VirtualControlLoopEvent event = new VirtualControlLoopEvent(); - event.closedLoopControlName = policy.getControlLoop().getControlLoopName(); - event.requestID = requestID; - event.target = "generic-vnf.vnf-id"; - event.closedLoopAlarmStart = Instant.now(); - event.AAI = new HashMap<>(); - event.AAI.put("generic-vnf.vnf-id", "testGenericVnfId"); - event.closedLoopEventStatus = ControlLoopEventStatus.ONSET; - kieSession.insert(event); - Thread.sleep(2000); + public void newEventNotification(String topic) { + /* + * Pull the object that was sent out to DMAAP and make + * sure it is a ControlLoopNoticiation of type active + */ + Object obj = engine.subscribe("UEB", topic); + assertNotNull(obj); + if (obj instanceof VirtualControlLoopNotification) { + VirtualControlLoopNotification notification = (VirtualControlLoopNotification) obj; + String policyName = notification.policyName; + if (policyName.endsWith("EVENT")) { + logger.debug("Rule Fired: " + notification.policyName); + assertTrue(ControlLoopNotificationType.ACTIVE.equals(notification.notification)); + } + else if (policyName.endsWith("GUARD_NOT_YET_QUERIED")) { + logger.debug("Rule Fired: " + notification.policyName); + assertTrue(ControlLoopNotificationType.OPERATION.equals(notification.notification)); + assertNotNull(notification.message); + assertTrue(notification.message.startsWith("Sending guard query")); + } + else if (policyName.endsWith("GUARD.RESPONSE")) { + logger.debug("Rule Fired: " + notification.policyName); + assertTrue(ControlLoopNotificationType.OPERATION.equals(notification.notification)); + assertNotNull(notification.message); + assertTrue(notification.message.endsWith("PERMIT")); + } + else if (policyName.endsWith("GUARD_PERMITTED")) { + logger.debug("Rule Fired: " + notification.policyName); + assertTrue(ControlLoopNotificationType.OPERATION.equals(notification.notification)); + assertNotNull(notification.message); + assertTrue(notification.message.startsWith("actor=APPC")); + } + else if (policyName.endsWith("OPERATION.TIMEOUT")) { + logger.debug("Rule Fired: " + notification.policyName); + kieSession.halt(); + logger.debug("The operation timed out"); + fail("Operation Timed Out"); + } + else if (policyName.endsWith("APPC.LCM.RESPONSE")) { + logger.debug("Rule Fired: " + notification.policyName); + assertTrue(ControlLoopNotificationType.OPERATION_SUCCESS.equals(notification.notification)); + assertNotNull(notification.message); + assertTrue(notification.message.startsWith("actor=APPC")); + sendEvent(pair.a, requestID, ControlLoopEventStatus.ABATED); + } + else if (policyName.endsWith("EVENT.MANAGER")) { + logger.debug("Rule Fired: " + notification.policyName); + assertTrue(ControlLoopNotificationType.FINAL_SUCCESS.equals(notification.notification)); + kieSession.halt(); + } + else if (policyName.endsWith("EVENT.MANAGER.TIMEOUT")) { + logger.debug("Rule Fired: " + notification.policyName); + kieSession.halt(); + logger.debug("The control loop timed out"); + fail("Control Loop Timed Out"); + } + } + else if (obj instanceof LCMRequestWrapper) { + /* + * The request should be of type LCMRequestWrapper + * and the subrequestid should be 1 + */ + LCMRequestWrapper dmaapRequest = (LCMRequestWrapper) obj; + LCMRequest appcRequest = dmaapRequest.getBody(); + assertTrue(appcRequest.getCommonHeader().getSubRequestId().equals("1")); + + logger.debug("\n============ APPC received the request!!! ===========\n"); + + /* + * Simulate a success response from APPC and insert + * the response into the working memory + */ + LCMResponseWrapper dmaapResponse = new LCMResponseWrapper(); + LCMResponse appcResponse = new LCMResponse(appcRequest); + appcResponse.getStatus().setCode(400); + appcResponse.getStatus().setMessage("AppC success"); + dmaapResponse.setBody(appcResponse); + kieSession.insert(dmaapResponse); + } } /** * This method is used to simulate event messages from DCAE - * that end the control loop (abatement message). + * that start the control loop (onset message) or end the + * control loop (abatement message). * * @param policy the controlLoopName comes from the policy * @param requestID the requestId for this event - * @param triggerSourceName - * @throws InterruptedException + * @param status could be onset or abated */ - protected void sendAbatement(ControlLoopPolicy policy, UUID requestID, String triggerSourceName) throws InterruptedException { + protected void sendEvent(ControlLoopPolicy policy, UUID requestID, ControlLoopEventStatus status) { VirtualControlLoopEvent event = new VirtualControlLoopEvent(); event.closedLoopControlName = policy.getControlLoop().getControlLoopName(); event.requestID = requestID; event.target = "generic-vnf.vnf-id"; - event.closedLoopAlarmStart = Instant.now().minusSeconds(5); - event.closedLoopAlarmEnd = Instant.now(); + event.closedLoopAlarmStart = Instant.now(); event.AAI = new HashMap<>(); - event.AAI.put("generic-vnf.vnf-id", "testGenericVnfId"); - event.closedLoopEventStatus = ControlLoopEventStatus.ABATED; + event.AAI.put("generic-vnf.vnf-id", "testGenericVnfID"); + event.closedLoopEventStatus = status; kieSession.insert(event); } diff --git a/controlloop/templates/template.demo/src/test/java/org/onap/policy/template/demo/VDNSControlLoopTest.java b/controlloop/templates/template.demo/src/test/java/org/onap/policy/template/demo/VDNSControlLoopTest.java index 00e00cc24..641b56f13 100644 --- a/controlloop/templates/template.demo/src/test/java/org/onap/policy/template/demo/VDNSControlLoopTest.java +++ b/controlloop/templates/template.demo/src/test/java/org/onap/policy/template/demo/VDNSControlLoopTest.java @@ -20,7 +20,7 @@ package org.onap.policy.template.demo; -import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; @@ -38,24 +38,25 @@ import org.kie.api.runtime.KieSession; import org.kie.api.runtime.rule.FactHandle; import org.onap.policy.controlloop.ControlLoopEventStatus; import org.onap.policy.controlloop.ControlLoopNotificationType; -import org.onap.policy.controlloop.ControlLoopTargetType; import org.onap.policy.controlloop.VirtualControlLoopEvent; import org.onap.policy.controlloop.VirtualControlLoopNotification; import org.onap.policy.controlloop.policy.ControlLoopPolicy; -import org.onap.policy.controlloop.policy.TargetType; +import org.onap.policy.drools.PolicyEngineListener; import org.onap.policy.drools.http.server.HttpServletServer; import org.onap.policy.drools.impl.PolicyEngineJUnitImpl; -import org.onap.policy.guard.PolicyGuard; + +import org.onap.policy.so.SORequest; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -public class VDNSControlLoopTest { +public class VDNSControlLoopTest implements PolicyEngineListener { private static final Logger logger = LoggerFactory.getLogger(VDNSControlLoopTest.class); private KieSession kieSession; private Util.Pair<ControlLoopPolicy, String> pair; private PolicyEngineJUnitImpl engine; + private UUID requestID; static { /* Set environment properties */ @@ -100,89 +101,30 @@ public class VDNSControlLoopTest { } /* - * Create a thread to continuously fire rules - * until main thread calls halt - */ - new Thread( new Runnable() { - @Override - public void run() { - kieSession.fireUntilHalt(); - } - } ).start(); - - /* - * Create a unique requestId and a unique trigger source + * Allows the PolicyEngine to callback to this object to + * notify that there is an event ready to be pulled + * from the queue */ - UUID requestID = UUID.randomUUID(); - String triggerSourceName = "foobartriggersource36"; + engine.addListener(this); /* - * This will be the object returned from the PolicyEngine + * Create a unique requestId */ - Object obj = null; + requestID = UUID.randomUUID(); /* * Simulate an onset event the policy engine will * receive from DCAE to kick off processing through * the rules */ - try { - sendOnset(pair.a, requestID, triggerSourceName); - } catch (InterruptedException e) { - e.printStackTrace(); - logger.debug("Unable to send onset event"); - fail("Unable to send onset event"); - } + sendEvent(pair.a, requestID, ControlLoopEventStatus.ONSET); - /* - * Pull the object that was sent out and make - * sure it is a ControlLoopNoticiation of type active - */ - obj = engine.subscribe("UEB", "POLICY-CL-MGT"); - assertNotNull(obj); - assertTrue(obj instanceof VirtualControlLoopNotification); - assertTrue(((VirtualControlLoopNotification)obj).notification.equals(ControlLoopNotificationType.ACTIVE)); - - - /* - * Give the control loop time to acquire a lock - */ - try { - Thread.sleep(4000); - } catch (InterruptedException e) { - e.printStackTrace(); - logger.debug("An interrupt Exception was thrown"); - fail("An interrupt Exception was thrown"); - } - - /* - * Give time to finish processing - */ - try { - Thread.sleep(10000); - } catch (InterruptedException e) { - e.printStackTrace(); - logger.debug("An interrupt Exception was thrown"); - fail("An interrupt Exception was thrown"); - } - - /* - * One final check to make sure the lock is released - */ - assertFalse(PolicyGuard.isLocked(TargetType.VNF, triggerSourceName, requestID)); - - /* - * This will stop the thread that is firing the rules - */ - kieSession.halt(); + kieSession.fireUntilHalt(); /* * The only fact in memory should be Params */ - // assertEquals(1, kieSession.getFactCount()); - if (kieSession.getFactCount() != 1L) { - logger.error("FACT count mismatch: 1 expected but there are {}", kieSession.getFactCount()); - } + assertEquals(1, kieSession.getFactCount()); /* * Print what's left in memory @@ -249,55 +191,91 @@ public class VDNSControlLoopTest { return kieSession; } - - /** - * This method is used to simulate event messages from DCAE - * that start the control loop (onset message). - * - * @param policy the controlLoopName comes from the policy - * @param requestID the requestId for this event - * @param triggerSourceName - * @throws InterruptedException + + /* + * (non-Javadoc) + * @see org.onap.policy.drools.PolicyEngineListener#newEventNotification(java.lang.String) */ - protected void sendOnset(ControlLoopPolicy policy, UUID requestID, String triggerSourceName) throws InterruptedException { - VirtualControlLoopEvent event = new VirtualControlLoopEvent(); - event.closedLoopControlName = policy.getControlLoop().getControlLoopName(); - event.requestID = requestID; - event.target = "VNF_NAME"; - event.target_type = ControlLoopTargetType.VNF; - event.closedLoopAlarmStart = Instant.now(); - event.AAI = new HashMap<>(); - event.AAI.put("cloud-region.identity-url", "foo"); - event.AAI.put("vserver.selflink", "bar"); - event.AAI.put("vserver.is-closed-loop-disabled", "false"); - event.AAI.put("vserver.vserver-name", "vserver-name-16102016-aai3255-data-11-1"); - event.closedLoopEventStatus = ControlLoopEventStatus.ONSET; - kieSession.insert(event); - Thread.sleep(2000); + public void newEventNotification(String topic) { + /* + * Pull the object that was sent out to DMAAP and make + * sure it is a ControlLoopNoticiation of type active + */ + Object obj = engine.subscribe("UEB", topic); + assertNotNull(obj); + if (obj instanceof VirtualControlLoopNotification) { + VirtualControlLoopNotification notification = (VirtualControlLoopNotification) obj; + String policyName = notification.policyName; + if (policyName.endsWith("EVENT")) { + logger.debug("Rule Fired: " + notification.policyName); + assertTrue(ControlLoopNotificationType.ACTIVE.equals(notification.notification)); + } + else if (policyName.endsWith("GUARD_NOT_YET_QUERIED")) { + logger.debug("Rule Fired: " + notification.policyName); + assertTrue(ControlLoopNotificationType.OPERATION.equals(notification.notification)); + assertNotNull(notification.message); + assertTrue(notification.message.startsWith("Sending guard query")); + } + else if (policyName.endsWith("GUARD.RESPONSE")) { + logger.debug("Rule Fired: " + notification.policyName); + assertTrue(ControlLoopNotificationType.OPERATION.equals(notification.notification)); + assertNotNull(notification.message); + assertTrue(notification.message.endsWith("PERMIT")); + } + else if (policyName.endsWith("GUARD_PERMITTED")) { + logger.debug("Rule Fired: " + notification.policyName); + assertTrue(ControlLoopNotificationType.OPERATION.equals(notification.notification)); + assertNotNull(notification.message); + assertTrue(notification.message.startsWith("actor=SO")); + } + else if (policyName.endsWith("OPERATION.TIMEOUT")) { + logger.debug("Rule Fired: " + notification.policyName); + kieSession.halt(); + logger.debug("The operation timed out"); + fail("Operation Timed Out"); + } + else if (policyName.endsWith("SO.RESPONSE")) { + logger.debug("Rule Fired: " + notification.policyName); + assertTrue(ControlLoopNotificationType.OPERATION_SUCCESS.equals(notification.notification)); + assertNotNull(notification.message); + assertTrue(notification.message.startsWith("actor=SO")); + } + else if (policyName.endsWith("EVENT.MANAGER")) { + logger.debug("Rule Fired: " + notification.policyName); + assertTrue(ControlLoopNotificationType.FINAL_SUCCESS.equals(notification.notification)); + kieSession.halt(); + } + else if (policyName.endsWith("EVENT.MANAGER.TIMEOUT")) { + logger.debug("Rule Fired: " + notification.policyName); + kieSession.halt(); + logger.debug("The control loop timed out"); + fail("Control Loop Timed Out"); + } + } + else if (obj instanceof SORequest) { + logger.debug("\n============ SO received the request!!! ===========\n"); + } } /** * This method is used to simulate event messages from DCAE - * that end the control loop (abatement message). + * that start the control loop (onset message) or end the + * control loop (abatement message). * * @param policy the controlLoopName comes from the policy * @param requestID the requestId for this event - * @param triggerSourceName - * @throws InterruptedException + * @param status could be onset or abated */ - protected void sendAbatement(ControlLoopPolicy policy, UUID requestID, String triggerSourceName) throws InterruptedException { + protected void sendEvent(ControlLoopPolicy policy, UUID requestID, ControlLoopEventStatus status) { VirtualControlLoopEvent event = new VirtualControlLoopEvent(); event.closedLoopControlName = policy.getControlLoop().getControlLoopName(); event.requestID = requestID; - event.target = "generic-vnf.vnf-id"; - event.closedLoopAlarmStart = Instant.now().minusSeconds(5); - event.closedLoopAlarmEnd = Instant.now(); + event.target = "vserver.vserver-name"; + event.closedLoopAlarmStart = Instant.now(); event.AAI = new HashMap<>(); - event.AAI.put("cloud-region.identity-url", "foo"); - event.AAI.put("vserver.selflink", "bar"); + event.AAI.put("vserver.vserver-name", "dfw1lb01lb01"); event.AAI.put("vserver.is-closed-loop-disabled", "false"); - event.AAI.put("generic-vnf.vnf-id", "testGenericVnfID"); - event.closedLoopEventStatus = ControlLoopEventStatus.ABATED; + event.closedLoopEventStatus = status; kieSession.insert(event); } diff --git a/controlloop/templates/template.demo/src/test/java/org/onap/policy/template/demo/VFCControlLoopTest.java b/controlloop/templates/template.demo/src/test/java/org/onap/policy/template/demo/VFCControlLoopTest.java index 648ac0abf..6f0527773 100644 --- a/controlloop/templates/template.demo/src/test/java/org/onap/policy/template/demo/VFCControlLoopTest.java +++ b/controlloop/templates/template.demo/src/test/java/org/onap/policy/template/demo/VFCControlLoopTest.java @@ -20,6 +20,7 @@ package org.onap.policy.template.demo; +import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; @@ -36,25 +37,26 @@ import org.junit.Test; import org.kie.api.runtime.KieSession; import org.kie.api.runtime.rule.FactHandle; import org.onap.policy.controlloop.ControlLoopEventStatus; -import org.onap.policy.controlloop.ControlLoopLogger; +import org.onap.policy.controlloop.ControlLoopNotificationType; import org.onap.policy.controlloop.ControlLoopTargetType; import org.onap.policy.controlloop.VirtualControlLoopEvent; -import org.onap.policy.controlloop.impl.ControlLoopLoggerStdOutImpl; +import org.onap.policy.controlloop.VirtualControlLoopNotification; import org.onap.policy.controlloop.policy.ControlLoopPolicy; +import org.onap.policy.drools.PolicyEngineListener; import org.onap.policy.drools.http.server.HttpServletServer; import org.onap.policy.drools.impl.PolicyEngineJUnitImpl; -import org.onap.policy.drools.system.PolicyEngine; -import org.onap.policy.vfc.util.Serialization; +import org.onap.policy.vfc.VFCRequest; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -public class VFCControlLoopTest { +public class VFCControlLoopTest implements PolicyEngineListener { - private static final Logger log = LoggerFactory.getLogger(VFCControlLoopTest.class); + private static final Logger logger = LoggerFactory.getLogger(VFCControlLoopTest.class); private KieSession kieSession; private Util.Pair<ControlLoopPolicy, String> pair; private PolicyEngineJUnitImpl engine; + private UUID requestID; static { /* Set environment properties */ @@ -81,156 +83,58 @@ public class VFCControlLoopTest { } @Test - public void testVolte() throws IOException { + public void successTest() throws IOException { - final String yaml = "src/test/resources/yaml/policy_ControlLoop_VFC.yaml"; - - // - // Pull info from the yaml - // - final Util.Pair<ControlLoopPolicy, String> pair = Util.loadYaml(yaml); - assertNotNull(pair); - assertNotNull(pair.a); - assertNotNull(pair.a.getControlLoop()); - assertNotNull(pair.a.getControlLoop().getControlLoopName()); - assertTrue(pair.a.getControlLoop().getControlLoopName().length() > 0); - final String closedLoopControlName = pair.a.getControlLoop().getControlLoopName(); - - /* + /* * Start the kie session */ - try { - kieSession = startSession("src/main/resources/ControlLoop_Template_xacml_guard.drl", - "src/test/resources/yaml/policy_ControlLoop_VFC.yaml", - "service=ServiceTest;resource=ResourceTest;type=operational", - "CL_VFC", - "org.onap.closed_loop.ServiceTest:VNFS:1.0.0"); - } catch (IOException e) { - e.printStackTrace(); - log.debug("Could not create kieSession"); - fail("Could not create kieSession"); - } - - - // - // Insert our globals - // - final ControlLoopLogger logger = new ControlLoopLoggerStdOutImpl(); - kieSession.setGlobal("Logger", logger); - final PolicyEngineJUnitImpl engine = new PolicyEngineJUnitImpl(); - kieSession.setGlobal("Engine", engine); - - // - // Initial fire of rules - // - kieSession.fireAllRules(); - // - // Kick a thread that starts testing - // - new Thread(new Runnable() { - - @Override - public void run() { - - log.debug("\n************ Starting VoLTE Test *************\n"); - - // - // Generate an invalid DCAE Event with requestID=null - // - VirtualControlLoopEvent invalidEvent = new VirtualControlLoopEvent(); - invalidEvent.closedLoopControlName = closedLoopControlName; - invalidEvent.requestID = null; - invalidEvent.closedLoopEventClient = "tca.instance00009"; - invalidEvent.target_type = ControlLoopTargetType.VNF; - invalidEvent.target = "generic-vnf.vnf-id"; - invalidEvent.from = "DCAE"; - invalidEvent.closedLoopAlarmStart = Instant.now(); - invalidEvent.AAI = new HashMap<String, String>(); - invalidEvent.AAI.put("vserver.vserver-name", "vserver-name-16102016-aai3255-data-11-1"); - invalidEvent.closedLoopEventStatus = ControlLoopEventStatus.ONSET; - - log.debug("-------- Sending Invalid ONSET --------"); - log.debug(Serialization.gsonPretty.toJson(invalidEvent)); - - // - // Insert invalid DCAE Event into memory - // - kieSession.insert(invalidEvent); - try { - Thread.sleep(500); - } catch (InterruptedException e) { - } - // - // Generate first DCAE ONSET Event - // - VirtualControlLoopEvent onsetEvent = new VirtualControlLoopEvent(); - onsetEvent.closedLoopControlName = closedLoopControlName; - onsetEvent.requestID = UUID.randomUUID(); - onsetEvent.closedLoopEventClient = "tca.instance00009"; - onsetEvent.target_type = ControlLoopTargetType.VM; - onsetEvent.target = "VM_NAME"; - onsetEvent.from = "DCAE"; - onsetEvent.closedLoopAlarmStart = Instant.now(); - onsetEvent.AAI = new HashMap<String, String>(); - onsetEvent.AAI.put("vserver.vserver-name", "vserver-name-16102016-aai3255-data-11-1"); - onsetEvent.AAI.put("vserver.vserver-id", "vserver-id-16102016-aai3255-data-11-1"); - onsetEvent.AAI.put("generic-vnf.vnf-id", "vnf-id-16102016-aai3255-data-11-1"); - onsetEvent.AAI.put("service-instance.service-instance-id", "service-instance-id-16102016-aai3255-data-11-1"); - onsetEvent.AAI.put("vserver.is-closed-loop-disabled", "false"); - onsetEvent.closedLoopEventStatus = ControlLoopEventStatus.ONSET; - - log.debug("-------- Sending Valid ONSET --------"); - log.debug(Serialization.gsonPretty.toJson(onsetEvent)); - - // - // Insert first DCAE ONSET Event into memory - // - kieSession.insert(onsetEvent); - // - // We have test for subsequent ONSET Events in testvFirewall() - // So no need to test it again here - // - try { - Thread.sleep(30000); - } catch (InterruptedException e) { - } - // - // Test is finished, so stop the kieSession - // - kieSession.halt(); - } - // - }).start(); - // - // Start firing rules - // - kieSession.fireUntilHalt(); - // - // Dump working memory - // - dumpFacts(kieSession); - - // - // See if there is anything left in memory, there SHOULD only be - // a params fact. - // - //assertEquals("There should only be 1 Fact left in memory.", 1, kieSession.getFactCount()); - if (kieSession.getFactCount() != 1L) { - log.error("FACT count mismatch: 1 expected but there are {}", kieSession.getFactCount()); - } - for (FactHandle handle : kieSession.getFactHandles()) { - Object fact = kieSession.getObject(handle); - // assertEquals("Non-Param Fact left in working memory", "org.onap.policy.controlloop.Params", fact.getClass().getName()); - log.info("Working Memory FACT: {}", fact.getClass().getName()); - } - - } - - public static void dumpFacts(KieSession kieSession) { - log.debug("Fact Count: " + kieSession.getFactCount()); - for (FactHandle handle : kieSession.getFactHandles()) { - log.debug("FACT: " + handle); - } + try { + kieSession = startSession("src/main/resources/ControlLoop_Template_xacml_guard.drl", + "src/test/resources/yaml/policy_ControlLoop_VFC.yaml", + "type=operational", + "CL_VoLTE", + "v2.0"); + } catch (IOException e) { + e.printStackTrace(); + logger.debug("Could not create kieSession"); + fail("Could not create kieSession"); + } + + /* + * Allows the PolicyEngine to callback to this object to + * notify that there is an event ready to be pulled + * from the queue + */ + engine.addListener(this); + + /* + * Create a unique requestId + */ + requestID = UUID.randomUUID(); + + /* + * Simulate an onset event the policy engine will + * receive from DCAE to kick off processing through + * the rules + */ + sendEvent(pair.a, requestID, ControlLoopEventStatus.ONSET); + + kieSession.fireUntilHalt(); + + /* + * The only fact in memory should be Params + */ + assertEquals(1, kieSession.getFactCount()); + + /* + * Print what's left in memory + */ + dumpFacts(kieSession); + + /* + * Gracefully shut down the kie session + */ + kieSession.dispose(); } /** @@ -281,12 +185,112 @@ public class VFCControlLoopTest { */ engine = (PolicyEngineJUnitImpl) kieSession.getGlobal("Engine"); - log.debug("============"); - log.debug(URLEncoder.encode(pair.b, "UTF-8")); - log.debug("============"); + logger.debug("============"); + logger.debug(URLEncoder.encode(pair.b, "UTF-8")); + logger.debug("============"); return kieSession; } + + /* + * (non-Javadoc) + * @see org.onap.policy.drools.PolicyEngineListener#newEventNotification(java.lang.String) + */ + public void newEventNotification(String topic) { + /* + * Pull the object that was sent out to DMAAP and make + * sure it is a ControlLoopNoticiation of type active + */ + Object obj = engine.subscribe("UEB", topic); + assertNotNull(obj); + if (obj instanceof VirtualControlLoopNotification) { + VirtualControlLoopNotification notification = (VirtualControlLoopNotification) obj; + String policyName = notification.policyName; + if (policyName.endsWith("EVENT")) { + logger.debug("Rule Fired: " + notification.policyName); + assertTrue(ControlLoopNotificationType.ACTIVE.equals(notification.notification)); + } + else if (policyName.endsWith("GUARD_NOT_YET_QUERIED")) { + logger.debug("Rule Fired: " + notification.policyName); + assertTrue(ControlLoopNotificationType.OPERATION.equals(notification.notification)); + assertNotNull(notification.message); + assertTrue(notification.message.startsWith("Sending guard query")); + } + else if (policyName.endsWith("GUARD.RESPONSE")) { + logger.debug("Rule Fired: " + notification.policyName); + assertTrue(ControlLoopNotificationType.OPERATION.equals(notification.notification)); + assertNotNull(notification.message); + assertTrue(notification.message.endsWith("PERMIT")); + } + else if (policyName.endsWith("GUARD_PERMITTED")) { + logger.debug("Rule Fired: " + notification.policyName); + assertTrue(ControlLoopNotificationType.OPERATION.equals(notification.notification)); + assertNotNull(notification.message); + assertTrue(notification.message.startsWith("actor=VFC")); + } + else if (policyName.endsWith("OPERATION.TIMEOUT")) { + logger.debug("Rule Fired: " + notification.policyName); + kieSession.halt(); + logger.debug("The operation timed out"); + fail("Operation Timed Out"); + } + else if (policyName.endsWith("VFC.RESPONSE")) { + logger.debug("Rule Fired: " + notification.policyName); + assertTrue(ControlLoopNotificationType.OPERATION_SUCCESS.equals(notification.notification)); + assertNotNull(notification.message); + assertTrue(notification.message.startsWith("actor=VFC")); + } + else if (policyName.endsWith("EVENT.MANAGER")) { + logger.debug("Rule Fired: " + notification.policyName); + assertTrue(ControlLoopNotificationType.FINAL_SUCCESS.equals(notification.notification)); + kieSession.halt(); + } + else if (policyName.endsWith("EVENT.MANAGER.TIMEOUT")) { + logger.debug("Rule Fired: " + notification.policyName); + kieSession.halt(); + logger.debug("The control loop timed out"); + fail("Control Loop Timed Out"); + } + } + else if (obj instanceof VFCRequest) { + logger.debug("\n============ VFC received the request!!! ===========\n"); + } + } + + /** + * This method is used to simulate event messages from DCAE + * that start the control loop (onset message) or end the + * control loop (abatement message). + * + * @param policy the controlLoopName comes from the policy + * @param requestID the requestId for this event + * @param status could be onset or abated + */ + protected void sendEvent(ControlLoopPolicy policy, UUID requestID, ControlLoopEventStatus status) { + VirtualControlLoopEvent event = new VirtualControlLoopEvent(); + event.closedLoopControlName = policy.getControlLoop().getControlLoopName(); + event.requestID = UUID.randomUUID(); + event.closedLoopEventClient = "tca.instance00009"; + event.target_type = ControlLoopTargetType.VM; + event.target = "VM_NAME"; + event.from = "DCAE"; + event.closedLoopAlarmStart = Instant.now(); + event.AAI = new HashMap<String, String>(); + event.AAI.put("vserver.vserver-name", "vserver-name-16102016-aai3255-data-11-1"); + event.AAI.put("vserver.vserver-id", "vserver-id-16102016-aai3255-data-11-1"); + event.AAI.put("generic-vnf.vnf-id", "vnf-id-16102016-aai3255-data-11-1"); + event.AAI.put("service-instance.service-instance-id", "service-instance-id-16102016-aai3255-data-11-1"); + event.AAI.put("vserver.is-closed-loop-disabled", "false"); + event.closedLoopEventStatus = ControlLoopEventStatus.ONSET; + kieSession.insert(event); + } + + public static void dumpFacts(KieSession kieSession) { + logger.debug("Fact Count: " + kieSession.getFactCount()); + for (FactHandle handle : kieSession.getFactHandles()) { + logger.debug("FACT: " + handle); + } + } } diff --git a/controlloop/templates/template.demo/src/test/java/org/onap/policy/template/demo/VFWControlLoopTest.java b/controlloop/templates/template.demo/src/test/java/org/onap/policy/template/demo/VFWControlLoopTest.java index 533e9ac69..fb4dc0265 100644 --- a/controlloop/templates/template.demo/src/test/java/org/onap/policy/template/demo/VFWControlLoopTest.java +++ b/controlloop/templates/template.demo/src/test/java/org/onap/policy/template/demo/VFWControlLoopTest.java @@ -20,7 +20,7 @@ package org.onap.policy.template.demo; -import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; @@ -44,20 +44,20 @@ import org.onap.policy.controlloop.ControlLoopNotificationType; import org.onap.policy.controlloop.VirtualControlLoopEvent; import org.onap.policy.controlloop.VirtualControlLoopNotification; import org.onap.policy.controlloop.policy.ControlLoopPolicy; -import org.onap.policy.controlloop.policy.TargetType; +import org.onap.policy.drools.PolicyEngineListener; import org.onap.policy.drools.http.server.HttpServletServer; import org.onap.policy.drools.impl.PolicyEngineJUnitImpl; -import org.onap.policy.guard.PolicyGuard; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -public class VFWControlLoopTest { +public class VFWControlLoopTest implements PolicyEngineListener { private static final Logger logger = LoggerFactory.getLogger(VFWControlLoopTest.class); private KieSession kieSession; private Util.Pair<ControlLoopPolicy, String> pair; private PolicyEngineJUnitImpl engine; + private UUID requestID; static { /* Set environment properties */ @@ -100,241 +100,30 @@ public class VFWControlLoopTest { } /* - * Create a thread to continuously fire rules - * until main thread calls halt - */ - new Thread( new Runnable() { - @Override - public void run() { - kieSession.fireUntilHalt(); - } - } ).start(); - - /* - * Create a unique requestId and a unique trigger source + * Allows the PolicyEngine to callback to this object to + * notify that there is an event ready to be pulled + * from the queue */ - UUID requestID = UUID.randomUUID(); - String triggerSourceName = "foobartriggersource36"; + engine.addListener(this); /* - * This will be the object returned from the PolicyEngine + * Create a unique requestId */ - Object obj = null; + requestID = UUID.randomUUID(); /* * Simulate an onset event the policy engine will * receive from DCAE to kick off processing through * the rules */ - try { - sendOnset(pair.a, requestID, triggerSourceName); - } catch (InterruptedException e) { - e.printStackTrace(); - logger.debug("Unable to send onset event"); - fail("Unable to send onset event"); - } - - /* - * Pull the object that was sent out to DMAAP and make - * sure it is a ControlLoopNoticiation of type active - */ - obj = engine.subscribe("UEB", "POLICY-CL-MGT"); - assertNotNull(obj); - assertTrue(obj instanceof VirtualControlLoopNotification); - assertTrue(((VirtualControlLoopNotification)obj).notification.equals(ControlLoopNotificationType.ACTIVE)); - - /* - * Give the control loop time to acquire a lock - */ - try { - Thread.sleep(4000); - } catch (InterruptedException e) { - e.printStackTrace(); - logger.debug("An interrupt Exception was thrown"); - fail("An interrupt Exception was thrown"); - } + sendEvent(pair.a, requestID, ControlLoopEventStatus.ONSET); - /* - * The fact should be ready to query guard now to see - * if a ModifyConfig recipe is allowed - */ - obj = engine.subscribe("UEB", "POLICY-CL-MGT"); - assertNotNull(obj); - logger.debug("\n\n####################### GOING TO QUERY GUARD about ModifyConfig!!!!!!"); - logger.debug("Rule: {} Message {}", ((VirtualControlLoopNotification)obj).policyName, ((VirtualControlLoopNotification)obj).message); - - /* - * Make sure the object is an instance of a ControlLoopNotification - * and is of type operation - */ - assertTrue(obj instanceof VirtualControlLoopNotification); - assertTrue(((VirtualControlLoopNotification)obj).notification.equals(ControlLoopNotificationType.OPERATION)); - - try { - Thread.sleep(4000); - } catch (InterruptedException e) { - e.printStackTrace(); - logger.debug("An interrupt Exception was thrown"); - fail("An interrupt Exception was thrown"); - } - - /* - * The guard response should be received at this point - */ - obj = engine.subscribe("UEB", "POLICY-CL-MGT"); - assertNotNull(obj); - logger.debug("Rule: {} Message {}", ((VirtualControlLoopNotification)obj).policyName, ((VirtualControlLoopNotification)obj).message); - - /* - * The object should be a ControlLoopNotification with type operation - */ - assertTrue(obj instanceof VirtualControlLoopNotification); - assertTrue(((VirtualControlLoopNotification)obj).notification.equals(ControlLoopNotificationType.OPERATION)); - - /* - * See if Guard permits this action, if it does - * not then the test should fail - */ - if (((VirtualControlLoopNotification)obj).message.contains("PERMIT")) { - - /* - * Obtain the ControlLoopNoticiation, it should be of type operation - */ - obj = engine.subscribe("UEB", "POLICY-CL-MGT"); - assertNotNull(obj); - logger.debug("Rule: {} Message {}", ((VirtualControlLoopNotification)obj).policyName, ((VirtualControlLoopNotification)obj).message); - - /* - * A notification should be sent out of the Policy - * Engine at this point, it will be of type operation - */ - assertTrue(obj instanceof VirtualControlLoopNotification); - assertTrue(((VirtualControlLoopNotification)obj).notification.equals(ControlLoopNotificationType.OPERATION)); - - try { - Thread.sleep(1000); - } catch (InterruptedException e) { - e.printStackTrace(); - logger.debug("An interrupt Exception was thrown"); - fail("An interrupt Exception was thrown"); - } - - /* - * Obtain the request sent from the Policy Engine - */ - obj = engine.subscribe("UEB", "APPC-CL"); - assertNotNull(obj); - - /* - * The request should be of type Request - * and the subrequestid should be 1 - */ - assertTrue(obj instanceof Request); - assertTrue(((Request)obj).getCommonHeader().SubRequestID.equals("1")); - - logger.debug("\n============ APPC received the request!!! ===========\n"); - - /* - * Give some time for processing - */ - try { - Thread.sleep(1000); - } catch (InterruptedException e) { - e.printStackTrace(); - logger.debug("An interrupt Exception was thrown"); - fail("An interrupt Exception was thrown"); - } - - /* - * Simulate a success response from APPC and insert - * the response into the working memory - */ - Response appcResponse = new Response((Request)obj); - appcResponse.getStatus().Code = ResponseCode.SUCCESS.getValue(); - appcResponse.getStatus().Value = "SUCCESS"; - kieSession.insert(appcResponse); - - /* - * Give time for processing - */ - try { - Thread.sleep(4000); - } catch (InterruptedException e) { - e.printStackTrace(); - logger.debug("An interrupt Exception was thrown"); - fail("An interrupt Exception was thrown"); - } - - /* - * Make sure the next notification is delivered - */ - obj = engine.subscribe("UEB", "POLICY-CL-MGT"); - assertNotNull(obj); - logger.debug("Rule: {} Message {}", ((VirtualControlLoopNotification)obj).policyName, ((VirtualControlLoopNotification)obj).message); - - /* - * The ControlLoopNotification should be - * an OPERATION_SUCCESS - */ - assertTrue(obj instanceof VirtualControlLoopNotification); - assertTrue(((VirtualControlLoopNotification)obj).notification.equals(ControlLoopNotificationType.OPERATION_SUCCESS)); - - /* - * Now simulate the abatement sent from DCAE - */ - try { - sendAbatement(pair.a, requestID, triggerSourceName); - } catch (InterruptedException e1) { - e1.printStackTrace(); - logger.debug("Abatement could not be sent"); - fail("Abatement could not be sent"); - } - - /* - * Give time to finish processing - */ - try { - Thread.sleep(20000); - } catch (InterruptedException e) { - e.printStackTrace(); - logger.debug("An interrupt Exception was thrown"); - fail("An interrupt Exception was thrown"); - } - - /* - * This should be the final notification from the Policy Engine - */ - obj = engine.subscribe("UEB", "POLICY-CL-MGT"); - assertNotNull(obj); - logger.debug("Rule: {} Message {}", ((VirtualControlLoopNotification)obj).policyName, ((VirtualControlLoopNotification)obj).message); - - /* - * The ControlLoopNotification should be of type FINAL_SUCCESS - */ - assertTrue(obj instanceof VirtualControlLoopNotification); - assertTrue(((VirtualControlLoopNotification)obj).notification.equals(ControlLoopNotificationType.FINAL_SUCCESS)); - - /* - * One final check to make sure the lock is released - */ - assertFalse(PolicyGuard.isLocked(TargetType.VNF, triggerSourceName, requestID)); - } - else { - fail("Operation Denied by Guard"); - } - - /* - * This will stop the thread that is firing the rules - */ - kieSession.halt(); + kieSession.fireUntilHalt(); /* * The only fact in memory should be Params */ - // assertEquals(1, kieSession.getFactCount()); - if (kieSession.getFactCount() != 1L) { - logger.error("FACT count mismatch: 1 expected but there are {}", kieSession.getFactCount()); - } + assertEquals(1, kieSession.getFactCount()); /* * Print what's left in memory @@ -401,51 +190,101 @@ public class VFWControlLoopTest { return kieSession; } - - /** - * This method is used to simulate event messages from DCAE - * that start the control loop (onset message). - * - * @param policy the controlLoopName comes from the policy - * @param requestID the requestId for this event - * @param triggerSourceName - * @throws InterruptedException + + /* + * @see org.onap.policy.drools.PolicyEngineListener#newEventNotification(java.lang.String) */ - protected void sendOnset(ControlLoopPolicy policy, UUID requestID, String triggerSourceName) throws InterruptedException { - VirtualControlLoopEvent event = new VirtualControlLoopEvent(); - event.closedLoopControlName = policy.getControlLoop().getControlLoopName(); - event.requestID = requestID; - event.target = "generic-vnf.vnf-id"; - event.closedLoopAlarmStart = Instant.now(); - event.AAI = new HashMap<>(); - event.AAI.put("generic-vnf.vnf-id", "testGenericVnfID"); - event.closedLoopEventStatus = ControlLoopEventStatus.ONSET; - kieSession.insert(event); - Thread.sleep(2000); + public void newEventNotification(String topic) { + /* + * Pull the object that was sent out to DMAAP and make + * sure it is a ControlLoopNoticiation of type active + */ + Object obj = engine.subscribe("UEB", topic); + assertNotNull(obj); + if (obj instanceof VirtualControlLoopNotification) { + VirtualControlLoopNotification notification = (VirtualControlLoopNotification) obj; + String policyName = notification.policyName; + if (policyName.endsWith("EVENT")) { + logger.debug("Rule Fired: " + notification.policyName); + assertTrue(ControlLoopNotificationType.ACTIVE.equals(notification.notification)); + } + else if (policyName.endsWith("GUARD_NOT_YET_QUERIED")) { + logger.debug("Rule Fired: " + notification.policyName); + assertTrue(ControlLoopNotificationType.OPERATION.equals(notification.notification)); + assertNotNull(notification.message); + assertTrue(notification.message.startsWith("Sending guard query")); + } + else if (policyName.endsWith("GUARD.RESPONSE")) { + logger.debug("Rule Fired: " + notification.policyName); + assertTrue(ControlLoopNotificationType.OPERATION.equals(notification.notification)); + assertNotNull(notification.message); + assertTrue(notification.message.endsWith("PERMIT")); + } + else if (policyName.endsWith("GUARD_PERMITTED")) { + logger.debug("Rule Fired: " + notification.policyName); + assertTrue(ControlLoopNotificationType.OPERATION.equals(notification.notification)); + assertNotNull(notification.message); + assertTrue(notification.message.startsWith("actor=APPC")); + } + else if (policyName.endsWith("OPERATION.TIMEOUT")) { + logger.debug("Rule Fired: " + notification.policyName); + kieSession.halt(); + logger.debug("The operation timed out"); + fail("Operation Timed Out"); + } + else if (policyName.endsWith("APPC.RESPONSE")) { + logger.debug("Rule Fired: " + notification.policyName); + assertTrue(ControlLoopNotificationType.OPERATION_SUCCESS.equals(notification.notification)); + assertNotNull(notification.message); + assertTrue(notification.message.startsWith("actor=APPC")); + sendEvent(pair.a, requestID, ControlLoopEventStatus.ABATED); + } + else if (policyName.endsWith("EVENT.MANAGER")) { + logger.debug("Rule Fired: " + notification.policyName); + assertTrue(ControlLoopNotificationType.FINAL_SUCCESS.equals(notification.notification)); + kieSession.halt(); + } + else if (policyName.endsWith("EVENT.MANAGER.TIMEOUT")) { + logger.debug("Rule Fired: " + notification.policyName); + kieSession.halt(); + logger.debug("The control loop timed out"); + fail("Control Loop Timed Out"); + } + } + else if (obj instanceof Request) { + assertTrue(((Request)obj).getCommonHeader().SubRequestID.equals("1")); + + logger.debug("\n============ APPC received the request!!! ===========\n"); + + /* + * Simulate a success response from APPC and insert + * the response into the working memory + */ + Response appcResponse = new Response((Request)obj); + appcResponse.getStatus().Code = ResponseCode.SUCCESS.getValue(); + appcResponse.getStatus().Value = "SUCCESS"; + kieSession.insert(appcResponse); + } } /** * This method is used to simulate event messages from DCAE - * that end the control loop (abatement message). + * that start the control loop (onset message) or end the + * control loop (abatement message). * * @param policy the controlLoopName comes from the policy * @param requestID the requestId for this event - * @param triggerSourceName - * @throws InterruptedException + * @param status could be onset or abated */ - protected void sendAbatement(ControlLoopPolicy policy, UUID requestID, String triggerSourceName) throws InterruptedException { + protected void sendEvent(ControlLoopPolicy policy, UUID requestID, ControlLoopEventStatus status) { VirtualControlLoopEvent event = new VirtualControlLoopEvent(); event.closedLoopControlName = policy.getControlLoop().getControlLoopName(); event.requestID = requestID; event.target = "generic-vnf.vnf-id"; - event.closedLoopAlarmStart = Instant.now().minusSeconds(5); - event.closedLoopAlarmEnd = Instant.now(); + event.closedLoopAlarmStart = Instant.now(); event.AAI = new HashMap<>(); - event.AAI.put("cloud-region.identity-url", "foo"); - event.AAI.put("vserver.selflink", "bar"); - event.AAI.put("vserver.is-closed-loop-disabled", "false"); event.AAI.put("generic-vnf.vnf-id", "testGenericVnfID"); - event.closedLoopEventStatus = ControlLoopEventStatus.ABATED; + event.closedLoopEventStatus = status; kieSession.insert(event); } diff --git a/controlloop/templates/template.demo/src/test/resources/yaml/policy_ControlLoop_SO-test.yaml b/controlloop/templates/template.demo/src/test/resources/yaml/policy_ControlLoop_SO-test.yaml index d3ae91650..d4b040396 100644 --- a/controlloop/templates/template.demo/src/test/resources/yaml/policy_ControlLoop_SO-test.yaml +++ b/controlloop/templates/template.demo/src/test/resources/yaml/policy_ControlLoop_SO-test.yaml @@ -6,7 +6,7 @@ controlLoop: serviceInvariantUUID: dc112d6e-7e73-4777-9c6f-1a7fb5fd1b6f serviceUUID: 2eea06c6-e1d3-4c3a-b9c4-478c506eeedf trigger_policy: unique-policy-id-1-scale-up - timeout: 1200 + timeout: 20 policies: - id: unique-policy-id-1-scale-up @@ -17,7 +17,7 @@ policies: target: type: VNF retry: 0 - timeout: 1200 + timeout: 10 success: final_success failure: final_failure failure_timeout: final_failure_timeout diff --git a/controlloop/templates/template.demo/src/test/resources/yaml/policy_ControlLoop_VFC.yaml b/controlloop/templates/template.demo/src/test/resources/yaml/policy_ControlLoop_VFC.yaml index 00cced484..336d83fc3 100644 --- a/controlloop/templates/template.demo/src/test/resources/yaml/policy_ControlLoop_VFC.yaml +++ b/controlloop/templates/template.demo/src/test/resources/yaml/policy_ControlLoop_VFC.yaml @@ -3,7 +3,7 @@ controlLoop: controlLoopName: ControlLoop-VOLTE-2179b738-fd36-4843-a71a-a8c24c70c55b trigger_policy: unique-policy-id-1-restart - timeout: 3600 + timeout: 20 policies: - id: unique-policy-id-1-restart @@ -14,7 +14,7 @@ policies: target: type: VM retry: 3 - timeout: 1200 + timeout: 10 success: final_success failure: final_failure failure_timeout: final_failure_timeout diff --git a/controlloop/templates/template.demo/src/test/resources/yaml/policy_ControlLoop_vCPE.yaml b/controlloop/templates/template.demo/src/test/resources/yaml/policy_ControlLoop_vCPE.yaml index de2ece4ed..65a3a4f8b 100644 --- a/controlloop/templates/template.demo/src/test/resources/yaml/policy_ControlLoop_vCPE.yaml +++ b/controlloop/templates/template.demo/src/test/resources/yaml/policy_ControlLoop_vCPE.yaml @@ -2,7 +2,7 @@ controlLoop: version: 2.0.0 controlLoopName: ControlLoop-vCPE-48f0c2c3-a172-4192-9ae3-052274181b6e trigger_policy: unique-policy-id-1-restart - timeout: 3600 + timeout: 20 abatement: true policies: @@ -14,7 +14,7 @@ policies: target: type: VM retry: 3 - timeout: 1200 + timeout: 10 success: final_success failure: final_failure failure_timeout: final_failure_timeout diff --git a/controlloop/templates/template.demo/src/test/resources/yaml/policy_ControlLoop_vFW.yaml b/controlloop/templates/template.demo/src/test/resources/yaml/policy_ControlLoop_vFW.yaml index d15c46126..4a92a24f7 100644 --- a/controlloop/templates/template.demo/src/test/resources/yaml/policy_ControlLoop_vFW.yaml +++ b/controlloop/templates/template.demo/src/test/resources/yaml/policy_ControlLoop_vFW.yaml @@ -6,7 +6,7 @@ controlLoop: serviceUUID: 0f40bba5-986e-4b3c-803f-ddd1b7b25f24 serviceName: 57e66ea7-0ed6-45c7-970f trigger_policy: unique-policy-id-1-modifyConfig - timeout: 1200 + timeout: 20 abatement: true policies: @@ -19,7 +19,7 @@ policies: resourceID: Eace933104d443b496b8.nodes.heat.vpg type: VNF retry: 0 - timeout: 300 + timeout: 10 success: final_success failure: final_failure failure_timeout: final_failure_timeout |