[SDNC-30] summary
[ccsdk/sli/adaptors.git] / aai-service / provider / src / main / java / org / onap / ccsdk / sli / adaptors / aai / AAIRequest.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * openECOMP : SDN-C
4  * ================================================================================
5  * Copyright (C) 2017 ONAP Intellectual Property. All rights
6  *                                              reserved.
7  * ================================================================================
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  * 
12  *      http://www.apache.org/licenses/LICENSE-2.0
13  * 
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  * ============LICENSE_END=========================================================
20  */
21
22 package org.onap.ccsdk.sli.adaptors.aai;
23
24 import java.io.IOException;
25 import java.io.InputStream;
26 import java.io.InputStreamReader;
27 import java.io.Reader;
28 import java.io.UnsupportedEncodingException;
29 import java.lang.reflect.Method;
30 import java.net.MalformedURLException;
31 import java.net.URL;
32 import java.net.URLDecoder;
33 import java.net.URLEncoder;
34 import java.util.ArrayList;
35 import java.util.Arrays;
36 import java.util.BitSet;
37 import java.util.HashMap;
38 import java.util.LinkedHashMap;
39 import java.util.List;
40 import java.util.Map;
41 import java.util.Properties;
42 import java.util.Set;
43 import java.util.TreeSet;
44
45 import org.apache.commons.lang.StringUtils;
46 import org.openecomp.aai.inventory.v11.GenericVnf;
47 import org.onap.ccsdk.sli.adaptors.aai.data.AAIDatum;
48 import org.osgi.framework.Bundle;
49 import org.osgi.framework.BundleContext;
50 import org.osgi.framework.FrameworkUtil;
51 import org.slf4j.Logger;
52 import org.slf4j.LoggerFactory;
53
54 import com.fasterxml.jackson.core.JsonParseException;
55 import com.fasterxml.jackson.core.JsonProcessingException;
56 import com.fasterxml.jackson.databind.JsonMappingException;
57 import com.fasterxml.jackson.databind.ObjectMapper;
58
59 public abstract class AAIRequest {
60         protected static final Logger LOG = LoggerFactory.getLogger(AAIRequest.class);
61
62         protected static final String TARGET_URI = "org.onap.ccsdk.sli.adaptors.aai.uri";
63
64         protected static final String MASTER_REQUEST = "master-request";
65
66         public static final String RESOURCE_VERSION = "resource-version";
67
68         public static final String DEPTH = "depth";
69
70         protected static Properties configProperties;
71         protected final String target_uri;
72         protected static AAIService aaiService;
73
74         protected AAIDatum requestDatum;
75
76         protected final Properties requestProperties = new Properties();
77
78
79         public static AAIRequest createRequest(String resoourceName, Map<String, String> nameValues){
80
81                 String resoource = resoourceName;
82
83                 if(resoource == null)
84                         return null;
85
86                 if(resoource.contains(":")) {
87                         String[] tokens = resoource.split(":");
88                         if(tokens != null && tokens.length > 0) {
89                                 resoource = tokens[0];
90                         }
91                 }
92
93                 if(nameValues.containsKey("selflink")){
94                         Class<? extends AAIDatum> clazz = null;
95                         try {
96                                 clazz = getClassFromResource(resoource) ;
97                         } catch (ClassNotFoundException e) {
98                                 LOG.warn("AAIRequest does not support class: " + e.getMessage());
99                                 return null;
100                         }
101
102                         if(clazz != null)
103                                 return new SelfLinkRequest(clazz);
104                         else
105                                 return null;
106                 }
107
108                 switch(resoource){
109                 case "generic-query":
110                         return new GenericQueryRequest();
111                 case "named-query":
112                         return new NamedQueryRequest();
113                 case "nodes-query":
114                         return new NodesQueryRequest();
115                 case "custom-query":
116                 case "formatted-query":
117                         return new CustomQueryRequest();
118                 case "linterface":
119                         return new LInterfaceRequest(LInterfaceRequest.TYPE.L2_BRIDGE_SBG);
120                 case "l2-bridge-sbg":
121                         return new SubInterfaceRequest(SubInterfaceRequest.TYPE.L2_BRIDGE_SBG);
122                 case "l2-bridge-bgf":
123                         return new SubInterfaceRequest(SubInterfaceRequest.TYPE.L2_BRIDGE_BGF);
124                 case "echo":
125                 case "test":
126                         return new EchoRequest();
127
128                 default:
129                         {
130                                 AAIRequest request = getRequestFromResource(resoource);
131                                 if(request ==  null) {
132                                         return null;
133                                 }
134                                 return request;
135                         }
136                 }
137         }
138
139
140         /**
141          * Map containing resource tag to its bit position in bitset mapping
142          */
143         private static Map<String, String> tagValues = new LinkedHashMap<String, String>();
144         /**
145          * Map containing bitset value of the path to its path mapping
146          */
147         private static Map<BitSet, String> bitsetPaths = new LinkedHashMap<BitSet, String>();
148
149
150         public static Set<String> getResourceNames() {
151                 return tagValues.keySet();
152         }
153
154
155         public static void setProperties(Properties props, AAIService aaiService) {
156                 AAIRequest.configProperties = props;
157                 AAIRequest.aaiService = aaiService;
158
159                 try
160                 {
161                         URL url = null;
162                         Bundle bundle = FrameworkUtil.getBundle(AAIServiceActivator.class);
163                         if(bundle != null) {
164                                 BundleContext ctx = bundle.getBundleContext();
165                                 if(ctx == null)
166                                         return;
167
168                                 url = ctx.getBundle().getResource(AAIService.PATH_PROPERTIES);
169                         } else {
170                                 url = aaiService.getClass().getResource("/aai-path.properties");
171                         }
172
173                         InputStream in = url.openStream();
174                         Reader reader = new InputStreamReader(in, "UTF-8");
175
176                         Properties properties = new Properties();
177                         properties.load(reader);
178                         LOG.info("loaded " + properties.size());
179
180                         Set<String> keys = properties.stringPropertyNames();
181
182                         int index = 0;
183                         Set<String> resourceNames = new TreeSet<String>();
184
185                         for(String key : keys) {
186                                 String[] tags = key.split("\\|");
187                                 for(String tag : tags) {
188                                         if(!resourceNames.contains(tag)) {
189                                                 resourceNames.add(tag);
190                                                 tagValues.put(tag, Integer.toString(++index));
191                                         }
192                                 }
193                                 BitSet bs = new BitSet(256);
194                                 for(String tag : tags) {
195                                         String value = tagValues.get(tag);
196                                         Integer bitIndex = Integer.parseInt(value) ;
197                                         bs.set(bitIndex);
198                                 }
199                                 String path = properties.getProperty(key);
200                                 LOG.info(String.format("bitset %s\t\t%s", bs.toString(), path));
201                                 bitsetPaths.put(bs, path);
202                         }
203                         LOG.info("loaded " + resourceNames.toString());
204                 }
205                 catch (Exception e)
206                 {
207                         LOG.error("Caught exception", e);
208                 }
209         }
210
211         public AAIRequest() {
212                 target_uri      = configProperties.getProperty(TARGET_URI);
213         }
214
215         public void addRequestProperty(String key, String value) {
216                 requestProperties.put(key, value);
217         }
218
219         public final void setRequestObject(AAIDatum value) {
220                 requestDatum = value;
221         }
222
223         public final AAIDatum getRequestObject() {
224                 return requestDatum;
225         }
226
227         public final void addMasterRequest(AAIRequest masterRequest) {
228                 requestProperties.put(MASTER_REQUEST, masterRequest);
229         }
230
231         protected static String encodeQuery(String param) throws UnsupportedEncodingException {
232                 return URLEncoder.encode(param, "UTF-8").replace("+", "%20");
233         }
234
235         protected void handleException(AAIRequest lInterfaceRequest, JsonProcessingException exc) {
236                 aaiService.getLogger().warn("Could not deserialize object of type " + lInterfaceRequest.getClass().getSimpleName(), exc) ;
237         }
238
239         public URL getRequestUrl(String method, String resourceVersion) throws UnsupportedEncodingException, MalformedURLException {
240
241                 String request_url = null;
242
243                 request_url = target_uri + updatePathDataValues(resourceVersion);
244
245                 URL http_req_url =      new URL(request_url);
246
247                 aaiService.LOGwriteFirstTrace(method, http_req_url.toString());
248
249                 return http_req_url;
250         }
251         
252         public String updatePathDataValues(Object resourceVersion) throws UnsupportedEncodingException, MalformedURLException {
253                 String request_url = getRequestPath();
254                 
255                 Set<String> uniqueResources = extractUniqueResourceSetFromKeys(requestProperties.stringPropertyNames());
256
257                 for(String resoourceName:uniqueResources) {
258                         AAIRequest locRequest = AAIRequest.createRequest(resoourceName, new HashMap<String, String>());
259                         if(locRequest != null) {
260                                 Class<?> clazz = locRequest.getClass();
261                                 Method function = null;
262                                 try {
263                                         function = clazz.getMethod("processPathData", request_url.getClass(), requestProperties.getClass());
264                                         request_url = (String) function.invoke(null, request_url,  requestProperties);
265                                 } catch (Exception e) {
266                                         e.printStackTrace();
267                                 }
268                         }
269                 }
270
271                 if(resourceVersion != null) {
272                         request_url = request_url +"?resource-version="+resourceVersion;
273                 }
274
275                 return request_url;
276         }
277
278
279         protected String getRequestPath() throws MalformedURLException {
280                 Set<String> uniqueResources = extractUniqueResourceSetFromKeys(requestProperties.stringPropertyNames());
281                 BitSet bitset = new BitSet();
282                 for(String key : uniqueResources) {
283                         if(tagValues.containsKey(key)) {
284                                 Object tmpValue = tagValues.get(key);
285                                 if(tmpValue != null) {
286                                         String value = tmpValue.toString();
287                                         int bitIndex = Integer.parseInt(value);
288                                         bitset.set(bitIndex);
289                                 }
290                         }
291                 }
292                 
293                 String path = bitsetPaths.get(bitset);
294                 if(path == null) {
295                         throw new MalformedURLException("PATH not found for key string containing valies :" +requestProperties.toString());
296                 }
297                 return path;
298         }
299
300         public abstract URL getRequestQueryUrl(String method) throws UnsupportedEncodingException, MalformedURLException;
301
302         public abstract String toJSONString();
303
304         public abstract String[] getArgsList();
305
306         public abstract Class<? extends AAIDatum> getModelClass() ;
307
308         public String getPrimaryResourceName(String resource) {
309                 return resource;
310         }
311
312         public String formatKey(String argument) {
313                 return argument;
314         }
315
316         public AAIDatum jsonStringToObject(String jsonData) throws JsonParseException, JsonMappingException, IOException {
317                 if(jsonData == null) {
318                         return null;
319                 }
320
321                 AAIDatum response = null;
322                 ObjectMapper mapper = getObjectMapper();
323                 response = mapper.readValue(jsonData, getModelClass());
324                 return response;
325         }
326
327         protected static Set<String> extractUniqueResourceSetFromKeys(Set<String> keySet) {
328                 Set<String> uniqueResources = new TreeSet<String>();
329                 List<String> keys = new ArrayList<String>(keySet);
330                 for(String resource : keys) {
331                         if(resource.contains(".")) {
332                                 String [] split = resource.split("\\.");
333                                 uniqueResources.add(split[0].replaceAll("_", "-"));
334                         }
335                 }
336                 return uniqueResources;
337         }
338
339         public void processRequestPathValues(Map<String, String> nameValues) {
340                 Set<String> uniqueResources = extractUniqueResourceSetFromKeys(nameValues.keySet());
341
342                 Set<String> tokens = new TreeSet<String>();
343                 tokens.add(DEPTH);
344                 tokens.addAll(Arrays.asList(this.getArgsList()));
345
346                 for(String resoourceName:uniqueResources) {
347                         AAIRequest locRequest = AAIRequest.createRequest(resoourceName, nameValues);
348                         if(locRequest != null)
349                                 tokens.addAll(Arrays.asList(locRequest.getArgsList()));
350                 }
351
352                 String[] arguments = tokens.toArray(new String[0]);
353                 for(String name : arguments) {
354                         String tmpName = name.replaceAll("-", "_");
355                         String value = nameValues.get(tmpName);
356                         if(value != null && !value.isEmpty()) {
357                                 value = value.trim().replace("'", "").replace("$", "").replace("'", "");
358                                 this.addRequestProperty(name, value);
359                         }
360                 }
361         }
362
363         public static String processPathData(String request_url, Properties requestProperties) throws UnsupportedEncodingException {
364                 return request_url;
365         }
366
367         public boolean isDeleteDataRequired() {
368                 return false;
369         }
370
371         ObjectMapper getObjectMapper() {
372         return AAIService.getObjectMapper();
373         }
374
375         public static Class<? extends AAIDatum> getClassFromResource(String resoourceName) throws ClassNotFoundException {
376                 String className = GenericVnf.class.getName();
377                 String[] split = resoourceName.split("-");
378                 for(int i = 0; i < split.length; i++) {
379                         split[i] = StringUtils.capitalize(split[i]);
380                 }
381
382                 String caps = StringUtils.join(split);
383                 className = className.replace("GenericVnf", caps);
384                 Class<? extends AAIDatum> clazz = null;
385                 try {
386                         clazz = (Class<? extends AAIDatum>)Class.forName(className);
387                 } catch (ClassNotFoundException e) {
388                         LOG.warn("AAIRequest does not support class: " + e.getMessage());
389                         return null;
390                 }
391
392                 return clazz;
393         }
394
395         protected static AAIRequest getRequestFromResource(String resoourceName) {
396
397                 Class<? extends AAIDatum> clazz = null;
398                 try {
399                         clazz = getClassFromResource(resoourceName);
400                 } catch (ClassNotFoundException e) {
401                         LOG.warn("AAIRequest does not support class: " + e.getMessage());
402                         return null;
403                 }
404                 if(clazz == null) {
405                         return null;
406                 }
407                 GenericRequest request = new GenericRequest(clazz);
408                 return request;
409         }
410
411         public static Map<String, String> splitQuery(String query) throws UnsupportedEncodingException {
412             Map<String, String> query_pairs = new LinkedHashMap<String, String>();
413
414             if(query != null && !query.isEmpty()) {
415                 String[] pairs = query.split("&");
416                 for (String pair : pairs) {
417                         int idx = pair.indexOf("=");
418                         query_pairs.put(URLDecoder.decode(pair.substring(0, idx), "UTF-8"), URLDecoder.decode(pair.substring(idx + 1), "UTF-8"));
419                 }
420             }
421             return query_pairs;
422         }
423
424         public static Map<String, String> splitPath(String path) throws UnsupportedEncodingException {
425             Map<String, String> query_pairs = new LinkedHashMap<String, String>();
426
427             if(path != null && !path.isEmpty()) {
428                 String[] pairs = path.split("/");
429                 for (String pair : pairs) {
430                         int idx = pair.indexOf("=");
431                         query_pairs.put(URLDecoder.decode(pair.substring(0, idx), "UTF-8"), URLDecoder.decode(pair.substring(idx + 1), "UTF-8"));
432                 }
433             }
434             return query_pairs;
435         }
436         
437         protected boolean expectsDataFromPUTRequest() {
438                 return false;
439         }
440 }