[SDNC-30] summary
[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 ONAP Intellectual Property. All rights
6  *                                              reserved.
7  * ================================================================================
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  * 
12  *      http://www.apache.org/licenses/LICENSE-2.0
13  * 
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  * ============LICENSE_END=========================================================
20  */
21
22 package org.onap.ccsdk.sli.adaptors.aai;
23
24 import java.io.IOException;
25 import java.io.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 = null;
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<String,Object>();
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", "" + exc.getReturnCode());
249                                                         }
250                                                         return QueryStatus.FAILURE;
251                                                 }
252                                         } else {
253                                                 getLogger().warn("No arguments are available to process generic VNF");
254                                                 return QueryStatus.FAILURE;
255                                         }
256                                         break;
257                                 case "vserver":
258                                 case "vserver2":
259                                         String vserverName = null;
260                                         if(nameValues.containsKey("vserver_name"))
261                                                 vserverName = nameValues.get("vserver_name");
262                                         else if(nameValues.containsKey("vserver.vserver_name"))
263                                                 vserverName = nameValues.get("vserver.vserver_name");
264
265                                         String vserverId = null;
266                                         if(nameValues.containsKey("vserver_id"))
267                                                 vserverId = nameValues.get("vserver_id");
268                                         if(nameValues.containsKey("vserver.vserver_id"))
269                                                 vserverId = nameValues.get("vserver.vserver_id");
270                                         String tenantId = nameValues.get("teannt_id");
271
272                                         if(vserverName != null) vserverName = vserverName.trim().replace("'", "").replace("$", "").replace("'", "");
273                                         if(vserverId != null) vserverId = vserverId.trim().replace("'", "").replace("$", "").replace("'", "");
274                                         if(tenantId != null) tenantId = tenantId.trim().replace("'", "").replace("$", "").replace("'", "");
275
276                                 if (vserverName != null) {
277                                         URL vserverUrl = null;
278                                         try {
279                                                 vserverUrl = this.requestVserverURLNodeQuery(vserverName);
280                                         } catch (AAIServiceException aaiexc) {
281                                                 ctx.setAttribute(prefix + ".error.message", aaiexc.getMessage());
282                                                 if (aaiexc.getReturnCode() >= 300) {
283                                                         ctx.setAttribute(prefix + ".error.http.response-code", "" + aaiexc.getReturnCode());
284                                                 }
285
286                                                 if (aaiexc.getReturnCode() == 404)
287                                                         return QueryStatus.NOT_FOUND;
288                                                 else
289                                                         return QueryStatus.FAILURE;
290                                         }
291                                         if (vserverUrl == null) {
292                                                 return QueryStatus.NOT_FOUND;
293                                         }
294
295                                         tenantId = getTenantIdFromVserverUrl(vserverUrl);
296                                                         String cloudOwner = getCloudOwnerFromVserverUrl(vserverUrl);
297                                                         String cloudRegionId = getCloudRegionFromVserverUrl(vserverUrl);
298
299                                         Vserver vserver = null;
300                                         try {
301                                                 vserver = this.requestVServerDataByURL(vserverUrl);
302                                         } catch (AAIServiceException aaiexc) {
303                                                 ctx.setAttribute(prefix + ".error.message", aaiexc.getMessage());
304                                                 if (aaiexc.getReturnCode() >= 300) {
305                                                         ctx.setAttribute(prefix + ".error.http.response-code", "" + aaiexc.getReturnCode());
306                                                 }
307
308                                                 if (aaiexc.getReturnCode() == 404)
309                                                         return QueryStatus.NOT_FOUND;
310                                                 else
311                                                         return QueryStatus.FAILURE;
312                                         }
313                                         if (vserver == null) {
314                                                 return QueryStatus.NOT_FOUND;
315                                         }
316                                         attributes = mapper.convertValue(vserver, attributes.getClass());
317                                         if (!attributes.containsKey("tenant-id") && tenantId != null) {
318                                                 attributes.put("tenant-id", tenantId);
319                                         }
320                                         if (!attributes.containsKey("cloud-owner") && cloudOwner != null) {
321                                                 attributes.put("cloud-owner", cloudOwner);
322                                         }
323                                         if (!attributes.containsKey("cloud-region-id") && cloudRegionId != null) {
324                                                 attributes.put("cloud-region-id", cloudRegionId);
325                                         }
326                                 } else if (vserverId != null && tenantId != null) {
327                                                 Vserver vserver = this.requestVServerData(tenantId, vserverId, "att-aic", "AAIAIC25");
328                                                 if(vserver == null) {
329                                                         return QueryStatus.NOT_FOUND;
330                                                 }
331                                                 attributes = mapper.convertValue(vserver, attributes.getClass());
332                                                 if(!attributes.containsKey("tenant-id") && tenantId != null){
333                                                         attributes.put("tenant-id", tenantId);
334                                                 }
335                                         } else {
336                                                 return QueryStatus.FAILURE;
337                                         }
338                                         break;
339
340                                 default:
341                                         return QueryStatus.FAILURE;
342                         }
343
344                         QueryStatus retval = QueryStatus.SUCCESS;
345
346                         if (attributes == null || attributes.isEmpty()) {
347                                 retval = QueryStatus.NOT_FOUND;
348                                 getLogger().debug("No data found");
349                         } else {
350                                 if (ctx != null) {
351                                         if (prefix != null) {
352                                                 ArrayList<String> keys = new ArrayList<String>(attributes.keySet());
353
354                                                 int numCols = keys.size();
355
356                                                 for (int i = 0; i < numCols; i++) {
357                                                         String colValue = null;
358                                                         String colName = keys.get(i);
359                                                         Object object = attributes.get(colName);
360
361                                                         if(object != null && object instanceof String) {
362                                                                 colValue = (String)object;
363
364                                                                 if (prefix != null) {
365                                                                         getLogger().debug("Setting "+prefix     + "." + colName.replaceAll("_", "-")+" = "+ colValue);
366                                                                         ctx.setAttribute(prefix + "." + colName.replaceAll("_", "-"), colValue);
367                                                                 } else {
368                                                                         getLogger().debug("Setting " + colValue.replaceAll("_", "-")+" = "+colValue);
369                                                                         ctx.setAttribute(colValue.replaceAll("_", "-"), colValue);
370                                                                 }
371                                                         } else if(object != null && object instanceof Map) {
372                                                                 if(colName.equals(modifier) || colName.equals("relationship-list")){
373                                                                         String localNodifier = modifier;
374                                                                         if(localNodifier == null)
375                                                                                 localNodifier = "relationship-list";
376                                                                         Map<String, Object> properties = (Map<String, Object>)object;
377                                                                         writeMap(properties, prefix+"."+localNodifier,  ctx);
378                                                                 }
379                                                         }
380                                                 }
381                                         }
382                                 }
383                         }
384                         getLogger().debug("Query - returning " + retval);
385                         return (retval);
386
387                 } catch (Exception exc) {
388                         getLogger().warn("Failed query - returning FAILURE", exc);
389                         return QueryStatus.FAILURE;
390                 }
391
392 //              return QueryStatus.SUCCESS;
393         }
394
395
396         public void writeMap(Map<String, Object> properties, String prefix, SvcLogicContext ctx) {
397                 Set<String> mapKeys = properties.keySet();
398
399                 for(String mapKey : mapKeys) {
400                         Object entity = properties.get(mapKey);
401                         if(entity instanceof ArrayList) {
402                                 writeList((ArrayList<?>)entity, prefix + "." + mapKey, ctx);
403                         } else
404                         if(entity instanceof String ||  entity instanceof Long || entity instanceof Integer || entity instanceof Boolean) {
405                                 ctx.setAttribute(prefix + "." + mapKey, entity.toString());
406                                 getLogger().debug(prefix + "." + mapKey + " : " + entity.toString());
407                         } else if(entity instanceof Map) {
408                                 String localPrefix = prefix;
409                                 if(mapKey != null) {
410                                         localPrefix = String.format("%s.%s", prefix, mapKey);
411                                 }
412                                 writeMap( (Map<String, Object>)entity,  localPrefix,  ctx);
413                         }
414                 }
415         }
416
417         private void writeList(ArrayList<?> list, String prefix, SvcLogicContext ctx) {
418                 for(int i = 0; i < list.size(); i++ ) {
419                         Object entity = list.get(i);
420                         if(entity instanceof Map) {
421                                 writeMap( (Map<String, Object>)entity,  prefix + "[" + i + "]",  ctx);
422                         } else
423                                 if(entity instanceof String ||  entity instanceof Long || entity instanceof Integer || entity instanceof Boolean) {
424                                 ctx.setAttribute(prefix, entity.toString());
425                                 getLogger().debug(prefix  + " : " + entity.toString());
426                         }
427                 }
428
429                 if(list.size() > 0) {
430                         ctx.setAttribute(prefix + "_length", Integer.toString(list.size()));
431                         getLogger().debug(prefix + "_length"  + " : " + Integer.toString(list.size()));
432                 }
433         }
434
435         @Override
436         public QueryStatus save(String resource, boolean force, boolean localOnly, String key, Map<String, String> params, String prefix, SvcLogicContext ctx)
437                         throws SvcLogicException {
438
439                 getLogger().debug("AAIService.save\tresource="+resource);
440                 HashMap<String, String> nameValues = AAIServiceUtils.keyToHashMap(key, ctx);
441
442                 if(!AAIServiceUtils.isValidFormat(resource, nameValues)) {
443                         ctx.setAttribute(String.format("%s.error.message", prefix), String.format("Resource %s is not supported. Key string contains invaid identifiers", resource));
444                         return QueryStatus.FAILURE;
445                 }
446
447                 if(resource == null || resource.isEmpty() || AAIRequest.createRequest(resource, nameValues) == null) {
448                         getLogger().warn("AAIService.save has unspecified resource");
449                         ctx.setAttribute(String.format("%s.error.message", prefix), String.format("Resource %s is not supported", resource));
450                         return QueryStatus.FAILURE;
451                 }
452                 // keys passed
453                 getLogger().debug("key = "+ Arrays.toString(nameValues.entrySet().toArray()));
454
455                 // process params
456                 if(params.containsKey("prefix")) {
457                         Map<String, String> tmpParams = ctxGetBeginsWith(ctx, params.get("prefix"));
458                         if(!tmpParams.isEmpty()) {
459                                 params.putAll(tmpParams);
460 //                              params.remove("prefix");
461                         }
462                 }
463                 // params passed
464                 getLogger().debug("parms = "+ Arrays.toString(params.entrySet().toArray()));
465
466                 boolean useNewModelProcessing = true;
467                 // process server query by name the old way
468                 if(("vserver".equals(resource) || "vserver2".equals(resource))){
469                         if(nameValues.containsKey("vserver-name")) {
470                                 useNewModelProcessing = false;
471                         }
472
473                         if(!params.containsKey("vserver-selflink")) {
474
475                                 AAIRequest request = AAIRequest.createRequest(resource, nameValues);
476                                 URL path = null;
477                                 try {
478                                         request.processRequestPathValues(nameValues);
479                                         path = request.getRequestUrl("GET", null);
480                                         params.put("vserver-selflink", path.toString());
481                                 } catch (UnsupportedEncodingException | MalformedURLException e) {
482                                         // TODO : Fix this
483                                         params.put("vserver-selflink", "/vserver");
484                                 }
485                         }
486                 }
487
488                 // process data using new model
489                 if(useNewModelProcessing && AAIRequest.createRequest(resource, nameValues) != null) {
490
491                         try {
492                                 if(!resource.contains(":")){
493                                         return newModelSave(resource, force, key, params, prefix, ctx);
494                                 } else {
495                                         String[] tokens = resource.split(":");
496                                         String localResource = tokens[0];
497                                         String dependency = tokens[1];
498
499                                         AAIDatum instance = newModelObjectRequest( localResource, nameValues, prefix, ctx);
500                                         if(instance == null) {
501                                                 return QueryStatus.NOT_FOUND;
502                                         }
503
504                                         switch(dependency){
505                                         case "relationship-list":
506                                                 newModelProcessRelationshipList(instance, params, prefix, ctx);
507                                                 break;
508                                         }
509                                         // create a method to update relationship-list
510                                         AAIRequest request = AAIRequest.createRequest(localResource, nameValues);
511                                         request.setRequestObject(instance);
512                                         request.processRequestPathValues(nameValues);
513
514                                         getExecutor().post(request);
515                                                 getLogger().debug("Save relationship list - returning SUCCESS");
516                                                 return QueryStatus.SUCCESS;
517                                 }
518                         } catch (Exception exc) {
519                                 ctx.setAttribute(prefix + ".error.message", exc.getMessage());
520                                 if(exc instanceof AAIServiceException) {
521                                         AAIServiceException aaiexc = (AAIServiceException)exc;
522                                         if(aaiexc.getReturnCode() >= 300) {
523                                                 ctx.setAttribute(prefix + ".error.http.response-code", "" + aaiexc.getReturnCode());
524                                         }
525
526                                         if(aaiexc.getReturnCode() == 404) {
527                                                 return QueryStatus.NOT_FOUND;
528                                         }
529                                 }
530                                 getLogger().warn("Failed save() - returning FAILURE", exc);
531                                 return QueryStatus.FAILURE;
532                         }
533                 } else {
534                         String reSource = resource.toLowerCase().replace("-", "_");
535                                 String vnfId = null;
536
537                         try {
538                                 switch(reSource) {
539                                         case "generic_vnf":
540                                         case "generic-vnf":
541                                                 vnfId = nameValues.get("vnf_id");
542                                                 if(vnfId == null) {
543                                                         getLogger().debug("Save(generic-vnf) with no vnf-id specified. Returning FAILURE");
544                                                         return QueryStatus.FAILURE;
545                                                 }
546                                                 vnfId = vnfId.trim().replace("'", "").replace("$", "").replace("'", "");
547                                                 GenericVnf vnf = this.requestGenericVnfData(vnfId);
548                                                 String status = params.get("prov-status");
549                                                 boolean updated = false;
550                                                 if(status != null && !status.isEmpty()) {
551                                                         vnf.setProvStatus(status);
552                                                 }
553                                                 if(updated) {
554                                                         this.postGenericVnfData(vnfId, vnf);
555                                                 }
556                                                 break;
557                                         case "vpe":
558                                                 return update( resource,  key, params, prefix, ctx) ;
559
560                                         default:
561                                                 getLogger().debug("Save() executing default path - returning FAILURE");
562                                                 return QueryStatus.FAILURE;
563                                 }
564                         } catch (Exception exc) {
565                                 getLogger().warn("Failed save - returning FAILURE", exc);
566                                 ctx.setAttribute(prefix + ".error.message", exc.getMessage());
567                                 return QueryStatus.FAILURE;
568                         }
569                 }
570
571                 getLogger().debug("Save - returning SUCCESS");
572                 return QueryStatus.SUCCESS;
573         }
574
575         @Override
576         public QueryStatus update(String resource, String key, Map<String, String> params, String prefix, SvcLogicContext ctx) throws SvcLogicException {
577
578                 resource = resource.toLowerCase();
579                 HashMap<String, String> nameValues = AAIServiceUtils.keyToHashMap(key, ctx);
580                 getLogger().debug("key = "+ Arrays.toString(nameValues.entrySet().toArray()));
581                 if(!AAIServiceUtils.isValidFormat(resource, nameValues)) {
582                         ctx.setAttribute(String.format("%s.error.message", prefix), String.format("Resource %s is not supported. Key string contains invaid identifiers", resource));
583                         return QueryStatus.FAILURE;
584                 }
585
586                 if(resource == null || resource.isEmpty() || AAIRequest.createRequest(resource, nameValues) == null) {
587                         ctx.setAttribute(String.format("%s.error.message", prefix), String.format("Resource %s is not supported", resource));
588                         return QueryStatus.FAILURE;
589                 }
590
591                 getLogger().debug("parms = "+ Arrays.toString(params.entrySet().toArray()));
592
593                 AAIRequest request = AAIRequest.createRequest(resource, nameValues);
594                 request = new UpdateRequest(request, params);
595
596                 String[] arguments = request.getArgsList();
597                 for(String name : arguments) {
598                         String modifiedKey = name.replaceAll("-", "_");
599                         if(nameValues.containsKey(modifiedKey)) {
600                                 String argValue = nameValues.get(modifiedKey);
601                                 if(argValue != null) argValue = argValue.trim().replace("'", "").replace("$", "").replace("'", "");
602                                 request.addRequestProperty(name, argValue);
603                         }
604                 }
605
606                 try {
607                         QueryStatus retval = QueryStatus.SUCCESS;
608
609                         retval = newModelQuery(resource, false, null, key, "tmpDelete", null,  ctx);
610
611                         if(retval == null || retval != QueryStatus.SUCCESS) {
612                                 return retval;
613                         }
614
615                         String resourceVersion = ctx.getAttribute("tmpDelete.resource-version");
616                         if(resourceVersion == null) {
617                                 return QueryStatus.NOT_FOUND;
618                         }
619                         params.put("resource-version", resourceVersion);
620
621                         request.processRequestPathValues(nameValues);
622                         getExecutor().patch(request, resourceVersion);
623                 } catch(AAIServiceException aaiexc) {
624                         if(aaiexc.getReturnCode() == 404)
625                                 return QueryStatus.NOT_FOUND;
626                         else
627                                 return QueryStatus.FAILURE;
628                 } catch (Exception exc) {
629                         getLogger().warn("Failed update - returning FAILURE", exc);
630                         return QueryStatus.FAILURE;
631                 }
632
633                 getLogger().debug("Update - returning SUCCESS");
634                 return QueryStatus.SUCCESS;
635         }
636
637         @Override
638         public QueryStatus delete(String resource, String key, SvcLogicContext ctx) throws SvcLogicException {
639                 getLogger().debug("AAIService.delete\tresource="+resource);
640                 HashMap<String, String> nameValues = AAIServiceUtils.keyToHashMap(key, ctx);
641                 getLogger().debug("key = "+ Arrays.toString(nameValues.entrySet().toArray()));
642
643                 if(!AAIServiceUtils.isValidFormat(resource, nameValues)) {
644                         ctx.setAttribute(String.format("%s.error.message", "aaiData"), String.format("Resource %s is not supported. Key string contains invaid identifiers", resource));
645                         return QueryStatus.FAILURE;
646                 }
647
648                 if(resource == null || resource.isEmpty() || AAIRequest.createRequest(resource, nameValues) == null) {
649                         ctx.setAttribute(String.format("%s.error.message", "tmpDelete"), String.format("Resource %s is not supported", resource));
650                         return QueryStatus.FAILURE;
651                 }
652
653                 if(AAIRequest.createRequest(resource, nameValues) != null) {
654                         if(resource.contains(":")) {
655                                 return processDeleteRelationshipList(resource, key, ctx, nameValues);
656                         }
657
658
659                         try {
660                                 QueryStatus retval = QueryStatus.SUCCESS;
661
662                                 retval = newModelQuery(resource, false, null, key, "tmpDelete", null,  ctx);
663
664                                 if(retval == null || retval != QueryStatus.SUCCESS) {
665                                         return retval;
666                                 }
667
668                                 String resourceVersion = ctx.getAttribute("tmpDelete.resource-version");
669                                 if(resourceVersion == null) {
670                                         return QueryStatus.NOT_FOUND;
671                                 }
672
673                                 try {
674                                         AAIRequest request = AAIRequest.createRequest(resource, nameValues);
675                                         if(request == null) {
676                                                 return QueryStatus.FAILURE;
677                                         }
678
679                                         request.processRequestPathValues(nameValues);
680
681                                         if(getExecutor().delete(request, resourceVersion)) {
682                                                 return QueryStatus.SUCCESS;
683                                         }
684                                 } catch(AAIServiceException aaiexc) {
685                                         if(aaiexc.getReturnCode() == 404)
686                                                 return QueryStatus.NOT_FOUND;
687                                         else
688                                                 return QueryStatus.FAILURE;
689
690                                 } catch (Exception exc) {
691                                         getLogger().warn("requestGenericVnfData", exc);
692                                         return QueryStatus.FAILURE;
693                                 }
694
695                         } catch (Exception exc) {
696                                 getLogger().warn("Failed delete - returning FAILURE", exc);
697                                 return QueryStatus.FAILURE;
698                         }
699                 } else {
700                         String resoourceName = resource;
701                         String identifier = null;
702
703                         if(resoourceName == null)
704                                 return QueryStatus.FAILURE;
705
706                         if(resoourceName.contains(":")) {
707                                 String[] tokens = resoourceName.split(":");
708                                 if(tokens != null && tokens.length > 0) {
709                                         resoourceName = tokens[0];
710                                         identifier = tokens[1];
711                                 }
712                         }
713                         if("relationship-list".equals(identifier) || "relationshipList".equals(identifier)) {
714 //                              RelationshipRequest relationshipRequest = new RelationshipRequest();
715                                 if("generic-vnf".equals(resoourceName)){
716                                         String vnfId = nameValues.get("vnf_id");
717                                         String relatedTo  = nameValues.get("related_to");
718                                         vnfId = vnfId.trim().replace("'", "").replace("$", "").replace("'", "");
719                                         relatedTo = relatedTo.trim().replace("'", "").replace("$", "").replace("'", "");
720
721                                         GenericVnf vnf;
722                                         try {
723                                                 vnf = this.requestGenericVnfData(vnfId);
724                                                 if(vnf == null)
725                                                         return QueryStatus.NOT_FOUND;
726                                         } catch (AAIServiceException exc) {
727                                                 getLogger().warn("Failed delete - returning NOT_FOUND", exc);
728                                                 return QueryStatus.NOT_FOUND;
729                                         }
730                                         boolean itemRemoved = false;
731                                         RelationshipList relationshipList = vnf.getRelationshipList();
732                                         List<Relationship> relationships = relationshipList.getRelationship();
733                                         List<Relationship> iterableList = new LinkedList<Relationship>(relationships);
734                                         for(Relationship relationship : iterableList) {
735                                                 if(relationship.getRelatedTo().equals(relatedTo)) {
736                                                         relationships.remove(relationship);
737                                                         itemRemoved = true;
738                                                 }
739                                         }
740
741                                         if(!itemRemoved)
742                                                 return QueryStatus.NOT_FOUND;
743
744 //                                      AAIRequest masterRequest = new GenericVnfRequest();
745 //                                      masterRequest.addRequestProperty(GenericVnfRequest.VNF_ID, vnfId);
746 //                                      relationshipRequest.addMasterRequest(masterRequest);
747 //                                      Map<String, String> attributes = objectToProperties(vnf);
748 //                                      try {
749 //                                              Boolean result = getExecutor().delete(relationshipRequest, attributes.get(AAIRequest.RESOURCE_VERSION));
750 //                                      } catch (AAIServiceException e) {
751 //                                              return QueryStatus.FAILURE;
752 //                                      }
753
754                                         try {
755                                                 this.postGenericVnfData(vnf.getVnfId(), vnf);
756                                         } catch (AAIServiceException exc) {
757                                                 if(exc.getReturnCode() == 404){
758                                                         return QueryStatus.NOT_FOUND;
759                                                 } else {
760                                                         getLogger().warn("Failed delete - returning FAILURE", exc);
761                                                         return QueryStatus.FAILURE;
762                                                 }
763                                         }
764                                         return QueryStatus.SUCCESS;
765                                 }
766                         }
767                 }
768                 return QueryStatus.FAILURE;
769         }
770
771         @Override
772         public QueryStatus exists(String resource, String key, String prefix, SvcLogicContext ctx) throws SvcLogicException {
773                 return query(resource, false, null, key, prefix, null, ctx);
774         }
775
776         @Override
777         public QueryStatus isAvailable(String arg0, String arg1, String arg2, SvcLogicContext arg3)
778                         throws SvcLogicException {
779                 // TODO Auto-generated method stub
780                 throw new SvcLogicException("Method AAIService.isAvailable() has not been implemented yet");
781         }
782
783         @Override
784         public QueryStatus notify(String resource, String action, String key, SvcLogicContext ctx) throws SvcLogicException {
785                 // TODO Auto-generated method stub
786                 throw new SvcLogicException("Method AAIService.notify() has not been implemented yet");
787         }
788
789 //      @Override
790         public QueryStatus newModelQuery(String resource, boolean localOnly, String select, String key, String prefix, String orderBy, SvcLogicContext ctx) {
791
792                 Object response = null;
793                 QueryStatus retval = QueryStatus.SUCCESS;
794                 String modifier = null;
795
796                 HashMap<String, String> nameValues = AAIServiceUtils.keyToHashMap(key, ctx);
797                 if(resource.contains(":")) {
798                         modifier = resource.split(":")[1];
799                 }
800
801                 try {
802                         AAIRequest request = AAIRequest.createRequest(resource, nameValues);
803                         if(request == null) {
804                                 return QueryStatus.FAILURE;
805                         }
806
807                         Map<String, String> params = new HashMap<String, String>();
808
809                         request.processRequestPathValues(nameValues);
810                         if(nameValues.containsKey("prefix")){
811                                 Map<String, String> tmpParams = ctxGetBeginsWith(ctx, nameValues.get("prefix"));
812                                 if(!tmpParams.isEmpty()) {
813                                         params.putAll(tmpParams);
814                                 }
815                                 if("named-query".equals(resource))
816                                         request.setRequestObject(extractNamedQueryDataFromQueryPrefix(nameValues, params));
817                         }
818                         String rv = getExecutor().get(request);
819
820                         retval = processResponseData(rv, resource, request, prefix,  ctx, nameValues, modifier);
821
822                 } catch(AAIServiceException aaiexc) {
823                         int errorCode = aaiexc.getReturnCode();
824                         ctx.setAttribute(prefix + ".error.message", aaiexc.getMessage());
825                         if(errorCode >= 300) {
826                                 ctx.setAttribute(prefix + ".error.http.response-code", "" + aaiexc.getReturnCode());
827                         }
828
829                         if(aaiexc.getReturnCode() == 404)
830                                 return QueryStatus.NOT_FOUND;
831
832                         return QueryStatus.FAILURE;
833                 } catch (Exception exc) {
834                         getLogger().warn("requestGenericVnfData", exc);
835                         ctx.setAttribute(prefix + ".error.message", exc.getMessage());
836                         return QueryStatus.FAILURE;
837                 }
838
839                 return retval;
840         }
841
842         public QueryStatus processResponseData(String rv, String resource, AAIRequest request, String prefix,  SvcLogicContext ctx, HashMap<String, String> nameValues, String modifier) throws JsonParseException, JsonMappingException, IOException, AAIServiceException
843         {
844                 Object response = null;
845
846                         if(rv == null) {
847                                 return QueryStatus.NOT_FOUND;
848                         }
849
850                         response = request.jsonStringToObject(rv);
851                         if(response == null) {
852                                 return QueryStatus.NOT_FOUND;
853                         }
854
855                         if("generic-query".equals(resource)) {
856                                 SearchResults rd = SearchResults.class.cast(response);
857                                 List<ResultData> rdList = rd.getResultData();
858                                 if(rdList == null || rdList.isEmpty()) {
859                                         return QueryStatus.NOT_FOUND;
860                                 }
861                                 ResultData rDatum = rdList.get(0);
862                                 nameValues.put("selflink", rDatum.getResourceLink());
863                                 AAIRequest req2 = AAIRequest.createRequest(rDatum.getResourceType(), nameValues);
864                                 req2.processRequestPathValues(nameValues);
865                                 rv = getExecutor().get(req2);
866                                 if(rv == null) {
867                                         return QueryStatus.NOT_FOUND;
868                                 }
869
870                                 response = req2.jsonStringToObject(rv);
871                                 if(response == null) {
872                                         return QueryStatus.NOT_FOUND;
873                                 }
874                         }
875
876                         if("named-query".equals(resource)) {
877                                 InventoryResponseItems rd = InventoryResponseItems.class.cast(response);
878                                 List<InventoryResponseItem> iRIlist = rd.getInventoryResponseItem();
879                                 if(iRIlist == null || iRIlist.isEmpty()) {
880                                         return QueryStatus.NOT_FOUND;
881                                 }
882                         }
883
884                         if("nodes-query".equals(resource)) {
885                                 SearchResults rd = SearchResults.class.cast(response);
886                                 List<ResultData> rdList = rd.getResultData();
887                                 if(rdList == null || rdList.isEmpty()) {
888                                         return QueryStatus.NOT_FOUND;
889                                 }
890                                 ResultData rDatum = rdList.get(0);
891                                 response = rDatum;
892                         }
893
894                 if("formatted-query".equals(resource) || "custom-query".equals(resource)) {
895                         FormattedQueryResultList rd = FormattedQueryResultList.class.cast(response);
896                         List<Results> iRIlist = rd.getResults();
897                         if(iRIlist == null || iRIlist.isEmpty()) {
898                                 return QueryStatus.NOT_FOUND;
899                         }
900                 }
901
902                 // process relationship list
903                 // this is a temporary soluton to address the realationship handling changes added in Release 17.07
904                 try {
905                         Class<?> clazz = response.getClass();
906                         Method getter = clazz.getMethod("getRelationshipList");
907                         Object obj = getter.invoke(response);
908                         if(obj != null && obj instanceof RelationshipList) {
909                                 RelationshipList list = RelationshipList.class.cast(obj);
910                                 AAIServiceUtils.populateRelationshipDataFromPath(list);
911                         }
912                 } catch(Exception exc) {
913                         getLogger().debug("Retrofiting relationship data: " + exc.getMessage());
914                 }
915
916                         String preFix = null;
917                         if(prefix == null || prefix.isEmpty()) {
918                                 preFix = "";
919                         } else {
920                                 preFix = prefix + ".";
921                         }
922
923                     Map<String,Object> props = objectToProperties(response);
924                     Set<String> keys = props.keySet();
925                     for(String theKey: keys) {
926                         if(getLogger().isTraceEnabled())
927                                 getLogger().trace(theKey);
928
929                         Object value = props.get(theKey);
930                         if(value == null)
931                                 continue;
932                         Object type = value.getClass();
933                         if(value instanceof String) {
934                                 ctx.setAttribute(preFix + theKey, value.toString());
935                                 continue;
936                         }
937                         if(value instanceof Boolean) {
938                                 ctx.setAttribute(preFix + theKey, value.toString());
939                                 continue;
940                         }
941                         if(value instanceof Integer) {
942                                 ctx.setAttribute(preFix + theKey, value.toString());
943                                 continue;
944                         }
945                         if(value instanceof Long) {
946                                 ctx.setAttribute(preFix + theKey, value.toString());
947                                 continue;
948                         }
949
950                         if(value instanceof ArrayList) {
951                                 ArrayList<?> array = ArrayList.class.cast(value);
952                                 for(int i = 0; i < array.size(); i++) {
953                                         writeList(array, String.format("%s.%s", prefix, theKey), ctx);
954                                 }
955                                 continue;
956                         }
957
958                         if("relationship-list".equals(theKey)){
959                                 Map<String, Object> relationshipList = (Map<String, Object>)value;
960                                 // we are interested in seeing just the selected relationship
961                                 if(theKey.equals(modifier)) {
962                                         List<?> relationships = (List<?>)relationshipList.get("relationship");
963                                         if(relationships != null && !relationships.isEmpty()) {
964
965                                                 List newRelationships = new LinkedList();
966                                                 newRelationships.addAll(relationships);
967
968                                                 for(Object obj : newRelationships){
969                                                         if(obj instanceof Map<?, ?>) {
970                                                                 Map<?, ?> relProperties = (Map<?, ?>)obj;
971                                                                 if(relProperties.containsKey("related-to")) {
972                                                                         Object relPropsRelatedTo = relProperties.get("related-to");
973
974                                                                         String relatedTo = nameValues.get("related_to");
975                                                                         if(relatedTo != null) {
976                                                                                 relatedTo = relatedTo.trim().replace("'", "").replace("$", "").replace("'", "");
977                                                                                 if(!relatedTo.equals(relPropsRelatedTo)) {
978                                                                                         relationships.remove(relProperties);
979                                                                                 }
980                                                                                 continue;
981                                                                         } else {
982                                                                                 continue;
983                                                                         }
984                                                                 }
985                                                         }
986                                                 }
987                                         }
988                                 }
989                                 writeMap(relationshipList, String.format("%s.%s", prefix, theKey), ctx);
990                                 continue;
991                         }
992
993                         if(value instanceof Map) {
994                                 Map<String, Object> subnetsList = (Map<String, Object>)value;
995                                 writeMap(subnetsList, String.format("%s.%s", prefix, theKey), ctx);
996                                 continue;
997                         }
998
999                     }
1000             return QueryStatus.SUCCESS;
1001         }
1002
1003
1004         public QueryStatus newModelBackupRequest(String resource,  Map<String, String> params,  String prefix,  SvcLogicContext ctx) {
1005
1006                 QueryStatus retval = QueryStatus.SUCCESS;
1007                 HashMap<String, String> nameValues = new HashMap<String, String>();
1008
1009                 try {
1010                         AAIRequest request = AAIRequest.createRequest(resource, nameValues);
1011                         if(request == null) {
1012                                 return QueryStatus.FAILURE;
1013                         }
1014
1015                         boolean argsFound = false;
1016                         String[] arguments = request.getArgsList();
1017                         for(String name : arguments) {
1018                                 String tmpName = name.replaceAll("-", "_");
1019                                 String value = params.get(tmpName);
1020                                 if(value != null && !value.isEmpty()) {
1021                                         value = value.trim().replace("'", "").replace("$", "").replace("'", "");
1022                                         request.addRequestProperty(name, value);
1023                                         argsFound = true;
1024                                 }
1025                         }
1026                         if(!argsFound) {
1027                                 getLogger().warn("No arguments were found. Terminating backup request.");
1028                                 return QueryStatus.FAILURE;
1029                         }
1030
1031                         String rv = getExecutor().get(request);
1032                     ctx.setAttribute(prefix, rv);
1033                 } catch(AAIServiceException aaiexc) {
1034                         if(aaiexc.getReturnCode() == 404)
1035                                 return QueryStatus.NOT_FOUND;
1036
1037                         return QueryStatus.FAILURE;
1038                 } catch (Exception exc) {
1039                         getLogger().warn("newModelBackupRequest", exc);
1040                         return QueryStatus.FAILURE;
1041                 }
1042
1043                 return retval;
1044         }
1045
1046         public AAIDatum newModelObjectRequest(String resource,  Map<String, String> params,  String prefix,  SvcLogicContext ctx)
1047                         throws AAIServiceException {
1048
1049                 AAIDatum response = null;
1050
1051                 try {
1052                         AAIRequest request = AAIRequest.createRequest(resource, params);
1053                         if(request == null) {
1054                                 return null;
1055                         }
1056
1057                         request.processRequestPathValues(params);
1058                         String rv = getExecutor().get(request);
1059                         response = request.jsonStringToObject(rv);
1060                 } catch(AAIServiceException aaiexc) {
1061                         throw aaiexc;
1062                 } catch (Exception exc) {
1063                         getLogger().warn("newModelBackupRequest", exc);
1064                         throw new AAIServiceException(exc);
1065                 }
1066
1067                 return response;
1068         }
1069
1070
1071         @Override
1072         public QueryStatus release(String arg0, String arg1, SvcLogicContext arg2) throws SvcLogicException {
1073                 // TODO Auto-generated method stub
1074                 throw new SvcLogicException("Method AAIService.release() has not been implemented yet");
1075         }
1076
1077         @Override
1078         public QueryStatus reserve(String arg0, String arg1, String arg2, String arg3, SvcLogicContext arg4)
1079                         throws SvcLogicException {
1080                 // TODO Auto-generated method stub
1081                 throw new SvcLogicException("Method AAIService.reserve() has not been implemented yet");
1082         }
1083
1084         private QueryStatus newModelSave(String resource, boolean force, String key, Map<String, String> params, String prefix, SvcLogicContext ctx) {
1085                 getLogger().debug("Executing newModelSave for resource : " + resource);
1086                 HashMap<String, String> nameValues = AAIServiceUtils.keyToHashMap(key, ctx);
1087
1088                 try {
1089                         ArrayList<String> subResources = new ArrayList<String>();
1090                         Set<String> set = params.keySet();
1091                         Map<String, Method> setters = new HashMap<String, Method>();
1092                         Map<String, Method> getters = new HashMap<String, Method>();
1093
1094                         // 1. find class
1095                         AAIRequest request = AAIRequest.createRequest(resource, nameValues);
1096                         Class<? extends AAIDatum> resourceClass = request.getModelClass();
1097                         getLogger().debug(resourceClass.getName());
1098                         AAIDatum instance = resourceClass.newInstance();
1099
1100                         {
1101                                 Annotation[] annotations = resourceClass.getAnnotations();
1102                                 for(Annotation annotation : annotations) {
1103                                         Class<? extends Annotation> anotationType = annotation.annotationType();
1104                                         String annotationName = anotationType.getName();
1105
1106                                         // 2. find string property setters and getters for the lists
1107                                         if("javax.xml.bind.annotation.XmlType".equals(annotationName)){
1108                                                 XmlType order = (XmlType)annotation;
1109                                                 String[]  values = order.propOrder();
1110                                                 for(String value : values) {
1111                                                         String id = AAIServiceUtils.camelCaseToDashedString(value);
1112                                                         Field field = resourceClass.getDeclaredField(value);
1113                                                         Class<?> type = field.getType();
1114                                                         Method setter = null;
1115                                                         try {
1116                                                                 setter = resourceClass.getMethod("set"+StringUtils.capitalize(value), type);
1117                                                                 if(type.getName().startsWith("java.lang") || "boolean".equals(type.getName()) || "long".equals(type.getName())) {
1118                                                                         try {
1119                                                                                 setter.setAccessible(true);
1120                                                                                 Object arglist[] = new Object[1];
1121                                                                                 arglist[0] = params.get(id);
1122
1123                                                                                 if(arglist[0] != null) {
1124                                                                                         if(!type.getName().equals("java.lang.String")) {
1125 //                                                                                      getLogger().debug(String.format("Processing %s with parameter %s", types[0].getName(), value));
1126                                                                                                 if("boolean".equals(type.getName())) {
1127                                                                                                         arglist[0] = valueOf(Boolean.class, params.get(id));
1128                                                                                                 } else if("long".equals(type.getName())) {
1129                                                                                                                 arglist[0] = valueOf(Long.class, params.get(id));
1130                                                                                                 } else {
1131                                                                                                         arglist[0] = valueOf(type, params.get(id));
1132                                                                                                 }
1133                                                                                         }
1134                                                                                         Object o = setter.invoke(instance, arglist);
1135                                                                                 }
1136                                                                                 set.remove(id);
1137
1138                                                                         } catch (Exception x) {
1139                                                                                 Throwable cause = x.getCause();
1140                                                                                 getLogger().warn("Failed process for " + resourceClass.getName(), x);
1141                                                                         }
1142                                                                 } else if(type.getName().equals("java.util.List")) {
1143                                                                         List<String> newValues = new ArrayList<String>();
1144                                                                         String length = id+"_length";
1145                                                                         if(!params.isEmpty() && params.containsKey(length)) {
1146                                                                                 String tmp = params.get(length).toString();
1147                                                                                 int count = Integer.valueOf(tmp);
1148                                                                                 for(int i=0; i<count; i++) {
1149                                                                                         String tmpValue = params.get(String.format("%s[%d]", id, i));
1150                                                                                         newValues.add(tmpValue);
1151                                                                                 }
1152                                                                                 if(!newValues.isEmpty()) {
1153                                                                                         Object o = setter.invoke(instance, newValues);
1154                                                                                 }
1155                                                                         }
1156                                                                         set.remove(id);
1157                                                                 } else {
1158                                                                         setters.put(id, setter);
1159                                                                 }
1160                                                         } catch(Exception exc) {
1161
1162                                                         }
1163
1164                                                         Method getter = null;
1165                                                         try {
1166                                                                 getter = resourceClass.getMethod("get"+StringUtils.capitalize(value));
1167                                                                 if(!type.getName().equals("java.lang.String")) {
1168                                                                         getters.put(id, getter);
1169                                                                 }
1170                                                         } catch(Exception exc) {
1171
1172                                                         }
1173
1174                                                 }
1175                                                 subResources.addAll(Arrays.asList(values));
1176                                         }
1177                                 }
1178                         }
1179
1180                         // remove getters that have matching setter
1181                         for(String setKey : setters.keySet()) {
1182                                 if(getters.containsKey(setKey)) {
1183                                         getters.remove(setKey);
1184                                 }
1185                         }
1186
1187                         Set<String> relationshipKeys = new TreeSet<String>();
1188                         Set<String> vlansKeys = new TreeSet<String>();
1189                         Set<String> metadataKeys = new TreeSet<String>();
1190
1191                         for(String attribute : set) {
1192                                 String value = params.get(attribute);
1193                                 if(attribute.startsWith("relationship-list")) {
1194                                         relationshipKeys.add(attribute);
1195                                 } else if(attribute.startsWith("vlans")) {
1196                                         vlansKeys.add(attribute);
1197                                 } else if(attribute.startsWith("metadata")) {
1198                                         metadataKeys.add(attribute);
1199                                 }
1200                         }
1201                         // 3. find list property getters
1202                         for(String attribute : set) {
1203                                 String value = params.get(attribute);
1204                                 Method method = getters.get(attribute);
1205                                 if(method != null) {
1206                                         try {
1207                                                 method.setAccessible(true);
1208                                                 Object arglist[] = new Object[0];
1209 //                                              arglist[0] = value;
1210                                                 Class<?>[] types = method.getParameterTypes();
1211                                                 if(types.length == 0){
1212                                                         Object o = method.invoke(instance, arglist);
1213                                                         if(o instanceof ArrayList) {
1214                                                                 ArrayList<String> values = (ArrayList<String>)o;
1215 //                                                              getLogger().debug(String.format("Processing %s with parameter %s", types[0].getName(), value));
1216                                                                 value = value.replace("[", "").replace("]", "");
1217                                                                 List<String> items = Arrays.asList(value.split("\\s*,\\s*"));
1218                                                                 for(String s : items) {
1219                                                                         values.add(s.trim());
1220                                                                 }
1221                                                         }
1222                                                 }
1223                                         } catch (Exception x) {
1224                                                 Throwable cause = x.getCause();
1225                                                 getLogger().warn("Failed process for " + resourceClass.getName(), x);
1226                                         }
1227                                 }
1228                         }
1229                         // 4. Process Relationships
1230                         // add relationship list
1231                         if( (subResources.contains("relationship-list") || subResources.contains("relationshipList")) &&  !relationshipKeys.isEmpty()) {
1232                                 RelationshipList relationshipList = null;
1233                                 Object obj = null;
1234                                 Method getRelationshipListMethod = null;
1235                                 try {
1236                                          getRelationshipListMethod = resourceClass.getMethod("getRelationshipList");
1237                                 } catch(Exception exc) {
1238                                         getLogger().debug("Retrofiting relationship data: " + exc.getMessage());
1239                                 }
1240
1241                                 if(getRelationshipListMethod != null){
1242                                         try {
1243                                                 getRelationshipListMethod.setAccessible(true);
1244                                                 obj = getRelationshipListMethod.invoke(instance);
1245                                         } catch (InvocationTargetException x) {
1246                                                 Throwable cause = x.getCause();
1247                                         }
1248                                 }
1249                                 if(obj != null && obj instanceof RelationshipList){
1250                                         relationshipList = (RelationshipList)obj;
1251                                 } else {
1252                                         relationshipList = new RelationshipList();
1253                                         Method setRelationshipListMethod = resourceClass.getMethod("setRelationshipList", RelationshipList.class);
1254                                         if(setRelationshipListMethod != null){
1255                                                 try {
1256                                                         setRelationshipListMethod.setAccessible(true);
1257                                                         Object arglist[] = new Object[1];
1258                                                         arglist[0] = relationshipList;
1259
1260                                                         obj = setRelationshipListMethod.invoke(instance, arglist);
1261                                                 } catch (InvocationTargetException x) {
1262                                                         Throwable cause = x.getCause();
1263                                                 }
1264                                         }
1265                                 }
1266
1267                                 List<Relationship> relationships = relationshipList.getRelationship();
1268
1269                                 int i = 0;
1270                                 while(true){
1271                                         String searchKey = "relationship-list.relationship[" + i + "].related-to";
1272                                         if(!params.containsKey(searchKey))
1273                                                 break;
1274                                         int j = 0;
1275                                         String relatedTo = params.get(searchKey);
1276                                         String relatedLinkKey = "relationship-list.relationship[" + i + "].related-link";
1277                                         String relatedLink = null;
1278                                         if(params.containsKey(relatedLinkKey)) {
1279                                                 relatedLink = params.get(relatedLinkKey);
1280                                         }
1281                                         Relationship relationship = new Relationship();
1282                                         relationships.add(relationship);
1283                                         relationship.setRelatedTo(relatedTo);
1284                                         if(relatedLink != null) {
1285                                                 relationship.setRelatedLink(relatedLink);
1286                                         } else {
1287 //                                              List<RelationshipData> relData = relationship.getRelationshipData();
1288                                                 Map<String, String> relParams = new HashMap<String, String>();
1289
1290                                         while(true) {
1291                                                 String searchRelationshipKey = "relationship-list.relationship[" + i + "].relationship-data[" + j + "].relationship-key";
1292                                                 String searchRelationshipValue = "relationship-list.relationship[" + i + "].relationship-data[" + j + "].relationship-value";
1293                                                         if(!params.containsKey(searchRelationshipKey))
1294                                                         break;
1295
1296                                                         relParams.put(params.get(searchRelationshipKey), params.get(searchRelationshipValue));
1297                                                 j++;
1298                                         }
1299                                                 AAIRequest rlRequest = AAIRequest.createRequest(relatedTo, relParams);
1300                                                 for(String key1 : relParams.keySet()) {
1301                                                         rlRequest.addRequestProperty(key1, relParams.get(key1));
1302                                                 }
1303                                                 String path = rlRequest.updatePathDataValues(null);
1304                                                 relationship.setRelatedLink(path);
1305                                         }
1306                                         i++;
1307                                 }
1308                         }
1309
1310                         // 4. vlans
1311                         if(subResources.contains("vlans") &&  !vlansKeys.isEmpty()) {
1312                                 Object obj = null;
1313                                 Vlans vlanList = null;
1314                                 Method getVLansMethod = resourceClass.getMethod("getVlans");
1315                                 if(getVLansMethod != null){
1316                                         try {
1317                                                 getVLansMethod.setAccessible(true);
1318                                                 obj = getVLansMethod.invoke(instance);
1319                                         } catch (InvocationTargetException x) {
1320                                                 Throwable cause = x.getCause();
1321                                         }
1322                                 }
1323                                 if(obj != null && obj instanceof Vlans){
1324                                         vlanList = (Vlans)obj;
1325                                 } else {
1326                                         vlanList = new Vlans();
1327                                         Method setVlansMethod = resourceClass.getMethod("setVlans", Vlans.class);
1328                                         if(setVlansMethod != null){
1329                                                 try {
1330                                                         setVlansMethod.setAccessible(true);
1331                                                         Object arglist[] = new Object[1];
1332                                                         arglist[0] = vlanList;
1333
1334                                                         obj = setVlansMethod.invoke(instance, arglist);
1335                                                 } catch (InvocationTargetException x) {
1336                                                         Throwable cause = x.getCause();
1337                                                 }
1338                                         }
1339                                 }
1340
1341                                 int i = 0;
1342                                 while(true){
1343                                         String searchKey = "vlans.vlan[" + i + "].vlan-interface";
1344                                         if(!params.containsKey(searchKey))
1345                                                 break;
1346
1347                                         String vlanInterface = params.get("vlans.vlan[" + i + "].vlan-interface");
1348                                         String vlanIdInner      = params.get("vlans.vlan[" + i + "].vlan-id-inner");
1349                                         String vlanIdOute       = params.get("vlans.vlan[" + i + "].vlan-id-outer");
1350                                         String speedValue       = params.get("vlans.vlan[" + i + "].speed-value");
1351                                         String speedUnits       = params.get("vlans.vlan[" + i + "].speed-units");
1352
1353                                         Vlan vlan = new Vlan();
1354                                         vlan.setVlanInterface(vlanInterface);
1355
1356                                         if(vlanIdInner != null) {
1357                                         Long iVlanIdInner = Long.parseLong(vlanIdInner);
1358                                         vlan.setVlanIdInner(iVlanIdInner);
1359                                         }
1360
1361                                         if(vlanIdOute != null) {
1362                                                 Long iVlanIdOuter = Long.parseLong(vlanIdOute);
1363                                         vlan.setVlanIdOuter(iVlanIdOuter);
1364                                         }
1365
1366                                         if(speedValue != null) {
1367                                         vlan.setSpeedValue(speedValue);
1368                                         vlan.setSpeedUnits(speedUnits);
1369                                         }
1370
1371                                         vlanList.getVlan().add(vlan);
1372                                         i++;
1373                                 }
1374                         }
1375
1376                         // 5. metadata
1377                         if(subResources.contains("metadata") &&  !metadataKeys.isEmpty()) {
1378                                 Object obj = null;
1379                                 Metadata metadataList = null;
1380                                 Method getMetadataMethod = resourceClass.getMethod("getMetadata");
1381                                 if(getMetadataMethod != null){
1382                                         try {
1383                                                 getMetadataMethod.setAccessible(true);
1384                                                 obj = getMetadataMethod.invoke(instance);
1385                                         } catch (InvocationTargetException x) {
1386                                                 Throwable cause = x.getCause();
1387                                         }
1388                                 }
1389                                 if(obj != null && obj instanceof Metadata){
1390                                         metadataList = (Metadata)obj;
1391                                 } else {
1392                                         metadataList = new Metadata();
1393                                         Method setMetadataMethod = resourceClass.getMethod("setMetadata", Metadata.class);
1394                                         if(setMetadataMethod != null){
1395                                                 try {
1396                                                         setMetadataMethod.setAccessible(true);
1397                                                         Object arglist[] = new Object[1];
1398                                                         arglist[0] = metadataList;
1399
1400                                                         obj = setMetadataMethod.invoke(instance, arglist);
1401                                                 } catch (InvocationTargetException x) {
1402                                                         Throwable cause = x.getCause();
1403                                                 }
1404                                         }
1405                                 }
1406
1407                                 if(metadataList.getMetadatum() == null) {
1408 //                                      metadataList.setMetadatum(new ArrayList<Metadatum>());
1409                                 }
1410
1411                                 // process data
1412                                 int i = 0;
1413                                 while(true){
1414                                         String metaKey = "metadata.metadatum[" + i + "].meta-key";
1415                                         if(!params.containsKey(metaKey))
1416                                                 break;
1417
1418                                         String metaValue = params.get("metadata.metadatum[" + i + "].meta-value");
1419
1420                                         Metadatum vlan = new Metadatum();
1421                                         vlan.setMetaname(metaKey);
1422                                         vlan.setMetaval(metaValue);
1423
1424                                         metadataList.getMetadatum().add(vlan);
1425                                         i++;
1426                                 }
1427
1428                         }
1429
1430
1431                         // 6. Prepare AAI request
1432                         String[] args = request.getArgsList();
1433                         for(String arg : args) {
1434                                 String modifiedKey = arg.replaceAll("-", "_");
1435                                 if(nameValues.containsKey(modifiedKey)) {
1436                                         String argValue = nameValues.get(modifiedKey);
1437                                         if(argValue != null) argValue = argValue.trim().replace("'", "").replace("$", "").replace("'", "");
1438                                         request.addRequestProperty(arg, argValue);
1439                                 }
1440                         }
1441
1442                         request.processRequestPathValues(nameValues);
1443                         request.setRequestObject(instance);
1444                                 Object response = getExecutor().post(request);
1445                                 if(request.expectsDataFromPUTRequest()){
1446                                         if(response != null && response instanceof String) {
1447                                                 String rv = response.toString();
1448                                                 QueryStatus retval = processResponseData(rv, resource, request, prefix,  ctx, nameValues, null);
1449                                                 getLogger().debug("newModelSave - returning " + retval.toString());
1450                                                 return retval;
1451                                         }
1452                                 }
1453
1454                 } catch(AAIServiceException exc){
1455                         ctx.setAttribute(prefix + ".error.message", exc.getMessage());
1456                         int returnCode = exc.getReturnCode();
1457                         if(returnCode >= 300) {
1458                                 ctx.setAttribute(prefix + ".error.http.response-code", "" + 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<String>();
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 = null;
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<String, String>();
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<String, String>();
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<String, String>();
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<String, String>();
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<String, String>();
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<String>();
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 }