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.util.ArrayList;
34 import java.util.Arrays;
35 import java.util.HashMap;
36 import java.util.LinkedList;
37 import java.util.List;
40 import java.util.SortedSet;
41 import java.util.TreeSet;
42 import java.util.regex.Matcher;
43 import java.util.regex.Pattern;
45 import javax.xml.bind.annotation.XmlType;
47 import org.apache.commons.lang.StringUtils;
48 import org.onap.ccsdk.sli.core.sli.SvcLogicContext;
49 import org.onap.ccsdk.sli.core.sli.SvcLogicException;
50 import org.onap.ccsdk.sli.core.sli.SvcLogicResource.QueryStatus;
51 import org.openecomp.aai.inventory.v11.GenericVnf;
52 import org.openecomp.aai.inventory.v11.InventoryResponseItem;
53 import org.openecomp.aai.inventory.v11.InventoryResponseItems;
54 import org.openecomp.aai.inventory.v11.L3Network;
55 import org.openecomp.aai.inventory.v11.LogicalLink;
56 import org.openecomp.aai.inventory.v11.Metadata;
57 import org.openecomp.aai.inventory.v11.Metadatum;
58 import org.openecomp.aai.inventory.v11.Pnf;
59 import org.openecomp.aai.inventory.v11.Relationship;
60 import org.openecomp.aai.inventory.v11.RelationshipData;
61 import org.openecomp.aai.inventory.v11.RelationshipList;
62 import org.openecomp.aai.inventory.v11.ResultData;
63 import org.openecomp.aai.inventory.v11.SearchResults;
64 import org.openecomp.aai.inventory.v11.ServiceInstance;
65 import org.openecomp.aai.inventory.v11.Vlan;
66 import org.openecomp.aai.inventory.v11.Vlans;
67 import org.openecomp.aai.inventory.v11.Vserver;
68 import org.onap.ccsdk.sli.adaptors.aai.AAIService.AAIRequestExecutor;
69 import org.onap.ccsdk.sli.adaptors.aai.data.AAIDatum;
70 import org.onap.ccsdk.sli.adaptors.aai.query.FormattedQueryResultList;
71 import org.onap.ccsdk.sli.adaptors.aai.query.InstanceFilter;
72 import org.onap.ccsdk.sli.adaptors.aai.query.InstanceFilters;
73 import org.onap.ccsdk.sli.adaptors.aai.query.NamedQuery;
74 import org.onap.ccsdk.sli.adaptors.aai.query.NamedQueryData;
75 import org.onap.ccsdk.sli.adaptors.aai.query.QueryParameters;
76 import org.onap.ccsdk.sli.adaptors.aai.query.Result;
77 import org.slf4j.Logger;
78 import org.slf4j.LoggerFactory;
80 import com.fasterxml.jackson.core.JsonParseException;
81 import com.fasterxml.jackson.databind.JsonMappingException;
82 import com.fasterxml.jackson.databind.ObjectMapper;
85 public abstract class AAIDeclarations implements AAIClient {
87 public static final String TRUSTSTORE_PATH = "org.onap.ccsdk.sli.adaptors.aai.ssl.trust";
88 public static final String TRUSTSTORE_PSSWD = "org.onap.ccsdk.sli.adaptors.aai.ssl.trust.psswd";
89 public static final String KEYSTORE_PATH = "org.onap.ccsdk.sli.adaptors.aai.ssl.key";
90 public static final String KEYSTORE_PSSWD = "org.onap.ccsdk.sli.adaptors.aai.ssl.key.psswd";
92 public static final String APPLICATION_ID = "org.onap.ccsdk.sli.adaptors.aai.application";
94 public static final String CLIENT_NAME = "org.onap.ccsdk.sli.adaptors.aai.client.name";
95 public static final String CLIENT_PWWD = "org.onap.ccsdk.sli.adaptors.aai.client.psswd";
98 public static final String CONNECTION_TIMEOUT = "connection.timeout";
99 public static final String READ_TIMEOUT = "read.timeout";
101 public static final String TARGET_URI = "org.onap.ccsdk.sli.adaptors.aai.uri";
103 // Availability zones query
104 public static final String QUERY_PATH = "org.onap.ccsdk.sli.adaptors.aai.path.query";
107 public static final String UPDATE_PATH = "org.onap.ccsdk.sli.adaptors.aai.update";
110 public static final String SVC_INSTANCE_PATH = "org.onap.ccsdk.sli.adaptors.aai.path.svcinst";
111 public static final String SVC_INST_QRY_PATH = "org.onap.ccsdk.sli.adaptors.aai.path.svcinst.query";
114 public static final String NETWORK_VSERVER_PATH = "org.onap.ccsdk.sli.adaptors.aai.path.vserver";
116 public static final String VNF_IMAGE_QUERY_PATH = "org.onap.ccsdk.sli.adaptors.aai.path.vnf.image.query";
118 public static final String PARAM_SERVICE_TYPE = "org.onap.ccsdk.sli.adaptors.aai.param.service.type";
119 public static final String CERTIFICATE_HOST_ERROR = "org.onap.ccsdk.sli.adaptors.aai.host.certificate.ignore";
122 public static final String UBB_NOTIFY_PATH = "org.onap.ccsdk.sli.adaptors.aai.path.notify";
123 public static final String SELFLINK_AVPN = "org.onap.ccsdk.sli.adaptors.aai.notify.selflink.avpn";
124 public static final String SELFLINK_FQDN = "org.onap.ccsdk.sli.adaptors.aai.notify.selflink.fqdn";
127 public static final String SERVICE_PATH = "org.onap.ccsdk.sli.adaptors.aai.path.service";
130 public static final String P_INTERFACE_PATH = "org.onap.ccsdk.sli.adaptors.aai.path.pserver.pinterface";
133 public static final String SITE_PAIR_SET_PATH = "org.onap.ccsdk.sli.adaptors.aai.path.site.pair.set";
136 public static final String QUERY_NODES_PATH = "org.onap.ccsdk.sli.adaptors.aai.query.nodes";
139 protected abstract Logger getLogger();
140 public abstract AAIRequestExecutor getExecutor();
144 public QueryStatus query(String resource, boolean localOnly, String select, String key, String prefix, String orderBy, SvcLogicContext ctx)
145 throws SvcLogicException {
147 getLogger().debug("AAIService.query \tresource = "+resource);
150 String vnfName = null;
151 HashMap<String, String> nameValues = AAIServiceUtils.keyToHashMap(key, ctx);
152 getLogger().debug("key = "+ nameValues.toString());
154 if(!AAIServiceUtils.isValidFormat(resource, nameValues)) {
155 ctx.setAttribute(String.format("%s.error.message", prefix), String.format("Resource %s is not supported. Key string contains invaid identifiers", resource));
156 return QueryStatus.FAILURE;
159 if(resource == null || resource.isEmpty() || AAIRequest.createRequest(resource, nameValues) == null) {
160 ctx.setAttribute(String.format("%s.error.message", prefix), String.format("Resource %s is not supported", resource));
161 return QueryStatus.FAILURE;
164 // process data using new model
165 boolean useNewModelProcessing = true;
166 // process server query by name the old way
167 if("vserver".equals(resource) || "vserver2".equals(resource)){
168 if(nameValues.containsKey("vserver_name") || nameValues.containsKey("vserver-name") || nameValues.containsKey("vserver.vserver_name") || nameValues.containsKey("vserver.vserver-name"))
169 useNewModelProcessing = false;
171 if("generic-vnf".equals(resource)){
172 if(nameValues.containsKey("vnf_name") || nameValues.containsKey("vnf-name") || nameValues.containsKey("generic_vnf.vnf_name") || nameValues.containsKey("generic-vnf.vnf-name"))
173 useNewModelProcessing = false;
176 // process data using new model
177 if(useNewModelProcessing && AAIRequest.createRequest(resource, nameValues) != null) {
180 return newModelQuery(resource, localOnly, select, key, prefix, orderBy, ctx);
181 } catch (Exception exc) {
182 getLogger().warn("Failed query - returning FAILURE", exc);
183 return QueryStatus.FAILURE;
187 ObjectMapper mapper = AAIService.getObjectMapper();
188 Map<String,Object> attributes = new HashMap<>();
190 String modifier = null;
192 if(resource.contains(":")) {
193 String[] tokens = resource.split(":");
194 resource = tokens[0];
195 if(tokens.length > 1) {
196 modifier = tokens[1];
200 resource = resource.toLowerCase().replace("-", "_");
206 vnfId = nameValues.get("vnf_id");
207 if(nameValues.containsKey("vnf_id"))
208 vnfId = nameValues.get("vnf_id");
209 else if(nameValues.containsKey("generic_vnf.vnf_name"))
210 vnfId = nameValues.get("generic_vnf.vserver_name");
212 if(nameValues.containsKey("vnf_name"))
213 vnfName = nameValues.get("vnf_name");
214 else if(nameValues.containsKey("generic_vnf.vnf_name"))
215 vnfName = nameValues.get("generic_vnf.vnf_name");
217 if(vnfId != null && !vnfId.isEmpty()) {
218 // at this point of the project this part should not be executed
219 vnfId = vnfId.trim().replace("'", "").replace("$", "").replace("'", "");
220 GenericVnf vnf = this.requestGenericVnfData(vnfId);
222 return QueryStatus.NOT_FOUND;
225 attributes = mapper.convertValue(vnf, attributes.getClass());
226 } else if(vnfName != null && !vnfName.isEmpty()) {
228 vnfName = vnfName.trim().replace("'", "").replace("$", "").replace("'", "");
229 GenericVnf vnf = this.requestGenericVnfeNodeQuery(vnfName);
231 return QueryStatus.NOT_FOUND;
233 vnfId=vnf.getVnfId();
234 nameValues.put("vnf_id", vnfId);
235 attributes = mapper.convertValue(vnf, attributes.getClass());
236 } catch (AAIServiceException exc) {
237 int errorCode = exc.getReturnCode();
244 getLogger().warn("Caught exception trying to refresh generic VNF", exc);
246 ctx.setAttribute(prefix + ".error.message", exc.getMessage());
247 if(errorCode >= 300) {
248 ctx.setAttribute(prefix + ".error.http.response-code",
249 Integer.toString(exc.getReturnCode()));
251 return QueryStatus.FAILURE;
254 getLogger().warn("No arguments are available to process generic VNF");
255 return QueryStatus.FAILURE;
260 String vserverName = null;
261 if(nameValues.containsKey("vserver_name"))
262 vserverName = nameValues.get("vserver_name");
263 else if(nameValues.containsKey("vserver.vserver_name"))
264 vserverName = nameValues.get("vserver.vserver_name");
266 String vserverId = null;
267 if(nameValues.containsKey("vserver_id"))
268 vserverId = nameValues.get("vserver_id");
269 if(nameValues.containsKey("vserver.vserver_id"))
270 vserverId = nameValues.get("vserver.vserver_id");
271 String tenantId = nameValues.get("teannt_id");
273 if(vserverName != null) vserverName = vserverName.trim().replace("'", "").replace("$", "").replace("'", "");
274 if(vserverId != null) vserverId = vserverId.trim().replace("'", "").replace("$", "").replace("'", "");
275 if(tenantId != null) tenantId = tenantId.trim().replace("'", "").replace("$", "").replace("'", "");
277 if (vserverName != null) {
278 URL vserverUrl = null;
280 vserverUrl = this.requestVserverURLNodeQuery(vserverName);
281 } catch (AAIServiceException aaiexc) {
282 ctx.setAttribute(prefix + ".error.message", aaiexc.getMessage());
283 if (aaiexc.getReturnCode() >= 300) {
284 ctx.setAttribute(prefix + ".error.http.response-code", "" + aaiexc.getReturnCode());
287 if (aaiexc.getReturnCode() == 404)
288 return QueryStatus.NOT_FOUND;
290 return QueryStatus.FAILURE;
292 if (vserverUrl == null) {
293 return QueryStatus.NOT_FOUND;
296 tenantId = getTenantIdFromVserverUrl(vserverUrl);
297 String cloudOwner = getCloudOwnerFromVserverUrl(vserverUrl);
298 String cloudRegionId = getCloudRegionFromVserverUrl(vserverUrl);
300 Vserver vserver = null;
302 vserver = this.requestVServerDataByURL(vserverUrl);
303 } catch (AAIServiceException aaiexc) {
304 ctx.setAttribute(prefix + ".error.message", aaiexc.getMessage());
305 if (aaiexc.getReturnCode() >= 300) {
306 ctx.setAttribute(prefix + ".error.http.response-code", "" + aaiexc.getReturnCode());
309 if (aaiexc.getReturnCode() == 404)
310 return QueryStatus.NOT_FOUND;
312 return QueryStatus.FAILURE;
314 if (vserver == null) {
315 return QueryStatus.NOT_FOUND;
317 attributes = mapper.convertValue(vserver, attributes.getClass());
318 if (!attributes.containsKey("tenant-id") && tenantId != null) {
319 attributes.put("tenant-id", tenantId);
321 if (!attributes.containsKey("cloud-owner") && cloudOwner != null) {
322 attributes.put("cloud-owner", cloudOwner);
324 if (!attributes.containsKey("cloud-region-id") && cloudRegionId != null) {
325 attributes.put("cloud-region-id", cloudRegionId);
327 } else if (vserverId != null && tenantId != null) {
328 Vserver vserver = this.requestVServerData(tenantId, vserverId, "att-aic", "AAIAIC25");
329 if(vserver == null) {
330 return QueryStatus.NOT_FOUND;
332 attributes = mapper.convertValue(vserver, attributes.getClass());
333 if(!attributes.containsKey("tenant-id") && tenantId != null){
334 attributes.put("tenant-id", tenantId);
337 return QueryStatus.FAILURE;
342 return QueryStatus.FAILURE;
345 QueryStatus retval = QueryStatus.SUCCESS;
347 if (attributes == null || attributes.isEmpty()) {
348 retval = QueryStatus.NOT_FOUND;
349 getLogger().debug("No data found");
352 if (prefix != null) {
353 ArrayList<String> keys = new ArrayList<>(attributes.keySet());
355 int numCols = keys.size();
357 for (int i = 0; i < numCols; i++) {
359 String colName = keys.get(i);
360 Object object = attributes.get(colName);
362 if(object != null && object instanceof String) {
363 colValue = (String)object;
365 if (prefix != null) {
366 getLogger().debug("Setting "+prefix + "." + colName.replaceAll("_", "-")+" = "+ colValue);
367 ctx.setAttribute(prefix + "." + colName.replaceAll("_", "-"), colValue);
369 getLogger().debug("Setting " + colValue.replaceAll("_", "-")+" = "+colValue);
370 ctx.setAttribute(colValue.replaceAll("_", "-"), colValue);
372 } else if(object != null && object instanceof Map) {
373 if(colName.equals(modifier) || "relationship-list".equals(colName)){
374 String localNodifier = modifier;
375 if(localNodifier == null)
376 localNodifier = "relationship-list";
377 Map<String, Object> properties = (Map<String, Object>)object;
378 writeMap(properties, prefix+"."+localNodifier, ctx);
385 getLogger().debug("Query - returning " + retval);
388 } catch (Exception exc) {
389 getLogger().warn("Failed query - returning FAILURE", exc);
390 return QueryStatus.FAILURE;
393 // return QueryStatus.SUCCESS;
397 public void writeMap(Map<String, Object> properties, String prefix, SvcLogicContext ctx) {
398 Set<String> mapKeys = properties.keySet();
400 for(String mapKey : mapKeys) {
401 Object entity = properties.get(mapKey);
402 if(entity instanceof ArrayList) {
403 writeList((ArrayList<?>)entity, prefix + "." + mapKey, ctx);
405 if(entity instanceof String || entity instanceof Long || entity instanceof Integer || entity instanceof Boolean) {
406 ctx.setAttribute(prefix + "." + mapKey, entity.toString());
407 getLogger().debug(prefix + "." + mapKey + " : " + entity.toString());
408 } else if(entity instanceof Map) {
409 String localPrefix = prefix;
411 localPrefix = String.format("%s.%s", prefix, mapKey);
413 writeMap( (Map<String, Object>)entity, localPrefix, ctx);
418 private void writeList(ArrayList<?> list, String prefix, SvcLogicContext ctx) {
419 for(int i = 0; i < list.size(); i++ ) {
420 Object entity = list.get(i);
421 if(entity instanceof Map) {
422 writeMap( (Map<String, Object>)entity, prefix + "[" + i + "]", ctx);
424 if(entity instanceof String || entity instanceof Long || entity instanceof Integer || entity instanceof Boolean) {
425 ctx.setAttribute(prefix, entity.toString());
426 getLogger().debug(prefix + " : " + entity.toString());
430 if(!list.isEmpty()) {
431 ctx.setAttribute(prefix + "_length", Integer.toString(list.size()));
432 getLogger().debug(prefix + "_length" + " : " + Integer.toString(list.size()));
437 public QueryStatus save(String resource, boolean force, boolean localOnly, String key, Map<String, String> params, String prefix, SvcLogicContext ctx)
438 throws SvcLogicException {
440 getLogger().debug("AAIService.save\tresource="+resource);
441 HashMap<String, String> nameValues = AAIServiceUtils.keyToHashMap(key, ctx);
443 if(!AAIServiceUtils.isValidFormat(resource, nameValues)) {
444 ctx.setAttribute(String.format("%s.error.message", prefix), String.format("Resource %s is not supported. Key string contains invaid identifiers", resource));
445 return QueryStatus.FAILURE;
448 if(resource == null || resource.isEmpty() || AAIRequest.createRequest(resource, nameValues) == null) {
449 getLogger().warn("AAIService.save has unspecified resource");
450 ctx.setAttribute(String.format("%s.error.message", prefix), String.format("Resource %s is not supported", resource));
451 return QueryStatus.FAILURE;
454 getLogger().debug("key = "+ Arrays.toString(nameValues.entrySet().toArray()));
457 if(params.containsKey("prefix")) {
458 Map<String, String> tmpParams = ctxGetBeginsWith(ctx, params.get("prefix"));
459 if(!tmpParams.isEmpty()) {
460 params.putAll(tmpParams);
461 // params.remove("prefix");
465 getLogger().debug("parms = "+ Arrays.toString(params.entrySet().toArray()));
467 boolean useNewModelProcessing = true;
468 // process server query by name the old way
469 if("vserver".equals(resource) || "vserver2".equals(resource)){
470 if(nameValues.containsKey("vserver-name")) {
471 useNewModelProcessing = false;
474 if(!params.containsKey("vserver-selflink")) {
476 AAIRequest request = AAIRequest.createRequest(resource, nameValues);
479 request.processRequestPathValues(nameValues);
480 path = request.getRequestUrl("GET", null);
481 params.put("vserver-selflink", path.toString());
482 } catch (UnsupportedEncodingException | MalformedURLException e) {
484 params.put("vserver-selflink", "/vserver");
489 // process data using new model
490 if(useNewModelProcessing && AAIRequest.createRequest(resource, nameValues) != null) {
493 if(!resource.contains(":")){
494 return newModelSave(resource, force, key, params, prefix, ctx);
496 String[] tokens = resource.split(":");
497 String localResource = tokens[0];
498 String dependency = tokens[1];
500 AAIDatum instance = newModelObjectRequest( localResource, nameValues, prefix, ctx);
501 if(instance == null) {
502 return QueryStatus.NOT_FOUND;
506 case "relationship-list":
507 newModelProcessRelationshipList(instance, params, prefix, ctx);
510 // create a method to update relationship-list
511 AAIRequest request = AAIRequest.createRequest(localResource, nameValues);
512 request.setRequestObject(instance);
513 request.processRequestPathValues(nameValues);
515 getExecutor().post(request);
516 getLogger().debug("Save relationship list - returning SUCCESS");
517 return QueryStatus.SUCCESS;
519 } catch (Exception exc) {
520 ctx.setAttribute(prefix + ".error.message", exc.getMessage());
521 if(exc instanceof AAIServiceException) {
522 AAIServiceException aaiexc = (AAIServiceException)exc;
523 if(aaiexc.getReturnCode() >= 300) {
524 ctx.setAttribute(prefix + ".error.http.response-code", "" + aaiexc.getReturnCode());
527 if(aaiexc.getReturnCode() == 404) {
528 return QueryStatus.NOT_FOUND;
531 getLogger().warn("Failed save() - returning FAILURE", exc);
532 return QueryStatus.FAILURE;
535 String reSource = resource.toLowerCase().replace("-", "_");
542 vnfId = nameValues.get("vnf_id");
544 getLogger().debug("Save(generic-vnf) with no vnf-id specified. Returning FAILURE");
545 return QueryStatus.FAILURE;
547 vnfId = vnfId.trim().replace("'", "").replace("$", "").replace("'", "");
548 GenericVnf vnf = this.requestGenericVnfData(vnfId);
549 String status = params.get("prov-status");
550 boolean updated = false;
551 if(status != null && !status.isEmpty()) {
552 vnf.setProvStatus(status);
555 this.postGenericVnfData(vnfId, vnf);
559 return update( resource, key, params, prefix, ctx) ;
562 getLogger().debug("Save() executing default path - returning FAILURE");
563 return QueryStatus.FAILURE;
565 } catch (Exception exc) {
566 getLogger().warn("Failed save - returning FAILURE", exc);
567 ctx.setAttribute(prefix + ".error.message", exc.getMessage());
568 return QueryStatus.FAILURE;
572 getLogger().debug("Save - returning SUCCESS");
573 return QueryStatus.SUCCESS;
577 public QueryStatus update(String resource, String key, Map<String, String> params, String prefix, SvcLogicContext ctx) throws SvcLogicException {
579 resource = resource.toLowerCase();
580 HashMap<String, String> nameValues = AAIServiceUtils.keyToHashMap(key, ctx);
581 getLogger().debug("key = "+ Arrays.toString(nameValues.entrySet().toArray()));
582 if(!AAIServiceUtils.isValidFormat(resource, nameValues)) {
583 ctx.setAttribute(String.format("%s.error.message", prefix), String.format("Resource %s is not supported. Key string contains invaid identifiers", resource));
584 return QueryStatus.FAILURE;
587 if(resource == null || resource.isEmpty() || AAIRequest.createRequest(resource, nameValues) == null) {
588 ctx.setAttribute(String.format("%s.error.message", prefix), String.format("Resource %s is not supported", resource));
589 return QueryStatus.FAILURE;
592 // check if request is for groups
593 if(!AAIServiceUtils.containsResource(resource, nameValues)) {
594 ctx.setAttribute(String.format("%s.error.message", prefix), String.format("Resource %s is not permitted in 'update' operation", resource));
595 return QueryStatus.FAILURE;
598 getLogger().debug("parms = "+ Arrays.toString(params.entrySet().toArray()));
600 AAIRequest request = AAIRequest.createRequest(resource, nameValues);
601 request = new UpdateRequest(request, params);
603 String[] arguments = request.getArgsList();
604 for(String name : arguments) {
605 String modifiedKey = name.replaceAll("-", "_");
606 if(nameValues.containsKey(modifiedKey)) {
607 String argValue = nameValues.get(modifiedKey);
608 if(argValue != null) argValue = argValue.trim().replace("'", "").replace("$", "").replace("'", "");
609 request.addRequestProperty(name, argValue);
614 QueryStatus retval = QueryStatus.SUCCESS;
616 retval = newModelQuery(resource, false, null, key, "tmpDelete", null, ctx);
618 if(retval == null || retval != QueryStatus.SUCCESS) {
622 String resourceVersion = ctx.getAttribute("tmpDelete.resource-version");
623 if(resourceVersion == null) {
624 return QueryStatus.NOT_FOUND;
626 params.put("resource-version", resourceVersion);
628 request.processRequestPathValues(nameValues);
629 getExecutor().patch(request, resourceVersion);
630 } catch(AAIServiceException aaiexc) {
631 if(aaiexc.getReturnCode() == 404)
632 return QueryStatus.NOT_FOUND;
634 return QueryStatus.FAILURE;
635 } catch (Exception exc) {
636 getLogger().warn("Failed update - returning FAILURE", exc);
637 return QueryStatus.FAILURE;
640 getLogger().debug("Update - returning SUCCESS");
641 return QueryStatus.SUCCESS;
645 public QueryStatus delete(String resource, String key, SvcLogicContext ctx) throws SvcLogicException {
646 getLogger().debug("AAIService.delete\tresource="+resource);
647 HashMap<String, String> nameValues = AAIServiceUtils.keyToHashMap(key, ctx);
648 getLogger().debug("key = "+ Arrays.toString(nameValues.entrySet().toArray()));
650 if(!AAIServiceUtils.isValidFormat(resource, nameValues)) {
651 ctx.setAttribute(String.format("%s.error.message", "aaiData"), String.format("Resource %s is not supported. Key string contains invaid identifiers", resource));
652 return QueryStatus.FAILURE;
655 if(resource == null || resource.isEmpty() || AAIRequest.createRequest(resource, nameValues) == null) {
656 ctx.setAttribute(String.format("%s.error.message", "tmpDelete"), String.format("Resource %s is not supported", resource));
657 return QueryStatus.FAILURE;
660 // check if request is for groups
661 if(!AAIServiceUtils.containsResource(resource, nameValues)) {
662 ctx.setAttribute(String.format("%s.error.message", "tmpDelete"), String.format("Resource %s is not permitted in 'delete' operation", resource));
663 return QueryStatus.FAILURE;
666 if(AAIRequest.createRequest(resource, nameValues) != null) {
667 if(resource.contains(":")) {
668 return processDeleteRelationshipList(resource, key, ctx, nameValues);
673 QueryStatus retval = QueryStatus.SUCCESS;
675 retval = newModelQuery(resource, false, null, key, "tmpDelete", null, ctx);
677 if(retval == null || retval != QueryStatus.SUCCESS) {
681 String resourceVersion = ctx.getAttribute("tmpDelete.resource-version");
682 if(resourceVersion == null) {
683 return QueryStatus.NOT_FOUND;
687 AAIRequest request = AAIRequest.createRequest(resource, nameValues);
688 if(request == null) {
689 return QueryStatus.FAILURE;
692 request.processRequestPathValues(nameValues);
694 if(getExecutor().delete(request, resourceVersion)) {
695 return QueryStatus.SUCCESS;
697 } catch(AAIServiceException aaiexc) {
698 if(aaiexc.getReturnCode() == 404)
699 return QueryStatus.NOT_FOUND;
701 return QueryStatus.FAILURE;
703 } catch (Exception exc) {
704 getLogger().warn("requestGenericVnfData", exc);
705 return QueryStatus.FAILURE;
708 } catch (Exception exc) {
709 getLogger().warn("Failed delete - returning FAILURE", exc);
710 return QueryStatus.FAILURE;
713 String resoourceName = resource;
714 String identifier = null;
716 if(resoourceName == null)
717 return QueryStatus.FAILURE;
719 if(resoourceName.contains(":")) {
720 String[] tokens = resoourceName.split(":");
721 if(tokens != null && tokens.length > 0) {
722 resoourceName = tokens[0];
723 identifier = tokens[1];
726 if("relationship-list".equals(identifier) || "relationshipList".equals(identifier)) {
727 // RelationshipRequest relationshipRequest = new RelationshipRequest();
728 if("generic-vnf".equals(resoourceName)){
729 String vnfId = nameValues.get("vnf_id");
730 String relatedTo = nameValues.get("related_to");
731 vnfId = vnfId.trim().replace("'", "").replace("$", "").replace("'", "");
732 relatedTo = relatedTo.trim().replace("'", "").replace("$", "").replace("'", "");
736 vnf = this.requestGenericVnfData(vnfId);
738 return QueryStatus.NOT_FOUND;
739 } catch (AAIServiceException exc) {
740 getLogger().warn("Failed delete - returning NOT_FOUND", exc);
741 return QueryStatus.NOT_FOUND;
743 boolean itemRemoved = false;
744 RelationshipList relationshipList = vnf.getRelationshipList();
745 List<Relationship> relationships = relationshipList.getRelationship();
746 List<Relationship> iterableList = new LinkedList<Relationship>(relationships);
747 for(Relationship relationship : iterableList) {
748 if(relationship.getRelatedTo().equals(relatedTo)) {
749 relationships.remove(relationship);
755 return QueryStatus.NOT_FOUND;
757 // AAIRequest masterRequest = new GenericVnfRequest();
758 // masterRequest.addRequestProperty(GenericVnfRequest.VNF_ID, vnfId);
759 // relationshipRequest.addMasterRequest(masterRequest);
760 // Map<String, String> attributes = objectToProperties(vnf);
762 // Boolean result = getExecutor().delete(relationshipRequest, attributes.get(AAIRequest.RESOURCE_VERSION));
763 // } catch (AAIServiceException e) {
764 // return QueryStatus.FAILURE;
768 this.postGenericVnfData(vnf.getVnfId(), vnf);
769 } catch (AAIServiceException exc) {
770 if(exc.getReturnCode() == 404){
771 return QueryStatus.NOT_FOUND;
773 getLogger().warn("Failed delete - returning FAILURE", exc);
774 return QueryStatus.FAILURE;
777 return QueryStatus.SUCCESS;
781 return QueryStatus.FAILURE;
785 public QueryStatus exists(String resource, String key, String prefix, SvcLogicContext ctx) throws SvcLogicException {
786 return query(resource, false, null, key, prefix, null, ctx);
790 public QueryStatus isAvailable(String arg0, String arg1, String arg2, SvcLogicContext arg3)
791 throws SvcLogicException {
792 // TODO Auto-generated method stub
793 throw new SvcLogicException("Method AAIService.isAvailable() has not been implemented yet");
797 public QueryStatus notify(String resource, String action, String key, SvcLogicContext ctx) throws SvcLogicException {
798 // TODO Auto-generated method stub
799 throw new SvcLogicException("Method AAIService.notify() has not been implemented yet");
803 public QueryStatus newModelQuery(String resource, boolean localOnly, String select, String key, String prefix, String orderBy, SvcLogicContext ctx) {
805 Object response = null;
806 QueryStatus retval = QueryStatus.SUCCESS;
807 String modifier = null;
809 HashMap<String, String> nameValues = AAIServiceUtils.keyToHashMap(key, ctx);
810 if(resource.contains(":")) {
811 modifier = resource.split(":")[1];
815 AAIRequest request = AAIRequest.createRequest(resource, nameValues);
816 if(request == null) {
817 return QueryStatus.FAILURE;
820 Map<String, String> params = new HashMap<>();
822 request.processRequestPathValues(nameValues);
823 if(nameValues.containsKey("prefix")){
824 Map<String, String> tmpParams = ctxGetBeginsWith(ctx, nameValues.get("prefix"));
825 if(!tmpParams.isEmpty()) {
826 params.putAll(tmpParams);
828 if("named-query".equals(resource))
829 request.setRequestObject(extractNamedQueryDataFromQueryPrefix(nameValues, params));
831 String rv = getExecutor().get(request);
833 retval = processResponseData(rv, resource, request, prefix, ctx, nameValues, modifier);
835 } catch(AAIServiceException aaiexc) {
836 int errorCode = aaiexc.getReturnCode();
837 ctx.setAttribute(prefix + ".error.message", aaiexc.getMessage());
838 if(errorCode >= 300) {
839 ctx.setAttribute(prefix + ".error.http.response-code",
840 Integer.toString(aaiexc.getReturnCode()));
843 if(aaiexc.getReturnCode() == 404)
844 return QueryStatus.NOT_FOUND;
846 return QueryStatus.FAILURE;
847 } catch (Exception exc) {
848 getLogger().warn("requestGenericVnfData", exc);
849 ctx.setAttribute(prefix + ".error.message", exc.getMessage());
850 return QueryStatus.FAILURE;
856 public QueryStatus processResponseData(String rv, String resource, AAIRequest request, String prefix, SvcLogicContext ctx, HashMap<String, String> nameValues, String modifier) throws JsonParseException, JsonMappingException, IOException, AAIServiceException
861 return QueryStatus.NOT_FOUND;
864 response = request.jsonStringToObject(rv);
865 if(response == null) {
866 return QueryStatus.NOT_FOUND;
869 if("generic-query".equals(resource)) {
870 SearchResults rd = SearchResults.class.cast(response);
871 List<ResultData> rdList = rd.getResultData();
872 if(rdList == null || rdList.isEmpty()) {
873 return QueryStatus.NOT_FOUND;
875 ResultData rDatum = rdList.get(0);
876 nameValues.put("selflink", rDatum.getResourceLink());
877 AAIRequest req2 = AAIRequest.createRequest(rDatum.getResourceType(), nameValues);
878 req2.processRequestPathValues(nameValues);
879 rv = getExecutor().get(req2);
881 return QueryStatus.NOT_FOUND;
884 response = req2.jsonStringToObject(rv);
885 if(response == null) {
886 return QueryStatus.NOT_FOUND;
890 if("named-query".equals(resource)) {
891 InventoryResponseItems rd = InventoryResponseItems.class.cast(response);
892 List<InventoryResponseItem> iRIlist = rd.getInventoryResponseItem();
893 if(iRIlist == null || iRIlist.isEmpty()) {
894 return QueryStatus.NOT_FOUND;
898 if("nodes-query".equals(resource)) {
899 SearchResults rd = SearchResults.class.cast(response);
900 List<ResultData> rdList = rd.getResultData();
901 if(rdList == null || rdList.isEmpty()) {
902 return QueryStatus.NOT_FOUND;
904 ResultData rDatum = rdList.get(0);
908 if("formatted-query".equals(resource) || "custom-query".equals(resource)) {
909 FormattedQueryResultList rd = FormattedQueryResultList.class.cast(response);
910 List<Result> iRIlist = rd.getResults();
911 if(iRIlist == null || iRIlist.isEmpty()) {
912 return QueryStatus.NOT_FOUND;
916 // process relationship list
917 // this is a temporary soluton to address the realationship handling changes added in Release 17.07
919 Class<?> clazz = response.getClass();
920 Method getter = clazz.getMethod("getRelationshipList");
921 Object obj = getter.invoke(response);
922 if(obj != null && obj instanceof RelationshipList) {
923 RelationshipList list = RelationshipList.class.cast(obj);
924 AAIServiceUtils.populateRelationshipDataFromPath(list);
926 } catch(Exception exc) {
927 getLogger().debug("Retrofiting relationship data: " + exc.getMessage());
931 if(prefix == null || prefix.isEmpty()) {
934 preFix = prefix + ".";
937 Map<String,Object> props = objectToProperties(response);
938 Set<String> keys = props.keySet();
939 for(String theKey: keys) {
940 if(getLogger().isTraceEnabled())
941 getLogger().trace(theKey);
943 Object value = props.get(theKey);
946 Object type = value.getClass();
947 if(value instanceof String) {
948 ctx.setAttribute(preFix + theKey, value.toString());
951 if(value instanceof Boolean) {
952 ctx.setAttribute(preFix + theKey, value.toString());
955 if(value instanceof Integer) {
956 ctx.setAttribute(preFix + theKey, value.toString());
959 if(value instanceof Long) {
960 ctx.setAttribute(preFix + theKey, value.toString());
964 if(value instanceof ArrayList) {
965 ArrayList<?> array = ArrayList.class.cast(value);
966 for(int i = 0; i < array.size(); i++) {
967 writeList(array, String.format("%s.%s", prefix, theKey), ctx);
972 if("relationship-list".equals(theKey)){
973 Map<String, Object> relationshipList = (Map<String, Object>)value;
974 // we are interested in seeing just the selected relationship
975 if(theKey.equals(modifier)) {
976 List<?> relationships = (List<?>)relationshipList.get("relationship");
977 if(relationships != null && !relationships.isEmpty()) {
979 List newRelationships = new LinkedList();
980 newRelationships.addAll(relationships);
982 for(Object obj : newRelationships){
983 if(obj instanceof Map<?, ?>) {
984 Map<?, ?> relProperties = (Map<?, ?>)obj;
985 if(relProperties.containsKey("related-to")) {
986 Object relPropsRelatedTo = relProperties.get("related-to");
988 String relatedTo = nameValues.get("related_to");
989 if(relatedTo != null) {
990 relatedTo = relatedTo.trim().replace("'", "").replace("$", "").replace("'", "");
991 if(!relatedTo.equals(relPropsRelatedTo)) {
992 relationships.remove(relProperties);
1003 writeMap(relationshipList, String.format("%s.%s", prefix, theKey), ctx);
1007 if(value instanceof Map) {
1008 Map<String, Object> subnetsList = (Map<String, Object>)value;
1009 writeMap(subnetsList, String.format("%s.%s", prefix, theKey), ctx);
1014 return QueryStatus.SUCCESS;
1018 public QueryStatus newModelBackupRequest(String resource, Map<String, String> params, String prefix, SvcLogicContext ctx) {
1020 QueryStatus retval = QueryStatus.SUCCESS;
1021 HashMap<String, String> nameValues = new HashMap<>();
1024 AAIRequest request = AAIRequest.createRequest(resource, nameValues);
1025 if(request == null) {
1026 return QueryStatus.FAILURE;
1029 boolean argsFound = false;
1030 String[] arguments = request.getArgsList();
1031 for(String name : arguments) {
1032 String tmpName = name.replaceAll("-", "_");
1033 String value = params.get(tmpName);
1034 if(value != null && !value.isEmpty()) {
1035 value = value.trim().replace("'", "").replace("$", "").replace("'", "");
1036 request.addRequestProperty(name, value);
1041 getLogger().warn("No arguments were found. Terminating backup request.");
1042 return QueryStatus.FAILURE;
1045 String rv = getExecutor().get(request);
1046 ctx.setAttribute(prefix, rv);
1047 } catch(AAIServiceException aaiexc) {
1048 if(aaiexc.getReturnCode() == 404)
1049 return QueryStatus.NOT_FOUND;
1051 return QueryStatus.FAILURE;
1052 } catch (Exception exc) {
1053 getLogger().warn("newModelBackupRequest", exc);
1054 return QueryStatus.FAILURE;
1060 public AAIDatum newModelObjectRequest(String resource, Map<String, String> params, String prefix, SvcLogicContext ctx)
1061 throws AAIServiceException {
1063 AAIDatum response = null;
1066 AAIRequest request = AAIRequest.createRequest(resource, params);
1067 if(request == null) {
1071 request.processRequestPathValues(params);
1072 String rv = getExecutor().get(request);
1073 response = request.jsonStringToObject(rv);
1074 } catch(AAIServiceException aaiexc) {
1076 } catch (Exception exc) {
1077 getLogger().warn("newModelBackupRequest", exc);
1078 throw new AAIServiceException(exc);
1086 public QueryStatus release(String arg0, String arg1, SvcLogicContext arg2) throws SvcLogicException {
1087 // TODO Auto-generated method stub
1088 throw new SvcLogicException("Method AAIService.release() has not been implemented yet");
1092 public QueryStatus reserve(String arg0, String arg1, String arg2, String arg3, SvcLogicContext arg4)
1093 throws SvcLogicException {
1094 // TODO Auto-generated method stub
1095 throw new SvcLogicException("Method AAIService.reserve() has not been implemented yet");
1098 private QueryStatus newModelSave(String resource, boolean force, String key, Map<String, String> params, String prefix, SvcLogicContext ctx) {
1099 getLogger().debug("Executing newModelSave for resource : " + resource);
1100 HashMap<String, String> nameValues = AAIServiceUtils.keyToHashMap(key, ctx);
1103 ArrayList<String> subResources = new ArrayList<>();
1104 Set<String> set = params.keySet();
1105 Map<String, Method> setters = new HashMap<>();
1106 Map<String, Method> getters = new HashMap<>();
1109 AAIRequest request = AAIRequest.createRequest(resource, nameValues);
1110 Class<? extends AAIDatum> resourceClass = request.getModelClass();
1111 getLogger().debug(resourceClass.getName());
1112 AAIDatum instance = resourceClass.newInstance();
1115 Annotation[] annotations = resourceClass.getAnnotations();
1116 for(Annotation annotation : annotations) {
1117 Class<? extends Annotation> anotationType = annotation.annotationType();
1118 String annotationName = anotationType.getName();
1120 // 2. find string property setters and getters for the lists
1121 if("javax.xml.bind.annotation.XmlType".equals(annotationName)){
1122 XmlType order = (XmlType)annotation;
1123 String[] values = order.propOrder();
1124 for(String value : values) {
1125 String id = AAIServiceUtils.camelCaseToDashedString(value);
1126 Field field = resourceClass.getDeclaredField(value);
1127 Class<?> type = field.getType();
1128 Method setter = null;
1130 setter = resourceClass.getMethod("set"+StringUtils.capitalize(value), type);
1131 if(type.getName().startsWith("java.lang") || "boolean".equals(type.getName()) || "long".equals(type.getName())) {
1133 setter.setAccessible(true);
1134 Object arglist[] = new Object[1];
1135 arglist[0] = params.get(id);
1137 if(arglist[0] != null) {
1138 if(!type.getName().equals("java.lang.String")) {
1139 // getLogger().debug(String.format("Processing %s with parameter %s", types[0].getName(), value));
1140 if("boolean".equals(type.getName())) {
1141 arglist[0] = valueOf(Boolean.class, params.get(id));
1142 } else if("long".equals(type.getName())) {
1143 arglist[0] = valueOf(Long.class, params.get(id));
1145 arglist[0] = valueOf(type, params.get(id));
1148 Object o = setter.invoke(instance, arglist);
1152 } catch (Exception x) {
1153 Throwable cause = x.getCause();
1154 getLogger().warn("Failed process for " + resourceClass.getName(), x);
1156 } else if(type.getName().equals("java.util.List")) {
1157 List<String> newValues = new ArrayList<>();
1158 String length = id+"_length";
1159 if(!params.isEmpty() && params.containsKey(length)) {
1160 String tmp = params.get(length).toString();
1161 int count = Integer.parseInt(tmp);
1162 for(int i=0; i<count; i++) {
1163 String tmpValue = params.get(String.format("%s[%d]", id, i));
1164 newValues.add(tmpValue);
1166 if(!newValues.isEmpty()) {
1167 Object o = setter.invoke(instance, newValues);
1172 setters.put(id, setter);
1174 } catch(Exception exc) {
1180 getter = resourceClass.getMethod("get"+StringUtils.capitalize(value));
1181 if(!type.getName().equals("java.lang.String")) {
1182 getters.put(id, getter);
1184 } catch(Exception exc) {
1189 subResources.addAll(Arrays.asList(values));
1194 // remove getters that have matching setter
1195 for(String setKey : setters.keySet()) {
1196 if(getters.containsKey(setKey)) {
1197 getters.remove(setKey);
1201 Set<String> relationshipKeys = new TreeSet<>();
1202 Set<String> vlansKeys = new TreeSet<>();
1203 Set<String> metadataKeys = new TreeSet<>();
1205 for(String attribute : set) {
1206 String value = params.get(attribute);
1207 if(attribute.startsWith("relationship-list")) {
1208 relationshipKeys.add(attribute);
1209 } else if(attribute.startsWith("vlans")) {
1210 vlansKeys.add(attribute);
1211 } else if(attribute.startsWith("metadata")) {
1212 metadataKeys.add(attribute);
1215 // 3. find list property getters
1216 for(String attribute : set) {
1217 String value = params.get(attribute);
1218 Method method = getters.get(attribute);
1219 if(method != null) {
1221 method.setAccessible(true);
1222 Object arglist[] = new Object[0];
1223 // arglist[0] = value;
1224 Class<?>[] types = method.getParameterTypes();
1225 if(types.length == 0){
1226 Object o = method.invoke(instance, arglist);
1227 if(o instanceof ArrayList) {
1228 ArrayList<String> values = (ArrayList<String>)o;
1229 // getLogger().debug(String.format("Processing %s with parameter %s", types[0].getName(), value));
1230 value = value.replace("[", "").replace("]", "");
1231 List<String> items = Arrays.asList(value.split("\\s*,\\s*"));
1232 for(String s : items) {
1233 values.add(s.trim());
1237 } catch (Exception x) {
1238 Throwable cause = x.getCause();
1239 getLogger().warn("Failed process for " + resourceClass.getName(), x);
1243 // 4. Process Relationships
1244 // add relationship list
1245 if( (subResources.contains("relationship-list") || subResources.contains("relationshipList")) && !relationshipKeys.isEmpty()) {
1246 RelationshipList relationshipList = null;
1248 Method getRelationshipListMethod = null;
1250 getRelationshipListMethod = resourceClass.getMethod("getRelationshipList");
1251 } catch(Exception exc) {
1252 getLogger().debug("Retrofiting relationship data: " + exc.getMessage());
1255 if(getRelationshipListMethod != null){
1257 getRelationshipListMethod.setAccessible(true);
1258 obj = getRelationshipListMethod.invoke(instance);
1259 } catch (InvocationTargetException x) {
1260 Throwable cause = x.getCause();
1263 if(obj != null && obj instanceof RelationshipList){
1264 relationshipList = (RelationshipList)obj;
1266 relationshipList = new RelationshipList();
1267 Method setRelationshipListMethod = resourceClass.getMethod("setRelationshipList", RelationshipList.class);
1268 if(setRelationshipListMethod != null){
1270 setRelationshipListMethod.setAccessible(true);
1271 Object arglist[] = new Object[1];
1272 arglist[0] = relationshipList;
1274 obj = setRelationshipListMethod.invoke(instance, arglist);
1275 } catch (InvocationTargetException x) {
1276 Throwable cause = x.getCause();
1281 List<Relationship> relationships = relationshipList.getRelationship();
1285 String searchKey = "relationship-list.relationship[" + i + "].related-to";
1286 if(!params.containsKey(searchKey))
1289 String relatedTo = params.get(searchKey);
1290 String relatedLinkKey = "relationship-list.relationship[" + i + "].related-link";
1291 String relatedLink = null;
1292 if(params.containsKey(relatedLinkKey)) {
1293 relatedLink = params.get(relatedLinkKey);
1295 Relationship relationship = new Relationship();
1296 relationships.add(relationship);
1297 relationship.setRelatedTo(relatedTo);
1298 if(relatedLink != null) {
1299 relationship.setRelatedLink(relatedLink);
1301 // List<RelationshipData> relData = relationship.getRelationshipData();
1302 Map<String, String> relParams = new HashMap<String, String>();
1305 String searchRelationshipKey = "relationship-list.relationship[" + i + "].relationship-data[" + j + "].relationship-key";
1306 String searchRelationshipValue = "relationship-list.relationship[" + i + "].relationship-data[" + j + "].relationship-value";
1307 if(!params.containsKey(searchRelationshipKey))
1310 relParams.put(params.get(searchRelationshipKey), params.get(searchRelationshipValue));
1313 AAIRequest rlRequest = AAIRequest.createRequest(relatedTo, relParams);
1314 for(Map.Entry<String,String> entry : relParams.entrySet()) {
1315 rlRequest.addRequestProperty(entry.getKey(), entry.getValue());
1317 String path = rlRequest.updatePathDataValues(null);
1318 relationship.setRelatedLink(path);
1325 if(subResources.contains("vlans") && !vlansKeys.isEmpty()) {
1327 Vlans vlanList = null;
1328 Method getVLansMethod = resourceClass.getMethod("getVlans");
1329 if(getVLansMethod != null){
1331 getVLansMethod.setAccessible(true);
1332 obj = getVLansMethod.invoke(instance);
1333 } catch (InvocationTargetException x) {
1334 Throwable cause = x.getCause();
1337 if(obj != null && obj instanceof Vlans){
1338 vlanList = (Vlans)obj;
1340 vlanList = new Vlans();
1341 Method setVlansMethod = resourceClass.getMethod("setVlans", Vlans.class);
1342 if(setVlansMethod != null){
1344 setVlansMethod.setAccessible(true);
1345 Object arglist[] = new Object[1];
1346 arglist[0] = vlanList;
1348 obj = setVlansMethod.invoke(instance, arglist);
1349 } catch (InvocationTargetException x) {
1350 Throwable cause = x.getCause();
1357 String searchKey = "vlans.vlan[" + i + "].vlan-interface";
1358 if(!params.containsKey(searchKey))
1361 String vlanInterface = params.get("vlans.vlan[" + i + "].vlan-interface");
1362 String vlanIdInner = params.get("vlans.vlan[" + i + "].vlan-id-inner");
1363 String vlanIdOute = params.get("vlans.vlan[" + i + "].vlan-id-outer");
1364 String speedValue = params.get("vlans.vlan[" + i + "].speed-value");
1365 String speedUnits = params.get("vlans.vlan[" + i + "].speed-units");
1367 Vlan vlan = new Vlan();
1368 vlan.setVlanInterface(vlanInterface);
1370 if(vlanIdInner != null) {
1371 Long iVlanIdInner = Long.parseLong(vlanIdInner);
1372 vlan.setVlanIdInner(iVlanIdInner);
1375 if(vlanIdOute != null) {
1376 Long iVlanIdOuter = Long.parseLong(vlanIdOute);
1377 vlan.setVlanIdOuter(iVlanIdOuter);
1380 if(speedValue != null) {
1381 vlan.setSpeedValue(speedValue);
1382 vlan.setSpeedUnits(speedUnits);
1385 vlanList.getVlan().add(vlan);
1391 if(subResources.contains("metadata") && !metadataKeys.isEmpty()) {
1393 Metadata metadataList = null;
1394 Method getMetadataMethod = resourceClass.getMethod("getMetadata");
1395 if(getMetadataMethod != null){
1397 getMetadataMethod.setAccessible(true);
1398 obj = getMetadataMethod.invoke(instance);
1399 } catch (InvocationTargetException x) {
1400 Throwable cause = x.getCause();
1403 if(obj != null && obj instanceof Metadata){
1404 metadataList = (Metadata)obj;
1406 metadataList = new Metadata();
1407 Method setMetadataMethod = resourceClass.getMethod("setMetadata", Metadata.class);
1408 if(setMetadataMethod != null){
1410 setMetadataMethod.setAccessible(true);
1411 Object arglist[] = new Object[1];
1412 arglist[0] = metadataList;
1414 obj = setMetadataMethod.invoke(instance, arglist);
1415 } catch (InvocationTargetException x) {
1416 Throwable cause = x.getCause();
1421 if(metadataList.getMetadatum() == null) {
1422 // metadataList.setMetadatum(new ArrayList<Metadatum>());
1428 String metaKey = "metadata.metadatum[" + i + "].meta-key";
1429 if(!params.containsKey(metaKey))
1432 String metaValue = params.get("metadata.metadatum[" + i + "].meta-value");
1434 Metadatum vlan = new Metadatum();
1435 vlan.setMetaname(metaKey);
1436 vlan.setMetaval(metaValue);
1438 metadataList.getMetadatum().add(vlan);
1445 // 6. Prepare AAI request
1446 String[] args = request.getArgsList();
1447 for(String arg : args) {
1448 String modifiedKey = arg.replaceAll("-", "_");
1449 if(nameValues.containsKey(modifiedKey)) {
1450 String argValue = nameValues.get(modifiedKey);
1451 if(argValue != null) argValue = argValue.trim().replace("'", "").replace("$", "").replace("'", "");
1452 request.addRequestProperty(arg, argValue);
1456 request.processRequestPathValues(nameValues);
1457 request.setRequestObject(instance);
1458 Object response = getExecutor().post(request);
1459 if(request.expectsDataFromPUTRequest()){
1460 if(response != null && response instanceof String) {
1461 String rv = response.toString();
1462 QueryStatus retval = processResponseData(rv, resource, request, prefix, ctx, nameValues, null);
1463 getLogger().debug("newModelSave - returning " + retval.toString());
1468 } catch(AAIServiceException exc){
1469 ctx.setAttribute(prefix + ".error.message", exc.getMessage());
1470 int returnCode = exc.getReturnCode();
1471 if(returnCode >= 300) {
1472 ctx.setAttribute(prefix + ".error.http.response-code",
1473 Integer.toString(exc.getReturnCode()));
1476 if(returnCode == 400 || returnCode == 412)
1477 return QueryStatus.FAILURE;
1478 else if(returnCode == 404)
1479 return QueryStatus.NOT_FOUND;
1481 getLogger().warn("Failed newModelSave - returning FAILURE", exc);
1482 return QueryStatus.FAILURE;
1484 } catch(Exception exc){
1485 getLogger().warn("Failed newModelSave - returning FAILURE", exc);
1486 ctx.setAttribute(prefix + ".error.message", exc.getMessage());
1487 return QueryStatus.FAILURE;
1490 getLogger().debug("newModelSave - returning SUCCESS");
1491 return QueryStatus.SUCCESS;
1494 private QueryStatus newModelProcessRelationshipList(Object instance, Map<String, String> params, String prefix, SvcLogicContext ctx) throws Exception {
1496 Class resourceClass = instance.getClass();
1498 Set<String> relationshipKeys = new TreeSet<>();
1500 Set<String> set = params.keySet();
1502 for(String attribute : set) {
1503 String value = params.get(attribute);
1505 if(attribute.startsWith("relationship-list")) {
1506 relationshipKeys.add(attribute);
1510 // 3. Process Relationships
1511 // add relationship list
1512 if(!relationshipKeys.isEmpty()) {
1513 RelationshipList relationshipList;
1515 Method getRelationshipListMethod = null;
1517 getRelationshipListMethod = resourceClass.getMethod("getRelationshipList");
1518 } catch(Exception exc) {
1519 getLogger().debug("Retrofiting relationship data: " + exc.getMessage());
1521 if(getRelationshipListMethod != null){
1523 getRelationshipListMethod.setAccessible(true);
1524 obj = getRelationshipListMethod.invoke(instance);
1525 } catch (InvocationTargetException x) {
1526 Throwable cause = x.getCause();
1529 if(obj != null && obj instanceof RelationshipList){
1530 relationshipList = (RelationshipList)obj;
1532 relationshipList = new RelationshipList();
1533 Method setRelationshipListMethod = resourceClass.getMethod("setRelationshipList", RelationshipList.class);
1534 if(setRelationshipListMethod != null){
1536 setRelationshipListMethod.setAccessible(true);
1537 Object arglist[] = new Object[1];
1538 arglist[0] = relationshipList;
1540 obj = setRelationshipListMethod.invoke(instance, arglist);
1541 } catch (InvocationTargetException x) {
1542 Throwable cause = x.getCause();
1547 boolean createdNewRelationships = false;
1548 List<Relationship> relationships = relationshipList.getRelationship();
1549 if(relationships == null) {
1550 relationships = new ArrayList<Relationship>();
1551 createdNewRelationships = true;
1556 String searchKey = "relationship-list.relationship[" + i + "].related-to";
1557 if(!params.containsKey(searchKey))
1561 String relatedTo = params.get(searchKey);
1562 String relatedLinkKey = "relationship-list.relationship[" + i + "].related-link";
1563 String relatedLink = null;
1564 if(params.containsKey(relatedLinkKey)) {
1565 relatedLink = params.get(relatedLinkKey);
1568 Relationship relationship = new Relationship();
1569 relationships.add(relationship);
1570 relationship.setRelatedTo(relatedTo);
1571 if(relatedLink != null) {
1572 relationship.setRelatedLink(relatedLink);
1574 Map<String, String> relParams = new HashMap<>();
1577 String searchRelationshipKey = "relationship-list.relationship[" + i + "].relationship-data[" + j + "].relationship-key";
1578 String searchRelationshipValue = "relationship-list.relationship[" + i + "].relationship-data[" + j + "].relationship-value";
1579 if(!params.containsKey(searchRelationshipKey))
1582 relParams.put(params.get(searchRelationshipKey), params.get(searchRelationshipValue));
1585 AAIRequest rlRequest = AAIRequest.createRequest(relatedTo, relParams);
1586 for(String key : relParams.keySet()) {
1587 rlRequest.addRequestProperty(key, relParams.get(key));
1589 String path = rlRequest.updatePathDataValues(null);
1590 relationship.setRelatedLink(path);
1597 return QueryStatus.SUCCESS;
1600 private Relationship findRelationship(List<Relationship> relationships, String relatedTo) {
1601 if(relatedTo == null)
1604 for(Relationship relationship : relationships) {
1605 if(relationship.getRelatedTo().equals(relatedTo)){
1606 return relationship;
1613 public QueryStatus backup(Map<String, String> params, SvcLogicContext ctx) throws SvcLogicException {
1614 String resource = params.get("resource").toLowerCase();
1615 String prefix = params.get("data-key");
1617 HashMap<String, String> nameValues = new HashMap<>();
1618 if(AAIRequest.createRequest(resource, nameValues) != null) {
1621 return newModelBackupRequest(resource, params, prefix, ctx);
1622 } catch (Exception exc) {
1623 getLogger().warn("Failed backup - returning FAILURE", exc);
1624 return QueryStatus.FAILURE;
1628 return QueryStatus.NOT_FOUND;
1632 public QueryStatus restore(Map<String, String> params, SvcLogicContext ctx) throws SvcLogicException {
1634 QueryStatus retval = QueryStatus.SUCCESS;
1635 String resource = params.get("resource").toLowerCase();
1636 String prefix = params.get("data-key");
1638 HashMap<String, String> nameValues = new HashMap<>();
1639 if(AAIRequest.createRequest(resource, nameValues) != null) {
1642 retval = newModelBackupRequest(resource, params, "tmpRestore", ctx);
1643 if(retval == QueryStatus.SUCCESS) {
1644 String current_json = ctx.getAttribute("tmpRestore");
1645 ctx. setAttribute("tmpRestore", null);
1647 String snapshot_json = ctx.getAttribute(prefix);
1649 } catch (Exception exc) {
1650 getLogger().warn("Failed restore - returning FAILURE", exc);
1651 return QueryStatus.FAILURE;
1655 return QueryStatus.NOT_FOUND;
1658 protected Map<String, Object> objectToProperties(Object object) {
1659 ObjectMapper mapper = AAIService.getObjectMapper();
1660 return mapper.convertValue(object, Map.class);
1663 static <T> T valueOf(Class<T> klazz, String arg) {
1664 Exception cause = null;
1667 ret = klazz.cast(klazz.getDeclaredMethod("valueOf", String.class).invoke(null, arg));
1668 } catch (NoSuchMethodException exc) {
1669 LoggerFactory.getLogger(AAIService.class).warn("Wrong data type", exc);
1670 ret = klazz.cast(arg);
1671 } catch (IllegalAccessException e) {
1673 } catch (InvocationTargetException e) {
1676 if (cause == null) {
1679 throw new IllegalArgumentException(cause);
1683 private QueryStatus processDeleteRelationshipList(String resource, String key, SvcLogicContext ctx, HashMap<String, String> nameValues) {
1685 AAIRequest request = AAIRequest.createRequest(resource, nameValues);
1686 if(request == null) {
1687 return QueryStatus.FAILURE;
1690 request.processRequestPathValues(nameValues);
1691 URL url = request.getRequestUrl("GET", null);
1693 Class resourceClass = request.getModelClass();
1694 Object instance = getResource(url.toString(), resourceClass);
1695 if(instance == null)
1696 return QueryStatus.NOT_FOUND;
1698 // get resource version
1699 String resourceVersion = null;
1700 Method getResourceVersionMethod = resourceClass.getMethod("getResourceVersion");
1701 if(getResourceVersionMethod != null){
1703 getResourceVersionMethod.setAccessible(true);
1704 Object object = getResourceVersionMethod.invoke(instance);
1706 resourceVersion = object.toString();
1707 } catch (InvocationTargetException x) {
1708 Throwable cause = x.getCause();
1712 RelationshipList relationshipList = null;
1714 Method getRelationshipListMethod = null;
1716 getRelationshipListMethod = resourceClass.getMethod("getRelationshipList");
1717 } catch(Exception exc) {
1718 getLogger().debug("Retrofiting relationship data: " + exc.getMessage());
1720 if(getRelationshipListMethod != null){
1722 getRelationshipListMethod.setAccessible(true);
1723 obj = getRelationshipListMethod.invoke(instance);
1724 } catch (InvocationTargetException x) {
1725 Throwable cause = x.getCause();
1728 if(obj != null && obj instanceof RelationshipList){
1729 relationshipList = (RelationshipList)obj;
1731 getLogger().debug("No relationships found to process.");
1732 return QueryStatus.NOT_FOUND;
1735 if(relationshipList.getRelationship() == null || relationshipList.getRelationship().isEmpty()) {
1736 return QueryStatus.NOT_FOUND;
1738 String relatedTo = nameValues.get("related_to");
1739 if(relatedTo == null) {
1740 return QueryStatus.FAILURE;
1743 relatedTo = relatedTo.replaceAll("_", "-");
1745 String relatedLink = nameValues.get("relationship.related_link");
1746 if(relatedLink != null) {
1747 relatedLink = URLDecoder.decode(relatedLink, "UTF-8");
1750 List<Relationship> relationships = relationshipList.getRelationship();
1751 List<Relationship> relationshipsToDelete = new LinkedList<Relationship>();
1753 for(Relationship relationship : relationships) {
1754 if(relatedTo.equals(relationship.getRelatedTo())) {
1755 if(relatedLink != null) {
1756 if(relationship.getRelatedLink() != null ) {
1757 String localRelatedLink = relationship.getRelatedLink();
1758 localRelatedLink = URLDecoder.decode(localRelatedLink, "UTF-8");
1759 if(localRelatedLink.endsWith(relatedLink)) {
1760 getLogger().debug(String.format("Found relationship of '%s' to keyword '%s'", relationship.getRelatedTo(), relatedTo));
1761 relationshipsToDelete.add(relationship);
1765 getLogger().debug(String.format("Found relationship of '%s' to keyword '%s'", relationship.getRelatedTo(), relatedTo));
1766 relationshipsToDelete.add(relationship);
1770 if(relationshipsToDelete == null || relationshipsToDelete.isEmpty()) {
1771 getLogger().info(String.format("Relationship has not been found for %s", key));
1772 return QueryStatus.NOT_FOUND;
1775 String path = url.toString();
1776 path = path + "/relationship-list/relationship";
1777 URL deleteUrl = new URL(path);
1779 ObjectMapper mapper = AAIService.getObjectMapper();
1781 boolean cumulativeResponse = true;
1783 for(Relationship targetRelationship : relationshipsToDelete) {
1784 String json_text = mapper.writeValueAsString(targetRelationship);
1785 boolean response = deleteRelationshipList(deleteUrl, json_text);
1787 cumulativeResponse = response;
1791 if(!cumulativeResponse)
1792 return QueryStatus.FAILURE;
1794 return QueryStatus.SUCCESS;
1796 } catch(Exception exc) {
1797 getLogger().warn("processDelete", exc);
1798 return QueryStatus.FAILURE;
1802 static final Map<String, String> ctxGetBeginsWith( SvcLogicContext ctx, String prefix ) {
1803 Map<String, String> tmpPrefixMap = new HashMap<>();
1805 if(prefix == null || prefix.isEmpty()){
1806 return tmpPrefixMap;
1809 for( String key : ctx.getAttributeKeySet() ) {
1810 if( key.startsWith(prefix) ) {
1811 String tmpKey = key.substring(prefix.length() + 1);
1812 tmpPrefixMap.put( tmpKey, ctx.getAttribute(key));
1816 Map<String, String> prefixMap = new HashMap<>();
1817 Pattern p = Pattern.compile(".*\\[\\d\\]");
1819 SortedSet<String> keys = new TreeSet(tmpPrefixMap.keySet () );
1820 for(String key : keys) {
1821 Matcher m = p.matcher(key);
1824 } else if(key.endsWith("_length")) {
1825 String listKey = key.substring(0, key.indexOf("_length"));
1826 int max = Integer.parseInt(tmpPrefixMap.get(key));
1828 ArrayList<String> data = new ArrayList<>();
1829 for(int x = 0; x < max; x++){
1830 String tmpKey = String.format("%s[%d]", listKey, x);
1831 String tmpValue = tmpPrefixMap.get(tmpKey);
1832 if(tmpValue != null && !tmpValue.isEmpty()) {
1836 if(!data.isEmpty()) {
1837 prefixMap.put(listKey, data.toString());
1839 prefixMap.put(key, tmpPrefixMap.get(key));
1842 prefixMap.put(key, tmpPrefixMap.get(key));
1851 protected NamedQueryData extractNamedQueryDataFromQueryPrefix(HashMap<String, String> nameValues, Map<String, String> parms) {
1852 if(parms.isEmpty()) {
1856 NamedQueryData data = new NamedQueryData();
1859 if(data.getQueryParameters() == null) {
1860 data.setQueryParameters(new QueryParameters());
1862 String namedQueryUuid = nameValues.get("named-query-uuid".replaceAll("-", "_"));
1863 if(namedQueryUuid == null) {
1864 namedQueryUuid = parms.get("query-parameters.named-query.named-query-uuid");
1866 NamedQuery namedQuery = new NamedQuery();
1867 namedQuery.setNamedQueryUuid(namedQueryUuid);
1868 data.getQueryParameters().setNamedQuery(namedQuery);
1871 if(data.getInstanceFilters() == null) {
1872 data.setInstanceFilters(new InstanceFilters());
1876 String quantity = parms.get("instance-filters.instance-filter_length");
1877 if(quantity != null && StringUtils.isNumeric(quantity)) {
1878 int max = Integer.parseInt(quantity);
1879 for(int i = 0; i < max; i++) {
1880 String keyPattern = String.format("instance-filters.instance-filter[%d].", i);
1881 Set<String> keys = parms.keySet();
1882 for(String key: keys) {
1883 if(key.startsWith(keyPattern)){
1884 String value = parms.get(key);
1885 String remainder = key.substring(keyPattern.length());
1886 String[] split = remainder.split("\\.");
1887 getLogger().debug(String.format("%s", remainder));
1888 if("logical-link".equals(split[0])) {
1889 InstanceFilter insf = null;
1890 if(data.getInstanceFilters().getInstanceFilter().isEmpty()) {
1891 insf = new InstanceFilter();
1892 data.getInstanceFilters().getInstanceFilter().add(insf);
1894 insf = data.getInstanceFilters().getInstanceFilter().get(0);
1896 LogicalLink logicalLink = insf.getLogicalLink();
1897 if(logicalLink == null) {
1898 logicalLink = new LogicalLink();
1899 insf.setLogicalLink(logicalLink);
1904 logicalLink.setLinkName(value);
1907 logicalLink.setLinkType(value);
1909 case "operational-state":
1910 logicalLink.setOperationalStatus(value);
1914 } else if("pnf".equals(split[0])) {
1915 Pnf pnf = new Pnf();
1916 pnf.setPnfName(value);
1918 InstanceFilter insf = new InstanceFilter();
1920 data.getInstanceFilters().getInstanceFilter().add(insf);
1922 } else if("service-instance".equals(split[0])) {
1923 ServiceInstance serviceInstance = new ServiceInstance();
1924 serviceInstance.setServiceInstanceId(value);
1926 InstanceFilter insf = new InstanceFilter();
1927 insf.setServiceInstance(serviceInstance);
1928 data.getInstanceFilters().getInstanceFilter().add(insf);
1930 } else if("l3-network".equals(split[0])) {
1931 L3Network l3Network = new L3Network();
1932 if("network-role".equals(split[1])) {
1933 l3Network.setNetworkRole(value);
1936 InstanceFilter insf = new InstanceFilter();
1937 insf.setL3Network(l3Network);
1938 data.getInstanceFilters().getInstanceFilter().add(insf);
1939 } else if("generic-vnf".equals(split[0])) {
1940 GenericVnf vnf = new GenericVnf();
1941 if("vnf-id".equals(split[1])) {
1942 vnf.setVnfId(value);
1945 InstanceFilter insf = new InstanceFilter();
1946 insf.setGenericVnf(vnf);
1947 data.getInstanceFilters().getInstanceFilter().add(insf);
1957 public abstract <T> T getResource(String key, Class<T> type) throws AAIServiceException ;
1958 protected abstract boolean deleteRelationshipList(URL url, String caller) throws AAIServiceException;