Enhancements for the aai-common library
[aai/aai-common.git] / aai-core / src / main / java / org / onap / aai / rest / ueb / UEBNotification.java
1 /**
2  * ============LICENSE_START=======================================================
3  * org.onap.aai
4  * ================================================================================
5  * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved.
6  * ================================================================================
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *    http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  * ============LICENSE_END=========================================================
19  */
20
21 package org.onap.aai.rest.ueb;
22
23 import org.slf4j.Logger;
24 import org.slf4j.LoggerFactory;
25 import org.onap.aai.exceptions.AAIException;
26 import org.onap.aai.introspection.Introspector;
27 import org.onap.aai.introspection.Loader;
28 import org.onap.aai.introspection.LoaderFactory;
29 import org.onap.aai.introspection.ModelType;
30 import org.onap.aai.introspection.exceptions.AAIUnknownObjectException;
31 import org.onap.aai.introspection.exceptions.AAIUnmarshallingException;
32 import org.onap.aai.logging.LogFormatTools;
33 import org.onap.aai.parsers.uri.URIToObject;
34 import org.onap.aai.setup.SchemaVersion;
35 import org.onap.aai.setup.SchemaVersions;
36
37 import javax.ws.rs.core.Response.Status;
38 import java.io.UnsupportedEncodingException;
39 import java.net.URI;
40 import java.util.*;
41
42 /**
43  * The Class UEBNotification.
44  */
45 public class UEBNotification {
46
47     private static final Logger LOGGER = LoggerFactory.getLogger(UEBNotification.class);
48
49     private Loader currentVersionLoader = null;
50     protected Map<String, NotificationEvent> events = null;
51     private SchemaVersion notificationVersion = null;
52
53     /**
54      * Instantiates a new UEB notification.
55      *
56      * @param loader the loader
57      */
58     public UEBNotification(Loader loader, LoaderFactory loaderFactory, SchemaVersions schemaVersions) {
59         events = new LinkedHashMap<>();
60         SchemaVersion defaultVersion = schemaVersions.getDefaultVersion();
61         currentVersionLoader = loaderFactory.createLoaderForVersion(loader.getModelType(), defaultVersion);
62         notificationVersion = defaultVersion;
63     }
64
65     /**
66      * Instantiates a new UEB notification.
67      *
68      * @param modelType - Model type
69      * @param loaderFactory - the loader factory
70      * @param schemaVersions the schema versions bean
71      */
72     public UEBNotification(ModelType modelType, LoaderFactory loaderFactory, SchemaVersions schemaVersions) {
73         events = new LinkedHashMap<>();
74         SchemaVersion defaultVersion = schemaVersions.getDefaultVersion();
75         currentVersionLoader = loaderFactory.createLoaderForVersion(modelType, defaultVersion);
76         notificationVersion = defaultVersion;
77     }
78
79     /**
80      * Creates the notification event.
81      *
82      * @param transactionId the X-TransactionId
83      * @param sourceOfTruth
84      * @param status the status
85      * @param uri the uri
86      * @param obj the obj
87      * @param basePath base URI path
88      * @throws AAIException the AAI exception
89      * @throws IllegalArgumentException the illegal argument exception
90      * @throws UnsupportedEncodingException the unsupported encoding exception
91      */
92     public void createNotificationEvent(String transactionId, String sourceOfTruth, Status status, URI uri,
93             Introspector obj, HashMap<String, Introspector> relatedObjects, String basePath)
94             throws AAIException, UnsupportedEncodingException {
95
96         String action = "UPDATE";
97
98         if (status.equals(Status.CREATED)) {
99             action = "CREATE";
100         } else if (status.equals(Status.OK)) {
101             action = "UPDATE";
102         } else if (status.equals(Status.NO_CONTENT)) {
103             action = "DELETE";
104         }
105
106         try {
107             Introspector eventHeader = currentVersionLoader.introspectorFromName("notification-event-header");
108             URIToObject parser = new URIToObject(currentVersionLoader, uri, relatedObjects);
109
110             if ((basePath != null) && (!basePath.isEmpty())) {
111                 if (!(basePath.startsWith("/"))) {
112                     basePath = "/" + basePath;
113                 }
114                 if (!(basePath.endsWith("/"))) {
115                     basePath = basePath + "/";
116                 }
117             } else {
118                 // default
119                 basePath = "/aai/";
120                 if (LOGGER.isDebugEnabled()) {
121                     LOGGER.debug("Please check the schema.uri.base.path as it didn't seem to be set");
122                 }
123             }
124
125             String uriStr = getUri(uri.toString(), basePath);
126             String entityLink;
127             if (uriStr.startsWith("/")) {
128                 entityLink = basePath + notificationVersion + uriStr;
129             } else {
130                 entityLink = basePath + notificationVersion + "/" + uriStr;
131             }
132
133             eventHeader.setValue("entity-link", entityLink);
134             eventHeader.setValue("action", action);
135             eventHeader.setValue("entity-type", obj.getDbName());
136             eventHeader.setValue("top-entity-type", parser.getTopEntityName());
137             eventHeader.setValue("source-name", sourceOfTruth);
138             eventHeader.setValue("version", notificationVersion.toString());
139             eventHeader.setValue("id", transactionId);
140
141             List<Object> parentList = parser.getParentList();
142             parentList.clear();
143
144             if (!parser.getTopEntity().equals(parser.getEntity())) {
145                 Introspector child = obj;
146                 if (!parser.getLoader().getVersion().equals(obj.getVersion())) {
147                     String json = obj.marshal(false);
148                     child = parser.getLoader().unmarshal(parser.getEntity().getName(), json);
149                 }
150
151                 // wrap the child object in its parents
152                 parentList.add(child.getUnderlyingObject());
153             }
154
155             final Introspector eventObject;
156
157             // convert to most resent version
158             if (!parser.getLoader().getVersion().equals(currentVersionLoader.getVersion())) {
159                 String json = "";
160                 if (parser.getTopEntity().equals(parser.getEntity())) {
161                     // convert the parent object passed in
162                     json = obj.marshal(false);
163                     eventObject = currentVersionLoader.unmarshal(obj.getName(), json);
164                 } else {
165                     // convert the object created in the parser
166                     json = parser.getTopEntity().marshal(false);
167                     eventObject = currentVersionLoader.unmarshal(parser.getTopEntity().getName(), json);
168                 }
169             } else {
170                 if (parser.getTopEntity().equals(parser.getEntity())) {
171                     // take the top level parent object passed in
172                     eventObject = obj;
173                 } else {
174                     // take the wrapped child objects (ogres are like onions)
175                     eventObject = parser.getTopEntity();
176                 }
177             }
178             final NotificationEvent event =
179                     new NotificationEvent(currentVersionLoader, eventHeader, eventObject, transactionId, sourceOfTruth);
180             events.put(uri.toString(), event);
181         } catch (AAIUnknownObjectException e) {
182             throw new RuntimeException("Fatal error - notification-event-header object not found!");
183         } catch (AAIUnmarshallingException e) {
184             LOGGER.error(
185                     "Unmarshalling error occurred while generating UEBNotification " + LogFormatTools.getStackTop(e));
186         }
187     }
188
189     /**
190      * Trigger events.
191      *
192      * @throws AAIException the AAI exception
193      */
194     public void triggerEvents() throws AAIException {
195         for (NotificationEvent event : events.values()) {
196             event.trigger();
197         }
198         clearEvents();
199     }
200
201     public List<NotificationEvent> getEvents() {
202         return new ArrayList<>(this.events.values());
203     }
204     public Map<String, NotificationEvent> getEventsMap() {
205         return this.events;
206     }
207
208     private String getUri(String uri, String basePath) {
209         if (uri == null || uri.isEmpty()) {
210             return uri;
211         } else if (uri.charAt(0) != '/') {
212             uri = '/' + uri;
213         }
214
215         if ((basePath != null) && (!basePath.isEmpty())) {
216             if (!(basePath.startsWith("/"))) {
217                 basePath = "/" + basePath;
218             }
219             if (!(basePath.endsWith("/"))) {
220                 basePath = basePath + "/";
221             }
222         }
223
224         LOGGER.trace("Notification header uri base path:'{}', uri:'{}'", basePath, uri);
225
226         return uri.replaceAll("^" + basePath + "v\\d+", "");
227     }
228
229     public void clearEvents() {
230         events.clear();
231     }
232 }