Add swagger docs for gizmo APIs 87/72087/1
authorBansal, Nitin (nb121v) <nitin.bansal@amdocs.com>
Wed, 7 Nov 2018 15:36:38 +0000 (10:36 -0500)
committerBansal, Nitin (nb121v) <nitin.bansal@amdocs.com>
Wed, 7 Nov 2018 15:37:47 +0000 (10:37 -0500)
    Improve the way node type is resolved from OXM jaxbContext.

    Issue-ID: AAI-1882

Change-Id: Ia72fea0ac286dc96bb3b29d117b241b58b7eece7
Signed-off-by: Bansal, Nitin (nb121v) <nitin.bansal@amdocs.com>
pom.xml
src/main/java/org/onap/crud/CrudApplication.java
src/main/java/org/onap/crud/config/JerseyConfig.java
src/main/java/org/onap/crud/entity/Vertex.java
src/main/java/org/onap/crud/service/CrudRestService.java
src/main/java/org/onap/crud/util/CombinedResourceProvider.java [new file with mode: 0644]
src/main/java/org/onap/schema/OxmModelLoader.java
src/main/java/org/onap/schema/validation/OxmModelValidator.java
src/test/java/org/onap/crud/service/CrudRestServiceTest.java

diff --git a/pom.xml b/pom.xml
index 12ff45b..51441e8 100644 (file)
--- a/pom.xml
+++ b/pom.xml
@@ -93,6 +93,24 @@ limitations under the License.
             <artifactId>cxf-rt-frontend-jaxrs</artifactId>
             <version>3.2.5</version>
         </dependency>
+        
+
+     <dependency>
+         <groupId>io.swagger</groupId>
+         <artifactId>swagger-jersey2-jaxrs</artifactId>
+         <version>1.5.8</version>
+      </dependency>
+      <dependency>
+         <groupId>io.springfox</groupId>
+         <artifactId>springfox-swagger2</artifactId>
+         <version>2.9.2</version>
+      </dependency>
+            <dependency>
+         <groupId>io.springfox</groupId>
+         <artifactId>springfox-swagger-ui</artifactId>
+         <version>2.9.2</version>
+      </dependency>
+      
 
         <!-- ONAP AAI-COMMON (incl. model) -->
         <dependency>
index 008ff3f..a1531f1 100644 (file)
@@ -22,7 +22,10 @@ package org.onap.crud;
 
 import java.util.HashMap;
 import java.util.Map;
+import java.util.Collections;
+
 import javax.annotation.PostConstruct;
+
 import org.eclipse.jetty.util.security.Password;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.boot.autoconfigure.SpringBootApplication;
@@ -31,10 +34,19 @@ import org.springframework.boot.web.support.SpringBootServletInitializer;
 import org.springframework.context.annotation.ImportResource;
 import org.springframework.core.env.Environment;
 
+import springfox.documentation.builders.PathSelectors;
+import springfox.documentation.builders.RequestHandlerSelectors;
+import springfox.documentation.service.ApiInfo;
+import springfox.documentation.service.Contact;
+import springfox.documentation.spi.DocumentationType;
+import springfox.documentation.spring.web.plugins.Docket;
+import springfox.documentation.swagger2.annotations.EnableSwagger2;
+
 /**
  * Crud application class - SpringApplication.run
  */
 @SpringBootApplication
+@EnableSwagger2
 @ImportResource({"file:${SERVICE_BEANS}/*.xml"})
 public class CrudApplication extends SpringBootServletInitializer{// NOSONAR
     @Autowired
@@ -67,4 +79,15 @@ public class CrudApplication extends SpringBootServletInitializer{// NOSONAR
             }
         }
     }
+    public static final Contact DEFAULT_CONTACT = new Contact("Amdocs", "http://www.amdocs.com", "noreply@amdocs.com");
+
+    public static final ApiInfo DEFAULT_API_INFO = new ApiInfo("AAI NCSO Adapter Service", "AAI NCSO Adapter Service.",
+        "1.0", "urn:tos", DEFAULT_CONTACT, "Apache 2.0", "API license URL", Collections.emptyList());
+
+    
+   
+    public Docket api() {      
+      return new Docket(DocumentationType.SWAGGER_2).apiInfo(DEFAULT_API_INFO).select().paths(PathSelectors.any())
+          .apis(RequestHandlerSelectors.basePackage("org.onap.crud")).build();
+    }
 }
index 654ff81..60167d5 100644 (file)
  */
 package org.onap.crud.config;
 
+import javax.annotation.PostConstruct;
+import javax.ws.rs.ApplicationPath;
+
 import org.glassfish.jersey.server.ResourceConfig;
 import org.onap.crud.service.CrudRestService;
 import org.onap.crud.service.JaxrsEchoService;
 import org.springframework.stereotype.Component;
 
+import io.swagger.jaxrs.config.BeanConfig;
+import io.swagger.jaxrs.listing.ApiListingResource;
+import io.swagger.jaxrs.listing.SwaggerSerializers;
+
 /**
  * Registers Crud Rest interface as JAX-RS endpoints.
  */
+
+@ApplicationPath("/services")
 @Component
 public class JerseyConfig extends ResourceConfig {
 
@@ -35,5 +44,26 @@ public class JerseyConfig extends ResourceConfig {
         register(crudRestService);
         register(jaxrsEchoService);
     }
+    
+    @PostConstruct
+    public void init() {
+      // Register components where DI is needed
+      this.SwaggerConfig();
+    }
+  private void SwaggerConfig() {
+      this.register(ApiListingResource.class);
+      this.register(SwaggerSerializers.class);
+
+      BeanConfig swaggerConfigBean = new BeanConfig();
+      swaggerConfigBean.setConfigId("Gizmo");
+      swaggerConfigBean.setTitle("Gizmo Rest API ");
+      swaggerConfigBean.setVersion("v1");
+      swaggerConfigBean.setContact("Amdocs Inc.");
+      swaggerConfigBean.setSchemes(new String[] { "https" });
+      swaggerConfigBean.setBasePath("/services");
+      swaggerConfigBean.setResourcePackage("org.onap.crud");
+      swaggerConfigBean.setPrettyPrint(true);
+      swaggerConfigBean.setScan(true);
+    }
 
 }
index fd03827..a70253e 100644 (file)
@@ -113,9 +113,8 @@ public class Vertex {
 
       type = OxmModelValidator.resolveCollectionType(version, type);
       DynamicJAXBContext jaxbContext = OxmModelLoader.getContextForVersion(version);
-      String modelObjectClass = CaseFormat.LOWER_CAMEL.to(CaseFormat.UPPER_CAMEL, CaseFormat.LOWER_HYPHEN.to(CaseFormat.UPPER_CAMEL, type));
-
-      final DynamicType modelObjectType = jaxbContext.getDynamicType(modelObjectClass);
+      
+      final DynamicType modelObjectType = OxmModelLoader.getDynamicTypeForVersion(version, type);
       final DynamicType reservedType = jaxbContext.getDynamicType("ReservedPropNames");
 
 
index 7bf4ca4..f975347 100644 (file)
@@ -20,7 +20,6 @@
  */
 package org.onap.crud.service;
 
-import com.google.gson.JsonElement;
 import java.security.cert.X509Certificate;
 import java.util.ArrayList;
 import java.util.Arrays;
@@ -28,6 +27,7 @@ import java.util.HashMap;
 import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
+
 import javax.security.auth.x500.X500Principal;
 import javax.servlet.http.HttpServletRequest;
 import javax.ws.rs.Consumes;
@@ -47,6 +47,7 @@ import javax.ws.rs.core.Response;
 import javax.ws.rs.core.Response.ResponseBuilder;
 import javax.ws.rs.core.Response.Status;
 import javax.ws.rs.core.UriInfo;
+
 import org.apache.commons.lang3.tuple.ImmutablePair;
 import org.apache.cxf.jaxrs.ext.PATCH;
 import org.onap.aai.cl.api.Logger;
@@ -63,7 +64,16 @@ import org.onap.crud.util.CrudServiceConstants;
 import org.onap.crud.util.CrudServiceUtil;
 import org.slf4j.MDC;
 
-@Path("/services/inventory")
+import com.google.gson.JsonElement;
+
+import io.swagger.annotations.ApiImplicitParam;
+import io.swagger.annotations.ApiImplicitParams;
+import io.swagger.annotations.ApiOperation;
+import io.swagger.annotations.ApiParam;
+import io.swagger.annotations.ApiResponse;
+import io.swagger.annotations.ApiResponses;
+
+@Path("/inventory")
 public class CrudRestService {
 
     private AbstractGraphDataService graphDataService;
@@ -93,13 +103,23 @@ public class CrudRestService {
     public void startup() {
 
     }
-
+    
+    @ApiOperation(value = "Get Vertex" , notes="For example : https://<host>:9520/services/inventory/v11/pserver/<id>")
+    @ApiResponses({    
+      @ApiResponse(code = 200, message = "Success"),
+      @ApiResponse(code = 403, message = "Forbidden"),    
+      @ApiResponse(code = 404, message = "Not Found"),
+      @ApiResponse(code = 500, message = "Internal Server Error") })
+    @ApiImplicitParams({
+      @ApiImplicitParam(name = "X-FromAppId", required = true, dataType = "string", paramType = "header"),
+      @ApiImplicitParam(name = "X-TransactionId",  required = true, dataType = "string", paramType = "header"),    
+    })
     @GET
     @Path("/{version}/{type}/{id}")
     @Consumes({MediaType.APPLICATION_JSON})
     @Produces({MediaType.APPLICATION_JSON})
-    public Response getVertex(String content, @PathParam("version") String version, @PathParam("type") String type,
-            @PathParam("id") String id, @PathParam("uri") @Encoded String uri, @Context HttpHeaders headers,
+    public Response getVertex(@ApiParam(hidden=true) String content, @PathParam("version") @ApiParam(value="oxm model version",defaultValue="v13") String version, @PathParam("type") String type,
+            @PathParam("id") String id, @PathParam("uri") @Encoded @ApiParam(hidden=true) String uri, @Context HttpHeaders headers,
             @Context UriInfo uriInfo, @Context HttpServletRequest req) {
 
         LoggingUtil.initMdcContext(req, headers);
@@ -130,12 +150,22 @@ public class CrudRestService {
         return response;
     }
 
+    @ApiOperation(value = "Get Vertices" , notes="For example : https://<host>:9520/services/inventory/v11/pserver/")
+    @ApiResponses({    
+      @ApiResponse(code = 200, message = "Success"),
+      @ApiResponse(code = 403, message = "Forbidden"),    
+      @ApiResponse(code = 404, message = "Not Found"),
+      @ApiResponse(code = 500, message = "Internal Server Error") })
+    @ApiImplicitParams({
+      @ApiImplicitParam(name = "X-FromAppId", required = true, dataType = "string", paramType = "header"),    
+      @ApiImplicitParam(name = "X-TransactionId",  required = true, dataType = "string", paramType = "header"),    
+    })
     @GET
     @Path("/{version}/{type}/")
     @Consumes({MediaType.APPLICATION_JSON})
     @Produces({MediaType.APPLICATION_JSON})
-    public Response getVertices(String content, @PathParam("version") String version, @PathParam("type") String type,
-            @PathParam("uri") @Encoded String uri, @Context HttpHeaders headers, @Context UriInfo uriInfo,
+    public Response getVertices(@ApiParam(hidden=true) String content, @PathParam("version") @ApiParam(value="oxm model version",defaultValue="v13") String version, @PathParam("type") String type,
+            @PathParam("uri") @Encoded @ApiParam(hidden=true) String uri, @Context HttpHeaders headers, @Context UriInfo uriInfo,
             @Context HttpServletRequest req) {
 
         LoggingUtil.initMdcContext(req, headers);
@@ -175,12 +205,22 @@ public class CrudRestService {
         return response;
     }
 
+    @ApiOperation(value = "Get Edge" , notes="For example : https://<host>:9520/services/inventory/relationships/v11/tosca.relationships.HostedOn/<id>")
+    @ApiResponses({    
+      @ApiResponse(code = 200, message = "Success"),
+      @ApiResponse(code = 403, message = "Forbidden"),    
+      @ApiResponse(code = 404, message = "Not Found"),
+      @ApiResponse(code = 500, message = "Internal Server Error") })
+    @ApiImplicitParams({
+      @ApiImplicitParam(name = "X-FromAppId", required = true, dataType = "string", paramType = "header"),
+      @ApiImplicitParam(name = "X-TransactionId",  required = true, dataType = "string", paramType = "header"),    
+    })
     @GET
     @Path("/relationships/{version}/{type}/{id}")
     @Consumes({MediaType.APPLICATION_JSON})
     @Produces({MediaType.APPLICATION_JSON})
-    public Response getEdge(String content, @PathParam("version") String version, @PathParam("type") String type,
-            @PathParam("id") String id, @PathParam("uri") @Encoded String uri, @Context HttpHeaders headers,
+    public Response getEdge(@ApiParam(hidden=true) String content, @PathParam("version") @ApiParam(value="oxm model version",defaultValue="v13") String version, @PathParam("type") String type,
+            @PathParam("id") String id, @PathParam("uri") @Encoded @ApiParam(hidden=true) String uri, @Context HttpHeaders headers,
             @Context UriInfo uriInfo, @Context HttpServletRequest req) {
 
         LoggingUtil.initMdcContext(req, headers);
@@ -211,12 +251,22 @@ public class CrudRestService {
         return response;
     }
 
+    @ApiOperation(value = "Get Edges" , notes="For example : https://<host>:9520/services/inventory/relationships/v11/tosca.relationships.HostedOn/")
+    @ApiResponses({    
+      @ApiResponse(code = 200, message = "Success"),
+      @ApiResponse(code = 403, message = "Forbidden"),    
+      @ApiResponse(code = 404, message = "Not Found"),
+      @ApiResponse(code = 500, message = "Internal Server Error") })
+    @ApiImplicitParams({
+      @ApiImplicitParam(name = "X-FromAppId", required = true, dataType = "string", paramType = "header"),
+      @ApiImplicitParam(name = "X-TransactionId",  required = true, dataType = "string", paramType = "header"),    
+    })
     @GET
     @Path("/relationships/{version}/{type}/")
     @Consumes({MediaType.APPLICATION_JSON})
     @Produces({MediaType.APPLICATION_JSON})
-    public Response getEdges(String content, @PathParam("version") String version, @PathParam("type") String type,
-            @PathParam("uri") @Encoded String uri, @Context HttpHeaders headers, @Context UriInfo uriInfo,
+    public Response getEdges(@ApiParam(hidden=true) String content, @PathParam("version") @ApiParam(value="oxm model version",defaultValue="v13") String version, @PathParam("type") String type,
+            @PathParam("uri") @Encoded @ApiParam(hidden=true) String uri, @Context HttpHeaders headers, @Context UriInfo uriInfo,
             @Context HttpServletRequest req) {
 
         LoggingUtil.initMdcContext(req, headers);
@@ -246,12 +296,29 @@ public class CrudRestService {
         return response;
     }
 
+    @ApiOperation(value = "Update Edge" , notes = "# Payload \n"
+        + "{  \r\n" + 
+        "   \"properties\":{  \r\n" + 
+        "        \"prop1\" : \"value\",\r\n" + 
+        "        \"prop2\" :\"value\",\r\n" +  
+        "    ..}\r\n" + 
+        " }")
+    @ApiResponses({    
+      @ApiResponse(code = 200, message = "Success"),
+      @ApiResponse(code = 403, message = "Forbidden"),    
+      @ApiResponse(code = 404, message = "Not Found"),
+      @ApiResponse(code = 400, message = "Bad Request"),
+      @ApiResponse(code = 500, message = "Internal Server Error") })
+    @ApiImplicitParams({
+      @ApiImplicitParam(name = "X-FromAppId", required = true, dataType = "string", paramType = "header"),
+      @ApiImplicitParam(name = "X-TransactionId",  required = true, dataType = "string", paramType = "header"),    
+    })
     @PUT
     @Path("/relationships/{version}/{type}/{id}")
     @Consumes({MediaType.APPLICATION_JSON})
     @Produces({MediaType.APPLICATION_JSON})
-    public Response updateEdge(String content, @PathParam("version") String version, @PathParam("type") String type,
-            @PathParam("id") String id, @PathParam("uri") @Encoded String uri, @Context HttpHeaders headers,
+    public Response updateEdge(String content, @PathParam("version") @ApiParam(value="oxm model version",defaultValue="v13") String version, @PathParam("type") String type,
+            @PathParam("id") String id, @PathParam("uri") @Encoded @ApiParam(hidden=true) String uri, @Context HttpHeaders headers,
             @Context UriInfo uriInfo, @Context HttpServletRequest req) {
 
         LoggingUtil.initMdcContext(req, headers);
@@ -296,12 +363,29 @@ public class CrudRestService {
         return response;
     }
 
+    @ApiOperation(value = "Patch Edge" , notes = "# Payload \n"
+        + "{  \r\n" + 
+        "   \"properties\":{  \r\n" + 
+        "        \"prop1\" : \"value\",\r\n" + 
+        "        \"prop2\" :\"value\",\r\n" +  
+        "    ..}\r\n" + 
+        " }")
+    @ApiResponses({    
+      @ApiResponse(code = 200, message = "Success"),
+      @ApiResponse(code = 403, message = "Forbidden"), 
+      @ApiResponse(code = 400, message = "Bad Request"),
+      @ApiResponse(code = 404, message = "Not Found"),
+      @ApiResponse(code = 500, message = "Internal Server Error") })
+    @ApiImplicitParams({
+      @ApiImplicitParam(name = "X-FromAppId", required = true, dataType = "string", paramType = "header"),
+      @ApiImplicitParam(name = "X-TransactionId",  required = true, dataType = "string", paramType = "header"),    
+    })
     @PATCH
     @Path("/relationships/{version}/{type}/{id}")
     @Consumes({"application/merge-patch+json"})
     @Produces({MediaType.APPLICATION_JSON})
-    public Response patchEdge(String content, @PathParam("version") String version, @PathParam("type") String type,
-            @PathParam("id") String id, @PathParam("uri") @Encoded String uri, @Context HttpHeaders headers,
+    public Response patchEdge(String content, @PathParam("version") @ApiParam(value="oxm model version",defaultValue="v13") String version, @PathParam("type") String type,
+            @PathParam("id") String id, @PathParam("uri") @Encoded @ApiParam(hidden=true) String uri, @Context HttpHeaders headers,
             @Context UriInfo uriInfo, @Context HttpServletRequest req) {
 
         LoggingUtil.initMdcContext(req, headers);
@@ -338,12 +422,30 @@ public class CrudRestService {
         return response;
     }
 
+    @ApiOperation(value = "Update Vertex" , notes = "# Payload \n"
+        + "{\r\n" + 
+        "   \"type\" :\"vertex type from oxm like comcast.nodes.sdwan.vpn\",\r\n" + 
+        "    \"properties\": {\r\n" + 
+        "        \"prop1\" : \"value\",\r\n" + 
+        "        \"prop2\" :\"value\",\r\n" +          
+        "    ..}\r\n" + 
+        " }")
+    @ApiResponses({    
+      @ApiResponse(code = 200, message = "Success"),
+      @ApiResponse(code = 403, message = "Forbidden"), 
+      @ApiResponse(code = 400, message = "Bad Request"),
+      @ApiResponse(code = 404, message = "Not Found"),
+      @ApiResponse(code = 500, message = "Internal Server Error") })
+    @ApiImplicitParams({
+      @ApiImplicitParam(name = "X-FromAppId", required = true, dataType = "string", paramType = "header"),
+      @ApiImplicitParam(name = "X-TransactionId",  required = true, dataType = "string", paramType = "header"),    
+    })
     @PUT
     @Path("/{version}/{type}/{id}")
     @Consumes({MediaType.APPLICATION_JSON})
     @Produces({MediaType.APPLICATION_JSON})
-    public Response updateVertex(String content, @PathParam("version") String version, @PathParam("type") String type,
-            @PathParam("id") String id, @PathParam("uri") @Encoded String uri, @Context HttpHeaders headers,
+    public Response updateVertex(String content, @PathParam("version") @ApiParam(value="oxm model version",defaultValue="v13") String version, @PathParam("type") String type,
+            @PathParam("id") String id, @PathParam("uri") @Encoded @ApiParam(hidden=true) String uri, @Context HttpHeaders headers,
             @Context UriInfo uriInfo, @Context HttpServletRequest req) {
 
         LoggingUtil.initMdcContext(req, headers);
@@ -392,12 +494,30 @@ public class CrudRestService {
         return response;
     }
 
+    @ApiOperation(value = "Patch Vertex" , notes = "# Payload \n"
+        + "{\r\n" + 
+        "   \"type\" :\"vertex type from oxm like comcast.nodes.sdwan.vpn\",\r\n" + 
+        "    \"properties\": {\r\n" + 
+        "        \"prop1\" : \"true\",\r\n" + 
+        "        \"prop2\" :\"name1\",\r\n" +         
+        "    ..}\r\n" + 
+        " }")
+    @ApiResponses({    
+      @ApiResponse(code = 200, message = "Success"),
+      @ApiResponse(code = 403, message = "Forbidden"), 
+      @ApiResponse(code = 400, message = "Bad Request"),
+      @ApiResponse(code = 404, message = "Not Found"),
+      @ApiResponse(code = 500, message = "Internal Server Error") })
+    @ApiImplicitParams({
+      @ApiImplicitParam(name = "X-FromAppId", required = true, dataType = "string", paramType = "header"),
+      @ApiImplicitParam(name = "X-TransactionId",  required = true, dataType = "string", paramType = "header"),    
+    })
     @PATCH
     @Path("/{version}/{type}/{id}")
     @Consumes({"application/merge-patch+json"})
     @Produces({MediaType.APPLICATION_JSON})
-    public Response patchVertex(String content, @PathParam("version") String version, @PathParam("type") String type,
-            @PathParam("id") String id, @PathParam("uri") @Encoded String uri, @Context HttpHeaders headers,
+    public Response patchVertex(String content, @PathParam("version") @ApiParam(value="oxm model version",defaultValue="v13") String version, @PathParam("type") String type,
+            @PathParam("id") String id, @PathParam("uri") @Encoded @ApiParam(hidden=true) String uri, @Context HttpHeaders headers,
             @Context UriInfo uriInfo, @Context HttpServletRequest req) {
 
         LoggingUtil.initMdcContext(req, headers);
@@ -437,12 +557,29 @@ public class CrudRestService {
         return response;
     }
 
+    @ApiOperation(value = "Create Vertex" , notes = "# Payload \n"
+        + "{\r\n" +      
+        "    \"properties\": {\r\n" + 
+        "        \"prop1\" : \"value\",\r\n" + 
+        "        \"prop2\" :\"value\",\r\n" +         
+        "    ..}\r\n" + 
+        " }")
+    @ApiResponses({    
+      @ApiResponse(code = 201, message = "Created"),
+      @ApiResponse(code = 403, message = "Forbidden"), 
+      @ApiResponse(code = 400, message = "Bad Request"),
+      @ApiResponse(code = 404, message = "Not Found"),
+      @ApiResponse(code = 500, message = "Internal Server Error") })
+    @ApiImplicitParams({
+      @ApiImplicitParam(name = "X-FromAppId", required = true, dataType = "string", paramType = "header"),
+      @ApiImplicitParam(name = "X-TransactionId",  required = true, dataType = "string", paramType = "header"),    
+    })
     @POST
     @Path("/{version}/{type}/")
     @Consumes({MediaType.APPLICATION_JSON})
     @Produces({MediaType.APPLICATION_JSON})
-    public Response addVertex(String content, @PathParam("version") String version, @PathParam("type") String type,
-            @PathParam("uri") @Encoded String uri, @Context HttpHeaders headers, @Context UriInfo uriInfo,
+    public Response addVertex(String content, @PathParam("version") @ApiParam(value="oxm model version",defaultValue="v13") String version, @PathParam("type") String type,
+            @PathParam("uri") @Encoded @ApiParam(hidden=true) String uri, @Context HttpHeaders headers, @Context UriInfo uriInfo,
             @Context HttpServletRequest req) {
 
         LoggingUtil.initMdcContext(req, headers);
@@ -586,12 +723,23 @@ public class CrudRestService {
 
     }
 
+    @ApiOperation(value = "Bulk API" , notes="For example : https://<host>:9520/services/inventory/v11/bulk")
+    @ApiResponses({    
+      @ApiResponse(code = 200, message = "Success"),
+      @ApiResponse(code = 403, message = "Forbidden"), 
+      @ApiResponse(code = 400, message = "Bad Request"),
+      @ApiResponse(code = 404, message = "Not Found"),
+      @ApiResponse(code = 500, message = "Internal Server Error") })
+    @ApiImplicitParams({
+      @ApiImplicitParam(name = "X-FromAppId", required = true, dataType = "string", paramType = "header"),
+      @ApiImplicitParam(name = "X-TransactionId",  required = true, dataType = "string", paramType = "header"),    
+    })
     @POST
     @Path("/{version}/bulk/")
     @Consumes({MediaType.APPLICATION_JSON})
     @Produces({MediaType.APPLICATION_JSON})
-    public Response addBulk(String content, @PathParam("version") String version, @PathParam("type") String type,
-            @PathParam("uri") @Encoded String uri, @Context HttpHeaders headers, @Context UriInfo uriInfo,
+    public Response addBulk(String content, @PathParam("version") @ApiParam(value="oxm model version",defaultValue="v13") String version, 
+            @PathParam("uri") @Encoded @ApiParam(hidden=true) String uri, @Context HttpHeaders headers, @Context UriInfo uriInfo,
             @Context HttpServletRequest req) {
 
         LoggingUtil.initMdcContext(req, headers);
@@ -627,12 +775,30 @@ public class CrudRestService {
         return response;
     }
 
+    @ApiOperation(value = "Create Vertex (typeless endpoint)" , nickname="addVertex-typeless",notes = "# Payload \n"
+        + "{\r\n" +  
+        "   \"type\" :\"vertex type from oxm like comcast.nodes.sdwan.vpn\",\r\n" +       
+        "    \"properties\": {\r\n" + 
+        "        \"prop1\" : \"value\",\r\n" + 
+        "        \"prop2\" :\"value\",\r\n" +          
+        "    ..}\r\n" + 
+        " }")
+    @ApiResponses({   
+      @ApiResponse(code = 201, message = "Created"),
+      @ApiResponse(code = 403, message = "Forbidden"), 
+      @ApiResponse(code = 400, message = "Bad Request"),
+      @ApiResponse(code = 404, message = "Not Found"),
+      @ApiResponse(code = 500, message = "Internal Server Error") })
+    @ApiImplicitParams({
+      @ApiImplicitParam(name = "X-FromAppId", required = true, dataType = "string", paramType = "header"),
+      @ApiImplicitParam(name = "X-TransactionId",  required = true, dataType = "string", paramType = "header"),    
+    })
     @POST
     @Path("/{version}/")
     @Consumes({MediaType.APPLICATION_JSON})
     @Produces({MediaType.APPLICATION_JSON})
-    public Response addVertex(String content, @PathParam("version") String version,
-            @PathParam("uri") @Encoded String uri, @Context HttpHeaders headers, @Context UriInfo uriInfo,
+    public Response addVertex(String content, @PathParam("version") @ApiParam(value="oxm model version",defaultValue="v13") String version,
+            @PathParam("uri") @Encoded  @ApiParam(hidden=true) String uri, @Context HttpHeaders headers, @Context UriInfo uriInfo,
             @Context HttpServletRequest req) {
 
         LoggingUtil.initMdcContext(req, headers);
@@ -677,12 +843,32 @@ public class CrudRestService {
         return response;
     }
 
+    @ApiOperation(value = "Create Edge" , notes = "# Payload \n"
+        + "{  \r\n" + 
+        "   \"source\":\"source vertex like : services/inventory/v11/vserver/0\",\r\n" + 
+        "   \"target\":\"target vertex like : services/inventory/v11/pserver/7\",\r\n" + 
+        "   \"properties\":{  \r\n" + 
+        "        \"prop1\" : \"value\",\r\n" + 
+        "        \"prop2\" :\"value\",\r\n" +  
+        "    ..}\r\n" + 
+        " }")
+    @ApiResponses({   
+      @ApiResponse(code = 201, message = "Created"),
+      @ApiResponse(code = 403, message = "Forbidden"), 
+      @ApiResponse(code = 400, message = "Bad Request"),
+      @ApiResponse(code = 404, message = "Not Found"),
+      @ApiResponse(code = 500, message = "Internal Server Error") })
+   
+    @ApiImplicitParams({
+      @ApiImplicitParam(name = "X-FromAppId", required = true, dataType = "string", paramType = "header"),
+      @ApiImplicitParam(name = "X-TransactionId",  required = true, dataType = "string", paramType = "header"),       
+    })
     @POST
     @Path("/relationships/{version}/{type}/")
     @Consumes({MediaType.APPLICATION_JSON})
     @Produces({MediaType.APPLICATION_JSON})
-    public Response addEdge(String content, @PathParam("version") String version, @PathParam("type") String type,
-            @PathParam("uri") @Encoded String uri, @Context HttpHeaders headers, @Context UriInfo uriInfo,
+    public Response addEdge(String content, @PathParam("version") @ApiParam(value="oxm model version",defaultValue="v13") String version, @PathParam("type") String type,
+            @PathParam("uri") @Encoded @ApiParam(hidden=true) String uri, @Context HttpHeaders headers, @Context UriInfo uriInfo,
             @Context HttpServletRequest req) {
 
         LoggingUtil.initMdcContext(req, headers);
@@ -722,11 +908,31 @@ public class CrudRestService {
         return response;
     }
 
+    @ApiOperation(value = "Create Edge (typeless endpoint)" , nickname="addEdge-typeless",notes = "# Payload \n"
+        + "{  \r\n" + 
+        "   \"type\":\"edge type like : tosca.relationships.HostedOn\",\r\n" +      
+        "   \"source\":\"source vertex like : services/inventory/v11/vserver/0\",\r\n" + 
+        "   \"target\":\"target vertex like : services/inventory/v11/pserver/7\",\r\n" + 
+        "   \"properties\":{  \r\n" + 
+        "        \"prop1\" : \"value\",\r\n" + 
+        "        \"prop2\" :\"value\",\r\n" +  
+        "    ..}\r\n" + 
+        " }")
+    @ApiResponses({  
+      @ApiResponse(code = 201, message = "Created"),
+      @ApiResponse(code = 403, message = "Forbidden"), 
+      @ApiResponse(code = 400, message = "Bad Request"),
+      @ApiResponse(code = 404, message = "Not Found"),
+      @ApiResponse(code = 500, message = "Internal Server Error") })
+    @ApiImplicitParams({
+      @ApiImplicitParam(name = "X-FromAppId", required = true, dataType = "string", paramType = "header"),
+      @ApiImplicitParam(name = "X-TransactionId",  required = true, dataType = "string", paramType = "header"),    
+    })
     @POST
     @Path("/relationships/{version}/")
     @Consumes({MediaType.APPLICATION_JSON})
     @Produces({MediaType.APPLICATION_JSON})
-    public Response addEdge(String content, @PathParam("version") String version, @PathParam("uri") @Encoded String uri,
+    public Response addEdge(String content, @PathParam("version")  @ApiParam(value="oxm model version",defaultValue="v13") String version, @PathParam("uri") @Encoded @ApiParam(hidden=true) String uri,
             @Context HttpHeaders headers, @Context UriInfo uriInfo, @Context HttpServletRequest req) {
 
         LoggingUtil.initMdcContext(req, headers);
@@ -767,12 +973,23 @@ public class CrudRestService {
         return response;
     }
 
+    @ApiOperation(value = "Delete Vertex" , notes="For example : https://<host>:9520/services/inventory/v11/pserver/<id>")
+    @ApiResponses({  
+      @ApiResponse(code = 200, message = "Success"),
+      @ApiResponse(code = 403, message = "Forbidden"), 
+      @ApiResponse(code = 400, message = "Bad Request"),
+      @ApiResponse(code = 404, message = "Not Found"),
+      @ApiResponse(code = 500, message = "Internal Server Error") })
+    @ApiImplicitParams({
+      @ApiImplicitParam(name = "X-FromAppId", required = true, dataType = "string", paramType = "header"),
+      @ApiImplicitParam(name = "X-TransactionId",  required = true, dataType = "string", paramType = "header"),    
+    })
     @DELETE
     @Path("/{version}/{type}/{id}")
     @Consumes({MediaType.APPLICATION_JSON})
     @Produces({MediaType.APPLICATION_JSON})
-    public Response deleteVertex(String content, @PathParam("version") String version, @PathParam("type") String type,
-            @PathParam("id") String id, @PathParam("uri") @Encoded String uri, @Context HttpHeaders headers,
+    public Response deleteVertex(@ApiParam(hidden=true) String content, @PathParam("version") @ApiParam(value="oxm model version",defaultValue="v13") String version, @PathParam("type") String type,
+            @PathParam("id") String id, @PathParam("uri") @Encoded @ApiParam(hidden=true)  String uri, @Context HttpHeaders headers,
             @Context UriInfo uriInfo, @Context HttpServletRequest req) {
 
         LoggingUtil.initMdcContext(req, headers);
@@ -800,12 +1017,23 @@ public class CrudRestService {
         return response;
     }
 
+    @ApiOperation(value = "Delete Edge" , notes="For example : https://<host>:9520/services/inventory/v11/pserver/<id>")
+    @ApiResponses({ 
+      @ApiResponse(code = 200, message = "Success"),
+      @ApiResponse(code = 403, message = "Forbidden"), 
+      @ApiResponse(code = 400, message = "Bad Request"),
+      @ApiResponse(code = 404, message = "Not Found"),
+      @ApiResponse(code = 500, message = "Internal Server Error") })
+    @ApiImplicitParams({
+      @ApiImplicitParam(name = "X-FromAppId", required = true, dataType = "string", paramType = "header"),
+      @ApiImplicitParam(name = "X-TransactionId",  required = true, dataType = "string", paramType = "header"),    
+    })
     @DELETE
     @Path("/relationships/{version}/{type}/{id}")
     @Consumes({MediaType.APPLICATION_JSON})
     @Produces({MediaType.APPLICATION_JSON})
-    public Response deleteEdge(String content, @PathParam("version") String version, @PathParam("type") String type,
-            @PathParam("id") String id, @PathParam("uri") @Encoded String uri, @Context HttpHeaders headers,
+    public Response deleteEdge(@ApiParam(hidden=true) String content, @PathParam("version") @ApiParam(value="oxm model version",defaultValue="v13") String version, @PathParam("type") String type,
+            @PathParam("id") String id, @PathParam("uri") @Encoded @ApiParam(hidden=true) String uri, @Context HttpHeaders headers,
             @Context UriInfo uriInfo, @Context HttpServletRequest req) {
 
         LoggingUtil.initMdcContext(req, headers);
diff --git a/src/main/java/org/onap/crud/util/CombinedResourceProvider.java b/src/main/java/org/onap/crud/util/CombinedResourceProvider.java
new file mode 100644 (file)
index 0000000..483ac5e
--- /dev/null
@@ -0,0 +1,50 @@
+/**
+ * ============LICENSE_START=======================================================
+ * org.onap.aai
+ * ================================================================================
+ * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved.
+ * Copyright © 2017-2018 Amdocs
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+package org.onap.crud.util;
+
+import org.springframework.context.annotation.Primary;
+import org.springframework.stereotype.Component;
+import springfox.documentation.swagger.web.InMemorySwaggerResourcesProvider;
+import springfox.documentation.swagger.web.SwaggerResource;
+import springfox.documentation.swagger.web.SwaggerResourcesProvider;
+
+import javax.annotation.Resource;
+import java.util.List;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+
+@Component
+@Primary
+public class CombinedResourceProvider implements SwaggerResourcesProvider {
+
+
+    public List<SwaggerResource> get() {
+
+        SwaggerResource jerseySwaggerResource = new SwaggerResource();
+        jerseySwaggerResource.setLocation("/services/swagger.json");
+        jerseySwaggerResource.setSwaggerVersion("2.0");
+        jerseySwaggerResource.setName("Jersey");
+
+        return Stream.of(jerseySwaggerResource).collect(Collectors.toList());
+    }
+
+}
\ No newline at end of file
index 8f55602..948914c 100644 (file)
@@ -22,12 +22,18 @@ package org.onap.schema;
 
 import java.io.IOException;
 import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
+
 import javax.ws.rs.core.Response.Status;
+
+import org.eclipse.persistence.dynamic.DynamicType;
+import org.eclipse.persistence.internal.oxm.mappings.Descriptor;
 import org.eclipse.persistence.jaxb.dynamic.DynamicJAXBContext;
 import org.onap.aai.cl.eelf.LoggerFactory;
 import org.onap.aai.nodes.NodeIngestor;
@@ -38,10 +44,14 @@ import org.onap.crud.exception.CrudException;
 import org.onap.crud.logging.CrudServiceMsgs;
 import org.onap.schema.util.SchemaIngestPropertyReader;
 
+import com.google.common.base.CaseFormat;
+
 public class OxmModelLoader {
 
     private static Map<String, DynamicJAXBContext> versionContextMap =
             new ConcurrentHashMap<>();
+    
+    private static Map<String, HashMap<String, DynamicType>> xmlElementLookup = new ConcurrentHashMap<String, HashMap<String, DynamicType>>();
 
     static final Pattern p = Pattern.compile("aai_oxm_(.*).xml");
     static final Pattern versionPattern = Pattern.compile("V(\\d*)");
@@ -82,6 +92,7 @@ public class OxmModelLoader {
 
     private static synchronized void loadModel(String oxmVersion, DynamicJAXBContext jaxbContext) {
         versionContextMap.put(oxmVersion, jaxbContext);
+        loadXmlLookupMap(oxmVersion, jaxbContext);
         logger.info(CrudServiceMsgs.LOADED_OXM_FILE, oxmVersion);
     }
 
@@ -192,4 +203,59 @@ public class OxmModelLoader {
     public static void setVersionContextMap(Map<String, DynamicJAXBContext> versionContextMap) {
         OxmModelLoader.versionContextMap = versionContextMap;
     }
+    
+   
+    public static void loadXmlLookupMap(String version, DynamicJAXBContext jaxbContext )  {
+      
+      @SuppressWarnings("rawtypes")
+      List<Descriptor> descriptorsList = jaxbContext.getXMLContext().getDescriptors();     
+      HashMap<String,DynamicType> types = new HashMap<String,DynamicType>();
+
+      for (@SuppressWarnings("rawtypes")
+      Descriptor desc : descriptorsList) {
+
+        DynamicType entity = jaxbContext.getDynamicType(desc.getAlias());
+        String entityName = desc.getDefaultRootElement();
+        types.put(entityName, entity);
+      }
+      xmlElementLookup.put(version, types);
+    }
+    
+    
+  public static DynamicType getDynamicTypeForVersion(String version, String type) throws CrudException {
+
+    DynamicType dynamicType;
+    // If we haven't already loaded in the available OXM models, then do so now.
+    if (versionContextMap == null || versionContextMap.isEmpty()) {
+      loadModels();
+    } else if (!versionContextMap.containsKey(version)) {
+      logger.error(CrudServiceMsgs.OXM_LOAD_ERROR, "Error loading oxm model: " + version);
+      throw new CrudException("Error loading oxm model: " + version, Status.INTERNAL_SERVER_ERROR);
+    }
+
+    // First try to match the Java-type based on hyphen to camel case translation
+    String javaTypeName = CaseFormat.LOWER_HYPHEN.to(CaseFormat.UPPER_CAMEL, type);
+    dynamicType = versionContextMap.get(version).getDynamicType(javaTypeName);
+
+    //Attempt to lookup in xml elements
+    if (xmlElementLookup.containsKey(version)) {
+      if (dynamicType == null) {
+        // Try to lookup by xml root element by exact match
+        dynamicType = xmlElementLookup.get(version).get(type);
+      }
+
+      if (dynamicType == null) {
+        // Try to lookup by xml root element by lowercase
+        dynamicType = xmlElementLookup.get(version).get(type.toLowerCase());
+      }
+
+      if (dynamicType == null) {
+        // Direct lookup as java-type name
+        dynamicType = versionContextMap.get(version).getDynamicType(type);
+      }
+    }
+
+    return dynamicType;
+
+  }
 }
index d317678..9da835e 100644 (file)
@@ -88,8 +88,7 @@ public class OxmModelValidator {
       logger.error(CrudServiceMsgs.OXM_LOAD_ERROR, OXM_LOAD_ERROR + ": " + version);
       throw new CrudException(OXM_LOAD_ERROR + ": " + version, Status.NOT_FOUND);
     }
-    final DynamicType modelObjectType = jaxbContext.getDynamicType(
-        CaseFormat.LOWER_CAMEL.to(CaseFormat.UPPER_CAMEL, CaseFormat.LOWER_HYPHEN.to(CaseFormat.UPPER_CAMEL, type)));
+    final DynamicType modelObjectType = OxmModelLoader.getDynamicTypeForVersion(version, type);
     final DynamicType reservedObjectType = jaxbContext.getDynamicType("ReservedPropNames");
 
     for (String key : filter.keySet()) {
@@ -137,8 +136,7 @@ public class OxmModelValidator {
     }
     // Determine if the Object part is a collection type in the model
     // definition
-    final DynamicType modelObjectType = jaxbContext.getDynamicType(
-        CaseFormat.LOWER_CAMEL.to(CaseFormat.UPPER_CAMEL, CaseFormat.LOWER_HYPHEN.to(CaseFormat.UPPER_CAMEL, type)));
+    final DynamicType modelObjectType = OxmModelLoader.getDynamicTypeForVersion(version, type);
 
     if (modelObjectType == null) {
       logger.error(CrudServiceMsgs.INVALID_OXM_FILE, "Object of collection type not found: " + type);
@@ -168,10 +166,8 @@ public class OxmModelValidator {
     try {
       type = resolveCollectionType(version, type);
       DynamicJAXBContext jaxbContext = OxmModelLoader.getContextForVersion(version);
-      String modelObjectClass = CaseFormat.LOWER_CAMEL.to(CaseFormat.UPPER_CAMEL,
-          CaseFormat.LOWER_HYPHEN.to(CaseFormat.UPPER_CAMEL, type));
 
-      final DynamicType modelObjectType = jaxbContext.getDynamicType(modelObjectClass);
+      final DynamicType modelObjectType = OxmModelLoader.getDynamicTypeForVersion(version, type);
       final DynamicType reservedType = jaxbContext.getDynamicType("ReservedPropNames");
 
       Set<Map.Entry<String, JsonElement>> payloadEntriesSet = properties.getAsJsonObject().entrySet();
@@ -252,10 +248,8 @@ public class OxmModelValidator {
     try {
       type = resolveCollectionType(version, type);
       DynamicJAXBContext jaxbContext = OxmModelLoader.getContextForVersion(version);
-      String modelObjectClass = CaseFormat.LOWER_CAMEL.to(CaseFormat.UPPER_CAMEL,
-          CaseFormat.LOWER_HYPHEN.to(CaseFormat.UPPER_CAMEL, type));
-
-      final DynamicType modelObjectType = jaxbContext.getDynamicType(modelObjectClass);
+      
+      final DynamicType modelObjectType =  OxmModelLoader.getDynamicTypeForVersion(version, type);
       final DynamicType reservedType = jaxbContext.getDynamicType("ReservedPropNames");
 
       Set<Map.Entry<String, JsonElement>> payloadEntriesSet = properties.getAsJsonObject().entrySet();
@@ -326,11 +320,11 @@ public class OxmModelValidator {
 
     try {
       DynamicJAXBContext jaxbContext = OxmModelLoader.getContextForVersion(version);
-      String modelObjectClass = CaseFormat.LOWER_CAMEL.to(CaseFormat.UPPER_CAMEL,
-          CaseFormat.LOWER_HYPHEN.to(CaseFormat.UPPER_CAMEL,
-              vertex.getProperties().get(Metadata.NODE_TYPE.propertyName()) != null
-                  ? vertex.getProperties().get(Metadata.NODE_TYPE.propertyName()).toString() : vertex.getType()));
-      final DynamicType modelObjectType = jaxbContext.getDynamicType(modelObjectClass);
+
+      final DynamicType modelObjectType = OxmModelLoader.getDynamicTypeForVersion(version,
+          vertex.getProperties().get(Metadata.NODE_TYPE.propertyName()) != null
+              ? vertex.getProperties().get(Metadata.NODE_TYPE.propertyName()).toString()
+              : vertex.getType());
       final DynamicType reservedObjectType = jaxbContext.getDynamicType("ReservedPropNames");
 
       for (String key : vertex.getProperties().keySet()) {
index 1098284..bc70a36 100644 (file)
@@ -333,7 +333,7 @@ public class CrudRestServiceTest {
     String payloadStr = readFileToString(bulkFile);
     System.out.println(payloadStr);
 
-    response = mockService.addBulk(payloadStr, "v9", "",
+    response = mockService.addBulk(payloadStr, "v9", 
         "services/inventory/v9", new TestHeaders(), null, new TestRequest());
     System.out.println("Bulk Response: " + response);
     System.out.println("Response Entity: " + response.getEntity().toString());