Refactor HttpEntryTest
[aai/aai-common.git] / aai-core / src / test / java / org / onap / aai / rest / db / HttpEntryTest.java
1 /**
2  * ============LICENSE_START=======================================================
3  * org.onap.aai
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
12  *
13  *    http://www.apache.org/licenses/LICENSE-2.0
14  *
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=========================================================
21  */
22
23 package org.onap.aai.rest.db;
24
25 import static org.onap.aai.edges.enums.AAIDirection.NONE;
26 import static org.hamcrest.Matchers.containsString;
27 import static org.hamcrest.Matchers.not;
28 import static org.junit.Assert.assertEquals;
29 import static org.junit.Assert.assertFalse;
30 import static org.junit.Assert.assertThat;
31 import static org.junit.Assert.assertTrue;
32 import static org.mockito.ArgumentMatchers.any;
33 import static org.mockito.Mockito.doNothing;
34 import static org.mockito.Mockito.when;
35
36 import com.fasterxml.jackson.core.JsonProcessingException;
37 import com.fasterxml.jackson.databind.JsonMappingException;
38 import com.fasterxml.jackson.databind.ObjectMapper;
39 import com.google.gson.JsonObject;
40 import com.google.gson.JsonParser;
41
42 import java.io.UnsupportedEncodingException;
43 import java.net.URI;
44 import java.util.ArrayList;
45 import java.util.Arrays;
46 import java.util.Collection;
47 import java.util.HashSet;
48 import java.util.List;
49 import java.util.Set;
50 import java.util.UUID;
51
52 import javax.ws.rs.core.HttpHeaders;
53 import javax.ws.rs.core.MediaType;
54 import javax.ws.rs.core.MultivaluedHashMap;
55 import javax.ws.rs.core.MultivaluedMap;
56 import javax.ws.rs.core.Response;
57 import javax.ws.rs.core.UriBuilder;
58 import javax.ws.rs.core.UriInfo;
59
60 import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversal;
61 import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversalSource;
62 import org.apache.tinkerpop.gremlin.structure.Edge;
63 import org.apache.tinkerpop.gremlin.structure.Vertex;
64 import org.javatuples.Pair;
65 import org.json.JSONArray;
66 import org.json.JSONObject;
67 import org.junit.After;
68 import org.junit.Assert;
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.introspection.ModelType;
84 import org.onap.aai.parsers.query.QueryParser;
85 import org.onap.aai.rest.db.responses.ErrorResponse;
86 import org.onap.aai.rest.db.responses.Relationship;
87 import org.onap.aai.rest.db.responses.RelationshipWrapper;
88 import org.onap.aai.rest.db.responses.ServiceException;
89 import org.onap.aai.rest.ueb.UEBNotification;
90 import org.onap.aai.restcore.HttpMethod;
91 import org.onap.aai.serialization.engines.QueryStyle;
92 import org.onap.aai.serialization.engines.TransactionalGraphEngine;
93 import org.onap.aai.util.AAIConfig;
94 import org.skyscreamer.jsonassert.JSONAssert;
95 import org.skyscreamer.jsonassert.JSONCompareMode;
96
97 @RunWith(value = Parameterized.class)
98 @FixMethodOrder(MethodSorters.NAME_ASCENDING)
99 public class HttpEntryTest extends AAISetup {
100
101     protected static final MediaType APPLICATION_JSON = MediaType.valueOf("application/json");
102
103     private static final Set<Integer> VALID_HTTP_STATUS_CODES = new HashSet<>();
104
105     static {
106         VALID_HTTP_STATUS_CODES.add(200);
107         VALID_HTTP_STATUS_CODES.add(201);
108         VALID_HTTP_STATUS_CODES.add(204);
109     }
110
111     @Parameterized.Parameter(value = 0)
112     public QueryStyle queryStyle;
113
114     /*
115      * TODO Change the HttpEntry instances accoringly
116      */
117     @Parameterized.Parameters(name = "QueryStyle.{0}")
118     public static Collection<Object[]> data() {
119         return Arrays.asList(new Object[][] { { QueryStyle.TRAVERSAL }, { QueryStyle.TRAVERSAL_URI } });
120     }
121
122     private Loader loader;
123     private TransactionalGraphEngine dbEngine;
124     private GraphTraversalSource traversal;
125
126     private HttpHeaders httpHeaders;
127
128     private UriInfo uriInfo;
129
130     private MultivaluedMap<String, String> headersMultiMap;
131     private MultivaluedMap<String, String> queryParameters;
132
133     private List<String> aaiRequestContextList;
134
135     private List<MediaType> outputMediaTypes;
136
137     ObjectMapper mapper = new ObjectMapper();
138
139     @Before
140     public void setup() {
141
142         httpHeaders = Mockito.mock(HttpHeaders.class);
143         uriInfo = Mockito.mock(UriInfo.class);
144
145         headersMultiMap = new MultivaluedHashMap<>();
146         queryParameters = Mockito.spy(new MultivaluedHashMap<>());
147
148         headersMultiMap.add("X-FromAppId", "JUNIT");
149         headersMultiMap.add("X-TransactionId", UUID.randomUUID().toString());
150         headersMultiMap.add("Real-Time", "true");
151         headersMultiMap.add("Accept", "application/json");
152         headersMultiMap.add("aai-request-context", "");
153
154         outputMediaTypes = new ArrayList<>();
155         outputMediaTypes.add(APPLICATION_JSON);
156
157         aaiRequestContextList = new ArrayList<>();
158         aaiRequestContextList.add("");
159
160         traversalHttpEntry.setHttpEntryProperties(schemaVersions.getDefaultVersion());
161         loader = traversalHttpEntry.getLoader();
162         dbEngine = traversalHttpEntry.getDbEngine();
163         traversal = dbEngine.tx().traversal();
164
165         when(httpHeaders.getAcceptableMediaTypes()).thenReturn(outputMediaTypes);
166         when(httpHeaders.getRequestHeaders()).thenReturn(headersMultiMap);
167
168         when(httpHeaders.getRequestHeader("aai-request-context")).thenReturn(aaiRequestContextList);
169
170         when(uriInfo.getQueryParameters()).thenReturn(queryParameters);
171         when(uriInfo.getQueryParameters(false)).thenReturn(queryParameters);
172
173         // TODO - Check if this is valid since RemoveDME2QueryParameters seems to be
174         // very unreasonable
175         Mockito.doReturn(null).when(queryParameters).remove(any());
176
177         when(httpHeaders.getMediaType()).thenReturn(APPLICATION_JSON);
178     }
179
180     @After
181     public void rollback() {
182         dbEngine.rollback();
183     }
184
185     @Test
186     public void thatObjectsCanBeRetrieved() throws UnsupportedEncodingException, AAIException {
187         String uri = "/cloud-infrastructure/pservers/pserver/theHostname";
188         traversal.addV()
189                 .property("aai-node-type", "pserver")
190                 .property("hostname", "theHostname")
191                 .property("equip-type", "theEquipType")
192                 .property(AAIProperties.AAI_URI, uri)
193                 .next();
194         String requestBody = new JSONObject()
195                 .put("hostname", "theHostname")
196                 .put("equip-type", "theEquipType")
197                 .toString();
198
199         Response response = doRequest(traversalHttpEntry, loader, dbEngine, HttpMethod.GET, uri, requestBody);
200         assertEquals("Expected the pserver to be returned", 200, response.getStatus());
201     }
202
203     @Test
204     public void thatObjectsCanNotBeFound() throws UnsupportedEncodingException, AAIException {
205         String uri = "/cloud-infrastructure/pservers/pserver/junit-test2";
206         String requestBody = "";
207
208         Response response = doRequest(traversalHttpEntry, loader, dbEngine, HttpMethod.GET, uri, requestBody);
209         assertEquals("The pserver is not found", 404, response.getStatus());
210     }
211
212     @Test
213     public void thatObjectCanBeCreatedViaPUT() throws UnsupportedEncodingException, AAIException {
214         String uri = "/cloud-infrastructure/pservers/pserver/theHostname";
215         String requestBody = new JSONObject().put("hostname", "theHostname").toString();
216
217         Response response = doRequest(traversalHttpEntry, loader, dbEngine, HttpMethod.PUT, uri, requestBody);
218         assertEquals("Expecting the pserver to be created", 201, response.getStatus());
219     }
220
221     @Test
222     public void thatObjectCreationFailsWhenResourceVersionIsProvided()
223             throws UnsupportedEncodingException, AAIException, JsonMappingException, JsonProcessingException {
224         String uri = "/cloud-infrastructure/pservers/pserver/theHostname";
225         String requestBody = new JSONObject()
226                 .put("hostname", "theHostname")
227                 .put("resource-version", "123")
228                 .toString();
229
230         Response response = doRequest(traversalHttpEntry, loader, dbEngine, HttpMethod.PUT, uri, requestBody);
231         ErrorResponse errorResponseEntity = mapper.readValue(response.getEntity().toString(), ErrorResponse.class);
232         assertEquals("Expecting the pserver to be created", 412, response.getStatus());
233         assertEquals(
234                 "Resource version specified on create:resource-version passed for create of /cloud-infrastructure/pservers/pserver/theHostname",
235                 errorResponseEntity.getRequestError().getServiceException().getVariables().get(2));
236     }
237
238     @Test
239     public void thatObjectCanBeUpdatedViaPUT() throws UnsupportedEncodingException, AAIException {
240         String uri = "/cloud-infrastructure/pservers/pserver/theHostname";
241         traversal.addV()
242                 .property("aai-node-type", "pserver")
243                 .property("hostname", "theHostname")
244                 .property("number-of-cpus", "10")
245                 .property(AAIProperties.AAI_URI, uri)
246                 .property(AAIProperties.RESOURCE_VERSION, "123")
247                 .next();
248         String requestBody = new JSONObject()
249                 .put("hostname", "updatedHostname")
250                 .put("resource-version", "123")
251                 .toString();
252
253         Response response = doRequest(traversalHttpEntry, loader, dbEngine, HttpMethod.PUT, uri, requestBody);
254         assertEquals("Expecting the pserver to be updated", 200, response.getStatus());
255         assertTrue("That old properties are removed",
256                 traversal.V().has("hostname", "updatedHostname").hasNot("number-of-cpus").hasNext());
257     }
258
259     @Test
260     public void thatUpdateFailsWhenResourceVersionsMismatch()
261             throws UnsupportedEncodingException, AAIException, JsonMappingException, JsonProcessingException {
262         String uri = "/cloud-infrastructure/pservers/pserver/theHostname";
263         traversal.addV()
264                 .property("aai-node-type", "pserver")
265                 .property("hostname", "theHostname")
266                 .property(AAIProperties.AAI_URI, uri)
267                 .property(AAIProperties.RESOURCE_VERSION, "123")
268                 .next();
269         String requestBody = new JSONObject()
270                 .put("hostname", "updatedHostname")
271                 .put("resource-version", "456")
272                 .toString();
273
274         Response response = doRequest(traversalHttpEntry, loader, dbEngine, HttpMethod.PUT, uri, requestBody);
275         ErrorResponse errorResponseEntity = mapper.readValue(response.getEntity().toString(), ErrorResponse.class);
276         assertEquals("Expecting the update to fail", 412, response.getStatus());
277         assertEquals(
278                 "Precondition Failed:resource-version MISMATCH for update of /cloud-infrastructure/pservers/pserver/updatedHostname",
279                 errorResponseEntity.getRequestError().getServiceException().getVariables().get(2));
280     }
281
282     @Test
283     public void thatUpdateFailsWhenResourceVersionIsNotProvided()
284             throws UnsupportedEncodingException, AAIException, JsonMappingException, JsonProcessingException {
285         String uri = "/cloud-infrastructure/pservers/pserver/theHostname";
286         traversal.addV()
287                 .property("aai-node-type", "pserver")
288                 .property("hostname", "theHostname")
289                 .property("in-maint", "false")
290                 .property(AAIProperties.AAI_URI, uri)
291                 .next();
292
293         String requestBody = new JSONObject()
294                 .put("hostname", "theHostname")
295                 .put("is-maint", "true")
296                 .toString();
297
298         doRequest(traversalHttpEntry, loader, dbEngine, HttpMethod.PUT, uri, requestBody);
299         Response response = doRequest(traversalHttpEntry, loader, dbEngine, HttpMethod.PUT, uri, requestBody);
300         ErrorResponse errorResponseEntity = mapper.readValue(response.getEntity().toString(), ErrorResponse.class);
301         assertEquals("Request should fail when no resource-version is provided", 412, response.getStatus());
302         assertEquals(
303                 "Precondition Required:resource-version not passed for update of /cloud-infrastructure/pservers/pserver/theHostname",
304                 errorResponseEntity.getRequestError().getServiceException().getVariables().get(2));
305     }
306
307     @Test
308     public void thatCreateViaPUTAddsRelationshipsToExistingObjects() throws UnsupportedEncodingException, AAIException {
309         traversal.addV()
310                 .property("aai-node-type", "pserver")
311                 .property("hostname", "hostname")
312                 .property(AAIProperties.AAI_URI, "/cloud-infrastructure/pservers/pserver/hostname")
313                 .next();
314         String uri = "/cloud-infrastructure/pservers/pserver/hostname/p-interfaces/p-interface/p1";
315         String requestBody = new JSONObject().put("interface-name", "p1").toString();
316
317         Response response = doRequest(traversalHttpEntry, loader, dbEngine, HttpMethod.PUT, uri, requestBody);
318         assertEquals("response is successful", 201, response.getStatus());
319         assertTrue("p-interface was created",
320                 traversal.V().has("aai-node-type", "p-interface").has("interface-name", "p1").hasNext());
321         assertTrue("p-interface has outgoing edge to p-server",
322                 traversal.V().has("aai-node-type", "p-interface").has("aai-uri", uri).has("interface-name", "p1")
323                         .out("tosca.relationships.network.BindsTo").has("aai-node-type", "pserver")
324                         .has("hostname", "hostname").hasNext());
325     }
326
327     @Test
328     public void thatObjectsCanBePatched() throws UnsupportedEncodingException, AAIException {
329         String uri = "/cloud-infrastructure/pservers/pserver/the-hostname";
330         traversal.addV()
331                 .property("aai-node-type", "pserver")
332                 .property("hostname", "the-hostname")
333                 .property("equip-type", "the-equip-type")
334                 .property(AAIProperties.AAI_URI, uri)
335                 .next();
336         String requestBody = new JSONObject()
337                 .put("hostname", "new-hostname")
338                 .toString();
339         Response response = doRequest(traversalHttpEntry, loader, dbEngine, HttpMethod.MERGE_PATCH, uri, requestBody);
340         assertEquals("Expected the pserver to be updated", 200, response.getStatus());
341         assertTrue("object should be updated while keeping old properties",
342                 traversal.V().has("aai-node-type", "pserver").has("hostname", "new-hostname")
343                         .has("equip-type", "the-equip-type").hasNext());
344     }
345
346     @Test
347     public void thatObjectsCanBeDeleted() throws UnsupportedEncodingException, AAIException {
348         String uri = "/cloud-infrastructure/pservers/pserver/the-hostname";
349         String resourceVersion = "123";
350         traversal.addV()
351                 .property("aai-node-type", "pserver")
352                 .property("hostname", "the-hostname")
353                 .property(AAIProperties.AAI_URI, uri)
354                 .property(AAIProperties.RESOURCE_VERSION, resourceVersion)
355                 .next();
356         assertEquals("Expecting a No Content response", 204,
357                 doDelete(resourceVersion, uri, "pserver").getStatus());
358         assertTrue("Expecting the pserver to be deleted",
359                 !traversal.V().has("aai-node-type", "pserver").has("hostname", "the-hostname").hasNext());
360     }
361
362     @Test
363     public void thatRelationshipCanBeCreated() throws UnsupportedEncodingException, AAIException {
364         String uri = "/cloud-infrastructure/pservers/pserver/edge-test-pserver";
365         traversal.addV()
366                 .property("aai-node-type", "pserver")
367                 .property("hostname", "edge-test-pserver")
368                 .property(AAIProperties.AAI_URI, uri)
369                 .property(AAIProperties.RESOURCE_VERSION, "123")
370                 .next();
371         uri = "/cloud-infrastructure/complexes/complex/edge-test-complex";
372         traversal.addV()
373                 .property("aai-node-type", "complex")
374                 .property("physical-location-id", "edge-test-complex")
375                 .property("physical-location-type", "AAIDefault")
376                 .property("street1", "AAIDefault")
377                 .property("city", "AAIDefault")
378                 .property("postal-code", "07748")
379                 .property("country", "USA")
380                 .property("region", "US")
381                 .property(AAIProperties.AAI_URI, uri)
382                 .property(AAIProperties.RESOURCE_VERSION, "234")
383                 .next();
384
385         uri = "/cloud-infrastructure/complexes/complex/edge-test-complex/relationship-list/relationship";
386         String requestBody = new JSONObject()
387                 .put("related-to", "pserver")
388                 .put("related-link",
389                         String.format("/aai/%s/cloud-infrastructure/pservers/pserver/edge-test-pserver",
390                                 schemaVersions.getDefaultVersion().toString()))
391                 .put("relationship-label", "org.onap.relationships.inventory.LocatedIn")
392                 .toString();
393
394         Response response = doRequest(traversalHttpEntry, loader, dbEngine, HttpMethod.PUT_EDGE, uri, requestBody);
395         assertEquals("Expected the pserver relationship to be created", 200, response.getStatus());
396         GraphTraversal<Vertex, Vertex> vertexQuery = traversal.V()
397                 .has("aai-node-type", "complex")
398                 .has("physical-location-id", "edge-test-complex")
399                 .in("org.onap.relationships.inventory.LocatedIn")
400                 .has("aai-node-type", "pserver")
401                 .has("hostname", "edge-test-pserver");
402         GraphTraversal<Edge, Edge> edgeQuery = traversal.E()
403                 .has(EdgeField.PRIVATE.toString(), "false")
404                 .has(EdgeProperty.CONTAINS.toString(), NONE.toString())
405                 .has(EdgeProperty.DELETE_OTHER_V.toString(), NONE.toString())
406                 .has(EdgeProperty.PREVENT_DELETE.toString(), "IN");
407         assertTrue("p-server has incoming edge from complex", vertexQuery.hasNext());
408         assertTrue("Created Edge has expected properties", edgeQuery.hasNext());
409     }
410
411     @Test
412     public void thatRelationshipCanNotBeCreatedEdgeMultiplicity()
413             throws UnsupportedEncodingException, AAIException, JsonMappingException, JsonProcessingException {
414         String uri = "/cloud-infrastructure/pservers/pserver/httpEntryTest-pserver-01";
415         traversal
416                 .addV() // pserver
417                 .property("aai-node-type", "pserver")
418                 .property("hostname", "httpEntryTest-pserver-01")
419                 .property(AAIProperties.AAI_URI, uri)
420                 .property(AAIProperties.RESOURCE_VERSION, "123")
421                 .as("v1")
422                 .addV() // complex
423                 .property("aai-node-type", "complex")
424                 .property("physical-location-id", "httpEntryTest-complex-01")
425                 .property("physical-location-type", "AAIDefault")
426                 .property("street1", "AAIDefault")
427                 .property("city", "AAIDefault")
428                 .property("postal-code", "07748")
429                 .property("country", "USA")
430                 .property("region", "US")
431                 .property(AAIProperties.AAI_URI, "/cloud-infrastructure/complexes/complex/httpEntryTest-complex-01")
432                 .property(AAIProperties.RESOURCE_VERSION, "234")
433                 .as("v2")
434                 // edge between pserver and complex
435                 .addE("org.onap.relationships.inventory.LocatedIn").from("v1").to("v2")
436                 .next();
437
438         // Put Relationship
439         uri = "/cloud-infrastructure/pservers/pserver/httpEntryTest-pserver-01/relationship-list/relationship";
440         String requestBody = new JSONObject()
441                 .put("related-to", "complex")
442                 .put("related-link",
443                         String.format("/aai/%s/cloud-infrastructure/complexes/complex/httpEntryTest-complex-01",
444                                 schemaVersions.getDefaultVersion().toString()))
445                 .put("relationship-label", "org.onap.relationships.inventory.LocatedIn")
446                 .toString();
447         Response response = doRequest(traversalHttpEntry, loader, dbEngine, HttpMethod.PUT_EDGE, uri, requestBody);
448         ServiceException serviceException = mapper.readValue(response.getEntity().toString(), ErrorResponse.class)
449                 .getRequestError().getServiceException();
450
451         assertEquals("Expected the response code to be Bad Request", 400, response.getStatus());
452         assertEquals("ERR.5.4.6140", serviceException.getVariables().get(3));
453         assertEquals(
454                 "Edge multiplicity violated:multiplicity rule violated: only one edge can exist with label: org.onap.relationships.inventory.LocatedIn between pserver and complex",
455                 serviceException.getVariables().get(2));
456     }
457
458     @Test
459     public void putEdgeWrongLabelTest()
460             throws UnsupportedEncodingException, AAIException, JsonMappingException, JsonProcessingException {
461         String uri = "/cloud-infrastructure/pservers/pserver/edge-test-pserver";
462         traversal.addV()
463                 .property("aai-node-type", "pserver")
464                 .property("hostname", "edge-test-pserver")
465                 .property(AAIProperties.AAI_URI, uri)
466                 .property(AAIProperties.RESOURCE_VERSION, "123")
467                 .next();
468         uri = "/cloud-infrastructure/complexes/complex/edge-test-complex";
469         traversal.addV()
470                 .property("aai-node-type", "complex")
471                 .property("physical-location-id", "edge-test-complex")
472                 .property("physical-location-type", "AAIDefault")
473                 .property("street1", "AAIDefault")
474                 .property("city", "AAIDefault")
475                 .property("postal-code", "07748")
476                 .property("country", "USA")
477                 .property("region", "US")
478                 .property(AAIProperties.AAI_URI, uri)
479                 .property(AAIProperties.RESOURCE_VERSION, "234")
480                 .next();
481
482         uri = "/cloud-infrastructure/complexes/complex/edge-test-complex/relationship-list/relationship";
483         String requestBody = new JSONObject()
484                 .put("related-to", "pserver")
485                 .put("related-link",
486                         String.format("/aai/%s/cloud-infrastructure/pservers/pserver/edge-test-pserver",
487                                 schemaVersions.getDefaultVersion().toString()))
488                 .put("relationship-label", "does.not.exist")
489                 .toString();
490
491         Response response = doRequest(traversalHttpEntry, loader, dbEngine, HttpMethod.PUT_EDGE, uri, requestBody);
492         ServiceException serviceException = mapper.readValue(response.getEntity().toString(), ErrorResponse.class)
493                 .getRequestError().getServiceException();
494
495         assertEquals("Expected the pserver to be created", 400, response.getStatus());
496         assertEquals("ERR.5.4.6107", serviceException.getVariables().get(3));
497         assertEquals(
498                 "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.",
499                 serviceException.getVariables().get(2));
500     }
501
502     @Test
503     public void thatObjectsCanBeRetrievedInPathedResponseFormat() throws UnsupportedEncodingException, AAIException {
504         traversal
505                 .addV() // pserver
506                 .property("aai-node-type", "pserver")
507                 .property("hostname", "pserver-1")
508                 .property(AAIProperties.AAI_URI, "/cloud-infrastructure/pservers/pserver/pserver-1")
509                 .property(AAIProperties.RESOURCE_VERSION, "123")
510                 .addV() // pserver
511                 .property("aai-node-type", "pserver")
512                 .property("hostname", "pserver-2")
513                 .property(AAIProperties.AAI_URI, "/cloud-infrastructure/pservers/pserver/pserver-2")
514                 .property(AAIProperties.RESOURCE_VERSION, "234")
515                 .next();
516
517         queryParameters.add("format", "pathed");
518         String requestBody = "";
519         Response response = doRequest(traversalHttpEntry, loader, dbEngine, HttpMethod.GET,
520                 "/cloud-infrastructure/pservers", requestBody);
521         queryParameters.remove("format");
522
523         String responseEntity = response.getEntity().toString();
524         assertEquals("Expected get to succeed", 200, response.getStatus());
525         assertThat(responseEntity, containsString("/cloud-infrastructure/pservers/pserver/pserver-1"));
526         assertThat(responseEntity, containsString("/cloud-infrastructure/pservers/pserver/pserver-2"));
527     }
528
529     @Test
530     public void thatRelatedObjectsCanBeRetrieved() throws UnsupportedEncodingException, AAIException {
531         String uri = "/cloud-infrastructure/pservers/pserver/related-to-pserver";
532         traversal
533                 .addV() // pserver
534                 .property("aai-node-type", "pserver")
535                 .property("hostname", "related-to-pserver")
536                 .property(AAIProperties.AAI_URI, uri)
537                 .property(AAIProperties.RESOURCE_VERSION, "123")
538                 .as("v1")
539                 .addV() // complex
540                 .property("aai-node-type", "complex")
541                 .property("physical-location-id", "related-to-complex")
542                 .property("physical-location-type", "AAIDefault")
543                 .property("street1", "AAIDefault")
544                 .property("city", "AAIDefault")
545                 .property("postal-code", "07748")
546                 .property("country", "USA")
547                 .property("region", "US")
548                 .property(AAIProperties.AAI_URI, "/cloud-infrastructure/complexes/complex/related-to-complex")
549                 .property(AAIProperties.RESOURCE_VERSION, "234")
550                 .as("v2")
551                 // edge between pserver and complex
552                 .addE("org.onap.relationships.inventory.LocatedIn").from("v1").to("v2")
553                 .next();
554
555         uri = "/cloud-infrastructure/complexes/complex/related-to-complex/related-to/pservers";
556         String responseBody = "";
557         Response response = doRequest(traversalHttpEntry, loader, dbEngine, HttpMethod.GET, uri, responseBody);
558
559         assertEquals("Expected the response to be successful", 200, response.getStatus());
560         assertThat("Related pserver is returned", response.getEntity().toString(),
561                 containsString("\"hostname\":\"related-to-pserver\""));
562
563     }
564
565     @Test
566     public void getAbstractTest() throws UnsupportedEncodingException, AAIException {
567         String uri = "/cloud-infrastructure/pservers/pserver/abstract-pserver";
568         traversal
569                 .addV() // pserver
570                 .property("aai-node-type", "pserver")
571                 .property("hostname", "abstract-pserver")
572                 .property(AAIProperties.AAI_URI, uri)
573                 .property(AAIProperties.RESOURCE_VERSION, "123")
574                 .as("v1")
575                 .addV() // generic-vnf
576                 .property("aai-node-type", "generic-vnf")
577                 .property("vnf-id", "abstract-generic-vnf")
578                 .property("vnf-name", "the-vnf-name")
579                 .property(AAIProperties.AAI_URI, "/network/generic-vnfs/generic-vnf/abstract-generic-vnf")
580                 .property(AAIProperties.RESOURCE_VERSION, "234")
581                 .as("v2")
582                 // edge between pserver and generic-vnf
583                 .addE("tosca.relationships.HostedOn").from("v2").to("v1")
584                 .next();
585
586         String requestBody = "";
587         uri = "/network/generic-vnfs/generic-vnf/abstract-generic-vnf/related-to/pservers";
588         Response response = doRequest(traversalHttpEntry, loader, dbEngine, HttpMethod.GET, uri, requestBody);
589         assertThat("Related to pserver is returned.", response.getEntity().toString(),
590                 containsString("\"hostname\":\"abstract-pserver\""));
591     }
592
593     @Test
594     public void getRelationshipListTest()
595             throws UnsupportedEncodingException, AAIException, JsonMappingException, JsonProcessingException {
596         String uri = "/cloud-infrastructure/pservers/pserver/related-to-pserver";
597         traversal
598                 .addV() // pserver
599                 .property("aai-node-type", "pserver")
600                 .property("hostname", "related-to-pserver")
601                 .property(AAIProperties.AAI_URI, uri)
602                 .property(AAIProperties.RESOURCE_VERSION, "123")
603                 .as("v1")
604                 .addV() // complex
605                 .property("aai-node-type", "complex")
606                 .property("physical-location-id", "related-to-complex")
607                 .property("physical-location-type", "AAIDefault")
608                 .property("street1", "AAIDefault")
609                 .property("city", "AAIDefault")
610                 .property("postal-code", "07748")
611                 .property("country", "USA")
612                 .property("region", "US")
613                 .property(AAIProperties.AAI_URI, "/cloud-infrastructure/complexes/complex/related-to-complex")
614                 .property(AAIProperties.RESOURCE_VERSION, "234")
615                 .as("v2")
616                 // edge between pserver and complex
617                 .addE("org.onap.relationships.inventory.LocatedIn").from("v1").to("v2")
618                 // these properties are required when finding related edges
619                 .property(EdgeProperty.CONTAINS.toString(), NONE.toString())
620                 .property(EdgeField.PRIVATE.toString(), "false")
621                 .next();
622
623         // Get Relationship
624         uri = "/cloud-infrastructure/pservers/pserver/related-to-pserver";
625         String requestBody = "";
626         Response response = doRequest(traversalHttpEntry, loader, dbEngine, HttpMethod.GET_RELATIONSHIP, uri,
627                 requestBody);
628         Relationship[] relationships = mapper.readValue(response.getEntity().toString(), RelationshipWrapper.class)
629                 .getRelationships();
630
631         assertEquals("complex", relationships[0].getRelatedTo());
632         assertEquals("org.onap.relationships.inventory.LocatedIn", relationships[0].getRelationshipLabel());
633         assertEquals("/aai/v14/cloud-infrastructure/complexes/complex/related-to-complex",
634                 relationships[0].getRelatedLink());
635         assertEquals("complex.physical-location-id", relationships[0].getRelationshipData()[0].getRelationshipKey());
636         assertEquals("related-to-complex", relationships[0].getRelationshipData()[0].getRelationshipValue());
637     }
638
639     @Test
640     public void getRelationshipListTestWithFormatSimple() throws UnsupportedEncodingException, AAIException {
641         String uri = "/cloud-infrastructure/pservers/pserver/related-to-pserver";
642         traversal
643                 .addV() // pserver
644                 .property("aai-node-type", "pserver")
645                 .property("hostname", "related-to-pserver")
646                 .property(AAIProperties.AAI_URI, uri)
647                 .property(AAIProperties.RESOURCE_VERSION, "123")
648                 .as("v1")
649                 .addV() // complex
650                 .property("aai-node-type", "complex")
651                 .property("physical-location-id", "related-to-complex")
652                 .property("physical-location-type", "AAIDefault")
653                 .property("street1", "AAIDefault")
654                 .property("city", "AAIDefault")
655                 .property("postal-code", "07748")
656                 .property("country", "USA")
657                 .property("region", "US")
658                 .property(AAIProperties.AAI_URI, "/cloud-infrastructure/complexes/complex/related-to-complex")
659                 .property(AAIProperties.RESOURCE_VERSION, "234")
660                 .as("v2")
661                 // edge between pserver and complex
662                 .addE("org.onap.relationships.inventory.LocatedIn").from("v1").to("v2")
663                 // these properties are required when finding related edges
664                 .property(EdgeProperty.CONTAINS.toString(), NONE.toString())
665                 .property(EdgeField.PRIVATE.toString(), "false")
666                 .next();
667
668         // Get Relationship
669         uri = "/cloud-infrastructure/pservers/pserver/related-to-pserver";
670         queryParameters.add("format", "resource");
671         String requestBody = "";
672         Response response = doRequest(traversalHttpEntry, loader, dbEngine, HttpMethod.GET_RELATIONSHIP, uri,
673                 requestBody);
674
675         JSONObject actualResponseBody = new JSONObject(response.getEntity().toString());
676
677         // Define the expected response
678         JSONObject relationshipData = new JSONObject().put("relationship-key", "complex.physical-location-id")
679                 .put("relationship-value", "related-to-complex");
680         JSONObject relationship = new JSONObject()
681                 .put("related-to", "complex")
682                 .put("relationship-label", "org.onap.relationships.inventory.LocatedIn")
683                 .put("related-link",
684                         String.format("/aai/%s/cloud-infrastructure/complexes/complex/related-to-complex",
685                                 schemaVersions.getDefaultVersion()))
686                 .put("relationship-data", new JSONArray().put(relationshipData));
687         JSONObject pserver = new JSONObject()
688                 .put("hostname", "related-to-pserver")
689                 .put("resource-version", "123")
690                 .put("relationship-list", new JSONObject().put("relationship", new JSONArray().put(relationship)));
691         JSONObject expectedResponseBody = new JSONObject()
692                 .put("results", new JSONArray().put(new JSONObject().put("pserver", pserver)));
693
694         JSONAssert.assertEquals(expectedResponseBody, actualResponseBody, JSONCompareMode.NON_EXTENSIBLE);
695         queryParameters.remove("format");
696     }
697
698     @Test
699     public void notificationOnRelatedToTest() throws UnsupportedEncodingException, AAIException {
700
701         Loader ld = loaderFactory.createLoaderForVersion(ModelType.MOXY, schemaVersions.getDefaultVersion());
702         UEBNotification uebNotification = Mockito.spy(new UEBNotification(ld, loaderFactory, schemaVersions));
703         traversalHttpEntry.setHttpEntryProperties(schemaVersions.getDefaultVersion(), uebNotification);
704
705         Loader loader = traversalHttpEntry.getLoader();
706         TransactionalGraphEngine dbEngine = traversalHttpEntry.getDbEngine();
707         // Put pserver
708         String uri = "/cloud-infrastructure/pservers/pserver/junit-edge-test-pserver";
709         String content = "{\"hostname\":\"junit-edge-test-pserver\"}";
710         doRequest(traversalHttpEntry, loader, dbEngine, HttpMethod.PUT, uri, content);
711         // Put complex
712         uri = "/cloud-infrastructure/complexes/complex/junit-edge-test-complex";
713         content = "{\"physical-location-id\":\"junit-edge-test-complex\",\"physical-location-type\":\"AAIDefault\",\"street1\":\"AAIDefault\",\"city\":\"AAIDefault\",\"state\":\"NJ\",\"postal-code\":\"07748\",\"country\":\"USA\",\"region\":\"US\"}";
714         doRequest(traversalHttpEntry, loader, dbEngine, HttpMethod.PUT, uri, content);
715
716         // PutEdge
717         uri = "/cloud-infrastructure/complexes/complex/junit-edge-test-complex/relationship-list/relationship";
718         content = "{\"related-to\":\"pserver\",\"related-link\":\"/aai/" + schemaVersions.getDefaultVersion().toString()
719                 + "/cloud-infrastructure/pservers/pserver/junit-edge-test-pserver\",\"relationship-label\":\"org.onap.relationships.inventory.LocatedIn\"}";
720
721         doNothing().when(uebNotification).triggerEvents();
722         Response response = doRequest(traversalHttpEntry, loader, dbEngine, HttpMethod.PUT_EDGE, uri, content);
723
724         assertEquals("Expected the pserver relationship to be deleted", 200, response.getStatus());
725         assertEquals("Two notifications", 2, uebNotification.getEvents().size());
726         assertEquals("Notification generated for PUT edge", "UPDATE",
727                 uebNotification.getEvents().get(0).getEventHeader().getValue("action").toString());
728         assertThat("Event body for the edge create has the related to",
729                 uebNotification.getEvents().get(0).getObj().marshal(false),
730                 containsString("cloud-infrastructure/pservers/pserver/junit-edge-test-pserver"));
731
732         response = doRequest(traversalHttpEntry, loader, dbEngine, HttpMethod.DELETE_EDGE, uri, content);
733         assertEquals("Expected the pserver relationship to be deleted", 204, response.getStatus());
734         assertEquals("Two notifications", 2, uebNotification.getEvents().size());
735         assertEquals("Notification generated for DELETE edge", "UPDATE",
736                 uebNotification.getEvents().get(0).getEventHeader().getValue("action").toString());
737         assertThat("Event body for the edge delete does not have the related to",
738                 uebNotification.getEvents().get(0).getObj().marshal(false),
739                 not(containsString("cloud-infrastructure/pservers/pserver/junit-edge-test-pserver")));
740         dbEngine.rollback();
741
742     }
743
744     private Response doRequest(HttpEntry httpEntry, Loader loader, TransactionalGraphEngine dbEngine, HttpMethod method,
745             String uri, String requestBody) throws UnsupportedEncodingException, AAIException {
746         URI uriObject = UriBuilder.fromPath(uri).build();
747         QueryParser uriQuery = dbEngine.getQueryBuilder().createQueryFromURI(uriObject);
748         String objType = uriQuery.getResultType();
749         if (uri.endsWith("relationship")) {
750             objType = "relationship";
751         }
752         Introspector obj;
753         if (method.equals(HttpMethod.GET) || method.equals(HttpMethod.GET_RELATIONSHIP)) {
754             obj = loader.introspectorFromName(objType);
755         } else {
756             obj = loader.unmarshal(objType, requestBody, org.onap.aai.restcore.MediaType.getEnum("application/json"));
757         }
758
759         DBRequest dbRequest = new DBRequest.Builder(method, uriObject, uriQuery, obj, httpHeaders, uriInfo,
760                 "JUNIT-TRANSACTION")
761                 .rawRequestContent(requestBody).build();
762
763         List<DBRequest> dbRequestList = new ArrayList<>();
764         dbRequestList.add(dbRequest);
765
766         Pair<Boolean, List<Pair<URI, Response>>> responsesTuple = httpEntry.process(dbRequestList, "JUNIT");
767         return responsesTuple.getValue1().get(0).getValue1();
768     }
769
770     private Response doDelete(String resourceVersion, String uri, String nodeType)
771             throws UnsupportedEncodingException, AAIException {
772         queryParameters.add("resource-version", resourceVersion);
773
774         URI uriObject = UriBuilder.fromPath(uri).build();
775
776         QueryParser uriQuery = dbEngine.getQueryBuilder().createQueryFromURI(uriObject);
777
778         String content = "";
779
780         Introspector obj = loader.introspectorFromName(nodeType);
781
782         DBRequest dbRequest = new DBRequest.Builder(HttpMethod.DELETE, uriObject, uriQuery, obj, httpHeaders, uriInfo,
783                 "JUNIT-TRANSACTION").rawRequestContent(content).build();
784
785         Pair<Boolean, List<Pair<URI, Response>>> responsesTuple = traversalHttpEntry.process(Arrays.asList(dbRequest),
786                 "JUNIT");
787         return responsesTuple.getValue1().get(0).getValue1();
788     }
789
790     @Test
791     public void testSetGetPaginationMethods() {
792         traversalHttpEntry.setHttpEntryProperties(schemaVersions.getDefaultVersion());
793         traversalHttpEntry.setPaginationBucket(10);
794         traversalHttpEntry.setPaginationIndex(1);
795         traversalHttpEntry.setTotalsForPaging(101, traversalHttpEntry.getPaginationBucket());
796         assertEquals("Expected the pagination bucket size to be 10", 10, traversalHttpEntry.getPaginationBucket());
797         assertEquals("Expected the total number of pagination buckets to be 11", 11,
798                 traversalHttpEntry.getTotalPaginationBuckets());
799         assertEquals("Expected the pagination index to be 1", 1, traversalHttpEntry.getPaginationIndex());
800         assertEquals("Expected the total amount of vertices to be 101", 101, traversalHttpEntry.getTotalVertices());
801     }
802
803     @Test
804     public void setDepthTest() throws AAIException {
805         System.setProperty("AJSC_HOME", ".");
806         System.setProperty("BUNDLECONFIG_DIR", "src/main/test/resources");
807
808         String depthParam = AAIConfig.get("aai.rest.getall.depthparam");
809         traversalHttpEntry.setHttpEntryProperties(schemaVersions.getDefaultVersion());
810         int depth = traversalHttpEntry.setDepth(null, depthParam);
811         assertEquals(AAIProperties.MAXIMUM_DEPTH.intValue(), depth);
812     }
813 }