2 * ============LICENSE_START=======================================================
4 * ================================================================================
5 * Copyright (C) 2017 AT&T 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;
31 import java.net.URISyntaxException;
33 import java.net.URLDecoder;
34 import java.net.URLEncoder;
35 import java.util.ArrayList;
36 import java.util.Arrays;
37 import java.util.HashMap;
38 import java.util.LinkedList;
39 import java.util.List;
42 import java.util.SortedSet;
43 import java.util.TreeSet;
44 import java.util.regex.Matcher;
45 import java.util.regex.Pattern;
47 import javax.xml.bind.annotation.XmlType;
49 import org.apache.commons.lang.StringUtils;
50 import org.onap.ccsdk.sli.adaptors.aai.data.AAIDatum;
51 import org.onap.ccsdk.sli.adaptors.aai.query.FormattedQueryResultList;
52 import org.onap.ccsdk.sli.adaptors.aai.query.InstanceFilter;
53 import org.onap.ccsdk.sli.adaptors.aai.query.InstanceFilters;
54 import org.onap.ccsdk.sli.adaptors.aai.query.NamedQuery;
55 import org.onap.ccsdk.sli.adaptors.aai.query.NamedQueryData;
56 import org.onap.ccsdk.sli.adaptors.aai.query.QueryParameters;
57 import org.onap.ccsdk.sli.adaptors.aai.query.Result;
58 import org.onap.ccsdk.sli.core.sli.SvcLogicContext;
59 import org.onap.ccsdk.sli.core.sli.SvcLogicException;
60 import org.onap.aai.inventory.v14.GenericVnf;
61 import org.onap.aai.inventory.v14.Image;
62 import org.onap.aai.inventory.v14.InventoryResponseItem;
63 import org.onap.aai.inventory.v14.InventoryResponseItems;
64 import org.onap.aai.inventory.v14.L3Network;
65 import org.onap.aai.inventory.v14.LogicalLink;
66 import org.onap.aai.inventory.v14.Metadata;
67 import org.onap.aai.inventory.v14.Metadatum;
68 import org.onap.aai.inventory.v14.Pnf;
69 import org.onap.aai.inventory.v14.RelatedToProperty;
70 import org.onap.aai.inventory.v14.Relationship;
71 import org.onap.aai.inventory.v14.RelationshipData;
72 import org.onap.aai.inventory.v14.RelationshipList;
73 import org.onap.aai.inventory.v14.ResultData;
74 import org.onap.aai.inventory.v14.SearchResults;
75 import org.onap.aai.inventory.v14.ServiceInstance;
76 import org.onap.aai.inventory.v14.Vlan;
77 import org.onap.aai.inventory.v14.Vlans;
78 import org.onap.aai.inventory.v14.Vserver;
79 import org.slf4j.Logger;
80 import org.slf4j.LoggerFactory;
82 import com.fasterxml.jackson.core.JsonParseException;
83 import com.fasterxml.jackson.databind.JsonMappingException;
84 import com.fasterxml.jackson.databind.ObjectMapper;
87 public abstract class AAIDeclarations implements AAIClient {
89 public static final String TRUSTSTORE_PATH = "org.onap.ccsdk.sli.adaptors.aai.ssl.trust";
90 public static final String TRUSTSTORE_PSSWD = "org.onap.ccsdk.sli.adaptors.aai.ssl.trust.psswd";
91 public static final String KEYSTORE_PATH = "org.onap.ccsdk.sli.adaptors.aai.ssl.key";
92 public static final String KEYSTORE_PSSWD = "org.onap.ccsdk.sli.adaptors.aai.ssl.key.psswd";
94 public static final String APPLICATION_ID = "org.onap.ccsdk.sli.adaptors.aai.application";
96 public static final String CLIENT_NAME = "org.onap.ccsdk.sli.adaptors.aai.client.name";
97 public static final String CLIENT_PWWD = "org.onap.ccsdk.sli.adaptors.aai.client.psswd";
100 public static final String CONNECTION_TIMEOUT = "connection.timeout";
101 public static final String READ_TIMEOUT = "read.timeout";
103 public static final String TARGET_URI = "org.onap.ccsdk.sli.adaptors.aai.uri";
105 public static final String AAI_VERSION = "org.onap.ccsdk.sli.adaptors.aai.version";
107 // Availability zones query
108 public static final String QUERY_PATH = "org.onap.ccsdk.sli.adaptors.aai.path.query";
111 public static final String UPDATE_PATH = "org.onap.ccsdk.sli.adaptors.aai.update";
114 public static final String SVC_INSTANCE_PATH = "org.onap.ccsdk.sli.adaptors.aai.path.svcinst";
115 public static final String SVC_INST_QRY_PATH = "org.onap.ccsdk.sli.adaptors.aai.path.svcinst.query";
118 public static final String NETWORK_VSERVER_PATH = "org.onap.ccsdk.sli.adaptors.aai.path.vserver";
120 public static final String VNF_IMAGE_QUERY_PATH = "org.onap.ccsdk.sli.adaptors.aai.path.vnf.image.query";
122 public static final String PARAM_SERVICE_TYPE = "org.onap.ccsdk.sli.adaptors.aai.param.service.type";
123 public static final String CERTIFICATE_HOST_ERROR = "org.onap.ccsdk.sli.adaptors.aai.host.certificate.ignore";
126 public static final String UBB_NOTIFY_PATH = "org.onap.ccsdk.sli.adaptors.aai.path.notify";
127 public static final String SELFLINK_AVPN = "org.onap.ccsdk.sli.adaptors.aai.notify.selflink.avpn";
128 public static final String SELFLINK_FQDN = "org.onap.ccsdk.sli.adaptors.aai.notify.selflink.fqdn";
131 public static final String SERVICE_PATH = "org.onap.ccsdk.sli.adaptors.aai.path.service";
134 public static final String P_INTERFACE_PATH = "org.onap.ccsdk.sli.adaptors.aai.path.pserver.pinterface";
137 public static final String SITE_PAIR_SET_PATH = "org.onap.ccsdk.sli.adaptors.aai.path.site.pair.set";
140 public static final String QUERY_NODES_PATH = "org.onap.ccsdk.sli.adaptors.aai.query.nodes";
142 private static final String VERSION_PATTERN = "/v$/";
145 protected abstract Logger getLogger();
146 public abstract AAIExecutorInterface getExecutor();
150 public QueryStatus query(String resource, boolean localOnly, String select, String key, String prefix, String orderBy, SvcLogicContext ctx)
151 throws SvcLogicException {
153 getLogger().debug("AAIService.query \tresource = "+resource);
156 String vnfName = null;
157 HashMap<String, String> nameValues = AAIServiceUtils.keyToHashMap(key, ctx);
158 getLogger().debug("key = "+ nameValues.toString());
160 if(!AAIServiceUtils.isValidFormat(resource, nameValues)) {
161 ctx.setAttribute(String.format("%s.error.message", prefix), String.format("Resource %s is not supported. Key string contains invaid identifiers", resource));
162 return QueryStatus.FAILURE;
165 if(resource == null || resource.isEmpty() || AAIRequest.createRequest(resource, nameValues) == null) {
166 ctx.setAttribute(String.format("%s.error.message", prefix), String.format("Resource %s is not supported", resource));
167 return QueryStatus.FAILURE;
170 // process data using new model
171 boolean useNewModelProcessing = true;
172 // process server query by name the old way
173 if("vserver".equals(resource) || "vserver2".equals(resource)){
174 if(nameValues.containsKey("vserver_name") || nameValues.containsKey("vserver-name") || nameValues.containsKey("vserver.vserver_name") || nameValues.containsKey("vserver.vserver-name"))
175 useNewModelProcessing = false;
177 if("generic-vnf".equals(resource)){
178 if(nameValues.containsKey("vnf_name") || nameValues.containsKey("vnf-name") || nameValues.containsKey("generic_vnf.vnf_name") || nameValues.containsKey("generic-vnf.vnf-name"))
179 useNewModelProcessing = false;
182 // process data using new model
183 if(useNewModelProcessing && AAIRequest.createRequest(resource, nameValues) != null) {
186 return newModelQuery(resource, localOnly, select, key, prefix, orderBy, ctx);
187 } catch (Exception exc) {
188 getLogger().warn("Failed query - returning FAILURE", exc);
189 return QueryStatus.FAILURE;
193 ObjectMapper mapper = AAIService.getObjectMapper();
194 Map<String,Object> attributes = new HashMap<>();
196 String modifier = null;
198 if(resource.contains(":")) {
199 String[] tokens = resource.split(":");
200 resource = tokens[0];
201 if(tokens.length > 1) {
202 modifier = tokens[1];
206 resource = resource.toLowerCase().replace("-", "_");
212 vnfId = nameValues.get("vnf_id");
213 if(nameValues.containsKey("vnf_id"))
214 vnfId = nameValues.get("vnf_id");
215 else if(nameValues.containsKey("generic_vnf.vnf_name"))
216 vnfId = nameValues.get("generic_vnf.vserver_name");
218 if(nameValues.containsKey("vnf_name"))
219 vnfName = nameValues.get("vnf_name");
220 else if(nameValues.containsKey("generic_vnf.vnf_name"))
221 vnfName = nameValues.get("generic_vnf.vnf_name");
223 if(vnfId != null && !vnfId.isEmpty()) {
224 // at this point of the project this part should not be executed
225 vnfId = vnfId.trim().replace("'", "").replace("$", "").replace("'", "");
226 GenericVnf vnf = this.requestGenericVnfData(vnfId);
228 return QueryStatus.NOT_FOUND;
231 attributes = mapper.convertValue(vnf, attributes.getClass());
232 } else if(vnfName != null && !vnfName.isEmpty()) {
234 vnfName = vnfName.trim().replace("'", "").replace("$", "").replace("'", "");
235 GenericVnf vnf = this.requestGenericVnfeNodeQuery(vnfName);
237 return QueryStatus.NOT_FOUND;
239 vnfId=vnf.getVnfId();
240 nameValues.put("vnf_id", vnfId);
241 attributes = mapper.convertValue(vnf, attributes.getClass());
242 } catch (AAIServiceException exc) {
243 int errorCode = exc.getReturnCode();
250 getLogger().warn("Caught exception trying to refresh generic VNF", exc);
252 ctx.setAttribute(prefix + ".error.message", exc.getMessage());
253 if(errorCode >= 300) {
254 ctx.setAttribute(prefix + ".error.http.response-code",
255 Integer.toString(exc.getReturnCode()));
257 return QueryStatus.FAILURE;
260 getLogger().warn("No arguments are available to process generic VNF");
261 return QueryStatus.FAILURE;
266 String vserverName = null;
267 if(nameValues.containsKey("vserver_name"))
268 vserverName = nameValues.get("vserver_name");
269 else if(nameValues.containsKey("vserver.vserver_name"))
270 vserverName = nameValues.get("vserver.vserver_name");
272 String vserverId = null;
273 if(nameValues.containsKey("vserver_id"))
274 vserverId = nameValues.get("vserver_id");
275 if(nameValues.containsKey("vserver.vserver_id"))
276 vserverId = nameValues.get("vserver.vserver_id");
277 String tenantId = nameValues.get("teannt_id");
279 if(vserverName != null) vserverName = vserverName.trim().replace("'", "").replace("$", "").replace("'", "");
280 if(vserverId != null) vserverId = vserverId.trim().replace("'", "").replace("$", "").replace("'", "");
281 if(tenantId != null) tenantId = tenantId.trim().replace("'", "").replace("$", "").replace("'", "");
283 if (vserverName != null) {
284 URL vserverUrl = null;
286 vserverUrl = this.requestVserverURLNodeQuery(vserverName);
287 } catch (AAIServiceException aaiexc) {
288 ctx.setAttribute(prefix + ".error.message", aaiexc.getMessage());
289 if (aaiexc.getReturnCode() >= 300) {
290 ctx.setAttribute(prefix + ".error.http" + "" + ".response-code", Integer.toString(aaiexc.getReturnCode()));
293 if (aaiexc.getReturnCode() == 404)
294 return QueryStatus.NOT_FOUND;
296 return QueryStatus.FAILURE;
298 if (vserverUrl == null) {
299 return QueryStatus.NOT_FOUND;
302 tenantId = getTenantIdFromVserverUrl(vserverUrl);
303 String cloudOwner = getCloudOwnerFromVserverUrl(vserverUrl);
304 String cloudRegionId = getCloudRegionFromVserverUrl(vserverUrl);
306 Vserver vserver = null;
308 vserver = this.requestVServerDataByURL(vserverUrl);
309 } catch (AAIServiceException aaiexc) {
310 ctx.setAttribute(prefix + ".error.message", aaiexc.getMessage());
311 if (aaiexc.getReturnCode() >= 300) {
312 ctx.setAttribute(prefix + ".error.http" + ".response-code", Integer.toString(aaiexc.getReturnCode()));
315 if (aaiexc.getReturnCode() == 404)
316 return QueryStatus.NOT_FOUND;
318 return QueryStatus.FAILURE;
320 if (vserver == null) {
321 return QueryStatus.NOT_FOUND;
323 attributes = mapper.convertValue(vserver, attributes.getClass());
324 if (!attributes.containsKey("tenant-id") && tenantId != null) {
325 attributes.put("tenant-id", tenantId);
327 if (!attributes.containsKey("cloud-owner") && cloudOwner != null) {
328 attributes.put("cloud-owner", cloudOwner);
330 if (!attributes.containsKey("cloud-region-id") && cloudRegionId != null) {
331 attributes.put("cloud-region-id", cloudRegionId);
333 } else if (vserverId != null && tenantId != null) {
334 Vserver vserver = this.requestVServerData(tenantId, vserverId, "att-aic", "AAIAIC25");
335 if(vserver == null) {
336 return QueryStatus.NOT_FOUND;
338 attributes = mapper.convertValue(vserver, attributes.getClass());
339 if(!attributes.containsKey("tenant-id") && tenantId != null){
340 attributes.put("tenant-id", tenantId);
343 return QueryStatus.FAILURE;
348 return QueryStatus.FAILURE;
351 QueryStatus retval = QueryStatus.SUCCESS;
353 if (attributes == null || attributes.isEmpty()) {
354 retval = QueryStatus.NOT_FOUND;
355 getLogger().debug("No data found");
358 if (prefix != null) {
359 ArrayList<String> keys = new ArrayList<>(attributes.keySet());
361 int numCols = keys.size();
363 for (int i = 0; i < numCols; i++) {
365 String colName = keys.get(i);
366 Object object = attributes.get(colName);
368 if(object != null && object instanceof String) {
369 colValue = (String)object;
371 if (prefix != null) {
372 getLogger().debug("Setting "+prefix + "." + colName.replaceAll("_", "-")+" = "+ colValue);
373 ctx.setAttribute(prefix + "." + colName.replaceAll("_", "-"), colValue);
375 getLogger().debug("Setting " + colValue.replaceAll("_", "-")+" = "+colValue);
376 ctx.setAttribute(colValue.replaceAll("_", "-"), colValue);
378 } else if(object != null && object instanceof Map) {
379 if(colName.equals(modifier) || "relationship-list".equals(colName)){
380 String localNodifier = modifier;
381 if(localNodifier == null)
382 localNodifier = "relationship-list";
383 Map<String, Object> properties = (Map<String, Object>)object;
384 writeMap(properties, prefix+"."+localNodifier, ctx);
391 getLogger().debug("Query - returning " + retval);
394 } catch (Exception exc) {
395 getLogger().warn("Failed query - returning FAILURE", exc);
396 return QueryStatus.FAILURE;
401 public void writeMap(Map<String, Object> properties, String prefix, SvcLogicContext ctx) {
402 Set<String> mapKeys = properties.keySet();
404 for(String mapKey : mapKeys) {
405 Object entity = properties.get(mapKey);
406 if(entity instanceof ArrayList) {
407 writeList((ArrayList<?>)entity, prefix + "." + mapKey, ctx);
409 if(entity instanceof String || entity instanceof Long || entity instanceof Integer || entity instanceof Boolean) {
410 ctx.setAttribute(prefix + "." + mapKey, entity.toString());
411 getLogger().debug(prefix + "." + mapKey + " : " + entity.toString());
412 } else if(entity instanceof Map) {
413 String localPrefix = prefix;
415 localPrefix = String.format("%s.%s", prefix, mapKey);
417 writeMap( (Map<String, Object>)entity, localPrefix, ctx);
422 private void writeList(ArrayList<?> list, String prefix, SvcLogicContext ctx) {
423 for(int i = 0; i < list.size(); i++ ) {
424 Object entity = list.get(i);
425 if(entity instanceof Map) {
426 writeMap( (Map<String, Object>)entity, prefix + "[" + i + "]", ctx);
428 if(entity instanceof String || entity instanceof Long || entity instanceof Integer || entity instanceof Boolean) {
429 ctx.setAttribute(prefix, entity.toString());
430 getLogger().debug(prefix + " : " + entity.toString());
434 if(!list.isEmpty()) {
435 ctx.setAttribute(prefix + "_length", Integer.toString(list.size()));
436 getLogger().debug(prefix + "_length" + " : " + Integer.toString(list.size()));
441 public QueryStatus save(String resource, boolean force, boolean localOnly, String key, Map<String, String> params, String prefix, SvcLogicContext ctx)
442 throws SvcLogicException {
444 getLogger().debug("AAIService.save\tresource="+resource);
445 HashMap<String, String> nameValues = AAIServiceUtils.keyToHashMap(key, ctx);
447 if(!AAIServiceUtils.isValidFormat(resource, nameValues)) {
448 ctx.setAttribute(String.format("%s.error.message", prefix), String.format("Resource %s is not supported. Key string contains invaid identifiers", resource));
449 return QueryStatus.FAILURE;
452 if(resource == null || resource.isEmpty() || AAIRequest.createRequest(resource, nameValues) == null) {
453 getLogger().warn("AAIService.save has unspecified resource");
454 ctx.setAttribute(String.format("%s.error.message", prefix), String.format("Resource %s is not supported", resource));
455 return QueryStatus.FAILURE;
458 getLogger().debug("key = "+ Arrays.toString(nameValues.entrySet().toArray()));
461 if(params.containsKey("prefix")) {
462 Map<String, String> tmpParams = ctxGetBeginsWith(ctx, params.get("prefix"));
463 if(!tmpParams.isEmpty()) {
464 params.putAll(tmpParams);
465 // params.remove("prefix");
469 getLogger().debug("parms = "+ Arrays.toString(params.entrySet().toArray()));
471 boolean useNewModelProcessing = true;
472 // process server query by name the old way
473 if("vserver".equals(resource) || "vserver2".equals(resource)){
474 if(nameValues.containsKey("vserver-name")) {
475 useNewModelProcessing = false;
478 if(!params.containsKey("vserver-selflink")) {
480 AAIRequest request = AAIRequest.createRequest(resource, nameValues);
483 request.processRequestPathValues(nameValues);
484 path = request.getRequestUrl("GET", null);
485 params.put("vserver-selflink", path.toString());
486 } catch (UnsupportedEncodingException | MalformedURLException | URISyntaxException e) {
487 params.put("vserver-selflink", "/vserver");
492 // process data using new model
493 if(useNewModelProcessing && AAIRequest.createRequest(resource, nameValues) != null) {
496 if(!resource.contains(":")){
497 return newModelSave(resource, force, key, params, prefix, ctx);
499 String[] tokens = resource.split(":");
500 String localResource = tokens[0];
501 String dependency = tokens[1];
503 AAIDatum instance = newModelObjectRequest( localResource, nameValues, prefix, ctx);
504 if(instance == null) {
505 return QueryStatus.NOT_FOUND;
509 case "relationship-list":
510 newModelProcessRelationshipList(instance, params, prefix, ctx);
513 newModelProcessMetadata(instance, params, prefix, ctx);
516 // create a method to update relationship-list
517 AAIRequest request = AAIRequest.createRequest(localResource, nameValues);
518 request.setRequestObject(instance);
519 request.processRequestPathValues(nameValues);
521 getExecutor().post(request);
522 getLogger().debug("Save relationship list - returning SUCCESS");
523 return QueryStatus.SUCCESS;
525 } catch (Exception exc) {
526 ctx.setAttribute(prefix + ".error.message", exc.getMessage());
527 if(exc instanceof AAIServiceException) {
528 AAIServiceException aaiexc = (AAIServiceException)exc;
529 if(aaiexc.getReturnCode() >= 300) {
530 ctx.setAttribute(prefix + ".error.http" + ".response-code", Integer.toString(aaiexc.getReturnCode()));
533 if(aaiexc.getReturnCode() == 404) {
534 return QueryStatus.NOT_FOUND;
537 getLogger().warn("Failed save() - returning FAILURE", exc);
538 return QueryStatus.FAILURE;
541 getLogger().debug("Save() request for {} is not supported- returning FAILURE", resource);
542 return QueryStatus.FAILURE;
547 public QueryStatus update(String resource, String key, Map<String, String> params, String prefix, SvcLogicContext ctx) throws SvcLogicException {
549 resource = resource.toLowerCase();
550 HashMap<String, String> nameValues = AAIServiceUtils.keyToHashMap(key, ctx);
551 getLogger().debug("key = "+ Arrays.toString(nameValues.entrySet().toArray()));
552 if(!AAIServiceUtils.isValidFormat(resource, nameValues)) {
553 ctx.setAttribute(String.format("%s.error.message", prefix), String.format("Resource %s is not supported. Key string contains invaid identifiers", resource));
554 return QueryStatus.FAILURE;
557 if(resource == null || resource.isEmpty() || AAIRequest.createRequest(resource, nameValues) == null) {
558 ctx.setAttribute(String.format("%s.error.message", prefix), String.format("Resource %s is not supported", resource));
559 return QueryStatus.FAILURE;
562 // check if request is for groups
563 if(!AAIServiceUtils.containsResource(resource, nameValues)) {
564 ctx.setAttribute(String.format("%s.error.message", prefix), String.format("Resource %s is not permitted in 'update' operation", resource));
565 return QueryStatus.FAILURE;
568 getLogger().debug("parms = "+ Arrays.toString(params.entrySet().toArray()));
570 AAIRequest request = AAIRequest.createRequest(resource, nameValues);
571 request = new UpdateRequest(request, params);
573 String[] arguments = request.getArgsList();
574 for(String name : arguments) {
575 String modifiedKey = name.replaceAll("-", "_");
576 if(nameValues.containsKey(modifiedKey)) {
577 String argValue = nameValues.get(modifiedKey);
578 if(argValue != null) argValue = argValue.trim().replace("'", "").replace("$", "").replace("'", "");
579 request.addRequestProperty(name, argValue);
584 QueryStatus retval = QueryStatus.SUCCESS;
586 retval = newModelQuery(resource, false, null, key, "tmpDelete", null, ctx);
588 if(retval == null || retval != QueryStatus.SUCCESS) {
592 String resourceVersion = ctx.getAttribute("tmpDelete.resource-version");
593 if(resourceVersion == null) {
594 return QueryStatus.NOT_FOUND;
596 params.put("resource-version", resourceVersion);
598 request.processRequestPathValues(nameValues);
599 getExecutor().patch(request, resourceVersion);
600 } catch(AAIServiceException aaiexc) {
601 if(aaiexc.getReturnCode() == 404)
602 return QueryStatus.NOT_FOUND;
604 return QueryStatus.FAILURE;
605 } catch (Exception exc) {
606 getLogger().warn("Failed update - returning FAILURE", exc);
607 return QueryStatus.FAILURE;
610 getLogger().debug("Update - returning SUCCESS");
611 return QueryStatus.SUCCESS;
615 public QueryStatus delete(String resource, String key, SvcLogicContext ctx) throws SvcLogicException {
616 getLogger().debug("AAIService.delete\tresource="+resource);
617 HashMap<String, String> nameValues = AAIServiceUtils.keyToHashMap(key, ctx);
618 getLogger().debug("key = "+ Arrays.toString(nameValues.entrySet().toArray()));
620 if(!AAIServiceUtils.isValidFormat(resource, nameValues)) {
621 ctx.setAttribute(String.format("%s.error.message", "aaiData"), String.format("Resource %s is not supported. Key string contains invaid identifiers", resource));
622 return QueryStatus.FAILURE;
625 if(resource == null || resource.isEmpty() || AAIRequest.createRequest(resource, nameValues) == null) {
626 ctx.setAttribute(String.format("%s.error.message", "tmpDelete"), String.format("Resource %s is not supported", resource));
627 return QueryStatus.FAILURE;
630 // check if request is for groups
631 if(!AAIServiceUtils.containsResource(resource, nameValues)) {
632 ctx.setAttribute(String.format("%s.error.message", "tmpDelete"), String.format("Resource %s is not permitted in 'delete' operation", resource));
633 return QueryStatus.FAILURE;
636 if(AAIRequest.createRequest(resource, nameValues) != null) {
637 if(resource.contains(":")) {
638 switch (resource.split(":")[1]){
639 case "relationship-list":
640 return processDeleteRelationshipList(resource, key, ctx, nameValues);
642 return processDeleteMetadata(resource, key, ctx, nameValues);
648 QueryStatus retval = QueryStatus.SUCCESS;
650 retval = newModelQuery(resource, false, null, key, "tmpDelete", null, ctx);
652 if(retval == null || retval != QueryStatus.SUCCESS) {
656 String resourceVersion = ctx.getAttribute("tmpDelete.resource-version");
657 if(resourceVersion == null) {
658 return QueryStatus.NOT_FOUND;
662 AAIRequest request = AAIRequest.createRequest(resource, nameValues);
663 if(request == null) {
664 return QueryStatus.FAILURE;
667 request.processRequestPathValues(nameValues);
669 if(getExecutor().delete(request, resourceVersion)) {
670 return QueryStatus.SUCCESS;
672 } catch(AAIServiceException aaiexc) {
673 if(aaiexc.getReturnCode() == 404)
674 return QueryStatus.NOT_FOUND;
676 return QueryStatus.FAILURE;
678 } catch (Exception exc) {
679 getLogger().warn("requestGenericVnfData", exc);
680 return QueryStatus.FAILURE;
683 } catch (Exception exc) {
684 getLogger().warn("Failed delete - returning FAILURE", exc);
685 return QueryStatus.FAILURE;
688 String resourceName = resource;
689 String identifier = null;
691 if(resourceName.contains(":")) {
692 String[] tokens = resourceName.split(":");
693 if(tokens != null && tokens.length > 0) {
694 resourceName = tokens[0];
695 identifier = tokens[1];
698 if("relationship-list".equals(identifier) || "relationshipList".equals(identifier)) {
699 // RelationshipRequest relationshipRequest = new RelationshipRequest();
700 if("generic-vnf".equals(resourceName)){
701 String vnfId = nameValues.get("vnf_id");
702 String relatedTo = nameValues.get("related_to");
703 vnfId = vnfId.trim().replace("'", "").replace("$", "").replace("'", "");
704 relatedTo = relatedTo.trim().replace("'", "").replace("$", "").replace("'", "");
708 vnf = this.requestGenericVnfData(vnfId);
710 return QueryStatus.NOT_FOUND;
711 } catch (AAIServiceException exc) {
712 getLogger().warn("Failed delete - returning NOT_FOUND", exc);
713 return QueryStatus.NOT_FOUND;
715 boolean itemRemoved = false;
716 RelationshipList relationshipList = vnf.getRelationshipList();
717 List<Relationship> relationships = relationshipList.getRelationship();
718 List<Relationship> iterableList = new LinkedList<>(relationships);
719 for(Relationship relationship : iterableList) {
720 if(relationship.getRelatedTo().equals(relatedTo)) {
721 relationships.remove(relationship);
727 return QueryStatus.NOT_FOUND;
729 this.postGenericVnfData(vnf.getVnfId(), vnf);
730 } catch (AAIServiceException exc) {
731 if(exc.getReturnCode() == 404){
732 return QueryStatus.NOT_FOUND;
734 getLogger().warn("Failed delete - returning FAILURE", exc);
735 return QueryStatus.FAILURE;
738 return QueryStatus.SUCCESS;
742 return QueryStatus.FAILURE;
746 public QueryStatus exists(String resource, String key, String prefix, SvcLogicContext ctx) throws SvcLogicException {
747 return query(resource, false, null, key, prefix, null, ctx);
751 public QueryStatus isAvailable(String arg0, String arg1, String arg2, SvcLogicContext arg3)
752 throws SvcLogicException {
753 throw new SvcLogicException("Method AAIService.isAvailable() has not been implemented yet");
757 public QueryStatus notify(String resource, String action, String key, SvcLogicContext ctx) throws SvcLogicException {
758 throw new SvcLogicException("Method AAIService.notify() has not been implemented yet");
762 public QueryStatus newModelQuery(String resource, boolean localOnly, String select, String key, String prefix, String orderBy, SvcLogicContext ctx) {
764 QueryStatus retval = QueryStatus.SUCCESS;
765 String modifier = null;
767 HashMap<String, String> nameValues = AAIServiceUtils.keyToHashMap(key, ctx);
768 if(resource.contains(":")) {
769 modifier = resource.split(":")[1];
773 AAIRequest request = AAIRequest.createRequest(resource, nameValues);
774 if(request == null) {
775 return QueryStatus.FAILURE;
778 Map<String, String> params = new HashMap<>();
780 request.processRequestPathValues(nameValues);
781 if(nameValues.containsKey("prefix")){
782 Map<String, String> tmpParams = ctxGetBeginsWith(ctx, nameValues.get("prefix"));
783 if(!tmpParams.isEmpty()) {
784 params.putAll(tmpParams);
786 if("named-query".equals(resource))
787 request.setRequestObject(extractNamedQueryDataFromQueryPrefix(nameValues, params));
789 String rv = getExecutor().get(request);
791 retval = processResponseData(rv, resource, request, prefix, ctx, nameValues, modifier);
793 } catch(AAIServiceException aaiexc) {
794 int errorCode = aaiexc.getReturnCode();
795 ctx.setAttribute(prefix + ".error.message", aaiexc.getMessage());
796 if(errorCode >= 300) {
797 ctx.setAttribute(prefix + ".error.http.response-code",
798 Integer.toString(aaiexc.getReturnCode()));
801 if(aaiexc.getReturnCode() == 404)
802 return QueryStatus.NOT_FOUND;
804 return QueryStatus.FAILURE;
805 } catch (Exception exc) {
806 getLogger().warn("requestGenericVnfData", exc);
807 ctx.setAttribute(prefix + ".error.message", exc.getMessage());
808 return QueryStatus.FAILURE;
814 public QueryStatus processResponseData(String rv, String resource, AAIRequest request, String prefix, SvcLogicContext ctx, Map<String, String> nameValues, String modifier) throws JsonParseException, JsonMappingException, IOException, AAIServiceException
819 return QueryStatus.NOT_FOUND;
822 response = request.jsonStringToObject(rv);
823 if(response == null) {
824 return QueryStatus.NOT_FOUND;
827 if("generic-query".equals(resource)) {
828 SearchResults rd = SearchResults.class.cast(response);
829 List<ResultData> rdList = rd.getResultData();
830 if(rdList == null || rdList.isEmpty()) {
831 return QueryStatus.NOT_FOUND;
833 ResultData rDatum = rdList.get(0);
834 nameValues.put("selflink", rDatum.getResourceLink());
835 AAIRequest req2 = AAIRequest.createRequest(rDatum.getResourceType(), nameValues);
836 req2.processRequestPathValues(nameValues);
837 rv = getExecutor().get(req2);
839 return QueryStatus.NOT_FOUND;
842 response = req2.jsonStringToObject(rv);
843 if(response == null) {
844 return QueryStatus.NOT_FOUND;
848 if("named-query".equals(resource)) {
849 InventoryResponseItems rd = InventoryResponseItems.class.cast(response);
850 List<InventoryResponseItem> iRIlist = rd.getInventoryResponseItem();
851 if(iRIlist == null || iRIlist.isEmpty()) {
852 return QueryStatus.NOT_FOUND;
856 if("nodes-query".equals(resource)) {
857 SearchResults rd = SearchResults.class.cast(response);
858 List<ResultData> rdList = rd.getResultData();
859 if(rdList == null || rdList.isEmpty()) {
860 return QueryStatus.NOT_FOUND;
862 ResultData rDatum = rdList.get(0);
866 if("formatted-query".equals(resource) || "custom-query".equals(resource)) {
867 FormattedQueryResultList rd = FormattedQueryResultList.class.cast(response);
868 List<Result> iRIlist = rd.getResults();
869 if(iRIlist == null || iRIlist.isEmpty()) {
870 return QueryStatus.NOT_FOUND;
874 // process relationship list
875 // this is a temporary soluton to address the realationship handling changes added in Release 17.07
877 Class<?> clazz = response.getClass();
878 Method getter = clazz.getMethod("getRelationshipList");
879 Object obj = getter.invoke(response);
880 if(obj != null && obj instanceof RelationshipList) {
881 RelationshipList list = RelationshipList.class.cast(obj);
882 AAIServiceUtils.populateRelationshipDataFromPath(list);
884 } catch(Exception exc) {
885 getLogger().debug("Retrofiting relationship data: " + exc.getMessage());
889 if(prefix == null || prefix.isEmpty()) {
892 preFix = prefix + ".";
895 Map<String,Object> props = objectToProperties(response);
896 Set<String> keys = props.keySet();
897 for(String theKey: keys) {
898 if(getLogger().isTraceEnabled())
899 getLogger().trace(theKey);
901 Object value = props.get(theKey);
904 Object type = value.getClass();
905 if(value instanceof String) {
906 ctx.setAttribute(preFix + theKey, value.toString());
909 if(value instanceof Boolean) {
910 ctx.setAttribute(preFix + theKey, value.toString());
913 if(value instanceof Integer) {
914 ctx.setAttribute(preFix + theKey, value.toString());
917 if(value instanceof Long) {
918 ctx.setAttribute(preFix + theKey, value.toString());
922 if(value instanceof ArrayList) {
923 ArrayList<?> array = ArrayList.class.cast(value);
924 for(int i = 0; i < array.size(); i++) {
925 writeList(array, String.format("%s.%s", prefix, theKey), ctx);
930 if("relationship-list".equals(theKey)){
931 Map<String, Object> relationshipList = (Map<String, Object>)value;
932 // we are interested in seeing just the selected relationship
933 if(theKey.equals(modifier)) {
934 List<?> relationships = (List<?>)relationshipList.get("relationship");
935 if(relationships != null && !relationships.isEmpty()) {
937 List newRelationships = new LinkedList();
938 newRelationships.addAll(relationships);
940 for(Object obj : newRelationships){
941 if(obj instanceof Map<?, ?>) {
942 Map<?, ?> relProperties = (Map<?, ?>)obj;
943 if(relProperties.containsKey("related-to")) {
944 Object relPropsRelatedTo = relProperties.get("related-to");
946 String relatedTo = nameValues.get("related_to");
947 if(relatedTo != null) {
948 relatedTo = relatedTo.trim().replace("'", "").replace("$", "").replace("'", "");
949 if(!relatedTo.equals(relPropsRelatedTo)) {
950 relationships.remove(relProperties);
961 writeMap(relationshipList, String.format("%s.%s", prefix, theKey), ctx);
965 if(value instanceof Map) {
966 Map<String, Object> subnetsList = (Map<String, Object>)value;
967 writeMap(subnetsList, String.format("%s.%s", prefix, theKey), ctx);
972 return QueryStatus.SUCCESS;
976 public QueryStatus newModelBackupRequest(String resource, Map<String, String> params, String prefix, SvcLogicContext ctx) {
978 QueryStatus retval = QueryStatus.SUCCESS;
979 HashMap<String, String> nameValues = new HashMap<>();
982 AAIRequest request = AAIRequest.createRequest(resource, nameValues);
983 if(request == null) {
984 return QueryStatus.FAILURE;
987 boolean argsFound = false;
988 String[] arguments = request.getArgsList();
989 for(String name : arguments) {
990 String tmpName = name.replaceAll("-", "_");
991 String value = params.get(tmpName);
992 if(value != null && !value.isEmpty()) {
993 value = value.trim().replace("'", "").replace("$", "").replace("'", "");
994 request.addRequestProperty(name, value);
999 getLogger().warn("No arguments were found. Terminating backup request.");
1000 return QueryStatus.FAILURE;
1003 String rv = getExecutor().get(request);
1004 ctx.setAttribute(prefix, rv);
1005 } catch(AAIServiceException aaiexc) {
1006 if(aaiexc.getReturnCode() == 404)
1007 return QueryStatus.NOT_FOUND;
1009 return QueryStatus.FAILURE;
1010 } catch (Exception exc) {
1011 getLogger().warn("newModelBackupRequest", exc);
1012 return QueryStatus.FAILURE;
1018 public AAIDatum newModelObjectRequest(String resource, Map<String, String> params, String prefix, SvcLogicContext ctx)
1019 throws AAIServiceException {
1021 AAIDatum response = null;
1024 AAIRequest request = AAIRequest.createRequest(resource, params);
1025 if(request == null) {
1029 request.processRequestPathValues(params);
1030 String rv = getExecutor().get(request);
1031 response = request.jsonStringToObject(rv);
1032 } catch(AAIServiceException aaiexc) {
1034 } catch (Exception exc) {
1035 getLogger().warn("newModelBackupRequest", exc);
1036 throw new AAIServiceException(exc);
1044 public QueryStatus release(String arg0, String arg1, SvcLogicContext arg2) throws SvcLogicException {
1045 throw new SvcLogicException("Method AAIService.release() has not been implemented yet");
1049 public QueryStatus reserve(String arg0, String arg1, String arg2, String arg3, SvcLogicContext arg4)
1050 throws SvcLogicException {
1051 throw new SvcLogicException("Method AAIService.reserve() has not been implemented yet");
1054 private QueryStatus newModelSave(String resource, boolean force, String key, Map<String, String> params, String prefix, SvcLogicContext ctx) {
1055 getLogger().debug("Executing newModelSave for resource : " + resource);
1056 HashMap<String, String> nameValues = AAIServiceUtils.keyToHashMap(key, ctx);
1059 ArrayList<String> subResources = new ArrayList<>();
1060 Set<String> set = params.keySet();
1061 Map<String, Method> setters = new HashMap<>();
1062 Map<String, Method> getters = new HashMap<>();
1065 AAIRequest request = AAIRequest.createRequest(resource, nameValues);
1066 Class<? extends AAIDatum> resourceClass = request.getModelClass();
1067 getLogger().debug(resourceClass.getName());
1068 AAIDatum instance = resourceClass.newInstance();
1071 Annotation[] annotations = resourceClass.getAnnotations();
1072 for(Annotation annotation : annotations) {
1073 Class<? extends Annotation> anotationType = annotation.annotationType();
1074 String annotationName = anotationType.getName();
1076 // 2. find string property setters and getters for the lists
1077 if("javax.xml.bind.annotation.XmlType".equals(annotationName)){
1078 XmlType order = (XmlType)annotation;
1079 String[] values = order.propOrder();
1080 for(String value : values) {
1081 String id = AAIServiceUtils.camelCaseToDashedString(value);
1082 Field field = resourceClass.getDeclaredField(value);
1083 Class<?> type = field.getType();
1084 Method setter = null;
1086 setter = resourceClass.getMethod("set"+StringUtils.capitalize(value), type);
1087 if(type.getName().startsWith("java.lang") || "boolean".equals(type.getName()) || "long".equals(type.getName()) || "int".equals(type.getName())) {
1089 Object arglist[] = new Object[1];
1090 arglist[0] = params.get(id);
1092 if(arglist[0] != null) {
1093 if(!type.getName().equals("java.lang.String")) {
1094 // getLogger().debug(String.format("Processing %s with parameter %s", types[0].getName(), value));
1095 if("java.lang.Long".equals(type.getName()) || "java.lang.Integer".equals(type.getName())) {
1096 String fv = params.get(id);
1097 if(fv == null || fv.isEmpty()) {
1100 arglist[0] = valueOf(type, params.get(id));
1102 } else if("boolean".equals(type.getName())) {
1103 arglist[0] = valueOf(Boolean.class, params.get(id));
1104 } else if("int".equals(type.getName())) {
1105 arglist[0] = valueOf(Integer.class, params.get(id));
1106 } else if("long".equals(type.getName())) {
1107 String fv = params.get(id);
1108 if(fv == null || fv.isEmpty()) {
1111 arglist[0] = valueOf(Long.class, params.get(id));
1114 arglist[0] = valueOf(type, params.get(id));
1117 Object obj = setter.invoke(instance, arglist);
1121 } catch (Exception x) {
1122 Throwable cause = x.getCause();
1123 getLogger().warn("Failed process for " + resourceClass.getName(), x);
1125 } else if("java.util.List".equals(type.getName())) {
1126 List<String> newValues = new ArrayList<>();
1127 String length = id+"_length";
1128 if(!params.isEmpty() && params.containsKey(length)) {
1129 String tmp = params.get(length);
1130 int count = Integer.parseInt(tmp);
1131 for(int i=0; i<count; i++) {
1132 String tmpValue = params.get(String.format("%s[%d]", id, i));
1133 newValues.add(tmpValue);
1135 if(!newValues.isEmpty()) {
1136 Object o = setter.invoke(instance, newValues);
1141 setters.put(id, setter);
1143 } catch(Exception exc) {
1149 getter = resourceClass.getMethod("get"+StringUtils.capitalize(value));
1150 if(!type.getName().equals("java.lang.String")) {
1151 getters.put(id, getter);
1153 } catch(Exception exc) {
1158 subResources.addAll(Arrays.asList(values));
1163 // remove getters that have matching setter
1164 for(String setKey : setters.keySet()) {
1165 if(getters.containsKey(setKey)) {
1166 getters.remove(setKey);
1170 Set<String> relationshipKeys = new TreeSet<>();
1171 Set<String> vlansKeys = new TreeSet<>();
1172 Set<String> metadataKeys = new TreeSet<>();
1174 for(String attribute : set) {
1175 String value = params.get(attribute);
1176 if(attribute.startsWith("relationship-list")) {
1177 relationshipKeys.add(attribute);
1178 } else if(attribute.startsWith("vlans")) {
1179 vlansKeys.add(attribute);
1180 } else if(attribute.startsWith("metadata")) {
1181 metadataKeys.add(attribute);
1184 // 3. find list property getters
1185 for(String attribute : set) {
1186 String value = params.get(attribute);
1187 Method method = getters.get(attribute);
1188 if(method != null) {
1190 Object arglist[] = new Object[0];
1191 // arglist[0] = value;
1192 Class<?>[] types = method.getParameterTypes();
1193 if(types.length == 0){
1194 Object o = method.invoke(instance, arglist);
1195 if(o instanceof ArrayList) {
1196 ArrayList<String> values = (ArrayList<String>)o;
1197 // getLogger().debug(String.format("Processing %s with parameter %s", types[0].getName(), value));
1198 value = value.replace("[", "").replace("]", "");
1199 List<String> items = Arrays.asList(value.split("\\s*,\\s*"));
1200 for(String s : items) {
1201 values.add(s.trim());
1205 } catch (Exception x) {
1206 Throwable cause = x.getCause();
1207 getLogger().warn("Failed process for " + resourceClass.getName(), x);
1211 // 4. Process Relationships
1212 // add relationship list
1213 if( (subResources.contains("relationship-list") || subResources.contains("relationshipList")) && !relationshipKeys.isEmpty()) {
1214 RelationshipList relationshipList = null;
1216 Method getRelationshipListMethod = null;
1218 getRelationshipListMethod = resourceClass.getMethod("getRelationshipList");
1219 } catch(Exception exc) {
1220 getLogger().debug("Retrofiting relationship data: " + exc.getMessage());
1223 if(getRelationshipListMethod != null){
1225 obj = getRelationshipListMethod.invoke(instance);
1226 } catch (InvocationTargetException x) {
1227 Throwable cause = x.getCause();
1230 if(obj != null && obj instanceof RelationshipList){
1231 relationshipList = (RelationshipList)obj;
1233 relationshipList = new RelationshipList();
1234 Method setRelationshipListMethod = resourceClass.getMethod("setRelationshipList", RelationshipList.class);
1235 if(setRelationshipListMethod != null){
1237 Object arglist[] = new Object[1];
1238 arglist[0] = relationshipList;
1240 obj = setRelationshipListMethod.invoke(instance, arglist);
1241 } catch (InvocationTargetException x) {
1242 Throwable cause = x.getCause();
1247 List<Relationship> relationships = relationshipList.getRelationship();
1251 String searchKey = "relationship-list.relationship[" + i + "].related-to";
1252 if(!params.containsKey(searchKey))
1255 String relatedTo = params.get(searchKey);
1256 String relatedLinkKey = "relationship-list.relationship[" + i + "].related-link";
1257 String relatedLink = null;
1258 if(params.containsKey(relatedLinkKey)) {
1259 relatedLink = params.get(relatedLinkKey);
1261 Relationship relationship = new Relationship();
1262 relationships.add(relationship);
1263 relationship.setRelatedTo(relatedTo);
1264 String relationshipLabel = "relationship-list.relationship[" + i + "].relationship-label";
1265 if(params.containsKey(searchKey)) {
1266 relationship.setRelationshipLabel(params.get(relationshipLabel));
1268 getLogger().debug("About to process related link of {}", relatedLink);
1269 if(relatedLink != null) {
1270 if(relatedLink.contains("v$"))
1271 relatedLink = relatedLink.replace(VERSION_PATTERN, "/v14/");
1272 relationship.setRelatedLink(relatedLink);
1274 Map<String, String> relParams = new HashMap<>();
1277 String searchRelationshipKey = "relationship-list.relationship[" + i + "].relationship-data[" + j + "].relationship-key";
1278 String searchRelationshipValue = "relationship-list.relationship[" + i + "].relationship-data[" + j + "].relationship-value";
1279 if(!params.containsKey(searchRelationshipKey))
1282 relParams.put(params.get(searchRelationshipKey), params.get(searchRelationshipValue));
1285 AAIRequest rlRequest = AAIRequest.createRequest(relatedTo, relParams);
1286 for(Map.Entry<String,String> entry : relParams.entrySet()) {
1287 rlRequest.addRequestProperty(entry.getKey(), entry.getValue());
1289 String path = rlRequest.updatePathDataValues(null);
1290 relationship.setRelatedLink(path);
1294 // process related to properties
1295 Map<String, String> relParams = new HashMap<String, String>();
1298 String searchRelatedToKey = "relationship-list.relationship[" + i + "].related-to-property[" + k + "].property-key";
1299 String searchRelatedToValue = "relationship-list.relationship[" + i + "].related-to-property[" + k + "].property-value";
1300 if(!params.containsKey(searchRelatedToKey))
1303 RelatedToProperty relDatum = new RelatedToProperty();
1304 relDatum.setPropertyKey(params.get(searchRelatedToKey));
1305 relDatum.setPropertyValue(params.get(searchRelatedToValue));
1306 relationship.getRelatedToProperty().add(relDatum);
1308 relParams.put(params.get(searchRelatedToKey), params.get(searchRelatedToValue));
1317 if(subResources.contains("vlans") && !vlansKeys.isEmpty()) {
1319 Vlans vlanList = null;
1320 Method getVLansMethod = resourceClass.getMethod("getVlans");
1321 if(getVLansMethod != null){
1323 obj = getVLansMethod.invoke(instance);
1324 } catch (InvocationTargetException x) {
1325 Throwable cause = x.getCause();
1328 if(obj != null && obj instanceof Vlans){
1329 vlanList = (Vlans)obj;
1331 vlanList = new Vlans();
1332 Method setVlansMethod = resourceClass.getMethod("setVlans", Vlans.class);
1333 if(setVlansMethod != null){
1335 Object arglist[] = new Object[1];
1336 arglist[0] = vlanList;
1338 obj = setVlansMethod.invoke(instance, arglist);
1339 } catch (InvocationTargetException x) {
1340 Throwable cause = x.getCause();
1347 String searchKey = "vlans.vlan[" + i + "].vlan-interface";
1348 if(!params.containsKey(searchKey))
1351 String vlanInterface = params.get("vlans.vlan[" + i + "].vlan-interface");
1352 String vlanIdInner = params.get("vlans.vlan[" + i + "].vlan-id-inner");
1353 String vlanIdOute = params.get("vlans.vlan[" + i + "].vlan-id-outer");
1354 String speedValue = params.get("vlans.vlan[" + i + "].speed-value");
1355 String speedUnits = params.get("vlans.vlan[" + i + "].speed-units");
1357 Vlan vlan = new Vlan();
1358 vlan.setVlanInterface(vlanInterface);
1360 if(vlanIdInner != null) {
1361 Long iVlanIdInner = Long.parseLong(vlanIdInner);
1362 vlan.setVlanIdInner(iVlanIdInner);
1365 if(vlanIdOute != null) {
1366 Long iVlanIdOuter = Long.parseLong(vlanIdOute);
1367 vlan.setVlanIdOuter(iVlanIdOuter);
1370 if(speedValue != null) {
1371 vlan.setSpeedValue(speedValue);
1372 vlan.setSpeedUnits(speedUnits);
1375 vlanList.getVlan().add(vlan);
1381 if(subResources.contains("metadata") && !metadataKeys.isEmpty()) {
1383 Metadata metadataList = null;
1384 Method getMetadataMethod = resourceClass.getMethod("getMetadata");
1385 if(getMetadataMethod != null){
1387 obj = getMetadataMethod.invoke(instance);
1388 } catch (InvocationTargetException x) {
1389 Throwable cause = x.getCause();
1392 if(obj != null && obj instanceof Metadata){
1393 metadataList = (Metadata)obj;
1395 metadataList = new Metadata();
1396 Method setMetadataMethod = resourceClass.getMethod("setMetadata", Metadata.class);
1397 if(setMetadataMethod != null){
1399 Object arglist[] = new Object[1];
1400 arglist[0] = metadataList;
1402 obj = setMetadataMethod.invoke(instance, arglist);
1403 } catch (InvocationTargetException x) {
1404 Throwable cause = x.getCause();
1412 String metaKey = "metadata.metadatum[" + i + "].meta-key";
1413 if(!params.containsKey(metaKey))
1416 String metaValue = params.get("metadata.metadatum[" + i + "].meta-value");
1418 Metadatum vlan = new Metadatum();
1419 vlan.setMetaname(metaKey);
1420 vlan.setMetaval(metaValue);
1422 metadataList.getMetadatum().add(vlan);
1429 // 6. Prepare AAI request
1430 String[] args = request.getArgsList();
1431 for(String arg : args) {
1432 String modifiedKey = arg.replaceAll("-", "_");
1433 if(nameValues.containsKey(modifiedKey)) {
1434 String argValue = nameValues.get(modifiedKey);
1435 if(argValue != null) argValue = argValue.trim().replace("'", "").replace("$", "").replace("'", "");
1436 request.addRequestProperty(arg, argValue);
1440 request.processRequestPathValues(nameValues);
1441 request.setRequestObject(instance);
1442 Object response = getExecutor().post(request);
1443 if(request.expectsDataFromPUTRequest()){
1444 if(response != null && response instanceof String) {
1445 String rv = response.toString();
1446 QueryStatus retval = processResponseData(rv, resource, request, prefix, ctx, nameValues, null);
1447 getLogger().debug("newModelSave - returning " + retval.toString());
1452 } catch(AAIServiceException exc){
1453 ctx.setAttribute(prefix + ".error.message", exc.getMessage());
1454 int returnCode = exc.getReturnCode();
1455 if(returnCode >= 300) {
1456 ctx.setAttribute(prefix + ".error.http.response-code",
1457 Integer.toString(exc.getReturnCode()));
1460 if(returnCode == 400 || returnCode == 412)
1461 return QueryStatus.FAILURE;
1462 else if(returnCode == 404)
1463 return QueryStatus.NOT_FOUND;
1465 getLogger().warn("Failed newModelSave - returning FAILURE", exc);
1466 return QueryStatus.FAILURE;
1468 } catch(Exception exc){
1469 getLogger().warn("Failed newModelSave - returning FAILURE", exc);
1470 ctx.setAttribute(prefix + ".error.message", exc.getMessage());
1471 return QueryStatus.FAILURE;
1474 getLogger().debug("newModelSave - returning SUCCESS");
1475 return QueryStatus.SUCCESS;
1478 private QueryStatus newModelProcessRelationshipList(Object instance, Map<String, String> params, String prefix, SvcLogicContext ctx) throws Exception {
1480 Class resourceClass = instance.getClass();
1482 Set<String> relationshipKeys = new TreeSet<>();
1484 Set<String> set = params.keySet();
1486 for(String attribute : set) {
1487 String value = params.get(attribute);
1489 if(attribute.startsWith("relationship-list")) {
1490 relationshipKeys.add(attribute);
1494 // 3. Process Relationships
1495 // add relationship list
1496 if(!relationshipKeys.isEmpty()) {
1497 RelationshipList relationshipList;
1499 Method getRelationshipListMethod = null;
1501 getRelationshipListMethod = resourceClass.getMethod("getRelationshipList");
1502 } catch(Exception exc) {
1503 getLogger().debug("Retrofiting relationship data: " + exc.getMessage());
1505 if(getRelationshipListMethod != null){
1507 obj = getRelationshipListMethod.invoke(instance);
1508 } catch (InvocationTargetException x) {
1509 Throwable cause = x.getCause();
1512 if(obj != null && obj instanceof RelationshipList){
1513 relationshipList = (RelationshipList)obj;
1515 relationshipList = new RelationshipList();
1516 Method setRelationshipListMethod = resourceClass.getMethod("setRelationshipList", RelationshipList.class);
1517 if(setRelationshipListMethod != null){
1519 Object arglist[] = new Object[1];
1520 arglist[0] = relationshipList;
1522 obj = setRelationshipListMethod.invoke(instance, arglist);
1523 } catch (InvocationTargetException x) {
1524 Throwable cause = x.getCause();
1529 boolean createdNewRelationships = false;
1530 List<Relationship> relationships = relationshipList.getRelationship();
1531 if(relationships == null) {
1532 relationships = new ArrayList<>();
1533 createdNewRelationships = true;
1538 String searchKey = "relationship-list.relationship[" + i + "].related-to";
1539 if(!params.containsKey(searchKey))
1542 String relatedTo = params.get(searchKey);
1543 String relatedLinkKey = "relationship-list.relationship[" + i + "].related-link";
1544 String relatedLink = null;
1545 if(params.containsKey(relatedLinkKey)) {
1546 relatedLink = params.get(relatedLinkKey);
1549 Relationship relationship = new Relationship();
1550 relationships.add(relationship);
1551 relationship.setRelatedTo(relatedTo);
1553 String relationshipLabel = "relationship-list.relationship[" + i + "].relationship-label";
1554 if(params.containsKey(searchKey)) {
1555 relationship.setRelationshipLabel(params.get(relationshipLabel));
1558 if (relatedLink != null) {
1559 if(relatedLink.contains("v$"))
1560 relatedLink = relatedLink.replace(VERSION_PATTERN, AAIRequest.getSupportedAAIVersion());
1561 relationship.setRelatedLink(relatedLink);
1563 Map<String, String> relParams = new HashMap<>();
1567 String searchRelationshipKey = "relationship-list.relationship[" + i + "].relationship-data["
1568 + j + "].relationship-key";
1569 String searchRelationshipValue = "relationship-list.relationship[" + i + "].relationship-data["
1570 + j + "].relationship-value";
1571 if (!params.containsKey(searchRelationshipKey))
1574 RelationshipData relDatum = new RelationshipData();
1575 relDatum.setRelationshipKey(params.get(searchRelationshipKey));
1576 relDatum.setRelationshipValue(params.get(searchRelationshipValue));
1577 relationship.getRelationshipData().add(relDatum);
1579 relParams.put(params.get(searchRelationshipKey), params.get(searchRelationshipValue));
1582 AAIRequest rlRequest = AAIRequest.createRequest(relatedTo, relParams);
1583 for (Map.Entry<String, String> entry : relParams.entrySet()) {
1584 rlRequest.addRequestProperty(entry.getKey(), entry.getValue());
1586 String path = rlRequest.updatePathDataValues(null);
1587 relationship.setRelatedLink(path);
1591 // process related to properties
1592 Map<String, String> relParams = new HashMap<String, String>();
1595 String searchRelatedToKey = "relationship-list.relationship[" + i + "].related-to-property[" + k + "].property-key";
1596 String searchRelatedToValue = "relationship-list.relationship[" + i + "].related-to-property[" + k + "].property-value";
1597 if(!params.containsKey(searchRelatedToKey))
1600 RelatedToProperty relDatum = new RelatedToProperty();
1601 relDatum.setPropertyKey(params.get(searchRelatedToKey));
1602 relDatum.setPropertyValue(params.get(searchRelatedToValue));
1603 relationship.getRelatedToProperty().add(relDatum);
1605 relParams.put(params.get(searchRelatedToKey), params.get(searchRelatedToValue));
1614 return QueryStatus.SUCCESS;
1617 private QueryStatus newModelProcessMetadata(Object instance, Map<String, String> params, String prefix, SvcLogicContext ctx) throws Exception {
1619 if (!(instance instanceof ServiceInstance) && !(instance instanceof Image)) {
1620 throw new IllegalArgumentException("request is not applicable for selected request");
1623 Class resourceClass = instance.getClass();
1624 Set<String> metadataKeys = new TreeSet<String>();
1625 Set<String> set = params.keySet();
1626 for(String attribute : set) {
1627 if(attribute.startsWith("metadata")) {
1628 metadataKeys.add(attribute);
1632 // 3. Process Metadata
1634 if(!metadataKeys.isEmpty()) {
1635 Metadata metadata = null;
1637 Method getMetadataMethod = resourceClass.getMethod("getMetadata");
1638 if(getMetadataMethod != null){
1640 obj = getMetadataMethod.invoke(instance);
1641 } catch (InvocationTargetException x) {
1642 Throwable cause = x.getCause();
1645 if(obj != null && obj instanceof Metadata){
1646 metadata = (Metadata)obj;
1648 metadata = new Metadata();
1649 Method setMetadataMethod = resourceClass.getMethod("setMetadata", Metadata.class);
1650 if(setMetadataMethod != null){
1652 setMetadataMethod.invoke(instance, metadata);
1653 } catch (InvocationTargetException x) {
1658 List<Metadatum> metadatumList = metadata.getMetadatum();
1661 String metaNameKey = "metadata.metadatum[" + i + "].metaname";
1662 String metaValueKey = "metadata.metadatum[" + i + "].metaval";
1663 if(!params.containsKey(metaNameKey) || !params.containsKey(metaValueKey))
1666 Metadatum metadatum = new Metadatum();
1667 metadatum.setMetaname(params.get(metaNameKey));
1668 metadatum.setMetaval(params.get(metaValueKey));
1669 metadatumList.add(metadatum);
1675 return QueryStatus.SUCCESS;
1678 private Relationship findRelationship(List<Relationship> relationships, String relatedTo) {
1679 if(relatedTo == null)
1682 for(Relationship relationship : relationships) {
1683 if(relationship.getRelatedTo().equals(relatedTo)){
1684 return relationship;
1691 public QueryStatus backup(Map<String, String> params, SvcLogicContext ctx) throws SvcLogicException {
1692 String resource = params.get("resource").toLowerCase();
1693 String prefix = params.get("data-key");
1695 HashMap<String, String> nameValues = new HashMap<>();
1696 if(AAIRequest.createRequest(resource, nameValues) != null) {
1699 return newModelBackupRequest(resource, params, prefix, ctx);
1700 } catch (Exception exc) {
1701 getLogger().warn("Failed backup - returning FAILURE", exc);
1702 return QueryStatus.FAILURE;
1706 return QueryStatus.NOT_FOUND;
1710 public QueryStatus restore(Map<String, String> params, SvcLogicContext ctx) throws SvcLogicException {
1712 QueryStatus retval = QueryStatus.SUCCESS;
1713 String resource = params.get("resource").toLowerCase();
1714 String prefix = params.get("data-key");
1716 HashMap<String, String> nameValues = new HashMap<>();
1717 if(AAIRequest.createRequest(resource, nameValues) != null) {
1720 retval = newModelBackupRequest(resource, params, "tmpRestore", ctx);
1721 if(retval == QueryStatus.SUCCESS) {
1722 ctx.setAttribute("tmpRestore", null);
1724 } catch (Exception exc) {
1725 getLogger().warn("Failed restore - returning FAILURE", exc);
1726 return QueryStatus.FAILURE;
1730 return QueryStatus.NOT_FOUND;
1733 protected Map<String, Object> objectToProperties(Object object) {
1734 ObjectMapper mapper = AAIService.getObjectMapper();
1735 return mapper.convertValue(object, Map.class);
1738 static <T> T valueOf(Class<T> klazz, String arg) {
1739 Exception cause = null;
1742 ret = klazz.cast(klazz.getDeclaredMethod("valueOf", String.class).invoke(null, arg));
1743 } catch (NoSuchMethodException exc) {
1744 LoggerFactory.getLogger(AAIService.class).warn("Wrong data type", exc);
1745 ret = klazz.cast(arg);
1746 } catch (IllegalAccessException e) {
1748 } catch (InvocationTargetException e) {
1751 if (cause == null) {
1754 throw new IllegalArgumentException(cause);
1758 private QueryStatus processDeleteRelationshipList(String resource, String key, SvcLogicContext ctx, HashMap<String, String> nameValues) {
1760 AAIRequest request = AAIRequest.createRequest(resource.split(":")[0], nameValues);
1761 if(request == null) {
1762 return QueryStatus.FAILURE;
1765 request.processRequestPathValues(nameValues);
1766 URL url = request.getRequestUrl("GET", null);
1768 Class resourceClass = request.getModelClass();
1769 Object instance = getResource(url.toString(), resourceClass);
1770 if(instance == null)
1771 return QueryStatus.NOT_FOUND;
1773 // get resource version
1774 String resourceVersion = null;
1775 Method getResourceVersionMethod = resourceClass.getMethod("getResourceVersion");
1776 if(getResourceVersionMethod != null){
1778 Object object = getResourceVersionMethod.invoke(instance);
1780 resourceVersion = object.toString();
1781 } catch (InvocationTargetException exc) {
1782 getLogger().warn("Retrieving resource version", exc);
1786 RelationshipList relationshipList = null;
1788 Method getRelationshipListMethod = null;
1790 getRelationshipListMethod = resourceClass.getMethod("getRelationshipList");
1791 } catch(Exception exc) {
1792 getLogger().debug("Retrofiting relationship data: " + exc.getMessage());
1794 if(getRelationshipListMethod != null){
1796 obj = getRelationshipListMethod.invoke(instance);
1797 } catch (InvocationTargetException x) {
1798 Throwable cause = x.getCause();
1801 if(obj != null && obj instanceof RelationshipList){
1802 relationshipList = (RelationshipList)obj;
1804 getLogger().debug("No relationships found to process.");
1805 return QueryStatus.NOT_FOUND;
1808 if(relationshipList.getRelationship() == null || relationshipList.getRelationship().isEmpty()) {
1809 return QueryStatus.NOT_FOUND;
1811 String relatedTo = nameValues.get("related_to");
1812 if(relatedTo == null) {
1813 return QueryStatus.FAILURE;
1816 relatedTo = relatedTo.replaceAll("_", "-");
1818 String relatedLink = nameValues.get("relationship.related_link");
1819 if(relatedLink != null) {
1820 relatedLink = URLDecoder.decode(relatedLink, "UTF-8");
1823 List<Relationship> relationships = relationshipList.getRelationship();
1824 List<Relationship> relationshipsToDelete = new LinkedList<>();
1826 for(Relationship relationship : relationships) {
1827 if(relatedTo.equals(relationship.getRelatedTo())) {
1828 if(relatedLink != null) {
1829 if(relationship.getRelatedLink() != null ) {
1830 String localRelatedLink = relationship.getRelatedLink();
1831 localRelatedLink = URLDecoder.decode(localRelatedLink, "UTF-8");
1832 if(localRelatedLink.endsWith(relatedLink)) {
1833 getLogger().debug(String.format("Found relationship of '%s' to keyword '%s'", relationship.getRelatedTo(), relatedTo));
1834 relationshipsToDelete.add(relationship);
1838 getLogger().debug(String.format("Found relationship of '%s' to keyword '%s'", relationship.getRelatedTo(), relatedTo));
1839 relationshipsToDelete.add(relationship);
1843 if(relationshipsToDelete == null || relationshipsToDelete.isEmpty()) {
1844 getLogger().info(String.format("Relationship has not been found for %s", key));
1845 return QueryStatus.NOT_FOUND;
1848 String path = url.toString();
1849 path = path + "/relationship-list/relationship";
1850 URL deleteUrl = new URL(path);
1852 ObjectMapper mapper = AAIService.getObjectMapper();
1854 boolean cumulativeResponse = true;
1856 for(Relationship targetRelationship : relationshipsToDelete) {
1857 String json_text = mapper.writeValueAsString(targetRelationship);
1858 boolean response = deleteList(deleteUrl, json_text);
1860 cumulativeResponse = response;
1864 if(!cumulativeResponse)
1865 return QueryStatus.FAILURE;
1867 return QueryStatus.SUCCESS;
1869 } catch(Exception exc) {
1870 getLogger().warn("processDelete", exc);
1871 return QueryStatus.FAILURE;
1875 private QueryStatus processDeleteMetadata(String resource, String key, SvcLogicContext ctx, HashMap<String, String> nameValues) {
1877 AAIRequest request = AAIRequest.createRequest(resource, nameValues);
1878 if(request == null) {
1879 return QueryStatus.FAILURE;
1882 request.processRequestPathValues(nameValues);
1883 URL url = request.getRequestUrl("GET", null);
1885 Class<?> resourceClass = request.getModelClass();
1886 Object instance = getResource(url.toString(), resourceClass);
1888 // get resource version
1889 String resourceVersion = null;
1890 Method getResourceVersionMethod = resourceClass.getMethod("getResourceVersion");
1891 if(getResourceVersionMethod != null){
1893 resourceVersion = (String) getResourceVersionMethod.invoke(instance);
1894 } catch (InvocationTargetException x) {
1898 Metadata metadata = null;
1900 Method getMetadataMethod = resourceClass.getMethod("getMetadata");
1901 if(getMetadataMethod != null){
1903 obj = getMetadataMethod.invoke(instance);
1904 } catch (InvocationTargetException x) {
1905 Throwable cause = x.getCause();
1908 if(obj != null && obj instanceof Metadata){
1909 metadata = (Metadata)obj;
1911 getLogger().debug("No metadata found to process.");
1912 return QueryStatus.NOT_FOUND;
1915 if(metadata.getMetadatum() == null || metadata.getMetadatum().isEmpty()) {
1916 return QueryStatus.NOT_FOUND;
1919 List<Metadatum> metadatumList = metadata.getMetadatum();
1920 Metadatum metadatumToDelete = null;
1922 final String metaname = nameValues.get("metaname");
1924 for(Metadatum metadatum : metadatumList) {
1925 getLogger().debug(String.format("Comparing existing metadatum of '%s' to keyword '%s'", metadatum.getMetaname(), metaname));
1926 if(metaname.equals(metadatum.getMetaname())) {
1927 metadatumToDelete = metadatum;
1931 if(metadatumToDelete == null) {
1932 getLogger().info(String.format("Metadatum has not been found for %s", key));
1933 return QueryStatus.NOT_FOUND;
1936 String path = url.toString();
1937 path = path + "/metadata/metadatum/" + encodeQuery( metadatumToDelete.getMetaname() ) +
1938 "?resource-version=" + metadatumToDelete.getResourceVersion();
1939 URL deleteUrl = new URL(path);
1940 boolean response = deleteList(deleteUrl, null);
1943 return QueryStatus.FAILURE;
1945 return QueryStatus.SUCCESS;
1947 } catch(Exception exc) {
1948 getLogger().warn("processDelete", exc);
1949 return QueryStatus.FAILURE;
1953 protected String encodeQuery(String param) throws UnsupportedEncodingException {
1954 return URLEncoder.encode(param, "UTF-8").replace("+", "%20");
1957 static final Map<String, String> ctxGetBeginsWith( SvcLogicContext ctx, String prefix ) {
1958 Map<String, String> tmpPrefixMap = new HashMap<>();
1960 if(prefix == null || prefix.isEmpty()){
1961 return tmpPrefixMap;
1964 for( String key : ctx.getAttributeKeySet() ) {
1965 if( key.startsWith(prefix) ) {
1966 String tmpKey = key.substring(prefix.length() + 1);
1967 tmpPrefixMap.put( tmpKey, ctx.getAttribute(key));
1971 Map<String, String> prefixMap = new HashMap<>();
1972 Pattern p = Pattern.compile(".*\\[\\d\\]");
1974 SortedSet<String> keys = new TreeSet<String>(tmpPrefixMap.keySet () );
1975 for(String key : keys) {
1976 Matcher m = p.matcher(key);
1979 } else if(key.endsWith("_length")) {
1980 String listKey = key.substring(0, key.indexOf("_length"));
1981 int max = Integer.parseInt(tmpPrefixMap.get(key));
1983 ArrayList<String> data = new ArrayList<>();
1984 for(int x = 0; x < max; x++){
1985 String tmpKey = String.format("%s[%d]", listKey, x);
1986 String tmpValue = tmpPrefixMap.get(tmpKey);
1987 if(tmpValue != null && !tmpValue.isEmpty()) {
1991 if(!data.isEmpty()) {
1992 prefixMap.put(listKey, data.toString());
1994 prefixMap.put(key, tmpPrefixMap.get(key));
1997 prefixMap.put(key, tmpPrefixMap.get(key));
2006 protected NamedQueryData extractNamedQueryDataFromQueryPrefix(HashMap<String, String> nameValues, Map<String, String> parms) {
2007 if(parms.isEmpty()) {
2011 NamedQueryData data = new NamedQueryData();
2014 if(data.getQueryParameters() == null) {
2015 data.setQueryParameters(new QueryParameters());
2017 String namedQueryUuid = nameValues.get("named-query-uuid".replaceAll("-", "_"));
2018 if(namedQueryUuid == null) {
2019 namedQueryUuid = parms.get("query-parameters.named-query.named-query-uuid");
2021 NamedQuery namedQuery = new NamedQuery();
2022 namedQuery.setNamedQueryUuid(namedQueryUuid);
2023 data.getQueryParameters().setNamedQuery(namedQuery);
2026 if(data.getInstanceFilters() == null) {
2027 data.setInstanceFilters(new InstanceFilters());
2031 String quantity = parms.get("instance-filters.instance-filter_length");
2032 if(quantity != null && StringUtils.isNumeric(quantity)) {
2033 int max = Integer.parseInt(quantity);
2034 for(int i = 0; i < max; i++) {
2035 String keyPattern = String.format("instance-filters.instance-filter[%d].", i);
2036 Set<String> keys = parms.keySet();
2037 for(String key: keys) {
2038 if(key.startsWith(keyPattern)){
2039 String value = parms.get(key);
2040 String remainder = key.substring(keyPattern.length());
2041 String[] split = remainder.split("\\.");
2042 getLogger().debug(String.format("%s", remainder));
2043 if("logical-link".equals(split[0])) {
2044 InstanceFilter insf = null;
2045 if(data.getInstanceFilters().getInstanceFilter().isEmpty()) {
2046 insf = new InstanceFilter();
2047 data.getInstanceFilters().getInstanceFilter().add(insf);
2049 insf = data.getInstanceFilters().getInstanceFilter().get(0);
2051 LogicalLink logicalLink = insf.getLogicalLink();
2052 if(logicalLink == null) {
2053 logicalLink = new LogicalLink();
2054 insf.setLogicalLink(logicalLink);
2059 logicalLink.setLinkName(value);
2062 logicalLink.setLinkType(value);
2064 case "operational-state":
2065 logicalLink.setOperationalStatus(value);
2069 } else if("pnf".equals(split[0])) {
2070 Pnf pnf = new Pnf();
2071 pnf.setPnfName(value);
2073 InstanceFilter insf = new InstanceFilter();
2075 data.getInstanceFilters().getInstanceFilter().add(insf);
2077 } else if("service-instance".equals(split[0])) {
2078 ServiceInstance serviceInstance = new ServiceInstance();
2079 serviceInstance.setServiceInstanceId(value);
2081 InstanceFilter insf = new InstanceFilter();
2082 insf.setServiceInstance(serviceInstance);
2083 data.getInstanceFilters().getInstanceFilter().add(insf);
2085 } else if("l3-network".equals(split[0])) {
2086 L3Network l3Network = new L3Network();
2087 if("network-role".equals(split[1])) {
2088 l3Network.setNetworkRole(value);
2091 InstanceFilter insf = new InstanceFilter();
2092 insf.setL3Network(l3Network);
2093 data.getInstanceFilters().getInstanceFilter().add(insf);
2094 } else if("generic-vnf".equals(split[0])) {
2095 GenericVnf vnf = new GenericVnf();
2096 if("vnf-id".equals(split[1])) {
2097 vnf.setVnfId(value);
2100 InstanceFilter insf = new InstanceFilter();
2101 insf.setGenericVnf(vnf);
2102 data.getInstanceFilters().getInstanceFilter().add(insf);
2112 public abstract <T> T getResource(String key, Class<T> type) throws AAIServiceException ;
2113 protected abstract boolean deleteList(URL url, String caller) throws AAIServiceException;