2 * ============LICENSE_START=======================================================
4 * ================================================================================
5 * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved.
6 * ================================================================================
7 * Modifications Copyright © 2024 Deutsche Telekom.
8 * ================================================================================
9 * Licensed under the Apache License, Version 2.0 (the "License");
10 * you may not use this file except in compliance with the License.
11 * You may obtain a copy of the License at
13 * http://www.apache.org/licenses/LICENSE-2.0
15 * Unless required by applicable law or agreed to in writing, software
16 * distributed under the License is distributed on an "AS IS" BASIS,
17 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18 * See the License for the specific language governing permissions and
19 * limitations under the License.
20 * ============LICENSE_END=========================================================
23 package org.onap.aai.rest.db;
25 import com.fasterxml.jackson.databind.JsonNode;
26 import com.fasterxml.jackson.databind.ObjectMapper;
27 import com.github.fge.jsonpatch.JsonPatchException;
28 import com.github.fge.jsonpatch.mergepatch.JsonMergePatch;
30 import java.io.IOException;
31 import java.io.UnsupportedEncodingException;
32 import java.lang.reflect.InvocationTargetException;
33 import java.net.MalformedURLException;
35 import java.net.URISyntaxException;
37 import java.util.stream.Collectors;
39 import jakarta.ws.rs.core.*;
40 import jakarta.ws.rs.core.Response.Status;
42 import org.apache.tinkerpop.gremlin.structure.Vertex;
43 import org.janusgraph.core.JanusGraphException;
44 import org.javatuples.Pair;
45 import org.onap.aai.aailog.logs.AaiDBMetricLog;
46 import org.onap.aai.db.props.AAIProperties;
47 import org.onap.aai.exceptions.AAIException;
48 import org.onap.aai.introspection.*;
49 import org.onap.aai.introspection.exceptions.AAIUnknownObjectException;
50 import org.onap.aai.introspection.sideeffect.OwnerCheck;
51 import org.onap.aai.logging.ErrorLogHelper;
52 import org.onap.aai.nodes.NodeIngestor;
53 import org.onap.aai.parsers.query.QueryParser;
54 import org.onap.aai.prevalidation.ValidationService;
55 import org.onap.aai.query.builder.QueryOptions;
56 import org.onap.aai.query.entities.PaginationResult;
57 import org.onap.aai.rest.notification.NotificationService;
58 import org.onap.aai.rest.notification.UEBNotification;
59 import org.onap.aai.restcore.HttpMethod;
60 import org.onap.aai.schema.enums.ObjectMetadata;
61 import org.onap.aai.serialization.db.DBSerializer;
62 import org.onap.aai.serialization.engines.JanusGraphDBEngine;
63 import org.onap.aai.serialization.engines.QueryStyle;
64 import org.onap.aai.serialization.engines.TransactionalGraphEngine;
65 import org.onap.aai.serialization.engines.query.QueryEngine;
66 import org.onap.aai.serialization.queryformats.Format;
67 import org.onap.aai.serialization.queryformats.FormatFactory;
68 import org.onap.aai.serialization.queryformats.Formatter;
69 import org.onap.aai.setup.SchemaVersion;
70 import org.onap.aai.setup.SchemaVersions;
71 import org.onap.aai.transforms.XmlFormatTransformer;
72 import org.onap.aai.util.AAIConfig;
73 import org.onap.aai.util.AAIConstants;
74 import org.slf4j.Logger;
75 import org.slf4j.LoggerFactory;
76 import org.springframework.beans.factory.annotation.Autowired;
77 import org.springframework.beans.factory.annotation.Value;
80 * The Class HttpEntry.
82 public class HttpEntry {
84 private static final Logger LOGGER = LoggerFactory.getLogger(HttpEntry.class);
86 private ModelType introspectorFactoryType;
87 private QueryStyle queryStyle;
88 private SchemaVersion version;
89 private Loader loader;
90 private TransactionalGraphEngine dbEngine;
93 private NodeIngestor nodeIngestor;
96 private LoaderFactory loaderFactory;
99 private SchemaVersions schemaVersions;
102 private NotificationService notificationService;
104 @Value("${schema.uri.base.path}")
105 private String basePath;
107 private String serverBase;
110 private XmlFormatTransformer xmlFormatTransformer;
112 private UEBNotification notification;
114 private int notificationDepth;
117 * Instantiates a new http entry.
119 * @param modelType the model type
120 * @param queryStyle the query style
122 public HttpEntry(ModelType modelType, QueryStyle queryStyle) {
123 this.introspectorFactoryType = modelType;
124 this.queryStyle = queryStyle;
127 public HttpEntry setHttpEntryProperties(SchemaVersion version) {
128 this.version = version;
129 this.loader = loaderFactory.createLoaderForVersion(introspectorFactoryType, version);
130 this.dbEngine = new JanusGraphDBEngine(queryStyle, loader);
132 getDbEngine().startTransaction();
133 this.notification = new UEBNotification(loaderFactory, schemaVersions);
134 if ("true".equals(AAIConfig.get("aai.notification.depth.all.enabled", "true"))) {
135 this.notificationDepth = AAIProperties.MAXIMUM_DEPTH;
137 this.notificationDepth = AAIProperties.MINIMUM_DEPTH;
142 public HttpEntry setHttpEntryProperties(SchemaVersion version, String serverBase) {
143 setHttpEntryProperties(version);
144 this.serverBase = serverBase;
148 public HttpEntry setHttpEntryProperties(SchemaVersion version, UEBNotification notification) {
149 setHttpEntryProperties(version);
150 this.notification = notification;
154 public HttpEntry setHttpEntryProperties(SchemaVersion version, UEBNotification notification,
155 int notificationDepth) {
156 setHttpEntryProperties(version);
157 this.notification = notification;
158 this.notificationDepth = notificationDepth;
162 public ModelType getIntrospectorFactoryType() {
163 return introspectorFactoryType;
166 public QueryStyle getQueryStyle() {
170 public SchemaVersion getVersion() {
174 public Loader getLoader() {
178 public TransactionalGraphEngine getDbEngine() {
182 public Pair<Boolean, List<Pair<URI, Response>>> process(List<DBRequest> requests, String sourceOfTruth) throws AAIException {
183 return this.process(requests, sourceOfTruth, true);
186 public Pair<Boolean, List<Pair<URI, Response>>> process(List<DBRequest> requests, String sourceOfTruth,boolean enableResourceVersion) throws AAIException {
187 return this.process(requests, sourceOfTruth, Collections.emptySet(), enableResourceVersion, null);
190 public Pair<Boolean, List<Pair<URI, Response>>> process(List<DBRequest> requests, String sourceOfTruth, Set<String> groups) throws AAIException {
191 return this.process(requests, sourceOfTruth, groups, true, null);
195 public Pair<Boolean, List<Pair<URI, Response>>> process(List<DBRequest> requests, String sourceOfTruth,
196 Set<String> groups, boolean enableResourceVersion, QueryOptions queryOptions) throws AAIException {
198 DBSerializer serializer = null;
199 if (serverBase != null) {
200 serializer = new DBSerializer(version, dbEngine, introspectorFactoryType, sourceOfTruth, groups,
201 notificationDepth, serverBase);
203 serializer = new DBSerializer(version, dbEngine, introspectorFactoryType, sourceOfTruth, groups,
207 Set<Vertex> mainVertexesToNotifyOn = new LinkedHashSet<>();
208 AaiDBMetricLog metricLog = new AaiDBMetricLog(AAIConstants.AAI_RESOURCES_MS);
210 String outputMediaType = null;
211 if (requests != null && !requests.isEmpty()) {
212 HttpHeaders headers = requests.get(0).getHeaders();
213 outputMediaType = getMediaType(headers.getAcceptableMediaTypes());
216 String transactionId = requests.get(0).getTransactionId();
217 boolean success = true;
218 QueryEngine queryEngine = dbEngine.getQueryEngine();
219 List<Pair<URI, Response>> responses = new ArrayList<>();
220 for (DBRequest request : requests) {
221 Response response = null;
222 Status status = Status.NOT_FOUND;
223 HttpMethod method = request.getMethod();
224 metricLog.pre(request);
227 String uriTemp = request.getUri().getRawPath().replaceFirst("^v\\d+/", "");
229 QueryParser query = request.getParser();
230 List<Vertex> queryResult;
231 PaginationResult<Vertex> paginationResult = null;
232 if(queryOptions != null && queryOptions.getPageable() != null) {
233 paginationResult = executePaginatedQuery(query, queryOptions);
234 queryResult = paginationResult.getResults();
236 queryResult = executeQuery(query, queryOptions);
239 boolean groupsAvailable = serializer.getGroups() != null && !serializer.getGroups().isEmpty();
240 List<Vertex> vertices = groupsAvailable
241 ? queryResult.stream()
242 .filter(vertex -> OwnerCheck.isAuthorized(groups, vertex))
243 .collect(Collectors.toList())
246 MultivaluedMap<String, String> params = request.getInfo().getQueryParameters(false);
247 Introspector obj = request.getIntrospector();
248 int depth = setDepth(obj, params.getFirst("depth"));
249 Format format = null;
250 if (params.containsKey("format")) {
251 format = Format.getFormat(params.getFirst("format"));
254 String cleanUp = params.getFirst("cleanup");
255 if (cleanUp == null) {
258 if (vertices.size() > 1
259 && !(method.equals(HttpMethod.GET) || method.equals(HttpMethod.GET_RELATIONSHIP))) {
260 if (method.equals(HttpMethod.DELETE)) {
262 throw new AAIException("AAI_6138");
264 throw new AAIException("AAI_6137");
268 if (method.equals(HttpMethod.PUT)) {
269 String resourceVersion = obj.getValue(AAIProperties.RESOURCE_VERSION);
270 if (vertices.isEmpty()) {
271 if (enableResourceVersion) {
272 serializer.verifyResourceVersion("create", query.getResultType(), "", resourceVersion,
277 if (enableResourceVersion) {
278 serializer.verifyResourceVersion("update", query.getResultType(),
279 vertices.get(0).<String>property(AAIProperties.RESOURCE_VERSION).orElse(null),
280 resourceVersion, obj.getURI());
285 if (vertices.isEmpty()) {
286 String msg = createNotFoundMessage(query.getResultType(), request.getUri());
287 throw new AAIException("AAI_6114", msg);
298 * This skip-related-to query parameter is used to determine if the relationships object will omit
299 * the related-to-property
300 * If a GET is sent to resources without a format, if format=resource, or if format=resource_and_url
301 * with this param set to false
302 * then behavior will be keep the related-to properties. By default, set to true.
303 * Otherwise, for any other case, when the skip-related-to parameter exists, has value=true, or some
304 * unfamiliar input (e.g. skip-related-to=bogusvalue), the value is true.
306 boolean isSkipRelatedTo = true;
307 if (params.containsKey("skip-related-to")) {
308 String skipRelatedTo = params.getFirst("skip-related-to");
309 isSkipRelatedTo = !(skipRelatedTo != null && skipRelatedTo.equals("false"));
311 // if skip-related-to param is missing, then default it to false;
312 isSkipRelatedTo = false;
315 HashMap<String, Introspector> relatedObjects = new HashMap<>();
316 String nodeOnly = params.getFirst("nodes-only");
317 boolean isNodeOnly = nodeOnly != null;
319 String requestContext = "";
320 List<String> requestContextList = request.getHeaders().getRequestHeader("aai-request-context");
321 if (requestContextList != null) {
322 requestContext = requestContextList.get(0);
324 URI uri = UriBuilder.fromPath(uriTemp).build();
325 HttpHeaders headers = request.getHeaders();
326 outputMediaType = getMediaType(headers.getAcceptableMediaTypes());
327 String result = null;
331 if (format == null) {
332 obj = this.getObjectFromDb(vertices, serializer, query, obj, request.getUri(), depth,
333 isNodeOnly, cleanUp, isSkipRelatedTo);
337 MarshallerProperties properties;
338 Optional<MarshallerProperties> marshallerPropOpt =
339 request.getMarshallerProperties();
340 if (marshallerPropOpt.isPresent()) {
341 properties = marshallerPropOpt.get();
343 properties = new MarshallerProperties.Builder(
344 org.onap.aai.restcore.MediaType.getEnum(outputMediaType)).build();
346 result = obj.marshal(properties);
349 FormatFactory ff = new FormatFactory(loader, serializer, schemaVersions, basePath + "/",
351 Formatter formatter = ff.get(format, params);
352 result = formatter.output(
353 vertices.stream().map(vertex -> (Object) vertex).collect(Collectors.toList()))
356 if (outputMediaType == null) {
357 outputMediaType = MediaType.APPLICATION_JSON;
360 if (MediaType.APPLICATION_XML_TYPE.isCompatible(MediaType.valueOf(outputMediaType))) {
361 result = xmlFormatTransformer.transform(result);
367 case GET_RELATIONSHIP:
368 if (format == null) {
369 obj = this.getRelationshipObjectFromDb(vertices, serializer, query,
370 request.getInfo().getRequestUri(), isSkipRelatedTo);
374 MarshallerProperties properties;
375 if (request.getMarshallerProperties().isEmpty()) {
376 properties = new MarshallerProperties.Builder(
377 org.onap.aai.restcore.MediaType.getEnum(outputMediaType)).build();
379 properties = request.getMarshallerProperties().get();
381 result = obj.marshal(properties);
384 createRelationshipNotFoundMessage(query.getResultType(), request.getUri());
385 throw new AAIException("AAI_6149", msg);
388 FormatFactory ff = new FormatFactory(loader, serializer, schemaVersions, basePath + "/",
390 Formatter formatter = ff.get(format, params);
391 result = formatter.output(
392 vertices.stream().map(vertex -> (Object) vertex).collect(Collectors.toList()))
395 if (outputMediaType == null) {
396 outputMediaType = MediaType.APPLICATION_JSON;
399 if (MediaType.APPLICATION_XML_TYPE.isCompatible(MediaType.valueOf(outputMediaType))) {
400 result = xmlFormatTransformer.transform(result);
407 v = serializer.createNewVertex(obj);
409 serializer.serializeToDb(obj, v, query, uri.getRawPath(), requestContext);
412 status = Status.CREATED;
415 mainVertexesToNotifyOn.add(v);
416 if (notificationDepth == AAIProperties.MINIMUM_DEPTH) {
417 Map<String, Pair<Introspector, LinkedHashMap<String, Introspector>>> allImpliedDeleteObjs =
418 serializer.getImpliedDeleteUriObjectPair();
420 for (Map.Entry<String, Pair<Introspector, LinkedHashMap<String, Introspector>>> entry : allImpliedDeleteObjs
422 // The format is purposefully %s/%s%s due to the fact
423 // that every aai-uri will have a slash at the beginning
424 // If that assumption isn't true, then its best to change this code
425 String curUri = "%s/%s%s".formatted(basePath, version, entry.getKey());
426 Introspector curObj = entry.getValue().getValue0();
427 HashMap<String, Introspector> curObjRelated = entry.getValue().getValue1();
428 notification.createNotificationEvent(transactionId, sourceOfTruth,
429 Status.NO_CONTENT, URI.create(curUri), curObj, curObjRelated, basePath);
435 serializer.touchStandardVertexProperties(v, false);
436 Vertex relatedVertex = serializer.createEdge(obj, v);
439 mainVertexesToNotifyOn.add(v);
440 serializer.addVertexToEdgeVertexes(relatedVertex);
443 Introspector existingObj = loader.introspectorFromName(obj.getDbName());
444 existingObj = this.getObjectFromDb(vertices, serializer, query, existingObj,
445 request.getUri(), 0, false, cleanUp);
446 String existingJson = existingObj.marshal(false);
449 if (request.getRawRequestContent().isPresent()) {
450 newJson = request.getRawRequestContent().get();
454 Object relationshipList = request.getIntrospector().getValue("relationship-list");
455 ObjectMapper mapper = new ObjectMapper();
457 JsonNode existingNode = mapper.readTree(existingJson);
458 JsonNode newNode = mapper.readTree(newJson);
459 JsonMergePatch patch = JsonMergePatch.fromJson(newNode);
460 JsonNode completed = patch.apply(existingNode);
461 String patched = mapper.writeValueAsString(completed);
462 Introspector patchedObj = loader.unmarshal(existingObj.getName(), patched);
463 if (relationshipList == null && patchedObj.hasProperty("relationship-list")) {
464 // if the caller didn't touch the relationship-list, we shouldn't either
465 patchedObj.setValue("relationship-list", null);
467 serializer.serializeToDb(patchedObj, v, query, uri.getRawPath(), requestContext);
469 mainVertexesToNotifyOn.add(v);
470 } catch (IOException | JsonPatchException e) {
471 throw new AAIException("AAI_3000", "could not perform patch operation");
475 String resourceVersion = params.getFirst(AAIProperties.RESOURCE_VERSION);
476 obj = serializer.getLatestVersionView(v, notificationDepth);
477 if (query.isDependent()) {
478 relatedObjects = serializer.getRelatedObjects(queryEngine, v, obj, this.loader);
481 * Find all Delete-other-vertex vertices and create structure for notify
482 * findDeleatble also returns the startVertex v and we dont want to create
483 * duplicate notification events for the same
484 * So remove the startvertex first
487 List<Vertex> deletableVertices = dbEngine.getQueryEngine().findDeletable(v);
491 * I am assuming vertexId cant be null
493 deletableVertices.removeIf(s -> vId.equals(s.id()));
494 boolean isDelVerticesPresent = !deletableVertices.isEmpty();
495 Map<Vertex, Introspector> deleteObjects = new HashMap<>();
496 Map<String, URI> uriMap = new HashMap<>();
497 Map<String, HashMap<String, Introspector>> deleteRelatedObjects = new HashMap<>();
499 if (isDelVerticesPresent) {
500 deleteObjects = this.buildIntrospectorObjects(serializer, deletableVertices);
502 uriMap = this.buildURIMap(serializer, deleteObjects);
503 deleteRelatedObjects = this.buildRelatedObjects(serializer, queryEngine, deleteObjects);
506 serializer.delete(v, deletableVertices, resourceVersion, enableResourceVersion);
507 status = Status.NO_CONTENT;
508 notification.createNotificationEvent(transactionId, sourceOfTruth, status, uri, obj,
509 relatedObjects, basePath);
512 * Notify delete-other-v candidates
515 if (isDelVerticesPresent) {
516 notificationService.buildNotificationEvent(sourceOfTruth, status, transactionId, notification,
517 deleteObjects, uriMap, deleteRelatedObjects, basePath);
521 serializer.touchStandardVertexProperties(v, false);
522 Optional<Vertex> otherV = serializer.deleteEdge(obj, v);
524 status = Status.NO_CONTENT;
525 if (otherV.isPresent()) {
526 mainVertexesToNotifyOn.add(v);
527 serializer.addVertexToEdgeVertexes(otherV.get());
535 * temporarily adding vertex id to the headers
536 * to be able to use for testing the vertex id endpoint functionality
537 * since we presently have no other way of generating those id urls
539 if (response == null && v != null && (method.equals(HttpMethod.PUT) || method.equals(HttpMethod.GET)
540 || method.equals(HttpMethod.MERGE_PATCH) || method.equals(HttpMethod.GET_RELATIONSHIP))
543 String myvertid = v.id().toString();
544 if (paginationResult != null && paginationResult.getTotalCount() != null) {
545 long totalPages = getTotalPages(queryOptions, paginationResult);
546 response = Response.status(status).header("vertex-id", myvertid)
547 .header("total-results", paginationResult.getTotalCount())
548 .header("total-pages", totalPages)
550 .type(outputMediaType).build();
552 response = Response.status(status).header("vertex-id", myvertid).entity(result)
553 .type(outputMediaType).build();
555 } else if (response == null) {
556 response = Response.status(status).type(outputMediaType).build();
557 } // else, response already set to something
559 Pair<URI, Response> pairedResp = Pair.with(request.getUri(), response);
560 responses.add(pairedResp);
561 } catch (JanusGraphException e) {
562 this.dbEngine.rollback();
563 throw new AAIException("AAI_6134", e);
565 } catch (AAIException e) {
567 ArrayList<String> templateVars = new ArrayList<>();
568 templateVars.add(request.getMethod().toString()); // GET, PUT, etc
569 templateVars.add(request.getUri().getPath());
570 templateVars.addAll(e.getTemplateVars());
571 ErrorLogHelper.logException(e);
573 Response.status(e.getErrorObject().getHTTPResponseCode())
574 .entity(ErrorLogHelper.getRESTAPIErrorResponse(
575 request.getHeaders().getAcceptableMediaTypes(), e, templateVars))
576 .type(outputMediaType).build();
577 Pair<URI, Response> pairedResp = Pair.with(request.getUri(), response);
578 responses.add(pairedResp);
579 } catch (Exception e) {
581 AAIException ex = new AAIException("AAI_4000", e);
582 ArrayList<String> templateVars = new ArrayList<>();
583 templateVars.add(request.getMethod().toString()); // GET, PUT, etc
584 templateVars.add(request.getUri().getPath());
585 ErrorLogHelper.logException(ex);
587 Response.status(ex.getErrorObject().getHTTPResponseCode())
588 .entity(ErrorLogHelper.getRESTAPIErrorResponse(
589 request.getHeaders().getAcceptableMediaTypes(), ex, templateVars))
590 .type(outputMediaType).build();
591 Pair<URI, Response> pairedResp = Pair.with(request.getUri(), response);
592 responses.add(pairedResp);
594 if (response != null) {
595 metricLog.post(request, response);
601 notificationService.generateEvents(notification, notificationDepth, sourceOfTruth, serializer, transactionId, queryEngine, mainVertexesToNotifyOn, version);
603 notification.clearEvents();
606 return Pair.with(success, responses);
609 private long getTotalPages(QueryOptions queryOptions, PaginationResult<Vertex> paginationResult) {
610 long totalCount = paginationResult.getTotalCount();
611 int pageSize = queryOptions.getPageable().getPageSize();
612 long totalPages = totalCount / pageSize;
613 // conditionally add a page for the remainder
614 if (totalCount % pageSize > 0) {
620 private List<Vertex> executeQuery(QueryParser query, QueryOptions queryOptions) {
621 return (queryOptions != null && queryOptions.getSort() != null)
622 ? query.getQueryBuilder().sort(queryOptions.getSort()).toList()
623 : query.getQueryBuilder().toList();
626 private PaginationResult<Vertex> executePaginatedQuery(QueryParser query, QueryOptions queryOptions) {
627 return queryOptions.getSort() != null
628 ? query.getQueryBuilder().sort(queryOptions.getSort()).toPaginationResult(queryOptions.getPageable())
629 : query.getQueryBuilder().toPaginationResult(queryOptions.getPageable());
632 private String getMediaType(List<MediaType> mediaTypeList) {
633 String mediaType = MediaType.APPLICATION_JSON; // json is the default
634 for (MediaType mt : mediaTypeList) {
635 if (MediaType.APPLICATION_XML_TYPE.isCompatible(mt)) {
636 mediaType = MediaType.APPLICATION_XML;
642 private Introspector getObjectFromDb(List<Vertex> results, DBSerializer serializer, QueryParser query,
643 Introspector obj, URI uri, int depth, boolean nodeOnly, String cleanUp)
644 throws AAIException, IllegalAccessException, IllegalArgumentException, InvocationTargetException,
645 SecurityException, InstantiationException, NoSuchMethodException, UnsupportedEncodingException,
646 AAIUnknownObjectException, URISyntaxException {
649 if (results.isEmpty()) {
650 String msg = createNotFoundMessage(query.getResultType(), uri);
651 throw new AAIException("AAI_6114", msg);
654 return serializer.dbToObject(results, obj, depth, nodeOnly, cleanUp);
658 private Introspector getObjectFromDb(List<Vertex> results, DBSerializer serializer, QueryParser query,
659 Introspector obj, URI uri, int depth, boolean nodeOnly, String cleanUp, boolean isSkipRelatedTo)
660 throws AAIException, IllegalAccessException, IllegalArgumentException, InvocationTargetException,
661 SecurityException, InstantiationException, NoSuchMethodException, UnsupportedEncodingException,
662 AAIUnknownObjectException, URISyntaxException {
665 if (results.isEmpty()) {
666 String msg = createNotFoundMessage(query.getResultType(), uri);
667 throw new AAIException("AAI_6114", msg);
670 return serializer.dbToObject(results, obj, depth, nodeOnly, cleanUp, isSkipRelatedTo);
674 private Introspector getRelationshipObjectFromDb(List<Vertex> results, DBSerializer serializer, QueryParser query,
675 URI uri, boolean isSkipRelatedTo) throws AAIException, IllegalArgumentException, SecurityException,
676 UnsupportedEncodingException, AAIUnknownObjectException {
679 if (results.isEmpty()) {
680 String msg = createNotFoundMessage(query.getResultType(), uri);
681 throw new AAIException("AAI_6114", msg);
684 if (results.size() > 1) {
685 throw new AAIException("AAI_6148", uri.getPath());
688 Vertex v = results.get(0);
689 return serializer.dbToRelationshipObject(v, isSkipRelatedTo);
692 private String createNotFoundMessage(String resultType, URI uri) {
693 return "No Node of type " + resultType + " found at: " + uri.getPath();
696 private String createRelationshipNotFoundMessage(String resultType, URI uri) {
697 return "No relationship found of type " + resultType + " at the given URI: " + uri.getPath()
698 + "/relationship-list";
701 protected int setDepth(Introspector obj, String depthParam) throws AAIException {
702 int depth = AAIProperties.MAXIMUM_DEPTH;
704 String getAllRandomStr = AAIConfig.get("aai.rest.getall.depthparam", "");
705 if (getAllRandomStr != null && !getAllRandomStr.isEmpty() && getAllRandomStr.equals(depthParam)) {
709 if (depthParam == null) {
710 if (this.version.compareTo(schemaVersions.getDepthVersion()) >= 0) {
714 if (!depthParam.isEmpty() && !"all".equals(depthParam)) {
716 depth = Integer.parseInt(depthParam);
717 } catch (Exception e) {
718 throw new AAIException("AAI_4016");
723 String maxDepth = obj.getMetadata(ObjectMetadata.MAXIMUM_DEPTH);
725 int maximumDepth = AAIProperties.MAXIMUM_DEPTH;
727 if (maxDepth != null) {
729 maximumDepth = Integer.parseInt(maxDepth);
730 } catch (Exception ex) {
731 throw new AAIException("AAI_4018");
735 if (depth > maximumDepth) {
736 throw new AAIException("AAI_3303");
742 private Map<Vertex, Introspector> buildIntrospectorObjects(DBSerializer serializer, Iterable<Vertex> vertices) {
743 Map<Vertex, Introspector> deleteObjectMap = new HashMap<>();
744 for (Vertex vertex : vertices) {
746 Introspector deleteObj = serializer.getLatestVersionView(vertex, notificationDepth);
747 deleteObjectMap.put(vertex, deleteObj);
748 } catch (UnsupportedEncodingException | AAIException e) {
749 LOGGER.warn("Unable to get Introspctor Objects, Just continue");
754 return deleteObjectMap;
758 private Map<String, URI> buildURIMap(DBSerializer serializer, Map<Vertex, Introspector> introSpector) {
759 Map<String, URI> uriMap = new HashMap<>();
760 for (Map.Entry<Vertex, Introspector> entry : introSpector.entrySet()) {
763 uri = serializer.getURIForVertex(entry.getKey());
764 if (null != entry.getValue()) {
765 uriMap.put(entry.getValue().getObjectId(), uri);
767 } catch (UnsupportedEncodingException e) {
768 LOGGER.warn("Unable to get URIs, Just continue");
777 private Map<String, HashMap<String, Introspector>> buildRelatedObjects(DBSerializer serializer,
778 QueryEngine queryEngine, Map<Vertex, Introspector> introSpector) {
780 Map<String, HashMap<String, Introspector>> relatedObjectsMap = new HashMap<>();
781 for (Map.Entry<Vertex, Introspector> entry : introSpector.entrySet()) {
783 HashMap<String, Introspector> relatedObjects =
784 serializer.getRelatedObjects(queryEngine, entry.getKey(), entry.getValue(), this.loader);
785 if (null != entry.getValue()) {
786 relatedObjectsMap.put(entry.getValue().getObjectId(), relatedObjects);
788 } catch (IllegalArgumentException | SecurityException | UnsupportedEncodingException | AAIException e) {
789 LOGGER.warn("Unable to get realted Objects, Just continue");
794 return relatedObjectsMap;