Isolate deprecated code in CCSDK aai-service
[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 AT&T 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.URISyntaxException;
32 import java.net.URL;
33 import java.net.URLDecoder;
34 import java.net.URLEncoder;
35 import java.util.ArrayList;
36 import java.util.Arrays;
37 import java.util.BitSet;
38 import java.util.HashSet;
39 import java.util.HashMap;
40 import java.util.LinkedHashMap;
41 import java.util.List;
42 import java.util.Map;
43 import java.util.Properties;
44 import java.util.Set;
45 import java.util.TreeSet;
46
47 import org.apache.commons.lang.StringUtils;
48 import org.openecomp.aai.inventory.v11.GenericVnf;
49 import org.onap.ccsdk.sli.adaptors.aai.data.AAIDatum;
50 import org.osgi.framework.Bundle;
51 import org.osgi.framework.BundleContext;
52 import org.osgi.framework.FrameworkUtil;
53 import org.slf4j.Logger;
54 import org.slf4j.LoggerFactory;
55
56 import com.fasterxml.jackson.core.JsonParseException;
57 import com.fasterxml.jackson.core.JsonProcessingException;
58 import com.fasterxml.jackson.databind.JsonMappingException;
59 import com.fasterxml.jackson.databind.ObjectMapper;
60
61 public abstract class AAIRequest {
62     protected static final Logger LOG = LoggerFactory.getLogger(AAIRequest.class);
63
64     protected static final String TARGET_URI = "org.onap.ccsdk.sli.adaptors.aai.uri";
65
66     protected static final String MASTER_REQUEST = "master-request";
67
68     public static final String RESOURCE_VERSION = "resource-version";
69
70     public static final String DEPTH = "depth";
71
72     protected static Properties configProperties;
73     protected final String targetUri;
74     protected static AAIService aaiService;
75
76     protected AAIDatum requestDatum;
77
78     protected final Properties requestProperties = new Properties();
79
80
81     public static AAIRequest createRequest(String resoourceName, Map<String, String> nameValues){
82
83         String resoource = resoourceName;
84                 String masterResource = null;
85
86         if(resoource == null)
87             return null;
88
89         if(resoource.contains(":")) {
90             String[] tokens = resoource.split(":");
91                         if(tokens != null && tokens.length == 2) {
92                                 resoource = tokens[1];
93                                 masterResource = tokens[0];
94                                 //
95                                 Class<? extends AAIDatum> clazz = null;
96                                 try {
97                                         clazz = getClassFromResource(resoource) ;
98                                 } catch (ClassNotFoundException e) {
99                                         LOG.warn("AAIRequest does not support class: " + e.getMessage());
100                                         return null;
101                                 }
102
103                                 if(clazz == null) {
104                                         return null;
105                                 }
106             }
107         }
108
109         if(nameValues.containsKey("selflink")){
110             Class<? extends AAIDatum> clazz = null;
111             try {
112                 clazz = getClassFromResource(resoource) ;
113             } catch (ClassNotFoundException e) {
114                 LOG.warn("AAIRequest does not support class: " + e.getMessage());
115                 return null;
116             }
117
118             if(clazz != null)
119                 return new SelfLinkRequest(clazz);
120             else
121                 return null;
122         }
123
124         switch(resoource){
125         case "generic-query":
126             return new GenericQueryRequest();
127         case "named-query":
128             return new NamedQueryRequest();
129         case "nodes-query":
130             return new NodesQueryRequest();
131         case "custom-query":
132         case "formatted-query":
133             return new CustomQueryRequest();
134         case "echo":
135         case "test":
136             return new EchoRequest();
137
138         case "linterface":
139         case "l2-bridge-sbg":
140         case "l2-bridge-bgf":
141             {
142                 resoource = "l-interface";
143                 return getRequestFromResource("l-interface");
144             }
145                 case "relationship-list":
146                          return new RelationshipListRequest(AAIRequest.createRequest(masterResource, nameValues));
147                 case "relationship":
148                          return new RelationshipRequest(AAIRequest.createRequest(masterResource, nameValues));
149         default:
150                 return getRequestFromResource(resoource);
151         }
152     }
153
154
155     /**
156      * Map containing resource tag to its bit position in bitset mapping
157      */
158     private static Map<String, String> tagValues = new LinkedHashMap<>();
159     /**
160      * Map containing bitset value of the path to its path mapping
161      */
162     private static Map<BitSet, String> bitsetPaths = new LinkedHashMap<>();
163
164
165     public static Set<String> getResourceNames() {
166         return tagValues.keySet();
167     }
168
169
170     public static void setProperties(Properties props, AAIService aaiService) {
171         AAIRequest.configProperties = props;
172         AAIRequest.aaiService = aaiService;
173
174         try
175         {
176             URL url = null;
177             Bundle bundle = FrameworkUtil.getBundle(AAIServiceActivator.class);
178             if(bundle != null) {
179                 BundleContext ctx = bundle.getBundleContext();
180                 if(ctx == null)
181                     return;
182
183                 url = ctx.getBundle().getResource(AAIService.PATH_PROPERTIES);
184             } else {
185                 url = aaiService.getClass().getResource("/aai-path.properties");
186             }
187
188             InputStream in = url.openStream();
189             Reader reader = new InputStreamReader(in, "UTF-8");
190
191             Properties properties = new Properties();
192             properties.load(reader);
193             LOG.info("loaded " + properties.size());
194
195             Set<String> keys = properties.stringPropertyNames();
196
197             int index = 0;
198             Set<String> resourceNames = new TreeSet<>();
199
200             for(String key : keys) {
201                 String[] tags = key.split("\\|");
202                 for(String tag : tags) {
203                     if(!resourceNames.contains(tag)) {
204                         resourceNames.add(tag);
205                         tagValues.put(tag, Integer.toString(++index));
206                     }
207                 }
208                 BitSet bs = new BitSet(256);
209                 for(String tag : tags) {
210                     String value = tagValues.get(tag);
211                     Integer bitIndex = Integer.parseInt(value) ;
212                     bs.set(bitIndex);
213                 }
214                 String path = properties.getProperty(key);
215                 LOG.info(String.format("bitset %s\t\t%s", bs.toString(), path));
216                 bitsetPaths.put(bs, path);
217             }
218             LOG.info("loaded " + resourceNames.toString());
219         }
220         catch (Exception e)
221         {
222             LOG.error("Caught exception", e);
223         }
224     }
225
226     public AAIRequest() {
227         targetUri    = configProperties.getProperty(TARGET_URI);
228     }
229
230     public void addRequestProperty(String key, String value) {
231         requestProperties.put(key, value);
232     }
233
234     public final void setRequestObject(AAIDatum value) {
235         requestDatum = value;
236     }
237
238     public final AAIDatum getRequestObject() {
239         return requestDatum;
240     }
241
242     public final void addMasterRequest(AAIRequest masterRequest) {
243         requestProperties.put(MASTER_REQUEST, masterRequest);
244     }
245
246     protected static String encodeQuery(String param) throws UnsupportedEncodingException {
247         return URLEncoder.encode(param, "UTF-8").replace("+", "%20");
248     }
249
250     protected void handleException(AAIRequest lInterfaceRequest, JsonProcessingException exc) {
251         aaiService.getLogger().warn("Could not deserialize object of type " + lInterfaceRequest.getClass().getSimpleName(), exc) ;
252     }
253
254         public URL getRequestUrl(String method, String resourceVersion) throws UnsupportedEncodingException, MalformedURLException, URISyntaxException {
255
256         String request_url = null;
257
258         request_url = targetUri + updatePathDataValues(resourceVersion);
259
260         URL http_req_url =    new URL(request_url);
261
262         aaiService.LOGwriteFirstTrace(method, http_req_url.toString());
263
264         return http_req_url;
265     }
266
267     public String updatePathDataValues(Object resourceVersion) throws UnsupportedEncodingException, MalformedURLException {
268         String request_url = getRequestPath();
269
270         Set<String> uniqueResources = extractUniqueResourceSetFromKeys(requestProperties.stringPropertyNames());
271
272         for(String resoourceName:uniqueResources) {
273             AAIRequest locRequest = AAIRequest.createRequest(resoourceName, new HashMap<String, String>());
274             if(locRequest != null) {
275                 Class<?> clazz = locRequest.getClass();
276                 Method function = null;
277                 try {
278                     function = clazz.getMethod("processPathData", request_url.getClass(), requestProperties.getClass());
279                     request_url = (String) function.invoke(null, request_url,  requestProperties);
280                 } catch (Exception e) {
281                     e.printStackTrace();
282                 }
283             }
284         }
285
286         if(resourceVersion != null) {
287             request_url = request_url +"?resource-version="+resourceVersion;
288         }
289
290         return request_url;
291     }
292
293     protected String getRequestPath() throws MalformedURLException {
294         return getRequestPath(null);
295     }
296
297     protected String getRequestPath(String resource) throws MalformedURLException {
298                 if(requestProperties.containsKey("resource-path")) {
299                         return requestProperties.getProperty("resource-path");
300                 }
301
302         Set<String> uniqueResources = extractUniqueResourceSetFromKeys(requestProperties.stringPropertyNames());
303         if(resource != null) {
304             // for group search add itself, but remove singular version of itself
305             if(!uniqueResources.contains(resource)) {
306                 boolean replaced =  false;
307                 Set<String> tmpUniqueResources = new HashSet<String>();
308                 tmpUniqueResources.addAll(uniqueResources);
309                 for(String item : tmpUniqueResources){
310                     String plural = item +"s";
311                     if(item.endsWith("y")){
312                         plural = item.substring(0, item.length()-1)+ "ies";
313                     }
314                     if(plural.equals(resource)) {
315                         uniqueResources.remove(item);
316                         uniqueResources.add(resource);
317                         replaced = true;
318                         break;
319                     }
320                 }
321                 if(!replaced){
322                     if(!uniqueResources.contains(resource)) {
323                         uniqueResources.add(resource);
324                     }
325                 }
326             }
327         }
328         BitSet bitset = new BitSet();
329         for(String key : uniqueResources) {
330             if(tagValues.containsKey(key)) {
331                 Object tmpValue = tagValues.get(key);
332                 if(tmpValue != null) {
333                     String value = tmpValue.toString();
334                     int bitIndex = Integer.parseInt(value);
335                     bitset.set(bitIndex);
336                 }
337             }
338         }
339
340         String path = bitsetPaths.get(bitset);
341         if(path == null) {
342             throw new MalformedURLException("PATH not found for key string containing valies :" +requestProperties.toString());
343         }
344         return path;
345     }
346
347         public abstract URL getRequestQueryUrl(String method) throws UnsupportedEncodingException, MalformedURLException, URISyntaxException;
348
349     public abstract String toJSONString();
350
351     public abstract String[] getArgsList();
352
353     public abstract Class<? extends AAIDatum> getModelClass() ;
354
355     public String getPrimaryResourceName(String resource) {
356         return resource;
357     }
358
359     public String formatKey(String argument) {
360         return argument;
361     }
362
363     public AAIDatum jsonStringToObject(String jsonData) throws JsonParseException, JsonMappingException, IOException {
364         if(jsonData == null) {
365             return null;
366         }
367
368         AAIDatum response = null;
369         ObjectMapper mapper = getObjectMapper();
370         response = mapper.readValue(jsonData, getModelClass());
371         return response;
372     }
373
374     protected static Set<String> extractUniqueResourceSetFromKeys(Set<String> keySet) {
375         Set<String> uniqueResources = new TreeSet<>();
376         List<String> keys = new ArrayList<>(keySet);
377         for(String resource : keys) {
378             if(resource.contains(".")) {
379                 String [] split = resource.split("\\.");
380                 uniqueResources.add(split[0].replaceAll("_", "-"));
381             }
382         }
383         return uniqueResources;
384     }
385
386     public void processRequestPathValues(Map<String, String> nameValues) {
387         Set<String> uniqueResources = extractUniqueResourceSetFromKeys(nameValues.keySet());
388
389         Set<String> tokens = new TreeSet<>();
390         tokens.add(DEPTH);
391         tokens.addAll(Arrays.asList(this.getArgsList()));
392
393         for(String resoourceName:uniqueResources) {
394             AAIRequest locRequest = AAIRequest.createRequest(resoourceName, nameValues);
395             if(locRequest != null)
396                 tokens.addAll(Arrays.asList(locRequest.getArgsList()));
397         }
398
399         String[] arguments = tokens.toArray(new String[0]);
400         for(String name : arguments) {
401             String tmpName = name.replaceAll("-", "_");
402             String value = nameValues.get(tmpName);
403             if(value != null && !value.isEmpty()) {
404                 value = value.trim().replace("'", "").replace("$", "").replace("'", "");
405                 this.addRequestProperty(name, value);
406             }
407         }
408     }
409
410     public static String processPathData(String request_url, Properties requestProperties) throws UnsupportedEncodingException {
411         return request_url;
412     }
413
414     public boolean isDeleteDataRequired() {
415         return false;
416     }
417
418     ObjectMapper getObjectMapper() {
419         return AAIService.getObjectMapper();
420     }
421
422     public static Class<? extends AAIDatum> getClassFromResource(String resoourceName) throws ClassNotFoundException {
423         String className = GenericVnf.class.getName();
424         String[] split = resoourceName.split("-");
425         for(int i = 0; i < split.length; i++) {
426             split[i] = StringUtils.capitalize(split[i]);
427         }
428
429         String caps = StringUtils.join(split);
430         className = className.replace("GenericVnf", caps);
431         Class<? extends AAIDatum> clazz = null;
432         try {
433             clazz = (Class<? extends AAIDatum>)Class.forName(className);
434         } catch (ClassNotFoundException e) {
435             LOG.warn("AAIRequest does not support class: " + e.getMessage());
436             return null;
437         }
438
439         return clazz;
440     }
441
442     protected static AAIRequest getRequestFromResource(String resoourceName) {
443
444         Class<? extends AAIDatum> clazz = null;
445         try {
446             clazz = getClassFromResource(resoourceName);
447         } catch (ClassNotFoundException e) {
448             LOG.warn("AAIRequest does not support class: " + e.getMessage());
449             return null;
450         }
451         if(clazz == null) {
452             return null;
453         }
454         GenericRequest request = new GenericRequest(clazz);
455         return request;
456     }
457
458     public static Map<String, String> splitQuery(String query) throws UnsupportedEncodingException {
459         Map<String, String> query_pairs = new LinkedHashMap<>();
460
461         if(query != null && !query.isEmpty()) {
462             String[] pairs = query.split("&");
463             for (String pair : pairs) {
464                 int idx = pair.indexOf('=');
465                 query_pairs.put(URLDecoder.decode(pair.substring(0, idx), "UTF-8"), URLDecoder.decode(pair.substring(idx + 1), "UTF-8"));
466             }
467         }
468         return query_pairs;
469     }
470
471     public static Map<String, String> splitPath(String path) throws UnsupportedEncodingException {
472         Map<String, String> query_pairs = new LinkedHashMap<>();
473
474         if(path != null && !path.isEmpty()) {
475             String[] pairs = path.split("/");
476             for (String pair : pairs) {
477                 int idx = pair.indexOf('=');
478                 query_pairs.put(URLDecoder.decode(pair.substring(0, idx), "UTF-8"), URLDecoder.decode(pair.substring(idx + 1), "UTF-8"));
479             }
480         }
481         return query_pairs;
482     }
483
484     protected boolean expectsDataFromPUTRequest() {
485         return false;
486     }
487
488
489     public String getTargetUri() {
490         return targetUri;
491     }
492 }