10aec46aa86098aa3c2cfdeaefc7159ae0c70712
[ccsdk/sli/adaptors.git] / aai-service / provider / src / main / java / org / onap / ccsdk / sli / adaptors / aai / AAIServiceUtils.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.lang.annotation.Annotation;
25 import java.lang.reflect.Method;
26 import java.net.MalformedURLException;
27 import java.net.URI;
28 import java.net.URISyntaxException;
29 import java.util.Arrays;
30 import java.util.HashMap;
31 import java.util.Map;
32 import java.util.HashSet;
33 import java.util.Iterator;
34 import java.util.LinkedList;
35 import java.util.List;
36 import java.util.Set;
37
38 import javax.xml.bind.annotation.XmlType;
39
40 import org.apache.commons.lang.StringUtils;
41 import org.onap.aai.inventory.v14.Relationship;
42 import org.onap.aai.inventory.v14.RelationshipData;
43 import org.onap.aai.inventory.v14.RelationshipList;
44 import org.onap.ccsdk.sli.core.sli.SvcLogicContext;
45 import org.onap.ccsdk.sli.adaptors.aai.data.AAIDatum;
46 import org.slf4j.Logger;
47 import org.slf4j.LoggerFactory;
48
49 public class AAIServiceUtils {
50
51     private static final Logger LOG = LoggerFactory.getLogger(AAIService.class);
52
53     private AAIServiceUtils() {
54     }
55
56     public static String getPrimaryIdFromClass(Class<? extends AAIDatum> resourceClass){
57         // 1. find class
58         getLogger().debug(resourceClass.getName());
59
60         try {
61             Annotation[] annotations = resourceClass.getAnnotations();
62             for(Annotation annotation : annotations) {
63                 Class<? extends Annotation> anotationType = annotation.annotationType();
64                 String annotationName = anotationType.getName();
65
66                 // 2. find string property setters and getters for the lists
67                 if("javax.xml.bind.annotation.XmlType".equals(annotationName)){
68                     XmlType order = (XmlType)annotation;
69                     String[]  values = order.propOrder();
70                     for(String value : values) {
71                         String id = camelCaseToDashedString(value);
72                         return id;
73                     }
74                 }
75             }
76         } catch(Exception exc) {
77             getLogger().warn("getPrimaryIdFromClass failed", exc);
78         }
79         return null;
80     }
81
82     public static String getSecondaryIdFromClass(Class<? extends AAIDatum> resourceClass){
83         getLogger().debug(resourceClass.getName());
84
85         try {
86             Annotation[] annotations = resourceClass.getAnnotations();
87             for(Annotation annotation : annotations) {
88                 Class<? extends Annotation> anotationType = annotation.annotationType();
89                 String annotationName = anotationType.getName();
90
91                 // 2. find string property setters and getters for the lists
92                 if("javax.xml.bind.annotation.XmlType".equals(annotationName)){
93                     boolean primaryIdFound = false;
94                     XmlType order = (XmlType)annotation;
95                     String[]  values = order.propOrder();
96                     for(String value : values) {
97                         String id = camelCaseToDashedString(value);
98                         if(primaryIdFound) {
99                             return id;
100                         } else {
101                             primaryIdFound = true;
102                         }
103                     }
104                 }
105             }
106         } catch(Exception exc) {
107
108         }
109         return null;
110     }
111
112     public static Method getRelationshipListGetterMethodFromClassDefinition(Class resourceClass) {
113         Method getRelationshipListMethod = null;
114
115         try {
116              getRelationshipListMethod = resourceClass.getMethod("getRelationshipList");
117         } catch(Exception exc) {
118             getLogger().debug("Retrofiting relationship data: " + exc.getMessage());
119         }
120         return getRelationshipListMethod;
121     }
122
123     private static Logger getLogger() {
124         return LOG;
125     }
126
127
128     private static final String regex = "([A-Z][a-z,0-9]+)";
129     private static final String replacement = "-$1";
130
131     public static String camelCaseToDashedString(String propOrder) {
132         return propOrder.replaceAll(regex, replacement).toLowerCase();
133     }
134
135     public static HashMap<String,String> keyToHashMap(String key,    SvcLogicContext ctx) {
136         if (key == null) {
137             return (null);
138         }
139
140         getLogger().debug("Converting key [" + key + "] to where clause");
141
142         if (key.startsWith("'") && key.endsWith("'")) {
143             key = key.substring(1, key.length() - 1);
144
145             getLogger().debug("Stripped outer single quotes - key is now [" + key + "]");
146         }
147
148         String[] keyTerms = key.split("\\s+");
149
150         StringBuffer whereBuff = new StringBuffer();
151         String term1 = null;
152         String op = null;
153         String term2 = null;
154         HashMap<String, String> results = new HashMap<String, String>();
155
156         for (int i = 0; i < keyTerms.length; i++) {
157             if (term1 == null) {
158                 if ("and".equalsIgnoreCase(keyTerms[i])
159                         || "or".equalsIgnoreCase(keyTerms[i])) {
160                     // Skip over ADD/OR
161                 } else {
162                     term1 = resolveTerm(keyTerms[i], ctx);
163                 }
164             } else if (op == null) {
165                 if ("==".equals(keyTerms[i])) {
166                     op = "=";
167                 } else {
168                     op = keyTerms[i];
169                 }
170             } else {
171                 term2 = resolveTerm(keyTerms[i], ctx);
172                 term2 = term2.trim().replace("'", "").replace("$", "").replace("'", "");
173                 results.put(term1,  term2);
174
175                 term1 = null;
176                 op = null;
177                 term2 = null;
178             }
179         }
180
181         return (results);
182     }
183
184     private static String resolveTerm(String term, SvcLogicContext ctx) {
185         if (term == null) {
186             return (null);
187         }
188
189         getLogger().debug("resolveTerm: term is " + term);
190
191         if (term.startsWith("$") && (ctx != null)) {
192             // Resolve any index variables.
193
194             return ("'" + resolveCtxVariable(term.substring(1), ctx) + "'");
195         } else if (term.startsWith("'") || term.startsWith("\"")) {
196             return (term);
197         } else {
198             return (term.replaceAll("-", "_"));
199
200         }
201     }
202
203     private static String resolveCtxVariable(String ctxVarName, SvcLogicContext ctx) {
204
205         if (ctxVarName.indexOf('[') == -1) {
206             // Ctx variable contains no arrays
207             return (ctx.getAttribute(ctxVarName));
208         }
209
210         // Resolve any array references
211         StringBuffer sbuff = new StringBuffer();
212         String[] ctxVarParts = ctxVarName.split("\\[");
213         sbuff.append(ctxVarParts[0]);
214         for (int i = 1; i < ctxVarParts.length; i++) {
215             if (ctxVarParts[i].startsWith("$")) {
216                 int endBracketLoc = ctxVarParts[i].indexOf("]");
217                 if (endBracketLoc == -1) {
218                     // Missing end bracket ... give up parsing
219                     getLogger().warn("Variable reference " + ctxVarName
220                             + " seems to be missing a ']'");
221                     return (ctx.getAttribute(ctxVarName));
222                 }
223
224                 String idxVarName = ctxVarParts[i].substring(1, endBracketLoc);
225                 String remainder = ctxVarParts[i].substring(endBracketLoc);
226
227                 sbuff.append("[");
228                 sbuff.append(ctx.getAttribute(idxVarName));
229                 sbuff.append(remainder);
230
231             } else {
232                 // Index is not a variable reference
233                 sbuff.append("[");
234                 sbuff.append(ctxVarParts[i]);
235             }
236         }
237
238         return (ctx.getAttribute(sbuff.toString()));
239     }
240
241     public static void populateRelationshipDataFromPath(RelationshipList rl) throws URISyntaxException {
242         List<Relationship> list =  rl.getRelationship();
243         if(list != null && !list.isEmpty()) {
244             for(Relationship relationship : list) {
245                 if(relationship.getRelationshipData().isEmpty()){
246                     String link = relationship.getRelatedLink();
247                     URI uri = new URI(link);
248                         link = uri.getPath();
249                     HashMap<String,String> contributors = pathToHashMap(link);
250                     for(String key : contributors.keySet()) {
251                         RelationshipData rd = new RelationshipData();
252                         rd.setRelationshipKey(key);
253                         rd.setRelationshipValue(contributors.get(key));
254                         relationship.getRelationshipData().add(rd);
255                     }
256                 }
257             }
258         }
259     }
260
261     protected static HashMap<String,String> pathToHashMap(String path) {
262         HashMap<String, String> nameValues = new  HashMap<String, String>();
263
264         String[] split = path.split("/");
265
266         LinkedList<String> list = new LinkedList<String>( Arrays.asList(split));
267         Iterator<String> it = list.iterator();
268
269         while(it.hasNext()) {
270             String tag = it.next();
271             if(!tag.isEmpty()) {
272                 if(AAIRequest.getResourceNames().contains(tag)){
273                     LOG.info(tag);
274                     // get the class from tag
275                     Class<? extends AAIDatum> clazz = AAIRequest.getClassFromResource(tag);
276                     String fieldName = AAIServiceUtils.getPrimaryIdFromClass(clazz);
277
278                     String value = it.next();
279                     if(!StringUtils.isEmpty(value)){
280                         nameValues.put(String.format("%s.%s", tag, fieldName), value);
281                         switch(tag) {
282                         case "cloud-region":
283                         case "entitlement":
284                         case "license":
285                         case "route-target":
286                         case "service-capability":
287                         case "ctag-pool":
288                             String secondaryFieldName = AAIServiceUtils.getSecondaryIdFromClass(clazz);
289                             if(secondaryFieldName != null) {
290                                 value = it.next();
291                                 nameValues.put(String.format("%s.%s", tag, secondaryFieldName), value);
292                             }
293                             break;
294                         default:
295                             break;
296                         }
297                     }
298                 }
299             }
300         }
301         return nameValues;
302     }
303
304     public static String getPathForResource(String resource, String key, SvcLogicContext ctx ) throws MalformedURLException{
305         HashMap<String, String> nameValues = AAIServiceUtils.keyToHashMap(key, ctx);
306         AAIRequest request = AAIRequest.createRequest(resource, nameValues);
307
308         for(String name : nameValues.keySet()) {
309             request.addRequestProperty(name, nameValues.get(name));
310         }
311         return request.getRequestPath();
312     }
313
314     public static boolean isValidFormat(String resource, Map<String, String> nameValues) {
315
316         switch(resource){
317     case "custom-query":
318         case "formatted-query":
319         case "generic-query":
320         case "named-query":
321         case "nodes-query":
322         case "linterface":
323         case "l2-bridge-sbg":
324         case "l2-bridge-bgf":
325         case "echo":
326         case "test":
327             return true;
328         }
329         if(resource.contains(":")) {
330             resource = resource.substring(0, resource.indexOf(":"));
331         }
332
333         Set<String> keys = nameValues.keySet();
334         for(String key : keys) {
335             if(!key.contains(".")) {
336                 if("depth".equals(key) || "related-to".equals(key) || "related_to".equals(key) || "related-link".equals(key) || "related_link".equals(key) || "selflink".equals(key) || "resource_path".equals(key))
337                     continue;
338                 else {
339                     getLogger().warn(String.format("key '%s' is incompatible with resource type '%s'", key, resource));
340                 }
341             }
342         }
343         return true;
344     }
345
346     public static boolean containsResource(String resource, HashMap<String, String> nameValues) {
347         if(resource.contains(":")) {
348             return true;
349         }
350
351         switch(resource){
352         case "custom-query":
353         case "formatted-query":
354         case "generic-query":
355         case "named-query":
356         case "nodes-query":
357         case "linterface":
358         case "l2-bridge-sbg":
359         case "l2-bridge-bgf":
360         case "echo":
361         case "test":
362             return true;
363
364         default:
365             if(nameValues.containsKey("selflink")) {
366                 return true;
367             }
368         }
369
370         Set<String> tags = new HashSet<>();
371
372         for(String key : nameValues.keySet()) {
373             key = key.replace("_", "-");
374             if(key.contains(".")) {
375                 String[] split = key.split("\\.");
376                 tags.add(split[0]);
377             } else {
378                 tags.add(key);
379             }
380         }
381         return tags.contains(resource);
382     }
383 }