Fix Sonar Technical Debt, Unit Test for APPC POJOs
[policy/drools-applications.git] / controlloop / templates / template.demo / src / test / java / org / onap / policy / template / demo / VFWControlLoopTest.java
index 25920e8..95737b9 100644 (file)
 
 package org.onap.policy.template.demo;
 
-import static org.junit.Assert.*;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
 
 import java.io.IOException;
 import java.net.URLEncoder;
 import java.time.Instant;
 import java.util.HashMap;
+import java.util.List;
+import java.util.Properties;
 import java.util.UUID;
 
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
 import org.junit.Test;
 import org.kie.api.runtime.KieSession;
 import org.kie.api.runtime.rule.FactHandle;
@@ -39,28 +46,65 @@ 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.impl.PolicyEngineJUnitImpl;
-import org.onap.policy.guard.PolicyGuard;
+import org.onap.policy.drools.event.comm.TopicEndpoint;
+import org.onap.policy.drools.event.comm.TopicListener;
+import org.onap.policy.drools.event.comm.TopicSink;
+import org.onap.policy.drools.event.comm.Topic.CommInfrastructure;
+import org.onap.policy.drools.http.server.HttpServletServer;
+import org.onap.policy.drools.properties.PolicyProperties;
+import org.onap.policy.drools.protocol.coders.EventProtocolCoder;
+import org.onap.policy.drools.protocol.coders.JsonProtocolFilter;
+import org.onap.policy.drools.system.PolicyController;
+import org.onap.policy.drools.system.PolicyEngine;
+import org.onap.policy.drools.utils.LoggerUtil;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-public class VFWControlLoopTest {
+public class VFWControlLoopTest implements TopicListener {
 
     private static final Logger logger = LoggerFactory.getLogger(VFWControlLoopTest.class);
     
-    private KieSession kieSession;
-    private Util.Pair<ControlLoopPolicy, String> pair;
-    private PolicyEngineJUnitImpl engine;     
+    private static List<? extends TopicSink> noopTopics;
     
-    @Test
-    public void successTest() {
+    private static KieSession kieSession;
+    private static Util.Pair<ControlLoopPolicy, String> pair;
+    private UUID requestID;
+    
+    static {
+        /* Set environment properties */
+        Util.setAAIProps();
+        Util.setGuardProps();
+        Util.setPUProp();
+        LoggerUtil.setLevel(LoggerUtil.ROOT_LOGGER, "INFO");
+    }
+    
+    @BeforeClass
+    public static void setUpSimulator() {
+       PolicyEngine.manager.configure(new Properties());
+       assertTrue(PolicyEngine.manager.start());
+       Properties noopSinkProperties = new Properties();
+       noopSinkProperties.put(PolicyProperties.PROPERTY_NOOP_SINK_TOPICS, "APPC-CL,POLICY-CL-MGT");
+       noopSinkProperties.put("noop.sink.topics.APPC-CL.events", "org.onap.policy.appc.Response");
+       noopSinkProperties.put("noop.sink.topics.APPC-CL.events.custom.gson", "org.onap.policy.appc.util.Serialization,gsonPretty");
+       noopSinkProperties.put("noop.sink.topics.POLICY-CL-MGT.events", "org.onap.policy.controlloop.VirtualControlLoopNotification");
+       noopSinkProperties.put("noop.sink.topics.POLICY-CL-MGT.events.custom.gson", "org.onap.policy.controlloop.util.Serialization,gsonPretty");
+       noopTopics = TopicEndpoint.manager.addTopicSinks(noopSinkProperties);
+       
+       EventProtocolCoder.manager.addEncoder("junit.groupId", "junit.artifactId", "POLICY-CL-MGT", "org.onap.policy.controlloop.VirtualControlLoopNotification", new JsonProtocolFilter(), null, null, 1111);
+       EventProtocolCoder.manager.addEncoder("junit.groupId", "junit.artifactId", "APPC-CL", "org.onap.policy.appc.Request", new JsonProtocolFilter(), null, null, 1111);
+
+        try {
+            Util.buildAaiSim();
+            Util.buildGuardSim();
+        } catch (Exception e) {
+            fail(e.getMessage());
+        }
         
         /*
          * Start the kie session
          */
         try {
-            kieSession = startSession("src/main/resources/ControlLoop_Template_xacml_guard.drl", 
+            kieSession = startSession("../archetype-cl-amsterdam/src/main/resources/archetype-resources/src/main/resources/__closedLoopControlName__.drl", 
                         "src/test/resources/yaml/policy_ControlLoop_vFW.yaml",
                         "service=ServiceDemo;resource=Res1Demo;type=operational", 
                         "CL_vFW", 
@@ -70,235 +114,131 @@ public class VFWControlLoopTest {
             logger.debug("Could not create kieSession");
             fail("Could not create kieSession");
         }
+    }
+
+    @AfterClass
+    public static void tearDownSimulator() {
+       /*
+         * Gracefully shut down the kie session
+         */
+        kieSession.dispose();
         
-        /*
-         * Create a thread to continuously fire rules 
-         * until main thread calls halt
-         */      
-        new Thread( new Runnable() {
-            @Override
-            public void run() {
-                kieSession.fireUntilHalt();
-            }
-          } ).start();
+        PolicyEngine.manager.stop();
+        HttpServletServer.factory.destroy();
+        PolicyController.factory.shutdown();
+        TopicEndpoint.manager.shutdown();
+    }
+    
+    @Test
+    public void successTest() {
         
-        /*
-         * 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";
-        
+        for (TopicSink sink : noopTopics) {
+            assertTrue(sink.start());
+            sink.register(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
          */
+        sendEvent(pair.a, requestID, ControlLoopEventStatus.ONSET);
+        
         try {
-            sendOnset(pair.a, requestID, triggerSourceName);
-        } catch (InterruptedException e) {
-            e.printStackTrace();
-            logger.debug("Unable to send onset event");
-            fail("Unable to send onset event");
+               kieSession.fireUntilHalt();
         }
+        catch (Exception e) {
+               e.printStackTrace();
+               logger.warn(e.toString());
+               fail("fail");
+        }
+        
         
         /*
-         * Pull the object that was sent out to DMAAP and make
-         * sure it is a ControlLoopNoticiation of type active
+         * The only fact in memory should be Params
          */
-        obj = engine.subscribe("UEB", "POLICY-CL-MGT");
-        assertNotNull(obj);
-        assertTrue(obj instanceof VirtualControlLoopNotification);
-        assertTrue(((VirtualControlLoopNotification)obj).notification.equals(ControlLoopNotificationType.ACTIVE));
+        assertEquals(1, kieSession.getFactCount());
         
         /*
-         * Give the control loop time to acquire a lock
+         * Print what's left in memory
          */
-        try {
-            Thread.sleep(4000);
-        } catch (InterruptedException e) {
-            e.printStackTrace();
-            logger.debug("An interrupt Exception was thrown");
-            fail("An interrupt Exception was thrown");
-        }
+        dumpFacts(kieSession);
+    }
+    
+    @Test
+    public void aaiFailTests() {
         
         /*
-         * The fact should be ready to query guard now to see 
-         * if a ModifyConfig recipe is allowed
+         * Allows the PolicyEngine to callback to this object to
+         * notify that there is an event ready to be pulled 
+         * from the queue
          */
-        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);
+        for (TopicSink sink : noopTopics) {
+            assertTrue(sink.start());
+            sink.register(this);
+        }
         
         /*
-         * Make sure the object is an instance of a ControlLoopNotification
-         * and is of type operation
+         * Create a unique requestId
          */
-        assertTrue(obj instanceof VirtualControlLoopNotification);
-        assertTrue(((VirtualControlLoopNotification)obj).notification.equals(ControlLoopNotificationType.OPERATION));
-    
+        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, "error");
         try {
-            Thread.sleep(4000);
-        } catch (InterruptedException e) {
-            e.printStackTrace();
-            logger.debug("An interrupt Exception was thrown");
-            fail("An interrupt Exception was thrown");
+               kieSession.fireUntilHalt();
+        }
+        catch (Exception e) {
+               e.printStackTrace();
+               logger.warn(e.toString());
+               fail(e.getMessage());
         }
         
         /*
-         * The guard response should be received at this point
+         * The only fact in memory should be Params
          */
-        obj = engine.subscribe("UEB", "POLICY-CL-MGT");
-        assertNotNull(obj);
-        logger.debug("Rule: {} Message {}", ((VirtualControlLoopNotification)obj).policyName, ((VirtualControlLoopNotification)obj).message);
+        assertEquals(1, kieSession.getFactCount());
         
         /*
-         * The object should be a ControlLoopNotification with type operation
+         * Print what's left in memory
          */
-        assertTrue(obj instanceof VirtualControlLoopNotification);
-        assertTrue(((VirtualControlLoopNotification)obj).notification.equals(ControlLoopNotificationType.OPERATION));
+        dumpFacts(kieSession);
         
         /*
-         * See if Guard permits this action, if it does 
-         * not then the test should fail
+         * Create a unique requestId
          */
-        if (((VirtualControlLoopNotification)obj).message.contains("Guard result: 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().Description = "AppC 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.VM, triggerSourceName, requestID));
-        }
-        else {
-            fail("Operation Denied by Guard");
-        }
+        requestID = UUID.randomUUID();
         
-        /*
-         * This will stop the thread that is firing the rules
+        /* 
+         * Simulate an onset event the policy engine will 
+         * receive from DCAE to kick off processing through
+         * the rules
          */
-        kieSession.halt();
+        
+        sendEvent(pair.a, requestID, ControlLoopEventStatus.ONSET, "getFail");
+        
+        try {
+               kieSession.fireUntilHalt();
+        }
+        catch (Exception e) {
+               e.printStackTrace();
+               logger.warn(e.toString());
+               fail(e.getMessage());
+        }
         
         /*
          * The only fact in memory should be Params
@@ -309,11 +249,6 @@ public class VFWControlLoopTest {
          * Print what's left in memory
          */
         dumpFacts(kieSession);
-        
-        /*
-         * Gracefully shut down the kie session
-         */
-        kieSession.dispose();
     }
     
     /**
@@ -333,7 +268,7 @@ public class VFWControlLoopTest {
      * @return the kieSession to be used to insert facts 
      * @throws IOException
      */
-    private KieSession startSession(String droolsTemplate, 
+    private static KieSession startSession(String droolsTemplate, 
             String yamlFile, 
             String policyScope, 
             String policyName, 
@@ -362,7 +297,6 @@ public class VFWControlLoopTest {
         /*
          * Retrieve the Policy Engine
          */
-        engine = (PolicyEngineJUnitImpl) kieSession.getGlobal("Engine");
         
         logger.debug("============");
         logger.debug(URLEncoder.encode(pair.b, "UTF-8"));
@@ -370,54 +304,137 @@ public class VFWControlLoopTest {
         
         return kieSession;
     }
-
+    
+    /*
+     * @see org.onap.policy.drools.PolicyEngineListener#newEventNotification(java.lang.String)
+     */
+    public void onTopicEvent(CommInfrastructure commType, String topic, String event) {
+        /*
+         * Pull the object that was sent out to DMAAP and make
+         * sure it is a ControlLoopNoticiation of type active
+         */
+       Object obj = null;
+        if ("POLICY-CL-MGT".equals(topic)) {
+               obj = org.onap.policy.controlloop.util.Serialization.gsonJunit.fromJson(event, org.onap.policy.controlloop.VirtualControlLoopNotification.class);
+       }
+       else if ("APPC-CL".equals(topic))
+               obj = org.onap.policy.appc.util.Serialization.gsonPretty.fromJson(event, org.onap.policy.appc.Request.class);
+        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.toLowerCase().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);
+                if ("error".equals(notification.AAI.get("generic-vnf.vnf-name"))) {
+                       assertEquals(ControlLoopNotificationType.FINAL_FAILURE, notification.notification);
+                       assertEquals("Target vnf-id could not be found", notification.message);
+                }
+                else if ("getFail".equals(notification.AAI.get("generic-vnf.vnf-name"))) {
+                    assertEquals(ControlLoopNotificationType.FINAL_FAILURE, notification.notification);
+                }
+                else {
+                    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().getSubRequestID().equals("1"));
+            assertNotNull(((Request)obj).getPayload().get("generic-vnf.vnf-id"));
+            
+            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().setCode(ResponseCode.SUCCESS.getValue());
+            appcResponse.getStatus().setValue("SUCCESS");
+            kieSession.insert(appcResponse);
+        }        
+    }
+    
     /**
      * This method is used to simulate event messages from DCAE
-     * that start the control loop (onset 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 sendOnset(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 = "vserver.vserver-name";
+        event.target = "generic-vnf.vnf-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.is-closed-loop-disabled", "false");
-        event.AAI.put("vserver.vserver-name", "testGenericVnfName");
-        event.closedLoopEventStatus = ControlLoopEventStatus.ONSET;
+        event.AAI.put("generic-vnf.vnf-name", "testGenericVnfID");
+        event.closedLoopEventStatus = status;
         kieSession.insert(event);
-        Thread.sleep(2000);
     }
     
     /**
      * 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, String vnfId) {
         VirtualControlLoopEvent event = new VirtualControlLoopEvent();
         event.closedLoopControlName = policy.getControlLoop().getControlLoopName();
         event.requestID = requestID;
-        event.target = "vserver.vserver-name";
-        event.closedLoopAlarmStart = Instant.now().minusSeconds(5);
-        event.closedLoopAlarmEnd = Instant.now();
+        event.target = "generic-vnf.vnf-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.is-closed-loop-disabled", "false");
-        event.AAI.put("generic-vnf.vnf-name", "testGenericVnfName");
-        event.closedLoopEventStatus = ControlLoopEventStatus.ABATED;
+        event.AAI.put("generic-vnf.vnf-name", vnfId);
+        event.closedLoopEventStatus = status;
         kieSession.insert(event);
     }