9a5acbf3e28cd52410aa4d4f1b6cf7a1264fd295
[policy/apex-pdp.git] / core / core-engine / src / main / java / org / onap / policy / apex / core / engine / event / EnEvent.java
1 /*-
2  * ============LICENSE_START=======================================================
3  *  Copyright (C) 2016-2018 Ericsson. All rights reserved.
4  *  Modifications Copyright (C) 2019 Nordix Foundation.
5  * ================================================================================
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  *      http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  *
18  * SPDX-License-Identifier: Apache-2.0
19  * ============LICENSE_END=========================================================
20  */
21
22 package org.onap.policy.apex.core.engine.event;
23
24 import java.util.ArrayList;
25 import java.util.Arrays;
26 import java.util.Collection;
27 import java.util.HashMap;
28 import java.util.HashSet;
29 import java.util.Map;
30 import java.util.Properties;
31 import java.util.Random;
32 import java.util.Set;
33
34 import lombok.Getter;
35 import lombok.Setter;
36
37 import org.onap.policy.apex.core.engine.monitoring.EventMonitor;
38 import org.onap.policy.apex.model.basicmodel.concepts.AxArtifactKey;
39 import org.onap.policy.apex.model.basicmodel.concepts.AxConcept;
40 import org.onap.policy.apex.model.basicmodel.service.ModelService;
41 import org.onap.policy.apex.model.eventmodel.concepts.AxEvent;
42 import org.onap.policy.apex.model.eventmodel.concepts.AxEvents;
43 import org.onap.policy.apex.model.eventmodel.concepts.AxField;
44 import org.slf4j.ext.XLogger;
45 import org.slf4j.ext.XLoggerFactory;
46
47 /**
48  * Instances of the Class EnEvent are events being passed through the Apex system. All events in the
49  * system are instances of this class.
50  *
51  * @author Liam Fallon (liam.fallon@ericsson.com)
52  */
53 public class EnEvent extends HashMap<String, Object> {
54     private static final long serialVersionUID = 6311863111866294637L;
55
56     // Logger for this class
57     private static final XLogger LOGGER = XLoggerFactory.getXLogger(EnEvent.class);
58
59     // Repeasted string constants
60     private static final String NULL_KEYS_ILLEGAL = "null keys are illegal on method parameter \"key\"";
61
62     // The definition of this event in the Apex model
63     private final AxEvent axEvent;
64
65     // The event monitor for this event
66     private final transient EventMonitor eventMonitor = new EventMonitor();
67
68     // The stack of execution of this event, used for monitoring
69     @Getter
70     @Setter
71     private AxConcept[] userArtifactStack;
72
73     private static Random rand = new Random(System.nanoTime());
74
75     // An identifier for the current event execution. The default value here will always be a random
76     // number, and should
77     // be reset
78     @Getter
79     @Setter
80     private long executionId = rand.nextLong();
81
82     // Event related properties used during processing of this event
83     @Getter
84     @Setter
85     private Properties executionProperties = new Properties();
86
87     // A string holding a message that indicates why processing of this event threw an exception
88     @Getter
89     @Setter
90     private String exceptionMessage;
91
92     /**
93      * Instantiates a new EnEvent, an Engine Event.
94      *
95      * @param eventKey the key of the event definition from the Apex model
96      */
97     public EnEvent(final AxArtifactKey eventKey) {
98         this(ModelService.getModel(AxEvents.class).get(eventKey));
99     }
100
101     /**
102      * Instantiates a new EnEvent, an Engine Event.
103      *
104      * @param axEvent the event definition from the Apex model
105      */
106     public EnEvent(final AxEvent axEvent) {
107         super();
108
109         if (axEvent == null) {
110             throw new EnException("event definition is null or was not found in model service");
111         }
112         // Save the event definition from the Apex model
113         this.axEvent = axEvent;
114     }
115
116     /**
117      * Gets the event definition of this event.
118      *
119      * @return the event definition
120      */
121     public AxEvent getAxEvent() {
122         return axEvent;
123     }
124
125     /**
126      * Get the name of the event.
127      *
128      * @return the event name
129      */
130     public String getName() {
131         return axEvent.getKey().getName();
132     }
133
134     /**
135      * Get the key of the event.
136      *
137      * @return the event key
138      */
139     public AxArtifactKey getKey() {
140         return axEvent.getKey();
141     }
142
143     /**
144      * Get the ID of the event.
145      *
146      * @return the event key
147      */
148     public String getId() {
149         return axEvent.getKey().getId();
150     }
151
152     /**
153      * {@inheritDoc}.
154      */
155     @Override
156     public Object get(final Object key) {
157         if (key == null) {
158             LOGGER.warn("null values are illegal on method parameter \"key\"");
159             throw new EnException("null values are illegal on method parameter \"key\"");
160         }
161
162         // Check if this key is a parameter on our event
163         final AxField eventParameter = axEvent.getParameterMap().get(key);
164         if (eventParameter == null) {
165             String message = "parameter with key " + key + " not defined on this event";
166             LOGGER.warn(message);
167             throw new EnException(message);
168         }
169
170         // Get the item
171         final Object item = super.get(key);
172
173         // Get the parameter value and monitor it
174         eventMonitor.monitorGet(eventParameter, item, userArtifactStack);
175         return item;
176     }
177
178     /**
179      * {@inheritDoc}.
180      */
181     @Override
182     public Collection<Object> values() {
183         // Build the key set and return it
184         final ArrayList<Object> valueList = new ArrayList<>();
185
186         // Override the generic "values()" call as we want to monitor the gets
187         for (final String key : super.keySet()) {
188             valueList.add(this.get(key));
189         }
190
191         return valueList;
192     }
193
194     /**
195      * {@inheritDoc}.
196      */
197     @Override
198     public Set<Map.Entry<String, Object>> entrySet() {
199         // Build the entry set and return it
200         final Set<Map.Entry<String, Object>> entrySet = new HashSet<>();
201
202         // Override the generic "entrySet()" call as we want to monitor the gets
203         for (final String key : super.keySet()) {
204             entrySet.add(new SimpleEntry<>(key, this.get(key)));
205         }
206
207         return entrySet;
208     }
209
210     /**
211      * {@inheritDoc}.
212      */
213     @Override
214     public Object put(final String key, final Object incomingValue) {
215         if (key == null) {
216             String message = NULL_KEYS_ILLEGAL;
217             LOGGER.warn(message);
218             throw new EnException(message);
219         }
220
221         // Check if this key is a parameter on our event
222         final AxField eventParameter = axEvent.getParameterMap().get(key);
223         if (eventParameter == null) {
224             String message = "parameter with key \"" + key + "\" not defined on event \"" + getName() + "\"";
225             LOGGER.warn(message);
226             throw new EnException(message);
227         }
228
229         // We allow null values
230         if (incomingValue == null) {
231             eventMonitor.monitorSet(eventParameter, incomingValue, userArtifactStack);
232             return super.put(key, incomingValue);
233         }
234
235         // Holder for the object to assign
236         final Object valueToAssign = new EnField(eventParameter, incomingValue).getAssignableValue();
237
238         // Update the value in the parameter map
239         eventMonitor.monitorSet(eventParameter, valueToAssign, userArtifactStack);
240         return super.put(key, valueToAssign);
241     }
242
243     /**
244      * {@inheritDoc}.
245      */
246     @Override
247     public void putAll(final Map<? extends String, ? extends Object> incomingMap) {
248         // Override the generic "putAll()" call as we want to monitor the puts
249         for (final Map.Entry<? extends String, ? extends Object> incomingEntry : incomingMap.entrySet()) {
250             put(incomingEntry.getKey(), incomingEntry.getValue());
251         }
252     }
253
254     /**
255      * {@inheritDoc}.
256      */
257     @Override
258     public Object remove(final Object key) {
259         if (key == null) {
260             LOGGER.warn(NULL_KEYS_ILLEGAL);
261             throw new EnException(NULL_KEYS_ILLEGAL);
262         }
263
264         // Check if this key is a parameter on our event
265         final AxField eventParameter = axEvent.getParameterMap().get(key);
266         if (eventParameter == null) {
267             String message = "parameter with key " + key + " not defined on this event";
268             LOGGER.warn(message);
269             throw new EnException(message);
270         }
271
272         final Object removedValue = super.remove(key);
273         eventMonitor.monitorRemove(eventParameter, removedValue, userArtifactStack);
274         return removedValue;
275     }
276
277     /**
278      * {@inheritDoc}.
279      */
280     @Override
281     public void clear() {
282         // Override the generic "clear()" call as we want to monitor removals
283         final Set<String> deleteSet = new HashSet<>();
284         deleteSet.addAll(keySet());
285
286         for (final String deleteKey : deleteSet) {
287             this.remove(deleteKey);
288         }
289     }
290
291     /**
292      * {@inheritDoc}.
293      */
294     @Override
295     public String toString() {
296         return "EnEvent [axEvent=" + axEvent + ", userArtifactStack=" + Arrays.toString(userArtifactStack) + ", map="
297                 + super.toString() + "]";
298     }
299
300     /**
301      * {@inheritDoc}.
302      */
303     @Override
304     public int hashCode() {
305         final int prime = 31;
306         int result = super.hashCode();
307         result = prime * result + axEvent.hashCode();
308         return result;
309     }
310
311     /**
312      * {@inheritDoc}.
313      */
314     @Override
315     public boolean equals(Object obj) {
316         if (this == obj) {
317             return true;
318         }
319         if (!super.equals(obj)) {
320             return false;
321         }
322         if (!(obj instanceof EnEvent)) {
323             return false;
324         }
325         EnEvent other = (EnEvent) obj;
326         if (axEvent == null) {
327             if (other.axEvent != null) {
328                 return false;
329             }
330         } else if (!axEvent.equals(other.axEvent)) {
331             return false;
332         }
333         return true;
334     }
335 }