diff options
author | 2020-10-30 12:58:54 +0000 | |
---|---|---|
committer | 2020-11-02 09:07:28 +0000 | |
commit | 2371fe79fe36a6629810b6dcfd435a95ce0fd54d (patch) | |
tree | 73236becb44eaffad1f36c49600a5e7003e7358b | |
parent | b4cd52f312c85e182fbaf7cc57ffdb32e6459f9b (diff) |
IS: Remove Jersey and Use Spring Framework
Issue-ID: CCSDK-2959
Issue-Link: https://jira.onap.org/browse/CCSDK-2959
Signed-off-by: Rishi Chail <rishi.chail@est.tech>
Change-Id: Ie87d2fe53bffcaf2af0229961139910faeb36e26
6 files changed, 156 insertions, 365 deletions
diff --git a/cps/cps-rest/pom.xml b/cps/cps-rest/pom.xml index 3cecc5f73..ed896a82f 100644 --- a/cps/cps-rest/pom.xml +++ b/cps/cps-rest/pom.xml @@ -24,18 +24,8 @@ </dependency>
<dependency>
- <groupId>org.glassfish.jersey.media</groupId>
- <artifactId>jersey-media-multipart</artifactId>
- </dependency>
-
- <dependency>
- <groupId>org.springframework</groupId>
- <artifactId>spring-webmvc</artifactId>
- </dependency>
-
- <dependency>
<groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter-jersey</artifactId>
+ <artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
@@ -73,20 +63,6 @@ </exclusions>
</dependency>
- <!-- Used by the generated API -->
- <dependency>
- <groupId>org.apache.cxf</groupId>
- <artifactId>cxf-bundle-jaxrs</artifactId>
- <version>${cxf-bundle-jaxrs.version}</version>
- </dependency>
-
- <!-- Used by the generated API -->
- <dependency>
- <groupId>org.apache.cxf</groupId>
- <artifactId>cxf-rt-rs-service-description</artifactId>
- <version>${cxf-rt-rs-service.version}</version>
- </dependency>
-
</dependencies>
<build>
@@ -105,32 +81,6 @@ </plugin>
<plugin>
- <groupId>io.swagger.codegen.v3</groupId>
- <artifactId>swagger-codegen-maven-plugin</artifactId>
- <version>${swagger-codegen.version}</version>
- <executions>
- <execution>
- <goals>
- <goal>generate</goal>
- </goals>
- <configuration>
- <inputSpec>${project.basedir}/docs/api/swagger/openapi.yml</inputSpec>
- <invokerPackage>org.onap.cps.rest.controller</invokerPackage>
- <modelPackage>org.onap.cps.rest.model</modelPackage>
- <apiPackage>org.onap.cps.rest.controller</apiPackage>
- <language>jaxrs-cxf</language>
- <generateSupportingFiles>true</generateSupportingFiles>
- <configOptions>
- <sourceFolder>src/gen/java</sourceFolder>
- <dateLibrary>java8</dateLibrary>
- <library>jersey2</library>
- <interfaceOnly>true</interfaceOnly>
- </configOptions>
- </configuration>
- </execution>
- </executions>
- </plugin>
- <plugin>
<!-- Download Swagger UI webjar. -->
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
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 index 553c16b55..000000000 --- a/cps/cps-rest/src/main/java/org/onap/cps/rest/config/JerseyConfig.java +++ /dev/null @@ -1,72 +0,0 @@ -/*-
- * ============LICENSE_START=======================================================
- * Copyright (C) 2020 Nordix Foundation. 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.config;
-
-import io.swagger.v3.jaxrs2.integration.JaxrsOpenApiContextBuilder;
-import io.swagger.v3.jaxrs2.integration.resources.AcceptHeaderOpenApiResource;
-import io.swagger.v3.jaxrs2.integration.resources.OpenApiResource;
-import io.swagger.v3.oas.integration.OpenApiConfigurationException;
-import javax.annotation.PostConstruct;
-import javax.ws.rs.ApplicationPath;
-import org.glassfish.jersey.media.multipart.MultiPartFeature;
-import org.glassfish.jersey.server.ResourceConfig;
-import org.glassfish.jersey.servlet.ServletProperties;
-import org.onap.cps.rest.controller.ModelController;
-import org.onap.cps.rest.controller.RestController;
-import org.springframework.context.annotation.Configuration;
-
-@Configuration
-@ApplicationPath("api")
-public class JerseyConfig extends ResourceConfig {
-
- /**
- * This method is used to setup Jersey related configuration.
- */
- @PostConstruct
- public void init() {
- register(MultiPartFeature.class);
- register(OpenApiResource.class);
- register(AcceptHeaderOpenApiResource.class);
-
- // Register controllers
- register(ModelController.class);
- register(RestController.class);
-
- configureSwagger();
- configureSwaggerUI();
- }
-
- private void configureSwagger() {
- try {
- new JaxrsOpenApiContextBuilder<>().buildContext(true).read();
- } catch (final OpenApiConfigurationException e) {
- throw new RuntimeException(e.getMessage(), e);
- }
- }
-
- private void configureSwaggerUI() {
- // Enable Jersey filter forwarding to next filter for 404 responses.
- // This configuration lets Jersey servlet container forwarding static swagger ui requests to spring mvc filter
- // to be handle by spring mvc dispatcher servlet.
- property(ServletProperties.FILTER_FORWARD_ON_404, true);
- }
-
-}
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 index 000000000..a577af70e --- /dev/null +++ b/cps/cps-rest/src/main/java/org/onap/cps/rest/controller/CpsRestController.java @@ -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 index e155aa94c..000000000 --- a/cps/cps-rest/src/main/java/org/onap/cps/rest/controller/ModelController.java +++ /dev/null @@ -1,36 +0,0 @@ -/*-
- * ============LICENSE_START=======================================================
- * Copyright (C) 2020 Nordix Foundation. 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 javax.ws.rs.GET;
-import javax.ws.rs.Path;
-import javax.ws.rs.Produces;
-import javax.ws.rs.core.MediaType;
-
-@Path("/hi")
-public class ModelController {
-
- @GET
- @Produces(MediaType.TEXT_PLAIN)
- public String sayHello() {
- return "Hi";
- }
-}
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 index d3ff91b07..000000000 --- a/cps/cps-rest/src/main/java/org/onap/cps/rest/controller/RestController.java +++ /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 diff --git a/cps/cps-rest/src/main/resources/application.yml b/cps/cps-rest/src/main/resources/application.yml index c9154ba1f..8e2aee043 100644 --- a/cps/cps-rest/src/main/resources/application.yml +++ b/cps/cps-rest/src/main/resources/application.yml @@ -1,5 +1,7 @@ server:
port: 8080
+ servlet:
+ context-path: /api/cps
spring:
main:
|