2 * ============LICENSE_START=======================================================
3 * controlloop operation manager
4 * ================================================================================
5 * Copyright (C) 2017-2019 AT&T Intellectual Property. All rights reserved.
6 * Modifications Copyright (C) 2019 Huawei Technologies Co., Ltd. All rights reserved.
7 * ================================================================================
8 * Licensed under the Apache License, Version 2.0 (the "License");
9 * you may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
12 * http://www.apache.org/licenses/LICENSE-2.0
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
19 * ============LICENSE_END=========================================================
22 package org.onap.policy.controlloop.eventmanager;
24 import java.io.Serializable;
25 import java.sql.Timestamp;
26 import java.time.Instant;
27 import java.util.AbstractMap;
28 import java.util.LinkedList;
29 import java.util.List;
30 import java.util.NoSuchElementException;
31 import java.util.Properties;
32 import javax.persistence.EntityManager;
33 import javax.persistence.Persistence;
34 import org.eclipse.persistence.config.PersistenceUnitProperties;
35 import org.onap.policy.aai.util.AaiException;
36 import org.onap.policy.appc.Response;
37 import org.onap.policy.appc.ResponseCode;
38 import org.onap.policy.appclcm.LcmResponseWrapper;
39 import org.onap.policy.controlloop.ControlLoopEvent;
40 import org.onap.policy.controlloop.ControlLoopException;
41 import org.onap.policy.controlloop.ControlLoopOperation;
42 import org.onap.policy.controlloop.ControlLoopResponse;
43 import org.onap.policy.controlloop.VirtualControlLoopEvent;
44 import org.onap.policy.controlloop.actor.appc.AppcActorServiceProvider;
45 import org.onap.policy.controlloop.actor.appclcm.AppcLcmActorServiceProvider;
46 import org.onap.policy.controlloop.actor.sdnc.SdncActorServiceProvider;
47 import org.onap.policy.controlloop.actor.sdnr.SdnrActorServiceProvider;
48 import org.onap.policy.controlloop.actor.so.SoActorServiceProvider;
49 import org.onap.policy.controlloop.actor.vfc.VfcActorServiceProvider;
50 import org.onap.policy.controlloop.policy.Policy;
51 import org.onap.policy.controlloop.policy.PolicyResult;
52 import org.onap.policy.drools.system.PolicyEngine;
53 import org.onap.policy.guard.Util;
54 import org.onap.policy.sdnc.SdncResponse;
55 import org.onap.policy.sdnr.PciResponseWrapper;
56 import org.onap.policy.so.SoResponseWrapper;
57 import org.onap.policy.vfc.VfcResponse;
58 import org.slf4j.Logger;
59 import org.slf4j.LoggerFactory;
61 public class ControlLoopOperationManager implements Serializable {
62 private static final long serialVersionUID = -3773199283624595410L;
63 private static final Logger logger = LoggerFactory.getLogger(ControlLoopOperationManager.class);
65 private static final String VSERVER_VSERVER_NAME = "vserver.vserver-name";
66 private static final String GENERIC_VNF_VNF_NAME = "generic-vnf.vnf-name";
67 private static final String GENERIC_VNF_VNF_ID = "generic-vnf.vnf-id";
70 // These properties are not changeable, but accessible
71 // for Drools Rule statements.
73 public final ControlLoopEvent onset;
74 public final Policy policy;
77 // Properties used to track the Operation
79 private int attempts = 0;
80 private Operation currentOperation = null;
81 private LinkedList<Operation> operationHistory = new LinkedList<>();
82 private PolicyResult policyResult = null;
83 private ControlLoopEventManager eventManager = null;
84 private String targetEntity;
85 private String guardApprovalStatus = "NONE";// "NONE", "PERMIT", "DENY"
86 private transient Object operationRequest;
89 * Construct an instance.
91 * @param onset the onset event
92 * @param policy the policy
93 * @param em the event manager
94 * @throws ControlLoopException if an error occurs
95 * @throws AaiException if an error occurs retrieving information from A&AI
97 public ControlLoopOperationManager(ControlLoopEvent onset, Policy policy, ControlLoopEventManager em)
98 throws ControlLoopException, AaiException {
100 this.policy = policy;
101 this.guardApprovalStatus = "NONE";
102 this.eventManager = em;
103 this.targetEntity = getTarget(policy);
106 // Let's make a sanity check
108 switch (policy.getActor()) {
110 if ("ModifyConfig".equalsIgnoreCase(policy.getRecipe())) {
112 * The target vnf-id may not be the same as the source vnf-id specified in the
113 * yaml, the target vnf-id is retrieved by a named query to A&AI.
115 String targetVnf = AppcLcmActorServiceProvider.vnfNamedQuery(policy.getTarget().getResourceID(),
116 this.targetEntity, PolicyEngine.manager.getEnvironmentProperty("aai.url"),
117 PolicyEngine.manager.getEnvironmentProperty("aai.username"),
118 PolicyEngine.manager.getEnvironmentProperty("aai.password"));
119 this.targetEntity = targetVnf;
131 throw new ControlLoopException("ControlLoopEventManager: policy has an unknown actor.");
135 public ControlLoopEventManager getEventManager() {
139 public void setEventManager(ControlLoopEventManager eventManager) {
140 this.eventManager = eventManager;
143 public String getTargetEntity() {
144 return this.targetEntity;
148 public String toString() {
149 return "ControlLoopOperationManager [onset=" + (onset != null ? onset.getRequestId() : "null") + ", policy="
150 + (policy != null ? policy.getId() : "null") + ", attempts=" + attempts + ", policyResult="
151 + policyResult + ", currentOperation=" + currentOperation + ", operationHistory=" + operationHistory
156 // Internal class used for tracking
158 private class Operation implements Serializable {
159 private static final long serialVersionUID = 1L;
161 private ControlLoopOperation clOperation = new ControlLoopOperation();
162 private PolicyResult policyResult = null;
163 private int attempt = 0;
166 public String toString() {
167 return "Operation [attempt=" + attempt + ", policyResult=" + policyResult + ", operation=" + clOperation
172 public Object getOperationRequest() {
173 return operationRequest;
176 public String getGuardApprovalStatus() {
177 return guardApprovalStatus;
180 public void setGuardApprovalStatus(String guardApprovalStatus) {
181 this.guardApprovalStatus = guardApprovalStatus;
185 * Get the target for a policy.
187 * @param policy the policy
189 * @throws ControlLoopException if an error occurs
190 * @throws AaiException if an error occurs retrieving information from A&AI
192 public String getTarget(Policy policy) throws ControlLoopException, AaiException {
193 if (policy.getTarget() == null) {
194 throw new ControlLoopException("The target is null");
197 if (policy.getTarget().getType() == null) {
198 throw new ControlLoopException("The target type is null");
201 switch (policy.getTarget().getType()) {
203 throw new ControlLoopException("PNF target is not supported");
206 VirtualControlLoopEvent virtualOnset = (VirtualControlLoopEvent) this.onset;
207 if (this.onset.getTarget().equalsIgnoreCase(VSERVER_VSERVER_NAME)) {
208 return virtualOnset.getAai().get(VSERVER_VSERVER_NAME);
209 } else if (this.onset.getTarget().equalsIgnoreCase(GENERIC_VNF_VNF_ID)) {
210 return virtualOnset.getAai().get(GENERIC_VNF_VNF_ID);
211 } else if (this.onset.getTarget().equalsIgnoreCase(GENERIC_VNF_VNF_NAME)) {
213 * If the onset is enriched with the vnf-id, we don't need an A&AI response
215 if (virtualOnset.getAai().containsKey(GENERIC_VNF_VNF_ID)) {
216 return virtualOnset.getAai().get(GENERIC_VNF_VNF_ID);
220 * If the vnf-name was retrieved from the onset then the vnf-id must be obtained
221 * from the event manager's A&AI GET query
223 String vnfId = this.eventManager.getVnfResponse().getVnfId();
225 throw new AaiException("No vnf-id found");
229 throw new ControlLoopException("Target does not match target type");
231 throw new ControlLoopException("The target type is not supported");
236 * Start an operation.
238 * @param onset the onset event
239 * @return the operation request
240 * @throws ControlLoopException if an error occurs
242 public Object startOperation(/* VirtualControlLoopEvent */ControlLoopEvent onset) throws ControlLoopException {
243 verifyOperatonCanRun();
248 this.policyResult = null;
249 Operation operation = new Operation();
250 operation.attempt = ++this.attempts;
251 operation.clOperation.setActor(this.policy.getActor());
252 operation.clOperation.setOperation(this.policy.getRecipe());
253 operation.clOperation.setTarget(this.policy.getTarget().toString());
254 operation.clOperation.setSubRequestId(Integer.toString(operation.attempt));
256 // Now determine which actor we need to construct a request for
258 switch (policy.getActor()) {
261 * If the recipe is ModifyConfig, a legacy APPC request is constructed. Otherwise an
262 * LCMRequest is constructed.
264 this.currentOperation = operation;
265 if ("ModifyConfig".equalsIgnoreCase(policy.getRecipe())) {
266 this.operationRequest = AppcActorServiceProvider.constructRequest((VirtualControlLoopEvent) onset,
267 operation.clOperation, this.policy, this.targetEntity);
269 this.operationRequest = AppcLcmActorServiceProvider.constructRequest(
270 (VirtualControlLoopEvent) onset, operation.clOperation, this.policy, this.targetEntity);
273 // Save the operation
276 return operationRequest;
278 SoActorServiceProvider soActorSp = new SoActorServiceProvider();
279 this.operationRequest = soActorSp.constructRequest((VirtualControlLoopEvent) onset,
280 operation.clOperation, this.policy, eventManager.getNqVserverFromAai());
282 // Save the operation
283 this.currentOperation = operation;
285 if (this.operationRequest == null) {
286 this.policyResult = PolicyResult.FAILURE;
289 return operationRequest;
291 this.operationRequest = VfcActorServiceProvider.constructRequest((VirtualControlLoopEvent) onset,
292 operation.clOperation, this.policy, this.eventManager.getVnfResponse(),
293 PolicyEngine.manager.getEnvironmentProperty("vfc.url"),
294 PolicyEngine.manager.getEnvironmentProperty("vfc.username"),
295 PolicyEngine.manager.getEnvironmentProperty("vfc.password"));
296 this.currentOperation = operation;
297 if (this.operationRequest == null) {
298 this.policyResult = PolicyResult.FAILURE;
300 return operationRequest;
303 * If the recipe is ModifyConfig or ModifyConfigANR, a SDNR request is constructed.
305 this.currentOperation = operation;
306 this.operationRequest = SdnrActorServiceProvider.constructRequest((VirtualControlLoopEvent) onset,
307 operation.clOperation, this.policy);
309 // Save the operation
311 if (this.operationRequest == null) {
312 this.policyResult = PolicyResult.FAILURE;
315 return operationRequest;
317 SdncActorServiceProvider provider = new SdncActorServiceProvider();
318 this.operationRequest = provider.constructRequest((VirtualControlLoopEvent) onset,
319 operation.clOperation, this.policy);
320 this.currentOperation = operation;
321 if (this.operationRequest == null) {
322 this.policyResult = PolicyResult.FAILURE;
324 return operationRequest;
326 throw new ControlLoopException("invalid actor " + policy.getActor() + " on policy");
333 * @param response the response
334 * @return a PolicyResult
336 public PolicyResult onResponse(Object response) {
338 // Which response is it?
340 if (response instanceof Response) {
342 // Cast APPC response and handle it
344 return onResponse((Response) response);
345 } else if (response instanceof LcmResponseWrapper) {
347 // Cast LCM response and handle it
349 return onResponse((LcmResponseWrapper) response);
350 } else if (response instanceof PciResponseWrapper) {
352 // Cast SDNR response and handle it
354 return onResponse((PciResponseWrapper) response);
355 } else if (response instanceof SoResponseWrapper) {
357 // Cast SO response and handle it
359 return onResponse((SoResponseWrapper) response);
360 } else if (response instanceof VfcResponse) {
362 // Cast VFC response and handle it
364 return onResponse((VfcResponse) response);
365 } else if (response instanceof SdncResponse) {
367 // Cast SDNC response and handle it
369 return onResponse((SdncResponse) response);
376 * This method handles operation responses from APPC.
378 * @param appcResponse the APPC response
379 * @return The result of the response handling
381 private PolicyResult onResponse(Response appcResponse) {
383 // Determine which subrequestID (ie. attempt)
385 Integer operationAttempt = null;
387 operationAttempt = Integer.parseInt(appcResponse.getCommonHeader().getSubRequestId());
388 } catch (NumberFormatException e) {
390 // We cannot tell what happened if this doesn't exist
392 this.completeOperation(operationAttempt, "Policy was unable to parse APP-C SubRequestID (it was null).",
393 PolicyResult.FAILURE_EXCEPTION);
394 return PolicyResult.FAILURE_EXCEPTION;
397 // Sanity check the response message
399 if (appcResponse.getStatus() == null) {
401 // We cannot tell what happened if this doesn't exist
403 this.completeOperation(operationAttempt,
404 "Policy was unable to parse APP-C response status field (it was null).",
405 PolicyResult.FAILURE_EXCEPTION);
406 return PolicyResult.FAILURE_EXCEPTION;
409 // Get the Response Code
411 ResponseCode code = ResponseCode.toResponseCode(appcResponse.getStatus().getCode());
414 // We are unaware of this code
416 this.completeOperation(operationAttempt, "Policy was unable to parse APP-C response status code field.",
417 PolicyResult.FAILURE_EXCEPTION);
418 return PolicyResult.FAILURE_EXCEPTION;
421 // Ok, let's figure out what APP-C's response is
426 // This is good, they got our original message and
429 // Is there any need to track this?
435 // We'll consider these two codes as exceptions
437 this.completeOperation(operationAttempt, appcResponse.getStatus().getDescription(),
438 PolicyResult.FAILURE_EXCEPTION);
439 if (this.policyResult != null && this.policyResult.equals(PolicyResult.FAILURE_TIMEOUT)) {
442 return PolicyResult.FAILURE_EXCEPTION;
447 this.completeOperation(operationAttempt, appcResponse.getStatus().getDescription(),
448 PolicyResult.SUCCESS);
449 if (this.policyResult != null && this.policyResult.equals(PolicyResult.FAILURE_TIMEOUT)) {
452 return PolicyResult.SUCCESS;
457 this.completeOperation(operationAttempt, appcResponse.getStatus().getDescription(),
458 PolicyResult.FAILURE);
459 if (this.policyResult != null && this.policyResult.equals(PolicyResult.FAILURE_TIMEOUT)) {
462 return PolicyResult.FAILURE;
469 * This method handles operation responses from LCM.
471 * @param dmaapResponse the LCM response
472 * @return The result of the response handling
474 private PolicyResult onResponse(LcmResponseWrapper dmaapResponse) {
476 * Parse out the operation attempt using the subrequestid
478 Integer operationAttempt = AppcLcmActorServiceProvider
479 .parseOperationAttempt(dmaapResponse.getBody().getCommonHeader().getSubRequestId());
480 if (operationAttempt == null) {
481 this.completeOperation(operationAttempt, "Policy was unable to parse APP-C SubRequestID (it was null).",
482 PolicyResult.FAILURE_EXCEPTION);
486 * Process the APPCLCM response to see what PolicyResult should be returned
488 AbstractMap.SimpleEntry<PolicyResult, String> result =
489 AppcLcmActorServiceProvider.processResponse(dmaapResponse);
491 if (result.getKey() != null) {
492 this.completeOperation(operationAttempt, result.getValue(), result.getKey());
493 if (PolicyResult.FAILURE_TIMEOUT.equals(this.policyResult)) {
496 return result.getKey();
502 * This method handles operation responses from SDNR.
504 * @param dmaapResponse the SDNR response
505 * @return the result of the response handling
507 private PolicyResult onResponse(PciResponseWrapper dmaapResponse) {
509 * Parse out the operation attempt using the subrequestid
511 Integer operationAttempt = SdnrActorServiceProvider
512 .parseOperationAttempt(dmaapResponse.getBody().getCommonHeader().getSubRequestId());
513 if (operationAttempt == null) {
514 this.completeOperation(operationAttempt, "Policy was unable to parse SDNR SubRequestID.",
515 PolicyResult.FAILURE_EXCEPTION);
519 * Process the SDNR response to see what PolicyResult should be returned
521 SdnrActorServiceProvider.Pair<PolicyResult, String> result =
522 SdnrActorServiceProvider.processResponse(dmaapResponse);
524 if (result.getResult() != null) {
525 this.completeOperation(operationAttempt, result.getMessage(), result.getResult());
526 if (PolicyResult.FAILURE_TIMEOUT.equals(this.policyResult)) {
529 return result.getResult();
535 * This method handles operation responses from SO.
537 * @param msoResponse the SO response
538 * @return The result of the response handling
540 private PolicyResult onResponse(SoResponseWrapper msoResponse) {
541 switch (msoResponse.getSoResponse().getHttpResponseCode()) {
545 // Consider it as success
547 this.completeOperation(this.attempts, msoResponse.getSoResponse().getHttpResponseCode() + " Success",
548 PolicyResult.SUCCESS);
549 if (this.policyResult != null && this.policyResult.equals(PolicyResult.FAILURE_TIMEOUT)) {
552 return PolicyResult.SUCCESS;
555 // Consider it as failure
557 this.completeOperation(this.attempts, msoResponse.getSoResponse().getHttpResponseCode() + " Failed",
558 PolicyResult.FAILURE);
559 if (this.policyResult != null && this.policyResult.equals(PolicyResult.FAILURE_TIMEOUT)) {
562 return PolicyResult.FAILURE;
567 * This method handles operation responses from VFC.
569 * @param vfcResponse the VFC response
570 * @return The result of the response handling
572 private PolicyResult onResponse(VfcResponse vfcResponse) {
573 if ("finished".equalsIgnoreCase(vfcResponse.getResponseDescriptor().getStatus())) {
575 // Consider it as success
577 this.completeOperation(this.attempts, " Success", PolicyResult.SUCCESS);
578 if (this.policyResult != null && this.policyResult.equals(PolicyResult.FAILURE_TIMEOUT)) {
581 return PolicyResult.SUCCESS;
584 // Consider it as failure
586 this.completeOperation(this.attempts, " Failed", PolicyResult.FAILURE);
587 if (this.policyResult != null && this.policyResult.equals(PolicyResult.FAILURE_TIMEOUT)) {
590 // increment operation attempts for retries
592 return PolicyResult.FAILURE;
597 * This method handles operation responses from SDNC.
599 * @param sdncResponse the VFC response
600 * @return The result of the response handling
602 private PolicyResult onResponse(SdncResponse sdncResponse) {
603 if ("200".equals(sdncResponse.getResponseOutput().getResponseCode())) {
605 // Consider it as success
607 this.completeOperation(this.attempts, " Success", PolicyResult.SUCCESS);
608 if (this.policyResult != null && this.policyResult.equals(PolicyResult.FAILURE_TIMEOUT)) {
611 return PolicyResult.SUCCESS;
614 // Consider it as failure
616 this.completeOperation(this.attempts, " Failed", PolicyResult.FAILURE);
617 if (this.policyResult != null && this.policyResult.equals(PolicyResult.FAILURE_TIMEOUT)) {
620 // increment operation attempts for retries
622 return PolicyResult.FAILURE;
627 * Get the operation timeout.
629 * @return the timeout
631 public Integer getOperationTimeout() {
635 if (this.policy == null) {
636 logger.debug("getOperationTimeout returning 0");
639 logger.debug("getOperationTimeout returning {}", this.policy.getTimeout());
640 return this.policy.getTimeout();
644 * Get the operation timeout as a String.
646 * @param defaultTimeout the default timeout
647 * @return the timeout as a String
649 public String getOperationTimeoutString(int defaultTimeout) {
650 Integer to = this.getOperationTimeout();
651 if (to == null || to == 0) {
652 return Integer.toString(defaultTimeout) + "s";
654 return to.toString() + "s";
657 public PolicyResult getOperationResult() {
658 return this.policyResult;
662 * Get the operation as a message.
664 * @return the operation as a message
666 public String getOperationMessage() {
667 if (this.currentOperation != null && this.currentOperation.clOperation != null) {
668 return this.currentOperation.clOperation.toMessage();
671 if (!this.operationHistory.isEmpty()) {
672 return this.operationHistory.getLast().clOperation.toMessage();
678 * Get the operation as a message including the guard result.
680 * @param guardResult the guard result
681 * @return the operation as a message including the guard result
683 public String getOperationMessage(String guardResult) {
684 if (this.currentOperation != null && this.currentOperation.clOperation != null) {
685 return this.currentOperation.clOperation.toMessage() + ", Guard result: " + guardResult;
688 if (!this.operationHistory.isEmpty()) {
689 return this.operationHistory.getLast().clOperation.toMessage() + ", Guard result: " + guardResult;
695 * Get the operation history.
697 * @return the operation history
699 public String getOperationHistory() {
700 if (this.currentOperation != null && this.currentOperation.clOperation != null) {
701 return this.currentOperation.clOperation.toHistory();
704 if (!this.operationHistory.isEmpty()) {
705 return this.operationHistory.getLast().clOperation.toHistory();
713 * @return the list of control loop operations
715 public List<ControlLoopOperation> getHistory() {
716 LinkedList<ControlLoopOperation> history = new LinkedList<>();
717 for (Operation op : this.operationHistory) {
718 history.add(new ControlLoopOperation(op.clOperation));
725 * Set the operation has timed out.
727 public void setOperationHasTimedOut() {
731 this.completeOperation(this.attempts, "Operation timed out", PolicyResult.FAILURE_TIMEOUT);
735 * Set the operation has been denied by guard.
737 public void setOperationHasGuardDeny() {
741 this.completeOperation(this.attempts, "Operation denied by Guard", PolicyResult.FAILURE_GUARD);
744 public void setOperationHasException(String message) {
745 this.completeOperation(this.attempts, message, PolicyResult.FAILURE_EXCEPTION);
749 * Is the operation complete.
751 * @return <code>true</code> if the operation is complete, <code>false</code> otherwise
753 public boolean isOperationComplete() {
755 // Is there currently a result?
757 if (this.policyResult == null) {
759 // either we are in process or we
765 // We have some result, check if the operation failed
767 if (this.policyResult.equals(PolicyResult.FAILURE)) {
769 // Check if there were no retries specified
771 if (policy.getRetry() == null || policy.getRetry() == 0) {
773 // The result is the failure
780 if (this.isRetriesMaxedOut()) {
782 // No more attempts allowed, reset
783 // that our actual result is failure due to retries
785 this.policyResult = PolicyResult.FAILURE_RETRIES;
789 // There are more attempts available to try the
796 // Other results mean we are done
801 public boolean isOperationRunning() {
802 return (this.currentOperation != null);
806 * This method verifies that the operation manager may run an operation.
808 * @return True if the operation can run, false otherwise
809 * @throws ControlLoopException if the operation cannot run
811 private void verifyOperatonCanRun() throws ControlLoopException {
813 // They shouldn't call us if we currently running something
815 if (this.currentOperation != null) {
817 // what do we do if we are already running an operation?
819 throw new ControlLoopException("current operation is not null (an operation is already running)");
822 // Check if we have maxed out on retries
824 if (this.policy.getRetry() == null || this.policy.getRetry() < 1) {
826 // No retries are allowed, so check have we even made
827 // one attempt to execute the operation?
829 if (this.attempts >= 1) {
831 // We have, let's ensure our PolicyResult is set
833 if (this.policyResult == null) {
834 this.policyResult = PolicyResult.FAILURE_RETRIES;
839 throw new ControlLoopException("current operation failed and retries are not allowed");
843 // Have we maxed out on retries?
845 if (this.attempts > this.policy.getRetry()) {
846 if (this.policyResult == null) {
847 this.policyResult = PolicyResult.FAILURE_RETRIES;
849 throw new ControlLoopException("current oepration has failed after " + this.attempts + " retries");
854 private boolean isRetriesMaxedOut() {
855 if (policy.getRetry() == null || policy.getRetry() == 0) {
857 // There were NO retries specified, so declare
858 // this as completed.
860 return (this.attempts > 0);
862 return (this.attempts > policy.getRetry());
865 private void storeOperationInDataBase() {
866 // Only store in DB if enabled
867 boolean guardEnabled = "false".equalsIgnoreCase(PolicyEngine.manager.getEnvironmentProperty("guard.disabled"));
874 Properties props = new Properties();
875 if (PolicyEngine.manager.getEnvironmentProperty(Util.ONAP_KEY_URL) != null
876 && PolicyEngine.manager.getEnvironmentProperty(Util.ONAP_KEY_USER) != null
877 && PolicyEngine.manager.getEnvironmentProperty(Util.ONAP_KEY_PASS) != null) {
878 props.put(Util.ECLIPSE_LINK_KEY_URL, PolicyEngine.manager.getEnvironmentProperty(Util.ONAP_KEY_URL));
879 props.put(Util.ECLIPSE_LINK_KEY_USER, PolicyEngine.manager.getEnvironmentProperty(Util.ONAP_KEY_USER));
880 props.put(Util.ECLIPSE_LINK_KEY_PASS, PolicyEngine.manager.getEnvironmentProperty(Util.ONAP_KEY_PASS));
881 props.put(PersistenceUnitProperties.CLASSLOADER, ControlLoopOperationManager.class.getClassLoader());
885 String opsHistPu = System.getProperty("OperationsHistoryPU");
886 if (!"TestOperationsHistoryPU".equals(opsHistPu)) {
887 opsHistPu = "OperationsHistoryPU";
893 em = Persistence.createEntityManagerFactory(opsHistPu, props).createEntityManager();
894 } catch (Exception e) {
895 logger.error("storeOperationInDataBase threw: ", e);
899 OperationsHistoryDbEntry newEntry = new OperationsHistoryDbEntry();
901 newEntry.setClosedLoopName(this.onset.getClosedLoopControlName());
902 newEntry.setRequestId(this.onset.getRequestId().toString());
903 newEntry.setActor(this.currentOperation.clOperation.getActor());
904 newEntry.setOperation(this.currentOperation.clOperation.getOperation());
905 newEntry.setTarget(this.targetEntity);
906 newEntry.setStarttime(Timestamp.from(this.currentOperation.clOperation.getStart()));
907 newEntry.setSubrequestId(this.currentOperation.clOperation.getSubRequestId());
908 newEntry.setEndtime(new Timestamp(this.currentOperation.clOperation.getEnd().toEpochMilli()));
909 newEntry.setMessage(this.currentOperation.clOperation.getMessage());
910 newEntry.setOutcome(this.currentOperation.clOperation.getOutcome());
912 em.getTransaction().begin();
913 em.persist(newEntry);
914 em.getTransaction().commit();
919 private void completeOperation(Integer attempt, String message, PolicyResult result) {
920 if (attempt == null) {
921 logger.debug("attempt cannot be null (i.e. subRequestID)");
924 if (this.currentOperation != null) {
925 if (this.currentOperation.attempt == attempt.intValue()) {
926 this.currentOperation.clOperation.setEnd(Instant.now());
927 this.currentOperation.clOperation.setMessage(message);
928 this.currentOperation.clOperation.setOutcome(result.toString());
929 this.currentOperation.policyResult = result;
931 // Save it in history
933 this.operationHistory.add(this.currentOperation);
934 this.storeOperationInDataBase();
936 // Set our last result
938 this.policyResult = result;
940 // Clear the current operation field
942 this.currentOperation = null;
945 logger.debug("not current");
947 for (Operation op : this.operationHistory) {
948 if (op.attempt == attempt.intValue()) {
949 op.clOperation.setEnd(Instant.now());
950 op.clOperation.setMessage(message);
951 op.clOperation.setOutcome(result.toString());
952 op.policyResult = result;
956 logger.debug("Could not find associated operation");
961 * Commit the abatement to the history database.
963 * @param message the abatement message
964 * @param outcome the abatement outcome
966 public void commitAbatement(String message, String outcome) {
967 logger.info("commitAbatement: {}. {}", message, outcome);
969 if (this.currentOperation == null) {
971 this.currentOperation = this.operationHistory.getLast();
972 } catch (NoSuchElementException e) {
973 logger.error("{}: commitAbatement threw an exception ", this, e);
977 this.currentOperation.clOperation.setEnd(Instant.now());
978 this.currentOperation.clOperation.setMessage(message);
979 this.currentOperation.clOperation.setOutcome(outcome);
981 // Store commit in DB
983 this.storeOperationInDataBase();
985 // Clear the current operation field
987 this.currentOperation = null;
991 * Construct a ControlLoopResponse object from actor response and input event.
993 * @param response the response from actor
994 * @param event the input event
996 * @return a ControlLoopResponse
998 public ControlLoopResponse getControlLoopResponse(Object response, VirtualControlLoopEvent event) {
999 if (response instanceof PciResponseWrapper) {
1001 // Cast SDNR response and handle it
1003 return SdnrActorServiceProvider.getControlLoopResponse((PciResponseWrapper) response, event);