Release version 1.1.0 of sli/northbound
[ccsdk/sli/northbound.git] / dmaap-listener / src / main / java / org / onap / ccsdk / sli / northbound / dmaapclient / SdncAaiDmaapConsumer.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * openECOMP : SDN-C
4  * ================================================================================
5  * Copyright (C) 2017 AT&T Intellectual Property. All rights
6  *             reserved.
7  * Modifications Copyright © 2018 IBM.
8  * ================================================================================
9  * Licensed under the Apache License, Version 2.0 (the "License");
10  * you may not use this file except in compliance with the License.
11  * You may obtain a copy of the License at
12  *
13  *      http://www.apache.org/licenses/LICENSE-2.0
14  *
15  * Unless required by applicable law or agreed to in writing, software
16  * distributed under the License is distributed on an "AS IS" BASIS,
17  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18  * See the License for the specific language governing permissions and
19  * limitations under the License.
20  * ============LICENSE_END=========================================================
21  */
22
23 package org.onap.ccsdk.sli.northbound.dmaapclient;
24
25 import java.io.BufferedReader;
26 import java.io.File;
27 import java.io.FileReader;
28 import java.io.IOException;
29 import java.io.StringWriter;
30 import java.io.Writer;
31 import java.time.Instant;
32 import java.util.HashMap;
33 import java.util.Map;
34 import java.util.Properties;
35 import org.apache.velocity.VelocityContext;
36 import org.apache.velocity.app.VelocityEngine;
37 import org.json.JSONArray;
38 import org.json.JSONObject;
39 import org.slf4j.Logger;
40 import org.slf4j.LoggerFactory;
41 import com.fasterxml.jackson.databind.JsonNode;
42 import com.fasterxml.jackson.databind.ObjectMapper;
43
44 public class SdncAaiDmaapConsumer extends SdncDmaapConsumerImpl {
45
46     private static final Logger LOG = LoggerFactory.getLogger(SdncAaiDmaapConsumer.class);
47     private static final String SDNC_ENDPOINT = "SDNC.endpoint";
48     private static final String TEMPLATE = "SDNC.template";
49     private static final String DMAAPLISTENERROOT = "DMAAPLISTENERROOT";
50
51     private static final String ESR_SYSTEM_INFO = "esr-system-info";
52     private static final String RELATIONSHIP_LIST = "relationship-list";
53     private static final String ESR_SYSTEM_INFO_LIST = "esr-system-info-list";
54     private static final String AAI_EVENT = "AAI-EVENT";
55
56     private static final String EVENT_TYPE = "event-type";
57     private static final String ENTITY = "entity";
58     private static final String ENTITY_TYPE = "entity-type";
59     private static final String EVENT_HEADER = "event-header";
60
61     private String rootDir;
62
63     protected VelocityEngine velocityEngine;
64
65     public SdncAaiDmaapConsumer() {
66         velocityEngine = new VelocityEngine();
67         Properties props = new Properties();
68         rootDir = System.getenv(DMAAPLISTENERROOT);
69
70         if ((rootDir == null) || (rootDir.length() == 0)) {
71             rootDir = "/opt/onap/sdnc/dmaap-listener/lib/";
72         }
73         else {
74             rootDir = rootDir + "/lib/";
75         }
76
77         props.put("file.resource.loader.path", rootDir);
78         velocityEngine.init(props);
79     }
80
81     /*
82      * for testing purposes
83      */
84     SdncAaiDmaapConsumer(Properties props) {
85         velocityEngine = new VelocityEngine();
86         velocityEngine.init(props);
87     }
88
89     protected String publish(String templatePath, String jsonString) throws IOException
90     {
91         if (templatePath.contains("esr-thirdparty-sdnc")){
92             return publishEsrThirdPartySdnc(templatePath, jsonString);
93         } else {
94             return publishFullMessage(templatePath, jsonString);
95         }
96     }
97
98     private String publishFullMessage(String templatePath, String jsonString) throws IOException
99     {
100         JSONObject jsonObj = new JSONObject(jsonString);
101         VelocityContext context = new VelocityContext();
102         for(Object key : jsonObj.keySet())
103         {
104             context.put((String)key, jsonObj.get((String)key));
105         }
106
107         String id = jsonObj.getJSONObject(EVENT_HEADER).get("id").toString();
108         context.put("req_id", id);
109
110         context.put("curr_time", Instant.now());
111
112         ObjectMapper oMapper = new ObjectMapper();
113
114         String rpcMsgbody = oMapper.writeValueAsString(jsonString);
115         context.put("full_message", rpcMsgbody);
116
117         Writer writer = new StringWriter();
118         velocityEngine.mergeTemplate(templatePath, "UTF-8", context, writer);
119         writer.flush();
120
121         return writer.toString();
122     }
123
124     private String publishEsrThirdPartySdnc(String templatePath, String jsonString) throws IOException
125     {
126         JSONObject jsonObj = new JSONObject(jsonString);
127         VelocityContext context = new VelocityContext();
128
129         JSONObject eventHeader = jsonObj.getJSONObject(EVENT_HEADER);
130         for(Object key : eventHeader.keySet())
131         {
132             if (!("action").equals(key)) {
133                 context.put(((String)key).replaceAll("-", ""), eventHeader.get((String)key));
134             } else {
135                 String action = (String) eventHeader.get((String) key);
136                 if (("create").equalsIgnoreCase(action)) {
137                     context.put((String)key,"Update");
138                 } else if (("delete").equalsIgnoreCase(action)) {
139                     context.put((String) key, "Delete");
140                 } else {
141                     throw new IOException("Action type not supported " + action);
142                 }
143             }
144         }
145
146         JSONObject entityObj = jsonObj.getJSONObject(ENTITY);
147         for(Object key : entityObj.keySet())
148         {
149             switch((String)key)
150             {
151                 case ESR_SYSTEM_INFO_LIST :
152                     JSONArray esrSystemInfo = entityObj.getJSONObject((String)key)
153                                                        .getJSONArray(ESR_SYSTEM_INFO);
154
155                     for (int i = 0; i < esrSystemInfo.length(); i++) {
156                         JSONObject objects = esrSystemInfo.getJSONObject(i);
157
158                         for (Object name : objects.keySet()) {
159                             context.put(((String)name).replaceAll("-", ""),
160                                         objects.get((String)name).toString());
161                         }
162                     }
163                     break;
164
165                 case RELATIONSHIP_LIST :
166                     //convertion not required for relationship
167                     break;
168
169                 default :
170                     context.put(((String)key).replaceAll("-", ""),
171                                 entityObj.get((String)key).toString());
172                     break;
173             }
174         }
175
176         Writer writer = new StringWriter();
177         velocityEngine.mergeTemplate(templatePath, "UTF-8", context, writer);
178         writer.flush();
179
180         return writer.toString();
181     }
182
183     @Override
184     public void processMsg(String msg) throws InvalidMessageException {
185
186         if (msg == null) {
187             throw new InvalidMessageException("Null message");
188         }
189
190         ObjectMapper oMapper = new ObjectMapper();
191         JsonNode aaiRootNode;
192         try {
193             aaiRootNode = oMapper.readTree(msg);
194         } catch (Exception e) {
195             throw new InvalidMessageException("Cannot parse json object", e);
196         }
197
198         JsonNode eventHeaderNode = aaiRootNode.get(EVENT_HEADER);
199         if(eventHeaderNode == null) {
200             LOG.info("Missing Event Header node.");
201             return;
202         }
203         JsonNode eventTypeNode = eventHeaderNode.get(EVENT_TYPE);
204         String eventType = eventTypeNode.textValue();
205
206         if(!AAI_EVENT.equals(eventType)) {
207             LOG.info("Unknown Event Type {}", eventType);
208             return;
209         }
210
211         JsonNode entityTypeNode = eventHeaderNode.get(ENTITY_TYPE);
212         String entityType = entityTypeNode.textValue();
213
214         String mapFilename = rootDir + entityType + ".map";
215         Map<String, String> fieldMap = loadMap(mapFilename);
216         if (fieldMap == null) {
217             return;
218         }
219
220         if (!fieldMap.containsKey(SDNC_ENDPOINT)) {
221             return;
222         }
223         String sdncEndpoint = fieldMap.get(SDNC_ENDPOINT);
224
225         if (!fieldMap.containsKey(TEMPLATE)) {
226             throw new InvalidMessageException("No SDNC template known for message " + entityType);
227         }
228         String templateName = fieldMap.get(TEMPLATE);
229
230         try {
231             String rpcMsgbody = publish(templateName, msg);
232             String odlUrlBase = getProperty("sdnc.odl.url-base");
233             String odlUser = getProperty("sdnc.odl.user");
234             String odlPassword = getProperty("sdnc.odl.password");
235
236             if ((odlUrlBase != null) && (odlUrlBase.length() > 0)) {
237                 SdncOdlConnection conn = SdncOdlConnection.newInstance(odlUrlBase + "/" + sdncEndpoint, odlUser, odlPassword);
238
239                 conn.send("POST", "application/json", rpcMsgbody);
240             } else {
241                 LOG.info("POST message body would be:\n" + rpcMsgbody);
242             }
243         } catch (Exception e) {
244             LOG.error("Unable to process message", e);
245         }
246     }
247
248     private Map<String, String> loadMap(String mapFilename) {
249         File mapFile = new File(mapFilename);
250
251         if (!mapFile.canRead()) {
252             LOG.error(String.format("Cannot read map file (%s)", mapFilename));
253             return null;
254         }
255
256         Map<String, String> results = new HashMap<>();
257         try (BufferedReader mapReader = new BufferedReader(new FileReader(mapFile))) {
258
259             String curLine;
260
261             while ((curLine = mapReader.readLine()) != null) {
262                 curLine = curLine.trim();
263
264                 if ((curLine.length() > 0) && (!curLine.startsWith("#")) && curLine.contains("=>")) {
265                     String[] entry = curLine.split("=>");
266                     if (entry.length == 2) {
267                         results.put(entry[0].trim(), entry[1].trim());
268                     }
269                 }
270             }
271             mapReader.close();
272         } catch (Exception e) {
273             LOG.error("Caught exception reading map " + mapFilename, e);
274             return null;
275         }
276
277         return results;
278     }
279
280 }