From d5322dbd0fa1e32d543b24824a28d6bf0a0b5497 Mon Sep 17 00:00:00 2001 From: "Sotiropoulos, Ioannis (is948x)" Date: Tue, 10 Jul 2018 17:57:43 +0100 Subject: [PATCH] Increase code coverage Add tests to increase code coverage above 60 percent. Issue-ID: AAI-1198 Change-Id: I4c2f964ce41d01521cc1313e32e34fb6460d49bf Signed-off-by: Sotiropoulos, Ioannis (is948x) --- pom.xml | 25 +- src/main/java/org/onap/crud/dao/DataRouterDAO.java | 4 - .../java/org/onap/crud/dao/champ/ChampDao.java | 10 +- .../event/response/GraphEventResponseHandler.java | 48 +- .../org/onap/crud/service/AaiResourceService.java | 5 +- .../crud/service/CrudAsyncGraphEventCache.java | 6 +- .../response/GraphEventResponseHandlerTest.java | 100 +- .../org/onap/crud/service/BulkPayloadTest.java | 36 +- .../onap/crud/service/ChampDaoExceptionsTest.java | 787 +++++++++ .../org/onap/crud/service/ChampDaoMockTest.java | 562 ++++++ .../org/onap/crud/service/CrudRestServiceTest.java | 7 +- .../org/onap/crud/service/TestEventConsumer.java | 58 + .../org/onap/crud/service/TestEventPublisher.java | 82 + .../service/TestResourceServiceEdgeOperations.java | 284 +++ .../org/onap/crud/service/VertexPayloadTest.java | 50 + .../java/org/onap/schema/EdgeRulesLoaderTest.java | 10 +- .../schema/RelationshipSchemaValidatorTest.java | 269 +++ .../validation/MultiplicityValidatorTest.java | 5 +- .../model/DbEdgeRules_v10.json | 1819 ++++++++++++++++++++ .../model/edge_properties_v10.json | 6 + .../model/edge_properties_v11.json | 6 + .../aai-resource-service/post-edge-auto-props.json | 6 + .../aai-resource-service/post-edge-no-props.json | 5 + .../aai-resource-service/post-edge-no-type.json | 5 + .../aai-resource-service/post-edge-null-props.json | 6 + .../aai-resource-service/post-edge-upsert.json | 7 + .../aai-resource-service/post-edge-with-id.json | 7 + .../resources/aai-resource-service/post-edge.json | 12 + src/test/resources/auth/crud_policy.json | 18 + src/test/resources/event/champ-edge-event.json | 30 + .../resources/event/champ-vertex-event-error.json | 26 + .../event/champ-vertex-event-violations.json | 30 + src/test/resources/event/champ-vertex-event.json | 25 + .../event-envelope-sentinel-no-violations.json | 2 +- .../resources/event/event-envelope-sentinel.json | 2 +- src/test/resources/event/graph-edge-event.json | 19 + src/test/resources/event/graph-vertex-event.json | 12 + 37 files changed, 4301 insertions(+), 90 deletions(-) create mode 100644 src/test/java/org/onap/crud/service/ChampDaoExceptionsTest.java create mode 100644 src/test/java/org/onap/crud/service/ChampDaoMockTest.java create mode 100644 src/test/java/org/onap/crud/service/TestEventConsumer.java create mode 100644 src/test/java/org/onap/crud/service/TestEventPublisher.java create mode 100644 src/test/java/org/onap/crud/service/TestResourceServiceEdgeOperations.java create mode 100644 src/test/java/org/onap/crud/service/VertexPayloadTest.java create mode 100644 src/test/java/org/onap/schema/RelationshipSchemaValidatorTest.java create mode 100644 src/test/resources/aai-resource-service/model/DbEdgeRules_v10.json create mode 100644 src/test/resources/aai-resource-service/model/edge_properties_v10.json create mode 100644 src/test/resources/aai-resource-service/model/edge_properties_v11.json create mode 100644 src/test/resources/aai-resource-service/post-edge-auto-props.json create mode 100644 src/test/resources/aai-resource-service/post-edge-no-props.json create mode 100644 src/test/resources/aai-resource-service/post-edge-no-type.json create mode 100644 src/test/resources/aai-resource-service/post-edge-null-props.json create mode 100644 src/test/resources/aai-resource-service/post-edge-upsert.json create mode 100644 src/test/resources/aai-resource-service/post-edge-with-id.json create mode 100644 src/test/resources/aai-resource-service/post-edge.json create mode 100644 src/test/resources/auth/crud_policy.json create mode 100644 src/test/resources/event/champ-edge-event.json create mode 100644 src/test/resources/event/champ-vertex-event-error.json create mode 100644 src/test/resources/event/champ-vertex-event-violations.json create mode 100644 src/test/resources/event/champ-vertex-event.json create mode 100644 src/test/resources/event/graph-edge-event.json create mode 100644 src/test/resources/event/graph-vertex-event.json diff --git a/pom.xml b/pom.xml index 50c6c88..e79e4ad 100644 --- a/pom.xml +++ b/pom.xml @@ -41,7 +41,6 @@ limitations under the License. https://nexus.onap.org workstation DEV - 1.3 @@ -84,6 +83,17 @@ limitations under the License. org.springframework.boot spring-boot-starter-actuator + + org.springframework.boot + + spring-boot-configuration-processor + + true + + + org.springframework.boot + spring-boot-starter-test + org.apache.cxf cxf-rt-frontend-jaxrs @@ -288,12 +298,6 @@ limitations under the License. 1.5.0 test - - org.hamcrest - hamcrest-library - ${version.org.hamcrest.hamcrest-library} - test - org.apache.httpcomponents httpclient @@ -304,13 +308,6 @@ limitations under the License. httpcore 4.4.1 - - org.springframework.boot - - spring-boot-configuration-processor - - true - diff --git a/src/main/java/org/onap/crud/dao/DataRouterDAO.java b/src/main/java/org/onap/crud/dao/DataRouterDAO.java index c0cf7c1..e5b6d5a 100644 --- a/src/main/java/org/onap/crud/dao/DataRouterDAO.java +++ b/src/main/java/org/onap/crud/dao/DataRouterDAO.java @@ -21,16 +21,12 @@ package org.onap.crud.dao; import org.eclipse.jetty.util.security.Password; -import org.onap.aai.cl.api.Logger; -import org.onap.aai.cl.eelf.LoggerFactory; import org.onap.aai.restclient.client.RestClient; import org.onap.aai.restclient.enums.RestAuthenticationMode; import org.onap.crud.dao.champ.ChampDao; import org.onap.crud.util.CrudServiceConstants; public class DataRouterDAO extends ChampDao { - private Logger logger = LoggerFactory.getInstance().getLogger(DataRouterDAO.class.getName()); - public DataRouterDAO(String url, String certPassword) { try { client = new RestClient().authenticationMode(RestAuthenticationMode.SSL_CERT).validateServerHostname(false) diff --git a/src/main/java/org/onap/crud/dao/champ/ChampDao.java b/src/main/java/org/onap/crud/dao/champ/ChampDao.java index 7bd4754..6817ea6 100644 --- a/src/main/java/org/onap/crud/dao/champ/ChampDao.java +++ b/src/main/java/org/onap/crud/dao/champ/ChampDao.java @@ -33,8 +33,6 @@ import org.apache.http.NameValuePair; import org.apache.http.client.utils.URLEncodedUtils; import org.apache.http.message.BasicNameValuePair; import org.eclipse.jetty.util.security.Password; -import org.onap.aai.cl.api.Logger; -import org.onap.aai.cl.eelf.LoggerFactory; import org.onap.aai.cl.mdc.MdcContext; import org.onap.aai.logging.LoggingContext; import org.onap.aai.restclient.client.OperationResult; @@ -64,8 +62,6 @@ public class ChampDao implements GraphDao { protected static final String RELATIONSHIP_SUB_URL = "relationships"; protected static final String TRANSACTION_SUB_URL = "transaction"; - private Logger logger = LoggerFactory.getInstance().getLogger(ChampDao.class.getName()); - // We use a custom vertex serializer for champ because it expects "key" // instead of "id" protected static final Gson champGson = new GsonBuilder() @@ -209,7 +205,7 @@ public class ChampDao implements GraphDao { if (!edge.getType().equalsIgnoreCase(type)) { // We didn't find an edge with the supplied type, so just throw an // exception. - throw new CrudException("No edge with id " + id + "and type " + type + " found in graph", + throw new CrudException("No edge with id " + id + " and type " + type + " found in graph", javax.ws.rs.core.Response.Status.NOT_FOUND); } return getResult; @@ -537,7 +533,7 @@ public class ChampDao implements GraphDao { if (!edge.getType().equalsIgnoreCase(type)) { // We didn't find an edge with the supplied type, so just throw an // exception. - throw new CrudException("No edge with id " + id + "and type " + type + " found in graph", + throw new CrudException("No edge with id " + id + " and type " + type + " found in graph", javax.ws.rs.core.Response.Status.NOT_FOUND); } return edge; @@ -558,7 +554,7 @@ public class ChampDao implements GraphDao { if (!vert.getType().equalsIgnoreCase(type)) { // We didn't find a vertex with the supplied type, so just throw an // exception. - throw new CrudException("No vertex with id " + id + "and type " + type + " found in graph", + throw new CrudException("No vertex with id " + id + " and type " + type + " found in graph", javax.ws.rs.core.Response.Status.NOT_FOUND); } return vert; diff --git a/src/main/java/org/onap/crud/event/response/GraphEventResponseHandler.java b/src/main/java/org/onap/crud/event/response/GraphEventResponseHandler.java index d858384..83be4bc 100644 --- a/src/main/java/org/onap/crud/event/response/GraphEventResponseHandler.java +++ b/src/main/java/org/onap/crud/event/response/GraphEventResponseHandler.java @@ -42,12 +42,7 @@ public class GraphEventResponseHandler { public String handleVertexResponse(String version, GraphEvent event, GraphEventEnvelope response) throws CrudException { - handlePolicyViolations(event, response); - logResponse(event, response.getBody()); - - if (isErrorResponse(response.getBody())) { - throwOperationException(response); - } + validate(event, response); return CrudResponseBuilder.buildUpsertVertexResponse( OxmModelValidator.validateOutgoingPayload(version, response.getBody().getVertex().toVertex()), version); @@ -55,12 +50,7 @@ public class GraphEventResponseHandler { public String handleEdgeResponse(String version, GraphEvent event, GraphEventEnvelope response) throws CrudException { - handlePolicyViolations(event, response); - logResponse(event, response.getBody()); - - if (isErrorResponse(response.getBody())) { - throwOperationException(response); - } + validate(event, response); return CrudResponseBuilder.buildUpsertEdgeResponse( RelationshipSchemaValidator.validateOutgoingPayload(version, response.getBody().getEdge().toEdge()), @@ -68,23 +58,12 @@ public class GraphEventResponseHandler { } public String handleDeletionResponse(GraphEvent event, GraphEventEnvelope response) throws CrudException { - handlePolicyViolations(event, response); - logResponse(event, response.getBody()); - - if (isErrorResponse(response.getBody())) { - throwOperationException(response); - } - + validate(event, response); return ""; } public void handleBulkEventResponse(GraphEvent event, GraphEventEnvelope response) throws CrudException { - handlePolicyViolations(event, response); - logResponse(event, response.getBody()); - - if (isErrorResponse(response.getBody())) { - throwOperationException(response); - } + validate(event, response); } public boolean hasPolicyViolations(GraphEventEnvelope event) { @@ -92,6 +71,18 @@ public class GraphEventResponseHandler { && event.getPolicyViolations().getAsJsonArray().size() != 0; } + private void validate(GraphEvent event, GraphEventEnvelope response) throws CrudException { + handlePolicyViolations(event, response); + logResponse(event, response.getBody()); + + if (isErrorResponse(response.getBody())) { + throw new CrudException( + GraphEventResponseMessage.OPERATION_ERROR_EXCEPTION_MESSAGE + .getMessage(response.getBody().getTransactionId(), response.getBody().getErrorMessage()), + response.getBody().getHttpErrorStatus()); + } + } + private void handlePolicyViolations(GraphEvent event, GraphEventEnvelope response) throws CrudException { if (hasPolicyViolations(response)) { logPolicyViolation(event, response); @@ -126,13 +117,6 @@ public class GraphEventResponseHandler { //@formatter:on } - private void throwOperationException(GraphEventEnvelope response) throws CrudException { - throw new CrudException( - GraphEventResponseMessage.OPERATION_ERROR_EXCEPTION_MESSAGE - .getMessage(response.getBody().getTransactionId(), response.getBody().getErrorMessage()), - response.getBody().getHttpErrorStatus()); - } - private boolean isErrorResponse(GraphEvent response) { return GraphEventResult.FAILURE.equals(response.getResult()); } diff --git a/src/main/java/org/onap/crud/service/AaiResourceService.java b/src/main/java/org/onap/crud/service/AaiResourceService.java index 881f9fd..c2e0338 100644 --- a/src/main/java/org/onap/crud/service/AaiResourceService.java +++ b/src/main/java/org/onap/crud/service/AaiResourceService.java @@ -169,8 +169,9 @@ public class AaiResourceService { ImmutablePair result = graphDataService.addEdge(EdgeRulesLoader.getLatestSchemaVersion(), type, payload); response = Response.status(Status.CREATED).entity(result.getValue()).tag(result.getKey()).type(mediaType).build(); - } catch (CrudException e) { - + } catch (CrudException ce) { + response = Response.status(ce.getHttpStatus()).entity(ce.getMessage()).build(); + } catch (Exception e) { response = Response.status(Status.INTERNAL_SERVER_ERROR).entity(e.getMessage()).build(); } } diff --git a/src/main/java/org/onap/crud/service/CrudAsyncGraphEventCache.java b/src/main/java/org/onap/crud/service/CrudAsyncGraphEventCache.java index 3457cff..ff5170a 100644 --- a/src/main/java/org/onap/crud/service/CrudAsyncGraphEventCache.java +++ b/src/main/java/org/onap/crud/service/CrudAsyncGraphEventCache.java @@ -20,17 +20,15 @@ */ package org.onap.crud.service; -import com.google.common.cache.Cache; -import com.google.common.cache.CacheBuilder; - import java.util.concurrent.TimeUnit; - import org.onap.aai.cl.api.Logger; import org.onap.aai.cl.eelf.LoggerFactory; import org.onap.crud.logging.CrudServiceMsgs; import org.onap.crud.service.CrudAsyncGraphDataService.CollectGraphResponse; import org.onap.crud.util.CrudProperties; import org.onap.crud.util.CrudServiceConstants; +import com.google.common.cache.Cache; +import com.google.common.cache.CacheBuilder; /** * Self expiring Cache to hold request transactionIds . Events are expired diff --git a/src/test/java/org/onap/crud/event/response/GraphEventResponseHandlerTest.java b/src/test/java/org/onap/crud/event/response/GraphEventResponseHandlerTest.java index 1829496..e5ac52d 100644 --- a/src/test/java/org/onap/crud/event/response/GraphEventResponseHandlerTest.java +++ b/src/test/java/org/onap/crud/event/response/GraphEventResponseHandlerTest.java @@ -20,15 +20,34 @@ */ package org.onap.crud.event.response; -import static org.hamcrest.Matchers.is; -import static org.junit.Assert.assertThat; +import static org.assertj.core.api.Assertions.assertThat; +import org.junit.BeforeClass; +import org.junit.Rule; import org.junit.Test; +import org.junit.rules.ExpectedException; +import org.onap.crud.event.GraphEvent; +import org.onap.crud.event.GraphEvent.GraphEventOperation; import org.onap.crud.event.envelope.GraphEventEnvelope; +import org.onap.crud.exception.CrudException; import org.onap.crud.util.TestUtil; +import org.onap.schema.OxmModelLoader; import com.google.gson.Gson; +import com.google.gson.JsonParser; public class GraphEventResponseHandlerTest { + @Rule + public ExpectedException expectedException = ExpectedException.none(); + + @BeforeClass + public static void setUpBeforeClass() throws Exception { + System.setProperty("CONFIG_HOME", "src/test/resources"); + System.setProperty("AJSC_HOME", "."); + System.setProperty("BUNDLECONFIG_DIR", "src/test/resources/bundleconfig-local"); + + OxmModelLoader.loadModels(); + } + @Test public void testPolicyViolationsNotDetected() throws Exception { String expectedEnvelope = TestUtil.getFileAsString("event/event-envelope-sentinel-no-violations.json"); @@ -36,7 +55,7 @@ public class GraphEventResponseHandlerTest { GraphEventEnvelope envelope = gson.fromJson(expectedEnvelope, GraphEventEnvelope.class); GraphEventResponseHandler graphEventResponseHandler = new GraphEventResponseHandler(); - assertThat(graphEventResponseHandler.hasPolicyViolations(envelope), is(false)); + assertThat(graphEventResponseHandler.hasPolicyViolations(envelope)).isFalse(); } @Test @@ -46,6 +65,79 @@ public class GraphEventResponseHandlerTest { GraphEventEnvelope envelope = gson.fromJson(expectedEnvelope, GraphEventEnvelope.class); GraphEventResponseHandler graphEventResponseHandler = new GraphEventResponseHandler(); - assertThat(graphEventResponseHandler.hasPolicyViolations(envelope), is(true)); + assertThat(graphEventResponseHandler.hasPolicyViolations(envelope)).isTrue(); + } + + @Test + public void testHandleVertexResponse() throws Exception { + String graphEvent = TestUtil.getFileAsString("event/graph-vertex-event.json"); + String champResult = TestUtil.getFileAsString("event/champ-vertex-event.json"); + Gson gson = new Gson(); + GraphEvent event = gson.fromJson(graphEvent, GraphEvent.class); + GraphEventEnvelope result = gson.fromJson(champResult, GraphEventEnvelope.class); + + GraphEventResponseHandler graphEventResponseHandler = new GraphEventResponseHandler(); + String response = graphEventResponseHandler.handleVertexResponse("v13", event, result); + + assertThat(new JsonParser().parse(response).getAsJsonObject().get("url").getAsString()) + .isEqualTo("services/inventory/v13/pserver/890c8b3f-892f-48e3-85cd-748ebf0426a5"); + } + + @Test + public void testHandleVertexResponseWithError() throws Exception { + expectedException.expect(CrudException.class); + expectedException.expectMessage("test error"); + + String graphEvent = TestUtil.getFileAsString("event/graph-vertex-event.json"); + String champResult = TestUtil.getFileAsString("event/champ-vertex-event-error.json"); + Gson gson = new Gson(); + GraphEvent event = gson.fromJson(graphEvent, GraphEvent.class); + GraphEventEnvelope result = gson.fromJson(champResult, GraphEventEnvelope.class); + + GraphEventResponseHandler graphEventResponseHandler = new GraphEventResponseHandler(); + graphEventResponseHandler.handleVertexResponse("v13", event, result); + } + + @Test(expected = CrudException.class) + public void testHandleVertexResponseWithViolations() throws Exception { + + String graphEvent = TestUtil.getFileAsString("event/graph-vertex-event.json"); + String champResult = TestUtil.getFileAsString("event/champ-vertex-event-violations.json"); + Gson gson = new Gson(); + GraphEvent event = gson.fromJson(graphEvent, GraphEvent.class); + GraphEventEnvelope result = gson.fromJson(champResult, GraphEventEnvelope.class); + + GraphEventResponseHandler graphEventResponseHandler = new GraphEventResponseHandler(); + graphEventResponseHandler.handleVertexResponse("v13", event, result); + } + + @Test + public void testHandleEdgeResponse() throws Exception { + String graphEvent = TestUtil.getFileAsString("event/graph-edge-event.json"); + String champResult = TestUtil.getFileAsString("event/champ-edge-event.json"); + Gson gson = new Gson(); + GraphEvent event = gson.fromJson(graphEvent, GraphEvent.class); + GraphEventEnvelope result = gson.fromJson(champResult, GraphEventEnvelope.class); + + GraphEventResponseHandler graphEventResponseHandler = new GraphEventResponseHandler(); + String response = graphEventResponseHandler.handleEdgeResponse("v10", event, result); + + String id = new JsonParser().parse(response).getAsJsonObject().get("id").getAsString(); + assertThat(id).isEqualTo("test-key"); + } + + @Test + public void testHandleDeletionResponse() throws Exception { + GraphEventResponseHandler graphEventResponseHandler = new GraphEventResponseHandler(); + GraphEvent event = GraphEvent.builder(GraphEventOperation.DELETE).build(); + String response = graphEventResponseHandler.handleDeletionResponse(event, new GraphEventEnvelope(event)); + assertThat(response).isEqualTo(""); + } + + @Test + public void testHandleBulkEventResponse() throws Exception { + GraphEventResponseHandler graphEventResponseHandler = new GraphEventResponseHandler(); + GraphEvent event = GraphEvent.builder(GraphEventOperation.CREATE).build(); + graphEventResponseHandler.handleBulkEventResponse(event, new GraphEventEnvelope(event)); } } diff --git a/src/test/java/org/onap/crud/service/BulkPayloadTest.java b/src/test/java/org/onap/crud/service/BulkPayloadTest.java index c768339..7a409ec 100644 --- a/src/test/java/org/onap/crud/service/BulkPayloadTest.java +++ b/src/test/java/org/onap/crud/service/BulkPayloadTest.java @@ -20,16 +20,19 @@ */ package org.onap.crud.service; -import com.google.gson.JsonArray; -import com.google.gson.JsonElement; -import com.google.gson.JsonObject; - -import org.junit.Test; -import org.onap.crud.parser.BulkPayload; +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.assertThat; import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.Set; +import javax.ws.rs.core.Response.Status; +import org.junit.Test; +import org.onap.crud.exception.CrudException; +import org.onap.crud.parser.BulkPayload; +import com.google.gson.JsonArray; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; public class BulkPayloadTest { @@ -70,4 +73,23 @@ public class BulkPayloadTest { System.out.println("root: " + root.toString()); System.out.println("payload ids: " + ids.toString()); } -} \ No newline at end of file + + @Test + public void testExceptionHandling() { + String payload = null; + try { + BulkPayload.fromJson(payload); + } catch (CrudException e) { + assertThat(e.getHttpStatus(), is(Status.BAD_REQUEST)); + assertThat(e.getMessage(), is("Invalid Json Payload")); + } + + payload = "Invalid Json"; + try { + BulkPayload.fromJson(payload); + } catch (CrudException e) { + assertThat(e.getHttpStatus(), is(Status.BAD_REQUEST)); + assertThat(e.getMessage(), is("Invalid Json Payload")); + } + } +} diff --git a/src/test/java/org/onap/crud/service/ChampDaoExceptionsTest.java b/src/test/java/org/onap/crud/service/ChampDaoExceptionsTest.java new file mode 100644 index 0000000..1f0a20b --- /dev/null +++ b/src/test/java/org/onap/crud/service/ChampDaoExceptionsTest.java @@ -0,0 +1,787 @@ +/** + * ============LICENSE_START======================================================= + * org.onap.aai + * ================================================================================ + * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved. + * Copyright © 2017-2018 Amdocs + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ +package org.onap.crud.service; + +import static org.hamcrest.CoreMatchers.containsString; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertThat; +import static org.mockito.Matchers.anyString; +import static org.mockito.Matchers.eq; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import javax.ws.rs.core.MediaType; +import org.junit.Before; +import org.junit.Test; +import org.onap.aai.cl.mdc.MdcContext; +import org.onap.aai.restclient.client.OperationResult; +import org.onap.aai.restclient.client.RestClient; +import org.onap.crud.dao.champ.ChampDao; +import org.onap.crud.entity.Edge; +import org.onap.crud.entity.Vertex; +import org.onap.crud.exception.CrudException; +import org.slf4j.MDC; + +public class ChampDaoExceptionsTest { + // @formatter:off + private final String champVertex = "{" + + "\"key\": \"test-uuid\"," + + "\"type\": \"vertexType\"," + + "\"properties\": {" + + "\"fqdn\": \"myhost.onap.com\"," + + "\"hostname\": \"myhost\" } }"; + + private final String champEdge = "{" + + "\"key\": \"test-uuid\"," + + "\"type\": \"edgeType\"," + + "\"properties\": {" + + "\"prevent-delete\": \"NONE\" }," + + "\"source\": {" + + "\"key\": \"50bdab41-ad1c-4d00-952c-a0aa5d827811\", \"type\": \"vserver\"}," + + "\"target\": {" + + "\"key\": \"1d326bc7-b985-492b-9604-0d5d1f06f908\", \"type\": \"pserver\"}" + + " }"; + + private final String vertexPayload = "{" + + "\"type\":\"pserver\"," + + "\"properties\":{" + + "\"aai-node-type\":\"pserver\"}}"; + // @formatter:on + + private RestClient restClientMock; + private ChampDao champDao; + + static final String CHAMP_URL = "https://host:9522/services/champ-service/v1/"; + static final String OBJECT_SUB_URL = "objects"; + static final String RELATIONSHIP_SUB_URL = "relationships"; + static final String TRANSACTION_SUB_URL = "transaction"; + static final String BASE_OBJECT_URL = CHAMP_URL + OBJECT_SUB_URL; + static final String HEADER_FROM_APP = "X-FromAppId"; + static final String HEADER_TRANS_ID = "X-TransactionId"; + static final String FROM_APP_NAME = "Gizmo"; + + @Before + public void setup() { + restClientMock = mock(RestClient.class); + } + + @Test + public void testGetVertexIdNotExists() { + String id = "test-id"; + String idNotExists = "test-id-not-exists"; + String type = "pserver"; + String version = "v11"; + String failureCauseForGetVertex = "No vertex with id " + id + " found in graph"; + + Map queryParams = new HashMap<>(); + queryParams.put("hostname", "myhost"); + mockGetVertex(idNotExists, "", "", type, 404, failureCauseForGetVertex); + buildChampDao(); + + try { + champDao.getVertex(idNotExists, version); + } catch (CrudException e) { + assertEquals(404, e.getHttpStatus().getStatusCode()); + assertThat(e.getMessage(), containsString(failureCauseForGetVertex)); + } + } + + @Test + public void testGetVertexIdNotExistsWithQueryParams() { + String id = "test-id"; + String idNotExists = "test-id-not-exists"; + String queryParamsForMock = "?hostname=myhost"; + String type = "pserver"; + String version = "v11"; + String failureCauseForGetVertex = "No vertex with id " + id + " found in graph"; + + Map queryParams = new HashMap<>(); + queryParams.put("hostname", "myhost"); + mockGetVertex(idNotExists, queryParamsForMock, "", type, 404, failureCauseForGetVertex); + buildChampDao(); + + try { + champDao.getVertex(idNotExists, type, version, queryParams); + } catch (CrudException e) { + assertEquals(404, e.getHttpStatus().getStatusCode()); + assertThat(e.getMessage(), containsString(failureCauseForGetVertex)); + } + } + + @Test + public void testGetVertexWithQueryParamsTypeNotMatch() { + String id = "test-id"; + String queryParamsForMock = "?hostname=myhost"; + String type = "pserver"; + String version = "v11"; + String failureCauseForGetVertexTypeNotMatches = "No vertex with id " + id + " and type vserver found in graph"; + + Map queryParams = new HashMap<>(); + queryParams.put("hostname", "myhost"); + mockGetVertex(id, queryParamsForMock, "", type, 200, ""); + buildChampDao(); + + try { + champDao.getVertex(id, "vserver", version, queryParams); + } catch (CrudException e) { + assertEquals(404, e.getHttpStatus().getStatusCode()); + assertThat(e.getMessage(), containsString(failureCauseForGetVertexTypeNotMatches)); + } + } + + @Test + public void testGetVertexIdNotExistsWithTxId() { + String id = "test-id"; + String idNotExists = "test-id-not-exists"; + String txId = "1234"; + String type = "pserver"; + String version = "v11"; + String failureCauseForGetVertex = "No vertex with id " + id + " found in graph"; + + Map queryParams = new HashMap<>(); + queryParams.put("hostname", "myhost"); + mockGetVertex(idNotExists, "", txId, type, 404, failureCauseForGetVertex); + buildChampDao(); + + try { + champDao.getVertex(idNotExists, type, version, txId); + } catch (CrudException e) { + assertEquals(404, e.getHttpStatus().getStatusCode()); + assertThat(e.getMessage(), containsString(failureCauseForGetVertex)); + } + } + + @Test + public void testGetVertexWithTxIdAndTypeNotMatch() { + String id = "test-id"; + String txId = "1234"; + String type = "pserver"; + String version = "v11"; + String failureCauseForGetVertexTypeNotMatches = "No vertex with id " + id + " and type vserver found in graph"; + + Map queryParams = new HashMap<>(); + queryParams.put("hostname", "myhost"); + mockGetVertex(id, "", txId, type, 200, ""); + buildChampDao(); + + try { + champDao.getVertex(id, "vserver", version, txId); + } catch (CrudException e) { + assertEquals(404, e.getHttpStatus().getStatusCode()); + assertThat(e.getMessage(), containsString(failureCauseForGetVertexTypeNotMatches)); + } + } + + @Test + public void testGetVertices() { + String queryParamsForMockGetVertices = "?aai-node-type=pserver"; + String type = "pserver"; + String version = "v11"; + String failureCauseForGetVertices = "No vertices found in graph for given filters"; + + Map filter = new HashMap<>(); + Map queryParams = new HashMap<>(); + queryParams.put("hostname", "myhost"); + mockGetVertices(queryParamsForMockGetVertices, type, 404, failureCauseForGetVertices); + buildChampDao(); + + try { + champDao.getVertices(type, filter, version); + } catch (CrudException e) { + assertEquals(404, e.getHttpStatus().getStatusCode()); + assertThat(e.getMessage(), containsString(failureCauseForGetVertices)); + } + } + + @Test + public void testGetEdgeIdNotExists() { + String idNotExists = "test-id-not-exists"; + String id = "test-id"; + String txId = "1234"; + String type = "tosca.relationships.HostedOn"; + String failureCauseForGetEdge = "No edge with id " + id + " found in graph"; + + Map queryParams = new HashMap<>(); + queryParams.put("hostname", "myhost"); + mockGetEdge(idNotExists, "", txId, type, 404, failureCauseForGetEdge); + buildChampDao(); + + try { + champDao.getEdge(idNotExists, type, txId); + } catch (CrudException e) { + assertEquals(404, e.getHttpStatus().getStatusCode()); + assertThat(e.getMessage(), containsString(failureCauseForGetEdge)); + } + } + + @Test + public void testGetEdgeTypeNotMatch() { + String id = "test-id"; + String txId = "1234"; + String type = "tosca.relationships.HostedOn"; + String failureCauseForGetEdgeTypeNotMatches = "No edge with id " + id + " and type " + "" + " found in graph"; + + Map queryParams = new HashMap<>(); + queryParams.put("hostname", "myhost"); + mockGetEdge(id, "", txId, type, 200, ""); + buildChampDao(); + + // Type not matches + try { + champDao.getEdge(id, "", txId); + } catch (CrudException e) { + assertEquals(404, e.getHttpStatus().getStatusCode()); + assertThat(e.getMessage(), containsString(failureCauseForGetEdgeTypeNotMatches)); + } + } + + @Test + public void testGetEdgeIdNotExistsWithQueryParams() { + String idNotExists = "test-id-not-exists"; + String id = "test-id"; + String queryParamsForMock = "?hostname=myhost"; + String type = "tosca.relationships.HostedOn"; + String failureCauseForGetEdge = "No edge with id " + id + " found in graph"; + + Map queryParams = new HashMap<>(); + queryParams.put("hostname", "myhost"); + mockGetEdge(idNotExists, queryParamsForMock, "", type, 404, failureCauseForGetEdge); + buildChampDao(); + + try { + champDao.getEdge(idNotExists, type, queryParams); + } catch (CrudException e) { + assertEquals(404, e.getHttpStatus().getStatusCode()); + assertThat(e.getMessage(), containsString(failureCauseForGetEdge)); + } + } + + @Test + public void testGetEdgeTypeNotMatchWithQueryParams() { + String id = "test-id"; + String queryParamsForMock = "?hostname=myhost"; + String type = "tosca.relationships.HostedOn"; + String failureCauseForGetEdgeTypeNotMatches = "No edge with id " + id + " and type " + "" + " found in graph"; + + Map queryParams = new HashMap<>(); + queryParams.put("hostname", "myhost"); + mockGetEdge(id, queryParamsForMock, "", type, 200, ""); + buildChampDao(); + + // Type not matches + try { + champDao.getEdge(id, "", queryParams); + } catch (CrudException e) { + assertEquals(404, e.getHttpStatus().getStatusCode()); + assertThat(e.getMessage(), containsString(failureCauseForGetEdgeTypeNotMatches)); + } + } + + @Test + public void testGetEdges() { + String type = "tosca.relationships.HostedOn"; + String failureCauseForGetEdges = "No edges found in graph for given filters"; + + Map filter = new HashMap<>(); + Map queryParams = new HashMap<>(); + queryParams.put("hostname", "myhost"); + mockGetEdges("?", type, 404, failureCauseForGetEdges); + buildChampDao(); + + try { + champDao.getEdges(type, filter); + } catch (CrudException e) { + assertEquals(404, e.getHttpStatus().getStatusCode()); + assertThat(e.getMessage(), containsString(failureCauseForGetEdges)); + } + } + + @Test + public void testGetVertexEdges() { + String idNotExists = "test-id-not-exists"; + String id = "test-id"; + String queryParamsForMock = "?hostname=myhost"; + String type = "tosca.relationships.HostedOn"; + String failureCauseForGetVertexEdges = "No vertex with id " + id + " found in graph"; + + Map queryParams = new HashMap<>(); + queryParams.put("hostname", "myhost"); + mockGetVertexEdges(idNotExists, queryParamsForMock, type, 404, failureCauseForGetVertexEdges); + buildChampDao(); + + try { + champDao.getVertexEdges(idNotExists, queryParams); + } catch (CrudException e) { + assertEquals(404, e.getHttpStatus().getStatusCode()); + assertThat(e.getMessage(), containsString(failureCauseForGetVertexEdges)); + } + } + + @Test + public void addVertexTest() { + String type = "pserver"; + String txId = "1234"; + String version = "v11"; + + Map properties = new HashMap<>(); + + mockAddVertex(type, vertexPayload, "", 400); + mockAddVertex(type, vertexPayload, txId, 400); + buildChampDao(); + + try { + champDao.addVertex(type, properties, version); + } catch (CrudException e) { + assertEquals(400, e.getHttpStatus().getStatusCode()); + assertThat(e.getMessage(), containsString("Failed to create vertex")); + } + + try { + champDao.addVertex(type, properties, version, txId); + } catch (CrudException e) { + assertEquals(400, e.getHttpStatus().getStatusCode()); + assertThat(e.getMessage(), containsString("Failed to create vertex")); + } + } + + @Test + public void addEdgeTest() throws CrudException { + String txId = "1234"; + String vertexType = "pserver"; + String edgeType = "tosca.relationships.HostedOn"; + String version = "v11"; + + Map properties = new HashMap<>(); + + mockGetVertex("test-uuid", "", "", "pserver", 200, ""); + mockGetVertex("test-uuid", "", txId, "pserver", 200, ""); + mockAddEdge(edgeType, "", 400); + mockAddEdge(edgeType, txId, 400); + buildChampDao(); + + String vertex = champVertex.replace("vertexType", vertexType); + Vertex source = Vertex.fromJson(vertex, "v11"); + Vertex target = Vertex.fromJson(vertex, "v11"); + + try { + champDao.addEdge(edgeType, source, target, properties, version); + } catch (CrudException e) { + assertEquals(400, e.getHttpStatus().getStatusCode()); + assertThat(e.getMessage(), containsString("Failed to create edge")); + } + + try { + champDao.addEdge(edgeType, source, target, properties, version, txId); + } catch (CrudException e) { + assertEquals(400, e.getHttpStatus().getStatusCode()); + assertThat(e.getMessage(), containsString("Failed to create edge")); + } + } + + @Test + public void updateVertexTest() { + String id = "test-id"; + String type = "pserver"; + String txId = "1234"; + String version = "v11"; + + Map properties = new HashMap<>(); + + mockPutVertex(id, type, "", 400); + mockPutVertex(id, type, txId, 400); + buildChampDao(); + + try { + champDao.updateVertex(id, type, properties, version); + } catch (CrudException e) { + assertEquals(400, e.getHttpStatus().getStatusCode()); + assertThat(e.getMessage(), containsString("Failed to update vertex")); + } + + try { + champDao.updateVertex(id, type, properties, version, txId); + } catch (CrudException e) { + assertEquals(400, e.getHttpStatus().getStatusCode()); + assertThat(e.getMessage(), containsString("Failed to update vertex")); + } + } + + @Test + public void updateEdgeTest() { + String id = "test-uuid"; + String txId = "1234"; + String type = "tosca.relationships.HostedOn"; + + mockPutEdge(id, type, "", 400); + mockPutEdge(id, type, txId, 400); + buildChampDao(); + + String champJson = champEdge.replace("\"test-uuid\"", "null").replace("edgeType", type); + Edge edge = Edge.fromJson(champJson); + + try { + champDao.updateEdge(edge); + } catch (CrudException e) { + assertEquals(400, e.getHttpStatus().getStatusCode()); + assertThat(e.getMessage(), containsString("Unable to identify edge")); + } + + try { + champDao.updateEdge(edge, txId); + } catch (CrudException e) { + assertEquals(400, e.getHttpStatus().getStatusCode()); + assertThat(e.getMessage(), containsString("Unable to identify edge")); + } + + champJson = champEdge.replace("edgeType", type); + edge = Edge.fromJson(champJson); + + try { + champDao.updateEdge(edge); + } catch (CrudException e) { + assertEquals(400, e.getHttpStatus().getStatusCode()); + assertThat(e.getMessage(), containsString("Failed to update edge")); + } + + try { + champDao.updateEdge(edge, txId); + } catch (CrudException e) { + assertEquals(400, e.getHttpStatus().getStatusCode()); + assertThat(e.getMessage(), containsString("Failed to update edge")); + } + } + + @Test + public void deleteVertexTest() { + String id = "test-id"; + String type = "pserver"; + String txId = "1234"; + + mockDeleteVertex(id, type, "", 400); + mockDeleteVertex(id, type, txId, 400); + buildChampDao(); + + try { + champDao.deleteVertex(id, type); + } catch (CrudException e) { + assertEquals(400, e.getHttpStatus().getStatusCode()); + assertThat(e.getMessage(), containsString("Failed to delete vertex")); + } + try { + champDao.deleteVertex(id, type, txId); + } catch (CrudException e) { + assertEquals(400, e.getHttpStatus().getStatusCode()); + assertThat(e.getMessage(), containsString("Failed to delete vertex")); + } + } + + @Test + public void deleteEdgeTest() { + String id = "test-uuid"; + String txId = "1234"; + String type = "tosca.relationships.HostedOn"; + String failureCauseFordeleteEdge = "No edge with id " + id + " found in graph"; + + mockDeleteEdge(id, type, "", 400, failureCauseFordeleteEdge); + mockDeleteEdge(id, type, txId, 400, failureCauseFordeleteEdge); + buildChampDao(); + + try { + champDao.deleteEdge(id, type); + } catch (CrudException e) { + assertEquals(400, e.getHttpStatus().getStatusCode()); + assertThat(e.getMessage(), containsString(failureCauseFordeleteEdge)); + } + try { + champDao.deleteEdge(id, type, txId); + } catch (CrudException e) { + assertEquals(400, e.getHttpStatus().getStatusCode()); + assertThat(e.getMessage(), containsString(failureCauseFordeleteEdge)); + } + } + + @Test + public void transactionsTest() { + String id = "test-id"; + int resultCode = 500; + + mockOpenTransaction(resultCode); + mockRollbackTransaction(id, resultCode); + mockCommitTransaction(id, resultCode); + buildChampDao(); + + String response = champDao.openTransaction(); + assertEquals(null, response); + + try { + champDao.rollbackTransaction(id); + } catch (CrudException e) { + assertEquals(500, e.getHttpStatus().getStatusCode()); + assertThat(e.getMessage(), containsString("Unable to rollback transaction")); + } + + try { + champDao.commitTransaction(id); + } catch (CrudException e) { + assertEquals(500, e.getHttpStatus().getStatusCode()); + assertThat(e.getMessage(), containsString("Unable to commit transaction")); + } + } + + public void buildChampDao() { + String baseRelationshipUrl = CHAMP_URL + RELATIONSHIP_SUB_URL; + String baseTransactionUrl = CHAMP_URL + TRANSACTION_SUB_URL; + champDao = new ChampDao(restClientMock, BASE_OBJECT_URL, baseRelationshipUrl, baseTransactionUrl); + } + + public void mockOpenTransaction(int resultCode) { + OperationResult operationResult = new OperationResult(); + operationResult.setResult(""); + operationResult.setResultCode(resultCode); + String url = CHAMP_URL + "transaction"; + + when(restClientMock.post(url, "", createHeader(), MediaType.TEXT_PLAIN_TYPE, MediaType.TEXT_PLAIN_TYPE)) + .thenReturn(operationResult); + } + + public void mockRollbackTransaction(String id, int resultCode) { + OperationResult operationResult = new OperationResult(); + operationResult.setResult(""); + operationResult.setResultCode(resultCode); + String url = CHAMP_URL + TRANSACTION_SUB_URL + "/" + id; + + when(restClientMock.put(url, "{\"method\": \"rollback\"}", createHeader(), MediaType.APPLICATION_JSON_TYPE, + MediaType.TEXT_PLAIN_TYPE)).thenReturn(operationResult); + } + + public void mockCommitTransaction(String id, int resultCode) { + OperationResult operationResult = new OperationResult(); + operationResult.setResult(""); + operationResult.setResultCode(resultCode); + String url = CHAMP_URL + TRANSACTION_SUB_URL + "/" + id; + + when(restClientMock.put(url, "{\"method\": \"commit\"}", createHeader(), MediaType.APPLICATION_JSON_TYPE, + MediaType.TEXT_PLAIN_TYPE)).thenReturn(operationResult); + } + + public void mockGetVertex(String id, String queryParams, String txId, String type, int resultCode, + String failureCause) { + String vertexResponse = champVertex.replace("vertexType", type); + OperationResult operationResult = new OperationResult(); + operationResult.setResult(vertexResponse); + operationResult.setResultCode(resultCode); + operationResult.setFailureCause(failureCause); + String url; + + if (queryParams != null && !queryParams.isEmpty() && (txId.isEmpty() || txId == null)) { + url = BASE_OBJECT_URL + "/" + id + queryParams; + } else if (txId != null && !txId.isEmpty() && (queryParams.isEmpty() || queryParams == null)) { + url = BASE_OBJECT_URL + "/" + id + "?transactionId=" + txId; + } else { + url = BASE_OBJECT_URL + "/" + id; + } + + when(restClientMock.get(url, createHeader(), MediaType.APPLICATION_JSON_TYPE)).thenReturn(operationResult); + } + + public void mockGetVertexEdges(String id, String queryParams, String type, int resultCode, String failureCause) { + String edgeResponse = champEdge.replace("edgeType", type); + OperationResult operationResult = new OperationResult(); + List edgeResponselist = new ArrayList<>(); + edgeResponselist.add(edgeResponse); + operationResult.setResult(edgeResponselist.toString()); + operationResult.setResultCode(resultCode); + operationResult.setFailureCause(failureCause); + + String url = BASE_OBJECT_URL + "/" + RELATIONSHIP_SUB_URL + "/" + id + queryParams; + + when(restClientMock.get(url, createHeader(), MediaType.APPLICATION_JSON_TYPE)).thenReturn(operationResult); + } + + public void mockGetVertices(String queryParams, String type, int resultCode, String failureCause) { + String vertexResponse = champVertex.replace("vertexType", type); + OperationResult operationResult = new OperationResult(); + List vertexResponselist = new ArrayList<>(); + vertexResponselist.add(vertexResponse); + operationResult.setResult(vertexResponselist.toString()); + operationResult.setResultCode(resultCode); + operationResult.setFailureCause(failureCause); + + String url = BASE_OBJECT_URL + "/" + "filter" + queryParams; + + when(restClientMock.get(url, createHeader(), MediaType.APPLICATION_JSON_TYPE)).thenReturn(operationResult); + } + + public void mockGetEdges(String queryParams, String type, int resultCode, String failureCause) { + String edgeResponse = champEdge.replace("edgeType", type); + OperationResult operationResult = new OperationResult(); + List edgeResponselist = new ArrayList<>(); + edgeResponselist.add(edgeResponse); + operationResult.setResult(edgeResponselist.toString()); + operationResult.setResultCode(resultCode); + operationResult.setFailureCause(failureCause); + + String url = CHAMP_URL + RELATIONSHIP_SUB_URL + "/" + "filter" + queryParams; + + when(restClientMock.get(url, createHeader(), MediaType.APPLICATION_JSON_TYPE)).thenReturn(operationResult); + } + + public void mockGetEdge(String id, String queryParams, String txId, String type, int resultCode, + String failureCause) { + String edgeResponse = champEdge.replace("edgeType", type); + OperationResult operationResult = new OperationResult(); + operationResult.setResult(edgeResponse); + operationResult.setResultCode(resultCode); + operationResult.setFailureCause(failureCause); + + String url; + + if (queryParams != null && !queryParams.isEmpty() && (txId.isEmpty() || txId == null)) { + url = CHAMP_URL + RELATIONSHIP_SUB_URL + "/" + id + queryParams; + } else if (txId != null && !txId.isEmpty() && (queryParams.isEmpty() || queryParams == null)) { + url = CHAMP_URL + RELATIONSHIP_SUB_URL + "/" + id + "?transactionId=" + txId; + } else { + url = CHAMP_URL + RELATIONSHIP_SUB_URL + "/" + id; + } + + when(restClientMock.get(url, createHeader(), MediaType.APPLICATION_JSON_TYPE)).thenReturn(operationResult); + } + + public void mockAddEdge(String type, String txId, int resultCode) { + String edgeResponse = champEdge.replace("edgeType", type); + OperationResult operationResult = new OperationResult(); + operationResult.setResult(edgeResponse); + operationResult.setResultCode(resultCode); + + String url; + if (txId != null && !txId.isEmpty()) { + url = CHAMP_URL + RELATIONSHIP_SUB_URL + "?transactionId=" + txId; + } else { + url = CHAMP_URL + RELATIONSHIP_SUB_URL; + } + + when(restClientMock.post(eq(url), anyString(), eq(createHeader()), eq(MediaType.APPLICATION_JSON_TYPE), + eq(MediaType.APPLICATION_JSON_TYPE))).thenReturn(operationResult); + } + + public void mockAddVertex(String type, String payload, String txId, int resultCode) { + String vertexResponse = champVertex.replace("vertexType", type); + OperationResult operationResult = new OperationResult(); + operationResult.setResult(vertexResponse); + operationResult.setResultCode(resultCode); + + String url; + if (txId != null && !txId.isEmpty()) { + url = BASE_OBJECT_URL + "?transactionId=" + txId; + } else { + url = BASE_OBJECT_URL; + } + + when(restClientMock.post(url, payload, createHeader(), MediaType.APPLICATION_JSON_TYPE, + MediaType.APPLICATION_JSON_TYPE)).thenReturn(operationResult); + } + + public void mockPutVertex(String id, String type, String txId, int resultCode) { + String vertexResponse = champVertex.replace("vertexType", type); + OperationResult operationResult = new OperationResult(); + operationResult.setResult(vertexResponse); + operationResult.setResultCode(resultCode); + + String url; + if (txId != null && !txId.isEmpty()) { + url = BASE_OBJECT_URL + "/" + id + "?transactionId=" + txId; + } else { + url = BASE_OBJECT_URL + "/" + id; + } + + when(restClientMock.put(eq(url), anyString(), eq(createHeader()), eq(MediaType.APPLICATION_JSON_TYPE), + eq(MediaType.APPLICATION_JSON_TYPE))).thenReturn(operationResult); + } + + public void mockPutEdge(String id, String type, String txId, int resultCode) { + String edgeResponse = champEdge.replace("edgeType", type); + OperationResult operationResult = new OperationResult(); + operationResult.setResult(edgeResponse); + operationResult.setResultCode(resultCode); + + String url; + if (txId != null && !txId.isEmpty()) { + url = CHAMP_URL + RELATIONSHIP_SUB_URL + "/" + id + "?transactionId=" + txId; + } else { + url = CHAMP_URL + RELATIONSHIP_SUB_URL + "/" + id; + } + + when(restClientMock.put(eq(url), anyString(), eq(createHeader()), eq(MediaType.APPLICATION_JSON_TYPE), + eq(MediaType.APPLICATION_JSON_TYPE))).thenReturn(operationResult); + } + + public void mockDeleteVertex(String id, String type, String txId, int resultCode) { + String vertexResponse = champVertex.replace("vertexType", type); + OperationResult operationResult = new OperationResult(); + operationResult.setResult(vertexResponse); + operationResult.setResultCode(resultCode); + + String url; + if (txId != null && !txId.isEmpty()) { + url = BASE_OBJECT_URL + "/" + id + "?transactionId=" + txId; + } else { + url = BASE_OBJECT_URL + "/" + id; + } + + when(restClientMock.delete(url, createHeader(), MediaType.APPLICATION_JSON_TYPE)).thenReturn(operationResult); + } + + public void mockDeleteEdge(String id, String type, String txId, int resultCode, String failureCause) { + String edgeResponse = champEdge.replace("edgeType", type); + OperationResult operationResult = new OperationResult(); + operationResult.setResult(edgeResponse); + operationResult.setResultCode(resultCode); + operationResult.setFailureCause(failureCause); + + String url; + if (txId != null && !txId.isEmpty()) { + url = CHAMP_URL + RELATIONSHIP_SUB_URL + "/" + id + "?transactionId=" + txId; + } else { + url = CHAMP_URL + RELATIONSHIP_SUB_URL + "/" + id; + } + + when(restClientMock.delete(url, createHeader(), MediaType.APPLICATION_JSON_TYPE)).thenReturn(operationResult); + } + + public ChampDao getChampDao() { + return champDao; + } + + public void setChampDao(ChampDao champDao) { + this.champDao = champDao; + } + + private Map> createHeader() { + Map> headers = new HashMap<>(); + headers.put(HEADER_FROM_APP, Arrays.asList(FROM_APP_NAME)); + headers.put(HEADER_TRANS_ID, Arrays.asList(MDC.get(MdcContext.MDC_REQUEST_ID))); + return headers; + } +} diff --git a/src/test/java/org/onap/crud/service/ChampDaoMockTest.java b/src/test/java/org/onap/crud/service/ChampDaoMockTest.java new file mode 100644 index 0000000..75d5bfd --- /dev/null +++ b/src/test/java/org/onap/crud/service/ChampDaoMockTest.java @@ -0,0 +1,562 @@ +/** + * ============LICENSE_START======================================================= + * org.onap.aai + * ================================================================================ + * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved. + * Copyright © 2017-2018 Amdocs + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ +package org.onap.crud.service; + +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.MultivaluedHashMap; +import javax.ws.rs.core.MultivaluedMap; +import org.onap.aai.logging.LoggingContext; +import org.onap.aai.restclient.client.OperationResult; +import org.onap.aai.restclient.client.RestClient; +import org.onap.crud.dao.champ.ChampDao; +import org.slf4j.MDC; + +public class ChampDaoMockTest { + // @formatter:off + private final String champVertex = "{" + + "\"key\": \"test-uuid\"," + + "\"type\": \"vertexType\"," + + "\"properties\": {" + + "\"fqdn\": \"myhost.onap.com\"," + + "\"hostname\": \"myhost\" } }"; + + private final String champEdge = "{" + + "\"key\": \"test-uuid\"," + + "\"type\": \"edgeType\"," + + "\"properties\": {" + + "\"prevent-delete\": \"NONE\" }," + + "\"source\": {" + + "\"key\": \"50bdab41-ad1c-4d00-952c-a0aa5d827811\", \"type\": \"vserver\"}," + + "\"target\": {" + + "\"key\": \"1d326bc7-b985-492b-9604-0d5d1f06f908\", \"type\": \"pserver\"}" + + " }"; + + private final String edgePayload = "{" + + "\"type\":\"tosca.relationships.HostedOn\"," + + "\"properties\":{" + + "\"prevent-delete\":\"NONE\"}," + + "\"source\":{" + + "\"key\":\"test-uuid\"," + + "\"type\":\"vserver\"," + + "\"properties\":{}}," + + "\"target\":{" + + "\"key\":\"test-uuid\"," + + "\"type\":\"pserver\"," + + "\"properties\":{" + + "\"hostname\":\"myhost\"," + + "\"fqdn\":\"myhost.onap.com\"}}}"; + + private final String edgePayloadForPut = "{" + + "\"key\":\"test-uuid\"," + + "\"type\":\"tosca.relationships.HostedOn\"," + + "\"properties\":{" + + "\"prevent-delete\":\"NONE\"}," + + "\"source\":{" + + "\"key\":\"50bdab41-ad1c-4d00-952c-a0aa5d827811\"," + + "\"type\":\"vserver\"," + + "\"properties\":{}}," + + "\"target\":{" + + "\"key\":\"1d326bc7-b985-492b-9604-0d5d1f06f908\"," + + "\"type\":\"pserver\"," + + "\"properties\":{}}}"; + + private final String edgePayloadForPatch = "{" + + "\"key\":\"test-uuid\"," + + "\"type\":\"tosca.relationships.HostedOn\"," + + "\"properties\":{" + + "\"prevent-delete\":\"NONE\"}," + + "\"source\":{" + + "\"key\":\"50bdab41-ad1c-4d00-952c-a0aa5d827811\"," + + "\"type\":\"vserver\"}," + + "\"target\":{" + + "\"key\":\"1d326bc7-b985-492b-9604-0d5d1f06f908\"," + + "\"type\":\"pserver\"}}"; + + private final String edgePayloadForPost = "{" + + "\"type\":\"tosca.relationships.HostedOn\"," + + "\"properties\":{" + + "\"SVC-INFRA\":\"OUT\"," + + "\"prevent-delete\":\"IN\"," + + "\"delete-other-v\":\"NONE\"," + + "\"contains-other-v\":\"NONE\"" + + "}," + + "\"source\":{" + + "\"key\":\"test-uuid\"," + + "\"type\":\"vserver\"," + + "\"properties\":{" + + "" + + "}" + + "}," + + "\"target\":{" + + "\"key\":\"test-uuid\"," + + "\"type\":\"pserver\"," + + "\"properties\":{" + + "\"hostname\":\"myhost\"," + + "\"fqdn\":\"myhost.onap.com\"" + + "}" + + "}" + + "}"; + + private final String edgePayloadForPutNoProperties = "{" + + "\"key\":\"test-uuid\"," + + "\"type\":\"tosca.relationships.HostedOn\"," + + "\"properties\":{" + + "\"SVC-INFRA\":\"OUT\"," + + "\"prevent-delete\":\"IN\"," + + "\"delete-other-v\":\"NONE\"," + + "\"contains-other-v\":\"NONE\"" + + "}," + + "\"source\":{" + + "\"key\":\"50bdab41-ad1c-4d00-952c-a0aa5d827811\"," + + "\"type\":\"vserver\"," + + "\"properties\":{" + + "" + + "}" + + "}," + + "\"target\":{" + + "\"key\":\"1d326bc7-b985-492b-9604-0d5d1f06f908\"," + + "\"type\":\"pserver\"," + + "\"properties\":{" + + "" + + "}" + + "}" + + "}"; + + private final String vertexPayload = "{" + + "\"type\":\"pserver\"," + + "\"properties\":{" + + "\"hostname\":\"myhost\"," + + "\"in-maint\":false," + + "\"fqdn\":\"myhost.onap.com\"," + + "\"last-mod-source-of-truth\":\"source-of-truth\"," + + "\"source-of-truth\":\"source-of-truth\"," + + "\"aai-node-type\":\"pserver\"}}"; + + private final String vertexPayloadForVserver = "{" + + "\"type\":\"vserver\"," + + "\"properties\":{" + + "\"in-maint\":false," + + "\"vserver-name\":\"test-vserver\"," + + "\"vserver-id\":\"VSER1\"," + + "\"last-mod-source-of-truth\":\"source-of-truth\"," + + "\"vserver-name2\":\"alt-test-vserver\"," + + "\"source-of-truth\":\"source-of-truth\"," + + "\"vserver-selflink\":\"http://1.2.3.4/moreInfo\"," + + "\"is-closed-loop-disabled\":false," + + "\"aai-node-type\":\"vserver\"}}"; + + private final String vertexPayloadForPserver = "{" + + "\"key\":\"50bdab41-ad1c-4d00-952c-a0aa5d827811\"," + + "\"type\":\"pserver\"," + + "\"properties\":{" + + "\"ptnii-equip-name\":\"e-name\"," + + "\"hostname\":\"steve-host2\"," + + "\"equip-type\":\"server\"," + + "\"equip-vendor\":\"HP\"," + + "\"equip-model\":\"DL380p-nd\"," + + "\"in-maint\":false," + + "\"fqdn\":\"myhost.onap.net\"," + + "\"purpose\":\"my-purpose\"," + + "\"ipv4-oam-address\":\"1.2.3.4\"," + + "\"last-mod-source-of-truth\":\"source-of-truth\"," + + "\"aai-node-type\":\"pserver\"}}"; + + private final String vertexPayloadForPut = "{" + + "\"key\":\"test-uuid\"," + + "\"type\":\"pserver\"," + + "\"properties\":{" + + "\"hostname\":\"myhost\"," + + "\"in-maint\":false," + + "\"fqdn\":\"myhost.onap.com\"," + + "\"last-mod-source-of-truth\":\"source-of-truth\"," + + "\"aai-node-type\":\"pserver\"}}"; + + private final String vertexPayloadForPatch = "{" + + "\"key\":\"test-uuid\"," + + "\"type\":\"pserver\"," + + "\"properties\":{" + + "\"hostname\":\"myhost\"," + + "\"fqdn\":\"myhost.onap.com\"," + + "\"last-mod-source-of-truth\":\"source-of-truth\"," + + "\"aai-node-type\":\"pserver\"}}"; + // @formatter:on + + private RestClient restClientMock; + private ChampDao champDao; + + static final String CHAMP_URL = "https://host:9522/services/champ-service/v1/"; + static final String OBJECT_SUB_URL = "objects"; + static final String RELATIONSHIP_SUB_URL = "relationships"; + static final String TRANSACTION_SUB_URL = "transaction"; + static final String BASE_OBJECT_URL = CHAMP_URL + OBJECT_SUB_URL; + static final String HEADER_FROM_APP = "X-FromAppId"; + static final String HEADER_TRANS_ID = "X-TransactionId"; + static final String FROM_APP_NAME = "Gizmo"; + static final String HEADER_TRANS_ID_VALUE = "1234567890"; + + ChampDaoMockTest() { + restClientMock = mock(RestClient.class); + init(); + buildChampDao(); + } + + public void init() { + + Map queryParamsVertex = new HashMap<>(); + queryParamsVertex.put("_reserved_version", "v11"); + queryParamsVertex.put("hostname", "myhost"); + queryParamsVertex.put("_reserved_aai-type", "pserver"); + + Map queryParamsVertexV13 = new HashMap<>(); + queryParamsVertexV13.put("_reserved_version", "v13"); + queryParamsVertexV13.put("hostname", "myhost"); + queryParamsVertexV13.put("_reserved_aai-type", "pserver"); + + Map queryParamsVertices = new HashMap<>(); + queryParamsVertices.put("_reserved_version", "v11"); + queryParamsVertices.put("hostname", "myhost"); + queryParamsVertices.put("_reserved_aai-type", "pserver"); + queryParamsVertices.put("aai-node-type", "pserver"); + + Map queryParamsVerticesV13 = new HashMap<>(); + queryParamsVerticesV13.put("_reserved_version", "v13"); + queryParamsVerticesV13.put("hostname", "myhost"); + queryParamsVerticesV13.put("_reserved_aai-type", "pserver"); + queryParamsVerticesV13.put("aai-node-type", "pserver"); + + Map queryParamsEdge = new HashMap<>(); + queryParamsEdge.put("_reserved_version", "v11"); + queryParamsEdge.put("hostname", "myhost"); + queryParamsEdge.put("_reserved_aai-type", "tosca.relationships.HostedOn"); + + Map emptyQueryParams = null; + + mockOpenTransaction(); + mockRollbackTransaction(""); + mockTransactionExists(""); + mockCommitTransaction(""); + mockGetVertex("872dd5df-0be9-4167-95e9-2cf4b21165ed", queryParamsVertex, "pserver"); + mockGetVertex("872dd5df-0be9-4167-95e9-2cf4b21165ed", queryParamsVertexV13, "pserver"); + mockGetVertex("50bdab41-ad1c-4d00-952c-a0aa5d827811", "", "vserver"); + mockGetVertex("1d326bc7-b985-492b-9604-0d5d1f06f908", "", "pserver"); + mockGetVertex("1d326bc7-b985-492b-9604-0d5d1f06f908", "?transactionId=", "pserver"); + mockGetVertex("test-uuid", "", "pserver"); + mockGetVertex("50bdab41-ad1c-4d00-952c-a0aa5d827811", "?transactionId=", "vserver"); + mockGetVertices(queryParamsVertices, "pserver"); + mockGetVertices(queryParamsVerticesV13, "pserver"); + mockGetVertexEdges("872dd5df-0be9-4167-95e9-2cf4b21165ed", queryParamsVertex, "tosca.relationships.HostedOn"); + mockGetVertexEdges("872dd5df-0be9-4167-95e9-2cf4b21165ed", queryParamsVertexV13, + "tosca.relationships.HostedOn"); + mockGetVertexEdges("50bdab41-ad1c-4d00-952c-a0aa5d827811", emptyQueryParams, "tosca.relationships.HostedOn"); + mockGetVertexEdges("1d326bc7-b985-492b-9604-0d5d1f06f908", emptyQueryParams, "tosca.relationships.HostedOn"); + mockGetEdges("?", "tosca.relationships.HostedOn"); + mockGetEdge("50bdab41-ad1c-4d00-952c-a0aa5d827811", "?transactionId=", "tosca.relationships.HostedOn"); + mockGetEdge("872dd5df-0be9-4167-95e9-2cf4b21165ed", emptyQueryParams, "tosca.relationships.HostedOn"); + mockGetEdge("872dd5df-0be9-4167-95e9-2cf4b21165ed", queryParamsEdge, "tosca.relationships.HostedOn"); + mockGetEdge("my-uuid", emptyQueryParams, "tosca.relationships.HostedOn"); + mockGetEdge("50bdab41-ad1c-4d00-952c-a0aa5d827811", queryParamsEdge, "tosca.relationships.HostedOn"); + mockPostEdge("tosca.relationships.HostedOn", "", edgePayload); + mockPostEdge("tosca.relationships.HostedOn", "?transactionId=", edgePayloadForPost); + mockPostVertex("pserver", vertexPayload, ""); + mockPostVertex("vserver", vertexPayloadForVserver, "?transactionId="); + mockPutVertex("test-uuid", "pserver", vertexPayloadForPut, ""); + mockPutVertex("test-uuid", "pserver", vertexPayloadForPatch, ""); + mockPutVertex("50bdab41-ad1c-4d00-952c-a0aa5d827811", "pserver", vertexPayloadForPserver, "?transactionId="); + mockPutEdge("test-uuid", "tosca.relationships.HostedOn", "", edgePayloadForPut); + mockPutEdge("test-uuid", "tosca.relationships.HostedOn", "", edgePayloadForPatch); + mockPutEdge("test-uuid", "tosca.relationships.HostedOn", "?transactionId=", edgePayloadForPutNoProperties); + mockDeleteVertex("872dd5df-0be9-4167-95e9-2cf4b21165ed", "pserver", ""); + mockDeleteVertex("50bdab41-ad1c-4d00-952c-a0aa5d827811", "pserver", "?transactionId="); + mockDeleteEdge("872dd5df-0be9-4167-95e9-2cf4b21165ed", "tosca.relationships.HostedOn", ""); + mockDeleteEdge("50bdab41-ad1c-4d00-952c-a0aa5d827811", "tosca.relationships.HostedOn", "?transactionId="); + } + + public void buildChampDao() { + String baseRelationshipUrl = CHAMP_URL + RELATIONSHIP_SUB_URL; + String baseTransactionUrl = CHAMP_URL + TRANSACTION_SUB_URL; + champDao = new ChampDao(restClientMock, BASE_OBJECT_URL, baseRelationshipUrl, baseTransactionUrl); + } + + public void mockOpenTransaction() { + OperationResult operationResult = new OperationResult(); + operationResult.setResult(""); + operationResult.setResultCode(200); + String url = CHAMP_URL + "transaction"; + + + when(restClientMock.post(url, "", createHeaders(), MediaType.TEXT_PLAIN_TYPE, MediaType.TEXT_PLAIN_TYPE)) + .thenReturn(operationResult); + } + + public void mockRollbackTransaction(String id) { + OperationResult operationResult = new OperationResult(); + operationResult.setResult(""); + operationResult.setResultCode(200); + String url = CHAMP_URL + TRANSACTION_SUB_URL + "/" + id; + + + when(restClientMock.put(url, "{\"method\": \"rollback\"}", createHeaders(), MediaType.APPLICATION_JSON_TYPE, + MediaType.TEXT_PLAIN_TYPE)).thenReturn(operationResult); + } + + public void mockCommitTransaction(String id) { + OperationResult operationResult = new OperationResult(); + operationResult.setResult(""); + operationResult.setResultCode(200); + String url = CHAMP_URL + TRANSACTION_SUB_URL + "/" + id; + + + when(restClientMock.put(url, "{\"method\": \"commit\"}", createHeaders(), MediaType.APPLICATION_JSON_TYPE, + MediaType.TEXT_PLAIN_TYPE)).thenReturn(operationResult); + } + + public void mockTransactionExists(String id) { + OperationResult operationResult = new OperationResult(); + operationResult.setResult(""); + operationResult.setResultCode(200); + String url = CHAMP_URL + TRANSACTION_SUB_URL + "/" + id; + + Map> headers = new HashMap<>(); + headers.put(HEADER_FROM_APP, Arrays.asList(FROM_APP_NAME)); + headers.put(HEADER_TRANS_ID, Arrays.asList(MDC.get(LoggingContext.LoggingField.REQUEST_ID.toString()))); + + when(restClientMock.get(url, headers, MediaType.APPLICATION_JSON_TYPE)).thenReturn(operationResult); + } + + public void mockGetVertex(String id, String txId, String type) { + String vertexResponse = champVertex.replace("vertexType", type); + OperationResult operationResult = new OperationResult(); + operationResult.setResult(vertexResponse); + operationResult.setResultCode(200); + + String url = BASE_OBJECT_URL + "/" + id + txId; + + + when(restClientMock.get(url, createHeaders(), MediaType.APPLICATION_JSON_TYPE)).thenReturn(operationResult); + } + + public void mockGetVertex(String id, Map queryParams, String type) { + String vertexResponse = champVertex.replace("vertexType", type); + OperationResult operationResult = new OperationResult(); + operationResult.setResult(vertexResponse); + operationResult.setResultCode(200); + + StringBuilder url = appendQueryParams(BASE_OBJECT_URL + "/" + id, queryParams); + + when(restClientMock.get(url.toString(), createHeaders(), MediaType.APPLICATION_JSON_TYPE)) + .thenReturn(operationResult); + } + + public void mockGetVertexEdges(String id, Map queryParams, String type) { + String edgeResponse = champEdge.replace("edgeType", type); + OperationResult operationResult = new OperationResult(); + List edgeResponselist = new ArrayList<>(); + edgeResponselist.add(edgeResponse); + operationResult.setResult(edgeResponselist.toString()); + operationResult.setResultCode(200); + + StringBuilder url = appendQueryParams(BASE_OBJECT_URL + "/" + RELATIONSHIP_SUB_URL + "/" + id, queryParams); + + when(restClientMock.get(url.toString(), createHeaders(), MediaType.APPLICATION_JSON_TYPE)) + .thenReturn(operationResult); + } + + public void mockGetVertices(Map queryParams, String type) { + String vertexResponse = champVertex.replace("vertexType", type); + OperationResult operationResult = new OperationResult(); + List vertexResponselist = new ArrayList<>(); + vertexResponselist.add(vertexResponse); + operationResult.setResult(vertexResponselist.toString()); + operationResult.setResultCode(200); + + StringBuilder url = appendQueryParams(BASE_OBJECT_URL + "/" + "filter", queryParams); + + when(restClientMock.get(url.toString(), createHeaders(), MediaType.APPLICATION_JSON_TYPE)) + .thenReturn(operationResult); + } + + public void mockGetEdges(String queryParams, String type) { + String edgeResponse = champEdge.replace("edgeType", type); + OperationResult operationResult = new OperationResult(); + List edgeResponselist = new ArrayList<>(); + edgeResponselist.add(edgeResponse); + operationResult.setResult(edgeResponselist.toString()); + operationResult.setResultCode(200); + + String url = CHAMP_URL + RELATIONSHIP_SUB_URL + "/" + "filter" + queryParams; + + + when(restClientMock.get(url, createHeaders(), MediaType.APPLICATION_JSON_TYPE)).thenReturn(operationResult); + } + + public void mockGetEdge(String id, String txId, String type) { + String edgeResponse = champEdge.replace("edgeType", type); + OperationResult operationResult = new OperationResult(); + operationResult.setResult(edgeResponse); + operationResult.setResultCode(200); + + String url = CHAMP_URL + RELATIONSHIP_SUB_URL + "/" + id + txId; + + when(restClientMock.get(url, createHeaders(), MediaType.APPLICATION_JSON_TYPE)).thenReturn(operationResult); + } + + public void mockGetEdge(String id, Map queryParams, String type) { + String edgeResponse = champEdge.replace("edgeType", type); + OperationResult operationResult = new OperationResult(); + operationResult.setResult(edgeResponse); + operationResult.setResultCode(200); + + StringBuilder url = appendQueryParams(CHAMP_URL + RELATIONSHIP_SUB_URL + "/" + id, queryParams); + + when(restClientMock.get(url.toString(), createHeaders(), MediaType.APPLICATION_JSON_TYPE)) + .thenReturn(operationResult); + } + + public void mockPostEdge(String type, String txId, String payload) { + String edgeResponse = champEdge.replace("edgeType", type); + OperationResult operationResult = new OperationResult(); + operationResult.setResult(edgeResponse); + operationResult.setResultCode(201); + MultivaluedMap headers = new MultivaluedHashMap(); + headers.add("etag", "test123"); + operationResult.setHeaders(headers); + + String baseRelationshipUrl = CHAMP_URL + RELATIONSHIP_SUB_URL + txId; + String url = baseRelationshipUrl; + + + when(restClientMock.post(url, payload, createHeaders(), MediaType.APPLICATION_JSON_TYPE, + MediaType.APPLICATION_JSON_TYPE)).thenReturn(operationResult); + } + + public void mockPostVertex(String type, String payload, String txId) { + String vertexResponse = champVertex.replace("vertexType", type); + OperationResult operationResult = new OperationResult(); + operationResult.setResult(vertexResponse); + operationResult.setResultCode(201); + MultivaluedMap headers = new MultivaluedHashMap(); + headers.add("etag", "test123"); + operationResult.setHeaders(headers); + + String url = BASE_OBJECT_URL + txId; + + + when(restClientMock.post(url, payload, createHeaders(), MediaType.APPLICATION_JSON_TYPE, + MediaType.APPLICATION_JSON_TYPE)).thenReturn(operationResult); + } + + public void mockPutVertex(String id, String type, String payload, String txId) { + String vertexResponse = champVertex.replace("vertexType", type); + OperationResult operationResult = new OperationResult(); + operationResult.setResult(vertexResponse); + operationResult.setResultCode(200); + MultivaluedMap headers = new MultivaluedHashMap(); + headers.add("etag", "test123"); + operationResult.setHeaders(headers); + + String url = BASE_OBJECT_URL + "/" + id + txId; + + + when(restClientMock.put(url, payload, createHeaders(), MediaType.APPLICATION_JSON_TYPE, + MediaType.APPLICATION_JSON_TYPE)).thenReturn(operationResult); + } + + public void mockPutEdge(String id, String type, String txId, String payload) { + String edgeResponse = champEdge.replace("edgeType", type); + OperationResult operationResult = new OperationResult(); + operationResult.setResult(edgeResponse); + operationResult.setResultCode(200); + MultivaluedMap headers = new MultivaluedHashMap(); + headers.add("etag", "test123"); + operationResult.setHeaders(headers); + + String url = CHAMP_URL + RELATIONSHIP_SUB_URL + "/" + id + txId; + + + when(restClientMock.put(url, payload, createHeaders(), MediaType.APPLICATION_JSON_TYPE, + MediaType.APPLICATION_JSON_TYPE)).thenReturn(operationResult); + } + + public void mockDeleteVertex(String id, String type, String txId) { + String vertexResponse = champVertex.replace("vertexType", type); + OperationResult operationResult = new OperationResult(); + operationResult.setResult(vertexResponse); + operationResult.setResultCode(200); + + String url = BASE_OBJECT_URL + "/" + id + txId; + + + when(restClientMock.delete(url, createHeaders(), MediaType.APPLICATION_JSON_TYPE)).thenReturn(operationResult); + } + + public void mockDeleteEdge(String id, String type, String txId) { + String edgeResponse = champEdge.replace("edgeType", type); + OperationResult operationResult = new OperationResult(); + operationResult.setResult(edgeResponse); + operationResult.setResultCode(200); + + String url = CHAMP_URL + RELATIONSHIP_SUB_URL + "/" + id + txId; + + + when(restClientMock.delete(url, createHeaders(), MediaType.APPLICATION_JSON_TYPE)).thenReturn(operationResult); + } + + private Map> createHeaders() { + Map> headers = new HashMap<>(); + List listFromApp = new ArrayList<>(); + List listTransId = new ArrayList<>(); + listFromApp.add(FROM_APP_NAME); + listTransId.add(HEADER_TRANS_ID_VALUE); + headers.put(HEADER_FROM_APP, listFromApp); + headers.put(HEADER_TRANS_ID, listTransId); + + return headers; + } + + private StringBuilder appendQueryParams(String url, Map queryParams) { + StringBuilder strBuilder = new StringBuilder(url); + + if (queryParams != null) { + String prefix = "?"; + for (Map.Entry entry : queryParams.entrySet()) { + strBuilder.append(prefix); + prefix = "&"; + strBuilder.append(entry.getKey() + "=" + entry.getValue()); + } + } + return strBuilder; + } + + public ChampDao getChampDao() { + return champDao; + } + + public void setChampDao(ChampDao champDao) { + this.champDao = champDao; + } +} diff --git a/src/test/java/org/onap/crud/service/CrudRestServiceTest.java b/src/test/java/org/onap/crud/service/CrudRestServiceTest.java index ddf3847..d8be704 100644 --- a/src/test/java/org/onap/crud/service/CrudRestServiceTest.java +++ b/src/test/java/org/onap/crud/service/CrudRestServiceTest.java @@ -77,12 +77,11 @@ public class CrudRestServiceTest { @Before public void init() throws Exception { - ClassLoader classLoader = getClass().getClassLoader(); - File dir = new File(classLoader.getResource("rules").getFile()); - System.setProperty("CONFIG_HOME", dir.getParent()); + System.setProperty("CONFIG_HOME", "src/test/resources"); EdgeRulesLoader.resetSchemaVersionContext(); - CrudGraphDataService service = new CrudGraphDataService(new TestDao()); + ChampDaoMockTest champDaoTest = new ChampDaoMockTest(); + CrudGraphDataService service = new CrudGraphDataService(champDaoTest.getChampDao()); CrudRestService restService = new CrudRestService(service, null); mockService = Mockito.spy(restService); diff --git a/src/test/java/org/onap/crud/service/TestEventConsumer.java b/src/test/java/org/onap/crud/service/TestEventConsumer.java new file mode 100644 index 0000000..8f864f8 --- /dev/null +++ b/src/test/java/org/onap/crud/service/TestEventConsumer.java @@ -0,0 +1,58 @@ +/** + * ============LICENSE_START======================================================= + * org.onap.aai + * ================================================================================ + * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved. + * Copyright © 2017-2018 Amdocs + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ +package org.onap.crud.service; + +import org.onap.aai.event.api.EventConsumer; +import org.onap.aai.event.api.MessageWithOffset; + +public class TestEventConsumer implements EventConsumer { + + @Override + public void commitOffsets() throws Exception { + // TODO Auto-generated method stub + + } + + @Override + public void commitOffsets(long arg0) throws Exception { + // TODO Auto-generated method stub + + } + + @Override + public Iterable consume() throws Exception { + // TODO Auto-generated method stub + return null; + } + + @Override + public Iterable consumeAndCommit() throws Exception { + // TODO Auto-generated method stub + return null; + } + + @Override + public Iterable consumeWithOffsets() throws Exception { + // TODO Auto-generated method stub + return null; + } + +} diff --git a/src/test/java/org/onap/crud/service/TestEventPublisher.java b/src/test/java/org/onap/crud/service/TestEventPublisher.java new file mode 100644 index 0000000..3931c44 --- /dev/null +++ b/src/test/java/org/onap/crud/service/TestEventPublisher.java @@ -0,0 +1,82 @@ +/** + * ============LICENSE_START======================================================= + * org.onap.aai + * ================================================================================ + * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved. + * Copyright © 2017-2018 Amdocs + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ +package org.onap.crud.service; + +import java.util.Collection; +import org.onap.aai.event.api.EventPublisher; + +public class TestEventPublisher implements EventPublisher { + + @Override + public void close() throws Exception { + // TODO Auto-generated method stub + + } + + @Override + public void sendAsync(String arg0) throws Exception { + // TODO Auto-generated method stub + + } + + @Override + public void sendAsync(Collection arg0) throws Exception { + // TODO Auto-generated method stub + + } + + @Override + public void sendAsync(String arg0, String arg1) throws Exception { + // TODO Auto-generated method stub + + } + + @Override + public void sendAsync(String arg0, Collection arg1) throws Exception { + // TODO Auto-generated method stub + + } + + @Override + public int sendSync(String arg0) throws Exception { + // TODO Auto-generated method stub + return 0; + } + + @Override + public int sendSync(Collection arg0) throws Exception { + // TODO Auto-generated method stub + return 0; + } + + @Override + public int sendSync(String arg0, String arg1) throws Exception { + // TODO Auto-generated method stub + return 0; + } + + @Override + public int sendSync(String arg0, Collection arg1) throws Exception { + // TODO Auto-generated method stub + return 0; + } + +} diff --git a/src/test/java/org/onap/crud/service/TestResourceServiceEdgeOperations.java b/src/test/java/org/onap/crud/service/TestResourceServiceEdgeOperations.java new file mode 100644 index 0000000..4998e74 --- /dev/null +++ b/src/test/java/org/onap/crud/service/TestResourceServiceEdgeOperations.java @@ -0,0 +1,284 @@ +/** + * ============LICENSE_START======================================================= + * org.onap.aai + * ================================================================================ + * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved. + * Copyright © 2017-2018 Amdocs + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ +package org.onap.crud.service; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Matchers.any; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; +import java.security.cert.X509Certificate; +import java.util.Collections; +import java.util.List; +import java.util.Map.Entry; +import javax.security.auth.x500.X500Principal; +import javax.ws.rs.core.EntityTag; +import javax.ws.rs.core.HttpHeaders; +import javax.ws.rs.core.MultivaluedHashMap; +import javax.ws.rs.core.Response; +import javax.ws.rs.core.UriInfo; +import org.apache.commons.lang3.tuple.ImmutablePair; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; +import org.mockito.Mockito; +import org.onap.crud.exception.CrudException; +import org.onap.crud.util.TestUtil; +import org.onap.schema.OxmModelLoader; +import org.springframework.mock.web.MockHttpServletRequest; +import com.att.aft.dme2.internal.jersey.api.client.ClientResponse.Status; + +public class TestResourceServiceEdgeOperations { + + private MockHttpServletRequest servletRequest; + private UriInfo uriInfo; + private HttpHeaders headers; + private AbstractGraphDataService graphDataService; + + @BeforeClass + public static void setUpBeforeClass() throws Exception { + System.setProperty("CONFIG_HOME", "src/test/resources"); + System.setProperty("AJSC_HOME", "."); + System.setProperty("BUNDLECONFIG_DIR", "src/test/resources/bundleconfig-local"); + + OxmModelLoader.loadModels(); + } + + @Before + public void setUp() throws Exception { + graphDataService = mock(CrudGraphDataService.class); + uriInfo = mock(UriInfo.class); + + mockHeaderRequests(getCreateHeaders()); + + servletRequest = new MockHttpServletRequest(); + servletRequest.setSecure(true); + servletRequest.setScheme("https"); + servletRequest.setServerPort(9520); + servletRequest.setServerName("localhost"); + servletRequest.setRequestURI("/services/inventory/relationships/"); + + setUser("CN=ONAP, OU=ONAP, O=ONAP, L=Ottawa, ST=Ontario, C=CA"); + + servletRequest.setAttribute("javax.servlet.request.cipher_suite", ""); + } + + private MultivaluedHashMap getCreateHeaders() { + MultivaluedHashMap headersMap = new MultivaluedHashMap<>(); + headersMap.put("X-TransactionId", createSingletonList("transaction-id")); + headersMap.put("X-FromAppId", createSingletonList("app-id")); + headersMap.put("Host", createSingletonList("hostname")); + return headersMap; + } + + private void mockHeaderRequests(MultivaluedHashMap headersMap) { + headers = Mockito.mock(HttpHeaders.class); + for (Entry> entry : headersMap.entrySet()) { + when(headers.getRequestHeader(entry.getKey())).thenReturn(entry.getValue()); + } + when(headers.getRequestHeaders()).thenReturn(headersMap); + } + + @Test + public void testCreateRelationship() throws Exception { + String postEdgeBody = TestUtil.getFileAsString("aai-resource-service/post-edge-auto-props.json"); + + Response response = callCreateRelationship(postEdgeBody); + + assertThat(response.getStatus()).isEqualTo(Status.CREATED.getStatusCode()); + } + + @Test + public void testCreateRelationshipWithMatchingType() throws Exception { + String postEdgeBody = TestUtil.getFileAsString("aai-resource-service/post-edge-auto-props.json"); + String type = "tosca.relationships.HostedOn"; + + Response response = createRelationshipWithType(postEdgeBody, type); + + assertThat(response.getStatus()).isEqualTo(Status.CREATED.getStatusCode()); + } + + @Test + public void testCreateRelationshipNoMatchingType() throws Exception { + String postEdgeBody = TestUtil.getFileAsString("aai-resource-service/post-edge-auto-props.json"); + String type = "type.does.not.match"; + + Response response = createRelationshipWithType(postEdgeBody, type); + + assertThat(response.getStatus()).isEqualTo(Status.BAD_REQUEST.getStatusCode()); + } + + @Test + public void testCreateRelationshipWithTypeNullPropsIsBadRequest() throws Exception { + String postEdgeBody = TestUtil.getFileAsString("aai-resource-service/post-edge-null-props.json"); + String type = "tosca.relationships.HostedOn"; + + Response response = createRelationshipWithType(postEdgeBody, type); + + assertThat(response.getStatus()).isEqualTo(Status.BAD_REQUEST.getStatusCode()); + } + + @Test + public void testCreateRelationshipWithTypeWithIdIsBadRequest() throws Exception { + String postEdgeBody = TestUtil.getFileAsString("aai-resource-service/post-edge-with-id.json"); + String type = "tosca.relationships.HostedOn"; + + Response response = createRelationshipWithType(postEdgeBody, type); + + assertThat(response.getStatus()).isEqualTo(Status.BAD_REQUEST.getStatusCode()); + } + + @Test + public void testInvalidUser() throws Exception { + String postEdgeBody = TestUtil.getFileAsString("aai-resource-service/post-edge-auto-props.json"); + + setUser("CN=INVALID, OU=INVALID, O=INVALID, L=Ottawa, ST=Ontario, C=CA"); + + Response response = callCreateRelationship(postEdgeBody); + + assertThat(response.getStatus()).isEqualTo(Status.FORBIDDEN.getStatusCode()); + } + + @Test + public void testNullPropertiesIsBadRequest() throws Exception { + String postEdgeBody = TestUtil.getFileAsString("aai-resource-service/post-edge-null-props.json"); + + Response response = callCreateRelationship(postEdgeBody); + + assertThat(response.getStatus()).isEqualTo(Status.BAD_REQUEST.getStatusCode()); + } + + @Test + public void testNoPropertiesIsBadRequest() throws Exception { + String postEdgeBody = TestUtil.getFileAsString("aai-resource-service/post-edge-no-props.json"); + + Response response = callCreateRelationship(postEdgeBody); + + assertThat(response.getStatus()).isEqualTo(Status.BAD_REQUEST.getStatusCode()); + } + + @Test + public void testCreateWithIdIsBadRequest() throws Exception { + String postEdgeBody = TestUtil.getFileAsString("aai-resource-service/post-edge-with-id.json"); + + Response response = callCreateRelationship(postEdgeBody); + + assertThat(response.getStatus()).isEqualTo(Status.BAD_REQUEST.getStatusCode()); + } + + @Test + public void testNoTypeIsBadRequest() throws Exception { + String postEdgeBody = TestUtil.getFileAsString("aai-resource-service/post-edge-no-type.json"); + + Response response = callCreateRelationship(postEdgeBody); + + assertThat(response.getStatus()).isEqualTo(Status.BAD_REQUEST.getStatusCode()); + } + + @Test + public void testPatchEdge() throws Exception { + MultivaluedHashMap headersMap = getCreateHeaders(); + headersMap.put(AaiResourceService.HTTP_PATCH_METHOD_OVERRIDE, createSingletonList("PATCH")); + mockHeaderRequests(headersMap); + + String postEdgeBody = TestUtil.getFileAsString("aai-resource-service/post-edge-upsert.json"); + String type = "tosca.relationships.HostedOn"; + String id = "12345"; + EntityTag entityTag = new EntityTag("1234"); + + when(graphDataService.patchEdge(any(), any(), any(), any())).thenReturn(new ImmutablePair(entityTag, "dummy output")); + AaiResourceService aaiResourceService = new AaiResourceService(graphDataService); + Response response = + aaiResourceService.upsertEdge(postEdgeBody, type, id, "uri", headers, uriInfo, servletRequest); + assertThat(response.getStatus()).isEqualTo(Status.OK.getStatusCode()); + } + + @Test + public void testUpdateEdge() throws Exception { + String postEdgeBody = TestUtil.getFileAsString("aai-resource-service/post-edge-upsert.json"); + String type = "tosca.relationships.HostedOn"; + String id = "12345"; + EntityTag entityTag = new EntityTag("1234"); + + when(graphDataService.updateEdge(any(), any(), any(), any())).thenReturn(new ImmutablePair(entityTag, "dummy output")); + AaiResourceService aaiResourceService = new AaiResourceService(graphDataService); + Response response = + aaiResourceService.upsertEdge(postEdgeBody, type, id, "uri", headers, uriInfo, servletRequest); + assertThat(response.getStatus()).isEqualTo(Status.OK.getStatusCode()); + } + + @Test + public void testUpdateEdgeNullPropsIsBadRequest() throws Exception { + String postEdgeBody = TestUtil.getFileAsString("aai-resource-service/post-edge-null-props.json"); + String type = "tosca.relationships.HostedOn"; + String id = "12345"; + EntityTag entityTag = new EntityTag("1234"); + + when(graphDataService.updateEdge(any(), any(), any(), any())).thenReturn(new ImmutablePair(entityTag, "dummy output")); + AaiResourceService aaiResourceService = new AaiResourceService(graphDataService); + Response response = + aaiResourceService.upsertEdge(postEdgeBody, type, id, "uri", headers, uriInfo, servletRequest); + assertThat(response.getStatus()).isEqualTo(Status.BAD_REQUEST.getStatusCode()); + } + + @Test + public void testUpdateEdgeWithMismatchIdIsBadRequest() throws Exception { + String postEdgeBody = TestUtil.getFileAsString("aai-resource-service/post-edge-upsert.json"); + String type = "tosca.relationships.HostedOn"; + String id = "mismatch"; + EntityTag entityTag = new EntityTag("1234"); + + when(graphDataService.updateEdge(any(), any(), any(), any())).thenReturn(new ImmutablePair(entityTag, "dummy output")); + AaiResourceService aaiResourceService = new AaiResourceService(graphDataService); + Response response = + aaiResourceService.upsertEdge(postEdgeBody, type, id, "uri", headers, uriInfo, servletRequest); + assertThat(response.getStatus()).isEqualTo(Status.BAD_REQUEST.getStatusCode()); + } + + private Response createRelationshipWithType(String postEdgeBody, String type) throws CrudException, Exception { + EntityTag entityTag = new EntityTag("1234"); + + when(graphDataService.addEdge(any(), any(), any())).thenReturn(new ImmutablePair(entityTag, "dummy output")); + AaiResourceService aaiResourceService = new AaiResourceService(graphDataService); + Response response = + aaiResourceService.createRelationship(postEdgeBody, type, "uri", headers, uriInfo, servletRequest); + return response; + } + + private Response callCreateRelationship(String postEdgeBody) throws CrudException, Exception { + EntityTag entityTag = new EntityTag("1234"); + + when(graphDataService.addEdge(any(), any(), any())).thenReturn(new ImmutablePair(entityTag, "dummy output")); + AaiResourceService aaiResourceService = new AaiResourceService(graphDataService); + Response response = + aaiResourceService.createRelationship(postEdgeBody, "uri", headers, uriInfo, servletRequest); + return response; + } + + private void setUser(String user) { + X509Certificate mockCertificate = Mockito.mock(X509Certificate.class); + when(mockCertificate.getSubjectX500Principal()).thenReturn(new X500Principal(user)); + servletRequest.setAttribute("javax.servlet.request.X509Certificate", new X509Certificate[] {mockCertificate}); + } + + private List createSingletonList(String listItem) { + return Collections.singletonList(listItem); + } +} diff --git a/src/test/java/org/onap/crud/service/VertexPayloadTest.java b/src/test/java/org/onap/crud/service/VertexPayloadTest.java new file mode 100644 index 0000000..df0656f --- /dev/null +++ b/src/test/java/org/onap/crud/service/VertexPayloadTest.java @@ -0,0 +1,50 @@ +/** + * ============LICENSE_START======================================================= + * org.onap.aai + * ================================================================================ + * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved. + * Copyright © 2017-2018 Amdocs + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ +package org.onap.crud.service; + +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.assertThat; +import javax.ws.rs.core.Response.Status; +import org.junit.Test; +import org.onap.crud.exception.CrudException; +import org.onap.crud.parser.VertexPayload; + +public class VertexPayloadTest { + + @Test + public void testExceptionHandling() { + String payload = null; + try { + VertexPayload.fromJson(payload); + } catch (CrudException e) { + assertThat(e.getHttpStatus(), is(Status.BAD_REQUEST)); + assertThat(e.getMessage(), is("Invalid Json Payload")); + } + + payload = "Invalid Json"; + try { + VertexPayload.fromJson(payload); + } catch (CrudException e) { + assertThat(e.getHttpStatus(), is(Status.BAD_REQUEST)); + assertThat(e.getMessage(), is("Invalid Json Payload")); + } + } +} diff --git a/src/test/java/org/onap/schema/EdgeRulesLoaderTest.java b/src/test/java/org/onap/schema/EdgeRulesLoaderTest.java index 073e1d3..05f998f 100644 --- a/src/test/java/org/onap/schema/EdgeRulesLoaderTest.java +++ b/src/test/java/org/onap/schema/EdgeRulesLoaderTest.java @@ -20,15 +20,13 @@ */ package org.onap.schema; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; import org.junit.Test; import org.onap.crud.exception.CrudException; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.Map; - -import static org.junit.Assert.*; - public class EdgeRulesLoaderTest { @Test diff --git a/src/test/java/org/onap/schema/RelationshipSchemaValidatorTest.java b/src/test/java/org/onap/schema/RelationshipSchemaValidatorTest.java new file mode 100644 index 0000000..711152d --- /dev/null +++ b/src/test/java/org/onap/schema/RelationshipSchemaValidatorTest.java @@ -0,0 +1,269 @@ +/** + * ============LICENSE_START======================================================= + * org.onap.aai + * ================================================================================ + * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved. + * Copyright © 2017-2018 Amdocs + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ +package org.onap.schema; + +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertThat; +import org.junit.Before; +import org.junit.Test; +import org.onap.crud.entity.Edge; +import org.onap.crud.exception.CrudException; +import org.onap.crud.parser.EdgePayload; +import org.onap.schema.validation.RelationshipSchemaValidator; + +public class RelationshipSchemaValidatorTest { + // @formatter:off + private final String edgePayload = "{" + + "\"type\": \"tosca.relationships.HostedOn\"," + + "\"source\": \"services/inventory/v12/vserver/50bdab41-ad1c-4d00-952c-a0aa5d827811\"," + + "\"target\": \"services/inventory/v12/pserver/1d326bc7-b985-492b-9604-0d5d1f06f908\"," + + "\"properties\": {" + + "\"prevent-delete\": \"NONE\" } }"; + + private final String champEdge = "{" + + "\"key\": \"test-uuid\"," + + "\"type\": \"edgeType\"," + + "\"properties\": {" + + "\"prevent-delete\": \"NONE\" }," + + "\"source\": {" + + "\"key\": \"50bdab41-ad1c-4d00-952c-a0aa5d827811\", \"type\": \"vserver\"}," + + "\"target\": {" + + "\"key\": \"1d326bc7-b985-492b-9604-0d5d1f06f908\", \"type\": \"pserver\"}" + + " }"; + // @formatter:on + + @Before + public void init() throws Exception { + System.setProperty("CONFIG_HOME", "src/test/resources"); + } + + @Test + public void testValidateIncomingUpdatePayloadMissingSource() throws CrudException { + String type = "tosca.relationships.HostedOn"; + String version = "v11"; + String jsonString; + EdgePayload payload; + + String champJson = champEdge.replace("edgeType", type); + Edge edge = Edge.fromJson(champJson); + + jsonString = edgePayload.replace("services/inventory/v12/vserver/50bdab41-ad1c-4d00-952c-a0aa5d827811", ""); + payload = EdgePayload.fromJson(jsonString); + + try { + RelationshipSchemaValidator.validateIncomingUpdatePayload(edge, version, payload); + } catch (CrudException e) { + assertEquals(400, e.getHttpStatus().getStatusCode()); + assertThat(e.getMessage(), is("Invalid Source/Target Urls")); + } + } + + @Test + public void testValidateIncomingUpdatePayloadInvalidSource() throws CrudException { + String type = "tosca.relationships.HostedOn"; + String version = "v11"; + String jsonString; + EdgePayload payload; + + String champJson = champEdge.replace("edgeType", type); + Edge edge = Edge.fromJson(champJson); + + jsonString = edgePayload.replace("1d326bc7-b985-492b-9604-0d5d1f06f908", "invalidId"); + payload = EdgePayload.fromJson(jsonString); + + try { + RelationshipSchemaValidator.validateIncomingUpdatePayload(edge, version, payload); + } catch (CrudException e) { + assertEquals(400, e.getHttpStatus().getStatusCode()); + assertThat(e.getMessage(), is("Target can't be updated")); + } + } + + @Test + public void testValidateIncomingUpdatePayloadMissingTarget() throws CrudException { + String type = "tosca.relationships.HostedOn"; + String version = "v11"; + String jsonString; + EdgePayload payload; + + String champJson = champEdge.replace("edgeType", type); + Edge edge = Edge.fromJson(champJson); + + jsonString = edgePayload.replace("services/inventory/v12/pserver/1d326bc7-b985-492b-9604-0d5d1f06f908", ""); + payload = EdgePayload.fromJson(jsonString); + + try { + RelationshipSchemaValidator.validateIncomingUpdatePayload(edge, version, payload); + } catch (CrudException e) { + assertEquals(400, e.getHttpStatus().getStatusCode()); + assertThat(e.getMessage(), is("Invalid Source/Target Urls")); + } + } + + @Test + public void testValidateIncomingUpdatePayloadInvalidTarget() throws CrudException { + String type = "tosca.relationships.HostedOn"; + String version = "v11"; + String jsonString; + EdgePayload payload; + + String champJson = champEdge.replace("edgeType", type); + Edge edge = Edge.fromJson(champJson); + + jsonString = edgePayload.replace("50bdab41-ad1c-4d00-952c-a0aa5d827811", "invalidId"); + payload = EdgePayload.fromJson(jsonString); + + try { + RelationshipSchemaValidator.validateIncomingUpdatePayload(edge, version, payload); + } catch (CrudException e) { + assertEquals(400, e.getHttpStatus().getStatusCode()); + assertThat(e.getMessage(), is("Source can't be updated")); + } + } + + @Test + public void testValidateIncomingAddPayloadExceptionHandling() throws CrudException { + String type = "tosca.relationships.HostedOn"; + String version = "v11"; + String jsonString; + + EdgePayload payload; + jsonString = edgePayload.replace("services/inventory/v12/vserver/50bdab41-ad1c-4d00-952c-a0aa5d827811", ""); + payload = EdgePayload.fromJson(jsonString); + + try { + RelationshipSchemaValidator.validateIncomingAddPayload(version, type, payload); + } catch (CrudException e) { + assertEquals(400, e.getHttpStatus().getStatusCode()); + assertThat(e.getMessage(), is("Invalid Source/Target Urls")); + } + + jsonString = edgePayload; + payload = EdgePayload.fromJson(jsonString); + type = "tosca.relationships.invalidType"; + try { + RelationshipSchemaValidator.validateIncomingAddPayload(version, type, payload); + } catch (CrudException e) { + assertEquals(400, e.getHttpStatus().getStatusCode()); + assertThat(e.getMessage(), is("Invalid source/target/relationship type: vserver:pserver:" + type)); + } + } + + @Test + public void testValidateIncomingPatchPayloadMissingSource() throws CrudException { + String type = "tosca.relationships.HostedOn"; + String version = "v11"; + String jsonString; + + String champJson = champEdge.replace("edgeType", type); + Edge edge = Edge.fromJson(champJson); + + EdgePayload payload; + + jsonString = edgePayload.replace("services/inventory/v12/vserver/50bdab41-ad1c-4d00-952c-a0aa5d827811", ""); + payload = EdgePayload.fromJson(jsonString); + + try { + RelationshipSchemaValidator.validateIncomingPatchPayload(edge, version, payload); + } catch (CrudException e) { + assertEquals(400, e.getHttpStatus().getStatusCode()); + assertThat(e.getMessage(), is("Invalid Source/Target Urls")); + } + } + + @Test + public void testValidateIncomingPatchPayloadInvalidSource() throws CrudException { + String type = "tosca.relationships.HostedOn"; + String version = "v11"; + String jsonString; + + String champJson = champEdge.replace("edgeType", type); + Edge edge = Edge.fromJson(champJson); + + EdgePayload payload; + + jsonString = edgePayload.replace("50bdab41-ad1c-4d00-952c-a0aa5d827811", "invalidId"); + payload = EdgePayload.fromJson(jsonString); + try { + RelationshipSchemaValidator.validateIncomingPatchPayload(edge, version, payload); + } catch (CrudException e) { + assertEquals(400, e.getHttpStatus().getStatusCode()); + assertThat(e.getMessage(), is("Source can't be updated")); + } + } + + @Test + public void testValidateIncomingPatchPayloadMissingTarget() throws CrudException { + String type = "tosca.relationships.HostedOn"; + String version = "v11"; + String jsonString; + + String champJson = champEdge.replace("edgeType", type); + Edge edge = Edge.fromJson(champJson); + + EdgePayload payload; + + jsonString = edgePayload.replace("services/inventory/v12/pserver/1d326bc7-b985-492b-9604-0d5d1f06f908", ""); + payload = EdgePayload.fromJson(jsonString); + + try { + RelationshipSchemaValidator.validateIncomingPatchPayload(edge, version, payload); + } catch (CrudException e) { + assertEquals(400, e.getHttpStatus().getStatusCode()); + assertThat(e.getMessage(), is("Invalid Source/Target Urls")); + } + } + + @Test + public void testValidateIncomingPatchPayloadInvalidTarget() throws CrudException { + String type = "tosca.relationships.HostedOn"; + String version = "v11"; + String jsonString; + + String champJson = champEdge.replace("edgeType", type); + Edge edge = Edge.fromJson(champJson); + + EdgePayload payload; + + jsonString = edgePayload.replace("1d326bc7-b985-492b-9604-0d5d1f06f908", "invalidId"); + payload = EdgePayload.fromJson(jsonString); + try { + RelationshipSchemaValidator.validateIncomingPatchPayload(edge, version, payload); + } catch (CrudException e) { + assertEquals(400, e.getHttpStatus().getStatusCode()); + assertThat(e.getMessage(), is("Target can't be updated")); + } + } + + @Test + public void testValidateTypeExceptionHandling() { + String version = "v11"; + String type = "tosca.relationships.invalidType"; + + try { + RelationshipSchemaValidator.validateType(version, type); + } catch (CrudException e) { + assertEquals(400, e.getHttpStatus().getStatusCode()); + assertThat(e.getMessage(), is("Invalid " + RelationshipSchema.SCHEMA_RELATIONSHIP_TYPE + ": " + type)); + } + } +} diff --git a/src/test/java/org/onap/schema/validation/MultiplicityValidatorTest.java b/src/test/java/org/onap/schema/validation/MultiplicityValidatorTest.java index 409ce3c..b4d5a31 100644 --- a/src/test/java/org/onap/schema/validation/MultiplicityValidatorTest.java +++ b/src/test/java/org/onap/schema/validation/MultiplicityValidatorTest.java @@ -20,7 +20,6 @@ */ package org.onap.schema.validation; -import java.io.File; import java.util.ArrayList; import java.util.HashMap; import java.util.List; @@ -49,9 +48,7 @@ public class MultiplicityValidatorTest { @Before public void init() { - ClassLoader classLoader = getClass().getClassLoader(); - File dir = new File(classLoader.getResource("rules").getFile()); - System.setProperty("CONFIG_HOME", dir.getParent()); + System.setProperty("CONFIG_HOME", "src/test/resources"); EdgeRulesLoader.resetSchemaVersionContext(); } diff --git a/src/test/resources/aai-resource-service/model/DbEdgeRules_v10.json b/src/test/resources/aai-resource-service/model/DbEdgeRules_v10.json new file mode 100644 index 0000000..0381090 --- /dev/null +++ b/src/test/resources/aai-resource-service/model/DbEdgeRules_v10.json @@ -0,0 +1,1819 @@ +{ + "rules": [ + { + "from": "availability-zone", + "to": "complex", + "label": "groupsResourcesIn", + "direction": "OUT", + "multiplicity": "Many2Many", + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "SVC-INFRA": "NONE", + "prevent-delete": "!${direction}" + }, + { + "from": "generic-vnf", + "to": "license-key-resource", + "label": "uses", + "direction": "OUT", + "multiplicity": "Many2Many", + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "SVC-INFRA": "NONE", + "prevent-delete": "!${direction}" + }, + { + "from": "availability-zone", + "to": "service-capability", + "label": "supportsServiceCapability", + "direction": "OUT", + "multiplicity": "Many2Many", + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "SVC-INFRA": "NONE", + "prevent-delete": "!${direction}" + }, + { + "from": "cloud-region", + "to": "complex", + "label": "locatedIn", + "direction": "OUT", + "multiplicity": "Many2One", + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "SVC-INFRA": "NONE", + "prevent-delete": "!${direction}" + }, + { + "from": "cloud-region", + "to": "l3-network", + "label": "uses", + "direction": "OUT", + "multiplicity": "Many2Many", + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "SVC-INFRA": "NONE", + "prevent-delete": "NONE" + }, + { + "from": "cloud-region", + "to": "tenant", + "label": "has", + "direction": "OUT", + "multiplicity": "One2Many", + "contains-other-v": "${direction}", + "delete-other-v": "NONE", + "SVC-INFRA": "!${direction}", + "prevent-delete": "${direction}" + }, + { + "from": "cloud-region", + "to": "image", + "label": "has", + "direction": "OUT", + "multiplicity": "One2Many", + "contains-other-v": "${direction}", + "delete-other-v": "NONE", + "SVC-INFRA": "NONE", + "prevent-delete": "${direction}" + }, + { + "from": "cloud-region", + "to": "flavor", + "label": "has", + "direction": "OUT", + "multiplicity": "One2Many", + "contains-other-v": "${direction}", + "delete-other-v": "NONE", + "SVC-INFRA": "NONE", + "prevent-delete": "${direction}" + }, + { + "from": "cloud-region", + "to": "availability-zone", + "label": "has", + "direction": "OUT", + "multiplicity": "One2Many", + "contains-other-v": "${direction}", + "delete-other-v": "NONE", + "SVC-INFRA": "NONE", + "prevent-delete": "${direction}" + }, + { + "from": "cloud-region", + "to": "oam-network", + "label": "has", + "direction": "OUT", + "multiplicity": "One2Many", + "contains-other-v": "${direction}", + "delete-other-v": "NONE", + "SVC-INFRA": "NONE", + "prevent-delete": "${direction}" + }, + { + "from": "cloud-region", + "to": "dvs-switch", + "label": "has", + "direction": "OUT", + "multiplicity": "One2Many", + "contains-other-v": "${direction}", + "delete-other-v": "NONE", + "SVC-INFRA": "NONE", + "prevent-delete": "${direction}" + }, + { + "from": "cloud-region", + "to": "volume-group", + "label": "has", + "direction": "OUT", + "multiplicity": "One2Many", + "contains-other-v": "${direction}", + "delete-other-v": "NONE", + "SVC-INFRA": "NONE", + "prevent-delete": "${direction}" + }, + { + "from": "cloud-region", + "to": "group-assignment", + "label": "has", + "direction": "OUT", + "multiplicity": "One2Many", + "contains-other-v": "${direction}", + "delete-other-v": "NONE", + "SVC-INFRA": "NONE", + "prevent-delete": "${direction}" + }, + { + "from": "cloud-region", + "to": "snapshot", + "label": "has", + "direction": "OUT", + "multiplicity": "One2Many", + "contains-other-v": "${direction}", + "delete-other-v": "NONE", + "SVC-INFRA": "NONE", + "prevent-delete": "${direction}" + }, + { + "from": "cloud-region", + "to": "zone", + "label": "isMemberOf", + "direction": "OUT", + "multiplicity": "Many2One", + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "SVC-INFRA": "NONE", + "prevent-delete": "NONE" + }, + { + "from": "complex", + "to": "ctag-pool", + "label": "hasCtagPool", + "direction": "OUT", + "multiplicity": "Many2Many", + "contains-other-v": "${direction}", + "delete-other-v": "NONE", + "SVC-INFRA": "NONE", + "prevent-delete": "NONE" + }, + { + "from": "complex", + "to": "l3-network", + "label": "usesL3Network", + "direction": "OUT", + "multiplicity": "Many2Many", + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "SVC-INFRA": "${direction}", + "prevent-delete": "NONE" + }, + { + "from": "ctag-pool", + "to": "availability-zone", + "label": "supportsAvailabilityZone", + "direction": "OUT", + "multiplicity": "Many2Many", + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "SVC-INFRA": "NONE", + "prevent-delete": "!${direction}" + }, + { + "from": "customer", + "to": "service-subscription", + "label": "subscribesTo", + "direction": "OUT", + "multiplicity": "Many2Many", + "contains-other-v": "${direction}", + "delete-other-v": "NONE", + "SVC-INFRA": "!${direction}", + "prevent-delete": "NONE" + }, + { + "from": "dvs-switch", + "to": "availability-zone", + "label": "existsIn", + "direction": "OUT", + "multiplicity": "Many2Many", + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "SVC-INFRA": "NONE", + "prevent-delete": "!${direction}" + }, + { + "from": "generic-vnf", + "to": "l-interface", + "label": "hasLInterface", + "direction": "OUT", + "multiplicity": "Many2Many", + "contains-other-v": "${direction}", + "delete-other-v": "NONE", + "SVC-INFRA": "${direction}", + "prevent-delete": "NONE" + }, + { + "from": "generic-vnf", + "to": "availability-zone", + "label": "hasAvailabilityZone", + "direction": "OUT", + "multiplicity": "Many2Many", + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "SVC-INFRA": "${direction}", + "prevent-delete": "!${direction}" + }, + { + "from": "generic-vnf", + "to": "lag-interface", + "label": "hasLAGInterface", + "direction": "OUT", + "multiplicity": "Many2Many", + "contains-other-v": "${direction}", + "delete-other-v": "NONE", + "SVC-INFRA": "${direction}", + "prevent-delete": "NONE" + }, + { + "from": "generic-vnf", + "to": "l3-network", + "label": "usesL3Network", + "direction": "OUT", + "multiplicity": "Many2Many", + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "SVC-INFRA": "${direction}", + "prevent-delete": "NONE" + }, + { + "from": "generic-vnf", + "to": "pserver", + "label": "runsOnPserver", + "direction": "OUT", + "multiplicity": "Many2Many", + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "SVC-INFRA": "${direction}", + "prevent-delete": "!${direction}" + }, + { + "from": "generic-vnf", + "to": "vnf-image", + "label": "usesVnfImage", + "direction": "OUT", + "multiplicity": "Many2One", + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "SVC-INFRA": "${direction}", + "prevent-delete": "!${direction}" + }, + { + "from": "generic-vnf", + "to": "vserver", + "label": "runsOnVserver", + "direction": "OUT", + "multiplicity": "One2Many", + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "SVC-INFRA": "${direction}", + "prevent-delete": "NONE" + }, + { + "from": "generic-vnf", + "to": "service-instance", + "label": "hasInstance", + "direction": "OUT", + "multiplicity": "Many2Many", + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "SVC-INFRA": "${direction}", + "prevent-delete": "NONE" + }, + { + "from": "generic-vnf", + "to": "site-pair-set", + "label": "hasSitePairSet", + "direction": "OUT", + "multiplicity": "Many2Many", + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "SVC-INFRA": "NONE", + "prevent-delete": "NONE" + }, + { + "from": "generic-vnf", + "to": "network-profile", + "label": "hasNetworkProfile", + "direction": "OUT", + "multiplicity": "Many2Many", + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "SVC-INFRA": "NONE", + "prevent-delete": "NONE" + }, + { + "from": "group-assignment", + "to": "tenant", + "label": "has", + "direction": "OUT", + "multiplicity": "Many2Many", + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "SVC-INFRA": "NONE", + "prevent-delete": "NONE" + }, + { + "from": "group-assignment", + "to": "pserver", + "label": "has", + "direction": "OUT", + "multiplicity": "One2Many", + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "SVC-INFRA": "NONE", + "prevent-delete": "!${direction}" + }, + { + "from": "image", + "to": "metadatum", + "label": "hasMetaDatum", + "direction": "OUT", + "multiplicity": "Many2Many", + "contains-other-v": "${direction}", + "delete-other-v": "NONE", + "SVC-INFRA": "NONE", + "prevent-delete": "NONE" + }, + { + "from": "l-interface", + "to": "instance-group", + "label": "isMemberOf", + "direction": "OUT", + "multiplicity": "Many2Many", + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "SVC-INFRA": "NONE", + "prevent-delete": "NONE" + }, + { + "from": "l-interface", + "to": "l3-interface-ipv4-address-list", + "label": "hasIpAddress", + "direction": "OUT", + "multiplicity": "Many2Many", + "contains-other-v": "${direction}", + "delete-other-v": "NONE", + "SVC-INFRA": "${direction}", + "prevent-delete": "NONE" + }, + { + "from": "l-interface", + "to": "l3-interface-ipv6-address-list", + "label": "hasIpAddress", + "direction": "OUT", + "multiplicity": "Many2Many", + "contains-other-v": "${direction}", + "delete-other-v": "NONE", + "SVC-INFRA": "${direction}", + "prevent-delete": "NONE" + }, + { + "from": "l-interface", + "to": "l-interface", + "label": "has", + "direction": "OUT", + "multiplicity": "One2Many", + "contains-other-v": "${direction}", + "delete-other-v": "NONE", + "SVC-INFRA": "${direction}", + "prevent-delete": "NONE" + }, + { + "from": "l-interface", + "to": "logical-link", + "label": "usesLogicalLink", + "direction": "OUT", + "multiplicity": "Many2Many", + "contains-other-v": "NONE", + "delete-other-v": "${direction}", + "SVC-INFRA": "${direction}", + "prevent-delete": "NONE" + }, + { + "from": "lag-interface", + "to": "logical-link", + "label": "uses", + "direction": "OUT", + "multiplicity": "Many2Many", + "contains-other-v": "NONE", + "delete-other-v": "${direction}", + "SVC-INFRA": "${direction}", + "prevent-delete": "NONE" + }, + { + "from": "l-interface", + "to": "vlan", + "label": "hasVlan", + "direction": "OUT", + "multiplicity": "Many2Many", + "contains-other-v": "${direction}", + "delete-other-v": "NONE", + "SVC-INFRA": "NONE", + "prevent-delete": "NONE" + }, + { + "from": "l-interface", + "to": "sriov-vf", + "label": "has", + "direction": "OUT", + "multiplicity": "One2One", + "contains-other-v": "${direction}", + "delete-other-v": "NONE", + "SVC-INFRA": "NONE", + "prevent-delete": "NONE" + }, + { + "from": "l3-interface-ipv4-address-list", + "to": "instance-group", + "label": "isMemberOf", + "direction": "OUT", + "multiplicity": "Many2Many", + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "SVC-INFRA": "NONE", + "prevent-delete": "NONE" + }, + { + "from": "l3-interface-ipv6-address-list", + "to": "instance-group", + "label": "isMemberOf", + "direction": "OUT", + "multiplicity": "Many2Many", + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "SVC-INFRA": "NONE", + "prevent-delete": "NONE" + }, + { + "from": "l3-interface-ipv4-address-list", + "to": "l3-network", + "label": "isMemberOf", + "direction": "OUT", + "multiplicity": "Many2Many", + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "SVC-INFRA": "${direction}", + "prevent-delete": "NONE" + }, + { + "from": "l3-interface-ipv6-address-list", + "to": "l3-network", + "label": "isMemberOf", + "direction": "OUT", + "multiplicity": "Many2Many", + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "SVC-INFRA": "${direction}", + "prevent-delete": "NONE" + }, + { + "from": "l3-interface-ipv4-address-list", + "to": "subnet", + "label": "isMemberOf", + "direction": "OUT", + "multiplicity": "Many2Many", + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "SVC-INFRA": "${direction}", + "prevent-delete": "!${direction}" + }, + { + "from": "l3-interface-ipv6-address-list", + "to": "subnet", + "label": "isMemberOf", + "direction": "OUT", + "multiplicity": "Many2Many", + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "SVC-INFRA": "${direction}", + "prevent-delete": "!${direction}" + }, + { + "from": "l3-network", + "to": "vpn-binding", + "label": "usesVpnBinding", + "direction": "OUT", + "multiplicity": "Many2Many", + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "SVC-INFRA": "NONE", + "prevent-delete": "!${direction}" + }, + { + "from": "l3-network", + "to": "subnet", + "label": "hasSubnet", + "direction": "OUT", + "multiplicity": "Many2Many", + "contains-other-v": "${direction}", + "delete-other-v": "NONE", + "SVC-INFRA": "!${direction}", + "prevent-delete": "NONE" + }, + { + "from": "l3-network", + "to": "service-instance", + "label": "hasInstance", + "direction": "OUT", + "multiplicity": "Many2Many", + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "SVC-INFRA": "!${direction}", + "prevent-delete": "NONE" + }, + { + "from": "l3-network", + "to": "ctag-assignment", + "label": "hasCtagAssignment", + "direction": "OUT", + "multiplicity": "Many2Many", + "contains-other-v": "${direction}", + "delete-other-v": "NONE", + "SVC-INFRA": "${direction}", + "prevent-delete": "NONE" + }, + { + "from": "l3-network", + "to": "network-policy", + "label": "uses", + "direction": "OUT", + "multiplicity": "Many2Many", + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "SVC-INFRA": "${direction}", + "prevent-delete": "NONE" + }, + { + "from": "l3-network", + "to": "segmentation-assignment", + "label": "has", + "direction": "OUT", + "multiplicity": "One2Many", + "contains-other-v": "${direction}", + "delete-other-v": "NONE", + "SVC-INFRA": "NONE", + "prevent-delete": "NONE" + }, + { + "from": "l3-network", + "to": "route-table-reference", + "label": "uses", + "direction": "OUT", + "multiplicity": "Many2Many", + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "SVC-INFRA": "NONE", + "prevent-delete": "NONE" + }, + { + "from": "lag-interface", + "to": "lag-link", + "label": "usesLAGLink", + "direction": "OUT", + "multiplicity": "Many2Many", + "contains-other-v": "NONE", + "delete-other-v": "${direction}", + "SVC-INFRA": "${direction}", + "prevent-delete": "NONE" + }, + { + "from": "lag-interface", + "to": "p-interface", + "label": "usesPInterface", + "direction": "OUT", + "multiplicity": "Many2Many", + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "SVC-INFRA": "${direction}", + "prevent-delete": "NONE" + }, + { + "from": "lag-interface", + "to": "l-interface", + "label": "hasLInterface", + "direction": "OUT", + "multiplicity": "Many2Many", + "contains-other-v": "${direction}", + "delete-other-v": "NONE", + "SVC-INFRA": "${direction}", + "prevent-delete": "NONE" + }, + { + "from": "logical-link", + "to": "lag-link", + "label": "usesLAGLink", + "direction": "OUT", + "multiplicity": "Many2Many", + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "SVC-INFRA": "${direction}", + "prevent-delete": "NONE" + }, + { + "from": "logical-link", + "to": "pnf", + "label": "bridgedTo", + "direction": "OUT", + "multiplicity": "Many2Many", + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "SVC-INFRA": "NONE", + "prevent-delete": "NONE" + }, + { + "from": "logical-link", + "to": "logical-link", + "label": "uses", + "direction": "OUT", + "multiplicity": "One2Many", + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "SVC-INFRA": "${direction}", + "prevent-delete": "NONE" + }, + { + "from": "model", + "to": "model-ver", + "label": "has", + "direction": "OUT", + "multiplicity": "One2Many", + "contains-other-v": "${direction}", + "delete-other-v": "NONE", + "SVC-INFRA": "NONE", + "prevent-delete": "NONE" + }, + { + "from": "model-ver", + "to": "model-element", + "label": "startsWith", + "direction": "OUT", + "multiplicity": "One2Many", + "contains-other-v": "${direction}", + "delete-other-v": "NONE", + "SVC-INFRA": "NONE", + "prevent-delete": "NONE" + }, + { + "from": "model-element", + "to": "model-ver", + "label": "isA", + "direction": "OUT", + "multiplicity": "Many2One", + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "SVC-INFRA": "NONE", + "prevent-delete": "!${direction}" + }, + { + "from": "model-ver", + "to": "metadatum", + "label": "hasMetaData", + "direction": "OUT", + "multiplicity": "One2Many", + "contains-other-v": "${direction}", + "delete-other-v": "NONE", + "SVC-INFRA": "NONE", + "prevent-delete": "NONE" + }, + { + "from": "model-element", + "to": "model-element", + "label": "connectsTo", + "direction": "OUT", + "multiplicity": "One2Many", + "contains-other-v": "${direction}", + "delete-other-v": "NONE", + "SVC-INFRA": "NONE", + "prevent-delete": "NONE" + }, + { + "from": "model-element", + "to": "model-constraint", + "label": "uses", + "direction": "OUT", + "multiplicity": "One2Many", + "contains-other-v": "${direction}", + "delete-other-v": "NONE", + "SVC-INFRA": "NONE", + "prevent-delete": "NONE" + }, + { + "from": "model-element", + "to": "constrained-element-set", + "label": "connectsTo", + "direction": "OUT", + "multiplicity": "One2Many", + "contains-other-v": "${direction}", + "delete-other-v": "NONE", + "SVC-INFRA": "NONE", + "prevent-delete": "NONE" + }, + { + "from": "model-constraint", + "to": "constrained-element-set", + "label": "uses", + "direction": "OUT", + "multiplicity": "One2Many", + "contains-other-v": "${direction}", + "delete-other-v": "NONE", + "SVC-INFRA": "NONE", + "prevent-delete": "NONE" + }, + { + "from": "constrained-element-set", + "to": "element-choice-set", + "label": "uses", + "direction": "OUT", + "multiplicity": "One2Many", + "contains-other-v": "${direction}", + "delete-other-v": "NONE", + "SVC-INFRA": "NONE", + "prevent-delete": "NONE" + }, + { + "from": "element-choice-set", + "to": "model-element", + "label": "has", + "direction": "OUT", + "multiplicity": "One2Many", + "contains-other-v": "${direction}", + "delete-other-v": "NONE", + "SVC-INFRA": "NONE", + "prevent-delete": "NONE" + }, + { + "from": "named-query", + "to": "model", + "label": "relatedTo", + "direction": "OUT", + "multiplicity": "One2Many", + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "SVC-INFRA": "NONE", + "prevent-delete": "!${direction}" + }, + { + "from": "named-query", + "to": "named-query-element", + "label": "startsWith", + "direction": "OUT", + "multiplicity": "One2One", + "contains-other-v": "${direction}", + "delete-other-v": "NONE", + "SVC-INFRA": "NONE", + "prevent-delete": "NONE" + }, + { + "from": "named-query-element", + "to": "named-query-element", + "label": "connectsTo", + "direction": "OUT", + "multiplicity": "Many2Many", + "contains-other-v": "${direction}", + "delete-other-v": "NONE", + "SVC-INFRA": "NONE", + "prevent-delete": "NONE" + }, + { + "from": "named-query-element", + "to": "model", + "label": "isA", + "direction": "OUT", + "multiplicity": "Many2One", + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "SVC-INFRA": "NONE", + "prevent-delete": "!${direction}" + }, + { + "from": "named-query-element", + "to": "property-constraint", + "label": "uses", + "direction": "OUT", + "multiplicity": "One2Many", + "contains-other-v": "${direction}", + "delete-other-v": "NONE", + "SVC-INFRA": "NONE", + "prevent-delete": "NONE" + }, + { + "from": "named-query-element", + "to": "related-lookup", + "label": "uses", + "direction": "OUT", + "multiplicity": "One2Many", + "contains-other-v": "${direction}", + "delete-other-v": "NONE", + "SVC-INFRA": "NONE", + "prevent-delete": "NONE" + }, + { + "from": "instance-group", + "to": "model", + "label": "targets", + "direction": "OUT", + "multiplicity": "Many2Many", + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "SVC-INFRA": "NONE", + "prevent-delete": "!${direction}" + }, + { + "from": "newvce", + "to": "l-interface", + "label": "hasLInterface", + "direction": "OUT", + "multiplicity": "Many2Many", + "contains-other-v": "${direction}", + "delete-other-v": "NONE", + "SVC-INFRA": "NONE", + "prevent-delete": "NONE" + }, + { + "from": "oam-network", + "to": "complex", + "label": "definedFor", + "direction": "OUT", + "multiplicity": "Many2Many", + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "SVC-INFRA": "NONE", + "prevent-delete": "!${direction}" + }, + { + "from": "oam-network", + "to": "service-capability", + "label": "supportsServiceCapability", + "direction": "OUT", + "multiplicity": "Many2Many", + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "SVC-INFRA": "NONE", + "prevent-delete": "!${direction}" + }, + { + "from": "p-interface", + "to": "l-interface", + "label": "hasLInterface", + "direction": "OUT", + "multiplicity": "Many2Many", + "contains-other-v": "${direction}", + "delete-other-v": "NONE", + "SVC-INFRA": "${direction}", + "prevent-delete": "NONE" + }, + { + "from": "p-interface", + "to": "physical-link", + "label": "usesPhysicalLink", + "direction": "OUT", + "multiplicity": "Many2Many", + "contains-other-v": "NONE", + "delete-other-v": "${direction}", + "SVC-INFRA": "NONE", + "prevent-delete": "NONE" + }, + { + "from": "p-interface", + "to": "logical-link", + "label": "usesLogicalLink", + "direction": "OUT", + "multiplicity": "Many2One", + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "SVC-INFRA": "${direction}", + "prevent-delete": "NONE" + }, + { + "from": "port-group", + "to": "cvlan-tag", + "label": "hasCTag", + "direction": "OUT", + "multiplicity": "Many2Many", + "contains-other-v": "${direction}", + "delete-other-v": "NONE", + "SVC-INFRA": "${direction}", + "prevent-delete": "NONE" + }, + { + "from": "pserver", + "to": "complex", + "label": "locatedIn", + "direction": "OUT", + "multiplicity": "Many2One", + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "SVC-INFRA": "${direction}", + "prevent-delete": "!${direction}" + }, + { + "from": "pserver", + "to": "cloud-region", + "label": "locatedIn", + "direction": "OUT", + "multiplicity": "Many2One", + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "SVC-INFRA": "${direction}", + "prevent-delete": "NONE" + }, + { + "from": "pserver", + "to": "availability-zone", + "label": "existsIn", + "direction": "OUT", + "multiplicity": "Many2One", + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "SVC-INFRA": "${direction}", + "prevent-delete": "!${direction}" + }, + { + "from": "pserver", + "to": "lag-interface", + "label": "hasLAGInterface", + "direction": "OUT", + "multiplicity": "Many2Many", + "contains-other-v": "${direction}", + "delete-other-v": "NONE", + "SVC-INFRA": "${direction}", + "prevent-delete": "NONE" + }, + { + "from": "pserver", + "to": "p-interface", + "label": "hasPinterface", + "direction": "OUT", + "multiplicity": "Many2Many", + "contains-other-v": "${direction}", + "delete-other-v": "NONE", + "SVC-INFRA": "${direction}", + "prevent-delete": "NONE" + }, + { + "from": "pserver", + "to": "zone", + "label": "isMemberOf", + "direction": "OUT", + "multiplicity": "Many2One", + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "SVC-INFRA": "NONE", + "prevent-delete": "NONE" + }, + { + "from": "pnf", + "to": "p-interface", + "label": "hasPinterface", + "direction": "OUT", + "multiplicity": "Many2Many", + "contains-other-v": "${direction}", + "delete-other-v": "NONE", + "SVC-INFRA": "${direction}", + "prevent-delete": "NONE" + }, + { + "from": "pnf", + "to": "lag-interface", + "label": "has", + "direction": "OUT", + "multiplicity": "One2Many", + "contains-other-v": "${direction}", + "delete-other-v": "NONE", + "SVC-INFRA": "${direction}", + "prevent-delete": "NONE" + }, + { + "from": "pnf", + "to": "complex", + "label": "locatedIn", + "direction": "OUT", + "multiplicity": "Many2One", + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "SVC-INFRA": "NONE", + "prevent-delete": "!${direction}" + }, + { + "from": "pnf", + "to": "instance-group", + "label": "isMemberOf", + "direction": "OUT", + "multiplicity": "Many2Many", + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "SVC-INFRA": "NONE", + "prevent-delete": "NONE" + }, + { + "from": "pnf", + "to": "zone", + "label": "isMemberOf", + "direction": "OUT", + "multiplicity": "Many2One", + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "SVC-INFRA": "NONE", + "prevent-delete": "NONE" + }, + { + "from": "service-instance", + "to": "cvlan-tag", + "label": "hasIPAGFacingVLAN", + "direction": "OUT", + "multiplicity": "Many2Many", + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "SVC-INFRA": "NONE", + "prevent-delete": "NONE" + }, + { + "from": "service-instance", + "to": "pnf", + "label": "uses", + "direction": "OUT", + "multiplicity": "One2Many", + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "SVC-INFRA": "NONE", + "prevent-delete": "NONE" + }, + { + "from": "service-subscription", + "to": "service-instance", + "label": "hasInstance", + "direction": "OUT", + "multiplicity": "Many2Many", + "contains-other-v": "${direction}", + "delete-other-v": "NONE", + "SVC-INFRA": "!${direction}", + "prevent-delete": "NONE" + }, + { + "from": "site-pair-set", + "to": "routing-instance", + "label": "hasRoutingInstance", + "direction": "OUT", + "multiplicity": "Many2Many", + "contains-other-v": "${direction}", + "delete-other-v": "NONE", + "SVC-INFRA": "NONE", + "prevent-delete": "NONE" + }, + { + "from": "routing-instance", + "to": "site-pair", + "label": "hasSitePair", + "direction": "OUT", + "multiplicity": "Many2Many", + "contains-other-v": "${direction}", + "delete-other-v": "NONE", + "SVC-INFRA": "NONE", + "prevent-delete": "NONE" + }, + { + "from": "site-pair", + "to": "class-of-service", + "label": "hasClassOfService", + "direction": "OUT", + "multiplicity": "Many2Many", + "contains-other-v": "${direction}", + "delete-other-v": "NONE", + "SVC-INFRA": "NONE", + "prevent-delete": "NONE" + }, + { + "from": "tenant", + "to": "l3-network", + "label": "usesL3Network", + "direction": "OUT", + "multiplicity": "Many2Many", + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "SVC-INFRA": "NONE", + "prevent-delete": "NONE" + }, + { + "from": "tenant", + "to": "service-subscription", + "label": "relatedTo", + "direction": "OUT", + "multiplicity": "Many2Many", + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "SVC-INFRA": "NONE", + "prevent-delete": "NONE" + }, + { + "from": "tenant", + "to": "vserver", + "label": "owns", + "direction": "OUT", + "multiplicity": "One2Many", + "contains-other-v": "${direction}", + "delete-other-v": "NONE", + "SVC-INFRA": "!${direction}", + "prevent-delete": "${direction}" + }, + { + "from": "vce", + "to": "availability-zone", + "label": "hasAvailabilityZone", + "direction": "OUT", + "multiplicity": "Many2Many", + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "SVC-INFRA": "NONE", + "prevent-delete": "!${direction}" + }, + { + "from": "vce", + "to": "complex", + "label": "locatedIn", + "direction": "OUT", + "multiplicity": "Many2Many", + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "SVC-INFRA": "${direction}", + "prevent-delete": "!${direction}" + }, + { + "from": "vce", + "to": "port-group", + "label": "hasPortGroup", + "direction": "OUT", + "multiplicity": "Many2Many", + "contains-other-v": "${direction}", + "delete-other-v": "NONE", + "SVC-INFRA": "${direction}", + "prevent-delete": "NONE" + }, + { + "from": "vce", + "to": "vserver", + "label": "runsOnVserver", + "direction": "OUT", + "multiplicity": "Many2Many", + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "SVC-INFRA": "${direction}", + "prevent-delete": "NONE" + }, + { + "from": "vce", + "to": "service-instance", + "label": "hasServiceInstance", + "direction": "OUT", + "multiplicity": "Many2Many", + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "SVC-INFRA": "!${direction}", + "prevent-delete": "NONE" + }, + { + "from": "virtual-data-center", + "to": "generic-vnf", + "label": "hasVNF", + "direction": "OUT", + "multiplicity": "Many2Many", + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "SVC-INFRA": "!${direction}", + "prevent-delete": "NONE" + }, + { + "from": "vlan", + "to": "l3-interface-ipv4-address-list", + "label": "hasIpAddress", + "direction": "OUT", + "multiplicity": "Many2Many", + "contains-other-v": "${direction}", + "delete-other-v": "NONE", + "SVC-INFRA": "${direction}", + "prevent-delete": "NONE" + }, + { + "from": "vlan", + "to": "l3-interface-ipv6-address-list", + "label": "hasIpAddress", + "direction": "OUT", + "multiplicity": "Many2Many", + "contains-other-v": "${direction}", + "delete-other-v": "NONE", + "SVC-INFRA": "${direction}", + "prevent-delete": "NONE" + }, + { + "from": "vpls-pe", + "to": "complex", + "label": "locatedIn", + "direction": "OUT", + "multiplicity": "Many2Many", + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "SVC-INFRA": "NONE", + "prevent-delete": "!${direction}" + }, + { + "from": "vpls-pe", + "to": "ctag-pool", + "label": "usesCtagPool", + "direction": "OUT", + "multiplicity": "Many2Many", + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "SVC-INFRA": "NONE", + "prevent-delete": "NONE" + }, + { + "from": "vpls-pe", + "to": "p-interface", + "label": "hasPinterface", + "direction": "OUT", + "multiplicity": "Many2Many", + "contains-other-v": "${direction}", + "delete-other-v": "NONE", + "SVC-INFRA": "NONE", + "prevent-delete": "NONE" + }, + { + "from": "vpls-pe", + "to": "lag-interface", + "label": "hasLAGinterface", + "direction": "OUT", + "multiplicity": "Many2Many", + "contains-other-v": "${direction}", + "delete-other-v": "NONE", + "SVC-INFRA": "NONE", + "prevent-delete": "NONE" + }, + { + "from": "vserver", + "to": "flavor", + "label": "hasFlavor", + "direction": "OUT", + "multiplicity": "Many2One", + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "SVC-INFRA": "${direction}", + "prevent-delete": "!${direction}" + }, + { + "from": "vserver", + "to": "image", + "label": "hasImage", + "direction": "OUT", + "multiplicity": "Many2One", + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "SVC-INFRA": "${direction}", + "prevent-delete": "!${direction}" + }, + { + "from": "vserver", + "to": "l-interface", + "label": "hasLInterface", + "direction": "OUT", + "multiplicity": "Many2Many", + "contains-other-v": "${direction}", + "delete-other-v": "NONE", + "SVC-INFRA": "${direction}", + "prevent-delete": "NONE" + }, + { + "from": "vserver", + "to": "pserver", + "label": "runsOnPserver", + "direction": "OUT", + "multiplicity": "Many2One", + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "SVC-INFRA": "${direction}", + "prevent-delete": "!${direction}" + }, + { + "from": "vserver", + "to": "volume", + "label": "hasVolume", + "direction": "OUT", + "multiplicity": "Many2Many", + "contains-other-v": "${direction}", + "delete-other-v": "NONE", + "SVC-INFRA": "${direction}", + "prevent-delete": "NONE" + }, + { + "from": "vserver", + "to": "vnfc", + "label": "hosts", + "direction": "OUT", + "multiplicity": "Many2Many", + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "SVC-INFRA": "${direction}", + "prevent-delete": "NONE" + }, + { + "from": "vserver", + "to": "snapshot", + "label": "uses", + "direction": "OUT", + "multiplicity": "One2One", + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "SVC-INFRA": "${direction}", + "prevent-delete": "NONE" + }, + { + "from": "service-instance", + "to": "connector", + "label": "uses", + "direction": "OUT", + "multiplicity": "Many2Many", + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "SVC-INFRA": "NONE", + "prevent-delete": "NONE" + }, + { + "from": "service-instance", + "to": "metadatum", + "label": "hasMetaData", + "direction": "OUT", + "multiplicity": "Many2Many", + "contains-other-v": "${direction}", + "delete-other-v": "NONE", + "SVC-INFRA": "NONE", + "prevent-delete": "NONE" + }, + { + "from": "service-instance", + "to": "logical-link", + "label": "uses", + "direction": "OUT", + "multiplicity": "Many2Many", + "contains-other-v": "NONE", + "delete-other-v": "${direction}", + "SVC-INFRA": "NONE", + "prevent-delete": "NONE" + }, + { + "from": "service-instance", + "to": "vlan", + "label": "dependsOn", + "direction": "OUT", + "multiplicity": "One2Many", + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "SVC-INFRA": "NONE", + "prevent-delete": "NONE" + }, + { + "from": "service-instance", + "to": "service-instance", + "label": "dependsOn", + "direction": "OUT", + "multiplicity": "One2Many", + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "SVC-INFRA": "NONE", + "prevent-delete": "NONE" + }, + { + "from": "connector", + "to": "virtual-data-center", + "label": "contains", + "direction": "OUT", + "multiplicity": "Many2Many", + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "SVC-INFRA": "NONE", + "prevent-delete": "NONE" + }, + { + "from": "connector", + "to": "metadatum", + "label": "hasMetaData", + "direction": "OUT", + "multiplicity": "Many2Many", + "contains-other-v": "${direction}", + "delete-other-v": "NONE", + "SVC-INFRA": "NONE", + "prevent-delete": "NONE" + }, + { + "from": "virtual-data-center", + "to": "logical-link", + "label": "contains", + "direction": "OUT", + "multiplicity": "Many2Many", + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "SVC-INFRA": "NONE", + "prevent-delete": "NONE" + }, + { + "from": "logical-link", + "to": "generic-vnf", + "label": "bridgedTo", + "direction": "OUT", + "multiplicity": "Many2Many", + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "SVC-INFRA": "NONE", + "prevent-delete": "NONE" + }, + { + "from": "logical-link", + "to": "pserver", + "label": "bridgedTo", + "direction": "OUT", + "multiplicity": "Many2Many", + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "SVC-INFRA": "NONE", + "prevent-delete": "!${direction}" + }, + { + "from": "vlan", + "to": "multicast-configuration", + "label": "uses", + "direction": "OUT", + "multiplicity": "Many2Many", + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "SVC-INFRA": "NONE", + "prevent-delete": "NONE" + }, + { + "from": "volume-group", + "to": "complex", + "label": "existsIn", + "direction": "OUT", + "multiplicity": "Many2Many", + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "SVC-INFRA": "${direction}", + "prevent-delete": "!${direction}" + }, + { + "from": "volume-group", + "to": "tenant", + "label": "belongsTo", + "direction": "OUT", + "multiplicity": "Many2Many", + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "SVC-INFRA": "${direction}", + "prevent-delete": "NONE" + }, + { + "from": "ipsec-configuration", + "to": "vig-server", + "label": "hasVigServer", + "direction": "OUT", + "multiplicity": "One2Many", + "contains-other-v": "${direction}", + "delete-other-v": "NONE", + "SVC-INFRA": "NONE", + "prevent-delete": "NONE" + }, + { + "from": "generic-vnf", + "to": "ipsec-configuration", + "label": "uses", + "direction": "OUT", + "multiplicity": "Many2One", + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "SVC-INFRA": "NONE", + "prevent-delete": "NONE" + }, + { + "from": "vf-module", + "to": "volume-group", + "label": "uses", + "direction": "OUT", + "multiplicity": "One2One", + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "SVC-INFRA": "${direction}", + "prevent-delete": "NONE" + }, + { + "from": "vserver", + "to": "vf-module", + "label": "isPartOf", + "direction": "OUT", + "multiplicity": "Many2One", + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "SVC-INFRA": "${direction}", + "prevent-delete": "NONE" + }, + { + "from": "vf-module", + "to": "l3-network", + "label": "uses", + "direction": "OUT", + "multiplicity": "Many2Many", + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "SVC-INFRA": "${direction}", + "prevent-delete": "NONE" + }, + { + "from": "vf-module", + "to": "vnfc", + "label": "uses", + "direction": "OUT", + "multiplicity": "One2Many", + "contains-other-v": "NONE", + "delete-other-v": "${direction}", + "SVC-INFRA": "${direction}", + "prevent-delete": "${direction}" + }, + { + "from": "generic-vnf", + "to": "vf-module", + "label": "has", + "direction": "OUT", + "multiplicity": "One2Many", + "contains-other-v": "${direction}", + "delete-other-v": "NONE", + "SVC-INFRA": "${direction}", + "prevent-delete": "NONE" + }, + { + "from": "generic-vnf", + "to": "volume-group", + "label": "uses", + "direction": "OUT", + "multiplicity": "One2Many", + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "SVC-INFRA": "${direction}", + "prevent-delete": "NONE" + }, + { + "from": "generic-vnf", + "to": "vnfc", + "label": "uses", + "direction": "OUT", + "multiplicity": "One2Many", + "contains-other-v": "NONE", + "delete-other-v": "${direction}", + "SVC-INFRA": "${direction}", + "prevent-delete": "NONE" + }, + { + "from": "vlan", + "to": "logical-link", + "label": "usesLogicalLink", + "direction": "OUT", + "multiplicity": "Many2Many", + "contains-other-v": "NONE", + "delete-other-v": "${direction}", + "SVC-INFRA": "${direction}", + "prevent-delete": "NONE" + }, + { + "from": "vpn-binding", + "to": "route-target", + "label": "has", + "direction": "OUT", + "multiplicity": "One2Many", + "contains-other-v": "${direction}", + "delete-other-v": "NONE", + "SVC-INFRA": "NONE", + "prevent-delete": "NONE" + }, + { + "from": "service-instance", + "to": "ctag-assignment", + "label": "uses", + "direction": "OUT", + "multiplicity": "One2Many", + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "SVC-INFRA": "NONE", + "prevent-delete": "NONE" + }, + { + "from": "allotted-resource", + "to": "generic-vnf", + "label": "isPartOf", + "direction": "OUT", + "multiplicity": "Many2Many", + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "SVC-INFRA": "NONE", + "prevent-delete": "NONE" + }, + { + "from": "allotted-resource", + "to": "l3-network", + "label": "isPartOf", + "direction": "OUT", + "multiplicity": "Many2Many", + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "SVC-INFRA": "NONE", + "prevent-delete": "NONE" + }, + { + "from": "allotted-resource", + "to": "instance-group", + "label": "isMemberOf", + "direction": "OUT", + "multiplicity": "Many2Many", + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "SVC-INFRA": "NONE", + "prevent-delete": "NONE" + }, + { + "from": "allotted-resource", + "to": "network-policy", + "label": "uses", + "direction": "OUT", + "multiplicity": "One2One", + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "SVC-INFRA": "NONE", + "prevent-delete": "NONE" + }, + { + "from": "allotted-resource", + "to": "vlan", + "label": "isPartOf", + "direction": "OUT", + "multiplicity": "Many2Many", + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "SVC-INFRA": "NONE", + "prevent-delete": "NONE" + }, + { + "from": "generic-vnf", + "to": "instance-group", + "label": "isMemberOf", + "direction": "OUT", + "multiplicity": "Many2Many", + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "SVC-INFRA": "NONE", + "prevent-delete": "NONE" + }, + { + "from": "service-instance", + "to": "instance-group", + "label": "isMemberOf", + "direction": "OUT", + "multiplicity": "Many2Many", + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "SVC-INFRA": "NONE", + "prevent-delete": "NONE" + }, + { + "from": "allotted-resource", + "to": "tunnel-xconnect", + "label": "has", + "direction": "OUT", + "multiplicity": "One2One", + "contains-other-v": "${direction}", + "delete-other-v": "NONE", + "SVC-INFRA": "NONE", + "prevent-delete": "NONE" + }, + { + "from": "logical-link", + "to": "cloud-region", + "label": "existsIn", + "direction": "OUT", + "multiplicity": "Many2Many", + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "SVC-INFRA": "NONE", + "prevent-delete": "NONE" + }, + { + "from": "logical-link", + "to": "vpn-binding", + "label": "uses", + "direction": "OUT", + "multiplicity": "Many2Many", + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "SVC-INFRA": "NONE", + "prevent-delete": "!${direction}" + }, + { + "from": "generic-vnf", + "to": "entitlement", + "label": "has", + "direction": "OUT", + "multiplicity": "One2Many", + "contains-other-v": "${direction}", + "delete-other-v": "NONE", + "SVC-INFRA": "NONE", + "prevent-delete": "NONE" + }, + { + "from": "generic-vnf", + "to": "license", + "label": "has", + "direction": "OUT", + "multiplicity": "One2Many", + "contains-other-v": "${direction}", + "delete-other-v": "NONE", + "SVC-INFRA": "NONE", + "prevent-delete": "NONE" + }, + { + "from": "vce", + "to": "entitlement", + "label": "has", + "direction": "OUT", + "multiplicity": "One2Many", + "contains-other-v": "${direction}", + "delete-other-v": "NONE", + "SVC-INFRA": "NONE", + "prevent-delete": "NONE" + }, + { + "from": "vce", + "to": "license", + "label": "has", + "direction": "OUT", + "multiplicity": "One2Many", + "contains-other-v": "${direction}", + "delete-other-v": "NONE", + "SVC-INFRA": "NONE", + "prevent-delete": "NONE" + }, + { + "from": "zone", + "to": "complex", + "label": "existsIn", + "direction": "OUT", + "multiplicity": "Many2One", + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "SVC-INFRA": "NONE", + "prevent-delete": "!${direction}" + }, + { + "from": "service-instance", + "to": "allotted-resource", + "label": "has", + "direction": "OUT", + "multiplicity": "Many2Many", + "contains-other-v": "${direction}", + "delete-other-v": "NONE", + "SVC-INFRA": "NONE", + "prevent-delete": "NONE" + }, + { + "from": "service-instance", + "to": "allotted-resource", + "label": "uses", + "direction": "OUT", + "multiplicity": "Many2Many", + "contains-other-v": "NONE", + "delete-other-v": "NONE", + "SVC-INFRA": "NONE", + "prevent-delete": "NONE" + } + ] +} diff --git a/src/test/resources/aai-resource-service/model/edge_properties_v10.json b/src/test/resources/aai-resource-service/model/edge_properties_v10.json new file mode 100644 index 0000000..8d00636 --- /dev/null +++ b/src/test/resources/aai-resource-service/model/edge_properties_v10.json @@ -0,0 +1,6 @@ +{ + "contains-other-v": "java.lang.String", + "delete-other-v": "java.lang.String", + "SVC-INFRA": "java.lang.String", + "prevent-delete": "java.lang.String" +} \ No newline at end of file diff --git a/src/test/resources/aai-resource-service/model/edge_properties_v11.json b/src/test/resources/aai-resource-service/model/edge_properties_v11.json new file mode 100644 index 0000000..8d00636 --- /dev/null +++ b/src/test/resources/aai-resource-service/model/edge_properties_v11.json @@ -0,0 +1,6 @@ +{ + "contains-other-v": "java.lang.String", + "delete-other-v": "java.lang.String", + "SVC-INFRA": "java.lang.String", + "prevent-delete": "java.lang.String" +} \ No newline at end of file diff --git a/src/test/resources/aai-resource-service/post-edge-auto-props.json b/src/test/resources/aai-resource-service/post-edge-auto-props.json new file mode 100644 index 0000000..2d71bd6 --- /dev/null +++ b/src/test/resources/aai-resource-service/post-edge-auto-props.json @@ -0,0 +1,6 @@ +{ + "type": "tosca.relationships.HostedOn", + "source": "services/inventory/v12/vserver/f5eb0ad4-1845-4945-b208-df11b0155e3b", + "target": "services/inventory/v11/pserver/46e61b9b-ea02-46ca-b07e-95c7fed60fdf", + "properties": {} +} diff --git a/src/test/resources/aai-resource-service/post-edge-no-props.json b/src/test/resources/aai-resource-service/post-edge-no-props.json new file mode 100644 index 0000000..b655eda --- /dev/null +++ b/src/test/resources/aai-resource-service/post-edge-no-props.json @@ -0,0 +1,5 @@ +{ + "type": "tosca.relationships.HostedOn", + "source": "services/inventory/v12/vserver/f5eb0ad4-1845-4945-b208-df11b0155e3b", + "target": "services/inventory/v11/pserver/46e61b9b-ea02-46ca-b07e-95c7fed60fdf" +} diff --git a/src/test/resources/aai-resource-service/post-edge-no-type.json b/src/test/resources/aai-resource-service/post-edge-no-type.json new file mode 100644 index 0000000..0b7ae98 --- /dev/null +++ b/src/test/resources/aai-resource-service/post-edge-no-type.json @@ -0,0 +1,5 @@ +{ + "source":"services/inventory/v12/vserver/f5eb0ad4-1845-4945-b208-df11b0155e3b", + "target":"services/inventory/v11/pserver/46e61b9b-ea02-46ca-b07e-95c7fed60fdf", + "properties":{} +} diff --git a/src/test/resources/aai-resource-service/post-edge-null-props.json b/src/test/resources/aai-resource-service/post-edge-null-props.json new file mode 100644 index 0000000..40fef7d --- /dev/null +++ b/src/test/resources/aai-resource-service/post-edge-null-props.json @@ -0,0 +1,6 @@ +{ + "type":"tosca.relationships.HostedOn", + "source":"services/inventory/v12/vserver/f5eb0ad4-1845-4945-b208-df11b0155e3b", + "target":"services/inventory/v11/pserver/46e61b9b-ea02-46ca-b07e-95c7fed60fdf", + "properties":null +} diff --git a/src/test/resources/aai-resource-service/post-edge-upsert.json b/src/test/resources/aai-resource-service/post-edge-upsert.json new file mode 100644 index 0000000..f66fd04 --- /dev/null +++ b/src/test/resources/aai-resource-service/post-edge-upsert.json @@ -0,0 +1,7 @@ +{ + "id": "12345", + "type":"tosca.relationships.HostedOn", + "source":"services/inventory/v12/vserver/f5eb0ad4-1845-4945-b208-df11b0155e3b", + "target":"services/inventory/v11/pserver/46e61b9b-ea02-46ca-b07e-95c7fed60fdf", + "properties":{} +} diff --git a/src/test/resources/aai-resource-service/post-edge-with-id.json b/src/test/resources/aai-resource-service/post-edge-with-id.json new file mode 100644 index 0000000..4d987b9 --- /dev/null +++ b/src/test/resources/aai-resource-service/post-edge-with-id.json @@ -0,0 +1,7 @@ +{ + "id":"12345", + "type":"tosca.relationships.HostedOn", + "source":"services/inventory/v12/vserver/f5eb0ad4-1845-4945-b208-df11b0155e3b", + "target":"services/inventory/v11/pserver/46e61b9b-ea02-46ca-b07e-95c7fed60fdf", + "properties":{} +} diff --git a/src/test/resources/aai-resource-service/post-edge.json b/src/test/resources/aai-resource-service/post-edge.json new file mode 100644 index 0000000..040ccd8 --- /dev/null +++ b/src/test/resources/aai-resource-service/post-edge.json @@ -0,0 +1,12 @@ +{ + "type":"tosca.relationships.HostedOn", + "source":"services/inventory/v12/vserver/f5eb0ad4-1845-4945-b208-df11b0155e3b", + "target":"services/inventory/v11/pserver/46e61b9b-ea02-46ca-b07e-95c7fed60fdf", + "properties":{ + "contains-other-v":"NONE", + "delete-other-v":"NONE", + "SVC-INFRA":"OUT", + "prevent-delete":"IN", + "multiplicity": "MANY2ONE" + } +} diff --git a/src/test/resources/auth/crud_policy.json b/src/test/resources/auth/crud_policy.json new file mode 100644 index 0000000..d60312b --- /dev/null +++ b/src/test/resources/auth/crud_policy.json @@ -0,0 +1,18 @@ +{ + "roles": [ + { + "name": "admin", + "functions": [ + { + "name": "crud", "methods": [ { "name": "GET" },{ "name": "DELETE" }, { "name": "PUT" }, { "name": "POST" }, { "name": "PATCH" } ] + } + ], + + "users": [ + { + "username": "CN=ONAP, OU=ONAP, O=ONAP, L=Ottawa, ST=Ontario, C=CA" + } + ] + } + ] +} diff --git a/src/test/resources/event/champ-edge-event.json b/src/test/resources/event/champ-edge-event.json new file mode 100644 index 0000000..375901a --- /dev/null +++ b/src/test/resources/event/champ-edge-event.json @@ -0,0 +1,30 @@ +{ + "header": { + "request-id": "5cf7f973-c406-4507-ad71-72d7b3d26c36", + "timestamp": "20180316T092301Z", + "source-name": "CHAMP", + "event-type": "update-result" + }, + "body": { + "operation": "CREATE", + "transaction-id": "6544a144-0c56-4f71-81d8-a6170efbb296", + "timestamp": 1521192181065, + "edge": { + "key": "test-key", + "type": "tosca.relationships.HostedOn", + "properties": { + "prevent-delete": "NONE" + }, + "source": { + "key": "50bdab41-ad1c-4d00-952c-a0aa5d827811", + "type": "vserver" + }, + "target": { + "key": "1d326bc7-b985-492b-9604-0d5d1f06f908", + "type": "pserver" + } + }, + "result": "SUCCESS" + }, + "policyViolations": [] +} \ No newline at end of file diff --git a/src/test/resources/event/champ-vertex-event-error.json b/src/test/resources/event/champ-vertex-event-error.json new file mode 100644 index 0000000..03f3018 --- /dev/null +++ b/src/test/resources/event/champ-vertex-event-error.json @@ -0,0 +1,26 @@ +{ + "header": { + "request-id": "5cf7f973-c406-4507-ad71-72d7b3d26c36", + "timestamp": "20180316T092301Z", + "source-name": "CHAMP", + "event-type": "update-result", + "validation-entity-type": "pserver" + }, + "body": { + "operation": "CREATE", + "transaction-id": "6544a144-0c56-4f71-81d8-a6170efbb296", + "timestamp": 1521192181065, + "vertex": { + "key": "890c8b3f-892f-48e3-85cd-748ebf0426a5", + "schema-version": "v13", + "type": "pserver", + "properties": { + "hostname":"hostname1" + } + }, + "result": "FAILURE", + "error-message":"test error", + "httpErrorStatus":"INTERNAL_SERVER_ERROR" + }, + "policyViolations": [] +} \ No newline at end of file diff --git a/src/test/resources/event/champ-vertex-event-violations.json b/src/test/resources/event/champ-vertex-event-violations.json new file mode 100644 index 0000000..ad30912 --- /dev/null +++ b/src/test/resources/event/champ-vertex-event-violations.json @@ -0,0 +1,30 @@ +{ + "header": { + "request-id": "5cf7f973-c406-4507-ad71-72d7b3d26c36", + "timestamp": "20180316T092301Z", + "source-name": "CHAMP", + "event-type": "update-result", + "validation-entity-type": "pserver" + }, + "body": { + "operation": "CREATE", + "transaction-id": "6544a144-0c56-4f71-81d8-a6170efbb296", + "timestamp": 1521192181065, + "vertex": { + "key": "890c8b3f-892f-48e3-85cd-748ebf0426a5", + "schema-version": "v13", + "type": "pserver", + "properties": { + "hostname":"hostname1", + "number-of-cpus":8 + } + }, + "result": "SUCCESS" + }, + "policyViolations": [ + { + "summary": "a summary", + "policyName": "a policy name" + } + ] +} \ No newline at end of file diff --git a/src/test/resources/event/champ-vertex-event.json b/src/test/resources/event/champ-vertex-event.json new file mode 100644 index 0000000..815780f --- /dev/null +++ b/src/test/resources/event/champ-vertex-event.json @@ -0,0 +1,25 @@ +{ + "header": { + "request-id": "5cf7f973-c406-4507-ad71-72d7b3d26c36", + "timestamp": "20180316T092301Z", + "source-name": "CHAMP", + "event-type": "update-result", + "validation-entity-type": "pserver" + }, + "body": { + "operation": "CREATE", + "transaction-id": "6544a144-0c56-4f71-81d8-a6170efbb296", + "timestamp": 1521192181065, + "vertex": { + "key": "890c8b3f-892f-48e3-85cd-748ebf0426a5", + "schema-version": "v13", + "type": "pserver", + "properties": { + "hostname":"hostname1", + "number-of-cpus":8 + } + }, + "result": "SUCCESS" + }, + "policyViolations": [] +} \ No newline at end of file diff --git a/src/test/resources/event/event-envelope-sentinel-no-violations.json b/src/test/resources/event/event-envelope-sentinel-no-violations.json index 88e4123..5b6f906 100644 --- a/src/test/resources/event/event-envelope-sentinel-no-violations.json +++ b/src/test/resources/event/event-envelope-sentinel-no-violations.json @@ -2,7 +2,7 @@ "header": { "request-id": "5cf7f973-c406-4507-ad71-72d7b3d26c36", "timestamp": "20180316T092301Z", - "source-name": "SENTINE", + "source-name": "SENTINEL", "event-type": "update-result", "validation-entity-type": "pserver" }, diff --git a/src/test/resources/event/event-envelope-sentinel.json b/src/test/resources/event/event-envelope-sentinel.json index 91e6c76..567e7d3 100644 --- a/src/test/resources/event/event-envelope-sentinel.json +++ b/src/test/resources/event/event-envelope-sentinel.json @@ -2,7 +2,7 @@ "header": { "request-id": "5cf7f973-c406-4507-ad71-72d7b3d26c36", "timestamp": "20180316T092301Z", - "source-name": "SENTINE", + "source-name": "SENTINEL", "event-type": "update-result", "validation-entity-type": "pserver" }, diff --git a/src/test/resources/event/graph-edge-event.json b/src/test/resources/event/graph-edge-event.json new file mode 100644 index 0000000..30fe94f --- /dev/null +++ b/src/test/resources/event/graph-edge-event.json @@ -0,0 +1,19 @@ +{ + "operation": "CREATE", + "transaction-id": "6544a144-0c56-4f71-81d8-a6170efbb296", + "timestamp": 1521192181065, + "edge": { + "type": "tosca.relationships.HostedOn", + "properties": { + "prevent-delete": "NONE" + }, + "source": { + "key": "50bdab41-ad1c-4d00-952c-a0aa5d827811", + "type": "vserver" + }, + "target": { + "key": "1d326bc7-b985-492b-9604-0d5d1f06f908", + "type": "pserver" + } + } +} diff --git a/src/test/resources/event/graph-vertex-event.json b/src/test/resources/event/graph-vertex-event.json new file mode 100644 index 0000000..2dcfaee --- /dev/null +++ b/src/test/resources/event/graph-vertex-event.json @@ -0,0 +1,12 @@ +{ + "operation": "CREATE", + "transaction-id": "6544a144-0c56-4f71-81d8-a6170efbb296", + "timestamp": 1521192181065, + "vertex": { + "schema-version": "v13", + "type": "pserver", + "properties": { + "hostname":"hostname1" + } + } +} \ No newline at end of file -- 2.16.6