From e765d005f0fa917411ac150f251c812398224067 Mon Sep 17 00:00:00 2001 From: Bruno Sakoto Date: Mon, 20 Jul 2020 15:33:54 -0400 Subject: Add dedicated folder for CPS PoC Issue-ID: CCSDK-2510 Signed-off-by: Bruno Sakoto Change-Id: Ib9017d57860ac6e8e5c719d54bcb5905b52dffd8 --- cps/README.md | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 cps/README.md diff --git a/cps/README.md b/cps/README.md new file mode 100644 index 000000000..b6131a1fa --- /dev/null +++ b/cps/README.md @@ -0,0 +1,7 @@ +# Configuration & Persistency Service + +This folder contains all files for +[Configuration & Persistency Service](https://wiki.onap.org/pages/viewpage.action?pageId=81406119). + +The code here is related to CPS POC, then it must be kept self contained in this cps folder to prevent any impact on +current ccsdk components and to be ready to be moved in its own repo once CPS becomes a standalone project. \ No newline at end of file -- cgit 1.2.3-korg From b220d74e147ebdb86c5416432968bef6de22ca77 Mon Sep 17 00:00:00 2001 From: Rishi Chail Date: Wed, 16 Sep 2020 15:23:53 +0100 Subject: DP: [Spike] Project Structure and basic conf Issue-ID: CCSDK-2749 https: //jira.onap.org/browse/CCSDK-2749 Change-Id: I668f97629a5d514e6b43da67063d1e1bdf8e49da Signed-off-by: Rishi Chail --- cps/.gitignore | 21 +++ cps/Dockerfile | 1 + cps/LICENSE.txt | 176 +++++++++++++++++++++ cps/cps-rest/pom.xml | 77 +++++++++ .../main/java/org/onap/cps/rest/Application.java | 32 ++++ .../org/onap/cps/rest/config/JerseyConfig.java | 37 +++++ .../onap/cps/rest/controller/ModelController.java | 36 +++++ cps/cps-rest/src/main/resources/application.yml | 11 ++ cps/cps-rest/src/main/resources/logback-spring.xml | 48 ++++++ cps/cps-ri/lombok.config | 2 + cps/cps-ri/pom.xml | 31 ++++ .../src/main/java/org/onap/cps/spi/dummy.txt | 1 + cps/cps-ri/src/main/resources/application.yml | 8 + cps/cps-ri/src/main/resources/logback-spring.xml | 48 ++++++ cps/cps-service/pom.xml | 42 +++++ .../src/main/java/org/onap/cps/api/dummy.txt | 1 + .../src/main/java/org/onap/cps/spi/dummy.txt | 1 + .../src/main/resources/logback-spring.xml | 48 ++++++ cps/pom.xml | 115 ++++++++++++++ cps/version.properties | 12 ++ 20 files changed, 748 insertions(+) create mode 100644 cps/.gitignore create mode 100644 cps/Dockerfile create mode 100644 cps/LICENSE.txt create mode 100644 cps/cps-rest/pom.xml create mode 100644 cps/cps-rest/src/main/java/org/onap/cps/rest/Application.java create mode 100644 cps/cps-rest/src/main/java/org/onap/cps/rest/config/JerseyConfig.java create mode 100644 cps/cps-rest/src/main/java/org/onap/cps/rest/controller/ModelController.java create mode 100644 cps/cps-rest/src/main/resources/application.yml create mode 100644 cps/cps-rest/src/main/resources/logback-spring.xml create mode 100644 cps/cps-ri/lombok.config create mode 100644 cps/cps-ri/pom.xml create mode 100644 cps/cps-ri/src/main/java/org/onap/cps/spi/dummy.txt create mode 100644 cps/cps-ri/src/main/resources/application.yml create mode 100644 cps/cps-ri/src/main/resources/logback-spring.xml create mode 100644 cps/cps-service/pom.xml create mode 100644 cps/cps-service/src/main/java/org/onap/cps/api/dummy.txt create mode 100644 cps/cps-service/src/main/java/org/onap/cps/spi/dummy.txt create mode 100644 cps/cps-service/src/main/resources/logback-spring.xml create mode 100644 cps/pom.xml create mode 100644 cps/version.properties diff --git a/cps/.gitignore b/cps/.gitignore new file mode 100644 index 000000000..ba64fc2fd --- /dev/null +++ b/cps/.gitignore @@ -0,0 +1,21 @@ +*.class +*.jar +*.war + +target/ +log/ + +.idea/ +.idea_modules/ +*.iml +*.ipr +*.iws + +.settings/ +bin/ +tmp/ +.metadata +.classpath +.project +*.tmp +.checkstyle \ No newline at end of file diff --git a/cps/Dockerfile b/cps/Dockerfile new file mode 100644 index 000000000..81fdf16d3 --- /dev/null +++ b/cps/Dockerfile @@ -0,0 +1 @@ +FROM openjdk:11-jre-slim \ No newline at end of file diff --git a/cps/LICENSE.txt b/cps/LICENSE.txt new file mode 100644 index 000000000..2bb9ad240 --- /dev/null +++ b/cps/LICENSE.txt @@ -0,0 +1,176 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS \ No newline at end of file diff --git a/cps/cps-rest/pom.xml b/cps/cps-rest/pom.xml new file mode 100644 index 000000000..41b5c42f3 --- /dev/null +++ b/cps/cps-rest/pom.xml @@ -0,0 +1,77 @@ + + 4.0.0 + cps-rest + + org.onap.cps + cps + 0.0.1-SNAPSHOT + + + + + + org.onap.cps + cps-service + ${project.version} + + + + org.onap.cps + cps-ri + ${project.version} + + + org.springframework.boot + spring-boot-starter-data-jpa + + + + + + org.springframework.boot + spring-boot-starter-jersey + + + org.springframework.boot + spring-boot-starter-tomcat + + + + + + org.springframework.boot + spring-boot-starter-jetty + + + + org.springframework.boot + spring-boot-starter-test + test + + + org.junit.vintage + junit-vintage-engine + + + + + + + + + org.springframework.boot + spring-boot-maven-plugin + ${springboot.version} + + + + repackage + + + + + + + diff --git a/cps/cps-rest/src/main/java/org/onap/cps/rest/Application.java b/cps/cps-rest/src/main/java/org/onap/cps/rest/Application.java new file mode 100644 index 000000000..3183efc65 --- /dev/null +++ b/cps/cps-rest/src/main/java/org/onap/cps/rest/Application.java @@ -0,0 +1,32 @@ +/*- + * ============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; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class Application { + + public static void main(String[] args) { + SpringApplication.run(Application.class, args); + } +} \ No newline at end of file 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 new file mode 100644 index 000000000..a7c4307ab --- /dev/null +++ b/cps/cps-rest/src/main/java/org/onap/cps/rest/config/JerseyConfig.java @@ -0,0 +1,37 @@ +/*- + * ============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 javax.annotation.PostConstruct; +import javax.ws.rs.ApplicationPath; +import org.glassfish.jersey.server.ResourceConfig; +import org.onap.cps.rest.controller.ModelController; +import org.springframework.context.annotation.Configuration; + +@Configuration +@ApplicationPath("/api/v1") +public class JerseyConfig extends ResourceConfig { + + @PostConstruct + public void init() { + register(ModelController.class); + } +} \ 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 new file mode 100644 index 000000000..e155aa94c --- /dev/null +++ b/cps/cps-rest/src/main/java/org/onap/cps/rest/controller/ModelController.java @@ -0,0 +1,36 @@ +/*- + * ============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/resources/application.yml b/cps/cps-rest/src/main/resources/application.yml new file mode 100644 index 000000000..ab19fe9ab --- /dev/null +++ b/cps/cps-rest/src/main/resources/application.yml @@ -0,0 +1,11 @@ +server: + port: 8080 + +spring: + main: + banner-mode: "off" + +logging: + level: + org: + springframework: INFO \ No newline at end of file diff --git a/cps/cps-rest/src/main/resources/logback-spring.xml b/cps/cps-rest/src/main/resources/logback-spring.xml new file mode 100644 index 000000000..fce0aca2c --- /dev/null +++ b/cps/cps-rest/src/main/resources/logback-spring.xml @@ -0,0 +1,48 @@ + + + + + + + + + + + + + + + + + ../log/${logName}.log + + ${debugLogName}.%d{yyyy-MM-dd}.%i.log.zip + + ${maxFileSize} + ${maxHistory} + ${totalSizeCap} + + + ${debugPattern} + + + + + 256 + + true + + + + + + + + + + + + \ No newline at end of file diff --git a/cps/cps-ri/lombok.config b/cps/cps-ri/lombok.config new file mode 100644 index 000000000..a23edb413 --- /dev/null +++ b/cps/cps-ri/lombok.config @@ -0,0 +1,2 @@ +config.stopBubbling = true +lombok.addLombokGeneratedAnnotation = true \ No newline at end of file diff --git a/cps/cps-ri/pom.xml b/cps/cps-ri/pom.xml new file mode 100644 index 000000000..3d0ccf0af --- /dev/null +++ b/cps/cps-ri/pom.xml @@ -0,0 +1,31 @@ + + 4.0.0 + + org.onap.cps + cps + 0.0.1-SNAPSHOT + + cps-ri + + + + + org.springframework.boot + spring-boot-starter-data-jpa + + + + org.springframework.boot + spring-boot-starter-validation + + + + org.projectlombok + lombok + + + + + \ No newline at end of file diff --git a/cps/cps-ri/src/main/java/org/onap/cps/spi/dummy.txt b/cps/cps-ri/src/main/java/org/onap/cps/spi/dummy.txt new file mode 100644 index 000000000..ff2b9f30c --- /dev/null +++ b/cps/cps-ri/src/main/java/org/onap/cps/spi/dummy.txt @@ -0,0 +1 @@ +Have a good day ! \ No newline at end of file diff --git a/cps/cps-ri/src/main/resources/application.yml b/cps/cps-ri/src/main/resources/application.yml new file mode 100644 index 000000000..fc6883346 --- /dev/null +++ b/cps/cps-ri/src/main/resources/application.yml @@ -0,0 +1,8 @@ +spring: + jpa: + hibernate: + ddl-auto: create + datasource: + url: jdbc:mariadb://${DB_HOST}:3306/${DB_NAME} + username: ${USERNAME} + password: ${PWD} \ No newline at end of file diff --git a/cps/cps-ri/src/main/resources/logback-spring.xml b/cps/cps-ri/src/main/resources/logback-spring.xml new file mode 100644 index 000000000..fce0aca2c --- /dev/null +++ b/cps/cps-ri/src/main/resources/logback-spring.xml @@ -0,0 +1,48 @@ + + + + + + + + + + + + + + + + + ../log/${logName}.log + + ${debugLogName}.%d{yyyy-MM-dd}.%i.log.zip + + ${maxFileSize} + ${maxHistory} + ${totalSizeCap} + + + ${debugPattern} + + + + + 256 + + true + + + + + + + + + + + + \ No newline at end of file diff --git a/cps/cps-service/pom.xml b/cps/cps-service/pom.xml new file mode 100644 index 000000000..a0bf49767 --- /dev/null +++ b/cps/cps-service/pom.xml @@ -0,0 +1,42 @@ + + 4.0.0 + + org.onap.cps + cps + 0.0.1-SNAPSHOT + + cps-service + + + 5.0.5 + + + + + + org.opendaylight.yangtools + yang-parser-api + ${org.opendaylight.yangtools.version} + + + + org.opendaylight.yangtools + yang-parser-impl + ${org.opendaylight.yangtools.version} + + + + org.opendaylight.yangtools + yang-model-util + ${org.opendaylight.yangtools.version} + + + + org.opendaylight.yangtools + yang-data-codec-xml + ${org.opendaylight.yangtools.version} + + + + + \ No newline at end of file diff --git a/cps/cps-service/src/main/java/org/onap/cps/api/dummy.txt b/cps/cps-service/src/main/java/org/onap/cps/api/dummy.txt new file mode 100644 index 000000000..ff2b9f30c --- /dev/null +++ b/cps/cps-service/src/main/java/org/onap/cps/api/dummy.txt @@ -0,0 +1 @@ +Have a good day ! \ No newline at end of file diff --git a/cps/cps-service/src/main/java/org/onap/cps/spi/dummy.txt b/cps/cps-service/src/main/java/org/onap/cps/spi/dummy.txt new file mode 100644 index 000000000..ff2b9f30c --- /dev/null +++ b/cps/cps-service/src/main/java/org/onap/cps/spi/dummy.txt @@ -0,0 +1 @@ +Have a good day ! \ No newline at end of file diff --git a/cps/cps-service/src/main/resources/logback-spring.xml b/cps/cps-service/src/main/resources/logback-spring.xml new file mode 100644 index 000000000..fce0aca2c --- /dev/null +++ b/cps/cps-service/src/main/resources/logback-spring.xml @@ -0,0 +1,48 @@ + + + + + + + + + + + + + + + + + ../log/${logName}.log + + ${debugLogName}.%d{yyyy-MM-dd}.%i.log.zip + + ${maxFileSize} + ${maxHistory} + ${totalSizeCap} + + + ${debugPattern} + + + + + 256 + + true + + + + + + + + + + + + \ No newline at end of file diff --git a/cps/pom.xml b/cps/pom.xml new file mode 100644 index 000000000..94ed29c07 --- /dev/null +++ b/cps/pom.xml @@ -0,0 +1,115 @@ + + 4.0.0 + + org.onap.oparent + oparent + 3.1.0 + + org.onap.cps + cps + 0.0.1-SNAPSHOT + pom + cps + ONAP Configuration and Persistency Service + + ONAP - CPS + http://www.onap.org/ + + + + 11 + 2.3.3.RELEASE + 1.6.7 + 3.1.0 + + + + + + org.springframework.boot + spring-boot-dependencies + ${springboot.version} + pom + import + + + + + + + + src/main/resources + true + + + + target/generated-sources/license + + third-party-licenses.txt + + + + + target/generated-resources/licenses + + *.* + + third-party-licenses + + + + + + org.apache.maven.plugins + maven-compiler-plugin + + ${version.java.compiler} + ${version.java.compiler} + + + + + org.apache.maven.plugins + maven-checkstyle-plugin + + + onap-java-style + + check + + process-sources + + onap-checkstyle/onap-java-style.xml + ${project.build.sourceDirectory} + true + true + true + true + warning + true + + + + + + + org.onap.oparent + checkstyle + ${oparent.version} + compile + + + + + + + + + cps-service + cps-rest + cps-ri + + + \ No newline at end of file diff --git a/cps/version.properties b/cps/version.properties new file mode 100644 index 000000000..12156a9a6 --- /dev/null +++ b/cps/version.properties @@ -0,0 +1,12 @@ +# Note that these variables cannot be structured (e.g. : version.release or version.snapshot etc... ) +# because they are used in Jenkins, whose plug-in doesn't support this + +major=1 +minor=0 +patch=0 + +base_version=${major}.${minor}.${patch} + +# Release must be completed with git revision # in Jenkins +release_version=${base_version} +snapshot_version=${base_version}-SNAPSHOT -- cgit 1.2.3-korg From b08767ed33915b9199f07cc9bca94b346e752196 Mon Sep 17 00:00:00 2001 From: Rishi Chail Date: Mon, 21 Sep 2020 11:27:32 +0100 Subject: DP: Project Structure and basic conf Issue-ID: CCSDK-2749 https: //jira.onap.org/browse/CCSDK-2749 Signed-off-by: Rishi Chail Change-Id: Ib2139263be435414855e2f487e96c2122f21c978 Signed-off-by: Rishi Chail --- cps/.gitignore | 2 ++ cps/cps-rest/pom.xml | 6 ---- .../src/main/java/org/onap/cps/Application.java | 32 ++++++++++++++++++++++ .../main/java/org/onap/cps/rest/Application.java | 32 ---------------------- cps/cps-rest/src/main/resources/application.yml | 9 ++++++ cps/cps-rest/src/main/resources/logback-spring.xml | 2 +- cps/cps-ri/pom.xml | 12 ++++++++ cps/cps-ri/src/main/resources/application.yml | 8 ------ cps/cps-ri/src/main/resources/logback-spring.xml | 2 +- .../src/main/resources/logback-spring.xml | 2 +- 10 files changed, 58 insertions(+), 49 deletions(-) create mode 100644 cps/cps-rest/src/main/java/org/onap/cps/Application.java delete mode 100644 cps/cps-rest/src/main/java/org/onap/cps/rest/Application.java delete mode 100644 cps/cps-ri/src/main/resources/application.yml diff --git a/cps/.gitignore b/cps/.gitignore index ba64fc2fd..624c9b63b 100644 --- a/cps/.gitignore +++ b/cps/.gitignore @@ -1,6 +1,8 @@ *.class *.jar *.war +*.zip +*.log target/ log/ diff --git a/cps/cps-rest/pom.xml b/cps/cps-rest/pom.xml index 41b5c42f3..0e8317b62 100644 --- a/cps/cps-rest/pom.xml +++ b/cps/cps-rest/pom.xml @@ -21,12 +21,6 @@ org.onap.cps cps-ri ${project.version} - - - org.springframework.boot - spring-boot-starter-data-jpa - - diff --git a/cps/cps-rest/src/main/java/org/onap/cps/Application.java b/cps/cps-rest/src/main/java/org/onap/cps/Application.java new file mode 100644 index 000000000..9f6c2edce --- /dev/null +++ b/cps/cps-rest/src/main/java/org/onap/cps/Application.java @@ -0,0 +1,32 @@ +/*- + * ============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; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class Application { + + public static void main(String[] args) { + SpringApplication.run(Application.class, args); + } +} \ No newline at end of file diff --git a/cps/cps-rest/src/main/java/org/onap/cps/rest/Application.java b/cps/cps-rest/src/main/java/org/onap/cps/rest/Application.java deleted file mode 100644 index 3183efc65..000000000 --- a/cps/cps-rest/src/main/java/org/onap/cps/rest/Application.java +++ /dev/null @@ -1,32 +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; - -import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.SpringBootApplication; - -@SpringBootApplication -public class Application { - - public static void main(String[] args) { - SpringApplication.run(Application.class, args); - } -} \ 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 ab19fe9ab..bc726694c 100644 --- a/cps/cps-rest/src/main/resources/application.yml +++ b/cps/cps-rest/src/main/resources/application.yml @@ -4,6 +4,15 @@ server: spring: main: banner-mode: "off" + # for POC only, later this should move to cpi-ri module + jpa: + hibernate: + ddl-auto: create + datasource: + url: jdbc:mariadb://${DB_HOST}:3306/${DB_NAME} + username: ${USERNAME} + password: ${PWD} + driverClassName: org.mariadb.jdbc.Driver logging: level: diff --git a/cps/cps-rest/src/main/resources/logback-spring.xml b/cps/cps-rest/src/main/resources/logback-spring.xml index fce0aca2c..8a4ae07c5 100644 --- a/cps/cps-rest/src/main/resources/logback-spring.xml +++ b/cps/cps-rest/src/main/resources/logback-spring.xml @@ -19,7 +19,7 @@ ../log/${logName}.log - ${debugLogName}.%d{yyyy-MM-dd}.%i.log.zip + ${logName}.%d{yyyy-MM-dd}.%i.log.zip ${maxFileSize} ${maxHistory} diff --git a/cps/cps-ri/pom.xml b/cps/cps-ri/pom.xml index 3d0ccf0af..0d6dcace4 100644 --- a/cps/cps-ri/pom.xml +++ b/cps/cps-ri/pom.xml @@ -11,6 +11,13 @@ + + org.onap.cps + cps-service + ${project.version} + compile + + org.springframework.boot spring-boot-starter-data-jpa @@ -21,6 +28,11 @@ spring-boot-starter-validation + + org.mariadb.jdbc + mariadb-java-client + + org.projectlombok lombok diff --git a/cps/cps-ri/src/main/resources/application.yml b/cps/cps-ri/src/main/resources/application.yml deleted file mode 100644 index fc6883346..000000000 --- a/cps/cps-ri/src/main/resources/application.yml +++ /dev/null @@ -1,8 +0,0 @@ -spring: - jpa: - hibernate: - ddl-auto: create - datasource: - url: jdbc:mariadb://${DB_HOST}:3306/${DB_NAME} - username: ${USERNAME} - password: ${PWD} \ No newline at end of file diff --git a/cps/cps-ri/src/main/resources/logback-spring.xml b/cps/cps-ri/src/main/resources/logback-spring.xml index fce0aca2c..8a4ae07c5 100644 --- a/cps/cps-ri/src/main/resources/logback-spring.xml +++ b/cps/cps-ri/src/main/resources/logback-spring.xml @@ -19,7 +19,7 @@ ../log/${logName}.log - ${debugLogName}.%d{yyyy-MM-dd}.%i.log.zip + ${logName}.%d{yyyy-MM-dd}.%i.log.zip ${maxFileSize} ${maxHistory} diff --git a/cps/cps-service/src/main/resources/logback-spring.xml b/cps/cps-service/src/main/resources/logback-spring.xml index fce0aca2c..8a4ae07c5 100644 --- a/cps/cps-service/src/main/resources/logback-spring.xml +++ b/cps/cps-service/src/main/resources/logback-spring.xml @@ -19,7 +19,7 @@ ../log/${logName}.log - ${debugLogName}.%d{yyyy-MM-dd}.%i.log.zip + ${logName}.%d{yyyy-MM-dd}.%i.log.zip ${maxFileSize} ${maxHistory} -- cgit 1.2.3-korg From 6820538d8f5f999f1fa7bc64ad40e2a2cee7c85b Mon Sep 17 00:00:00 2001 From: niamhcore Date: Wed, 23 Sep 2020 11:36:33 +0100 Subject: Adding upload and validation of yang model Issue-ID: CCSDK-2718 https: //jira.onap.org/browse/CCSDK-2718 Change-Id: I919525595e28d46f20c1adb560232c31025687e3 --- cps/cps-rest/pom.xml | 6 + .../org/onap/cps/rest/config/JerseyConfig.java | 6 +- .../onap/cps/rest/controller/RestController.java | 71 +++++++ cps/cps-ri/pom.xml | 85 +++++---- .../src/main/java/org/onap/cps/spi/dummy.txt | 1 - .../cps/spi/impl/ModelPersistencyServiceImpl.java | 46 +++++ .../onap/cps/spi/impl/entities/ModuleEntity.java | 63 +++++++ .../onap/cps/spi/repository/ModuleRepository.java | 30 +++ cps/cps-service/pom.xml | 75 +++++--- .../src/main/java/org/onap/cps/api/CPService.java | 55 ++++++ .../src/main/java/org/onap/cps/api/dummy.txt | 1 - .../java/org/onap/cps/api/impl/CPServiceImpl.java | 89 +++++++++ .../org/onap/cps/spi/ModelPersistencyService.java | 35 ++++ .../src/main/java/org/onap/cps/spi/dummy.txt | 1 - cps/pom.xml | 203 ++++++++++----------- 15 files changed, 590 insertions(+), 177 deletions(-) create mode 100644 cps/cps-rest/src/main/java/org/onap/cps/rest/controller/RestController.java delete mode 100644 cps/cps-ri/src/main/java/org/onap/cps/spi/dummy.txt create mode 100644 cps/cps-ri/src/main/java/org/onap/cps/spi/impl/ModelPersistencyServiceImpl.java create mode 100644 cps/cps-ri/src/main/java/org/onap/cps/spi/impl/entities/ModuleEntity.java create mode 100644 cps/cps-ri/src/main/java/org/onap/cps/spi/repository/ModuleRepository.java create mode 100644 cps/cps-service/src/main/java/org/onap/cps/api/CPService.java delete mode 100644 cps/cps-service/src/main/java/org/onap/cps/api/dummy.txt create mode 100644 cps/cps-service/src/main/java/org/onap/cps/api/impl/CPServiceImpl.java create mode 100644 cps/cps-service/src/main/java/org/onap/cps/spi/ModelPersistencyService.java delete mode 100644 cps/cps-service/src/main/java/org/onap/cps/spi/dummy.txt diff --git a/cps/cps-rest/pom.xml b/cps/cps-rest/pom.xml index 0e8317b62..bd9be8dfd 100644 --- a/cps/cps-rest/pom.xml +++ b/cps/cps-rest/pom.xml @@ -23,6 +23,11 @@ ${project.version} + + org.glassfish.jersey.media + jersey-media-multipart + + org.springframework.boot spring-boot-starter-jersey @@ -39,6 +44,7 @@ spring-boot-starter-jetty + org.springframework.boot spring-boot-starter-test 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 index a7c4307ab..44487fe06 100644 --- 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 @@ -22,8 +22,9 @@ package org.onap.cps.rest.config; import javax.annotation.PostConstruct; import javax.ws.rs.ApplicationPath; +import org.glassfish.jersey.media.multipart.MultiPartFeature; import org.glassfish.jersey.server.ResourceConfig; -import org.onap.cps.rest.controller.ModelController; +import org.onap.cps.rest.controller.RestController; import org.springframework.context.annotation.Configuration; @Configuration @@ -32,6 +33,7 @@ public class JerseyConfig extends ResourceConfig { @PostConstruct public void init() { - register(ModelController.class); + register(RestController.class); + register(MultiPartFeature.class); } } \ No newline at end of file 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 new file mode 100644 index 000000000..d2f1a3e03 --- /dev/null +++ b/cps/cps-rest/src/main/java/org/onap/cps/rest/controller/RestController.java @@ -0,0 +1,71 @@ +/* + * ============LICENSE_START======================================================= + * Copyright (C) 2020 Nordix Foundation + * ================================================================================ + * 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 java.io.File; +import java.io.IOException; +import javax.ws.rs.Consumes; +import javax.ws.rs.POST; +import javax.ws.rs.Path; +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.glassfish.jersey.media.multipart.FormDataParam; +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; + + +@Path("cps") +public class RestController { + + @Autowired + private CPService cpService; + + @POST + @Path("uploadYangFile") + @Produces(MediaType.APPLICATION_JSON) + @Consumes(MediaType.MULTIPART_FORM_DATA) + public Response uploadFile(@FormDataParam("file") File uploadedFile) throws IOException { + try { + File fileToParse = renameFileIfNeeded(uploadedFile); + SchemaContext schemaContext = cpService.parseAndValidateModel(fileToParse); + cpService.storeSchemaContext(schemaContext); + return Response.status(Status.OK).entity("Yang File Parsed").build(); + } catch (YangParserException e) { + return Response.status(Status.BAD_REQUEST).entity(e.getMessage()).build(); + } + } + + private static File renameFileIfNeeded(File originalFile) { + if (originalFile.getName().endsWith(".yang")) { + return originalFile; + } + File renamedFile = new File(originalFile.getName() + ".yang"); + originalFile.renameTo(renamedFile); + return renamedFile; + } +} + + + + diff --git a/cps/cps-ri/pom.xml b/cps/cps-ri/pom.xml index 0d6dcace4..781f8e832 100644 --- a/cps/cps-ri/pom.xml +++ b/cps/cps-ri/pom.xml @@ -1,43 +1,48 @@ - 4.0.0 - - org.onap.cps - cps - 0.0.1-SNAPSHOT - - cps-ri - - - - - org.onap.cps - cps-service - ${project.version} - compile - - - - org.springframework.boot - spring-boot-starter-data-jpa - - - - org.springframework.boot - spring-boot-starter-validation - - - - org.mariadb.jdbc - mariadb-java-client - - - - org.projectlombok - lombok - - - + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> + 4.0.0 + + org.onap.cps + cps + 0.0.1-SNAPSHOT + + cps-ri + + + + + org.onap.cps + cps-service + ${project.version} + + + + org.springframework.boot + spring-boot-starter-data-jpa + + + + org.springframework.boot + spring-boot-starter-validation + + + + org.mariadb.jdbc + mariadb-java-client + + + + org.projectlombok + lombok + + + + + jakarta.persistence + jakarta.persistence-api + + + \ No newline at end of file diff --git a/cps/cps-ri/src/main/java/org/onap/cps/spi/dummy.txt b/cps/cps-ri/src/main/java/org/onap/cps/spi/dummy.txt deleted file mode 100644 index ff2b9f30c..000000000 --- a/cps/cps-ri/src/main/java/org/onap/cps/spi/dummy.txt +++ /dev/null @@ -1 +0,0 @@ -Have a good day ! \ No newline at end of file diff --git a/cps/cps-ri/src/main/java/org/onap/cps/spi/impl/ModelPersistencyServiceImpl.java b/cps/cps-ri/src/main/java/org/onap/cps/spi/impl/ModelPersistencyServiceImpl.java new file mode 100644 index 000000000..6e718c8c6 --- /dev/null +++ b/cps/cps-ri/src/main/java/org/onap/cps/spi/impl/ModelPersistencyServiceImpl.java @@ -0,0 +1,46 @@ +/* + * ============LICENSE_START======================================================= + * Copyright (C) 2020 Nordix Foundation + * ================================================================================ + * 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.spi.impl; + + +import org.onap.cps.spi.impl.entities.ModuleEntity; +import org.onap.cps.spi.ModelPersistencyService; +import org.onap.cps.spi.repository.ModuleRepository; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +@Component +public class ModelPersistencyServiceImpl implements ModelPersistencyService { + + + private final ModuleRepository moduleRepository; + + @Autowired + public ModelPersistencyServiceImpl(final ModuleRepository moduleRepository) { + this.moduleRepository = moduleRepository; + } + + @Override + public void storeModule(final String name, final String moduleContent, final String revision) { + final ModuleEntity moduleEntity = new ModuleEntity(name, moduleContent, revision); + moduleRepository.save(moduleEntity); + + } +} diff --git a/cps/cps-ri/src/main/java/org/onap/cps/spi/impl/entities/ModuleEntity.java b/cps/cps-ri/src/main/java/org/onap/cps/spi/impl/entities/ModuleEntity.java new file mode 100644 index 000000000..be3dfefef --- /dev/null +++ b/cps/cps-ri/src/main/java/org/onap/cps/spi/impl/entities/ModuleEntity.java @@ -0,0 +1,63 @@ +/* + * ============LICENSE_START======================================================= + * Copyright (C) 2020 Nordix Foundation + * ================================================================================ + * 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.spi.impl.entities; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.Table; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; + + +/** + * Entity to store a yang module. + */ +@Getter +@Setter +@Entity +@AllArgsConstructor +@NoArgsConstructor +@Table(name = "modules") +public class ModuleEntity { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Integer id; + + @Column + private String name; + + @Column + private String moduleContent; + + @Column + private String revision; + + public ModuleEntity(String name, String moduleContent, String revision) { + this.name = name; + this.moduleContent = moduleContent; + this.revision = revision; + } +} \ No newline at end of file diff --git a/cps/cps-ri/src/main/java/org/onap/cps/spi/repository/ModuleRepository.java b/cps/cps-ri/src/main/java/org/onap/cps/spi/repository/ModuleRepository.java new file mode 100644 index 000000000..84441cbf7 --- /dev/null +++ b/cps/cps-ri/src/main/java/org/onap/cps/spi/repository/ModuleRepository.java @@ -0,0 +1,30 @@ +/* + * ============LICENSE_START======================================================= + * Copyright (C) 2020 Nordix Foundation + * ================================================================================ + * 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.spi.repository; + + +import org.onap.cps.spi.impl.entities.ModuleEntity; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; + +@Repository +public interface ModuleRepository extends JpaRepository { + +} \ No newline at end of file diff --git a/cps/cps-service/pom.xml b/cps/cps-service/pom.xml index a0bf49767..844539410 100644 --- a/cps/cps-service/pom.xml +++ b/cps/cps-service/pom.xml @@ -1,4 +1,6 @@ - + 4.0.0 org.onap.cps @@ -7,36 +9,49 @@ cps-service - - 5.0.5 - - - - org.opendaylight.yangtools - yang-parser-api - ${org.opendaylight.yangtools.version} - - - - org.opendaylight.yangtools - yang-parser-impl - ${org.opendaylight.yangtools.version} - - - - org.opendaylight.yangtools - yang-model-util - ${org.opendaylight.yangtools.version} - - - - org.opendaylight.yangtools - yang-data-codec-xml - ${org.opendaylight.yangtools.version} - - - + + org.opendaylight.yangtools + yang-parser-api + ${org.opendaylight.yangtools.version} + + + + org.opendaylight.yangtools + yang-parser-impl + ${org.opendaylight.yangtools.version} + + + + org.opendaylight.yangtools + yang-model-util + ${org.opendaylight.yangtools.version} + + + + org.opendaylight.yangtools + yang-data-codec-xml + ${org.opendaylight.yangtools.version} + + + + org.projectlombok + lombok + + + + + org.slf4j + slf4j-api + + + + + org.springframework + spring-context + + + \ No newline at end of file diff --git a/cps/cps-service/src/main/java/org/onap/cps/api/CPService.java b/cps/cps-service/src/main/java/org/onap/cps/api/CPService.java new file mode 100644 index 000000000..51622c3b0 --- /dev/null +++ b/cps/cps-service/src/main/java/org/onap/cps/api/CPService.java @@ -0,0 +1,55 @@ +/* + * ============LICENSE_START======================================================= + * Copyright (C) 2020 Nordix Foundation + * ================================================================================ + * 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.api; + +import java.io.File; +import java.io.IOException; +import org.opendaylight.yangtools.yang.model.api.SchemaContext; +import org.opendaylight.yangtools.yang.model.parser.api.YangParserException; + +/** + * Configuration and persistency service interface which holds methods for parsing and storing yang models and data. + */ +public interface CPService { + + /** + * Parse and validate a string representing a yang model to generate a schema context. + * + * @param yangModelContent the input stream + * @return the schema context + */ + SchemaContext parseAndValidateModel(final String yangModelContent) throws IOException, YangParserException; + + /** + * Parse and validate a file representing a yang model to generate a schema context. + * + * @param yangModelFile the yang file + * @return the schema context + */ + SchemaContext parseAndValidateModel(final File yangModelFile) throws IOException, YangParserException; + + /** + * Store schema context for a yang model. + * + * @param schemaContext the schema context + */ + void storeSchemaContext(final SchemaContext schemaContext); + +} diff --git a/cps/cps-service/src/main/java/org/onap/cps/api/dummy.txt b/cps/cps-service/src/main/java/org/onap/cps/api/dummy.txt deleted file mode 100644 index ff2b9f30c..000000000 --- a/cps/cps-service/src/main/java/org/onap/cps/api/dummy.txt +++ /dev/null @@ -1 +0,0 @@ -Have a good day ! \ No newline at end of file diff --git a/cps/cps-service/src/main/java/org/onap/cps/api/impl/CPServiceImpl.java b/cps/cps-service/src/main/java/org/onap/cps/api/impl/CPServiceImpl.java new file mode 100644 index 000000000..5bd6e4490 --- /dev/null +++ b/cps/cps-service/src/main/java/org/onap/cps/api/impl/CPServiceImpl.java @@ -0,0 +1,89 @@ +/* + * ============LICENSE_START======================================================= + * Copyright (C) 2020 Nordix Foundation + * ================================================================================ + * 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.api.impl; + + +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; +import java.util.Iterator; +import java.util.ServiceLoader; +import org.onap.cps.api.CPService; +import org.onap.cps.spi.ModelPersistencyService; +import org.opendaylight.yangtools.yang.model.api.Module; +import org.opendaylight.yangtools.yang.model.api.SchemaContext; +import org.opendaylight.yangtools.yang.model.parser.api.YangParser; +import org.opendaylight.yangtools.yang.model.parser.api.YangParserException; +import org.opendaylight.yangtools.yang.model.parser.api.YangParserFactory; +import org.opendaylight.yangtools.yang.model.repo.api.StatementParserMode; +import org.opendaylight.yangtools.yang.model.repo.api.YangTextSchemaSource; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +@Component +public class CPServiceImpl implements CPService { + + private final static Logger LOGGER = LoggerFactory.getLogger(CPServiceImpl.class); + + private static final YangParserFactory PARSER_FACTORY; + + static { + final Iterator it = + ServiceLoader.load(YangParserFactory.class).iterator(); + if (!it.hasNext()) { + throw new IllegalStateException("No YangParserFactory found"); + } + PARSER_FACTORY = it.next(); + } + + @Autowired + private ModelPersistencyService modelPersistencyService; + + @Override + public SchemaContext parseAndValidateModel(final String yangModelContent) + throws IOException, YangParserException { + final File tempFile = File.createTempFile("yang", ".yang"); + try (BufferedWriter writer = new BufferedWriter(new FileWriter(tempFile))) { + writer.write(yangModelContent); + } catch (IOException e) { + LOGGER.error("Unable to write to temporary file {}", e.getMessage()); + } + return parseAndValidateModel(tempFile); + } + + @Override + public SchemaContext parseAndValidateModel(final File yangModelFile) throws IOException, YangParserException { + final YangTextSchemaSource yangTextSchemaSource = YangTextSchemaSource.forFile(yangModelFile); + final YangParser yangParser = PARSER_FACTORY.createParser(StatementParserMode.DEFAULT_MODE); + yangParser.addSource(yangTextSchemaSource); + return yangParser.buildEffectiveModel(); + } + + @Override + public void storeSchemaContext(final SchemaContext schemaContext) { + for (final Module module : schemaContext.getModules()) { + modelPersistencyService.storeModule(module.getName(), module.toString(), + module.getRevision().toString()); + } + } +} diff --git a/cps/cps-service/src/main/java/org/onap/cps/spi/ModelPersistencyService.java b/cps/cps-service/src/main/java/org/onap/cps/spi/ModelPersistencyService.java new file mode 100644 index 000000000..e0286c1b2 --- /dev/null +++ b/cps/cps-service/src/main/java/org/onap/cps/spi/ModelPersistencyService.java @@ -0,0 +1,35 @@ +/* + * ============LICENSE_START======================================================= + * Copyright (C) 2020 Nordix Foundation + * ================================================================================ + * 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.spi; + +/** + * Defines methods to access and manipulate data using the chosen database solution. + */ +public interface ModelPersistencyService { + + /** + * Store the module from a yang model in the database. + * @param name + * @param moduleContent + * @param revision + */ + void storeModule(final String name, final String moduleContent, final String revision); + +} diff --git a/cps/cps-service/src/main/java/org/onap/cps/spi/dummy.txt b/cps/cps-service/src/main/java/org/onap/cps/spi/dummy.txt deleted file mode 100644 index ff2b9f30c..000000000 --- a/cps/cps-service/src/main/java/org/onap/cps/spi/dummy.txt +++ /dev/null @@ -1 +0,0 @@ -Have a good day ! \ No newline at end of file diff --git a/cps/pom.xml b/cps/pom.xml index 94ed29c07..1c1b2b151 100644 --- a/cps/pom.xml +++ b/cps/pom.xml @@ -1,115 +1,114 @@ - 4.0.0 - - org.onap.oparent - oparent - 3.1.0 - - org.onap.cps - cps - 0.0.1-SNAPSHOT - pom - cps - ONAP Configuration and Persistency Service - - ONAP - CPS - http://www.onap.org/ - + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> + 4.0.0 + + org.onap.oparent + oparent + 3.1.0 + + org.onap.cps + cps + 0.0.1-SNAPSHOT + pom + cps + ONAP Configuration and Persistency Service + + ONAP - CPS + http://www.onap.org/ + - - 11 - 2.3.3.RELEASE - 1.6.7 - 3.1.0 - + + 11 + 2.3.3.RELEASE + 3.1.0 + 5.0.5 + - - - - org.springframework.boot - spring-boot-dependencies - ${springboot.version} - pom - import - - - + + + + org.springframework.boot + spring-boot-dependencies + ${springboot.version} + pom + import + + + - - - - src/main/resources - true - + + + + src/main/resources + true + - - target/generated-sources/license - - third-party-licenses.txt - - + + target/generated-sources/license + + third-party-licenses.txt + + - - target/generated-resources/licenses - - *.* - - third-party-licenses - - + + target/generated-resources/licenses + + *.* + + third-party-licenses + + - - - org.apache.maven.plugins - maven-compiler-plugin - - ${version.java.compiler} - ${version.java.compiler} - - + + + org.apache.maven.plugins + maven-compiler-plugin + + ${version.java.compiler} + ${version.java.compiler} + + - - org.apache.maven.plugins - maven-checkstyle-plugin - - - onap-java-style - - check - - process-sources - - onap-checkstyle/onap-java-style.xml - ${project.build.sourceDirectory} - true - true - true - true - warning - true - - - + + org.apache.maven.plugins + maven-checkstyle-plugin + + + onap-java-style + + check + + process-sources + + onap-checkstyle/onap-java-style.xml + ${project.build.sourceDirectory} + true + true + true + true + warning + true + + + - - - org.onap.oparent - checkstyle - ${oparent.version} - compile - - + + + org.onap.oparent + checkstyle + ${oparent.version} + + - - - + + + - - cps-service - cps-rest - cps-ri - + + cps-service + cps-rest + cps-ri + \ No newline at end of file -- cgit 1.2.3-korg From f925587e61afd94d8510420e2c4df886e12cfad5 Mon Sep 17 00:00:00 2001 From: Rishi Chail Date: Mon, 28 Sep 2020 12:30:58 +0100 Subject: IS: Add CheckStyle goal to Maven Issue-ID: CCSDK-2746 https: //jira.onap.org/browse/CCSDK-2746 Change-Id: I0442b62cbecb16c979a43d3d5d68fdb1c62a2276 --- .../onap/cps/rest/controller/RestController.java | 4 +- .../src/main/java/org/onap/cps/api/CPService.java | 55 ------------- .../src/main/java/org/onap/cps/api/CpService.java | 55 +++++++++++++ .../java/org/onap/cps/api/impl/CPServiceImpl.java | 89 ---------------------- .../java/org/onap/cps/api/impl/CpServiceImpl.java | 89 ++++++++++++++++++++++ .../org/onap/cps/spi/ModelPersistencyService.java | 7 +- cps/pom.xml | 6 +- 7 files changed, 153 insertions(+), 152 deletions(-) delete mode 100644 cps/cps-service/src/main/java/org/onap/cps/api/CPService.java create mode 100644 cps/cps-service/src/main/java/org/onap/cps/api/CpService.java delete mode 100644 cps/cps-service/src/main/java/org/onap/cps/api/impl/CPServiceImpl.java create mode 100644 cps/cps-service/src/main/java/org/onap/cps/api/impl/CpServiceImpl.java 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 index d2f1a3e03..dc6411009 100644 --- 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 @@ -29,7 +29,7 @@ import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; import javax.ws.rs.core.Response.Status; import org.glassfish.jersey.media.multipart.FormDataParam; -import org.onap.cps.api.CPService; +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; @@ -39,7 +39,7 @@ import org.springframework.beans.factory.annotation.Autowired; public class RestController { @Autowired - private CPService cpService; + private CpService cpService; @POST @Path("uploadYangFile") diff --git a/cps/cps-service/src/main/java/org/onap/cps/api/CPService.java b/cps/cps-service/src/main/java/org/onap/cps/api/CPService.java deleted file mode 100644 index 51622c3b0..000000000 --- a/cps/cps-service/src/main/java/org/onap/cps/api/CPService.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * ============LICENSE_START======================================================= - * Copyright (C) 2020 Nordix Foundation - * ================================================================================ - * 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.api; - -import java.io.File; -import java.io.IOException; -import org.opendaylight.yangtools.yang.model.api.SchemaContext; -import org.opendaylight.yangtools.yang.model.parser.api.YangParserException; - -/** - * Configuration and persistency service interface which holds methods for parsing and storing yang models and data. - */ -public interface CPService { - - /** - * Parse and validate a string representing a yang model to generate a schema context. - * - * @param yangModelContent the input stream - * @return the schema context - */ - SchemaContext parseAndValidateModel(final String yangModelContent) throws IOException, YangParserException; - - /** - * Parse and validate a file representing a yang model to generate a schema context. - * - * @param yangModelFile the yang file - * @return the schema context - */ - SchemaContext parseAndValidateModel(final File yangModelFile) throws IOException, YangParserException; - - /** - * Store schema context for a yang model. - * - * @param schemaContext the schema context - */ - void storeSchemaContext(final SchemaContext schemaContext); - -} diff --git a/cps/cps-service/src/main/java/org/onap/cps/api/CpService.java b/cps/cps-service/src/main/java/org/onap/cps/api/CpService.java new file mode 100644 index 000000000..a5ab485f6 --- /dev/null +++ b/cps/cps-service/src/main/java/org/onap/cps/api/CpService.java @@ -0,0 +1,55 @@ +/* + * ============LICENSE_START======================================================= + * Copyright (C) 2020 Nordix Foundation + * ================================================================================ + * 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.api; + +import java.io.File; +import java.io.IOException; +import org.opendaylight.yangtools.yang.model.api.SchemaContext; +import org.opendaylight.yangtools.yang.model.parser.api.YangParserException; + +/** + * Configuration and persistency service interface which holds methods for parsing and storing yang models and data. + */ +public interface CpService { + + /** + * Parse and validate a string representing a yang model to generate a schema context. + * + * @param yangModelContent the input stream + * @return the schema context + */ + SchemaContext parseAndValidateModel(final String yangModelContent) throws IOException, YangParserException; + + /** + * Parse and validate a file representing a yang model to generate a schema context. + * + * @param yangModelFile the yang file + * @return the schema context + */ + SchemaContext parseAndValidateModel(final File yangModelFile) throws IOException, YangParserException; + + /** + * Store schema context for a yang model. + * + * @param schemaContext the schema context + */ + void storeSchemaContext(final SchemaContext schemaContext); + +} diff --git a/cps/cps-service/src/main/java/org/onap/cps/api/impl/CPServiceImpl.java b/cps/cps-service/src/main/java/org/onap/cps/api/impl/CPServiceImpl.java deleted file mode 100644 index 5bd6e4490..000000000 --- a/cps/cps-service/src/main/java/org/onap/cps/api/impl/CPServiceImpl.java +++ /dev/null @@ -1,89 +0,0 @@ -/* - * ============LICENSE_START======================================================= - * Copyright (C) 2020 Nordix Foundation - * ================================================================================ - * 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.api.impl; - - -import java.io.BufferedWriter; -import java.io.File; -import java.io.FileWriter; -import java.io.IOException; -import java.util.Iterator; -import java.util.ServiceLoader; -import org.onap.cps.api.CPService; -import org.onap.cps.spi.ModelPersistencyService; -import org.opendaylight.yangtools.yang.model.api.Module; -import org.opendaylight.yangtools.yang.model.api.SchemaContext; -import org.opendaylight.yangtools.yang.model.parser.api.YangParser; -import org.opendaylight.yangtools.yang.model.parser.api.YangParserException; -import org.opendaylight.yangtools.yang.model.parser.api.YangParserFactory; -import org.opendaylight.yangtools.yang.model.repo.api.StatementParserMode; -import org.opendaylight.yangtools.yang.model.repo.api.YangTextSchemaSource; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Component; - -@Component -public class CPServiceImpl implements CPService { - - private final static Logger LOGGER = LoggerFactory.getLogger(CPServiceImpl.class); - - private static final YangParserFactory PARSER_FACTORY; - - static { - final Iterator it = - ServiceLoader.load(YangParserFactory.class).iterator(); - if (!it.hasNext()) { - throw new IllegalStateException("No YangParserFactory found"); - } - PARSER_FACTORY = it.next(); - } - - @Autowired - private ModelPersistencyService modelPersistencyService; - - @Override - public SchemaContext parseAndValidateModel(final String yangModelContent) - throws IOException, YangParserException { - final File tempFile = File.createTempFile("yang", ".yang"); - try (BufferedWriter writer = new BufferedWriter(new FileWriter(tempFile))) { - writer.write(yangModelContent); - } catch (IOException e) { - LOGGER.error("Unable to write to temporary file {}", e.getMessage()); - } - return parseAndValidateModel(tempFile); - } - - @Override - public SchemaContext parseAndValidateModel(final File yangModelFile) throws IOException, YangParserException { - final YangTextSchemaSource yangTextSchemaSource = YangTextSchemaSource.forFile(yangModelFile); - final YangParser yangParser = PARSER_FACTORY.createParser(StatementParserMode.DEFAULT_MODE); - yangParser.addSource(yangTextSchemaSource); - return yangParser.buildEffectiveModel(); - } - - @Override - public void storeSchemaContext(final SchemaContext schemaContext) { - for (final Module module : schemaContext.getModules()) { - modelPersistencyService.storeModule(module.getName(), module.toString(), - module.getRevision().toString()); - } - } -} diff --git a/cps/cps-service/src/main/java/org/onap/cps/api/impl/CpServiceImpl.java b/cps/cps-service/src/main/java/org/onap/cps/api/impl/CpServiceImpl.java new file mode 100644 index 000000000..b71e4714b --- /dev/null +++ b/cps/cps-service/src/main/java/org/onap/cps/api/impl/CpServiceImpl.java @@ -0,0 +1,89 @@ +/* + * ============LICENSE_START======================================================= + * Copyright (C) 2020 Nordix Foundation + * ================================================================================ + * 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.api.impl; + + +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; +import java.util.Iterator; +import java.util.ServiceLoader; +import org.onap.cps.api.CpService; +import org.onap.cps.spi.ModelPersistencyService; +import org.opendaylight.yangtools.yang.model.api.Module; +import org.opendaylight.yangtools.yang.model.api.SchemaContext; +import org.opendaylight.yangtools.yang.model.parser.api.YangParser; +import org.opendaylight.yangtools.yang.model.parser.api.YangParserException; +import org.opendaylight.yangtools.yang.model.parser.api.YangParserFactory; +import org.opendaylight.yangtools.yang.model.repo.api.StatementParserMode; +import org.opendaylight.yangtools.yang.model.repo.api.YangTextSchemaSource; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +@Component +public class CpServiceImpl implements CpService { + + private static final Logger LOGGER = LoggerFactory.getLogger(CpServiceImpl.class); + + private static final YangParserFactory PARSER_FACTORY; + + static { + final Iterator it = + ServiceLoader.load(YangParserFactory.class).iterator(); + if (!it.hasNext()) { + throw new IllegalStateException("No YangParserFactory found"); + } + PARSER_FACTORY = it.next(); + } + + @Autowired + private ModelPersistencyService modelPersistencyService; + + @Override + public SchemaContext parseAndValidateModel(final String yangModelContent) + throws IOException, YangParserException { + final File tempFile = File.createTempFile("yang", ".yang"); + try (BufferedWriter writer = new BufferedWriter(new FileWriter(tempFile))) { + writer.write(yangModelContent); + } catch (final IOException e) { + LOGGER.error("Unable to write to temporary file {}", e.getMessage()); + } + return parseAndValidateModel(tempFile); + } + + @Override + public SchemaContext parseAndValidateModel(final File yangModelFile) throws IOException, YangParserException { + final YangTextSchemaSource yangTextSchemaSource = YangTextSchemaSource.forFile(yangModelFile); + final YangParser yangParser = PARSER_FACTORY.createParser(StatementParserMode.DEFAULT_MODE); + yangParser.addSource(yangTextSchemaSource); + return yangParser.buildEffectiveModel(); + } + + @Override + public void storeSchemaContext(final SchemaContext schemaContext) { + for (final Module module : schemaContext.getModules()) { + modelPersistencyService.storeModule(module.getName(), module.toString(), + module.getRevision().toString()); + } + } +} diff --git a/cps/cps-service/src/main/java/org/onap/cps/spi/ModelPersistencyService.java b/cps/cps-service/src/main/java/org/onap/cps/spi/ModelPersistencyService.java index e0286c1b2..f88c6b241 100644 --- a/cps/cps-service/src/main/java/org/onap/cps/spi/ModelPersistencyService.java +++ b/cps/cps-service/src/main/java/org/onap/cps/spi/ModelPersistencyService.java @@ -26,9 +26,10 @@ public interface ModelPersistencyService { /** * Store the module from a yang model in the database. - * @param name - * @param moduleContent - * @param revision + * + * @param name module name + * @param moduleContent module content + * @param revision module revision */ void storeModule(final String name, final String moduleContent, final String revision); diff --git a/cps/pom.xml b/cps/pom.xml index 1c1b2b151..7f50cb143 100644 --- a/cps/pom.xml +++ b/cps/pom.xml @@ -86,9 +86,9 @@ true true true - true + false warning - true + true @@ -111,4 +111,4 @@ cps-ri - \ No newline at end of file + -- cgit 1.2.3-korg From 6612c79168d699190044ab1950400061c85d1be7 Mon Sep 17 00:00:00 2001 From: niamhcore Date: Fri, 25 Sep 2020 14:53:25 +0100 Subject: Store and Validate a JSON Object Issue-ID: CCSDK-2757 Jira Link: https://jira.onap.org/browse/CCSDK-2757 Change-Id: Icfdbaec1a853ba5ba4a22742fb3091fc71a11d71 Change-Id: I80777bb2692e6e7f7594f787ec480817e8df0a35 --- .../onap/cps/rest/controller/RestController.java | 50 ++++++++++++++-- .../org/onap/cps/spi/entities/JsonDataEntity.java | 54 +++++++++++++++++ .../org/onap/cps/spi/entities/ModuleEntity.java | 70 ++++++++++++++++++++++ .../cps/spi/impl/DataPersistencyServiceImpl.java | 46 ++++++++++++++ .../cps/spi/impl/ModelPersistencyServiceImpl.java | 3 +- .../onap/cps/spi/impl/entities/ModuleEntity.java | 63 ------------------- .../onap/cps/spi/repository/DataRepository.java | 28 +++++++++ .../onap/cps/spi/repository/ModuleRepository.java | 2 +- cps/cps-service/pom.xml | 6 ++ .../src/main/java/org/onap/cps/api/CpService.java | 7 +++ .../java/org/onap/cps/api/impl/CpServiceImpl.java | 17 +++++- .../org/onap/cps/spi/DataPersistencyService.java | 34 +++++++++++ 12 files changed, 305 insertions(+), 75 deletions(-) create mode 100644 cps/cps-ri/src/main/java/org/onap/cps/spi/entities/JsonDataEntity.java create mode 100644 cps/cps-ri/src/main/java/org/onap/cps/spi/entities/ModuleEntity.java create mode 100644 cps/cps-ri/src/main/java/org/onap/cps/spi/impl/DataPersistencyServiceImpl.java delete mode 100644 cps/cps-ri/src/main/java/org/onap/cps/spi/impl/entities/ModuleEntity.java create mode 100644 cps/cps-ri/src/main/java/org/onap/cps/spi/repository/DataRepository.java create mode 100644 cps/cps-service/src/main/java/org/onap/cps/spi/DataPersistencyService.java 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 index dc6411009..a64cd6a04 100644 --- 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 @@ -19,6 +19,8 @@ package org.onap.cps.rest.controller; +import com.google.gson.Gson; +import com.google.gson.JsonSyntaxException; import java.io.File; import java.io.IOException; import javax.ws.rs.Consumes; @@ -41,26 +43,62 @@ public class RestController { @Autowired private CpService cpService; + /** + * Upload a yang model file. + * + * @param uploadedFile the yang model file. + * @return a http response code. + */ @POST - @Path("uploadYangFile") + @Path("upload-yang-model-file") @Produces(MediaType.APPLICATION_JSON) @Consumes(MediaType.MULTIPART_FORM_DATA) - public Response uploadFile(@FormDataParam("file") File uploadedFile) throws IOException { + public final Response uploadYangModelFile(@FormDataParam("file") File uploadedFile) throws IOException { try { - File fileToParse = renameFileIfNeeded(uploadedFile); - SchemaContext schemaContext = cpService.parseAndValidateModel(fileToParse); + final File fileToParse = renameFileIfNeeded(uploadedFile); + final SchemaContext schemaContext = cpService.parseAndValidateModel(fileToParse); cpService.storeSchemaContext(schemaContext); return Response.status(Status.OK).entity("Yang File Parsed").build(); } catch (YangParserException e) { return Response.status(Status.BAD_REQUEST).entity(e.getMessage()).build(); + } catch (Exception e) { + return Response.status(Status.INTERNAL_SERVER_ERROR).entity(e.getMessage()).build(); } } - private static File renameFileIfNeeded(File originalFile) { + /** + * 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") 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 (JsonSyntaxException e) { + return Response.status(Status.BAD_REQUEST).entity(e.getMessage()).build(); + } catch (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(File originalFile) { if (originalFile.getName().endsWith(".yang")) { return originalFile; } - File renamedFile = new File(originalFile.getName() + ".yang"); + final File renamedFile = new File(originalFile.getName() + ".yang"); originalFile.renameTo(renamedFile); return renamedFile; } diff --git a/cps/cps-ri/src/main/java/org/onap/cps/spi/entities/JsonDataEntity.java b/cps/cps-ri/src/main/java/org/onap/cps/spi/entities/JsonDataEntity.java new file mode 100644 index 000000000..413362e38 --- /dev/null +++ b/cps/cps-ri/src/main/java/org/onap/cps/spi/entities/JsonDataEntity.java @@ -0,0 +1,54 @@ +/* + * ============LICENSE_START======================================================= + * Copyright (C) 2020 Nordix Foundation + * ================================================================================ + * 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.spi.entities; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.Table; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; + +/** + * Entity to store a JSON data structure. + */ +@Getter +@Setter +@Entity +@AllArgsConstructor +@NoArgsConstructor +@Table(name = "JsonData") +public class JsonDataEntity { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Integer id; + + @Column + private String jsonStructure; + + public JsonDataEntity(String jsonStructure) { + this.jsonStructure = jsonStructure; + } +} diff --git a/cps/cps-ri/src/main/java/org/onap/cps/spi/entities/ModuleEntity.java b/cps/cps-ri/src/main/java/org/onap/cps/spi/entities/ModuleEntity.java new file mode 100644 index 000000000..f786c58f1 --- /dev/null +++ b/cps/cps-ri/src/main/java/org/onap/cps/spi/entities/ModuleEntity.java @@ -0,0 +1,70 @@ +/* + * ============LICENSE_START======================================================= + * Copyright (C) 2020 Nordix Foundation + * ================================================================================ + * 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.spi.entities; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.Table; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; + + +/** + * Entity to store a yang module. + */ +@Getter +@Setter +@Entity +@AllArgsConstructor +@NoArgsConstructor +@Table(name = "modules") +public class ModuleEntity { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Integer id; + + @Column + private String name; + + @Column + private String moduleContent; + + @Column + private String revision; + + /** + * Initialize a module entity. + * + * @param name the module name. + * @param moduleContent the module content. + * @param revision the revision number of the module. + */ + public ModuleEntity(String name, String moduleContent, String revision) { + this.name = name; + this.moduleContent = moduleContent; + this.revision = revision; + } +} \ No newline at end of file diff --git a/cps/cps-ri/src/main/java/org/onap/cps/spi/impl/DataPersistencyServiceImpl.java b/cps/cps-ri/src/main/java/org/onap/cps/spi/impl/DataPersistencyServiceImpl.java new file mode 100644 index 000000000..93746e06f --- /dev/null +++ b/cps/cps-ri/src/main/java/org/onap/cps/spi/impl/DataPersistencyServiceImpl.java @@ -0,0 +1,46 @@ +/* + * ============LICENSE_START======================================================= + * Copyright (C) 2020 Nordix Foundation + * ================================================================================ + * 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.spi.impl; + +import org.onap.cps.spi.DataPersistencyService; +import org.onap.cps.spi.entities.JsonDataEntity; +import org.onap.cps.spi.repository.DataRepository; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + + +@Component +public class DataPersistencyServiceImpl implements DataPersistencyService { + + @Autowired + private DataRepository dataRepository; + + /** + * Method to store a JSON data structure in the database. + * + * @param jsonStructure the JSON data structure. + * @return + */ + public final Integer storeJsonStructure(final String jsonStructure) { + final JsonDataEntity jsonDataEntity = new JsonDataEntity(jsonStructure); + dataRepository.save(jsonDataEntity); + return jsonDataEntity.getId(); + } +} diff --git a/cps/cps-ri/src/main/java/org/onap/cps/spi/impl/ModelPersistencyServiceImpl.java b/cps/cps-ri/src/main/java/org/onap/cps/spi/impl/ModelPersistencyServiceImpl.java index 6e718c8c6..14085c7cf 100644 --- a/cps/cps-ri/src/main/java/org/onap/cps/spi/impl/ModelPersistencyServiceImpl.java +++ b/cps/cps-ri/src/main/java/org/onap/cps/spi/impl/ModelPersistencyServiceImpl.java @@ -19,9 +19,8 @@ package org.onap.cps.spi.impl; - -import org.onap.cps.spi.impl.entities.ModuleEntity; import org.onap.cps.spi.ModelPersistencyService; +import org.onap.cps.spi.entities.ModuleEntity; import org.onap.cps.spi.repository.ModuleRepository; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; diff --git a/cps/cps-ri/src/main/java/org/onap/cps/spi/impl/entities/ModuleEntity.java b/cps/cps-ri/src/main/java/org/onap/cps/spi/impl/entities/ModuleEntity.java deleted file mode 100644 index be3dfefef..000000000 --- a/cps/cps-ri/src/main/java/org/onap/cps/spi/impl/entities/ModuleEntity.java +++ /dev/null @@ -1,63 +0,0 @@ -/* - * ============LICENSE_START======================================================= - * Copyright (C) 2020 Nordix Foundation - * ================================================================================ - * 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.spi.impl.entities; - -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; -import javax.persistence.Id; -import javax.persistence.Table; -import lombok.AllArgsConstructor; -import lombok.Getter; -import lombok.NoArgsConstructor; -import lombok.Setter; - - -/** - * Entity to store a yang module. - */ -@Getter -@Setter -@Entity -@AllArgsConstructor -@NoArgsConstructor -@Table(name = "modules") -public class ModuleEntity { - - @Id - @GeneratedValue(strategy = GenerationType.IDENTITY) - private Integer id; - - @Column - private String name; - - @Column - private String moduleContent; - - @Column - private String revision; - - public ModuleEntity(String name, String moduleContent, String revision) { - this.name = name; - this.moduleContent = moduleContent; - this.revision = revision; - } -} \ No newline at end of file diff --git a/cps/cps-ri/src/main/java/org/onap/cps/spi/repository/DataRepository.java b/cps/cps-ri/src/main/java/org/onap/cps/spi/repository/DataRepository.java new file mode 100644 index 000000000..f3dd58600 --- /dev/null +++ b/cps/cps-ri/src/main/java/org/onap/cps/spi/repository/DataRepository.java @@ -0,0 +1,28 @@ +/* + * ============LICENSE_START======================================================= + * Copyright (C) 2020 Nordix Foundation + * ================================================================================ + * 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.spi.repository; + +import org.onap.cps.spi.entities.JsonDataEntity; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; + +@Repository +public interface DataRepository extends JpaRepository { +} \ No newline at end of file diff --git a/cps/cps-ri/src/main/java/org/onap/cps/spi/repository/ModuleRepository.java b/cps/cps-ri/src/main/java/org/onap/cps/spi/repository/ModuleRepository.java index 84441cbf7..0fe53b621 100644 --- a/cps/cps-ri/src/main/java/org/onap/cps/spi/repository/ModuleRepository.java +++ b/cps/cps-ri/src/main/java/org/onap/cps/spi/repository/ModuleRepository.java @@ -20,7 +20,7 @@ package org.onap.cps.spi.repository; -import org.onap.cps.spi.impl.entities.ModuleEntity; +import org.onap.cps.spi.entities.ModuleEntity; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.stereotype.Repository; diff --git a/cps/cps-service/pom.xml b/cps/cps-service/pom.xml index 844539410..e0d7ebd8e 100644 --- a/cps/cps-service/pom.xml +++ b/cps/cps-service/pom.xml @@ -52,6 +52,12 @@ spring-context + + + com.google.code.gson + gson + + \ No newline at end of file diff --git a/cps/cps-service/src/main/java/org/onap/cps/api/CpService.java b/cps/cps-service/src/main/java/org/onap/cps/api/CpService.java index a5ab485f6..cdd1c4dca 100644 --- a/cps/cps-service/src/main/java/org/onap/cps/api/CpService.java +++ b/cps/cps-service/src/main/java/org/onap/cps/api/CpService.java @@ -52,4 +52,11 @@ public interface CpService { */ void storeSchemaContext(final SchemaContext schemaContext); + /** + * Store the JSON structure in the database. + * + * @param jsonStructure the JSON structure. + * @return entity ID. + */ + Integer storeJsonStructure(final String jsonStructure); } diff --git a/cps/cps-service/src/main/java/org/onap/cps/api/impl/CpServiceImpl.java b/cps/cps-service/src/main/java/org/onap/cps/api/impl/CpServiceImpl.java index b71e4714b..8d6b63bd5 100644 --- a/cps/cps-service/src/main/java/org/onap/cps/api/impl/CpServiceImpl.java +++ b/cps/cps-service/src/main/java/org/onap/cps/api/impl/CpServiceImpl.java @@ -27,6 +27,7 @@ import java.io.IOException; import java.util.Iterator; import java.util.ServiceLoader; import org.onap.cps.api.CpService; +import org.onap.cps.spi.DataPersistencyService; import org.onap.cps.spi.ModelPersistencyService; import org.opendaylight.yangtools.yang.model.api.Module; import org.opendaylight.yangtools.yang.model.api.SchemaContext; @@ -40,6 +41,7 @@ import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; + @Component public class CpServiceImpl implements CpService { @@ -59,8 +61,12 @@ public class CpServiceImpl implements CpService { @Autowired private ModelPersistencyService modelPersistencyService; + @Autowired + private DataPersistencyService dataPersistencyService; + + @Override - public SchemaContext parseAndValidateModel(final String yangModelContent) + public final SchemaContext parseAndValidateModel(final String yangModelContent) throws IOException, YangParserException { final File tempFile = File.createTempFile("yang", ".yang"); try (BufferedWriter writer = new BufferedWriter(new FileWriter(tempFile))) { @@ -72,7 +78,7 @@ public class CpServiceImpl implements CpService { } @Override - public SchemaContext parseAndValidateModel(final File yangModelFile) throws IOException, YangParserException { + public final SchemaContext parseAndValidateModel(final File yangModelFile) throws IOException, YangParserException { final YangTextSchemaSource yangTextSchemaSource = YangTextSchemaSource.forFile(yangModelFile); final YangParser yangParser = PARSER_FACTORY.createParser(StatementParserMode.DEFAULT_MODE); yangParser.addSource(yangTextSchemaSource); @@ -80,7 +86,12 @@ public class CpServiceImpl implements CpService { } @Override - public void storeSchemaContext(final SchemaContext schemaContext) { + public final Integer storeJsonStructure(final String jsonStructure) { + return dataPersistencyService.storeJsonStructure(jsonStructure); + } + + @Override + public final void storeSchemaContext(final SchemaContext schemaContext) { for (final Module module : schemaContext.getModules()) { modelPersistencyService.storeModule(module.getName(), module.toString(), module.getRevision().toString()); diff --git a/cps/cps-service/src/main/java/org/onap/cps/spi/DataPersistencyService.java b/cps/cps-service/src/main/java/org/onap/cps/spi/DataPersistencyService.java new file mode 100644 index 000000000..4dcd31d95 --- /dev/null +++ b/cps/cps-service/src/main/java/org/onap/cps/spi/DataPersistencyService.java @@ -0,0 +1,34 @@ +/* + * ============LICENSE_START======================================================= + * Copyright (C) 2020 Nordix Foundation + * ================================================================================ + * 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.spi; + +/** + * Defines methods to access and manipulate data using the chosen database solution. + */ +public interface DataPersistencyService { + + /** + * Store the JSON structure in the database. + * + * @param jsonStructure the JSON structure. + * @return jsonEntityID the ID of the JSON entity. + */ + Integer storeJsonStructure(final String jsonStructure); +} -- cgit 1.2.3-korg From dce3695032ff3320fc7bfee46c4e36fde6d98883 Mon Sep 17 00:00:00 2001 From: ToineSiebelink Date: Wed, 30 Sep 2020 16:11:55 +0100 Subject: Set up Groovy & Spock Test Framework Add basic first test (CpServiceImplSpec) for illustartion purposes Issue-ID: CCSDK-2786 Jira Link: https://jira.onap.org/browse/CCSDK-2786 Change-Id: Ibda81289fb5c9a57474f242e26847b8464dc6b59 --- cps/cps-service/pom.xml | 25 +++++++++++++++-- .../org/onap/cps/api/impl/CpServiceImplSpec.groovy | 27 ++++++++++++++++++ cps/pom.xml | 32 ++++++++++++++++++++++ 3 files changed, 82 insertions(+), 2 deletions(-) create mode 100644 cps/cps-service/src/test/groovy/org/onap/cps/api/impl/CpServiceImplSpec.groovy diff --git a/cps/cps-service/pom.xml b/cps/cps-service/pom.xml index e0d7ebd8e..a59376c20 100644 --- a/cps/cps-service/pom.xml +++ b/cps/cps-service/pom.xml @@ -30,8 +30,9 @@ + org.opendaylight.yangtools - yang-data-codec-xml + yang-data-codec-gson ${org.opendaylight.yangtools.version} @@ -58,6 +59,26 @@ gson + + + + org.codehaus.groovy + groovy + ${version.groovy} + test + + + org.spockframework + spock-core + ${version.spock-core} + test + + + cglib + cglib-nodep + 3.1 + test + - \ No newline at end of file + diff --git a/cps/cps-service/src/test/groovy/org/onap/cps/api/impl/CpServiceImplSpec.groovy b/cps/cps-service/src/test/groovy/org/onap/cps/api/impl/CpServiceImplSpec.groovy new file mode 100644 index 000000000..27f748211 --- /dev/null +++ b/cps/cps-service/src/test/groovy/org/onap/cps/api/impl/CpServiceImplSpec.groovy @@ -0,0 +1,27 @@ +package org.onap.cps.api.impl + +import org.onap.cps.spi.DataPersistencyService +import spock.lang.Specification; + + +class CpServiceImplSpec extends Specification { + + def dataPersistencyService = Mock(DataPersistencyService) + def objectUnderTest = new CpServiceImpl() + + def setup() { + // Insert mocked dependencies + objectUnderTest.dataPersistencyService = dataPersistencyService; + } + + def 'Storing a json object'() { + given: 'that the data persistency service returns an id of 123' + dataPersistencyService.storeJsonStructure(_) >> 123 + + when: 'a json structure is stored using the data persistency service' + def result = objectUnderTest.storeJsonStructure('') + + then: ' the same id is returned' + result == 123 + } +} diff --git a/cps/pom.xml b/cps/pom.xml index 7f50cb143..5435c4a4a 100644 --- a/cps/pom.xml +++ b/cps/pom.xml @@ -23,6 +23,8 @@ 2.3.3.RELEASE 3.1.0 5.0.5 + 3.0.6 + 2.0-M2-groovy-3.0 @@ -102,6 +104,36 @@ + + + + + org.codehaus.gmavenplus + gmavenplus-plugin + 1.9.0 + + + + compileTests + + + + + + + org.apache.maven.plugins + maven-surefire-plugin + 3.0.0-M5 + + false + + **/*Spec.java + **/*Test.java + + + + -- cgit 1.2.3-korg From 5654561386856a7816a7f4e00cef746bc2facedc Mon Sep 17 00:00:00 2001 From: Bruno Sakoto Date: Thu, 1 Oct 2020 23:47:01 -0400 Subject: Introduce swagger configuration Issue-ID: CCSDK-2754 Change-Id: I22bd50431ad24202dc84dd982bf7e7d2388ee981 Signed-off-by: Bruno Sakoto --- cps/cps-rest/pom.xml | 16 +++++++++ .../org/onap/cps/rest/config/SpringFoxConfig.java | 38 ++++++++++++++++++++++ .../onap/cps/rest/controller/RestController.java | 14 ++++++++ 3 files changed, 68 insertions(+) create mode 100644 cps/cps-rest/src/main/java/org/onap/cps/rest/config/SpringFoxConfig.java diff --git a/cps/cps-rest/pom.xml b/cps/cps-rest/pom.xml index bd9be8dfd..253c29c51 100644 --- a/cps/cps-rest/pom.xml +++ b/cps/cps-rest/pom.xml @@ -44,6 +44,22 @@ spring-boot-starter-jetty + + org.springframework.boot + spring-boot-starter-web + + + + io.springfox + springfox-swagger2 + 2.9.2 + + + + io.springfox + springfox-swagger-ui + 2.9.2 + org.springframework.boot diff --git a/cps/cps-rest/src/main/java/org/onap/cps/rest/config/SpringFoxConfig.java b/cps/cps-rest/src/main/java/org/onap/cps/rest/config/SpringFoxConfig.java new file mode 100644 index 000000000..3a9e53947 --- /dev/null +++ b/cps/cps-rest/src/main/java/org/onap/cps/rest/config/SpringFoxConfig.java @@ -0,0 +1,38 @@ +package org.onap.cps.rest.config; + + +import static springfox.documentation.builders.PathSelectors.regex; + +import com.google.common.base.Predicate; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import springfox.documentation.builders.RequestHandlerSelectors; +import springfox.documentation.spi.DocumentationType; +import springfox.documentation.spring.web.plugins.Docket; +import springfox.documentation.swagger2.annotations.EnableSwagger2; + +/** + * Swagger configuration. + */ +@Configuration +@EnableSwagger2 +public class SpringFoxConfig { + + /** + * Define api configuration. + */ + @Bean + public Docket api() { + return new Docket(DocumentationType.SWAGGER_2) + .select() + .apis(RequestHandlerSelectors.any()) + .paths(paths()) + .build(); + } + + private Predicate paths() { + return regex("/model.*"); + } + +} + 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 index a64cd6a04..9b7c0008e 100644 --- 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 @@ -23,6 +23,7 @@ import com.google.gson.Gson; import com.google.gson.JsonSyntaxException; import java.io.File; import java.io.IOException; +import java.util.UUID; import javax.ws.rs.Consumes; import javax.ws.rs.POST; import javax.ws.rs.Path; @@ -35,9 +36,15 @@ 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.http.HttpStatus; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.ResponseStatus; +import org.springframework.web.multipart.MultipartFile; @Path("cps") +@org.springframework.web.bind.annotation.RestController public class RestController { @Autowired @@ -66,6 +73,13 @@ public class RestController { } } + @PostMapping("/model") + @ResponseStatus(HttpStatus.CREATED) + public String addModel(@RequestParam("file") MultipartFile file) { + // Store and return a model dto ... + return UUID.randomUUID() + " : " + file.getOriginalFilename(); + } + /** * Upload a JSON file. * -- cgit 1.2.3-korg From f244c9cff733fe756177f3d33f7624977b660f5f Mon Sep 17 00:00:00 2001 From: Bruno Sakoto Date: Fri, 2 Oct 2020 00:08:27 -0400 Subject: Revert "Introduce swagger configuration" This reverts commit 0cc57ba05cc474007c91589242bfe7fc8afa9946. --- cps/cps-rest/pom.xml | 16 --------- .../org/onap/cps/rest/config/SpringFoxConfig.java | 38 ---------------------- .../onap/cps/rest/controller/RestController.java | 14 -------- 3 files changed, 68 deletions(-) delete mode 100644 cps/cps-rest/src/main/java/org/onap/cps/rest/config/SpringFoxConfig.java diff --git a/cps/cps-rest/pom.xml b/cps/cps-rest/pom.xml index 253c29c51..bd9be8dfd 100644 --- a/cps/cps-rest/pom.xml +++ b/cps/cps-rest/pom.xml @@ -44,22 +44,6 @@ spring-boot-starter-jetty - - org.springframework.boot - spring-boot-starter-web - - - - io.springfox - springfox-swagger2 - 2.9.2 - - - - io.springfox - springfox-swagger-ui - 2.9.2 - org.springframework.boot diff --git a/cps/cps-rest/src/main/java/org/onap/cps/rest/config/SpringFoxConfig.java b/cps/cps-rest/src/main/java/org/onap/cps/rest/config/SpringFoxConfig.java deleted file mode 100644 index 3a9e53947..000000000 --- a/cps/cps-rest/src/main/java/org/onap/cps/rest/config/SpringFoxConfig.java +++ /dev/null @@ -1,38 +0,0 @@ -package org.onap.cps.rest.config; - - -import static springfox.documentation.builders.PathSelectors.regex; - -import com.google.common.base.Predicate; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import springfox.documentation.builders.RequestHandlerSelectors; -import springfox.documentation.spi.DocumentationType; -import springfox.documentation.spring.web.plugins.Docket; -import springfox.documentation.swagger2.annotations.EnableSwagger2; - -/** - * Swagger configuration. - */ -@Configuration -@EnableSwagger2 -public class SpringFoxConfig { - - /** - * Define api configuration. - */ - @Bean - public Docket api() { - return new Docket(DocumentationType.SWAGGER_2) - .select() - .apis(RequestHandlerSelectors.any()) - .paths(paths()) - .build(); - } - - private Predicate paths() { - return regex("/model.*"); - } - -} - 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 index 9b7c0008e..a64cd6a04 100644 --- 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 @@ -23,7 +23,6 @@ import com.google.gson.Gson; import com.google.gson.JsonSyntaxException; import java.io.File; import java.io.IOException; -import java.util.UUID; import javax.ws.rs.Consumes; import javax.ws.rs.POST; import javax.ws.rs.Path; @@ -36,15 +35,9 @@ 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.http.HttpStatus; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.RequestParam; -import org.springframework.web.bind.annotation.ResponseStatus; -import org.springframework.web.multipart.MultipartFile; @Path("cps") -@org.springframework.web.bind.annotation.RestController public class RestController { @Autowired @@ -73,13 +66,6 @@ public class RestController { } } - @PostMapping("/model") - @ResponseStatus(HttpStatus.CREATED) - public String addModel(@RequestParam("file") MultipartFile file) { - // Store and return a model dto ... - return UUID.randomUUID() + " : " + file.getOriginalFilename(); - } - /** * Upload a JSON file. * -- cgit 1.2.3-korg From 79ade5d05ead5c020adcaa0220e42149ef18683d Mon Sep 17 00:00:00 2001 From: ToineSiebelink Date: Thu, 1 Oct 2020 14:43:49 +0100 Subject: introducing YangUtils with tests Issue-ID: CCSDK-2757 Jira Link: https://jira.onap.org/browse/CCSDK-2757 Change-Id: I3c396ef1e29e9f30027702f3d36ee3bbb1de9b8e --- .../java/org/onap/cps/api/impl/CpServiceImpl.java | 28 ++---- .../main/java/org/onap/cps/utils/YangUtils.java | 99 ++++++++++++++++++++++ .../org/onap/cps/api/impl/CpServiceImplSpec.groovy | 30 +++++-- .../groovy/org/onap/cps/utils/YangUtilsSpec.groovy | 80 +++++++++++++++++ .../src/test/java/org/onap/cps/TestUtils.java | 41 +++++++++ cps/cps-service/src/test/resources/bookstore.json | 34 ++++++++ cps/cps-service/src/test/resources/bookstore.yang | 50 +++++++++++ cps/cps-service/src/test/resources/invalid.yang | 1 + .../src/test/resources/someOtherFile.txt | 0 9 files changed, 333 insertions(+), 30 deletions(-) create mode 100644 cps/cps-service/src/main/java/org/onap/cps/utils/YangUtils.java create mode 100644 cps/cps-service/src/test/groovy/org/onap/cps/utils/YangUtilsSpec.groovy create mode 100644 cps/cps-service/src/test/java/org/onap/cps/TestUtils.java create mode 100644 cps/cps-service/src/test/resources/bookstore.json create mode 100644 cps/cps-service/src/test/resources/bookstore.yang create mode 100644 cps/cps-service/src/test/resources/invalid.yang create mode 100644 cps/cps-service/src/test/resources/someOtherFile.txt diff --git a/cps/cps-service/src/main/java/org/onap/cps/api/impl/CpServiceImpl.java b/cps/cps-service/src/main/java/org/onap/cps/api/impl/CpServiceImpl.java index 8d6b63bd5..cb8e20c8a 100644 --- a/cps/cps-service/src/main/java/org/onap/cps/api/impl/CpServiceImpl.java +++ b/cps/cps-service/src/main/java/org/onap/cps/api/impl/CpServiceImpl.java @@ -24,18 +24,14 @@ import java.io.BufferedWriter; import java.io.File; import java.io.FileWriter; import java.io.IOException; -import java.util.Iterator; -import java.util.ServiceLoader; import org.onap.cps.api.CpService; import org.onap.cps.spi.DataPersistencyService; import org.onap.cps.spi.ModelPersistencyService; +import org.onap.cps.utils.YangUtils; import org.opendaylight.yangtools.yang.model.api.Module; import org.opendaylight.yangtools.yang.model.api.SchemaContext; -import org.opendaylight.yangtools.yang.model.parser.api.YangParser; import org.opendaylight.yangtools.yang.model.parser.api.YangParserException; import org.opendaylight.yangtools.yang.model.parser.api.YangParserFactory; -import org.opendaylight.yangtools.yang.model.repo.api.StatementParserMode; -import org.opendaylight.yangtools.yang.model.repo.api.YangTextSchemaSource; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; @@ -49,16 +45,7 @@ public class CpServiceImpl implements CpService { private static final YangParserFactory PARSER_FACTORY; - static { - final Iterator it = - ServiceLoader.load(YangParserFactory.class).iterator(); - if (!it.hasNext()) { - throw new IllegalStateException("No YangParserFactory found"); - } - PARSER_FACTORY = it.next(); - } - - @Autowired + @Autowired private ModelPersistencyService modelPersistencyService; @Autowired @@ -66,23 +53,18 @@ public class CpServiceImpl implements CpService { @Override - public final SchemaContext parseAndValidateModel(final String yangModelContent) - throws IOException, YangParserException { + public final SchemaContext parseAndValidateModel(final String yangModelContent) throws IOException, + YangParserException { final File tempFile = File.createTempFile("yang", ".yang"); try (BufferedWriter writer = new BufferedWriter(new FileWriter(tempFile))) { writer.write(yangModelContent); - } catch (final IOException e) { - LOGGER.error("Unable to write to temporary file {}", e.getMessage()); } return parseAndValidateModel(tempFile); } @Override public final SchemaContext parseAndValidateModel(final File yangModelFile) throws IOException, YangParserException { - final YangTextSchemaSource yangTextSchemaSource = YangTextSchemaSource.forFile(yangModelFile); - final YangParser yangParser = PARSER_FACTORY.createParser(StatementParserMode.DEFAULT_MODE); - yangParser.addSource(yangTextSchemaSource); - return yangParser.buildEffectiveModel(); + return YangUtils.parseYangModelFile(yangModelFile); } @Override diff --git a/cps/cps-service/src/main/java/org/onap/cps/utils/YangUtils.java b/cps/cps-service/src/main/java/org/onap/cps/utils/YangUtils.java new file mode 100644 index 000000000..e9757eca0 --- /dev/null +++ b/cps/cps-service/src/main/java/org/onap/cps/utils/YangUtils.java @@ -0,0 +1,99 @@ +/* + * ============LICENSE_START======================================================= + * Copyright (C) 2020 Nordix Foundation + * ================================================================================ + * 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.utils; + +import com.google.gson.stream.JsonReader; +import java.io.File; +import java.io.IOException; +import java.io.StringReader; +import java.util.Iterator; +import java.util.ServiceLoader; +import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode; +import org.opendaylight.yangtools.yang.data.api.schema.stream.NormalizedNodeStreamWriter; +import org.opendaylight.yangtools.yang.data.codec.gson.JSONCodecFactory; +import org.opendaylight.yangtools.yang.data.codec.gson.JSONCodecFactorySupplier; +import org.opendaylight.yangtools.yang.data.codec.gson.JsonParserStream; +import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNormalizedNodeStreamWriter; +import org.opendaylight.yangtools.yang.data.impl.schema.NormalizedNodeResult; +import org.opendaylight.yangtools.yang.model.api.SchemaContext; +import org.opendaylight.yangtools.yang.model.parser.api.YangParser; +import org.opendaylight.yangtools.yang.model.parser.api.YangParserException; +import org.opendaylight.yangtools.yang.model.parser.api.YangParserFactory; +import org.opendaylight.yangtools.yang.model.repo.api.StatementParserMode; +import org.opendaylight.yangtools.yang.model.repo.api.YangTextSchemaSource; + +public class YangUtils { + + private static final YangParserFactory PARSER_FACTORY; + + private YangUtils() { + throw new IllegalStateException("Utility class"); + } + + static { + final Iterator it = ServiceLoader.load(YangParserFactory.class).iterator(); + if (!it.hasNext()) { + throw new IllegalStateException("No YangParserFactory found"); + } + PARSER_FACTORY = it.next(); + } + + /** + * Parse a file containing yang modules. + * @param yangModelFile a file containing one or more yang modules + * (please note the file has to have a .yang extension if not an exception will be thrown) + * @return a SchemaContext representing the yang model + * @throws IOException when the system as an IO issue + * @throws YangParserException when the file does not contain a valid yang structure + */ + public static SchemaContext parseYangModelFile(final File yangModelFile) throws IOException, YangParserException { + YangTextSchemaSource yangTextSchemaSource = YangTextSchemaSource.forFile(yangModelFile); + final YangParser yangParser = PARSER_FACTORY + .createParser(StatementParserMode.DEFAULT_MODE); + yangParser.addSource(yangTextSchemaSource); + return yangParser.buildEffectiveModel(); + } + + /** + * Parse a file containing json data for a certain model (schemaContext). + * @param jsonData a string containing json data for the given model + * @param schemaContext the SchemaContext for the given data + * @return the NormalizedNode representing the json data + */ + public static NormalizedNode parseJsonData(final String jsonData, final SchemaContext schemaContext) + throws IOException { + JSONCodecFactory jsonCodecFactory = JSONCodecFactorySupplier.DRAFT_LHOTKA_NETMOD_YANG_JSON_02 + .getShared(schemaContext); + final NormalizedNodeResult normalizedNodeResult = new NormalizedNodeResult(); + final NormalizedNodeStreamWriter normalizedNodeStreamWriter = ImmutableNormalizedNodeStreamWriter + .from(normalizedNodeResult); + try (JsonParserStream jsonParserStream = JsonParserStream + .create(normalizedNodeStreamWriter, jsonCodecFactory)) { + final JsonReader jsonReader = new JsonReader(new StringReader(jsonData)); + jsonParserStream.parse(jsonReader); + } + return normalizedNodeResult.getResult(); + } + + public static void chopNormalizedNode(NormalizedNode tree) { + //TODO Toine Siebelink, add code from proto-type (other user story) + } + +} diff --git a/cps/cps-service/src/test/groovy/org/onap/cps/api/impl/CpServiceImplSpec.groovy b/cps/cps-service/src/test/groovy/org/onap/cps/api/impl/CpServiceImplSpec.groovy index 27f748211..a1c9dd951 100644 --- a/cps/cps-service/src/test/groovy/org/onap/cps/api/impl/CpServiceImplSpec.groovy +++ b/cps/cps-service/src/test/groovy/org/onap/cps/api/impl/CpServiceImplSpec.groovy @@ -1,3 +1,22 @@ +/* + * ============LICENSE_START======================================================= + * Copyright (C) 2020 Nordix Foundation + * ================================================================================ + * 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.api.impl import org.onap.cps.spi.DataPersistencyService @@ -14,14 +33,11 @@ class CpServiceImplSpec extends Specification { objectUnderTest.dataPersistencyService = dataPersistencyService; } - def 'Storing a json object'() { - given: 'that the data persistency service returns an id of 123' + def 'Cps Service provides to its client the id assigned by the system when storing a data structure'() { + given: 'that data persistency service is giving id 123 to a data structure it is asked to store' dataPersistencyService.storeJsonStructure(_) >> 123 - when: 'a json structure is stored using the data persistency service' - def result = objectUnderTest.storeJsonStructure('') - - then: ' the same id is returned' - result == 123 + expect: 'Cps service returns the same id when storing data structure' + objectUnderTest.storeJsonStructure('') == 123 } } diff --git a/cps/cps-service/src/test/groovy/org/onap/cps/utils/YangUtilsSpec.groovy b/cps/cps-service/src/test/groovy/org/onap/cps/utils/YangUtilsSpec.groovy new file mode 100644 index 000000000..8aabc4844 --- /dev/null +++ b/cps/cps-service/src/test/groovy/org/onap/cps/utils/YangUtilsSpec.groovy @@ -0,0 +1,80 @@ +/* + * ============LICENSE_START======================================================= + * Copyright (C) 2020 Nordix Foundation + * ================================================================================ + * 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.utils + +import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode +import org.opendaylight.yangtools.yang.common.QName +import org.opendaylight.yangtools.yang.common.Revision +import org.opendaylight.yangtools.yang.model.parser.api.YangSyntaxErrorException +import spock.lang.Specification +import spock.lang.Unroll + +class YangUtilsSpec extends Specification{ + def 'Parsing a valid Yang Model'() { + given: 'a yang model (file)' + def file = new File(ClassLoader.getSystemClassLoader().getResource('bookstore.yang').getFile()) + when: 'the file is parsed' + def result = YangUtils.parseYangModelFile(file) + then: 'the result contain 1 module of the correct name and revision' + result.modules.size() == 1 + def optionalModule = result.findModule('bookstore', Revision.of('2020-09-15')) + optionalModule.isPresent() + } + + @Unroll + def 'parsing invalid yang file (#description)'() { + given: 'a file with #description' + File file = new File(ClassLoader.getSystemClassLoader().getResource(filename).getFile()); + when: 'the file is parsed' + YangUtils.parseYangModelFile(file) + then: 'an exception is thrown' + thrown(expectedException) + where: 'the following parameters are used' + filename | description || expectedException + 'invalid.yang' | 'no valid content' || YangSyntaxErrorException + 'someOtherFile.txt' | 'no .yang extension' || IllegalArgumentException + } + + def 'Parsing a valid Json String'() { + given: 'a yang model (file)' + def jsonData = org.onap.cps.TestUtils.getResourceFileContent('bookstore.json') + and: 'a model for that data' + def file = new File(ClassLoader.getSystemClassLoader().getResource('bookstore.yang').getFile()) + def schemaContext = YangUtils.parseYangModelFile(file) + when: 'the json data is parsed' + NormalizedNode result = YangUtils.parseJsonData(jsonData, schemaContext); + then: 'the result is a normalized node of the correct type' + result.nodeType == QName.create('org:onap:ccsdk:sample','2020-09-15','bookstore') + } + + def 'Parsing an invalid Json String'() { + given: 'a yang model (file)' + def jsonData = '{incomplete json' + and: 'a model' + def file = new File(ClassLoader.getSystemClassLoader().getResource('bookstore.yang').getFile()) + def schemaContext = YangUtils.parseYangModelFile(file) + when: 'the invalid json is parsed' + YangUtils.parseJsonData(jsonData, schemaContext); + then: ' an exception is thrown' + thrown(IllegalStateException) + } + + +} diff --git a/cps/cps-service/src/test/java/org/onap/cps/TestUtils.java b/cps/cps-service/src/test/java/org/onap/cps/TestUtils.java new file mode 100644 index 000000000..e15cf525f --- /dev/null +++ b/cps/cps-service/src/test/java/org/onap/cps/TestUtils.java @@ -0,0 +1,41 @@ +/* + * ============LICENSE_START======================================================= + * Copyright (C) 2020 Nordix Foundation + * ================================================================================ + * 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; + +import java.io.File; +import java.io.IOException; +import java.nio.file.Files; + +/** + * Common convenience methods for testing + */ +public class TestUtils { + /** + * Convert a file in the test resource folder to a string + * + * @param filename to name of the file in test/resources + * @return the content of the file as a String + * @throws IOException when there is an IO issue + */ + public static String getResourceFileContent(final String filename) throws IOException { + File file = new File(ClassLoader.getSystemClassLoader().getResource(filename).getFile()); + return new String(Files.readAllBytes(file.toPath())); + } +} diff --git a/cps/cps-service/src/test/resources/bookstore.json b/cps/cps-service/src/test/resources/bookstore.json new file mode 100644 index 000000000..44d5d424c --- /dev/null +++ b/cps/cps-service/src/test/resources/bookstore.json @@ -0,0 +1,34 @@ +{ + "test:bookstore":{ + "categories":[ + { + "name":"web", + "books":[ + { + "authors":[ + "Toine Siebelink","David Lang" + ], + "lang":"en", + "price":"123456", + "pub_year":"2020", + "title":"My first book" + } + ] + }, + { + "name":"art", + "books":[ + { + "authors":[ + "Test" + ], + "lang":"en", + "price":"1234", + "pub_year":"2020", + "title":"My 2nd book" + } + ] + } + ] + } +} \ No newline at end of file diff --git a/cps/cps-service/src/test/resources/bookstore.yang b/cps/cps-service/src/test/resources/bookstore.yang new file mode 100644 index 000000000..01eac5f33 --- /dev/null +++ b/cps/cps-service/src/test/resources/bookstore.yang @@ -0,0 +1,50 @@ +module bookstore { + yang-version 1.1; + + namespace "org:onap:ccsdk:sample"; + + prefix book-store; + + revision "2020-09-15" { + description + "Sample Model"; + } + + typedef year { + type uint16 { + range "1000..9999"; + } + } + + container bookstore { + + list categories { + + key name; + + leaf name { + type string; + } + + list books { + key title; + + leaf title { + type string; + } + leaf lang { + type string; + } + leaf-list authors { + type string; + } + leaf pub_year { + type year; + } + leaf price { + type uint64; + } + } + } + } +} diff --git a/cps/cps-service/src/test/resources/invalid.yang b/cps/cps-service/src/test/resources/invalid.yang new file mode 100644 index 000000000..66cfd1079 --- /dev/null +++ b/cps/cps-service/src/test/resources/invalid.yang @@ -0,0 +1 @@ +no yang at all! diff --git a/cps/cps-service/src/test/resources/someOtherFile.txt b/cps/cps-service/src/test/resources/someOtherFile.txt new file mode 100644 index 000000000..e69de29bb -- cgit 1.2.3-korg From 14f3af1327204bdeee57241bd094b426e0741312 Mon Sep 17 00:00:00 2001 From: Rishi Chail Date: Fri, 2 Oct 2020 09:33:35 +0100 Subject: DM: Enable Swagger Issue-ID: CCSDK-2754 https: //jira.onap.org/browse/CCSDK-2754 Change-Id: I20f8ab029082bb0012d5933f47d15a2f482ee378 Signed-off-by: Rishi Chail --- cps/cps-rest/pom.xml | 11 +++++++++ .../org/onap/cps/rest/config/JerseyConfig.java | 24 ++++++++++++++++--- .../src/main/resources/openapi-configuration.json | 28 ++++++++++++++++++++++ cps/cps-service/pom.xml | 12 +++++----- cps/pom.xml | 13 +++++----- 5 files changed, 73 insertions(+), 15 deletions(-) create mode 100644 cps/cps-rest/src/main/resources/openapi-configuration.json diff --git a/cps/cps-rest/pom.xml b/cps/cps-rest/pom.xml index bd9be8dfd..2b4cbb894 100644 --- a/cps/cps-rest/pom.xml +++ b/cps/cps-rest/pom.xml @@ -44,6 +44,17 @@ spring-boot-starter-jetty + + io.swagger.core.v3 + swagger-annotations + ${swagger.version} + + + + io.swagger.core.v3 + swagger-jaxrs2 + ${swagger.version} + org.springframework.boot 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 index 44487fe06..ea273986c 100644 --- 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 @@ -20,20 +20,38 @@ 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.onap.cps.rest.controller.RestController; import org.springframework.context.annotation.Configuration; @Configuration @ApplicationPath("/api/v1") public class JerseyConfig extends ResourceConfig { + /** + * This method is used to setup Jersey related configuration. + */ @PostConstruct public void init() { - register(RestController.class); register(MultiPartFeature.class); + register(OpenApiResource.class); + register(AcceptHeaderOpenApiResource.class); + + packages("org.onap.cps.rest.controller"); + configureSwagger(); + } + + private void configureSwagger() { + try { + new JaxrsOpenApiContextBuilder<>().buildContext(true).read(); + } catch (final OpenApiConfigurationException e) { + throw new RuntimeException(e.getMessage(), e); + } } -} \ No newline at end of file +} diff --git a/cps/cps-rest/src/main/resources/openapi-configuration.json b/cps/cps-rest/src/main/resources/openapi-configuration.json new file mode 100644 index 000000000..ad5998feb --- /dev/null +++ b/cps/cps-rest/src/main/resources/openapi-configuration.json @@ -0,0 +1,28 @@ +{ + "resourcePackages": [ + "org.onap.cps.rest.controller" + ], + "prettyPrint": true, + "cacheTTL": 0, + "openAPI": { + "info": { + "title": "ONAP Open API v3 CPS Spec", + "description": "The API Description may be multiline, and GitHub Flavored Markdown, GFM syntax, can be used for rich text representation.", + "x-logo": { + "url": "logo.png" + }, + "contact": { + "name": "ONAP", + "url": "https://onap.readthedocs.io", + "email": "onap-discuss@lists.onap.org" + }, + "license": { + "name": "Apache 2.0", + "url": "http://www.apache.org/licenses/LICENSE-2.0" + }, + "version": "1.2.34", + "x-planned-retirement-date": "202207", + "x-component": "Modeling" + } + } +} diff --git a/cps/cps-service/pom.xml b/cps/cps-service/pom.xml index a59376c20..731873420 100644 --- a/cps/cps-service/pom.xml +++ b/cps/cps-service/pom.xml @@ -14,26 +14,26 @@ org.opendaylight.yangtools yang-parser-api - ${org.opendaylight.yangtools.version} + ${yangtools.version} org.opendaylight.yangtools yang-parser-impl - ${org.opendaylight.yangtools.version} + ${yangtools.version} org.opendaylight.yangtools yang-model-util - ${org.opendaylight.yangtools.version} + ${yangtools.version} org.opendaylight.yangtools yang-data-codec-gson - ${org.opendaylight.yangtools.version} + ${yangtools.version} @@ -64,13 +64,13 @@ org.codehaus.groovy groovy - ${version.groovy} + ${groovy.version} test org.spockframework spock-core - ${version.spock-core} + ${spock-core.version} test diff --git a/cps/pom.xml b/cps/pom.xml index 5435c4a4a..d81ee9e08 100644 --- a/cps/pom.xml +++ b/cps/pom.xml @@ -19,12 +19,13 @@ - 11 + 11 2.3.3.RELEASE 3.1.0 - 5.0.5 - 3.0.6 - 2.0-M2-groovy-3.0 + 5.0.6 + 2.1.4 + 3.0.6 + 2.0-M2-groovy-3.0 @@ -67,8 +68,8 @@ org.apache.maven.plugins maven-compiler-plugin - ${version.java.compiler} - ${version.java.compiler} + ${java.version} + ${java.version} -- cgit 1.2.3-korg From 42374f88049182a1a548f800da83a54b47ea9a15 Mon Sep 17 00:00:00 2001 From: ToineSiebelink Date: Mon, 5 Oct 2020 10:29:14 +0100 Subject: Fixing checkstyle issues Issue-ID: CCSDK-2757 Jira Link: https://jira.onap.org/browse/CCSDK-2757 Change-Id: I933f1c44f7525aeb57916b2db63ea0b96e457368 --- .../src/main/java/org/onap/cps/api/impl/CpServiceImpl.java | 4 +--- cps/cps-service/src/test/java/org/onap/cps/TestUtils.java | 4 ++-- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/cps/cps-service/src/main/java/org/onap/cps/api/impl/CpServiceImpl.java b/cps/cps-service/src/main/java/org/onap/cps/api/impl/CpServiceImpl.java index cb8e20c8a..001a47438 100644 --- a/cps/cps-service/src/main/java/org/onap/cps/api/impl/CpServiceImpl.java +++ b/cps/cps-service/src/main/java/org/onap/cps/api/impl/CpServiceImpl.java @@ -43,9 +43,7 @@ public class CpServiceImpl implements CpService { private static final Logger LOGGER = LoggerFactory.getLogger(CpServiceImpl.class); - private static final YangParserFactory PARSER_FACTORY; - - @Autowired + @Autowired private ModelPersistencyService modelPersistencyService; @Autowired diff --git a/cps/cps-service/src/test/java/org/onap/cps/TestUtils.java b/cps/cps-service/src/test/java/org/onap/cps/TestUtils.java index e15cf525f..07647520b 100644 --- a/cps/cps-service/src/test/java/org/onap/cps/TestUtils.java +++ b/cps/cps-service/src/test/java/org/onap/cps/TestUtils.java @@ -24,11 +24,11 @@ import java.io.IOException; import java.nio.file.Files; /** - * Common convenience methods for testing + * Common convenience methods for testing. */ public class TestUtils { /** - * Convert a file in the test resource folder to a string + * Convert a file in the test resource folder to a string. * * @param filename to name of the file in test/resources * @return the content of the file as a String -- cgit 1.2.3-korg From 75a05e296781f9427959355443bbebfc28ac804e Mon Sep 17 00:00:00 2001 From: niamhcore Date: Mon, 5 Oct 2020 10:10:44 +0100 Subject: Adding tests for CpServiceImpl Issue-ID: CCSDK-2757 Jira Link: https://jira.onap.org/browse/CCSDK-2757 Change-Id: I153642c837a0797faab3e8a324ff77a673582e91 --- .../org/onap/cps/api/impl/CpServiceImplSpec.groovy | 53 +++++++++++++++++++--- 1 file changed, 46 insertions(+), 7 deletions(-) diff --git a/cps/cps-service/src/test/groovy/org/onap/cps/api/impl/CpServiceImplSpec.groovy b/cps/cps-service/src/test/groovy/org/onap/cps/api/impl/CpServiceImplSpec.groovy index a1c9dd951..67bbab3c6 100644 --- a/cps/cps-service/src/test/groovy/org/onap/cps/api/impl/CpServiceImplSpec.groovy +++ b/cps/cps-service/src/test/groovy/org/onap/cps/api/impl/CpServiceImplSpec.groovy @@ -19,25 +19,64 @@ package org.onap.cps.api.impl +import org.onap.cps.TestUtils import org.onap.cps.spi.DataPersistencyService -import spock.lang.Specification; - +import org.opendaylight.yangtools.yang.common.Revision +import org.opendaylight.yangtools.yang.model.api.SchemaContext +import org.opendaylight.yangtools.yang.model.parser.api.YangParserException +import spock.lang.Specification class CpServiceImplSpec extends Specification { - def dataPersistencyService = Mock(DataPersistencyService) + def mockDataPersistencyService = Mock(DataPersistencyService) def objectUnderTest = new CpServiceImpl() def setup() { - // Insert mocked dependencies - objectUnderTest.dataPersistencyService = dataPersistencyService; + objectUnderTest.dataPersistencyService = mockDataPersistencyService; } def 'Cps Service provides to its client the id assigned by the system when storing a data structure'() { given: 'that data persistency service is giving id 123 to a data structure it is asked to store' - dataPersistencyService.storeJsonStructure(_) >> 123 - + mockDataPersistencyService.storeJsonStructure(_) >> 123 expect: 'Cps service returns the same id when storing data structure' objectUnderTest.storeJsonStructure('') == 123 } + + def 'Parse and Validate a Yang Model with a Valid Yang Model'() { + given: 'a yang model (file)' + def yangModel = TestUtils.getResourceFileContent('bookstore.yang') + when: 'a valid model is parsed and validated' + def result = objectUnderTest.parseAndValidateModel(yangModel) + then: 'Verify a schema context for that model is created with the correct identity' + assertModule(result) + } + + def 'Parse and Validate a Yang Model Using a File'() { + given: 'a yang file that contains a yang model' + File file = new File(ClassLoader.getSystemClassLoader().getResource('bookstore.yang').getFile()) + when: 'a model is parsed and validated' + def result = objectUnderTest.parseAndValidateModel(file) + then: 'Verify a schema context for that model is created with the correct identity' + assertModule(result) + + } + + def assertModule(SchemaContext schemaContext){ + def optionalModule = schemaContext.findModule('bookstore', Revision.of('2020-09-15')) + return schemaContext.modules.size() == 1 && optionalModule.isPresent() + } + + def 'Parse and Validate an Invalid Model'() { + given: 'a yang file that contains a invalid yang model' + File file = new File(ClassLoader.getSystemClassLoader().getResource('invalid.yang').getFile()) + when: 'the model is parsed and validated' + objectUnderTest.parseAndValidateModel(file) + then: 'a YangParserException is thrown' + thrown(YangParserException) + } + + def 'Store a SchemaContext'() { + expect: 'No exception to be thrown when a valid model (schema) is stored' + objectUnderTest.storeSchemaContext(Stub(SchemaContext.class)) + } } -- cgit 1.2.3-korg From 1d8e556c8cea9c0c8b78381e1e4ce3c36b965dc9 Mon Sep 17 00:00:00 2001 From: niamhcore Date: Thu, 8 Oct 2020 14:19:23 +0100 Subject: Abandoned Review because of git issues; https://gerrit.nordix.org/#/c/onap/ccsdk/features/+/6170/ Change-Id: I63d0d460e120b12851e0b3b460639ee4c34c4e0c --- .../onap/cps/rest/controller/RestController.java | 21 +++++++++++++ cps/cps-rest/src/main/resources/application.yml | 34 ++++++++++++---------- .../cps/spi/impl/DataPersistencyServiceImpl.java | 12 +++++++- .../src/main/java/org/onap/cps/api/CpService.java | 8 +++++ .../java/org/onap/cps/api/impl/CpServiceImpl.java | 6 +++- .../org/onap/cps/spi/DataPersistencyService.java | 8 +++++ .../org/onap/cps/api/impl/CpServiceImplSpec.groovy | 17 +++++++++++ 7 files changed, 89 insertions(+), 17 deletions(-) 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 index a64cd6a04..2cac690b1 100644 --- 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 @@ -23,9 +23,12 @@ import com.google.gson.Gson; import com.google.gson.JsonSyntaxException; import java.io.File; import java.io.IOException; +import javax.persistence.PersistenceException; import javax.ws.rs.Consumes; +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; @@ -89,6 +92,24 @@ public class RestController { } } + /** + * 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") int jsonObjectId) { + try { + return Response.status(Status.OK).entity(cpService.getJsonById(jsonObjectId)).build(); + } catch (PersistenceException e) { + return Response.status(Status.NOT_FOUND).entity(e.getMessage()).build(); + } catch (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); diff --git a/cps/cps-rest/src/main/resources/application.yml b/cps/cps-rest/src/main/resources/application.yml index bc726694c..a8a4690f6 100644 --- a/cps/cps-rest/src/main/resources/application.yml +++ b/cps/cps-rest/src/main/resources/application.yml @@ -1,20 +1,24 @@ server: - port: 8080 + port: 8080 spring: - main: - banner-mode: "off" - # for POC only, later this should move to cpi-ri module - jpa: - hibernate: - ddl-auto: create - datasource: - url: jdbc:mariadb://${DB_HOST}:3306/${DB_NAME} - username: ${USERNAME} - password: ${PWD} - driverClassName: org.mariadb.jdbc.Driver + main: + banner-mode: "off" + # for POC only, later this should move to cpi-ri module + jpa: + hibernate: + ddl-auto: create + open-in-view: false + properties: + hibernate: + enable_lazy_load_no_trans: true + datasource: + url: jdbc:mariadb://${DB_HOST}:3306/${DB_NAME} + username: ${USERNAME} + password: ${PWD} + driverClassName: org.mariadb.jdbc.Driver logging: - level: - org: - springframework: INFO \ No newline at end of file + level: + org: + springframework: INFO \ No newline at end of file diff --git a/cps/cps-ri/src/main/java/org/onap/cps/spi/impl/DataPersistencyServiceImpl.java b/cps/cps-ri/src/main/java/org/onap/cps/spi/impl/DataPersistencyServiceImpl.java index 93746e06f..44d38f91d 100644 --- a/cps/cps-ri/src/main/java/org/onap/cps/spi/impl/DataPersistencyServiceImpl.java +++ b/cps/cps-ri/src/main/java/org/onap/cps/spi/impl/DataPersistencyServiceImpl.java @@ -36,11 +36,21 @@ public class DataPersistencyServiceImpl implements DataPersistencyService { * Method to store a JSON data structure in the database. * * @param jsonStructure the JSON data structure. - * @return + * @return the entity identifier. */ public final Integer storeJsonStructure(final String jsonStructure) { final JsonDataEntity jsonDataEntity = new JsonDataEntity(jsonStructure); dataRepository.save(jsonDataEntity); return jsonDataEntity.getId(); } + + /** + * Return the JSON structure from the database using the object identifier. + * + * @param jsonStructureId the JSON object identifier. + * @return the JSON structure from the database as a string. + */ + public final String getJsonById(final int jsonStructureId) { + return dataRepository.getOne(jsonStructureId).getJsonStructure(); + } } diff --git a/cps/cps-service/src/main/java/org/onap/cps/api/CpService.java b/cps/cps-service/src/main/java/org/onap/cps/api/CpService.java index cdd1c4dca..2a8b2165b 100644 --- a/cps/cps-service/src/main/java/org/onap/cps/api/CpService.java +++ b/cps/cps-service/src/main/java/org/onap/cps/api/CpService.java @@ -59,4 +59,12 @@ public interface CpService { * @return entity ID. */ Integer storeJsonStructure(final String jsonStructure); + + /** + * Read a JSON Object using the object identifier. + * + * @param jsonObjectId the JSON object identifier. + * @return the JSON structure. + */ + String getJsonById(final int jsonObjectId); } diff --git a/cps/cps-service/src/main/java/org/onap/cps/api/impl/CpServiceImpl.java b/cps/cps-service/src/main/java/org/onap/cps/api/impl/CpServiceImpl.java index 001a47438..4113fbc64 100644 --- a/cps/cps-service/src/main/java/org/onap/cps/api/impl/CpServiceImpl.java +++ b/cps/cps-service/src/main/java/org/onap/cps/api/impl/CpServiceImpl.java @@ -31,7 +31,6 @@ import org.onap.cps.utils.YangUtils; import org.opendaylight.yangtools.yang.model.api.Module; import org.opendaylight.yangtools.yang.model.api.SchemaContext; import org.opendaylight.yangtools.yang.model.parser.api.YangParserException; -import org.opendaylight.yangtools.yang.model.parser.api.YangParserFactory; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; @@ -70,6 +69,11 @@ public class CpServiceImpl implements CpService { return dataPersistencyService.storeJsonStructure(jsonStructure); } + @Override + public final String getJsonById(final int jsonObjectId) { + return dataPersistencyService.getJsonById(jsonObjectId); + } + @Override public final void storeSchemaContext(final SchemaContext schemaContext) { for (final Module module : schemaContext.getModules()) { diff --git a/cps/cps-service/src/main/java/org/onap/cps/spi/DataPersistencyService.java b/cps/cps-service/src/main/java/org/onap/cps/spi/DataPersistencyService.java index 4dcd31d95..11f9ed0db 100644 --- a/cps/cps-service/src/main/java/org/onap/cps/spi/DataPersistencyService.java +++ b/cps/cps-service/src/main/java/org/onap/cps/spi/DataPersistencyService.java @@ -31,4 +31,12 @@ public interface DataPersistencyService { * @return jsonEntityID the ID of the JSON entity. */ Integer storeJsonStructure(final String jsonStructure); + + /** + * Get the JSON structure from the database using the entity identifier. + * + * @param jsonStructureId the json entity identifier. + * @return a JSON Structure. + */ + String getJsonById(int jsonStructureId); } diff --git a/cps/cps-service/src/test/groovy/org/onap/cps/api/impl/CpServiceImplSpec.groovy b/cps/cps-service/src/test/groovy/org/onap/cps/api/impl/CpServiceImplSpec.groovy index 67bbab3c6..f112fa210 100644 --- a/cps/cps-service/src/test/groovy/org/onap/cps/api/impl/CpServiceImplSpec.groovy +++ b/cps/cps-service/src/test/groovy/org/onap/cps/api/impl/CpServiceImplSpec.groovy @@ -79,4 +79,21 @@ class CpServiceImplSpec extends Specification { expect: 'No exception to be thrown when a valid model (schema) is stored' objectUnderTest.storeSchemaContext(Stub(SchemaContext.class)) } + + def 'Read a JSON object with a valid identifier'(){ + given: 'that the data persistence service returns a JSON structure for identifier 1' + mockDataPersistencyService.getJsonById(1) >> '{name : hello}' + expect: 'that the same JSON structure is returned by CPS' + objectUnderTest.getJsonById(1) == '{name : hello}' + } + + def 'Read a JSON object with an identifier that does not exist'(){ + given: 'that the data persistence service throws an exception' + def exceptionThrownByPersistenceService = new IllegalStateException() + mockDataPersistencyService.getJsonById(_) >> {throw exceptionThrownByPersistenceService} + when: 'we try to get the JSON structure' + objectUnderTest.getJsonById(1); + then: 'the same exception is thrown by CPS' + thrown(IllegalStateException) + } } -- cgit 1.2.3-korg From 8af414a6c52e2e0d5d6a87581122b8e4ae86cb00 Mon Sep 17 00:00:00 2001 From: Rishi Chail Date: Thu, 8 Oct 2020 12:33:33 +0100 Subject: DM: Introduce Postgres and Script generated Schema Jira ID:CCSDK-2869 Jira Link: https://jira.onap.org/browse/CCSDK-2869 Signed-off-by: Rishi Chail Change-Id: I54007daf1ad2491d49142168e8cb44e6eb2da8b9 --- cps/cps-rest/src/main/resources/application.yml | 38 ++++++----- cps/cps-rest/src/main/resources/schema.sql | 63 +++++++++++++++++ cps/cps-ri/pom.xml | 89 ++++++++++++------------- 3 files changed, 125 insertions(+), 65 deletions(-) create mode 100644 cps/cps-rest/src/main/resources/schema.sql diff --git a/cps/cps-rest/src/main/resources/application.yml b/cps/cps-rest/src/main/resources/application.yml index a8a4690f6..5cfa97415 100644 --- a/cps/cps-rest/src/main/resources/application.yml +++ b/cps/cps-rest/src/main/resources/application.yml @@ -2,23 +2,25 @@ server: port: 8080 spring: - main: - banner-mode: "off" - # for POC only, later this should move to cpi-ri module - jpa: - hibernate: - ddl-auto: create - open-in-view: false - properties: - hibernate: - enable_lazy_load_no_trans: true - datasource: - url: jdbc:mariadb://${DB_HOST}:3306/${DB_NAME} - username: ${USERNAME} - password: ${PWD} - driverClassName: org.mariadb.jdbc.Driver + main: + banner-mode: "off" +# for POC only, later this should move to cpi-ri module + jpa: + ddl-auto: create + open-in-view: false + properties: + hibernate: + enable_lazy_load_no_trans: true + dialect: org.hibernate.dialect.PostgreSQLDialect + + datasource: + url: jdbc:postgresql://${DB_HOST}:5432/cpsdb + username: ${DB_USERNAME} + password: ${DB_PASSWORD} + driverClassName: org.postgresql.Driver + initialization-mode: always logging: - level: - org: - springframework: INFO \ No newline at end of file + level: + org: + springframework: INFO diff --git a/cps/cps-rest/src/main/resources/schema.sql b/cps/cps-rest/src/main/resources/schema.sql new file mode 100644 index 000000000..446d6e584 --- /dev/null +++ b/cps/cps-rest/src/main/resources/schema.sql @@ -0,0 +1,63 @@ +/* Initialisation script for CPS. + +To be moved to cps-ri in Honolulu. */ + + +CREATE TABLE IF NOT EXISTS RELATION_TYPE +( + RELATION_TYPE TEXT NOT NULL, + ID SERIAL PRIMARY KEY +); + +CREATE TABLE IF NOT EXISTS DATASPACE +( + ID SERIAL PRIMARY KEY, + NAME TEXT NOT NULL, + CONSTRAINT "UQ_NAME" UNIQUE (NAME) +); + +CREATE TABLE IF NOT EXISTS SCHEMA_NODE +( + SCHEMA_NODE_IDENTIFIER TEXT NOT NULL, + ID SERIAL PRIMARY KEY +); + +CREATE TABLE IF NOT EXISTS MODULE_SET +( + MODULE_SET_REFERENCE TEXT NOT NULL, + ID SERIAL PRIMARY KEY +); + +CREATE TABLE IF NOT EXISTS FRAGMENT +( + ID BIGSERIAL PRIMARY KEY, + XPATH TEXT NOT NULL, + DATASPACE_ID INTEGER NOT NULL REFERENCES DATASPACE(ID), + ATTRIBUTES JSONB, + ANCHOR_ID BIGINT REFERENCES FRAGMENT(ID), + PARENT_ID BIGINT REFERENCES FRAGMENT(ID), + MODULE_SET_ID INTEGER REFERENCES MODULE_SET(ID), + SCHEMA_NODE_ID INTEGER REFERENCES SCHEMA_NODE(ID) +); + +CREATE TABLE IF NOT EXISTS RELATION +( + FROM_FRAGMENT_ID BIGINT NOT NULL REFERENCES FRAGMENT(ID), + TO_FRAGMENT_ID BIGINT NOT NULL REFERENCES FRAGMENT(ID), + RELATION_TYPE_ID INTEGER NOT NULL REFERENCES RELATION_TYPE(ID), + FROM_REL_XPATH TEXT NOT NULL, + TO_REL_XPATH TEXT NOT NULL, + CONSTRAINT RELATION_PKEY PRIMARY KEY (TO_FRAGMENT_ID, FROM_FRAGMENT_ID, RELATION_TYPE_ID) +); + +CREATE INDEX IF NOT EXISTS "FKI_FRAGMENT_DATASPACE_ID_FK" ON FRAGMENT USING BTREE(DATASPACE_ID) ; +CREATE INDEX IF NOT EXISTS "FKI_FRAGMENT_MODULE_SET_ID_FK" ON FRAGMENT USING BTREE(MODULE_SET_ID) ; +CREATE INDEX IF NOT EXISTS "FKI_FRAGMENT_PARENT_ID_FK" ON FRAGMENT USING BTREE(PARENT_ID) ; +CREATE INDEX IF NOT EXISTS "FKI_FRAGMENT_ANCHOR_ID_FK" ON FRAGMENT USING BTREE(ANCHOR_ID) ; +CREATE INDEX IF NOT EXISTS "PERF_SCHEMA_NODE_SCHEMA_NODE_ID" ON SCHEMA_NODE USING BTREE(SCHEMA_NODE_IDENTIFIER) ; +CREATE INDEX IF NOT EXISTS "FKI_SCHEMA_NODE_ID_TO_ID" ON FRAGMENT USING BTREE(SCHEMA_NODE_ID) ; +CREATE INDEX IF NOT EXISTS "FKI_RELATION_TYPE_ID_FK" ON RELATION USING BTREE(RELATION_TYPE_ID); +CREATE INDEX IF NOT EXISTS "FKI_RELATIONS_FROM_ID_FK" ON RELATION USING BTREE(FROM_FRAGMENT_ID); +CREATE INDEX IF NOT EXISTS "FKI_RELATIONS_TO_ID_FK" ON RELATION USING BTREE(TO_FRAGMENT_ID); +CREATE INDEX IF NOT EXISTS "PERF_MODULE_SET_MODULE_SET_REFERENCE" ON MODULE_SET USING BTREE(MODULE_SET_REFERENCE) ; +CREATE UNIQUE INDEX IF NOT EXISTS "UQ_FRAGMENT_XPATH"ON FRAGMENT USING btree(xpath COLLATE pg_catalog."default" text_pattern_ops, dataspace_id); \ No newline at end of file diff --git a/cps/cps-ri/pom.xml b/cps/cps-ri/pom.xml index 781f8e832..334e47662 100644 --- a/cps/cps-ri/pom.xml +++ b/cps/cps-ri/pom.xml @@ -1,48 +1,43 @@ - 4.0.0 - - org.onap.cps - cps - 0.0.1-SNAPSHOT - - cps-ri - - - - - org.onap.cps - cps-service - ${project.version} - - - - org.springframework.boot - spring-boot-starter-data-jpa - - - - org.springframework.boot - spring-boot-starter-validation - - - - org.mariadb.jdbc - mariadb-java-client - - - - org.projectlombok - lombok - - - - - jakarta.persistence - jakarta.persistence-api - - - - - \ No newline at end of file + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> + 4.0.0 + + org.onap.cps + cps + 0.0.1-SNAPSHOT + + cps-ri + + + + + org.onap.cps + cps-service + ${project.version} + + + + org.springframework.boot + spring-boot-starter-data-jpa + + + + org.springframework.boot + spring-boot-starter-validation + + + + org.postgresql + postgresql + + + + + org.projectlombok + lombok + + + + + -- cgit 1.2.3-korg From 21173da7370016c46a840e2595ecfe0a3d1558ac Mon Sep 17 00:00:00 2001 From: Rishi Chail Date: Fri, 9 Oct 2020 09:00:24 +0100 Subject: IS: Correct REST base Url Issue-ID: CCSDK-2870 https://jira.onap.org/browse/CCSDK-2870 Signed-off-by: Rishi Chail Change-Id: I72afa3057a06a5af2507f8e45fe53230603d45ac --- .../org/onap/cps/rest/config/JerseyConfig.java | 2 +- .../onap/cps/rest/controller/RestController.java | 27 +++++----- cps/cps-rest/src/main/resources/schema.sql | 63 ---------------------- cps/cps-ri/src/main/resources/schema.sql | 58 ++++++++++++++++++++ 4 files changed, 71 insertions(+), 79 deletions(-) delete mode 100644 cps/cps-rest/src/main/resources/schema.sql create mode 100644 cps/cps-ri/src/main/resources/schema.sql 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 index ea273986c..290ad5d9e 100644 --- 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 @@ -31,7 +31,7 @@ import org.glassfish.jersey.server.ResourceConfig; import org.springframework.context.annotation.Configuration; @Configuration -@ApplicationPath("/api/v1") +@ApplicationPath("/api/cps") public class JerseyConfig extends ResourceConfig { /** 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 index 2cac690b1..68d101f3b 100644 --- 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 @@ -40,7 +40,8 @@ import org.opendaylight.yangtools.yang.model.parser.api.YangParserException; import org.springframework.beans.factory.annotation.Autowired; -@Path("cps") + +@Path("v1") public class RestController { @Autowired @@ -53,7 +54,7 @@ public class RestController { * @return a http response code. */ @POST - @Path("upload-yang-model-file") + @Path("/upload-yang-model-file") @Produces(MediaType.APPLICATION_JSON) @Consumes(MediaType.MULTIPART_FORM_DATA) public final Response uploadYangModelFile(@FormDataParam("file") File uploadedFile) throws IOException { @@ -62,9 +63,9 @@ public class RestController { final SchemaContext schemaContext = cpService.parseAndValidateModel(fileToParse); cpService.storeSchemaContext(schemaContext); return Response.status(Status.OK).entity("Yang File Parsed").build(); - } catch (YangParserException e) { + } catch (final YangParserException e) { return Response.status(Status.BAD_REQUEST).entity(e.getMessage()).build(); - } catch (Exception e) { + } catch (final Exception e) { return Response.status(Status.INTERNAL_SERVER_ERROR).entity(e.getMessage()).build(); } } @@ -76,7 +77,7 @@ public class RestController { * @return a http response code. */ @POST - @Path("upload-yang-json-data-file") + @Path("/upload-yang-json-data-file") @Produces(MediaType.APPLICATION_JSON) @Consumes(MediaType.MULTIPART_FORM_DATA) public final Response uploadYangJsonDataFile(@FormDataParam("file") String uploadedFile) { @@ -85,9 +86,9 @@ public class RestController { final int persistenceObjectId = cpService.storeJsonStructure(uploadedFile); return Response.status(Status.OK).entity("Object stored in CPS with identity: " + persistenceObjectId) .build(); - } catch (JsonSyntaxException e) { + } catch (final JsonSyntaxException e) { return Response.status(Status.BAD_REQUEST).entity(e.getMessage()).build(); - } catch (Exception e) { + } catch (final Exception e) { return Response.status(Status.INTERNAL_SERVER_ERROR).entity(e.getMessage()).build(); } } @@ -99,13 +100,13 @@ public class RestController { * @return a HTTP response. */ @GET - @Path("json-object/{id}") + @Path("/json-object/{id}") public final Response getJsonObjectById(@PathParam("id") int jsonObjectId) { try { return Response.status(Status.OK).entity(cpService.getJsonById(jsonObjectId)).build(); - } catch (PersistenceException e) { + } catch (final PersistenceException e) { return Response.status(Status.NOT_FOUND).entity(e.getMessage()).build(); - } catch (Exception e) { + } catch (final Exception e) { return Response.status(Status.INTERNAL_SERVER_ERROR).entity(e.getMessage()).build(); } } @@ -123,8 +124,4 @@ public class RestController { originalFile.renameTo(renamedFile); return renamedFile; } -} - - - - +} \ No newline at end of file diff --git a/cps/cps-rest/src/main/resources/schema.sql b/cps/cps-rest/src/main/resources/schema.sql deleted file mode 100644 index 446d6e584..000000000 --- a/cps/cps-rest/src/main/resources/schema.sql +++ /dev/null @@ -1,63 +0,0 @@ -/* Initialisation script for CPS. - -To be moved to cps-ri in Honolulu. */ - - -CREATE TABLE IF NOT EXISTS RELATION_TYPE -( - RELATION_TYPE TEXT NOT NULL, - ID SERIAL PRIMARY KEY -); - -CREATE TABLE IF NOT EXISTS DATASPACE -( - ID SERIAL PRIMARY KEY, - NAME TEXT NOT NULL, - CONSTRAINT "UQ_NAME" UNIQUE (NAME) -); - -CREATE TABLE IF NOT EXISTS SCHEMA_NODE -( - SCHEMA_NODE_IDENTIFIER TEXT NOT NULL, - ID SERIAL PRIMARY KEY -); - -CREATE TABLE IF NOT EXISTS MODULE_SET -( - MODULE_SET_REFERENCE TEXT NOT NULL, - ID SERIAL PRIMARY KEY -); - -CREATE TABLE IF NOT EXISTS FRAGMENT -( - ID BIGSERIAL PRIMARY KEY, - XPATH TEXT NOT NULL, - DATASPACE_ID INTEGER NOT NULL REFERENCES DATASPACE(ID), - ATTRIBUTES JSONB, - ANCHOR_ID BIGINT REFERENCES FRAGMENT(ID), - PARENT_ID BIGINT REFERENCES FRAGMENT(ID), - MODULE_SET_ID INTEGER REFERENCES MODULE_SET(ID), - SCHEMA_NODE_ID INTEGER REFERENCES SCHEMA_NODE(ID) -); - -CREATE TABLE IF NOT EXISTS RELATION -( - FROM_FRAGMENT_ID BIGINT NOT NULL REFERENCES FRAGMENT(ID), - TO_FRAGMENT_ID BIGINT NOT NULL REFERENCES FRAGMENT(ID), - RELATION_TYPE_ID INTEGER NOT NULL REFERENCES RELATION_TYPE(ID), - FROM_REL_XPATH TEXT NOT NULL, - TO_REL_XPATH TEXT NOT NULL, - CONSTRAINT RELATION_PKEY PRIMARY KEY (TO_FRAGMENT_ID, FROM_FRAGMENT_ID, RELATION_TYPE_ID) -); - -CREATE INDEX IF NOT EXISTS "FKI_FRAGMENT_DATASPACE_ID_FK" ON FRAGMENT USING BTREE(DATASPACE_ID) ; -CREATE INDEX IF NOT EXISTS "FKI_FRAGMENT_MODULE_SET_ID_FK" ON FRAGMENT USING BTREE(MODULE_SET_ID) ; -CREATE INDEX IF NOT EXISTS "FKI_FRAGMENT_PARENT_ID_FK" ON FRAGMENT USING BTREE(PARENT_ID) ; -CREATE INDEX IF NOT EXISTS "FKI_FRAGMENT_ANCHOR_ID_FK" ON FRAGMENT USING BTREE(ANCHOR_ID) ; -CREATE INDEX IF NOT EXISTS "PERF_SCHEMA_NODE_SCHEMA_NODE_ID" ON SCHEMA_NODE USING BTREE(SCHEMA_NODE_IDENTIFIER) ; -CREATE INDEX IF NOT EXISTS "FKI_SCHEMA_NODE_ID_TO_ID" ON FRAGMENT USING BTREE(SCHEMA_NODE_ID) ; -CREATE INDEX IF NOT EXISTS "FKI_RELATION_TYPE_ID_FK" ON RELATION USING BTREE(RELATION_TYPE_ID); -CREATE INDEX IF NOT EXISTS "FKI_RELATIONS_FROM_ID_FK" ON RELATION USING BTREE(FROM_FRAGMENT_ID); -CREATE INDEX IF NOT EXISTS "FKI_RELATIONS_TO_ID_FK" ON RELATION USING BTREE(TO_FRAGMENT_ID); -CREATE INDEX IF NOT EXISTS "PERF_MODULE_SET_MODULE_SET_REFERENCE" ON MODULE_SET USING BTREE(MODULE_SET_REFERENCE) ; -CREATE UNIQUE INDEX IF NOT EXISTS "UQ_FRAGMENT_XPATH"ON FRAGMENT USING btree(xpath COLLATE pg_catalog."default" text_pattern_ops, dataspace_id); \ No newline at end of file diff --git a/cps/cps-ri/src/main/resources/schema.sql b/cps/cps-ri/src/main/resources/schema.sql new file mode 100644 index 000000000..05d31d92f --- /dev/null +++ b/cps/cps-ri/src/main/resources/schema.sql @@ -0,0 +1,58 @@ +CREATE TABLE IF NOT EXISTS RELATION_TYPE +( + RELATION_TYPE TEXT NOT NULL, + ID SERIAL PRIMARY KEY +); + +CREATE TABLE IF NOT EXISTS DATASPACE +( + ID SERIAL PRIMARY KEY, + NAME TEXT NOT NULL, + CONSTRAINT "UQ_NAME" UNIQUE (NAME) +); + +CREATE TABLE IF NOT EXISTS SCHEMA_NODE +( + SCHEMA_NODE_IDENTIFIER TEXT NOT NULL, + ID SERIAL PRIMARY KEY +); + +CREATE TABLE IF NOT EXISTS MODULE_SET +( + MODULE_SET_REFERENCE TEXT NOT NULL, + ID SERIAL PRIMARY KEY +); + +CREATE TABLE IF NOT EXISTS FRAGMENT +( + ID BIGSERIAL PRIMARY KEY, + XPATH TEXT NOT NULL, + DATASPACE_ID INTEGER NOT NULL REFERENCES DATASPACE(ID), + ATTRIBUTES JSONB, + ANCHOR_ID BIGINT REFERENCES FRAGMENT(ID), + PARENT_ID BIGINT REFERENCES FRAGMENT(ID), + MODULE_SET_ID INTEGER REFERENCES MODULE_SET(ID), + SCHEMA_NODE_ID INTEGER REFERENCES SCHEMA_NODE(ID) +); + +CREATE TABLE IF NOT EXISTS RELATION +( + FROM_FRAGMENT_ID BIGINT NOT NULL REFERENCES FRAGMENT(ID), + TO_FRAGMENT_ID BIGINT NOT NULL REFERENCES FRAGMENT(ID), + RELATION_TYPE_ID INTEGER NOT NULL REFERENCES RELATION_TYPE(ID), + FROM_REL_XPATH TEXT NOT NULL, + TO_REL_XPATH TEXT NOT NULL, + CONSTRAINT RELATION_PKEY PRIMARY KEY (TO_FRAGMENT_ID, FROM_FRAGMENT_ID, RELATION_TYPE_ID) +); + +CREATE INDEX IF NOT EXISTS "FKI_FRAGMENT_DATASPACE_ID_FK" ON FRAGMENT USING BTREE(DATASPACE_ID) ; +CREATE INDEX IF NOT EXISTS "FKI_FRAGMENT_MODULE_SET_ID_FK" ON FRAGMENT USING BTREE(MODULE_SET_ID) ; +CREATE INDEX IF NOT EXISTS "FKI_FRAGMENT_PARENT_ID_FK" ON FRAGMENT USING BTREE(PARENT_ID) ; +CREATE INDEX IF NOT EXISTS "FKI_FRAGMENT_ANCHOR_ID_FK" ON FRAGMENT USING BTREE(ANCHOR_ID) ; +CREATE INDEX IF NOT EXISTS "PERF_SCHEMA_NODE_SCHEMA_NODE_ID" ON SCHEMA_NODE USING BTREE(SCHEMA_NODE_IDENTIFIER) ; +CREATE INDEX IF NOT EXISTS "FKI_SCHEMA_NODE_ID_TO_ID" ON FRAGMENT USING BTREE(SCHEMA_NODE_ID) ; +CREATE INDEX IF NOT EXISTS "FKI_RELATION_TYPE_ID_FK" ON RELATION USING BTREE(RELATION_TYPE_ID); +CREATE INDEX IF NOT EXISTS "FKI_RELATIONS_FROM_ID_FK" ON RELATION USING BTREE(FROM_FRAGMENT_ID); +CREATE INDEX IF NOT EXISTS "FKI_RELATIONS_TO_ID_FK" ON RELATION USING BTREE(TO_FRAGMENT_ID); +CREATE INDEX IF NOT EXISTS "PERF_MODULE_SET_MODULE_SET_REFERENCE" ON MODULE_SET USING BTREE(MODULE_SET_REFERENCE) ; +CREATE UNIQUE INDEX IF NOT EXISTS "UQ_FRAGMENT_XPATH"ON FRAGMENT USING btree(xpath COLLATE pg_catalog."default" text_pattern_ops, dataspace_id); \ No newline at end of file -- cgit 1.2.3-korg From 4dbcd00b188506d76f7b5721191e713ded0ae726 Mon Sep 17 00:00:00 2001 From: Rishi Chail Date: Thu, 15 Oct 2020 08:40:23 +0100 Subject: VSE: Delete a JSON Object Issue-ID: CCSDK-2760 https://jira.onap.org/browse/CCSDK-2760 Signed-off-by: Rishi Chail Change-Id: Ie6b3235c3eb17ce30b00533ea2b8a25a9823ef2c --- .../onap/cps/rest/controller/RestController.java | 21 +++++++++++++++++++++ .../cps/spi/impl/DataPersistencyServiceImpl.java | 15 ++++++++++++++- .../src/main/java/org/onap/cps/api/CpService.java | 7 +++++++ .../java/org/onap/cps/api/impl/CpServiceImpl.java | 7 ++++++- .../org/onap/cps/spi/DataPersistencyService.java | 9 ++++++++- .../org/onap/cps/api/impl/CpServiceImplSpec.groovy | 18 +++++++++++++++++- 6 files changed, 73 insertions(+), 4 deletions(-) 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 index 68d101f3b..e86d329ba 100644 --- 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 @@ -25,6 +25,7 @@ import java.io.File; import java.io.IOException; import javax.persistence.PersistenceException; 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; @@ -38,6 +39,7 @@ 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; @@ -111,6 +113,25 @@ public class RestController { } } + /** + * 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") 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); diff --git a/cps/cps-ri/src/main/java/org/onap/cps/spi/impl/DataPersistencyServiceImpl.java b/cps/cps-ri/src/main/java/org/onap/cps/spi/impl/DataPersistencyServiceImpl.java index 44d38f91d..2b4f1357d 100644 --- a/cps/cps-ri/src/main/java/org/onap/cps/spi/impl/DataPersistencyServiceImpl.java +++ b/cps/cps-ri/src/main/java/org/onap/cps/spi/impl/DataPersistencyServiceImpl.java @@ -38,19 +38,32 @@ public class DataPersistencyServiceImpl implements DataPersistencyService { * @param jsonStructure the JSON data structure. * @return the entity identifier. */ + @Override public final Integer storeJsonStructure(final String jsonStructure) { final JsonDataEntity jsonDataEntity = new JsonDataEntity(jsonStructure); dataRepository.save(jsonDataEntity); return jsonDataEntity.getId(); } - /** + /* * Return the JSON structure from the database using the object identifier. * * @param jsonStructureId the JSON object identifier. + * * @return the JSON structure from the database as a string. */ + @Override public final String getJsonById(final int jsonStructureId) { return dataRepository.getOne(jsonStructureId).getJsonStructure(); } + + /** + * Delete the JSON structure from the database using the object identifier. + * + * @param jsonStructureId the JSON object identifier. + */ + @Override + public void deleteJsonById(int jsonStructureId) { + dataRepository.deleteById(jsonStructureId); + } } diff --git a/cps/cps-service/src/main/java/org/onap/cps/api/CpService.java b/cps/cps-service/src/main/java/org/onap/cps/api/CpService.java index 2a8b2165b..177fc043a 100644 --- a/cps/cps-service/src/main/java/org/onap/cps/api/CpService.java +++ b/cps/cps-service/src/main/java/org/onap/cps/api/CpService.java @@ -67,4 +67,11 @@ public interface CpService { * @return the JSON structure. */ String getJsonById(final int jsonObjectId); + + /** + * Delete a JSON Object using the object identifier. + * + * @param jsonObjectId the JSON object identifier. + */ + void deleteJsonById(final int jsonObjectId); } diff --git a/cps/cps-service/src/main/java/org/onap/cps/api/impl/CpServiceImpl.java b/cps/cps-service/src/main/java/org/onap/cps/api/impl/CpServiceImpl.java index 4113fbc64..73138ccc1 100644 --- a/cps/cps-service/src/main/java/org/onap/cps/api/impl/CpServiceImpl.java +++ b/cps/cps-service/src/main/java/org/onap/cps/api/impl/CpServiceImpl.java @@ -51,7 +51,7 @@ public class CpServiceImpl implements CpService { @Override public final SchemaContext parseAndValidateModel(final String yangModelContent) throws IOException, - YangParserException { + YangParserException { final File tempFile = File.createTempFile("yang", ".yang"); try (BufferedWriter writer = new BufferedWriter(new FileWriter(tempFile))) { writer.write(yangModelContent); @@ -74,6 +74,11 @@ public class CpServiceImpl implements CpService { return dataPersistencyService.getJsonById(jsonObjectId); } + @Override + public void deleteJsonById(int jsonObjectId) { + dataPersistencyService.deleteJsonById(jsonObjectId);; + } + @Override public final void storeSchemaContext(final SchemaContext schemaContext) { for (final Module module : schemaContext.getModules()) { diff --git a/cps/cps-service/src/main/java/org/onap/cps/spi/DataPersistencyService.java b/cps/cps-service/src/main/java/org/onap/cps/spi/DataPersistencyService.java index 11f9ed0db..ce51f40ac 100644 --- a/cps/cps-service/src/main/java/org/onap/cps/spi/DataPersistencyService.java +++ b/cps/cps-service/src/main/java/org/onap/cps/spi/DataPersistencyService.java @@ -39,4 +39,11 @@ public interface DataPersistencyService { * @return a JSON Structure. */ String getJsonById(int jsonStructureId); -} + + /** + * Delete the JSON structure from the database using the entity identifier. + * + * @param jsonStructureId the json entity identifier. + */ + void deleteJsonById(int jsonStructureId); +} \ No newline at end of file diff --git a/cps/cps-service/src/test/groovy/org/onap/cps/api/impl/CpServiceImplSpec.groovy b/cps/cps-service/src/test/groovy/org/onap/cps/api/impl/CpServiceImplSpec.groovy index f112fa210..a2f9b3543 100644 --- a/cps/cps-service/src/test/groovy/org/onap/cps/api/impl/CpServiceImplSpec.groovy +++ b/cps/cps-service/src/test/groovy/org/onap/cps/api/impl/CpServiceImplSpec.groovy @@ -96,4 +96,20 @@ class CpServiceImplSpec extends Specification { then: 'the same exception is thrown by CPS' thrown(IllegalStateException) } -} + + def 'Delete a JSON object with a valid identifier'(){ + given: 'that the data persistence service can delete a JSON structure for identifier 1' + mockDataPersistencyService.deleteJsonById(1) + expect: 'No exception is thrown when we delete a JSON structure with identifier 1' + objectUnderTest.deleteJsonById(1) + } + + def 'Delete a JSON object with an identifier that does not exist'(){ + given: 'that the data persistence service throws an exception' + mockDataPersistencyService.deleteJsonById(_) >> {throw new IllegalStateException()} + when: 'we try to delete a JSON structure' + objectUnderTest.deleteJsonById(100); + then: 'the same exception is thrown by CPS' + thrown(IllegalStateException) + } +} \ No newline at end of file -- cgit 1.2.3-korg From 49c88d9f013f97d598a6c38f73fde2e9c9e9da5c Mon Sep 17 00:00:00 2001 From: Bruno Sakoto Date: Tue, 6 Oct 2020 22:09:58 -0400 Subject: Add swagger-ui It is available at http://{{host}}:{{port}}/swagger-ui/index.html Jira Link: https://jira.onap.org/browse/CCSDK-2895 Issue-ID: CCSDK-2895 Signed-off-by: Bruno Sakoto Change-Id: I5e8e39c90354506206bc43dfafbc11d0e62eee28 --- cps/README.md | 33 ++++++++- cps/cps-rest/pom.xml | 78 ++++++++++++++++++++++ .../org/onap/cps/rest/config/JerseyConfig.java | 17 ++++- cps/cps-rest/src/main/resources/application.yml | 2 + .../java/org/onap/cps/api/impl/CpServiceImpl.java | 3 +- cps/pom.xml | 4 ++ 6 files changed, 131 insertions(+), 6 deletions(-) diff --git a/cps/README.md b/cps/README.md index b6131a1fa..791015ef1 100644 --- a/cps/README.md +++ b/cps/README.md @@ -1,7 +1,34 @@ # Configuration & Persistency Service -This folder contains all files for +This folder contains all files for [Configuration & Persistency Service](https://wiki.onap.org/pages/viewpage.action?pageId=81406119). -The code here is related to CPS POC, then it must be kept self contained in this cps folder to prevent any impact on -current ccsdk components and to be ready to be moved in its own repo once CPS becomes a standalone project. \ No newline at end of file +The code here is related to CPS POC, then it must be kept self contained in this cps folder to prevent any impact on +current ccsdk components and to be ready to be moved in its own repo once CPS becomes a standalone project. + + +## Running Locally + +* Run a postgres container instance and create `cpsdb' database: + +``` +CREATE USER cps WITH PASSWORD 'cps'; +CREATE DATABASE cpsdb OWNER cps; +``` + +* Build (from cps root folder) + +```bash +mvn clean package +``` + +* Run (from cps root folder) + +```bash +java -DDB_HOST=localhost -DDB_USERNAME=cps -DDB_PASSWORD=cps -jar cps-rest/target/cps-rest-0.0.1-SNAPSHOT.jar +``` + +* Browse + * [Swagger UI](http://localhost:8080/swagger-ui/index.html) + * OpenAPI Specification in [JSON](http://localhost:8080/api/cps/openapi.json) + or [YAML](http://localhost:8080/api/cps/openapi.yaml) format diff --git a/cps/cps-rest/pom.xml b/cps/cps-rest/pom.xml index 2b4cbb894..274e57f52 100644 --- a/cps/cps-rest/pom.xml +++ b/cps/cps-rest/pom.xml @@ -28,6 +28,11 @@ jersey-media-multipart + + org.springframework + spring-webmvc + + org.springframework.boot spring-boot-starter-jersey @@ -83,6 +88,79 @@ + + + org.apache.maven.plugins + maven-dependency-plugin + ${maven-dependency-plugin.version} + + + prepare-package + + unpack + + + + + org.webjars + swagger-ui + ${swagger-ui.version} + + + ${project.build.directory}/swagger-ui-${swagger-ui.version} + + + + + + + org.apache.maven.plugins + maven-resources-plugin + ${maven-resources-plugin.version} + + + copy-resources + prepare-package + + copy-resources + + + ${project.build.outputDirectory}/static/swagger-ui + + + ${project.build.directory}/swagger-ui-${swagger-ui.version}/META-INF/resources/webjars/swagger-ui/${swagger-ui.version}/ + + **/*.gz + + + + + + + + + + com.google.code.maven-replacer-plugin + replacer + ${maven-replacer-plugin.version} + + + prepare-package + + replace + + + + + ${project.build.outputDirectory}/static/swagger-ui/index.html + + + https://petstore.swagger.io/v2/swagger.json + /api/cps/openapi.json + + + + 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 index 290ad5d9e..ac781d337 100644 --- 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 @@ -28,6 +28,9 @@ 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 @@ -43,8 +46,12 @@ public class JerseyConfig extends ResourceConfig { register(OpenApiResource.class); register(AcceptHeaderOpenApiResource.class); - packages("org.onap.cps.rest.controller"); + // Register controllers + register(ModelController.class); + register(RestController.class); + configureSwagger(); + configureSwaggerUI(); } private void configureSwagger() { @@ -54,4 +61,12 @@ public class JerseyConfig extends ResourceConfig { 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/resources/application.yml b/cps/cps-rest/src/main/resources/application.yml index 5cfa97415..c9154ba1f 100644 --- a/cps/cps-rest/src/main/resources/application.yml +++ b/cps/cps-rest/src/main/resources/application.yml @@ -19,6 +19,8 @@ spring: password: ${DB_PASSWORD} driverClassName: org.postgresql.Driver initialization-mode: always + jersey: + type: filter logging: level: diff --git a/cps/cps-service/src/main/java/org/onap/cps/api/impl/CpServiceImpl.java b/cps/cps-service/src/main/java/org/onap/cps/api/impl/CpServiceImpl.java index 4113fbc64..f9d066e46 100644 --- a/cps/cps-service/src/main/java/org/onap/cps/api/impl/CpServiceImpl.java +++ b/cps/cps-service/src/main/java/org/onap/cps/api/impl/CpServiceImpl.java @@ -77,8 +77,7 @@ public class CpServiceImpl implements CpService { @Override public final void storeSchemaContext(final SchemaContext schemaContext) { for (final Module module : schemaContext.getModules()) { - modelPersistencyService.storeModule(module.getName(), module.toString(), - module.getRevision().toString()); + modelPersistencyService.storeModule(module.getName(), module.toString(), module.getRevision().toString()); } } } diff --git a/cps/pom.xml b/cps/pom.xml index d81ee9e08..c70af6be8 100644 --- a/cps/pom.xml +++ b/cps/pom.xml @@ -26,6 +26,10 @@ 2.1.4 3.0.6 2.0-M2-groovy-3.0 + 3.1.2 + 3.2.0 + 1.5.3 + 3.35.0 -- cgit 1.2.3-korg From 6f523dbc6659ff5793f6707a71f2c401e1148d83 Mon Sep 17 00:00:00 2001 From: Rishi Chail Date: Wed, 21 Oct 2020 12:04:16 +0100 Subject: VSE: Introduce entities for fragment and dataspace Issue-ID: CCSDK-2898 https://jira.onap.org/browse/CCSDK-2898 Signed-off-by: Rishi Chail Change-Id: Iab733008021ea315707d4c4e6a6ec357f205ee05 --- cps/cps-ri/pom.xml | 6 + .../java/org/onap/cps/spi/entities/Dataspace.java | 52 ++++ .../java/org/onap/cps/spi/entities/Fragment.java | 76 ++++++ cps/cps-ri/src/main/resources/hibernate.properties | 1 + cps/pom.xml | 274 +++++++++++---------- 5 files changed, 273 insertions(+), 136 deletions(-) create mode 100644 cps/cps-ri/src/main/java/org/onap/cps/spi/entities/Dataspace.java create mode 100644 cps/cps-ri/src/main/java/org/onap/cps/spi/entities/Fragment.java create mode 100644 cps/cps-ri/src/main/resources/hibernate.properties diff --git a/cps/cps-ri/pom.xml b/cps/cps-ri/pom.xml index 334e47662..77cb5f86a 100644 --- a/cps/cps-ri/pom.xml +++ b/cps/cps-ri/pom.xml @@ -32,6 +32,12 @@ postgresql + + + com.vladmihalcea + hibernate-types-52 + ${hibernate-types.version} + org.projectlombok diff --git a/cps/cps-ri/src/main/java/org/onap/cps/spi/entities/Dataspace.java b/cps/cps-ri/src/main/java/org/onap/cps/spi/entities/Dataspace.java new file mode 100644 index 000000000..8f37692b1 --- /dev/null +++ b/cps/cps-ri/src/main/java/org/onap/cps/spi/entities/Dataspace.java @@ -0,0 +1,52 @@ +/* + * ============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.spi.entities; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.Table; +import javax.validation.constraints.NotNull; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; + +/** + * Entity to store a dataspace. + */ +@Getter +@Setter +@Entity +@AllArgsConstructor +@NoArgsConstructor +@Table(name = "dataspace") +public class Dataspace { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Integer id; + + @NotNull + @Column(columnDefinition = "text") + private String name; +} diff --git a/cps/cps-ri/src/main/java/org/onap/cps/spi/entities/Fragment.java b/cps/cps-ri/src/main/java/org/onap/cps/spi/entities/Fragment.java new file mode 100644 index 000000000..12422dc5f --- /dev/null +++ b/cps/cps-ri/src/main/java/org/onap/cps/spi/entities/Fragment.java @@ -0,0 +1,76 @@ +/*- + * ============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.spi.entities; + +import com.vladmihalcea.hibernate.type.json.JsonBinaryType; +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.FetchType; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.JoinColumn; +import javax.persistence.ManyToOne; +import javax.persistence.OneToOne; +import javax.validation.constraints.NotNull; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; +import org.hibernate.annotations.Type; +import org.hibernate.annotations.TypeDef; +import org.hibernate.annotations.TypeDefs; + +/** + * Entity to store a fragment. + */ +@Getter +@Setter +@Entity +@AllArgsConstructor +@NoArgsConstructor +@TypeDefs({@TypeDef(name = "jsonb", typeClass = JsonBinaryType.class)}) +public class Fragment { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @NotNull + @Column(columnDefinition = "text") + private String xpath; + + @Type(type = "jsonb") + @Column(columnDefinition = "jsonb") + private String attributes; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "dataspace_id") + private Dataspace dataspace; + + @OneToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "anchor_id") + private Fragment anchorFragment; + + @OneToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "parent_id") + private Fragment parentFragment; +} diff --git a/cps/cps-ri/src/main/resources/hibernate.properties b/cps/cps-ri/src/main/resources/hibernate.properties new file mode 100644 index 000000000..a22fe63cf --- /dev/null +++ b/cps/cps-ri/src/main/resources/hibernate.properties @@ -0,0 +1 @@ +hibernate.types.print.banner=false \ No newline at end of file diff --git a/cps/pom.xml b/cps/pom.xml index c70af6be8..4e9ca39db 100644 --- a/cps/pom.xml +++ b/cps/pom.xml @@ -1,151 +1,153 @@ - 4.0.0 - - org.onap.oparent - oparent - 3.1.0 - - org.onap.cps - cps - 0.0.1-SNAPSHOT - pom - cps - ONAP Configuration and Persistency Service - - ONAP - CPS - http://www.onap.org/ - + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> + 4.0.0 + + org.onap.oparent + oparent + 3.1.0 + + org.onap.cps + cps + 0.0.1-SNAPSHOT + pom + cps + ONAP Configuration and Persistency Service + + ONAP - CPS + http://www.onap.org/ + - - 11 - 2.3.3.RELEASE - 3.1.0 - 5.0.6 - 2.1.4 - 3.0.6 - 2.0-M2-groovy-3.0 - 3.1.2 - 3.2.0 - 1.5.3 - 3.35.0 - + + 11 + 2.3.3.RELEASE + 3.1.0 + 5.0.6 + 2.1.4 + 3.0.6 + 2.0-M2-groovy-3.0 + 3.1.2 + 3.2.0 + 1.5.3 + 3.35.0 + 2.10.0 + - - - - org.springframework.boot - spring-boot-dependencies - ${springboot.version} - pom - import - - - + + + + org.springframework.boot + spring-boot-dependencies + ${springboot.version} + pom + import + + + - - - - src/main/resources - true - + + + + src/main/resources + true + - - target/generated-sources/license - - third-party-licenses.txt - - + + target/generated-sources/license + + third-party-licenses.txt + + - - target/generated-resources/licenses - - *.* - - third-party-licenses - - + + target/generated-resources/licenses + + *.* + + third-party-licenses + + - - - org.apache.maven.plugins - maven-compiler-plugin - - ${java.version} - ${java.version} - - + + + org.apache.maven.plugins + maven-compiler-plugin + + ${java.version} + ${java.version} + + - - org.apache.maven.plugins - maven-checkstyle-plugin - - - onap-java-style - - check - - process-sources - - onap-checkstyle/onap-java-style.xml - ${project.build.sourceDirectory} - true - true - true - false - warning - true - - - + + org.apache.maven.plugins + maven-checkstyle-plugin + + + onap-java-style + + check + + process-sources + + onap-checkstyle/onap-java-style.xml + ${project.build.sourceDirectory} + true + true + true + false + warning + true + + + - - - org.onap.oparent - checkstyle - ${oparent.version} - - + + + org.onap.oparent + checkstyle + ${oparent.version} + + - + - - - - org.codehaus.gmavenplus - gmavenplus-plugin - 1.9.0 - - - - compileTests - - - - - - - org.apache.maven.plugins - maven-surefire-plugin - 3.0.0-M5 - - false - - **/*Spec.java - **/*Test.java - - - + + + + org.codehaus.gmavenplus + gmavenplus-plugin + 1.9.0 + + + + compileTests + + + + + + + org.apache.maven.plugins + maven-surefire-plugin + 3.0.0-M5 + + false + + **/*Spec.java + **/*Test.java + + + - - + + - - cps-service - cps-rest - cps-ri - + + cps-service + cps-rest + cps-ri + -- cgit 1.2.3-korg From f7ba359b048cb6f7dc12a00df872b9c19eda76ba Mon Sep 17 00:00:00 2001 From: niamhcore Date: Mon, 19 Oct 2020 12:48:06 +0100 Subject: Adding swagger codegen Jira Link: https://jira.onap.org/browse/CCSDK-2907 Issue-ID: CCSDK-2907 Signed-off-by: Niamh Core Change-Id: I07c27cd1709f9bc19d67443daaf0c9c59507a5a0 --- cps/cps-rest/docs/api/swagger/openapi.yml | 402 +++++++++++++++++++++ cps/cps-rest/pom.xml | 57 ++- .../org/onap/cps/rest/config/JerseyConfig.java | 2 +- .../onap/cps/rest/controller/RestController.java | 65 +++- cps/pom.xml | 35 +- 5 files changed, 535 insertions(+), 26 deletions(-) create mode 100644 cps/cps-rest/docs/api/swagger/openapi.yml diff --git a/cps/cps-rest/docs/api/swagger/openapi.yml b/cps/cps-rest/docs/api/swagger/openapi.yml new file mode 100644 index 000000000..1f9019a63 --- /dev/null +++ b/cps/cps-rest/docs/api/swagger/openapi.yml @@ -0,0 +1,402 @@ +openapi: 3.0.1 +info: + title: CPS API + description: Configuration Persistence Service API + version: "1.0" +servers: + - url: //localhost:8088/ +tags: + - name: cps-resource + description: cps Resource +paths: + /v1/dataspaces/{dataspace-name}/: + delete: + tags: + - cps-resource + summary: Delete the given dataspace + operationId: deleteDataspace + parameters: + - name: dataspace-name + in: path + description: dataspace-name + required: true + schema: + type: integer + format: int32 + responses: + 200: + description: OK + content: + application/json: + schema: + type: object + 204: + description: No Content + content: {} + 401: + description: Unauthorized + content: {} + 403: + description: Forbidden + content: {} + /v1/dataspaces/{dataspace-name}/anchors: + get: + tags: + - cps-resource + summary: Read all anchors, given a dataspace + operationId: getAnchors + parameters: + - name: dataspace-name + in: path + description: dataspace-name + required: true + schema: + type: integer + format: int32 + responses: + 200: + description: OK + content: + application/json: + schema: + type: object + 401: + description: Unauthorized + content: {} + 403: + description: Forbidden + content: {} + 404: + description: Not Found + content: {} + post: + tags: + - cps-resource + summary: Create a new anchor in the given dataspace + operationId: createAnchor + parameters: + - name: dataspace-name + in: path + description: dataspace-name + required: true + schema: + type: integer + format: int32 + requestBody: + content: + multipart/form-data: + schema: + required: + - file + properties: + file: + type: string + description: file + format: binary + required: true + responses: + 200: + description: OK + content: + application/json: + schema: + type: object + 201: + description: Created + content: {} + 401: + description: Unauthorized + content: {} + 403: + description: Forbidden + content: {} + 404: + description: Not Found + content: {} + /v1/dataspaces/{dataspace-name}/anchors/{anchor-name}: + get: + tags: + - cps-resource + summary: Read an anchor given a anchor and a dataspace + operationId: getAnchor + parameters: + - name: dataspace-name + in: path + description: dataspace-name + required: true + schema: + type: integer + format: int32 + - name: anchor-name + in: path + description: anchor-name + required: true + schema: + type: integer + format: int32 + responses: + 200: + description: OK + content: + application/json: + schema: + type: object + 401: + description: Unauthorized + content: {} + 403: + description: Forbidden + content: {} + 404: + description: Not Found + content: {} + delete: + tags: + - cps-resource + summary: Delete an anchor given a anchor and a dataspace + operationId: deleteAnchor + parameters: + - name: dataspace-name + in: path + description: dataspace-name + required: true + schema: + type: integer + format: int32 + - name: anchor-name + in: path + description: anchor-name + required: true + schema: + type: integer + format: int32 + responses: + 200: + description: OK + content: + application/json: + schema: + type: object + 204: + description: No Content + content: {} + 401: + description: Unauthorized + content: {} + 403: + description: Forbidden + content: {} + /v1/dataspaces/{dataspace-name}/anchors/{anchor-name}/nodes: + get: + tags: + - cps-resource + summary: Get a node given an anchor for the given dataspace + operationId: getNodeByDataspaceAndAnchor + parameters: + - name: dataspaceName + in: path + description: dataspaceName + required: true + schema: + type: integer + format: int32 + - name: anchorpoint + in: path + description: anchorpoint + required: true + schema: + type: integer + format: int32 + requestBody: + description: xpath + content: + application/json: + schema: + type: string + required: true + responses: + 200: + description: OK + content: + application/json: + schema: + type: object + 401: + description: Unauthorized + content: {} + 403: + description: Forbidden + content: {} + 404: + description: Not Found + content: {} + x-codegen-request-body-name: xpath + /v1/dataspaces/{dataspace-name}/modules: + get: + tags: + - cps-resource + summary: Read all yang modules in the store + operationId: getModule + parameters: + - name: dataspaceName + in: path + description: dataspaceName + required: true + schema: + type: integer + format: int32 + - name: namespace-name + in: query + description: namespace-name + schema: + type: integer + format: int32 + - name: revision + in: query + description: revision + schema: + type: integer + format: int32 + responses: + 200: + description: OK + content: + application/json: + schema: + type: object + 401: + description: Unauthorized + content: {} + 403: + description: Forbidden + content: {} + 404: + description: Not Found + content: {} + post: + tags: + - cps-resource + summary: Create modules for the given dataspace + operationId: createModules + parameters: + - name: dataspace-name + in: path + description: dataspace-name + required: true + schema: + type: integer + format: int32 + requestBody: + content: + multipart/form-data: + schema: + required: + - file + properties: + file: + type: string + description: file + format: binary + required: true + responses: + 200: + description: OK + content: + application/json: + schema: + type: object + 201: + description: Created + content: {} + 401: + description: Unauthorized + content: {} + 403: + description: Forbidden + content: {} + 404: + description: Not Found + content: {} + /v1/dataspaces/{dataspace-name}/nodes: + get: + tags: + - cps-resource + summary: Get all nodes for a given dataspace using an xpath or schema node identifier + operationId: getNode + parameters: + - name: dataspaceName + in: path + description: dataspaceName + required: true + schema: + type: integer + format: int32 + requestBody: + description: requestBody + content: + application/json: + schema: + type: string + required: true + responses: + 200: + description: OK + content: + application/json: + schema: + type: object + 401: + description: Unauthorized + content: {} + 403: + description: Forbidden + content: {} + 404: + description: Not Found + content: {} + x-codegen-request-body-name: requestBody + post: + tags: + - cps-resource + summary: Create a node for a given anchor for the given dataspace + operationId: createNode + parameters: + - name: dataspace-name + in: path + description: dataspace-name + required: true + schema: + type: integer + format: int32 + requestBody: + content: + multipart/form-data: + schema: + required: + - file + properties: + file: + type: string + description: file + format: binary + required: true + responses: + 200: + description: OK + content: + application/json: + schema: + type: object + 201: + description: Created + content: {} + 401: + description: Unauthorized + content: {} + 403: + description: Forbidden + content: {} + 404: + description: Not Found + content: {} +components: {} diff --git a/cps/cps-rest/pom.xml b/cps/cps-rest/pom.xml index 274e57f52..3cecc5f73 100644 --- a/cps/cps-rest/pom.xml +++ b/cps/cps-rest/pom.xml @@ -1,6 +1,6 @@ + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 cps-rest @@ -72,6 +72,21 @@ + + + + org.apache.cxf + cxf-bundle-jaxrs + ${cxf-bundle-jaxrs.version} + + + + + org.apache.cxf + cxf-rt-rs-service-description + ${cxf-rt-rs-service.version} + + @@ -88,6 +103,33 @@ + + + io.swagger.codegen.v3 + swagger-codegen-maven-plugin + ${swagger-codegen.version} + + + + generate + + + ${project.basedir}/docs/api/swagger/openapi.yml + org.onap.cps.rest.controller + org.onap.cps.rest.model + org.onap.cps.rest.controller + jaxrs-cxf + true + + src/gen/java + java8 + jersey2 + true + + + + + org.apache.maven.plugins @@ -107,7 +149,9 @@ ${swagger-ui.version} - ${project.build.directory}/swagger-ui-${swagger-ui.version} + + ${project.build.directory}/swagger-ui-${swagger-ui.version} + @@ -125,10 +169,13 @@ copy-resources - ${project.build.outputDirectory}/static/swagger-ui + ${project.build.outputDirectory}/static/swagger-ui + - ${project.build.directory}/swagger-ui-${swagger-ui.version}/META-INF/resources/webjars/swagger-ui/${swagger-ui.version}/ + + ${project.build.directory}/swagger-ui-${swagger-ui.version}/META-INF/resources/webjars/swagger-ui/${swagger-ui.version}/ + **/*.gz 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 index ac781d337..553c16b55 100644 --- 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 @@ -34,7 +34,7 @@ import org.onap.cps.rest.controller.RestController; import org.springframework.context.annotation.Configuration; @Configuration -@ApplicationPath("/api/cps") +@ApplicationPath("api") public class JerseyConfig extends ResourceConfig { /** 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 index e86d329ba..18e24b437 100644 --- 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 @@ -23,7 +23,9 @@ import com.google.gson.Gson; import com.google.gson.JsonSyntaxException; import java.io.File; import java.io.IOException; +import java.io.InputStream; import javax.persistence.PersistenceException; +import javax.validation.Valid; import javax.ws.rs.Consumes; import javax.ws.rs.DELETE; import javax.ws.rs.GET; @@ -34,6 +36,9 @@ 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 javax.ws.rs.core.SecurityContext; +import org.apache.cxf.jaxrs.ext.multipart.Attachment; +import org.glassfish.jersey.media.multipart.FormDataContentDisposition; import org.glassfish.jersey.media.multipart.FormDataParam; import org.onap.cps.api.CpService; import org.opendaylight.yangtools.yang.model.api.SchemaContext; @@ -41,14 +46,66 @@ import org.opendaylight.yangtools.yang.model.parser.api.YangParserException; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.dao.EmptyResultDataAccessException; - - -@Path("v1") -public class RestController { +@Path("cps") +public class RestController implements CpsResourceApi { @Autowired private CpService cpService; + @Override + public Object createAnchor(Attachment fileDetail, Integer dataspaceName) { + return null; + } + + @Override + public Object createModules(Attachment fileDetail, Integer dataspaceName) { + return null; + } + + @Override + public Object createNode(Attachment fileDetail, Integer dataspaceName) { + return null; + } + + @Override + public Object deleteAnchor(Integer dataspaceName, Integer anchorName) { + return null; + } + + @Override + public Object deleteDataspace(Integer dataspaceName) { + return null; + } + + @Override + public Object getAnchor(Integer dataspaceName, Integer anchorName) { + return null; + } + + @Override + public Object getAnchors(Integer dataspaceName) { + return null; + } + + @Override + public Object getModule(Integer dataspaceName, Integer namespaceName, Integer revision) { + return null; + } + + @Override + public Object getNode(@Valid String body, Integer dataspaceName) { + return null; + } + + @Override + public Object getNodeByDataspaceAndAnchor(@Valid String body, Integer dataspaceName, Integer anchorpoint) { + return null; + } + + /* + Old rest endpoints before contract first approach (Need to be removed). + */ + /** * Upload a yang model file. * diff --git a/cps/pom.xml b/cps/pom.xml index 4e9ca39db..dd98ca586 100644 --- a/cps/pom.xml +++ b/cps/pom.xml @@ -18,20 +18,23 @@ http://www.onap.org/ - - 11 - 2.3.3.RELEASE - 3.1.0 - 5.0.6 - 2.1.4 - 3.0.6 - 2.0-M2-groovy-3.0 - 3.1.2 - 3.2.0 - 1.5.3 - 3.35.0 - 2.10.0 - + + 11 + 2.3.3.RELEASE + 3.1.0 + 5.0.6 + 2.1.4 + 3.0.6 + 2.0-M2-groovy-3.0 + 3.0.18 + 3.0.0 + 2.2.9 + 3.1.2 + 3.2.0 + 1.5.3 + 3.35.0 + 2.10.0 + @@ -113,7 +116,7 @@ - org.codehaus.gmavenplus gmavenplus-plugin @@ -126,7 +129,7 @@ - org.apache.maven.plugins -- cgit 1.2.3-korg From 252b950552a9815f2680c457e7bd0e8af9f610f7 Mon Sep 17 00:00:00 2001 From: "puthuparambil.aditya" Date: Tue, 20 Oct 2020 12:23:34 +0100 Subject: VSE: Upload modules (a model file) to a (new) dataspace 1. Schema.sql modified to include modules and json_data tables which can be removed after the PoC 2. URI changed as per the proposal to '/dataspaces/{dataspace_name}/modules' 3. Dataspace name corresponding to a model is passed as a parameter. 4. In case the dataspace doesnt exist in the dataspace table, a new entry for the passed dataspace is created. 5. The corresponding dataspace_id is also stored as a reference in the modules table. 6. Test case for Rest API will be pushed as another review. JIRA: https://jira.onap.org/browse/CCSDK-2897 Issue-ID: CCSDK-2897 Change-Id: Ic9caa39b5a7afca28c0365cdb4f492848d0ead3e Signed-off-by: puthuparambil.aditya --- cps/README.md | 4 +-- .../onap/cps/rest/controller/RestController.java | 18 ++++++------ .../java/org/onap/cps/spi/entities/Dataspace.java | 12 +++++++- .../org/onap/cps/spi/entities/ModuleEntity.java | 28 ++++++++++++++----- .../cps/spi/impl/ModelPersistencyServiceImpl.java | 20 +++++++++++--- .../cps/spi/repository/DataspaceRepository.java | 32 ++++++++++++++++++++++ .../onap/cps/spi/repository/ModuleRepository.java | 1 - cps/cps-ri/src/main/resources/schema.sql | 17 ++++++++---- cps/cps-service/pom.xml | 8 +----- .../src/main/java/org/onap/cps/api/CpService.java | 4 ++- .../java/org/onap/cps/api/impl/CpServiceImpl.java | 18 ++++++------ .../org/onap/cps/spi/ModelPersistencyService.java | 7 +++-- .../org/onap/cps/api/impl/CpServiceImplSpec.groovy | 6 ++-- cps/pom.xml | 21 ++++++++++++++ 14 files changed, 145 insertions(+), 51 deletions(-) create mode 100644 cps/cps-ri/src/main/java/org/onap/cps/spi/repository/DataspaceRepository.java diff --git a/cps/README.md b/cps/README.md index 791015ef1..d1bf49d8c 100644 --- a/cps/README.md +++ b/cps/README.md @@ -1,7 +1,7 @@ -# Configuration & Persistency Service +# Configuration Persistence Service This folder contains all files for -[Configuration & Persistency Service](https://wiki.onap.org/pages/viewpage.action?pageId=81406119). +[Configuration Persistence Service](https://wiki.onap.org/pages/viewpage.action?pageId=81406119). The code here is related to CPS POC, then it must be kept self contained in this cps folder to prevent any impact on current ccsdk components and to be ready to be moved in its own repo once CPS becomes a standalone project. 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 index 18e24b437..703e77823 100644 --- 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 @@ -1,6 +1,7 @@ /* * ============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. @@ -22,8 +23,6 @@ package org.onap.cps.rest.controller; import com.google.gson.Gson; import com.google.gson.JsonSyntaxException; import java.io.File; -import java.io.IOException; -import java.io.InputStream; import javax.persistence.PersistenceException; import javax.validation.Valid; import javax.ws.rs.Consumes; @@ -36,10 +35,9 @@ 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 javax.ws.rs.core.SecurityContext; import org.apache.cxf.jaxrs.ext.multipart.Attachment; -import org.glassfish.jersey.media.multipart.FormDataContentDisposition; 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; @@ -110,19 +108,21 @@ public class RestController implements CpsResourceApi { * 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("/upload-yang-model-file") + @Path("/dataspaces/{dataspace_name}/modules") @Produces(MediaType.APPLICATION_JSON) @Consumes(MediaType.MULTIPART_FORM_DATA) - public final Response uploadYangModelFile(@FormDataParam("file") File uploadedFile) throws IOException { + 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); - return Response.status(Status.OK).entity("Yang File Parsed").build(); - } catch (final YangParserException e) { + 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(); diff --git a/cps/cps-ri/src/main/java/org/onap/cps/spi/entities/Dataspace.java b/cps/cps-ri/src/main/java/org/onap/cps/spi/entities/Dataspace.java index 8f37692b1..627a14467 100644 --- a/cps/cps-ri/src/main/java/org/onap/cps/spi/entities/Dataspace.java +++ b/cps/cps-ri/src/main/java/org/onap/cps/spi/entities/Dataspace.java @@ -31,6 +31,7 @@ import lombok.Getter; import lombok.NoArgsConstructor; import lombok.Setter; + /** * Entity to store a dataspace. */ @@ -49,4 +50,13 @@ public class Dataspace { @NotNull @Column(columnDefinition = "text") private String name; -} + + /** + * Initialize a Dataspace . + * + * @param name the Dataspace name. + */ + public Dataspace(String name) { + this.name = name; + } +} \ No newline at end of file diff --git a/cps/cps-ri/src/main/java/org/onap/cps/spi/entities/ModuleEntity.java b/cps/cps-ri/src/main/java/org/onap/cps/spi/entities/ModuleEntity.java index f786c58f1..d2130aeec 100644 --- a/cps/cps-ri/src/main/java/org/onap/cps/spi/entities/ModuleEntity.java +++ b/cps/cps-ri/src/main/java/org/onap/cps/spi/entities/ModuleEntity.java @@ -1,6 +1,7 @@ /* * ============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. @@ -21,10 +22,14 @@ package org.onap.cps.spi.entities; import javax.persistence.Column; import javax.persistence.Entity; +import javax.persistence.FetchType; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; +import javax.persistence.JoinColumn; +import javax.persistence.ManyToOne; import javax.persistence.Table; +import javax.validation.constraints.NotNull; import lombok.AllArgsConstructor; import lombok.Getter; import lombok.NoArgsConstructor; @@ -39,32 +44,41 @@ import lombok.Setter; @Entity @AllArgsConstructor @NoArgsConstructor -@Table(name = "modules") +@Table(name = "module") public class ModuleEntity { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Integer id; - @Column - private String name; - + @NotNull @Column private String moduleContent; + @NotNull @Column private String revision; + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "dataspace_id", referencedColumnName = "ID") + private Dataspace dataspace; + + @NotNull + @Column + private String namespace; + /** * Initialize a module entity. * - * @param name the module name. + * @param namespace the module namespace. * @param moduleContent the module content. * @param revision the revision number of the module. + * @param dataspace the dataspace related to the module. */ - public ModuleEntity(String name, String moduleContent, String revision) { - this.name = name; + public ModuleEntity(String namespace, String moduleContent, String revision, Dataspace dataspace) { + this.namespace = namespace; this.moduleContent = moduleContent; this.revision = revision; + this.dataspace = dataspace; } } \ No newline at end of file diff --git a/cps/cps-ri/src/main/java/org/onap/cps/spi/impl/ModelPersistencyServiceImpl.java b/cps/cps-ri/src/main/java/org/onap/cps/spi/impl/ModelPersistencyServiceImpl.java index 14085c7cf..01c7a7b53 100644 --- a/cps/cps-ri/src/main/java/org/onap/cps/spi/impl/ModelPersistencyServiceImpl.java +++ b/cps/cps-ri/src/main/java/org/onap/cps/spi/impl/ModelPersistencyServiceImpl.java @@ -1,6 +1,7 @@ /* * ============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. @@ -20,7 +21,9 @@ package org.onap.cps.spi.impl; import org.onap.cps.spi.ModelPersistencyService; +import org.onap.cps.spi.entities.Dataspace; import org.onap.cps.spi.entities.ModuleEntity; +import org.onap.cps.spi.repository.DataspaceRepository; import org.onap.cps.spi.repository.ModuleRepository; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; @@ -31,15 +34,24 @@ public class ModelPersistencyServiceImpl implements ModelPersistencyService { private final ModuleRepository moduleRepository; + private final DataspaceRepository dataspaceRepository; + @Autowired - public ModelPersistencyServiceImpl(final ModuleRepository moduleRepository) { + public ModelPersistencyServiceImpl(final ModuleRepository moduleRepository, + final DataspaceRepository dataspaceRepository) { this.moduleRepository = moduleRepository; + this.dataspaceRepository = dataspaceRepository; } @Override - public void storeModule(final String name, final String moduleContent, final String revision) { - final ModuleEntity moduleEntity = new ModuleEntity(name, moduleContent, revision); + public void storeModule(final String namespace, final String moduleContent, final String revision, + final String dataspaceName) { + final Dataspace dataspace = new Dataspace(dataspaceName); + if (Boolean.FALSE.equals(dataspaceRepository.existsByName(dataspaceName))) { + dataspaceRepository.save(dataspace); + } + dataspace.setId(dataspaceRepository.findByName(dataspaceName).getId()); + final ModuleEntity moduleEntity = new ModuleEntity(namespace, moduleContent, revision, dataspace); moduleRepository.save(moduleEntity); - } } diff --git a/cps/cps-ri/src/main/java/org/onap/cps/spi/repository/DataspaceRepository.java b/cps/cps-ri/src/main/java/org/onap/cps/spi/repository/DataspaceRepository.java new file mode 100644 index 000000000..46a526610 --- /dev/null +++ b/cps/cps-ri/src/main/java/org/onap/cps/spi/repository/DataspaceRepository.java @@ -0,0 +1,32 @@ +/* + * ============LICENSE_START======================================================= + * 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.spi.repository; + + +import org.onap.cps.spi.entities.Dataspace; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; + +@Repository +public interface DataspaceRepository extends JpaRepository { + Boolean existsByName(String name); //Checks if there are any records by name() + + Dataspace findByName(String name); +} \ No newline at end of file diff --git a/cps/cps-ri/src/main/java/org/onap/cps/spi/repository/ModuleRepository.java b/cps/cps-ri/src/main/java/org/onap/cps/spi/repository/ModuleRepository.java index 0fe53b621..f9078d7c1 100644 --- a/cps/cps-ri/src/main/java/org/onap/cps/spi/repository/ModuleRepository.java +++ b/cps/cps-ri/src/main/java/org/onap/cps/spi/repository/ModuleRepository.java @@ -26,5 +26,4 @@ import org.springframework.stereotype.Repository; @Repository public interface ModuleRepository extends JpaRepository { - } \ No newline at end of file diff --git a/cps/cps-ri/src/main/resources/schema.sql b/cps/cps-ri/src/main/resources/schema.sql index 05d31d92f..6a76fbd19 100644 --- a/cps/cps-ri/src/main/resources/schema.sql +++ b/cps/cps-ri/src/main/resources/schema.sql @@ -17,12 +17,6 @@ CREATE TABLE IF NOT EXISTS SCHEMA_NODE ID SERIAL PRIMARY KEY ); -CREATE TABLE IF NOT EXISTS MODULE_SET -( - MODULE_SET_REFERENCE TEXT NOT NULL, - ID SERIAL PRIMARY KEY -); - CREATE TABLE IF NOT EXISTS FRAGMENT ( ID BIGSERIAL PRIMARY KEY, @@ -45,6 +39,17 @@ CREATE TABLE IF NOT EXISTS RELATION CONSTRAINT RELATION_PKEY PRIMARY KEY (TO_FRAGMENT_ID, FROM_FRAGMENT_ID, RELATION_TYPE_ID) ); +CREATE TABLE IF NOT EXISTS MODULE +( + NAMESPACE TEXT NOT NULL, + REVISION TEXT NOT NULL, + MODULE_CONTENT TEXT NOT NULL, + DATASPACE_ID BIGINT NOT NULL, + ID SERIAL PRIMARY KEY, + UNIQUE (NAMESPACE, REVISION), + CONSTRAINT module_dataspace FOREIGN KEY (DATASPACE_ID) REFERENCES DATASPACE (id) ON UPDATE CASCADE ON DELETE CASCADE +); + CREATE INDEX IF NOT EXISTS "FKI_FRAGMENT_DATASPACE_ID_FK" ON FRAGMENT USING BTREE(DATASPACE_ID) ; CREATE INDEX IF NOT EXISTS "FKI_FRAGMENT_MODULE_SET_ID_FK" ON FRAGMENT USING BTREE(MODULE_SET_ID) ; CREATE INDEX IF NOT EXISTS "FKI_FRAGMENT_PARENT_ID_FK" ON FRAGMENT USING BTREE(PARENT_ID) ; diff --git a/cps/cps-service/pom.xml b/cps/cps-service/pom.xml index 731873420..ea1bdad39 100644 --- a/cps/cps-service/pom.xml +++ b/cps/cps-service/pom.xml @@ -60,25 +60,19 @@ - org.codehaus.groovy groovy - ${groovy.version} - test org.spockframework spock-core - ${spock-core.version} - test cglib cglib-nodep - 3.1 - test + diff --git a/cps/cps-service/src/main/java/org/onap/cps/api/CpService.java b/cps/cps-service/src/main/java/org/onap/cps/api/CpService.java index 177fc043a..2f735abc7 100644 --- a/cps/cps-service/src/main/java/org/onap/cps/api/CpService.java +++ b/cps/cps-service/src/main/java/org/onap/cps/api/CpService.java @@ -1,6 +1,7 @@ /* * ============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. @@ -49,8 +50,9 @@ public interface CpService { * Store schema context for a yang model. * * @param schemaContext the schema context + * @param dataspaceName the dataspace name */ - void storeSchemaContext(final SchemaContext schemaContext); + void storeSchemaContext(final SchemaContext schemaContext, final String dataspaceName); /** * Store the JSON structure in the database. diff --git a/cps/cps-service/src/main/java/org/onap/cps/api/impl/CpServiceImpl.java b/cps/cps-service/src/main/java/org/onap/cps/api/impl/CpServiceImpl.java index 80a685b09..45aad3e44 100644 --- a/cps/cps-service/src/main/java/org/onap/cps/api/impl/CpServiceImpl.java +++ b/cps/cps-service/src/main/java/org/onap/cps/api/impl/CpServiceImpl.java @@ -1,6 +1,7 @@ /* * ============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. @@ -19,20 +20,19 @@ package org.onap.cps.api.impl; - import java.io.BufferedWriter; import java.io.File; import java.io.FileWriter; import java.io.IOException; +import java.util.Optional; import org.onap.cps.api.CpService; import org.onap.cps.spi.DataPersistencyService; import org.onap.cps.spi.ModelPersistencyService; import org.onap.cps.utils.YangUtils; +import org.opendaylight.yangtools.yang.common.Revision; import org.opendaylight.yangtools.yang.model.api.Module; import org.opendaylight.yangtools.yang.model.api.SchemaContext; import org.opendaylight.yangtools.yang.model.parser.api.YangParserException; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; @@ -40,15 +40,12 @@ import org.springframework.stereotype.Component; @Component public class CpServiceImpl implements CpService { - private static final Logger LOGGER = LoggerFactory.getLogger(CpServiceImpl.class); - @Autowired private ModelPersistencyService modelPersistencyService; @Autowired private DataPersistencyService dataPersistencyService; - @Override public final SchemaContext parseAndValidateModel(final String yangModelContent) throws IOException, YangParserException { @@ -76,13 +73,16 @@ public class CpServiceImpl implements CpService { @Override public void deleteJsonById(int jsonObjectId) { - dataPersistencyService.deleteJsonById(jsonObjectId);; + dataPersistencyService.deleteJsonById(jsonObjectId); } @Override - public final void storeSchemaContext(final SchemaContext schemaContext) { + public final void storeSchemaContext(final SchemaContext schemaContext, final String dataspaceName) { for (final Module module : schemaContext.getModules()) { - modelPersistencyService.storeModule(module.getName(), module.toString(), module.getRevision().toString()); + Optional optionalRevision = module.getRevision(); + String revisionValue = optionalRevision.isPresent() ? optionalRevision.get().toString() : null; + modelPersistencyService.storeModule(module.getNamespace().toString(), module.toString(), + revisionValue, dataspaceName); } } } diff --git a/cps/cps-service/src/main/java/org/onap/cps/spi/ModelPersistencyService.java b/cps/cps-service/src/main/java/org/onap/cps/spi/ModelPersistencyService.java index f88c6b241..2afdaa82a 100644 --- a/cps/cps-service/src/main/java/org/onap/cps/spi/ModelPersistencyService.java +++ b/cps/cps-service/src/main/java/org/onap/cps/spi/ModelPersistencyService.java @@ -1,6 +1,7 @@ /* * ============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. @@ -27,10 +28,12 @@ public interface ModelPersistencyService { /** * Store the module from a yang model in the database. * - * @param name module name + * @param namespace module namespace * @param moduleContent module content * @param revision module revision + * @param dataspaceName the name of the dataspace the module is associated with */ - void storeModule(final String name, final String moduleContent, final String revision); + void storeModule(final String namespace, final String moduleContent, final String revision, + final String dataspaceName); } diff --git a/cps/cps-service/src/test/groovy/org/onap/cps/api/impl/CpServiceImplSpec.groovy b/cps/cps-service/src/test/groovy/org/onap/cps/api/impl/CpServiceImplSpec.groovy index a2f9b3543..5e6fccb7a 100644 --- a/cps/cps-service/src/test/groovy/org/onap/cps/api/impl/CpServiceImplSpec.groovy +++ b/cps/cps-service/src/test/groovy/org/onap/cps/api/impl/CpServiceImplSpec.groovy @@ -1,6 +1,7 @@ /* * ============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. @@ -21,6 +22,7 @@ package org.onap.cps.api.impl import org.onap.cps.TestUtils import org.onap.cps.spi.DataPersistencyService + import org.opendaylight.yangtools.yang.common.Revision import org.opendaylight.yangtools.yang.model.api.SchemaContext import org.opendaylight.yangtools.yang.model.parser.api.YangParserException @@ -32,7 +34,7 @@ class CpServiceImplSpec extends Specification { def objectUnderTest = new CpServiceImpl() def setup() { - objectUnderTest.dataPersistencyService = mockDataPersistencyService; + objectUnderTest.dataPersistencyService = mockDataPersistencyService } def 'Cps Service provides to its client the id assigned by the system when storing a data structure'() { @@ -77,7 +79,7 @@ class CpServiceImplSpec extends Specification { def 'Store a SchemaContext'() { expect: 'No exception to be thrown when a valid model (schema) is stored' - objectUnderTest.storeSchemaContext(Stub(SchemaContext.class)) + objectUnderTest.storeSchemaContext(Stub(SchemaContext.class), "sampleDataspace") } def 'Read a JSON object with a valid identifier'(){ diff --git a/cps/pom.xml b/cps/pom.xml index dd98ca586..892492d2d 100644 --- a/cps/pom.xml +++ b/cps/pom.xml @@ -45,6 +45,27 @@ pom import + + + + org.codehaus.groovy + groovy + ${groovy.version} + test + + + org.spockframework + spock-core + ${spock-core.version} + test + + + cglib + cglib-nodep + 3.1 + test + + -- cgit 1.2.3-korg From b4cd52f312c85e182fbaf7cc57ffdb32e6459f9b Mon Sep 17 00:00:00 2001 From: niamhcore Date: Tue, 27 Oct 2020 15:49:30 +0000 Subject: Changing variable types for api Jira Link: https://jira.onap.org/browse/CCSDK-2907 Issue-ID: CCSDK-2907 Change-Id: Ib473370222b1e5b2c27f4a6bcf01b2d8ef523c9b --- cps/cps-rest/docs/api/swagger/openapi.yml | 63 +++++++++------------- .../onap/cps/rest/controller/RestController.java | 29 +++++----- 2 files changed, 39 insertions(+), 53 deletions(-) diff --git a/cps/cps-rest/docs/api/swagger/openapi.yml b/cps/cps-rest/docs/api/swagger/openapi.yml index 1f9019a63..f116c26ce 100644 --- a/cps/cps-rest/docs/api/swagger/openapi.yml +++ b/cps/cps-rest/docs/api/swagger/openapi.yml @@ -21,8 +21,7 @@ paths: description: dataspace-name required: true schema: - type: integer - format: int32 + type: string responses: 200: description: OK @@ -51,8 +50,7 @@ paths: description: dataspace-name required: true schema: - type: integer - format: int32 + type: string responses: 200: description: OK @@ -80,8 +78,7 @@ paths: description: dataspace-name required: true schema: - type: integer - format: int32 + type: string requestBody: content: multipart/form-data: @@ -125,15 +122,13 @@ paths: description: dataspace-name required: true schema: - type: integer - format: int32 + type: string - name: anchor-name in: path description: anchor-name required: true schema: - type: integer - format: int32 + type: string responses: 200: description: OK @@ -161,15 +156,13 @@ paths: description: dataspace-name required: true schema: - type: integer - format: int32 + type: string - name: anchor-name in: path description: anchor-name required: true schema: - type: integer - format: int32 + type: string responses: 200: description: OK @@ -193,20 +186,18 @@ paths: summary: Get a node given an anchor for the given dataspace operationId: getNodeByDataspaceAndAnchor parameters: - - name: dataspaceName + - name: dataspace-name in: path - description: dataspaceName + description: dataspace-name required: true schema: - type: integer - format: int32 - - name: anchorpoint + type: string + - name: anchor-name in: path - description: anchorpoint + description: anchor-name required: true schema: - type: integer - format: int32 + type: string requestBody: description: xpath content: @@ -238,25 +229,22 @@ paths: summary: Read all yang modules in the store operationId: getModule parameters: - - name: dataspaceName + - name: dataspace-name in: path - description: dataspaceName + description: dataspace-name required: true schema: - type: integer - format: int32 + type: string - name: namespace-name in: query description: namespace-name schema: - type: integer - format: int32 + type: string - name: revision in: query description: revision schema: - type: integer - format: int32 + type: string responses: 200: description: OK @@ -284,8 +272,7 @@ paths: description: dataspace-name required: true schema: - type: integer - format: int32 + type: string requestBody: content: multipart/form-data: @@ -324,13 +311,12 @@ paths: summary: Get all nodes for a given dataspace using an xpath or schema node identifier operationId: getNode parameters: - - name: dataspaceName + - name: dataspace-name in: path - description: dataspaceName + description: dataspace-name required: true schema: - type: integer - format: int32 + type: string requestBody: description: requestBody content: @@ -366,8 +352,7 @@ paths: description: dataspace-name required: true schema: - type: integer - format: int32 + type: string requestBody: content: multipart/form-data: @@ -399,4 +384,4 @@ paths: 404: description: Not Found content: {} -components: {} +components: {} \ No newline at end of file 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 index 703e77823..d3ff91b07 100644 --- 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 @@ -51,52 +51,53 @@ public class RestController implements CpsResourceApi { private CpService cpService; @Override - public Object createAnchor(Attachment fileDetail, Integer dataspaceName) { + public Object createAnchor(final Attachment fileDetail, final String dataspaceName) { return null; } @Override - public Object createModules(Attachment fileDetail, Integer dataspaceName) { + public Object createModules(final Attachment fileDetail, final String dataspaceName) { return null; } @Override - public Object createNode(Attachment fileDetail, Integer dataspaceName) { + public Object createNode(final Attachment fileDetail, final String dataspaceName) { return null; } @Override - public Object deleteAnchor(Integer dataspaceName, Integer anchorName) { + public Object deleteAnchor(final String dataspaceName, final String anchorName) { return null; } @Override - public Object deleteDataspace(Integer dataspaceName) { + public Object deleteDataspace(final String dataspaceName) { return null; } @Override - public Object getAnchor(Integer dataspaceName, Integer anchorName) { + public Object getAnchor(final String dataspaceName, final String anchorName) { return null; } @Override - public Object getAnchors(Integer dataspaceName) { + public Object getAnchors(final String dataspaceName) { return null; } @Override - public Object getModule(Integer dataspaceName, Integer namespaceName, Integer revision) { + public Object getModule(final String dataspaceName, final String namespaceName, final String revision) { return null; } @Override - public Object getNode(@Valid String body, Integer dataspaceName) { + public Object getNode(@Valid final String body, final String dataspaceName) { return null; } @Override - public Object getNodeByDataspaceAndAnchor(@Valid String body, Integer dataspaceName, Integer anchorpoint) { + public Object getNodeByDataspaceAndAnchor(@Valid final String body, final String dataspaceName, + final String anchorName) { return null; } @@ -139,7 +140,7 @@ public class RestController implements CpsResourceApi { @Path("/upload-yang-json-data-file") @Produces(MediaType.APPLICATION_JSON) @Consumes(MediaType.MULTIPART_FORM_DATA) - public final Response uploadYangJsonDataFile(@FormDataParam("file") String uploadedFile) { + public final Response uploadYangJsonDataFile(@FormDataParam("file") final String uploadedFile) { try { validateJsonStructure(uploadedFile); final int persistenceObjectId = cpService.storeJsonStructure(uploadedFile); @@ -160,7 +161,7 @@ public class RestController implements CpsResourceApi { */ @GET @Path("/json-object/{id}") - public final Response getJsonObjectById(@PathParam("id") int jsonObjectId) { + public final Response getJsonObjectById(@PathParam("id") final int jsonObjectId) { try { return Response.status(Status.OK).entity(cpService.getJsonById(jsonObjectId)).build(); } catch (final PersistenceException e) { @@ -178,7 +179,7 @@ public class RestController implements CpsResourceApi { */ @DELETE @Path("json-object/{id}") - public final Response deleteJsonObjectById(@PathParam("id") int jsonObjectId) { + public final Response deleteJsonObjectById(@PathParam("id") final int jsonObjectId) { try { cpService.deleteJsonById(jsonObjectId); return Response.status(Status.OK).entity(Status.OK.toString()).build(); @@ -194,7 +195,7 @@ public class RestController implements CpsResourceApi { gson.fromJson(jsonFile, Object.class); } - private static final File renameFileIfNeeded(File originalFile) { + private static final File renameFileIfNeeded(final File originalFile) { if (originalFile.getName().endsWith(".yang")) { return originalFile; } -- cgit 1.2.3-korg From 2371fe79fe36a6629810b6dcfd435a95ce0fd54d Mon Sep 17 00:00:00 2001 From: Rishi Chail Date: Fri, 30 Oct 2020 12:58:54 +0000 Subject: 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 Change-Id: Ie87d2fe53bffcaf2af0229961139910faeb36e26 --- cps/cps-rest/pom.xml | 52 +----- .../org/onap/cps/rest/config/JerseyConfig.java | 72 ------- .../cps/rest/controller/CpsRestController.java | 153 +++++++++++++++ .../onap/cps/rest/controller/ModelController.java | 36 ---- .../onap/cps/rest/controller/RestController.java | 206 --------------------- cps/cps-rest/src/main/resources/application.yml | 2 + 6 files changed, 156 insertions(+), 365 deletions(-) delete mode 100644 cps/cps-rest/src/main/java/org/onap/cps/rest/config/JerseyConfig.java create mode 100644 cps/cps-rest/src/main/java/org/onap/cps/rest/controller/CpsRestController.java delete mode 100644 cps/cps-rest/src/main/java/org/onap/cps/rest/controller/ModelController.java delete mode 100644 cps/cps-rest/src/main/java/org/onap/cps/rest/controller/RestController.java 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 @@ -23,19 +23,9 @@ ${project.version} - - org.glassfish.jersey.media - jersey-media-multipart - - - - org.springframework - spring-webmvc - - org.springframework.boot - spring-boot-starter-jersey + spring-boot-starter-web org.springframework.boot @@ -73,20 +63,6 @@ - - - org.apache.cxf - cxf-bundle-jaxrs - ${cxf-bundle-jaxrs.version} - - - - - org.apache.cxf - cxf-rt-rs-service-description - ${cxf-rt-rs-service.version} - - @@ -104,32 +80,6 @@ - - io.swagger.codegen.v3 - swagger-codegen-maven-plugin - ${swagger-codegen.version} - - - - generate - - - ${project.basedir}/docs/api/swagger/openapi.yml - org.onap.cps.rest.controller - org.onap.cps.rest.model - org.onap.cps.rest.controller - jaxrs-cxf - true - - src/gen/java - java8 - jersey2 - true - - - - - org.apache.maven.plugins 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 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("Resource successfully created", HttpStatus.CREATED); + } catch (final YangParserException | ConstraintViolationException e) { + return new ResponseEntity(e.getMessage(), HttpStatus.BAD_REQUEST); + } catch (final Exception e) { + return new ResponseEntity(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 uploadYangJsonDataFile( + @RequestParam("file") MultipartFile uploadedFile) { + try { + validateJsonStructure(uploadedFile); + final int persistenceObjectId = cpService.storeJsonStructure(new String(uploadedFile.getBytes())); + return new ResponseEntity( + "Object stored in CPS with identity: " + persistenceObjectId, HttpStatus.OK); + } catch (final JsonSyntaxException e) { + return new ResponseEntity(e.getMessage(), HttpStatus.BAD_REQUEST); + } catch (final Exception e) { + return new ResponseEntity(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 getJsonObjectById( + @PathVariable("id") final int jsonObjectId) { + try { + return new ResponseEntity(cpService.getJsonById(jsonObjectId), HttpStatus.OK); + } catch (final PersistenceException e) { + return new ResponseEntity(e.getMessage(), HttpStatus.NOT_FOUND); + } catch (final Exception e) { + return new ResponseEntity(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 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: -- cgit 1.2.3-korg From 70c17020b7025a9ff18192d4d5add6f75ace49aa Mon Sep 17 00:00:00 2001 From: Claudio David Gasparini Date: Mon, 26 Oct 2020 10:12:10 +0100 Subject: Reestructore cps project + Introduce BOM artifacts + decoupling of root from parent new artifacts introduced: cps-bom: contains dependencyManagement declarations of all published components cps-dependencies: contains dependencyManagement declarations of upstream versions cps-parent: parent of cps project / decoupling of root project pom responsabilities JIRA: CCSDK-2946 Signed-off-by: Claudio David Gasparini Change-Id: I752c19dea6c92f939f0a313f6a93f13a489cdef0 Change-Id: Iafb4eee7d1b20aa4e7fcca0c0027f5a0605e035d --- cps/cps-bom/pom.xml | 31 ++++++ cps/cps-dependencies/pom.xml | 72 ++++++++++++++ cps/cps-parent/pom.xml | 231 +++++++++++++++++++++++++++++++++++++++++++ cps/cps-rest/pom.xml | 94 ++---------------- cps/cps-ri/pom.xml | 17 +--- cps/cps-service/pom.xml | 24 ++--- cps/pom.xml | 166 +++---------------------------- 7 files changed, 364 insertions(+), 271 deletions(-) create mode 100644 cps/cps-bom/pom.xml create mode 100644 cps/cps-dependencies/pom.xml create mode 100644 cps/cps-parent/pom.xml diff --git a/cps/cps-bom/pom.xml b/cps/cps-bom/pom.xml new file mode 100644 index 000000000..ae9e806f3 --- /dev/null +++ b/cps/cps-bom/pom.xml @@ -0,0 +1,31 @@ + + + 4.0.0 + org.onap.cps + cps-bom + 0.0.1-SNAPSHOT + pom + + This artifact contains dependencyManagement declarations of all published CPS components. + + + + org.onap.cps + cps-service + ${project.version} + + + org.onap.cps + cps-rest + ${project.version} + + + org.onap.cps + cps-ri + ${project.version} + + + + \ No newline at end of file diff --git a/cps/cps-dependencies/pom.xml b/cps/cps-dependencies/pom.xml new file mode 100644 index 000000000..6f50cd0fc --- /dev/null +++ b/cps/cps-dependencies/pom.xml @@ -0,0 +1,72 @@ + + + + 4.0.0 + org.onap.cps + cps-dependencies + 0.0.1-SNAPSHOT + pom + + ${project.groupId}:${project.artifactId} + This artifact contains dependencyManagement declarations of upstream versions. + + + 3.0.6 + 2.10.0 + 2.0-M2-groovy-3.0 + 2.3.3.RELEASE + 2.1.4 + 5.0.6 + + + + + + org.springframework.boot + spring-boot-dependencies + ${springboot.version} + pom + import + + + org.opendaylight.yangtools + yangtools-artifacts + ${yangtools.version} + pom + import + + + io.swagger.core.v3 + swagger-annotations + ${swagger.version} + + + io.swagger.core.v3 + swagger-jaxrs2 + ${swagger.version} + + + com.vladmihalcea + hibernate-types-52 + ${hibernate-types.version} + + + org.codehaus.groovy + groovy + ${groovy.version} + + + org.spockframework + spock-core + ${spock-core.version} + + + cglib + cglib-nodep + 3.1 + + + + \ No newline at end of file diff --git a/cps/cps-parent/pom.xml b/cps/cps-parent/pom.xml new file mode 100644 index 000000000..2ddb2b668 --- /dev/null +++ b/cps/cps-parent/pom.xml @@ -0,0 +1,231 @@ + + + + org.onap.oparent + oparent + 3.1.0 + + + 4.0.0 + + org.onap.cps + cps-parent + 0.0.1-SNAPSHOT + pom + + + 11 + 3.2.0 + 3.1.2 + 1.5.3 + 3.1.0 + 2.3.3.RELEASE + 3.35.0 + + + + + + org.onap.cps + cps-dependencies + ${project.version} + pom + import + + + org.onap.cps + cps-bom + ${project.version} + pom + import + + + + + + + + src/main/resources + true + + + target/generated-sources/license + + third-party-licenses.txt + + + + target/generated-resources/licenses + + *.* + + third-party-licenses + + + + + + org.springframework.boot + spring-boot-maven-plugin + ${spring-boot-maven-plugin.version} + + + + repackage + + + + + + + org.apache.maven.plugins + maven-dependency-plugin + ${maven-dependency-plugin.version} + + + prepare-package + + unpack + + + + + org.webjars + swagger-ui + ${swagger-ui.version} + + + + ${project.build.directory}/swagger-ui-${swagger-ui.version} + + + + + + + + org.apache.maven.plugins + maven-resources-plugin + ${maven-resources-plugin.version} + + + copy-resources + prepare-package + + copy-resources + + + ${project.build.outputDirectory}/static/swagger-ui + + + + + ${project.build.directory}/swagger-ui-${swagger-ui.version}/META-INF/resources/webjars/swagger-ui/${swagger-ui.version}/ + + + **/*.gz + + + + + + + + + + com.google.code.maven-replacer-plugin + replacer + ${maven-replacer-plugin.version} + + + prepare-package + + replace + + + + + ${project.build.outputDirectory}/static/swagger-ui/index.html + + + https://petstore.swagger.io/v2/swagger.json + /api/cps/openapi.json + + + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + + ${java.version} + ${java.version} + + + + org.apache.maven.plugins + maven-checkstyle-plugin + + + onap-java-style + + check + + process-sources + + onap-checkstyle/onap-java-style.xml + ${project.build.sourceDirectory} + true + true + true + false + warning + true + + + + + + org.onap.oparent + checkstyle + ${oparent.version} + + + + + + + org.codehaus.gmavenplus + gmavenplus-plugin + 1.9.0 + + + + compileTests + + + + + + + org.apache.maven.plugins + maven-surefire-plugin + 3.0.0-M5 + + false + + **/*Spec.java + **/*Test.java + + + + + + \ No newline at end of file diff --git a/cps/cps-rest/pom.xml b/cps/cps-rest/pom.xml index ed896a82f..f9be75b7e 100644 --- a/cps/cps-rest/pom.xml +++ b/cps/cps-rest/pom.xml @@ -2,27 +2,24 @@ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 - cps-rest org.onap.cps - cps + cps-parent 0.0.1-SNAPSHOT + ../cps-parent/pom.xml - + cps-rest + - org.onap.cps + ${project.groupId} cps-service - ${project.version} - - org.onap.cps + ${project.groupId} cps-ri - ${project.version} - org.springframework.boot spring-boot-starter-web @@ -33,24 +30,18 @@ - org.springframework.boot spring-boot-starter-jetty - io.swagger.core.v3 swagger-annotations - ${swagger.version} - io.swagger.core.v3 swagger-jaxrs2 - ${swagger.version} - org.springframework.boot spring-boot-starter-test @@ -62,7 +53,6 @@ - @@ -70,93 +60,21 @@ org.springframework.boot spring-boot-maven-plugin - ${springboot.version} - - - - repackage - - - - org.apache.maven.plugins maven-dependency-plugin - ${maven-dependency-plugin.version} - - - prepare-package - - unpack - - - - - org.webjars - swagger-ui - ${swagger-ui.version} - - - - ${project.build.directory}/swagger-ui-${swagger-ui.version} - - - - org.apache.maven.plugins maven-resources-plugin - ${maven-resources-plugin.version} - - - copy-resources - prepare-package - - copy-resources - - - ${project.build.outputDirectory}/static/swagger-ui - - - - - ${project.build.directory}/swagger-ui-${swagger-ui.version}/META-INF/resources/webjars/swagger-ui/${swagger-ui.version}/ - - - **/*.gz - - - - - - com.google.code.maven-replacer-plugin replacer - ${maven-replacer-plugin.version} - - - prepare-package - - replace - - - - - ${project.build.outputDirectory}/static/swagger-ui/index.html - - - https://petstore.swagger.io/v2/swagger.json - /api/cps/openapi.json - - - diff --git a/cps/cps-ri/pom.xml b/cps/cps-ri/pom.xml index 77cb5f86a..2c28212af 100644 --- a/cps/cps-ri/pom.xml +++ b/cps/cps-ri/pom.xml @@ -4,46 +4,37 @@ 4.0.0 org.onap.cps - cps + cps-parent 0.0.1-SNAPSHOT + ../cps-parent/pom.xml cps-ri - - org.onap.cps + ${project.groupId} cps-service - ${project.version} - org.springframework.boot spring-boot-starter-data-jpa - org.springframework.boot spring-boot-starter-validation - org.postgresql postgresql - - + com.vladmihalcea hibernate-types-52 - ${hibernate-types.version} - org.projectlombok lombok - - diff --git a/cps/cps-service/pom.xml b/cps/cps-service/pom.xml index ea1bdad39..3e8cc2deb 100644 --- a/cps/cps-service/pom.xml +++ b/cps/cps-service/pom.xml @@ -4,75 +4,65 @@ 4.0.0 org.onap.cps - cps + cps-parent 0.0.1-SNAPSHOT + ../cps-parent/pom.xml + cps-service - org.opendaylight.yangtools yang-parser-api - ${yangtools.version} - org.opendaylight.yangtools yang-parser-impl - ${yangtools.version} - org.opendaylight.yangtools yang-model-util - ${yangtools.version} - + - org.opendaylight.yangtools yang-data-codec-gson - ${yangtools.version} - org.projectlombok lombok - org.slf4j slf4j-api - org.springframework spring-context - com.google.code.gson gson - org.codehaus.groovy groovy + test org.spockframework spock-core + test cglib cglib-nodep + test - - diff --git a/cps/pom.xml b/cps/pom.xml index 892492d2d..c2d6c7994 100644 --- a/cps/pom.xml +++ b/cps/pom.xml @@ -1,177 +1,37 @@ + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 org.onap.oparent oparent 3.1.0 + org.onap.cps - cps + cps-aggregator 0.0.1-SNAPSHOT pom + cps ONAP Configuration and Persistency Service + ONAP - CPS http://www.onap.org/ - - 11 - 2.3.3.RELEASE - 3.1.0 - 5.0.6 - 2.1.4 - 3.0.6 - 2.0-M2-groovy-3.0 - 3.0.18 - 3.0.0 - 2.2.9 - 3.1.2 - 3.2.0 - 1.5.3 - 3.35.0 - 2.10.0 - - - - - - org.springframework.boot - spring-boot-dependencies - ${springboot.version} - pom - import - - - - - org.codehaus.groovy - groovy - ${groovy.version} - test - - - org.spockframework - spock-core - ${spock-core.version} - test - - - cglib - cglib-nodep - 3.1 - test - - - - - - - - - src/main/resources - true - - - - target/generated-sources/license - - third-party-licenses.txt - - - - - target/generated-resources/licenses - - *.* - - third-party-licenses - - - - - - org.apache.maven.plugins - maven-compiler-plugin - - ${java.version} - ${java.version} - - - - - org.apache.maven.plugins - maven-checkstyle-plugin - - - onap-java-style - - check - - process-sources - - onap-checkstyle/onap-java-style.xml - ${project.build.sourceDirectory} - true - true - true - false - warning - true - - - - - - - org.onap.oparent - checkstyle - ${oparent.version} - - - - - - - - - org.codehaus.gmavenplus - gmavenplus-plugin - 1.9.0 - - - - compileTests - - - - - - - org.apache.maven.plugins - maven-surefire-plugin - 3.0.0-M5 - - false - - **/*Spec.java - **/*Test.java - - - - - - + + true + true + + cps-dependencies + cps-bom + cps-parent cps-service cps-rest cps-ri - -- cgit 1.2.3-korg From 47598117ee0b411cfc6fad323598f5644b51c9c9 Mon Sep 17 00:00:00 2001 From: "puthuparambil.aditya" Date: Mon, 2 Nov 2020 11:31:39 +0000 Subject: Swagger codegen using Spring framework 1. Pom.xml updated to generate API code using Swagger codegen. 2. Moved the createModule code to the method implemented by Swagger. JIRA: https://jira.onap.org/browse/CCSDK-2897 Issue-ID: CCSDK-2897 Signed-off-by: puthuparambil.aditya Change-Id: Iadd3dc0402f06a597a179148fd5f43e0fe7c48f6 Signed-off-by: puthuparambil.aditya --- cps/cps-dependencies/pom.xml | 11 ++++ cps/cps-parent/pom.xml | 28 ++++++++ cps/cps-rest/docs/api/swagger/openapi.yml | 34 +++++----- cps/cps-rest/pom.xml | 13 ++++ .../cps/rest/controller/CpsRestController.java | 77 ++++++++++++++++------ 5 files changed, 127 insertions(+), 36 deletions(-) diff --git a/cps/cps-dependencies/pom.xml b/cps/cps-dependencies/pom.xml index 6f50cd0fc..ad71b1158 100644 --- a/cps/cps-dependencies/pom.xml +++ b/cps/cps-dependencies/pom.xml @@ -17,6 +17,7 @@ 2.10.0 2.0-M2-groovy-3.0 2.3.3.RELEASE + 2.6.1 2.1.4 5.0.6 @@ -47,6 +48,16 @@ swagger-jaxrs2 ${swagger.version} + + io.springfox + springfox-swagger2 + ${springfox-swagger2.version} + + + io.springfox + springfox-swagger-ui + ${springfox-swagger2.version} + com.vladmihalcea hibernate-types-52 diff --git a/cps/cps-parent/pom.xml b/cps/cps-parent/pom.xml index 2ddb2b668..db80970c5 100644 --- a/cps/cps-parent/pom.xml +++ b/cps/cps-parent/pom.xml @@ -22,6 +22,7 @@ 1.5.3 3.1.0 2.3.3.RELEASE + 3.0.18 3.35.0 @@ -78,6 +79,33 @@ + + + io.swagger.codegen.v3 + swagger-codegen-maven-plugin + ${swagger-codegen-maven-plugin.version} + + + + generate + + + ${project.basedir}/docs/api/swagger/openapi.yml + org.onap.cps.rest.controller + org.onap.cps.rest.model + org.onap.cps.rest.api + spring + false + + src/gen/java + java11 + true + true + + + + + org.apache.maven.plugins diff --git a/cps/cps-rest/docs/api/swagger/openapi.yml b/cps/cps-rest/docs/api/swagger/openapi.yml index f116c26ce..9b2ac1ec5 100644 --- a/cps/cps-rest/docs/api/swagger/openapi.yml +++ b/cps/cps-rest/docs/api/swagger/openapi.yml @@ -6,13 +6,13 @@ info: servers: - url: //localhost:8088/ tags: - - name: cps-resource + - name: cps-rest description: cps Resource paths: /v1/dataspaces/{dataspace-name}/: delete: tags: - - cps-resource + - cps-rest summary: Delete the given dataspace operationId: deleteDataspace parameters: @@ -41,7 +41,7 @@ paths: /v1/dataspaces/{dataspace-name}/anchors: get: tags: - - cps-resource + - cps-rest summary: Read all anchors, given a dataspace operationId: getAnchors parameters: @@ -69,7 +69,7 @@ paths: content: {} post: tags: - - cps-resource + - cps-rest summary: Create a new anchor in the given dataspace operationId: createAnchor parameters: @@ -86,9 +86,9 @@ paths: required: - file properties: - file: + multipartFile: type: string - description: file + description: multipartFile format: binary required: true responses: @@ -113,7 +113,7 @@ paths: /v1/dataspaces/{dataspace-name}/anchors/{anchor-name}: get: tags: - - cps-resource + - cps-rest summary: Read an anchor given a anchor and a dataspace operationId: getAnchor parameters: @@ -147,7 +147,7 @@ paths: content: {} delete: tags: - - cps-resource + - cps-rest summary: Delete an anchor given a anchor and a dataspace operationId: deleteAnchor parameters: @@ -182,7 +182,7 @@ paths: /v1/dataspaces/{dataspace-name}/anchors/{anchor-name}/nodes: get: tags: - - cps-resource + - cps-rest summary: Get a node given an anchor for the given dataspace operationId: getNodeByDataspaceAndAnchor parameters: @@ -225,7 +225,7 @@ paths: /v1/dataspaces/{dataspace-name}/modules: get: tags: - - cps-resource + - cps-rest summary: Read all yang modules in the store operationId: getModule parameters: @@ -263,7 +263,7 @@ paths: content: {} post: tags: - - cps-resource + - cps-rest summary: Create modules for the given dataspace operationId: createModules parameters: @@ -280,9 +280,9 @@ paths: required: - file properties: - file: + multipartFile: type: string - description: file + description: multipartFile format: binary required: true responses: @@ -307,7 +307,7 @@ paths: /v1/dataspaces/{dataspace-name}/nodes: get: tags: - - cps-resource + - cps-rest summary: Get all nodes for a given dataspace using an xpath or schema node identifier operationId: getNode parameters: @@ -343,7 +343,7 @@ paths: x-codegen-request-body-name: requestBody post: tags: - - cps-resource + - cps-rest summary: Create a node for a given anchor for the given dataspace operationId: createNode parameters: @@ -360,9 +360,9 @@ paths: required: - file properties: - file: + multipartFile: type: string - description: file + description: multipartFile format: binary required: true responses: diff --git a/cps/cps-rest/pom.xml b/cps/cps-rest/pom.xml index f9be75b7e..fcd97dcf7 100644 --- a/cps/cps-rest/pom.xml +++ b/cps/cps-rest/pom.xml @@ -42,6 +42,14 @@ io.swagger.core.v3 swagger-jaxrs2 + + io.springfox + springfox-swagger2 + + + io.springfox + springfox-swagger-ui + org.springframework.boot spring-boot-starter-test @@ -61,6 +69,11 @@ org.springframework.boot spring-boot-maven-plugin + + + io.swagger.codegen.v3 + swagger-codegen-maven-plugin + org.apache.maven.plugins 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 index a577af70e..9a31b6d8e 100644 --- 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 @@ -27,8 +27,10 @@ import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStream; import javax.persistence.PersistenceException; +import javax.validation.Valid; import org.hibernate.exception.ConstraintViolationException; import org.onap.cps.api.CpService; +import org.onap.cps.rest.api.CpsRestApi; import org.opendaylight.yangtools.yang.model.api.SchemaContext; import org.opendaylight.yangtools.yang.model.parser.api.YangParserException; import org.springframework.beans.factory.annotation.Autowired; @@ -44,38 +46,75 @@ import org.springframework.web.bind.annotation.RestController; import org.springframework.web.multipart.MultipartFile; @RestController -public class CpsRestController { +public class CpsRestController implements CpsRestApi { @Autowired private CpService cpService; - /* - Old rest endpoints before contract first approach (Need to be removed). - */ + @Override + public ResponseEntity createAnchor(@Valid MultipartFile multipartFile, String dataspaceName) { + return null; + } - /** - * 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 uploadYangModelFile( - @RequestParam("file") MultipartFile uploadedFile, - @PathVariable("dataspace_name") String dataspaceName) { + @Override + public ResponseEntity createModules(@Valid MultipartFile multipartFile, String dataspaceName) { try { - final File fileToParse = saveToFile(uploadedFile); + final File fileToParse = saveToFile(multipartFile); final SchemaContext schemaContext = cpService.parseAndValidateModel(fileToParse); cpService.storeSchemaContext(schemaContext, dataspaceName); - return new ResponseEntity("Resource successfully created", HttpStatus.CREATED); + return new ResponseEntity<>("Resource successfully created", HttpStatus.CREATED); } catch (final YangParserException | ConstraintViolationException e) { - return new ResponseEntity(e.getMessage(), HttpStatus.BAD_REQUEST); + return new ResponseEntity<>(e.getMessage(), HttpStatus.BAD_REQUEST); } catch (final Exception e) { - return new ResponseEntity(e.getMessage(), HttpStatus.INTERNAL_SERVER_ERROR); + return new ResponseEntity<>(e.getMessage(), HttpStatus.INTERNAL_SERVER_ERROR); } } + @Override + public ResponseEntity createNode(@Valid MultipartFile multipartFile, String dataspaceName) { + return null; + } + + @Override + public ResponseEntity deleteAnchor(String dataspaceName, String anchorName) { + return null; + } + + @Override + public ResponseEntity deleteDataspace(String dataspaceName) { + return null; + } + + @Override + public ResponseEntity getAnchor(String dataspaceName, String anchorName) { + return null; + } + + @Override + public ResponseEntity getAnchors(String dataspaceName) { + return null; + } + + @Override + public ResponseEntity getModule(String dataspaceName, @Valid String namespaceName, @Valid String revision) { + return null; + } + + @Override + public ResponseEntity getNode(@Valid String body, String dataspaceName) { + return null; + } + + @Override + public ResponseEntity getNodeByDataspaceAndAnchor(@Valid String body, String dataspaceName, + String anchorName) { + return null; + } + + /* + Old rest endpoints before contract first approach (Need to be removed). + */ + /** * Upload a JSON file. * -- cgit 1.2.3-korg From f4d1c984c6bb290c4bb58001231a1cfefac002cc Mon Sep 17 00:00:00 2001 From: Ruslan Kashapov Date: Thu, 29 Oct 2020 11:39:31 +0200 Subject: Spring Boot Actuator enabled on /manage Change-Id: I39970e920ae9b10aed038bc3da7a59b2ae370cf2 Issue-ID: CPS-16 JIRA: https://jira.onap.org/browse/CPS-16 Signed-off-by: Ruslan Kashapov --- cps/cps-parent/pom.xml | 1 + cps/cps-rest/pom.xml | 4 ++++ cps/cps-rest/src/main/resources/application.yml | 12 ++++++++++++ 3 files changed, 17 insertions(+) diff --git a/cps/cps-parent/pom.xml b/cps/cps-parent/pom.xml index 2ddb2b668..4984b6194 100644 --- a/cps/cps-parent/pom.xml +++ b/cps/cps-parent/pom.xml @@ -73,6 +73,7 @@ + build-info repackage diff --git a/cps/cps-rest/pom.xml b/cps/cps-rest/pom.xml index f9be75b7e..2d125803d 100644 --- a/cps/cps-rest/pom.xml +++ b/cps/cps-rest/pom.xml @@ -34,6 +34,10 @@ org.springframework.boot spring-boot-starter-jetty + + org.springframework.boot + spring-boot-starter-actuator + io.swagger.core.v3 swagger-annotations diff --git a/cps/cps-rest/src/main/resources/application.yml b/cps/cps-rest/src/main/resources/application.yml index 8e2aee043..84f3f79cd 100644 --- a/cps/cps-rest/src/main/resources/application.yml +++ b/cps/cps-rest/src/main/resources/application.yml @@ -24,6 +24,18 @@ spring: jersey: type: filter +# Actuator +management: + endpoints: + web: + base-path: /manage + endpoint: + health: + show-details: always + # kubernetes probes: liveness and readiness + probes: + enabled: true + logging: level: org: -- cgit 1.2.3-korg From f338b922dbd40df98aa94312ab0a13e9581f3b26 Mon Sep 17 00:00:00 2001 From: Ruslan Kashapov Date: Wed, 28 Oct 2020 16:53:58 +0200 Subject: Exception handling on REST interface - customisable error message - unified approach for exception handling - unified approach for error message delivery Change-Id: Iecb46a119008fdae284fc730f459e729168e92a7 Issue-ID: CPS-41 JIRA: https://jira.onap.org/browse/CPS-41 Signed-off-by: Ruslan Kashapov --- cps/cps-rest/pom.xml | 16 ++++ .../cps/rest/controller/CpsRestController.java | 88 +++++++++---------- .../rest/exceptions/CpsRestExceptionHandler.java | 98 ++++++++++++++++++++++ .../org/onap/cps/rest/exceptions/ErrorMessage.java | 37 ++++++++ .../src/main/java/org/onap/cps/api/CpService.java | 4 +- .../java/org/onap/cps/api/impl/CpServiceImpl.java | 28 +++++-- .../java/org/onap/cps/exceptions/CpsException.java | 62 ++++++++++++++ .../onap/cps/exceptions/CpsNotFoundException.java | 57 +++++++++++++ .../cps/exceptions/CpsValidationException.java | 55 ++++++++++++ .../org/onap/cps/api/impl/CpServiceImplSpec.groovy | 7 +- 10 files changed, 389 insertions(+), 63 deletions(-) create mode 100644 cps/cps-rest/src/main/java/org/onap/cps/rest/exceptions/CpsRestExceptionHandler.java create mode 100644 cps/cps-rest/src/main/java/org/onap/cps/rest/exceptions/ErrorMessage.java create mode 100644 cps/cps-service/src/main/java/org/onap/cps/exceptions/CpsException.java create mode 100644 cps/cps-service/src/main/java/org/onap/cps/exceptions/CpsNotFoundException.java create mode 100644 cps/cps-service/src/main/java/org/onap/cps/exceptions/CpsValidationException.java diff --git a/cps/cps-rest/pom.xml b/cps/cps-rest/pom.xml index fcd97dcf7..c1f08eaba 100644 --- a/cps/cps-rest/pom.xml +++ b/cps/cps-rest/pom.xml @@ -61,6 +61,22 @@ + + + org.codehaus.groovy + groovy + test + + + org.spockframework + spock-core + test + + + cglib + cglib-nodep + test + 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 index 9a31b6d8e..90c287cda 100644 --- 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 @@ -26,15 +26,13 @@ import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStream; -import javax.persistence.PersistenceException; import javax.validation.Valid; -import org.hibernate.exception.ConstraintViolationException; import org.onap.cps.api.CpService; +import org.onap.cps.exceptions.CpsException; +import org.onap.cps.exceptions.CpsValidationException; import org.onap.cps.rest.api.CpsRestApi; 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; @@ -58,16 +56,10 @@ public class CpsRestController implements CpsRestApi { @Override public ResponseEntity createModules(@Valid MultipartFile multipartFile, String dataspaceName) { - try { - final File fileToParse = saveToFile(multipartFile); - final SchemaContext schemaContext = cpService.parseAndValidateModel(fileToParse); - cpService.storeSchemaContext(schemaContext, dataspaceName); - return new ResponseEntity<>("Resource successfully created", HttpStatus.CREATED); - } catch (final YangParserException | ConstraintViolationException e) { - return new ResponseEntity<>(e.getMessage(), HttpStatus.BAD_REQUEST); - } catch (final Exception e) { - return new ResponseEntity<>(e.getMessage(), HttpStatus.INTERNAL_SERVER_ERROR); - } + final File fileToParse = saveToFile(multipartFile); + final SchemaContext schemaContext = cpService.parseAndValidateModel(fileToParse); + cpService.storeSchemaContext(schemaContext, dataspaceName); + return new ResponseEntity<>("Resource successfully created", HttpStatus.CREATED); } @Override @@ -124,16 +116,11 @@ public class CpsRestController implements CpsRestApi { @PostMapping("/upload-yang-json-data-file") public final ResponseEntity uploadYangJsonDataFile( @RequestParam("file") MultipartFile uploadedFile) { - try { - validateJsonStructure(uploadedFile); - final int persistenceObjectId = cpService.storeJsonStructure(new String(uploadedFile.getBytes())); - return new ResponseEntity( - "Object stored in CPS with identity: " + persistenceObjectId, HttpStatus.OK); - } catch (final JsonSyntaxException e) { - return new ResponseEntity(e.getMessage(), HttpStatus.BAD_REQUEST); - } catch (final Exception e) { - return new ResponseEntity(e.getMessage(), HttpStatus.INTERNAL_SERVER_ERROR); - } + validateJsonStructure(uploadedFile); + final int persistenceObjectId = cpService.storeJsonStructure(getJsonString(uploadedFile)); + return new ResponseEntity( + "Object stored in CPS with identity: " + persistenceObjectId, HttpStatus.OK); + } /** @@ -145,13 +132,7 @@ public class CpsRestController implements CpsRestApi { @GetMapping("/json-object/{id}") public final ResponseEntity getJsonObjectById( @PathVariable("id") final int jsonObjectId) { - try { - return new ResponseEntity(cpService.getJsonById(jsonObjectId), HttpStatus.OK); - } catch (final PersistenceException e) { - return new ResponseEntity(e.getMessage(), HttpStatus.NOT_FOUND); - } catch (final Exception e) { - return new ResponseEntity(e.getMessage(), HttpStatus.INTERNAL_SERVER_ERROR); - } + return new ResponseEntity(cpService.getJsonById(jsonObjectId), HttpStatus.OK); } /** @@ -163,30 +144,39 @@ public class CpsRestController implements CpsRestApi { @DeleteMapping("json-object/{id}") public final ResponseEntity deleteJsonObjectById( @PathVariable("id") final int jsonObjectId) { + cpService.deleteJsonById(jsonObjectId); + return new ResponseEntity<>(HttpStatus.NO_CONTENT); + } + + private static void validateJsonStructure(final MultipartFile multipartFile) { 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); + final Gson gson = new Gson(); + gson.fromJson(getJsonString(multipartFile), Object.class); + } catch (JsonSyntaxException e) { + throw new CpsValidationException("Not a valid JSON file.", e); } } - 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 File saveToFile(final MultipartFile multipartFile) { + try { + final File file = File.createTempFile("tempFile", ".yang"); + file.deleteOnExit(); - 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; - try (OutputStream outputStream = new FileOutputStream(file)) { - outputStream.write(multipartFile.getBytes()); + } catch (IOException e) { + throw new CpsException(e); + } + } + + private static String getJsonString(final MultipartFile multipartFile) { + try { + return new String(multipartFile.getBytes()); + } catch (IOException e) { + throw new CpsException(e); } - return file; } } \ No newline at end of file diff --git a/cps/cps-rest/src/main/java/org/onap/cps/rest/exceptions/CpsRestExceptionHandler.java b/cps/cps-rest/src/main/java/org/onap/cps/rest/exceptions/CpsRestExceptionHandler.java new file mode 100644 index 000000000..9cf4935d4 --- /dev/null +++ b/cps/cps-rest/src/main/java/org/onap/cps/rest/exceptions/CpsRestExceptionHandler.java @@ -0,0 +1,98 @@ +/* + * ============LICENSE_START======================================================= + * Copyright (C) 2020 Pantheon.tech + * ================================================================================ + * 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.exceptions; + +import org.apache.commons.lang3.exception.ExceptionUtils; +import org.hibernate.exception.ConstraintViolationException; +import org.onap.cps.exceptions.CpsException; +import org.onap.cps.exceptions.CpsNotFoundException; +import org.onap.cps.exceptions.CpsValidationException; +import org.onap.cps.rest.controller.CpsRestController; +import org.springframework.dao.EmptyResultDataAccessException; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.ExceptionHandler; +import org.springframework.web.bind.annotation.RestControllerAdvice; + +@RestControllerAdvice(assignableTypes = {CpsRestController.class}) +public class CpsRestExceptionHandler { + + /** + * Default exception handler. + * + * @param exception the exception to handle + * @return response with response code 500. + */ + @ExceptionHandler + public ResponseEntity handleInternalErrorException(Exception exception) { + return buildErrorResponse(HttpStatus.INTERNAL_SERVER_ERROR, exception); + } + + /* + TODO: Rid off extra dependencies. + + Generic exception handler and CpsException (incl. children) are the only + exceptions to be handled here. All the other exceptions which require a special + treatment should be rethrown as CpsException in the place of occurrence -> + e.g. persistence exceptions are to be handled in cps-ri module. + */ + + @ExceptionHandler({ConstraintViolationException.class}) + public ResponseEntity handleBadRequestException(Exception exception) { + return buildErrorResponse(HttpStatus.BAD_REQUEST, exception); + } + + @ExceptionHandler({EmptyResultDataAccessException.class}) + public ResponseEntity handleNotFoundException(Exception exception) { + return buildErrorResponse(HttpStatus.NOT_FOUND, exception); + } + + @ExceptionHandler({CpsException.class}) + public ResponseEntity handleCpsException(CpsException exception) { + return buildErrorResponse(HttpStatus.INTERNAL_SERVER_ERROR, exception.getMessage(), extractDetails(exception)); + } + + @ExceptionHandler({CpsValidationException.class}) + public ResponseEntity handleCpsValidationException(CpsException exception) { + return buildErrorResponse(HttpStatus.BAD_REQUEST, exception.getMessage(), extractDetails(exception)); + } + + @ExceptionHandler({CpsNotFoundException.class}) + public ResponseEntity handleCpsNotFoundException(CpsException exception) { + return buildErrorResponse(HttpStatus.NOT_FOUND, exception.getMessage(), extractDetails(exception)); + } + + private static ResponseEntity buildErrorResponse(HttpStatus status, Exception exception) { + return buildErrorResponse(status, exception.getMessage(), ExceptionUtils.getStackTrace(exception)); + } + + private static ResponseEntity buildErrorResponse(HttpStatus status, String message, String details) { + return new ResponseEntity<>( + ErrorMessage.builder().status(status.toString()).message(message).details(details).build(), + status + ); + } + + private static String extractDetails(CpsException exception) { + return exception.getCause() == null + ? exception.getDetails() + : ExceptionUtils.getStackTrace(exception.getCause()); + } +} diff --git a/cps/cps-rest/src/main/java/org/onap/cps/rest/exceptions/ErrorMessage.java b/cps/cps-rest/src/main/java/org/onap/cps/rest/exceptions/ErrorMessage.java new file mode 100644 index 000000000..1f2a0b786 --- /dev/null +++ b/cps/cps-rest/src/main/java/org/onap/cps/rest/exceptions/ErrorMessage.java @@ -0,0 +1,37 @@ +/* + * ============LICENSE_START======================================================= + * Copyright (C) 2020 Pantheon.tech + * ================================================================================ + * 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.exceptions; + +import lombok.Builder; +import lombok.Data; + +/** + * Temporary POJO class used as error response model. + * TODO: To replace with model class generated from Open API specification. + * + */ +@Builder +@Data +public class ErrorMessage { + private String status; + private String message; + private String details; +} + diff --git a/cps/cps-service/src/main/java/org/onap/cps/api/CpService.java b/cps/cps-service/src/main/java/org/onap/cps/api/CpService.java index 2f735abc7..4d94a4654 100644 --- a/cps/cps-service/src/main/java/org/onap/cps/api/CpService.java +++ b/cps/cps-service/src/main/java/org/onap/cps/api/CpService.java @@ -36,7 +36,7 @@ public interface CpService { * @param yangModelContent the input stream * @return the schema context */ - SchemaContext parseAndValidateModel(final String yangModelContent) throws IOException, YangParserException; + SchemaContext parseAndValidateModel(final String yangModelContent); /** * Parse and validate a file representing a yang model to generate a schema context. @@ -44,7 +44,7 @@ public interface CpService { * @param yangModelFile the yang file * @return the schema context */ - SchemaContext parseAndValidateModel(final File yangModelFile) throws IOException, YangParserException; + SchemaContext parseAndValidateModel(final File yangModelFile); /** * Store schema context for a yang model. diff --git a/cps/cps-service/src/main/java/org/onap/cps/api/impl/CpServiceImpl.java b/cps/cps-service/src/main/java/org/onap/cps/api/impl/CpServiceImpl.java index 45aad3e44..c33746e86 100644 --- a/cps/cps-service/src/main/java/org/onap/cps/api/impl/CpServiceImpl.java +++ b/cps/cps-service/src/main/java/org/onap/cps/api/impl/CpServiceImpl.java @@ -26,6 +26,8 @@ import java.io.FileWriter; import java.io.IOException; import java.util.Optional; import org.onap.cps.api.CpService; +import org.onap.cps.exceptions.CpsException; +import org.onap.cps.exceptions.CpsValidationException; import org.onap.cps.spi.DataPersistencyService; import org.onap.cps.spi.ModelPersistencyService; import org.onap.cps.utils.YangUtils; @@ -47,18 +49,28 @@ public class CpServiceImpl implements CpService { private DataPersistencyService dataPersistencyService; @Override - public final SchemaContext parseAndValidateModel(final String yangModelContent) throws IOException, - YangParserException { - final File tempFile = File.createTempFile("yang", ".yang"); - try (BufferedWriter writer = new BufferedWriter(new FileWriter(tempFile))) { - writer.write(yangModelContent); + public final SchemaContext parseAndValidateModel(final String yangModelContent) { + + try { + final File tempFile = File.createTempFile("yang", ".yang"); + try (BufferedWriter writer = new BufferedWriter(new FileWriter(tempFile))) { + writer.write(yangModelContent); + } + return parseAndValidateModel(tempFile); + } catch (IOException e) { + throw new CpsException(e); } - return parseAndValidateModel(tempFile); } @Override - public final SchemaContext parseAndValidateModel(final File yangModelFile) throws IOException, YangParserException { - return YangUtils.parseYangModelFile(yangModelFile); + public final SchemaContext parseAndValidateModel(final File yangModelFile) { + try { + return YangUtils.parseYangModelFile(yangModelFile); + } catch (YangParserException e) { + throw new CpsValidationException("Yang file validation failed", e.getMessage()); + } catch (IOException e) { + throw new CpsException(e); + } } @Override diff --git a/cps/cps-service/src/main/java/org/onap/cps/exceptions/CpsException.java b/cps/cps-service/src/main/java/org/onap/cps/exceptions/CpsException.java new file mode 100644 index 000000000..b54453cd9 --- /dev/null +++ b/cps/cps-service/src/main/java/org/onap/cps/exceptions/CpsException.java @@ -0,0 +1,62 @@ +/* + * ============LICENSE_START======================================================= + * Copyright (C) 2020 Pantheon.tech + * ================================================================================ + * 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.exceptions; + +import lombok.Getter; +import org.springframework.core.NestedExceptionUtils; + +/** + * CP Service exception. + */ +public class CpsException extends RuntimeException { + + @Getter + String details; + + /** + * Constructor. + * + * @param cause the cause of the exception + */ + public CpsException(Throwable cause) { + super(cause.getMessage(), cause); + } + + /** + * Constructor. + * + * @param message the error message + * @param cause the cause of the exception + */ + public CpsException(String message, Throwable cause) { + super(message, cause); + } + + /** + * Constructor. + * + * @param message the error message + * @param details the error details + */ + public CpsException(String message, String details) { + super(message); + this.details = details; + } +} diff --git a/cps/cps-service/src/main/java/org/onap/cps/exceptions/CpsNotFoundException.java b/cps/cps-service/src/main/java/org/onap/cps/exceptions/CpsNotFoundException.java new file mode 100644 index 000000000..f44fe806c --- /dev/null +++ b/cps/cps-service/src/main/java/org/onap/cps/exceptions/CpsNotFoundException.java @@ -0,0 +1,57 @@ +/* + * ============LICENSE_START======================================================= + * Copyright (C) 2020 Pantheon.tech + * ================================================================================ + * 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.exceptions; + +import lombok.Getter; + +/** + * CP Service exception. Indicates the requested data being absent. + */ +public class CpsNotFoundException extends CpsException { + + /** + * Constructor. + * + * @param cause the cause of the exception + */ + public CpsNotFoundException(Throwable cause) { + super(cause.getMessage(), cause); + } + + /** + * Constructor. + * + * @param message the error message + * @param cause the cause of the exception + */ + public CpsNotFoundException(String message, Throwable cause) { + super(message, cause); + } + + /** + * Constructor. + * + * @param message the error message + * @param details the error details + */ + public CpsNotFoundException(String message, String details) { + super(message, details); + } +} diff --git a/cps/cps-service/src/main/java/org/onap/cps/exceptions/CpsValidationException.java b/cps/cps-service/src/main/java/org/onap/cps/exceptions/CpsValidationException.java new file mode 100644 index 000000000..dba9c165b --- /dev/null +++ b/cps/cps-service/src/main/java/org/onap/cps/exceptions/CpsValidationException.java @@ -0,0 +1,55 @@ +/* + * ============LICENSE_START======================================================= + * Copyright (C) 2020 Pantheon.tech + * ================================================================================ + * 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.exceptions; + +/** + * CP Service exception. Indicates the parameter validation failure. + */ +public class CpsValidationException extends CpsException { + + /** + * Constructor. + * + * @param cause the cause of the exception + */ + public CpsValidationException(Throwable cause) { + super(cause.getMessage(), cause); + } + + /** + * Constructor. + * + * @param message the error message + * @param cause the cause of the exception + */ + public CpsValidationException(String message, Throwable cause) { + super(message, cause); + } + + /** + * Constructor. + * + * @param message the error message + * @param details the error details + */ + public CpsValidationException(String message, String details) { + super(message, details); + } +} diff --git a/cps/cps-service/src/test/groovy/org/onap/cps/api/impl/CpServiceImplSpec.groovy b/cps/cps-service/src/test/groovy/org/onap/cps/api/impl/CpServiceImplSpec.groovy index 5e6fccb7a..5f42810bd 100644 --- a/cps/cps-service/src/test/groovy/org/onap/cps/api/impl/CpServiceImplSpec.groovy +++ b/cps/cps-service/src/test/groovy/org/onap/cps/api/impl/CpServiceImplSpec.groovy @@ -21,11 +21,10 @@ package org.onap.cps.api.impl import org.onap.cps.TestUtils +import org.onap.cps.exceptions.CpsValidationException import org.onap.cps.spi.DataPersistencyService - import org.opendaylight.yangtools.yang.common.Revision import org.opendaylight.yangtools.yang.model.api.SchemaContext -import org.opendaylight.yangtools.yang.model.parser.api.YangParserException import spock.lang.Specification class CpServiceImplSpec extends Specification { @@ -73,8 +72,8 @@ class CpServiceImplSpec extends Specification { File file = new File(ClassLoader.getSystemClassLoader().getResource('invalid.yang').getFile()) when: 'the model is parsed and validated' objectUnderTest.parseAndValidateModel(file) - then: 'a YangParserException is thrown' - thrown(YangParserException) + then: 'a CpsValidationException is thrown' + thrown(CpsValidationException) } def 'Store a SchemaContext'() { -- cgit 1.2.3-korg From 52cff68a4eed173059d3cda05435786f24cdf95e Mon Sep 17 00:00:00 2001 From: "puthuparambil.aditya" Date: Thu, 5 Nov 2020 11:34:41 +0000 Subject: Swagger-UI using Spring framework JIRA: https://jira.onap.org/browse/CCSDK-2895 Issue-ID: CCSDK-2895 Signed-off-by: puthuparambil.aditya Change-Id: I6e9e4b93aec25b0dd7a1acd3612140de47320d3c --- cps/README.md | 5 +- cps/cps-dependencies/pom.xml | 16 +---- cps/cps-parent/pom.xml | 82 ---------------------- cps/cps-rest/pom.xml | 26 +------ .../onap/cps/swagger/config/SpringFoxConfig.java | 46 ++++++++++++ cps/cps-rest/src/main/resources/application.yml | 8 +-- 6 files changed, 56 insertions(+), 127 deletions(-) create mode 100644 cps/cps-rest/src/main/java/org/onap/cps/swagger/config/SpringFoxConfig.java diff --git a/cps/README.md b/cps/README.md index d1bf49d8c..d5f0c66f4 100644 --- a/cps/README.md +++ b/cps/README.md @@ -29,6 +29,5 @@ java -DDB_HOST=localhost -DDB_USERNAME=cps -DDB_PASSWORD=cps -jar cps-rest/targe ``` * Browse - * [Swagger UI](http://localhost:8080/swagger-ui/index.html) - * OpenAPI Specification in [JSON](http://localhost:8080/api/cps/openapi.json) - or [YAML](http://localhost:8080/api/cps/openapi.yaml) format + * [Swagger UI](http://localhost:8080/api/cps/swagger-ui/index.html) + * [Api Documentation](http://localhost:8080/api/cps/v3/api-docs) diff --git a/cps/cps-dependencies/pom.xml b/cps/cps-dependencies/pom.xml index ad71b1158..ee37b1e0a 100644 --- a/cps/cps-dependencies/pom.xml +++ b/cps/cps-dependencies/pom.xml @@ -17,7 +17,7 @@ 2.10.0 2.0-M2-groovy-3.0 2.3.3.RELEASE - 2.6.1 + 3.0.0 2.1.4 5.0.6 @@ -43,20 +43,10 @@ swagger-annotations ${swagger.version} - - io.swagger.core.v3 - swagger-jaxrs2 - ${swagger.version} - - - io.springfox - springfox-swagger2 - ${springfox-swagger2.version} - io.springfox - springfox-swagger-ui - ${springfox-swagger2.version} + springfox-boot-starter + ${springfox.version} com.vladmihalcea diff --git a/cps/cps-parent/pom.xml b/cps/cps-parent/pom.xml index db80970c5..04f423caa 100644 --- a/cps/cps-parent/pom.xml +++ b/cps/cps-parent/pom.xml @@ -17,13 +17,9 @@ 11 - 3.2.0 - 3.1.2 - 1.5.3 3.1.0 2.3.3.RELEASE 3.0.18 - 3.35.0 @@ -106,84 +102,6 @@ - - - org.apache.maven.plugins - maven-dependency-plugin - ${maven-dependency-plugin.version} - - - prepare-package - - unpack - - - - - org.webjars - swagger-ui - ${swagger-ui.version} - - - - ${project.build.directory}/swagger-ui-${swagger-ui.version} - - - - - - - - org.apache.maven.plugins - maven-resources-plugin - ${maven-resources-plugin.version} - - - copy-resources - prepare-package - - copy-resources - - - ${project.build.outputDirectory}/static/swagger-ui - - - - - ${project.build.directory}/swagger-ui-${swagger-ui.version}/META-INF/resources/webjars/swagger-ui/${swagger-ui.version}/ - - - **/*.gz - - - - - - - - - - com.google.code.maven-replacer-plugin - replacer - ${maven-replacer-plugin.version} - - - prepare-package - - replace - - - - - ${project.build.outputDirectory}/static/swagger-ui/index.html - - - https://petstore.swagger.io/v2/swagger.json - /api/cps/openapi.json - - - - diff --git a/cps/cps-rest/pom.xml b/cps/cps-rest/pom.xml index fcd97dcf7..d10e0b63b 100644 --- a/cps/cps-rest/pom.xml +++ b/cps/cps-rest/pom.xml @@ -38,18 +38,11 @@ io.swagger.core.v3 swagger-annotations - - io.swagger.core.v3 - swagger-jaxrs2 - io.springfox - springfox-swagger2 - - - io.springfox - springfox-swagger-ui + springfox-boot-starter + org.springframework.boot spring-boot-starter-test @@ -74,21 +67,6 @@ io.swagger.codegen.v3 swagger-codegen-maven-plugin - - - org.apache.maven.plugins - maven-dependency-plugin - - - - org.apache.maven.plugins - maven-resources-plugin - - - - com.google.code.maven-replacer-plugin - replacer - diff --git a/cps/cps-rest/src/main/java/org/onap/cps/swagger/config/SpringFoxConfig.java b/cps/cps-rest/src/main/java/org/onap/cps/swagger/config/SpringFoxConfig.java new file mode 100644 index 000000000..73e179511 --- /dev/null +++ b/cps/cps-rest/src/main/java/org/onap/cps/swagger/config/SpringFoxConfig.java @@ -0,0 +1,46 @@ +/* + * ============LICENSE_START======================================================= + * 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.swagger.config; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import springfox.documentation.builders.PathSelectors; +import springfox.documentation.builders.RequestHandlerSelectors; +import springfox.documentation.spi.DocumentationType; +import springfox.documentation.spring.web.plugins.Docket; + +/** + * Swagger configuration. + */ +@Configuration +public class SpringFoxConfig { + + /** + * Define api configuration. + */ + @Bean + public Docket api() { + return new Docket(DocumentationType.OAS_30) + .select() + .apis(RequestHandlerSelectors.any()) + .paths(PathSelectors.any()) + .build(); + } +} diff --git a/cps/cps-rest/src/main/resources/application.yml b/cps/cps-rest/src/main/resources/application.yml index 8e2aee043..545faafc3 100644 --- a/cps/cps-rest/src/main/resources/application.yml +++ b/cps/cps-rest/src/main/resources/application.yml @@ -1,7 +1,7 @@ server: - port: 8080 - servlet: - context-path: /api/cps + port: 8080 + servlet: + context-path: /api/cps spring: main: @@ -21,8 +21,6 @@ spring: password: ${DB_PASSWORD} driverClassName: org.postgresql.Driver initialization-mode: always - jersey: - type: filter logging: level: -- cgit 1.2.3-korg