summaryrefslogtreecommitdiffstats
path: root/dcae-analytics/dcae-analytics-tca-core/src
diff options
context:
space:
mode:
Diffstat (limited to 'dcae-analytics/dcae-analytics-tca-core/src')
-rw-r--r--dcae-analytics/dcae-analytics-tca-core/src/main/java/org/onap/dcae/analytics/tca/core/exception/TcaProcessingException.java48
-rw-r--r--dcae-analytics/dcae-analytics-tca-core/src/main/java/org/onap/dcae/analytics/tca/core/service/GenericTcaExecutionContext.java48
-rw-r--r--dcae-analytics/dcae-analytics-tca-core/src/main/java/org/onap/dcae/analytics/tca/core/service/GenericTcaProcessingContext.java41
-rw-r--r--dcae-analytics/dcae-analytics-tca-core/src/main/java/org/onap/dcae/analytics/tca/core/service/GenericTcaResultContext.java41
-rw-r--r--dcae-analytics/dcae-analytics-tca-core/src/main/java/org/onap/dcae/analytics/tca/core/service/TcaAaiEnrichmentContext.java33
-rw-r--r--dcae-analytics/dcae-analytics-tca-core/src/main/java/org/onap/dcae/analytics/tca/core/service/TcaAaiEnrichmentService.java39
-rw-r--r--dcae-analytics/dcae-analytics-tca-core/src/main/java/org/onap/dcae/analytics/tca/core/service/TcaAbatementContext.java57
-rw-r--r--dcae-analytics/dcae-analytics-tca-core/src/main/java/org/onap/dcae/analytics/tca/core/service/TcaAbatementEntity.java61
-rw-r--r--dcae-analytics/dcae-analytics-tca-core/src/main/java/org/onap/dcae/analytics/tca/core/service/TcaAbatementRepository.java49
-rw-r--r--dcae-analytics/dcae-analytics-tca-core/src/main/java/org/onap/dcae/analytics/tca/core/service/TcaExecutionContext.java102
-rw-r--r--dcae-analytics/dcae-analytics-tca-core/src/main/java/org/onap/dcae/analytics/tca/core/service/TcaProcessingContext.java92
-rw-r--r--dcae-analytics/dcae-analytics-tca-core/src/main/java/org/onap/dcae/analytics/tca/core/service/TcaResultContext.java88
-rw-r--r--dcae-analytics/dcae-analytics-tca-core/src/main/java/org/onap/dcae/analytics/tca/core/util/function/calculation/TcaAaiEnrichmentFunction.java62
-rw-r--r--dcae-analytics/dcae-analytics-tca-core/src/main/java/org/onap/dcae/analytics/tca/core/util/function/calculation/TcaAbatementCalculator.java159
-rw-r--r--dcae-analytics/dcae-analytics-tca-core/src/main/java/org/onap/dcae/analytics/tca/core/util/function/calculation/TcaAlertCreationFunction.java129
-rw-r--r--dcae-analytics/dcae-analytics-tca-core/src/main/java/org/onap/dcae/analytics/tca/core/util/function/calculation/TcaCalculationFunction.java84
-rw-r--r--dcae-analytics/dcae-analytics-tca-core/src/main/java/org/onap/dcae/analytics/tca/core/util/function/calculation/TcaCalculator.java60
-rw-r--r--dcae-analytics/dcae-analytics-tca-core/src/main/java/org/onap/dcae/analytics/tca/core/util/function/calculation/TcaDomainFilter.java75
-rw-r--r--dcae-analytics/dcae-analytics-tca-core/src/main/java/org/onap/dcae/analytics/tca/core/util/function/calculation/TcaEventListenerExtractor.java76
-rw-r--r--dcae-analytics/dcae-analytics-tca-core/src/main/java/org/onap/dcae/analytics/tca/core/util/function/calculation/TcaEventNameFilter.java77
-rw-r--r--dcae-analytics/dcae-analytics-tca-core/src/main/java/org/onap/dcae/analytics/tca/core/util/function/calculation/TcaThresholdViolationCalculator.java270
-rw-r--r--dcae-analytics/dcae-analytics-tca-core/src/test/java/org/onap/dcae/analytics/tca/core/BaseTcaCoreTest.java121
-rw-r--r--dcae-analytics/dcae-analytics-tca-core/src/test/java/org/onap/dcae/analytics/tca/core/domain/TestTcaAaiEnrichmentContext.java36
-rw-r--r--dcae-analytics/dcae-analytics-tca-core/src/test/java/org/onap/dcae/analytics/tca/core/domain/TestTcaAaiEnrichmentService.java41
-rw-r--r--dcae-analytics/dcae-analytics-tca-core/src/test/java/org/onap/dcae/analytics/tca/core/domain/TestTcaAbatementContext.java46
-rw-r--r--dcae-analytics/dcae-analytics-tca-core/src/test/java/org/onap/dcae/analytics/tca/core/domain/TestTcaAbatementEntity.java41
-rw-r--r--dcae-analytics/dcae-analytics-tca-core/src/test/java/org/onap/dcae/analytics/tca/core/domain/TestTcaAbatementRepository.java48
-rw-r--r--dcae-analytics/dcae-analytics-tca-core/src/test/java/org/onap/dcae/analytics/tca/core/util/function/calculation/TcaCalculatorTest.java88
28 files changed, 2112 insertions, 0 deletions
diff --git a/dcae-analytics/dcae-analytics-tca-core/src/main/java/org/onap/dcae/analytics/tca/core/exception/TcaProcessingException.java b/dcae-analytics/dcae-analytics-tca-core/src/main/java/org/onap/dcae/analytics/tca/core/exception/TcaProcessingException.java
new file mode 100644
index 0000000..87d0634
--- /dev/null
+++ b/dcae-analytics/dcae-analytics-tca-core/src/main/java/org/onap/dcae/analytics/tca/core/exception/TcaProcessingException.java
@@ -0,0 +1,48 @@
+/*
+ * ================================================================================
+ * Copyright (c) 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ *
+ */
+
+package org.onap.dcae.analytics.tca.core.exception;
+
+/**
+ * @author Rajiv Singla
+ */
+public class TcaProcessingException extends RuntimeException {
+
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * CDR Exception with message
+ *
+ * @param message Error Message for Exception
+ */
+ public TcaProcessingException(final String message) {
+ super(message);
+ }
+
+ /**
+ * CDR exception with message and cause
+ *
+ * @param message Error Message for Exception
+ * @param cause Actual Exception which caused {@link TcaProcessingException}
+ */
+ public TcaProcessingException(final String message, final Throwable cause) {
+ super(message, cause);
+ }
+
+}
diff --git a/dcae-analytics/dcae-analytics-tca-core/src/main/java/org/onap/dcae/analytics/tca/core/service/GenericTcaExecutionContext.java b/dcae-analytics/dcae-analytics-tca-core/src/main/java/org/onap/dcae/analytics/tca/core/service/GenericTcaExecutionContext.java
new file mode 100644
index 0000000..6a208d2
--- /dev/null
+++ b/dcae-analytics/dcae-analytics-tca-core/src/main/java/org/onap/dcae/analytics/tca/core/service/GenericTcaExecutionContext.java
@@ -0,0 +1,48 @@
+/*
+ * ================================================================================
+ * Copyright (c) 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ *
+ */
+
+package org.onap.dcae.analytics.tca.core.service;
+
+import lombok.Builder;
+import lombok.EqualsAndHashCode;
+import lombok.Getter;
+import lombok.ToString;
+
+import org.onap.dcae.analytics.tca.model.policy.TcaPolicy;
+
+/**
+ * @author Rajiv Singla
+ */
+@Builder
+@Getter
+@EqualsAndHashCode
+@ToString
+public class GenericTcaExecutionContext implements TcaExecutionContext {
+
+ private final String requestId;
+ private final String transactionId;
+ private final int messageIndex;
+ private final String cefMessage;
+ private final TcaPolicy tcaPolicy;
+ private final TcaProcessingContext tcaProcessingContext;
+ private final TcaResultContext tcaResultContext;
+ private final TcaAbatementContext tcaAbatementContext;
+ private final TcaAaiEnrichmentContext tcaAaiEnrichmentContext;
+
+}
diff --git a/dcae-analytics/dcae-analytics-tca-core/src/main/java/org/onap/dcae/analytics/tca/core/service/GenericTcaProcessingContext.java b/dcae-analytics/dcae-analytics-tca-core/src/main/java/org/onap/dcae/analytics/tca/core/service/GenericTcaProcessingContext.java
new file mode 100644
index 0000000..aceb4be
--- /dev/null
+++ b/dcae-analytics/dcae-analytics-tca-core/src/main/java/org/onap/dcae/analytics/tca/core/service/GenericTcaProcessingContext.java
@@ -0,0 +1,41 @@
+/*
+ * ================================================================================
+ * Copyright (c) 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ *
+ */
+
+package org.onap.dcae.analytics.tca.core.service;
+
+
+import lombok.Data;
+
+import org.onap.dcae.analytics.model.cef.EventListener;
+
+/**
+ * A Generic implementation for {@link TcaProcessingContext}
+ *
+ * @author Rajiv Singla
+ */
+
+@Data
+public class GenericTcaProcessingContext implements TcaProcessingContext {
+
+ private EventListener eventListener;
+ private boolean continueProcessing = true;
+ private String earlyTerminationMessage;
+ private String errorMessage;
+
+}
diff --git a/dcae-analytics/dcae-analytics-tca-core/src/main/java/org/onap/dcae/analytics/tca/core/service/GenericTcaResultContext.java b/dcae-analytics/dcae-analytics-tca-core/src/main/java/org/onap/dcae/analytics/tca/core/service/GenericTcaResultContext.java
new file mode 100644
index 0000000..ee8ef86
--- /dev/null
+++ b/dcae-analytics/dcae-analytics-tca-core/src/main/java/org/onap/dcae/analytics/tca/core/service/GenericTcaResultContext.java
@@ -0,0 +1,41 @@
+/*
+ * ================================================================================
+ * Copyright (c) 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ *
+ */
+
+package org.onap.dcae.analytics.tca.core.service;
+
+import lombok.Data;
+
+import org.onap.dcae.analytics.tca.model.facade.TcaAlert;
+import org.onap.dcae.analytics.tca.model.policy.MetricsPerEventName;
+
+/**
+ * @author Rajiv Singla
+ */
+@Data
+public class GenericTcaResultContext implements TcaResultContext {
+
+ private MetricsPerEventName violatedMetricsPerEventName;
+ private TcaAlert tcaAlert;
+ private String previousRequestId;
+
+ @Override
+ public boolean isThresholdViolationsPresent() {
+ return getViolatedMetricsPerEventName() != null;
+ }
+}
diff --git a/dcae-analytics/dcae-analytics-tca-core/src/main/java/org/onap/dcae/analytics/tca/core/service/TcaAaiEnrichmentContext.java b/dcae-analytics/dcae-analytics-tca-core/src/main/java/org/onap/dcae/analytics/tca/core/service/TcaAaiEnrichmentContext.java
new file mode 100644
index 0000000..292905e
--- /dev/null
+++ b/dcae-analytics/dcae-analytics-tca-core/src/main/java/org/onap/dcae/analytics/tca/core/service/TcaAaiEnrichmentContext.java
@@ -0,0 +1,33 @@
+/*
+ * ================================================================================
+ * Copyright (c) 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ *
+ */
+
+package org.onap.dcae.analytics.tca.core.service;
+
+/**
+ * Provides abstractions for TCA AAI Enrichment
+ *
+ * @author Rajiv Singla
+ */
+public interface TcaAaiEnrichmentContext {
+
+ boolean isAaiEnrichmentEnabled();
+
+ TcaAaiEnrichmentService getAaiEnrichmentService();
+
+}
diff --git a/dcae-analytics/dcae-analytics-tca-core/src/main/java/org/onap/dcae/analytics/tca/core/service/TcaAaiEnrichmentService.java b/dcae-analytics/dcae-analytics-tca-core/src/main/java/org/onap/dcae/analytics/tca/core/service/TcaAaiEnrichmentService.java
new file mode 100644
index 0000000..f2d140c
--- /dev/null
+++ b/dcae-analytics/dcae-analytics-tca-core/src/main/java/org/onap/dcae/analytics/tca/core/service/TcaAaiEnrichmentService.java
@@ -0,0 +1,39 @@
+/*
+ * ================================================================================
+ * Copyright (c) 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ *
+ */
+
+package org.onap.dcae.analytics.tca.core.service;
+
+import org.onap.dcae.analytics.tca.model.facade.TcaAlert;
+
+/**
+ * TCA AAI Enrichment Service enriches {@link TcaAlert#getAai()}
+ *
+ * @author Rajiv Singla
+ */
+@FunctionalInterface
+public interface TcaAaiEnrichmentService {
+
+ /**
+ * @param tcaExecutionContext tca execution context
+ *
+ * @return tca alert with AAI enrichment
+ */
+ TcaAlert doAaiEnrichment(TcaExecutionContext tcaExecutionContext);
+
+}
diff --git a/dcae-analytics/dcae-analytics-tca-core/src/main/java/org/onap/dcae/analytics/tca/core/service/TcaAbatementContext.java b/dcae-analytics/dcae-analytics-tca-core/src/main/java/org/onap/dcae/analytics/tca/core/service/TcaAbatementContext.java
new file mode 100644
index 0000000..9ec4192
--- /dev/null
+++ b/dcae-analytics/dcae-analytics-tca-core/src/main/java/org/onap/dcae/analytics/tca/core/service/TcaAbatementContext.java
@@ -0,0 +1,57 @@
+/*
+ * ================================================================================
+ * Copyright (c) 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ *
+ */
+
+package org.onap.dcae.analytics.tca.core.service;
+
+/**
+ * Provides abstractions for TCA Abatement processing calculations
+ *
+ * @author Rajiv Singla
+ */
+public interface TcaAbatementContext {
+
+ /**
+ * Returns true if TCA Abatement calculations are enabled
+ *
+ * @return true if TCA Abatement calculations are enabled
+ */
+ boolean isAbatementEnabled();
+
+
+ /**
+ * Provides abstractions for Tca Abatement Persistence
+ *
+ * @return abstractions for Tca Abatement Persistence
+ */
+ TcaAbatementRepository getTcaAbatementRepository();
+
+
+ /**
+ * Creates new instance of TCA Abatement persistence Entity
+ *
+ * @param lookupKey lookup key
+ * @param requestId request id
+ * @param isAbatementAlertSent true if abatement alert was already sent
+ *
+ * @return new instance of TCA Abatement Persistence Entity
+ */
+ TcaAbatementEntity create(String lookupKey, String requestId, boolean isAbatementAlertSent);
+
+
+}
diff --git a/dcae-analytics/dcae-analytics-tca-core/src/main/java/org/onap/dcae/analytics/tca/core/service/TcaAbatementEntity.java b/dcae-analytics/dcae-analytics-tca-core/src/main/java/org/onap/dcae/analytics/tca/core/service/TcaAbatementEntity.java
new file mode 100644
index 0000000..fe0ac5e
--- /dev/null
+++ b/dcae-analytics/dcae-analytics-tca-core/src/main/java/org/onap/dcae/analytics/tca/core/service/TcaAbatementEntity.java
@@ -0,0 +1,61 @@
+/*
+ * ================================================================================
+ * Copyright (c) 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ *
+ */
+
+package org.onap.dcae.analytics.tca.core.service;
+
+import java.util.Date;
+
+/**
+ * TCA Abatement Persistence Entity
+ *
+ * @author Rajiv Singla
+ */
+public interface TcaAbatementEntity {
+
+ /**
+ * Last Modified Date when entity was modified
+ *
+ * @return last modified date
+ */
+ Date getLastModificationDate();
+
+ /**
+ * Lookup Key
+ *
+ * @return provides Lookup Key
+ */
+ String getLookupKey();
+
+
+ /**
+ * Provides Request Id
+ *
+ * @return request id
+ */
+ String getRequestId();
+
+
+ /**
+ * Return true if alert was already sent for this Entity else false
+ *
+ * @return true if alert was already sent for this Entity else false
+ */
+ boolean isAbatementAlertSent();
+
+}
diff --git a/dcae-analytics/dcae-analytics-tca-core/src/main/java/org/onap/dcae/analytics/tca/core/service/TcaAbatementRepository.java b/dcae-analytics/dcae-analytics-tca-core/src/main/java/org/onap/dcae/analytics/tca/core/service/TcaAbatementRepository.java
new file mode 100644
index 0000000..c1d3a78
--- /dev/null
+++ b/dcae-analytics/dcae-analytics-tca-core/src/main/java/org/onap/dcae/analytics/tca/core/service/TcaAbatementRepository.java
@@ -0,0 +1,49 @@
+/*
+ * ================================================================================
+ * Copyright (c) 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ *
+ */
+
+package org.onap.dcae.analytics.tca.core.service;
+
+import java.util.List;
+
+/**
+ * Provides abstractions for Tca Abatement Persistence
+ *
+ * @author Rajiv Singla
+ */
+public interface TcaAbatementRepository {
+
+ /**
+ * Saves new Tca Abatement Entity to some persistent store
+ *
+ * @param tcaAbatementEntity Tca Abatement Entity that need to be stored
+ */
+ void save(TcaAbatementEntity tcaAbatementEntity);
+
+
+ /**
+ * Provides any saved Tca Abatement Entities which same look up key
+ *
+ * @param lookUpKey look up key for abatement persistence entity
+ *
+ * @return list of previously saved tca abatement persistence entities has given lookup key
+ */
+ List<TcaAbatementEntity> findByLookupKey(String lookUpKey);
+
+
+}
diff --git a/dcae-analytics/dcae-analytics-tca-core/src/main/java/org/onap/dcae/analytics/tca/core/service/TcaExecutionContext.java b/dcae-analytics/dcae-analytics-tca-core/src/main/java/org/onap/dcae/analytics/tca/core/service/TcaExecutionContext.java
new file mode 100644
index 0000000..9a55151
--- /dev/null
+++ b/dcae-analytics/dcae-analytics-tca-core/src/main/java/org/onap/dcae/analytics/tca/core/service/TcaExecutionContext.java
@@ -0,0 +1,102 @@
+/*
+ * ================================================================================
+ * Copyright (c) 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ *
+ */
+
+package org.onap.dcae.analytics.tca.core.service;
+
+import org.onap.dcae.analytics.tca.model.policy.TcaPolicy;
+
+/**
+ * TCA Execution context captures various fields required to calculate a TCA threshold violation calculation execution
+ *
+ * @author Rajiv Singla
+ */
+public interface TcaExecutionContext {
+
+ /**
+ * Provides request id associated with execution context
+ *
+ * @return request id associated with execution context
+ */
+ String getRequestId();
+
+
+ /**
+ * Provides transaction id associated with execution context
+ *
+ * @return transaction id associated with execution context
+ */
+ String getTransactionId();
+
+
+ /**
+ * Provides message order number inside a execution batch
+ *
+ * @return message order number inside a execution batch
+ */
+ int getMessageIndex();
+
+
+ /**
+ * Provides common event format message as JSON string that is being analyzed
+ *
+ * @return common event format message as JSON string that is being analyzed
+ */
+ String getCefMessage();
+
+
+ /**
+ * Provides TCA Policy associated with the processing context
+ *
+ * @return TCA Policy associated with processing context
+ */
+ TcaPolicy getTcaPolicy();
+
+
+ /**
+ * Provides TCA Processing Context captures various mutable fields that are computed during TCA execution
+ *
+ * @return TCA Processing Context captures various mutable fields that are computed during TCA execution
+ */
+ TcaProcessingContext getTcaProcessingContext();
+
+
+ /**
+ * Provides TCA Processing Result Context which captures outputs of TCA execution
+ *
+ * @return TCA Processing Result Context which captures outputs of TCA execution
+ */
+ TcaResultContext getTcaResultContext();
+
+
+ /**
+ * Provides TCA Abatement context containing abstractions for TCA Abatement processing calculations
+ *
+ * @return TCA abatement context containing abstractions for TCA Abatement processing calculations
+ */
+ TcaAbatementContext getTcaAbatementContext();
+
+
+ /**
+ * Provides TCA AAI Enrichment Context
+ *
+ * @return TCA AAI enrichment context
+ */
+ TcaAaiEnrichmentContext getTcaAaiEnrichmentContext();
+
+}
diff --git a/dcae-analytics/dcae-analytics-tca-core/src/main/java/org/onap/dcae/analytics/tca/core/service/TcaProcessingContext.java b/dcae-analytics/dcae-analytics-tca-core/src/main/java/org/onap/dcae/analytics/tca/core/service/TcaProcessingContext.java
new file mode 100644
index 0000000..69a5ab0
--- /dev/null
+++ b/dcae-analytics/dcae-analytics-tca-core/src/main/java/org/onap/dcae/analytics/tca/core/service/TcaProcessingContext.java
@@ -0,0 +1,92 @@
+/*
+ * ================================================================================
+ * Copyright (c) 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ *
+ */
+
+package org.onap.dcae.analytics.tca.core.service;
+
+import org.onap.dcae.analytics.model.cef.EventListener;
+
+/**
+ * TCA Processing Context captures various mutable fields that are computed during TCA execution
+ *
+ * @author Rajiv Singla
+ */
+public interface TcaProcessingContext {
+
+
+ /**
+ * Provides common event format message as JAVA object that is being analyzed
+ *
+ * @return common event format message as JAVA object that is being analyzed
+ */
+ EventListener getEventListener();
+
+
+ /**
+ * Sets new values for common event format message as JAVA object that is being analyzed
+ *
+ * @param eventListener new values for common event format message as JAVA object that is being analyzed
+ */
+ void setEventListener(EventListener eventListener);
+
+
+ /**
+ * Provides flag which is false if TCA processing cannot continue to next stage due to some prior condition
+ *
+ * @return false if TCA processing cannot continue to next stage due to some condition
+ */
+ boolean isContinueProcessing();
+
+ /**
+ * Sets TCA processing continue flag
+ *
+ * @param isContinueProcessing - TCA processing continue flag
+ */
+ void setContinueProcessing(boolean isContinueProcessing);
+
+
+ /**
+ * Provides early termination message message if present or null
+ *
+ * @return early termination message if present or null
+ */
+ String getEarlyTerminationMessage();
+
+ /**
+ * Sets early termination message
+ *
+ * @param earlyTerminationMessage sets a new value for early termination message
+ */
+ void setEarlyTerminationMessage(String earlyTerminationMessage);
+
+
+ /**
+ * Returns error message if present or null
+ *
+ * @return error message if present or null
+ */
+ String getErrorMessage();
+
+ /**
+ * Sets new value for error message
+ *
+ * @param errorMessage new value for error message
+ */
+ void setErrorMessage(final String errorMessage);
+
+}
diff --git a/dcae-analytics/dcae-analytics-tca-core/src/main/java/org/onap/dcae/analytics/tca/core/service/TcaResultContext.java b/dcae-analytics/dcae-analytics-tca-core/src/main/java/org/onap/dcae/analytics/tca/core/service/TcaResultContext.java
new file mode 100644
index 0000000..b166a5f
--- /dev/null
+++ b/dcae-analytics/dcae-analytics-tca-core/src/main/java/org/onap/dcae/analytics/tca/core/service/TcaResultContext.java
@@ -0,0 +1,88 @@
+/*
+ * ================================================================================
+ * Copyright (c) 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ *
+ */
+
+package org.onap.dcae.analytics.tca.core.service;
+
+import org.onap.dcae.analytics.tca.model.facade.TcaAlert;
+import org.onap.dcae.analytics.tca.model.policy.MetricsPerEventName;
+
+/**
+ * TCA Processing Result Context which captures outputs of TCA Execution
+ *
+ * @author Rajiv Singla
+ */
+public interface TcaResultContext {
+
+ /**
+ * Returns true if Threshold violations are present
+ *
+ * @return true if Threshold violations are present
+ */
+ boolean isThresholdViolationsPresent();
+
+
+ /**
+ * Returns TCA policy's violated metrics per event name that was violated by the incoming message
+ *
+ * @return TCA policy's violated metrics per event name that was violated by the incoming message
+ */
+ MetricsPerEventName getViolatedMetricsPerEventName();
+
+
+ /**
+ * Sets new value for violated metrics per event name that was violated by the incoming message
+ *
+ * @param violatedMetricsPerEventName new value for violated metrics per event name that was violated by the
+ * incoming message
+ */
+ void setViolatedMetricsPerEventName(MetricsPerEventName violatedMetricsPerEventName);
+
+
+ /**
+ * Provides TCA Alert message that is generated if there is any TCA policy's threshold violation
+ *
+ * @return TCA Alert message that is generated if there is any TCA policy's threshold violation
+ */
+ TcaAlert getTcaAlert();
+
+
+ /**
+ * Sets new value for TCA Alert
+ *
+ * @param tcaAlert new value for TCA Alert
+ */
+ void setTcaAlert(TcaAlert tcaAlert);
+
+ /**
+ * Provides previous request id for abated threshold violations if present or null
+ *
+ * @return previous request id for abated threshold violations if present or null
+ */
+ String getPreviousRequestId();
+
+
+ /**
+ * Sets previous request id for abated threshold violations
+ *
+ * @param previousRequestId new value of request id for abated threshold violations
+ */
+ void setPreviousRequestId(String previousRequestId);
+
+
+}
diff --git a/dcae-analytics/dcae-analytics-tca-core/src/main/java/org/onap/dcae/analytics/tca/core/util/function/calculation/TcaAaiEnrichmentFunction.java b/dcae-analytics/dcae-analytics-tca-core/src/main/java/org/onap/dcae/analytics/tca/core/util/function/calculation/TcaAaiEnrichmentFunction.java
new file mode 100644
index 0000000..27263c8
--- /dev/null
+++ b/dcae-analytics/dcae-analytics-tca-core/src/main/java/org/onap/dcae/analytics/tca/core/util/function/calculation/TcaAaiEnrichmentFunction.java
@@ -0,0 +1,62 @@
+/*
+ * ================================================================================
+ * Copyright (c) 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ *
+ */
+
+package org.onap.dcae.analytics.tca.core.util.function.calculation;
+
+import java.util.Optional;
+
+import org.onap.dcae.analytics.tca.core.service.TcaAaiEnrichmentContext;
+import org.onap.dcae.analytics.tca.core.service.TcaAaiEnrichmentService;
+import org.onap.dcae.analytics.tca.core.service.TcaExecutionContext;
+import org.onap.dcae.analytics.tca.model.facade.TcaAlert;
+import org.onap.dcae.analytics.tca.model.policy.ClosedLoopEventStatus;
+
+/**
+ * @author Rajiv Singla
+ */
+public class TcaAaiEnrichmentFunction implements TcaCalculationFunction {
+
+ @Override
+ public TcaExecutionContext calculate(final TcaExecutionContext tcaExecutionContext) {
+
+ final TcaAaiEnrichmentContext aaiEnrichmentContext = tcaExecutionContext.getTcaAaiEnrichmentContext();
+ final Optional<TcaAlert> tcaAlertOptional =
+ Optional.ofNullable(tcaExecutionContext.getTcaResultContext().getTcaAlert());
+
+ // Skip Aai Enrichment - if aai enrichment is not enabled or no alert is present
+ if (!aaiEnrichmentContext.isAaiEnrichmentEnabled() || !tcaAlertOptional.isPresent()) {
+ return tcaExecutionContext;
+ }
+
+ // Skip Aai Enrichment - if Alert Closed Loop Event status is not ONSET
+ final TcaAlert tcaAlert = tcaAlertOptional.get();
+ final ClosedLoopEventStatus closedLoopEventStatus =
+ ClosedLoopEventStatus.valueOf(tcaAlert.getClosedLoopEventStatus());
+ if (closedLoopEventStatus != ClosedLoopEventStatus.ONSET) {
+ return tcaExecutionContext;
+ }
+
+ // do Aai Enrichment
+ final TcaAaiEnrichmentService aaiEnrichmentService = aaiEnrichmentContext.getAaiEnrichmentService();
+ final TcaAlert enrichedTcaAlert = aaiEnrichmentService.doAaiEnrichment(tcaExecutionContext);
+ tcaExecutionContext.getTcaResultContext().setTcaAlert(enrichedTcaAlert);
+
+ return tcaExecutionContext;
+ }
+}
diff --git a/dcae-analytics/dcae-analytics-tca-core/src/main/java/org/onap/dcae/analytics/tca/core/util/function/calculation/TcaAbatementCalculator.java b/dcae-analytics/dcae-analytics-tca-core/src/main/java/org/onap/dcae/analytics/tca/core/util/function/calculation/TcaAbatementCalculator.java
new file mode 100644
index 0000000..0322456
--- /dev/null
+++ b/dcae-analytics/dcae-analytics-tca-core/src/main/java/org/onap/dcae/analytics/tca/core/util/function/calculation/TcaAbatementCalculator.java
@@ -0,0 +1,159 @@
+/*
+ * ================================================================================
+ * Copyright (c) 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ *
+ */
+
+package org.onap.dcae.analytics.tca.core.util.function.calculation;
+
+import java.util.Comparator;
+import java.util.List;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+import org.onap.dcae.analytics.model.TcaModelConstants;
+import org.onap.dcae.analytics.model.cef.EventListener;
+import org.onap.dcae.analytics.tca.core.exception.TcaProcessingException;
+import org.onap.dcae.analytics.tca.core.service.TcaAbatementContext;
+import org.onap.dcae.analytics.tca.core.service.TcaAbatementEntity;
+import org.onap.dcae.analytics.tca.core.service.TcaAbatementRepository;
+import org.onap.dcae.analytics.tca.core.service.TcaExecutionContext;
+import org.onap.dcae.analytics.tca.core.service.TcaProcessingContext;
+import org.onap.dcae.analytics.tca.core.service.TcaResultContext;
+import org.onap.dcae.analytics.tca.model.policy.ClosedLoopEventStatus;
+import org.onap.dcae.analytics.tca.model.policy.MetricsPerEventName;
+import org.onap.dcae.analytics.tca.model.policy.Threshold;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * @author Rajiv Singla
+ */
+public class TcaAbatementCalculator implements TcaCalculationFunction {
+
+ private static final Logger logger = LoggerFactory.getLogger(TcaAbatementCalculator.class);
+
+ @Override
+ public TcaExecutionContext calculate(final TcaExecutionContext tcaExecutionContext) {
+
+ final TcaAbatementContext abatementContext = tcaExecutionContext.getTcaAbatementContext();
+ final TcaAbatementRepository abatementPersistenceContext = abatementContext
+ .getTcaAbatementRepository();
+ final TcaResultContext resultContext = tcaExecutionContext.getTcaResultContext();
+ final TcaProcessingContext processingContext = tcaExecutionContext.getTcaProcessingContext();
+
+
+ // Skip Abatement processing - if it is not enabled
+ if (!abatementContext.isAbatementEnabled() ||
+ // Skip if no threshold violations are present
+ !resultContext.isThresholdViolationsPresent()) {
+ return tcaExecutionContext;
+ }
+
+
+ final EventListener eventListener = processingContext.getEventListener();
+ final MetricsPerEventName violatedMetricsPerEventName = resultContext.getViolatedMetricsPerEventName();
+ final Threshold violatedThreshold = violatedMetricsPerEventName.getThresholds().get(0);
+ final ClosedLoopEventStatus closedLoopEventStatus = violatedThreshold.getClosedLoopEventStatus();
+ final String requestId = tcaExecutionContext.getRequestId();
+ final String lookupKey = createLookupKey(eventListener, violatedMetricsPerEventName);
+
+
+ switch (closedLoopEventStatus) {
+
+ // ONSET - save alert info in database so that next abated event can fetch its request id for abated
+ // alert
+ case ONSET:
+
+ final TcaAbatementEntity tcaAbatementEntity =
+ abatementContext.create(lookupKey, requestId, false);
+ logger.debug("Request Id: {}. Alert ClosedLoop Status is ONSET. " +
+ "Saving abatement Entity to repository with lookupKey: {}",
+ requestId, tcaAbatementEntity.getLookupKey());
+ abatementPersistenceContext.save(tcaAbatementEntity);
+ return tcaExecutionContext;
+
+ // ABATED - look up previous saved request id from db
+ case ABATED:
+
+ final List<TcaAbatementEntity> previousTcaAbatementEntities =
+ abatementPersistenceContext.findByLookupKey(lookupKey);
+
+ // if previous abatement are indeed present - sort them my last modified date and get latest entity
+ if (previousTcaAbatementEntities != null && !previousTcaAbatementEntities.isEmpty()) {
+ previousTcaAbatementEntities.sort(
+ Comparator.comparing(TcaAbatementEntity::getLastModificationDate));
+ final TcaAbatementEntity previousTcaAbatementEntity =
+ previousTcaAbatementEntities.get(previousTcaAbatementEntities.size() - 1);
+
+ logger.debug("Request Id: {}. Found previous Abatement Entity: {}", requestId,
+ previousTcaAbatementEntity);
+
+ // previous abatement entity was found - but it was already sent before - so ignore alert creation
+ if (previousTcaAbatementEntity.isAbatementAlertSent()) {
+ final String terminatingMessage = "Abatement alert was already sent before on: " +
+ previousTcaAbatementEntity.getLastModificationDate();
+ setTerminatingMessage(terminatingMessage, tcaExecutionContext, false);
+ return tcaExecutionContext;
+ }
+
+ // no previous abatement was sent
+ final String previousRequestId = previousTcaAbatementEntity.getRequestId();
+ // set abated alert request id to previous ONSET alert request id
+ logger.debug("Request Id: {}. No previous abated alert was sent. Setting previous request id: {}",
+ requestId, previousRequestId);
+ resultContext.setPreviousRequestId(previousRequestId);
+ // save new entity with alert as sent
+ final TcaAbatementEntity newTcaAbatementEntity =
+ abatementContext.create(lookupKey, previousRequestId, true);
+ logger.debug("Request Id: {}. Saving new entity with alert as sent: {}",
+ requestId, newTcaAbatementEntity);
+ abatementPersistenceContext.save(newTcaAbatementEntity);
+ return tcaExecutionContext;
+
+ } else {
+ // no previous onset event found
+ final String terminatingMessage =
+ "Ignored orphan Abated Message. No previous ONSET event found for lookup key: " + lookupKey;
+ setTerminatingMessage(terminatingMessage, tcaExecutionContext, false);
+ return tcaExecutionContext;
+ }
+
+ // Only ONSET and ABATED closed loop status are supported
+ default:
+ final String errorMessage = String.format(
+ "Request Id: %s. Unexpected ClosedLoopEventStatus: %s - Only ONSET and ABATED are supported.",
+ requestId, closedLoopEventStatus);
+ throw new TcaProcessingException(errorMessage, new IllegalStateException(errorMessage));
+ }
+
+ }
+
+ private static String createLookupKey(final EventListener eventListener,
+ final MetricsPerEventName violatedMetricsPerEventName) {
+ // no null check required as all are required fields
+ final String eventName = violatedMetricsPerEventName.getEventName();
+ final String sourceName = eventListener.getEvent().getCommonEventHeader().getSourceName();
+ final String reportingEntityName = eventListener.getEvent().getCommonEventHeader().getReportingEntityName();
+ // violated threshold will always be present
+ final Threshold violatedThreshold = violatedMetricsPerEventName.getThresholds().get(0);
+ final String closedLoopControlName = violatedThreshold.getClosedLoopControlName();
+ final String fieldPath = violatedThreshold.getFieldPath();
+ return Stream.of(eventName, sourceName, reportingEntityName, closedLoopControlName, fieldPath)
+ .collect(Collectors.joining(TcaModelConstants.TCA_ROW_KEY_DELIMITER));
+
+ }
+}
diff --git a/dcae-analytics/dcae-analytics-tca-core/src/main/java/org/onap/dcae/analytics/tca/core/util/function/calculation/TcaAlertCreationFunction.java b/dcae-analytics/dcae-analytics-tca-core/src/main/java/org/onap/dcae/analytics/tca/core/util/function/calculation/TcaAlertCreationFunction.java
new file mode 100644
index 0000000..54ea48d
--- /dev/null
+++ b/dcae-analytics/dcae-analytics-tca-core/src/main/java/org/onap/dcae/analytics/tca/core/util/function/calculation/TcaAlertCreationFunction.java
@@ -0,0 +1,129 @@
+/*
+ * ================================================================================
+ * Copyright (c) 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ *
+ */
+
+package org.onap.dcae.analytics.tca.core.util.function.calculation;
+
+import java.util.Optional;
+
+import org.onap.dcae.analytics.model.TcaModelConstants;
+import org.onap.dcae.analytics.model.cef.CommonEventHeader;
+import org.onap.dcae.analytics.model.cef.EventListener;
+import org.onap.dcae.analytics.tca.core.service.TcaExecutionContext;
+import org.onap.dcae.analytics.tca.core.service.TcaResultContext;
+import org.onap.dcae.analytics.tca.model.facade.Aai;
+import org.onap.dcae.analytics.tca.model.facade.TcaAlert;
+import org.onap.dcae.analytics.tca.model.policy.ClosedLoopEventStatus;
+import org.onap.dcae.analytics.tca.model.policy.ControlLoopSchemaType;
+import org.onap.dcae.analytics.tca.model.policy.MetricsPerEventName;
+import org.onap.dcae.analytics.tca.model.policy.Threshold;
+
+/**
+ * @author Rajiv Singla
+ */
+public class TcaAlertCreationFunction implements TcaCalculationFunction {
+
+ @Override
+ public TcaExecutionContext calculate(final TcaExecutionContext tcaExecutionContext) {
+
+ // get violated metrics per event name
+ final Optional<MetricsPerEventName> violatedMetricsPerEventNameOptional =
+ Optional.ofNullable(tcaExecutionContext.getTcaResultContext())
+ .map(TcaResultContext::getViolatedMetricsPerEventName);
+
+ // If no violated metrics per event name is present skip alert creation
+ if (!violatedMetricsPerEventNameOptional.isPresent()) {
+ return tcaExecutionContext;
+ }
+
+ final TcaResultContext resultContext = tcaExecutionContext.getTcaResultContext();
+
+ // Request id should be set to previous request id for abated events if present
+ final String requestId = Optional.ofNullable(resultContext.getPreviousRequestId())
+ .orElse(tcaExecutionContext.getRequestId());
+
+ // create new tca alert
+ final TcaAlert tcaAlert = createNewTcaAlert(requestId, tcaExecutionContext.getTcaProcessingContext()
+ .getEventListener(), violatedMetricsPerEventNameOptional.get());
+
+ // update tca processing result context with alert message
+ tcaExecutionContext.getTcaResultContext().setTcaAlert(tcaAlert);
+
+ return tcaExecutionContext;
+ }
+
+ private static TcaAlert createNewTcaAlert(final String requestId,
+ final EventListener eventListener,
+ final MetricsPerEventName violatedMetricsPerEventName) {
+ final Threshold violatedThreshold = violatedMetricsPerEventName.getThresholds().get(0);
+ final CommonEventHeader commonEventHeader = eventListener.getEvent().getCommonEventHeader();
+
+ final TcaAlert tcaAlert = new TcaAlert();
+ // ClosedLoopControlName included in the DCAE configuration Policy
+ tcaAlert.setClosedLoopControlName(violatedThreshold.getClosedLoopControlName());
+ // version included in the DCAE configuration Policy
+ tcaAlert.setVersion(violatedThreshold.getVersion());
+ // request id
+ tcaAlert.setRequestId(requestId);
+ // commonEventHeader.startEpochMicrosec from the received VES message
+ tcaAlert.setClosedLoopAlarmStart(commonEventHeader.getStartEpochMicrosec());
+ // commonEventHeader.lastEpochMicrosec from the received VES message for abated alerts
+ if (violatedThreshold.getClosedLoopEventStatus() == ClosedLoopEventStatus.ABATED) {
+ tcaAlert.setClosedLoopAlarmEnd(commonEventHeader.getLastEpochMicrosec());
+ }
+ // get service name
+ tcaAlert.setClosedLoopEventClient(TcaModelConstants.TCA_SERVICE_NAME);
+
+ final Aai aai = new Aai();
+ tcaAlert.setAai(aai);
+
+ // VM specific settings
+ if (violatedMetricsPerEventName.getControlLoopSchemaType() == ControlLoopSchemaType.VM) {
+ // Hard Coded - "VM"
+ tcaAlert.setTargetType(TcaModelConstants.TCA_ALERT_VM_TARGET_TYPE);
+ // Hard Coded - "vserver.vserver-name"
+ tcaAlert.setTarget(TcaModelConstants.TCA_ALERT_VM_TARGET);
+ // commonEventHeader.sourceName from the received VES message
+ aai.setGenericServerName(commonEventHeader.getSourceName());
+ } else {
+ // VNF specific settings
+ // Hard Coded - "VNF"
+ tcaAlert.setTargetType(TcaModelConstants.TCA_ALERT_VNF_TARGET_TYPE);
+ // Hard Coded - "generic-vnf.vnf-name"
+ tcaAlert.setTarget(TcaModelConstants.TCA_ALERT_VNF_TARGET);
+ // commonEventHeader.sourceName from the received VES message
+ aai.setGenericVNFName(commonEventHeader.getSourceName());
+ }
+
+ // Hard Coded - "DCAE"
+ tcaAlert.setFrom(TcaModelConstants.TCA_VES_RESPONSE_FROM);
+ // policyScope included in the DCAE configuration Policy
+ tcaAlert.setPolicyScope(violatedMetricsPerEventName.getPolicyScope());
+ // policyName included in the DCAE configuration Policy
+ tcaAlert.setPolicyName(violatedMetricsPerEventName.getPolicyName());
+ // policyVersion included in the DCAE configuration Policy
+ tcaAlert.setPolicyVersion(violatedMetricsPerEventName.getPolicyVersion());
+ // Extracted from violated threshold
+ tcaAlert.setClosedLoopEventStatus(violatedThreshold.getClosedLoopEventStatus().name());
+
+ // return new tca Alert
+ return tcaAlert;
+ }
+
+
+}
diff --git a/dcae-analytics/dcae-analytics-tca-core/src/main/java/org/onap/dcae/analytics/tca/core/util/function/calculation/TcaCalculationFunction.java b/dcae-analytics/dcae-analytics-tca-core/src/main/java/org/onap/dcae/analytics/tca/core/util/function/calculation/TcaCalculationFunction.java
new file mode 100644
index 0000000..ec9f7bd
--- /dev/null
+++ b/dcae-analytics/dcae-analytics-tca-core/src/main/java/org/onap/dcae/analytics/tca/core/util/function/calculation/TcaCalculationFunction.java
@@ -0,0 +1,84 @@
+/*
+ * ================================================================================
+ * Copyright (c) 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ *
+ */
+
+package org.onap.dcae.analytics.tca.core.util.function.calculation;
+
+import java.util.function.Function;
+
+import org.onap.dcae.analytics.tca.core.service.TcaExecutionContext;
+import org.onap.dcae.analytics.tca.core.service.TcaProcessingContext;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Functional interface which all TCA calculation functions should implement
+ *
+ * @author Rajiv Singla
+ */
+@FunctionalInterface
+public interface TcaCalculationFunction extends Function<TcaExecutionContext, TcaExecutionContext> {
+
+ Logger logger = LoggerFactory.getLogger(TcaCalculationFunction.class);
+
+ TcaExecutionContext calculate(TcaExecutionContext tcaExecutionContext);
+
+
+ default TcaExecutionContext preCalculation(TcaExecutionContext tcaExecutionContext) {
+ // do nothing
+ return tcaExecutionContext;
+ }
+
+ default TcaExecutionContext postCalculation(TcaExecutionContext tcaExecutionContext) {
+ // do nothing
+ return tcaExecutionContext;
+ }
+
+ @Override
+ default TcaExecutionContext apply(TcaExecutionContext tcaExecutionContext) {
+ // triggers pre calculate, calculate nad post calculate
+ return postCalculation(calculate(preCalculation(tcaExecutionContext)));
+ }
+
+ /**
+ * Updates TCA Processing context with early terminating message or error message
+ *
+ * @param terminatingMessage terminating message to be set in processing context
+ * @param tcaExecutionContext current tca execution context
+ * @param isErrorMessage specifies if terminating message is an error message
+ *
+ * @return updated tca execution context with early termination or error message and continue processing flag as
+ * false
+ */
+ default TcaExecutionContext setTerminatingMessage(final String terminatingMessage,
+ final TcaExecutionContext tcaExecutionContext,
+ final boolean isErrorMessage) {
+ final TcaProcessingContext tcaProcessingContext = tcaExecutionContext.getTcaProcessingContext();
+ if (isErrorMessage) {
+ logger.error("Request Id: {}. Error Message: {}", tcaExecutionContext.getRequestId(), terminatingMessage);
+ tcaProcessingContext.setErrorMessage(terminatingMessage);
+ } else {
+ logger.debug("Request Id: {}. Early Termination Message: {}", tcaExecutionContext.getRequestId(),
+ terminatingMessage);
+ tcaProcessingContext.setEarlyTerminationMessage(terminatingMessage);
+ }
+ tcaProcessingContext.setContinueProcessing(false);
+ return tcaExecutionContext;
+ }
+
+}
diff --git a/dcae-analytics/dcae-analytics-tca-core/src/main/java/org/onap/dcae/analytics/tca/core/util/function/calculation/TcaCalculator.java b/dcae-analytics/dcae-analytics-tca-core/src/main/java/org/onap/dcae/analytics/tca/core/util/function/calculation/TcaCalculator.java
new file mode 100644
index 0000000..d404ffe
--- /dev/null
+++ b/dcae-analytics/dcae-analytics-tca-core/src/main/java/org/onap/dcae/analytics/tca/core/util/function/calculation/TcaCalculator.java
@@ -0,0 +1,60 @@
+/*
+ * ================================================================================
+ * Copyright (c) 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ *
+ */
+
+package org.onap.dcae.analytics.tca.core.util.function.calculation;
+
+import java.util.List;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+import org.onap.dcae.analytics.tca.core.service.TcaExecutionContext;
+
+/**
+ * TCA Calculator combines all TCA calculation functions into one single function
+ *
+ * @author Rajiv Singla
+ */
+public class TcaCalculator implements TcaCalculationFunction {
+
+ private static final List<TcaCalculationFunction> TCA_CALCULATOR_FUNCTIONS_CHAIN =
+ Stream.of(
+ new TcaEventListenerExtractor(),
+ new TcaDomainFilter(),
+ new TcaEventNameFilter(),
+ new TcaThresholdViolationCalculator(),
+ new TcaAbatementCalculator(),
+ new TcaAlertCreationFunction(),
+ new TcaAaiEnrichmentFunction()).collect(Collectors.toList());
+
+ @Override
+ public TcaExecutionContext calculate(final TcaExecutionContext tcaExecutionContext) {
+
+ TcaExecutionContext accumulator = tcaExecutionContext;
+
+ for (TcaCalculationFunction tcaCalculationFunction : TCA_CALCULATOR_FUNCTIONS_CHAIN) {
+ if (!accumulator.getTcaProcessingContext().isContinueProcessing()) {
+ // do early termination
+ break;
+ } else {
+ accumulator = tcaCalculationFunction.apply(accumulator);
+ }
+ }
+ return accumulator;
+ }
+}
diff --git a/dcae-analytics/dcae-analytics-tca-core/src/main/java/org/onap/dcae/analytics/tca/core/util/function/calculation/TcaDomainFilter.java b/dcae-analytics/dcae-analytics-tca-core/src/main/java/org/onap/dcae/analytics/tca/core/util/function/calculation/TcaDomainFilter.java
new file mode 100644
index 0000000..a54b615
--- /dev/null
+++ b/dcae-analytics/dcae-analytics-tca-core/src/main/java/org/onap/dcae/analytics/tca/core/util/function/calculation/TcaDomainFilter.java
@@ -0,0 +1,75 @@
+/*
+ * ================================================================================
+ * Copyright (c) 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ *
+ */
+
+package org.onap.dcae.analytics.tca.core.util.function.calculation;
+
+import java.util.Optional;
+
+import org.onap.dcae.analytics.model.cef.CommonEventHeader;
+import org.onap.dcae.analytics.model.cef.Domain;
+import org.onap.dcae.analytics.model.cef.Event;
+import org.onap.dcae.analytics.model.cef.EventListener;
+import org.onap.dcae.analytics.tca.core.service.TcaExecutionContext;
+import org.onap.dcae.analytics.tca.core.service.TcaProcessingContext;
+
+/**
+ * @author Rajiv Singla
+ */
+public class TcaDomainFilter implements TcaCalculationFunction {
+
+ @Override
+ public TcaExecutionContext calculate(final TcaExecutionContext tcaExecutionContext) {
+
+ final TcaProcessingContext tcaProcessingContext = tcaExecutionContext.getTcaProcessingContext();
+ final String cefMessage = tcaExecutionContext.getCefMessage();
+
+ // Extract CEF domain as it is must be present as per CEF Schema
+ final Optional<Domain> domainOptional = Optional.ofNullable(tcaProcessingContext.getEventListener())
+ .map(EventListener::getEvent)
+ .map(Event::getCommonEventHeader)
+ .map(CommonEventHeader::getDomain);
+
+ // Check domain is present
+ if (!domainOptional.isPresent()) {
+ final String errorMessage =
+ "Event -> Common Event Header -> Domain not present. Invalid CEF Message: " + cefMessage;
+ setTerminatingMessage(errorMessage, tcaExecutionContext, true);
+ return tcaExecutionContext;
+ }
+
+ // Get Policy and CEF Message Domain
+ final String policyDomain = tcaExecutionContext.getTcaPolicy().getDomain();
+ final String cefMessageDomain = domainOptional.get().name();
+
+ // Check Policy domain matches CEF message domain
+ if (!policyDomain.equalsIgnoreCase(cefMessageDomain)) {
+ final String earlyTerminationMessage = String.format(
+ "Policy Domain does not match CEF Message Domain. Policy Domain: %s, CEF Message Domain: %s",
+ policyDomain, cefMessageDomain);
+ setTerminatingMessage(earlyTerminationMessage, tcaExecutionContext, false);
+ return tcaExecutionContext;
+ }
+
+
+ // Policy Domain and CEF Message Domain match successful
+ // do nothing
+
+ return tcaExecutionContext;
+ }
+}
diff --git a/dcae-analytics/dcae-analytics-tca-core/src/main/java/org/onap/dcae/analytics/tca/core/util/function/calculation/TcaEventListenerExtractor.java b/dcae-analytics/dcae-analytics-tca-core/src/main/java/org/onap/dcae/analytics/tca/core/util/function/calculation/TcaEventListenerExtractor.java
new file mode 100644
index 0000000..b194da8
--- /dev/null
+++ b/dcae-analytics/dcae-analytics-tca-core/src/main/java/org/onap/dcae/analytics/tca/core/util/function/calculation/TcaEventListenerExtractor.java
@@ -0,0 +1,76 @@
+/*
+ * ================================================================================
+ * Copyright (c) 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ *
+ */
+
+package org.onap.dcae.analytics.tca.core.util.function.calculation;
+
+import java.util.Optional;
+
+import org.onap.dcae.analytics.model.cef.EventListener;
+import org.onap.dcae.analytics.model.util.json.AnalyticsModelJsonConversion;
+import org.onap.dcae.analytics.tca.core.service.TcaExecutionContext;
+
+/**
+ * Tca Event Listener Calculation Function converts incoming CEF string message
+ * to Java Object of type Event Listener
+ *
+ * @author Rajiv Singla
+ */
+public class TcaEventListenerExtractor implements TcaCalculationFunction {
+
+ @Override
+ public TcaExecutionContext calculate(final TcaExecutionContext tcaExecutionContext) {
+
+ final String cefMessage = tcaExecutionContext.getCefMessage();
+
+ // Check blank message
+ if (cefMessage == null || cefMessage.isEmpty() || cefMessage.trim().isEmpty()) {
+ final String errorMessage = "Blank CEF message cannot be converted to CEF Event Listener Object";
+ setTerminatingMessage(errorMessage, tcaExecutionContext, true);
+ return tcaExecutionContext;
+ }
+
+
+ // Check CEF message is a valid JSON Object
+ final String trimmedMessage = cefMessage.trim();
+ if (!(trimmedMessage.startsWith("{") && trimmedMessage.endsWith("}"))) {
+ final String errorMessage =
+ "CEF Message must be a JSON object starting and ending with curly braces. Invalid JSON String: " +
+ cefMessage;
+ setTerminatingMessage(errorMessage, tcaExecutionContext, true);
+ return tcaExecutionContext;
+ }
+
+ // Parse CEF message as JSON Object
+ final Optional<EventListener> eventListenerOptional =
+ AnalyticsModelJsonConversion.EVENT_LISTENER_JSON_FUNCTION.apply(cefMessage);
+
+ if (!eventListenerOptional.isPresent()) {
+ final String errorMessage =
+ "Unable to parse given CEF Message as JSON Object. CEF Message String: " + cefMessage;
+ setTerminatingMessage(errorMessage, tcaExecutionContext, true);
+ return tcaExecutionContext;
+ }
+
+
+ // JSON parsing completed successfully
+ tcaExecutionContext.getTcaProcessingContext().setEventListener(eventListenerOptional.get());
+
+ return tcaExecutionContext;
+ }
+}
diff --git a/dcae-analytics/dcae-analytics-tca-core/src/main/java/org/onap/dcae/analytics/tca/core/util/function/calculation/TcaEventNameFilter.java b/dcae-analytics/dcae-analytics-tca-core/src/main/java/org/onap/dcae/analytics/tca/core/util/function/calculation/TcaEventNameFilter.java
new file mode 100644
index 0000000..574e9ba
--- /dev/null
+++ b/dcae-analytics/dcae-analytics-tca-core/src/main/java/org/onap/dcae/analytics/tca/core/util/function/calculation/TcaEventNameFilter.java
@@ -0,0 +1,77 @@
+/*
+ * ================================================================================
+ * Copyright (c) 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ *
+ */
+
+package org.onap.dcae.analytics.tca.core.util.function.calculation;
+
+import java.util.Optional;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+import org.onap.dcae.analytics.model.cef.CommonEventHeader;
+import org.onap.dcae.analytics.model.cef.Event;
+import org.onap.dcae.analytics.model.cef.EventListener;
+import org.onap.dcae.analytics.tca.core.service.TcaExecutionContext;
+import org.onap.dcae.analytics.tca.model.policy.MetricsPerEventName;
+import org.onap.dcae.analytics.tca.model.policy.TcaPolicy;
+
+/**
+ * @author Rajiv Singla
+ */
+public class TcaEventNameFilter implements TcaCalculationFunction {
+
+ @Override
+ public TcaExecutionContext calculate(final TcaExecutionContext tcaExecutionContext) {
+
+ final String cefMessage = tcaExecutionContext.getCefMessage();
+ final EventListener eventListener = tcaExecutionContext.getTcaProcessingContext().getEventListener();
+
+ final Optional<String> eventNameOptional = Optional.ofNullable(eventListener)
+ .map(EventListener::getEvent)
+ .map(Event::getCommonEventHeader)
+ .map(CommonEventHeader::getEventName);
+
+ // Check Event name is present
+ if (!eventNameOptional.isPresent()) {
+ final String errorMessage =
+ "Event -> Common Event Header -> Event Name not present. Invalid CEF Message: " + cefMessage;
+ setTerminatingMessage(errorMessage, tcaExecutionContext, true);
+ return tcaExecutionContext;
+ }
+
+ // Get CEF Message Event name and Event names in tca policy
+ final String cefMessageEventName = eventNameOptional.get();
+ final TcaPolicy tcaPolicy = tcaExecutionContext.getTcaPolicy();
+ final Set<String> policyEventNames = tcaPolicy.getMetricsPerEventName().stream()
+ .map(MetricsPerEventName::getEventName).collect(Collectors.toSet());
+
+ // Check CEF Message Event name matches any Policy Event names
+ if (!policyEventNames.contains(cefMessageEventName)) {
+ final String earlyTerminationMessage = String.format(
+ "CEF Message Event name does not match any Policy Event Names. " +
+ "Message EventName: %s, Policy Event Names: %s", cefMessageEventName, policyEventNames);
+ setTerminatingMessage(earlyTerminationMessage, tcaExecutionContext, false);
+ return tcaExecutionContext;
+ }
+
+ // CEF Messages one of the the Policy Event names
+ // do nothing
+
+ return tcaExecutionContext;
+ }
+}
diff --git a/dcae-analytics/dcae-analytics-tca-core/src/main/java/org/onap/dcae/analytics/tca/core/util/function/calculation/TcaThresholdViolationCalculator.java b/dcae-analytics/dcae-analytics-tca-core/src/main/java/org/onap/dcae/analytics/tca/core/util/function/calculation/TcaThresholdViolationCalculator.java
new file mode 100644
index 0000000..053fcab
--- /dev/null
+++ b/dcae-analytics/dcae-analytics-tca-core/src/main/java/org/onap/dcae/analytics/tca/core/util/function/calculation/TcaThresholdViolationCalculator.java
@@ -0,0 +1,270 @@
+/*
+ * ================================================================================
+ * Copyright (c) 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ *
+ */
+
+package org.onap.dcae.analytics.tca.core.util.function.calculation;
+
+import com.jayway.jsonpath.DocumentContext;
+import com.jayway.jsonpath.JsonPath;
+import com.jayway.jsonpath.TypeRef;
+
+import java.math.BigDecimal;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.LinkedHashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Optional;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+import javax.annotation.Nonnull;
+
+import org.onap.dcae.analytics.model.cef.CommonEventHeader;
+import org.onap.dcae.analytics.model.cef.Event;
+import org.onap.dcae.analytics.model.cef.EventListener;
+import org.onap.dcae.analytics.tca.core.exception.TcaProcessingException;
+import org.onap.dcae.analytics.tca.core.service.TcaExecutionContext;
+import org.onap.dcae.analytics.tca.core.service.TcaResultContext;
+import org.onap.dcae.analytics.tca.model.policy.MetricsPerEventName;
+import org.onap.dcae.analytics.tca.model.policy.TcaPolicy;
+import org.onap.dcae.analytics.tca.model.policy.Threshold;
+
+/**
+ * @author Rajiv Singla
+ */
+public class TcaThresholdViolationCalculator implements TcaCalculationFunction {
+
+ @Override
+ public TcaExecutionContext calculate(final TcaExecutionContext tcaExecutionContext) {
+
+ final String cefMessage = tcaExecutionContext.getCefMessage();
+ final EventListener eventListener = tcaExecutionContext.getTcaProcessingContext().getEventListener();
+ final TcaPolicy tcaPolicy = tcaExecutionContext.getTcaPolicy();
+
+ // Get CEF Event Name
+ final String cefEventName = Optional.ofNullable(eventListener)
+ .map(EventListener::getEvent)
+ .map(Event::getCommonEventHeader)
+ .map(CommonEventHeader::getEventName)
+ .orElseThrow(() -> new TcaProcessingException("Required Field: EventName not present"));
+
+ // Get Policy's metrics per event name matching CEF message event name
+ final MetricsPerEventName policyMetricsPerEventName =
+ tcaPolicy.getMetricsPerEventName().stream()
+ .filter(m -> m.getEventName().equalsIgnoreCase(cefEventName))
+ .findFirst().orElseThrow(() ->
+ new TcaProcessingException("Required Field: MetricsPerEventName not present"));
+
+
+ // get violated policy threshold for cef event name sorted by severity
+ final Optional<Threshold> thresholdOptional =
+ getViolatedThreshold(policyMetricsPerEventName.getThresholds(), cefMessage);
+
+
+ // Check if threshold violation is present
+ if (!thresholdOptional.isPresent()) {
+ final String earlyTerminationMessage = "No Policy Threshold violation detected in CEF Message";
+ setTerminatingMessage(earlyTerminationMessage, tcaExecutionContext, false);
+ return tcaExecutionContext;
+ }
+
+
+ // Threshold violations are present - update tca processing result context
+ final MetricsPerEventName violatedMetricsPerEventName = copyMetricsPerEventName(policyMetricsPerEventName);
+ final Threshold violatedThreshold = thresholdOptional.get();
+ violatedMetricsPerEventName.setThresholds(Collections.singletonList(violatedThreshold));
+ final TcaResultContext tcaResultContext =
+ tcaExecutionContext.getTcaResultContext();
+ tcaResultContext.setViolatedMetricsPerEventName(violatedMetricsPerEventName);
+
+ return tcaExecutionContext;
+ }
+
+
+ /**
+ * Provides violated threshold
+ *
+ * @param policyThresholds policy thresholds that need to applied to incoming cef message
+ * @param cefMessage incoming cef message
+ *
+ * @return list of all violated threshold
+ */
+ private static Optional<Threshold> getViolatedThreshold(final List<Threshold> policyThresholds,
+ final String cefMessage) {
+
+ // map containing key as field path and associated policy thresholds
+ final Map<String, List<Threshold>> policyFieldPathsMap = new LinkedHashMap<>();
+ for (final Threshold policyThreshold : policyThresholds) {
+ if (policyFieldPathsMap.get(policyThreshold.getFieldPath()) == null) {
+ final LinkedList<Threshold> policyThresholdList = new LinkedList<>();
+ policyThresholdList.add(policyThreshold);
+ policyFieldPathsMap.put(policyThreshold.getFieldPath(), policyThresholdList);
+ } else {
+ policyFieldPathsMap.get(policyThreshold.getFieldPath()).add(policyThreshold);
+ }
+ }
+
+ // get map containing key as field path and values for json path
+ final Map<String, List<BigDecimal>> messageFieldValuesMap =
+ getJsonPathValues(cefMessage, policyFieldPathsMap.keySet());
+
+ // if no matching path values - assuming no threshold violations
+ if (messageFieldValuesMap.isEmpty()) {
+ return Optional.empty();
+ }
+
+ // Determine all violated thresholds per message field Path
+ final Map<String, Threshold> violatedThresholdsMap = new HashMap<>();
+ for (Map.Entry<String, List<BigDecimal>> messageFieldValuesMapEntry : messageFieldValuesMap.entrySet()) {
+ final String messageFieldPath = messageFieldValuesMapEntry.getKey();
+ final List<Threshold> messageFieldAssociatedPolicyThresholds = policyFieldPathsMap.get(messageFieldPath);
+ if (messageFieldAssociatedPolicyThresholds != null) {
+ final Optional<Threshold> thresholdOptional = computeViolatedThreshold(
+ messageFieldValuesMapEntry.getValue(), messageFieldAssociatedPolicyThresholds);
+ thresholdOptional.ifPresent(threshold -> violatedThresholdsMap.put(messageFieldPath, threshold));
+ }
+ }
+
+ // if multiple fields have violated threshold - grab the first one with max severity
+ return violatedThresholdsMap.values().stream()
+ .sorted(Comparator.comparing(Threshold::getSeverity)).findFirst();
+
+ }
+
+ /**
+ * Computes if any CEF Message Fields have violated any Policy Thresholds. For the same policy field path
+ * it applies threshold in order of their severity and then by direction and returns first violated threshold
+ *
+ * @param messageFieldValues Field Path Values extracted from CEF Message
+ * @param fieldThresholds Policy Thresholds for Field Path
+ *
+ * @return Optional of violated threshold for a field path
+ */
+ private static Optional<Threshold> computeViolatedThreshold(final List<BigDecimal> messageFieldValues,
+ final List<Threshold> fieldThresholds) {
+
+ // sort thresholds based on severity and then based on direction
+ final List<Threshold> sortedPolicyThresholds = fieldThresholds.stream()
+ .sorted((t1, t2) -> {
+ if (t1.getSeverity().compareTo(t2.getSeverity()) != 0) {
+ return t1.getSeverity().compareTo(t2.getSeverity());
+ } else {
+ return t1.getDirection().compareTo(t2.getDirection());
+ }
+ })
+ .collect(Collectors.toList());
+
+ // Now apply each threshold to field values
+ for (final Threshold policyThreshold : sortedPolicyThresholds) {
+ for (final BigDecimal messageFieldValue : messageFieldValues) {
+ final Boolean isThresholdViolated =
+ policyThreshold.getDirection().operate(messageFieldValue,
+ new BigDecimal(policyThreshold.getThresholdValue()));
+ if (isThresholdViolated) {
+ final Threshold violatedThreshold = copyThreshold(policyThreshold);
+ violatedThreshold.setActualFieldValue(messageFieldValue);
+ return Optional.of(violatedThreshold);
+ }
+ }
+ }
+ return Optional.empty();
+ }
+
+ /**
+ * Extracts json path values for given json Field Path from using Json path notation.
+ *
+ * @param message CEF Message
+ * @param jsonFieldPaths Json Field Paths
+ *
+ * @return Map containing key as json path and values as values associated with that json path
+ */
+ private static Map<String, List<BigDecimal>> getJsonPathValues(@Nonnull String message,
+ @Nonnull Set<String> jsonFieldPaths) {
+
+ final Map<String, List<BigDecimal>> jsonFieldPathMap = new HashMap<>();
+ final DocumentContext documentContext = JsonPath.parse(message);
+
+ for (String jsonFieldPath : jsonFieldPaths) {
+ List<BigDecimal> jsonFieldValues;
+
+ try {
+ jsonFieldValues = documentContext.read(jsonFieldPath, new TypeRef<List<BigDecimal>>() {
+ });
+ } catch (Exception e) {
+ final String errorMessage = String.format(
+ "Unable to convert jsonFieldPath value to valid number." +
+ "Json Path: %s.Incoming message: %s", jsonFieldPath, message);
+ throw new TcaProcessingException(errorMessage, e);
+ }
+ // If Json Field Values are present
+ if (jsonFieldValues != null && !jsonFieldValues.isEmpty()) {
+ // Filter out all null values in the filed values list
+ final List<BigDecimal> nonNullValues =
+ jsonFieldValues.stream().filter(Objects::nonNull).collect(Collectors.toList());
+ // If there are non null values put them in the map
+ if (!nonNullValues.isEmpty()) {
+ jsonFieldPathMap.put(jsonFieldPath, nonNullValues);
+ }
+ }
+ }
+
+ return jsonFieldPathMap;
+ }
+
+ /**
+ * Creates a new threshold hold object by copying the value of given threshold object
+ *
+ * @param threshold threshold that needs to be copied
+ *
+ * @return new threshold object which is copy of given threshold object
+ */
+ private static Threshold copyThreshold(final Threshold threshold) {
+ final Threshold copyThreshold = new Threshold();
+ copyThreshold.setClosedLoopControlName(threshold.getClosedLoopControlName());
+ copyThreshold.setClosedLoopEventStatus(threshold.getClosedLoopEventStatus());
+ copyThreshold.setVersion(threshold.getVersion());
+ copyThreshold.setFieldPath(threshold.getFieldPath());
+ copyThreshold.setThresholdValue(threshold.getThresholdValue());
+ copyThreshold.setDirection(threshold.getDirection());
+ copyThreshold.setSeverity(threshold.getSeverity());
+ return copyThreshold;
+ }
+
+ /**
+ * Returns a copy of metric Per event name without copying thresholds
+ *
+ * @param metricsPerEventName metric per event name that needs to be copied
+ *
+ * @return new metric per event name object which is copy of given object
+ */
+ private static MetricsPerEventName copyMetricsPerEventName(final MetricsPerEventName metricsPerEventName) {
+ final MetricsPerEventName copyMetricsPerEventName = new MetricsPerEventName();
+ copyMetricsPerEventName.setEventName(metricsPerEventName.getEventName());
+ copyMetricsPerEventName.setControlLoopSchemaType(metricsPerEventName.getControlLoopSchemaType());
+ copyMetricsPerEventName.setPolicyScope(metricsPerEventName.getPolicyScope());
+ copyMetricsPerEventName.setPolicyName(metricsPerEventName.getPolicyName());
+ copyMetricsPerEventName.setPolicyVersion(metricsPerEventName.getPolicyVersion());
+ // no thresholds copied
+ return copyMetricsPerEventName;
+ }
+
+}
diff --git a/dcae-analytics/dcae-analytics-tca-core/src/test/java/org/onap/dcae/analytics/tca/core/BaseTcaCoreTest.java b/dcae-analytics/dcae-analytics-tca-core/src/test/java/org/onap/dcae/analytics/tca/core/BaseTcaCoreTest.java
new file mode 100644
index 0000000..0d32190
--- /dev/null
+++ b/dcae-analytics/dcae-analytics-tca-core/src/test/java/org/onap/dcae/analytics/tca/core/BaseTcaCoreTest.java
@@ -0,0 +1,121 @@
+/*
+ * ================================================================================
+ * Copyright (c) 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ *
+ */
+
+package org.onap.dcae.analytics.tca.core;
+
+import org.onap.dcae.analytics.model.cef.EventListener;
+import org.onap.dcae.analytics.model.util.json.AnalyticsModelJsonConversion;
+import org.onap.dcae.analytics.tca.core.domain.TestTcaAaiEnrichmentContext;
+import org.onap.dcae.analytics.tca.core.domain.TestTcaAbatementContext;
+import org.onap.dcae.analytics.tca.core.service.GenericTcaExecutionContext;
+import org.onap.dcae.analytics.tca.core.service.GenericTcaExecutionContext.GenericTcaExecutionContextBuilder;
+import org.onap.dcae.analytics.tca.core.service.GenericTcaProcessingContext;
+import org.onap.dcae.analytics.tca.core.service.GenericTcaResultContext;
+import org.onap.dcae.analytics.tca.core.service.TcaAbatementContext;
+import org.onap.dcae.analytics.tca.core.service.TcaExecutionContext;
+import org.onap.dcae.analytics.tca.core.service.TcaProcessingContext;
+import org.onap.dcae.analytics.tca.core.service.TcaResultContext;
+import org.onap.dcae.analytics.tca.model.policy.TcaPolicy;
+import org.onap.dcae.analytics.tca.model.util.json.TcaModelJsonConversion;
+import org.onap.dcae.analytics.test.BaseAnalyticsUnitTest;
+
+/**
+ * @author Rajiv Singla
+ */
+public abstract class BaseTcaCoreTest extends BaseAnalyticsUnitTest {
+
+
+ protected static final String TEST_POLICY_JSON_STRING;
+ protected static final String TEST_CEF_EVENT_LISTENER_STRING;
+ protected static final String TEST_CEF_JSON_MESSAGE_WITH_VIOLATION_STRING;
+ protected static final String TEST_CEF_JSON_MESSAGE_WITH_ABATEMENT_STRING;
+ protected static final String TEST_CEF_JSON_MESSAGE_WITH_INAPPLICABLE_EVENT_NAME;
+ protected static final String TEST_REQUEST_ID = "testRequestId";
+ protected static final TcaPolicy TEST_TCA_POLICY;
+
+ static {
+
+ TEST_POLICY_JSON_STRING = fromStream(TestFileLocation.TCA_POLICY_JSON);
+ TEST_CEF_EVENT_LISTENER_STRING = fromStream(TestFileLocation.CEF_JSON_MESSAGE);
+ TEST_CEF_JSON_MESSAGE_WITH_VIOLATION_STRING = fromStream(TestFileLocation.CEF_JSON_MESSAGE_WITH_VIOLATION);
+ TEST_CEF_JSON_MESSAGE_WITH_ABATEMENT_STRING = fromStream(TestFileLocation.CEF_JSON_MESSAGE_WITH_ABATEMENT);
+ TEST_CEF_JSON_MESSAGE_WITH_INAPPLICABLE_EVENT_NAME = fromStream(TestFileLocation
+ .CEF_JSON_MESSAGE_WITH_INAPPLICABLE_EVENT_NAME);
+ TEST_TCA_POLICY = TcaModelJsonConversion.TCA_POLICY_JSON_FUNCTION.apply(TEST_POLICY_JSON_STRING)
+ .orElseThrow(() -> new IllegalStateException("Unable to get Test TcaPolicy"));
+ }
+
+ /**
+ * Provides Event Listener that can be used for testing purposes
+ *
+ * @return test Event Listener
+ */
+ protected EventListener getTestEventListener() {
+ return AnalyticsModelJsonConversion.EVENT_LISTENER_JSON_FUNCTION
+ .apply(TEST_CEF_EVENT_LISTENER_STRING)
+ .orElseThrow(() -> new IllegalStateException("Unable to get Test CEF Event Listener"));
+ }
+
+ /**
+ * Provides Event Listener with violation that can be used for testing purposes
+ *
+ * @return test Event Listener with violation
+ */
+ protected EventListener getTestEventListenerWithViolation() {
+ return AnalyticsModelJsonConversion.EVENT_LISTENER_JSON_FUNCTION
+ .apply(TEST_CEF_JSON_MESSAGE_WITH_VIOLATION_STRING)
+ .orElseThrow(() -> new IllegalStateException("Unable to get Test CEF Event Listeners with violation"));
+ }
+
+
+ /**
+ * Provides Event Listener with abatement that can be used for testing purposes
+ *
+ * @return test Event Listener with abatement
+ */
+ protected EventListener getTestEventListenerWithAbatement() {
+ return AnalyticsModelJsonConversion.EVENT_LISTENER_JSON_FUNCTION
+ .apply(TEST_CEF_JSON_MESSAGE_WITH_ABATEMENT_STRING)
+ .orElseThrow(() -> new IllegalStateException("Unable to get Test CEF Event Listeners with abatement"));
+ }
+
+
+ protected TcaExecutionContext getTestExecutionContext(final String cefMessage) {
+ final TestTcaAbatementContext testTcaAbatementContext = new TestTcaAbatementContext();
+ return getTestExecutionContextBuilder(cefMessage, TEST_TCA_POLICY, testTcaAbatementContext).build();
+ }
+
+ protected GenericTcaExecutionContextBuilder getTestExecutionContextBuilder(
+ final String cefMessage, final TcaPolicy tcaPolicy, final TcaAbatementContext tcaAbatementContext) {
+
+ final TcaProcessingContext tcaProcessingContext = new GenericTcaProcessingContext();
+ final TcaResultContext tcaResultContext = new GenericTcaResultContext();
+ final TestTcaAaiEnrichmentContext testTcaAaiEnrichmentContext = new TestTcaAaiEnrichmentContext();
+
+ return GenericTcaExecutionContext.builder()
+ .requestId(TEST_REQUEST_ID)
+ .cefMessage(cefMessage)
+ .tcaPolicy(tcaPolicy)
+ .tcaProcessingContext(tcaProcessingContext)
+ .tcaResultContext(tcaResultContext)
+ .tcaAbatementContext(tcaAbatementContext)
+ .tcaAaiEnrichmentContext(testTcaAaiEnrichmentContext);
+ }
+
+}
diff --git a/dcae-analytics/dcae-analytics-tca-core/src/test/java/org/onap/dcae/analytics/tca/core/domain/TestTcaAaiEnrichmentContext.java b/dcae-analytics/dcae-analytics-tca-core/src/test/java/org/onap/dcae/analytics/tca/core/domain/TestTcaAaiEnrichmentContext.java
new file mode 100644
index 0000000..db54a84
--- /dev/null
+++ b/dcae-analytics/dcae-analytics-tca-core/src/test/java/org/onap/dcae/analytics/tca/core/domain/TestTcaAaiEnrichmentContext.java
@@ -0,0 +1,36 @@
+/*
+ * ================================================================================
+ * Copyright (c) 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ *
+ */
+
+package org.onap.dcae.analytics.tca.core.domain;
+
+import lombok.Data;
+
+import org.onap.dcae.analytics.tca.core.service.TcaAaiEnrichmentContext;
+import org.onap.dcae.analytics.tca.core.service.TcaAaiEnrichmentService;
+
+/**
+ * @author Rajiv Singla
+ */
+@Data
+public class TestTcaAaiEnrichmentContext implements TcaAaiEnrichmentContext {
+
+ private boolean isAaiEnrichmentEnabled = true;
+ private TcaAaiEnrichmentService aaiEnrichmentService = new TestTcaAaiEnrichmentService();
+
+}
diff --git a/dcae-analytics/dcae-analytics-tca-core/src/test/java/org/onap/dcae/analytics/tca/core/domain/TestTcaAaiEnrichmentService.java b/dcae-analytics/dcae-analytics-tca-core/src/test/java/org/onap/dcae/analytics/tca/core/domain/TestTcaAaiEnrichmentService.java
new file mode 100644
index 0000000..2352f50
--- /dev/null
+++ b/dcae-analytics/dcae-analytics-tca-core/src/test/java/org/onap/dcae/analytics/tca/core/domain/TestTcaAaiEnrichmentService.java
@@ -0,0 +1,41 @@
+/*
+ * ================================================================================
+ * Copyright (c) 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ *
+ */
+
+package org.onap.dcae.analytics.tca.core.domain;
+
+import lombok.Data;
+
+import org.onap.dcae.analytics.tca.core.service.TcaAaiEnrichmentService;
+import org.onap.dcae.analytics.tca.core.service.TcaExecutionContext;
+import org.onap.dcae.analytics.tca.model.facade.TcaAlert;
+
+/**
+ * @author Rajiv Singla
+ */
+@Data
+public class TestTcaAaiEnrichmentService implements TcaAaiEnrichmentService {
+
+ private TcaAlert enrichedTcaAlert;
+
+ @Override
+ public TcaAlert doAaiEnrichment(final TcaExecutionContext tcaExecutionContext) {
+ final TcaAlert tcaAlert = tcaExecutionContext.getTcaResultContext().getTcaAlert();
+ return enrichedTcaAlert == null ? tcaAlert : enrichedTcaAlert;
+ }
+}
diff --git a/dcae-analytics/dcae-analytics-tca-core/src/test/java/org/onap/dcae/analytics/tca/core/domain/TestTcaAbatementContext.java b/dcae-analytics/dcae-analytics-tca-core/src/test/java/org/onap/dcae/analytics/tca/core/domain/TestTcaAbatementContext.java
new file mode 100644
index 0000000..6a456b0
--- /dev/null
+++ b/dcae-analytics/dcae-analytics-tca-core/src/test/java/org/onap/dcae/analytics/tca/core/domain/TestTcaAbatementContext.java
@@ -0,0 +1,46 @@
+/*
+ * ================================================================================
+ * Copyright (c) 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ *
+ */
+
+package org.onap.dcae.analytics.tca.core.domain;
+
+import lombok.Data;
+
+import java.util.Date;
+
+import org.onap.dcae.analytics.tca.core.service.TcaAbatementContext;
+import org.onap.dcae.analytics.tca.core.service.TcaAbatementEntity;
+import org.onap.dcae.analytics.tca.core.service.TcaAbatementRepository;
+
+/**
+ * @author Rajiv Singla
+ */
+@Data
+public class TestTcaAbatementContext implements TcaAbatementContext {
+
+ private boolean isAbatementEnabled = true;
+ private TcaAbatementRepository tcaAbatementRepository = new TestTcaAbatementRepository();
+
+
+ @Override
+ public TcaAbatementEntity create(
+ final String lookupKey, final String requestId, final boolean isAbatementAlertSent) {
+ return new TestTcaAbatementEntity(new Date(), lookupKey, requestId, isAbatementAlertSent);
+ }
+
+}
diff --git a/dcae-analytics/dcae-analytics-tca-core/src/test/java/org/onap/dcae/analytics/tca/core/domain/TestTcaAbatementEntity.java b/dcae-analytics/dcae-analytics-tca-core/src/test/java/org/onap/dcae/analytics/tca/core/domain/TestTcaAbatementEntity.java
new file mode 100644
index 0000000..3e11405
--- /dev/null
+++ b/dcae-analytics/dcae-analytics-tca-core/src/test/java/org/onap/dcae/analytics/tca/core/domain/TestTcaAbatementEntity.java
@@ -0,0 +1,41 @@
+/*
+ * ================================================================================
+ * Copyright (c) 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ *
+ */
+
+package org.onap.dcae.analytics.tca.core.domain;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+
+import java.util.Date;
+
+import org.onap.dcae.analytics.tca.core.service.TcaAbatementEntity;
+
+/**
+ * @author Rajiv Singla
+ */
+@Data
+@AllArgsConstructor
+public class TestTcaAbatementEntity implements TcaAbatementEntity {
+
+ private Date lastModificationDate;
+ private String lookupKey;
+ private String requestId;
+ private boolean isAbatementAlertSent;
+
+}
diff --git a/dcae-analytics/dcae-analytics-tca-core/src/test/java/org/onap/dcae/analytics/tca/core/domain/TestTcaAbatementRepository.java b/dcae-analytics/dcae-analytics-tca-core/src/test/java/org/onap/dcae/analytics/tca/core/domain/TestTcaAbatementRepository.java
new file mode 100644
index 0000000..a55422a
--- /dev/null
+++ b/dcae-analytics/dcae-analytics-tca-core/src/test/java/org/onap/dcae/analytics/tca/core/domain/TestTcaAbatementRepository.java
@@ -0,0 +1,48 @@
+/*
+ * ================================================================================
+ * Copyright (c) 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ *
+ */
+
+package org.onap.dcae.analytics.tca.core.domain;
+
+import lombok.Data;
+
+import java.util.LinkedList;
+import java.util.List;
+
+import org.onap.dcae.analytics.tca.core.service.TcaAbatementEntity;
+import org.onap.dcae.analytics.tca.core.service.TcaAbatementRepository;
+
+/**
+ * @author Rajiv Singla
+ */
+@Data
+public class TestTcaAbatementRepository implements TcaAbatementRepository {
+
+ private List<TcaAbatementEntity> testLookupAbatementEntities = new LinkedList<>();
+
+ @Override
+ public void save(final TcaAbatementEntity tcaAbatementEntity) {
+ // do nothing
+ }
+
+ @Override
+ public List<TcaAbatementEntity> findByLookupKey(final String lookUpKey) {
+ return testLookupAbatementEntities;
+ }
+
+}
diff --git a/dcae-analytics/dcae-analytics-tca-core/src/test/java/org/onap/dcae/analytics/tca/core/util/function/calculation/TcaCalculatorTest.java b/dcae-analytics/dcae-analytics-tca-core/src/test/java/org/onap/dcae/analytics/tca/core/util/function/calculation/TcaCalculatorTest.java
new file mode 100644
index 0000000..d8fe043
--- /dev/null
+++ b/dcae-analytics/dcae-analytics-tca-core/src/test/java/org/onap/dcae/analytics/tca/core/util/function/calculation/TcaCalculatorTest.java
@@ -0,0 +1,88 @@
+/*
+ * ================================================================================
+ * Copyright (c) 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ *
+ */
+
+package org.onap.dcae.analytics.tca.core.util.function.calculation;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+import java.util.Collections;
+import java.util.Date;
+
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.Test;
+import org.onap.dcae.analytics.tca.core.BaseTcaCoreTest;
+import org.onap.dcae.analytics.tca.core.domain.TestTcaAbatementContext;
+import org.onap.dcae.analytics.tca.core.domain.TestTcaAbatementEntity;
+import org.onap.dcae.analytics.tca.core.domain.TestTcaAbatementRepository;
+import org.onap.dcae.analytics.tca.core.service.TcaExecutionContext;
+
+
+/**
+ * @author Rajiv Singla
+ */
+class TcaCalculatorTest extends BaseTcaCoreTest {
+
+ @Test
+ @DisplayName("Test TCA calculator with CEF Message without violation")
+ void testCEFMessageWithoutViolation() {
+ final TcaExecutionContext testExecutionContext =
+ getTestExecutionContext(TEST_CEF_EVENT_LISTENER_STRING);
+ final TcaExecutionContext result = new TcaCalculator().apply(testExecutionContext);
+ assertThat(result.getTcaProcessingContext().isContinueProcessing()).isFalse();
+ assertThat(result.getTcaProcessingContext().getErrorMessage()).isNull();
+ final String earlyTerminationMessage = result.getTcaProcessingContext().getEarlyTerminationMessage();
+ assertThat(earlyTerminationMessage).isNotNull();
+ logger.debug(earlyTerminationMessage);
+ assertThat(result.getTcaResultContext().isThresholdViolationsPresent()).isFalse();
+ }
+
+ @Test
+ @DisplayName("Test TCA calculator with CEF Message with violation")
+ void testCEFMessageWithViolation() {
+ final TcaExecutionContext testExecutionContext =
+ getTestExecutionContext(TEST_CEF_JSON_MESSAGE_WITH_VIOLATION_STRING);
+ final TcaExecutionContext result = new TcaCalculator().apply(testExecutionContext);
+ assertThat(result.getTcaProcessingContext().isContinueProcessing()).isTrue();
+ assertThat(result.getTcaResultContext().isThresholdViolationsPresent()).isTrue();
+ assertThat(result.getTcaResultContext().getTcaAlert().getRequestId()).isEqualTo(TEST_REQUEST_ID);
+ }
+
+
+ @Test
+ @DisplayName("Test TCA calculator with Abatement")
+ void testCEFMessageWithAbatement() {
+ final TestTcaAbatementContext testTcaAbatementContext = new TestTcaAbatementContext();
+ final TestTcaAbatementRepository testAbatementPersistenceContext =
+ (TestTcaAbatementRepository) testTcaAbatementContext.getTcaAbatementRepository();
+ final String previousRequestId = "previousRequestId";
+ final TestTcaAbatementEntity testTcaAbatementPersistenceEntity
+ = new TestTcaAbatementEntity(new Date(), "", previousRequestId, false);
+ testAbatementPersistenceContext.setTestLookupAbatementEntities(
+ Collections.singletonList(testTcaAbatementPersistenceEntity));
+
+ final TcaExecutionContext testExecutionContext =
+ getTestExecutionContextBuilder(TEST_CEF_JSON_MESSAGE_WITH_ABATEMENT_STRING,
+ TEST_TCA_POLICY, testTcaAbatementContext).build();
+
+ final TcaExecutionContext result = new TcaCalculator().apply(testExecutionContext);
+ assertThat(result.getTcaResultContext().getTcaAlert().getRequestId()).isEqualTo(previousRequestId);
+ }
+
+
+}