aboutsummaryrefslogtreecommitdiffstats
path: root/controlloop/common/eventmanager/src/main/java
diff options
context:
space:
mode:
Diffstat (limited to 'controlloop/common/eventmanager/src/main/java')
-rw-r--r--controlloop/common/eventmanager/src/main/java/org/onap/policy/controlloop/ControlLoopException.java36
-rw-r--r--controlloop/common/eventmanager/src/main/java/org/onap/policy/controlloop/ControlLoopLogger.java49
-rw-r--r--controlloop/common/eventmanager/src/main/java/org/onap/policy/controlloop/ControlLoopPublisher.java42
-rw-r--r--controlloop/common/eventmanager/src/main/java/org/onap/policy/controlloop/eventmanager/ControlLoopEventManager.java1431
-rw-r--r--controlloop/common/eventmanager/src/main/java/org/onap/policy/controlloop/eventmanager/ControlLoopOperationManager.java1504
-rw-r--r--controlloop/common/eventmanager/src/main/java/org/onap/policy/controlloop/eventmanager/OperationsHistoryDbEntry.java195
-rw-r--r--controlloop/common/eventmanager/src/main/java/org/onap/policy/controlloop/impl/ControlLoopLoggerStdOutImpl.java36
-rw-r--r--controlloop/common/eventmanager/src/main/java/org/onap/policy/controlloop/impl/ControlLoopPublisherJUnitImpl.java11
-rw-r--r--controlloop/common/eventmanager/src/main/java/org/onap/policy/controlloop/processor/ControlLoopProcessor.java152
-rw-r--r--controlloop/common/eventmanager/src/main/java/org/onap/policy/drools/PolicyEngine.java5
-rw-r--r--controlloop/common/eventmanager/src/main/java/org/onap/policy/drools/PolicyEngineListener.java11
-rw-r--r--controlloop/common/eventmanager/src/main/java/org/onap/policy/drools/impl/PolicyEngineJUnitImpl.java203
12 files changed, 1959 insertions, 1716 deletions
diff --git a/controlloop/common/eventmanager/src/main/java/org/onap/policy/controlloop/ControlLoopException.java b/controlloop/common/eventmanager/src/main/java/org/onap/policy/controlloop/ControlLoopException.java
index 3f19fdcaf..e6ccc18af 100644
--- a/controlloop/common/eventmanager/src/main/java/org/onap/policy/controlloop/ControlLoopException.java
+++ b/controlloop/common/eventmanager/src/main/java/org/onap/policy/controlloop/ControlLoopException.java
@@ -2,7 +2,7 @@
* ============LICENSE_START=======================================================
* controlloop
* ================================================================================
- * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * Copyright (C) 2017-2018 AT&T Intellectual Property. All rights reserved.
* ================================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -21,26 +21,26 @@
package org.onap.policy.controlloop;
public class ControlLoopException extends Exception {
- private static final long serialVersionUID = 6400725747325923701L;
+ private static final long serialVersionUID = 6400725747325923701L;
- public ControlLoopException() {
- super();
- }
+ public ControlLoopException() {
+ super();
+ }
- public ControlLoopException(String message, Throwable cause, boolean enableSuppression,
- boolean writableStackTrace) {
- super(message, cause, enableSuppression, writableStackTrace);
- }
+ public ControlLoopException(String message, Throwable cause, boolean enableSuppression,
+ boolean writableStackTrace) {
+ super(message, cause, enableSuppression, writableStackTrace);
+ }
- public ControlLoopException(String message, Throwable cause) {
- super(message, cause);
- }
+ public ControlLoopException(String message, Throwable cause) {
+ super(message, cause);
+ }
- public ControlLoopException(String message) {
- super(message);
- }
+ public ControlLoopException(String message) {
+ super(message);
+ }
- public ControlLoopException(Throwable cause) {
- super(cause);
- }
+ public ControlLoopException(Throwable cause) {
+ super(cause);
+ }
}
diff --git a/controlloop/common/eventmanager/src/main/java/org/onap/policy/controlloop/ControlLoopLogger.java b/controlloop/common/eventmanager/src/main/java/org/onap/policy/controlloop/ControlLoopLogger.java
index 437920cfb..4bf500704 100644
--- a/controlloop/common/eventmanager/src/main/java/org/onap/policy/controlloop/ControlLoopLogger.java
+++ b/controlloop/common/eventmanager/src/main/java/org/onap/policy/controlloop/ControlLoopLogger.java
@@ -2,7 +2,7 @@
* ============LICENSE_START=======================================================
* controlloop
* ================================================================================
- * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * Copyright (C) 2017-2018 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.
@@ -26,24 +26,31 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public interface ControlLoopLogger {
-
- public void info(String... parameters);
-
- public void metrics(String... msgs);
-
- public void metrics(Object obj);
-
- public static class Factory {
- private static final Logger logger = LoggerFactory.getLogger(Factory.class);
-
- public ControlLoopLogger buildLogger(String className) throws ControlLoopException {
- try {
- Constructor<?> constr = Class.forName(className).getConstructor();
- return (ControlLoopLogger) constr.newInstance();
- } catch (Exception e) {
- logger.error("buildLogger threw: ", e);
- throw new ControlLoopException("Cannot load class " + className + " as a control loop logger");
- }
- }
- }
+
+ public void info(String... parameters);
+
+ public void metrics(String... msgs);
+
+ public void metrics(Object obj);
+
+ public static class Factory {
+ private static final Logger logger = LoggerFactory.getLogger(Factory.class);
+
+ /**
+ * Construct an instance.
+ *
+ * @param className name of the class
+ * @return the instance
+ * @throws ControlLoopException if an error occurs
+ */
+ public ControlLoopLogger buildLogger(String className) throws ControlLoopException {
+ try {
+ Constructor<?> constr = Class.forName(className).getConstructor();
+ return (ControlLoopLogger) constr.newInstance();
+ } catch (Exception e) {
+ logger.error("buildLogger threw: ", e);
+ throw new ControlLoopException("Cannot load class " + className + " as a control loop logger");
+ }
+ }
+ }
}
diff --git a/controlloop/common/eventmanager/src/main/java/org/onap/policy/controlloop/ControlLoopPublisher.java b/controlloop/common/eventmanager/src/main/java/org/onap/policy/controlloop/ControlLoopPublisher.java
index 3d31c413b..2b1fbefc7 100644
--- a/controlloop/common/eventmanager/src/main/java/org/onap/policy/controlloop/ControlLoopPublisher.java
+++ b/controlloop/common/eventmanager/src/main/java/org/onap/policy/controlloop/ControlLoopPublisher.java
@@ -2,7 +2,7 @@
* ============LICENSE_START=======================================================
* controlloop
* ================================================================================
- * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * Copyright (C) 2017-2018 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.
@@ -26,21 +26,27 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public interface ControlLoopPublisher {
-
- public void publish(Object object);
-
- public static class Factory {
- private static final Logger logger = LoggerFactory.getLogger(Factory.class);
-
-
- public ControlLoopPublisher buildLogger(String className) throws ControlLoopException {
- try {
- Constructor<?> constr = Class.forName(className).getConstructor();
- return (ControlLoopPublisher) constr.newInstance();
- } catch (Exception e) {
- logger.error("ControlLoopPublisher.buildLogger threw: ", e);
- throw new ControlLoopException("Cannot load class " + className + " as a control loop publisher");
- }
- }
- }
+
+ public void publish(Object object);
+
+ public static class Factory {
+ private static final Logger logger = LoggerFactory.getLogger(Factory.class);
+
+ /**
+ * Construct an instance.
+ *
+ * @param className name of the class
+ * @return the instance
+ * @throws ControlLoopException if an error occurs
+ */
+ public ControlLoopPublisher buildLogger(String className) throws ControlLoopException {
+ try {
+ Constructor<?> constr = Class.forName(className).getConstructor();
+ return (ControlLoopPublisher) constr.newInstance();
+ } catch (Exception e) {
+ logger.error("ControlLoopPublisher.buildLogger threw: ", e);
+ throw new ControlLoopException("Cannot load class " + className + " as a control loop publisher");
+ }
+ }
+ }
}
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 1d1451461..224e33559 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
@@ -41,682 +41,779 @@ import org.onap.policy.controlloop.VirtualControlLoopNotification;
import org.onap.policy.controlloop.policy.FinalResult;
import org.onap.policy.controlloop.policy.Policy;
import org.onap.policy.controlloop.processor.ControlLoopProcessor;
+import org.onap.policy.drools.system.PolicyEngine;
import org.onap.policy.guard.GuardResult;
import org.onap.policy.guard.LockCallback;
import org.onap.policy.guard.PolicyGuard;
import org.onap.policy.guard.PolicyGuard.LockResult;
import org.onap.policy.guard.TargetLock;
import org.onap.policy.rest.RESTManager;
-import org.onap.policy.drools.system.PolicyEngine;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class ControlLoopEventManager implements LockCallback, Serializable {
- private static final String VM_NAME = "VM_NAME";
- private static final String VNF_NAME = "VNF_NAME";
- private static final String GENERIC_VNF_VNF_ID = "generic-vnf.vnf-id";
- private static final String GENERIC_VNF_VNF_NAME = "generic-vnf.vnf-name";
- private static final String VSERVER_VSERVER_NAME = "vserver.vserver-name";
- private static final String GENERIC_VNF_IS_CLOSED_LOOP_DISABLED = "generic-vnf.is-closed-loop-disabled";
- private static final String VSERVER_IS_CLOSED_LOOP_DISABLED = "vserver.is-closed-loop-disabled";
-
- private static final Logger logger = LoggerFactory.getLogger(ControlLoopEventManager.class);
-
- private static final long serialVersionUID = -1216568161322872641L;
- public final String closedLoopControlName;
- public final UUID requestID;
-
- private String controlLoopResult;
- private transient ControlLoopProcessor processor = null;
- private VirtualControlLoopEvent onset;
- private Integer numOnsets = 0;
- private Integer numAbatements = 0;
- private VirtualControlLoopEvent abatement;
- private FinalResult controlLoopTimedOut = null;
-
- private boolean isActivated = false;
- private LinkedList<ControlLoopOperation> controlLoopHistory = new LinkedList<>();
- private ControlLoopOperationManager currentOperation = null;
- private transient TargetLock targetLock = null;
- private AAIGETVnfResponse vnfResponse = null;
- private AAIGETVserverResponse vserverResponse = null;
- private static String aaiHostURL;
- private static String aaiUser;
- private static String aaiPassword;
-
- private static Collection<String> requiredAAIKeys = new ArrayList<>();
- static {
- requiredAAIKeys.add("AICVServerSelfLink");
- requiredAAIKeys.add("AICIdentity");
- requiredAAIKeys.add("is_closed_loop_disabled");
- requiredAAIKeys.add(VM_NAME);
- }
-
- public ControlLoopEventManager(String closedLoopControlName, UUID requestID) {
- this.closedLoopControlName = closedLoopControlName;
- this.requestID = requestID;
- }
-
- public String getControlLoopResult() {
- return controlLoopResult;
- }
-
- public void setControlLoopResult(String controlLoopResult) {
- this.controlLoopResult = controlLoopResult;
- }
-
- public Integer getNumOnsets() {
- return numOnsets;
- }
-
- public void setNumOnsets(Integer numOnsets) {
- this.numOnsets = numOnsets;
- }
-
- public Integer getNumAbatements() {
- return numAbatements;
- }
-
- public void setNumAbatements(Integer numAbatements) {
- this.numAbatements = numAbatements;
- }
-
- public boolean isActivated() {
- return isActivated;
- }
-
- public void setActivated(boolean isActivated) {
- this.isActivated = isActivated;
- }
-
- public VirtualControlLoopEvent getOnsetEvent() {
- return this.onset;
- }
-
- public VirtualControlLoopEvent getAbatementEvent() {
- return this.abatement;
- }
-
- public ControlLoopProcessor getProcessor() {
- return this.processor;
- }
-
- public VirtualControlLoopNotification activate(VirtualControlLoopEvent event) {
- VirtualControlLoopNotification notification = new VirtualControlLoopNotification(event);
- try {
- //
- // This method should ONLY be called ONCE
- //
- if (this.isActivated) {
- throw new ControlLoopException("ControlLoopEventManager has already been activated.");
- }
- //
- // Syntax check the event
- //
- checkEventSyntax(event);
-
- //
- // At this point we are good to go with this event
- //
- this.onset = event;
- this.numOnsets = 1;
- //
- notification.setNotification(ControlLoopNotificationType.ACTIVE);
- //
- // Set ourselves as active
- //
- this.isActivated = true;
- } catch (ControlLoopException e) {
- logger.error("{}: activate by event threw: ", this, e);
- notification.setNotification(ControlLoopNotificationType.REJECTED);
- notification.setMessage(e.getMessage());
- }
- return notification;
- }
-
- public VirtualControlLoopNotification activate(String yamlSpecification, VirtualControlLoopEvent event) {
- VirtualControlLoopNotification notification = new VirtualControlLoopNotification(event);
- try {
- //
- // This method should ONLY be called ONCE
- //
- if (this.isActivated) {
- throw new ControlLoopException("ControlLoopEventManager has already been activated.");
- }
- //
- // Syntax check the event
- //
- checkEventSyntax(event);
-
- //
- // Check the YAML
- //
- if (yamlSpecification == null || yamlSpecification.length() < 1) {
- throw new ControlLoopException("yaml specification is null or 0 length");
- }
- } catch (ControlLoopException e) {
- logger.error("{}: activate by YAML specification and event threw: ",this, e);
- notification.setNotification(ControlLoopNotificationType.REJECTED);
- notification.setMessage(e.getMessage());
- return notification;
- }
-
- String decodedYaml = null;
- try {
- decodedYaml = URLDecoder.decode(yamlSpecification, "UTF-8");
- if (decodedYaml != null && decodedYaml.length() > 0) {
- yamlSpecification = decodedYaml;
- }
- } catch (UnsupportedEncodingException e) {
- logger.error("{}: YAML decode in activate by YAML specification and event threw: ", this, e);
- notification.setNotification(ControlLoopNotificationType.REJECTED);
- notification.setMessage(e.getMessage());
- return notification;
- }
-
- try {
- //
- // Parse the YAML specification
- //
- this.processor = new ControlLoopProcessor(yamlSpecification);
-
- //
- // At this point we are good to go with this event
- //
- this.onset = event;
- this.numOnsets = 1;
- //
- //
- //
- notification.setNotification(ControlLoopNotificationType.ACTIVE);
- //
- // Set ourselves as active
- //
- this.isActivated = true;
- } catch (ControlLoopException e) {
- logger.error("{}: activate by YAML specification and event threw: ",this, e);
- notification.setNotification(ControlLoopNotificationType.REJECTED);
- notification.setMessage(e.getMessage());
- }
- return notification;
- }
-
- public VirtualControlLoopNotification isControlLoopFinal() throws ControlLoopException {
- //
- // Check if they activated us
- //
- if (!this.isActivated) {
- throw new ControlLoopException("ControlLoopEventManager MUST be activated first.");
- }
- //
- // Make sure we are expecting this call.
- //
- if (this.onset == null) {
- throw new ControlLoopException("No onset event for ControlLoopEventManager.");
- }
- //
- // Ok, start creating the notification
- //
- VirtualControlLoopNotification notification = new VirtualControlLoopNotification(this.onset);
- //
- // Check if the overall control loop has timed out
- //
- if (this.isControlLoopTimedOut()) {
- //
- // Yes we have timed out
- //
- notification.setNotification(ControlLoopNotificationType.FINAL_FAILURE);
- notification.setMessage("Control Loop timed out");
- notification.getHistory().addAll(this.controlLoopHistory);
- return notification;
- }
- //
- // Check if the current policy is Final
- //
- FinalResult result = this.processor.checkIsCurrentPolicyFinal();
- if (result == null) {
- //
- // we are not at a final result
- //
- return null;
- }
-
- switch (result) {
- case FINAL_FAILURE_EXCEPTION:
- notification.setNotification(ControlLoopNotificationType.FINAL_FAILURE);
- notification.setMessage("Exception in processing closed loop");
- break;
- case FINAL_FAILURE:
- case FINAL_FAILURE_RETRIES:
- case FINAL_FAILURE_TIMEOUT:
- case FINAL_FAILURE_GUARD:
- notification.setNotification(ControlLoopNotificationType.FINAL_FAILURE);
- break;
- case FINAL_OPENLOOP:
- notification.setNotification(ControlLoopNotificationType.FINAL_OPENLOOP);
- break;
- case FINAL_SUCCESS:
- notification.setNotification(ControlLoopNotificationType.FINAL_SUCCESS);
- break;
- default:
- return null;
- }
- //
- // Be sure to add all the history
- //
- notification.getHistory().addAll(this.controlLoopHistory);
- return notification;
- }
-
- public ControlLoopOperationManager processControlLoop() throws ControlLoopException, AAIException {
- //
- // Check if they activated us
- //
- if (!this.isActivated) {
- throw new ControlLoopException("ControlLoopEventManager MUST be activated first.");
- }
- //
- // Make sure we are expecting this call.
- //
- if (this.onset == null) {
- throw new ControlLoopException("No onset event for ControlLoopEventManager.");
- }
- //
- // Is there a current operation?
- //
- if (this.currentOperation != null) {
- //
- // Throw an exception, or simply return the current operation?
- //
- throw new ControlLoopException("Already working an Operation, do not call this method.");
- }
- //
- // Ensure we are not FINAL
- //
- VirtualControlLoopNotification notification = this.isControlLoopFinal();
- if (notification != null) {
- //
- // This is weird, we require them to call the isControlLoopFinal() method first
- //
- // We should really abstract this and avoid throwing an exception, because it really
- // isn't an exception.
- //
- throw new ControlLoopException("Control Loop is in FINAL state, do not call this method.");
- }
- //
- // Not final so get the policy that needs to be worked on.
- //
- Policy policy = this.processor.getCurrentPolicy();
- if (policy == null) {
- throw new ControlLoopException("ControlLoopEventManager: processor came upon null Policy.");
- }
- //
- // And setup an operation
- //
- this.currentOperation = new ControlLoopOperationManager(this.onset, policy, this);
- //
- // Return it
- //
- return this.currentOperation;
- }
-
- public void finishOperation(ControlLoopOperationManager operation) throws ControlLoopException {
- //
- // Verify we have a current operation
- //
- if (this.currentOperation != null) {
- //
- // Validate they are finishing the current operation
- // PLD - this is simply comparing the policy. Do we want to equals the whole object?
- //
- if (this.currentOperation.policy.equals(operation.policy)) {
- logger.debug("Finishing {} result is {}", this.currentOperation.policy.getRecipe(), this.currentOperation.getOperationResult());
- //
- // Save history
- //
- this.controlLoopHistory.addAll(this.currentOperation.getHistory());
- //
- // Move to the next Policy
- //
- this.processor.nextPolicyForResult(this.currentOperation.getOperationResult());
- //
- // Just null this out
- //
- this.currentOperation = null;
- //
- // TODO: Release our lock
- //
- return;
- }
- logger.debug("Cannot finish current operation {} does not match given operation {}", this.currentOperation.policy, operation.policy);
- return;
- }
- throw new ControlLoopException("No operation to finish.");
- }
-
- public synchronized LockResult<GuardResult, TargetLock> lockCurrentOperation() throws ControlLoopException {
- //
- // Sanity check
- //
- if (this.currentOperation == null) {
- throw new ControlLoopException("Do not have a current operation.");
- }
- //
- // Have we acquired it already?
- //
- if (this.targetLock != null) {
- //
- // TODO: Make sure the current lock is for the same target.
- // Currently, it should be. But in the future it may not.
- //
- return new LockResult<>(GuardResult.LOCK_ACQUIRED, this.targetLock);
- } else {
- //
- // Ask the Guard
- //
- LockResult<GuardResult, TargetLock> lockResult = PolicyGuard.lockTarget(
- this.currentOperation.policy.getTarget().getType(),
- this.currentOperation.getTargetEntity(),
- this.onset.getRequestID(),
- this);
- //
- // Was it acquired?
- //
- if (lockResult.getA().equals(GuardResult.LOCK_ACQUIRED)) {
- //
- // Yes, let's save it
- //
- this.targetLock = lockResult.getB();
- }
- return lockResult;
- }
- }
-
- public synchronized TargetLock unlockCurrentOperation() {
- if (this.targetLock == null) {
- return null;
- }
- if (PolicyGuard.unlockTarget(this.targetLock)) {
- TargetLock returnLock = this.targetLock;
- this.targetLock = null;
- return returnLock;
- }
- return null;
- }
-
- public enum NEW_EVENT_STATUS {
- FIRST_ONSET,
- SUBSEQUENT_ONSET,
- FIRST_ABATEMENT,
- SUBSEQUENT_ABATEMENT,
- SYNTAX_ERROR
- ;
- }
-
- public NEW_EVENT_STATUS onNewEvent(VirtualControlLoopEvent event) throws AAIException {
- try {
- this.checkEventSyntax(event);
- if (event.getClosedLoopEventStatus() == ControlLoopEventStatus.ONSET) {
- //
- // Check if this is our original ONSET
- //
- if (event.equals(this.onset)) {
- //
- // Query A&AI if needed
- //
- queryAai(event);
-
- //
- // DO NOT retract it
- //
- return NEW_EVENT_STATUS.FIRST_ONSET;
- }
- //
- // Log that we got an onset
- //
- this.numOnsets++;
- return NEW_EVENT_STATUS.SUBSEQUENT_ONSET;
- }
- else if (event.getClosedLoopEventStatus() == ControlLoopEventStatus.ABATED) {
- //
- // Have we already got an abatement?
- //
- if (this.abatement == null) {
- //
- // Save this
- //
- this.abatement = event;
- //
- // Keep track that we received another
- //
- this.numAbatements++;
- //
- //
- //
- return NEW_EVENT_STATUS.FIRST_ABATEMENT;
- }
- else {
- //
- // Keep track that we received another
- //
- this.numAbatements++;
- //
- //
- //
- return NEW_EVENT_STATUS.SUBSEQUENT_ABATEMENT;
- }
- }
- }
- catch (ControlLoopException e) {
- logger.error("{}: onNewEvent threw: ",this, e);
- }
- return NEW_EVENT_STATUS.SYNTAX_ERROR;
- }
-
- public VirtualControlLoopNotification setControlLoopTimedOut() {
- this.controlLoopTimedOut = FinalResult.FINAL_FAILURE_TIMEOUT;
- VirtualControlLoopNotification notification = new VirtualControlLoopNotification(this.onset);
- notification.setNotification(ControlLoopNotificationType.FINAL_FAILURE);
- notification.setMessage("Control Loop timed out");
- notification.getHistory().addAll(this.controlLoopHistory);
- return notification;
- }
-
- public boolean isControlLoopTimedOut() {
- return (this.controlLoopTimedOut == FinalResult.FINAL_FAILURE_TIMEOUT);
- }
-
- public int getControlLoopTimeout(Integer defaultTimeout) {
- if (this.processor != null && this.processor.getControlLoop() != null) {
- return this.processor.getControlLoop().getTimeout();
- }
- if (defaultTimeout != null) {
- return defaultTimeout;
- }
- return 0;
- }
-
- public AAIGETVnfResponse getVnfResponse() {
- return vnfResponse;
- }
-
- public AAIGETVserverResponse getVserverResponse() {
- return vserverResponse;
- }
-
- public void checkEventSyntax(VirtualControlLoopEvent event) throws ControlLoopException {
- if (event.getClosedLoopEventStatus() == null ||
- (event.getClosedLoopEventStatus() != ControlLoopEventStatus.ONSET &&
- event.getClosedLoopEventStatus() != ControlLoopEventStatus.ABATED)) {
- throw new ControlLoopException("Invalid value in closedLoopEventStatus");
- }
- if (event.getClosedLoopControlName() == null || event.getClosedLoopControlName().length() < 1) {
- throw new ControlLoopException("No control loop name");
- }
- if (event.getRequestID() == null) {
- throw new ControlLoopException("No request ID");
- }
- if (event.getClosedLoopEventStatus() == ControlLoopEventStatus.ABATED) {
- return;
- }
- if (event.getTarget() == null || event.getTarget().length() < 1) {
- throw new ControlLoopException("No target field");
- } else if (! VM_NAME.equalsIgnoreCase(event.getTarget()) &&
- ! VNF_NAME.equalsIgnoreCase(event.getTarget()) &&
- ! VSERVER_VSERVER_NAME.equalsIgnoreCase(event.getTarget()) &&
- ! GENERIC_VNF_VNF_ID.equalsIgnoreCase(event.getTarget()) &&
- ! GENERIC_VNF_VNF_NAME.equalsIgnoreCase(event.getTarget()) ) {
- throw new ControlLoopException("target field invalid - expecting VM_NAME or VNF_NAME");
- }
- if (event.getAAI() == null) {
- throw new ControlLoopException("AAI is null");
- }
- if (event.getAAI().get(GENERIC_VNF_VNF_ID) == null && event.getAAI().get(VSERVER_VSERVER_NAME) == null &&
- event.getAAI().get(GENERIC_VNF_VNF_NAME) == null) {
- throw new ControlLoopException("generic-vnf.vnf-id or generic-vnf.vnf-name or vserver.vserver-name information missing");
- }
- }
-
- public void queryAai(VirtualControlLoopEvent event) throws AAIException {
- if ((event.getAAI().get(VSERVER_IS_CLOSED_LOOP_DISABLED) != null || event.getAAI().get(GENERIC_VNF_IS_CLOSED_LOOP_DISABLED) != null) && isClosedLoopDisabled(event)) {
- throw new AAIException("is-closed-loop-disabled is set to true on VServer or VNF");
- }
-
- try {
- if (event.getAAI().get(GENERIC_VNF_VNF_ID) != null || event.getAAI().get(GENERIC_VNF_VNF_NAME) != null) {
- vnfResponse = getAAIVnfInfo(event);
- processVNFResponse(vnfResponse, event.getAAI().get(GENERIC_VNF_VNF_ID) != null);
- }
- else if (event.getAAI().get(VSERVER_VSERVER_NAME) != null) {
- vserverResponse = getAAIVserverInfo(event);
- processVServerResponse(vserverResponse);
- }
- } catch (Exception e) {
- logger.error("Exception from queryAai: ", e);
- throw new AAIException("Exception from queryAai: " + e.toString());
- }
- }
-
- private static void processVNFResponse(AAIGETVnfResponse aaiResponse, boolean queryByVNFID) throws AAIException {
- String queryTypeString = (queryByVNFID ? "vnf-id" : "vnf-name");
-
- if (aaiResponse == null) {
- throw new AAIException("AAI Response is null (query by " + queryTypeString + ")");
- }
- if (aaiResponse.getRequestError() != null) {
- throw new AAIException("AAI Responded with a request error (query by " + queryTypeString + ")");
- }
-
- if (aaiResponse.getIsClosedLoopDisabled() != null) {
- String value = aaiResponse.getIsClosedLoopDisabled();
- if ("true".equalsIgnoreCase(value) || "T".equalsIgnoreCase(value) ||
- "yes".equalsIgnoreCase(value) || "Y".equalsIgnoreCase(value)) {
- throw new AAIException("is-closed-loop-disabled is set to true (query by " + queryTypeString + ")");
- }
- }
- }
-
- private static void processVServerResponse(AAIGETVserverResponse aaiResponse) throws AAIException {
- if (aaiResponse == null) {
- throw new AAIException("AAI Response is null (query by vserver-name)");
- }
- if (aaiResponse.getRequestError() != null) {
- throw new AAIException("AAI responded with a request error (query by vserver-name)");
- }
-
- if (aaiResponse.getIsClosedLoopDisabled() != null) {
- String value = aaiResponse.getIsClosedLoopDisabled();
- if ("true".equalsIgnoreCase(value) || "T".equalsIgnoreCase(value) ||
- "yes".equalsIgnoreCase(value) || "Y".equalsIgnoreCase(value)) {
- throw new AAIException("is-closed-loop-disabled is set to true (query by vserver-name)");
- }
- }
- }
-
- public static boolean isClosedLoopDisabled(VirtualControlLoopEvent event) {
- if ("true".equalsIgnoreCase(event.getAAI().get(VSERVER_IS_CLOSED_LOOP_DISABLED)) ||
- "T".equalsIgnoreCase(event.getAAI().get(VSERVER_IS_CLOSED_LOOP_DISABLED)) ||
- "yes".equalsIgnoreCase(event.getAAI().get(VSERVER_IS_CLOSED_LOOP_DISABLED)) ||
- "Y".equalsIgnoreCase(event.getAAI().get(VSERVER_IS_CLOSED_LOOP_DISABLED))) {
- return true;
- }
- return ("true".equalsIgnoreCase(event.getAAI().get(GENERIC_VNF_IS_CLOSED_LOOP_DISABLED)) ||
- "T".equalsIgnoreCase(event.getAAI().get(GENERIC_VNF_IS_CLOSED_LOOP_DISABLED)) ||
- "yes".equalsIgnoreCase(event.getAAI().get(GENERIC_VNF_IS_CLOSED_LOOP_DISABLED)) ||
- "Y".equalsIgnoreCase(event.getAAI().get(GENERIC_VNF_IS_CLOSED_LOOP_DISABLED)));
- }
-
- public static AAIGETVserverResponse getAAIVserverInfo(VirtualControlLoopEvent event) throws ControlLoopException {
- UUID requestID = event.getRequestID();
- AAIGETVserverResponse response = null;
- String vserverName = event.getAAI().get(VSERVER_VSERVER_NAME);
-
- try {
- if (vserverName != null) {
- aaiHostURL = PolicyEngine.manager.getEnvironmentProperty("aai.url");
- aaiUser = PolicyEngine.manager.getEnvironmentProperty("aai.username");
- aaiPassword = PolicyEngine.manager.getEnvironmentProperty("aai.password");
- String aaiGetQueryByVserver = "/aai/v11/nodes/vservers?vserver-name=";
- String url = aaiHostURL + aaiGetQueryByVserver;
- logger.info("AAI Host URL by VServer: {}", url);
- response = new AAIManager(new RESTManager()).getQueryByVserverName(url, aaiUser, aaiPassword, requestID, vserverName);
- }
- } catch (Exception e) {
- logger.error("getAAIVserverInfo exception: ", e);
- throw new ControlLoopException("Exception in getAAIVserverInfo: ", e);
- }
-
- return response;
- }
-
- public static AAIGETVnfResponse getAAIVnfInfo(VirtualControlLoopEvent event) throws ControlLoopException {
- UUID requestID = event.getRequestID();
- AAIGETVnfResponse response = null;
- String vnfName = event.getAAI().get(GENERIC_VNF_VNF_NAME);
- String vnfID = event.getAAI().get(GENERIC_VNF_VNF_ID);
-
- aaiHostURL = PolicyEngine.manager.getEnvironmentProperty("aai.url");
- aaiUser = PolicyEngine.manager.getEnvironmentProperty("aai.username");
- aaiPassword = PolicyEngine.manager.getEnvironmentProperty("aai.password");
-
- try {
- if (vnfName != null) {
- String aaiGetQueryByVnfName = "/aai/v11/network/generic-vnfs/generic-vnf?vnf-name=";
- String url = aaiHostURL + aaiGetQueryByVnfName;
- logger.info("AAI Host URL by VNF name: {}", url);
- response = new AAIManager(new RESTManager()).getQueryByVnfName(url, aaiUser, aaiPassword, requestID, vnfName);
- } else if (vnfID != null) {
- String aaiGetQueryByVnfID = "/aai/v11/network/generic-vnfs/generic-vnf/";
- String url = aaiHostURL + aaiGetQueryByVnfID;
- logger.info("AAI Host URL by VNF ID: {}", url);
- response = new AAIManager(new RESTManager()).getQueryByVnfID(url, aaiUser, aaiPassword, requestID, vnfID);
- }
- } catch (Exception e) {
- logger.error("getAAIVnfInfo exception: ", e);
- throw new ControlLoopException("Exception in getAAIVnfInfo: ", e);
- }
-
- return response;
- }
-
- @Override
- public boolean isActive() {
- // TODO
- return true;
- }
-
- @Override
- public boolean releaseLock() {
- // TODO
- return false;
- }
-
- @Override
- public String toString() {
- return "ControlLoopEventManager [closedLoopControlName=" + closedLoopControlName + ", requestID=" + requestID
- + ", processor=" + processor + ", onset=" + (onset != null ? onset.getRequestID() : "null") + ", numOnsets=" + numOnsets + ", numAbatements="
- + numAbatements + ", isActivated="
- + isActivated + ", currentOperation=" + currentOperation + ", targetLock=" + targetLock + "]";
- }
+ private static final String VM_NAME = "VM_NAME";
+ private static final String VNF_NAME = "VNF_NAME";
+ private static final String GENERIC_VNF_VNF_ID = "generic-vnf.vnf-id";
+ private static final String GENERIC_VNF_VNF_NAME = "generic-vnf.vnf-name";
+ private static final String VSERVER_VSERVER_NAME = "vserver.vserver-name";
+ private static final String GENERIC_VNF_IS_CLOSED_LOOP_DISABLED = "generic-vnf.is-closed-loop-disabled";
+ private static final String VSERVER_IS_CLOSED_LOOP_DISABLED = "vserver.is-closed-loop-disabled";
+
+ private static final Logger logger = LoggerFactory.getLogger(ControlLoopEventManager.class);
+
+ private static final long serialVersionUID = -1216568161322872641L;
+ public final String closedLoopControlName;
+ public final UUID requestID;
+
+ private String controlLoopResult;
+ private transient ControlLoopProcessor processor = null;
+ private VirtualControlLoopEvent onset;
+ private Integer numOnsets = 0;
+ private Integer numAbatements = 0;
+ private VirtualControlLoopEvent abatement;
+ private FinalResult controlLoopTimedOut = null;
+
+ private boolean isActivated = false;
+ private LinkedList<ControlLoopOperation> controlLoopHistory = new LinkedList<>();
+ private ControlLoopOperationManager currentOperation = null;
+ private transient TargetLock targetLock = null;
+ private AAIGETVnfResponse vnfResponse = null;
+ private AAIGETVserverResponse vserverResponse = null;
+ private static String aaiHostURL;
+ private static String aaiUser;
+ private static String aaiPassword;
+
+ private static Collection<String> requiredAAIKeys = new ArrayList<>();
+
+ static {
+ requiredAAIKeys.add("AICVServerSelfLink");
+ requiredAAIKeys.add("AICIdentity");
+ requiredAAIKeys.add("is_closed_loop_disabled");
+ requiredAAIKeys.add(VM_NAME);
+ }
+
+ public ControlLoopEventManager(String closedLoopControlName, UUID requestID) {
+ this.closedLoopControlName = closedLoopControlName;
+ this.requestID = requestID;
+ }
+
+ public String getControlLoopResult() {
+ return controlLoopResult;
+ }
+
+ public void setControlLoopResult(String controlLoopResult) {
+ this.controlLoopResult = controlLoopResult;
+ }
+
+ public Integer getNumOnsets() {
+ return numOnsets;
+ }
+
+ public void setNumOnsets(Integer numOnsets) {
+ this.numOnsets = numOnsets;
+ }
+
+ public Integer getNumAbatements() {
+ return numAbatements;
+ }
+
+ public void setNumAbatements(Integer numAbatements) {
+ this.numAbatements = numAbatements;
+ }
+
+ public boolean isActivated() {
+ return isActivated;
+ }
+
+ public void setActivated(boolean isActivated) {
+ this.isActivated = isActivated;
+ }
+
+ public VirtualControlLoopEvent getOnsetEvent() {
+ return this.onset;
+ }
+
+ public VirtualControlLoopEvent getAbatementEvent() {
+ return this.abatement;
+ }
+
+ public ControlLoopProcessor getProcessor() {
+ return this.processor;
+ }
+
+ /**
+ * Activate a control loop event.
+ *
+ * @param event the event
+ * @return the VirtualControlLoopNotification
+ */
+ public VirtualControlLoopNotification activate(VirtualControlLoopEvent event) {
+ VirtualControlLoopNotification notification = new VirtualControlLoopNotification(event);
+ try {
+ //
+ // This method should ONLY be called ONCE
+ //
+ if (this.isActivated) {
+ throw new ControlLoopException("ControlLoopEventManager has already been activated.");
+ }
+ //
+ // Syntax check the event
+ //
+ checkEventSyntax(event);
+
+ //
+ // At this point we are good to go with this event
+ //
+ this.onset = event;
+ this.numOnsets = 1;
+ //
+ notification.setNotification(ControlLoopNotificationType.ACTIVE);
+ //
+ // Set ourselves as active
+ //
+ this.isActivated = true;
+ } catch (ControlLoopException e) {
+ logger.error("{}: activate by event threw: ", this, e);
+ notification.setNotification(ControlLoopNotificationType.REJECTED);
+ notification.setMessage(e.getMessage());
+ }
+ return notification;
+ }
+
+ /**
+ * Activate a control loop event.
+ *
+ * @param yamlSpecification the yaml specification
+ * @param event the event
+ * @return the VirtualControlLoopNotification
+ */
+ public VirtualControlLoopNotification activate(String yamlSpecification, VirtualControlLoopEvent event) {
+ VirtualControlLoopNotification notification = new VirtualControlLoopNotification(event);
+ try {
+ //
+ // This method should ONLY be called ONCE
+ //
+ if (this.isActivated) {
+ throw new ControlLoopException("ControlLoopEventManager has already been activated.");
+ }
+ //
+ // Syntax check the event
+ //
+ checkEventSyntax(event);
+
+ //
+ // Check the YAML
+ //
+ if (yamlSpecification == null || yamlSpecification.length() < 1) {
+ throw new ControlLoopException("yaml specification is null or 0 length");
+ }
+ } catch (ControlLoopException e) {
+ logger.error("{}: activate by YAML specification and event threw: ", this, e);
+ notification.setNotification(ControlLoopNotificationType.REJECTED);
+ notification.setMessage(e.getMessage());
+ return notification;
+ }
+
+ String decodedYaml = null;
+ try {
+ decodedYaml = URLDecoder.decode(yamlSpecification, "UTF-8");
+ if (decodedYaml != null && decodedYaml.length() > 0) {
+ yamlSpecification = decodedYaml;
+ }
+ } catch (UnsupportedEncodingException e) {
+ logger.error("{}: YAML decode in activate by YAML specification and event threw: ", this, e);
+ notification.setNotification(ControlLoopNotificationType.REJECTED);
+ notification.setMessage(e.getMessage());
+ return notification;
+ }
+
+ try {
+ //
+ // Parse the YAML specification
+ //
+ this.processor = new ControlLoopProcessor(yamlSpecification);
+
+ //
+ // At this point we are good to go with this event
+ //
+ this.onset = event;
+ this.numOnsets = 1;
+ //
+ //
+ //
+ notification.setNotification(ControlLoopNotificationType.ACTIVE);
+ //
+ // Set ourselves as active
+ //
+ this.isActivated = true;
+ } catch (ControlLoopException e) {
+ logger.error("{}: activate by YAML specification and event threw: ", this, e);
+ notification.setNotification(ControlLoopNotificationType.REJECTED);
+ notification.setMessage(e.getMessage());
+ }
+ return notification;
+ }
+
+ /**
+ * Check if the control loop is final.
+ *
+ * @return a VirtualControlLoopNotification if the control loop is final, otherwise
+ * <code>null</code> is returned
+ * @throws ControlLoopException if an error occurs
+ */
+ public VirtualControlLoopNotification isControlLoopFinal() throws ControlLoopException {
+ //
+ // Check if they activated us
+ //
+ if (!this.isActivated) {
+ throw new ControlLoopException("ControlLoopEventManager MUST be activated first.");
+ }
+ //
+ // Make sure we are expecting this call.
+ //
+ if (this.onset == null) {
+ throw new ControlLoopException("No onset event for ControlLoopEventManager.");
+ }
+ //
+ // Ok, start creating the notification
+ //
+ VirtualControlLoopNotification notification = new VirtualControlLoopNotification(this.onset);
+ //
+ // Check if the overall control loop has timed out
+ //
+ if (this.isControlLoopTimedOut()) {
+ //
+ // Yes we have timed out
+ //
+ notification.setNotification(ControlLoopNotificationType.FINAL_FAILURE);
+ notification.setMessage("Control Loop timed out");
+ notification.getHistory().addAll(this.controlLoopHistory);
+ return notification;
+ }
+ //
+ // Check if the current policy is Final
+ //
+ FinalResult result = this.processor.checkIsCurrentPolicyFinal();
+ if (result == null) {
+ //
+ // we are not at a final result
+ //
+ return null;
+ }
+
+ switch (result) {
+ case FINAL_FAILURE_EXCEPTION:
+ notification.setNotification(ControlLoopNotificationType.FINAL_FAILURE);
+ notification.setMessage("Exception in processing closed loop");
+ break;
+ case FINAL_FAILURE:
+ case FINAL_FAILURE_RETRIES:
+ case FINAL_FAILURE_TIMEOUT:
+ case FINAL_FAILURE_GUARD:
+ notification.setNotification(ControlLoopNotificationType.FINAL_FAILURE);
+ break;
+ case FINAL_OPENLOOP:
+ notification.setNotification(ControlLoopNotificationType.FINAL_OPENLOOP);
+ break;
+ case FINAL_SUCCESS:
+ notification.setNotification(ControlLoopNotificationType.FINAL_SUCCESS);
+ break;
+ default:
+ return null;
+ }
+ //
+ // Be sure to add all the history
+ //
+ notification.getHistory().addAll(this.controlLoopHistory);
+ return notification;
+ }
+
+ /**
+ * Process the control loop.
+ *
+ * @return a ControlLoopOperationManager
+ * @throws ControlLoopException if an error occurs
+ * @throws AAIException if an error occurs retrieving information from A&AI
+ */
+ public ControlLoopOperationManager processControlLoop() throws ControlLoopException, AAIException {
+ //
+ // Check if they activated us
+ //
+ if (!this.isActivated) {
+ throw new ControlLoopException("ControlLoopEventManager MUST be activated first.");
+ }
+ //
+ // Make sure we are expecting this call.
+ //
+ if (this.onset == null) {
+ throw new ControlLoopException("No onset event for ControlLoopEventManager.");
+ }
+ //
+ // Is there a current operation?
+ //
+ if (this.currentOperation != null) {
+ //
+ // Throw an exception, or simply return the current operation?
+ //
+ throw new ControlLoopException("Already working an Operation, do not call this method.");
+ }
+ //
+ // Ensure we are not FINAL
+ //
+ VirtualControlLoopNotification notification = this.isControlLoopFinal();
+ if (notification != null) {
+ //
+ // This is weird, we require them to call the isControlLoopFinal() method first
+ //
+ // We should really abstract this and avoid throwing an exception, because it really
+ // isn't an exception.
+ //
+ throw new ControlLoopException("Control Loop is in FINAL state, do not call this method.");
+ }
+ //
+ // Not final so get the policy that needs to be worked on.
+ //
+ Policy policy = this.processor.getCurrentPolicy();
+ if (policy == null) {
+ throw new ControlLoopException("ControlLoopEventManager: processor came upon null Policy.");
+ }
+ //
+ // And setup an operation
+ //
+ this.currentOperation = new ControlLoopOperationManager(this.onset, policy, this);
+ //
+ // Return it
+ //
+ return this.currentOperation;
+ }
+
+ /**
+ * Finish an operation.
+ *
+ * @param operation the operation
+ */
+ public void finishOperation(ControlLoopOperationManager operation) throws ControlLoopException {
+ //
+ // Verify we have a current operation
+ //
+ if (this.currentOperation != null) {
+ //
+ // Validate they are finishing the current operation
+ // PLD - this is simply comparing the policy. Do we want to equals the whole object?
+ //
+ if (this.currentOperation.policy.equals(operation.policy)) {
+ logger.debug("Finishing {} result is {}", this.currentOperation.policy.getRecipe(),
+ this.currentOperation.getOperationResult());
+ //
+ // Save history
+ //
+ this.controlLoopHistory.addAll(this.currentOperation.getHistory());
+ //
+ // Move to the next Policy
+ //
+ this.processor.nextPolicyForResult(this.currentOperation.getOperationResult());
+ //
+ // Just null this out
+ //
+ this.currentOperation = null;
+ //
+ // TODO: Release our lock
+ //
+ return;
+ }
+ logger.debug("Cannot finish current operation {} does not match given operation {}",
+ this.currentOperation.policy, operation.policy);
+ return;
+ }
+ throw new ControlLoopException("No operation to finish.");
+ }
+
+ /**
+ * Obtain a lock for the current operation.
+ *
+ * @return the lock result
+ * @throws ControlLoopException if an error occurs
+ */
+ public synchronized LockResult<GuardResult, TargetLock> lockCurrentOperation() throws ControlLoopException {
+ //
+ // Sanity check
+ //
+ if (this.currentOperation == null) {
+ throw new ControlLoopException("Do not have a current operation.");
+ }
+ //
+ // Have we acquired it already?
+ //
+ if (this.targetLock != null) {
+ //
+ // TODO: Make sure the current lock is for the same target.
+ // Currently, it should be. But in the future it may not.
+ //
+ return new LockResult<>(GuardResult.LOCK_ACQUIRED, this.targetLock);
+ } else {
+ //
+ // Ask the Guard
+ //
+ LockResult<GuardResult, TargetLock> lockResult =
+ PolicyGuard.lockTarget(this.currentOperation.policy.getTarget().getType(),
+ this.currentOperation.getTargetEntity(), this.onset.getRequestID(), this);
+ //
+ // Was it acquired?
+ //
+ if (lockResult.getA().equals(GuardResult.LOCK_ACQUIRED)) {
+ //
+ // Yes, let's save it
+ //
+ this.targetLock = lockResult.getB();
+ }
+ return lockResult;
+ }
+ }
+
+ /**
+ * Release the lock for the current operation.
+ *
+ * @return the target lock
+ */
+ public synchronized TargetLock unlockCurrentOperation() {
+ if (this.targetLock == null) {
+ return null;
+ }
+ if (PolicyGuard.unlockTarget(this.targetLock)) {
+ TargetLock returnLock = this.targetLock;
+ this.targetLock = null;
+ return returnLock;
+ }
+ return null;
+ }
+
+ public enum NEW_EVENT_STATUS {
+ FIRST_ONSET, SUBSEQUENT_ONSET, FIRST_ABATEMENT, SUBSEQUENT_ABATEMENT, SYNTAX_ERROR;
+ }
+
+ /**
+ * An event onset/abatement.
+ *
+ * @param event the event
+ * @return the status
+ * @throws AAIException if an error occurs retrieving information from A&AI
+ */
+ public NEW_EVENT_STATUS onNewEvent(VirtualControlLoopEvent event) throws AAIException {
+ try {
+ this.checkEventSyntax(event);
+ if (event.getClosedLoopEventStatus() == ControlLoopEventStatus.ONSET) {
+ //
+ // Check if this is our original ONSET
+ //
+ if (event.equals(this.onset)) {
+ //
+ // Query A&AI if needed
+ //
+ queryAai(event);
+
+ //
+ // DO NOT retract it
+ //
+ return NEW_EVENT_STATUS.FIRST_ONSET;
+ }
+ //
+ // Log that we got an onset
+ //
+ this.numOnsets++;
+ return NEW_EVENT_STATUS.SUBSEQUENT_ONSET;
+ } else if (event.getClosedLoopEventStatus() == ControlLoopEventStatus.ABATED) {
+ //
+ // Have we already got an abatement?
+ //
+ if (this.abatement == null) {
+ //
+ // Save this
+ //
+ this.abatement = event;
+ //
+ // Keep track that we received another
+ //
+ this.numAbatements++;
+ //
+ //
+ //
+ return NEW_EVENT_STATUS.FIRST_ABATEMENT;
+ } else {
+ //
+ // Keep track that we received another
+ //
+ this.numAbatements++;
+ //
+ //
+ //
+ return NEW_EVENT_STATUS.SUBSEQUENT_ABATEMENT;
+ }
+ }
+ } catch (ControlLoopException e) {
+ logger.error("{}: onNewEvent threw: ", this, e);
+ }
+ return NEW_EVENT_STATUS.SYNTAX_ERROR;
+ }
+
+ /**
+ * Set the control loop time out.
+ *
+ * @return a VirtualControlLoopNotification
+ */
+ public VirtualControlLoopNotification setControlLoopTimedOut() {
+ this.controlLoopTimedOut = FinalResult.FINAL_FAILURE_TIMEOUT;
+ VirtualControlLoopNotification notification = new VirtualControlLoopNotification(this.onset);
+ notification.setNotification(ControlLoopNotificationType.FINAL_FAILURE);
+ notification.setMessage("Control Loop timed out");
+ notification.getHistory().addAll(this.controlLoopHistory);
+ return notification;
+ }
+
+ public boolean isControlLoopTimedOut() {
+ return (this.controlLoopTimedOut == FinalResult.FINAL_FAILURE_TIMEOUT);
+ }
+
+ /**
+ * Get the control loop timeout.
+ *
+ * @param defaultTimeout the default timeout
+ * @return the timeout
+ */
+ public int getControlLoopTimeout(Integer defaultTimeout) {
+ if (this.processor != null && this.processor.getControlLoop() != null) {
+ return this.processor.getControlLoop().getTimeout();
+ }
+ if (defaultTimeout != null) {
+ return defaultTimeout;
+ }
+ return 0;
+ }
+
+ public AAIGETVnfResponse getVnfResponse() {
+ return vnfResponse;
+ }
+
+ public AAIGETVserverResponse getVserverResponse() {
+ return vserverResponse;
+ }
+
+ /**
+ * Check an event syntax.
+ *
+ * @param event the event syntax
+ * @throws ControlLoopException if an error occurs
+ */
+ public void checkEventSyntax(VirtualControlLoopEvent event) throws ControlLoopException {
+ if (event.getClosedLoopEventStatus() == null
+ || (event.getClosedLoopEventStatus() != ControlLoopEventStatus.ONSET
+ && event.getClosedLoopEventStatus() != ControlLoopEventStatus.ABATED)) {
+ throw new ControlLoopException("Invalid value in closedLoopEventStatus");
+ }
+ if (event.getClosedLoopControlName() == null || event.getClosedLoopControlName().length() < 1) {
+ throw new ControlLoopException("No control loop name");
+ }
+ if (event.getRequestID() == null) {
+ throw new ControlLoopException("No request ID");
+ }
+ if (event.getClosedLoopEventStatus() == ControlLoopEventStatus.ABATED) {
+ return;
+ }
+ if (event.getTarget() == null || event.getTarget().length() < 1) {
+ throw new ControlLoopException("No target field");
+ } else if (!VM_NAME.equalsIgnoreCase(event.getTarget()) && !VNF_NAME.equalsIgnoreCase(event.getTarget())
+ && !VSERVER_VSERVER_NAME.equalsIgnoreCase(event.getTarget())
+ && !GENERIC_VNF_VNF_ID.equalsIgnoreCase(event.getTarget())
+ && !GENERIC_VNF_VNF_NAME.equalsIgnoreCase(event.getTarget())) {
+ throw new ControlLoopException("target field invalid - expecting VM_NAME or VNF_NAME");
+ }
+ if (event.getAAI() == null) {
+ throw new ControlLoopException("AAI is null");
+ }
+ if (event.getAAI().get(GENERIC_VNF_VNF_ID) == null && event.getAAI().get(VSERVER_VSERVER_NAME) == null
+ && event.getAAI().get(GENERIC_VNF_VNF_NAME) == null) {
+ throw new ControlLoopException(
+ "generic-vnf.vnf-id or generic-vnf.vnf-name or vserver.vserver-name information missing");
+ }
+ }
+
+ /**
+ * Query A&AI for an event.
+ *
+ * @param event the event
+ * @throws AAIException if an error occurs retrieving information from A&AI
+ */
+ public void queryAai(VirtualControlLoopEvent event) throws AAIException {
+ if ((event.getAAI().get(VSERVER_IS_CLOSED_LOOP_DISABLED) != null
+ || event.getAAI().get(GENERIC_VNF_IS_CLOSED_LOOP_DISABLED) != null) && isClosedLoopDisabled(event)) {
+ throw new AAIException("is-closed-loop-disabled is set to true on VServer or VNF");
+ }
+
+ try {
+ if (event.getAAI().get(GENERIC_VNF_VNF_ID) != null || event.getAAI().get(GENERIC_VNF_VNF_NAME) != null) {
+ vnfResponse = getAAIVnfInfo(event);
+ processVNFResponse(vnfResponse, event.getAAI().get(GENERIC_VNF_VNF_ID) != null);
+ } else if (event.getAAI().get(VSERVER_VSERVER_NAME) != null) {
+ vserverResponse = getAAIVserverInfo(event);
+ processVServerResponse(vserverResponse);
+ }
+ } catch (Exception e) {
+ logger.error("Exception from queryAai: ", e);
+ throw new AAIException("Exception from queryAai: " + e.toString());
+ }
+ }
+
+ /**
+ * Process a response from A&AI for a VNF.
+ *
+ * @param aaiResponse the response from A&AI
+ * @param queryByVnfId <code>true</code> if the query was based on vnf-id, <code>false</code> if
+ * the query was based on vnf-name
+ * @throws AAIException if an error occurs processing the response
+ */
+ private static void processVNFResponse(AAIGETVnfResponse aaiResponse, boolean queryByVNFID) throws AAIException {
+ String queryTypeString = (queryByVNFID ? "vnf-id" : "vnf-name");
+
+ if (aaiResponse == null) {
+ throw new AAIException("AAI Response is null (query by " + queryTypeString + ")");
+ }
+ if (aaiResponse.getRequestError() != null) {
+ throw new AAIException("AAI Responded with a request error (query by " + queryTypeString + ")");
+ }
+
+ if (aaiResponse.getIsClosedLoopDisabled() != null) {
+ String value = aaiResponse.getIsClosedLoopDisabled();
+ if ("true".equalsIgnoreCase(value) || "T".equalsIgnoreCase(value) || "yes".equalsIgnoreCase(value)
+ || "Y".equalsIgnoreCase(value)) {
+ throw new AAIException("is-closed-loop-disabled is set to true (query by " + queryTypeString + ")");
+ }
+ }
+ }
+
+ private static void processVServerResponse(AAIGETVserverResponse aaiResponse) throws AAIException {
+ if (aaiResponse == null) {
+ throw new AAIException("AAI Response is null (query by vserver-name)");
+ }
+ if (aaiResponse.getRequestError() != null) {
+ throw new AAIException("AAI responded with a request error (query by vserver-name)");
+ }
+
+ if (aaiResponse.getIsClosedLoopDisabled() != null) {
+ String value = aaiResponse.getIsClosedLoopDisabled();
+ if ("true".equalsIgnoreCase(value) || "T".equalsIgnoreCase(value) || "yes".equalsIgnoreCase(value)
+ || "Y".equalsIgnoreCase(value)) {
+ throw new AAIException("is-closed-loop-disabled is set to true (query by vserver-name)");
+ }
+ }
+ }
+
+ /**
+ * Is closed loop disabled for an event.
+ *
+ * @param event the event
+ * @return <code>true</code> if the contol loop is disabled, <code>false</code> otherwise
+ */
+ public static boolean isClosedLoopDisabled(VirtualControlLoopEvent event) {
+ if ("true".equalsIgnoreCase(event.getAAI().get(VSERVER_IS_CLOSED_LOOP_DISABLED))
+ || "T".equalsIgnoreCase(event.getAAI().get(VSERVER_IS_CLOSED_LOOP_DISABLED))
+ || "yes".equalsIgnoreCase(event.getAAI().get(VSERVER_IS_CLOSED_LOOP_DISABLED))
+ || "Y".equalsIgnoreCase(event.getAAI().get(VSERVER_IS_CLOSED_LOOP_DISABLED))) {
+ return true;
+ }
+ return ("true".equalsIgnoreCase(event.getAAI().get(GENERIC_VNF_IS_CLOSED_LOOP_DISABLED))
+ || "T".equalsIgnoreCase(event.getAAI().get(GENERIC_VNF_IS_CLOSED_LOOP_DISABLED))
+ || "yes".equalsIgnoreCase(event.getAAI().get(GENERIC_VNF_IS_CLOSED_LOOP_DISABLED))
+ || "Y".equalsIgnoreCase(event.getAAI().get(GENERIC_VNF_IS_CLOSED_LOOP_DISABLED)));
+ }
+
+ /**
+ * Get the A&AI VService information for an event.
+ *
+ * @param event the event
+ * @return a AAIGETVserverResponse
+ * @throws ControlLoopException if an error occurs
+ */
+ public static AAIGETVserverResponse getAAIVserverInfo(VirtualControlLoopEvent event) throws ControlLoopException {
+ UUID requestId = event.getRequestID();
+ AAIGETVserverResponse response = null;
+ String vserverName = event.getAAI().get(VSERVER_VSERVER_NAME);
+
+ try {
+ if (vserverName != null) {
+ aaiHostURL = PolicyEngine.manager.getEnvironmentProperty("aai.url");
+ aaiUser = PolicyEngine.manager.getEnvironmentProperty("aai.username");
+ aaiPassword = PolicyEngine.manager.getEnvironmentProperty("aai.password");
+ String aaiGetQueryByVserver = "/aai/v11/nodes/vservers?vserver-name=";
+ String url = aaiHostURL + aaiGetQueryByVserver;
+ logger.info("AAI Host URL by VServer: {}", url);
+ response = new AAIManager(new RESTManager()).getQueryByVserverName(url, aaiUser, aaiPassword, requestId,
+ vserverName);
+ }
+ } catch (Exception e) {
+ logger.error("getAAIVserverInfo exception: ", e);
+ throw new ControlLoopException("Exception in getAAIVserverInfo: ", e);
+ }
+
+ return response;
+ }
+
+ /**
+ * Get A&AI VNF information for an event.
+ *
+ * @param event the event
+ * @return a AAIGETVnfResponse
+ * @throws ControlLoopException if an error occurs
+ */
+ public static AAIGETVnfResponse getAAIVnfInfo(VirtualControlLoopEvent event) throws ControlLoopException {
+ UUID requestId = event.getRequestID();
+ AAIGETVnfResponse response = null;
+ String vnfName = event.getAAI().get(GENERIC_VNF_VNF_NAME);
+ String vnfId = event.getAAI().get(GENERIC_VNF_VNF_ID);
+
+ aaiHostURL = PolicyEngine.manager.getEnvironmentProperty("aai.url");
+ aaiUser = PolicyEngine.manager.getEnvironmentProperty("aai.username");
+ aaiPassword = PolicyEngine.manager.getEnvironmentProperty("aai.password");
+
+ try {
+ if (vnfName != null) {
+ String aaiGetQueryByVnfName = "/aai/v11/network/generic-vnfs/generic-vnf?vnf-name=";
+ String url = aaiHostURL + aaiGetQueryByVnfName;
+ logger.info("AAI Host URL by VNF name: {}", url);
+ response = new AAIManager(new RESTManager()).getQueryByVnfName(url, aaiUser, aaiPassword, requestId,
+ vnfName);
+ } else if (vnfId != null) {
+ String aaiGetQueryByVnfId = "/aai/v11/network/generic-vnfs/generic-vnf/";
+ String url = aaiHostURL + aaiGetQueryByVnfId;
+ logger.info("AAI Host URL by VNF ID: {}", url);
+ response =
+ new AAIManager(new RESTManager()).getQueryByVnfID(url, aaiUser, aaiPassword, requestId, vnfId);
+ }
+ } catch (Exception e) {
+ logger.error("getAAIVnfInfo exception: ", e);
+ throw new ControlLoopException("Exception in getAAIVnfInfo: ", e);
+ }
+
+ return response;
+ }
+
+ @Override
+ public boolean isActive() {
+ // TODO
+ return true;
+ }
+
+ @Override
+ public boolean releaseLock() {
+ // TODO
+ return false;
+ }
+
+ @Override
+ public String toString() {
+ return "ControlLoopEventManager [closedLoopControlName=" + closedLoopControlName + ", requestID=" + requestID
+ + ", processor=" + processor + ", onset=" + (onset != null ? onset.getRequestID() : "null")
+ + ", numOnsets=" + numOnsets + ", numAbatements=" + numAbatements + ", isActivated=" + isActivated
+ + ", currentOperation=" + currentOperation + ", targetLock=" + targetLock + "]";
+ }
}
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 ba2df3358..7c900249c 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
@@ -2,7 +2,7 @@
* ============LICENSE_START=======================================================
* controlloop operation manager
* ================================================================================
- * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * Copyright (C) 2017-2018 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.
@@ -54,715 +54,797 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class ControlLoopOperationManager implements Serializable {
- private static final long serialVersionUID = -3773199283624595410L;
- private static final Logger logger = LoggerFactory.getLogger(ControlLoopOperationManager.class);
-
- private static final String VSERVER_VSERVER_NAME = "vserver.vserver-name";
- private static final String GENERIC_VNF_VNF_NAME = "generic-vnf.vnf-name";
- private static final String GENERIC_VNF_VNF_ID = "generic-vnf.vnf-id";
-
- @Override
- public String toString() {
- return "ControlLoopOperationManager [onset=" + (onset != null ? onset.getRequestID() : "null") + ", policy="
- + (policy != null ? policy.getId() : "null") + ", attempts=" + attempts
- + ", policyResult=" + policyResult
- + ", currentOperation=" + currentOperation + ", operationHistory=" + operationHistory
- + "]";
- }
-
- //
- // These properties are not changeable, but accessible
- // for Drools Rule statements.
- //
- public final ControlLoopEvent onset;
- public final transient Policy policy;
-
- //
- // Properties used to track the Operation
- //
- private int attempts = 0;
- private transient Operation currentOperation = null;
- private LinkedList<Operation> operationHistory = new LinkedList<>();
- private PolicyResult policyResult = null;
- private ControlLoopEventManager eventManager = null;
- private String targetEntity;
-
- public ControlLoopEventManager getEventManager() {
- return eventManager;
- }
-
- public void setEventManager(ControlLoopEventManager eventManager) {
- this.eventManager = eventManager;
- }
-
- public String getTargetEntity() {
- return this.targetEntity;
- }
-
- //
- // Internal class used for tracking
- //
- private class Operation {
- private ControlLoopOperation clOperation = new ControlLoopOperation();
- private PolicyResult policyResult = null;
- private int attempt = 0;
-
- @Override
- public String toString() {
- return "Operation [attempt=" + attempt + ", policyResult=" + policyResult + ", operation=" + clOperation
- + "]";
- }
- }
-
- private String guardApprovalStatus = "NONE";//"NONE", "PERMIT", "DENY"
- private transient Object operationRequest;
-
- public Object getOperationRequest() {
- return operationRequest;
- }
-
- public String getGuardApprovalStatus() {
- return guardApprovalStatus;
- }
- public void setGuardApprovalStatus(String guardApprovalStatus) {
- this.guardApprovalStatus = guardApprovalStatus;
- }
-
- public String getTarget(Policy policy) throws ControlLoopException, AAIException {
- if (policy.getTarget() == null) {
- throw new ControlLoopException("The target is null");
- }
-
- if (policy.getTarget().getType() == null) {
- throw new ControlLoopException("The target type is null");
- }
-
- switch(policy.getTarget().getType()) {
- case PNF:
- throw new ControlLoopException("PNF target is not supported");
- case VM:
- case VNF:
- VirtualControlLoopEvent virtualOnset = (VirtualControlLoopEvent) this.onset;
- if (this.onset.getTarget().equalsIgnoreCase(VSERVER_VSERVER_NAME)) {
- return virtualOnset.getAAI().get(VSERVER_VSERVER_NAME);
- }
- else if (this.onset.getTarget().equalsIgnoreCase(GENERIC_VNF_VNF_ID)) {
- return virtualOnset.getAAI().get(GENERIC_VNF_VNF_ID);
- }
- else if (this.onset.getTarget().equalsIgnoreCase(GENERIC_VNF_VNF_NAME)) {
- /*
- * If the onset is enriched with the vnf-id,
- * we don't need an A&AI response
- */
- if (virtualOnset.getAAI().containsKey(GENERIC_VNF_VNF_ID)) {
- return virtualOnset.getAAI().get(GENERIC_VNF_VNF_ID);
- }
-
- /*
- * If the vnf-name was retrieved from the onset then the vnf-id
- * must be obtained from the event manager's A&AI GET query
- */
- String vnfId = this.eventManager.getVnfResponse().getVnfID();
- if (vnfId == null) {
- throw new AAIException("No vnf-id found");
- }
- return vnfId;
- }
- throw new ControlLoopException("Target does not match target type");
- default:
- throw new ControlLoopException("The target type is not supported");
- }
- }
-
- public ControlLoopOperationManager(ControlLoopEvent onset, Policy policy, ControlLoopEventManager em) throws ControlLoopException, AAIException {
- this.onset = onset;
- this.policy = policy;
- this.guardApprovalStatus = "NONE";
- this.eventManager = em;
- this.targetEntity = getTarget(policy);
-
- //
- // Let's make a sanity check
- //
- switch (policy.getActor()) {
- case "APPC":
- if ("ModifyConfig".equalsIgnoreCase(policy.getRecipe())) {
- /*
- * The target vnf-id may not be the same as the source vnf-id
- * specified in the yaml, the target vnf-id is retrieved by
- * a named query to A&AI.
- */
- String targetVnf = AppcLcmActorServiceProvider.vnfNamedQuery( policy.getTarget().getResourceID(), this.targetEntity);
- this.targetEntity = targetVnf;
- }
- break;
- case "SO":
- break;
- case "VFC":
- break;
- default:
- throw new ControlLoopException("ControlLoopEventManager: policy has an unknown actor.");
- }
- }
-
- public Object startOperation(/*VirtualControlLoopEvent*/ControlLoopEvent onset) throws ControlLoopException{
- verifyOperatonCanRun();
-
- //
- // Setup
- //
- this.policyResult = null;
- Operation operation = new Operation();
- operation.attempt = ++this.attempts;
- operation.clOperation.setActor(this.policy.getActor());
- operation.clOperation.setOperation(this.policy.getRecipe());
- operation.clOperation.setTarget(this.policy.getTarget().toString());
- operation.clOperation.setSubRequestId(Integer.toString(operation.attempt));
- //
- // Now determine which actor we need to construct a request for
- //
- switch (policy.getActor()) {
- case "APPC":
- /*
- * If the recipe is ModifyConfig, a legacy APPC
- * request is constructed. Otherwise an LCMRequest
- * is constructed.
- */
- this.currentOperation = operation;
- if ("ModifyConfig".equalsIgnoreCase(policy.getRecipe())) {
- this.operationRequest = APPCActorServiceProvider.constructRequest((VirtualControlLoopEvent) onset,
- operation.clOperation, this.policy, this.targetEntity);
- }
- else {
- this.operationRequest = AppcLcmActorServiceProvider.constructRequest((VirtualControlLoopEvent) onset,
- operation.clOperation, this.policy, this.targetEntity);
- }
- //
- // Save the operation
- //
-
- return operationRequest;
- case "SO":
- SOActorServiceProvider soActorSP = new SOActorServiceProvider();
- this.operationRequest = soActorSP.constructRequest((VirtualControlLoopEvent)onset, operation.clOperation, this.policy);
-
- // Save the operation
- this.currentOperation = operation;
-
- if (this.operationRequest == null) {
- this.policyResult = PolicyResult.FAILURE;
- }
-
- return operationRequest;
- case "VFC":
- this.operationRequest = VFCActorServiceProvider.constructRequest((VirtualControlLoopEvent) onset, operation.clOperation, this.policy, this.eventManager.getVnfResponse());
- this.currentOperation = operation;
- if (this.operationRequest == null) {
- this.policyResult = PolicyResult.FAILURE;
- }
- return operationRequest;
- default:
- throw new ControlLoopException("invalid actor " + policy.getActor() + " on policy");
- }
- }
-
- public PolicyResult onResponse(Object response) {
- //
- // Which response is it?
- //
- if (response instanceof Response) {
- //
- // Cast APPC response and handle it
- //
- return onResponse((Response) response);
- }
- else if (response instanceof LCMResponseWrapper) {
- //
- // Cast LCM response and handle it
- //
- return onResponse((LCMResponseWrapper) response);
- }
- else if (response instanceof SOResponseWrapper) {
- //
- // Cast SO response and handle it
- //
- return onResponse((SOResponseWrapper) response);
- }
- else if (response instanceof VFCResponse) {
- //
- // Cast VFC response and handle it
- //
- return onResponse((VFCResponse) response);
- }
- else {
- return null;
- }
- }
-
- /**
- * This method handles operation responses from APPC
- * @param appcResponse the APPC response
- * @return The result of the response handling
- */
- private PolicyResult onResponse(Response appcResponse) {
- //
- // Determine which subrequestID (ie. attempt)
- //
- Integer operationAttempt = null;
- try {
- operationAttempt = Integer.parseInt(appcResponse.getCommonHeader().getSubRequestID());
- } catch (NumberFormatException e) {
- //
- // We cannot tell what happened if this doesn't exist
- //
- this.completeOperation(operationAttempt, "Policy was unable to parse APP-C SubRequestID (it was null).", PolicyResult.FAILURE_EXCEPTION);
- return PolicyResult.FAILURE_EXCEPTION;
- }
- //
- // Sanity check the response message
- //
- if (appcResponse.getStatus() == null) {
- //
- // We cannot tell what happened if this doesn't exist
- //
- this.completeOperation(operationAttempt, "Policy was unable to parse APP-C response status field (it was null).", PolicyResult.FAILURE_EXCEPTION);
- return PolicyResult.FAILURE_EXCEPTION;
- }
- //
- // Get the Response Code
- //
- ResponseCode code = ResponseCode.toResponseCode(appcResponse.getStatus().getCode());
- if (code == null) {
- //
- // We are unaware of this code
- //
- this.completeOperation(operationAttempt, "Policy was unable to parse APP-C response status code field.", PolicyResult.FAILURE_EXCEPTION);
- return PolicyResult.FAILURE_EXCEPTION;
- }
- //
- // Ok, let's figure out what APP-C's response is
- //
- switch (code) {
- case ACCEPT:
- //
- // This is good, they got our original message and
- // acknowledged it.
- //
- // Is there any need to track this?
- //
- return null;
- case ERROR:
- case REJECT:
- //
- // We'll consider these two codes as exceptions
- //
- this.completeOperation(operationAttempt, appcResponse.getStatus().getDescription(), PolicyResult.FAILURE_EXCEPTION);
- if (this.policyResult != null && this.policyResult.equals(PolicyResult.FAILURE_TIMEOUT)) {
- return null;
- }
- return PolicyResult.FAILURE_EXCEPTION;
- case SUCCESS:
- //
- //
- //
- this.completeOperation(operationAttempt, appcResponse.getStatus().getDescription(), PolicyResult.SUCCESS);
- if (this.policyResult != null && this.policyResult.equals(PolicyResult.FAILURE_TIMEOUT)) {
- return null;
- }
- return PolicyResult.SUCCESS;
- case FAILURE:
- //
- //
- //
- this.completeOperation(operationAttempt, appcResponse.getStatus().getDescription(), PolicyResult.FAILURE);
- if (this.policyResult != null && this.policyResult.equals(PolicyResult.FAILURE_TIMEOUT)) {
- return null;
- }
- return PolicyResult.FAILURE;
- default:
- return null;
- }
- }
-
- /**
- * This method handles operation responses from LCM
- * @param dmaapResponse the LCM response
- * @return The result of the response handling
- */
- private PolicyResult onResponse(LCMResponseWrapper dmaapResponse) {
- /*
- * Parse out the operation attempt using the subrequestid
- */
- Integer operationAttempt = AppcLcmActorServiceProvider.parseOperationAttempt(dmaapResponse.getBody().getCommonHeader().getSubRequestId());
- if (operationAttempt == null) {
- this.completeOperation(operationAttempt, "Policy was unable to parse APP-C SubRequestID (it was null).", PolicyResult.FAILURE_EXCEPTION);
- }
-
- /*
- * Process the APPCLCM response to see what PolicyResult
- * should be returned
- */
- AbstractMap.SimpleEntry<PolicyResult, String> result = AppcLcmActorServiceProvider.processResponse(dmaapResponse);
-
- if (result.getKey() != null) {
- this.completeOperation(operationAttempt, result.getValue(), result.getKey());
- if (PolicyResult.FAILURE_TIMEOUT.equals(this.policyResult)) {
- return null;
- }
- return result.getKey();
- }
- return null;
- }
-
- /**
- * This method handles operation responses from SO
- * @param msoResponse the SO response
- * @return The result of the response handling
- */
- private PolicyResult onResponse(SOResponseWrapper msoResponse) {
- switch (msoResponse.getSoResponse().getHttpResponseCode()) {
- case 200:
- case 202:
- //
- // Consider it as success
- //
- this.completeOperation(this.attempts, msoResponse.getSoResponse().getHttpResponseCode() + " Success", PolicyResult.SUCCESS);
- if (this.policyResult != null && this.policyResult.equals(PolicyResult.FAILURE_TIMEOUT)) {
- return null;
- }
- return PolicyResult.SUCCESS;
- default:
- //
- // Consider it as failure
- //
- this.completeOperation(this.attempts, msoResponse.getSoResponse().getHttpResponseCode() + " Failed", PolicyResult.FAILURE);
- if (this.policyResult != null && this.policyResult.equals(PolicyResult.FAILURE_TIMEOUT)) {
- return null;
- }
- return PolicyResult.FAILURE;
- }
- }
-
- /**
- * This method handles operation responses from VFC
- * @param vfcResponse the VFC response
- * @return The result of the response handling
- */
- private PolicyResult onResponse(VFCResponse vfcResponse) {
- if (vfcResponse.getResponseDescriptor().getStatus().equalsIgnoreCase("finished")) {
- //
- // Consider it as success
- //
- this.completeOperation(this.attempts, " Success", PolicyResult.SUCCESS);
- if (this.policyResult != null && this.policyResult.equals(PolicyResult.FAILURE_TIMEOUT)) {
- return null;
- }
- return PolicyResult.SUCCESS;
- } else {
- //
- // Consider it as failure
- //
- this.completeOperation(this.attempts, " Failed", PolicyResult.FAILURE);
- if (this.policyResult != null && this.policyResult.equals(PolicyResult.FAILURE_TIMEOUT)) {
- return null;
- }
- // increment operation attempts for retries
- this.attempts += 1;
- return PolicyResult.FAILURE;
- }
- }
-
- public Integer getOperationTimeout() {
- //
- // Sanity check
- //
- if (this.policy == null) {
- logger.debug("getOperationTimeout returning 0");
- return 0;
- }
- logger.debug("getOperationTimeout returning {}", this.policy.getTimeout());
- return this.policy.getTimeout();
- }
-
- public String getOperationTimeoutString(int defaultTimeout) {
- Integer to = this.getOperationTimeout();
- if (to == null || to == 0) {
- return Integer.toString(defaultTimeout) + "s";
- }
- return to.toString() + "s";
- }
-
- public PolicyResult getOperationResult() {
- return this.policyResult;
- }
-
- public String getOperationMessage() {
- if (this.currentOperation != null && this.currentOperation.clOperation != null) {
- return this.currentOperation.clOperation.toMessage();
- }
-
- if (!this.operationHistory.isEmpty()) {
- return this.operationHistory.getLast().clOperation.toMessage();
- }
- return null;
- }
-
- public String getOperationMessage(String guardResult) {
- if (this.currentOperation != null && this.currentOperation.clOperation != null) {
- return this.currentOperation.clOperation.toMessage()+ ", Guard result: " + guardResult;
- }
-
- if (!this.operationHistory.isEmpty()) {
- return this.operationHistory.getLast().clOperation.toMessage() + ", Guard result: " + guardResult;
- }
- return null;
- }
-
- public String getOperationHistory() {
- if (this.currentOperation != null && this.currentOperation.clOperation != null) {
- return this.currentOperation.clOperation.toHistory();
- }
-
- if (!this.operationHistory.isEmpty()) {
- return this.operationHistory.getLast().clOperation.toHistory();
- }
- return null;
- }
-
- public List<ControlLoopOperation> getHistory() {
- LinkedList<ControlLoopOperation> history = new LinkedList<>();
- for (Operation op : this.operationHistory) {
- history.add(new ControlLoopOperation(op.clOperation));
-
- }
- return history;
- }
-
- public void setOperationHasTimedOut() {
- //
- //
- //
- this.completeOperation(this.attempts, "Operation timed out", PolicyResult.FAILURE_TIMEOUT);
- }
-
- public void setOperationHasGuardDeny() {
- //
- //
- //
- 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() {
- //
- // Is there currently a result?
- //
- if (this.policyResult == null) {
- //
- // either we are in process or we
- // haven't started
- //
- return false;
- }
- //
- // We have some result, check if the operation failed
- //
- if (this.policyResult.equals(PolicyResult.FAILURE)) {
- //
- // Check if there were no retries specified
- //
- if (policy.getRetry() == null || policy.getRetry() == 0) {
- //
- // The result is the failure
- //
- return true;
- }
- //
- // Check retries
- //
- if (this.isRetriesMaxedOut()) {
- //
- // No more attempts allowed, reset
- // that our actual result is failure due to retries
- //
- this.policyResult = PolicyResult.FAILURE_RETRIES;
- return true;
- } else {
- //
- // There are more attempts available to try the
- // policy recipe.
- //
- return false;
- }
- }
- //
- // Other results mean we are done
- //
- return true;
- }
-
- public boolean isOperationRunning() {
- return (this.currentOperation != null);
- }
-
- /**
- * This method verifies that the operation manager may run an operation.
- * @return True if the operation can run, false otherwise
- * @throws ControlLoopException if the operation cannot run
- */
- private void verifyOperatonCanRun() throws ControlLoopException {
- //
- // They shouldn't call us if we currently running something
- //
- if (this.currentOperation != null) {
- //
- // what do we do if we are already running an operation?
- //
- throw new ControlLoopException("current operation is not null (an operation is already running)");
- }
- //
- // Check if we have maxed out on retries
- //
- if (this.policy.getRetry() == null || this.policy.getRetry() < 1) {
- //
- // No retries are allowed, so check have we even made
- // one attempt to execute the operation?
- //
- if (this.attempts >= 1) {
- //
- // We have, let's ensure our PolicyResult is set
- //
- if (this.policyResult == null) {
- this.policyResult = PolicyResult.FAILURE_RETRIES;
- }
- //
- //
- //
- throw new ControlLoopException("current operation failed and retries are not allowed");
- }
- } else {
- //
- // Have we maxed out on retries?
- //
- if (this.attempts > this.policy.getRetry()) {
- if (this.policyResult == null) {
- this.policyResult = PolicyResult.FAILURE_RETRIES;
- }
- throw new ControlLoopException("current oepration has failed after " + this.attempts + " retries");
- }
- }
-
- return;
- }
-
- private boolean isRetriesMaxedOut() {
- if (policy.getRetry() == null || policy.getRetry() == 0) {
- //
- // There were NO retries specified, so declare
- // this as completed.
- //
- return (this.attempts > 0);
- }
- return (this.attempts > policy.getRetry());
- }
-
- private void storeOperationInDataBase(){
- // Only store in DB if enabled
- boolean guardEnabled = "false".equalsIgnoreCase(PolicyEngine.manager.getEnvironmentProperty("guard.disabled"));
- if( !guardEnabled ){
- return;
- }
-
-
- // DB Properties
- Properties props = new Properties();
- if(PolicyEngine.manager.getEnvironmentProperty(Util.ONAP_KEY_URL) != null &&
- PolicyEngine.manager.getEnvironmentProperty(Util.ONAP_KEY_USER) != null &&
- PolicyEngine.manager.getEnvironmentProperty(Util.ONAP_KEY_PASS) != null){
- props.put(Util.ECLIPSE_LINK_KEY_URL, PolicyEngine.manager.getEnvironmentProperty(Util.ONAP_KEY_URL));
- props.put(Util.ECLIPSE_LINK_KEY_USER, PolicyEngine.manager.getEnvironmentProperty(Util.ONAP_KEY_USER));
- props.put(Util.ECLIPSE_LINK_KEY_PASS, PolicyEngine.manager.getEnvironmentProperty(Util.ONAP_KEY_PASS));
- props.put(PersistenceUnitProperties.CLASSLOADER, ControlLoopOperationManager.class.getClassLoader());
- }
-
-
- String opsHistPU = System.getProperty("OperationsHistoryPU");
- if(opsHistPU == null || !opsHistPU.equals("TestOperationsHistoryPU")){
- opsHistPU = "OperationsHistoryPU";
- }
- else{
- props.clear();
- }
- EntityManager em;
- try{
- em = Persistence.createEntityManagerFactory(opsHistPU, props).createEntityManager();
- }catch(Exception e){
- logger.error("storeOperationInDataBase threw: ", e);
- return;
- }
-
- OperationsHistoryDbEntry newEntry = new OperationsHistoryDbEntry();
-
- newEntry.setClosedLoopName(this.onset.getClosedLoopControlName());
- newEntry.setRequestId(this.onset.getRequestID().toString());
- newEntry.setActor(this.currentOperation.clOperation.getActor());
- newEntry.setOperation(this.currentOperation.clOperation.getOperation());
- newEntry.setTarget(this.targetEntity);
- newEntry.setStarttime(Timestamp.from(this.currentOperation.clOperation.getStart()));
- newEntry.setSubrequestId(this.currentOperation.clOperation.getSubRequestId());
- newEntry.setEndtime(new Timestamp(this.currentOperation.clOperation.getEnd().toEpochMilli()));
- newEntry.setMessage(this.currentOperation.clOperation.getMessage());
- newEntry.setOutcome(this.currentOperation.clOperation.getOutcome());
-
- em.getTransaction().begin();
- em.persist(newEntry);
- em.getTransaction().commit();
-
- em.close();
- }
-
- private void completeOperation(Integer attempt, String message, PolicyResult result) {
- if (attempt == null) {
- logger.debug("attempt cannot be null (i.e. subRequestID)");
- return;
- }
- if (this.currentOperation != null) {
- if (this.currentOperation.attempt == attempt.intValue()) {
- this.currentOperation.clOperation.setEnd(Instant.now());
- this.currentOperation.clOperation.setMessage(message);
- this.currentOperation.clOperation.setOutcome(result.toString());
- this.currentOperation.policyResult = result;
- //
- // Save it in history
- //
- this.operationHistory.add(this.currentOperation);
- this.storeOperationInDataBase();
- //
- // Set our last result
- //
- this.policyResult = result;
- //
- // Clear the current operation field
- //
- this.currentOperation = null;
- return;
- }
- logger.debug("not current");
- }
- for (Operation op : this.operationHistory) {
- if (op.attempt == attempt.intValue()) {
- op.clOperation.setEnd(Instant.now());
- op.clOperation.setMessage(message);
- op.clOperation.setOutcome(result.toString());
- op.policyResult = result;
- return;
- }
- }
- logger.debug("Could not find associated operation");
-
- }
+ private static final long serialVersionUID = -3773199283624595410L;
+ private static final Logger logger = LoggerFactory.getLogger(ControlLoopOperationManager.class);
+
+ private static final String VSERVER_VSERVER_NAME = "vserver.vserver-name";
+ private static final String GENERIC_VNF_VNF_NAME = "generic-vnf.vnf-name";
+ private static final String GENERIC_VNF_VNF_ID = "generic-vnf.vnf-id";
+
+ @Override
+ public String toString() {
+ return "ControlLoopOperationManager [onset=" + (onset != null ? onset.getRequestID() : "null") + ", policy="
+ + (policy != null ? policy.getId() : "null") + ", attempts=" + attempts + ", policyResult="
+ + policyResult + ", currentOperation=" + currentOperation + ", operationHistory=" + operationHistory
+ + "]";
+ }
+
+ //
+ // These properties are not changeable, but accessible
+ // for Drools Rule statements.
+ //
+ public final ControlLoopEvent onset;
+ public final transient Policy policy;
+
+ //
+ // Properties used to track the Operation
+ //
+ private int attempts = 0;
+ private transient Operation currentOperation = null;
+ private LinkedList<Operation> operationHistory = new LinkedList<>();
+ private PolicyResult policyResult = null;
+ private ControlLoopEventManager eventManager = null;
+ private String targetEntity;
+
+ public ControlLoopEventManager getEventManager() {
+ return eventManager;
+ }
+
+ public void setEventManager(ControlLoopEventManager eventManager) {
+ this.eventManager = eventManager;
+ }
+
+ public String getTargetEntity() {
+ return this.targetEntity;
+ }
+
+ //
+ // Internal class used for tracking
+ //
+ private class Operation {
+ private ControlLoopOperation clOperation = new ControlLoopOperation();
+ private PolicyResult policyResult = null;
+ private int attempt = 0;
+
+ @Override
+ public String toString() {
+ return "Operation [attempt=" + attempt + ", policyResult=" + policyResult + ", operation=" + clOperation
+ + "]";
+ }
+ }
+
+ private String guardApprovalStatus = "NONE";// "NONE", "PERMIT", "DENY"
+ private transient Object operationRequest;
+
+ public Object getOperationRequest() {
+ return operationRequest;
+ }
+
+ public String getGuardApprovalStatus() {
+ return guardApprovalStatus;
+ }
+
+ public void setGuardApprovalStatus(String guardApprovalStatus) {
+ this.guardApprovalStatus = guardApprovalStatus;
+ }
+
+ /**
+ * Get the target for a policy.
+ *
+ * @param policy the policy
+ * @return the target
+ * @throws ControlLoopException if an error occurs
+ * @throws AAIException if an error occurs retrieving information from A&AI
+ */
+ public String getTarget(Policy policy) throws ControlLoopException, AAIException {
+ if (policy.getTarget() == null) {
+ throw new ControlLoopException("The target is null");
+ }
+
+ if (policy.getTarget().getType() == null) {
+ throw new ControlLoopException("The target type is null");
+ }
+
+ switch (policy.getTarget().getType()) {
+ case PNF:
+ throw new ControlLoopException("PNF target is not supported");
+ case VM:
+ case VNF:
+ VirtualControlLoopEvent virtualOnset = (VirtualControlLoopEvent) this.onset;
+ if (this.onset.getTarget().equalsIgnoreCase(VSERVER_VSERVER_NAME)) {
+ return virtualOnset.getAAI().get(VSERVER_VSERVER_NAME);
+ } else if (this.onset.getTarget().equalsIgnoreCase(GENERIC_VNF_VNF_ID)) {
+ return virtualOnset.getAAI().get(GENERIC_VNF_VNF_ID);
+ } else if (this.onset.getTarget().equalsIgnoreCase(GENERIC_VNF_VNF_NAME)) {
+ /*
+ * If the onset is enriched with the vnf-id, we don't need an A&AI response
+ */
+ if (virtualOnset.getAAI().containsKey(GENERIC_VNF_VNF_ID)) {
+ return virtualOnset.getAAI().get(GENERIC_VNF_VNF_ID);
+ }
+
+ /*
+ * If the vnf-name was retrieved from the onset then the vnf-id must be obtained
+ * from the event manager's A&AI GET query
+ */
+ String vnfId = this.eventManager.getVnfResponse().getVnfID();
+ if (vnfId == null) {
+ throw new AAIException("No vnf-id found");
+ }
+ return vnfId;
+ }
+ throw new ControlLoopException("Target does not match target type");
+ default:
+ throw new ControlLoopException("The target type is not supported");
+ }
+ }
+
+ /**
+ * Construct an instance.
+ *
+ * @param onset the onset event
+ * @param policy the policy
+ * @param em the event manager
+ * @throws ControlLoopException if an error occurs
+ * @throws AAIException if an error occurs retrieving information from A&AI
+ */
+ public ControlLoopOperationManager(ControlLoopEvent onset, Policy policy, ControlLoopEventManager em)
+ throws ControlLoopException, AAIException {
+ this.onset = onset;
+ this.policy = policy;
+ this.guardApprovalStatus = "NONE";
+ this.eventManager = em;
+ this.targetEntity = getTarget(policy);
+
+ //
+ // Let's make a sanity check
+ //
+ switch (policy.getActor()) {
+ case "APPC":
+ if ("ModifyConfig".equalsIgnoreCase(policy.getRecipe())) {
+ /*
+ * The target vnf-id may not be the same as the source vnf-id specified in the
+ * yaml, the target vnf-id is retrieved by a named query to A&AI.
+ */
+ String targetVnf = AppcLcmActorServiceProvider.vnfNamedQuery(policy.getTarget().getResourceID(),
+ this.targetEntity);
+ this.targetEntity = targetVnf;
+ }
+ break;
+ case "SO":
+ break;
+ case "VFC":
+ break;
+ default:
+ throw new ControlLoopException("ControlLoopEventManager: policy has an unknown actor.");
+ }
+ }
+
+ /**
+ * Start an operation.
+ *
+ * @param onset the onset event
+ * @return the operation request
+ * @throws ControlLoopException if an error occurs
+ */
+ public Object startOperation(/* VirtualControlLoopEvent */ControlLoopEvent onset) throws ControlLoopException {
+ verifyOperatonCanRun();
+
+ //
+ // Setup
+ //
+ this.policyResult = null;
+ Operation operation = new Operation();
+ operation.attempt = ++this.attempts;
+ operation.clOperation.setActor(this.policy.getActor());
+ operation.clOperation.setOperation(this.policy.getRecipe());
+ operation.clOperation.setTarget(this.policy.getTarget().toString());
+ operation.clOperation.setSubRequestId(Integer.toString(operation.attempt));
+ //
+ // Now determine which actor we need to construct a request for
+ //
+ switch (policy.getActor()) {
+ case "APPC":
+ /*
+ * If the recipe is ModifyConfig, a legacy APPC request is constructed. Otherwise an
+ * LCMRequest is constructed.
+ */
+ this.currentOperation = operation;
+ if ("ModifyConfig".equalsIgnoreCase(policy.getRecipe())) {
+ this.operationRequest = APPCActorServiceProvider.constructRequest((VirtualControlLoopEvent) onset,
+ operation.clOperation, this.policy, this.targetEntity);
+ } else {
+ this.operationRequest = AppcLcmActorServiceProvider.constructRequest(
+ (VirtualControlLoopEvent) onset, operation.clOperation, this.policy, this.targetEntity);
+ }
+ //
+ // Save the operation
+ //
+
+ return operationRequest;
+ case "SO":
+ SOActorServiceProvider soActorSp = new SOActorServiceProvider();
+ this.operationRequest =
+ soActorSp.constructRequest((VirtualControlLoopEvent) onset, operation.clOperation, this.policy);
+
+ // Save the operation
+ this.currentOperation = operation;
+
+ if (this.operationRequest == null) {
+ this.policyResult = PolicyResult.FAILURE;
+ }
+
+ return operationRequest;
+ case "VFC":
+ this.operationRequest = VFCActorServiceProvider.constructRequest((VirtualControlLoopEvent) onset,
+ operation.clOperation, this.policy, this.eventManager.getVnfResponse());
+ this.currentOperation = operation;
+ if (this.operationRequest == null) {
+ this.policyResult = PolicyResult.FAILURE;
+ }
+ return operationRequest;
+ default:
+ throw new ControlLoopException("invalid actor " + policy.getActor() + " on policy");
+ }
+ }
+
+ /**
+ * Handle a response.
+ *
+ * @param response the response
+ * @return a PolicyResult
+ */
+ public PolicyResult onResponse(Object response) {
+ //
+ // Which response is it?
+ //
+ if (response instanceof Response) {
+ //
+ // Cast APPC response and handle it
+ //
+ return onResponse((Response) response);
+ } else if (response instanceof LCMResponseWrapper) {
+ //
+ // Cast LCM response and handle it
+ //
+ return onResponse((LCMResponseWrapper) response);
+ } else if (response instanceof SOResponseWrapper) {
+ //
+ // Cast SO response and handle it
+ //
+ return onResponse((SOResponseWrapper) response);
+ } else if (response instanceof VFCResponse) {
+ //
+ // Cast VFC response and handle it
+ //
+ return onResponse((VFCResponse) response);
+ } else {
+ return null;
+ }
+ }
+
+ /**
+ * This method handles operation responses from APPC.
+ *
+ * @param appcResponse the APPC response
+ * @return The result of the response handling
+ */
+ private PolicyResult onResponse(Response appcResponse) {
+ //
+ // Determine which subrequestID (ie. attempt)
+ //
+ Integer operationAttempt = null;
+ try {
+ operationAttempt = Integer.parseInt(appcResponse.getCommonHeader().getSubRequestID());
+ } catch (NumberFormatException e) {
+ //
+ // We cannot tell what happened if this doesn't exist
+ //
+ this.completeOperation(operationAttempt, "Policy was unable to parse APP-C SubRequestID (it was null).",
+ PolicyResult.FAILURE_EXCEPTION);
+ return PolicyResult.FAILURE_EXCEPTION;
+ }
+ //
+ // Sanity check the response message
+ //
+ if (appcResponse.getStatus() == null) {
+ //
+ // We cannot tell what happened if this doesn't exist
+ //
+ this.completeOperation(operationAttempt,
+ "Policy was unable to parse APP-C response status field (it was null).",
+ PolicyResult.FAILURE_EXCEPTION);
+ return PolicyResult.FAILURE_EXCEPTION;
+ }
+ //
+ // Get the Response Code
+ //
+ ResponseCode code = ResponseCode.toResponseCode(appcResponse.getStatus().getCode());
+ if (code == null) {
+ //
+ // We are unaware of this code
+ //
+ this.completeOperation(operationAttempt, "Policy was unable to parse APP-C response status code field.",
+ PolicyResult.FAILURE_EXCEPTION);
+ return PolicyResult.FAILURE_EXCEPTION;
+ }
+ //
+ // Ok, let's figure out what APP-C's response is
+ //
+ switch (code) {
+ case ACCEPT:
+ //
+ // This is good, they got our original message and
+ // acknowledged it.
+ //
+ // Is there any need to track this?
+ //
+ return null;
+ case ERROR:
+ case REJECT:
+ //
+ // We'll consider these two codes as exceptions
+ //
+ this.completeOperation(operationAttempt, appcResponse.getStatus().getDescription(),
+ PolicyResult.FAILURE_EXCEPTION);
+ if (this.policyResult != null && this.policyResult.equals(PolicyResult.FAILURE_TIMEOUT)) {
+ return null;
+ }
+ return PolicyResult.FAILURE_EXCEPTION;
+ case SUCCESS:
+ //
+ //
+ //
+ this.completeOperation(operationAttempt, appcResponse.getStatus().getDescription(),
+ PolicyResult.SUCCESS);
+ if (this.policyResult != null && this.policyResult.equals(PolicyResult.FAILURE_TIMEOUT)) {
+ return null;
+ }
+ return PolicyResult.SUCCESS;
+ case FAILURE:
+ //
+ //
+ //
+ this.completeOperation(operationAttempt, appcResponse.getStatus().getDescription(),
+ PolicyResult.FAILURE);
+ if (this.policyResult != null && this.policyResult.equals(PolicyResult.FAILURE_TIMEOUT)) {
+ return null;
+ }
+ return PolicyResult.FAILURE;
+ default:
+ return null;
+ }
+ }
+
+ /**
+ * This method handles operation responses from LCM.
+ *
+ * @param dmaapResponse the LCM response
+ * @return The result of the response handling
+ */
+ private PolicyResult onResponse(LCMResponseWrapper dmaapResponse) {
+ /*
+ * Parse out the operation attempt using the subrequestid
+ */
+ Integer operationAttempt = AppcLcmActorServiceProvider
+ .parseOperationAttempt(dmaapResponse.getBody().getCommonHeader().getSubRequestId());
+ if (operationAttempt == null) {
+ this.completeOperation(operationAttempt, "Policy was unable to parse APP-C SubRequestID (it was null).",
+ PolicyResult.FAILURE_EXCEPTION);
+ }
+
+ /*
+ * Process the APPCLCM response to see what PolicyResult should be returned
+ */
+ AbstractMap.SimpleEntry<PolicyResult, String> result =
+ AppcLcmActorServiceProvider.processResponse(dmaapResponse);
+
+ if (result.getKey() != null) {
+ this.completeOperation(operationAttempt, result.getValue(), result.getKey());
+ if (PolicyResult.FAILURE_TIMEOUT.equals(this.policyResult)) {
+ return null;
+ }
+ return result.getKey();
+ }
+ return null;
+ }
+
+ /**
+ * This method handles operation responses from SO.
+ *
+ * @param msoResponse the SO response
+ * @return The result of the response handling
+ */
+ private PolicyResult onResponse(SOResponseWrapper msoResponse) {
+ switch (msoResponse.getSoResponse().getHttpResponseCode()) {
+ case 200:
+ case 202:
+ //
+ // Consider it as success
+ //
+ this.completeOperation(this.attempts, msoResponse.getSoResponse().getHttpResponseCode() + " Success",
+ PolicyResult.SUCCESS);
+ if (this.policyResult != null && this.policyResult.equals(PolicyResult.FAILURE_TIMEOUT)) {
+ return null;
+ }
+ return PolicyResult.SUCCESS;
+ default:
+ //
+ // Consider it as failure
+ //
+ this.completeOperation(this.attempts, msoResponse.getSoResponse().getHttpResponseCode() + " Failed",
+ PolicyResult.FAILURE);
+ if (this.policyResult != null && this.policyResult.equals(PolicyResult.FAILURE_TIMEOUT)) {
+ return null;
+ }
+ return PolicyResult.FAILURE;
+ }
+ }
+
+ /**
+ * This method handles operation responses from VFC.
+ *
+ * @param vfcResponse the VFC response
+ * @return The result of the response handling
+ */
+ private PolicyResult onResponse(VFCResponse vfcResponse) {
+ if (vfcResponse.getResponseDescriptor().getStatus().equalsIgnoreCase("finished")) {
+ //
+ // Consider it as success
+ //
+ this.completeOperation(this.attempts, " Success", PolicyResult.SUCCESS);
+ if (this.policyResult != null && this.policyResult.equals(PolicyResult.FAILURE_TIMEOUT)) {
+ return null;
+ }
+ return PolicyResult.SUCCESS;
+ } else {
+ //
+ // Consider it as failure
+ //
+ this.completeOperation(this.attempts, " Failed", PolicyResult.FAILURE);
+ if (this.policyResult != null && this.policyResult.equals(PolicyResult.FAILURE_TIMEOUT)) {
+ return null;
+ }
+ // increment operation attempts for retries
+ this.attempts += 1;
+ return PolicyResult.FAILURE;
+ }
+ }
+
+ /**
+ * Get the operation timeout.
+ *
+ * @return the timeout
+ */
+ public Integer getOperationTimeout() {
+ //
+ // Sanity check
+ //
+ if (this.policy == null) {
+ logger.debug("getOperationTimeout returning 0");
+ return 0;
+ }
+ logger.debug("getOperationTimeout returning {}", this.policy.getTimeout());
+ return this.policy.getTimeout();
+ }
+
+ /**
+ * Get the operation timeout as a String.
+ *
+ * @param defaultTimeout the default timeout
+ * @return the timeout as a String
+ */
+ public String getOperationTimeoutString(int defaultTimeout) {
+ Integer to = this.getOperationTimeout();
+ if (to == null || to == 0) {
+ return Integer.toString(defaultTimeout) + "s";
+ }
+ return to.toString() + "s";
+ }
+
+ public PolicyResult getOperationResult() {
+ return this.policyResult;
+ }
+
+ /**
+ * Get the operation as a message.
+ *
+ * @return the operation as a message
+ */
+ public String getOperationMessage() {
+ if (this.currentOperation != null && this.currentOperation.clOperation != null) {
+ return this.currentOperation.clOperation.toMessage();
+ }
+
+ if (!this.operationHistory.isEmpty()) {
+ return this.operationHistory.getLast().clOperation.toMessage();
+ }
+ return null;
+ }
+
+ /**
+ * Get the operation as a message including the guard result.
+ *
+ * @param guardResult the guard result
+ * @return the operation as a message including the guard result
+ */
+ public String getOperationMessage(String guardResult) {
+ if (this.currentOperation != null && this.currentOperation.clOperation != null) {
+ return this.currentOperation.clOperation.toMessage() + ", Guard result: " + guardResult;
+ }
+
+ if (!this.operationHistory.isEmpty()) {
+ return this.operationHistory.getLast().clOperation.toMessage() + ", Guard result: " + guardResult;
+ }
+ return null;
+ }
+
+ /**
+ * Get the operation history.
+ *
+ * @return the operation history
+ */
+ public String getOperationHistory() {
+ if (this.currentOperation != null && this.currentOperation.clOperation != null) {
+ return this.currentOperation.clOperation.toHistory();
+ }
+
+ if (!this.operationHistory.isEmpty()) {
+ return this.operationHistory.getLast().clOperation.toHistory();
+ }
+ return null;
+ }
+
+ /**
+ * Get the history.
+ *
+ * @return the list of control loop operations
+ */
+ public List<ControlLoopOperation> getHistory() {
+ LinkedList<ControlLoopOperation> history = new LinkedList<>();
+ for (Operation op : this.operationHistory) {
+ history.add(new ControlLoopOperation(op.clOperation));
+
+ }
+ return history;
+ }
+
+ /**
+ * Set the operation has timed out.
+ */
+ public void setOperationHasTimedOut() {
+ //
+ //
+ //
+ this.completeOperation(this.attempts, "Operation timed out", PolicyResult.FAILURE_TIMEOUT);
+ }
+
+ /**
+ * Set the operation has been denied by guard.
+ */
+ public void setOperationHasGuardDeny() {
+ //
+ //
+ //
+ this.completeOperation(this.attempts, "Operation denied by Guard", PolicyResult.FAILURE_GUARD);
+ }
+
+ public void setOperationHasException(String message) {
+ this.completeOperation(this.attempts, message, PolicyResult.FAILURE_EXCEPTION);
+ }
+
+ /**
+ * Is the operation complete.
+ *
+ * @return <code>true</code> if the operation is complete, <code>false</code> otherwise
+ */
+ public boolean isOperationComplete() {
+ //
+ // Is there currently a result?
+ //
+ if (this.policyResult == null) {
+ //
+ // either we are in process or we
+ // haven't started
+ //
+ return false;
+ }
+ //
+ // We have some result, check if the operation failed
+ //
+ if (this.policyResult.equals(PolicyResult.FAILURE)) {
+ //
+ // Check if there were no retries specified
+ //
+ if (policy.getRetry() == null || policy.getRetry() == 0) {
+ //
+ // The result is the failure
+ //
+ return true;
+ }
+ //
+ // Check retries
+ //
+ if (this.isRetriesMaxedOut()) {
+ //
+ // No more attempts allowed, reset
+ // that our actual result is failure due to retries
+ //
+ this.policyResult = PolicyResult.FAILURE_RETRIES;
+ return true;
+ } else {
+ //
+ // There are more attempts available to try the
+ // policy recipe.
+ //
+ return false;
+ }
+ }
+ //
+ // Other results mean we are done
+ //
+ return true;
+ }
+
+ public boolean isOperationRunning() {
+ return (this.currentOperation != null);
+ }
+
+ /**
+ * This method verifies that the operation manager may run an operation.
+ *
+ * @return True if the operation can run, false otherwise
+ * @throws ControlLoopException if the operation cannot run
+ */
+ private void verifyOperatonCanRun() throws ControlLoopException {
+ //
+ // They shouldn't call us if we currently running something
+ //
+ if (this.currentOperation != null) {
+ //
+ // what do we do if we are already running an operation?
+ //
+ throw new ControlLoopException("current operation is not null (an operation is already running)");
+ }
+ //
+ // Check if we have maxed out on retries
+ //
+ if (this.policy.getRetry() == null || this.policy.getRetry() < 1) {
+ //
+ // No retries are allowed, so check have we even made
+ // one attempt to execute the operation?
+ //
+ if (this.attempts >= 1) {
+ //
+ // We have, let's ensure our PolicyResult is set
+ //
+ if (this.policyResult == null) {
+ this.policyResult = PolicyResult.FAILURE_RETRIES;
+ }
+ //
+ //
+ //
+ throw new ControlLoopException("current operation failed and retries are not allowed");
+ }
+ } else {
+ //
+ // Have we maxed out on retries?
+ //
+ if (this.attempts > this.policy.getRetry()) {
+ if (this.policyResult == null) {
+ this.policyResult = PolicyResult.FAILURE_RETRIES;
+ }
+ throw new ControlLoopException("current oepration has failed after " + this.attempts + " retries");
+ }
+ }
+
+ return;
+ }
+
+ private boolean isRetriesMaxedOut() {
+ if (policy.getRetry() == null || policy.getRetry() == 0) {
+ //
+ // There were NO retries specified, so declare
+ // this as completed.
+ //
+ return (this.attempts > 0);
+ }
+ return (this.attempts > policy.getRetry());
+ }
+
+ private void storeOperationInDataBase() {
+ // Only store in DB if enabled
+ boolean guardEnabled = "false".equalsIgnoreCase(PolicyEngine.manager.getEnvironmentProperty("guard.disabled"));
+ if (!guardEnabled) {
+ return;
+ }
+
+
+ // DB Properties
+ Properties props = new Properties();
+ if (PolicyEngine.manager.getEnvironmentProperty(Util.ONAP_KEY_URL) != null
+ && PolicyEngine.manager.getEnvironmentProperty(Util.ONAP_KEY_USER) != null
+ && PolicyEngine.manager.getEnvironmentProperty(Util.ONAP_KEY_PASS) != null) {
+ props.put(Util.ECLIPSE_LINK_KEY_URL, PolicyEngine.manager.getEnvironmentProperty(Util.ONAP_KEY_URL));
+ props.put(Util.ECLIPSE_LINK_KEY_USER, PolicyEngine.manager.getEnvironmentProperty(Util.ONAP_KEY_USER));
+ props.put(Util.ECLIPSE_LINK_KEY_PASS, PolicyEngine.manager.getEnvironmentProperty(Util.ONAP_KEY_PASS));
+ props.put(PersistenceUnitProperties.CLASSLOADER, ControlLoopOperationManager.class.getClassLoader());
+ }
+
+
+ String opsHistPu = System.getProperty("OperationsHistoryPU");
+ if (opsHistPu == null || !opsHistPu.equals("TestOperationsHistoryPU")) {
+ opsHistPu = "OperationsHistoryPU";
+ } else {
+ props.clear();
+ }
+ EntityManager em;
+ try {
+ em = Persistence.createEntityManagerFactory(opsHistPu, props).createEntityManager();
+ } catch (Exception e) {
+ logger.error("storeOperationInDataBase threw: ", e);
+ return;
+ }
+
+ OperationsHistoryDbEntry newEntry = new OperationsHistoryDbEntry();
+
+ newEntry.setClosedLoopName(this.onset.getClosedLoopControlName());
+ newEntry.setRequestId(this.onset.getRequestID().toString());
+ newEntry.setActor(this.currentOperation.clOperation.getActor());
+ newEntry.setOperation(this.currentOperation.clOperation.getOperation());
+ newEntry.setTarget(this.targetEntity);
+ newEntry.setStarttime(Timestamp.from(this.currentOperation.clOperation.getStart()));
+ newEntry.setSubrequestId(this.currentOperation.clOperation.getSubRequestId());
+ newEntry.setEndtime(new Timestamp(this.currentOperation.clOperation.getEnd().toEpochMilli()));
+ newEntry.setMessage(this.currentOperation.clOperation.getMessage());
+ newEntry.setOutcome(this.currentOperation.clOperation.getOutcome());
+
+ em.getTransaction().begin();
+ em.persist(newEntry);
+ em.getTransaction().commit();
+
+ em.close();
+ }
+
+ private void completeOperation(Integer attempt, String message, PolicyResult result) {
+ if (attempt == null) {
+ logger.debug("attempt cannot be null (i.e. subRequestID)");
+ return;
+ }
+ if (this.currentOperation != null) {
+ if (this.currentOperation.attempt == attempt.intValue()) {
+ this.currentOperation.clOperation.setEnd(Instant.now());
+ this.currentOperation.clOperation.setMessage(message);
+ this.currentOperation.clOperation.setOutcome(result.toString());
+ this.currentOperation.policyResult = result;
+ //
+ // Save it in history
+ //
+ this.operationHistory.add(this.currentOperation);
+ this.storeOperationInDataBase();
+ //
+ // Set our last result
+ //
+ this.policyResult = result;
+ //
+ // Clear the current operation field
+ //
+ this.currentOperation = null;
+ return;
+ }
+ logger.debug("not current");
+ }
+ for (Operation op : this.operationHistory) {
+ if (op.attempt == attempt.intValue()) {
+ op.clOperation.setEnd(Instant.now());
+ op.clOperation.setMessage(message);
+ op.clOperation.setOutcome(result.toString());
+ op.policyResult = result;
+ return;
+ }
+ }
+ logger.debug("Could not find associated operation");
+
+ }
}
diff --git a/controlloop/common/eventmanager/src/main/java/org/onap/policy/controlloop/eventmanager/OperationsHistoryDbEntry.java b/controlloop/common/eventmanager/src/main/java/org/onap/policy/controlloop/eventmanager/OperationsHistoryDbEntry.java
index 30273d377..002f39119 100644
--- a/controlloop/common/eventmanager/src/main/java/org/onap/policy/controlloop/eventmanager/OperationsHistoryDbEntry.java
+++ b/controlloop/common/eventmanager/src/main/java/org/onap/policy/controlloop/eventmanager/OperationsHistoryDbEntry.java
@@ -2,7 +2,7 @@
* ============LICENSE_START=======================================================
* controlloop
* ================================================================================
- * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * Copyright (C) 2017-2018 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.
@@ -30,92 +30,115 @@ import javax.persistence.Id;
import javax.persistence.Table;
@Entity
-@Table(name="operationshistory10")
+@Table(name = "operationshistory10")
public class OperationsHistoryDbEntry implements Serializable {
- private static final long serialVersionUID = 1L;
-
- @Id@GeneratedValue
- @Column(name="ROWID")
- public long rowid;
-
- @Column(name="CLNAME")
- private String closedLoopName;
-
- private String requestId;
- private String actor;
- private String operation;
- private String target;
- private Timestamp starttime;
- private Timestamp endtime;
- private String subrequestId;
- private String outcome;
- private String message;
- public long getRowid() {
- return rowid;
- }
- public void setRowid(long rowid) {
- this.rowid = rowid;
- }
- public String getClosedLoopName() {
- return closedLoopName;
- }
- public void setClosedLoopName(String closedLoopName) {
- this.closedLoopName = closedLoopName;
- }
- public String getRequestId() {
- return requestId;
- }
- public void setRequestId(String requestId) {
- this.requestId = requestId;
- }
- public String getActor() {
- return actor;
- }
- public void setActor(String actor) {
- this.actor = actor;
- }
- public String getOperation() {
- return operation;
- }
- public void setOperation(String operation) {
- this.operation = operation;
- }
- public String getTarget() {
- return target;
- }
- public void setTarget(String target) {
- this.target = target;
- }
- public Timestamp getStarttime() {
- return starttime;
- }
- public void setStarttime(Timestamp starttime) {
- this.starttime = starttime;
- }
- public Timestamp getEndtime() {
- return endtime;
- }
- public void setEndtime(Timestamp endtime) {
- this.endtime = endtime;
- }
- public String getSubrequestId() {
- return subrequestId;
- }
- public void setSubrequestId(String subrequestId) {
- this.subrequestId = subrequestId;
- }
- public String getOutcome() {
- return outcome;
- }
- public void setOutcome(String outcome) {
- this.outcome = outcome;
- }
- public String getMessage() {
- return message;
- }
- public void setMessage(String message) {
- this.message = message;
- }
+ private static final long serialVersionUID = 1L;
+
+ @Id
+ @GeneratedValue
+ @Column(name = "ROWID")
+ public long rowid;
+
+ @Column(name = "CLNAME")
+ private String closedLoopName;
+
+ private String requestId;
+ private String actor;
+ private String operation;
+ private String target;
+ private Timestamp starttime;
+ private Timestamp endtime;
+ private String subrequestId;
+ private String outcome;
+ private String message;
+
+ public long getRowid() {
+ return rowid;
+ }
+
+ public void setRowid(long rowid) {
+ this.rowid = rowid;
+ }
+
+ public String getClosedLoopName() {
+ return closedLoopName;
+ }
+
+ public void setClosedLoopName(String closedLoopName) {
+ this.closedLoopName = closedLoopName;
+ }
+
+ public String getRequestId() {
+ return requestId;
+ }
+
+ public void setRequestId(String requestId) {
+ this.requestId = requestId;
+ }
+
+ public String getActor() {
+ return actor;
+ }
+
+ public void setActor(String actor) {
+ this.actor = actor;
+ }
+
+ public String getOperation() {
+ return operation;
+ }
+
+ public void setOperation(String operation) {
+ this.operation = operation;
+ }
+
+ public String getTarget() {
+ return target;
+ }
+
+ public void setTarget(String target) {
+ this.target = target;
+ }
+
+ public Timestamp getStarttime() {
+ return starttime;
+ }
+
+ public void setStarttime(Timestamp starttime) {
+ this.starttime = starttime;
+ }
+
+ public Timestamp getEndtime() {
+ return endtime;
+ }
+
+ public void setEndtime(Timestamp endtime) {
+ this.endtime = endtime;
+ }
+
+ public String getSubrequestId() {
+ return subrequestId;
+ }
+
+ public void setSubrequestId(String subrequestId) {
+ this.subrequestId = subrequestId;
+ }
+
+ public String getOutcome() {
+ return outcome;
+ }
+
+ public void setOutcome(String outcome) {
+ this.outcome = outcome;
+ }
+
+ public String getMessage() {
+ return message;
+ }
+
+ public void setMessage(String message) {
+ this.message = message;
+ }
}
diff --git a/controlloop/common/eventmanager/src/main/java/org/onap/policy/controlloop/impl/ControlLoopLoggerStdOutImpl.java b/controlloop/common/eventmanager/src/main/java/org/onap/policy/controlloop/impl/ControlLoopLoggerStdOutImpl.java
index 33042a915..fbff87fdd 100644
--- a/controlloop/common/eventmanager/src/main/java/org/onap/policy/controlloop/impl/ControlLoopLoggerStdOutImpl.java
+++ b/controlloop/common/eventmanager/src/main/java/org/onap/policy/controlloop/impl/ControlLoopLoggerStdOutImpl.java
@@ -2,7 +2,7 @@
* ============LICENSE_START=======================================================
* controlloop
* ================================================================================
- * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * Copyright (C) 2017-2018 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.
@@ -24,23 +24,23 @@ package org.onap.policy.controlloop.impl;
import org.onap.policy.controlloop.ControlLoopLogger;
public class ControlLoopLoggerStdOutImpl implements ControlLoopLogger {
- @Override
- public void info(String... parameters) {
- StringBuilder builder = new StringBuilder();
- for (String param : parameters) {
- builder.append(param);
- builder.append(" " );
- }
- System.out.println(builder.toString().trim());
- }
+ @Override
+ public void info(String... parameters) {
+ StringBuilder builder = new StringBuilder();
+ for (String param : parameters) {
+ builder.append(param);
+ builder.append(" ");
+ }
+ System.out.println(builder.toString().trim());
+ }
- @Override
- public void metrics(String... msgs) {
- this.info(msgs);
- }
+ @Override
+ public void metrics(String... msgs) {
+ this.info(msgs);
+ }
- @Override
- public void metrics(Object obj) {
- this.info(obj.toString());
- }
+ @Override
+ public void metrics(Object obj) {
+ this.info(obj.toString());
+ }
}
diff --git a/controlloop/common/eventmanager/src/main/java/org/onap/policy/controlloop/impl/ControlLoopPublisherJUnitImpl.java b/controlloop/common/eventmanager/src/main/java/org/onap/policy/controlloop/impl/ControlLoopPublisherJUnitImpl.java
index eb50ac36e..13f52e36e 100644
--- a/controlloop/common/eventmanager/src/main/java/org/onap/policy/controlloop/impl/ControlLoopPublisherJUnitImpl.java
+++ b/controlloop/common/eventmanager/src/main/java/org/onap/policy/controlloop/impl/ControlLoopPublisherJUnitImpl.java
@@ -2,7 +2,7 @@
* ============LICENSE_START=======================================================
* controlloop
* ================================================================================
- * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * Copyright (C) 2017-2018 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.
@@ -23,8 +23,9 @@ package org.onap.policy.controlloop.impl;
import org.onap.policy.controlloop.ControlLoopPublisher;
public class ControlLoopPublisherJUnitImpl implements ControlLoopPublisher {
- @Override
- public void publish(Object object) {
- throw new UnsupportedOperationException("publish() method is not implemented on " + this.getClass().getCanonicalName());
- }
+ @Override
+ public void publish(Object object) {
+ throw new UnsupportedOperationException(
+ "publish() method is not implemented on " + this.getClass().getCanonicalName());
+ }
}
diff --git a/controlloop/common/eventmanager/src/main/java/org/onap/policy/controlloop/processor/ControlLoopProcessor.java b/controlloop/common/eventmanager/src/main/java/org/onap/policy/controlloop/processor/ControlLoopProcessor.java
index 451244392..3dbc25fcf 100644
--- a/controlloop/common/eventmanager/src/main/java/org/onap/policy/controlloop/processor/ControlLoopProcessor.java
+++ b/controlloop/common/eventmanager/src/main/java/org/onap/policy/controlloop/processor/ControlLoopProcessor.java
@@ -2,7 +2,7 @@
* ============LICENSE_START=======================================================
* controlloop processor
* ================================================================================
- * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * Copyright (C) 2017-2018 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.
@@ -31,76 +31,96 @@ import org.yaml.snakeyaml.constructor.CustomClassLoaderConstructor;
public class ControlLoopProcessor {
- private final String yaml;
- private final ControlLoopPolicy policy;
- private String currentNestedPolicyID = null;
+ private final String yaml;
+ private final ControlLoopPolicy policy;
+ private String currentNestedPolicyId = null;
- public ControlLoopProcessor(String yaml) throws ControlLoopException {
- this.yaml = yaml;
- try {
- final Yaml y = new Yaml(new CustomClassLoaderConstructor(ControlLoopPolicy.class, ControlLoopPolicy.class.getClassLoader()));
- final Object obj = y.load(this.yaml);
+ /**
+ * Construct an instance from yaml.
+ *
+ * @param yaml the yaml
+ * @throws ControlLoopException if an error occurs
+ */
+ public ControlLoopProcessor(String yaml) throws ControlLoopException {
+ this.yaml = yaml;
+ try {
+ final Yaml y = new Yaml(new CustomClassLoaderConstructor(ControlLoopPolicy.class,
+ ControlLoopPolicy.class.getClassLoader()));
+ final Object obj = y.load(this.yaml);
- this.policy = (ControlLoopPolicy) obj;
- this.currentNestedPolicyID = this.policy.getControlLoop().getTrigger_policy();
- } catch (final Exception e) {
- //
- // Most likely this is a YAML Exception
- //
- throw new ControlLoopException(e);
- }
- }
+ this.policy = (ControlLoopPolicy) obj;
+ this.currentNestedPolicyId = this.policy.getControlLoop().getTrigger_policy();
+ } catch (final Exception e) {
+ //
+ // Most likely this is a YAML Exception
+ //
+ throw new ControlLoopException(e);
+ }
+ }
- public ControlLoop getControlLoop() {
- return this.policy.getControlLoop();
- }
+ public ControlLoop getControlLoop() {
+ return this.policy.getControlLoop();
+ }
- public FinalResult checkIsCurrentPolicyFinal() {
- return FinalResult.toResult(this.currentNestedPolicyID);
- }
+ public FinalResult checkIsCurrentPolicyFinal() {
+ return FinalResult.toResult(this.currentNestedPolicyId);
+ }
- public Policy getCurrentPolicy() throws ControlLoopException {
- if (this.policy == null || this.policy.getPolicies() == null) {
- throw new ControlLoopException("There are no policies defined.");
- }
+ /**
+ * Get the current policy.
+ *
+ * @return the current policy
+ * @throws ControlLoopException if an error occurs
+ */
+ public Policy getCurrentPolicy() throws ControlLoopException {
+ if (this.policy == null || this.policy.getPolicies() == null) {
+ throw new ControlLoopException("There are no policies defined.");
+ }
- for (final Policy nestedPolicy : this.policy.getPolicies()) {
- if (nestedPolicy.getId().equals(this.currentNestedPolicyID)) {
- return nestedPolicy;
- }
- }
- return null;
- }
+ for (final Policy nestedPolicy : this.policy.getPolicies()) {
+ if (nestedPolicy.getId().equals(this.currentNestedPolicyId)) {
+ return nestedPolicy;
+ }
+ }
+ return null;
+ }
- public void nextPolicyForResult(PolicyResult result) throws ControlLoopException {
- final Policy currentPolicy = this.getCurrentPolicy();
- try {
- if (currentPolicy == null) {
- throw new ControlLoopException("There is no current policy to determine where to go to.");
- }
- switch (result) {
- case SUCCESS:
- this.currentNestedPolicyID = currentPolicy.getSuccess();
- break;
- case FAILURE:
- this.currentNestedPolicyID = currentPolicy.getFailure();
- break;
- case FAILURE_TIMEOUT:
- this.currentNestedPolicyID = currentPolicy.getFailure_timeout();
- break;
- case FAILURE_RETRIES:
- this.currentNestedPolicyID = currentPolicy.getFailure_retries();
- break;
- case FAILURE_EXCEPTION:
- this.currentNestedPolicyID = currentPolicy.getFailure_exception();
- break;
- case FAILURE_GUARD:
- this.currentNestedPolicyID = currentPolicy.getFailure_guard();
- break;
- }
- } catch (final ControlLoopException e) {
- this.currentNestedPolicyID = FinalResult.FINAL_FAILURE_EXCEPTION.toString();
- throw e;
- }
- }
+ /**
+ * Get the next policy given a result of the current policy.
+ *
+ * @param result the result of the current policy
+ * @throws ControlLoopException if an error occurs
+ */
+ public void nextPolicyForResult(PolicyResult result) throws ControlLoopException {
+ final Policy currentPolicy = this.getCurrentPolicy();
+ try {
+ if (currentPolicy == null) {
+ throw new ControlLoopException("There is no current policy to determine where to go to.");
+ }
+ switch (result) {
+ case SUCCESS:
+ this.currentNestedPolicyId = currentPolicy.getSuccess();
+ break;
+ case FAILURE:
+ this.currentNestedPolicyId = currentPolicy.getFailure();
+ break;
+ case FAILURE_TIMEOUT:
+ this.currentNestedPolicyId = currentPolicy.getFailure_timeout();
+ break;
+ case FAILURE_RETRIES:
+ this.currentNestedPolicyId = currentPolicy.getFailure_retries();
+ break;
+ case FAILURE_EXCEPTION:
+ this.currentNestedPolicyId = currentPolicy.getFailure_exception();
+ break;
+ case FAILURE_GUARD:
+ default:
+ this.currentNestedPolicyId = currentPolicy.getFailure_guard();
+ break;
+ }
+ } catch (final ControlLoopException e) {
+ this.currentNestedPolicyId = FinalResult.FINAL_FAILURE_EXCEPTION.toString();
+ throw e;
+ }
+ }
}
diff --git a/controlloop/common/eventmanager/src/main/java/org/onap/policy/drools/PolicyEngine.java b/controlloop/common/eventmanager/src/main/java/org/onap/policy/drools/PolicyEngine.java
index 7acaf370d..3bf364ea4 100644
--- a/controlloop/common/eventmanager/src/main/java/org/onap/policy/drools/PolicyEngine.java
+++ b/controlloop/common/eventmanager/src/main/java/org/onap/policy/drools/PolicyEngine.java
@@ -2,7 +2,7 @@
* ============LICENSE_START=======================================================
* policy engine
* ================================================================================
- * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * Copyright (C) 2017-2018 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.
@@ -17,8 +17,9 @@
* limitations under the License.
* ============LICENSE_END=========================================================
*/
+
package org.onap.policy.drools;
public interface PolicyEngine {
- public boolean deliver(String busType, String topic, Object obj);
+ public boolean deliver(String busType, String topic, Object obj);
}
diff --git a/controlloop/common/eventmanager/src/main/java/org/onap/policy/drools/PolicyEngineListener.java b/controlloop/common/eventmanager/src/main/java/org/onap/policy/drools/PolicyEngineListener.java
index 5bd5d8d2c..419c31094 100644
--- a/controlloop/common/eventmanager/src/main/java/org/onap/policy/drools/PolicyEngineListener.java
+++ b/controlloop/common/eventmanager/src/main/java/org/onap/policy/drools/PolicyEngineListener.java
@@ -2,7 +2,7 @@
* ============LICENSE_START=======================================================
* policy engine
* ================================================================================
- * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * Copyright (C) 2017-2018 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.
@@ -20,14 +20,13 @@
package org.onap.policy.drools;
+@FunctionalInterface
public interface PolicyEngineListener {
/**
- * Any class that implements this interface will
- * be notified of a new event on the queue in the
- * PolicyEngineJUnitImpl
+ * Any class that implements this interface will be notified of a new event on the queue in the
+ * PolicyEngineJUnitImpl.
*
- * @param topic a key to the queue that contains
- * the event
+ * @param topic a key to the queue that contains the event
*/
public void newEventNotification(String topic);
}
diff --git a/controlloop/common/eventmanager/src/main/java/org/onap/policy/drools/impl/PolicyEngineJUnitImpl.java b/controlloop/common/eventmanager/src/main/java/org/onap/policy/drools/impl/PolicyEngineJUnitImpl.java
index e94657fee..d5f73c741 100644
--- a/controlloop/common/eventmanager/src/main/java/org/onap/policy/drools/impl/PolicyEngineJUnitImpl.java
+++ b/controlloop/common/eventmanager/src/main/java/org/onap/policy/drools/impl/PolicyEngineJUnitImpl.java
@@ -2,7 +2,7 @@
* ============LICENSE_START=======================================================
* policy engine
* ================================================================================
- * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * Copyright (C) 2017-2018 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.
@@ -31,111 +31,118 @@ import org.onap.policy.appc.Request;
import org.onap.policy.appclcm.LCMRequestWrapper;
import org.onap.policy.controlloop.ControlLoopNotification;
import org.onap.policy.controlloop.util.Serialization;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
import org.onap.policy.drools.PolicyEngine;
import org.onap.policy.drools.PolicyEngineListener;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
public class PolicyEngineJUnitImpl implements PolicyEngine {
- private static final Logger logger = LoggerFactory.getLogger(PolicyEngineJUnitImpl.class);
- private Map<String, Map<String, Queue<Object>>> busMap = new HashMap<>();
- private List<PolicyEngineListener> listeners = new ArrayList<>();
+ private static final Logger logger = LoggerFactory.getLogger(PolicyEngineJUnitImpl.class);
+ private Map<String, Map<String, Queue<Object>>> busMap = new HashMap<>();
+ private List<PolicyEngineListener> listeners = new ArrayList<>();
- /**
- * Adds all objects that implement PolicyEngineListener
- * to the notification list when an event occurs
- *
- * @param listener an object that is interest in knowing
- * about events published to the PolicyEngine
- */
- public void addListener(PolicyEngineListener listener) {
- listeners.add(listener);
- }
+ /**
+ * Adds all objects that implement PolicyEngineListener to the notification list when an event
+ * occurs.
+ *
+ * @param listener an object that is interest in knowing about events published to the
+ * PolicyEngine
+ */
+ public void addListener(PolicyEngineListener listener) {
+ listeners.add(listener);
+ }
- /**
- * Notifies all listeners about a new event
- * @param topic the topic in which the notification
- * was sent to
- */
- public void notifyListeners(String topic) {
- for (PolicyEngineListener listener: listeners) {
- listener.newEventNotification(topic);
- }
- }
+ /**
+ * Notifies all listeners about a new event.
+ *
+ * @param topic the topic in which the notification was sent to
+ */
+ public void notifyListeners(String topic) {
+ for (PolicyEngineListener listener : listeners) {
+ listener.newEventNotification(topic);
+ }
+ }
- @Override
- public boolean deliver(String busType, String topic, Object obj) {
- if (obj instanceof ControlLoopNotification) {
- ControlLoopNotification notification = (ControlLoopNotification) obj;
- if (logger.isDebugEnabled()) {
- logger.debug(Serialization.gsonPretty.toJson(notification));
- }
- }
- if (obj instanceof Request) {
- Request request = (Request) obj;
- logger.debug("Request: {} subrequest {}", request.getAction(), request.getCommonHeader().getSubRequestID());
- }
- else if (obj instanceof LCMRequestWrapper) {
- LCMRequestWrapper dmaapRequest = (LCMRequestWrapper) obj;
- logger.debug("Request: {} subrequest {}", dmaapRequest.getBody().getAction(), dmaapRequest.getBody().getCommonHeader().getSubRequestId());
- }
- //
- // Does the bus exist?
- //
- if (!busMap.containsKey(busType)) {
- logger.debug("creating new bus type {}", busType);
- //
- // Create the bus
- //
- busMap.put(busType, new HashMap<>());
- }
- //
- // Get the bus
- //
- Map<String, Queue<Object>> topicMap = busMap.get(busType);
- //
- // Does the topic exist?
- //
- if (!topicMap.containsKey(topic)) {
- logger.debug("creating new topic {}", topic);
- //
- // Create the topic
- //
- topicMap.put(topic, new LinkedList<>());
- }
- //
- // Get the topic queue
- //
- logger.debug("queueing");
- boolean res = topicMap.get(topic).add(obj);
- notifyListeners(topic);
- return res;
- }
+ @Override
+ public boolean deliver(String busType, String topic, Object obj) {
+ if (obj instanceof ControlLoopNotification) {
+ ControlLoopNotification notification = (ControlLoopNotification) obj;
+ if (logger.isDebugEnabled()) {
+ logger.debug(Serialization.gsonPretty.toJson(notification));
+ }
+ }
+ if (obj instanceof Request) {
+ Request request = (Request) obj;
+ logger.debug("Request: {} subrequest {}", request.getAction(), request.getCommonHeader().getSubRequestID());
+ } else if (obj instanceof LCMRequestWrapper) {
+ LCMRequestWrapper dmaapRequest = (LCMRequestWrapper) obj;
+ logger.debug("Request: {} subrequest {}", dmaapRequest.getBody().getAction(),
+ dmaapRequest.getBody().getCommonHeader().getSubRequestId());
+ }
+ //
+ // Does the bus exist?
+ //
+ if (!busMap.containsKey(busType)) {
+ logger.debug("creating new bus type {}", busType);
+ //
+ // Create the bus
+ //
+ busMap.put(busType, new HashMap<>());
+ }
+ //
+ // Get the bus
+ //
+ Map<String, Queue<Object>> topicMap = busMap.get(busType);
+ //
+ // Does the topic exist?
+ //
+ if (!topicMap.containsKey(topic)) {
+ logger.debug("creating new topic {}", topic);
+ //
+ // Create the topic
+ //
+ topicMap.put(topic, new LinkedList<>());
+ }
+ //
+ // Get the topic queue
+ //
+ logger.debug("queueing");
+ boolean res = topicMap.get(topic).add(obj);
+ notifyListeners(topic);
+ return res;
+ }
- public Object subscribe(String busType, String topic) {
- //
- // Does the bus exist?
- //
- if (busMap.containsKey(busType)) {
- //
- // Get the bus
- //
- Map<String, Queue<Object>> topicMap = busMap.get(busType);
- //
- // Does the topic exist?
- //
- if (topicMap.containsKey(topic)) {
- logger.debug("The queue has {}", topicMap.get(topic).size());
- return topicMap.get(topic).poll();
- } else {
- logger.error("No topic exists {}", topic);
- }
- } else {
- logger.error("No bus exists {}", busType);
- }
- return null;
- }
+ /**
+ * Subscribe to a topic on a bus.
+ *
+ * @param busType the bus type
+ * @param topic the topic
+ * @return the head of the queue, or <code>null</code> if the queue or bus does not exist or the
+ * queue is empty
+ */
+ public Object subscribe(String busType, String topic) {
+ //
+ // Does the bus exist?
+ //
+ if (busMap.containsKey(busType)) {
+ //
+ // Get the bus
+ //
+ Map<String, Queue<Object>> topicMap = busMap.get(busType);
+ //
+ // Does the topic exist?
+ //
+ if (topicMap.containsKey(topic)) {
+ logger.debug("The queue has {}", topicMap.get(topic).size());
+ return topicMap.get(topic).poll();
+ } else {
+ logger.error("No topic exists {}", topic);
+ }
+ } else {
+ logger.error("No bus exists {}", busType);
+ }
+ return null;
+ }
}