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