2 * ============LICENSE_START=======================================================
4 * ================================================================================
5 * Copyright (C) 2017 ONAP Intellectual Property. All rights
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
12 * http://www.apache.org/licenses/LICENSE-2.0
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=========================================================
22 package org.onap.ccsdk.sli.adaptors.aai;
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;
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;
40 import java.util.SortedSet;
41 import java.util.TreeSet;
42 import java.util.regex.Matcher;
43 import java.util.regex.Pattern;
45 import javax.xml.bind.annotation.XmlType;
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.onap.ccsdk.sli.adaptors.aai.AAIService.AAIRequestExecutor;
69 import org.onap.ccsdk.sli.adaptors.aai.data.AAIDatum;
70 import org.onap.ccsdk.sli.adaptors.aai.query.FormattedQueryResultList;
71 import org.onap.ccsdk.sli.adaptors.aai.query.InstanceFilter;
72 import org.onap.ccsdk.sli.adaptors.aai.query.InstanceFilters;
73 import org.onap.ccsdk.sli.adaptors.aai.query.NamedQuery;
74 import org.onap.ccsdk.sli.adaptors.aai.query.NamedQueryData;
75 import org.onap.ccsdk.sli.adaptors.aai.query.QueryParameters;
76 import org.onap.ccsdk.sli.adaptors.aai.query.Results;
77 import org.slf4j.Logger;
78 import org.slf4j.LoggerFactory;
80 import com.fasterxml.jackson.core.JsonParseException;
81 import com.fasterxml.jackson.databind.JsonMappingException;
82 import com.fasterxml.jackson.databind.ObjectMapper;
85 public abstract class AAIDeclarations implements AAIClient {
87 public static final String TRUSTSTORE_PATH = "org.onap.ccsdk.sli.adaptors.aai.ssl.trust";
88 public static final String TRUSTSTORE_PSSWD = "org.onap.ccsdk.sli.adaptors.aai.ssl.trust.psswd";
89 public static final String KEYSTORE_PATH = "org.onap.ccsdk.sli.adaptors.aai.ssl.key";
90 public static final String KEYSTORE_PSSWD = "org.onap.ccsdk.sli.adaptors.aai.ssl.key.psswd";
92 public static final String APPLICATION_ID = "org.onap.ccsdk.sli.adaptors.aai.application";
94 public static final String CLIENT_NAME = "org.onap.ccsdk.sli.adaptors.aai.client.name";
95 public static final String CLIENT_PWWD = "org.onap.ccsdk.sli.adaptors.aai.client.psswd";
98 public static final String CONNECTION_TIMEOUT = "connection.timeout";
99 public static final String READ_TIMEOUT = "read.timeout";
101 public static final String TARGET_URI = "org.onap.ccsdk.sli.adaptors.aai.uri";
103 // Availability zones query
104 public static final String QUERY_PATH = "org.onap.ccsdk.sli.adaptors.aai.path.query";
107 public static final String UPDATE_PATH = "org.onap.ccsdk.sli.adaptors.aai.update";
110 public static final String SVC_INSTANCE_PATH = "org.onap.ccsdk.sli.adaptors.aai.path.svcinst";
111 public static final String SVC_INST_QRY_PATH = "org.onap.ccsdk.sli.adaptors.aai.path.svcinst.query";
114 public static final String NETWORK_VSERVER_PATH = "org.onap.ccsdk.sli.adaptors.aai.path.vserver";
116 public static final String VNF_IMAGE_QUERY_PATH = "org.onap.ccsdk.sli.adaptors.aai.path.vnf.image.query";
118 public static final String PARAM_SERVICE_TYPE = "org.onap.ccsdk.sli.adaptors.aai.param.service.type";
119 public static final String CERTIFICATE_HOST_ERROR = "org.onap.ccsdk.sli.adaptors.aai.host.certificate.ignore";
122 public static final String UBB_NOTIFY_PATH = "org.onap.ccsdk.sli.adaptors.aai.path.notify";
123 public static final String SELFLINK_AVPN = "org.onap.ccsdk.sli.adaptors.aai.notify.selflink.avpn";
124 public static final String SELFLINK_FQDN = "org.onap.ccsdk.sli.adaptors.aai.notify.selflink.fqdn";
127 public static final String SERVICE_PATH = "org.onap.ccsdk.sli.adaptors.aai.path.service";
130 public static final String P_INTERFACE_PATH = "org.onap.ccsdk.sli.adaptors.aai.path.pserver.pinterface";
133 public static final String SITE_PAIR_SET_PATH = "org.onap.ccsdk.sli.adaptors.aai.path.site.pair.set";
136 public static final String QUERY_NODES_PATH = "org.onap.ccsdk.sli.adaptors.aai.query.nodes";
139 protected abstract Logger getLogger();
140 public abstract AAIRequestExecutor getExecutor();
144 public QueryStatus query(String resource, boolean localOnly, String select, String key, String prefix, String orderBy, SvcLogicContext ctx)
145 throws SvcLogicException {
147 getLogger().debug("AAIService.query \tresource = "+resource);
150 String vnfName = null;
151 HashMap<String, String> nameValues = keyToHashMap(key, ctx);
152 getLogger().debug("key = "+ nameValues.toString());
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;
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;
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;
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;
176 // process data using new model
177 if(useNewModelProcessing && AAIRequest.createRequest(resource, nameValues) != null) {
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;
187 ObjectMapper mapper = AAIService.getObjectMapper();
188 Map<String,Object> attributes = new HashMap<String,Object>();
190 String modifier = null;
192 if(resource.contains(":")) {
193 String[] tokens = resource.split(":");
194 resource = tokens[0];
195 if(tokens.length > 1) {
196 modifier = tokens[1];
200 resource = resource.toLowerCase().replace("-", "_");
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");
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");
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);
222 return QueryStatus.NOT_FOUND;
225 attributes = mapper.convertValue(vnf, attributes.getClass());
226 } else if(vnfName != null && !vnfName.isEmpty()) {
228 vnfName = vnfName.trim().replace("'", "").replace("$", "").replace("'", "");
229 GenericVnf vnf = this.requestGenericVnfeNodeQuery(vnfName);
231 return QueryStatus.NOT_FOUND;
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();
244 getLogger().warn("Caught exception trying to refresh generic VNF", exc);
246 ctx.setAttribute(prefix + ".error.message", exc.getMessage());
247 if(errorCode >= 300) {
248 ctx.setAttribute(prefix + ".error.http.response-code", "" + exc.getReturnCode());
250 return QueryStatus.FAILURE;
253 getLogger().warn("No arguments are available to process generic VNF");
254 return QueryStatus.FAILURE;
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");
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");
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("'", "");
276 if (vserverName != null) {
277 URL vserverUrl = null;
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());
286 if (aaiexc.getReturnCode() == 404)
287 return QueryStatus.NOT_FOUND;
289 return QueryStatus.FAILURE;
291 if (vserverUrl == null) {
292 return QueryStatus.NOT_FOUND;
295 tenantId = getTenantIdFromVserverUrl(vserverUrl);
296 String cloudOwner = getCloudOwnerFromVserverUrl(vserverUrl);
297 String cloudRegionId = getCloudRegionFromVserverUrl(vserverUrl);
299 Vserver vserver = null;
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());
308 if (aaiexc.getReturnCode() == 404)
309 return QueryStatus.NOT_FOUND;
311 return QueryStatus.FAILURE;
313 if (vserver == null) {
314 return QueryStatus.NOT_FOUND;
316 attributes = mapper.convertValue(vserver, attributes.getClass());
317 if (!attributes.containsKey("tenant-id") && tenantId != null) {
318 attributes.put("tenant-id", tenantId);
320 if (!attributes.containsKey("cloud-owner") && cloudOwner != null) {
321 attributes.put("cloud-owner", cloudOwner);
323 if (!attributes.containsKey("cloud-region-id") && cloudRegionId != null) {
324 attributes.put("cloud-region-id", cloudRegionId);
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;
331 attributes = mapper.convertValue(vserver, attributes.getClass());
332 if(!attributes.containsKey("tenant-id") && tenantId != null){
333 attributes.put("tenant-id", tenantId);
336 return QueryStatus.FAILURE;
341 return QueryStatus.FAILURE;
344 QueryStatus retval = QueryStatus.SUCCESS;
346 if (attributes == null || attributes.isEmpty()) {
347 retval = QueryStatus.NOT_FOUND;
348 getLogger().debug("No data found");
351 if (prefix != null) {
352 ArrayList<String> keys = new ArrayList<String>(attributes.keySet());
354 int numCols = keys.size();
356 for (int i = 0; i < numCols; i++) {
357 String colValue = null;
358 String colName = keys.get(i);
359 Object object = attributes.get(colName);
361 if(object != null && object instanceof String) {
362 colValue = (String)object;
364 if (prefix != null) {
365 getLogger().debug("Setting "+prefix + "." + colName.replaceAll("_", "-")+" = "+ colValue);
366 ctx.setAttribute(prefix + "." + colName.replaceAll("_", "-"), colValue);
368 getLogger().debug("Setting " + colValue.replaceAll("_", "-")+" = "+colValue);
369 ctx.setAttribute(colValue.replaceAll("_", "-"), colValue);
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);
384 getLogger().debug("Query - returning " + retval);
387 } catch (Exception exc) {
388 getLogger().warn("Failed query - returning FAILURE", exc);
389 return QueryStatus.FAILURE;
392 // return QueryStatus.SUCCESS;
395 private boolean checkOldFormat(String resource, HashMap<String, String> nameValues) {
398 case "formatted-query":
399 case "generic-query":
403 case "l2-bridge-sbg":
404 case "l2-bridge-bgf":
409 if(resource.contains(":")) {
410 resource = resource.substring(0, resource.indexOf(":"));
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))
419 getLogger().warn(String.format("key %s is incompatible with resource type '%s'", key, resource));
427 public void writeMap(Map<String, Object> properties, String prefix, SvcLogicContext ctx) {
428 Set<String> mapKeys = properties.keySet();
430 for(String mapKey : mapKeys) {
431 Object entity = properties.get(mapKey);
432 if(entity instanceof ArrayList) {
433 writeList((ArrayList<?>)entity, prefix + "." + mapKey, ctx);
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;
441 localPrefix = String.format("%s.%s", prefix, mapKey);
443 writeMap( (Map<String, Object>)entity, localPrefix, ctx);
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);
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());
460 if(list.size() > 0) {
461 ctx.setAttribute(prefix + "_length", Integer.toString(list.size()));
462 getLogger().debug(prefix + "_length" + " : " + Integer.toString(list.size()));
467 public QueryStatus save(String resource, boolean force, boolean localOnly, String key, Map<String, String> params, String prefix, SvcLogicContext ctx)
468 throws SvcLogicException {
470 getLogger().debug("AAIService.save\tresource="+resource);
471 HashMap<String, String> nameValues = keyToHashMap(key, ctx);
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;
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;
484 getLogger().debug("key = "+ Arrays.toString(nameValues.entrySet().toArray()));
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");
495 getLogger().debug("parms = "+ Arrays.toString(params.entrySet().toArray()));
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;
504 if(!params.containsKey("vserver-selflink")) {
506 AAIRequest request = AAIRequest.createRequest(resource, nameValues);
509 request.processRequestPathValues(nameValues);
510 path = request.getRequestUrl("GET", null);
511 params.put("vserver-selflink", path.toString());
512 } catch (UnsupportedEncodingException | MalformedURLException e) {
514 params.put("vserver-selflink", "/vserver");
519 // process data using new model
520 if(useNewModelProcessing && AAIRequest.createRequest(resource, nameValues) != null) {
523 if(!resource.contains(":")){
524 return newModelSave(resource, force, key, params, prefix, ctx);
526 String[] tokens = resource.split(":");
527 String localResource = tokens[0];
528 String dependency = tokens[1];
530 AAIDatum instance = newModelObjectRequest( localResource, nameValues, prefix, ctx);
531 if(instance == null) {
532 return QueryStatus.NOT_FOUND;
536 case "relationship-list":
537 newModelProcessRelationshipList(instance, params, prefix, ctx);
540 // create a method to update relationship-list
541 AAIRequest request = AAIRequest.createRequest(localResource, nameValues);
542 request.setRequestObject(instance);
543 request.processRequestPathValues(nameValues);
545 getExecutor().post(request);
546 getLogger().debug("Save relationship list - returning SUCCESS");
547 return QueryStatus.SUCCESS;
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());
557 if(aaiexc.getReturnCode() == 404) {
558 return QueryStatus.NOT_FOUND;
561 getLogger().warn("Failed save() - returning FAILURE", exc);
562 return QueryStatus.FAILURE;
565 String reSource = resource.toLowerCase().replace("-", "_");
572 vnfId = nameValues.get("vnf_id");
574 getLogger().debug("Save(generic-vnf) with no vnf-id specified. Returning FAILURE");
575 return QueryStatus.FAILURE;
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);
585 this.postGenericVnfData(vnfId, vnf);
589 return update( resource, key, params, prefix, ctx) ;
592 getLogger().debug("Save() executing default path - returning FAILURE");
593 return QueryStatus.FAILURE;
595 } catch (Exception exc) {
596 getLogger().warn("Failed save - returning FAILURE", exc);
597 ctx.setAttribute(prefix + ".error.message", exc.getMessage());
598 return QueryStatus.FAILURE;
602 getLogger().debug("Save - returning SUCCESS");
603 return QueryStatus.SUCCESS;
607 public QueryStatus update(String resource, String key, Map<String, String> params, String prefix, SvcLogicContext ctx) throws SvcLogicException {
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;
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;
622 getLogger().debug("parms = "+ Arrays.toString(params.entrySet().toArray()));
624 AAIRequest request = AAIRequest.createRequest(resource, nameValues);
625 request = new UpdateRequest(request, params);
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);
638 QueryStatus retval = QueryStatus.SUCCESS;
640 retval = newModelQuery(resource, false, null, key, "tmpDelete", null, ctx);
642 if(retval == null || retval != QueryStatus.SUCCESS) {
646 String resourceVersion = ctx.getAttribute("tmpDelete.resource-version");
647 if(resourceVersion == null) {
648 return QueryStatus.NOT_FOUND;
650 params.put("resource-version", resourceVersion);
652 request.processRequestPathValues(nameValues);
653 getExecutor().patch(request, resourceVersion);
654 } catch(AAIServiceException aaiexc) {
655 if(aaiexc.getReturnCode() == 404)
656 return QueryStatus.NOT_FOUND;
658 return QueryStatus.FAILURE;
659 } catch (Exception exc) {
660 getLogger().warn("Failed update - returning FAILURE", exc);
661 return QueryStatus.FAILURE;
664 getLogger().debug("Update - returning SUCCESS");
665 return QueryStatus.SUCCESS;
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()));
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;
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;
684 if(AAIRequest.createRequest(resource, nameValues) != null) {
685 if(resource.contains(":")) {
686 return processDeleteRelationshipList(resource, key, ctx, nameValues);
691 QueryStatus retval = QueryStatus.SUCCESS;
693 retval = newModelQuery(resource, false, null, key, "tmpDelete", null, ctx);
695 if(retval == null || retval != QueryStatus.SUCCESS) {
699 String resourceVersion = ctx.getAttribute("tmpDelete.resource-version");
700 if(resourceVersion == null) {
701 return QueryStatus.NOT_FOUND;
705 AAIRequest request = AAIRequest.createRequest(resource, nameValues);
706 if(request == null) {
707 return QueryStatus.FAILURE;
710 request.processRequestPathValues(nameValues);
712 if(getExecutor().delete(request, resourceVersion)) {
713 return QueryStatus.SUCCESS;
715 } catch(AAIServiceException aaiexc) {
716 if(aaiexc.getReturnCode() == 404)
717 return QueryStatus.NOT_FOUND;
719 return QueryStatus.FAILURE;
721 } catch (Exception exc) {
722 getLogger().warn("requestGenericVnfData", exc);
723 return QueryStatus.FAILURE;
726 } catch (Exception exc) {
727 getLogger().warn("Failed delete - returning FAILURE", exc);
728 return QueryStatus.FAILURE;
731 String resoourceName = resource;
732 String identifier = null;
734 if(resoourceName == null)
735 return QueryStatus.FAILURE;
737 if(resoourceName.contains(":")) {
738 String[] tokens = resoourceName.split(":");
739 if(tokens != null && tokens.length > 0) {
740 resoourceName = tokens[0];
741 identifier = tokens[1];
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("'", "");
754 vnf = this.requestGenericVnfData(vnfId);
756 return QueryStatus.NOT_FOUND;
757 } catch (AAIServiceException exc) {
758 getLogger().warn("Failed delete - returning NOT_FOUND", exc);
759 return QueryStatus.NOT_FOUND;
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);
773 return QueryStatus.NOT_FOUND;
775 // AAIRequest masterRequest = new GenericVnfRequest();
776 // masterRequest.addRequestProperty(GenericVnfRequest.VNF_ID, vnfId);
777 // relationshipRequest.addMasterRequest(masterRequest);
778 // Map<String, String> attributes = objectToProperties(vnf);
780 // Boolean result = getExecutor().delete(relationshipRequest, attributes.get(AAIRequest.RESOURCE_VERSION));
781 // } catch (AAIServiceException e) {
782 // return QueryStatus.FAILURE;
786 this.postGenericVnfData(vnf.getVnfId(), vnf);
787 } catch (AAIServiceException exc) {
788 if(exc.getReturnCode() == 404){
789 return QueryStatus.NOT_FOUND;
791 getLogger().warn("Failed delete - returning FAILURE", exc);
792 return QueryStatus.FAILURE;
795 return QueryStatus.SUCCESS;
799 return QueryStatus.FAILURE;
803 public QueryStatus exists(String resource, String key, String prefix, SvcLogicContext ctx) throws SvcLogicException {
804 return query(resource, false, null, key, prefix, null, ctx);
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");
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");
821 public QueryStatus newModelQuery(String resource, boolean localOnly, String select, String key, String prefix, String orderBy, SvcLogicContext ctx) {
823 Object response = null;
824 QueryStatus retval = QueryStatus.SUCCESS;
825 String modifier = null;
827 HashMap<String, String> nameValues = keyToHashMap(key, ctx);
828 if(resource.contains(":")) {
829 modifier = resource.split(":")[1];
833 AAIRequest request = AAIRequest.createRequest(resource, nameValues);
834 if(request == null) {
835 return QueryStatus.FAILURE;
838 Map<String, String> params = new HashMap<String, String>();
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);
846 if("named-query".equals(resource))
847 request.setRequestObject(extractNamedQueryDataFromQueryPrefix(nameValues, params));
849 String rv = getExecutor().get(request);
851 retval = processResponseData(rv, resource, request, prefix, ctx, nameValues, modifier);
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());
860 if(aaiexc.getReturnCode() == 404)
861 return QueryStatus.NOT_FOUND;
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;
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
875 Object response = null;
878 return QueryStatus.NOT_FOUND;
881 response = request.jsonStringToObject(rv);
882 if(response == null) {
883 return QueryStatus.NOT_FOUND;
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;
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);
898 return QueryStatus.NOT_FOUND;
901 response = req2.jsonStringToObject(rv);
902 if(response == null) {
903 return QueryStatus.NOT_FOUND;
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;
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;
921 ResultData rDatum = rdList.get(0);
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;
933 String preFix = null;
934 if(prefix == null || prefix.isEmpty()) {
937 preFix = prefix + ".";
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);
946 Object value = props.get(theKey);
949 Object type = value.getClass();
950 if(value instanceof String) {
951 ctx.setAttribute(preFix + theKey, value.toString());
954 if(value instanceof Boolean) {
955 ctx.setAttribute(preFix + theKey, value.toString());
958 if(value instanceof Integer) {
959 ctx.setAttribute(preFix + theKey, value.toString());
962 if(value instanceof Long) {
963 ctx.setAttribute(preFix + theKey, value.toString());
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);
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()) {
983 List newRelationships = new LinkedList();
984 newRelationships.addAll(relationships);
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");
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);
1007 writeMap(relationshipList, String.format("%s.%s", prefix, theKey), ctx);
1011 if(value instanceof Map) {
1012 Map<String, Object> subnetsList = (Map<String, Object>)value;
1013 writeMap(subnetsList, String.format("%s.%s", prefix, theKey), ctx);
1018 return QueryStatus.SUCCESS;
1022 public QueryStatus newModelBackupRequest(String resource, Map<String, String> params, String prefix, SvcLogicContext ctx) {
1024 QueryStatus retval = QueryStatus.SUCCESS;
1025 HashMap<String, String> nameValues = new HashMap<String, String>();
1028 AAIRequest request = AAIRequest.createRequest(resource, nameValues);
1029 if(request == null) {
1030 return QueryStatus.FAILURE;
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);
1045 getLogger().warn("No arguments were found. Terminating backup request.");
1046 return QueryStatus.FAILURE;
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;
1055 return QueryStatus.FAILURE;
1056 } catch (Exception exc) {
1057 getLogger().warn("newModelBackupRequest", exc);
1058 return QueryStatus.FAILURE;
1064 public AAIDatum newModelObjectRequest(String resource, Map<String, String> params, String prefix, SvcLogicContext ctx)
1065 throws AAIServiceException {
1067 AAIDatum response = null;
1070 AAIRequest request = AAIRequest.createRequest(resource, params);
1071 if(request == null) {
1075 request.processRequestPathValues(params);
1076 String rv = getExecutor().get(request);
1077 response = request.jsonStringToObject(rv);
1078 } catch(AAIServiceException aaiexc) {
1080 } catch (Exception exc) {
1081 getLogger().warn("newModelBackupRequest", exc);
1082 throw new AAIServiceException(exc);
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");
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");
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);
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>();
1113 AAIRequest request = AAIRequest.createRequest(resource, nameValues);
1114 Class<? extends AAIDatum> resourceClass = request.getModelClass();
1115 getLogger().debug(resourceClass.getName());
1116 AAIDatum instance = resourceClass.newInstance();
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)){
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;
1135 setter = resourceClass.getMethod("set"+StringUtils.capitalize(value), type);
1136 if(type.getName().startsWith("java.lang") || "boolean".equals(type.getName()) || "long".equals(type.getName())) {
1138 setter.setAccessible(true);
1139 Object arglist[] = new Object[1];
1140 arglist[0] = parms.get(id);
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));
1150 arglist[0] = valueOf(type, parms.get(id));
1153 Object o = setter.invoke(instance, arglist);
1157 } catch (Exception x) {
1158 Throwable cause = x.getCause();
1159 getLogger().warn("Failed process for " + resourceClass.getName(), x);
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);
1171 if(!newValues.isEmpty()) {
1172 Object o = setter.invoke(instance, newValues);
1177 setters.put(id, setter);
1179 } catch(Exception exc) {
1183 Method getter = null;
1185 getter = resourceClass.getMethod("get"+StringUtils.capitalize(value));
1186 if(!type.getName().equals("java.lang.String")) {
1187 getters.put(id, getter);
1189 } catch(Exception exc) {
1194 subResources.addAll(Arrays.asList(values));
1199 // remove getters that have matching setter
1200 for(String setKey : setters.keySet()) {
1201 if(getters.containsKey(setKey)) {
1202 getters.remove(setKey);
1206 Set<String> relationshipKeys = new TreeSet<String>();
1207 Set<String> vlansKeys = new TreeSet<String>();
1208 Set<String> metadataKeys = new TreeSet<String>();
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);
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) {
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());
1242 } catch (Exception x) {
1243 Throwable cause = x.getCause();
1244 getLogger().warn("Failed process for " + resourceClass.getName(), x);
1248 // 4. Process Relationships
1249 // add relationship list
1250 if( (subResources.contains("relationship-list") || subResources.contains("relationshipList")) && !relationshipKeys.isEmpty()) {
1251 RelationshipList relationshipList = null;
1253 Method getRelationshipListMethod = resourceClass.getMethod("getRelationshipList");
1254 if(getRelationshipListMethod != null){
1256 getRelationshipListMethod.setAccessible(true);
1257 obj = getRelationshipListMethod.invoke(instance);
1258 } catch (InvocationTargetException x) {
1259 Throwable cause = x.getCause();
1262 if(obj != null && obj instanceof RelationshipList){
1263 relationshipList = (RelationshipList)obj;
1265 relationshipList = new RelationshipList();
1266 Method setRelationshipListMethod = resourceClass.getMethod("setRelationshipList", RelationshipList.class);
1267 if(setRelationshipListMethod != null){
1269 setRelationshipListMethod.setAccessible(true);
1270 Object arglist[] = new Object[1];
1271 arglist[0] = relationshipList;
1273 obj = setRelationshipListMethod.invoke(instance, arglist);
1274 } catch (InvocationTargetException x) {
1275 Throwable cause = x.getCause();
1280 List<Relationship> relationships = relationshipList.getRelationship();
1285 String searchKey = "relationship-list.relationship[" + i + "].related-to";
1286 if(!parms.containsKey(searchKey))
1288 Relationship relationship = new Relationship();
1289 relationships.add(relationship);
1291 String relatedTo = parms.get(searchKey);
1292 relationship.setRelatedTo(relatedTo);
1294 List<RelationshipData> relData = relationship.getRelationshipData();
1295 // if(relData == null) {
1296 // relData = new LinkedList<RelationshipData>();
1297 // relationship.setRelationshipData(relData);
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))
1306 RelationshipData relDatum = new RelationshipData();
1307 relDatum.setRelationshipKey(parms.get(searchRelationshipKey));
1308 relDatum.setRelationshipValue(parms.get(searchRelationshipValue));
1309 relData.add(relDatum);
1318 if(subResources.contains("vlans") && !vlansKeys.isEmpty()) {
1320 Vlans vlanList = null;
1321 Method getVLansMethod = resourceClass.getMethod("getVlans");
1322 if(getVLansMethod != null){
1324 getVLansMethod.setAccessible(true);
1325 obj = getVLansMethod.invoke(instance);
1326 } catch (InvocationTargetException x) {
1327 Throwable cause = x.getCause();
1330 if(obj != null && obj instanceof Vlans){
1331 vlanList = (Vlans)obj;
1333 vlanList = new Vlans();
1334 Method setVlansMethod = resourceClass.getMethod("setVlans", Vlans.class);
1335 if(setVlansMethod != null){
1337 setVlansMethod.setAccessible(true);
1338 Object arglist[] = new Object[1];
1339 arglist[0] = vlanList;
1341 obj = setVlansMethod.invoke(instance, arglist);
1342 } catch (InvocationTargetException x) {
1343 Throwable cause = x.getCause();
1350 String searchKey = "vlans.vlan[" + i + "].vlan-interface";
1351 if(!parms.containsKey(searchKey))
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");
1360 Vlan vlan = new Vlan();
1361 vlan.setVlanInterface(vlanInterface);
1363 if(vlanIdInner != null) {
1364 Long iVlanIdInner = Long.parseLong(vlanIdInner);
1365 vlan.setVlanIdInner(iVlanIdInner);
1368 if(vlanIdOute != null) {
1369 Long iVlanIdOuter = Long.parseLong(vlanIdOute);
1370 vlan.setVlanIdOuter(iVlanIdOuter);
1373 if(speedValue != null) {
1374 vlan.setSpeedValue(speedValue);
1375 vlan.setSpeedUnits(speedUnits);
1378 vlanList.getVlan().add(vlan);
1384 if(subResources.contains("metadata") && !metadataKeys.isEmpty()) {
1386 Metadata metadataList = null;
1387 Method getMetadataMethod = resourceClass.getMethod("getMetadata");
1388 if(getMetadataMethod != null){
1390 getMetadataMethod.setAccessible(true);
1391 obj = getMetadataMethod.invoke(instance);
1392 } catch (InvocationTargetException x) {
1393 Throwable cause = x.getCause();
1396 if(obj != null && obj instanceof Metadata){
1397 metadataList = (Metadata)obj;
1399 metadataList = new Metadata();
1400 Method setMetadataMethod = resourceClass.getMethod("setMetadata", Metadata.class);
1401 if(setMetadataMethod != null){
1403 setMetadataMethod.setAccessible(true);
1404 Object arglist[] = new Object[1];
1405 arglist[0] = metadataList;
1407 obj = setMetadataMethod.invoke(instance, arglist);
1408 } catch (InvocationTargetException x) {
1409 Throwable cause = x.getCause();
1414 if(metadataList.getMetadatum() == null) {
1415 // metadataList.setMetadatum(new ArrayList<Metadatum>());
1421 String metaKey = "metadata.metadatum[" + i + "].meta-key";
1422 if(!parms.containsKey(metaKey))
1425 String metaValue = parms.get("metadata.metadatum[" + i + "].meta-value");
1427 Metadatum vlan = new Metadatum();
1428 vlan.setMetaname(metaKey);
1429 vlan.setMetaval(metaValue);
1431 metadataList.getMetadatum().add(vlan);
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);
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());
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());
1468 if(returnCode == 400 || returnCode == 412)
1469 return QueryStatus.FAILURE;
1470 else if(returnCode == 404)
1471 return QueryStatus.NOT_FOUND;
1473 getLogger().warn("Failed newModelSave - returning FAILURE", exc);
1474 return QueryStatus.FAILURE;
1476 } catch(Exception exc){
1477 getLogger().warn("Failed newModelSave - returning FAILURE", exc);
1478 ctx.setAttribute(prefix + ".error.message", exc.getMessage());
1479 return QueryStatus.FAILURE;
1482 getLogger().debug("newModelSave - returning SUCCESS");
1483 return QueryStatus.SUCCESS;
1486 private static final String regex = "([A-Z][a-z,0-9]+)";
1487 private static final String replacement = "-$1";
1489 private String camelCaseToDashedString(String propOrder) {
1490 return propOrder.replaceAll(regex, replacement).toLowerCase();
1493 private QueryStatus newModelProcessRelationshipList(Object instance, Map<String, String> params, String prefix, SvcLogicContext ctx) throws Exception {
1495 Class resourceClass = instance.getClass();
1497 Set<String> relationshipKeys = new TreeSet<String>();
1499 Set<String> set = params.keySet();
1501 for(String attribute : set) {
1502 String value = params.get(attribute);
1504 if(attribute.startsWith("relationship-list")) {
1505 relationshipKeys.add(attribute);
1509 // 3. Process Relationships
1510 // add relationship list
1511 if(!relationshipKeys.isEmpty()) {
1512 RelationshipList relationshipList = null;
1514 Method getRelationshipListMethod = resourceClass.getMethod("getRelationshipList");
1515 if(getRelationshipListMethod != null){
1517 getRelationshipListMethod.setAccessible(true);
1518 obj = getRelationshipListMethod.invoke(instance);
1519 } catch (InvocationTargetException x) {
1520 Throwable cause = x.getCause();
1523 if(obj != null && obj instanceof RelationshipList){
1524 relationshipList = (RelationshipList)obj;
1526 relationshipList = new RelationshipList();
1527 Method setRelationshipListMethod = resourceClass.getMethod("setRelationshipList", RelationshipList.class);
1528 if(setRelationshipListMethod != null){
1530 setRelationshipListMethod.setAccessible(true);
1531 Object arglist[] = new Object[1];
1532 arglist[0] = relationshipList;
1534 obj = setRelationshipListMethod.invoke(instance, arglist);
1535 } catch (InvocationTargetException x) {
1536 Throwable cause = x.getCause();
1541 boolean createdNewRelationships = false;
1542 List<Relationship> relationships = relationshipList.getRelationship();
1543 if(relationships == null) {
1544 relationships = new ArrayList<Relationship>();
1545 createdNewRelationships = true;
1551 String searchKey = "relationship-list.relationship[" + i + "].related-to";
1552 if(!params.containsKey(searchKey))
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);
1563 Relationship relationship = new Relationship();
1564 relationships.add(relationship);
1565 relationship.setRelatedTo(relatedTo);
1566 if(relatedLink != null) {
1567 relationship.setRelatedLink(relatedLink);
1569 List<RelationshipData> relData = relationship.getRelationshipData();
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))
1577 RelationshipData relDatum = new RelationshipData();
1578 relDatum.setRelationshipKey(params.get(searchRelationshipKey));
1579 relDatum.setRelationshipValue(params.get(searchRelationshipValue));
1580 relData.add(relDatum);
1590 return QueryStatus.SUCCESS;
1593 private Relationship findRelationship(List<Relationship> relationships, String relatedTo) {
1594 if(relatedTo == null)
1597 for(Relationship relationship : relationships) {
1598 if(relationship.getRelatedTo().equals(relatedTo)){
1599 return relationship;
1605 protected HashMap<String,String> keyToHashMap(String key, SvcLogicContext ctx) {
1610 getLogger().debug("Converting key [" + key + "] to where clause");
1612 if (key.startsWith("'") && key.endsWith("'")) {
1613 key = key.substring(1, key.length() - 1);
1615 getLogger().debug("Stripped outer single quotes - key is now [" + key + "]");
1618 String[] keyTerms = key.split("\\s+");
1620 StringBuffer whereBuff = new StringBuffer();
1621 String term1 = null;
1623 String term2 = null;
1624 HashMap<String, String> results = new HashMap<String, String>();
1626 for (int i = 0; i < keyTerms.length; i++) {
1627 if (term1 == null) {
1628 if ("and".equalsIgnoreCase(keyTerms[i])
1629 || "or".equalsIgnoreCase(keyTerms[i])) {
1632 term1 = resolveTerm(keyTerms[i], ctx);
1634 } else if (op == null) {
1635 if ("==".equals(keyTerms[i])) {
1641 term2 = resolveTerm(keyTerms[i], ctx);
1642 term2 = term2.trim().replace("'", "").replace("$", "").replace("'", "");
1643 results.put(term1, term2);
1654 private String resolveTerm(String term, SvcLogicContext ctx) {
1659 getLogger().debug("resolveTerm: term is " + term);
1661 if (term.startsWith("$") && (ctx != null)) {
1662 // Resolve any index variables.
1664 return ("'" + resolveCtxVariable(term.substring(1), ctx) + "'");
1665 } else if (term.startsWith("'") || term.startsWith("\"")) {
1668 return (term.replaceAll("-", "_"));
1674 private String resolveCtxVariable(String ctxVarName, SvcLogicContext ctx) {
1676 if (ctxVarName.indexOf('[') == -1) {
1677 // Ctx variable contains no arrays
1678 return (ctx.getAttribute(ctxVarName));
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));
1695 String idxVarName = ctxVarParts[i].substring(1, endBracketLoc);
1696 String remainder = ctxVarParts[i].substring(endBracketLoc);
1699 sbuff.append(ctx.getAttribute(idxVarName));
1700 sbuff.append(remainder);
1703 // Index is not a variable reference
1705 sbuff.append(ctxVarParts[i]);
1709 return (ctx.getAttribute(sbuff.toString()));
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");
1717 HashMap<String, String> nameValues = new HashMap<String, String>();
1718 if(AAIRequest.createRequest(resource, nameValues) != null) {
1721 return newModelBackupRequest(resource, params, prefix, ctx);
1722 } catch (Exception exc) {
1723 getLogger().warn("Failed backup - returning FAILURE", exc);
1724 return QueryStatus.FAILURE;
1728 return QueryStatus.NOT_FOUND;
1732 public QueryStatus restore(Map<String, String> params, SvcLogicContext ctx) throws SvcLogicException {
1734 QueryStatus retval = QueryStatus.SUCCESS;
1735 String resource = params.get("resource").toLowerCase();
1736 String prefix = params.get("data-key");
1738 HashMap<String, String> nameValues = new HashMap<String, String>();
1739 if(AAIRequest.createRequest(resource, nameValues) != null) {
1742 retval = newModelBackupRequest(resource, params, "tmpRestore", ctx);
1743 if(retval == QueryStatus.SUCCESS) {
1744 String current_json = ctx.getAttribute("tmpRestore");
1745 ctx. setAttribute("tmpRestore", null);
1747 String snapshot_json = ctx.getAttribute(prefix);
1749 } catch (Exception exc) {
1750 getLogger().warn("Failed restore - returning FAILURE", exc);
1751 return QueryStatus.FAILURE;
1755 return QueryStatus.NOT_FOUND;
1758 protected Map<String, Object> objectToProperties(Object object) {
1759 ObjectMapper mapper = AAIService.getObjectMapper();
1760 return mapper.convertValue(object, Map.class);
1763 static <T> T valueOf(Class<T> klazz, String arg) {
1764 Exception cause = null;
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) {
1773 } catch (InvocationTargetException e) {
1776 if (cause == null) {
1779 throw new IllegalArgumentException(cause);
1783 private QueryStatus processDeleteRelationshipList(String resource, String key, SvcLogicContext ctx, HashMap<String, String> nameValues) {
1785 AAIRequest request = AAIRequest.createRequest(resource, nameValues);
1786 if(request == null) {
1787 return QueryStatus.FAILURE;
1790 request.processRequestPathValues(nameValues);
1791 URL url = request.getRequestUrl("GET", null);
1793 Class resourceClass = request.getModelClass();
1794 Object instance = getResource(url.toString(), resourceClass);
1795 if(instance == null)
1796 return QueryStatus.NOT_FOUND;
1798 // get resource version
1799 String resourceVersion = null;
1800 Method getResourceVersionMethod = resourceClass.getMethod("getResourceVersion");
1801 if(getResourceVersionMethod != null){
1803 getResourceVersionMethod.setAccessible(true);
1804 Object object = getResourceVersionMethod.invoke(instance);
1806 resourceVersion = object.toString();
1807 } catch (InvocationTargetException x) {
1808 Throwable cause = x.getCause();
1812 RelationshipList relationshipList = null;
1814 Method getRelationshipListMethod = resourceClass.getMethod("getRelationshipList");
1815 if(getRelationshipListMethod != null){
1817 getRelationshipListMethod.setAccessible(true);
1818 obj = getRelationshipListMethod.invoke(instance);
1819 } catch (InvocationTargetException x) {
1820 Throwable cause = x.getCause();
1823 if(obj != null && obj instanceof RelationshipList){
1824 relationshipList = (RelationshipList)obj;
1826 getLogger().debug("No relationships found to process.");
1827 return QueryStatus.NOT_FOUND;
1830 if(relationshipList.getRelationship() == null || relationshipList.getRelationship().isEmpty()) {
1831 return QueryStatus.NOT_FOUND;
1833 String relatedTo = nameValues.get("related_to");
1834 if(relatedTo == null) {
1835 return QueryStatus.FAILURE;
1838 relatedTo = relatedTo.replaceAll("_", "-");
1840 String relatedLink = nameValues.get("relationship.related_link");
1841 if(relatedLink != null) {
1842 relatedLink = URLDecoder.decode(relatedLink, "UTF-8");
1845 List<Relationship> relationships = relationshipList.getRelationship();
1846 List<Relationship> relationshipsToDelete = new LinkedList<Relationship>();
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);
1860 getLogger().debug(String.format("Found relationship of '%s' to keyword '%s'", relationship.getRelatedTo(), relatedTo));
1861 relationshipsToDelete.add(relationship);
1865 if(relationshipsToDelete == null || relationshipsToDelete.isEmpty()) {
1866 getLogger().info(String.format("Relationship has not been found for %s", key));
1867 return QueryStatus.NOT_FOUND;
1870 String path = url.toString();
1871 path = path + "/relationship-list/relationship";
1872 URL deleteUrl = new URL(path);
1874 ObjectMapper mapper = AAIService.getObjectMapper();
1876 boolean cumulativeResponse = true;
1878 for(Relationship targetRelationship : relationshipsToDelete) {
1879 String json_text = mapper.writeValueAsString(targetRelationship);
1880 boolean response = deleteRelationshipList(deleteUrl, json_text);
1882 cumulativeResponse = response;
1886 if(!cumulativeResponse)
1887 return QueryStatus.FAILURE;
1889 return QueryStatus.SUCCESS;
1891 } catch(Exception exc) {
1892 getLogger().warn("processDelete", exc);
1893 return QueryStatus.FAILURE;
1897 static final Map<String, String> ctxGetBeginsWith( SvcLogicContext ctx, String prefix ) {
1898 Map<String, String> tmpPrefixMap = new HashMap<String, String>();
1900 if(prefix == null || prefix.isEmpty()){
1901 return tmpPrefixMap;
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));
1911 Map<String, String> prefixMap = new HashMap<String, String>();
1912 Pattern p = Pattern.compile(".*\\[\\d\\]");
1914 SortedSet<String> keys = new TreeSet(tmpPrefixMap.keySet () );
1915 for(String key : keys) {
1916 Matcher m = p.matcher(key);
1919 } else if(key.endsWith("_length")) {
1920 String listKey = key.substring(0, key.indexOf("_length"));
1921 int max = Integer.parseInt(tmpPrefixMap.get(key));
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()) {
1931 if(!data.isEmpty()) {
1932 prefixMap.put(listKey, data.toString());
1934 prefixMap.put(key, tmpPrefixMap.get(key));
1937 prefixMap.put(key, tmpPrefixMap.get(key));
1946 protected NamedQueryData extractNamedQueryDataFromQueryPrefix(HashMap<String, String> nameValues, Map<String, String> parms) {
1947 if(parms.isEmpty()) {
1951 NamedQueryData data = new NamedQueryData();
1954 if(data.getQueryParameters() == null) {
1955 data.setQueryParameters(new QueryParameters());
1957 String namedQueryUuid = nameValues.get("named-query-uuid".replaceAll("-", "_"));
1958 if(namedQueryUuid == null) {
1959 namedQueryUuid = parms.get("query-parameters.named-query.named-query-uuid");
1961 NamedQuery namedQuery = new NamedQuery();
1962 namedQuery.setNamedQueryUuid(namedQueryUuid);
1963 data.getQueryParameters().setNamedQuery(namedQuery);
1966 if(data.getInstanceFilters() == null) {
1967 data.setInstanceFilters(new InstanceFilters());
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);
1989 insf = data.getInstanceFilters().getInstanceFilter().get(0);
1991 LogicalLink logicalLink = insf.getLogicalLink();
1992 if(logicalLink == null) {
1993 logicalLink = new LogicalLink();
1994 insf.setLogicalLink(logicalLink);
1999 logicalLink.setLinkName(value);
2002 logicalLink.setLinkType(value);
2004 case "operational-state":
2005 logicalLink.setOperationalStatus(value);
2009 } else if("pnf".equals(split[0])) {
2010 Pnf pnf = new Pnf();
2011 pnf.setPnfName(value);
2013 InstanceFilter insf = new InstanceFilter();
2015 data.getInstanceFilters().getInstanceFilter().add(insf);
2017 } else if("service-instance".equals(split[0])) {
2018 ServiceInstance serviceInstance = new ServiceInstance();
2019 serviceInstance.setServiceInstanceId(value);
2021 InstanceFilter insf = new InstanceFilter();
2022 insf.setServiceInstance(serviceInstance);
2023 data.getInstanceFilters().getInstanceFilter().add(insf);
2025 } else if("l3-network".equals(split[0])) {
2026 L3Network l3Network = new L3Network();
2027 if("network-role".equals(split[1])) {
2028 l3Network.setNetworkRole(value);
2031 InstanceFilter insf = new InstanceFilter();
2032 insf.setL3Network(l3Network);
2033 data.getInstanceFilters().getInstanceFilter().add(insf);
2043 public abstract <T> T getResource(String key, Class<T> type) throws AAIServiceException ;
2044 protected abstract boolean deleteRelationshipList(URL url, String caller) throws AAIServiceException;