2 * ================================================================================
3 * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
4 * ================================================================================
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
9 * http://www.apache.org/licenses/LICENSE-2.0
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 * ============LICENSE_END=========================================================
20 package org.onap.dcae.analytics.tca.core.util.function.calculation;
22 import java.util.Comparator;
23 import java.util.List;
24 import java.util.stream.Collectors;
25 import java.util.stream.Stream;
27 import org.onap.dcae.analytics.model.TcaModelConstants;
28 import org.onap.dcae.analytics.model.cef.EventListener;
29 import org.onap.dcae.analytics.tca.core.exception.TcaProcessingException;
30 import org.onap.dcae.analytics.tca.core.service.TcaAbatementContext;
31 import org.onap.dcae.analytics.tca.core.service.TcaAbatementEntity;
32 import org.onap.dcae.analytics.tca.core.service.TcaAbatementRepository;
33 import org.onap.dcae.analytics.tca.core.service.TcaExecutionContext;
34 import org.onap.dcae.analytics.tca.core.service.TcaProcessingContext;
35 import org.onap.dcae.analytics.tca.core.service.TcaResultContext;
36 import org.onap.dcae.analytics.tca.model.policy.ClosedLoopEventStatus;
37 import org.onap.dcae.analytics.tca.model.policy.MetricsPerEventName;
38 import org.onap.dcae.analytics.tca.model.policy.Threshold;
39 import org.slf4j.Logger;
40 import org.slf4j.LoggerFactory;
43 * @author Rajiv Singla
45 public class TcaAbatementCalculator implements TcaCalculationFunction {
47 private static final Logger logger = LoggerFactory.getLogger(TcaAbatementCalculator.class);
50 public TcaExecutionContext calculate(final TcaExecutionContext tcaExecutionContext) {
52 final TcaAbatementContext abatementContext = tcaExecutionContext.getTcaAbatementContext();
53 final TcaAbatementRepository abatementPersistenceContext = abatementContext
54 .getTcaAbatementRepository();
55 final TcaResultContext resultContext = tcaExecutionContext.getTcaResultContext();
56 final TcaProcessingContext processingContext = tcaExecutionContext.getTcaProcessingContext();
59 // Skip Abatement processing - if it is not enabled
60 if (!abatementContext.isAbatementEnabled() ||
61 // Skip if no threshold violations are present
62 !resultContext.isThresholdViolationsPresent()) {
63 return tcaExecutionContext;
67 final EventListener eventListener = processingContext.getEventListener();
68 final MetricsPerEventName violatedMetricsPerEventName = resultContext.getViolatedMetricsPerEventName();
69 final Threshold violatedThreshold = violatedMetricsPerEventName.getThresholds().get(0);
70 final ClosedLoopEventStatus closedLoopEventStatus = violatedThreshold.getClosedLoopEventStatus();
71 final String requestId = tcaExecutionContext.getRequestId();
72 final String lookupKey = createLookupKey(eventListener, violatedMetricsPerEventName);
75 switch (closedLoopEventStatus) {
77 // ONSET - save alert info in database so that next abated event can fetch its request id for abated
81 final TcaAbatementEntity tcaAbatementEntity =
82 abatementContext.create(lookupKey, requestId, false);
83 logger.debug("Request Id: {}. Alert ClosedLoop Status is ONSET. " +
84 "Saving abatement Entity to repository with lookupKey: {}",
85 requestId, tcaAbatementEntity.getLookupKey());
86 abatementPersistenceContext.save(tcaAbatementEntity);
87 return tcaExecutionContext;
89 // ABATED - look up previous saved request id from db
92 final List<TcaAbatementEntity> previousTcaAbatementEntities =
93 abatementPersistenceContext.findByLookupKey(lookupKey);
95 // if previous abatement are indeed present - sort them my last modified date and get latest entity
96 if (previousTcaAbatementEntities != null && !previousTcaAbatementEntities.isEmpty()) {
97 previousTcaAbatementEntities.sort(
98 Comparator.comparing(TcaAbatementEntity::getLastModificationDate));
99 final TcaAbatementEntity previousTcaAbatementEntity =
100 previousTcaAbatementEntities.get(previousTcaAbatementEntities.size() - 1);
102 logger.debug("Request Id: {}. Found previous Abatement Entity: {}", requestId,
103 previousTcaAbatementEntity);
105 // previous abatement entity was found - but it was already sent before - so ignore alert creation
106 if (previousTcaAbatementEntity.isAbatementAlertSent()) {
107 final String terminatingMessage = "Abatement alert was already sent before on: " +
108 previousTcaAbatementEntity.getLastModificationDate();
109 setTerminatingMessage(terminatingMessage, tcaExecutionContext, false);
110 return tcaExecutionContext;
113 // no previous abatement was sent
114 final String previousRequestId = previousTcaAbatementEntity.getRequestId();
115 // set abated alert request id to previous ONSET alert request id
116 logger.debug("Request Id: {}. No previous abated alert was sent. Setting previous request id: {}",
117 requestId, previousRequestId);
118 resultContext.setPreviousRequestId(previousRequestId);
119 // save new entity with alert as sent
120 final TcaAbatementEntity newTcaAbatementEntity =
121 abatementContext.create(lookupKey, previousRequestId, true);
122 logger.debug("Request Id: {}. Saving new entity with alert as sent: {}",
123 requestId, newTcaAbatementEntity);
124 abatementPersistenceContext.save(newTcaAbatementEntity);
125 return tcaExecutionContext;
128 // no previous onset event found
129 final String terminatingMessage =
130 "Ignored orphan Abated Message. No previous ONSET event found for lookup key: " + lookupKey;
131 setTerminatingMessage(terminatingMessage, tcaExecutionContext, false);
132 return tcaExecutionContext;
135 // Only ONSET and ABATED closed loop status are supported
137 final String errorMessage = String.format(
138 "Request Id: %s. Unexpected ClosedLoopEventStatus: %s - Only ONSET and ABATED are supported.",
139 requestId, closedLoopEventStatus);
140 throw new TcaProcessingException(errorMessage, new IllegalStateException(errorMessage));
145 private static String createLookupKey(final EventListener eventListener,
146 final MetricsPerEventName violatedMetricsPerEventName) {
147 // no null check required as all are required fields
148 final String eventName = violatedMetricsPerEventName.getEventName();
149 final String sourceName = eventListener.getEvent().getCommonEventHeader().getSourceName();
150 final String reportingEntityName = eventListener.getEvent().getCommonEventHeader().getReportingEntityName();
151 // violated threshold will always be present
152 final Threshold violatedThreshold = violatedMetricsPerEventName.getThresholds().get(0);
153 final String closedLoopControlName = violatedThreshold.getClosedLoopControlName();
154 final String fieldPath = violatedThreshold.getFieldPath();
155 return Stream.of(eventName, sourceName, reportingEntityName, closedLoopControlName, fieldPath)
156 .collect(Collectors.joining(TcaModelConstants.TCA_ROW_KEY_DELIMITER));