2 * ============LICENSE_START=======================================================
4 * ================================================================================
5 * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved.
6 * ================================================================================
7 * Modifications Copyright © 2023 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 static org.onap.aai.edges.enums.AAIDirection.NONE;
26 import static org.hamcrest.Matchers.containsString;
27 import static org.junit.Assert.assertEquals;
28 import static org.junit.Assert.assertNull;
29 import static org.junit.Assert.assertThat;
30 import static org.junit.Assert.assertTrue;
31 import static org.mockito.ArgumentMatchers.any;
32 import static org.mockito.ArgumentMatchers.anyInt;
33 import static org.mockito.Mockito.never;
34 import static org.mockito.Mockito.times;
35 import static org.mockito.Mockito.verify;
36 import static org.mockito.Mockito.when;
38 import java.util.Collections;
39 import com.fasterxml.jackson.core.JsonProcessingException;
40 import com.fasterxml.jackson.databind.JsonMappingException;
41 import com.fasterxml.jackson.databind.ObjectMapper;
43 import java.io.UnsupportedEncodingException;
45 import java.util.ArrayList;
46 import java.util.Arrays;
47 import java.util.Collection;
48 import java.util.HashSet;
49 import java.util.List;
51 import java.util.UUID;
53 import jakarta.ws.rs.core.HttpHeaders;
54 import jakarta.ws.rs.core.MediaType;
55 import jakarta.ws.rs.core.MultivaluedHashMap;
56 import jakarta.ws.rs.core.MultivaluedMap;
57 import jakarta.ws.rs.core.Response;
58 import jakarta.ws.rs.core.UriBuilder;
59 import jakarta.ws.rs.core.UriInfo;
61 import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversal;
62 import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversalSource;
63 import org.apache.tinkerpop.gremlin.structure.Edge;
64 import org.apache.tinkerpop.gremlin.structure.Vertex;
65 import org.javatuples.Pair;
66 import org.json.JSONArray;
67 import org.json.JSONObject;
68 import org.junit.After;
69 import org.junit.Before;
70 import org.junit.FixMethodOrder;
71 import org.junit.Test;
72 import org.junit.runner.RunWith;
73 import org.junit.runners.MethodSorters;
74 import org.junit.runners.Parameterized;
75 import org.mockito.Mockito;
76 import org.onap.aai.AAISetup;
77 import org.onap.aai.db.props.AAIProperties;
78 import org.onap.aai.edges.enums.EdgeField;
79 import org.onap.aai.edges.enums.EdgeProperty;
80 import org.onap.aai.exceptions.AAIException;
81 import org.onap.aai.introspection.Introspector;
82 import org.onap.aai.introspection.Loader;
83 import org.onap.aai.parsers.query.QueryParser;
84 import org.onap.aai.prevalidation.ValidationService;
85 import org.onap.aai.query.builder.Pageable;
86 import org.onap.aai.query.builder.QueryOptions;
87 import org.onap.aai.query.builder.Sort;
88 import org.onap.aai.query.builder.Sort.Direction;
89 import org.onap.aai.rest.db.responses.ErrorResponse;
90 import org.onap.aai.rest.db.responses.Relationship;
91 import org.onap.aai.rest.db.responses.RelationshipWrapper;
92 import org.onap.aai.rest.db.responses.ServiceException;
93 import org.onap.aai.rest.notification.NotificationService;
94 import org.onap.aai.restcore.HttpMethod;
95 import org.onap.aai.serialization.engines.QueryStyle;
96 import org.onap.aai.serialization.engines.TransactionalGraphEngine;
97 import org.onap.aai.util.AAIConfig;
98 import org.skyscreamer.jsonassert.JSONAssert;
99 import org.skyscreamer.jsonassert.JSONCompareMode;
100 import org.springframework.boot.test.mock.mockito.MockBean;
101 import org.springframework.http.HttpStatus;
103 @RunWith(value = Parameterized.class)
104 @FixMethodOrder(MethodSorters.NAME_ASCENDING)
105 public class HttpEntryTest extends AAISetup {
107 @MockBean ValidationService validationService;
108 @MockBean NotificationService notificationService;
110 protected static final MediaType APPLICATION_JSON = MediaType.valueOf("application/json");
112 private static final Set<Integer> VALID_HTTP_STATUS_CODES = new HashSet<>();
115 VALID_HTTP_STATUS_CODES.add(200);
116 VALID_HTTP_STATUS_CODES.add(201);
117 VALID_HTTP_STATUS_CODES.add(204);
120 @Parameterized.Parameter(value = 0)
121 public QueryStyle queryStyle;
124 * TODO Change the HttpEntry instances accoringly
126 @Parameterized.Parameters(name = "QueryStyle.{0}")
127 public static Collection<Object[]> data() {
128 return Arrays.asList(new Object[][] { { QueryStyle.TRAVERSAL }, { QueryStyle.TRAVERSAL_URI } });
131 private Loader loader;
132 private TransactionalGraphEngine dbEngine;
133 private GraphTraversalSource traversal;
135 private HttpHeaders httpHeaders;
137 private UriInfo uriInfo;
139 private MultivaluedMap<String, String> headersMultiMap;
140 private MultivaluedMap<String, String> queryParameters;
142 private List<String> aaiRequestContextList;
144 private List<MediaType> outputMediaTypes;
146 ObjectMapper mapper = new ObjectMapper();
149 public void setup() {
151 httpHeaders = Mockito.mock(HttpHeaders.class);
152 uriInfo = Mockito.mock(UriInfo.class);
154 headersMultiMap = new MultivaluedHashMap<>();
155 queryParameters = Mockito.spy(new MultivaluedHashMap<>());
157 headersMultiMap.add("X-FromAppId", "JUNIT");
158 headersMultiMap.add("X-TransactionId", UUID.randomUUID().toString());
159 headersMultiMap.add("Real-Time", "true");
160 headersMultiMap.add("Accept", "application/json");
161 headersMultiMap.add("aai-request-context", "");
163 outputMediaTypes = new ArrayList<>();
164 outputMediaTypes.add(APPLICATION_JSON);
166 aaiRequestContextList = new ArrayList<>();
167 aaiRequestContextList.add("");
169 traversalHttpEntry.setHttpEntryProperties(schemaVersions.getDefaultVersion());
170 loader = traversalHttpEntry.getLoader();
171 dbEngine = traversalHttpEntry.getDbEngine();
172 traversal = dbEngine.tx().traversal();
174 when(httpHeaders.getAcceptableMediaTypes()).thenReturn(outputMediaTypes);
175 when(httpHeaders.getRequestHeaders()).thenReturn(headersMultiMap);
177 when(httpHeaders.getRequestHeader("aai-request-context")).thenReturn(aaiRequestContextList);
179 when(uriInfo.getQueryParameters()).thenReturn(queryParameters);
180 when(uriInfo.getQueryParameters(false)).thenReturn(queryParameters);
182 // TODO - Check if this is valid since RemoveDME2QueryParameters seems to be
184 Mockito.doReturn(null).when(queryParameters).remove(any());
186 when(httpHeaders.getMediaType()).thenReturn(APPLICATION_JSON);
190 public void rollback() {
195 public void thatObjectCanBeRetrieved() throws UnsupportedEncodingException, AAIException {
196 String uri = "/cloud-infrastructure/pservers/pserver/theHostname";
198 .property("aai-node-type", "pserver")
199 .property("hostname", "theHostname")
200 .property("equip-type", "theEquipType")
201 .property(AAIProperties.AAI_URI, uri)
204 JSONObject expectedResponseBody = new JSONObject()
205 .put("hostname", "theHostname")
206 .put("equip-type", "theEquipType");
207 Response response = doRequest(traversalHttpEntry, loader, dbEngine, HttpMethod.GET, uri);
208 JSONObject actualResponseBody = new JSONObject(response.getEntity().toString());
210 JSONAssert.assertEquals(expectedResponseBody, actualResponseBody, JSONCompareMode.NON_EXTENSIBLE);
211 assertEquals("Expected the pserver to be returned", 200, response.getStatus());
212 verify(notificationService, times(1)).generateEvents(any(), anyInt(), any(), any(), any(), any(), any(), any());
216 public void thatObjectsCanBeRetrieved() throws UnsupportedEncodingException, AAIException {
217 String uri = "/cloud-infrastructure/pservers/pserver/theHostname";
219 .property("aai-node-type", "pserver")
220 .property("hostname", "theHostname")
221 .property("equip-type", "theEquipType")
222 .property(AAIProperties.AAI_URI, uri)
225 .property("aai-node-type", "pserver")
226 .property("hostname", "theHostname2")
227 .property("equip-type", "theEquipType2")
228 .property(AAIProperties.AAI_URI, uri + "2")
231 JSONObject expectedResponseBody = new JSONObject();
232 JSONObject pserver1 = new JSONObject()
233 .put("hostname", "theHostname")
234 .put("equip-type", "theEquipType");
235 JSONObject pserver2 = new JSONObject()
236 .put("hostname", "theHostname2")
237 .put("equip-type", "theEquipType2");
238 expectedResponseBody.put("pserver", new JSONArray()
242 uri = "/cloud-infrastructure/pservers";
243 Response response = doRequest(traversalHttpEntry, loader, dbEngine, HttpMethod.GET, uri);
244 JSONObject actualResponseBody = new JSONObject(response.getEntity().toString());
246 JSONAssert.assertEquals(expectedResponseBody, actualResponseBody, JSONCompareMode.NON_EXTENSIBLE);
247 assertEquals("Expected the pservers to be returned", 200, response.getStatus());
248 verify(notificationService, times(1)).generateEvents(any(), anyInt(), any(), any(), any(), any(), any(), any());
252 public void thatPaginatedObjectsCanBeRetrieved() throws UnsupportedEncodingException, AAIException {
253 String uri = "/cloud-infrastructure/pservers/pserver/theHostname";
255 .property("aai-node-type", "pserver")
256 .property("hostname", "theHostname")
257 .property("equip-type", "theEquipType")
258 .property(AAIProperties.AAI_URI, uri)
261 .property("aai-node-type", "pserver")
262 .property("hostname", "theHostname2")
263 .property("equip-type", "theEquipType2")
264 .property(AAIProperties.AAI_URI, uri + "2")
267 JSONObject expectedResponseBody = new JSONObject();
268 JSONObject pserver1 = new JSONObject()
269 .put("hostname", "theHostname")
270 .put("equip-type", "theEquipType");
271 expectedResponseBody.put("pserver", new JSONArray()
274 uri = "/cloud-infrastructure/pservers";
275 QueryOptions queryOptions = QueryOptions.builder().pageable(new Pageable(1, 1)).build();
276 Response response = doRequest(traversalHttpEntry, loader, dbEngine, HttpMethod.GET, uri, queryOptions);
277 JSONObject actualResponseBody = new JSONObject(response.getEntity().toString());
279 assertNull(response.getHeaderString("total-results"));
280 assertEquals(1, actualResponseBody.getJSONArray("pserver").length());
281 assertEquals("Expected the pservers to be returned", 200, response.getStatus());
282 verify(notificationService, times(1)).generateEvents(any(), anyInt(), any(), any(), any(), any(), any(), any());
284 queryOptions = QueryOptions.builder().pageable(new Pageable(0,5).includeTotalCount()).build();
285 response = doRequest(traversalHttpEntry, loader, dbEngine, HttpMethod.GET, uri, queryOptions);
286 actualResponseBody = new JSONObject(response.getEntity().toString());
287 assertEquals(2, actualResponseBody.getJSONArray("pserver").length());
291 public void thatPaginationWithNoResultsCanBeRetrieved() throws UnsupportedEncodingException, AAIException {
292 String uri = "/cloud-infrastructure/pservers/pserver/theHostname";
294 uri = "/cloud-infrastructure/pservers";
295 QueryOptions queryOptions = QueryOptions.builder().pageable(new Pageable(0, 1)).build();
296 Response response = doRequest(traversalHttpEntry, loader, dbEngine, HttpMethod.GET, uri, queryOptions);
298 assertTrue(response.getEntity().toString().contains("Node Not Found:No Node of type pserver found at: /cloud-infrastructure/pservers"));
299 assertEquals(HttpStatus.NOT_FOUND.value(), response.getStatus());
301 queryOptions = QueryOptions.builder().pageable(new Pageable(0,1).includeTotalCount()).build();
302 response = doRequest(traversalHttpEntry, loader, dbEngine, HttpMethod.GET, uri, queryOptions);
304 assertTrue( response.getEntity().toString().contains("Node Not Found:No Node of type pserver found at: /cloud-infrastructure/pservers"));
305 assertEquals(HttpStatus.NOT_FOUND.value(), response.getStatus());
306 verify(notificationService, never()).generateEvents(any(), anyInt(), any(), any(), any(), any(), any(), any());
311 public void thatPagationResultWithTotalCountCanBeRetrieved() throws UnsupportedEncodingException, AAIException {
312 String uri = "/cloud-infrastructure/pservers/pserver/theHostname";
314 .property("aai-node-type", "pserver")
315 .property("hostname", "theHostname")
316 .property("equip-type", "theEquipType")
317 .property(AAIProperties.AAI_URI, uri)
320 .property("aai-node-type", "pserver")
321 .property("hostname", "theHostname2")
322 .property("equip-type", "theEquipType2")
323 .property(AAIProperties.AAI_URI, uri + "2")
326 JSONObject expectedResponseBody = new JSONObject();
327 JSONObject pserver1 = new JSONObject()
328 .put("hostname", "theHostname")
329 .put("equip-type", "theEquipType");
330 expectedResponseBody.put("pserver", new JSONArray()
333 uri = "/cloud-infrastructure/pservers";
334 QueryOptions queryOptions = QueryOptions.builder().pageable(new Pageable(1, 1).includeTotalCount()).build();
335 Response response = doRequest(traversalHttpEntry, loader, dbEngine, HttpMethod.GET, uri, queryOptions);
336 JSONObject actualResponseBody = new JSONObject(response.getEntity().toString());
337 String totalCount = response.getHeaderString("total-results");
338 String totalPages = response.getHeaderString("total-pages");
340 assertEquals(2, Integer.parseInt(totalCount));
341 assertEquals(2, Integer.parseInt(totalPages));
342 assertEquals(1, actualResponseBody.getJSONArray("pserver").length());
343 assertEquals("Expected the pservers to be returned", 200, response.getStatus());
344 verify(notificationService, times(1)).generateEvents(any(), anyInt(), any(), any(), any(), any(), any(), any());
346 queryOptions = QueryOptions.builder().pageable(new Pageable(0, 2)).build();
347 response = doRequest(traversalHttpEntry, loader, dbEngine, HttpMethod.GET, uri, queryOptions);
348 actualResponseBody = new JSONObject(response.getEntity().toString());
349 assertEquals(2, actualResponseBody.getJSONArray("pserver").length());
353 public void thatSortedObjectsCanBeRetrieved() throws UnsupportedEncodingException, AAIException {
354 String uri = "/cloud-infrastructure/pservers/pserver/theHostname";
356 .property("aai-node-type", "pserver")
357 .property("hostname", "theHostname")
358 .property("equip-type", "theEquipType")
359 .property(AAIProperties.AAI_URI, uri)
362 .property("aai-node-type", "pserver")
363 .property("hostname", "theHostname2")
364 .property("equip-type", "theEquipType2")
365 .property(AAIProperties.AAI_URI, uri + "2")
368 JSONObject expectedResponseBody = new JSONObject();
369 JSONObject pserver1 = new JSONObject()
370 .put("hostname", "theHostname")
371 .put("equip-type", "theEquipType");
372 JSONObject pserver2 = new JSONObject()
373 .put("hostname", "theHostname2")
374 .put("equip-type", "theEquipType2");
375 expectedResponseBody.put("pserver", new JSONArray()
376 .put(pserver1).put(pserver2));
379 uri = "/cloud-infrastructure/pservers";
380 QueryOptions queryOptions = QueryOptions.builder().sort(Sort.builder().property("equip-type").direction(Direction.ASC).build()).build();
381 Response response = doRequest(traversalHttpEntry, loader, dbEngine, HttpMethod.GET, uri, queryOptions);
382 JSONObject actualResponseBody = new JSONObject(response.getEntity().toString());
383 assertEquals("theEquipType", actualResponseBody.getJSONArray("pserver").getJSONObject(0).getString("equip-type"));
384 assertEquals("theEquipType2", actualResponseBody.getJSONArray("pserver").getJSONObject(1).getString("equip-type"));
387 queryOptions = QueryOptions.builder().sort(Sort.builder().property("equip-type").direction(Direction.DESC).build()).build();
388 response = doRequest(traversalHttpEntry, loader, dbEngine, HttpMethod.GET, uri, queryOptions);
389 actualResponseBody = new JSONObject(response.getEntity().toString());
390 assertEquals("theEquipType2", actualResponseBody.getJSONArray("pserver").getJSONObject(0).getString("equip-type"));
391 assertEquals("theEquipType", actualResponseBody.getJSONArray("pserver").getJSONObject(1).getString("equip-type"));
395 public void thatObjectsCanNotBeFound() throws UnsupportedEncodingException, AAIException {
396 String uri = "/cloud-infrastructure/pservers/pserver/junit-test2";
398 Response response = doRequest(traversalHttpEntry, loader, dbEngine, HttpMethod.GET, uri);
399 assertEquals("The pserver is not found", 404, response.getStatus());
400 verify(notificationService, never()).generateEvents(any(), anyInt(), any(), any(), any(), any(), any(), any());
404 public void thatObjectCanBeCreatedViaPUT() throws UnsupportedEncodingException, AAIException {
405 String uri = "/cloud-infrastructure/pservers/pserver/theHostname";
406 String requestBody = new JSONObject().put("hostname", "theHostname").toString();
408 Response response = doRequest(traversalHttpEntry, loader, dbEngine, HttpMethod.PUT, uri, requestBody);
409 assertEquals("Expecting the pserver to be created", 201, response.getStatus());
410 verify(notificationService, times(1)).generateEvents(any(), anyInt(), any(), any(), any(), any(), any(), any());
414 public void thatObjectCreationFailsWhenResourceVersionIsProvided()
415 throws UnsupportedEncodingException, AAIException, JsonMappingException, JsonProcessingException {
416 String uri = "/cloud-infrastructure/pservers/pserver/theHostname";
417 String requestBody = new JSONObject()
418 .put("hostname", "theHostname")
419 .put("resource-version", "123")
422 Response response = doRequest(traversalHttpEntry, loader, dbEngine, HttpMethod.PUT, uri, requestBody);
423 ErrorResponse errorResponseEntity = mapper.readValue(response.getEntity().toString(), ErrorResponse.class);
424 assertEquals("Expecting the pserver to be created", 412, response.getStatus());
426 "Resource version specified on create:resource-version passed for create of /cloud-infrastructure/pservers/pserver/theHostname",
427 errorResponseEntity.getRequestError().getServiceException().getVariables().get(2));
428 verify(notificationService, never()).generateEvents(any(), anyInt(), any(), any(), any(), any(), any(), any());
432 public void thatObjectCanBeUpdatedViaPUT() throws UnsupportedEncodingException, AAIException {
433 String uri = "/cloud-infrastructure/pservers/pserver/theHostname";
435 .property("aai-node-type", "pserver")
436 .property("hostname", "theHostname")
437 .property("number-of-cpus", "10")
438 .property(AAIProperties.AAI_URI, uri)
439 .property(AAIProperties.RESOURCE_VERSION, "123")
441 String requestBody = new JSONObject()
442 .put("hostname", "updatedHostname")
443 .put("resource-version", "123")
446 Response response = doRequest(traversalHttpEntry, loader, dbEngine, HttpMethod.PUT, uri, requestBody);
447 assertEquals("Expecting the pserver to be updated", 200, response.getStatus());
448 assertTrue("That old properties are removed",
449 traversal.V().has("hostname", "updatedHostname").hasNot("number-of-cpus").hasNext());
450 verify(notificationService, times(1)).generateEvents(any(), anyInt(), any(), any(), any(), any(), any(), any());
454 public void thatUpdateFailsWhenResourceVersionsMismatch()
455 throws UnsupportedEncodingException, AAIException, JsonMappingException, JsonProcessingException {
456 String uri = "/cloud-infrastructure/pservers/pserver/theHostname";
458 .property("aai-node-type", "pserver")
459 .property("hostname", "theHostname")
460 .property(AAIProperties.AAI_URI, uri)
461 .property(AAIProperties.RESOURCE_VERSION, "123")
463 String requestBody = new JSONObject()
464 .put("hostname", "updatedHostname")
465 .put("resource-version", "456")
468 Response response = doRequest(traversalHttpEntry, loader, dbEngine, HttpMethod.PUT, uri, requestBody);
469 ErrorResponse errorResponseEntity = mapper.readValue(response.getEntity().toString(), ErrorResponse.class);
470 assertEquals("Expecting the update to fail", 412, response.getStatus());
472 "Precondition Failed:resource-version MISMATCH for update of /cloud-infrastructure/pservers/pserver/updatedHostname",
473 errorResponseEntity.getRequestError().getServiceException().getVariables().get(2));
474 verify(notificationService, never()).generateEvents(any(), anyInt(), any(), any(), any(), any(), any(), any());
478 public void thatUpdateFailsWhenResourceVersionIsNotProvided()
479 throws UnsupportedEncodingException, AAIException, JsonMappingException, JsonProcessingException {
480 String uri = "/cloud-infrastructure/pservers/pserver/theHostname";
482 .property("aai-node-type", "pserver")
483 .property("hostname", "theHostname")
484 .property("in-maint", "false")
485 .property(AAIProperties.AAI_URI, uri)
488 String requestBody = new JSONObject()
489 .put("hostname", "theHostname")
490 .put("is-maint", "true")
493 doRequest(traversalHttpEntry, loader, dbEngine, HttpMethod.PUT, uri, requestBody);
494 Response response = doRequest(traversalHttpEntry, loader, dbEngine, HttpMethod.PUT, uri, requestBody);
495 ErrorResponse errorResponseEntity = mapper.readValue(response.getEntity().toString(), ErrorResponse.class);
496 assertEquals("Request should fail when no resource-version is provided", 412, response.getStatus());
498 "Precondition Required:resource-version not passed for update of /cloud-infrastructure/pservers/pserver/theHostname",
499 errorResponseEntity.getRequestError().getServiceException().getVariables().get(2));
503 public void thatCreateViaPUTAddsRelationshipsToExistingObjects() throws UnsupportedEncodingException, AAIException {
505 .property("aai-node-type", "pserver")
506 .property("hostname", "hostname")
507 .property(AAIProperties.AAI_URI, "/cloud-infrastructure/pservers/pserver/hostname")
509 String uri = "/cloud-infrastructure/pservers/pserver/hostname/p-interfaces/p-interface/p1";
510 String requestBody = new JSONObject().put("interface-name", "p1").toString();
512 Response response = doRequest(traversalHttpEntry, loader, dbEngine, HttpMethod.PUT, uri, requestBody);
513 assertEquals("response is successful", 201, response.getStatus());
514 assertTrue("p-interface was created",
515 traversal.V().has("aai-node-type", "p-interface").has("interface-name", "p1").hasNext());
516 assertTrue("p-interface has outgoing edge to p-server",
517 traversal.V().has("aai-node-type", "p-interface").has("aai-uri", uri).has("interface-name", "p1")
518 .out("tosca.relationships.network.BindsTo").has("aai-node-type", "pserver")
519 .has("hostname", "hostname").hasNext());
520 verify(notificationService, times(1)).generateEvents(any(), anyInt(), any(), any(), any(), any(), any(), any());
524 public void thatObjectsCanBePatched() throws UnsupportedEncodingException, AAIException {
525 String uri = "/cloud-infrastructure/pservers/pserver/the-hostname";
527 .property("aai-node-type", "pserver")
528 .property("hostname", "the-hostname")
529 .property("equip-type", "the-equip-type")
530 .property(AAIProperties.AAI_URI, uri)
532 String requestBody = new JSONObject()
533 .put("hostname", "new-hostname")
535 Response response = doRequest(traversalHttpEntry, loader, dbEngine, HttpMethod.MERGE_PATCH, uri, requestBody);
536 assertEquals("Expected the pserver to be updated", 200, response.getStatus());
537 assertTrue("object should be updated while keeping old properties",
538 traversal.V().has("aai-node-type", "pserver").has("hostname", "new-hostname")
539 .has("equip-type", "the-equip-type").hasNext());
540 verify(notificationService, times(1)).generateEvents(any(), anyInt(), any(), any(), any(), any(), any(), any());
544 public void thatObjectsCanBeDeleted() throws UnsupportedEncodingException, AAIException {
545 String uri = "/cloud-infrastructure/pservers/pserver/the-hostname";
546 String resourceVersion = "123";
548 .property("aai-node-type", "pserver")
549 .property("hostname", "the-hostname")
550 .property(AAIProperties.AAI_URI, uri)
551 .property(AAIProperties.RESOURCE_VERSION, resourceVersion)
553 assertEquals("Expecting a No Content response", 204,
554 doDelete(resourceVersion, uri, "pserver").getStatus());
555 assertTrue("Expecting the pserver to be deleted",
556 !traversal.V().has("aai-node-type", "pserver").has("hostname", "the-hostname").hasNext());
557 verify(notificationService, times(1)).generateEvents(any(), anyInt(), any(), any(), any(), any(), any(), any());
561 public void thatRelationshipCanBeCreated() throws UnsupportedEncodingException, AAIException {
562 String uri = "/cloud-infrastructure/pservers/pserver/edge-test-pserver";
564 .property("aai-node-type", "pserver")
565 .property("hostname", "edge-test-pserver")
566 .property(AAIProperties.AAI_URI, uri)
567 .property(AAIProperties.RESOURCE_VERSION, "123")
569 uri = "/cloud-infrastructure/complexes/complex/edge-test-complex";
571 .property("aai-node-type", "complex")
572 .property("physical-location-id", "edge-test-complex")
573 .property("physical-location-type", "AAIDefault")
574 .property("street1", "AAIDefault")
575 .property("city", "AAIDefault")
576 .property("postal-code", "07748")
577 .property("country", "USA")
578 .property("region", "US")
579 .property(AAIProperties.AAI_URI, uri)
580 .property(AAIProperties.RESOURCE_VERSION, "234")
583 uri = "/cloud-infrastructure/complexes/complex/edge-test-complex/relationship-list/relationship";
584 String requestBody = new JSONObject()
585 .put("related-to", "pserver")
587 String.format("/aai/%s/cloud-infrastructure/pservers/pserver/edge-test-pserver",
588 schemaVersions.getDefaultVersion().toString()))
589 .put("relationship-label", "org.onap.relationships.inventory.LocatedIn")
592 Response response = doRequest(traversalHttpEntry, loader, dbEngine, HttpMethod.PUT_EDGE, uri, requestBody);
593 assertEquals("Expected the pserver relationship to be created", 200, response.getStatus());
594 GraphTraversal<Vertex, Vertex> vertexQuery = traversal.V()
595 .has("aai-node-type", "complex")
596 .has("physical-location-id", "edge-test-complex")
597 .in("org.onap.relationships.inventory.LocatedIn")
598 .has("aai-node-type", "pserver")
599 .has("hostname", "edge-test-pserver");
600 GraphTraversal<Edge, Edge> edgeQuery = traversal.E()
601 .has(EdgeField.PRIVATE.toString(), "false")
602 .has(EdgeProperty.CONTAINS.toString(), NONE.toString())
603 .has(EdgeProperty.DELETE_OTHER_V.toString(), NONE.toString())
604 .has(EdgeProperty.PREVENT_DELETE.toString(), "IN");
605 assertTrue("p-server has incoming edge from complex", vertexQuery.hasNext());
606 assertTrue("Created Edge has expected properties", edgeQuery.hasNext());
607 verify(notificationService, times(1)).generateEvents(any(), anyInt(), any(), any(), any(), any(), any(), any());
611 public void thatRelationshipCanNotBeCreatedEdgeMultiplicity()
612 throws UnsupportedEncodingException, AAIException, JsonMappingException, JsonProcessingException {
613 String uri = "/cloud-infrastructure/pservers/pserver/httpEntryTest-pserver-01";
616 .property("aai-node-type", "pserver")
617 .property("hostname", "httpEntryTest-pserver-01")
618 .property(AAIProperties.AAI_URI, uri)
619 .property(AAIProperties.RESOURCE_VERSION, "123")
622 .property("aai-node-type", "complex")
623 .property("physical-location-id", "httpEntryTest-complex-01")
624 .property("physical-location-type", "AAIDefault")
625 .property("street1", "AAIDefault")
626 .property("city", "AAIDefault")
627 .property("postal-code", "07748")
628 .property("country", "USA")
629 .property("region", "US")
630 .property(AAIProperties.AAI_URI, "/cloud-infrastructure/complexes/complex/httpEntryTest-complex-01")
631 .property(AAIProperties.RESOURCE_VERSION, "234")
633 // edge between pserver and complex
634 .addE("org.onap.relationships.inventory.LocatedIn").from("v1").to("v2")
638 uri = "/cloud-infrastructure/pservers/pserver/httpEntryTest-pserver-01/relationship-list/relationship";
639 String requestBody = new JSONObject()
640 .put("related-to", "complex")
642 String.format("/aai/%s/cloud-infrastructure/complexes/complex/httpEntryTest-complex-01",
643 schemaVersions.getDefaultVersion().toString()))
644 .put("relationship-label", "org.onap.relationships.inventory.LocatedIn")
646 Response response = doRequest(traversalHttpEntry, loader, dbEngine, HttpMethod.PUT_EDGE, uri, requestBody);
647 ServiceException serviceException = mapper.readValue(response.getEntity().toString(), ErrorResponse.class)
648 .getRequestError().getServiceException();
650 assertEquals("Expected the response code to be Bad Request", 400, response.getStatus());
651 assertEquals("ERR.5.4.6140", serviceException.getVariables().get(3));
653 "Edge multiplicity violated:multiplicity rule violated: only one edge can exist with label: org.onap.relationships.inventory.LocatedIn between pserver and complex",
654 serviceException.getVariables().get(2));
658 public void putEdgeWrongLabelTest()
659 throws UnsupportedEncodingException, AAIException, JsonMappingException, JsonProcessingException {
660 String uri = "/cloud-infrastructure/pservers/pserver/edge-test-pserver";
662 .property("aai-node-type", "pserver")
663 .property("hostname", "edge-test-pserver")
664 .property(AAIProperties.AAI_URI, uri)
665 .property(AAIProperties.RESOURCE_VERSION, "123")
667 uri = "/cloud-infrastructure/complexes/complex/edge-test-complex";
669 .property("aai-node-type", "complex")
670 .property("physical-location-id", "edge-test-complex")
671 .property("physical-location-type", "AAIDefault")
672 .property("street1", "AAIDefault")
673 .property("city", "AAIDefault")
674 .property("postal-code", "07748")
675 .property("country", "USA")
676 .property("region", "US")
677 .property(AAIProperties.AAI_URI, uri)
678 .property(AAIProperties.RESOURCE_VERSION, "234")
681 uri = "/cloud-infrastructure/complexes/complex/edge-test-complex/relationship-list/relationship";
682 String requestBody = new JSONObject()
683 .put("related-to", "pserver")
685 String.format("/aai/%s/cloud-infrastructure/pservers/pserver/edge-test-pserver",
686 schemaVersions.getDefaultVersion().toString()))
687 .put("relationship-label", "does.not.exist")
690 Response response = doRequest(traversalHttpEntry, loader, dbEngine, HttpMethod.PUT_EDGE, uri, requestBody);
691 ServiceException serviceException = mapper.readValue(response.getEntity().toString(), ErrorResponse.class)
692 .getRequestError().getServiceException();
694 assertEquals("Expected the pserver to be created", 400, response.getStatus());
695 assertEquals("ERR.5.4.6107", serviceException.getVariables().get(3));
697 "Required Edge-property not found in input data:org.onap.aai.edges.exceptions.EdgeRuleNotFoundException: No rule found for EdgeRuleQuery with filter params node type: complex, node type: pserver, label: does.not.exist, type: COUSIN, isPrivate: false.",
698 serviceException.getVariables().get(2));
702 public void thatObjectsCanBeRetrievedInPathedResponseFormat() throws UnsupportedEncodingException, AAIException {
705 .property("aai-node-type", "pserver")
706 .property("hostname", "pserver-1")
707 .property(AAIProperties.AAI_URI, "/cloud-infrastructure/pservers/pserver/pserver-1")
708 .property(AAIProperties.RESOURCE_VERSION, "123")
710 .property("aai-node-type", "pserver")
711 .property("hostname", "pserver-2")
712 .property(AAIProperties.AAI_URI, "/cloud-infrastructure/pservers/pserver/pserver-2")
713 .property(AAIProperties.RESOURCE_VERSION, "234")
716 queryParameters.add("format", "pathed");
717 String requestBody = "";
718 Response response = doRequest(traversalHttpEntry, loader, dbEngine, HttpMethod.GET,
719 "/cloud-infrastructure/pservers");
720 queryParameters.remove("format");
722 String responseEntity = response.getEntity().toString();
723 assertEquals("Expected get to succeed", 200, response.getStatus());
724 assertThat(responseEntity, containsString("/cloud-infrastructure/pservers/pserver/pserver-1"));
725 assertThat(responseEntity, containsString("/cloud-infrastructure/pservers/pserver/pserver-2"));
726 verify(notificationService, times(1)).generateEvents(any(), anyInt(), any(), any(), any(), any(), any(), any());
730 public void thatRelatedObjectsCanBeRetrieved() throws UnsupportedEncodingException, AAIException {
731 String uri = "/cloud-infrastructure/pservers/pserver/related-to-pserver";
734 .property("aai-node-type", "pserver")
735 .property("hostname", "related-to-pserver")
736 .property(AAIProperties.AAI_URI, uri)
737 .property(AAIProperties.RESOURCE_VERSION, "123")
740 .property("aai-node-type", "complex")
741 .property("physical-location-id", "related-to-complex")
742 .property("physical-location-type", "AAIDefault")
743 .property("street1", "AAIDefault")
744 .property("city", "AAIDefault")
745 .property("postal-code", "07748")
746 .property("country", "USA")
747 .property("region", "US")
748 .property(AAIProperties.AAI_URI, "/cloud-infrastructure/complexes/complex/related-to-complex")
749 .property(AAIProperties.RESOURCE_VERSION, "234")
751 // edge between pserver and complex
752 .addE("org.onap.relationships.inventory.LocatedIn").from("v1").to("v2")
755 uri = "/cloud-infrastructure/complexes/complex/related-to-complex/related-to/pservers";
756 Response response = doRequest(traversalHttpEntry, loader, dbEngine, HttpMethod.GET, uri);
758 assertEquals("Expected the response to be successful", 200, response.getStatus());
759 assertThat("Related pserver is returned", response.getEntity().toString(),
760 containsString("\"hostname\":\"related-to-pserver\""));
761 verify(notificationService, times(1)).generateEvents(any(), anyInt(), any(), any(), any(), any(), any(), any());
766 public void getAbstractTest() throws UnsupportedEncodingException, AAIException {
767 String uri = "/cloud-infrastructure/pservers/pserver/abstract-pserver";
770 .property("aai-node-type", "pserver")
771 .property("hostname", "abstract-pserver")
772 .property(AAIProperties.AAI_URI, uri)
773 .property(AAIProperties.RESOURCE_VERSION, "123")
775 .addV() // generic-vnf
776 .property("aai-node-type", "generic-vnf")
777 .property("vnf-id", "abstract-generic-vnf")
778 .property("vnf-name", "the-vnf-name")
779 .property(AAIProperties.AAI_URI, "/network/generic-vnfs/generic-vnf/abstract-generic-vnf")
780 .property(AAIProperties.RESOURCE_VERSION, "234")
782 // edge between pserver and generic-vnf
783 .addE("tosca.relationships.HostedOn").from("v2").to("v1")
786 uri = "/network/generic-vnfs/generic-vnf/abstract-generic-vnf/related-to/pservers";
787 Response response = doRequest(traversalHttpEntry, loader, dbEngine, HttpMethod.GET, uri);
788 assertThat("Related to pserver is returned.", response.getEntity().toString(),
789 containsString("\"hostname\":\"abstract-pserver\""));
790 verify(notificationService, times(1)).generateEvents(any(), anyInt(), any(), any(), any(), any(), any(), any());
794 public void getRelationshipListTest()
795 throws UnsupportedEncodingException, AAIException, JsonMappingException, JsonProcessingException {
796 String uri = "/cloud-infrastructure/pservers/pserver/related-to-pserver";
799 .property("aai-node-type", "pserver")
800 .property("hostname", "related-to-pserver")
801 .property(AAIProperties.AAI_URI, uri)
802 .property(AAIProperties.RESOURCE_VERSION, "123")
805 .property("aai-node-type", "complex")
806 .property("physical-location-id", "related-to-complex")
807 .property("physical-location-type", "AAIDefault")
808 .property("street1", "AAIDefault")
809 .property("city", "AAIDefault")
810 .property("postal-code", "07748")
811 .property("country", "USA")
812 .property("region", "US")
813 .property(AAIProperties.AAI_URI, "/cloud-infrastructure/complexes/complex/related-to-complex")
814 .property(AAIProperties.RESOURCE_VERSION, "234")
816 // edge between pserver and complex
817 .addE("org.onap.relationships.inventory.LocatedIn").from("v1").to("v2")
818 // these properties are required when finding related edges
819 .property(EdgeProperty.CONTAINS.toString(), NONE.toString())
820 .property(EdgeField.PRIVATE.toString(), "false")
824 uri = "/cloud-infrastructure/pservers/pserver/related-to-pserver";
825 Response response = doRequest(traversalHttpEntry, loader, dbEngine, HttpMethod.GET_RELATIONSHIP, uri);
826 Relationship[] relationships = mapper.readValue(response.getEntity().toString(), RelationshipWrapper.class)
829 assertEquals("complex", relationships[0].getRelatedTo());
830 assertEquals("org.onap.relationships.inventory.LocatedIn", relationships[0].getRelationshipLabel());
831 assertEquals("/aai/v14/cloud-infrastructure/complexes/complex/related-to-complex",
832 relationships[0].getRelatedLink());
833 assertEquals("complex.physical-location-id", relationships[0].getRelationshipData()[0].getRelationshipKey());
834 assertEquals("related-to-complex", relationships[0].getRelationshipData()[0].getRelationshipValue());
835 verify(notificationService, times(1)).generateEvents(any(), anyInt(), any(), any(), any(), any(), any(), any());
839 public void getRelationshipListTestWithFormatSimple() throws UnsupportedEncodingException, AAIException {
840 String uri = "/cloud-infrastructure/pservers/pserver/related-to-pserver";
843 .property("aai-node-type", "pserver")
844 .property("hostname", "related-to-pserver")
845 .property(AAIProperties.AAI_URI, uri)
846 .property(AAIProperties.RESOURCE_VERSION, "123")
849 .property("aai-node-type", "complex")
850 .property("physical-location-id", "related-to-complex")
851 .property("physical-location-type", "AAIDefault")
852 .property("street1", "AAIDefault")
853 .property("city", "AAIDefault")
854 .property("postal-code", "07748")
855 .property("country", "USA")
856 .property("region", "US")
857 .property(AAIProperties.AAI_URI, "/cloud-infrastructure/complexes/complex/related-to-complex")
858 .property(AAIProperties.RESOURCE_VERSION, "234")
860 // edge between pserver and complex
861 .addE("org.onap.relationships.inventory.LocatedIn").from("v1").to("v2")
862 // these properties are required when finding related edges
863 .property(EdgeProperty.CONTAINS.toString(), NONE.toString())
864 .property(EdgeField.PRIVATE.toString(), "false")
868 uri = "/cloud-infrastructure/pservers/pserver/related-to-pserver";
869 queryParameters.add("format", "resource");
870 Response response = doRequest(traversalHttpEntry, loader, dbEngine, HttpMethod.GET_RELATIONSHIP, uri);
872 JSONObject actualResponseBody = new JSONObject(response.getEntity().toString());
874 // Define the expected response
875 JSONObject relationshipData = new JSONObject().put("relationship-key", "complex.physical-location-id")
876 .put("relationship-value", "related-to-complex");
877 JSONObject relationship = new JSONObject()
878 .put("related-to", "complex")
879 .put("relationship-label", "org.onap.relationships.inventory.LocatedIn")
881 String.format("/aai/%s/cloud-infrastructure/complexes/complex/related-to-complex",
882 schemaVersions.getDefaultVersion()))
883 .put("relationship-data", new JSONArray().put(relationshipData));
884 JSONObject pserver = new JSONObject()
885 .put("hostname", "related-to-pserver")
886 .put("resource-version", "123")
887 .put("relationship-list", new JSONObject().put("relationship", new JSONArray().put(relationship)));
888 JSONObject expectedResponseBody = new JSONObject()
889 .put("results", new JSONArray().put(new JSONObject().put("pserver", pserver)));
891 JSONAssert.assertEquals(expectedResponseBody, actualResponseBody, JSONCompareMode.NON_EXTENSIBLE);
892 queryParameters.remove("format");
893 verify(notificationService, times(1)).generateEvents(any(), anyInt(), any(), any(), any(), any(), any(), any());
896 private Response doRequest(HttpEntry httpEntry, Loader loader, TransactionalGraphEngine dbEngine, HttpMethod method,
897 String uri) throws UnsupportedEncodingException, AAIException {
898 return doRequest(httpEntry, loader, dbEngine, method, uri, null, null);
901 private Response doRequest(HttpEntry httpEntry, Loader loader, TransactionalGraphEngine dbEngine, HttpMethod method,
902 String uri, String requestBody) throws UnsupportedEncodingException, AAIException {
903 return doRequest(httpEntry, loader, dbEngine, method, uri, requestBody, null);
905 private Response doRequest(HttpEntry httpEntry, Loader loader, TransactionalGraphEngine dbEngine, HttpMethod method,
906 String uri, QueryOptions queryOptions) throws UnsupportedEncodingException, AAIException {
907 return doRequest(httpEntry, loader, dbEngine, method, uri, null, queryOptions);
910 private Response doRequest(HttpEntry httpEntry, Loader loader, TransactionalGraphEngine dbEngine, HttpMethod method,
911 String uri, String requestBody, QueryOptions queryOptions) throws UnsupportedEncodingException, AAIException {
912 URI uriObject = UriBuilder.fromPath(uri).build();
913 QueryParser uriQuery = dbEngine.getQueryBuilder().createQueryFromURI(uriObject);
915 if (!uriQuery.getContainerType().equals("")) {
916 objType = uriQuery.getContainerType();
918 objType = uriQuery.getResultType();
920 if (uri.endsWith("relationship")) {
921 objType = "relationship";
924 if (method.equals(HttpMethod.GET) || method.equals(HttpMethod.GET_RELATIONSHIP)) {
925 obj = loader.introspectorFromName(objType);
927 obj = loader.unmarshal(objType, requestBody, org.onap.aai.restcore.MediaType.getEnum("application/json"));
930 DBRequest.Builder builder = new DBRequest.Builder(method, uriObject, uriQuery, obj, httpHeaders, uriInfo,
931 "JUNIT-TRANSACTION");
932 DBRequest dbRequest = requestBody != null
933 ? builder.rawRequestContent(requestBody).build()
936 List<DBRequest> dbRequestList = Collections.singletonList(dbRequest);
938 Pair<Boolean, List<Pair<URI, Response>>> responsesTuple = httpEntry.process(dbRequestList, "JUNIT", Collections.emptySet(), true, queryOptions);
939 return responsesTuple.getValue1().get(0).getValue1();
942 private Response doDelete(String resourceVersion, String uri, String nodeType)
943 throws UnsupportedEncodingException, AAIException {
944 queryParameters.add("resource-version", resourceVersion);
946 URI uriObject = UriBuilder.fromPath(uri).build();
948 QueryParser uriQuery = dbEngine.getQueryBuilder().createQueryFromURI(uriObject);
952 Introspector obj = loader.introspectorFromName(nodeType);
954 DBRequest dbRequest = new DBRequest.Builder(HttpMethod.DELETE, uriObject, uriQuery, obj, httpHeaders, uriInfo,
955 "JUNIT-TRANSACTION").rawRequestContent(content).build();
957 Pair<Boolean, List<Pair<URI, Response>>> responsesTuple = traversalHttpEntry.process(Arrays.asList(dbRequest),
959 return responsesTuple.getValue1().get(0).getValue1();
963 public void setDepthTest() throws AAIException {
964 System.setProperty("AJSC_HOME", ".");
965 System.setProperty("BUNDLECONFIG_DIR", "src/main/test/resources");
967 String depthParam = AAIConfig.get("aai.rest.getall.depthparam");
968 traversalHttpEntry.setHttpEntryProperties(schemaVersions.getDefaultVersion());
969 int depth = traversalHttpEntry.setDepth(null, depthParam);
970 assertEquals(AAIProperties.MAXIMUM_DEPTH.intValue(), depth);
974 public void thatEventsAreValidated() throws AAIException, UnsupportedEncodingException {
975 String uri = "/cloud-infrastructure/pservers/pserver/theHostname";
977 .property("aai-node-type", "pserver")
978 .property("hostname", "theHostname")
979 .property("equip-type", "theEquipType")
980 .property(AAIProperties.AAI_URI, uri)
983 JSONObject expectedResponseBody = new JSONObject()
984 .put("hostname", "theHostname")
985 .put("equip-type", "theEquipType");
986 Response response = doRequest(traversalHttpEntry, loader, dbEngine, HttpMethod.GET, uri);
987 JSONObject actualResponseBody = new JSONObject(response.getEntity().toString());
989 JSONAssert.assertEquals(expectedResponseBody, actualResponseBody, JSONCompareMode.NON_EXTENSIBLE);
990 assertEquals("Expected the pserver to be returned", 200, response.getStatus());
991 verify(notificationService, times(1)).generateEvents(any(), anyInt(), any(), any(), any(), any(), any(), any());