From 506267bf7e9d961f1a6b2a989ee8a23ca67b9d61 Mon Sep 17 00:00:00 2001 From: Charles Cole Date: Mon, 16 Oct 2017 12:05:08 -0500 Subject: Add support for AAI Named Query error handling Errors from AAI after a Named query now throw an AAIEXception. This is caught in the template to allow the resources to be removed from memory and a final failure to be thrown. Issue-ID: POLICY-314 Change-Id: I319d29ef537b2d01ca288622aac1d9dbbe05f5eb Signed-off-by: Charles Cole --- .../actor/appc/APPCActorServiceProvider.java | 9 +- .../actor/appc/AppcServiceProviderTest.java | 9 +- controlloop/common/actors/actor.test/pom.xml | 6 ++ .../eventmanager/ControlLoopEventManager.java | 3 +- .../eventmanager/ControlLoopOperationManager.java | 10 ++- .../ControlLoopOperationManagerTest.java | 6 +- .../main/java/org/onap/policy/aai/AAIManager.java | 3 +- .../org/onap/policy/aai/AAINQRequestError.java | 33 ++++++++ .../java/org/onap/policy/aai/AAINQResponse.java | 3 + .../org/onap/policy/aai/AAINQServiceException.java | 39 +++++++++ .../org/onap/policy/aai/util/AAIException.java | 48 +++++++++++ .../onap/policy/simulators/AaiSimulatorJaxRs.java | 7 +- .../main/resources/__closedLoopControlName__.drl | 22 ++++- .../policy/template/demo/VFWControlLoopTest.java | 96 +++++++++++++++++++++- 14 files changed, 279 insertions(+), 15 deletions(-) create mode 100644 controlloop/common/model-impl/aai/src/main/java/org/onap/policy/aai/AAINQRequestError.java create mode 100644 controlloop/common/model-impl/aai/src/main/java/org/onap/policy/aai/AAINQServiceException.java create mode 100644 controlloop/common/model-impl/aai/src/main/java/org/onap/policy/aai/util/AAIException.java diff --git a/controlloop/common/actors/actor.appc/src/main/java/org/onap/policy/controlloop/actor/appc/APPCActorServiceProvider.java b/controlloop/common/actors/actor.appc/src/main/java/org/onap/policy/controlloop/actor/appc/APPCActorServiceProvider.java index 75810c01e..6ae62bbcd 100644 --- a/controlloop/common/actors/actor.appc/src/main/java/org/onap/policy/controlloop/actor/appc/APPCActorServiceProvider.java +++ b/controlloop/common/actors/actor.appc/src/main/java/org/onap/policy/controlloop/actor/appc/APPCActorServiceProvider.java @@ -25,6 +25,7 @@ import java.util.List; import org.onap.policy.controlloop.VirtualControlLoopEvent; import org.onap.policy.controlloop.actor.appclcm.AppcLcmActorServiceProvider; +import org.onap.policy.aai.util.AAIException; import org.onap.policy.appc.CommonHeader; import org.onap.policy.appc.Request; import org.onap.policy.controlloop.ControlLoopOperation; @@ -33,6 +34,7 @@ import org.onap.policy.vnf.trafficgenerator.PGRequest; import org.onap.policy.vnf.trafficgenerator.PGStream; import org.onap.policy.vnf.trafficgenerator.PGStreams; import org.onap.policy.controlloop.actorServiceProvider.spi.Actor; + import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; @@ -85,8 +87,9 @@ public class APPCActorServiceProvider implements Actor { * the policy the was specified from the yaml generated * by CLAMP or through the Policy GUI/API * @return an APPC request conforming to the legacy API + * @throws AAIException */ - public static Request constructRequest(VirtualControlLoopEvent onset, ControlLoopOperation operation, Policy policy) { + public static Request constructRequest(VirtualControlLoopEvent onset, ControlLoopOperation operation, Policy policy) throws AAIException { /* * Construct an APPC request */ @@ -111,6 +114,10 @@ public class APPCActorServiceProvider implements Actor { policy.getTarget().getResourceID(), onset.AAI.get("generic-vnf.vnf-id")); } + if (vnfId == null) { + throw new AAIException("No vnf id found"); + } + /* * For now Policy generates the PG Streams as a demo, in the * future the payload can be provided by CLAMP diff --git a/controlloop/common/actors/actor.appc/src/test/java/org/onap/policy/controlloop/actor/appc/AppcServiceProviderTest.java b/controlloop/common/actors/actor.appc/src/test/java/org/onap/policy/controlloop/actor/appc/AppcServiceProviderTest.java index 9d7e46320..7ab368f6f 100644 --- a/controlloop/common/actors/actor.appc/src/test/java/org/onap/policy/controlloop/actor/appc/AppcServiceProviderTest.java +++ b/controlloop/common/actors/actor.appc/src/test/java/org/onap/policy/controlloop/actor/appc/AppcServiceProviderTest.java @@ -29,6 +29,7 @@ import java.util.UUID; import org.junit.AfterClass; import org.junit.BeforeClass; import org.junit.Test; +import org.onap.policy.aai.util.AAIException; import org.onap.policy.appc.Request; import org.onap.policy.appc.Response; import org.onap.policy.appc.ResponseCode; @@ -115,7 +116,13 @@ public class AppcServiceProviderTest { @Test public void constructModifyConfigRequestTest() { - Request appcRequest = APPCActorServiceProvider.constructRequest(onsetEvent, operation, policy); + Request appcRequest = null; + try { + appcRequest = APPCActorServiceProvider.constructRequest(onsetEvent, operation, policy); + } catch (AAIException e) { + logger.warn(e.toString()); + fail("no vnfid found"); + } /* The service provider must return a non null APPC request */ assertNotNull(appcRequest); diff --git a/controlloop/common/actors/actor.test/pom.xml b/controlloop/common/actors/actor.test/pom.xml index c7e240ceb..79d6b6601 100644 --- a/controlloop/common/actors/actor.test/pom.xml +++ b/controlloop/common/actors/actor.test/pom.xml @@ -30,6 +30,12 @@ 1.1.0-SNAPSHOT provided + + org.onap.policy.drools-applications + aai + 1.1.0-SNAPSHOT + provided + junit junit diff --git a/controlloop/common/eventmanager/src/main/java/org/onap/policy/controlloop/eventmanager/ControlLoopEventManager.java b/controlloop/common/eventmanager/src/main/java/org/onap/policy/controlloop/eventmanager/ControlLoopEventManager.java index f8f3b4cc8..2fc43a01c 100644 --- a/controlloop/common/eventmanager/src/main/java/org/onap/policy/controlloop/eventmanager/ControlLoopEventManager.java +++ b/controlloop/common/eventmanager/src/main/java/org/onap/policy/controlloop/eventmanager/ControlLoopEventManager.java @@ -265,8 +265,9 @@ public class ControlLoopEventManager implements LockCallback, Serializable { } switch (result) { - case FINAL_FAILURE: case FINAL_FAILURE_EXCEPTION: + notification.message = "Exception in processing closed loop"; + case FINAL_FAILURE: case FINAL_FAILURE_RETRIES: case FINAL_FAILURE_TIMEOUT: case FINAL_FAILURE_GUARD: diff --git a/controlloop/common/eventmanager/src/main/java/org/onap/policy/controlloop/eventmanager/ControlLoopOperationManager.java b/controlloop/common/eventmanager/src/main/java/org/onap/policy/controlloop/eventmanager/ControlLoopOperationManager.java index 608d2c00d..edb6356d9 100644 --- a/controlloop/common/eventmanager/src/main/java/org/onap/policy/controlloop/eventmanager/ControlLoopOperationManager.java +++ b/controlloop/common/eventmanager/src/main/java/org/onap/policy/controlloop/eventmanager/ControlLoopOperationManager.java @@ -31,6 +31,7 @@ import java.util.Properties; import javax.persistence.EntityManager; import javax.persistence.Persistence; +import org.onap.policy.aai.util.AAIException; import org.onap.policy.appc.Response; import org.onap.policy.appc.ResponseCode; import org.onap.policy.appclcm.LCMResponseWrapper; @@ -145,7 +146,7 @@ public class ControlLoopOperationManager implements Serializable { } } - public Object startOperation(/*VirtualControlLoopEvent*/ControlLoopEvent onset) { + public Object startOperation(/*VirtualControlLoopEvent*/ControlLoopEvent onset) throws AAIException { // // They shouldn't call us if we currently running something // @@ -206,6 +207,7 @@ public class ControlLoopOperationManager implements Serializable { * request is constructed. Otherwise an LCMRequest * is constructed. */ + this.currentOperation = operation; if ("ModifyConfig".equalsIgnoreCase(policy.getRecipe())) { this.operationRequest = APPCActorServiceProvider.constructRequest((VirtualControlLoopEvent)onset, operation.operation, this.policy); @@ -216,7 +218,7 @@ public class ControlLoopOperationManager implements Serializable { // // Save the operation // - this.currentOperation = operation; + return operationRequest; case "SO": SOActorServiceProvider SOAsp = new SOActorServiceProvider(); @@ -482,6 +484,10 @@ public class ControlLoopOperationManager implements Serializable { // this.completeOperation(this.attempts, "Operation denied by Guard", PolicyResult.FAILURE_GUARD); } + + public void setOperationHasException(String message) { + this.completeOperation(this.attempts, message, PolicyResult.FAILURE_EXCEPTION); + } public boolean isOperationComplete() { // diff --git a/controlloop/common/eventmanager/src/test/java/org/onap/policy/controlloop/eventmanager/ControlLoopOperationManagerTest.java b/controlloop/common/eventmanager/src/test/java/org/onap/policy/controlloop/eventmanager/ControlLoopOperationManagerTest.java index 90f61e0c9..c5c0bc967 100644 --- a/controlloop/common/eventmanager/src/test/java/org/onap/policy/controlloop/eventmanager/ControlLoopOperationManagerTest.java +++ b/controlloop/common/eventmanager/src/test/java/org/onap/policy/controlloop/eventmanager/ControlLoopOperationManagerTest.java @@ -30,12 +30,12 @@ import java.util.HashMap; import java.util.UUID; import org.junit.Test; +import org.onap.policy.aai.util.AAIException; import org.onap.policy.appclcm.LCMRequest; import org.onap.policy.appclcm.LCMRequestWrapper; import org.onap.policy.appclcm.LCMResponse; import org.onap.policy.appclcm.LCMResponseWrapper; import org.onap.policy.controlloop.ControlLoopEventStatus; - import org.onap.policy.controlloop.VirtualControlLoopEvent; import org.onap.policy.controlloop.ControlLoopException; import org.onap.policy.controlloop.Util; @@ -171,7 +171,7 @@ public class ControlLoopOperationManagerTest { assertNotNull(manager.getOperationResult()); assertTrue(manager.getOperationResult().equals(PolicyResult.FAILURE_RETRIES)); assertTrue(manager.getHistory().size() == 2); - } catch (ControlLoopException e) { + } catch (ControlLoopException | AAIException e) { fail(e.getMessage()); } } @@ -253,7 +253,7 @@ public class ControlLoopOperationManagerTest { assertFalse(manager.isOperationRunning()); assertTrue(manager.getHistory().size() == 1); assertTrue(manager.getOperationResult().equals(PolicyResult.FAILURE_TIMEOUT)); - } catch (ControlLoopException e) { + } catch (ControlLoopException | AAIException e) { fail(e.getMessage()); } } diff --git a/controlloop/common/model-impl/aai/src/main/java/org/onap/policy/aai/AAIManager.java b/controlloop/common/model-impl/aai/src/main/java/org/onap/policy/aai/AAIManager.java index e373c1200..b295a0635 100644 --- a/controlloop/common/model-impl/aai/src/main/java/org/onap/policy/aai/AAIManager.java +++ b/controlloop/common/model-impl/aai/src/main/java/org/onap/policy/aai/AAIManager.java @@ -56,7 +56,7 @@ public final class AAIManager { logger.info(url); logger.info(httpDetails.a.toString()); logger.info(httpDetails.b); - if (httpDetails.a == 200) { + if (httpDetails.b != null) { try { AAINQResponse response = Serialization.gsonPretty.fromJson(httpDetails.b, AAINQResponse.class); return response; @@ -64,7 +64,6 @@ public final class AAIManager { logger.error("postQuery threw: ", e); } } - return null; } diff --git a/controlloop/common/model-impl/aai/src/main/java/org/onap/policy/aai/AAINQRequestError.java b/controlloop/common/model-impl/aai/src/main/java/org/onap/policy/aai/AAINQRequestError.java new file mode 100644 index 000000000..f6439cc4a --- /dev/null +++ b/controlloop/common/model-impl/aai/src/main/java/org/onap/policy/aai/AAINQRequestError.java @@ -0,0 +1,33 @@ +/*- + * ============LICENSE_START======================================================= + * aai + * ================================================================================ + * 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.aai; + +import java.io.Serializable; + +import com.google.gson.annotations.SerializedName; + +public class AAINQRequestError implements Serializable { + + private static final long serialVersionUID = -7742674155387022932L; + + @SerializedName("serviceException") + public AAINQServiceException serviceException; +} diff --git a/controlloop/common/model-impl/aai/src/main/java/org/onap/policy/aai/AAINQResponse.java b/controlloop/common/model-impl/aai/src/main/java/org/onap/policy/aai/AAINQResponse.java index 09f983094..527a12089 100644 --- a/controlloop/common/model-impl/aai/src/main/java/org/onap/policy/aai/AAINQResponse.java +++ b/controlloop/common/model-impl/aai/src/main/java/org/onap/policy/aai/AAINQResponse.java @@ -36,6 +36,9 @@ public class AAINQResponse implements Serializable { @SerializedName("inventory-response-item") public List inventoryResponseItems = new LinkedList<>(); + + @SerializedName("requestError") + public AAINQRequestError requestError; public AAINQResponse() { } diff --git a/controlloop/common/model-impl/aai/src/main/java/org/onap/policy/aai/AAINQServiceException.java b/controlloop/common/model-impl/aai/src/main/java/org/onap/policy/aai/AAINQServiceException.java new file mode 100644 index 000000000..64d407de4 --- /dev/null +++ b/controlloop/common/model-impl/aai/src/main/java/org/onap/policy/aai/AAINQServiceException.java @@ -0,0 +1,39 @@ +/*- + * ============LICENSE_START======================================================= + * aai + * ================================================================================ + * 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.aai; + +import java.io.Serializable; + +import com.google.gson.annotations.SerializedName; + +public class AAINQServiceException implements Serializable { + + private static final long serialVersionUID = 2858343404484338546L; + + @SerializedName("messageId") + public String messageId; + + @SerializedName("text") + public String text; + + @SerializedName("variables") + public String[] variables; +} diff --git a/controlloop/common/model-impl/aai/src/main/java/org/onap/policy/aai/util/AAIException.java b/controlloop/common/model-impl/aai/src/main/java/org/onap/policy/aai/util/AAIException.java new file mode 100644 index 000000000..7e65ece22 --- /dev/null +++ b/controlloop/common/model-impl/aai/src/main/java/org/onap/policy/aai/util/AAIException.java @@ -0,0 +1,48 @@ +/*- + * ============LICENSE_START======================================================= + * aai + * ================================================================================ + * 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.aai.util; + +public class AAIException extends Exception { + + private static final long serialVersionUID = 9220983727706207465L; + + public AAIException() { + super(); + } + + public AAIException(String message, Throwable cause, boolean enableSuppression, + boolean writableStackTrace) { + super(message, cause, enableSuppression, writableStackTrace); + } + + public AAIException(String message, Throwable cause) { + super(message, cause); + } + + public AAIException(String message) { + super(message); + } + + public AAIException(Throwable cause) { + super(cause); + } + +} diff --git a/controlloop/common/simulators/src/main/java/org/onap/policy/simulators/AaiSimulatorJaxRs.java b/controlloop/common/simulators/src/main/java/org/onap/policy/simulators/AaiSimulatorJaxRs.java index 5eac5cc51..4075fda06 100644 --- a/controlloop/common/simulators/src/main/java/org/onap/policy/simulators/AaiSimulatorJaxRs.java +++ b/controlloop/common/simulators/src/main/java/org/onap/policy/simulators/AaiSimulatorJaxRs.java @@ -59,7 +59,12 @@ public class AaiSimulatorJaxRs { else { String vnfID = request.instanceFilters.instanceFilter.get(0).get("generic-vnf").get("vnf-id"); - return "{\"inventory-response-item\": [{\"model-name\": \"service-instance\",\"generic-vnf\": {\"vnf-id\": \""+ vnfID + "\",\"vnf-name\": \"ZRDM2MMEX39\",\"vnf-type\": \"vMME Svc Jul 14/vMME VF Jul 14 1\",\"service-id\": \"a9a77d5a-123e-4ca2-9eb9-0b015d2ee0fb\",\"orchestration-status\": \"active\",\"in-maint\": false,\"is-closed-loop-disabled\": false,\"resource-version\": \"1503082370097\",\"model-invariant-id\": \"82194af1-3c2c-485a-8f44-420e22a9eaa4\",\"model-version-id\": \"46b92144-923a-4d20-b85a-3cbd847668a9\"},\"extra-properties\": {},\"inventory-response-items\": {\"inventory-response-item\": [{\"model-name\": \"service-instance\",\"service-instance\": {\"service-instance-id\": \"37b8cdb7-94eb-468f-a0c2-4e3c3546578e\",\"service-instance-name\": \"Changed Service Instance NAME\",\"model-invariant-id\": \"82194af1-3c2c-485a-8f44-420e22a9eaa4\",\"model-version-id\": \"46b92144-923a-4d20-b85a-3cbd847668a9\",\"resource-version\": \"1503082993532\",\"orchestration-status\": \"Active\"},\"extra-properties\": {},\"inventory-response-items\": {\"inventory-response-item\": [{\"model-name\": \"pnf\",\"generic-vnf\": {\"vnf-id\": \"jimmy-test\",\"vnf-name\": \"jimmy-test-vnf\",\"vnf-type\": \"vMME Svc Jul 14/vMME VF Jul 14 1\",\"service-id\": \"a9a77d5a-123e-4ca2-9eb9-0b015d2ee0fb\",\"orchestration-status\": \"active\",\"in-maint\": false,\"is-closed-loop-disabled\": false,\"resource-version\": \"1504013830207\",\"model-invariant-id\": \"862b25a1-262a-4961-bdaa-cdc55d69785a\",\"model-version-id\": \"e9f1fa7d-c839-418a-9601-03dc0d2ad687\"},\"extra-properties\": {}},{\"model-name\": \"service-instance\",\"generic-vnf\": {\"vnf-id\": \"jimmy-test-vnf2\",\"vnf-name\": \"jimmy-test-vnf2-named\",\"vnf-type\": \"vMME Svc Jul 14/vMME VF Jul 14 1\",\"service-id\": \"a9a77d5a-123e-4ca2-9eb9-0b015d2ee0fb\",\"orchestration-status\": \"active\",\"in-maint\": false,\"is-closed-loop-disabled\": false,\"resource-version\": \"1504014833841\",\"model-invariant-id\": \"Eace933104d443b496b8.nodes.heat.vpg\",\"model-version-id\": \"46b92144-923a-4d20-b85a-3cbd847668a9\"},\"extra-properties\": {}}]}}]}}]}"; + if ("error".equals(vnfID)) { + return "{\"requestError\":{\"serviceException\":{\"messageId\":\"SVC3001\",\"text\":\"Resource not found for %1 using id %2 (msg=%3) (ec=%4)\",\"variables\":[\"POST Search\",\"getNamedQueryResponse\",\"Node Not Found:No Node of type generic-vnf found for properties\",\"ERR.5.4.6114\"]}}}"; + } + else { + return "{\"inventory-response-item\": [{\"model-name\": \"service-instance\",\"generic-vnf\": {\"vnf-id\": \""+ vnfID + "\",\"vnf-name\": \"ZRDM2MMEX39\",\"vnf-type\": \"vMME Svc Jul 14/vMME VF Jul 14 1\",\"service-id\": \"a9a77d5a-123e-4ca2-9eb9-0b015d2ee0fb\",\"orchestration-status\": \"active\",\"in-maint\": false,\"is-closed-loop-disabled\": false,\"resource-version\": \"1503082370097\",\"model-invariant-id\": \"82194af1-3c2c-485a-8f44-420e22a9eaa4\",\"model-version-id\": \"46b92144-923a-4d20-b85a-3cbd847668a9\"},\"extra-properties\": {},\"inventory-response-items\": {\"inventory-response-item\": [{\"model-name\": \"service-instance\",\"service-instance\": {\"service-instance-id\": \"37b8cdb7-94eb-468f-a0c2-4e3c3546578e\",\"service-instance-name\": \"Changed Service Instance NAME\",\"model-invariant-id\": \"82194af1-3c2c-485a-8f44-420e22a9eaa4\",\"model-version-id\": \"46b92144-923a-4d20-b85a-3cbd847668a9\",\"resource-version\": \"1503082993532\",\"orchestration-status\": \"Active\"},\"extra-properties\": {},\"inventory-response-items\": {\"inventory-response-item\": [{\"model-name\": \"pnf\",\"generic-vnf\": {\"vnf-id\": \"jimmy-test\",\"vnf-name\": \"jimmy-test-vnf\",\"vnf-type\": \"vMME Svc Jul 14/vMME VF Jul 14 1\",\"service-id\": \"a9a77d5a-123e-4ca2-9eb9-0b015d2ee0fb\",\"orchestration-status\": \"active\",\"in-maint\": false,\"is-closed-loop-disabled\": false,\"resource-version\": \"1504013830207\",\"model-invariant-id\": \"862b25a1-262a-4961-bdaa-cdc55d69785a\",\"model-version-id\": \"e9f1fa7d-c839-418a-9601-03dc0d2ad687\"},\"extra-properties\": {}},{\"model-name\": \"service-instance\",\"generic-vnf\": {\"vnf-id\": \"jimmy-test-vnf2\",\"vnf-name\": \"jimmy-test-vnf2-named\",\"vnf-type\": \"vMME Svc Jul 14/vMME VF Jul 14 1\",\"service-id\": \"a9a77d5a-123e-4ca2-9eb9-0b015d2ee0fb\",\"orchestration-status\": \"active\",\"in-maint\": false,\"is-closed-loop-disabled\": false,\"resource-version\": \"1504014833841\",\"model-invariant-id\": \"Eace933104d443b496b8.nodes.heat.vpg\",\"model-version-id\": \"46b92144-923a-4d20-b85a-3cbd847668a9\"},\"extra-properties\": {}}]}}]}}]}"; + } } } diff --git a/controlloop/templates/archetype-cl-amsterdam/src/main/resources/archetype-resources/src/main/resources/__closedLoopControlName__.drl b/controlloop/templates/archetype-cl-amsterdam/src/main/resources/archetype-resources/src/main/resources/__closedLoopControlName__.drl index 3d6d89c69..705bbcd25 100644 --- a/controlloop/templates/archetype-cl-amsterdam/src/main/resources/archetype-resources/src/main/resources/__closedLoopControlName__.drl +++ b/controlloop/templates/archetype-cl-amsterdam/src/main/resources/archetype-resources/src/main/resources/__closedLoopControlName__.drl @@ -32,6 +32,7 @@ import org.onap.policy.controlloop.eventmanager.ControlLoopEventManager; import org.onap.policy.controlloop.eventmanager.ControlLoopEventManager.NEW_EVENT_STATUS; import org.onap.policy.controlloop.eventmanager.ControlLoopOperationManager; import org.onap.policy.controlloop.actor.so.SOActorServiceProvider; +import org.onap.policy.aai.util.AAIException; import org.onap.policy.appc.Request; import org.onap.policy.appc.Response; import org.onap.policy.appc.CommonHeader; @@ -507,6 +508,7 @@ rule "${policyName}.EVENT.MANAGER.OPERATION.LOCKED.GUARD_PERMITTED" $manager : ControlLoopEventManager( closedLoopControlName == $event.closedLoopControlName, requestID == $event.requestID ) $operation : ControlLoopOperationManager( onset.closedLoopControlName == $event.closedLoopControlName, onset.requestID == $event.requestID, "Permit".equalsIgnoreCase(getGuardApprovalStatus()) ) $lock : TargetLock (requestID == $event.requestID) + $opTimer : OperationTimer( closedLoopControlName == $event.closedLoopControlName, requestID == $event.requestID.toString() ) then Logger logger = LoggerFactory.getLogger(drools.getRule().getPackage()); @@ -514,9 +516,23 @@ rule "${policyName}.EVENT.MANAGER.OPERATION.LOCKED.GUARD_PERMITTED" $params.getClosedLoopControlName(), drools.getRule().getName(), $event, $manager, $operation, $lock); - Object request = $operation.startOperation($event); - - if (request != null) { + Object request = null; + boolean caughtException = false; + try { + request = $operation.startOperation($event); + } + catch (AAIException e) { + //We got an exception, retract everything for this current operation + $operation.setOperationHasException(e.getMessage()); + retract($opTimer); + retract($operation); + caughtException = true; + } + //Having the modify statement in the catch clause doesn't work for whatever reason + if (caughtException) { + modify($manager) {finishOperation($operation)}; + } + else if (request != null) { logger.debug("{}: {}: starting operation ..", $params.getClosedLoopControlName(), drools.getRule().getName()); // 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 cef39b5e8..6424d02b6 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 @@ -35,6 +35,7 @@ import java.util.UUID; import org.junit.AfterClass; import org.junit.BeforeClass; +import org.junit.Ignore; import org.junit.Test; import org.kie.api.runtime.KieSession; import org.kie.api.runtime.rule.FactHandle; @@ -170,6 +171,72 @@ public class VFWControlLoopTest implements TopicListener { kieSession.dispose(); } + @Test + public void namedQueryFailTest() { + + /* + * Start the kie session + */ + try { + kieSession = startSession("../archetype-cl-amsterdam/src/main/resources/archetype-resources/src/main/resources/__closedLoopControlName__.drl", + "src/test/resources/yaml/policy_ControlLoop_vFW.yaml", + "service=ServiceDemo;resource=Res1Demo;type=operational", + "CL_vFW", + "org.onap.closed_loop.ServiceDemo:VNFS:1.0.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 + */ + for (TopicSink sink : noopTopics) { + assertTrue(sink.start()); + sink.register(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, "error"); + + try { + kieSession.fireUntilHalt(); + } + catch (Exception e) { + e.printStackTrace(); + logger.warn(e.toString()); + fail(e.getMessage()); + } + + + /* + * 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(); + } + /** * This method will start a kie session and instantiate * the Policy Engine. @@ -279,7 +346,13 @@ public class VFWControlLoopTest implements TopicListener { } else if (policyName.endsWith("EVENT.MANAGER")) { logger.debug("Rule Fired: " + notification.policyName); - assertTrue(ControlLoopNotificationType.FINAL_SUCCESS.equals(notification.notification)); + if ("error".equals(notification.AAI.get("generic-vnf.vnf-id"))) { + assertTrue(ControlLoopNotificationType.FINAL_FAILURE.equals(notification.notification)); + assertEquals("Exception in processing closed loop", notification.message); + } + else { + assertTrue(ControlLoopNotificationType.FINAL_SUCCESS.equals(notification.notification)); + } kieSession.halt(); } else if (policyName.endsWith("EVENT.MANAGER.TIMEOUT")) { @@ -326,6 +399,27 @@ public class VFWControlLoopTest implements TopicListener { kieSession.insert(event); } + /** + * 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, String vnfId) { + 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", vnfId); + event.closedLoopEventStatus = status; + kieSession.insert(event); + } + /** * This method will dump all the facts in the working memory. * -- cgit 1.2.3-korg