IS: Remove Jersey and Use Spring Framework
authorRishi Chail <rishi.chail@est.tech>
Fri, 30 Oct 2020 12:58:54 +0000 (12:58 +0000)
committerRishi Chail <rishi.chail@est.tech>
Mon, 2 Nov 2020 09:07:28 +0000 (09:07 +0000)
Issue-ID: CCSDK-2959
Link: https://jira.onap.org/browse/CCSDK-2959
Signed-off-by: Rishi Chail <rishi.chail@est.tech>
Change-Id: Ie87d2fe53bffcaf2af0229961139910faeb36e26

cps/cps-rest/pom.xml
cps/cps-rest/src/main/java/org/onap/cps/rest/config/JerseyConfig.java [deleted file]
cps/cps-rest/src/main/java/org/onap/cps/rest/controller/CpsRestController.java [new file with mode: 0644]
cps/cps-rest/src/main/java/org/onap/cps/rest/controller/ModelController.java [deleted file]
cps/cps-rest/src/main/java/org/onap/cps/rest/controller/RestController.java [deleted file]
cps/cps-rest/src/main/resources/application.yml

index 3cecc5f..ed896a8 100644 (file)
             <version>${project.version}</version>\r
         </dependency>\r
 \r
-        <dependency>\r
-            <groupId>org.glassfish.jersey.media</groupId>\r
-            <artifactId>jersey-media-multipart</artifactId>\r
-        </dependency>\r
-\r
-        <dependency>\r
-            <groupId>org.springframework</groupId>\r
-            <artifactId>spring-webmvc</artifactId>\r
-        </dependency>\r
-\r
         <dependency>\r
             <groupId>org.springframework.boot</groupId>\r
-            <artifactId>spring-boot-starter-jersey</artifactId>\r
+            <artifactId>spring-boot-starter-web</artifactId>\r
             <exclusions>\r
                 <exclusion>\r
                     <groupId>org.springframework.boot</groupId>\r
             </exclusions>\r
         </dependency>\r
 \r
-        <!--   Used by the generated API     -->\r
-        <dependency>\r
-            <groupId>org.apache.cxf</groupId>\r
-            <artifactId>cxf-bundle-jaxrs</artifactId>\r
-            <version>${cxf-bundle-jaxrs.version}</version>\r
-        </dependency>\r
-\r
-        <!--   Used by the generated API     -->\r
-        <dependency>\r
-            <groupId>org.apache.cxf</groupId>\r
-            <artifactId>cxf-rt-rs-service-description</artifactId>\r
-            <version>${cxf-rt-rs-service.version}</version>\r
-        </dependency>\r
-\r
     </dependencies>\r
 \r
     <build>\r
                 </executions>\r
             </plugin>\r
 \r
-            <plugin>\r
-                <groupId>io.swagger.codegen.v3</groupId>\r
-                <artifactId>swagger-codegen-maven-plugin</artifactId>\r
-                <version>${swagger-codegen.version}</version>\r
-                <executions>\r
-                    <execution>\r
-                        <goals>\r
-                            <goal>generate</goal>\r
-                        </goals>\r
-                        <configuration>\r
-                            <inputSpec>${project.basedir}/docs/api/swagger/openapi.yml</inputSpec>\r
-                            <invokerPackage>org.onap.cps.rest.controller</invokerPackage>\r
-                            <modelPackage>org.onap.cps.rest.model</modelPackage>\r
-                            <apiPackage>org.onap.cps.rest.controller</apiPackage>\r
-                            <language>jaxrs-cxf</language>\r
-                            <generateSupportingFiles>true</generateSupportingFiles>\r
-                            <configOptions>\r
-                                <sourceFolder>src/gen/java</sourceFolder>\r
-                                <dateLibrary>java8</dateLibrary>\r
-                                <library>jersey2</library>\r
-                                <interfaceOnly>true</interfaceOnly>\r
-                            </configOptions>\r
-                        </configuration>\r
-                    </execution>\r
-                </executions>\r
-            </plugin>\r
             <plugin>\r
                 <!-- Download Swagger UI webjar. -->\r
                 <groupId>org.apache.maven.plugins</groupId>\r
diff --git a/cps/cps-rest/src/main/java/org/onap/cps/rest/config/JerseyConfig.java b/cps/cps-rest/src/main/java/org/onap/cps/rest/config/JerseyConfig.java
deleted file mode 100644 (file)
index 553c16b..0000000
+++ /dev/null
@@ -1,72 +0,0 @@
-/*-\r
- * ============LICENSE_START=======================================================\r
- *  Copyright (C) 2020 Nordix Foundation. All rights reserved.\r
- * ================================================================================\r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- *      http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- *\r
- * SPDX-License-Identifier: Apache-2.0\r
- * ============LICENSE_END=========================================================\r
- */\r
-\r
-package org.onap.cps.rest.config;\r
-\r
-import io.swagger.v3.jaxrs2.integration.JaxrsOpenApiContextBuilder;\r
-import io.swagger.v3.jaxrs2.integration.resources.AcceptHeaderOpenApiResource;\r
-import io.swagger.v3.jaxrs2.integration.resources.OpenApiResource;\r
-import io.swagger.v3.oas.integration.OpenApiConfigurationException;\r
-import javax.annotation.PostConstruct;\r
-import javax.ws.rs.ApplicationPath;\r
-import org.glassfish.jersey.media.multipart.MultiPartFeature;\r
-import org.glassfish.jersey.server.ResourceConfig;\r
-import org.glassfish.jersey.servlet.ServletProperties;\r
-import org.onap.cps.rest.controller.ModelController;\r
-import org.onap.cps.rest.controller.RestController;\r
-import org.springframework.context.annotation.Configuration;\r
-\r
-@Configuration\r
-@ApplicationPath("api")\r
-public class JerseyConfig extends ResourceConfig {\r
-\r
-    /**\r
-     * This method is used to setup Jersey related configuration.\r
-     */\r
-    @PostConstruct\r
-    public void init() {\r
-        register(MultiPartFeature.class);\r
-        register(OpenApiResource.class);\r
-        register(AcceptHeaderOpenApiResource.class);\r
-\r
-        // Register controllers\r
-        register(ModelController.class);\r
-        register(RestController.class);\r
-\r
-        configureSwagger();\r
-        configureSwaggerUI();\r
-    }\r
-\r
-    private void configureSwagger() {\r
-        try {\r
-            new JaxrsOpenApiContextBuilder<>().buildContext(true).read();\r
-        } catch (final OpenApiConfigurationException e) {\r
-            throw new RuntimeException(e.getMessage(), e);\r
-        }\r
-    }\r
-\r
-    private void configureSwaggerUI() {\r
-        // Enable Jersey filter forwarding to next filter for 404 responses.\r
-        // This configuration lets Jersey servlet container forwarding static swagger ui requests to spring mvc filter\r
-        // to be handle by spring mvc dispatcher servlet.\r
-        property(ServletProperties.FILTER_FORWARD_ON_404, true);\r
-    }\r
-\r
-}\r
diff --git a/cps/cps-rest/src/main/java/org/onap/cps/rest/controller/CpsRestController.java b/cps/cps-rest/src/main/java/org/onap/cps/rest/controller/CpsRestController.java
new file mode 100644 (file)
index 0000000..a577af7
--- /dev/null
@@ -0,0 +1,153 @@
+/*
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2020 Nordix Foundation
+ *  Modifications Copyright (C) 2020 Bell Canada. 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.
+ *
+ *  SPDX-License-Identifier: Apache-2.0
+ *  ============LICENSE_END=========================================================
+ */
+
+package org.onap.cps.rest.controller;
+
+import com.google.gson.Gson;
+import com.google.gson.JsonSyntaxException;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import javax.persistence.PersistenceException;
+import org.hibernate.exception.ConstraintViolationException;
+import org.onap.cps.api.CpService;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+import org.opendaylight.yangtools.yang.model.parser.api.YangParserException;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.dao.EmptyResultDataAccessException;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.DeleteMapping;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+import org.springframework.web.multipart.MultipartFile;
+
+@RestController
+public class CpsRestController {
+
+    @Autowired
+    private CpService cpService;
+
+    /*
+    Old rest endpoints before contract first approach (Need to be removed).
+     */
+
+    /**
+     * Upload a yang model file.
+     *
+     * @param uploadedFile the yang model Multipart File.
+     * @param dataspaceName the dataspace name linked to the model.
+     * @return a ResponseEntity.
+     */
+    @PostMapping("/dataspaces/{dataspace_name}/modules")
+    public final ResponseEntity<String> uploadYangModelFile(
+        @RequestParam("file") MultipartFile uploadedFile,
+        @PathVariable("dataspace_name") String dataspaceName) {
+        try {
+            final File fileToParse = saveToFile(uploadedFile);
+            final SchemaContext schemaContext = cpService.parseAndValidateModel(fileToParse);
+            cpService.storeSchemaContext(schemaContext, dataspaceName);
+            return new ResponseEntity<String>("Resource successfully created", HttpStatus.CREATED);
+        } catch (final YangParserException | ConstraintViolationException e) {
+            return new ResponseEntity<String>(e.getMessage(), HttpStatus.BAD_REQUEST);
+        } catch (final Exception e) {
+            return new ResponseEntity<String>(e.getMessage(), HttpStatus.INTERNAL_SERVER_ERROR);
+        }
+    }
+
+    /**
+     * Upload a JSON file.
+     *
+     * @param uploadedFile the JSON Multipart file.
+     * @return a ResponseEntity.
+     */
+    @PostMapping("/upload-yang-json-data-file")
+    public final ResponseEntity<String> uploadYangJsonDataFile(
+        @RequestParam("file") MultipartFile uploadedFile) {
+        try {
+            validateJsonStructure(uploadedFile);
+            final int persistenceObjectId = cpService.storeJsonStructure(new String(uploadedFile.getBytes()));
+            return new ResponseEntity<String>(
+                "Object stored in CPS with identity: " + persistenceObjectId, HttpStatus.OK);
+        } catch (final JsonSyntaxException e) {
+            return new ResponseEntity<String>(e.getMessage(), HttpStatus.BAD_REQUEST);
+        } catch (final Exception e) {
+            return new ResponseEntity<String>(e.getMessage(), HttpStatus.INTERNAL_SERVER_ERROR);
+        }
+    }
+
+    /**
+     * Read a JSON Object using the object identifier.
+     *
+     * @param jsonObjectId the JSON object identifier.
+     * @return a ResponseEntity.
+     */
+    @GetMapping("/json-object/{id}")
+    public final ResponseEntity<String> getJsonObjectById(
+        @PathVariable("id") final int jsonObjectId) {
+        try {
+            return new ResponseEntity<String>(cpService.getJsonById(jsonObjectId), HttpStatus.OK);
+        } catch (final PersistenceException e) {
+            return new ResponseEntity<String>(e.getMessage(), HttpStatus.NOT_FOUND);
+        } catch (final Exception e) {
+            return new ResponseEntity<String>(e.getMessage(), HttpStatus.INTERNAL_SERVER_ERROR);
+        }
+    }
+
+    /**
+     * Delete a JSON Object using the object identifier.
+     *
+     * @param jsonObjectId the JSON object identifier.
+     * @return a ResponseEntity.
+     */
+    @DeleteMapping("json-object/{id}")
+    public final ResponseEntity<Object> deleteJsonObjectById(
+        @PathVariable("id") final int jsonObjectId) {
+        try {
+            cpService.deleteJsonById(jsonObjectId);
+            return new ResponseEntity<>(HttpStatus.NO_CONTENT);
+        } catch (final EmptyResultDataAccessException e) {
+            return new ResponseEntity<>(HttpStatus.NOT_FOUND.toString(), HttpStatus.NOT_FOUND);
+        } catch (final Exception e) {
+            return new ResponseEntity<>(e.getMessage(), HttpStatus.INTERNAL_SERVER_ERROR);
+        }
+    }
+
+    private static final void validateJsonStructure(final MultipartFile jsonFile)
+        throws JsonSyntaxException, IOException {
+        final Gson gson = new Gson();
+        gson.fromJson(new String(jsonFile.getBytes()), Object.class);
+    }
+
+    private static final File saveToFile(final MultipartFile multipartFile)
+        throws IOException {
+        final File file = File.createTempFile("tempFile", ".yang");
+        file.deleteOnExit();
+
+        try (OutputStream outputStream = new FileOutputStream(file)) {
+            outputStream.write(multipartFile.getBytes());
+        }
+        return file;
+    }
+}
\ No newline at end of file
diff --git a/cps/cps-rest/src/main/java/org/onap/cps/rest/controller/ModelController.java b/cps/cps-rest/src/main/java/org/onap/cps/rest/controller/ModelController.java
deleted file mode 100644 (file)
index e155aa9..0000000
+++ /dev/null
@@ -1,36 +0,0 @@
-/*-\r
- * ============LICENSE_START=======================================================\r
- *  Copyright (C) 2020 Nordix Foundation. All rights reserved.\r
- * ================================================================================\r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- *      http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- *\r
- * SPDX-License-Identifier: Apache-2.0\r
- * ============LICENSE_END=========================================================\r
- */\r
-\r
-package org.onap.cps.rest.controller;\r
-\r
-import javax.ws.rs.GET;\r
-import javax.ws.rs.Path;\r
-import javax.ws.rs.Produces;\r
-import javax.ws.rs.core.MediaType;\r
-\r
-@Path("/hi")\r
-public class ModelController {\r
-\r
-    @GET\r
-    @Produces(MediaType.TEXT_PLAIN)\r
-    public String sayHello() {\r
-        return "Hi";\r
-    }\r
-}\r
diff --git a/cps/cps-rest/src/main/java/org/onap/cps/rest/controller/RestController.java b/cps/cps-rest/src/main/java/org/onap/cps/rest/controller/RestController.java
deleted file mode 100644 (file)
index d3ff91b..0000000
+++ /dev/null
@@ -1,206 +0,0 @@
-/*
- * ============LICENSE_START=======================================================
- *  Copyright (C) 2020 Nordix Foundation
- *  Modifications Copyright (C) 2020 Bell Canada. 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.
- *
- *  SPDX-License-Identifier: Apache-2.0
- *  ============LICENSE_END=========================================================
- */
-
-package org.onap.cps.rest.controller;
-
-import com.google.gson.Gson;
-import com.google.gson.JsonSyntaxException;
-import java.io.File;
-import javax.persistence.PersistenceException;
-import javax.validation.Valid;
-import javax.ws.rs.Consumes;
-import javax.ws.rs.DELETE;
-import javax.ws.rs.GET;
-import javax.ws.rs.POST;
-import javax.ws.rs.Path;
-import javax.ws.rs.PathParam;
-import javax.ws.rs.Produces;
-import javax.ws.rs.core.MediaType;
-import javax.ws.rs.core.Response;
-import javax.ws.rs.core.Response.Status;
-import org.apache.cxf.jaxrs.ext.multipart.Attachment;
-import org.glassfish.jersey.media.multipart.FormDataParam;
-import org.hibernate.exception.ConstraintViolationException;
-import org.onap.cps.api.CpService;
-import org.opendaylight.yangtools.yang.model.api.SchemaContext;
-import org.opendaylight.yangtools.yang.model.parser.api.YangParserException;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.dao.EmptyResultDataAccessException;
-
-@Path("cps")
-public class RestController implements CpsResourceApi {
-
-    @Autowired
-    private CpService cpService;
-
-    @Override
-    public Object createAnchor(final Attachment fileDetail, final String dataspaceName) {
-        return null;
-    }
-
-    @Override
-    public Object createModules(final Attachment fileDetail, final String dataspaceName) {
-        return null;
-    }
-
-    @Override
-    public Object createNode(final Attachment fileDetail, final String dataspaceName) {
-        return null;
-    }
-
-    @Override
-    public Object deleteAnchor(final String dataspaceName, final String anchorName) {
-        return null;
-    }
-
-    @Override
-    public Object deleteDataspace(final String dataspaceName) {
-        return null;
-    }
-
-    @Override
-    public Object getAnchor(final String dataspaceName, final String anchorName) {
-        return null;
-    }
-
-    @Override
-    public Object getAnchors(final String dataspaceName) {
-        return null;
-    }
-
-    @Override
-    public Object getModule(final String dataspaceName, final String namespaceName, final String revision) {
-        return null;
-    }
-
-    @Override
-    public Object getNode(@Valid final String body, final String dataspaceName) {
-        return null;
-    }
-
-    @Override
-    public Object getNodeByDataspaceAndAnchor(@Valid final String body, final String dataspaceName,
-        final String anchorName) {
-        return null;
-    }
-
-    /*
-    Old rest endpoints before contract first approach (Need to be removed).
-     */
-
-    /**
-     * Upload a yang model file.
-     *
-     * @param uploadedFile the yang model file.
-     * @param dataspaceName the dataspace name linked to the model.
-     * @return a http response code.
-     */
-    @POST
-    @Path("/dataspaces/{dataspace_name}/modules")
-    @Produces(MediaType.APPLICATION_JSON)
-    @Consumes(MediaType.MULTIPART_FORM_DATA)
-    public final Response uploadYangModelFile(@FormDataParam("file") File uploadedFile,
-        @PathParam("dataspace_name") String dataspaceName) {
-        try {
-            final File fileToParse = renameFileIfNeeded(uploadedFile);
-            final SchemaContext schemaContext = cpService.parseAndValidateModel(fileToParse);
-            cpService.storeSchemaContext(schemaContext, dataspaceName);
-            return Response.status(Status.CREATED).entity("Resource successfully created").build();
-        } catch (final YangParserException | ConstraintViolationException e) {
-            return Response.status(Status.BAD_REQUEST).entity(e.getMessage()).build();
-        } catch (final Exception e) {
-            return Response.status(Status.INTERNAL_SERVER_ERROR).entity(e.getMessage()).build();
-        }
-    }
-
-    /**
-     * Upload a JSON file.
-     *
-     * @param uploadedFile the JSON file.
-     * @return a http response code.
-     */
-    @POST
-    @Path("/upload-yang-json-data-file")
-    @Produces(MediaType.APPLICATION_JSON)
-    @Consumes(MediaType.MULTIPART_FORM_DATA)
-    public final Response uploadYangJsonDataFile(@FormDataParam("file") final String uploadedFile) {
-        try {
-            validateJsonStructure(uploadedFile);
-            final int persistenceObjectId = cpService.storeJsonStructure(uploadedFile);
-            return Response.status(Status.OK).entity("Object stored in CPS with identity: " + persistenceObjectId)
-                .build();
-        } catch (final JsonSyntaxException e) {
-            return Response.status(Status.BAD_REQUEST).entity(e.getMessage()).build();
-        } catch (final Exception e) {
-            return Response.status(Status.INTERNAL_SERVER_ERROR).entity(e.getMessage()).build();
-        }
-    }
-
-    /**
-     * Read a JSON Object using the object identifier.
-     *
-     * @param jsonObjectId the JSON object identifier.
-     * @return a HTTP response.
-     */
-    @GET
-    @Path("/json-object/{id}")
-    public final Response getJsonObjectById(@PathParam("id") final int jsonObjectId) {
-        try {
-            return Response.status(Status.OK).entity(cpService.getJsonById(jsonObjectId)).build();
-        } catch (final PersistenceException e) {
-            return Response.status(Status.NOT_FOUND).entity(e.getMessage()).build();
-        } catch (final Exception e) {
-            return Response.status(Status.INTERNAL_SERVER_ERROR).entity(e.getMessage()).build();
-        }
-    }
-
-    /**
-     * Delete a JSON Object using the object identifier.
-     *
-     * @param jsonObjectId the JSON object identifier.
-     * @return a HTTP response.
-     */
-    @DELETE
-    @Path("json-object/{id}")
-    public final Response deleteJsonObjectById(@PathParam("id") final int jsonObjectId) {
-        try {
-            cpService.deleteJsonById(jsonObjectId);
-            return Response.status(Status.OK).entity(Status.OK.toString()).build();
-        } catch (final EmptyResultDataAccessException e) {
-            return Response.status(Status.NOT_FOUND).entity(Status.NOT_FOUND.toString()).build();
-        } catch (final Exception e) {
-            return Response.status(Status.INTERNAL_SERVER_ERROR).entity(e.getMessage()).build();
-        }
-    }
-
-    private static final void validateJsonStructure(final String jsonFile) {
-        final Gson gson = new Gson();
-        gson.fromJson(jsonFile, Object.class);
-    }
-
-    private static final File renameFileIfNeeded(final File originalFile) {
-        if (originalFile.getName().endsWith(".yang")) {
-            return originalFile;
-        }
-        final File renamedFile = new File(originalFile.getName() + ".yang");
-        originalFile.renameTo(renamedFile);
-        return renamedFile;
-    }
-}
\ No newline at end of file
index c9154ba..8e2aee0 100644 (file)
@@ -1,5 +1,7 @@
 server:\r
   port: 8080\r
+  servlet:\r
+     context-path: /api/cps\r
 \r
 spring:\r
     main:\r