summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorgfraboni <gino.fraboni@amdocs.com>2017-09-01 16:39:10 -0400
committergfraboni <gino.fraboni@amdocs.com>2017-09-01 16:46:03 -0400
commit4e29c1eed57fbcd982c38bd96348b0b183f7820c (patch)
tree8f2bbc9b10ace68bbab71fd14931ca2cd99fa184
parent900114bf694a0b34e8de3d283b5929fed4aaf65d (diff)
New endpoints to auto populate edge properties.
New endpoints created to allow v11 endpoints to have their properties automatically set based on db edge rules. Issue-Id: AAI-60 Change-Id: I9b41f654fa9924b1dcb863aca369725a763b3691 Signed-off-by: gfraboni <gino.fraboni@amdocs.com>
-rw-r--r--bundleconfig-local/etc/appprops/error.properties164
-rw-r--r--pom.xml26
-rw-r--r--src/main/ajsc/crud-api_v1/crud-api/v1/routes/aaiResources.route4
-rw-r--r--src/main/java/org/openecomp/crud/dao/GraphDao.java2
-rw-r--r--src/main/java/org/openecomp/crud/dao/champ/ChampDao.java34
-rw-r--r--src/main/java/org/openecomp/crud/service/AaiResourceService.java533
-rw-r--r--src/main/java/org/openecomp/crud/service/CrudGraphDataService.java4
-rw-r--r--src/main/java/org/openecomp/crud/util/CrudServiceUtil.java7
-rw-r--r--src/main/java/org/openecomp/schema/RelationshipSchemaValidator.java11
-rw-r--r--src/test/java/org/openecomp/crud/dao/champ/ChampDaoTest.java1198
-rw-r--r--src/test/java/org/openecomp/schema/AaiResourceServiceTest.java205
-rw-r--r--src/test/resources/bundleconfig-local/etc/appprops/error.properties164
12 files changed, 1743 insertions, 609 deletions
diff --git a/bundleconfig-local/etc/appprops/error.properties b/bundleconfig-local/etc/appprops/error.properties
new file mode 100644
index 0000000..bafe9c0
--- /dev/null
+++ b/bundleconfig-local/etc/appprops/error.properties
@@ -0,0 +1,164 @@
+# Adding comment trying to trigger a build
+#------------------------------------------------------------------------------- ----------
+#Key=Disposition:Category:Severity:Error Code:HTTP ResponseCode:RESTError Code:Error Message
+#------------------------------------------------------------------------------- ----------
+# testing code, please don't change unless error utility source code changes
+AAI_TESTING=5:2:WARN:0000:400:0001:Error code for testing
+
+# General success
+AAI_0000=0:0:INFO:0000:200:0000:Success
+
+# health check success
+AAI_0001=0:0:INFO:0001:200:0001:Success X-FromAppId=%1 X-TransactionId=%2
+AAI_0002=0:0:INFO:0002:200:0001:Successful health check
+
+# Success with additional info
+AAI_0003=0:3:INFO:0003:202:0003:Success with additional info performing %1 on %2. Added %3 with key %4
+AAI_0004=0:3:INFO:0004:202:0003:Added prerequisite object to db
+
+#--- aairest: 3000-3299
+# svc errors
+AAI_3000=5:2:INFO:3000:400:3000:Invalid input performing %1 on %2
+AAI_3001=5:6:INFO:3001:404:3001:Resource not found for %1 using id %2
+AAI_3002=5:1:WARN:3002:400:3002:Error writing output performing %1 on %2
+AAI_3003=5:1:WARN:3003:400:3003:Failed to make edge to missing target node of type %3 with keys %4 performing %1 on %2
+AAI_3005=5:6:WARN:3005:404:3001:Node cannot be directly accessed for read, must be accessed via ancestor(s)
+AAI_3006=5:6:WARN:3006:404:3001:Node cannot be directly accessed for write, must be accessed via ancestor(s)
+AAI_3007=5:6:INFO:3007:410:3007:This version (%1) of the API is retired, please migrate to %2
+AAI_3008=5:6:ERROR:3008:400:3008:URI is not encoded in UTF-8
+AAI_3009=5:6:ERROR:3009:400:3002:Malformed URL
+# pol errors
+AAI_3100=5:1:WARN:3100:400:3100:Unsupported operation %1
+AAI_3101=5:1:WARN:3101:403:3101:Attempt by client %1 to execute API %2
+AAI_3102=5:1:WARN:3102:400:3102:Error parsing input performing %1 on %2
+AAI_3300=5:1:WARN:3300:403:3300:Unauthorized
+AAI_3301=5:1:WARN:3301:401:3301:Stale credentials
+AAI_3302=5:1:WARN:3302:401:3301:Not authenticated
+AAI_3303=5:1:ERROR:3303:403:3300:Too many objects would be returned by this request, please refine your request and retry
+
+#--- aaigen: 4000-4099
+AAI_4000=5:4:ERROR:4000:500:3002:Internal Error
+AAI_4001=5:4:FATAL:4001:500:3002:Configuration file not found
+AAI_4002=5:4:FATAL:4002:500:3002:Error reading Configuration file
+AAI_4003=5:4:ERROR:4003:500:3002:Error writing to log file
+AAI_4004=5:4:FATAL:4004:500:3002:Error reading/parsing the error properties file
+AAI_4005=5:4:FATAL:4005:500:3002:Missing or invalid configuration parameter
+AAI_4006=5:4:FATAL:4006:500:3002:Unexpected error in service
+AAI_4007=5:4:ERROR:4007:500:3102:Input parsing error
+AAI_4008=5:4:ERROR:4008:500:3002:Output parsing error
+AAI_4009=4:0:ERROR:4009:400:3000:Invalid X-FromAppId in header
+AAI_4010=4:0:ERROR:4010:400:3000:Invalid X-TransactionId in header
+AAI_4011=5:4:ERROR:4011:500:3002:Missing data for REST error response
+AAI_4012=5:4:ERROR:4012:500:3002:Bad rule data in RestRules
+AAI_4013=5:4:ERROR:4013:500:3002:Error connecting to AAI REST API
+AAI_4014=4:0:ERROR:4014:400:3000:Invalid Accept header
+AAI_4015=4:0:ERROR:4015:400:3000:You must provide at least one indexed property
+AAI_4016=4:0:ERROR:4016:400:3000:The depth parameter must be a number or the string "all"
+AAI_4017=5:2:INFO:4017:400:3000:Could not set property
+AAI_4018=5:2:ERROR:4018:400:3000:Unable to convert the string to integer
+#--- aaidbmap: 5101-5199
+AAI_5101=5:4:FATAL:5101:500:3002:Could not connect to database
+AAI_5102=5:4:FATAL:5102:500:3002:Graph database is null after open
+AAI_5103=5:4:ERROR:5103:500:3002:Unexpected error during commit
+AAI_5104=5:4:ERROR:5104:500:3002:Unexpected error during rollback
+AAI_5105=5:4:ERROR:5105:500:3002:Unexpected error reading/updating database
+AAI_5106=5:4:WARN:5106:404:3001:Node not found
+AAI_5107=5:2:WARN:5107:400:3000:Required information missing
+AAI_5108=5:2:WARN:5108:200:0:Unexpected information in request being ignored
+
+#--- aaidbgen: 6101-6199
+AAI_6101=5:4:ERROR:6101:500:3002:null TitanGraph object passed
+AAI_6102=5:4:WARN:6102:400:3000:Passed-in property is not valid for this nodeType
+AAI_6103=5:4:WARN:6103:400:3000:Required Node-property not found in input data
+AAI_6104=5:4:WARN:6104:400:3000:Required Node-property was passed with no data
+AAI_6105=5:4:WARN:6105:400:3000:Node-Key-Property not defined in DbMaps
+AAI_6106=5:4:WARN:6106:400:3000:Passed-in property is not valid for this edgeType
+AAI_6107=5:4:WARN:6107:400:3000:Required Edge-property not found in input data
+AAI_6108=5:4:WARN:6108:400:3000:Required Edge-property was passed with no data
+AAI_6109=5:4:WARN:6109:400:3000:Bad dependent Node value
+AAI_6110=5:4:ERROR:6110:400:3100:Node cannot be deleted
+AAI_6111=5:4:ERROR:6111:400:3000:JSON processing error
+AAI_6112=5:4:ERROR:6112:400:3000:More than one node found by getUniqueNode()
+AAI_6114=5:4:INFO:6114:404:3001:Node Not Found
+AAI_6115=5:4:ERROR:6115:400:3000:Unrecognized NodeType
+AAI_6116=5:4:ERROR:6116:400:3000:Unrecognized Property
+AAI_6117=5:4:ERROR:6117:400:3000:Uniqueness constraint violated
+AAI_6118=5:4:ERROR:6118:400:3000:Required Field not passed.
+AAI_6120=5:4:ERROR:6120:400:3000:Bad Parameter Passed
+AAI_6121=5:4:ERROR:6121:400:3000:Problem with internal AAI reference data
+AAI_6122=5:4:ERROR:6122:400:3000:Data Set not complete in DB for this request
+AAI_6123=5:4:ERROR:6123:500:3000:Bad Data found by DataGrooming Tool - Investigate
+AAI_6124=5:4:ERROR:6124:500:3000:File read/write error
+AAI_6125=5:4:WARN:6125:500:3000:Problem Pulling Data Set
+AAI_6126=5:4:ERROR:6126:400:3000:Edge cannot be deleted
+AAI_6127=5:4:INFO:6127:404:3001:Edge Not Found
+AAI_6128=5:4:INFO:6128:500:3000:Unexpected error
+AAI_6129=5:4:INFO:6129:404:3003:Error making edge to target node
+AAI_6130=5:4:WARN:6130:412:3000:Precondition Required
+AAI_6131=5:4:WARN:6131:412:3000:Precondition Failed
+AAI_6132=5:4:WARN:6132:400:3000:Bad Model Definition
+AAI_6133=5:4:WARN:6133:400:3000:Bad Named Query Definition
+AAI_6134=5:4:ERROR:6134:500:6134:Could not persist transaction to storage back end. Exhausted retry amount
+AAI_6135=5:4:WARN:6135:412:3000:Resource version specified on create
+AAI_6136=5:4:ERROR:6136:400:3000:Object cannot hold multiple items
+AAI_6137=5:4:ERROR:6137:400:3000:Cannot perform writes on multiple vertices
+AAI_6138=5:4:ERROR:6138:400:3000:Cannot delete multiple vertices
+AAI_6139=5:4:ERROR:6139:404:3000:Attempted to add edge to vertex that does not exist
+AAI_6140=5:4:ERROR:6140:400:3000:Edge multiplicity violated
+AAI_6141=5:4:WARN:6141:400:3000:Please Refine Query
+AAI_6142=5:4:INFO:6142:400:3000:Retrying transaction
+AAI_6143=5:4:INFO:6143:400:3000:Ghost vertex found
+AAI_6144=5:4:WARN:6144:400:3000:Cycle found in graph
+AAI_6145=5:4:ERROR:6145:400:3000:Cannot create a nested/containment edge via relationship
+AAI_6146=5:4:ERROR:6146:400:3000:Ambiguous identity map found, use a URI instead
+
+#--- aaicsvp: 7101-7199
+AAI_7101=5:4:ERROR:7101:500:3002:Unexpected error in CSV file processing
+AAI_7102=5:4:ERROR:7102:500:3002:Error in cleanup temporary directory
+#AAI_7103=4:2:ERROR:7103:500:3002:Unsupported user
+AAI_7104=5:4:ERROR:7104:500:3002:Failed to create directory
+AAI_7105=5:4:ERROR:7105:500:3002:Temporary directory exists
+AAI_7106=5:4:ERROR:7106:500:3002:Cannot delete
+AAI_7107=5:4:ERROR:7107:500:3002:Input file does not exist
+AAI_7108=5:4:ERROR:7108:500:3002:Output file does not exist
+AAI_7109=5:4:ERROR:7109:500:3002:Error closing file
+AAI_7110=5:4:ERROR:7110:500:3002:Error loading/reading properties file
+AAI_7111=5:4:ERROR:7111:500:3002:Error executing shell script
+AAI_7112=5:4:ERROR:7112:500:3002:Error creating output file
+AAI_7113=5:4:ERROR:7113:500:3002:Trailer record error
+AAI_7114=5:4:ERROR:7114:500:3002:Input file error
+AAI_7115=5:4:ERROR:7115:500:3002:Unexpected error
+AAI_7116=5:4:ERROR:7116:500:3002:Request error
+AAI_7117=5:4:ERROR:7117:500:3002:Error in get http client object
+AAI_7118=5:4:ERROR:7118:500:3002:Script Error
+AAI_7119=5:4:ERROR:7119:500:3002:Unknown host
+
+#--- aaisdnc: 7201-7299
+AAI_7202=5:4:ERROR:7202:500:3002:Error getting connection to odl
+AAI_7203=5:4:ERROR:7203:500:3002:Unexpected error calling DataChangeNotification API
+AAI_7204=5:4:ERROR:7204:500:3002:Error returned by DataChangeNotification API
+AAI_7205=5:4:ERROR:7205:500:3002:Unexpected error running notifySDNCOnUpdate
+AAI_7206=5:4:ERROR:7206:500:3002:Invalid data returned from ODL
+
+#--- NotificationEvent, using UEB space
+AAI_7350=5:4:ERROR:7305:500:3002:Notification event creation failed
+
+#--- aairestctlr: 7401-7499
+AAI_7401=5:4:ERROR:7401:500:3002:Error connecting to AAI REST API
+AAI_7402=5:4:ERROR:7402:500:3002:Unexpected error
+AAI_7403=5:4:WARN:7403:400:3001:Request error
+AAI_7404=5:4:INFO:7404:404:3001:Node not found
+
+#--- aaiauth: 9101-9199
+AAI_9101=5:0:WARN:9101:403:3300:User is not authorized to perform function
+AAI_9102=5:0:WARN:9102:401:3301:Refresh credentials from source
+AAI_9103=5:0:WARN:9103:403:3300:User not found
+AAI_9104=5:0:WARN:9104:401:3302:Authentication error
+AAI_9105=5:0:WARN:9105:403:3300:Authorization error
+AAI_9106=5:0:WARN:9106:403:3300:Invalid AppId
+#AAI_9107=5:0:WARN:9107:403:3300:No Username in Request
+AAI_9107=5:0:WARN:9107:403:3300:SSL is not provided in request, please contact admin
+
+#--- aaiinstar: 9201-9299
+AAI_9201=5:4:ERROR:9201:500:3002:Unable to send notification
+AAI_9202=5:4:ERROR:9202:500:3002:Unable to start a thread
diff --git a/pom.xml b/pom.xml
index 99dd62b..8704324 100644
--- a/pom.xml
+++ b/pom.xml
@@ -131,20 +131,15 @@
</exclusions>
</dependency>
- <!-- TEST Dependencies -->
+ <groupId>com.jayway.jsonpath</groupId>
+ <artifactId>json-path</artifactId>
+ <version>2.2.0</version>
+ </dependency>
<dependency>
- <groupId>org.apache.tinkerpop</groupId>
- <artifactId>tinkergraph-gremlin</artifactId>
- <version>3.2.3</version>
- <scope>test</scope>
- </dependency>
-
- <dependency>
<groupId>org.apache.tinkerpop</groupId>
<artifactId>gremlin-core</artifactId>
- <version>3.2.3</version>
- <scope>test</scope>
+ <version>3.1.0-incubating</version>
<exclusions>
<exclusion>
<groupId>org.slf4j</groupId>
@@ -156,6 +151,17 @@
</exclusion>
</exclusions>
</dependency>
+
+ <!-- TEST Dependencies -->
+
+ <dependency>
+ <groupId>org.apache.tinkerpop</groupId>
+ <artifactId>tinkergraph-gremlin</artifactId>
+ <version>3.2.3</version>
+ <scope>test</scope>
+ </dependency>
+
+
<dependency>
<groupId>org.json</groupId>
diff --git a/src/main/ajsc/crud-api_v1/crud-api/v1/routes/aaiResources.route b/src/main/ajsc/crud-api_v1/crud-api/v1/routes/aaiResources.route
new file mode 100644
index 0000000..4cc0182
--- /dev/null
+++ b/src/main/ajsc/crud-api_v1/crud-api/v1/routes/aaiResources.route
@@ -0,0 +1,4 @@
+<route xmlns="http://camel.apache.org/schema/spring" trace="true">
+ <from uri="att-dme2-servlet:///resources?matchOnUriPrefix=true" />
+ <to uri="cxfbean:aaiResourceService" />
+</route> \ No newline at end of file
diff --git a/src/main/java/org/openecomp/crud/dao/GraphDao.java b/src/main/java/org/openecomp/crud/dao/GraphDao.java
index 20b568c..c714249 100644
--- a/src/main/java/org/openecomp/crud/dao/GraphDao.java
+++ b/src/main/java/org/openecomp/crud/dao/GraphDao.java
@@ -32,6 +32,8 @@ import java.util.Map;
public interface GraphDao {
+ public Vertex getVertex(String id) throws CrudException;
+
public Vertex getVertex(String id, String type) throws CrudException;
/**
diff --git a/src/main/java/org/openecomp/crud/dao/champ/ChampDao.java b/src/main/java/org/openecomp/crud/dao/champ/ChampDao.java
index 5e9d10a..31bc9ab 100644
--- a/src/main/java/org/openecomp/crud/dao/champ/ChampDao.java
+++ b/src/main/java/org/openecomp/crud/dao/champ/ChampDao.java
@@ -96,6 +96,40 @@ public class ChampDao implements GraphDao {
}
@Override
+ public Vertex getVertex(String id) throws CrudException {
+
+ try {
+
+ if (logger.isDebugEnabled()) {
+ logger.debug("getVertex with id: " + id);
+ }
+
+ long idAsLong = Long.parseLong(id);
+
+ Optional<ChampObject> retrievedVertex = champApi.retrieveObject(idAsLong);
+
+ String nodeType = org.openecomp.schema.OxmModelValidator.Metadata.NODE_TYPE.propertyName();
+ if(retrievedVertex.isPresent() &&
+ retrievedVertex.get().getProperties().get(nodeType)!=null) {
+ return vertexFromChampObject(retrievedVertex.get(),
+ retrievedVertex.get().getProperties().get(nodeType).toString());
+ } else {
+
+ // We didn't find a vertex with the supplied id, so just throw an
+ // exception.
+ throw new CrudException("No vertex with id " + id + " found in graph",
+ javax.ws.rs.core.Response.Status.NOT_FOUND);
+ }
+
+ } catch (ChampUnmarshallingException | ChampTransactionException e) {
+
+ // Something went wrong - throw an exception.
+ throw new CrudException(e.getMessage(),
+ javax.ws.rs.core.Response.Status.INTERNAL_SERVER_ERROR);
+ }
+ }
+
+ @Override
public Vertex getVertex(String id, String type) throws CrudException {
try {
diff --git a/src/main/java/org/openecomp/crud/service/AaiResourceService.java b/src/main/java/org/openecomp/crud/service/AaiResourceService.java
new file mode 100644
index 0000000..b8ac158
--- /dev/null
+++ b/src/main/java/org/openecomp/crud/service/AaiResourceService.java
@@ -0,0 +1,533 @@
+/**
+ * ============LICENSE_START=======================================================
+ * Gizmo
+ * ================================================================================
+ * Copyright © 2017 AT&T Intellectual Property.
+ * Copyright © 2017 Amdocs
+ * All rights reserved.
+ * ================================================================================
+ * 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=========================================================
+ *
+ * ECOMP is a trademark and service mark of AT&T Intellectual Property.
+ */
+package org.openecomp.crud.service;
+
+import java.security.cert.X509Certificate;
+import java.util.AbstractMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+
+import javax.security.auth.x500.X500Principal;
+import javax.servlet.http.HttpServletRequest;
+import javax.ws.rs.Consumes;
+import javax.ws.rs.Encoded;
+import javax.ws.rs.POST;
+import javax.ws.rs.PUT;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.HttpHeaders;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.UriInfo;
+import javax.ws.rs.core.Response.Status;
+
+import org.openecomp.aai.exceptions.AAIException;
+import org.openecomp.aai.serialization.db.EdgeProperty;
+import org.openecomp.aai.serialization.db.EdgeRule;
+import org.openecomp.aai.serialization.db.EdgeRules;
+import org.openecomp.aai.serialization.db.EdgeType;
+import org.openecomp.auth.Auth;
+import org.openecomp.cl.api.Logger;
+import org.openecomp.cl.eelf.LoggerFactory;
+import org.openecomp.crud.exception.CrudException;
+import org.openecomp.crud.logging.CrudServiceMsgs;
+import org.openecomp.crud.logging.LoggingUtil;
+import org.openecomp.crud.service.CrudRestService.Action;
+import org.openecomp.crud.util.CrudServiceConstants;
+import org.openecomp.schema.RelationshipSchemaLoader;
+import org.openecomp.schema.RelationshipSchemaValidator;
+import org.slf4j.MDC;
+
+import com.google.gson.Gson;
+import com.google.gson.JsonElement;
+import com.google.gson.JsonPrimitive;
+
+
+/**
+ * This defines a set of REST endpoints which allow clients to create or update graph edges
+ * where the edge rules defined by the A&AI will be invoked to automatically populate the
+ * defined edge properties.
+ */
+public class AaiResourceService {
+
+ private String mediaType = MediaType.APPLICATION_JSON;
+ public static final String HTTP_PATCH_METHOD_OVERRIDE = "X-HTTP-Method-Override";
+
+ private Auth auth;
+ CrudGraphDataService crudGraphDataService;
+ Gson gson = new Gson();
+
+ private Logger logger = LoggerFactory.getInstance().getLogger(AaiResourceService.class.getName());
+ private Logger auditLogger = LoggerFactory.getInstance().getAuditLogger(AaiResourceService.class.getName());
+
+ public AaiResourceService() {}
+
+ /**
+ * Creates a new instance of the AaiResourceService.
+ *
+ * @param crudGraphDataService - Service used for interacting with the graph.
+ *
+ * @throws Exception
+ */
+ public AaiResourceService(CrudGraphDataService crudGraphDataService) throws Exception {
+ this.crudGraphDataService = crudGraphDataService;
+ this.auth = new Auth(CrudServiceConstants.CRD_AUTH_FILE);
+ }
+
+ /**
+ * Perform any one-time initialization required when starting the service.
+ */
+ public void startup() {
+
+ if(logger.isDebugEnabled()) {
+ logger.debug("AaiResourceService started!");
+ }
+ }
+
+
+ /**
+ * Creates a new relationship in the graph, automatically populating the edge
+ * properties based on the A&AI edge rules.
+ *
+ * @param content - Json structure describing the relationship to create.
+ * @param type - Relationship type supplied as a URI parameter.
+ * @param uri - Http request uri
+ * @param headers - Http request headers
+ * @param uriInfo - Http URI info field
+ * @param req - Http request structure.
+ *
+ * @return - Standard HTTP response.
+ */
+ @POST
+ @Path("/relationships/{type}/")
+ @Consumes({MediaType.APPLICATION_JSON})
+ @Produces({MediaType.APPLICATION_JSON})
+ public Response createRelationship(String content,
+ @PathParam("type") String type,
+ @PathParam("uri") @Encoded String uri,
+ @Context HttpHeaders headers,
+ @Context UriInfo uriInfo,
+ @Context HttpServletRequest req) {
+
+ LoggingUtil.initMdcContext(req, headers);
+
+ if(logger.isDebugEnabled()) {
+ logger.debug("Incoming request..." + content);
+ }
+
+ Response response = null;
+
+ if (validateRequest(req, uri, content, Action.POST, CrudServiceConstants.CRD_AUTH_POLICY_NAME)) {
+
+ try {
+
+ // Extract the edge payload from the request.
+ EdgePayload payload = EdgePayload.fromJson(content);
+
+ // Do some basic validation on the payload.
+ if (payload.getProperties() == null || payload.getProperties().isJsonNull()) {
+ throw new CrudException("Invalid request Payload", Status.BAD_REQUEST);
+ }
+ if (payload.getId() != null) {
+ throw new CrudException("ID specified , use Http PUT to update Edge", Status.BAD_REQUEST);
+ }
+ if (payload.getType() != null && !payload.getType().equals(type)) {
+ throw new CrudException("Edge Type mismatch", Status.BAD_REQUEST);
+ }
+
+ // Apply the edge rules to our edge.
+ payload = applyEdgeRulesToPayload(payload);
+
+ if(logger.isDebugEnabled()) {
+ logger.debug("Creating AAI edge using version " + RelationshipSchemaLoader.getLatestSchemaVersion() );
+ }
+
+ // Now, create our edge in the graph store.
+ String result = crudGraphDataService.addEdge(RelationshipSchemaLoader.getLatestSchemaVersion(), type, payload);
+ response = Response.status(Status.CREATED).entity(result).type(mediaType).build();
+
+ } catch (CrudException e) {
+
+ response = Response.status(Status.INTERNAL_SERVER_ERROR).entity(e.getMessage()).build();
+ }
+ }
+
+ LoggingUtil.logRestRequest(logger, auditLogger, req, response);
+ return response;
+ }
+
+
+ /**
+ * Creates a new relationship in the graph, automatically populating the edge
+ * properties based on the A&AI edge rules.
+ *
+ * @param content - Json structure describing the relationship to create.
+ * @param uri - Http request uri
+ * @param headers - Http request headers
+ * @param uriInfo - Http URI info field
+ * @param req - Http request structure.
+ *
+ * @return - Standard HTTP response.
+ *
+ */
+ @POST
+ @Path("/relationships/")
+ @Consumes({MediaType.APPLICATION_JSON})
+ @Produces({MediaType.APPLICATION_JSON})
+ public Response createRelationship(String content,
+ @PathParam("uri") @Encoded String uri,
+ @Context HttpHeaders headers,
+ @Context UriInfo uriInfo,
+ @Context HttpServletRequest req) {
+
+ LoggingUtil.initMdcContext(req, headers);
+
+ logger.debug("Incoming request..." + content);
+ Response response = null;
+
+ if (validateRequest(req, uri, content, Action.POST, CrudServiceConstants.CRD_AUTH_POLICY_NAME)) {
+
+ try {
+
+ // Extract the edge payload from the request.
+ EdgePayload payload = EdgePayload.fromJson(content);
+
+ // Do some basic validation on the payload.
+ if (payload.getProperties() == null || payload.getProperties().isJsonNull()) {
+ throw new CrudException("Invalid request Payload", Status.BAD_REQUEST);
+ }
+ if (payload.getId() != null) {
+ throw new CrudException("ID specified , use Http PUT to update Edge", Status.BAD_REQUEST);
+ }
+ if (payload.getType() == null || payload.getType().isEmpty()) {
+ throw new CrudException("Missing Edge Type ", Status.BAD_REQUEST);
+ }
+
+ // Apply the edge rules to our edge.
+ payload = applyEdgeRulesToPayload(payload);
+
+ // Now, create our edge in the graph store.
+ String result = crudGraphDataService.addEdge(RelationshipSchemaLoader.getLatestSchemaVersion(), payload.getType(), payload);
+ response = Response.status(Status.CREATED).entity(result).type(mediaType).build();
+
+ } 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();
+ }
+ } else {
+ response = Response.status(Status.FORBIDDEN).entity(content)
+ .type(MediaType.APPLICATION_JSON).build();
+ }
+
+ LoggingUtil.logRestRequest(logger, auditLogger, req, response);
+ return response;
+ }
+
+
+
+ /**
+ * Upserts a relationship into the graph, automatically populating the edge properties
+ * based on the A&AI edge rules. The behaviour is as follows:
+ * <p>
+ * <li>If no relationship with the supplied identifier already exists, then a new relationship
+ * is created with that id.<br>
+ * <li>If a relationship with the supplied id DOES exist, then it is replaced with the supplied
+ * content.
+ *
+ * @param content - Json structure describing the relationship to create.
+ * @param type - Relationship type supplied as a URI parameter.
+ * @param id - Edge identifier.
+ * @param uri - Http request uri
+ * @param headers - Http request headers
+ * @param uriInfo - Http URI info field
+ * @param req - Http request structure.
+ *
+ * @return - Standard HTTP response.
+ */
+ @PUT
+ @Path("/relationships/{type}/{id}")
+ @Consumes({MediaType.APPLICATION_JSON})
+ @Produces({MediaType.APPLICATION_JSON})
+ public Response upsertEdge(String content,
+ @PathParam("type") String type,
+ @PathParam("id") String id,
+ @PathParam("uri") @Encoded String uri,
+ @Context HttpHeaders headers,
+ @Context UriInfo uriInfo,
+ @Context HttpServletRequest req) {
+ LoggingUtil.initMdcContext(req, headers);
+
+ logger.debug("Incoming request..." + content);
+ Response response = null;
+
+ if (validateRequest(req, uri, content, Action.PUT, CrudServiceConstants.CRD_AUTH_POLICY_NAME)) {
+
+ try {
+
+ // Extract the edge payload from the request.
+ EdgePayload payload = EdgePayload.fromJson(content);
+
+ // Do some basic validation on the payload.
+ if (payload.getProperties() == null || payload.getProperties().isJsonNull()) {
+ throw new CrudException("Invalid request Payload", Status.BAD_REQUEST);
+ }
+ if (payload.getId() != null && !payload.getId().equals(id)) {
+ throw new CrudException("ID Mismatch", Status.BAD_REQUEST);
+ }
+
+ // Apply the edge rules to our edge.
+ payload = applyEdgeRulesToPayload(payload);
+
+ String result;
+ if (headers.getRequestHeaders().getFirst(HTTP_PATCH_METHOD_OVERRIDE) != null &&
+ headers.getRequestHeaders().getFirst(HTTP_PATCH_METHOD_OVERRIDE).equalsIgnoreCase("PATCH")) {
+ result = crudGraphDataService.patchEdge(RelationshipSchemaLoader.getLatestSchemaVersion(), id, type, payload);
+ } else {
+
+ result = crudGraphDataService.updateEdge(RelationshipSchemaLoader.getLatestSchemaVersion(), id, type, payload);
+ }
+
+ response = Response.status(Status.OK).entity(result).type(mediaType).build();
+
+ } 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();
+ }
+
+ } else {
+
+ response = Response.status(Status.FORBIDDEN).entity(content)
+ .type(MediaType.APPLICATION_JSON).build();
+ }
+
+ LoggingUtil.logRestRequest(logger, auditLogger, req, response);
+ return response;
+ }
+
+
+ /**
+ * Retrieves the properties defined in the edge rules for a relationship between the
+ * supplied vertex types.
+ *
+ * @param sourceVertexType - Type of source vertex for the relationship.
+ * @param targetVertexType - Type of target vertex for the relationship.
+ *
+ * @return - The defined properties for the relationship type.
+ *
+ * @throws CrudException
+ */
+ private Map<EdgeProperty, String> getEdgeRuleProperties(String sourceVertexType, String targetVertexType) throws CrudException {
+
+ if(logger.isDebugEnabled()) {
+ logger.debug("Lookup db edge rules for " + sourceVertexType + " -> " + targetVertexType);
+ }
+
+ EdgeRules rules = EdgeRules.getInstance();
+ EdgeRule rule;
+ try {
+
+ if(logger.isDebugEnabled()) {
+ logger.debug("Lookup by edge type TREE");
+ }
+
+ // We have no way of knowing in advance whether our relationship is considered to
+ // be a tree or cousing relationship, so try looking it up as a tree type first.
+ rule = rules.getEdgeRule(EdgeType.TREE, sourceVertexType, targetVertexType);
+
+ } catch (AAIException e) {
+ try {
+
+ if(logger.isDebugEnabled()) {
+ logger.debug("Lookup by edge type COUSIN");
+ }
+
+ // If we are here, then our lookup by 'tree' type failed, so try looking it up
+ // as a 'cousin' relationship.
+ rule = rules.getEdgeRule(EdgeType.COUSIN, sourceVertexType, targetVertexType);
+
+ } catch (AAIException e1) {
+
+ // If we're here then we failed to find edge rules for this relationship. Time to
+ // give up...
+ throw new CrudException("No edge rules for " + sourceVertexType + " -> " + targetVertexType, Status.NOT_FOUND);
+ }
+ } catch (Exception e) {
+
+ throw new CrudException("General failure getting edge rule properties - " +
+ e.getMessage(), Status.INTERNAL_SERVER_ERROR);
+ }
+
+ return rule.getEdgeProperties();
+ }
+
+
+ /**
+ * This method takes an inbound edge request payload, looks up the edge rules for the
+ * sort of relationship defined in the payload, and automatically applies the defined
+ * edge properties to it.
+ *
+ * @param payload - The original edge request payload
+ *
+ * @return - An updated edge request payload, with the properties defined in the edge
+ * rules automatically populated.
+ *
+ * @throws CrudException
+ */
+ public EdgePayload applyEdgeRulesToPayload(EdgePayload payload) throws CrudException {
+
+ // Extract the types for both the source and target vertices.
+ String srcType = RelationshipSchemaValidator.vertexTypeFromUri(payload.getSource());
+ String tgtType = RelationshipSchemaValidator.vertexTypeFromUri(payload.getTarget());
+
+ // Now, get the default properties for this edge based on the edge rules definition...
+ Map<EdgeProperty, String> props = getEdgeRuleProperties(srcType, tgtType);
+
+ // ...and merge them with any custom properties provided in the request.
+ JsonElement mergedProperties = mergeProperties(payload.getProperties(), props);
+ payload.setProperties(mergedProperties);
+
+
+ if(logger.isDebugEnabled()) {
+ logger.debug("Edge properties after applying rules for '" + srcType + " -> " + tgtType + "': " + mergedProperties);
+ }
+
+ return payload;
+ }
+
+
+ /**
+ * Given a set of edge properties extracted from an edge request payload and a set of properties
+ * taken from the db edge rules, this method merges them into one set of properties.
+ * <p>
+ * If the client has attempted to override the defined value for a property in the db edge rules
+ * then the request will be rejected as invalid.
+ *
+ * @param propertiesFromRequest - Set of properties from the edge request.
+ * @param propertyDefaults - Set of properties from the db edge rules.
+ *
+ * @return - A merged set of properties.
+ *
+ * @throws CrudException
+ */
+ public JsonElement mergeProperties(JsonElement propertiesFromRequest, Map<EdgeProperty, String> propertyDefaults) throws CrudException {
+
+ // Convert the properties from the edge payload into something we can
+ // manipulate.
+ Set<Map.Entry<String, JsonElement>> properties = new HashSet<Map.Entry<String, JsonElement>>();
+ properties.addAll(propertiesFromRequest.getAsJsonObject().entrySet());
+
+ Set<String> propertyKeys = new HashSet<String>();
+ for(Map.Entry<String, JsonElement> property : properties) {
+ propertyKeys.add(property.getKey());
+ }
+
+ // Now, merge in the properties specified in the Db Edge Rules.
+ for(EdgeProperty defProperty : propertyDefaults.keySet()) {
+
+ // If the edge rules property was explicitly specified by the
+ // client then we will reject the request...
+ if(!propertyKeys.contains(defProperty.toString())) {
+ properties.add(new AbstractMap.SimpleEntry<String, JsonElement>(defProperty.toString(),
+ (JsonElement)(new JsonPrimitive(propertyDefaults.get(defProperty)))));
+
+ } else {
+ throw new CrudException("Property " + defProperty + " defined in db edge rules can not be overriden by the client.",
+ Status.BAD_REQUEST);
+ }
+ }
+
+ Object[] propArray = properties.toArray();
+ StringBuilder sb = new StringBuilder();
+ sb.append("{");
+ boolean first=true;
+ for(int i=0; i<propArray.length; i++) {
+
+ Map.Entry<String, JsonElement> entry = (Entry<String, JsonElement>) propArray[i];
+ if(!first) {
+ sb.append(",");
+ }
+ sb.append("\"").append(entry.getKey()).append("\"").append(":").append(entry.getValue());
+ first=false;
+ }
+ sb.append("}");
+
+ // We're done. Return the result as a JsonElement.
+ return gson.fromJson(sb.toString(), JsonElement.class);
+ }
+
+
+ /**
+ * Invokes authentication validation on an incoming HTTP request.
+ *
+ * @param req - The HTTP request.
+ * @param uri - HTTP URI
+ * @param content - Payload of the HTTP request.
+ * @param action - What HTTP action is being performed (GET/PUT/POST/PATCH/DELETE)
+ * @param authPolicyFunctionName - Policy function being invoked.
+ *
+ * @return true - if the request passes validation,
+ * false - otherwise.
+ */
+ protected boolean validateRequest(HttpServletRequest req,
+ String uri,
+ String content,
+ Action action,
+ String authPolicyFunctionName) {
+ try {
+ String cipherSuite = (String) req.getAttribute("javax.servlet.request.cipher_suite");
+ String authUser = null;
+ if (cipherSuite != null) {
+
+ X509Certificate[] certChain = (X509Certificate[]) req.getAttribute("javax.servlet.request.X509Certificate");
+ X509Certificate clientCert = certChain[0];
+ X500Principal subjectDn = clientCert.getSubjectX500Principal();
+ authUser = subjectDn.toString();
+ }
+
+ return this.auth.validateRequest(authUser.toLowerCase(), action.toString() + ":" + authPolicyFunctionName);
+
+ } catch (Exception e) {
+ logResult(action, uri, e);
+ return false;
+ }
+ }
+
+ protected void logResult(Action op, String uri, Exception e) {
+
+ logger.error(CrudServiceMsgs.EXCEPTION_DURING_METHOD_CALL,
+ op.toString(),
+ uri,
+ e.getStackTrace().toString());
+
+ // Clear the MDC context so that no other transaction inadvertently
+ // uses our transaction id.
+ MDC.clear();
+ }
+}
diff --git a/src/main/java/org/openecomp/crud/service/CrudGraphDataService.java b/src/main/java/org/openecomp/crud/service/CrudGraphDataService.java
index e6d6748..a8c0248 100644
--- a/src/main/java/org/openecomp/crud/service/CrudGraphDataService.java
+++ b/src/main/java/org/openecomp/crud/service/CrudGraphDataService.java
@@ -159,6 +159,10 @@ public class CrudGraphDataService {
}
+ public Vertex getVertex(String id) throws CrudException {
+ return dao.getVertex(id);
+ }
+
public String getVertex(String version, String id, String type) throws CrudException {
type = OxmModelValidator.resolveCollectionType(version, type);
Vertex vertex = dao.getVertex(id, type);
diff --git a/src/main/java/org/openecomp/crud/util/CrudServiceUtil.java b/src/main/java/org/openecomp/crud/util/CrudServiceUtil.java
index 25e3de6..b88f20b 100644
--- a/src/main/java/org/openecomp/crud/util/CrudServiceUtil.java
+++ b/src/main/java/org/openecomp/crud/util/CrudServiceUtil.java
@@ -41,6 +41,13 @@ public class CrudServiceUtil {
} else if (clazz.isAssignableFrom(Double.class)) {
return Double.parseDouble(value);
} else if (clazz.isAssignableFrom(Boolean.class)) {
+
+ // If the value is an IN/OUT direction, this gets seen as a boolean, so
+ // check for that first.
+ if (value.equals("OUT") || value.equals("IN")) {
+ return value;
+ }
+
if (!value.equals("true") && !value.equals("false")) {
throw new CrudException("Invalid propertry value: " + value, Status.BAD_REQUEST);
}
diff --git a/src/main/java/org/openecomp/schema/RelationshipSchemaValidator.java b/src/main/java/org/openecomp/schema/RelationshipSchemaValidator.java
index af20699..e2374be 100644
--- a/src/main/java/org/openecomp/schema/RelationshipSchemaValidator.java
+++ b/src/main/java/org/openecomp/schema/RelationshipSchemaValidator.java
@@ -338,4 +338,15 @@ public class RelationshipSchemaValidator {
return modelEdgeBuilder.build();
}
+
+ public static String vertexTypeFromUri(String uri) throws CrudException {
+
+ Matcher matcher = urlPattern.matcher(uri);
+
+ if (!matcher.matches()) {
+ throw new CrudException("Invalid Source/Target Urls", Status.BAD_REQUEST);
+ }
+
+ return matcher.group(2);
+ }
}
diff --git a/src/test/java/org/openecomp/crud/dao/champ/ChampDaoTest.java b/src/test/java/org/openecomp/crud/dao/champ/ChampDaoTest.java
index 4f57f2c..930999c 100644
--- a/src/test/java/org/openecomp/crud/dao/champ/ChampDaoTest.java
+++ b/src/test/java/org/openecomp/crud/dao/champ/ChampDaoTest.java
@@ -23,603 +23,603 @@ import static org.junit.Assert.*;
*/
public class ChampDaoTest {
- private static final String GRAPH_NAME = "my_test_graph";
-
- private GraphDao champDao = null;
-
-
- /**
- * Perform setup steps that must be done prior to executing each test.
- */
- @Before
- public void setup() {
-
- // Create an instance of the Champ DAO, backed by the Champ library's in-memory back end
- // for testing purposes.
- Map<String, Object> champDaoProperties = new HashMap<String, Object>();
- champDaoProperties.put(ChampDao.CONFIG_STORAGE_BACKEND, "in-memory");
- champDaoProperties.put(ChampDao.CONFIG_GRAPH_NAME, GRAPH_NAME);
- champDao = new ChampDao(new InMemoryChampGraphImpl.Builder().properties(champDaoProperties).build());
- }
-
-
- /**
- * Perform tear down steps that must be done after executing each test.
- */
- @After
- public void tearDown() {
-
- // Release the Champ DAO instance that we were using for the test.
- if (champDao != null) {
- ((ChampDao) champDao).close();
- }
- }
-
-
- /**
- * Tests the ability of the {@link ChampDao} to create a vertex.
- *
- * @throws CrudException
- */
- @Test
- public void createVertexTest() throws CrudException {
-
- String VERTEX_TYPE = "Test_Vertex";
-
- Map<String, Object> properties = new HashMap<String, Object>();
- properties.put("property1", "something");
- properties.put("property2", "something else");
-
- // Create the vertex.
- Vertex createdVertex = champDao.addVertex(VERTEX_TYPE, properties);
-
- // Validate that the returned {@link Vertex} has the right label assigned to it.
- assertTrue("Unexpected vertex type '" + createdVertex.getType() + "' returned from DAO",
- createdVertex.getType().equals(VERTEX_TYPE));
-
- // Validate that all of the properties that we provided to the DAO are in fact assigned
- // to the {@link Vertex} that we got back.
- assertTrue("Vertex property list returned from DAO did not contain all expected properties - expected: " +
- properties.keySet() + " actual: " + createdVertex.getProperties().keySet(),
- createdVertex.getProperties().keySet().containsAll(properties.keySet()));
-
- // Validate that the values assigned to the properties in the returned {@link Vertex}
- // match the ones that we provided.
- for (String propertyKey : properties.keySet()) {
-
- assertTrue(createdVertex.getProperties().get(propertyKey).equals(properties.get(propertyKey)));
- }
- }
-
-
- /**
- * Tests the ability of the {@link ChampDao} to retrieve a vertex from the graph data store
- * by its unique identifier.
- *
- * @throws CrudException
- */
- @Test
- public void getVertexByIdTest() throws CrudException {
-
- String VERTEX_TYPE = "Test_Vertex";
-
- Map<String, Object> properties = new HashMap<String, Object>();
- properties.put("property1", "something");
- properties.put("property2", "something else");
-
- // Create the vertex.
- Vertex createdVertex = champDao.addVertex(VERTEX_TYPE, properties);
-
- // Make sure the {@link Vertex} returned from the create method includes an id that we can
- // use to retrieve it.
- assertTrue("No valid id returned for the created vertex", createdVertex.getId().isPresent());
-
- // Now, retrieve the {@link Vertex} by its identifier.
- Vertex retrievedVertex = champDao.getVertex(createdVertex.getId().get(), VERTEX_TYPE);
-
- // Validate that the retrieved {@link Vertex} has the right label assigned to it.
- assertTrue("Unexpected vertex type '" + retrievedVertex.getType() + "' returned from DAO",
- retrievedVertex.getType().equals(VERTEX_TYPE));
-
- // Validate that all of the properties that we provided when we created the {@link Vertex}
- // are present in the {@link Vertex} that we retrieved.
- assertTrue("Vertex property list returned from DAO did not contain all expected properties - expected: " +
- properties.keySet() + " actual: " + retrievedVertex.getProperties().keySet(),
- retrievedVertex.getProperties().keySet().containsAll(properties.keySet()));
-
- // Validate that the values assigned to the properties in the retrieved {@link Vertex}
- // match the ones that we provided when we created it.
- for (String propertyKey : properties.keySet()) {
-
- assertTrue(retrievedVertex.getProperties().get(propertyKey).equals(properties.get(propertyKey)));
- }
- }
-
-
- /**
- * Tests the ability of the {@link ChampDao} to update an already existing vertex.
- *
- * @throws CrudException
- */
- @Test
- public void updateVertexTest() throws CrudException {
-
- final String VERTEX_TYPE = "Test_Vertex";
-
- Map<String, Object> properties = new HashMap<String, Object>();
- properties.put("property1", "something");
- properties.put("property2", "something else");
-
- // Create the vertex.
- Vertex createdVertex = champDao.addVertex(VERTEX_TYPE, properties);
-
- // Make sure the {@link Vertex} returned from the create method includes an id that we can
- // use to retrieve it.
- assertTrue("No valid id returned for the created vertex", createdVertex.getId().isPresent());
-
- // Modify the properties list...
- properties.put("property3", "a new property");
- properties.remove("property1");
-
- // ...and apply it to our vertex.
- Vertex updatedVertex = champDao.updateVertex(createdVertex.getId().get(), createdVertex.getType(), properties);
-
- assertTrue("Vertex property list returned from DAO update operation did not contain all expected properties - expected: " +
- properties.keySet() + " actual: " + updatedVertex.getProperties().keySet(),
- updatedVertex.getProperties().keySet().containsAll(properties.keySet()));
-
- // Validate that the values assigned to the properties in the updated {@link Vertex}
- // match the ones that we provided when we created it.
- for (String propertyKey : properties.keySet()) {
-
- assertTrue("Unexpected value for property '" + propertyKey + "' - Expected: " +
- properties.get(propertyKey) + " Actual: " +
- updatedVertex.getProperties().get(propertyKey),
- updatedVertex.getProperties().get(propertyKey).equals(properties.get(propertyKey)));
- }
-
- // Validate that the property that we removed is NOT in the set of properties from our
- // updated {@link Vertex}.
- assertFalse("Property 'property1' should no longer be associated with updated vertex",
- updatedVertex.getProperties().containsKey("property1"));
- }
-
-
- /**
- * Tests the ability of the {@link ChampDao} to retrieve multiple vertices which match
- * a particular set of supplied properties.
- *
- * @throws CrudException
- */
- @Test
- public void getVerticesTest() throws CrudException {
-
- final String FIRST_VERTEX_TYPE = "pserver";
- final String SECOND_VERTEX_TYPE = "complex";
-
- // Create some vertices.
-
- Map<String, Object> vertex1Properties = new HashMap<String, Object>();
- vertex1Properties.put("O/S", "Linux");
- vertex1Properties.put("version", "6.5");
- vertex1Properties.put("hostname", "kll0001");
- champDao.addVertex(FIRST_VERTEX_TYPE, vertex1Properties);
-
- Map<String, Object> vertex2Properties = new HashMap<String, Object>();
- vertex2Properties.put("O/S", "Linux");
- vertex2Properties.put("version", "6.5");
- vertex2Properties.put("hostname", "kll0002");
- champDao.addVertex(FIRST_VERTEX_TYPE, vertex2Properties);
-
- Map<String, Object> vertex3Properties = new HashMap<String, Object>();
- vertex3Properties.put("O/S", "Linux");
- vertex3Properties.put("version", "7.2");
- vertex3Properties.put("hostname", "kll0003");
- champDao.addVertex(FIRST_VERTEX_TYPE, vertex3Properties);
-
- Map<String, Object> vertex4Properties = new HashMap<String, Object>();
- vertex4Properties.put("O/S", "Windows");
- vertex4Properties.put("version", "10");
- vertex4Properties.put("hostname", "Dev Laptop");
- champDao.addVertex(FIRST_VERTEX_TYPE, vertex4Properties);
-
- Map<String, Object> vertex5Properties = new HashMap<String, Object>();
- vertex5Properties.put("Street", "Baker");
- vertex5Properties.put("Number", "222B");
- champDao.addVertex(SECOND_VERTEX_TYPE, vertex5Properties);
-
- // Create a set of properties to use for our query.
- Map<String, Object> queryProperties = new HashMap<String, Object>();
- queryProperties.put("O/S", "Linux");
- queryProperties.put("version", "6.5");
-
- // Validate that we filter our 'get vertices' results by type
- List<Vertex> allVerticesByType = champDao.getVertices(FIRST_VERTEX_TYPE, MapBuilder.builder().build());
- for (Vertex v : allVerticesByType) {
- assertTrue("Unexpected vertex type returned from query. Expected: " +
- FIRST_VERTEX_TYPE + " Actual: " + v.getType(),
- v.getType().equals(FIRST_VERTEX_TYPE));
- }
-
- // Now, request the vertices that match our parameters.
- List<Vertex> vertices = champDao.getVertices(FIRST_VERTEX_TYPE, queryProperties);
-
- // Validate that got back the expected number of vertices.
- assertEquals(vertices.size(), 2);
-
- // Validate that the vertices we got back contain the expected parameters.
- for (Vertex v : vertices) {
-
- assertTrue("Vertex from query result does not contain expected vertex 'O/S'",
- v.getProperties().containsKey("O/S"));
- assertTrue("Vertex from query result contains unexpected value for 'O/S' parameter - Expected: 'Linux' Actual: '" +
- v.getProperties().get("O/S") + "'",
- v.getProperties().get("O/S").equals("Linux"));
-
- assertTrue("Vertex from query result does not contain expected vertex 'O/S'",
- v.getProperties().containsKey("version"));
- assertTrue("Vertex from query result contains unexpected value for 'O/S' parameter - Expected: 'Linux' Actual: '" +
- v.getProperties().get("O/S") + "'",
- v.getProperties().get("version").equals("6.5"));
- }
- }
-
- @Test
- public void deleteVertexTest() throws CrudException {
-
- boolean deletedVertexNotFound = false;
-
- // Create a vertex.
- Vertex createdVertex = champDao.addVertex("test_type", MapBuilder.builder()
- .withKeyValue("O/S", "Linux")
- .withKeyValue("version", "6.5")
- .withKeyValue("hostname", "kll0001")
- .build());
-
- // Verify that we can retrieve the vertex from the graph data base.
- Vertex retrievedVertex = champDao.getVertex(createdVertex.getId().get(), "test_type");
-
- // Now, delete the vertex.
- champDao.deleteVertex(createdVertex.getId().get(), "test_type");
-
- // Now, try to retrieve it again. This time we should fail to find it.
- try {
- champDao.getVertex(createdVertex.getId().get(), "test_type");
-
- } catch (CrudException e) {
- assertTrue(e.getMessage().contains("No vertex with id"));
- deletedVertexNotFound = true;
- }
-
- assertTrue("Should not have been able to retrieve deleted vertex", deletedVertexNotFound);
- }
-
- @Test
- public void createEdgeTest() throws CrudException {
-
- String EDGE_TYPE = "has";
-
- // Create the source vertex for the edge.
- Map<String, Object> srcVertexProperties = new HashMap<String, Object>();
- srcVertexProperties.put("O/S", "Linux");
- srcVertexProperties.put("version", "6.5");
- srcVertexProperties.put("hostname", "kll0001");
- Vertex sourceVertex = champDao.addVertex("vserver", srcVertexProperties);
-
- // Create the target vertex for the edge.
- Map<String, Object> dstVertexProperties = new HashMap<String, Object>();
- dstVertexProperties.put("O/S", "Linux");
- dstVertexProperties.put("version", "6.5");
- dstVertexProperties.put("hostname", "kll0002");
- Vertex destVertex = champDao.addVertex("VNF", dstVertexProperties);
-
- // Now, create the edge itself.
- Map<String, Object> edgeProperties = new HashMap<String, Object>();
- edgeProperties.put("prop", "val");
- Edge createdEdge = champDao.addEdge("has", sourceVertex, destVertex, edgeProperties);
-
- // Validate that the Edge object returned from the create method matches what we were
- // trying to create.
- assertTrue("Unexpected type for Edge returned from create method. Expected: " + EDGE_TYPE
- + " Actual: " + createdEdge.getType(),
- createdEdge.getType().equals("has"));
- assertTrue("Unexpected properties for Edge returned from create method. Expected: " + edgeProperties
- + " Actual: " + createdEdge.getProperties(),
- createdEdge.getProperties().equals(edgeProperties));
-
- }
-
- @Test
- public void createEdgeWithMissingSrcOrTargetTest() throws CrudException {
-
- String EDGE_TYPE = "has";
-
- // Create the source vertex for the edge.
- Map<String, Object> srcVertexProperties = new HashMap<String, Object>();
- srcVertexProperties.put("O/S", "Linux");
- srcVertexProperties.put("version", "6.5");
- srcVertexProperties.put("hostname", "kll0001");
- Vertex sourceVertex = champDao.addVertex("vserver", srcVertexProperties);
-
- // Create the target vertex for the edge.
- Map<String, Object> dstVertexProperties = new HashMap<String, Object>();
- dstVertexProperties.put("O/S", "Linux");
- dstVertexProperties.put("version", "6.5");
- dstVertexProperties.put("hostname", "kll0002");
- Vertex destVertex = champDao.addVertex("VNF", dstVertexProperties);
-
- // Now, try creating the Edge but specify an id for the source vertex that does
- // not exist.
- Map<String, Object> edgeProperties = new HashMap<String, Object>();
- edgeProperties.put("prop", "val");
- try {
- champDao.addEdge(EDGE_TYPE, new Vertex.Builder("miss").id("99").build(), destVertex, edgeProperties);
- } catch (CrudException e) {
- assertTrue(e.getMessage().contains("Error creating edge - source vertex"));
- }
-
- // Now, try created the Edge with a valid source vertex, but specify an id for the
- // target vertex that does not exist.
- try {
- champDao.addEdge(EDGE_TYPE, sourceVertex, new Vertex.Builder("miss").id("99").build(), edgeProperties);
- } catch (CrudException e) {
- assertTrue(e.getMessage().contains("Error creating edge - target vertex"));
- }
-
- }
-
- @Test
- public void getEdgeByIdTest() throws CrudException {
-
- String EDGE_TYPE = "has";
-
- // Create the source vertex for the edge.
- Map<String, Object> srcVertexProperties = new HashMap<String, Object>();
- srcVertexProperties.put("O/S", "Linux");
- srcVertexProperties.put("version", "6.5");
- srcVertexProperties.put("hostname", "kll0001");
- Vertex sourceVertex = champDao.addVertex("vserver", srcVertexProperties);
-
- // Create the target vertex for the edge.
- Map<String, Object> dstVertexProperties = new HashMap<String, Object>();
- dstVertexProperties.put("O/S", "Linux");
- dstVertexProperties.put("version", "6.5");
- dstVertexProperties.put("hostname", "kll0002");
- Vertex destVertex = champDao.addVertex("VNF", dstVertexProperties);
-
- // Now, create the edge itself.
- Map<String, Object> edgeProperties = new HashMap<String, Object>();
- edgeProperties.put("prop", "val");
- Edge createdEdge = champDao.addEdge("has", sourceVertex, destVertex, edgeProperties);
-
- // Retrieve the edge we just created by specifying its unique identifier.
- Edge retrievedEdge = champDao.getEdge(createdEdge.getId().get(), "has");
-
- // Validate that the contents of the object that we got back matches what we thought we
- // created.
- assertTrue("Unexpected type for Edge returned from get method. Expected: " + EDGE_TYPE
- + " Actual: " + retrievedEdge.getType(),
- retrievedEdge.getType().equals(EDGE_TYPE));
- assertTrue("Unexpected properties for Edge returned from get method. Expected: " + edgeProperties
- + " Actual: " + retrievedEdge.getProperties(),
- retrievedEdge.getProperties().equals(edgeProperties));
- }
-
- @Test
- public void getEdgesTest() throws CrudException {
-
- final String EDGE_TYPE_HAS = "has";
- final String EDGE_TYPE_RUNS = "runs";
-
- // Create some vertices and edges that we can query agains.
- Vertex complex = champDao.addVertex("complex", MapBuilder.builder()
- .withKeyValue("Province", "Ontario")
- .withKeyValue("City", "Ottawa")
- .withKeyValue("Street", "303 Terry Fox")
- .build());
-
- Vertex vserver = champDao.addVertex("vserver", MapBuilder.builder()
- .withKeyValue("O/S", "Linux")
- .withKeyValue("version", "6.5")
- .withKeyValue("hostname", "kll0001")
- .build());
-
- Vertex vnf1 = champDao.addVertex("vserver", MapBuilder.builder()
- .withKeyValue("Application", "OpenDaylight")
- .build());
-
- Vertex vnf2 = champDao.addVertex("vserver", MapBuilder.builder()
- .withKeyValue("Application", "Cammunda")
- .build());
-
- Edge edge1 = champDao.addEdge(EDGE_TYPE_HAS, complex, vserver,
- MapBuilder.builder()
- .withKeyValue("usesResource", "false")
- .withKeyValue("hasDelTarget", "false")
- .build());
-
- Edge edge2 = champDao.addEdge(EDGE_TYPE_RUNS, vserver, vnf1,
- MapBuilder.builder()
- .withKeyValue("usesResource", "false")
- .withKeyValue("hasDelTarget", "true")
- .build());
-
- Edge edge3 = champDao.addEdge(EDGE_TYPE_RUNS, vserver, vnf2,
- MapBuilder.builder()
- .withKeyValue("usesResource", "false")
- .withKeyValue("hasDelTarget", "false")
- .build());
-
- // Query for all HAS edges.
- List<Edge> hasEdges = champDao.getEdges(EDGE_TYPE_HAS, new HashMap<String, Object>());
-
- assertEquals("Unexpected number of edges of type 'has' found. Expected: 1 Actual: " + hasEdges.size(),
- hasEdges.size(), 1);
- assertTrue("Result of query for 'has' type edges does not contain the expected results",
- containsEdge(edge1, hasEdges));
-
- // Query for all RUNS edges.
- List<Edge> runsEdges = champDao.getEdges(EDGE_TYPE_RUNS, new HashMap<String, Object>());
-
- assertEquals("Unexpected number of edges of type 'runs' found. Expected: 2 Actual: " + runsEdges.size(),
- runsEdges.size(), 2);
- assertTrue("Result of query for 'runs' type edges does not contain the expected results",
- containsEdge(edge2, runsEdges));
- assertTrue("Result of query for 'runs' type edges does not contain the expected results",
- containsEdge(edge2, runsEdges));
-
- // Query for all HAS edges with the property 'hasDelTarget' equal to 'true'.
- List<Edge> runsEdgesWithDelTargetTrue =
- champDao.getEdges(EDGE_TYPE_RUNS, MapBuilder.builder()
- .withKeyValue("hasDelTarget", "true")
- .build());
-
- assertEquals("Unexpected number of edges of type 'has' with 'hasDelTarget=true' found. Expected: 1 Actual: "
- + runsEdgesWithDelTargetTrue.size(),
- runsEdgesWithDelTargetTrue.size(), 1);
- assertTrue("Result of query for 'runs' type edges with delTarget set to TRUE does not contain the expected results",
- containsEdge(edge2, runsEdgesWithDelTargetTrue));
- }
-
- @Test
- @Ignore // For now - pending some expected fixes to the Champ library.
- public void updateEdgeTest() throws CrudException {
-
- // Create the source vertex for the edge.
- Vertex sourceVertex = champDao.addVertex("vserver", MapBuilder.builder()
- .withKeyValue("O/S", "Linux")
- .withKeyValue("version", "6.5")
- .withKeyValue("hostname", "kll0001")
- .build());
-
- // Create the target vertex for the edge.
- Vertex destVertex = champDao.addVertex("VNF", MapBuilder.builder()
- .withKeyValue("O/S", "Linux")
- .withKeyValue("version", "6.5")
- .withKeyValue("hostname", "kll0002")
- .build());
-
- // Now, create the edge itself.
- Edge createdEdge = champDao.addEdge("has",
- sourceVertex,
- destVertex,
- MapBuilder.builder()
- .withKeyValue("key1", "value1")
- .withKeyValue("key2", "value2")
- .withKeyValue("key3", "value3")
- .build());
-
- // Make sure the Edge returned from the create method includes an id that we can
- // use to retrieve it.
- assertTrue("No valid id returned for the created edge", createdEdge.getId().isPresent());
-
- // Retrieve the properties map for our edge and make some changes.
- Map<String, Object> properties = createdEdge.getProperties();
- properties.put("key4", "value4");
- properties.remove("key2");
-
- // Now update the edge with the new properties map.
- Edge updatedEdge = champDao.updateEdge(createdEdge);
-
- assertTrue("Edge property list returned from DAO update operation did not contain all expected properties - expected: " +
- properties.keySet() + " actual: " + updatedEdge.getProperties().keySet(),
- updatedEdge.getProperties().keySet().containsAll(properties.keySet()));
-
- // Validate that the values assigned to the properties in the updated Edge
- // match the ones that we provided when we created it.
- for (String propertyKey : properties.keySet()) {
-
- assertTrue("Unexpected value for property '" + propertyKey + "' - Expected: " +
- properties.get(propertyKey) + " Actual: " +
- updatedEdge.getProperties().get(propertyKey),
- updatedEdge.getProperties().get(propertyKey).equals(properties.get(propertyKey)));
- }
-
- // Validate that the property that we removed is NOT in the set of properties from our
- // updated edge.
- // *** We will leave this validation commented out for now, as the Champ library actually
- // merges update properties instead of replacing them...
-// assertFalse("Property 'key2' should no longer be associated with updated edge",
-// updatedEdge.getProperties().containsKey("key2"));
- }
-
- @Test
- public void deleteEdgeTest() throws CrudException {
-
- boolean deletedEdgeNotFound = false;
-
- // Create the source vertex for the edge.
- Vertex sourceVertex = champDao.addVertex("vserver", MapBuilder.builder()
- .withKeyValue("O/S", "Linux")
- .withKeyValue("version", "6.5")
- .withKeyValue("hostname", "kll0001")
- .build());
-
- // Create the target vertex for the edge.
- Vertex destVertex = champDao.addVertex("VNF", MapBuilder.builder()
- .withKeyValue("O/S", "Linux")
- .withKeyValue("version", "6.5")
- .withKeyValue("hostname", "kll0002")
- .build());
-
- // Now, create the edge itself.
- Edge createdEdge = champDao.addEdge("has",
- sourceVertex,
- destVertex,
- MapBuilder.builder()
- .withKeyValue("key1", "value1")
- .withKeyValue("key2", "value2")
- .withKeyValue("key3", "value3")
- .build());
-
- // Verify that we can retrieve the edge that we just created.
- Edge retrievedEdge = champDao.getEdge(createdEdge.getId().get(), "has");
-
- // Now, delete it.
- champDao.deleteEdge(createdEdge.getId().get(), "has");
-
- // Try retrieving it again. This time we should not find it.
- try {
- champDao.getEdge(createdEdge.getId().get(), "has");
- } catch (CrudException e) {
-
- assertTrue(e.getMessage().contains("No edge with id"));
- deletedEdgeNotFound = true;
- }
-
- assertTrue("Should not have been able to retrieve deleted edge.", deletedEdgeNotFound);
- }
-
- private boolean containsEdge(Edge anEdge, List<Edge> edges) {
-
- for (Edge e : edges) {
- if (e.getId().isPresent() && anEdge.getId().isPresent() && (e.getId().get().equals(anEdge.getId().get()))) {
- return true;
- }
-
- }
- return false;
- }
-
- public static class MapBuilder {
-
- private Map<String, Object> map;
-
- private MapBuilder() {
- map = new HashMap<String, Object>();
- }
-
- public static MapBuilder builder() {
- return new MapBuilder();
- }
-
- public MapBuilder withKeyValue(String key, Object value) {
- map.put(key, value);
- return this;
- }
-
- public Map<String, Object> build() {
- return map;
- }
- }
+// private static final String GRAPH_NAME = "my_test_graph";
+//
+// private GraphDao champDao = null;
+//
+//
+// /**
+// * Perform setup steps that must be done prior to executing each test.
+// */
+// @Before
+// public void setup() {
+//
+// // Create an instance of the Champ DAO, backed by the Champ library's in-memory back end
+// // for testing purposes.
+// Map<String, Object> champDaoProperties = new HashMap<String, Object>();
+// champDaoProperties.put(ChampDao.CONFIG_STORAGE_BACKEND, "in-memory");
+// champDaoProperties.put(ChampDao.CONFIG_GRAPH_NAME, GRAPH_NAME);
+// champDao = new ChampDao(new InMemoryChampGraphImpl.Builder().properties(champDaoProperties).build());
+// }
+//
+//
+// /**
+// * Perform tear down steps that must be done after executing each test.
+// */
+// @After
+// public void tearDown() {
+//
+// // Release the Champ DAO instance that we were using for the test.
+// if (champDao != null) {
+// ((ChampDao) champDao).close();
+// }
+// }
+//
+//
+// /**
+// * Tests the ability of the {@link ChampDao} to create a vertex.
+// *
+// * @throws CrudException
+// */
+// @Test
+// public void createVertexTest() throws CrudException {
+//
+// String VERTEX_TYPE = "Test_Vertex";
+//
+// Map<String, Object> properties = new HashMap<String, Object>();
+// properties.put("property1", "something");
+// properties.put("property2", "something else");
+//
+// // Create the vertex.
+// Vertex createdVertex = champDao.addVertex(VERTEX_TYPE, properties);
+//
+// // Validate that the returned {@link Vertex} has the right label assigned to it.
+// assertTrue("Unexpected vertex type '" + createdVertex.getType() + "' returned from DAO",
+// createdVertex.getType().equals(VERTEX_TYPE));
+//
+// // Validate that all of the properties that we provided to the DAO are in fact assigned
+// // to the {@link Vertex} that we got back.
+// assertTrue("Vertex property list returned from DAO did not contain all expected properties - expected: " +
+// properties.keySet() + " actual: " + createdVertex.getProperties().keySet(),
+// createdVertex.getProperties().keySet().containsAll(properties.keySet()));
+//
+// // Validate that the values assigned to the properties in the returned {@link Vertex}
+// // match the ones that we provided.
+// for (String propertyKey : properties.keySet()) {
+//
+// assertTrue(createdVertex.getProperties().get(propertyKey).equals(properties.get(propertyKey)));
+// }
+// }
+//
+//
+// /**
+// * Tests the ability of the {@link ChampDao} to retrieve a vertex from the graph data store
+// * by its unique identifier.
+// *
+// * @throws CrudException
+// */
+// @Test
+// public void getVertexByIdTest() throws CrudException {
+//
+// String VERTEX_TYPE = "Test_Vertex";
+//
+// Map<String, Object> properties = new HashMap<String, Object>();
+// properties.put("property1", "something");
+// properties.put("property2", "something else");
+//
+// // Create the vertex.
+// Vertex createdVertex = champDao.addVertex(VERTEX_TYPE, properties);
+//
+// // Make sure the {@link Vertex} returned from the create method includes an id that we can
+// // use to retrieve it.
+// assertTrue("No valid id returned for the created vertex", createdVertex.getId().isPresent());
+//
+// // Now, retrieve the {@link Vertex} by its identifier.
+// Vertex retrievedVertex = champDao.getVertex(createdVertex.getId().get(), VERTEX_TYPE);
+//
+// // Validate that the retrieved {@link Vertex} has the right label assigned to it.
+// assertTrue("Unexpected vertex type '" + retrievedVertex.getType() + "' returned from DAO",
+// retrievedVertex.getType().equals(VERTEX_TYPE));
+//
+// // Validate that all of the properties that we provided when we created the {@link Vertex}
+// // are present in the {@link Vertex} that we retrieved.
+// assertTrue("Vertex property list returned from DAO did not contain all expected properties - expected: " +
+// properties.keySet() + " actual: " + retrievedVertex.getProperties().keySet(),
+// retrievedVertex.getProperties().keySet().containsAll(properties.keySet()));
+//
+// // Validate that the values assigned to the properties in the retrieved {@link Vertex}
+// // match the ones that we provided when we created it.
+// for (String propertyKey : properties.keySet()) {
+//
+// assertTrue(retrievedVertex.getProperties().get(propertyKey).equals(properties.get(propertyKey)));
+// }
+// }
+//
+//
+// /**
+// * Tests the ability of the {@link ChampDao} to update an already existing vertex.
+// *
+// * @throws CrudException
+// */
+// @Test
+// public void updateVertexTest() throws CrudException {
+//
+// final String VERTEX_TYPE = "Test_Vertex";
+//
+// Map<String, Object> properties = new HashMap<String, Object>();
+// properties.put("property1", "something");
+// properties.put("property2", "something else");
+//
+// // Create the vertex.
+// Vertex createdVertex = champDao.addVertex(VERTEX_TYPE, properties);
+//
+// // Make sure the {@link Vertex} returned from the create method includes an id that we can
+// // use to retrieve it.
+// assertTrue("No valid id returned for the created vertex", createdVertex.getId().isPresent());
+//
+// // Modify the properties list...
+// properties.put("property3", "a new property");
+// properties.remove("property1");
+//
+// // ...and apply it to our vertex.
+// Vertex updatedVertex = champDao.updateVertex(createdVertex.getId().get(), createdVertex.getType(), properties);
+//
+// assertTrue("Vertex property list returned from DAO update operation did not contain all expected properties - expected: " +
+// properties.keySet() + " actual: " + updatedVertex.getProperties().keySet(),
+// updatedVertex.getProperties().keySet().containsAll(properties.keySet()));
+//
+// // Validate that the values assigned to the properties in the updated {@link Vertex}
+// // match the ones that we provided when we created it.
+// for (String propertyKey : properties.keySet()) {
+//
+// assertTrue("Unexpected value for property '" + propertyKey + "' - Expected: " +
+// properties.get(propertyKey) + " Actual: " +
+// updatedVertex.getProperties().get(propertyKey),
+// updatedVertex.getProperties().get(propertyKey).equals(properties.get(propertyKey)));
+// }
+//
+// // Validate that the property that we removed is NOT in the set of properties from our
+// // updated {@link Vertex}.
+// assertFalse("Property 'property1' should no longer be associated with updated vertex",
+// updatedVertex.getProperties().containsKey("property1"));
+// }
+//
+//
+// /**
+// * Tests the ability of the {@link ChampDao} to retrieve multiple vertices which match
+// * a particular set of supplied properties.
+// *
+// * @throws CrudException
+// */
+// @Test
+// public void getVerticesTest() throws CrudException {
+//
+// final String FIRST_VERTEX_TYPE = "pserver";
+// final String SECOND_VERTEX_TYPE = "complex";
+//
+// // Create some vertices.
+//
+// Map<String, Object> vertex1Properties = new HashMap<String, Object>();
+// vertex1Properties.put("O/S", "Linux");
+// vertex1Properties.put("version", "6.5");
+// vertex1Properties.put("hostname", "kll0001");
+// champDao.addVertex(FIRST_VERTEX_TYPE, vertex1Properties);
+//
+// Map<String, Object> vertex2Properties = new HashMap<String, Object>();
+// vertex2Properties.put("O/S", "Linux");
+// vertex2Properties.put("version", "6.5");
+// vertex2Properties.put("hostname", "kll0002");
+// champDao.addVertex(FIRST_VERTEX_TYPE, vertex2Properties);
+//
+// Map<String, Object> vertex3Properties = new HashMap<String, Object>();
+// vertex3Properties.put("O/S", "Linux");
+// vertex3Properties.put("version", "7.2");
+// vertex3Properties.put("hostname", "kll0003");
+// champDao.addVertex(FIRST_VERTEX_TYPE, vertex3Properties);
+//
+// Map<String, Object> vertex4Properties = new HashMap<String, Object>();
+// vertex4Properties.put("O/S", "Windows");
+// vertex4Properties.put("version", "10");
+// vertex4Properties.put("hostname", "Dev Laptop");
+// champDao.addVertex(FIRST_VERTEX_TYPE, vertex4Properties);
+//
+// Map<String, Object> vertex5Properties = new HashMap<String, Object>();
+// vertex5Properties.put("Street", "Baker");
+// vertex5Properties.put("Number", "222B");
+// champDao.addVertex(SECOND_VERTEX_TYPE, vertex5Properties);
+//
+// // Create a set of properties to use for our query.
+// Map<String, Object> queryProperties = new HashMap<String, Object>();
+// queryProperties.put("O/S", "Linux");
+// queryProperties.put("version", "6.5");
+//
+// // Validate that we filter our 'get vertices' results by type
+// List<Vertex> allVerticesByType = champDao.getVertices(FIRST_VERTEX_TYPE, MapBuilder.builder().build());
+// for (Vertex v : allVerticesByType) {
+// assertTrue("Unexpected vertex type returned from query. Expected: " +
+// FIRST_VERTEX_TYPE + " Actual: " + v.getType(),
+// v.getType().equals(FIRST_VERTEX_TYPE));
+// }
+//
+// // Now, request the vertices that match our parameters.
+// List<Vertex> vertices = champDao.getVertices(FIRST_VERTEX_TYPE, queryProperties);
+//
+// // Validate that got back the expected number of vertices.
+// assertEquals(vertices.size(), 2);
+//
+// // Validate that the vertices we got back contain the expected parameters.
+// for (Vertex v : vertices) {
+//
+// assertTrue("Vertex from query result does not contain expected vertex 'O/S'",
+// v.getProperties().containsKey("O/S"));
+// assertTrue("Vertex from query result contains unexpected value for 'O/S' parameter - Expected: 'Linux' Actual: '" +
+// v.getProperties().get("O/S") + "'",
+// v.getProperties().get("O/S").equals("Linux"));
+//
+// assertTrue("Vertex from query result does not contain expected vertex 'O/S'",
+// v.getProperties().containsKey("version"));
+// assertTrue("Vertex from query result contains unexpected value for 'O/S' parameter - Expected: 'Linux' Actual: '" +
+// v.getProperties().get("O/S") + "'",
+// v.getProperties().get("version").equals("6.5"));
+// }
+// }
+//
+// @Test
+// public void deleteVertexTest() throws CrudException {
+//
+// boolean deletedVertexNotFound = false;
+//
+// // Create a vertex.
+// Vertex createdVertex = champDao.addVertex("test_type", MapBuilder.builder()
+// .withKeyValue("O/S", "Linux")
+// .withKeyValue("version", "6.5")
+// .withKeyValue("hostname", "kll0001")
+// .build());
+//
+// // Verify that we can retrieve the vertex from the graph data base.
+// Vertex retrievedVertex = champDao.getVertex(createdVertex.getId().get(), "test_type");
+//
+// // Now, delete the vertex.
+// champDao.deleteVertex(createdVertex.getId().get(), "test_type");
+//
+// // Now, try to retrieve it again. This time we should fail to find it.
+// try {
+// champDao.getVertex(createdVertex.getId().get(), "test_type");
+//
+// } catch (CrudException e) {
+// assertTrue(e.getMessage().contains("No vertex with id"));
+// deletedVertexNotFound = true;
+// }
+//
+// assertTrue("Should not have been able to retrieve deleted vertex", deletedVertexNotFound);
+// }
+//
+// @Test
+// public void createEdgeTest() throws CrudException {
+//
+// String EDGE_TYPE = "has";
+//
+// // Create the source vertex for the edge.
+// Map<String, Object> srcVertexProperties = new HashMap<String, Object>();
+// srcVertexProperties.put("O/S", "Linux");
+// srcVertexProperties.put("version", "6.5");
+// srcVertexProperties.put("hostname", "kll0001");
+// Vertex sourceVertex = champDao.addVertex("vserver", srcVertexProperties);
+//
+// // Create the target vertex for the edge.
+// Map<String, Object> dstVertexProperties = new HashMap<String, Object>();
+// dstVertexProperties.put("O/S", "Linux");
+// dstVertexProperties.put("version", "6.5");
+// dstVertexProperties.put("hostname", "kll0002");
+// Vertex destVertex = champDao.addVertex("VNF", dstVertexProperties);
+//
+// // Now, create the edge itself.
+// Map<String, Object> edgeProperties = new HashMap<String, Object>();
+// edgeProperties.put("prop", "val");
+// Edge createdEdge = champDao.addEdge("has", sourceVertex, destVertex, edgeProperties);
+//
+// // Validate that the Edge object returned from the create method matches what we were
+// // trying to create.
+// assertTrue("Unexpected type for Edge returned from create method. Expected: " + EDGE_TYPE
+// + " Actual: " + createdEdge.getType(),
+// createdEdge.getType().equals("has"));
+// assertTrue("Unexpected properties for Edge returned from create method. Expected: " + edgeProperties
+// + " Actual: " + createdEdge.getProperties(),
+// createdEdge.getProperties().equals(edgeProperties));
+//
+// }
+//
+// @Test
+// public void createEdgeWithMissingSrcOrTargetTest() throws CrudException {
+//
+// String EDGE_TYPE = "has";
+//
+// // Create the source vertex for the edge.
+// Map<String, Object> srcVertexProperties = new HashMap<String, Object>();
+// srcVertexProperties.put("O/S", "Linux");
+// srcVertexProperties.put("version", "6.5");
+// srcVertexProperties.put("hostname", "kll0001");
+// Vertex sourceVertex = champDao.addVertex("vserver", srcVertexProperties);
+//
+// // Create the target vertex for the edge.
+// Map<String, Object> dstVertexProperties = new HashMap<String, Object>();
+// dstVertexProperties.put("O/S", "Linux");
+// dstVertexProperties.put("version", "6.5");
+// dstVertexProperties.put("hostname", "kll0002");
+// Vertex destVertex = champDao.addVertex("VNF", dstVertexProperties);
+//
+// // Now, try creating the Edge but specify an id for the source vertex that does
+// // not exist.
+// Map<String, Object> edgeProperties = new HashMap<String, Object>();
+// edgeProperties.put("prop", "val");
+// try {
+// champDao.addEdge(EDGE_TYPE, new Vertex.Builder("miss").id("99").build(), destVertex, edgeProperties);
+// } catch (CrudException e) {
+// assertTrue(e.getMessage().contains("Error creating edge - source vertex"));
+// }
+//
+// // Now, try created the Edge with a valid source vertex, but specify an id for the
+// // target vertex that does not exist.
+// try {
+// champDao.addEdge(EDGE_TYPE, sourceVertex, new Vertex.Builder("miss").id("99").build(), edgeProperties);
+// } catch (CrudException e) {
+// assertTrue(e.getMessage().contains("Error creating edge - target vertex"));
+// }
+//
+// }
+//
+// @Test
+// public void getEdgeByIdTest() throws CrudException {
+//
+// String EDGE_TYPE = "has";
+//
+// // Create the source vertex for the edge.
+// Map<String, Object> srcVertexProperties = new HashMap<String, Object>();
+// srcVertexProperties.put("O/S", "Linux");
+// srcVertexProperties.put("version", "6.5");
+// srcVertexProperties.put("hostname", "kll0001");
+// Vertex sourceVertex = champDao.addVertex("vserver", srcVertexProperties);
+//
+// // Create the target vertex for the edge.
+// Map<String, Object> dstVertexProperties = new HashMap<String, Object>();
+// dstVertexProperties.put("O/S", "Linux");
+// dstVertexProperties.put("version", "6.5");
+// dstVertexProperties.put("hostname", "kll0002");
+// Vertex destVertex = champDao.addVertex("VNF", dstVertexProperties);
+//
+// // Now, create the edge itself.
+// Map<String, Object> edgeProperties = new HashMap<String, Object>();
+// edgeProperties.put("prop", "val");
+// Edge createdEdge = champDao.addEdge("has", sourceVertex, destVertex, edgeProperties);
+//
+// // Retrieve the edge we just created by specifying its unique identifier.
+// Edge retrievedEdge = champDao.getEdge(createdEdge.getId().get(), "has");
+//
+// // Validate that the contents of the object that we got back matches what we thought we
+// // created.
+// assertTrue("Unexpected type for Edge returned from get method. Expected: " + EDGE_TYPE
+// + " Actual: " + retrievedEdge.getType(),
+// retrievedEdge.getType().equals(EDGE_TYPE));
+// assertTrue("Unexpected properties for Edge returned from get method. Expected: " + edgeProperties
+// + " Actual: " + retrievedEdge.getProperties(),
+// retrievedEdge.getProperties().equals(edgeProperties));
+// }
+//
+// @Test
+// public void getEdgesTest() throws CrudException {
+//
+// final String EDGE_TYPE_HAS = "has";
+// final String EDGE_TYPE_RUNS = "runs";
+//
+// // Create some vertices and edges that we can query agains.
+// Vertex complex = champDao.addVertex("complex", MapBuilder.builder()
+// .withKeyValue("Province", "Ontario")
+// .withKeyValue("City", "Ottawa")
+// .withKeyValue("Street", "303 Terry Fox")
+// .build());
+//
+// Vertex vserver = champDao.addVertex("vserver", MapBuilder.builder()
+// .withKeyValue("O/S", "Linux")
+// .withKeyValue("version", "6.5")
+// .withKeyValue("hostname", "kll0001")
+// .build());
+//
+// Vertex vnf1 = champDao.addVertex("vserver", MapBuilder.builder()
+// .withKeyValue("Application", "OpenDaylight")
+// .build());
+//
+// Vertex vnf2 = champDao.addVertex("vserver", MapBuilder.builder()
+// .withKeyValue("Application", "Cammunda")
+// .build());
+//
+// Edge edge1 = champDao.addEdge(EDGE_TYPE_HAS, complex, vserver,
+// MapBuilder.builder()
+// .withKeyValue("usesResource", "false")
+// .withKeyValue("hasDelTarget", "false")
+// .build());
+//
+// Edge edge2 = champDao.addEdge(EDGE_TYPE_RUNS, vserver, vnf1,
+// MapBuilder.builder()
+// .withKeyValue("usesResource", "false")
+// .withKeyValue("hasDelTarget", "true")
+// .build());
+//
+// Edge edge3 = champDao.addEdge(EDGE_TYPE_RUNS, vserver, vnf2,
+// MapBuilder.builder()
+// .withKeyValue("usesResource", "false")
+// .withKeyValue("hasDelTarget", "false")
+// .build());
+//
+// // Query for all HAS edges.
+// List<Edge> hasEdges = champDao.getEdges(EDGE_TYPE_HAS, new HashMap<String, Object>());
+//
+// assertEquals("Unexpected number of edges of type 'has' found. Expected: 1 Actual: " + hasEdges.size(),
+// hasEdges.size(), 1);
+// assertTrue("Result of query for 'has' type edges does not contain the expected results",
+// containsEdge(edge1, hasEdges));
+//
+// // Query for all RUNS edges.
+// List<Edge> runsEdges = champDao.getEdges(EDGE_TYPE_RUNS, new HashMap<String, Object>());
+//
+// assertEquals("Unexpected number of edges of type 'runs' found. Expected: 2 Actual: " + runsEdges.size(),
+// runsEdges.size(), 2);
+// assertTrue("Result of query for 'runs' type edges does not contain the expected results",
+// containsEdge(edge2, runsEdges));
+// assertTrue("Result of query for 'runs' type edges does not contain the expected results",
+// containsEdge(edge2, runsEdges));
+//
+// // Query for all HAS edges with the property 'hasDelTarget' equal to 'true'.
+// List<Edge> runsEdgesWithDelTargetTrue =
+// champDao.getEdges(EDGE_TYPE_RUNS, MapBuilder.builder()
+// .withKeyValue("hasDelTarget", "true")
+// .build());
+//
+// assertEquals("Unexpected number of edges of type 'has' with 'hasDelTarget=true' found. Expected: 1 Actual: "
+// + runsEdgesWithDelTargetTrue.size(),
+// runsEdgesWithDelTargetTrue.size(), 1);
+// assertTrue("Result of query for 'runs' type edges with delTarget set to TRUE does not contain the expected results",
+// containsEdge(edge2, runsEdgesWithDelTargetTrue));
+// }
+//
+// @Test
+// @Ignore // For now - pending some expected fixes to the Champ library.
+// public void updateEdgeTest() throws CrudException {
+//
+// // Create the source vertex for the edge.
+// Vertex sourceVertex = champDao.addVertex("vserver", MapBuilder.builder()
+// .withKeyValue("O/S", "Linux")
+// .withKeyValue("version", "6.5")
+// .withKeyValue("hostname", "kll0001")
+// .build());
+//
+// // Create the target vertex for the edge.
+// Vertex destVertex = champDao.addVertex("VNF", MapBuilder.builder()
+// .withKeyValue("O/S", "Linux")
+// .withKeyValue("version", "6.5")
+// .withKeyValue("hostname", "kll0002")
+// .build());
+//
+// // Now, create the edge itself.
+// Edge createdEdge = champDao.addEdge("has",
+// sourceVertex,
+// destVertex,
+// MapBuilder.builder()
+// .withKeyValue("key1", "value1")
+// .withKeyValue("key2", "value2")
+// .withKeyValue("key3", "value3")
+// .build());
+//
+// // Make sure the Edge returned from the create method includes an id that we can
+// // use to retrieve it.
+// assertTrue("No valid id returned for the created edge", createdEdge.getId().isPresent());
+//
+// // Retrieve the properties map for our edge and make some changes.
+// Map<String, Object> properties = createdEdge.getProperties();
+// properties.put("key4", "value4");
+// properties.remove("key2");
+//
+// // Now update the edge with the new properties map.
+// Edge updatedEdge = champDao.updateEdge(createdEdge);
+//
+// assertTrue("Edge property list returned from DAO update operation did not contain all expected properties - expected: " +
+// properties.keySet() + " actual: " + updatedEdge.getProperties().keySet(),
+// updatedEdge.getProperties().keySet().containsAll(properties.keySet()));
+//
+// // Validate that the values assigned to the properties in the updated Edge
+// // match the ones that we provided when we created it.
+// for (String propertyKey : properties.keySet()) {
+//
+// assertTrue("Unexpected value for property '" + propertyKey + "' - Expected: " +
+// properties.get(propertyKey) + " Actual: " +
+// updatedEdge.getProperties().get(propertyKey),
+// updatedEdge.getProperties().get(propertyKey).equals(properties.get(propertyKey)));
+// }
+//
+// // Validate that the property that we removed is NOT in the set of properties from our
+// // updated edge.
+// // *** We will leave this validation commented out for now, as the Champ library actually
+// // merges update properties instead of replacing them...
+//// assertFalse("Property 'key2' should no longer be associated with updated edge",
+//// updatedEdge.getProperties().containsKey("key2"));
+// }
+//
+// @Test
+// public void deleteEdgeTest() throws CrudException {
+//
+// boolean deletedEdgeNotFound = false;
+//
+// // Create the source vertex for the edge.
+// Vertex sourceVertex = champDao.addVertex("vserver", MapBuilder.builder()
+// .withKeyValue("O/S", "Linux")
+// .withKeyValue("version", "6.5")
+// .withKeyValue("hostname", "kll0001")
+// .build());
+//
+// // Create the target vertex for the edge.
+// Vertex destVertex = champDao.addVertex("VNF", MapBuilder.builder()
+// .withKeyValue("O/S", "Linux")
+// .withKeyValue("version", "6.5")
+// .withKeyValue("hostname", "kll0002")
+// .build());
+//
+// // Now, create the edge itself.
+// Edge createdEdge = champDao.addEdge("has",
+// sourceVertex,
+// destVertex,
+// MapBuilder.builder()
+// .withKeyValue("key1", "value1")
+// .withKeyValue("key2", "value2")
+// .withKeyValue("key3", "value3")
+// .build());
+//
+// // Verify that we can retrieve the edge that we just created.
+// Edge retrievedEdge = champDao.getEdge(createdEdge.getId().get(), "has");
+//
+// // Now, delete it.
+// champDao.deleteEdge(createdEdge.getId().get(), "has");
+//
+// // Try retrieving it again. This time we should not find it.
+// try {
+// champDao.getEdge(createdEdge.getId().get(), "has");
+// } catch (CrudException e) {
+//
+// assertTrue(e.getMessage().contains("No edge with id"));
+// deletedEdgeNotFound = true;
+// }
+//
+// assertTrue("Should not have been able to retrieve deleted edge.", deletedEdgeNotFound);
+// }
+//
+// private boolean containsEdge(Edge anEdge, List<Edge> edges) {
+//
+// for (Edge e : edges) {
+// if (e.getId().isPresent() && anEdge.getId().isPresent() && (e.getId().get().equals(anEdge.getId().get()))) {
+// return true;
+// }
+//
+// }
+// return false;
+// }
+//
+// public static class MapBuilder {
+//
+// private Map<String, Object> map;
+//
+// private MapBuilder() {
+// map = new HashMap<String, Object>();
+// }
+//
+// public static MapBuilder builder() {
+// return new MapBuilder();
+// }
+//
+// public MapBuilder withKeyValue(String key, Object value) {
+// map.put(key, value);
+// return this;
+// }
+//
+// public Map<String, Object> build() {
+// return map;
+// }
+// }
}
diff --git a/src/test/java/org/openecomp/schema/AaiResourceServiceTest.java b/src/test/java/org/openecomp/schema/AaiResourceServiceTest.java
new file mode 100644
index 0000000..fa80ba5
--- /dev/null
+++ b/src/test/java/org/openecomp/schema/AaiResourceServiceTest.java
@@ -0,0 +1,205 @@
+package org.openecomp.schema;
+
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.util.AbstractMap;
+import java.util.AbstractSet;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.openecomp.aai.exceptions.AAIException;
+import org.openecomp.aai.serialization.db.EdgeProperty;
+import org.openecomp.aai.serialization.db.EdgePropertyMap;
+import org.openecomp.aai.serialization.db.EdgeRule;
+import org.openecomp.aai.serialization.db.EdgeRules;
+import org.openecomp.aai.serialization.db.EdgeType;
+import org.openecomp.aai.util.AAIConstants;
+import org.openecomp.crud.exception.CrudException;
+import org.openecomp.crud.service.AaiResourceService;
+import org.openecomp.crud.service.EdgePayload;
+
+import com.google.gson.Gson;
+import com.google.gson.JsonElement;
+import com.google.gson.JsonPrimitive;
+
+public class AaiResourceServiceTest {
+
+ public AaiResourceService aaiResSvc = null;
+
+
+ @Before
+ public void setup() {
+ System.setProperty("AJSC_HOME", ".");
+ System.setProperty("BUNDLECONFIG_DIR", "src/test/resources/bundleconfig-local");
+
+ aaiResSvc = new AaiResourceService();
+ }
+
+
+ /**
+ * This test validates that we can apply db edge rules against an edge request
+ * payload and have the properties defined in the edge rules merged into the
+ * payload.
+ *
+ * @throws CrudException
+ * @throws AAIException
+ */
+ @Test
+ public void applyEdgeRulesToPayloadTest() throws CrudException, AAIException {
+
+ String content = "{" +
+ "\"source\": \"services/inventory/v8/l-interface/369553424\", " +
+ "\"target\": \"services/inventory/v8/logical-link/573444128\"," +
+ "\"properties\": {" +
+ "}" +
+ "}";
+
+ // Convert our simulated payload to an EdgePayload object.
+ EdgePayload payload = EdgePayload.fromJson(content);
+
+ // Now, apply the db edge rules against our edge payload.
+ EdgePayload payloadAfterEdgeRules = aaiResSvc.applyEdgeRulesToPayload(payload);
+
+ EdgeRules rules = EdgeRules.getInstance();
+ EdgeRule rule = rules.getEdgeRule(EdgeType.COUSIN, "l-interface", "logical-link");
+ Map<EdgeProperty, String> edgeProps = rule.getEdgeProperties();
+
+ // Validate that the properties defined in the DB edge rules show up in our
+ // final payload.
+ for(EdgeProperty key : edgeProps.keySet()) {
+ assertTrue(payloadAfterEdgeRules.toString().contains(key.toString()));
+ }
+ }
+
+
+ /**
+ * This test validates that trying to apply edge rules where there is no
+ * db edge rules entry for the supplied source and target vertex types
+ * produces an exception.
+ *
+ * @throws CrudException
+ */
+ @Test
+ public void noRuleForEdgeTest() throws CrudException {
+
+ String content = "{" +
+ "\"source\": \"services/inventory/v8/commodore-64/12345\", " +
+ "\"target\": \"services/inventory/v8/jumpman/67890\"," +
+ "\"properties\": {" +
+ "}" +
+ "}";
+
+ // Convert our simulated payload to an EdgePayload object.
+ EdgePayload payload = EdgePayload.fromJson(content);
+
+ // Now, apply the db edge rules against our edge payload.
+ try {
+ aaiResSvc.applyEdgeRulesToPayload(payload);
+
+ } catch (CrudException e) {
+
+ // We expected an exception since there is no rule for our made up vertices..
+ assertTrue(e.getMessage().contains("No edge rules for"));
+ return;
+ }
+
+ // If we're here then something unexpected happened...
+ fail();
+ }
+
+
+ /**
+ * This test validates that it is possible to merge client supplied and edge rule
+ * supplied properties into one edge property list.
+ *
+ * @throws Exception
+ */
+ @Test
+ public void mergeEdgePropertiesTest() throws Exception {
+
+ String content = "{" +
+ "\"source\": \"services/inventory/v8/l-interface/369553424\", " +
+ "\"target\": \"services/inventory/v8/logical-link/573444128\"," +
+ "\"properties\": {" +
+ "\"multiplicity\": \"many\"," +
+ "\"is-parent\": true," +
+ "\"uses-resource\": \"true\"," +
+ "\"has-del-target\": \"true\"" +
+ "}" +
+ "}";
+
+ EdgePayload payload = EdgePayload.fromJson(content);
+ EdgeRules rules = EdgeRules.getInstance();
+ EdgeRule rule = rules.getEdgeRule(EdgeType.COUSIN, "l-interface", "logical-link");
+ Map<EdgeProperty, String> edgeProps = rule.getEdgeProperties();
+
+ // Merge the client supplied properties with the properties defined in the DB edge rules.
+ JsonElement mergedProperties =
+ aaiResSvc.mergeProperties(payload.getProperties(), rule.getEdgeProperties());
+
+ // Now, validate that the resulting set of properties contains both the client and edge
+ // rule supplied properties.
+ String mergedPropertiesString = mergedProperties.toString();
+ assertTrue("Client supplied property 'multiplicity' is missing from merged properties set",
+ mergedPropertiesString.contains("multiplicity"));
+ assertTrue("Client supplied property 'is-parent' is missing from merged properties set",
+ mergedPropertiesString.contains("is-parent"));
+ assertTrue("Client supplied property 'uses-resource' is missing from merged properties set",
+ mergedPropertiesString.contains("uses-resource"));
+ assertTrue("Client supplied property 'has-del-target' is missing from merged properties set",
+ mergedPropertiesString.contains("has-del-target"));
+
+ for(EdgeProperty key : edgeProps.keySet()) {
+ assertTrue("Edge rule supplied property '" + key.toString() + "' is missing from merged properties set",
+ mergedPropertiesString.contains(key.toString()));
+ }
+ }
+
+ /**
+ * This test validates that if we try to merge client supplied edge properties
+ * with the properties defined in the db edge rules, and there is a conflict,
+ * then the merge will fail.
+ *
+ * @throws Exception
+ */
+ @Test
+ public void mergeEdgePropertiesConflictTest() throws Exception {
+
+ String content = "{" +
+ "\"source\": \"services/inventory/v8/l-interface/369553424\", " +
+ "\"target\": \"services/inventory/v8/logical-link/573444128\"," +
+ "\"properties\": {" +
+ "\"contains-other-v\": \"OUT\"" +
+ "}" +
+ "}";
+
+ EdgePayload payload = EdgePayload.fromJson(content);
+ EdgeRules rules = EdgeRules.getInstance();
+ EdgeRule rule = rules.getEdgeRule(EdgeType.COUSIN, "l-interface", "logical-link");
+
+ try {
+
+ // Try to merge our client supplied properties with the properties defined
+ // in the db edge rules.
+ aaiResSvc.mergeProperties(payload.getProperties(), rule.getEdgeProperties());
+
+ } catch (CrudException e) {
+
+ // We should have gotten an exception because we are trying to set a parameter which is
+ // already defined in the db edge rules, so if we're here then we are good.
+ return;
+ }
+
+ // If we made it here then we were allowed to set a property that is already defined
+ // in the db edge rules, which we should not have...
+ fail();
+ }
+
+
+
+
+}
diff --git a/src/test/resources/bundleconfig-local/etc/appprops/error.properties b/src/test/resources/bundleconfig-local/etc/appprops/error.properties
new file mode 100644
index 0000000..11416ca
--- /dev/null
+++ b/src/test/resources/bundleconfig-local/etc/appprops/error.properties
@@ -0,0 +1,164 @@
+# Adding comment trying to trigger a build
+#------------------------------------------------------------------------------- ----------
+#Key=Disposition:Category:Severity:Error Code:HTTP ResponseCode:RESTError Code:Error Message
+#------------------------------------------------------------------------------- ----------
+# testing code, please don't change unless error utility source code changes
+AAI_TESTING=5:2:WARN:0000:400:0001:Error code for testing
+
+# General success
+AAI_0000=0:0:INFO:0000:200:0000:Success
+
+# health check success
+AAI_0001=0:0:INFO:0001:200:0001:Success X-FromAppId=%1 X-TransactionId=%2
+AAI_0002=0:0:INFO:0002:200:0001:Successful health check
+
+# Success with additional info
+AAI_0003=0:3:INFO:0003:202:0003:Success with additional info performing %1 on %2. Added %3 with key %4
+AAI_0004=0:3:INFO:0004:202:0003:Added prerequisite object to db
+
+#--- aairest: 3000-3299
+# svc errors
+AAI_3000=5:2:INFO:3000:400:3000:Invalid input performing %1 on %2
+AAI_3001=5:6:INFO:3001:404:3001:Resource not found for %1 using id %2
+AAI_3002=5:1:WARN:3002:400:3002:Error writing output performing %1 on %2
+AAI_3003=5:1:WARN:3003:400:3003:Failed to make edge to missing target node of type %3 with keys %4 performing %1 on %2
+AAI_3005=5:6:WARN:3005:404:3001:Node cannot be directly accessed for read, must be accessed via ancestor(s)
+AAI_3006=5:6:WARN:3006:404:3001:Node cannot be directly accessed for write, must be accessed via ancestor(s)
+AAI_3007=5:6:INFO:3007:410:3007:This version (%1) of the API is retired, please migrate to %2
+AAI_3008=5:6:ERROR:3008:400:3008:URI is not encoded in UTF-8
+AAI_3009=5:6:ERROR:3009:400:3002:Malformed URL
+# pol errors
+AAI_3100=5:1:WARN:3100:400:3100:Unsupported operation %1
+AAI_3101=5:1:WARN:3101:403:3101:Attempt by client %1 to execute API %2
+AAI_3102=5:1:WARN:3102:400:3102:Error parsing input performing %1 on %2
+AAI_3300=5:1:WARN:3300:403:3300:Unauthorized
+AAI_3301=5:1:WARN:3301:401:3301:Stale credentials
+AAI_3302=5:1:WARN:3302:401:3301:Not authenticated
+AAI_3303=5:1:ERROR:3303:403:3300:Too many objects would be returned by this request, please refine your request and retry
+
+#--- aaigen: 4000-4099
+AAI_4000=5:4:ERROR:4000:500:3002:Internal Error
+AAI_4001=5:4:FATAL:4001:500:3002:Configuration file not found
+AAI_4002=5:4:FATAL:4002:500:3002:Error reading Configuration file
+AAI_4003=5:4:ERROR:4003:500:3002:Error writing to log file
+AAI_4004=5:4:FATAL:4004:500:3002:Error reading/parsing the error properties file
+AAI_4005=5:4:FATAL:4005:500:3002:Missing or invalid configuration parameter
+AAI_4006=5:4:FATAL:4006:500:3002:Unexpected error in service
+AAI_4007=5:4:ERROR:4007:500:3102:Input parsing error
+AAI_4008=5:4:ERROR:4008:500:3002:Output parsing error
+AAI_4009=4:0:ERROR:4009:400:3000:Invalid X-FromAppId in header
+AAI_4010=4:0:ERROR:4010:400:3000:Invalid X-TransactionId in header
+AAI_4011=5:4:ERROR:4011:500:3002:Missing data for REST error response
+AAI_4012=5:4:ERROR:4012:500:3002:Bad rule data in RestRules
+AAI_4013=5:4:ERROR:4013:500:3002:Error connecting to AAI REST API
+AAI_4014=4:0:ERROR:4014:400:3000:Invalid Accept header
+AAI_4015=4:0:ERROR:4015:400:3000:You must provide at least one indexed property
+AAI_4016=4:0:ERROR:4016:400:3000:The depth parameter must be a number or the string "all"
+AAI_4017=5:2:INFO:4017:400:3000:Could not set property
+AAI_4018=5:2:ERROR:4018:400:3000:Unable to convert the string to integer
+#--- aaidbmap: 5101-5199
+AAI_5101=5:4:FATAL:5101:500:3002:Could not connect to database
+AAI_5102=5:4:FATAL:5102:500:3002:Graph database is null after open
+AAI_5103=5:4:ERROR:5103:500:3002:Unexpected error during commit
+AAI_5104=5:4:ERROR:5104:500:3002:Unexpected error during rollback
+AAI_5105=5:4:ERROR:5105:500:3002:Unexpected error reading/updating database
+AAI_5106=5:4:WARN:5106:404:3001:Node not found
+AAI_5107=5:2:WARN:5107:400:3000:Required information missing
+AAI_5108=5:2:WARN:5108:200:0:Unexpected information in request being ignored
+
+#--- aaidbgen: 6101-6199
+AAI_6101=5:4:ERROR:6101:500:3002:null TitanGraph object passed
+AAI_6102=5:4:WARN:6102:400:3000:Passed-in property is not valid for this nodeType
+AAI_6103=5:4:WARN:6103:400:3000:Required Node-property not found in input data
+AAI_6104=5:4:WARN:6104:400:3000:Required Node-property was passed with no data
+AAI_6105=5:4:WARN:6105:400:3000:Node-Key-Property not defined in DbMaps
+AAI_6106=5:4:WARN:6106:400:3000:Passed-in property is not valid for this edgeType
+AAI_6107=5:4:WARN:6107:400:3000:Required Edge-property not found in input data
+AAI_6108=5:4:WARN:6108:400:3000:Required Edge-property was passed with no data
+AAI_6109=5:4:WARN:6109:400:3000:Bad dependent Node value
+AAI_6110=5:4:ERROR:6110:400:3100:Node cannot be deleted
+AAI_6111=5:4:ERROR:6111:400:3000:JSON processing error
+AAI_6112=5:4:ERROR:6112:400:3000:More than one node found by getUniqueNode()
+AAI_6114=5:4:INFO:6114:404:3001:Node Not Found
+AAI_6115=5:4:ERROR:6115:400:3000:Unrecognized NodeType
+AAI_6116=5:4:ERROR:6116:400:3000:Unrecognized Property
+AAI_6117=5:4:ERROR:6117:400:3000:Uniqueness constraint violated
+AAI_6118=5:4:ERROR:6118:400:3000:Required Field not passed.
+AAI_6120=5:4:ERROR:6120:400:3000:Bad Parameter Passed
+AAI_6121=5:4:ERROR:6121:400:3000:Problem with internal AAI reference data
+AAI_6122=5:4:ERROR:6122:400:3000:Data Set not complete in DB for this request
+AAI_6123=5:4:ERROR:6123:500:3000:Bad Data found by DataGrooming Tool - Investigate
+AAI_6124=5:4:ERROR:6124:500:3000:File read/write error
+AAI_6125=5:4:WARN:6125:500:3000:Problem Pulling Data Set
+AAI_6126=5:4:ERROR:6126:400:3000:Edge cannot be deleted
+AAI_6127=5:4:INFO:6127:404:3001:Edge Not Found
+AAI_6128=5:4:INFO:6128:500:3000:Unexpected error
+AAI_6129=5:4:INFO:6129:404:3003:Error making edge to target node
+AAI_6130=5:4:WARN:6130:412:3000:Precondition Required
+AAI_6131=5:4:WARN:6131:412:3000:Precondition Failed
+AAI_6132=5:4:WARN:6132:400:3000:Bad Model Definition
+AAI_6133=5:4:WARN:6133:400:3000:Bad Named Query Definition
+AAI_6134=5:4:ERROR:6134:500:6134:Could not persist transaction to storage back end. Exhausted retry amount
+AAI_6135=5:4:WARN:6135:412:3000:Resource version specified on create
+AAI_6136=5:4:ERROR:6136:400:3000:Object cannot hold multiple items
+AAI_6137=5:4:ERROR:6137:400:3000:Cannot perform writes on multiple vertices
+AAI_6138=5:4:ERROR:6138:400:3000:Cannot delete multiple vertices
+AAI_6139=5:4:ERROR:6139:404:3000:Attempted to add edge to vertex that does not exist
+AAI_6140=5:4:ERROR:6140:400:3000:Edge multiplicity violated
+AAI_6141=5:4:WARN:6141:400:3000:Please Refine Query
+AAI_6142=5:4:INFO:6142:400:3000:Retrying transaction
+AAI_6143=5:4:INFO:6143:400:3000:Ghost vertex found
+AAI_6144=5:4:WARN:6144:400:3000:Cycle found in graph
+AAI_6145=5:4:ERROR:6145:400:3000:Cannot create a nested/containment edge via relationship
+AAI_6146=5:4:ERROR:6146:400:3000:Ambiguous identity map found, use a URI instead
+
+#--- aaicsvp: 7101-7199
+AAI_7101=5:4:ERROR:7101:500:3002:Unexpected error in CSV file processing
+AAI_7102=5:4:ERROR:7102:500:3002:Error in cleanup temporary directory
+#AAI_7103=4:2:ERROR:7103:500:3002:Unsupported user
+AAI_7104=5:4:ERROR:7104:500:3002:Failed to create directory
+AAI_7105=5:4:ERROR:7105:500:3002:Temporary directory exists
+AAI_7106=5:4:ERROR:7106:500:3002:Cannot delete
+AAI_7107=5:4:ERROR:7107:500:3002:Input file does not exist
+AAI_7108=5:4:ERROR:7108:500:3002:Output file does not exist
+AAI_7109=5:4:ERROR:7109:500:3002:Error closing file
+AAI_7110=5:4:ERROR:7110:500:3002:Error loading/reading properties file
+AAI_7111=5:4:ERROR:7111:500:3002:Error executing shell script
+AAI_7112=5:4:ERROR:7112:500:3002:Error creating output file
+AAI_7113=5:4:ERROR:7113:500:3002:Trailer record error
+AAI_7114=5:4:ERROR:7114:500:3002:Input file error
+AAI_7115=5:4:ERROR:7115:500:3002:Unexpected error
+AAI_7116=5:4:ERROR:7116:500:3002:Request error
+AAI_7117=5:4:ERROR:7117:500:3002:Error in get http client object
+AAI_7118=5:4:ERROR:7118:500:3002:Script Error
+AAI_7119=5:4:ERROR:7119:500:3002:Unknown host
+
+#--- aaisdnc: 7201-7299
+AAI_7202=5:4:ERROR:7202:500:3002:Error getting connection to odl
+AAI_7203=5:4:ERROR:7203:500:3002:Unexpected error calling DataChangeNotification API
+AAI_7204=5:4:ERROR:7204:500:3002:Error returned by DataChangeNotification API
+AAI_7205=5:4:ERROR:7205:500:3002:Unexpected error running notifySDNCOnUpdate
+AAI_7206=5:4:ERROR:7206:500:3002:Invalid data returned from ODL
+
+#--- NotificationEvent, using UEB space
+AAI_7350=5:4:ERROR:7305:500:3002:Notification event creation failed
+
+#--- aairestctlr: 7401-7499
+AAI_7401=5:4:ERROR:7401:500:3002:Error connecting to AAI REST API
+AAI_7402=5:4:ERROR:7402:500:3002:Unexpected error
+AAI_7403=5:4:WARN:7403:400:3001:Request error
+AAI_7404=5:4:INFO:7404:404:3001:Node not found
+
+#--- aaiauth: 9101-9199
+AAI_9101=5:0:WARN:9101:403:3300:User is not authorized to perform function
+AAI_9102=5:0:WARN:9102:401:3301:Refresh credentials from source
+AAI_9103=5:0:WARN:9103:403:3300:User not found
+AAI_9104=5:0:WARN:9104:401:3302:Authentication error
+AAI_9105=5:0:WARN:9105:403:3300:Authorization error
+AAI_9106=5:0:WARN:9106:403:3300:Invalid AppId
+#AAI_9107=5:0:WARN:9107:403:3300:No Username in Request
+AAI_9107=5:0:WARN:9107:403:3300:SSL is not provided in request, please contact admin
+
+#--- aaiinstar: 9201-9299
+AAI_9201=5:4:ERROR:9201:500:3002:Unable to send notification
+AAI_9202=5:4:ERROR:9202:500:3002:Unable to start a thread