aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSotiropoulos, Ioannis (is948x) <Ioannis.Sotiropoulos@amdocs.com>2018-07-10 17:57:43 +0100
committerSotiropoulos, Ioannis (is948x) <Ioannis.Sotiropoulos@amdocs.com>2018-07-10 17:57:43 +0100
commitd5322dbd0fa1e32d543b24824a28d6bf0a0b5497 (patch)
tree3fd9c7c2ce924395346601490e96327e47928afc
parent600ca7e0b82c6932caa4f4ffb53e6c053525d9d5 (diff)
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) <Ioannis.Sotiropoulos@amdocs.com>
-rw-r--r--pom.xml25
-rw-r--r--src/main/java/org/onap/crud/dao/DataRouterDAO.java4
-rw-r--r--src/main/java/org/onap/crud/dao/champ/ChampDao.java10
-rw-r--r--src/main/java/org/onap/crud/event/response/GraphEventResponseHandler.java48
-rw-r--r--src/main/java/org/onap/crud/service/AaiResourceService.java5
-rw-r--r--src/main/java/org/onap/crud/service/CrudAsyncGraphEventCache.java6
-rw-r--r--src/test/java/org/onap/crud/event/response/GraphEventResponseHandlerTest.java100
-rw-r--r--src/test/java/org/onap/crud/service/BulkPayloadTest.java36
-rw-r--r--src/test/java/org/onap/crud/service/ChampDaoExceptionsTest.java787
-rw-r--r--src/test/java/org/onap/crud/service/ChampDaoMockTest.java562
-rw-r--r--src/test/java/org/onap/crud/service/CrudRestServiceTest.java7
-rw-r--r--src/test/java/org/onap/crud/service/TestEventConsumer.java58
-rw-r--r--src/test/java/org/onap/crud/service/TestEventPublisher.java82
-rw-r--r--src/test/java/org/onap/crud/service/TestResourceServiceEdgeOperations.java284
-rw-r--r--src/test/java/org/onap/crud/service/VertexPayloadTest.java50
-rw-r--r--src/test/java/org/onap/schema/EdgeRulesLoaderTest.java10
-rw-r--r--src/test/java/org/onap/schema/RelationshipSchemaValidatorTest.java269
-rw-r--r--src/test/java/org/onap/schema/validation/MultiplicityValidatorTest.java5
-rw-r--r--src/test/resources/aai-resource-service/model/DbEdgeRules_v10.json1819
-rw-r--r--src/test/resources/aai-resource-service/model/edge_properties_v10.json6
-rw-r--r--src/test/resources/aai-resource-service/model/edge_properties_v11.json6
-rw-r--r--src/test/resources/aai-resource-service/post-edge-auto-props.json6
-rw-r--r--src/test/resources/aai-resource-service/post-edge-no-props.json5
-rw-r--r--src/test/resources/aai-resource-service/post-edge-no-type.json5
-rw-r--r--src/test/resources/aai-resource-service/post-edge-null-props.json6
-rw-r--r--src/test/resources/aai-resource-service/post-edge-upsert.json7
-rw-r--r--src/test/resources/aai-resource-service/post-edge-with-id.json7
-rw-r--r--src/test/resources/aai-resource-service/post-edge.json12
-rw-r--r--src/test/resources/auth/crud_policy.json18
-rw-r--r--src/test/resources/event/champ-edge-event.json30
-rw-r--r--src/test/resources/event/champ-vertex-event-error.json26
-rw-r--r--src/test/resources/event/champ-vertex-event-violations.json30
-rw-r--r--src/test/resources/event/champ-vertex-event.json25
-rw-r--r--src/test/resources/event/event-envelope-sentinel-no-violations.json2
-rw-r--r--src/test/resources/event/event-envelope-sentinel.json2
-rw-r--r--src/test/resources/event/graph-edge-event.json19
-rw-r--r--src/test/resources/event/graph-vertex-event.json12
37 files changed, 4301 insertions, 90 deletions
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.
<onap.nexus.url>https://nexus.onap.org</onap.nexus.url>
<testRouteOffer>workstation</testRouteOffer>
<testEnv>DEV</testEnv>
- <version.org.hamcrest.hamcrest-library>1.3</version.org.hamcrest.hamcrest-library>
</properties>
<dependencyManagement>
@@ -85,6 +84,17 @@ limitations under the License.
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
+ <groupId>org.springframework.boot</groupId>
+ <artifactId>
+ spring-boot-configuration-processor
+ </artifactId>
+ <optional>true</optional>
+ </dependency>
+ <dependency>
+ <groupId>org.springframework.boot</groupId>
+ <artifactId>spring-boot-starter-test</artifactId>
+ </dependency>
+ <dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-frontend-jaxrs</artifactId>
<version>3.2.4</version>
@@ -289,12 +299,6 @@ limitations under the License.
<scope>test</scope>
</dependency>
<dependency>
- <groupId>org.hamcrest</groupId>
- <artifactId>hamcrest-library</artifactId>
- <version>${version.org.hamcrest.hamcrest-library}</version>
- <scope>test</scope>
- </dependency>
- <dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.3</version>
@@ -304,13 +308,6 @@ limitations under the License.
<artifactId>httpcore</artifactId>
<version>4.4.1</version>
</dependency>
- <dependency>
- <groupId>org.springframework.boot</groupId>
- <artifactId>
- spring-boot-configuration-processor
- </artifactId>
- <optional>true</optional>
- </dependency>
</dependencies>
<build>
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<EntityTag, String> 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<String, String> 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<String, String> 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<String, String> 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<String, String> 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<String, String> 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<String, Object> filter = new HashMap<>();
+ Map<String, String> 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<String, String> 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<String, String> 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<String, String> 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<String, String> 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<String, Object> filter = new HashMap<>();
+ Map<String, String> 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<String, String> 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<String, Object> 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<String, Object> 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<String, Object> 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<String> 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<String> 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<String> 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<String, List<String>> createHeader() {
+ Map<String, List<String>> 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<String, String> queryParamsVertex = new HashMap<>();
+ queryParamsVertex.put("_reserved_version", "v11");
+ queryParamsVertex.put("hostname", "myhost");
+ queryParamsVertex.put("_reserved_aai-type", "pserver");
+
+ Map<String, String> queryParamsVertexV13 = new HashMap<>();
+ queryParamsVertexV13.put("_reserved_version", "v13");
+ queryParamsVertexV13.put("hostname", "myhost");
+ queryParamsVertexV13.put("_reserved_aai-type", "pserver");
+
+ Map<String, String> 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<String, String> 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<String, String> queryParamsEdge = new HashMap<>();
+ queryParamsEdge.put("_reserved_version", "v11");
+ queryParamsEdge.put("hostname", "myhost");
+ queryParamsEdge.put("_reserved_aai-type", "tosca.relationships.HostedOn");
+
+ Map<String, String> 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<String, List<String>> 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<String, String> 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<String, String> queryParams, String type) {
+ String edgeResponse = champEdge.replace("edgeType", type);
+ OperationResult operationResult = new OperationResult();
+ List<String> 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<String, String> queryParams, String type) {
+ String vertexResponse = champVertex.replace("vertexType", type);
+ OperationResult operationResult = new OperationResult();
+ List<String> 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<String> 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<String, String> 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<String, String> headers = new MultivaluedHashMap<String, String>();
+ 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<String, String> headers = new MultivaluedHashMap<String, String>();
+ 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<String, String> headers = new MultivaluedHashMap<String, String>();
+ 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<String, String> headers = new MultivaluedHashMap<String, String>();
+ 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<String, List<String>> createHeaders() {
+ Map<String, List<String>> headers = new HashMap<>();
+ List<String> listFromApp = new ArrayList<>();
+ List<String> 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<String, String> queryParams) {
+ StringBuilder strBuilder = new StringBuilder(url);
+
+ if (queryParams != null) {
+ String prefix = "?";
+ for (Map.Entry<String, String> 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<String> consume() throws Exception {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public Iterable<String> consumeAndCommit() throws Exception {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public Iterable<MessageWithOffset> 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<String> 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<String> 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<String> 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<String> 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<String, String> getCreateHeaders() {
+ MultivaluedHashMap<String, String> 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<String, String> headersMap) {
+ headers = Mockito.mock(HttpHeaders.class);
+ for (Entry<String, List<String>> 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<String, String> 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, String>(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, String>(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, String>(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, String>(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, String>(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, String>(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<String> createSingletonList(String listItem) {
+ return Collections.<String>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