import java.time.Instant;
import java.util.AbstractMap;
import java.util.LinkedList;
+import java.util.Properties;
import javax.persistence.EntityManager;
import javax.persistence.Persistence;
+import org.eclipse.persistence.config.PersistenceUnitProperties;
+import org.onap.policy.aai.util.AAIException;
import org.onap.policy.appc.Response;
import org.onap.policy.appc.ResponseCode;
import org.onap.policy.appclcm.LCMResponseWrapper;
import org.onap.policy.controlloop.ControlLoopOperation;
import org.onap.policy.controlloop.VirtualControlLoopEvent;
import org.onap.policy.controlloop.actor.appc.APPCActorServiceProvider;
+import org.onap.policy.controlloop.actor.appclcm.AppcLcmActorServiceProvider;
+import org.onap.policy.controlloop.actor.so.SOActorServiceProvider;
import org.onap.policy.controlloop.actor.vfc.VFCActorServiceProvider;
import org.onap.policy.controlloop.policy.Policy;
import org.onap.policy.controlloop.policy.PolicyResult;
-import org.onap.policy.controlloop.actor.so.SOActorServiceProvider;
+import org.onap.policy.drools.system.PolicyEngine;
+import org.onap.policy.guard.Util;
import org.onap.policy.so.SOResponse;
+import org.onap.policy.vfc.VFCResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import org.onap.policy.controlloop.actor.appclcm.AppcLcmActorServiceProvider;
public class ControlLoopOperationManager implements Serializable {
//
//public final ATTControlLoopEvent onset;
public final ControlLoopEvent onset;
- public final Policy policy;
+ public final transient Policy policy;
//
// Properties used to track the Operation
//
private int attempts = 0;
- private Operation currentOperation = null;
+ private transient Operation currentOperation = null;
private LinkedList<Operation> operationHistory = new LinkedList<Operation>();
private PolicyResult policyResult = null;
private ControlLoopEventManager eventManager = null;
+ private String targetEntity;
public ControlLoopEventManager getEventManager() {
return eventManager;
this.eventManager = eventManager;
}
+ public String getTargetEntity() {
+ return this.targetEntity;
+ }
//
// Internal class used for tracking
}
private String guardApprovalStatus = "NONE";//"NONE", "PERMIT", "DENY"
- private Object operationRequest;
+ private transient Object operationRequest;
public Object getOperationRequest() {
return operationRequest;
this.guardApprovalStatus = guardApprovalStatus;
}
-
- public ControlLoopOperationManager(ControlLoopEvent onset, Policy policy, ControlLoopEventManager em) throws ControlLoopException {
+ public String getTarget(Policy policy) throws ControlLoopException, AAIException {
+ if (policy.getTarget() != null) {
+ if (policy.getTarget().getType() != null) {
+ switch(policy.getTarget().getType()) {
+ case PNF:
+ break;
+ case VM:
+ case VNF:
+ VirtualControlLoopEvent virtualOnset = (VirtualControlLoopEvent) this.onset;
+ if (this.onset.target.equalsIgnoreCase("vserver.vserver-name")) {
+ return virtualOnset.AAI.get("vserver.vserver-name");
+ }
+ else if (this.onset.target.equalsIgnoreCase("generic-vnf.vnf-id")) {
+ return virtualOnset.AAI.get("generic-vnf.vnf-id");
+ }
+ else if (this.onset.target.equalsIgnoreCase("generic-vnf.vnf-name")) {
+ /*
+ * 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().vnfID;
+ if (vnfId == null) {
+ throw new AAIException("No vnf-id found");
+ }
+ return vnfId;
+ }
+ break;
+ default:
+ throw new ControlLoopException("The target type is not supported");
+ }
+ }
+ else {
+ throw new ControlLoopException("The target type is null");
+ }
+ }
+ else {
+ throw new ControlLoopException("The target is null");
+ }
+ throw new ControlLoopException("Target does not match target type");
+ }
+
+ 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;
+ break;
case "VFC":
break;
default:
}
}
- public Object startOperation(/*VirtualControlLoopEvent*/ControlLoopEvent onset) {
+ public Object startOperation(/*VirtualControlLoopEvent*/ControlLoopEvent onset) throws AAIException {
//
// They shouldn't call us if we currently running something
//
this.policyResult = null;
Operation operation = new Operation();
operation.attempt = ++this.attempts;
- operation.operation.actor = this.policy.getActor().toString();
+ operation.operation.actor = this.policy.getActor();
operation.operation.operation = this.policy.getRecipe();
operation.operation.target = this.policy.getTarget().toString();
operation.operation.subRequestId = Integer.toString(operation.attempt);
* request is constructed. Otherwise an LCMRequest
* is constructed.
*/
+ this.currentOperation = operation;
if ("ModifyConfig".equalsIgnoreCase(policy.getRecipe())) {
- this.operationRequest = APPCActorServiceProvider.constructRequest((VirtualControlLoopEvent)onset, operation.operation, this.policy);
+ this.operationRequest = APPCActorServiceProvider.constructRequest((VirtualControlLoopEvent) onset,
+ operation.operation, this.policy, this.targetEntity);
}
else {
- this.operationRequest = AppcLcmActorServiceProvider.constructRequest((VirtualControlLoopEvent) onset, operation.operation, this.policy);
+ this.operationRequest = AppcLcmActorServiceProvider.constructRequest((VirtualControlLoopEvent) onset,
+ operation.operation, this.policy, this.targetEntity);
}
//
// Save the operation
//
- this.currentOperation = operation;
+
return operationRequest;
case "SO":
SOActorServiceProvider SOAsp = new SOActorServiceProvider();
this.operationRequest = SOAsp.constructRequest((VirtualControlLoopEvent)onset, operation.operation, 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.operation, this.policy);
- this.currentOperation = operation;
- return operationRequest;
+ this.operationRequest = VFCActorServiceProvider.constructRequest((VirtualControlLoopEvent) onset, operation.operation, this.policy, this.eventManager.getVnfResponse());
+ this.currentOperation = operation;
+ if (this.operationRequest == null) {
+ this.policyResult = PolicyResult.FAILURE;
+ }
+ return operationRequest;
}
return null;
return null;
} else if (response instanceof SOResponse) {
SOResponse msoResponse = (SOResponse) response;
+
switch (msoResponse.httpResponseCode) {
case 200:
case 202:
//
// Consider it as success
//
- this.completeOperation(new Integer(1), msoResponse.httpResponseCode + " Success", PolicyResult.SUCCESS);
+ this.completeOperation(this.attempts, msoResponse.httpResponseCode + " Success", PolicyResult.SUCCESS);
if (this.policyResult != null && this.policyResult.equals(PolicyResult.FAILURE_TIMEOUT)) {
return null;
}
//
// Consider it as failure
//
- this.completeOperation(new Integer(1), msoResponse.httpResponseCode + " Failed", PolicyResult.FAILURE);
+ this.completeOperation(this.attempts, msoResponse.httpResponseCode + " Failed", PolicyResult.FAILURE);
if (this.policyResult != null && this.policyResult.equals(PolicyResult.FAILURE_TIMEOUT)) {
return null;
}
return PolicyResult.FAILURE;
}
-
+
+ } else if (response instanceof VFCResponse) {
+ VFCResponse vfcResponse = (VFCResponse) response;
+
+ if (vfcResponse.responseDescriptor.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;
+ }
}
-
return null;
}
if (this.currentOperation != null && this.currentOperation.operation != null) {
return this.currentOperation.operation.toMessage();
}
- if (this.operationHistory != null && this.operationHistory.size() > 0) {
+
+ if (!this.operationHistory.isEmpty()) {
return this.operationHistory.getLast().operation.toMessage();
}
return null;
if (this.currentOperation != null && this.currentOperation.operation != null) {
return this.currentOperation.operation.toMessage()+ ", Guard result: " + guardResult;
}
- if (this.operationHistory != null && this.operationHistory.size() > 0) {
+
+ if (!this.operationHistory.isEmpty()) {
return this.operationHistory.getLast().operation.toMessage() + ", Guard result: " + guardResult;
}
return null;
if (this.currentOperation != null && this.currentOperation.operation != null) {
return this.currentOperation.operation.toHistory();
}
- if (this.operationHistory != null && this.operationHistory.size() > 0) {
+
+ if (!this.operationHistory.isEmpty()) {
return this.operationHistory.getLast().operation.toHistory();
}
return null;
//
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() {
//
}
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).createEntityManager();
+ em = Persistence.createEntityManagerFactory(OpsHistPU, props).createEntityManager();
}catch(Exception e){
logger.error("storeOperationInDataBase threw: ", e);
return;
newEntry.requestId = this.onset.requestID.toString();
newEntry.actor = this.currentOperation.operation.actor;
newEntry.operation = this.currentOperation.operation.operation;
- newEntry.target = this.eventManager.getTargetInstance(this.policy);
+ newEntry.target = this.targetEntity;
newEntry.starttime = Timestamp.from(this.currentOperation.operation.start);
newEntry.subrequestId = this.currentOperation.operation.subRequestId;
newEntry.endtime = new Timestamp(this.currentOperation.operation.end.toEpochMilli());