61df170833adda1eaac693cef2c4eb44fa8308a9
[ccsdk/sli/adaptors.git] / aai-service / provider / src / main / java / org / onap / ccsdk / sli / adaptors / aai / AAIDeclarations.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.UnsupportedEncodingException;
26 import java.lang.annotation.Annotation;
27 import java.lang.reflect.Field;
28 import java.lang.reflect.InvocationTargetException;
29 import java.lang.reflect.Method;
30 import java.net.MalformedURLException;
31 import java.net.URL;
32 import java.net.URLDecoder;
33 import java.util.ArrayList;
34 import java.util.Arrays;
35 import java.util.HashMap;
36 import java.util.LinkedList;
37 import java.util.List;
38 import java.util.Map;
39 import java.util.Set;
40 import java.util.SortedSet;
41 import java.util.TreeSet;
42 import java.util.regex.Matcher;
43 import java.util.regex.Pattern;
44
45 import javax.xml.bind.annotation.XmlType;
46
47 import org.apache.commons.lang.StringUtils;
48 import org.onap.ccsdk.sli.core.sli.SvcLogicContext;
49 import org.onap.ccsdk.sli.core.sli.SvcLogicException;
50 import org.onap.ccsdk.sli.core.sli.SvcLogicResource.QueryStatus;
51 import org.openecomp.aai.inventory.v11.GenericVnf;
52 import org.openecomp.aai.inventory.v11.InventoryResponseItem;
53 import org.openecomp.aai.inventory.v11.InventoryResponseItems;
54 import org.openecomp.aai.inventory.v11.L3Network;
55 import org.openecomp.aai.inventory.v11.LogicalLink;
56 import org.openecomp.aai.inventory.v11.Metadata;
57 import org.openecomp.aai.inventory.v11.Metadatum;
58 import org.openecomp.aai.inventory.v11.Pnf;
59 import org.openecomp.aai.inventory.v11.Relationship;
60 import org.openecomp.aai.inventory.v11.RelationshipData;
61 import org.openecomp.aai.inventory.v11.RelationshipList;
62 import org.openecomp.aai.inventory.v11.ResultData;
63 import org.openecomp.aai.inventory.v11.SearchResults;
64 import org.openecomp.aai.inventory.v11.ServiceInstance;
65 import org.openecomp.aai.inventory.v11.Vlan;
66 import org.openecomp.aai.inventory.v11.Vlans;
67 import org.openecomp.aai.inventory.v11.Vserver;
68 import org.onap.ccsdk.sli.adaptors.aai.AAIService.AAIRequestExecutor;
69 import org.onap.ccsdk.sli.adaptors.aai.data.AAIDatum;
70 import org.onap.ccsdk.sli.adaptors.aai.query.FormattedQueryResultList;
71 import org.onap.ccsdk.sli.adaptors.aai.query.InstanceFilter;
72 import org.onap.ccsdk.sli.adaptors.aai.query.InstanceFilters;
73 import org.onap.ccsdk.sli.adaptors.aai.query.NamedQuery;
74 import org.onap.ccsdk.sli.adaptors.aai.query.NamedQueryData;
75 import org.onap.ccsdk.sli.adaptors.aai.query.QueryParameters;
76 import org.onap.ccsdk.sli.adaptors.aai.query.Results;
77 import org.slf4j.Logger;
78 import org.slf4j.LoggerFactory;
79
80 import com.fasterxml.jackson.core.JsonParseException;
81 import com.fasterxml.jackson.databind.JsonMappingException;
82 import com.fasterxml.jackson.databind.ObjectMapper;
83
84
85 public abstract class AAIDeclarations implements AAIClient {
86
87         public static final String TRUSTSTORE_PATH    = "org.onap.ccsdk.sli.adaptors.aai.ssl.trust";
88         public static final String TRUSTSTORE_PSSWD   = "org.onap.ccsdk.sli.adaptors.aai.ssl.trust.psswd";
89         public static final String KEYSTORE_PATH      = "org.onap.ccsdk.sli.adaptors.aai.ssl.key";
90         public static final String KEYSTORE_PSSWD     = "org.onap.ccsdk.sli.adaptors.aai.ssl.key.psswd";
91
92         public static final String APPLICATION_ID     = "org.onap.ccsdk.sli.adaptors.aai.application";
93
94         public static final String CLIENT_NAME            = "org.onap.ccsdk.sli.adaptors.aai.client.name";
95         public static final String CLIENT_PWWD            = "org.onap.ccsdk.sli.adaptors.aai.client.psswd";
96
97
98         public static final String CONNECTION_TIMEOUT = "connection.timeout";
99         public static final String READ_TIMEOUT           = "read.timeout";
100
101         public static final String TARGET_URI         = "org.onap.ccsdk.sli.adaptors.aai.uri";
102
103         // Availability zones query
104         public static final String QUERY_PATH         = "org.onap.ccsdk.sli.adaptors.aai.path.query";
105
106         // Update
107         public static final String UPDATE_PATH            = "org.onap.ccsdk.sli.adaptors.aai.update";
108
109         // Service instance
110         public static final String SVC_INSTANCE_PATH  = "org.onap.ccsdk.sli.adaptors.aai.path.svcinst";
111         public static final String SVC_INST_QRY_PATH  = "org.onap.ccsdk.sli.adaptors.aai.path.svcinst.query";
112
113         // VServer
114         public static final String NETWORK_VSERVER_PATH  = "org.onap.ccsdk.sli.adaptors.aai.path.vserver";
115
116         public static final String VNF_IMAGE_QUERY_PATH   = "org.onap.ccsdk.sli.adaptors.aai.path.vnf.image.query";
117
118         public static final String PARAM_SERVICE_TYPE     = "org.onap.ccsdk.sli.adaptors.aai.param.service.type";
119         public static final String CERTIFICATE_HOST_ERROR = "org.onap.ccsdk.sli.adaptors.aai.host.certificate.ignore";
120
121         // UBB Notify
122         public static final String UBB_NOTIFY_PATH        = "org.onap.ccsdk.sli.adaptors.aai.path.notify";
123         public static final String SELFLINK_AVPN          = "org.onap.ccsdk.sli.adaptors.aai.notify.selflink.avpn";
124         public static final String SELFLINK_FQDN          = "org.onap.ccsdk.sli.adaptors.aai.notify.selflink.fqdn";
125
126         //Service
127         public static final String SERVICE_PATH           = "org.onap.ccsdk.sli.adaptors.aai.path.service";
128
129         // P-Interfaces
130         public static final String P_INTERFACE_PATH       = "org.onap.ccsdk.sli.adaptors.aai.path.pserver.pinterface";
131
132         // site-pair-sets
133         public static final String SITE_PAIR_SET_PATH     = "org.onap.ccsdk.sli.adaptors.aai.path.site.pair.set";
134
135         // node query (1602)
136         public static final String QUERY_NODES_PATH               = "org.onap.ccsdk.sli.adaptors.aai.query.nodes";
137
138
139         protected abstract Logger getLogger();
140         public abstract AAIRequestExecutor getExecutor();
141
142
143         @Override
144         public QueryStatus query(String resource, boolean localOnly, String select, String key, String prefix, String orderBy, SvcLogicContext ctx)
145                 throws SvcLogicException {
146
147                 getLogger().debug("AAIService.query \tresource = "+resource);
148
149                 String vnfId;
150                 String vnfName = null;
151                 HashMap<String, String> nameValues = AAIServiceUtils.keyToHashMap(key, ctx);
152                 getLogger().debug("key = "+ nameValues.toString());
153
154                 if(!AAIServiceUtils.isValidFormat(resource, nameValues)) {
155                         ctx.setAttribute(String.format("%s.error.message", prefix), String.format("Resource %s is not supported. Key string contains invaid identifiers", resource));
156                         return QueryStatus.FAILURE;
157                 }
158
159                 if(resource == null || resource.isEmpty() || AAIRequest.createRequest(resource, nameValues) == null) {
160                         ctx.setAttribute(String.format("%s.error.message", prefix), String.format("Resource %s is not supported", resource));
161                         return QueryStatus.FAILURE;
162                 }
163
164                 // process data using new model
165                 boolean useNewModelProcessing = true;
166                 // process server query by name the old way
167                 if("vserver".equals(resource) || "vserver2".equals(resource)){
168                         if(nameValues.containsKey("vserver_name") || nameValues.containsKey("vserver-name") || nameValues.containsKey("vserver.vserver_name") || nameValues.containsKey("vserver.vserver-name"))
169                                 useNewModelProcessing = false;
170                 }
171                 if("generic-vnf".equals(resource)){
172                         if(nameValues.containsKey("vnf_name") || nameValues.containsKey("vnf-name") || nameValues.containsKey("generic_vnf.vnf_name") || nameValues.containsKey("generic-vnf.vnf-name"))
173                                 useNewModelProcessing = false;
174                 }
175
176                 // process data using new model
177                 if(useNewModelProcessing && AAIRequest.createRequest(resource, nameValues) != null) {
178
179                         try {
180                                 return newModelQuery(resource, localOnly, select, key, prefix, orderBy, ctx);
181                         } catch (Exception exc) {
182                                 getLogger().warn("Failed query - returning FAILURE", exc);
183                                 return QueryStatus.FAILURE;
184                         }
185                 }
186
187                 ObjectMapper mapper = AAIService.getObjectMapper();
188                 Map<String,Object> attributes = new HashMap<>();
189
190                 String modifier = null;
191
192                 if(resource.contains(":")) {
193                         String[] tokens = resource.split(":");
194                         resource = tokens[0];
195                         if(tokens.length > 1) {
196                                 modifier = tokens[1];
197                         }
198                 }
199
200                 resource = resource.toLowerCase().replace("-", "_");
201
202                 try {
203
204                         switch(resource) {
205                                 case "generic_vnf":
206                                         vnfId = nameValues.get("vnf_id");
207                                         if(nameValues.containsKey("vnf_id"))
208                                                 vnfId = nameValues.get("vnf_id");
209                                         else if(nameValues.containsKey("generic_vnf.vnf_name"))
210                                                 vnfId = nameValues.get("generic_vnf.vserver_name");
211
212                                         if(nameValues.containsKey("vnf_name"))
213                                                 vnfName = nameValues.get("vnf_name");
214                                         else if(nameValues.containsKey("generic_vnf.vnf_name"))
215                                                 vnfName = nameValues.get("generic_vnf.vnf_name");
216
217                                         if(vnfId != null && !vnfId.isEmpty()) {
218                                                 // at this point of the project this part should not be executed
219                                                 vnfId = vnfId.trim().replace("'", "").replace("$", "").replace("'", "");
220                                                 GenericVnf vnf = this.requestGenericVnfData(vnfId);
221                                                 if(vnf == null) {
222                                                         return QueryStatus.NOT_FOUND;
223                                                 }
224
225                                                 attributes = mapper.convertValue(vnf, attributes.getClass());
226                                         } else if(vnfName != null && !vnfName.isEmpty()) {
227                                                 try {
228                                                         vnfName = vnfName.trim().replace("'", "").replace("$", "").replace("'", "");
229                                                         GenericVnf vnf = this.requestGenericVnfeNodeQuery(vnfName);
230                                                         if(vnf == null) {
231                                                                 return QueryStatus.NOT_FOUND;
232                                                         }
233                                                         vnfId=vnf.getVnfId();
234                                                         nameValues.put("vnf_id", vnfId);
235                                                         attributes = mapper.convertValue(vnf, attributes.getClass());
236                                                 } catch (AAIServiceException exc) {
237                                                         int errorCode = exc.getReturnCode();
238                                                         switch(errorCode) {
239                                                         case 400:
240                                                         case 404:
241                                                         case 412:
242                                                                 break;
243                                                         default:
244                                                                 getLogger().warn("Caught exception trying to refresh generic VNF", exc);
245                                                         }
246                                                         ctx.setAttribute(prefix + ".error.message", exc.getMessage());
247                                                         if(errorCode >= 300) {
248                                                                 ctx.setAttribute(prefix + ".error.http.response-code",
249                                                                                                  Integer.toString(exc.getReturnCode()));
250                                                         }
251                                                         return QueryStatus.FAILURE;
252                                                 }
253                                         } else {
254                                                 getLogger().warn("No arguments are available to process generic VNF");
255                                                 return QueryStatus.FAILURE;
256                                         }
257                                         break;
258                                 case "vserver":
259                                 case "vserver2":
260                                         String vserverName = null;
261                                         if(nameValues.containsKey("vserver_name"))
262                                                 vserverName = nameValues.get("vserver_name");
263                                         else if(nameValues.containsKey("vserver.vserver_name"))
264                                                 vserverName = nameValues.get("vserver.vserver_name");
265
266                                         String vserverId = null;
267                                         if(nameValues.containsKey("vserver_id"))
268                                                 vserverId = nameValues.get("vserver_id");
269                                         if(nameValues.containsKey("vserver.vserver_id"))
270                                                 vserverId = nameValues.get("vserver.vserver_id");
271                                         String tenantId = nameValues.get("teannt_id");
272
273                                         if(vserverName != null) vserverName = vserverName.trim().replace("'", "").replace("$", "").replace("'", "");
274                                         if(vserverId != null) vserverId = vserverId.trim().replace("'", "").replace("$", "").replace("'", "");
275                                         if(tenantId != null) tenantId = tenantId.trim().replace("'", "").replace("$", "").replace("'", "");
276
277                                 if (vserverName != null) {
278                                         URL vserverUrl = null;
279                                         try {
280                                                 vserverUrl = this.requestVserverURLNodeQuery(vserverName);
281                                         } catch (AAIServiceException aaiexc) {
282                                                 ctx.setAttribute(prefix + ".error.message", aaiexc.getMessage());
283                                                 if (aaiexc.getReturnCode() >= 300) {
284                                                         ctx.setAttribute(prefix + ".error.http.response-code", "" + aaiexc.getReturnCode());
285                                                 }
286
287                                                 if (aaiexc.getReturnCode() == 404)
288                                                         return QueryStatus.NOT_FOUND;
289                                                 else
290                                                         return QueryStatus.FAILURE;
291                                         }
292                                         if (vserverUrl == null) {
293                                                 return QueryStatus.NOT_FOUND;
294                                         }
295
296                                         tenantId = getTenantIdFromVserverUrl(vserverUrl);
297                                                         String cloudOwner = getCloudOwnerFromVserverUrl(vserverUrl);
298                                                         String cloudRegionId = getCloudRegionFromVserverUrl(vserverUrl);
299
300                                         Vserver vserver = null;
301                                         try {
302                                                 vserver = this.requestVServerDataByURL(vserverUrl);
303                                         } catch (AAIServiceException aaiexc) {
304                                                 ctx.setAttribute(prefix + ".error.message", aaiexc.getMessage());
305                                                 if (aaiexc.getReturnCode() >= 300) {
306                                                         ctx.setAttribute(prefix + ".error.http.response-code", "" + aaiexc.getReturnCode());
307                                                 }
308
309                                                 if (aaiexc.getReturnCode() == 404)
310                                                         return QueryStatus.NOT_FOUND;
311                                                 else
312                                                         return QueryStatus.FAILURE;
313                                         }
314                                         if (vserver == null) {
315                                                 return QueryStatus.NOT_FOUND;
316                                         }
317                                         attributes = mapper.convertValue(vserver, attributes.getClass());
318                                         if (!attributes.containsKey("tenant-id") && tenantId != null) {
319                                                 attributes.put("tenant-id", tenantId);
320                                         }
321                                         if (!attributes.containsKey("cloud-owner") && cloudOwner != null) {
322                                                 attributes.put("cloud-owner", cloudOwner);
323                                         }
324                                         if (!attributes.containsKey("cloud-region-id") && cloudRegionId != null) {
325                                                 attributes.put("cloud-region-id", cloudRegionId);
326                                         }
327                                 } else if (vserverId != null && tenantId != null) {
328                                                 Vserver vserver = this.requestVServerData(tenantId, vserverId, "att-aic", "AAIAIC25");
329                                                 if(vserver == null) {
330                                                         return QueryStatus.NOT_FOUND;
331                                                 }
332                                                 attributes = mapper.convertValue(vserver, attributes.getClass());
333                                                 if(!attributes.containsKey("tenant-id") && tenantId != null){
334                                                         attributes.put("tenant-id", tenantId);
335                                                 }
336                                         } else {
337                                                 return QueryStatus.FAILURE;
338                                         }
339                                         break;
340
341                                 default:
342                                         return QueryStatus.FAILURE;
343                         }
344
345                         QueryStatus retval = QueryStatus.SUCCESS;
346
347                         if (attributes == null || attributes.isEmpty()) {
348                                 retval = QueryStatus.NOT_FOUND;
349                                 getLogger().debug("No data found");
350                         } else {
351                                 if (ctx != null) {
352                                         if (prefix != null) {
353                                                 ArrayList<String> keys = new ArrayList<>(attributes.keySet());
354
355                                                 int numCols = keys.size();
356
357                                                 for (int i = 0; i < numCols; i++) {
358                                                         String colValue;
359                                                         String colName = keys.get(i);
360                                                         Object object = attributes.get(colName);
361
362                                                         if(object != null && object instanceof String) {
363                                                                 colValue = (String)object;
364
365                                                                 if (prefix != null) {
366                                                                         getLogger().debug("Setting "+prefix     + "." + colName.replaceAll("_", "-")+" = "+ colValue);
367                                                                         ctx.setAttribute(prefix + "." + colName.replaceAll("_", "-"), colValue);
368                                                                 } else {
369                                                                         getLogger().debug("Setting " + colValue.replaceAll("_", "-")+" = "+colValue);
370                                                                         ctx.setAttribute(colValue.replaceAll("_", "-"), colValue);
371                                                                 }
372                                                         } else if(object != null && object instanceof Map) {
373                                                                 if(colName.equals(modifier) || "relationship-list".equals(colName)){
374                                                                         String localNodifier = modifier;
375                                                                         if(localNodifier == null)
376                                                                                 localNodifier = "relationship-list";
377                                                                         Map<String, Object> properties = (Map<String, Object>)object;
378                                                                         writeMap(properties, prefix+"."+localNodifier,  ctx);
379                                                                 }
380                                                         }
381                                                 }
382                                         }
383                                 }
384                         }
385                         getLogger().debug("Query - returning " + retval);
386                         return retval;
387
388                 } catch (Exception exc) {
389                         getLogger().warn("Failed query - returning FAILURE", exc);
390                         return QueryStatus.FAILURE;
391                 }
392
393 //              return QueryStatus.SUCCESS;
394         }
395
396
397         public void writeMap(Map<String, Object> properties, String prefix, SvcLogicContext ctx) {
398                 Set<String> mapKeys = properties.keySet();
399
400                 for(String mapKey : mapKeys) {
401                         Object entity = properties.get(mapKey);
402                         if(entity instanceof ArrayList) {
403                                 writeList((ArrayList<?>)entity, prefix + "." + mapKey, ctx);
404                         } else
405                         if(entity instanceof String ||  entity instanceof Long || entity instanceof Integer || entity instanceof Boolean) {
406                                 ctx.setAttribute(prefix + "." + mapKey, entity.toString());
407                                 getLogger().debug(prefix + "." + mapKey + " : " + entity.toString());
408                         } else if(entity instanceof Map) {
409                                 String localPrefix = prefix;
410                                 if(mapKey != null) {
411                                         localPrefix = String.format("%s.%s", prefix, mapKey);
412                                 }
413                                 writeMap( (Map<String, Object>)entity,  localPrefix,  ctx);
414                         }
415                 }
416         }
417
418         private void writeList(ArrayList<?> list, String prefix, SvcLogicContext ctx) {
419                 for(int i = 0; i < list.size(); i++ ) {
420                         Object entity = list.get(i);
421                         if(entity instanceof Map) {
422                                 writeMap( (Map<String, Object>)entity,  prefix + "[" + i + "]",  ctx);
423                         } else
424                                 if(entity instanceof String ||  entity instanceof Long || entity instanceof Integer || entity instanceof Boolean) {
425                                 ctx.setAttribute(prefix, entity.toString());
426                                 getLogger().debug(prefix  + " : " + entity.toString());
427                         }
428                 }
429
430                 if(!list.isEmpty()) {
431                         ctx.setAttribute(prefix + "_length", Integer.toString(list.size()));
432                         getLogger().debug(prefix + "_length"  + " : " + Integer.toString(list.size()));
433                 }
434         }
435
436         @Override
437         public QueryStatus save(String resource, boolean force, boolean localOnly, String key, Map<String, String> params, String prefix, SvcLogicContext ctx)
438                         throws SvcLogicException {
439
440                 getLogger().debug("AAIService.save\tresource="+resource);
441                 HashMap<String, String> nameValues = AAIServiceUtils.keyToHashMap(key, ctx);
442
443                 if(!AAIServiceUtils.isValidFormat(resource, nameValues)) {
444                         ctx.setAttribute(String.format("%s.error.message", prefix), String.format("Resource %s is not supported. Key string contains invaid identifiers", resource));
445                         return QueryStatus.FAILURE;
446                 }
447
448                 if(resource == null || resource.isEmpty() || AAIRequest.createRequest(resource, nameValues) == null) {
449                         getLogger().warn("AAIService.save has unspecified resource");
450                         ctx.setAttribute(String.format("%s.error.message", prefix), String.format("Resource %s is not supported", resource));
451                         return QueryStatus.FAILURE;
452                 }
453                 // keys passed
454                 getLogger().debug("key = "+ Arrays.toString(nameValues.entrySet().toArray()));
455
456                 // process params
457                 if(params.containsKey("prefix")) {
458                         Map<String, String> tmpParams = ctxGetBeginsWith(ctx, params.get("prefix"));
459                         if(!tmpParams.isEmpty()) {
460                                 params.putAll(tmpParams);
461 //                              params.remove("prefix");
462                         }
463                 }
464                 // params passed
465                 getLogger().debug("parms = "+ Arrays.toString(params.entrySet().toArray()));
466
467                 boolean useNewModelProcessing = true;
468                 // process server query by name the old way
469                 if("vserver".equals(resource) || "vserver2".equals(resource)){
470                         if(nameValues.containsKey("vserver-name")) {
471                                 useNewModelProcessing = false;
472                         }
473
474                         if(!params.containsKey("vserver-selflink")) {
475
476                                 AAIRequest request = AAIRequest.createRequest(resource, nameValues);
477                                 URL path = null;
478                                 try {
479                                         request.processRequestPathValues(nameValues);
480                                         path = request.getRequestUrl("GET", null);
481                                         params.put("vserver-selflink", path.toString());
482                                 } catch (UnsupportedEncodingException | MalformedURLException e) {
483                                         // TODO : Fix this
484                                         params.put("vserver-selflink", "/vserver");
485                                 }
486                         }
487                 }
488
489                 // process data using new model
490                 if(useNewModelProcessing && AAIRequest.createRequest(resource, nameValues) != null) {
491
492                         try {
493                                 if(!resource.contains(":")){
494                                         return newModelSave(resource, force, key, params, prefix, ctx);
495                                 } else {
496                                         String[] tokens = resource.split(":");
497                                         String localResource = tokens[0];
498                                         String dependency = tokens[1];
499
500                                         AAIDatum instance = newModelObjectRequest( localResource, nameValues, prefix, ctx);
501                                         if(instance == null) {
502                                                 return QueryStatus.NOT_FOUND;
503                                         }
504
505                                         switch(dependency){
506                                         case "relationship-list":
507                                                 newModelProcessRelationshipList(instance, params, prefix, ctx);
508                                                 break;
509                                         }
510                                         // create a method to update relationship-list
511                                         AAIRequest request = AAIRequest.createRequest(localResource, nameValues);
512                                         request.setRequestObject(instance);
513                                         request.processRequestPathValues(nameValues);
514
515                                         getExecutor().post(request);
516                                                 getLogger().debug("Save relationship list - returning SUCCESS");
517                                                 return QueryStatus.SUCCESS;
518                                 }
519                         } catch (Exception exc) {
520                                 ctx.setAttribute(prefix + ".error.message", exc.getMessage());
521                                 if(exc instanceof AAIServiceException) {
522                                         AAIServiceException aaiexc = (AAIServiceException)exc;
523                                         if(aaiexc.getReturnCode() >= 300) {
524                                                 ctx.setAttribute(prefix + ".error.http.response-code", "" + aaiexc.getReturnCode());
525                                         }
526
527                                         if(aaiexc.getReturnCode() == 404) {
528                                                 return QueryStatus.NOT_FOUND;
529                                         }
530                                 }
531                                 getLogger().warn("Failed save() - returning FAILURE", exc);
532                                 return QueryStatus.FAILURE;
533                         }
534                 } else {
535                         String reSource = resource.toLowerCase().replace("-", "_");
536                                 String vnfId;
537
538                         try {
539                                 switch(reSource) {
540                                         case "generic_vnf":
541                                         case "generic-vnf":
542                                                 vnfId = nameValues.get("vnf_id");
543                                                 if(vnfId == null) {
544                                                         getLogger().debug("Save(generic-vnf) with no vnf-id specified. Returning FAILURE");
545                                                         return QueryStatus.FAILURE;
546                                                 }
547                                                 vnfId = vnfId.trim().replace("'", "").replace("$", "").replace("'", "");
548                                                 GenericVnf vnf = this.requestGenericVnfData(vnfId);
549                                                 String status = params.get("prov-status");
550                                                 boolean updated = false;
551                                                 if(status != null && !status.isEmpty()) {
552                                                         vnf.setProvStatus(status);
553                                                 }
554                                                 if(updated) {
555                                                         this.postGenericVnfData(vnfId, vnf);
556                                                 }
557                                                 break;
558                                         case "vpe":
559                                                 return update( resource,  key, params, prefix, ctx) ;
560
561                                         default:
562                                                 getLogger().debug("Save() executing default path - returning FAILURE");
563                                                 return QueryStatus.FAILURE;
564                                 }
565                         } catch (Exception exc) {
566                                 getLogger().warn("Failed save - returning FAILURE", exc);
567                                 ctx.setAttribute(prefix + ".error.message", exc.getMessage());
568                                 return QueryStatus.FAILURE;
569                         }
570                 }
571
572                 getLogger().debug("Save - returning SUCCESS");
573                 return QueryStatus.SUCCESS;
574         }
575
576         @Override
577         public QueryStatus update(String resource, String key, Map<String, String> params, String prefix, SvcLogicContext ctx) throws SvcLogicException {
578
579                 resource = resource.toLowerCase();
580                 HashMap<String, String> nameValues = AAIServiceUtils.keyToHashMap(key, ctx);
581                 getLogger().debug("key = "+ Arrays.toString(nameValues.entrySet().toArray()));
582                 if(!AAIServiceUtils.isValidFormat(resource, nameValues)) {
583                         ctx.setAttribute(String.format("%s.error.message", prefix), String.format("Resource %s is not supported. Key string contains invaid identifiers", resource));
584                         return QueryStatus.FAILURE;
585                 }
586
587                 if(resource == null || resource.isEmpty() || AAIRequest.createRequest(resource, nameValues) == null) {
588                         ctx.setAttribute(String.format("%s.error.message", prefix), String.format("Resource %s is not supported", resource));
589                         return QueryStatus.FAILURE;
590                 }
591
592                 getLogger().debug("parms = "+ Arrays.toString(params.entrySet().toArray()));
593
594                 AAIRequest request = AAIRequest.createRequest(resource, nameValues);
595                 request = new UpdateRequest(request, params);
596
597                 String[] arguments = request.getArgsList();
598                 for(String name : arguments) {
599                         String modifiedKey = name.replaceAll("-", "_");
600                         if(nameValues.containsKey(modifiedKey)) {
601                                 String argValue = nameValues.get(modifiedKey);
602                                 if(argValue != null) argValue = argValue.trim().replace("'", "").replace("$", "").replace("'", "");
603                                 request.addRequestProperty(name, argValue);
604                         }
605                 }
606
607                 try {
608                         QueryStatus retval = QueryStatus.SUCCESS;
609
610                         retval = newModelQuery(resource, false, null, key, "tmpDelete", null,  ctx);
611
612                         if(retval == null || retval != QueryStatus.SUCCESS) {
613                                 return retval;
614                         }
615
616                         String resourceVersion = ctx.getAttribute("tmpDelete.resource-version");
617                         if(resourceVersion == null) {
618                                 return QueryStatus.NOT_FOUND;
619                         }
620                         params.put("resource-version", resourceVersion);
621
622                         request.processRequestPathValues(nameValues);
623                         getExecutor().patch(request, resourceVersion);
624                 } catch(AAIServiceException aaiexc) {
625                         if(aaiexc.getReturnCode() == 404)
626                                 return QueryStatus.NOT_FOUND;
627                         else
628                                 return QueryStatus.FAILURE;
629                 } catch (Exception exc) {
630                         getLogger().warn("Failed update - returning FAILURE", exc);
631                         return QueryStatus.FAILURE;
632                 }
633
634                 getLogger().debug("Update - returning SUCCESS");
635                 return QueryStatus.SUCCESS;
636         }
637
638         @Override
639         public QueryStatus delete(String resource, String key, SvcLogicContext ctx) throws SvcLogicException {
640                 getLogger().debug("AAIService.delete\tresource="+resource);
641                 HashMap<String, String> nameValues = AAIServiceUtils.keyToHashMap(key, ctx);
642                 getLogger().debug("key = "+ Arrays.toString(nameValues.entrySet().toArray()));
643
644                 if(!AAIServiceUtils.isValidFormat(resource, nameValues)) {
645                         ctx.setAttribute(String.format("%s.error.message", "aaiData"), String.format("Resource %s is not supported. Key string contains invaid identifiers", resource));
646                         return QueryStatus.FAILURE;
647                 }
648
649                 if(resource == null || resource.isEmpty() || AAIRequest.createRequest(resource, nameValues) == null) {
650                         ctx.setAttribute(String.format("%s.error.message", "tmpDelete"), String.format("Resource %s is not supported", resource));
651                         return QueryStatus.FAILURE;
652                 }
653
654                 if(AAIRequest.createRequest(resource, nameValues) != null) {
655                         if(resource.contains(":")) {
656                                 return processDeleteRelationshipList(resource, key, ctx, nameValues);
657                         }
658
659
660                         try {
661                                 QueryStatus retval = QueryStatus.SUCCESS;
662
663                                 retval = newModelQuery(resource, false, null, key, "tmpDelete", null,  ctx);
664
665                                 if(retval == null || retval != QueryStatus.SUCCESS) {
666                                         return retval;
667                                 }
668
669                                 String resourceVersion = ctx.getAttribute("tmpDelete.resource-version");
670                                 if(resourceVersion == null) {
671                                         return QueryStatus.NOT_FOUND;
672                                 }
673
674                                 try {
675                                         AAIRequest request = AAIRequest.createRequest(resource, nameValues);
676                                         if(request == null) {
677                                                 return QueryStatus.FAILURE;
678                                         }
679
680                                         request.processRequestPathValues(nameValues);
681
682                                         if(getExecutor().delete(request, resourceVersion)) {
683                                                 return QueryStatus.SUCCESS;
684                                         }
685                                 } catch(AAIServiceException aaiexc) {
686                                         if(aaiexc.getReturnCode() == 404)
687                                                 return QueryStatus.NOT_FOUND;
688                                         else
689                                                 return QueryStatus.FAILURE;
690
691                                 } catch (Exception exc) {
692                                         getLogger().warn("requestGenericVnfData", exc);
693                                         return QueryStatus.FAILURE;
694                                 }
695
696                         } catch (Exception exc) {
697                                 getLogger().warn("Failed delete - returning FAILURE", exc);
698                                 return QueryStatus.FAILURE;
699                         }
700                 } else {
701                         String resoourceName = resource;
702                         String identifier = null;
703
704                         if(resoourceName.contains(":")) {
705                                 String[] tokens = resoourceName.split(":");
706                                 if(tokens != null && tokens.length > 0) {
707                                         resoourceName = tokens[0];
708                                         identifier = tokens[1];
709                                 }
710                         }
711                         if("relationship-list".equals(identifier) || "relationshipList".equals(identifier)) {
712 //                              RelationshipRequest relationshipRequest = new RelationshipRequest();
713                                 if("generic-vnf".equals(resoourceName)){
714                                         String vnfId = nameValues.get("vnf_id");
715                                         String relatedTo  = nameValues.get("related_to");
716                                         vnfId = vnfId.trim().replace("'", "").replace("$", "").replace("'", "");
717                                         relatedTo = relatedTo.trim().replace("'", "").replace("$", "").replace("'", "");
718
719                                         GenericVnf vnf;
720                                         try {
721                                                 vnf = this.requestGenericVnfData(vnfId);
722                                                 if(vnf == null)
723                                                         return QueryStatus.NOT_FOUND;
724                                         } catch (AAIServiceException exc) {
725                                                 getLogger().warn("Failed delete - returning NOT_FOUND", exc);
726                                                 return QueryStatus.NOT_FOUND;
727                                         }
728                                         boolean itemRemoved = false;
729                                         RelationshipList relationshipList = vnf.getRelationshipList();
730                                         List<Relationship> relationships = relationshipList.getRelationship();
731                                         List<Relationship> iterableList = new LinkedList<Relationship>(relationships);
732                                         for(Relationship relationship : iterableList) {
733                                                 if(relationship.getRelatedTo().equals(relatedTo)) {
734                                                         relationships.remove(relationship);
735                                                         itemRemoved = true;
736                                                 }
737                                         }
738
739                                         if(!itemRemoved)
740                                                 return QueryStatus.NOT_FOUND;
741
742 //                                      AAIRequest masterRequest = new GenericVnfRequest();
743 //                                      masterRequest.addRequestProperty(GenericVnfRequest.VNF_ID, vnfId);
744 //                                      relationshipRequest.addMasterRequest(masterRequest);
745 //                                      Map<String, String> attributes = objectToProperties(vnf);
746 //                                      try {
747 //                                              Boolean result = getExecutor().delete(relationshipRequest, attributes.get(AAIRequest.RESOURCE_VERSION));
748 //                                      } catch (AAIServiceException e) {
749 //                                              return QueryStatus.FAILURE;
750 //                                      }
751
752                                         try {
753                                                 this.postGenericVnfData(vnf.getVnfId(), vnf);
754                                         } catch (AAIServiceException exc) {
755                                                 if(exc.getReturnCode() == 404){
756                                                         return QueryStatus.NOT_FOUND;
757                                                 } else {
758                                                         getLogger().warn("Failed delete - returning FAILURE", exc);
759                                                         return QueryStatus.FAILURE;
760                                                 }
761                                         }
762                                         return QueryStatus.SUCCESS;
763                                 }
764                         }
765                 }
766                 return QueryStatus.FAILURE;
767         }
768
769         @Override
770         public QueryStatus exists(String resource, String key, String prefix, SvcLogicContext ctx) throws SvcLogicException {
771                 return query(resource, false, null, key, prefix, null, ctx);
772         }
773
774         @Override
775         public QueryStatus isAvailable(String arg0, String arg1, String arg2, SvcLogicContext arg3)
776                         throws SvcLogicException {
777                 // TODO Auto-generated method stub
778                 throw new SvcLogicException("Method AAIService.isAvailable() has not been implemented yet");
779         }
780
781         @Override
782         public QueryStatus notify(String resource, String action, String key, SvcLogicContext ctx) throws SvcLogicException {
783                 // TODO Auto-generated method stub
784                 throw new SvcLogicException("Method AAIService.notify() has not been implemented yet");
785         }
786
787 //      @Override
788         public QueryStatus newModelQuery(String resource, boolean localOnly, String select, String key, String prefix, String orderBy, SvcLogicContext ctx) {
789
790                 Object response = null;
791                 QueryStatus retval = QueryStatus.SUCCESS;
792                 String modifier = null;
793
794                 HashMap<String, String> nameValues = AAIServiceUtils.keyToHashMap(key, ctx);
795                 if(resource.contains(":")) {
796                         modifier = resource.split(":")[1];
797                 }
798
799                 try {
800                         AAIRequest request = AAIRequest.createRequest(resource, nameValues);
801                         if(request == null) {
802                                 return QueryStatus.FAILURE;
803                         }
804
805                         Map<String, String> params = new HashMap<>();
806
807                         request.processRequestPathValues(nameValues);
808                         if(nameValues.containsKey("prefix")){
809                                 Map<String, String> tmpParams = ctxGetBeginsWith(ctx, nameValues.get("prefix"));
810                                 if(!tmpParams.isEmpty()) {
811                                         params.putAll(tmpParams);
812                                 }
813                                 if("named-query".equals(resource))
814                                         request.setRequestObject(extractNamedQueryDataFromQueryPrefix(nameValues, params));
815                         }
816                         String rv = getExecutor().get(request);
817
818                         retval = processResponseData(rv, resource, request, prefix,  ctx, nameValues, modifier);
819
820                 } catch(AAIServiceException aaiexc) {
821                         int errorCode = aaiexc.getReturnCode();
822                         ctx.setAttribute(prefix + ".error.message", aaiexc.getMessage());
823                         if(errorCode >= 300) {
824                                 ctx.setAttribute(prefix + ".error.http.response-code", "" +
825                                                 Integer.toString(aaiexc.getReturnCode()));
826                         }
827
828                         if(aaiexc.getReturnCode() == 404)
829                                 return QueryStatus.NOT_FOUND;
830
831                         return QueryStatus.FAILURE;
832                 } catch (Exception exc) {
833                         getLogger().warn("requestGenericVnfData", exc);
834                         ctx.setAttribute(prefix + ".error.message", exc.getMessage());
835                         return QueryStatus.FAILURE;
836                 }
837
838                 return retval;
839         }
840
841         public QueryStatus processResponseData(String rv, String resource, AAIRequest request, String prefix,  SvcLogicContext ctx, HashMap<String, String> nameValues, String modifier) throws JsonParseException, JsonMappingException, IOException, AAIServiceException
842         {
843                 Object response;
844
845                         if(rv == null) {
846                                 return QueryStatus.NOT_FOUND;
847                         }
848
849                         response = request.jsonStringToObject(rv);
850                         if(response == null) {
851                                 return QueryStatus.NOT_FOUND;
852                         }
853
854                         if("generic-query".equals(resource)) {
855                                 SearchResults rd = SearchResults.class.cast(response);
856                                 List<ResultData> rdList = rd.getResultData();
857                                 if(rdList == null || rdList.isEmpty()) {
858                                         return QueryStatus.NOT_FOUND;
859                                 }
860                                 ResultData rDatum = rdList.get(0);
861                                 nameValues.put("selflink", rDatum.getResourceLink());
862                                 AAIRequest req2 = AAIRequest.createRequest(rDatum.getResourceType(), nameValues);
863                                 req2.processRequestPathValues(nameValues);
864                                 rv = getExecutor().get(req2);
865                                 if(rv == null) {
866                                         return QueryStatus.NOT_FOUND;
867                                 }
868
869                                 response = req2.jsonStringToObject(rv);
870                                 if(response == null) {
871                                         return QueryStatus.NOT_FOUND;
872                                 }
873                         }
874
875                         if("named-query".equals(resource)) {
876                                 InventoryResponseItems rd = InventoryResponseItems.class.cast(response);
877                                 List<InventoryResponseItem> iRIlist = rd.getInventoryResponseItem();
878                                 if(iRIlist == null || iRIlist.isEmpty()) {
879                                         return QueryStatus.NOT_FOUND;
880                                 }
881                         }
882
883                         if("nodes-query".equals(resource)) {
884                                 SearchResults rd = SearchResults.class.cast(response);
885                                 List<ResultData> rdList = rd.getResultData();
886                                 if(rdList == null || rdList.isEmpty()) {
887                                         return QueryStatus.NOT_FOUND;
888                                 }
889                                 ResultData rDatum = rdList.get(0);
890                                 response = rDatum;
891                         }
892
893                 if("formatted-query".equals(resource) || "custom-query".equals(resource)) {
894                         FormattedQueryResultList rd = FormattedQueryResultList.class.cast(response);
895                         List<Results> iRIlist = rd.getResults();
896                         if(iRIlist == null || iRIlist.isEmpty()) {
897                                 return QueryStatus.NOT_FOUND;
898                         }
899                 }
900
901                 // process relationship list
902                 // this is a temporary soluton to address the realationship handling changes added in Release 17.07
903                 try {
904                         Class<?> clazz = response.getClass();
905                         Method getter = clazz.getMethod("getRelationshipList");
906                         Object obj = getter.invoke(response);
907                         if(obj != null && obj instanceof RelationshipList) {
908                                 RelationshipList list = RelationshipList.class.cast(obj);
909                                 AAIServiceUtils.populateRelationshipDataFromPath(list);
910                         }
911                 } catch(Exception exc) {
912                         getLogger().debug("Retrofiting relationship data: " + exc.getMessage());
913                 }
914
915                         String preFix;
916                         if(prefix == null || prefix.isEmpty()) {
917                                 preFix = "";
918                         } else {
919                                 preFix = prefix + ".";
920                         }
921
922                     Map<String,Object> props = objectToProperties(response);
923                     Set<String> keys = props.keySet();
924                     for(String theKey: keys) {
925                         if(getLogger().isTraceEnabled())
926                                 getLogger().trace(theKey);
927
928                         Object value = props.get(theKey);
929                         if(value == null)
930                                 continue;
931                         Object type = value.getClass();
932                         if(value instanceof String) {
933                                 ctx.setAttribute(preFix + theKey, value.toString());
934                                 continue;
935                         }
936                         if(value instanceof Boolean) {
937                                 ctx.setAttribute(preFix + theKey, value.toString());
938                                 continue;
939                         }
940                         if(value instanceof Integer) {
941                                 ctx.setAttribute(preFix + theKey, value.toString());
942                                 continue;
943                         }
944                         if(value instanceof Long) {
945                                 ctx.setAttribute(preFix + theKey, value.toString());
946                                 continue;
947                         }
948
949                         if(value instanceof ArrayList) {
950                                 ArrayList<?> array = ArrayList.class.cast(value);
951                                 for(int i = 0; i < array.size(); i++) {
952                                         writeList(array, String.format("%s.%s", prefix, theKey), ctx);
953                                 }
954                                 continue;
955                         }
956
957                         if("relationship-list".equals(theKey)){
958                                 Map<String, Object> relationshipList = (Map<String, Object>)value;
959                                 // we are interested in seeing just the selected relationship
960                                 if(theKey.equals(modifier)) {
961                                         List<?> relationships = (List<?>)relationshipList.get("relationship");
962                                         if(relationships != null && !relationships.isEmpty()) {
963
964                                                 List newRelationships = new LinkedList();
965                                                 newRelationships.addAll(relationships);
966
967                                                 for(Object obj : newRelationships){
968                                                         if(obj instanceof Map<?, ?>) {
969                                                                 Map<?, ?> relProperties = (Map<?, ?>)obj;
970                                                                 if(relProperties.containsKey("related-to")) {
971                                                                         Object relPropsRelatedTo = relProperties.get("related-to");
972
973                                                                         String relatedTo = nameValues.get("related_to");
974                                                                         if(relatedTo != null) {
975                                                                                 relatedTo = relatedTo.trim().replace("'", "").replace("$", "").replace("'", "");
976                                                                                 if(!relatedTo.equals(relPropsRelatedTo)) {
977                                                                                         relationships.remove(relProperties);
978                                                                                 }
979                                                                                 continue;
980                                                                         } else {
981                                                                                 continue;
982                                                                         }
983                                                                 }
984                                                         }
985                                                 }
986                                         }
987                                 }
988                                 writeMap(relationshipList, String.format("%s.%s", prefix, theKey), ctx);
989                                 continue;
990                         }
991
992                         if(value instanceof Map) {
993                                 Map<String, Object> subnetsList = (Map<String, Object>)value;
994                                 writeMap(subnetsList, String.format("%s.%s", prefix, theKey), ctx);
995                                 continue;
996                         }
997
998                     }
999             return QueryStatus.SUCCESS;
1000         }
1001
1002
1003         public QueryStatus newModelBackupRequest(String resource,  Map<String, String> params,  String prefix,  SvcLogicContext ctx) {
1004
1005                 QueryStatus retval = QueryStatus.SUCCESS;
1006                 HashMap<String, String> nameValues = new HashMap<>();
1007
1008                 try {
1009                         AAIRequest request = AAIRequest.createRequest(resource, nameValues);
1010                         if(request == null) {
1011                                 return QueryStatus.FAILURE;
1012                         }
1013
1014                         boolean argsFound = false;
1015                         String[] arguments = request.getArgsList();
1016                         for(String name : arguments) {
1017                                 String tmpName = name.replaceAll("-", "_");
1018                                 String value = params.get(tmpName);
1019                                 if(value != null && !value.isEmpty()) {
1020                                         value = value.trim().replace("'", "").replace("$", "").replace("'", "");
1021                                         request.addRequestProperty(name, value);
1022                                         argsFound = true;
1023                                 }
1024                         }
1025                         if(!argsFound) {
1026                                 getLogger().warn("No arguments were found. Terminating backup request.");
1027                                 return QueryStatus.FAILURE;
1028                         }
1029
1030                         String rv = getExecutor().get(request);
1031                     ctx.setAttribute(prefix, rv);
1032                 } catch(AAIServiceException aaiexc) {
1033                         if(aaiexc.getReturnCode() == 404)
1034                                 return QueryStatus.NOT_FOUND;
1035
1036                         return QueryStatus.FAILURE;
1037                 } catch (Exception exc) {
1038                         getLogger().warn("newModelBackupRequest", exc);
1039                         return QueryStatus.FAILURE;
1040                 }
1041
1042                 return retval;
1043         }
1044
1045         public AAIDatum newModelObjectRequest(String resource,  Map<String, String> params,  String prefix,  SvcLogicContext ctx)
1046                         throws AAIServiceException {
1047
1048                 AAIDatum response = null;
1049
1050                 try {
1051                         AAIRequest request = AAIRequest.createRequest(resource, params);
1052                         if(request == null) {
1053                                 return null;
1054                         }
1055
1056                         request.processRequestPathValues(params);
1057                         String rv = getExecutor().get(request);
1058                         response = request.jsonStringToObject(rv);
1059                 } catch(AAIServiceException aaiexc) {
1060                         throw aaiexc;
1061                 } catch (Exception exc) {
1062                         getLogger().warn("newModelBackupRequest", exc);
1063                         throw new AAIServiceException(exc);
1064                 }
1065
1066                 return response;
1067         }
1068
1069
1070         @Override
1071         public QueryStatus release(String arg0, String arg1, SvcLogicContext arg2) throws SvcLogicException {
1072                 // TODO Auto-generated method stub
1073                 throw new SvcLogicException("Method AAIService.release() has not been implemented yet");
1074         }
1075
1076         @Override
1077         public QueryStatus reserve(String arg0, String arg1, String arg2, String arg3, SvcLogicContext arg4)
1078                         throws SvcLogicException {
1079                 // TODO Auto-generated method stub
1080                 throw new SvcLogicException("Method AAIService.reserve() has not been implemented yet");
1081         }
1082
1083         private QueryStatus newModelSave(String resource, boolean force, String key, Map<String, String> params, String prefix, SvcLogicContext ctx) {
1084                 getLogger().debug("Executing newModelSave for resource : " + resource);
1085                 HashMap<String, String> nameValues = AAIServiceUtils.keyToHashMap(key, ctx);
1086
1087                 try {
1088                         ArrayList<String> subResources = new ArrayList<>();
1089                         Set<String> set = params.keySet();
1090                         Map<String, Method> setters = new HashMap<>();
1091                         Map<String, Method> getters = new HashMap<>();
1092
1093                         // 1. find class
1094                         AAIRequest request = AAIRequest.createRequest(resource, nameValues);
1095                         Class<? extends AAIDatum> resourceClass = request.getModelClass();
1096                         getLogger().debug(resourceClass.getName());
1097                         AAIDatum instance = resourceClass.newInstance();
1098
1099                         {
1100                                 Annotation[] annotations = resourceClass.getAnnotations();
1101                                 for(Annotation annotation : annotations) {
1102                                         Class<? extends Annotation> anotationType = annotation.annotationType();
1103                                         String annotationName = anotationType.getName();
1104
1105                                         // 2. find string property setters and getters for the lists
1106                                         if("javax.xml.bind.annotation.XmlType".equals(annotationName)){
1107                                                 XmlType order = (XmlType)annotation;
1108                                                 String[]  values = order.propOrder();
1109                                                 for(String value : values) {
1110                                                         String id = AAIServiceUtils.camelCaseToDashedString(value);
1111                                                         Field field = resourceClass.getDeclaredField(value);
1112                                                         Class<?> type = field.getType();
1113                                                         Method setter = null;
1114                                                         try {
1115                                                                 setter = resourceClass.getMethod("set"+StringUtils.capitalize(value), type);
1116                                                                 if(type.getName().startsWith("java.lang") || "boolean".equals(type.getName()) || "long".equals(type.getName())) {
1117                                                                         try {
1118                                                                                 setter.setAccessible(true);
1119                                                                                 Object arglist[] = new Object[1];
1120                                                                                 arglist[0] = params.get(id);
1121
1122                                                                                 if(arglist[0] != null) {
1123                                                                                         if(!type.getName().equals("java.lang.String")) {
1124 //                                                                                      getLogger().debug(String.format("Processing %s with parameter %s", types[0].getName(), value));
1125                                                                                                 if("boolean".equals(type.getName())) {
1126                                                                                                         arglist[0] = valueOf(Boolean.class, params.get(id));
1127                                                                                                 } else if("long".equals(type.getName())) {
1128                                                                                                                 arglist[0] = valueOf(Long.class, params.get(id));
1129                                                                                                 } else {
1130                                                                                                         arglist[0] = valueOf(type, params.get(id));
1131                                                                                                 }
1132                                                                                         }
1133                                                                                         Object o = setter.invoke(instance, arglist);
1134                                                                                 }
1135                                                                                 set.remove(id);
1136
1137                                                                         } catch (Exception x) {
1138                                                                                 Throwable cause = x.getCause();
1139                                                                                 getLogger().warn("Failed process for " + resourceClass.getName(), x);
1140                                                                         }
1141                                                                 } else if(type.getName().equals("java.util.List")) {
1142                                                                         List<String> newValues = new ArrayList<>();
1143                                                                         String length = id+"_length";
1144                                                                         if(!params.isEmpty() && params.containsKey(length)) {
1145                                                                                 String tmp = params.get(length).toString();
1146                                                                                 int count = Integer.parseInt(tmp);
1147                                                                                 for(int i=0; i<count; i++) {
1148                                                                                         String tmpValue = params.get(String.format("%s[%d]", id, i));
1149                                                                                         newValues.add(tmpValue);
1150                                                                                 }
1151                                                                                 if(!newValues.isEmpty()) {
1152                                                                                         Object o = setter.invoke(instance, newValues);
1153                                                                                 }
1154                                                                         }
1155                                                                         set.remove(id);
1156                                                                 } else {
1157                                                                         setters.put(id, setter);
1158                                                                 }
1159                                                         } catch(Exception exc) {
1160
1161                                                         }
1162
1163                                                         Method getter;
1164                                                         try {
1165                                                                 getter = resourceClass.getMethod("get"+StringUtils.capitalize(value));
1166                                                                 if(!type.getName().equals("java.lang.String")) {
1167                                                                         getters.put(id, getter);
1168                                                                 }
1169                                                         } catch(Exception exc) {
1170
1171                                                         }
1172
1173                                                 }
1174                                                 subResources.addAll(Arrays.asList(values));
1175                                         }
1176                                 }
1177                         }
1178
1179                         // remove getters that have matching setter
1180                         for(String setKey : setters.keySet()) {
1181                                 if(getters.containsKey(setKey)) {
1182                                         getters.remove(setKey);
1183                                 }
1184                         }
1185
1186                         Set<String> relationshipKeys = new TreeSet<>();
1187                         Set<String> vlansKeys = new TreeSet<>();
1188                         Set<String> metadataKeys = new TreeSet<>();
1189
1190                         for(String attribute : set) {
1191                                 String value = params.get(attribute);
1192                                 if(attribute.startsWith("relationship-list")) {
1193                                         relationshipKeys.add(attribute);
1194                                 } else if(attribute.startsWith("vlans")) {
1195                                         vlansKeys.add(attribute);
1196                                 } else if(attribute.startsWith("metadata")) {
1197                                         metadataKeys.add(attribute);
1198                                 }
1199                         }
1200                         // 3. find list property getters
1201                         for(String attribute : set) {
1202                                 String value = params.get(attribute);
1203                                 Method method = getters.get(attribute);
1204                                 if(method != null) {
1205                                         try {
1206                                                 method.setAccessible(true);
1207                                                 Object arglist[] = new Object[0];
1208 //                                              arglist[0] = value;
1209                                                 Class<?>[] types = method.getParameterTypes();
1210                                                 if(types.length == 0){
1211                                                         Object o = method.invoke(instance, arglist);
1212                                                         if(o instanceof ArrayList) {
1213                                                                 ArrayList<String> values = (ArrayList<String>)o;
1214 //                                                              getLogger().debug(String.format("Processing %s with parameter %s", types[0].getName(), value));
1215                                                                 value = value.replace("[", "").replace("]", "");
1216                                                                 List<String> items = Arrays.asList(value.split("\\s*,\\s*"));
1217                                                                 for(String s : items) {
1218                                                                         values.add(s.trim());
1219                                                                 }
1220                                                         }
1221                                                 }
1222                                         } catch (Exception x) {
1223                                                 Throwable cause = x.getCause();
1224                                                 getLogger().warn("Failed process for " + resourceClass.getName(), x);
1225                                         }
1226                                 }
1227                         }
1228                         // 4. Process Relationships
1229                         // add relationship list
1230                         if( (subResources.contains("relationship-list") || subResources.contains("relationshipList")) &&  !relationshipKeys.isEmpty()) {
1231                                 RelationshipList relationshipList = null;
1232                                 Object obj = null;
1233                                 Method getRelationshipListMethod = null;
1234                                 try {
1235                                          getRelationshipListMethod = resourceClass.getMethod("getRelationshipList");
1236                                 } catch(Exception exc) {
1237                                         getLogger().debug("Retrofiting relationship data: " + exc.getMessage());
1238                                 }
1239
1240                                 if(getRelationshipListMethod != null){
1241                                         try {
1242                                                 getRelationshipListMethod.setAccessible(true);
1243                                                 obj = getRelationshipListMethod.invoke(instance);
1244                                         } catch (InvocationTargetException x) {
1245                                                 Throwable cause = x.getCause();
1246                                         }
1247                                 }
1248                                 if(obj != null && obj instanceof RelationshipList){
1249                                         relationshipList = (RelationshipList)obj;
1250                                 } else {
1251                                         relationshipList = new RelationshipList();
1252                                         Method setRelationshipListMethod = resourceClass.getMethod("setRelationshipList", RelationshipList.class);
1253                                         if(setRelationshipListMethod != null){
1254                                                 try {
1255                                                         setRelationshipListMethod.setAccessible(true);
1256                                                         Object arglist[] = new Object[1];
1257                                                         arglist[0] = relationshipList;
1258
1259                                                         obj = setRelationshipListMethod.invoke(instance, arglist);
1260                                                 } catch (InvocationTargetException x) {
1261                                                         Throwable cause = x.getCause();
1262                                                 }
1263                                         }
1264                                 }
1265
1266                                 List<Relationship> relationships = relationshipList.getRelationship();
1267
1268                                 int i = 0;
1269                                 while(true){
1270                                         String searchKey = "relationship-list.relationship[" + i + "].related-to";
1271                                         if(!params.containsKey(searchKey))
1272                                                 break;
1273                                         int j = 0;
1274                                         String relatedTo = params.get(searchKey);
1275                                         String relatedLinkKey = "relationship-list.relationship[" + i + "].related-link";
1276                                         String relatedLink = null;
1277                                         if(params.containsKey(relatedLinkKey)) {
1278                                                 relatedLink = params.get(relatedLinkKey);
1279                                         }
1280                                         Relationship relationship = new Relationship();
1281                                         relationships.add(relationship);
1282                                         relationship.setRelatedTo(relatedTo);
1283                                         if(relatedLink != null) {
1284                                                 relationship.setRelatedLink(relatedLink);
1285                                         } else {
1286 //                                              List<RelationshipData> relData = relationship.getRelationshipData();
1287                                                 Map<String, String> relParams = new HashMap<String, String>();
1288
1289                                         while(true) {
1290                                                 String searchRelationshipKey = "relationship-list.relationship[" + i + "].relationship-data[" + j + "].relationship-key";
1291                                                 String searchRelationshipValue = "relationship-list.relationship[" + i + "].relationship-data[" + j + "].relationship-value";
1292                                                         if(!params.containsKey(searchRelationshipKey))
1293                                                         break;
1294
1295                                                         relParams.put(params.get(searchRelationshipKey), params.get(searchRelationshipValue));
1296                                                 j++;
1297                                         }
1298                                                 AAIRequest rlRequest = AAIRequest.createRequest(relatedTo, relParams);
1299                                                 for(Map.Entry<String,String> entry : relParams.entrySet()) {
1300                                                         rlRequest.addRequestProperty(entry.getKey(), entry.getValue());
1301                                                 }
1302                                                 String path = rlRequest.updatePathDataValues(null);
1303                                                 relationship.setRelatedLink(path);
1304                                         }
1305                                         i++;
1306                                 }
1307                         }
1308
1309                         // 4. vlans
1310                         if(subResources.contains("vlans") &&  !vlansKeys.isEmpty()) {
1311                                 Object obj = null;
1312                                 Vlans vlanList = null;
1313                                 Method getVLansMethod = resourceClass.getMethod("getVlans");
1314                                 if(getVLansMethod != null){
1315                                         try {
1316                                                 getVLansMethod.setAccessible(true);
1317                                                 obj = getVLansMethod.invoke(instance);
1318                                         } catch (InvocationTargetException x) {
1319                                                 Throwable cause = x.getCause();
1320                                         }
1321                                 }
1322                                 if(obj != null && obj instanceof Vlans){
1323                                         vlanList = (Vlans)obj;
1324                                 } else {
1325                                         vlanList = new Vlans();
1326                                         Method setVlansMethod = resourceClass.getMethod("setVlans", Vlans.class);
1327                                         if(setVlansMethod != null){
1328                                                 try {
1329                                                         setVlansMethod.setAccessible(true);
1330                                                         Object arglist[] = new Object[1];
1331                                                         arglist[0] = vlanList;
1332
1333                                                         obj = setVlansMethod.invoke(instance, arglist);
1334                                                 } catch (InvocationTargetException x) {
1335                                                         Throwable cause = x.getCause();
1336                                                 }
1337                                         }
1338                                 }
1339
1340                                 int i = 0;
1341                                 while(true){
1342                                         String searchKey = "vlans.vlan[" + i + "].vlan-interface";
1343                                         if(!params.containsKey(searchKey))
1344                                                 break;
1345
1346                                         String vlanInterface = params.get("vlans.vlan[" + i + "].vlan-interface");
1347                                         String vlanIdInner      = params.get("vlans.vlan[" + i + "].vlan-id-inner");
1348                                         String vlanIdOute       = params.get("vlans.vlan[" + i + "].vlan-id-outer");
1349                                         String speedValue       = params.get("vlans.vlan[" + i + "].speed-value");
1350                                         String speedUnits       = params.get("vlans.vlan[" + i + "].speed-units");
1351
1352                                         Vlan vlan = new Vlan();
1353                                         vlan.setVlanInterface(vlanInterface);
1354
1355                                         if(vlanIdInner != null) {
1356                                         Long iVlanIdInner = Long.parseLong(vlanIdInner);
1357                                         vlan.setVlanIdInner(iVlanIdInner);
1358                                         }
1359
1360                                         if(vlanIdOute != null) {
1361                                                 Long iVlanIdOuter = Long.parseLong(vlanIdOute);
1362                                         vlan.setVlanIdOuter(iVlanIdOuter);
1363                                         }
1364
1365                                         if(speedValue != null) {
1366                                         vlan.setSpeedValue(speedValue);
1367                                         vlan.setSpeedUnits(speedUnits);
1368                                         }
1369
1370                                         vlanList.getVlan().add(vlan);
1371                                         i++;
1372                                 }
1373                         }
1374
1375                         // 5. metadata
1376                         if(subResources.contains("metadata") &&  !metadataKeys.isEmpty()) {
1377                                 Object obj = null;
1378                                 Metadata metadataList = null;
1379                                 Method getMetadataMethod = resourceClass.getMethod("getMetadata");
1380                                 if(getMetadataMethod != null){
1381                                         try {
1382                                                 getMetadataMethod.setAccessible(true);
1383                                                 obj = getMetadataMethod.invoke(instance);
1384                                         } catch (InvocationTargetException x) {
1385                                                 Throwable cause = x.getCause();
1386                                         }
1387                                 }
1388                                 if(obj != null && obj instanceof Metadata){
1389                                         metadataList = (Metadata)obj;
1390                                 } else {
1391                                         metadataList = new Metadata();
1392                                         Method setMetadataMethod = resourceClass.getMethod("setMetadata", Metadata.class);
1393                                         if(setMetadataMethod != null){
1394                                                 try {
1395                                                         setMetadataMethod.setAccessible(true);
1396                                                         Object arglist[] = new Object[1];
1397                                                         arglist[0] = metadataList;
1398
1399                                                         obj = setMetadataMethod.invoke(instance, arglist);
1400                                                 } catch (InvocationTargetException x) {
1401                                                         Throwable cause = x.getCause();
1402                                                 }
1403                                         }
1404                                 }
1405
1406                                 if(metadataList.getMetadatum() == null) {
1407 //                                      metadataList.setMetadatum(new ArrayList<Metadatum>());
1408                                 }
1409
1410                                 // process data
1411                                 int i = 0;
1412                                 while(true){
1413                                         String metaKey = "metadata.metadatum[" + i + "].meta-key";
1414                                         if(!params.containsKey(metaKey))
1415                                                 break;
1416
1417                                         String metaValue = params.get("metadata.metadatum[" + i + "].meta-value");
1418
1419                                         Metadatum vlan = new Metadatum();
1420                                         vlan.setMetaname(metaKey);
1421                                         vlan.setMetaval(metaValue);
1422
1423                                         metadataList.getMetadatum().add(vlan);
1424                                         i++;
1425                                 }
1426
1427                         }
1428
1429
1430                         // 6. Prepare AAI request
1431                         String[] args = request.getArgsList();
1432                         for(String arg : args) {
1433                                 String modifiedKey = arg.replaceAll("-", "_");
1434                                 if(nameValues.containsKey(modifiedKey)) {
1435                                         String argValue = nameValues.get(modifiedKey);
1436                                         if(argValue != null) argValue = argValue.trim().replace("'", "").replace("$", "").replace("'", "");
1437                                         request.addRequestProperty(arg, argValue);
1438                                 }
1439                         }
1440
1441                         request.processRequestPathValues(nameValues);
1442                         request.setRequestObject(instance);
1443                                 Object response = getExecutor().post(request);
1444                                 if(request.expectsDataFromPUTRequest()){
1445                                         if(response != null && response instanceof String) {
1446                                                 String rv = response.toString();
1447                                                 QueryStatus retval = processResponseData(rv, resource, request, prefix,  ctx, nameValues, null);
1448                                                 getLogger().debug("newModelSave - returning " + retval.toString());
1449                                                 return retval;
1450                                         }
1451                                 }
1452
1453                 } catch(AAIServiceException exc){
1454                         ctx.setAttribute(prefix + ".error.message", exc.getMessage());
1455                         int returnCode = exc.getReturnCode();
1456                         if(returnCode >= 300) {
1457                                 ctx.setAttribute(prefix + ".error.http.response-code", "" +
1458                                                 Integer.toString(exc.getReturnCode()));
1459                         }
1460
1461                         if(returnCode == 400 || returnCode == 412)
1462                                 return QueryStatus.FAILURE;
1463                         else if(returnCode == 404)
1464                                 return QueryStatus.NOT_FOUND;
1465                         else {
1466                                 getLogger().warn("Failed newModelSave - returning FAILURE", exc);
1467                                 return QueryStatus.FAILURE;
1468                         }
1469                 } catch(Exception exc){
1470                         getLogger().warn("Failed newModelSave - returning FAILURE", exc);
1471                         ctx.setAttribute(prefix + ".error.message", exc.getMessage());
1472                         return QueryStatus.FAILURE;
1473                 }
1474
1475                 getLogger().debug("newModelSave - returning SUCCESS");
1476                 return QueryStatus.SUCCESS;
1477         }
1478
1479         private QueryStatus newModelProcessRelationshipList(Object instance, Map<String, String> params, String prefix, SvcLogicContext ctx) throws Exception {
1480
1481                 Class resourceClass = instance.getClass();
1482
1483                 Set<String> relationshipKeys = new TreeSet<>();
1484
1485                 Set<String> set = params.keySet();
1486
1487                 for(String attribute : set) {
1488                         String value = params.get(attribute);
1489
1490                         if(attribute.startsWith("relationship-list")) {
1491                                 relationshipKeys.add(attribute);
1492                         }
1493                 }
1494
1495                 // 3. Process Relationships
1496                 // add relationship list
1497                 if(!relationshipKeys.isEmpty()) {
1498                         RelationshipList relationshipList;
1499                         Object obj = null;
1500                         Method getRelationshipListMethod = null;
1501                         try {
1502                                  getRelationshipListMethod = resourceClass.getMethod("getRelationshipList");
1503                         } catch(Exception exc) {
1504                                 getLogger().debug("Retrofiting relationship data: " + exc.getMessage());
1505                         }
1506                         if(getRelationshipListMethod != null){
1507                                 try {
1508                                         getRelationshipListMethod.setAccessible(true);
1509                                         obj = getRelationshipListMethod.invoke(instance);
1510                                 } catch (InvocationTargetException x) {
1511                                         Throwable cause = x.getCause();
1512                                 }
1513                         }
1514                         if(obj != null && obj instanceof RelationshipList){
1515                                 relationshipList = (RelationshipList)obj;
1516                         } else {
1517                                 relationshipList = new RelationshipList();
1518                                 Method setRelationshipListMethod = resourceClass.getMethod("setRelationshipList", RelationshipList.class);
1519                                 if(setRelationshipListMethod != null){
1520                                         try {
1521                                                 setRelationshipListMethod.setAccessible(true);
1522                                                 Object arglist[] = new Object[1];
1523                                                 arglist[0] = relationshipList;
1524
1525                                                 obj = setRelationshipListMethod.invoke(instance, arglist);
1526                                         } catch (InvocationTargetException x) {
1527                                                 Throwable cause = x.getCause();
1528                                         }
1529                                 }
1530                         }
1531
1532                         boolean createdNewRelationships = false;
1533                         List<Relationship> relationships = relationshipList.getRelationship();
1534                         if(relationships == null) {
1535                                 relationships = new ArrayList<Relationship>();
1536                                 createdNewRelationships = true;
1537                         }
1538
1539                         int i = 0;
1540                         while(true){
1541                                 String searchKey = "relationship-list.relationship[" + i + "].related-to";
1542                                 if(!params.containsKey(searchKey))
1543                                         break;
1544
1545                                 int j = 0;
1546                                 String relatedTo = params.get(searchKey);
1547                                 String relatedLinkKey = "relationship-list.relationship[" + i + "].related-link";
1548                                 String relatedLink = null;
1549                                 if(params.containsKey(relatedLinkKey)) {
1550                                         relatedLink = params.get(relatedLinkKey);
1551                                 }
1552
1553                                 Relationship relationship = new Relationship();
1554                                         relationships.add(relationship);
1555                                         relationship.setRelatedTo(relatedTo);
1556                                         if(relatedLink != null) {
1557                                                 relationship.setRelatedLink(relatedLink);
1558                                 } else  {
1559                                         Map<String, String> relParams = new HashMap<>();
1560
1561                                 while(true) {
1562                                         String searchRelationshipKey = "relationship-list.relationship[" + i + "].relationship-data[" + j + "].relationship-key";
1563                                         String searchRelationshipValue = "relationship-list.relationship[" + i + "].relationship-data[" + j + "].relationship-value";
1564                                         if(!params.containsKey(searchRelationshipKey))
1565                                                 break;
1566
1567                                                 relParams.put(params.get(searchRelationshipKey), params.get(searchRelationshipValue));
1568                                         j++;
1569                                 }
1570                                         AAIRequest rlRequest = AAIRequest.createRequest(relatedTo, relParams);
1571                                         for(String key : relParams.keySet()) {
1572                                                 rlRequest.addRequestProperty(key, relParams.get(key));
1573                                         }
1574                                         String path = rlRequest.updatePathDataValues(null);
1575                                         relationship.setRelatedLink(path);
1576                                 }
1577
1578                                 i++;
1579                         }
1580                 }
1581
1582                 return QueryStatus.SUCCESS;
1583         }
1584
1585         private Relationship findRelationship(List<Relationship> relationships, String relatedTo) {
1586                 if(relatedTo == null)
1587                         return null;
1588
1589                 for(Relationship relationship : relationships) {
1590                         if(relationship.getRelatedTo().equals(relatedTo)){
1591                                 return relationship;
1592                         }
1593                 }
1594                 return null;
1595         }
1596
1597
1598         public QueryStatus backup(Map<String, String> params, SvcLogicContext ctx) throws SvcLogicException {
1599                 String resource = params.get("resource").toLowerCase();
1600                 String prefix = params.get("data-key");
1601
1602                 HashMap<String, String> nameValues = new HashMap<>();
1603                 if(AAIRequest.createRequest(resource, nameValues) != null) {
1604
1605                         try {
1606                                 return newModelBackupRequest(resource, params, prefix, ctx);
1607                         } catch (Exception exc) {
1608                                 getLogger().warn("Failed backup - returning FAILURE", exc);
1609                                 return QueryStatus.FAILURE;
1610                         }
1611                 }
1612
1613                 return QueryStatus.NOT_FOUND;
1614         }
1615
1616         @Override
1617         public QueryStatus restore(Map<String, String> params, SvcLogicContext ctx) throws SvcLogicException {
1618
1619                 QueryStatus retval = QueryStatus.SUCCESS;
1620                 String resource = params.get("resource").toLowerCase();
1621                 String prefix = params.get("data-key");
1622
1623                 HashMap<String, String> nameValues = new HashMap<>();
1624                 if(AAIRequest.createRequest(resource, nameValues) != null) {
1625
1626                         try {
1627                                 retval = newModelBackupRequest(resource, params, "tmpRestore", ctx);
1628                                 if(retval == QueryStatus.SUCCESS) {
1629                                         String current_json = ctx.getAttribute("tmpRestore");
1630                                         ctx.  setAttribute("tmpRestore", null);
1631
1632                                         String snapshot_json = ctx.getAttribute(prefix);
1633                                 }
1634                         } catch (Exception exc) {
1635                                 getLogger().warn("Failed restore - returning FAILURE", exc);
1636                                 return QueryStatus.FAILURE;
1637                         }
1638                 }
1639
1640                 return QueryStatus.NOT_FOUND;
1641         }
1642
1643         protected Map<String, Object> objectToProperties(Object object) {
1644                 ObjectMapper mapper = AAIService.getObjectMapper();
1645                 return mapper.convertValue(object, Map.class);
1646         }
1647
1648         static <T> T valueOf(Class<T> klazz, String arg) {
1649             Exception cause = null;
1650             T ret = null;
1651             try {
1652                 ret = klazz.cast(klazz.getDeclaredMethod("valueOf", String.class).invoke(null, arg));
1653             } catch (NoSuchMethodException exc) {
1654                 LoggerFactory.getLogger(AAIService.class).warn("Wrong data type", exc);
1655                 ret = klazz.cast(arg);
1656             } catch (IllegalAccessException e) {
1657                 cause = e;
1658             } catch (InvocationTargetException e) {
1659                 cause = e;
1660             }
1661             if (cause == null) {
1662                 return ret;
1663             } else {
1664                 throw new IllegalArgumentException(cause);
1665             }
1666         }
1667
1668         private QueryStatus processDeleteRelationshipList(String resource, String key, SvcLogicContext ctx, HashMap<String, String> nameValues) {
1669                 try {
1670                         AAIRequest request = AAIRequest.createRequest(resource, nameValues);
1671                         if(request == null) {
1672                                 return QueryStatus.FAILURE;
1673                         }
1674
1675                         request.processRequestPathValues(nameValues);
1676                         URL url = request.getRequestUrl("GET", null);
1677
1678                         Class resourceClass = request.getModelClass();
1679                         Object instance = getResource(url.toString(), resourceClass);
1680                         if(instance == null)
1681                                 return QueryStatus.NOT_FOUND;
1682
1683                         // get resource version
1684                         String resourceVersion = null;
1685                         Method getResourceVersionMethod = resourceClass.getMethod("getResourceVersion");
1686                         if(getResourceVersionMethod != null){
1687                                 try {
1688                                         getResourceVersionMethod.setAccessible(true);
1689                                         Object object = getResourceVersionMethod.invoke(instance);
1690                                         if(object != null)
1691                                                 resourceVersion = object.toString();
1692                                 } catch (InvocationTargetException x) {
1693                                         Throwable cause = x.getCause();
1694                                 }
1695                         }
1696
1697                         RelationshipList relationshipList = null;
1698                         Object obj = null;
1699                         Method getRelationshipListMethod = null;
1700                         try {
1701                                  getRelationshipListMethod = resourceClass.getMethod("getRelationshipList");
1702                         } catch(Exception exc) {
1703                                 getLogger().debug("Retrofiting relationship data: " + exc.getMessage());
1704                         }
1705                         if(getRelationshipListMethod != null){
1706                                 try {
1707                                         getRelationshipListMethod.setAccessible(true);
1708                                         obj = getRelationshipListMethod.invoke(instance);
1709                                 } catch (InvocationTargetException x) {
1710                                         Throwable cause = x.getCause();
1711                                 }
1712                         }
1713                         if(obj != null && obj instanceof RelationshipList){
1714                                 relationshipList = (RelationshipList)obj;
1715                         } else {
1716                                 getLogger().debug("No relationships found to process.");
1717                                 return QueryStatus.NOT_FOUND;
1718                         }
1719
1720                         if(relationshipList.getRelationship() == null || relationshipList.getRelationship().isEmpty()) {
1721                                 return QueryStatus.NOT_FOUND;
1722                         }
1723                         String relatedTo = nameValues.get("related_to");
1724                         if(relatedTo == null) {
1725                                 return QueryStatus.FAILURE;
1726                         }
1727
1728                         relatedTo = relatedTo.replaceAll("_", "-");
1729
1730                         String relatedLink = nameValues.get("relationship.related_link");
1731                         if(relatedLink != null) {
1732                                 relatedLink = URLDecoder.decode(relatedLink, "UTF-8");
1733                         }
1734
1735                         List<Relationship> relationships = relationshipList.getRelationship();
1736                         List<Relationship> relationshipsToDelete = new LinkedList<Relationship>();
1737
1738                         for(Relationship relationship : relationships) {
1739                                 if(relatedTo.equals(relationship.getRelatedTo())) {
1740                                         if(relatedLink != null) {
1741                                                 if(relationship.getRelatedLink() != null ) {
1742                                                         String localRelatedLink = relationship.getRelatedLink();
1743                                                         localRelatedLink = URLDecoder.decode(localRelatedLink, "UTF-8");
1744                                                         if(localRelatedLink.endsWith(relatedLink)) {
1745                                                                 getLogger().debug(String.format("Found relationship of '%s' to keyword '%s'", relationship.getRelatedTo(),  relatedTo));
1746                                                                 relationshipsToDelete.add(relationship);
1747                                                 }
1748                                         }
1749                                         } else {
1750                                         getLogger().debug(String.format("Found relationship of '%s' to keyword '%s'", relationship.getRelatedTo(),  relatedTo));
1751                                         relationshipsToDelete.add(relationship);
1752                                 }
1753                         }
1754                         }
1755                         if(relationshipsToDelete == null || relationshipsToDelete.isEmpty()) {
1756                                 getLogger().info(String.format("Relationship has not been found for %s", key));
1757                                 return QueryStatus.NOT_FOUND;
1758                         }
1759
1760                         String path = url.toString();
1761                         path = path + "/relationship-list/relationship";
1762                         URL deleteUrl = new URL(path);
1763
1764                         ObjectMapper mapper = AAIService.getObjectMapper();
1765
1766                         boolean cumulativeResponse = true;
1767
1768                         for(Relationship targetRelationship : relationshipsToDelete) {
1769                                 String json_text = mapper.writeValueAsString(targetRelationship);
1770                                 boolean response = deleteRelationshipList(deleteUrl, json_text);
1771                                 if(!response)
1772                                         cumulativeResponse = response;
1773
1774                         }
1775
1776                         if(!cumulativeResponse)
1777                                 return QueryStatus.FAILURE;
1778
1779                         return QueryStatus.SUCCESS;
1780
1781                 } catch(Exception exc) {
1782                         getLogger().warn("processDelete", exc);
1783                         return QueryStatus.FAILURE;
1784                 }
1785         }
1786
1787         static final Map<String, String> ctxGetBeginsWith( SvcLogicContext ctx, String prefix ) {
1788                 Map<String, String> tmpPrefixMap = new HashMap<>();
1789
1790                 if(prefix == null || prefix.isEmpty()){
1791                         return tmpPrefixMap;
1792                 }
1793
1794                 for( String key : ctx.getAttributeKeySet() ) {
1795                         if( key.startsWith(prefix) ) {
1796                                 String tmpKey = key.substring(prefix.length() + 1);
1797                                 tmpPrefixMap.put( tmpKey, ctx.getAttribute(key));
1798                         }
1799                 }
1800
1801                 Map<String, String> prefixMap = new HashMap<>();
1802                 Pattern p = Pattern.compile(".*\\[\\d\\]");
1803
1804                 SortedSet<String> keys = new TreeSet(tmpPrefixMap.keySet () );
1805                 for(String key : keys) {
1806                         Matcher m = p.matcher(key);
1807                         if(m.matches()) {
1808                                 continue;
1809                         } else if(key.endsWith("_length")) {
1810                                 String listKey = key.substring(0, key.indexOf("_length"));
1811                                 int max = Integer.parseInt(tmpPrefixMap.get(key));
1812
1813                                 ArrayList<String> data = new ArrayList<>();
1814                                 for(int x = 0; x < max; x++){
1815                                         String tmpKey = String.format("%s[%d]", listKey, x);
1816                                         String tmpValue = tmpPrefixMap.get(tmpKey);
1817                                         if(tmpValue != null && !tmpValue.isEmpty()) {
1818                                                 data.add(tmpValue);
1819                                         }
1820                                 }
1821                                 if(!data.isEmpty()) {
1822                                         prefixMap.put(listKey, data.toString());
1823                                 } else {
1824                                         prefixMap.put(key, tmpPrefixMap.get(key));
1825                                 }
1826                         } else {
1827                                 prefixMap.put(key, tmpPrefixMap.get(key));
1828                         }
1829                 }
1830
1831                 return prefixMap;
1832         }
1833
1834         /**
1835         */
1836         protected NamedQueryData extractNamedQueryDataFromQueryPrefix(HashMap<String, String> nameValues, Map<String, String> parms) {
1837                 if(parms.isEmpty()) {
1838                         return null;
1839                 }
1840
1841                 NamedQueryData data = new NamedQueryData();
1842
1843                 // query parameters
1844                 if(data.getQueryParameters() == null) {
1845                         data.setQueryParameters(new QueryParameters());
1846                 }
1847                 String namedQueryUuid = nameValues.get("named-query-uuid".replaceAll("-", "_"));
1848                 if(namedQueryUuid == null) {
1849                         namedQueryUuid = parms.get("query-parameters.named-query.named-query-uuid");
1850                 }
1851                 NamedQuery namedQuery = new NamedQuery();
1852                 namedQuery.setNamedQueryUuid(namedQueryUuid);
1853                 data.getQueryParameters().setNamedQuery(namedQuery);
1854
1855                 // instance filters
1856                 if(data.getInstanceFilters() == null) {
1857                         data.setInstanceFilters(new InstanceFilters());
1858                 }
1859
1860
1861                 String quantity = parms.get("instance-filters.instance-filter_length");
1862                 if(quantity != null && StringUtils.isNumeric(quantity)) {
1863                         int max = Integer.parseInt(quantity);
1864                         for(int i = 0; i < max; i++) {
1865                                 String keyPattern = String.format("instance-filters.instance-filter[%d].", i);
1866                                 Set<String> keys = parms.keySet();
1867                                 for(String key: keys) {
1868                                         if(key.startsWith(keyPattern)){
1869                                                 String value = parms.get(key);
1870                                                 String remainder = key.substring(keyPattern.length());
1871                                                 String[] split = remainder.split("\\.");
1872                                                 getLogger().debug(String.format("%s", remainder));
1873                                                 if("logical-link".equals(split[0])) {
1874                                                         InstanceFilter insf = null;
1875                                                         if(data.getInstanceFilters().getInstanceFilter().isEmpty()) {
1876                                                                 insf = new InstanceFilter();
1877                                                                 data.getInstanceFilters().getInstanceFilter().add(insf);
1878                                                         } else {
1879                                                                 insf = data.getInstanceFilters().getInstanceFilter().get(0);
1880                                                         }
1881                                                         LogicalLink logicalLink = insf.getLogicalLink();
1882                                                         if(logicalLink == null) {
1883                                                                 logicalLink = new LogicalLink();
1884                                                                 insf.setLogicalLink(logicalLink);
1885                                                         }
1886
1887                                                         switch(split[1]) {
1888                                                         case "link-name":
1889                                                                 logicalLink.setLinkName(value);
1890                                                                 break;
1891                                                         case "link-type":
1892                                                                 logicalLink.setLinkType(value);
1893                                                                 break;
1894                                                         case "operational-state":
1895                                                                 logicalLink.setOperationalStatus(value);
1896                                                                 break;
1897                                                         }
1898
1899                                                 } else if("pnf".equals(split[0])) {
1900                                                         Pnf pnf = new Pnf();
1901                                                         pnf.setPnfName(value);
1902
1903                                                         InstanceFilter insf = new InstanceFilter();
1904                                                         insf.setPnf(pnf);
1905                                                         data.getInstanceFilters().getInstanceFilter().add(insf);
1906
1907                                                 } else if("service-instance".equals(split[0])) {
1908                                                         ServiceInstance serviceInstance = new ServiceInstance();
1909                                                         serviceInstance.setServiceInstanceId(value);
1910
1911                                                         InstanceFilter insf = new InstanceFilter();
1912                                                         insf.setServiceInstance(serviceInstance);
1913                                                         data.getInstanceFilters().getInstanceFilter().add(insf);
1914
1915                                                 } else if("l3-network".equals(split[0])) {
1916                                                         L3Network l3Network = new L3Network();
1917                                                         if("network-role".equals(split[1])) {
1918                                                                 l3Network.setNetworkRole(value);
1919                                                         }
1920
1921                                                         InstanceFilter insf = new InstanceFilter();
1922                                                         insf.setL3Network(l3Network);
1923                                                         data.getInstanceFilters().getInstanceFilter().add(insf);
1924                                                 }
1925                                         }
1926                                 }
1927                         }
1928                 }
1929
1930                 return data;
1931         }
1932
1933         public abstract <T> T getResource(String key, Class<T> type) throws AAIServiceException ;
1934         protected abstract boolean deleteRelationshipList(URL url, String caller) throws AAIServiceException;
1935 }