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