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;
32 import java.net.URLDecoder;
33 import java.net.URLEncoder;
34 import java.util.ArrayList;
35 import java.util.Arrays;
36 import java.util.HashMap;
37 import java.util.LinkedList;
38 import java.util.List;
41 import java.util.SortedSet;
42 import java.util.TreeSet;
43 import java.util.regex.Matcher;
44 import java.util.regex.Pattern;
46 import javax.xml.bind.annotation.XmlType;
48 import org.apache.commons.lang.StringUtils;
49 import org.onap.ccsdk.sli.core.sli.SvcLogicContext;
50 import org.onap.ccsdk.sli.core.sli.SvcLogicException;
51 import org.onap.ccsdk.sli.core.sli.SvcLogicResource.QueryStatus;
52 import org.openecomp.aai.inventory.v11.Image;
53 import org.openecomp.aai.inventory.v11.GenericVnf;
54 import org.openecomp.aai.inventory.v11.InventoryResponseItem;
55 import org.openecomp.aai.inventory.v11.InventoryResponseItems;
56 import org.openecomp.aai.inventory.v11.L3Network;
57 import org.openecomp.aai.inventory.v11.LogicalLink;
58 import org.openecomp.aai.inventory.v11.Metadata;
59 import org.openecomp.aai.inventory.v11.Metadatum;
60 import org.openecomp.aai.inventory.v11.Pnf;
61 import org.openecomp.aai.inventory.v11.Relationship;
62 import org.openecomp.aai.inventory.v11.RelationshipData;
63 import org.openecomp.aai.inventory.v11.RelationshipList;
64 import org.openecomp.aai.inventory.v11.ResultData;
65 import org.openecomp.aai.inventory.v11.SearchResults;
66 import org.openecomp.aai.inventory.v11.ServiceInstance;
67 import org.openecomp.aai.inventory.v11.Vlan;
68 import org.openecomp.aai.inventory.v11.Vlans;
69 import org.openecomp.aai.inventory.v11.Vserver;
70 import org.onap.ccsdk.sli.adaptors.aai.AAIService.AAIRequestExecutor;
71 import org.onap.ccsdk.sli.adaptors.aai.data.AAIDatum;
72 import org.onap.ccsdk.sli.adaptors.aai.query.FormattedQueryResultList;
73 import org.onap.ccsdk.sli.adaptors.aai.query.InstanceFilter;
74 import org.onap.ccsdk.sli.adaptors.aai.query.InstanceFilters;
75 import org.onap.ccsdk.sli.adaptors.aai.query.NamedQuery;
76 import org.onap.ccsdk.sli.adaptors.aai.query.NamedQueryData;
77 import org.onap.ccsdk.sli.adaptors.aai.query.QueryParameters;
78 import org.onap.ccsdk.sli.adaptors.aai.query.Result;
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 // Availability zones query
106 public static final String QUERY_PATH = "org.onap.ccsdk.sli.adaptors.aai.path.query";
109 public static final String UPDATE_PATH = "org.onap.ccsdk.sli.adaptors.aai.update";
112 public static final String SVC_INSTANCE_PATH = "org.onap.ccsdk.sli.adaptors.aai.path.svcinst";
113 public static final String SVC_INST_QRY_PATH = "org.onap.ccsdk.sli.adaptors.aai.path.svcinst.query";
116 public static final String NETWORK_VSERVER_PATH = "org.onap.ccsdk.sli.adaptors.aai.path.vserver";
118 public static final String VNF_IMAGE_QUERY_PATH = "org.onap.ccsdk.sli.adaptors.aai.path.vnf.image.query";
120 public static final String PARAM_SERVICE_TYPE = "org.onap.ccsdk.sli.adaptors.aai.param.service.type";
121 public static final String CERTIFICATE_HOST_ERROR = "org.onap.ccsdk.sli.adaptors.aai.host.certificate.ignore";
124 public static final String UBB_NOTIFY_PATH = "org.onap.ccsdk.sli.adaptors.aai.path.notify";
125 public static final String SELFLINK_AVPN = "org.onap.ccsdk.sli.adaptors.aai.notify.selflink.avpn";
126 public static final String SELFLINK_FQDN = "org.onap.ccsdk.sli.adaptors.aai.notify.selflink.fqdn";
129 public static final String SERVICE_PATH = "org.onap.ccsdk.sli.adaptors.aai.path.service";
132 public static final String P_INTERFACE_PATH = "org.onap.ccsdk.sli.adaptors.aai.path.pserver.pinterface";
135 public static final String SITE_PAIR_SET_PATH = "org.onap.ccsdk.sli.adaptors.aai.path.site.pair.set";
138 public static final String QUERY_NODES_PATH = "org.onap.ccsdk.sli.adaptors.aai.query.nodes";
141 protected abstract Logger getLogger();
142 public abstract AAIRequestExecutor getExecutor();
146 public QueryStatus query(String resource, boolean localOnly, String select, String key, String prefix, String orderBy, SvcLogicContext ctx)
147 throws SvcLogicException {
149 getLogger().debug("AAIService.query \tresource = "+resource);
152 String vnfName = null;
153 HashMap<String, String> nameValues = AAIServiceUtils.keyToHashMap(key, ctx);
154 getLogger().debug("key = "+ nameValues.toString());
156 if(!AAIServiceUtils.isValidFormat(resource, nameValues)) {
157 ctx.setAttribute(String.format("%s.error.message", prefix), String.format("Resource %s is not supported. Key string contains invaid identifiers", resource));
158 return QueryStatus.FAILURE;
161 if(resource == null || resource.isEmpty() || AAIRequest.createRequest(resource, nameValues) == null) {
162 ctx.setAttribute(String.format("%s.error.message", prefix), String.format("Resource %s is not supported", resource));
163 return QueryStatus.FAILURE;
166 // process data using new model
167 boolean useNewModelProcessing = true;
168 // process server query by name the old way
169 if("vserver".equals(resource) || "vserver2".equals(resource)){
170 if(nameValues.containsKey("vserver_name") || nameValues.containsKey("vserver-name") || nameValues.containsKey("vserver.vserver_name") || nameValues.containsKey("vserver.vserver-name"))
171 useNewModelProcessing = false;
173 if("generic-vnf".equals(resource)){
174 if(nameValues.containsKey("vnf_name") || nameValues.containsKey("vnf-name") || nameValues.containsKey("generic_vnf.vnf_name") || nameValues.containsKey("generic-vnf.vnf-name"))
175 useNewModelProcessing = false;
178 // process data using new model
179 if(useNewModelProcessing && AAIRequest.createRequest(resource, nameValues) != null) {
182 return newModelQuery(resource, localOnly, select, key, prefix, orderBy, ctx);
183 } catch (Exception exc) {
184 getLogger().warn("Failed query - returning FAILURE", exc);
185 return QueryStatus.FAILURE;
189 ObjectMapper mapper = AAIService.getObjectMapper();
190 Map<String,Object> attributes = new HashMap<>();
192 String modifier = null;
194 if(resource.contains(":")) {
195 String[] tokens = resource.split(":");
196 resource = tokens[0];
197 if(tokens.length > 1) {
198 modifier = tokens[1];
202 resource = resource.toLowerCase().replace("-", "_");
208 vnfId = nameValues.get("vnf_id");
209 if(nameValues.containsKey("vnf_id"))
210 vnfId = nameValues.get("vnf_id");
211 else if(nameValues.containsKey("generic_vnf.vnf_name"))
212 vnfId = nameValues.get("generic_vnf.vserver_name");
214 if(nameValues.containsKey("vnf_name"))
215 vnfName = nameValues.get("vnf_name");
216 else if(nameValues.containsKey("generic_vnf.vnf_name"))
217 vnfName = nameValues.get("generic_vnf.vnf_name");
219 if(vnfId != null && !vnfId.isEmpty()) {
220 // at this point of the project this part should not be executed
221 vnfId = vnfId.trim().replace("'", "").replace("$", "").replace("'", "");
222 GenericVnf vnf = this.requestGenericVnfData(vnfId);
224 return QueryStatus.NOT_FOUND;
227 attributes = mapper.convertValue(vnf, attributes.getClass());
228 } else if(vnfName != null && !vnfName.isEmpty()) {
230 vnfName = vnfName.trim().replace("'", "").replace("$", "").replace("'", "");
231 GenericVnf vnf = this.requestGenericVnfeNodeQuery(vnfName);
233 return QueryStatus.NOT_FOUND;
235 vnfId=vnf.getVnfId();
236 nameValues.put("vnf_id", vnfId);
237 attributes = mapper.convertValue(vnf, attributes.getClass());
238 } catch (AAIServiceException exc) {
239 int errorCode = exc.getReturnCode();
246 getLogger().warn("Caught exception trying to refresh generic VNF", exc);
248 ctx.setAttribute(prefix + ".error.message", exc.getMessage());
249 if(errorCode >= 300) {
250 ctx.setAttribute(prefix + ".error.http.response-code",
251 Integer.toString(exc.getReturnCode()));
253 return QueryStatus.FAILURE;
256 getLogger().warn("No arguments are available to process generic VNF");
257 return QueryStatus.FAILURE;
262 String vserverName = null;
263 if(nameValues.containsKey("vserver_name"))
264 vserverName = nameValues.get("vserver_name");
265 else if(nameValues.containsKey("vserver.vserver_name"))
266 vserverName = nameValues.get("vserver.vserver_name");
268 String vserverId = null;
269 if(nameValues.containsKey("vserver_id"))
270 vserverId = nameValues.get("vserver_id");
271 if(nameValues.containsKey("vserver.vserver_id"))
272 vserverId = nameValues.get("vserver.vserver_id");
273 String tenantId = nameValues.get("teannt_id");
275 if(vserverName != null) vserverName = vserverName.trim().replace("'", "").replace("$", "").replace("'", "");
276 if(vserverId != null) vserverId = vserverId.trim().replace("'", "").replace("$", "").replace("'", "");
277 if(tenantId != null) tenantId = tenantId.trim().replace("'", "").replace("$", "").replace("'", "");
279 if (vserverName != null) {
280 URL vserverUrl = null;
282 vserverUrl = this.requestVserverURLNodeQuery(vserverName);
283 } catch (AAIServiceException aaiexc) {
284 ctx.setAttribute(prefix + ".error.message", aaiexc.getMessage());
285 if (aaiexc.getReturnCode() >= 300) {
286 ctx.setAttribute(prefix + ".error.http" + "" + ".response-code", Integer.toString(aaiexc.getReturnCode()));
289 if (aaiexc.getReturnCode() == 404)
290 return QueryStatus.NOT_FOUND;
292 return QueryStatus.FAILURE;
294 if (vserverUrl == null) {
295 return QueryStatus.NOT_FOUND;
298 tenantId = getTenantIdFromVserverUrl(vserverUrl);
299 String cloudOwner = getCloudOwnerFromVserverUrl(vserverUrl);
300 String cloudRegionId = getCloudRegionFromVserverUrl(vserverUrl);
302 Vserver vserver = null;
304 vserver = this.requestVServerDataByURL(vserverUrl);
305 } catch (AAIServiceException aaiexc) {
306 ctx.setAttribute(prefix + ".error.message", aaiexc.getMessage());
307 if (aaiexc.getReturnCode() >= 300) {
308 ctx.setAttribute(prefix + ".error.http" + ".response-code", Integer.toString(aaiexc.getReturnCode()));
311 if (aaiexc.getReturnCode() == 404)
312 return QueryStatus.NOT_FOUND;
314 return QueryStatus.FAILURE;
316 if (vserver == null) {
317 return QueryStatus.NOT_FOUND;
319 attributes = mapper.convertValue(vserver, attributes.getClass());
320 if (!attributes.containsKey("tenant-id") && tenantId != null) {
321 attributes.put("tenant-id", tenantId);
323 if (!attributes.containsKey("cloud-owner") && cloudOwner != null) {
324 attributes.put("cloud-owner", cloudOwner);
326 if (!attributes.containsKey("cloud-region-id") && cloudRegionId != null) {
327 attributes.put("cloud-region-id", cloudRegionId);
329 } else if (vserverId != null && tenantId != null) {
330 Vserver vserver = this.requestVServerData(tenantId, vserverId, "att-aic", "AAIAIC25");
331 if(vserver == null) {
332 return QueryStatus.NOT_FOUND;
334 attributes = mapper.convertValue(vserver, attributes.getClass());
335 if(!attributes.containsKey("tenant-id") && tenantId != null){
336 attributes.put("tenant-id", tenantId);
339 return QueryStatus.FAILURE;
344 return QueryStatus.FAILURE;
347 QueryStatus retval = QueryStatus.SUCCESS;
349 if (attributes == null || attributes.isEmpty()) {
350 retval = QueryStatus.NOT_FOUND;
351 getLogger().debug("No data found");
354 if (prefix != null) {
355 ArrayList<String> keys = new ArrayList<>(attributes.keySet());
357 int numCols = keys.size();
359 for (int i = 0; i < numCols; i++) {
361 String colName = keys.get(i);
362 Object object = attributes.get(colName);
364 if(object != null && object instanceof String) {
365 colValue = (String)object;
367 if (prefix != null) {
368 getLogger().debug("Setting "+prefix + "." + colName.replaceAll("_", "-")+" = "+ colValue);
369 ctx.setAttribute(prefix + "." + colName.replaceAll("_", "-"), colValue);
371 getLogger().debug("Setting " + colValue.replaceAll("_", "-")+" = "+colValue);
372 ctx.setAttribute(colValue.replaceAll("_", "-"), colValue);
374 } else if(object != null && object instanceof Map) {
375 if(colName.equals(modifier) || "relationship-list".equals(colName)){
376 String localNodifier = modifier;
377 if(localNodifier == null)
378 localNodifier = "relationship-list";
379 Map<String, Object> properties = (Map<String, Object>)object;
380 writeMap(properties, prefix+"."+localNodifier, ctx);
387 getLogger().debug("Query - returning " + retval);
390 } catch (Exception exc) {
391 getLogger().warn("Failed query - returning FAILURE", exc);
392 return QueryStatus.FAILURE;
395 // return QueryStatus.SUCCESS;
399 public void writeMap(Map<String, Object> properties, String prefix, SvcLogicContext ctx) {
400 Set<String> mapKeys = properties.keySet();
402 for(String mapKey : mapKeys) {
403 Object entity = properties.get(mapKey);
404 if(entity instanceof ArrayList) {
405 writeList((ArrayList<?>)entity, prefix + "." + mapKey, ctx);
407 if(entity instanceof String || entity instanceof Long || entity instanceof Integer || entity instanceof Boolean) {
408 ctx.setAttribute(prefix + "." + mapKey, entity.toString());
409 getLogger().debug(prefix + "." + mapKey + " : " + entity.toString());
410 } else if(entity instanceof Map) {
411 String localPrefix = prefix;
413 localPrefix = String.format("%s.%s", prefix, mapKey);
415 writeMap( (Map<String, Object>)entity, localPrefix, ctx);
420 private void writeList(ArrayList<?> list, String prefix, SvcLogicContext ctx) {
421 for(int i = 0; i < list.size(); i++ ) {
422 Object entity = list.get(i);
423 if(entity instanceof Map) {
424 writeMap( (Map<String, Object>)entity, prefix + "[" + i + "]", ctx);
426 if(entity instanceof String || entity instanceof Long || entity instanceof Integer || entity instanceof Boolean) {
427 ctx.setAttribute(prefix, entity.toString());
428 getLogger().debug(prefix + " : " + entity.toString());
432 if(!list.isEmpty()) {
433 ctx.setAttribute(prefix + "_length", Integer.toString(list.size()));
434 getLogger().debug(prefix + "_length" + " : " + Integer.toString(list.size()));
439 public QueryStatus save(String resource, boolean force, boolean localOnly, String key, Map<String, String> params, String prefix, SvcLogicContext ctx)
440 throws SvcLogicException {
442 getLogger().debug("AAIService.save\tresource="+resource);
443 HashMap<String, String> nameValues = AAIServiceUtils.keyToHashMap(key, ctx);
445 if(!AAIServiceUtils.isValidFormat(resource, nameValues)) {
446 ctx.setAttribute(String.format("%s.error.message", prefix), String.format("Resource %s is not supported. Key string contains invaid identifiers", resource));
447 return QueryStatus.FAILURE;
450 if(resource == null || resource.isEmpty() || AAIRequest.createRequest(resource, nameValues) == null) {
451 getLogger().warn("AAIService.save has unspecified resource");
452 ctx.setAttribute(String.format("%s.error.message", prefix), String.format("Resource %s is not supported", resource));
453 return QueryStatus.FAILURE;
456 getLogger().debug("key = "+ Arrays.toString(nameValues.entrySet().toArray()));
459 if(params.containsKey("prefix")) {
460 Map<String, String> tmpParams = ctxGetBeginsWith(ctx, params.get("prefix"));
461 if(!tmpParams.isEmpty()) {
462 params.putAll(tmpParams);
463 // params.remove("prefix");
467 getLogger().debug("parms = "+ Arrays.toString(params.entrySet().toArray()));
469 boolean useNewModelProcessing = true;
470 // process server query by name the old way
471 if("vserver".equals(resource) || "vserver2".equals(resource)){
472 if(nameValues.containsKey("vserver-name")) {
473 useNewModelProcessing = false;
476 if(!params.containsKey("vserver-selflink")) {
478 AAIRequest request = AAIRequest.createRequest(resource, nameValues);
481 request.processRequestPathValues(nameValues);
482 path = request.getRequestUrl("GET", null);
483 params.put("vserver-selflink", path.toString());
484 } catch (UnsupportedEncodingException | MalformedURLException e) {
486 params.put("vserver-selflink", "/vserver");
491 // process data using new model
492 if(useNewModelProcessing && AAIRequest.createRequest(resource, nameValues) != null) {
495 if(!resource.contains(":")){
496 return newModelSave(resource, force, key, params, prefix, ctx);
498 String[] tokens = resource.split(":");
499 String localResource = tokens[0];
500 String dependency = tokens[1];
502 AAIDatum instance = newModelObjectRequest( localResource, nameValues, prefix, ctx);
503 if(instance == null) {
504 return QueryStatus.NOT_FOUND;
508 case "relationship-list":
509 newModelProcessRelationshipList(instance, params, prefix, ctx);
512 newModelProcessMetadata(instance, params, prefix, ctx);
515 // create a method to update relationship-list
516 AAIRequest request = AAIRequest.createRequest(localResource, nameValues);
517 request.setRequestObject(instance);
518 request.processRequestPathValues(nameValues);
520 getExecutor().post(request);
521 getLogger().debug("Save relationship list - returning SUCCESS");
522 return QueryStatus.SUCCESS;
524 } catch (Exception exc) {
525 ctx.setAttribute(prefix + ".error.message", exc.getMessage());
526 if(exc instanceof AAIServiceException) {
527 AAIServiceException aaiexc = (AAIServiceException)exc;
528 if(aaiexc.getReturnCode() >= 300) {
529 ctx.setAttribute(prefix + ".error.http" + ".response-code", Integer.toString(aaiexc.getReturnCode()));
532 if(aaiexc.getReturnCode() == 404) {
533 return QueryStatus.NOT_FOUND;
536 getLogger().warn("Failed save() - returning FAILURE", exc);
537 return QueryStatus.FAILURE;
540 String reSource = resource.toLowerCase().replace("-", "_");
547 vnfId = nameValues.get("vnf_id");
549 getLogger().debug("Save(generic-vnf) with no vnf-id specified. Returning FAILURE");
550 return QueryStatus.FAILURE;
552 vnfId = vnfId.trim().replace("'", "").replace("$", "").replace("'", "");
553 GenericVnf vnf = this.requestGenericVnfData(vnfId);
554 String status = params.get("prov-status");
555 boolean updated = false;
556 if(status != null && !status.isEmpty()) {
557 vnf.setProvStatus(status);
560 this.postGenericVnfData(vnfId, vnf);
564 return update( resource, key, params, prefix, ctx) ;
567 getLogger().debug("Save() executing default path - returning FAILURE");
568 return QueryStatus.FAILURE;
570 } catch (Exception exc) {
571 getLogger().warn("Failed save - returning FAILURE", exc);
572 ctx.setAttribute(prefix + ".error.message", exc.getMessage());
573 return QueryStatus.FAILURE;
577 getLogger().debug("Save - returning SUCCESS");
578 return QueryStatus.SUCCESS;
582 public QueryStatus update(String resource, String key, Map<String, String> params, String prefix, SvcLogicContext ctx) throws SvcLogicException {
584 resource = resource.toLowerCase();
585 HashMap<String, String> nameValues = AAIServiceUtils.keyToHashMap(key, ctx);
586 getLogger().debug("key = "+ Arrays.toString(nameValues.entrySet().toArray()));
587 if(!AAIServiceUtils.isValidFormat(resource, nameValues)) {
588 ctx.setAttribute(String.format("%s.error.message", prefix), String.format("Resource %s is not supported. Key string contains invaid identifiers", resource));
589 return QueryStatus.FAILURE;
592 if(resource == null || resource.isEmpty() || AAIRequest.createRequest(resource, nameValues) == null) {
593 ctx.setAttribute(String.format("%s.error.message", prefix), String.format("Resource %s is not supported", resource));
594 return QueryStatus.FAILURE;
597 // check if request is for groups
598 if(!AAIServiceUtils.containsResource(resource, nameValues)) {
599 ctx.setAttribute(String.format("%s.error.message", prefix), String.format("Resource %s is not permitted in 'update' operation", resource));
600 return QueryStatus.FAILURE;
603 getLogger().debug("parms = "+ Arrays.toString(params.entrySet().toArray()));
605 AAIRequest request = AAIRequest.createRequest(resource, nameValues);
606 request = new UpdateRequest(request, params);
608 String[] arguments = request.getArgsList();
609 for(String name : arguments) {
610 String modifiedKey = name.replaceAll("-", "_");
611 if(nameValues.containsKey(modifiedKey)) {
612 String argValue = nameValues.get(modifiedKey);
613 if(argValue != null) argValue = argValue.trim().replace("'", "").replace("$", "").replace("'", "");
614 request.addRequestProperty(name, argValue);
619 QueryStatus retval = QueryStatus.SUCCESS;
621 retval = newModelQuery(resource, false, null, key, "tmpDelete", null, ctx);
623 if(retval == null || retval != QueryStatus.SUCCESS) {
627 String resourceVersion = ctx.getAttribute("tmpDelete.resource-version");
628 if(resourceVersion == null) {
629 return QueryStatus.NOT_FOUND;
631 params.put("resource-version", resourceVersion);
633 request.processRequestPathValues(nameValues);
634 getExecutor().patch(request, resourceVersion);
635 } catch(AAIServiceException aaiexc) {
636 if(aaiexc.getReturnCode() == 404)
637 return QueryStatus.NOT_FOUND;
639 return QueryStatus.FAILURE;
640 } catch (Exception exc) {
641 getLogger().warn("Failed update - returning FAILURE", exc);
642 return QueryStatus.FAILURE;
645 getLogger().debug("Update - returning SUCCESS");
646 return QueryStatus.SUCCESS;
650 public QueryStatus delete(String resource, String key, SvcLogicContext ctx) throws SvcLogicException {
651 getLogger().debug("AAIService.delete\tresource="+resource);
652 HashMap<String, String> nameValues = AAIServiceUtils.keyToHashMap(key, ctx);
653 getLogger().debug("key = "+ Arrays.toString(nameValues.entrySet().toArray()));
655 if(!AAIServiceUtils.isValidFormat(resource, nameValues)) {
656 ctx.setAttribute(String.format("%s.error.message", "aaiData"), String.format("Resource %s is not supported. Key string contains invaid identifiers", resource));
657 return QueryStatus.FAILURE;
660 if(resource == null || resource.isEmpty() || AAIRequest.createRequest(resource, nameValues) == null) {
661 ctx.setAttribute(String.format("%s.error.message", "tmpDelete"), String.format("Resource %s is not supported", resource));
662 return QueryStatus.FAILURE;
665 // check if request is for groups
666 if(!AAIServiceUtils.containsResource(resource, nameValues)) {
667 ctx.setAttribute(String.format("%s.error.message", "tmpDelete"), String.format("Resource %s is not permitted in 'delete' operation", resource));
668 return QueryStatus.FAILURE;
671 if(AAIRequest.createRequest(resource, nameValues) != null) {
672 if(resource.contains(":")) {
673 switch (resource.split(":")[1]){
674 case "relationship-list":
675 return processDeleteRelationshipList(resource, key, ctx, nameValues);
677 return processDeleteMetadata(resource, key, ctx, nameValues);
683 QueryStatus retval = QueryStatus.SUCCESS;
685 retval = newModelQuery(resource, false, null, key, "tmpDelete", null, ctx);
687 if(retval == null || retval != QueryStatus.SUCCESS) {
691 String resourceVersion = ctx.getAttribute("tmpDelete.resource-version");
692 if(resourceVersion == null) {
693 return QueryStatus.NOT_FOUND;
697 AAIRequest request = AAIRequest.createRequest(resource, nameValues);
698 if(request == null) {
699 return QueryStatus.FAILURE;
702 request.processRequestPathValues(nameValues);
704 if(getExecutor().delete(request, resourceVersion)) {
705 return QueryStatus.SUCCESS;
707 } catch(AAIServiceException aaiexc) {
708 if(aaiexc.getReturnCode() == 404)
709 return QueryStatus.NOT_FOUND;
711 return QueryStatus.FAILURE;
713 } catch (Exception exc) {
714 getLogger().warn("requestGenericVnfData", exc);
715 return QueryStatus.FAILURE;
718 } catch (Exception exc) {
719 getLogger().warn("Failed delete - returning FAILURE", exc);
720 return QueryStatus.FAILURE;
723 String resourceName = resource;
724 String identifier = null;
726 if(resourceName.contains(":")) {
727 String[] tokens = resourceName.split(":");
728 if(tokens != null && tokens.length > 0) {
729 resourceName = tokens[0];
730 identifier = tokens[1];
733 if("relationship-list".equals(identifier) || "relationshipList".equals(identifier)) {
734 // RelationshipRequest relationshipRequest = new RelationshipRequest();
735 if("generic-vnf".equals(resourceName)){
736 String vnfId = nameValues.get("vnf_id");
737 String relatedTo = nameValues.get("related_to");
738 vnfId = vnfId.trim().replace("'", "").replace("$", "").replace("'", "");
739 relatedTo = relatedTo.trim().replace("'", "").replace("$", "").replace("'", "");
743 vnf = this.requestGenericVnfData(vnfId);
745 return QueryStatus.NOT_FOUND;
746 } catch (AAIServiceException exc) {
747 getLogger().warn("Failed delete - returning NOT_FOUND", exc);
748 return QueryStatus.NOT_FOUND;
750 boolean itemRemoved = false;
751 RelationshipList relationshipList = vnf.getRelationshipList();
752 List<Relationship> relationships = relationshipList.getRelationship();
753 List<Relationship> iterableList = new LinkedList<>(relationships);
754 for(Relationship relationship : iterableList) {
755 if(relationship.getRelatedTo().equals(relatedTo)) {
756 relationships.remove(relationship);
762 return QueryStatus.NOT_FOUND;
764 // AAIRequest masterRequest = new GenericVnfRequest();
765 // masterRequest.addRequestProperty(GenericVnfRequest.VNF_ID, vnfId);
766 // relationshipRequest.addMasterRequest(masterRequest);
767 // Map<String, String> attributes = objectToProperties(vnf);
769 // Boolean result = getExecutor().delete(relationshipRequest, attributes.get(AAIRequest.RESOURCE_VERSION));
770 // } catch (AAIServiceException e) {
771 // return QueryStatus.FAILURE;
775 this.postGenericVnfData(vnf.getVnfId(), vnf);
776 } catch (AAIServiceException exc) {
777 if(exc.getReturnCode() == 404){
778 return QueryStatus.NOT_FOUND;
780 getLogger().warn("Failed delete - returning FAILURE", exc);
781 return QueryStatus.FAILURE;
784 return QueryStatus.SUCCESS;
788 return QueryStatus.FAILURE;
792 public QueryStatus exists(String resource, String key, String prefix, SvcLogicContext ctx) throws SvcLogicException {
793 return query(resource, false, null, key, prefix, null, ctx);
797 public QueryStatus isAvailable(String arg0, String arg1, String arg2, SvcLogicContext arg3)
798 throws SvcLogicException {
799 // TODO Auto-generated method stub
800 throw new SvcLogicException("Method AAIService.isAvailable() has not been implemented yet");
804 public QueryStatus notify(String resource, String action, String key, SvcLogicContext ctx) throws SvcLogicException {
805 // TODO Auto-generated method stub
806 throw new SvcLogicException("Method AAIService.notify() has not been implemented yet");
810 public QueryStatus newModelQuery(String resource, boolean localOnly, String select, String key, String prefix, String orderBy, SvcLogicContext ctx) {
812 Object response = null;
813 QueryStatus retval = QueryStatus.SUCCESS;
814 String modifier = null;
816 HashMap<String, String> nameValues = AAIServiceUtils.keyToHashMap(key, ctx);
817 if(resource.contains(":")) {
818 modifier = resource.split(":")[1];
822 AAIRequest request = AAIRequest.createRequest(resource, nameValues);
823 if(request == null) {
824 return QueryStatus.FAILURE;
827 Map<String, String> params = new HashMap<>();
829 request.processRequestPathValues(nameValues);
830 if(nameValues.containsKey("prefix")){
831 Map<String, String> tmpParams = ctxGetBeginsWith(ctx, nameValues.get("prefix"));
832 if(!tmpParams.isEmpty()) {
833 params.putAll(tmpParams);
835 if("named-query".equals(resource))
836 request.setRequestObject(extractNamedQueryDataFromQueryPrefix(nameValues, params));
838 String rv = getExecutor().get(request);
840 retval = processResponseData(rv, resource, request, prefix, ctx, nameValues, modifier);
842 } catch(AAIServiceException aaiexc) {
843 int errorCode = aaiexc.getReturnCode();
844 ctx.setAttribute(prefix + ".error.message", aaiexc.getMessage());
845 if(errorCode >= 300) {
846 ctx.setAttribute(prefix + ".error.http.response-code",
847 Integer.toString(aaiexc.getReturnCode()));
850 if(aaiexc.getReturnCode() == 404)
851 return QueryStatus.NOT_FOUND;
853 return QueryStatus.FAILURE;
854 } catch (Exception exc) {
855 getLogger().warn("requestGenericVnfData", exc);
856 ctx.setAttribute(prefix + ".error.message", exc.getMessage());
857 return QueryStatus.FAILURE;
863 public QueryStatus processResponseData(String rv, String resource, AAIRequest request, String prefix, SvcLogicContext ctx, HashMap<String, String> nameValues, String modifier) throws JsonParseException, JsonMappingException, IOException, AAIServiceException
868 return QueryStatus.NOT_FOUND;
871 response = request.jsonStringToObject(rv);
872 if(response == null) {
873 return QueryStatus.NOT_FOUND;
876 if("generic-query".equals(resource)) {
877 SearchResults rd = SearchResults.class.cast(response);
878 List<ResultData> rdList = rd.getResultData();
879 if(rdList == null || rdList.isEmpty()) {
880 return QueryStatus.NOT_FOUND;
882 ResultData rDatum = rdList.get(0);
883 nameValues.put("selflink", rDatum.getResourceLink());
884 AAIRequest req2 = AAIRequest.createRequest(rDatum.getResourceType(), nameValues);
885 req2.processRequestPathValues(nameValues);
886 rv = getExecutor().get(req2);
888 return QueryStatus.NOT_FOUND;
891 response = req2.jsonStringToObject(rv);
892 if(response == null) {
893 return QueryStatus.NOT_FOUND;
897 if("named-query".equals(resource)) {
898 InventoryResponseItems rd = InventoryResponseItems.class.cast(response);
899 List<InventoryResponseItem> iRIlist = rd.getInventoryResponseItem();
900 if(iRIlist == null || iRIlist.isEmpty()) {
901 return QueryStatus.NOT_FOUND;
905 if("nodes-query".equals(resource)) {
906 SearchResults rd = SearchResults.class.cast(response);
907 List<ResultData> rdList = rd.getResultData();
908 if(rdList == null || rdList.isEmpty()) {
909 return QueryStatus.NOT_FOUND;
911 ResultData rDatum = rdList.get(0);
915 if("formatted-query".equals(resource) || "custom-query".equals(resource)) {
916 FormattedQueryResultList rd = FormattedQueryResultList.class.cast(response);
917 List<Result> iRIlist = rd.getResults();
918 if(iRIlist == null || iRIlist.isEmpty()) {
919 return QueryStatus.NOT_FOUND;
923 // process relationship list
924 // this is a temporary soluton to address the realationship handling changes added in Release 17.07
926 Class<?> clazz = response.getClass();
927 Method getter = clazz.getMethod("getRelationshipList");
928 Object obj = getter.invoke(response);
929 if(obj != null && obj instanceof RelationshipList) {
930 RelationshipList list = RelationshipList.class.cast(obj);
931 AAIServiceUtils.populateRelationshipDataFromPath(list);
933 } catch(Exception exc) {
934 getLogger().debug("Retrofiting relationship data: " + exc.getMessage());
938 if(prefix == null || prefix.isEmpty()) {
941 preFix = prefix + ".";
944 Map<String,Object> props = objectToProperties(response);
945 Set<String> keys = props.keySet();
946 for(String theKey: keys) {
947 if(getLogger().isTraceEnabled())
948 getLogger().trace(theKey);
950 Object value = props.get(theKey);
953 Object type = value.getClass();
954 if(value instanceof String) {
955 ctx.setAttribute(preFix + theKey, value.toString());
958 if(value instanceof Boolean) {
959 ctx.setAttribute(preFix + theKey, value.toString());
962 if(value instanceof Integer) {
963 ctx.setAttribute(preFix + theKey, value.toString());
966 if(value instanceof Long) {
967 ctx.setAttribute(preFix + theKey, value.toString());
971 if(value instanceof ArrayList) {
972 ArrayList<?> array = ArrayList.class.cast(value);
973 for(int i = 0; i < array.size(); i++) {
974 writeList(array, String.format("%s.%s", prefix, theKey), ctx);
979 if("relationship-list".equals(theKey)){
980 Map<String, Object> relationshipList = (Map<String, Object>)value;
981 // we are interested in seeing just the selected relationship
982 if(theKey.equals(modifier)) {
983 List<?> relationships = (List<?>)relationshipList.get("relationship");
984 if(relationships != null && !relationships.isEmpty()) {
986 List newRelationships = new LinkedList();
987 newRelationships.addAll(relationships);
989 for(Object obj : newRelationships){
990 if(obj instanceof Map<?, ?>) {
991 Map<?, ?> relProperties = (Map<?, ?>)obj;
992 if(relProperties.containsKey("related-to")) {
993 Object relPropsRelatedTo = relProperties.get("related-to");
995 String relatedTo = nameValues.get("related_to");
996 if(relatedTo != null) {
997 relatedTo = relatedTo.trim().replace("'", "").replace("$", "").replace("'", "");
998 if(!relatedTo.equals(relPropsRelatedTo)) {
999 relationships.remove(relProperties);
1010 writeMap(relationshipList, String.format("%s.%s", prefix, theKey), ctx);
1014 if(value instanceof Map) {
1015 Map<String, Object> subnetsList = (Map<String, Object>)value;
1016 writeMap(subnetsList, String.format("%s.%s", prefix, theKey), ctx);
1021 return QueryStatus.SUCCESS;
1025 public QueryStatus newModelBackupRequest(String resource, Map<String, String> params, String prefix, SvcLogicContext ctx) {
1027 QueryStatus retval = QueryStatus.SUCCESS;
1028 HashMap<String, String> nameValues = new HashMap<>();
1031 AAIRequest request = AAIRequest.createRequest(resource, nameValues);
1032 if(request == null) {
1033 return QueryStatus.FAILURE;
1036 boolean argsFound = false;
1037 String[] arguments = request.getArgsList();
1038 for(String name : arguments) {
1039 String tmpName = name.replaceAll("-", "_");
1040 String value = params.get(tmpName);
1041 if(value != null && !value.isEmpty()) {
1042 value = value.trim().replace("'", "").replace("$", "").replace("'", "");
1043 request.addRequestProperty(name, value);
1048 getLogger().warn("No arguments were found. Terminating backup request.");
1049 return QueryStatus.FAILURE;
1052 String rv = getExecutor().get(request);
1053 ctx.setAttribute(prefix, rv);
1054 } catch(AAIServiceException aaiexc) {
1055 if(aaiexc.getReturnCode() == 404)
1056 return QueryStatus.NOT_FOUND;
1058 return QueryStatus.FAILURE;
1059 } catch (Exception exc) {
1060 getLogger().warn("newModelBackupRequest", exc);
1061 return QueryStatus.FAILURE;
1067 public AAIDatum newModelObjectRequest(String resource, Map<String, String> params, String prefix, SvcLogicContext ctx)
1068 throws AAIServiceException {
1070 AAIDatum response = null;
1073 AAIRequest request = AAIRequest.createRequest(resource, params);
1074 if(request == null) {
1078 request.processRequestPathValues(params);
1079 String rv = getExecutor().get(request);
1080 response = request.jsonStringToObject(rv);
1081 } catch(AAIServiceException aaiexc) {
1083 } catch (Exception exc) {
1084 getLogger().warn("newModelBackupRequest", exc);
1085 throw new AAIServiceException(exc);
1093 public QueryStatus release(String arg0, String arg1, SvcLogicContext arg2) throws SvcLogicException {
1094 // TODO Auto-generated method stub
1095 throw new SvcLogicException("Method AAIService.release() has not been implemented yet");
1099 public QueryStatus reserve(String arg0, String arg1, String arg2, String arg3, SvcLogicContext arg4)
1100 throws SvcLogicException {
1101 // TODO Auto-generated method stub
1102 throw new SvcLogicException("Method AAIService.reserve() has not been implemented yet");
1105 private QueryStatus newModelSave(String resource, boolean force, String key, Map<String, String> params, String prefix, SvcLogicContext ctx) {
1106 getLogger().debug("Executing newModelSave for resource : " + resource);
1107 HashMap<String, String> nameValues = AAIServiceUtils.keyToHashMap(key, ctx);
1110 ArrayList<String> subResources = new ArrayList<>();
1111 Set<String> set = params.keySet();
1112 Map<String, Method> setters = new HashMap<>();
1113 Map<String, Method> getters = new HashMap<>();
1116 AAIRequest request = AAIRequest.createRequest(resource, nameValues);
1117 Class<? extends AAIDatum> resourceClass = request.getModelClass();
1118 getLogger().debug(resourceClass.getName());
1119 AAIDatum instance = resourceClass.newInstance();
1122 Annotation[] annotations = resourceClass.getAnnotations();
1123 for(Annotation annotation : annotations) {
1124 Class<? extends Annotation> anotationType = annotation.annotationType();
1125 String annotationName = anotationType.getName();
1127 // 2. find string property setters and getters for the lists
1128 if("javax.xml.bind.annotation.XmlType".equals(annotationName)){
1129 XmlType order = (XmlType)annotation;
1130 String[] values = order.propOrder();
1131 for(String value : values) {
1132 String id = AAIServiceUtils.camelCaseToDashedString(value);
1133 Field field = resourceClass.getDeclaredField(value);
1134 Class<?> type = field.getType();
1135 Method setter = null;
1137 setter = resourceClass.getMethod("set"+StringUtils.capitalize(value), type);
1138 if(type.getName().startsWith("java.lang") || "boolean".equals(type.getName()) || "long".equals(type.getName())) {
1140 setter.setAccessible(true);
1141 Object arglist[] = new Object[1];
1142 arglist[0] = params.get(id);
1144 if(arglist[0] != null) {
1145 if(!type.getName().equals("java.lang.String")) {
1146 // getLogger().debug(String.format("Processing %s with parameter %s", types[0].getName(), value));
1147 if("boolean".equals(type.getName())) {
1148 arglist[0] = valueOf(Boolean.class, params.get(id));
1149 } else if("long".equals(type.getName())) {
1150 arglist[0] = valueOf(Long.class, params.get(id));
1152 arglist[0] = valueOf(type, params.get(id));
1155 Object o = setter.invoke(instance, arglist);
1159 } catch (Exception x) {
1160 Throwable cause = x.getCause();
1161 getLogger().warn("Failed process for " + resourceClass.getName(), x);
1163 } else if(type.getName().equals("java.util.List")) {
1164 List<String> newValues = new ArrayList<>();
1165 String length = id+"_length";
1166 if(!params.isEmpty() && params.containsKey(length)) {
1167 String tmp = params.get(length);
1168 int count = Integer.parseInt(tmp);
1169 for(int i=0; i<count; i++) {
1170 String tmpValue = params.get(String.format("%s[%d]", id, i));
1171 newValues.add(tmpValue);
1173 if(!newValues.isEmpty()) {
1174 Object o = setter.invoke(instance, newValues);
1179 setters.put(id, setter);
1181 } catch(Exception exc) {
1187 getter = resourceClass.getMethod("get"+StringUtils.capitalize(value));
1188 if(!type.getName().equals("java.lang.String")) {
1189 getters.put(id, getter);
1191 } catch(Exception exc) {
1196 subResources.addAll(Arrays.asList(values));
1201 // remove getters that have matching setter
1202 for(String setKey : setters.keySet()) {
1203 if(getters.containsKey(setKey)) {
1204 getters.remove(setKey);
1208 Set<String> relationshipKeys = new TreeSet<>();
1209 Set<String> vlansKeys = new TreeSet<>();
1210 Set<String> metadataKeys = new TreeSet<>();
1212 for(String attribute : set) {
1213 String value = params.get(attribute);
1214 if(attribute.startsWith("relationship-list")) {
1215 relationshipKeys.add(attribute);
1216 } else if(attribute.startsWith("vlans")) {
1217 vlansKeys.add(attribute);
1218 } else if(attribute.startsWith("metadata")) {
1219 metadataKeys.add(attribute);
1222 // 3. find list property getters
1223 for(String attribute : set) {
1224 String value = params.get(attribute);
1225 Method method = getters.get(attribute);
1226 if(method != null) {
1228 method.setAccessible(true);
1229 Object arglist[] = new Object[0];
1230 // arglist[0] = value;
1231 Class<?>[] types = method.getParameterTypes();
1232 if(types.length == 0){
1233 Object o = method.invoke(instance, arglist);
1234 if(o instanceof ArrayList) {
1235 ArrayList<String> values = (ArrayList<String>)o;
1236 // getLogger().debug(String.format("Processing %s with parameter %s", types[0].getName(), value));
1237 value = value.replace("[", "").replace("]", "");
1238 List<String> items = Arrays.asList(value.split("\\s*,\\s*"));
1239 for(String s : items) {
1240 values.add(s.trim());
1244 } catch (Exception x) {
1245 Throwable cause = x.getCause();
1246 getLogger().warn("Failed process for " + resourceClass.getName(), x);
1250 // 4. Process Relationships
1251 // add relationship list
1252 if( (subResources.contains("relationship-list") || subResources.contains("relationshipList")) && !relationshipKeys.isEmpty()) {
1253 RelationshipList relationshipList = null;
1255 Method getRelationshipListMethod = null;
1257 getRelationshipListMethod = resourceClass.getMethod("getRelationshipList");
1258 } catch(Exception exc) {
1259 getLogger().debug("Retrofiting relationship data: " + exc.getMessage());
1262 if(getRelationshipListMethod != null){
1264 getRelationshipListMethod.setAccessible(true);
1265 obj = getRelationshipListMethod.invoke(instance);
1266 } catch (InvocationTargetException x) {
1267 Throwable cause = x.getCause();
1270 if(obj != null && obj instanceof RelationshipList){
1271 relationshipList = (RelationshipList)obj;
1273 relationshipList = new RelationshipList();
1274 Method setRelationshipListMethod = resourceClass.getMethod("setRelationshipList", RelationshipList.class);
1275 if(setRelationshipListMethod != null){
1277 setRelationshipListMethod.setAccessible(true);
1278 Object arglist[] = new Object[1];
1279 arglist[0] = relationshipList;
1281 obj = setRelationshipListMethod.invoke(instance, arglist);
1282 } catch (InvocationTargetException x) {
1283 Throwable cause = x.getCause();
1288 List<Relationship> relationships = relationshipList.getRelationship();
1292 String searchKey = "relationship-list.relationship[" + i + "].related-to";
1293 if(!params.containsKey(searchKey))
1296 String relatedTo = params.get(searchKey);
1297 String relatedLinkKey = "relationship-list.relationship[" + i + "].related-link";
1298 String relatedLink = null;
1299 if(params.containsKey(relatedLinkKey)) {
1300 relatedLink = params.get(relatedLinkKey);
1302 Relationship relationship = new Relationship();
1303 relationships.add(relationship);
1304 relationship.setRelatedTo(relatedTo);
1305 if(relatedLink != null) {
1306 relationship.setRelatedLink(relatedLink);
1308 // List<RelationshipData> relData = relationship.getRelationshipData();
1309 Map<String, String> relParams = new HashMap<>();
1312 String searchRelationshipKey = "relationship-list.relationship[" + i + "].relationship-data[" + j + "].relationship-key";
1313 String searchRelationshipValue = "relationship-list.relationship[" + i + "].relationship-data[" + j + "].relationship-value";
1314 if(!params.containsKey(searchRelationshipKey))
1317 relParams.put(params.get(searchRelationshipKey), params.get(searchRelationshipValue));
1320 AAIRequest rlRequest = AAIRequest.createRequest(relatedTo, relParams);
1321 for(Map.Entry<String,String> entry : relParams.entrySet()) {
1322 rlRequest.addRequestProperty(entry.getKey(), entry.getValue());
1324 String path = rlRequest.updatePathDataValues(null);
1325 relationship.setRelatedLink(path);
1332 if(subResources.contains("vlans") && !vlansKeys.isEmpty()) {
1334 Vlans vlanList = null;
1335 Method getVLansMethod = resourceClass.getMethod("getVlans");
1336 if(getVLansMethod != null){
1338 getVLansMethod.setAccessible(true);
1339 obj = getVLansMethod.invoke(instance);
1340 } catch (InvocationTargetException x) {
1341 Throwable cause = x.getCause();
1344 if(obj != null && obj instanceof Vlans){
1345 vlanList = (Vlans)obj;
1347 vlanList = new Vlans();
1348 Method setVlansMethod = resourceClass.getMethod("setVlans", Vlans.class);
1349 if(setVlansMethod != null){
1351 setVlansMethod.setAccessible(true);
1352 Object arglist[] = new Object[1];
1353 arglist[0] = vlanList;
1355 obj = setVlansMethod.invoke(instance, arglist);
1356 } catch (InvocationTargetException x) {
1357 Throwable cause = x.getCause();
1364 String searchKey = "vlans.vlan[" + i + "].vlan-interface";
1365 if(!params.containsKey(searchKey))
1368 String vlanInterface = params.get("vlans.vlan[" + i + "].vlan-interface");
1369 String vlanIdInner = params.get("vlans.vlan[" + i + "].vlan-id-inner");
1370 String vlanIdOute = params.get("vlans.vlan[" + i + "].vlan-id-outer");
1371 String speedValue = params.get("vlans.vlan[" + i + "].speed-value");
1372 String speedUnits = params.get("vlans.vlan[" + i + "].speed-units");
1374 Vlan vlan = new Vlan();
1375 vlan.setVlanInterface(vlanInterface);
1377 if(vlanIdInner != null) {
1378 Long iVlanIdInner = Long.parseLong(vlanIdInner);
1379 vlan.setVlanIdInner(iVlanIdInner);
1382 if(vlanIdOute != null) {
1383 Long iVlanIdOuter = Long.parseLong(vlanIdOute);
1384 vlan.setVlanIdOuter(iVlanIdOuter);
1387 if(speedValue != null) {
1388 vlan.setSpeedValue(speedValue);
1389 vlan.setSpeedUnits(speedUnits);
1392 vlanList.getVlan().add(vlan);
1398 if(subResources.contains("metadata") && !metadataKeys.isEmpty()) {
1400 Metadata metadataList = null;
1401 Method getMetadataMethod = resourceClass.getMethod("getMetadata");
1402 if(getMetadataMethod != null){
1404 getMetadataMethod.setAccessible(true);
1405 obj = getMetadataMethod.invoke(instance);
1406 } catch (InvocationTargetException x) {
1407 Throwable cause = x.getCause();
1410 if(obj != null && obj instanceof Metadata){
1411 metadataList = (Metadata)obj;
1413 metadataList = new Metadata();
1414 Method setMetadataMethod = resourceClass.getMethod("setMetadata", Metadata.class);
1415 if(setMetadataMethod != null){
1417 setMetadataMethod.setAccessible(true);
1418 Object arglist[] = new Object[1];
1419 arglist[0] = metadataList;
1421 obj = setMetadataMethod.invoke(instance, arglist);
1422 } catch (InvocationTargetException x) {
1423 Throwable cause = x.getCause();
1428 if(metadataList.getMetadatum() == null) {
1429 // metadataList.setMetadatum(new ArrayList<Metadatum>());
1435 String metaKey = "metadata.metadatum[" + i + "].meta-key";
1436 if(!params.containsKey(metaKey))
1439 String metaValue = params.get("metadata.metadatum[" + i + "].meta-value");
1441 Metadatum vlan = new Metadatum();
1442 vlan.setMetaname(metaKey);
1443 vlan.setMetaval(metaValue);
1445 metadataList.getMetadatum().add(vlan);
1452 // 6. Prepare AAI request
1453 String[] args = request.getArgsList();
1454 for(String arg : args) {
1455 String modifiedKey = arg.replaceAll("-", "_");
1456 if(nameValues.containsKey(modifiedKey)) {
1457 String argValue = nameValues.get(modifiedKey);
1458 if(argValue != null) argValue = argValue.trim().replace("'", "").replace("$", "").replace("'", "");
1459 request.addRequestProperty(arg, argValue);
1463 request.processRequestPathValues(nameValues);
1464 request.setRequestObject(instance);
1465 Object response = getExecutor().post(request);
1466 if(request.expectsDataFromPUTRequest()){
1467 if(response != null && response instanceof String) {
1468 String rv = response.toString();
1469 QueryStatus retval = processResponseData(rv, resource, request, prefix, ctx, nameValues, null);
1470 getLogger().debug("newModelSave - returning " + retval.toString());
1475 } catch(AAIServiceException exc){
1476 ctx.setAttribute(prefix + ".error.message", exc.getMessage());
1477 int returnCode = exc.getReturnCode();
1478 if(returnCode >= 300) {
1479 ctx.setAttribute(prefix + ".error.http.response-code",
1480 Integer.toString(exc.getReturnCode()));
1483 if(returnCode == 400 || returnCode == 412)
1484 return QueryStatus.FAILURE;
1485 else if(returnCode == 404)
1486 return QueryStatus.NOT_FOUND;
1488 getLogger().warn("Failed newModelSave - returning FAILURE", exc);
1489 return QueryStatus.FAILURE;
1491 } catch(Exception exc){
1492 getLogger().warn("Failed newModelSave - returning FAILURE", exc);
1493 ctx.setAttribute(prefix + ".error.message", exc.getMessage());
1494 return QueryStatus.FAILURE;
1497 getLogger().debug("newModelSave - returning SUCCESS");
1498 return QueryStatus.SUCCESS;
1501 private QueryStatus newModelProcessRelationshipList(Object instance, Map<String, String> params, String prefix, SvcLogicContext ctx) throws Exception {
1503 Class resourceClass = instance.getClass();
1505 Set<String> relationshipKeys = new TreeSet<>();
1507 Set<String> set = params.keySet();
1509 for(String attribute : set) {
1510 String value = params.get(attribute);
1512 if(attribute.startsWith("relationship-list")) {
1513 relationshipKeys.add(attribute);
1517 // 3. Process Relationships
1518 // add relationship list
1519 if(!relationshipKeys.isEmpty()) {
1520 RelationshipList relationshipList;
1522 Method getRelationshipListMethod = null;
1524 getRelationshipListMethod = resourceClass.getMethod("getRelationshipList");
1525 } catch(Exception exc) {
1526 getLogger().debug("Retrofiting relationship data: " + exc.getMessage());
1528 if(getRelationshipListMethod != null){
1530 getRelationshipListMethod.setAccessible(true);
1531 obj = getRelationshipListMethod.invoke(instance);
1532 } catch (InvocationTargetException x) {
1533 Throwable cause = x.getCause();
1536 if(obj != null && obj instanceof RelationshipList){
1537 relationshipList = (RelationshipList)obj;
1539 relationshipList = new RelationshipList();
1540 Method setRelationshipListMethod = resourceClass.getMethod("setRelationshipList", RelationshipList.class);
1541 if(setRelationshipListMethod != null){
1543 setRelationshipListMethod.setAccessible(true);
1544 Object arglist[] = new Object[1];
1545 arglist[0] = relationshipList;
1547 obj = setRelationshipListMethod.invoke(instance, arglist);
1548 } catch (InvocationTargetException x) {
1549 Throwable cause = x.getCause();
1554 boolean createdNewRelationships = false;
1555 List<Relationship> relationships = relationshipList.getRelationship();
1556 if(relationships == null) {
1557 relationships = new ArrayList<>();
1558 createdNewRelationships = true;
1563 String searchKey = "relationship-list.relationship[" + i + "].related-to";
1564 if(!params.containsKey(searchKey))
1568 String relatedTo = params.get(searchKey);
1569 String relatedLinkKey = "relationship-list.relationship[" + i + "].related-link";
1570 String relatedLink = null;
1571 if(params.containsKey(relatedLinkKey)) {
1572 relatedLink = params.get(relatedLinkKey);
1575 Relationship relationship = new Relationship();
1576 relationships.add(relationship);
1577 relationship.setRelatedTo(relatedTo);
1578 if(relatedLink != null) {
1579 relationship.setRelatedLink(relatedLink);
1581 Map<String, String> relParams = new HashMap<>();
1584 String searchRelationshipKey = "relationship-list.relationship[" + i + "].relationship-data[" + j + "].relationship-key";
1585 String searchRelationshipValue = "relationship-list.relationship[" + i + "].relationship-data[" + j + "].relationship-value";
1586 if(!params.containsKey(searchRelationshipKey))
1589 relParams.put(params.get(searchRelationshipKey), params.get(searchRelationshipValue));
1592 AAIRequest rlRequest = AAIRequest.createRequest(relatedTo, relParams);
1593 for(Map.Entry<String,String> entry : relParams.entrySet()) {
1594 rlRequest.addRequestProperty(entry.getKey(), entry.getValue());
1596 String path = rlRequest.updatePathDataValues(null);
1597 relationship.setRelatedLink(path);
1604 return QueryStatus.SUCCESS;
1607 private QueryStatus newModelProcessMetadata(Object instance, Map<String, String> params, String prefix, SvcLogicContext ctx) throws Exception {
1609 if (!(instance instanceof ServiceInstance) && !(instance instanceof Image)) {
1610 throw new IllegalArgumentException("request is not applicable for selected request");
1613 Class resourceClass = instance.getClass();
1614 Set<String> metadataKeys = new TreeSet<String>();
1615 Set<String> set = params.keySet();
1616 for(String attribute : set) {
1617 if(attribute.startsWith("metadata")) {
1618 metadataKeys.add(attribute);
1622 // 3. Process Metadata
1624 if(!metadataKeys.isEmpty()) {
1625 Metadata metadata = null;
1627 Method getMetadataMethod = resourceClass.getMethod("getMetadata");
1628 if(getMetadataMethod != null){
1630 getMetadataMethod.setAccessible(true);
1631 obj = getMetadataMethod.invoke(instance);
1632 } catch (InvocationTargetException x) {
1633 Throwable cause = x.getCause();
1636 if(obj != null && obj instanceof Metadata){
1637 metadata = (Metadata)obj;
1639 metadata = new Metadata();
1640 Method setMetadataMethod = resourceClass.getMethod("setMetadata", Metadata.class);
1641 if(setMetadataMethod != null){
1643 setMetadataMethod.setAccessible(true);
1644 setMetadataMethod.invoke(instance, metadata);
1645 } catch (InvocationTargetException x) {
1650 List<Metadatum> metadatumList = metadata.getMetadatum();
1653 String metaNameKey = "metadata.metadatum[" + i + "].metaname";
1654 String metaValueKey = "metadata.metadatum[" + i + "].metaval";
1655 if(!params.containsKey(metaNameKey) || !params.containsKey(metaValueKey))
1658 Metadatum metadatum = new Metadatum();
1659 metadatum.setMetaname(params.get(metaNameKey));
1660 metadatum.setMetaval(params.get(metaValueKey));
1661 metadatumList.add(metadatum);
1667 return QueryStatus.SUCCESS;
1670 private Relationship findRelationship(List<Relationship> relationships, String relatedTo) {
1671 if(relatedTo == null)
1674 for(Relationship relationship : relationships) {
1675 if(relationship.getRelatedTo().equals(relatedTo)){
1676 return relationship;
1683 public QueryStatus backup(Map<String, String> params, SvcLogicContext ctx) throws SvcLogicException {
1684 String resource = params.get("resource").toLowerCase();
1685 String prefix = params.get("data-key");
1687 HashMap<String, String> nameValues = new HashMap<>();
1688 if(AAIRequest.createRequest(resource, nameValues) != null) {
1691 return newModelBackupRequest(resource, params, prefix, ctx);
1692 } catch (Exception exc) {
1693 getLogger().warn("Failed backup - returning FAILURE", exc);
1694 return QueryStatus.FAILURE;
1698 return QueryStatus.NOT_FOUND;
1702 public QueryStatus restore(Map<String, String> params, SvcLogicContext ctx) throws SvcLogicException {
1704 QueryStatus retval = QueryStatus.SUCCESS;
1705 String resource = params.get("resource").toLowerCase();
1706 String prefix = params.get("data-key");
1708 HashMap<String, String> nameValues = new HashMap<>();
1709 if(AAIRequest.createRequest(resource, nameValues) != null) {
1712 retval = newModelBackupRequest(resource, params, "tmpRestore", ctx);
1713 if(retval == QueryStatus.SUCCESS) {
1714 String current_json = ctx.getAttribute("tmpRestore");
1715 ctx. setAttribute("tmpRestore", null);
1717 String snapshot_json = ctx.getAttribute(prefix);
1719 } catch (Exception exc) {
1720 getLogger().warn("Failed restore - returning FAILURE", exc);
1721 return QueryStatus.FAILURE;
1725 return QueryStatus.NOT_FOUND;
1728 protected Map<String, Object> objectToProperties(Object object) {
1729 ObjectMapper mapper = AAIService.getObjectMapper();
1730 return mapper.convertValue(object, Map.class);
1733 static <T> T valueOf(Class<T> klazz, String arg) {
1734 Exception cause = null;
1737 ret = klazz.cast(klazz.getDeclaredMethod("valueOf", String.class).invoke(null, arg));
1738 } catch (NoSuchMethodException exc) {
1739 LoggerFactory.getLogger(AAIService.class).warn("Wrong data type", exc);
1740 ret = klazz.cast(arg);
1741 } catch (IllegalAccessException e) {
1743 } catch (InvocationTargetException e) {
1746 if (cause == null) {
1749 throw new IllegalArgumentException(cause);
1753 private QueryStatus processDeleteRelationshipList(String resource, String key, SvcLogicContext ctx, HashMap<String, String> nameValues) {
1755 AAIRequest request = AAIRequest.createRequest(resource, nameValues);
1756 if(request == null) {
1757 return QueryStatus.FAILURE;
1760 request.processRequestPathValues(nameValues);
1761 URL url = request.getRequestUrl("GET", null);
1763 Class resourceClass = request.getModelClass();
1764 Object instance = getResource(url.toString(), resourceClass);
1765 if(instance == null)
1766 return QueryStatus.NOT_FOUND;
1768 // get resource version
1769 String resourceVersion = null;
1770 Method getResourceVersionMethod = resourceClass.getMethod("getResourceVersion");
1771 if(getResourceVersionMethod != null){
1773 getResourceVersionMethod.setAccessible(true);
1774 Object object = getResourceVersionMethod.invoke(instance);
1776 resourceVersion = object.toString();
1777 } catch (InvocationTargetException x) {
1778 Throwable cause = x.getCause();
1782 RelationshipList relationshipList = null;
1784 Method getRelationshipListMethod = null;
1786 getRelationshipListMethod = resourceClass.getMethod("getRelationshipList");
1787 } catch(Exception exc) {
1788 getLogger().debug("Retrofiting relationship data: " + exc.getMessage());
1790 if(getRelationshipListMethod != null){
1792 getRelationshipListMethod.setAccessible(true);
1793 obj = getRelationshipListMethod.invoke(instance);
1794 } catch (InvocationTargetException x) {
1795 Throwable cause = x.getCause();
1798 if(obj != null && obj instanceof RelationshipList){
1799 relationshipList = (RelationshipList)obj;
1801 getLogger().debug("No relationships found to process.");
1802 return QueryStatus.NOT_FOUND;
1805 if(relationshipList.getRelationship() == null || relationshipList.getRelationship().isEmpty()) {
1806 return QueryStatus.NOT_FOUND;
1808 String relatedTo = nameValues.get("related_to");
1809 if(relatedTo == null) {
1810 return QueryStatus.FAILURE;
1813 relatedTo = relatedTo.replaceAll("_", "-");
1815 String relatedLink = nameValues.get("relationship.related_link");
1816 if(relatedLink != null) {
1817 relatedLink = URLDecoder.decode(relatedLink, "UTF-8");
1820 List<Relationship> relationships = relationshipList.getRelationship();
1821 List<Relationship> relationshipsToDelete = new LinkedList<>();
1823 for(Relationship relationship : relationships) {
1824 if(relatedTo.equals(relationship.getRelatedTo())) {
1825 if(relatedLink != null) {
1826 if(relationship.getRelatedLink() != null ) {
1827 String localRelatedLink = relationship.getRelatedLink();
1828 localRelatedLink = URLDecoder.decode(localRelatedLink, "UTF-8");
1829 if(localRelatedLink.endsWith(relatedLink)) {
1830 getLogger().debug(String.format("Found relationship of '%s' to keyword '%s'", relationship.getRelatedTo(), relatedTo));
1831 relationshipsToDelete.add(relationship);
1835 getLogger().debug(String.format("Found relationship of '%s' to keyword '%s'", relationship.getRelatedTo(), relatedTo));
1836 relationshipsToDelete.add(relationship);
1840 if(relationshipsToDelete == null || relationshipsToDelete.isEmpty()) {
1841 getLogger().info(String.format("Relationship has not been found for %s", key));
1842 return QueryStatus.NOT_FOUND;
1845 String path = url.toString();
1846 path = path + "/relationship-list/relationship";
1847 URL deleteUrl = new URL(path);
1849 ObjectMapper mapper = AAIService.getObjectMapper();
1851 boolean cumulativeResponse = true;
1853 for(Relationship targetRelationship : relationshipsToDelete) {
1854 String json_text = mapper.writeValueAsString(targetRelationship);
1855 boolean response = deleteList(deleteUrl, json_text);
1857 cumulativeResponse = response;
1861 if(!cumulativeResponse)
1862 return QueryStatus.FAILURE;
1864 return QueryStatus.SUCCESS;
1866 } catch(Exception exc) {
1867 getLogger().warn("processDelete", exc);
1868 return QueryStatus.FAILURE;
1872 private QueryStatus processDeleteMetadata(String resource, String key, SvcLogicContext ctx, HashMap<String, String> nameValues) {
1874 AAIRequest request = AAIRequest.createRequest(resource, nameValues);
1875 if(request == null) {
1876 return QueryStatus.FAILURE;
1879 request.processRequestPathValues(nameValues);
1880 URL url = request.getRequestUrl("GET", null);
1882 Class resourceClass = request.getModelClass();
1883 Object instance = getResource(url.toString(), resourceClass);
1885 // get resource version
1886 String resourceVersion = null;
1887 Method getResourceVersionMethod = resourceClass.getMethod("getResourceVersion");
1888 if(getResourceVersionMethod != null){
1890 getResourceVersionMethod.setAccessible(true);
1891 resourceVersion = (String) getResourceVersionMethod.invoke(instance);
1892 } catch (InvocationTargetException x) {
1896 Metadata metadata = null;
1898 Method getMetadataMethod = resourceClass.getMethod("getMetadata");
1899 if(getMetadataMethod != null){
1901 getMetadataMethod.setAccessible(true);
1902 obj = getMetadataMethod.invoke(instance);
1903 } catch (InvocationTargetException x) {
1904 Throwable cause = x.getCause();
1907 if(obj != null && obj instanceof Metadata){
1908 metadata = (Metadata)obj;
1910 getLogger().debug("No metadata found to process.");
1911 return QueryStatus.NOT_FOUND;
1914 if(metadata.getMetadatum() == null || metadata.getMetadatum().isEmpty()) {
1915 return QueryStatus.NOT_FOUND;
1918 List<Metadatum> metadatumList = metadata.getMetadatum();
1919 Metadatum metadatumToDelete = null;
1921 final String metaname = nameValues.get("metaname");
1923 for(Metadatum metadatum : metadatumList) {
1924 getLogger().debug(String.format("Comparing existing metadatum of '%s' to keyword '%s'", metadatum.getMetaname(), metaname));
1925 if(metaname.equals(metadatum.getMetaname())) {
1926 metadatumToDelete = metadatum;
1930 if(metadatumToDelete == null) {
1931 getLogger().info(String.format("Metadatum has not been found for %s", key));
1932 return QueryStatus.NOT_FOUND;
1935 String path = url.toString();
1936 path = path + "/metadata/metadatum/" + encodeQuery( metadatumToDelete.getMetaname() ) +
1937 "?resource-version=" + metadatumToDelete.getResourceVersion();
1938 URL deleteUrl = new URL(path);
1939 boolean response = deleteList(deleteUrl, null);
1942 return QueryStatus.FAILURE;
1944 return QueryStatus.SUCCESS;
1946 } catch(Exception exc) {
1947 getLogger().warn("processDelete", exc);
1948 return QueryStatus.FAILURE;
1952 protected String encodeQuery(String param) throws UnsupportedEncodingException {
1953 return URLEncoder.encode(param, "UTF-8").replace("+", "%20");
1956 static final Map<String, String> ctxGetBeginsWith( SvcLogicContext ctx, String prefix ) {
1957 Map<String, String> tmpPrefixMap = new HashMap<>();
1959 if(prefix == null || prefix.isEmpty()){
1960 return tmpPrefixMap;
1963 for( String key : ctx.getAttributeKeySet() ) {
1964 if( key.startsWith(prefix) ) {
1965 String tmpKey = key.substring(prefix.length() + 1);
1966 tmpPrefixMap.put( tmpKey, ctx.getAttribute(key));
1970 Map<String, String> prefixMap = new HashMap<>();
1971 Pattern p = Pattern.compile(".*\\[\\d\\]");
1973 SortedSet<String> keys = new TreeSet(tmpPrefixMap.keySet () );
1974 for(String key : keys) {
1975 Matcher m = p.matcher(key);
1978 } else if(key.endsWith("_length")) {
1979 String listKey = key.substring(0, key.indexOf("_length"));
1980 int max = Integer.parseInt(tmpPrefixMap.get(key));
1982 ArrayList<String> data = new ArrayList<>();
1983 for(int x = 0; x < max; x++){
1984 String tmpKey = String.format("%s[%d]", listKey, x);
1985 String tmpValue = tmpPrefixMap.get(tmpKey);
1986 if(tmpValue != null && !tmpValue.isEmpty()) {
1990 if(!data.isEmpty()) {
1991 prefixMap.put(listKey, data.toString());
1993 prefixMap.put(key, tmpPrefixMap.get(key));
1996 prefixMap.put(key, tmpPrefixMap.get(key));
2005 protected NamedQueryData extractNamedQueryDataFromQueryPrefix(HashMap<String, String> nameValues, Map<String, String> parms) {
2006 if(parms.isEmpty()) {
2010 NamedQueryData data = new NamedQueryData();
2013 if(data.getQueryParameters() == null) {
2014 data.setQueryParameters(new QueryParameters());
2016 String namedQueryUuid = nameValues.get("named-query-uuid".replaceAll("-", "_"));
2017 if(namedQueryUuid == null) {
2018 namedQueryUuid = parms.get("query-parameters.named-query.named-query-uuid");
2020 NamedQuery namedQuery = new NamedQuery();
2021 namedQuery.setNamedQueryUuid(namedQueryUuid);
2022 data.getQueryParameters().setNamedQuery(namedQuery);
2025 if(data.getInstanceFilters() == null) {
2026 data.setInstanceFilters(new InstanceFilters());
2030 String quantity = parms.get("instance-filters.instance-filter_length");
2031 if(quantity != null && StringUtils.isNumeric(quantity)) {
2032 int max = Integer.parseInt(quantity);
2033 for(int i = 0; i < max; i++) {
2034 String keyPattern = String.format("instance-filters.instance-filter[%d].", i);
2035 Set<String> keys = parms.keySet();
2036 for(String key: keys) {
2037 if(key.startsWith(keyPattern)){
2038 String value = parms.get(key);
2039 String remainder = key.substring(keyPattern.length());
2040 String[] split = remainder.split("\\.");
2041 getLogger().debug(String.format("%s", remainder));
2042 if("logical-link".equals(split[0])) {
2043 InstanceFilter insf = null;
2044 if(data.getInstanceFilters().getInstanceFilter().isEmpty()) {
2045 insf = new InstanceFilter();
2046 data.getInstanceFilters().getInstanceFilter().add(insf);
2048 insf = data.getInstanceFilters().getInstanceFilter().get(0);
2050 LogicalLink logicalLink = insf.getLogicalLink();
2051 if(logicalLink == null) {
2052 logicalLink = new LogicalLink();
2053 insf.setLogicalLink(logicalLink);
2058 logicalLink.setLinkName(value);
2061 logicalLink.setLinkType(value);
2063 case "operational-state":
2064 logicalLink.setOperationalStatus(value);
2068 } else if("pnf".equals(split[0])) {
2069 Pnf pnf = new Pnf();
2070 pnf.setPnfName(value);
2072 InstanceFilter insf = new InstanceFilter();
2074 data.getInstanceFilters().getInstanceFilter().add(insf);
2076 } else if("service-instance".equals(split[0])) {
2077 ServiceInstance serviceInstance = new ServiceInstance();
2078 serviceInstance.setServiceInstanceId(value);
2080 InstanceFilter insf = new InstanceFilter();
2081 insf.setServiceInstance(serviceInstance);
2082 data.getInstanceFilters().getInstanceFilter().add(insf);
2084 } else if("l3-network".equals(split[0])) {
2085 L3Network l3Network = new L3Network();
2086 if("network-role".equals(split[1])) {
2087 l3Network.setNetworkRole(value);
2090 InstanceFilter insf = new InstanceFilter();
2091 insf.setL3Network(l3Network);
2092 data.getInstanceFilters().getInstanceFilter().add(insf);
2093 } else if("generic-vnf".equals(split[0])) {
2094 GenericVnf vnf = new GenericVnf();
2095 if("vnf-id".equals(split[1])) {
2096 vnf.setVnfId(value);
2099 InstanceFilter insf = new InstanceFilter();
2100 insf.setGenericVnf(vnf);
2101 data.getInstanceFilters().getInstanceFilter().add(insf);
2111 public abstract <T> T getResource(String key, Class<T> type) throws AAIServiceException ;
2112 protected abstract boolean deleteList(URL url, String caller) throws AAIServiceException;