From 7a2c23b3ad83eab0eed5b990c70a1603447d5ee5 Mon Sep 17 00:00:00 2001 From: "Singla, Rajiv (rs153v)" Date: Wed, 15 Aug 2018 11:46:10 -0400 Subject: Standalone TCA with EELF Logger Issue-ID: DCAEGEN2-633 Change-Id: I4da76b532021c0d6248455e7bd6e77f4614c35a7 Signed-off-by: Singla, Rajiv (rs153v) --- dcae-analytics/dcae-analytics-tca-core/pom.xml | 78 ++++++ .../tca/core/exception/TcaProcessingException.java | 48 ++++ .../core/service/GenericTcaExecutionContext.java | 48 ++++ .../core/service/GenericTcaProcessingContext.java | 41 ++++ .../tca/core/service/GenericTcaResultContext.java | 41 ++++ .../tca/core/service/TcaAaiEnrichmentContext.java | 33 +++ .../tca/core/service/TcaAaiEnrichmentService.java | 39 +++ .../tca/core/service/TcaAbatementContext.java | 57 +++++ .../tca/core/service/TcaAbatementEntity.java | 61 +++++ .../tca/core/service/TcaAbatementRepository.java | 49 ++++ .../tca/core/service/TcaExecutionContext.java | 102 ++++++++ .../tca/core/service/TcaProcessingContext.java | 92 +++++++ .../tca/core/service/TcaResultContext.java | 88 +++++++ .../calculation/TcaAaiEnrichmentFunction.java | 62 +++++ .../calculation/TcaAbatementCalculator.java | 159 ++++++++++++ .../calculation/TcaAlertCreationFunction.java | 129 ++++++++++ .../calculation/TcaCalculationFunction.java | 84 +++++++ .../util/function/calculation/TcaCalculator.java | 60 +++++ .../util/function/calculation/TcaDomainFilter.java | 75 ++++++ .../calculation/TcaEventListenerExtractor.java | 76 ++++++ .../function/calculation/TcaEventNameFilter.java | 77 ++++++ .../TcaThresholdViolationCalculator.java | 270 +++++++++++++++++++++ .../dcae/analytics/tca/core/BaseTcaCoreTest.java | 121 +++++++++ .../core/domain/TestTcaAaiEnrichmentContext.java | 36 +++ .../core/domain/TestTcaAaiEnrichmentService.java | 41 ++++ .../tca/core/domain/TestTcaAbatementContext.java | 46 ++++ .../tca/core/domain/TestTcaAbatementEntity.java | 41 ++++ .../core/domain/TestTcaAbatementRepository.java | 48 ++++ .../function/calculation/TcaCalculatorTest.java | 88 +++++++ 29 files changed, 2190 insertions(+) create mode 100644 dcae-analytics/dcae-analytics-tca-core/pom.xml create mode 100644 dcae-analytics/dcae-analytics-tca-core/src/main/java/org/onap/dcae/analytics/tca/core/exception/TcaProcessingException.java create mode 100644 dcae-analytics/dcae-analytics-tca-core/src/main/java/org/onap/dcae/analytics/tca/core/service/GenericTcaExecutionContext.java create mode 100644 dcae-analytics/dcae-analytics-tca-core/src/main/java/org/onap/dcae/analytics/tca/core/service/GenericTcaProcessingContext.java create mode 100644 dcae-analytics/dcae-analytics-tca-core/src/main/java/org/onap/dcae/analytics/tca/core/service/GenericTcaResultContext.java create mode 100644 dcae-analytics/dcae-analytics-tca-core/src/main/java/org/onap/dcae/analytics/tca/core/service/TcaAaiEnrichmentContext.java create mode 100644 dcae-analytics/dcae-analytics-tca-core/src/main/java/org/onap/dcae/analytics/tca/core/service/TcaAaiEnrichmentService.java create mode 100644 dcae-analytics/dcae-analytics-tca-core/src/main/java/org/onap/dcae/analytics/tca/core/service/TcaAbatementContext.java create mode 100644 dcae-analytics/dcae-analytics-tca-core/src/main/java/org/onap/dcae/analytics/tca/core/service/TcaAbatementEntity.java create mode 100644 dcae-analytics/dcae-analytics-tca-core/src/main/java/org/onap/dcae/analytics/tca/core/service/TcaAbatementRepository.java create mode 100644 dcae-analytics/dcae-analytics-tca-core/src/main/java/org/onap/dcae/analytics/tca/core/service/TcaExecutionContext.java create mode 100644 dcae-analytics/dcae-analytics-tca-core/src/main/java/org/onap/dcae/analytics/tca/core/service/TcaProcessingContext.java create mode 100644 dcae-analytics/dcae-analytics-tca-core/src/main/java/org/onap/dcae/analytics/tca/core/service/TcaResultContext.java create mode 100644 dcae-analytics/dcae-analytics-tca-core/src/main/java/org/onap/dcae/analytics/tca/core/util/function/calculation/TcaAaiEnrichmentFunction.java create mode 100644 dcae-analytics/dcae-analytics-tca-core/src/main/java/org/onap/dcae/analytics/tca/core/util/function/calculation/TcaAbatementCalculator.java create mode 100644 dcae-analytics/dcae-analytics-tca-core/src/main/java/org/onap/dcae/analytics/tca/core/util/function/calculation/TcaAlertCreationFunction.java create mode 100644 dcae-analytics/dcae-analytics-tca-core/src/main/java/org/onap/dcae/analytics/tca/core/util/function/calculation/TcaCalculationFunction.java create mode 100644 dcae-analytics/dcae-analytics-tca-core/src/main/java/org/onap/dcae/analytics/tca/core/util/function/calculation/TcaCalculator.java create mode 100644 dcae-analytics/dcae-analytics-tca-core/src/main/java/org/onap/dcae/analytics/tca/core/util/function/calculation/TcaDomainFilter.java create mode 100644 dcae-analytics/dcae-analytics-tca-core/src/main/java/org/onap/dcae/analytics/tca/core/util/function/calculation/TcaEventListenerExtractor.java create mode 100644 dcae-analytics/dcae-analytics-tca-core/src/main/java/org/onap/dcae/analytics/tca/core/util/function/calculation/TcaEventNameFilter.java create mode 100644 dcae-analytics/dcae-analytics-tca-core/src/main/java/org/onap/dcae/analytics/tca/core/util/function/calculation/TcaThresholdViolationCalculator.java create mode 100644 dcae-analytics/dcae-analytics-tca-core/src/test/java/org/onap/dcae/analytics/tca/core/BaseTcaCoreTest.java create mode 100644 dcae-analytics/dcae-analytics-tca-core/src/test/java/org/onap/dcae/analytics/tca/core/domain/TestTcaAaiEnrichmentContext.java create mode 100644 dcae-analytics/dcae-analytics-tca-core/src/test/java/org/onap/dcae/analytics/tca/core/domain/TestTcaAaiEnrichmentService.java create mode 100644 dcae-analytics/dcae-analytics-tca-core/src/test/java/org/onap/dcae/analytics/tca/core/domain/TestTcaAbatementContext.java create mode 100644 dcae-analytics/dcae-analytics-tca-core/src/test/java/org/onap/dcae/analytics/tca/core/domain/TestTcaAbatementEntity.java create mode 100644 dcae-analytics/dcae-analytics-tca-core/src/test/java/org/onap/dcae/analytics/tca/core/domain/TestTcaAbatementRepository.java create mode 100644 dcae-analytics/dcae-analytics-tca-core/src/test/java/org/onap/dcae/analytics/tca/core/util/function/calculation/TcaCalculatorTest.java (limited to 'dcae-analytics/dcae-analytics-tca-core') diff --git a/dcae-analytics/dcae-analytics-tca-core/pom.xml b/dcae-analytics/dcae-analytics-tca-core/pom.xml new file mode 100644 index 0000000..c599c60 --- /dev/null +++ b/dcae-analytics/dcae-analytics-tca-core/pom.xml @@ -0,0 +1,78 @@ + + + + + + 4.0.0 + + + org.onap.dcaegen2.analytics + dcae-analytics + 3.0.0-SNAPSHOT + + + dcae-analytics-tca-core + jar + + + DCAE Analytics TCA Core + Contins Core functionality for TCA + + + ${project.parent.basedir} + + + + + + + ${project.groupId} + dcae-analytics-tca-model + + + + + org.projectlombok + lombok + provided + + + + + com.google.code.findbugs + jsr305 + + + com.google.code.findbugs + annotations + + + + + ${project.groupId} + dcae-analytics-test + + + + + + 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 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 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 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 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 { + + 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 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 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 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 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 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 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 getViolatedThreshold(final List policyThresholds, + final String cefMessage) { + + // map containing key as field path and associated policy thresholds + final Map> policyFieldPathsMap = new LinkedHashMap<>(); + for (final Threshold policyThreshold : policyThresholds) { + if (policyFieldPathsMap.get(policyThreshold.getFieldPath()) == null) { + final LinkedList 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> 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 violatedThresholdsMap = new HashMap<>(); + for (Map.Entry> messageFieldValuesMapEntry : messageFieldValuesMap.entrySet()) { + final String messageFieldPath = messageFieldValuesMapEntry.getKey(); + final List messageFieldAssociatedPolicyThresholds = policyFieldPathsMap.get(messageFieldPath); + if (messageFieldAssociatedPolicyThresholds != null) { + final Optional 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 computeViolatedThreshold(final List messageFieldValues, + final List fieldThresholds) { + + // sort thresholds based on severity and then based on direction + final List 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> getJsonPathValues(@Nonnull String message, + @Nonnull Set jsonFieldPaths) { + + final Map> jsonFieldPathMap = new HashMap<>(); + final DocumentContext documentContext = JsonPath.parse(message); + + for (String jsonFieldPath : jsonFieldPaths) { + List jsonFieldValues; + + try { + jsonFieldValues = documentContext.read(jsonFieldPath, new TypeRef>() { + }); + } 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 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 testLookupAbatementEntities = new LinkedList<>(); + + @Override + public void save(final TcaAbatementEntity tcaAbatementEntity) { + // do nothing + } + + @Override + public List 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); + } + + +} -- cgit 1.2.3-korg