From 290fc0a7a322c9426c3117ed6b8081b02c9d6bc9 Mon Sep 17 00:00:00 2001 From: Christos Tranoris Date: Mon, 6 Nov 2023 14:12:25 +0200 Subject: [PATCH] initial commi (cherry picked from commit fd4e5397ff6f42265e08fc1afbdd4436322fda81) --- .gitignore | 4 + Dockerfile.portalapi | 7 + LICENSE | 201 + README.md | 92 +- pom-prev.xml | 688 ++++ pom.xml | 299 ++ .../java/portal/api/LocalMysqlDialect.java | 29 + src/main/java/portal/api/MvcConfig.java | 76 + .../java/portal/api/PortalApplication.java | 59 + .../java/portal/api/bus/BusController.java | 643 +++ .../portal/api/bus/BusControllerActiveMQ.java | 479 +++ .../api/config/ActiveMQComponentConfig.java | 50 + .../config/BCryptPasswordEncoderConfig.java | 35 + .../api/config/CustomClaimVerifier.java | 37 + .../api/config/MethodSecurityConfig.java | 37 + .../config/RestAuthenticationEntryPoint.java | 56 + .../api/config/WebSecurityConfigKeycloak.java | 253 ++ .../controller/ArtifactsAPIController.java | 3495 +++++++++++++++++ .../api/controller/ForbiddenException.java | 30 + .../portal/api/controller/HomeController.java | 35 + .../controller/PortalRepositoryAPIImpl.java | 709 ++++ .../PortalRepositoryVFImageAPI.java | 432 ++ .../java/portal/api/mano/MANOController.java | 405 ++ .../portal/api/mano/MANORouteBuilder.java | 130 + .../java/portal/api/mano/MANOService.java | 57 + src/main/java/portal/api/mano/MANOStatus.java | 149 + .../mano/NSCreateInstanceRequestPayload.java | 40 + .../NSInstantiateInstanceRequestPayload.java | 103 + .../portal/api/repo/CategoriesRepository.java | 35 + .../repo/DeploymentDescriptorRepository.java | 178 + .../api/repo/InfrastructureRepository.java | 37 + .../api/repo/ManoPlatformRepository.java | 36 + .../api/repo/ManoProvidersRepository.java | 46 + .../portal/api/repo/NSDOBDRepository.java | 37 + .../java/portal/api/repo/NSDsRepository.java | 69 + .../api/repo/PortalPropertiesRepository.java | 39 + .../portal/api/repo/ProductRepository.java | 44 + .../java/portal/api/repo/UsersRepository.java | 56 + .../portal/api/repo/VFImageRepository.java | 47 + .../portal/api/repo/VxFOBDRepository.java | 49 + .../java/portal/api/repo/VxFsRepository.java | 61 + .../portal/api/service/CategoryService.java | 103 + .../service/DeploymentDescriptorService.java | 660 ++++ .../api/service/InfrastructureService.java | 130 + .../api/service/ItemNotFoundException.java | 31 + .../api/service/ManoPlatformService.java | 71 + .../api/service/ManoProviderService.java | 157 + .../portal/api/service/NSDOBDService.java | 147 + .../java/portal/api/service/NSDService.java | 171 + .../api/service/PortalPropertiesService.java | 120 + .../portal/api/service/ProductService.java | 55 + .../java/portal/api/service/UsersService.java | 209 + .../portal/api/service/VFImageService.java | 77 + .../portal/api/service/VxFOBDService.java | 180 + .../java/portal/api/service/VxFService.java | 185 + .../portal/api/swagger2/SwaggerConfig.java | 80 + .../java/portal/api/util/AttachmentUtil.java | 246 ++ src/main/java/portal/api/util/EmailUtil.java | 133 + .../api/validation/ci/ValidationCIClient.java | 54 + .../ci/ValidationCIRouteBuilder.java | 177 + .../validation/ci/ValidationJobResult.java | 98 + src/main/resources/application.yml | 117 + src/main/resources/banner.txt | 11 + src/main/resources/logback.xml | 60 + src/main/resources/public.txt | 9 + .../portal/api/InMemoryDBIntegrationTest.java | 608 +++ src/test/resources/application-testing.yml | 81 + src/test/resources/cirros_2vnf_ns.tar.gz | Bin 0 -> 18831 bytes src/test/resources/cirros_vnf.tar.gz | Bin 0 -> 4974 bytes src/test/resources/deploymentReq.txt | 129 + src/test/resources/logback-test.xml | 32 + src/test/resources/test | 0 src/test/resources/testnsd.txt | 1 + src/test/resources/testvxf.txt | 1 + 74 files changed, 13406 insertions(+), 91 deletions(-) create mode 100644 .gitignore create mode 100644 Dockerfile.portalapi create mode 100644 LICENSE create mode 100644 pom-prev.xml create mode 100644 pom.xml create mode 100644 src/main/java/portal/api/LocalMysqlDialect.java create mode 100644 src/main/java/portal/api/MvcConfig.java create mode 100644 src/main/java/portal/api/PortalApplication.java create mode 100644 src/main/java/portal/api/bus/BusController.java create mode 100644 src/main/java/portal/api/bus/BusControllerActiveMQ.java create mode 100644 src/main/java/portal/api/config/ActiveMQComponentConfig.java create mode 100644 src/main/java/portal/api/config/BCryptPasswordEncoderConfig.java create mode 100644 src/main/java/portal/api/config/CustomClaimVerifier.java create mode 100644 src/main/java/portal/api/config/MethodSecurityConfig.java create mode 100644 src/main/java/portal/api/config/RestAuthenticationEntryPoint.java create mode 100644 src/main/java/portal/api/config/WebSecurityConfigKeycloak.java create mode 100644 src/main/java/portal/api/controller/ArtifactsAPIController.java create mode 100644 src/main/java/portal/api/controller/ForbiddenException.java create mode 100644 src/main/java/portal/api/controller/HomeController.java create mode 100644 src/main/java/portal/api/controller/PortalRepositoryAPIImpl.java create mode 100644 src/main/java/portal/api/controller/PortalRepositoryVFImageAPI.java create mode 100644 src/main/java/portal/api/mano/MANOController.java create mode 100644 src/main/java/portal/api/mano/MANORouteBuilder.java create mode 100644 src/main/java/portal/api/mano/MANOService.java create mode 100644 src/main/java/portal/api/mano/MANOStatus.java create mode 100644 src/main/java/portal/api/mano/NSCreateInstanceRequestPayload.java create mode 100644 src/main/java/portal/api/mano/NSInstantiateInstanceRequestPayload.java create mode 100644 src/main/java/portal/api/repo/CategoriesRepository.java create mode 100644 src/main/java/portal/api/repo/DeploymentDescriptorRepository.java create mode 100644 src/main/java/portal/api/repo/InfrastructureRepository.java create mode 100644 src/main/java/portal/api/repo/ManoPlatformRepository.java create mode 100644 src/main/java/portal/api/repo/ManoProvidersRepository.java create mode 100644 src/main/java/portal/api/repo/NSDOBDRepository.java create mode 100644 src/main/java/portal/api/repo/NSDsRepository.java create mode 100644 src/main/java/portal/api/repo/PortalPropertiesRepository.java create mode 100644 src/main/java/portal/api/repo/ProductRepository.java create mode 100644 src/main/java/portal/api/repo/UsersRepository.java create mode 100644 src/main/java/portal/api/repo/VFImageRepository.java create mode 100644 src/main/java/portal/api/repo/VxFOBDRepository.java create mode 100644 src/main/java/portal/api/repo/VxFsRepository.java create mode 100644 src/main/java/portal/api/service/CategoryService.java create mode 100644 src/main/java/portal/api/service/DeploymentDescriptorService.java create mode 100644 src/main/java/portal/api/service/InfrastructureService.java create mode 100644 src/main/java/portal/api/service/ItemNotFoundException.java create mode 100644 src/main/java/portal/api/service/ManoPlatformService.java create mode 100644 src/main/java/portal/api/service/ManoProviderService.java create mode 100644 src/main/java/portal/api/service/NSDOBDService.java create mode 100644 src/main/java/portal/api/service/NSDService.java create mode 100644 src/main/java/portal/api/service/PortalPropertiesService.java create mode 100644 src/main/java/portal/api/service/ProductService.java create mode 100644 src/main/java/portal/api/service/UsersService.java create mode 100644 src/main/java/portal/api/service/VFImageService.java create mode 100644 src/main/java/portal/api/service/VxFOBDService.java create mode 100644 src/main/java/portal/api/service/VxFService.java create mode 100644 src/main/java/portal/api/swagger2/SwaggerConfig.java create mode 100644 src/main/java/portal/api/util/AttachmentUtil.java create mode 100644 src/main/java/portal/api/util/EmailUtil.java create mode 100644 src/main/java/portal/api/validation/ci/ValidationCIClient.java create mode 100644 src/main/java/portal/api/validation/ci/ValidationCIRouteBuilder.java create mode 100644 src/main/java/portal/api/validation/ci/ValidationJobResult.java create mode 100644 src/main/resources/application.yml create mode 100644 src/main/resources/banner.txt create mode 100644 src/main/resources/logback.xml create mode 100644 src/main/resources/public.txt create mode 100644 src/test/java/portal/api/InMemoryDBIntegrationTest.java create mode 100644 src/test/resources/application-testing.yml create mode 100644 src/test/resources/cirros_2vnf_ns.tar.gz create mode 100644 src/test/resources/cirros_vnf.tar.gz create mode 100644 src/test/resources/deploymentReq.txt create mode 100644 src/test/resources/logback-test.xml create mode 100644 src/test/resources/test create mode 100644 src/test/resources/testnsd.txt create mode 100644 src/test/resources/testvxf.txt diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..0bc3c3c --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +/target/ +/.project +/.classpath +/.settings diff --git a/Dockerfile.portalapi b/Dockerfile.portalapi new file mode 100644 index 0000000..614f44a --- /dev/null +++ b/Dockerfile.portalapi @@ -0,0 +1,7 @@ +FROM ibm-semeru-runtimes:open-17.0.7_7-jdk +MAINTAINER openslice.io +RUN mkdir /opt/shareclasses +RUN mkdir -p /opt/openslice/lib/ +COPY target/org.etsi.osl.portal.api-1.2.0-SNAPSHOT.jar /opt/openslice/lib/ +CMD ["java", "-Xshareclasses:cacheDir=/opt/shareclasses","-jar", "/opt/openslice/lib/org.etsi.osl.portal.api-1.2.0-SNAPSHOT.jar"] +EXPOSE 13000 \ No newline at end of file diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..261eeb9 --- /dev/null +++ b/LICENSE @@ -0,0 +1,201 @@ + 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 + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + 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. diff --git a/README.md b/README.md index 46ff88a..75485cb 100644 --- a/README.md +++ b/README.md @@ -1,92 +1,2 @@ # org.etsi.osl.portal.api - - - -## Getting started - -To make it easy for you to get started with GitLab, here's a list of recommended next steps. - -Already a pro? Just edit this README.md and make it your own. Want to make it easy? [Use the template at the bottom](#editing-this-readme)! - -## Add your files - -- [ ] [Create](https://docs.gitlab.com/ee/user/project/repository/web_editor.html#create-a-file) or [upload](https://docs.gitlab.com/ee/user/project/repository/web_editor.html#upload-a-file) files -- [ ] [Add files using the command line](https://docs.gitlab.com/ee/gitlab-basics/add-file.html#add-a-file-using-the-command-line) or push an existing Git repository with the following command: - -``` -cd existing_repo -git remote add origin https://labs.etsi.org/rep/osl/code/org.etsi.osl.portal.api.git -git branch -M main -git push -uf origin main -``` - -## Integrate with your tools - -- [ ] [Set up project integrations](https://labs.etsi.org/rep/osl/code/org.etsi.osl.portal.api/-/settings/integrations) - -## Collaborate with your team - -- [ ] [Invite team members and collaborators](https://docs.gitlab.com/ee/user/project/members/) -- [ ] [Create a new merge request](https://docs.gitlab.com/ee/user/project/merge_requests/creating_merge_requests.html) -- [ ] [Automatically close issues from merge requests](https://docs.gitlab.com/ee/user/project/issues/managing_issues.html#closing-issues-automatically) -- [ ] [Enable merge request approvals](https://docs.gitlab.com/ee/user/project/merge_requests/approvals/) -- [ ] [Automatically merge when pipeline succeeds](https://docs.gitlab.com/ee/user/project/merge_requests/merge_when_pipeline_succeeds.html) - -## Test and Deploy - -Use the built-in continuous integration in GitLab. - -- [ ] [Get started with GitLab CI/CD](https://docs.gitlab.com/ee/ci/quick_start/index.html) -- [ ] [Analyze your code for known vulnerabilities with Static Application Security Testing(SAST)](https://docs.gitlab.com/ee/user/application_security/sast/) -- [ ] [Deploy to Kubernetes, Amazon EC2, or Amazon ECS using Auto Deploy](https://docs.gitlab.com/ee/topics/autodevops/requirements.html) -- [ ] [Use pull-based deployments for improved Kubernetes management](https://docs.gitlab.com/ee/user/clusters/agent/) -- [ ] [Set up protected environments](https://docs.gitlab.com/ee/ci/environments/protected_environments.html) - -*** - -# Editing this README - -When you're ready to make this README your own, just edit this file and use the handy template below (or feel free to structure it however you want - this is just a starting point!). Thank you to [makeareadme.com](https://www.makeareadme.com/) for this template. - -## Suggestions for a good README -Every project is different, so consider which of these sections apply to yours. The sections used in the template are suggestions for most open source projects. Also keep in mind that while a README can be too long and detailed, too long is better than too short. If you think your README is too long, consider utilizing another form of documentation rather than cutting out information. - -## Name -Choose a self-explaining name for your project. - -## Description -Let people know what your project can do specifically. Provide context and add a link to any reference visitors might be unfamiliar with. A list of Features or a Background subsection can also be added here. If there are alternatives to your project, this is a good place to list differentiating factors. - -## Badges -On some READMEs, you may see small images that convey metadata, such as whether or not all the tests are passing for the project. You can use Shields to add some to your README. Many services also have instructions for adding a badge. - -## Visuals -Depending on what you are making, it can be a good idea to include screenshots or even a video (you'll frequently see GIFs rather than actual videos). Tools like ttygif can help, but check out Asciinema for a more sophisticated method. - -## Installation -Within a particular ecosystem, there may be a common way of installing things, such as using Yarn, NuGet, or Homebrew. However, consider the possibility that whoever is reading your README is a novice and would like more guidance. Listing specific steps helps remove ambiguity and gets people to using your project as quickly as possible. If it only runs in a specific context like a particular programming language version or operating system or has dependencies that have to be installed manually, also add a Requirements subsection. - -## Usage -Use examples liberally, and show the expected output if you can. It's helpful to have inline the smallest example of usage that you can demonstrate, while providing links to more sophisticated examples if they are too long to reasonably include in the README. - -## Support -Tell people where they can go to for help. It can be any combination of an issue tracker, a chat room, an email address, etc. - -## Roadmap -If you have ideas for releases in the future, it is a good idea to list them in the README. - -## Contributing -State if you are open to contributions and what your requirements are for accepting them. - -For people who want to make changes to your project, it's helpful to have some documentation on how to get started. Perhaps there is a script that they should run or some environment variables that they need to set. Make these steps explicit. These instructions could also be useful to your future self. - -You can also document commands to lint the code or run tests. These steps help to ensure high code quality and reduce the likelihood that the changes inadvertently break something. Having instructions for running tests is especially helpful if it requires external setup, such as starting a Selenium server for testing in a browser. - -## Authors and acknowledgment -Show your appreciation to those who have contributed to the project. - -## License -For open source projects, say how it is licensed. - -## Project status -If you have run out of energy or time for your project, put a note at the top of the README saying that development has slowed down or stopped completely. Someone may choose to fork your project or volunteer to step in as a maintainer or owner, allowing your project to keep going. You can also make an explicit request for maintainers. +The backend RESTful API for the openslice portal diff --git a/pom-prev.xml b/pom-prev.xml new file mode 100644 index 0000000..25d180f --- /dev/null +++ b/pom-prev.xml @@ -0,0 +1,688 @@ + + 4.0.0 + + org.etsi.osl + org.etsi.osl.portal.api + 0.0.1-SNAPSHOT + + org.etsi.osl.portal.api + http://maven.apache.org + + + + 2.8.11 + 1.2.5 + 3.2.5 + 4.2.1 + 2.24.1 + 5.15.9 + + + + repo-snapshot + repo-snapshot + ${nexusRepositories}/snapshots + + repo-release + repo-release + ${nexusRepositories}/releases + + repo-third-party-release + repo-third-party-release + ${nexusRepositories}/thirdparty + + + + + utf-8 + ${encoding} + ${encoding} + ${encoding} + ${encoding} + + 2.4.2 + 4.3.14.RELEASE + + 1.2.3 + 9.4.19.v20190610 + + + + + + org.apache.cxf + cxf-rt-rs-client + ${cxf.version} + + + org.apache.cxf + cxf-rt-transports-http-jetty + ${cxf.version} + + + org.apache.cxf + cxf-rt-frontend-jaxrs + ${cxf.version} + + + + org.apache.cxf + cxf-rt-rs-security-cors + ${cxf.version} + + + org.apache.cxf + cxf-rt-rs-security-oauth2 + ${cxf.version} + + + + com.fasterxml.jackson.dataformat + jackson-dataformat-yaml + ${jackson.version} + + + com.fasterxml.jackson.core + jackson-databind + ${jackson.version} + + + org.apache.camel + camel-core + ${camel.version} + + + org.apache.camel + camel-test + ${camel.version} + + + org.apache.camel + camel-spring + ${camel.version} + + + org.apache.camel + camel-jms + ${camel.version} + + + org.apache.camel + camel-http + ${camel.version} + + + org.apache.camel + camel-stream + ${camel.version} + + + org.apache.camel + camel-jackson + ${camel.version} + + + + + org.apache.activemq + activemq-camel + ${activemq.version} + + + org.apache.activemq + activemq-broker + ${activemq.version} + + + org.apache.activemq + activemq-client + ${activemq.version} + + + + org.apache.geronimo.specs + geronimo-jms_1.1_spec + + + + + + org.springframework + spring-web + ${spring.version} + + + org.springframework + spring-jdbc + ${spring.version} + + + org.springframework + spring-orm + ${spring.version} + + + org.springframework + spring-test + ${spring.version} + provided + + + org.springframework + spring-expression + ${spring.version} + + + + junit + junit + 4.12 + test + + + javax.servlet.jsp + jsp-api + 2.2 + + + org.apache.commons + commons-exec + 1.2 + + + + + + org.apache.openjpa + openjpa + ${openjpa.version} + + + org.apache.openjpa + openjpa-jdbc + ${openjpa.version} + + + org.apache.openjpa + openjpa-persistence-jdbc + ${openjpa.version} + + + com.h2database + h2 + 1.4.179 + + + javax.servlet + javax.servlet-api + 3.1.0 + + + + + org.apache.shiro + shiro-core + ${shiro.version} + + + org.apache.shiro + shiro-web + ${shiro.version} + + + org.apache.shiro + shiro-spring + ${shiro.version} + + + org.eclipse.jetty + jetty-servlets + ${jetty.version} + + + mysql + mysql-connector-java + 5.1.33 + + + + org.pacesys + openstack4j + 3.1.0 + withdeps + + + org.slf4j + slf4j-simple + 1.7.5 + + + + com.sun.mail + javax.mail + 1.5.2 + + + + org.etsi.osl + org.etsi.osl.sol005nbi.osm5 + 0.0.1-SNAPSHOT + + + + + + org.apache.cxf + cxf-rt-rs-service-description-swagger + ${cxf.version} + + + org.webjars + swagger-ui + 3.1.7 + + + + com.google.guava + guava + 23.3-jre + + + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + + 1.8 + 1.8 + + + + + + org.eclipse.m2e + lifecycle-mapping + 1.0.0 + + + + + + + org.apache.openjpa + + + openjpa-maven-plugin + + + [2.2.1,) + + + enhance + + + + + + + + + + + + + + + + + org.apache.openjpa + openjpa-maven-plugin + ${openjpa.version} + + org.etsi.osl.portal.api.model + **/org.etsi.osl.portal.api/*.class + true + true + + + + + enhancer-classes + process-classes + + enhance + + + + + + + org.apache.openjpa + openjpa + + ${openjpa.version} + + + + + + + + com.google.code.maven-license-plugin + maven-license-plugin + ${maven-license-plugin.version} + +
src/license/header.txt
+ + src/main/**/*.java + src/test/**/*.java + +
+ + + format-classes + + format + + + + check-classes + + check + + + +
+ + +
+
+ + + + + + ${repoMavenSnapshotId} + ${repoMavenSnapshotName} + ${repoMavenSnapshotUrl} + + + ${repoMavenId} + ${repoMavenName} + ${repoMavenUrl} + + + ${repoMavenThirdpartyId} + ${repoMavenThirdpartyName} + ${repoMavenThirdpartyUrl} + + + + + central + central-repository + http://repo1.maven.org/maven2 + + + central2 + central2-repository + http://repo2.maven.org/maven2 + + + + + com.springsource.repository.libraries.release + SpringSource Enterprise Bundle Repository - SpringSource Library Releases + http://repository.springsource.com/maven/libraries/release + + + com.springsource.repository.libraries.external + SpringSource Enterprise Bundle Repository - External Library Releases + http://repository.springsource.com/maven/libraries/external + + + + + + + + + + + docbkx + + package + + + + com.agilejava.docbkx + docbkx-maven-plugin + 2.0.14 + + + doc + package + + generate-html + + + + + + + net.sf.docbook + docbook-xml + 5.0-all + resources + zip + runtime + + + net.sf.xslthl + xslthl + 2.0.1 + runtime + + + net.sf.offo + fop-hyph + 1.2 + runtime + + + + + + + + + + + + + + + + + + + css/docbook.css + ${project.basedir}/src/documentation/docbkx-stylesheet/html/docbook.xsl + + ${project.basedir}/src/documentation/docbkx + target/docs/html + true + 1 + 1 + A4 + true + 1 + ${project.basedir}/src/documentation/docbkx-stylesheet/html/docbook.xsl + portal_manual.xml, test.xml + + + + + + + + + + + + + + jetty.integration + + + + + + + org.eclipse.jetty + jetty-maven-plugin + ${jetty.version} + + + + + 13000 + + 4 + + + /opensliceportal + + + + /static + /home/ubuntu/.portal/metadata/ + + no-cache + true + + + + /mp + ${project.basedir}/../org.etsi.osl.portal.web/src + + no-cache + true + + + + + + + + + run-jetty + + run + + + + + + + + + org.codehaus.mojo + build-helper-maven-plugin + 1.5 + + + reserve-network-port + + reserve-network-port + + process-test-resources + + + test.server.port + + + + + + + org.eclipse.jetty + jetty-maven-plugin + + + start-jetty + + run-war + + pre-integration-test + + + ${test.server.port} + + + /rsportal-srvtest + + 9999 + STOP + true + + + + stop-jetty + + stop + + post-integration-test + + STOP + 9999 + + + + + + + org.apache.maven.plugins + maven-failsafe-plugin + 2.8.1 + + + integration-test + + integration-test + + + + http://localhost:${test.server.port}/rsportal-srvtest + + + + + verify + + verify + + + + + + + + + + + +
\ No newline at end of file diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..8cf7444 --- /dev/null +++ b/pom.xml @@ -0,0 +1,299 @@ + + 4.0.0 + + + org.etsi.osl + org.etsi.osl.main + 1.2.0-SNAPSHOT + ../org.etsi.osl.main + + + org.etsi.osl.portal.api + + org.etsi.osl.portal.api + http://maven.apache.org + + + + + UTF-8 + UTF-8 + ${spring-boot-version} + ${springdoc-version} + 1.7.0 + 1.7.0 + ${mysql.connector.version} + + + + + + + + + org.springframework.boot + spring-boot-dependencies + ${spring.boot-version} + pom + import + + + + org.apache.camel.springboot + camel-spring-boot-dependencies + ${camel.version} + pom + import + + + + + com.google.guava + guava + 32.0.0-jre + + + + org.keycloak.bom + keycloak-adapter-bom + ${keycloak.version} + pom + import + + + + + + + + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.boot + spring-boot-starter-data-jpa + + + org.springframework.boot + spring-boot-starter-activemq + + + org.springframework.boot + spring-boot-starter-oauth2-resource-server + + + org.messaginghub + pooled-jms + + + + + org.springframework.boot + spring-boot-starter-actuator + + + + org.keycloak + keycloak-spring-boot-starter + + + org.keycloak + keycloak-spring-security-adapter + + + + org.keycloak + keycloak-admin-client + ${keycloak.version} + + + + mysql + mysql-connector-java + runtime + ${mysql-connector.version} + + + + org.projectlombok + lombok + provided + + + + + com.fasterxml.jackson.core + jackson-databind + + + com.fasterxml.jackson.datatype + jackson-datatype-hibernate5-jakarta + + + com.jayway.jsonpath + json-path + + + + + + + org.apache.camel.springboot + camel-spring-boot-starter + + + org.apache.camel + camel-jackson + + + org.apache.activemq + activemq-pool + + + org.apache.camel + camel-activemq + + + org.apache.activemq + activemq-broker + + + + + + org.apache.camel.springboot + camel-http-starter + + + org.apache.camel.springboot + camel-consul-starter + + + + + + + com.sun.mail + javax.mail + 1.4.7 + + + + org.apache.commons + commons-lang3 + + + + + + + org.springdoc + springdoc-openapi-starter-webmvc-ui + ${springdoc.version} + + + org.springdoc + springdoc-openapi-ui + ${springdoc.openapiui.version} + + + org.springdoc + springdoc-openapi-security + ${springdoc.security.version} + + + org.etsi.osl + org.etsi.osl.model + ${project.version} + + + org.etsi.osl.sol005nbi + org.etsi.osl.sol005nbi.osm + 1.2.0-SNAPSHOT + + + + org.etsi.osl.sol005nbi + org.etsi.osl.sol005nbi.osm10 + 1.2.0-SNAPSHOT + + + org.etsi.osl + org.etsi.osl.centrallog.client + ${project.version} + + + + + + + org.springframework.boot + spring-boot-starter-test + test + + + org.springframework.security + spring-security-test + test + + + com.h2database + h2 + test + + + + org.junit.jupiter + junit-jupiter-engine + test + + + org.junit.platform + junit-platform-commons + test + + + org.junit.platform + junit-platform-runner + test + + + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + + ${java.version} + ${java.version} + + + + + + + org.springframework.boot + spring-boot-maven-plugin + ${spring-boot-version} + + + + repackage + + + + + + + + + + + \ No newline at end of file diff --git a/src/main/java/portal/api/LocalMysqlDialect.java b/src/main/java/portal/api/LocalMysqlDialect.java new file mode 100644 index 0000000..bf200b9 --- /dev/null +++ b/src/main/java/portal/api/LocalMysqlDialect.java @@ -0,0 +1,29 @@ +/*- + * ========================LICENSE_START================================= + * org.etsi.osl.tmf.api + * %% + * Copyright (C) 2019 openslice.io + * %% + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * =========================LICENSE_END================================== + */ +package portal.api; + +import org.hibernate.dialect.MySQLDialect; ; + +public class LocalMysqlDialect extends MySQLDialect { + @Override + public String getTableTypeString() { + return " DEFAULT CHARSET=utf8"; + } +} diff --git a/src/main/java/portal/api/MvcConfig.java b/src/main/java/portal/api/MvcConfig.java new file mode 100644 index 0000000..f20af41 --- /dev/null +++ b/src/main/java/portal/api/MvcConfig.java @@ -0,0 +1,76 @@ +/*- + * ========================LICENSE_START================================= + * org.etsi.osl.portal.api + * %% + * Copyright (C) 2019 openslice.io + * %% + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * =========================LICENSE_END================================== + */ +package portal.api; + +import java.io.File; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.env.Environment; +import org.springframework.web.servlet.config.annotation.EnableWebMvc; +import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; +import org.springframework.web.servlet.config.annotation.ViewControllerRegistry; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; +import org.springframework.web.servlet.resource.EncodedResourceResolver; +import org.springframework.web.servlet.resource.PathResourceResolver; + +@Configuration +//@EnableWebMvc - removed 30/7/2021 +public class MvcConfig implements WebMvcConfigurer { + @Autowired + Environment env; + + public MvcConfig() { + super(); + } + + + @Override + public void addViewControllers(final ViewControllerRegistry registry) { + registry.addViewController("/index.html"); + + } + + @Override + public void addResourceHandlers(ResourceHandlerRegistry registry) { + // registry.addResourceHandler("/testweb/**").addResourceLocations("file:///C:/Users/ctranoris/git/org.etsi.osl.portal.web/src/").setCachePeriod(0); + String a = ( new File("../org.etsi.osl.portal.web/src/")).getAbsoluteFile().toURI().toString() ; + System.out.println("======================> " + a); + registry.addResourceHandler("/testweb/**") + .addResourceLocations( a ) //"file:///./../org.etsi.osl.portal.web/src/") + .setCachePeriod(0) + .resourceChain(true) + .addResolver(new EncodedResourceResolver()) + .addResolver(new PathResourceResolver()); + + registry.addResourceHandler("/swagger-ui/**") + .addResourceLocations("classpath:/META-INF/resources/webjars/springfox-swagger-ui/") + .resourceChain(false); + + registry.addResourceHandler("swagger-ui.html") + .addResourceLocations("classpath:/META-INF/resources/"); + + registry.addResourceHandler("/webjars/**") + .addResourceLocations("classpath:/META-INF/resources/webjars/"); + + } + + +} diff --git a/src/main/java/portal/api/PortalApplication.java b/src/main/java/portal/api/PortalApplication.java new file mode 100644 index 0000000..687f81a --- /dev/null +++ b/src/main/java/portal/api/PortalApplication.java @@ -0,0 +1,59 @@ +/*- + * ========================LICENSE_START================================= + * org.etsi.osl.portal.api + * %% + * Copyright (C) 2019 openslice.io + * %% + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * =========================LICENSE_END================================== + */ +package portal.api; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.autoconfigure.domain.EntityScan; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.web.servlet.config.annotation.EnableWebMvc; + + +/** + * Our API docs are at: + * http://localhost:13000/osapi/swagger-ui/index.html + * http://localhost:13000/osapi/v2/api-docs + * + * @author ctranoris + * + */ +@SpringBootApplication() +@EnableWebMvc +@EntityScan( basePackages = {"org.etsi.osl.model", "org.etsi.osl.centrallog.client"}) +@ComponentScan(basePackages = { + "portal.api", + "portal.api.bus", + "portal.api.config", + "portal.api.controller", + "portal.api.mano", + "portal.api.repo", + "portal.api.service", + "portal.api.swagger2", + "portal.api.util", + "portal.api.validation.ci", + "org.etsi.osl.centrallog.client" + }) +public class PortalApplication { + + public static void main(String[] args) { + SpringApplication.run(PortalApplication.class, args); + } + +} diff --git a/src/main/java/portal/api/bus/BusController.java b/src/main/java/portal/api/bus/BusController.java new file mode 100644 index 0000000..2a091aa --- /dev/null +++ b/src/main/java/portal/api/bus/BusController.java @@ -0,0 +1,643 @@ +/*- + * ========================LICENSE_START================================= + * org.etsi.osl.portal.api + * %% + * Copyright (C) 2019 openslice.io + * %% + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * =========================LICENSE_END================================== + */ + +package portal.api.bus; + +import java.io.IOException; + +import com.fasterxml.jackson.core.JsonParseException; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.JsonMappingException; +import com.fasterxml.jackson.databind.ObjectMapper; + +import org.apache.camel.CamelContext; +import org.apache.camel.FluentProducerTemplate; +import org.apache.camel.ProducerTemplate; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.json.JSONObject; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Configuration; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.jms.core.JmsTemplate; +import org.springframework.stereotype.Component; + +import org.etsi.osl.model.CompositeExperimentOnBoardDescriptor; +import org.etsi.osl.model.CompositeVxFOnBoardDescriptor; +import org.etsi.osl.model.DeploymentDescriptor; +import org.etsi.osl.model.ExperimentMetadata; +import org.etsi.osl.model.ExperimentOnBoardDescriptor; +import org.etsi.osl.model.PortalUser; +import org.etsi.osl.model.VFImage; +import org.etsi.osl.model.VxFMetadata; +import org.etsi.osl.model.VxFOnBoardedDescriptor; +import portal.api.mano.MANOStatus; +import portal.api.validation.ci.ValidationJobResult; + + +/** + * Exposes messages to Bus. Usually they should be aynchronous. + * Consult http://camel.apache.org/uris.html for URIs + * sendmessage(direct:mplampla) is Synchronous in same Context + * sendmessage(seda:mplampla) is aSynchronous in same Context + * * + * @author ctranoris + * + * + * + */ + +@Configuration +@Component +public class BusController { + + + + /** the Camel Context configure via Spring. See bean.xml*/ + + /** This is set by method setActx, see later */ + static CamelContext contxt; + + @Autowired + ProducerTemplate producerTemplate; + + + + private static final transient Log logger = LogFactory.getLog( BusController.class.getName()); + + + + /** + * @param actx + */ + @Autowired + public void setActx(CamelContext actx) { + BusController.contxt = actx; + logger.info( "BusController configure() contxt = " + contxt); + } + + + + + /** + * Asynchronously sends to the routing bus (seda:users.create?multipleConsumers=true) that a new user is added + * @param user a {@link PortalUser} + */ + public void newUserAdded( PortalUser user ) { + logger.info( "contxt = " + contxt); + FluentProducerTemplate template = contxt.createFluentProducerTemplate().to("seda:users.create?multipleConsumers=true"); + template.withBody( user ).asyncSend(); + + } + + /** + * Asynchronously sends to the routing bus (seda:deployments.create?multipleConsumers=true) that a new user is added + * @param deployment a {@link DeploymentDescriptor} + */ + // NOT USED + //public void newDeploymentRequest( DeploymentDescriptor deployment) { + // FluentProducerTemplate template = contxt.createFluentProducerTemplate().to("seda:deployments.create?multipleConsumers=true"); + // template.withBody( deployment ).asyncSend(); + //} + + /** + * Asynchronously sends to the routing bus (seda:deployments.create?multipleConsumers=true) that a new user is added + * @param deployment a {@link DeploymentDescriptor} + */ + public void rejectDeploymentRequest( DeploymentDescriptor deployment ) { + + FluentProducerTemplate template = contxt.createFluentProducerTemplate().to("seda:deployments.reject?multipleConsumers=true"); + template.withBody( deployment ).asyncSend(); + + } + + /** + * Asynchronously sends to the routing bus (seda:deployments.create?multipleConsumers=true) that a new user is added + * @param deployment a {@link DeploymentDescriptor} + */ + public void updateDeploymentRequest( DeploymentDescriptor deployment ) { + + FluentProducerTemplate template = contxt.createFluentProducerTemplate().to("seda:deployments.update?multipleConsumers=true"); + template.withBody( deployment ).asyncSend(); + + } + + /** + * Asynchronously sends to the routing bus (seda:vxf.create?multipleConsumers=true) that a new vxf is added + * @param deployment a {@link VxFMetadata} + */ + // NOT USED + public void newVxFUploadedToPortalRepo(long vxfmetadataid) { + FluentProducerTemplate template = contxt.createFluentProducerTemplate().to("seda:vxf.create?multipleConsumers=true"); + template.withBody( vxfmetadataid ).asyncSend(); + } + + /** + * Asynchronously sends to the routing bus (seda:vxf.onboard?multipleConsumers=true) to upload a new vxf + * @param deployment a {@link VxFMetadata} + */ + public void onBoardVxFAdded(VxFOnBoardedDescriptor obd) { + FluentProducerTemplate template = contxt.createFluentProducerTemplate().to("seda:vxf.onboard?multipleConsumers=true"); + template.withBody( obd ).asyncSend(); + } + + /** + * Asynchronously sends to the routing bus (seda:vxf.onboard?multipleConsumers=true) to upload a new vxf + * @param deployment a {@link VxFMetadata} + */ + public void onBoardVxFAddedByCompositeObj(CompositeVxFOnBoardDescriptor compobdobj) { + FluentProducerTemplate template = contxt.createFluentProducerTemplate().to("seda:vxf.onBoardByCompositeObj?multipleConsumers=true"); + template.withBody( compobdobj ).asyncSend(); + } + + @Autowired(required = true) + JmsTemplate jmsTemplate; +// +// @Autowired +// ActiveMQComponent activemq; + +// /** +// * @param obd +// * @param packageFileName +// * @param resource +// */ +// public void onBoardVxFAdded(VxFOnBoardedDescriptor obd, File packageFile, ByteArrayResource resource) { +//// JmsTemplate jmsTemplate = new JmsTemplate(); +//// jmsTemplate.setConnectionFactory( activemq.getConnectionFactory() ); +// jmsTemplate.send("activemq:queue:onBoardVxFAdded", new MessageCreator() { +// +// @Override +// public Message createMessage(Session session) throws JMSException { +// +// // Serialize the received object +// ObjectMapper mapper = new ObjectMapper(); +// String vxfobd_serialized = null; +// try { +// vxfobd_serialized = mapper.writeValueAsString( obd ); +// } catch (JsonProcessingException e2) { +// // TODO Auto-generated catch block +// logger.error(e2.getMessage()); +// } +// BytesMessage bytesMessage = session.createBytesMessage(); +// bytesMessage.setStringProperty("obd", vxfobd_serialized); +// bytesMessage.setStringProperty( "fileName" , packageFile.getName() ); +// bytesMessage.writeBytes( resource.getByteArray() ); +// return bytesMessage; +// } +// }); +// } + + public void onBoardVxFFailed(VxFOnBoardedDescriptor vxfobds_final) { + FluentProducerTemplate template = contxt.createFluentProducerTemplate().to("seda:vxf.onboard.fail?multipleConsumers=true"); + template.withBody( vxfobds_final ).asyncSend(); + } + + public void onBoardVxFSucceded(VxFOnBoardedDescriptor vxfobds_final) { + FluentProducerTemplate template = contxt.createFluentProducerTemplate().to("seda:vxf.onboard.success?multipleConsumers=true"); + template.withBody( vxfobds_final ).asyncSend(); + } + + public ResponseEntity offBoardVxF(VxFOnBoardedDescriptor u) { + // Serialize the received object + ObjectMapper mapper = new ObjectMapper(); + String vxfobd_serialized = null; + try { + vxfobd_serialized = mapper.writeValueAsString( u ); + } catch (JsonProcessingException e2) { + // TODO Auto-generated catch block + logger.error(e2.getMessage()); + } + logger.info("Sending Message " + vxfobd_serialized + " to offBoardVxF from AMQ:"); + // Send it to activemq endpoint + String ret = contxt.createProducerTemplate().requestBody( "activemq:topic:vxf.offboard", vxfobd_serialized, String.class); + logger.info("Message Received for offBoard from AMQ:"+ret); + + // Get the response and Map object to ExperimentMetadata + ResponseEntity response = null; + logger.info("From ActiveMQ:"+ret.toString()); + // Map object to VxFOnBoardedDescriptor + JSONObject obj = new JSONObject(ret); + logger.info("Status Code of response:"+obj.get("statusCode")); + response = new ResponseEntity(obj.get("body").toString(),HttpStatus.valueOf(obj.get("statusCode").toString())); + logger.info("Response from offboarding "+response); + return response; + } + + public void offBoardVxFFailed(VxFOnBoardedDescriptor vxfobds_final) { + FluentProducerTemplate template = contxt.createFluentProducerTemplate().to("seda:vxf.offboard.fail?multipleConsumers=true"); + template.withBody( vxfobds_final ).asyncSend(); + } + + public void offBoardVxFSucceded(VxFOnBoardedDescriptor vxfobds_final) { + FluentProducerTemplate template = contxt.createFluentProducerTemplate().to("seda:vxf.offboard.success?multipleConsumers=true"); + template.withBody( vxfobds_final ).asyncSend(); + } + + /** + * Asynchronously sends to the routing bus (seda:nsd.create?multipleConsumers=true) that a new NSD experiment is added + * @param deployment a {@link ExperimentMetadata} + */ + // There is no listener for nsd.create + public void newNSDAdded(ExperimentMetadata experimentSaved) { + FluentProducerTemplate template = contxt.createFluentProducerTemplate().to("seda:nsd.create?multipleConsumers=true"); + template.withBody( experimentSaved ).asyncSend(); + } + + public void onBoardNSDAddedByCompositeObj(CompositeExperimentOnBoardDescriptor compobdobj) { + FluentProducerTemplate template = contxt.createFluentProducerTemplate().to("seda:nsd.onBoardByCompositeObj?multipleConsumers=true"); + template.withBody( compobdobj ).asyncSend(); + } + + public void onBoardNSDFailed( ExperimentOnBoardDescriptor uexpobds) { + FluentProducerTemplate template = contxt.createFluentProducerTemplate().to("seda:nsd.onboard.fail?multipleConsumers=true"); + template.withBody( uexpobds ).asyncSend(); + } + + public void onBoardNSDSucceded(ExperimentOnBoardDescriptor uexpobdid) { + FluentProducerTemplate template = contxt.createFluentProducerTemplate().to("seda:nsd.onboard.success?multipleConsumers=true"); + template.withBody( uexpobdid ).asyncSend(); + } + + public ResponseEntity offBoardNSD(ExperimentOnBoardDescriptor u) { + // Serialize the received object + ObjectMapper mapper = new ObjectMapper(); + String nsdobd_serialized = null; + try { + nsdobd_serialized = mapper.writeValueAsString( u ); + } catch (JsonProcessingException e2) { + // TODO Auto-generated catch block + logger.error(e2.getMessage()); + } + logger.info("Sending Message " + nsdobd_serialized + " to offBoardNSD from AMQ:"); + // Send it to activemq endpoint + String ret = contxt.createProducerTemplate().requestBody( "activemq:topic:nsd.offboard", nsdobd_serialized, String.class); + logger.info("Message Received for offBoard from AMQ:"+ret); + + // Get the response and Map object to ExperimentMetadata + ResponseEntity response = null; + logger.info("From ActiveMQ:"+ret.toString()); + // Map object to VxFOnBoardedDescriptor + JSONObject obj = new JSONObject(ret); + logger.info("Status Code of response:"+obj.get("statusCode")); + response = new ResponseEntity(obj.get("body").toString(),HttpStatus.valueOf(obj.get("statusCode").toString())); + logger.info("Response from offboarding "+response); + return response; + } + + public VxFMetadata getVNFDMetadataFromMANO(VxFMetadata prod) { + // Serialize the received object + ObjectMapper mapper = new ObjectMapper(); + String prod_serialized = null; + try { + prod_serialized = mapper.writeValueAsString( prod ); + } catch (JsonProcessingException e2) { + // TODO Auto-generated catch block + logger.error(e2.getMessage()); + } + logger.info("getVNFDMetadataFromMANO(VxFMetadata prod). Sending Object to get VxFMetadata from AMQ:"); + // Send it to activemq endpoint + String ret = contxt.createProducerTemplate().requestBody("activemq:topic:vxf.metadata.retrieve", prod_serialized, String.class) ; + + logger.info("getVNFDMetadataFromMANO: From ActiveMQ:"+ret.toString()); + // Map object to VxFMetadata + // Get the response and Map object to ExperimentMetadata + VxFMetadata vxfmetadata = null; + try { + // Map object to VxFOnBoardedDescriptor + //ObjectMapper mapper = new ObjectMapper(); + logger.info("getVNFDMetadataFromMANO: From ActiveMQ:"+ret.toString()); + vxfmetadata = mapper.readValue(ret, VxFMetadata.class); + } catch (JsonParseException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (JsonMappingException e1) { + // TODO Auto-generated catch block + e1.printStackTrace(); + } catch (IOException e11) { + // TODO Auto-generated catch block + e11.printStackTrace(); + } + return vxfmetadata; + } + + public VxFMetadata getVNFDMetadataFromMANO(String osmType, String yamlFile) { + logger.info("Sending Object to get VxFMetadata from AMQ:"); + // Send it to activemq endpoint + String ret = contxt.createProducerTemplate().requestBodyAndHeader("activemq:topic:vxf.metadata.retrieve", yamlFile, "OSMType", osmType, String.class); + + logger.info("getVNFDMetadataFromMANO(String "+osmType+", String yamlFile). From ActiveMQ:"+ret.toString()); + ObjectMapper mapper = new ObjectMapper(); + // Map object to VxFMetadata + // Get the response and Map object to ExperimentMetadata + VxFMetadata vxfmetadata = null; + try { + // Map object to VxFOnBoardedDescriptor + //ObjectMapper mapper = new ObjectMapper(); + logger.info("From ActiveMQ:"+ret.toString()); + vxfmetadata = mapper.readValue(ret, VxFMetadata.class); + } catch (JsonParseException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (JsonMappingException e1) { + // TODO Auto-generated catch block + e1.printStackTrace(); + } catch (IOException e11) { + // TODO Auto-generated catch block + e11.printStackTrace(); + } + return vxfmetadata; + } + + public ExperimentMetadata getNSDMetadataFromMANO(String osmType, String yamlFile) { + logger.info("Sending Object to get ExperimentMetadata from AMQ: osmType = " + osmType); + // Send it to activemq endpoint + String ret = contxt.createProducerTemplate().requestBodyAndHeader("activemq:topic:ns.metadata.retrieve", yamlFile, "OSMType", osmType, String.class); + + logger.info("From ActiveMQ:"+ret.toString()); + ObjectMapper mapper = new ObjectMapper(); + // Map object to VxFMetadata + // Get the response and Map object to ExperimentMetadata + ExperimentMetadata experimentmetadata = null; + try { + // Map object to VxFOnBoardedDescriptor + //ObjectMapper mapper = new ObjectMapper(); + logger.info("From ActiveMQ:"+ret.toString()); + experimentmetadata = mapper.readValue(ret, ExperimentMetadata.class); + } catch (JsonParseException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (JsonMappingException e1) { + // TODO Auto-generated catch block + e1.printStackTrace(); + } catch (IOException e11) { + // TODO Auto-generated catch block + e11.printStackTrace(); + } + return experimentmetadata; + } + + public void offBoardNSDFailed(ExperimentOnBoardDescriptor experimentobds_final) { + FluentProducerTemplate template = contxt.createFluentProducerTemplate().to("seda:nsd.offboard.fail?multipleConsumers=true"); + template.withBody( experimentobds_final ).asyncSend(); + } + + public void offBoardNSDSucceded(ExperimentOnBoardDescriptor experimentobds_final) { + FluentProducerTemplate template = contxt.createFluentProducerTemplate().to("seda:nsd.offboard.success?multipleConsumers=true"); + template.withBody( experimentobds_final ).asyncSend(); + } + + + public void scheduleExperiment( DeploymentDescriptor aDeployment) { + FluentProducerTemplate template = contxt.createFluentProducerTemplate().to("seda:nsd.schedule?multipleConsumers=true"); + template.withBody( aDeployment ).asyncSend(); + } + + + public void deployExperiment( DeploymentDescriptor deploymentdescriptorid) { + logger.info( "deployExperiment: to(\"seda:nsd.deploy?multipleConsumers=true\")"); + FluentProducerTemplate template = contxt.createFluentProducerTemplate().to("seda:nsd.deploy?multipleConsumers=true"); + template.withBody( deploymentdescriptorid ).asyncSend(); + } + + // seda:nsd.deployment + + public void deploymentInstantiationSucceded(DeploymentDescriptor deploymentdescriptorid) + { + FluentProducerTemplate template = contxt.createFluentProducerTemplate().to("seda:nsd.deployment.instantiation.success?multipleConsumers=true"); + template.withBody( deploymentdescriptorid ).asyncSend(); + } + + public void deploymentInstantiationFailed(DeploymentDescriptor deploymentdescriptorid) + { + FluentProducerTemplate template = contxt.createFluentProducerTemplate().to("seda:nsd.deployment.instantiation.fail?multipleConsumers=true"); + template.withBody( deploymentdescriptorid ).asyncSend(); + } + + public void deploymentTerminationSucceded(DeploymentDescriptor deploymentdescriptorid) + { + FluentProducerTemplate template = contxt.createFluentProducerTemplate().to("seda:nsd.deployment.termination.success?multipleConsumers=true"); + template.withBody( deploymentdescriptorid ).asyncSend(); + } + + public void deploymentTerminationFailed(DeploymentDescriptor deploymentdescriptorid) + { + FluentProducerTemplate template = contxt.createFluentProducerTemplate().to("seda:nsd.deployment.termination.fail?multipleConsumers=true"); + template.withBody( deploymentdescriptorid ).asyncSend(); + } + + public void completeExperiment(DeploymentDescriptor deploymentdescriptorid) { + FluentProducerTemplate template = contxt.createFluentProducerTemplate().to("seda:nsd.deployment.complete?multipleConsumers=true"); + template.withBody( deploymentdescriptorid ).asyncSend(); + } + + public void deleteExperiment(DeploymentDescriptor deploymentdescriptorid) { + FluentProducerTemplate template = contxt.createFluentProducerTemplate().to("seda:nsd.deployment.delete?multipleConsumers=true"); + template.withBody( deploymentdescriptorid ).asyncSend(); + } + + public void rejectExperiment(DeploymentDescriptor deploymentdescriptorid) { + FluentProducerTemplate template = contxt.createFluentProducerTemplate().to("seda:nsd.deployment.reject?multipleConsumers=true"); + template.withBody( deploymentdescriptorid ).asyncSend(); + } + +// public void osm4CommunicationFailed(Class manostatus) +// { +// FluentProducerTemplate template = actx.createFluentProducerTemplate().to("seda:communication.osm4.fail?multipleConsumers=true"); +// template.withBody(manostatus).asyncSend(); +// } +// +// public void osm4CommunicationRestored(Class manostatus) +// { +// FluentProducerTemplate template = actx.createFluentProducerTemplate().to("seda:communication.osm4.success?multipleConsumers=true"); +// template.withBody(manostatus).asyncSend(); +// } +// + public void osm5CommunicationFailed(Class manostatus) + { + FluentProducerTemplate template = contxt.createFluentProducerTemplate().to("seda:communication.osm5.fail?multipleConsumers=true"); + template.withBody(manostatus).asyncSend(); + } + + public void osm5CommunicationRestored(Class manostatus) + { + FluentProducerTemplate template = contxt.createFluentProducerTemplate().to("seda:communication.osm5.success?multipleConsumers=true"); + template.withBody(manostatus).asyncSend(); + } + + public void terminateInstanceSucceded(DeploymentDescriptor deploymentdescriptorid) + { + FluentProducerTemplate template = contxt.createFluentProducerTemplate().to("seda:nsd.instance.termination.success?multipleConsumers=true"); + template.withBody( deploymentdescriptorid ).asyncSend(); + } + + public void terminateInstanceFailed(DeploymentDescriptor deploymentdescriptorid) + { + FluentProducerTemplate template = contxt.createFluentProducerTemplate().to("seda:nsd.instance.termination.fail?multipleConsumers=true"); + template.withBody( deploymentdescriptorid ).asyncSend(); + } + + public void deleteInstanceSucceded(DeploymentDescriptor deploymentdescriptorid) { + FluentProducerTemplate template = contxt.createFluentProducerTemplate().to("seda:nsd.instance.deletion.success?multipleConsumers=true"); + template.withBody( deploymentdescriptorid ).asyncSend(); + } + + public void deleteInstanceFailed(DeploymentDescriptor deploymentdescriptorid) { + FluentProducerTemplate template = contxt.createFluentProducerTemplate().to("seda:nsd.instance.deletion.fail?multipleConsumers=true"); + template.withBody( deploymentdescriptorid ).asyncSend(); + } + + /** + * Asynchronously sends to the routing bus (seda:vxf.update?multipleConsumers=true) that a vxf is updated + * @param deployment a {@link VxFMetadata} + */ + // There is no listener for this + public void updatedVxF(VxFMetadata vxfmetadataid) { + + FluentProducerTemplate template = contxt.createFluentProducerTemplate().to("seda:vxf.update?multipleConsumers=true"); + template.withBody( vxfmetadataid ).asyncSend(); + + } + + /** + * Asynchronously sends to the routing bus (seda:nsd.update?multipleConsumers=true) that a NSD experiment is updated + * @param experiment a {@link ExperimentMetadata} + */ + // There is no listener for this + public void updateNSD(ExperimentMetadata expmetasaved) { + FluentProducerTemplate template = contxt.createFluentProducerTemplate().to("seda:nsd.update?multipleConsumers=true"); + template.withBody( expmetasaved ).asyncSend(); + } + + + /** + * Asynchronously sends to the routing bus (seda:vxf.new.validation?multipleConsumers=true)to trigger VxF validation + * @param vxf a {@link VxFMetadata} + */ + public void validateVxF(VxFMetadata vxfmetadataid) { + + FluentProducerTemplate template = contxt.createFluentProducerTemplate().to("seda:vxf.new.validation?multipleConsumers=true"); + template.withBody( vxfmetadataid ).asyncSend(); + + } + + /** + * Asynchronously sends to the routing bus (seda:vxf.validationresult.update?multipleConsumers=true)to trigger update VxF validation + * @param vresult a {@link ValidationJobResult} + */ + public void updatedValidationJob(VxFMetadata vxf) { + + FluentProducerTemplate template = contxt.createFluentProducerTemplate().to("seda:vxf.validationresult.update?multipleConsumers=true"); + template.withBody( vxf ).asyncSend(); + + } + + /** + * Asynchronously sends to the routing bus (seda:nsd.validate.new?multipleConsumers=true) to trigger NSD validation + * @param deployment a {@link ExperimentMetadata} + */ + // There is no listener for this + public void validateNSD(ExperimentMetadata experimentSaved) { + FluentProducerTemplate template = contxt.createFluentProducerTemplate().to("seda:nsd.validate.new?multipleConsumers=true"); + template.withBody( experimentSaved ).asyncSend(); + } + + + /** + * Asynchronously sends to the routing bus (seda:nsd.validate.update?multipleConsumers=true) to trigger NSD validation + * @param deployment a {@link ExperimentMetadata} + */ + // There is no listener for this + public void validationUpdateNSD(ExperimentMetadata expmetasaved) { + FluentProducerTemplate template = contxt.createFluentProducerTemplate().to("seda:nsd.validate.update?multipleConsumers=true"); + template.withBody( expmetasaved ).asyncSend(); + } + + /** + * Asynchronously sends to the routing bus (seda:vxf.deleted?multipleConsumers=true) that a vxf is deleted + * @param deployment a {@link VxFMetadata} + */ + // There is no listener for this + public void deletedVxF(VxFMetadata vxf) { + + FluentProducerTemplate template = contxt.createFluentProducerTemplate().to("seda:vxf.deleted?multipleConsumers=true"); + template.withBody( vxf ).asyncSend(); + + } + + /** + * Asynchronously sends to the routing bus (seda:nsd.deleted?multipleConsumers=true) that a vxf is deleted + * @param deployment a {@link ExperimentMetadata} + */ + // There is no listener for this + public void deletedExperiment(ExperimentMetadata nsd) { + + FluentProducerTemplate template = contxt.createFluentProducerTemplate().to("seda:nsd.deleted?multipleConsumers=true"); + template.withBody( nsd ).asyncSend(); + + } + + /** + * Asynchronously sends to the routing bus (seda:nsd.onboard?multipleConsumers=true) to trigger new NSD onboarding + * @param deployment a {@link ExperimentOnBoardDescriptor} + */ + public void onBoardNSD(ExperimentOnBoardDescriptor obd) { + FluentProducerTemplate template = contxt.createFluentProducerTemplate().to("seda:nsd.onboard?multipleConsumers=true"); + template.withBody( obd ).asyncSend(); + } + +// /** +// * Asynchronously sends to the routing bus (seda:nsd.offboard?multipleConsumers=true) to trigger new NSD offboarding +// * @param deployment a {@link ExperimentOnBoardDescriptor} +// */ +// public void offBoardNSD(ExperimentOnBoardDescriptor u) { +// FluentProducerTemplate template = contxt.createFluentProducerTemplate().to("seda:nsd.offboard?multipleConsumers=true"); +// template.withBody( u ).asyncSend(); +// } + + /** + * @param vfimg + */ + public void newVFImageAdded(VFImage vfimg) { + // TODO Auto-generated method stub + + } + + public void aVFImageUpdated(VFImage vfimg) { + // TODO Auto-generated method stub + + } + + /** + * Asynchronously sends to the routing bus (seda:nsd.offboard?multipleConsumers=true) to trigger new NSD offboarding + * @param deployment a {@link ExperimentOnBoardDescriptor} + */ + public void propertiesUpdate(String props) { + + if ( contxt != null ) { + FluentProducerTemplate template = contxt.createFluentProducerTemplate().to("seda:properties.update?multipleConsumers=true"); + template.withBody( props ).asyncSend(); + + } + } + + + +} diff --git a/src/main/java/portal/api/bus/BusControllerActiveMQ.java b/src/main/java/portal/api/bus/BusControllerActiveMQ.java new file mode 100644 index 0000000..c829bc5 --- /dev/null +++ b/src/main/java/portal/api/bus/BusControllerActiveMQ.java @@ -0,0 +1,479 @@ +/*- + * ========================LICENSE_START================================= + * org.etsi.osl.portal.api + * %% + * Copyright (C) 2019 openslice.io + * %% + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * =========================LICENSE_END================================== + */ +package portal.api.bus; + +import org.apache.camel.CamelContext; +import org.apache.camel.LoggingLevel; +import org.apache.camel.builder.RouteBuilder; +import org.apache.camel.model.dataformat.JsonLibrary; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Configuration; +import org.springframework.stereotype.Component; + +import org.etsi.osl.model.CompositeExperimentOnBoardDescriptor; +import org.etsi.osl.model.CompositeVxFOnBoardDescriptor; +import org.etsi.osl.model.DeploymentDescriptor; +import org.etsi.osl.model.ExperimentOnBoardDescriptor; +import org.etsi.osl.model.PortalUser; +import org.etsi.osl.model.VxFOnBoardedDescriptor; +import portal.api.service.DeploymentDescriptorService; +import portal.api.service.InfrastructureService; +import portal.api.service.ManoProviderService; +import portal.api.service.NSDOBDService; +import portal.api.service.NSDService; +import portal.api.service.PortalPropertiesService; +import portal.api.service.UsersService; +import portal.api.service.VxFOBDService; +import portal.api.service.VxFService; + +@Configuration +@Component +public class BusControllerActiveMQ extends RouteBuilder { + + @Autowired + CamelContext actx; + + + @Autowired + VxFService vxfService; + + + @Autowired + NSDService nsdService; + + @Autowired + DeploymentDescriptorService deploymentDescriptorService; + + @Autowired + VxFOBDService vxfObdService; + + @Autowired + NSDOBDService nsdObdService; + + @Autowired + ManoProviderService manoProviderService; + + @Autowired + InfrastructureService infraStructureService; + + @Autowired + NSDService experimentService; + + @Autowired + PortalPropertiesService portalPropertyService; + + @Autowired + UsersService usersService; + + @Value("${NFV_CATALOG_GET_NSD_BY_ID}") + private String NFV_CATALOG_GET_NSD_BY_ID = ""; + + @Value("${NFV_CATALOG_DEPLOY_NSD_REQ}") + private String NFV_CATALOG_DEPLOY_NSD_REQ = ""; + + @Value("${NFV_CATALOG_GET_DEPLOYMENT_BY_ID}") + private String NFV_CATALOG_GET_DEPLOYMENT_BY_ID = ""; + + + @Value("${GET_USER_BY_USERNAME}") + private String GET_USER_BY_USERNAME = ""; + + + @Value("${NFV_CATALOG_UPD_DEPLOYMENT_BY_ID}") + private String NFV_CATALOG_UPD_DEPLOYMENT_BY_ID = ""; + + private static final transient Log logger = LogFactory.getLog(BusControllerActiveMQ.class.getName()); + + // template.withBody( objectMapper.writeValueAsString(user) ).asyncSend(); + + @Override + public void configure() throws Exception { + + /** + * from internal messaging to ActiveMQ + */ + from("seda:users.create?multipleConsumers=true") + .marshal().json( JsonLibrary.Jackson, PortalUser.class, true) + .convertBodyTo( String.class ) + .to( "activemq:topic:users.create" ); + + from("seda:vxf.onboard?multipleConsumers=true") + .marshal().json( JsonLibrary.Jackson, VxFOnBoardedDescriptor.class, true) + .convertBodyTo( String.class ) + .log( "Send to activemq:topic:vxf.onboard the payload ${body} !" ) + .to( "activemq:topic:vxf.onboard" ); + + from("seda:vxf.onBoardByCompositeObj?multipleConsumers=true") + .marshal().json( JsonLibrary.Jackson, CompositeVxFOnBoardDescriptor.class, true) + .convertBodyTo( String.class ) + .log( "Send to activemq:topic:vxf.onBoardByCompositeObj the payload ${body} !" ) + .to( "activemq:topic:vxf.onBoardByCompositeObj" ); + + from("seda:vxf.offboard?multipleConsumers=true") + .marshal().json( JsonLibrary.Jackson, VxFOnBoardedDescriptor.class, true) + .convertBodyTo( String.class ) + .log( "Send to activemq:topic:vxf.offboard the payload ${body} !" ) + .to( "activemq:topic:vxf.offboard" ) + .log("Got back from activemq:topic:vxf.offboard ${body}"); + + from("seda:vxf.onboard.fail?multipleConsumers=true") + .marshal().json( JsonLibrary.Jackson, VxFOnBoardedDescriptor.class, true) + .convertBodyTo( String.class ) + .to( "activemq:topic:vxf.onboard.fail" ); + + + from("seda:vxf.onboard.success?multipleConsumers=true") + .marshal().json( JsonLibrary.Jackson, VxFOnBoardedDescriptor.class, true) + .convertBodyTo( String.class ) + .to( "activemq:topic:vxf.onboard.success" ); + + from("seda:nsd.onboard?multipleConsumers=true") + .marshal().json( JsonLibrary.Jackson, ExperimentOnBoardDescriptor.class, true) + .convertBodyTo( String.class ) + .to( "activemq:topic:nsd.onboard" ); + + from("seda:nsd.onBoardByCompositeObj?multipleConsumers=true") + .marshal().json( JsonLibrary.Jackson, CompositeExperimentOnBoardDescriptor.class, true) + .convertBodyTo( String.class ) + .log( "Send to activemq:topic:nsd.onBoardByCompositeObj the payload ${body} !" ) + .to( "activemq:topic:nsd.onBoardByCompositeObj" ); + + from("seda:nsd.onboard.success?multipleConsumers=true") + .marshal().json( JsonLibrary.Jackson, ExperimentOnBoardDescriptor.class, true) + .convertBodyTo( String.class ) + .to( "activemq:topic:nsd.onboard.success" ); + + from("seda:nsd.offboard?multipleConsumers=true") + .marshal().json( JsonLibrary.Jackson, ExperimentOnBoardDescriptor.class, true) + .convertBodyTo( String.class ) + .log( "Send to activemq:topic:nsd.offboard the payload ${body} !" ) + .to( "activemq:topic:nsd.offboard" ) + .log("Got back from activemq:topic:nsd.offboard ${body}"); + + from("seda:nsd.onboard.fail?multipleConsumers=true") + .marshal().json( JsonLibrary.Jackson, ExperimentOnBoardDescriptor.class, true) + .convertBodyTo( String.class ) + .to( "activemq:topic:nsd.onboard.fail" ); + + //Dead end + //from("seda:deployments.create?multipleConsumers=true") + //.marshal().json( JsonLibrary.Jackson, DeploymentDescriptor.class, true) + //.convertBodyTo( String.class ) + //.to( "activemq:topic:deployments.create" ); + + from("seda:deployments.reject?multipleConsumers=true") + .marshal().json( JsonLibrary.Jackson, DeploymentDescriptor.class, true) + .convertBodyTo( String.class ) + .to( "activemq:topic:deployments.reject" ); + + from("seda:deployments.update?multipleConsumers=true") + .marshal().json( JsonLibrary.Jackson, DeploymentDescriptor.class, true) + .convertBodyTo( String.class ) + .to( "activemq:topic:deployments.update" ); + + from("seda:nsd.schedule?multipleConsumers=true") + .marshal().json( JsonLibrary.Jackson, DeploymentDescriptor.class, true) + .convertBodyTo( String.class ) + .to( "activemq:topic:nsd.schedule" ); + + from("seda:nsd.deploy?multipleConsumers=true") + .bean( deploymentDescriptorService, "getDeploymentEagerDataJson" ) + .convertBodyTo( String.class ) + .to( "activemq:topic:nsd.deploy" ); + + from("seda:nsd.deployment.instantiation.success?multipleConsumers=true") + .bean( deploymentDescriptorService, "getDeploymentEagerDataJson" ) + .convertBodyTo( String.class ) + .to( "activemq:topic:nsd.deployment.instantiation.success" ); + + from("seda:nsd.deployment.instantiation.fail?multipleConsumers=true") + .bean( deploymentDescriptorService, "getDeploymentEagerDataJson" ) + .convertBodyTo( String.class ) + .to( "activemq:topic:nsd.deployment.instantiation.fail" ); + + from("seda:nsd.deployment.termination.success?multipleConsumers=true") + .bean( deploymentDescriptorService, "getDeploymentEagerDataJson" ) + .convertBodyTo( String.class ) + .to( "activemq:topic:nsd.deployment.termination.success" ); + + from("seda:nsd.deployment.termination.fail?multipleConsumers=true") + .bean( deploymentDescriptorService, "getDeploymentEagerDataJson" ) + .convertBodyTo( String.class ) + .to( "activemq:topic:nsd.deployment.termination.fail" ); + + from("seda:nsd.deployment.complete?multipleConsumers=true") + .bean( deploymentDescriptorService, "getDeploymentEagerDataJson" ) + .convertBodyTo( String.class ) + .to( "activemq:topic:nsd.deployment.complete" ); + + from("seda:nsd.deployment.delete?multipleConsumers=true") + .bean( deploymentDescriptorService, "getDeploymentEagerDataJson" ) + .convertBodyTo( String.class ) + .to( "activemq:topic:nsd.deployment.delete" ); + + from("seda:nsd.deployment.reject?multipleConsumers=true") + .bean( deploymentDescriptorService, "getDeploymentEagerDataJson" ) + .convertBodyTo( String.class ) + .to( "activemq:topic:nsd.deployment.reject" ); + + + from("seda:nsd.instance.termination.success?multipleConsumers=true") + .bean( deploymentDescriptorService, "getDeploymentEagerDataJson" ) + .convertBodyTo( String.class ) + .to( "activemq:topic:nsd.instance.termination.success" ); + + from("seda:nsd.instance.termination.fail?multipleConsumers=true") + .bean( deploymentDescriptorService, "getDeploymentEagerDataJson" ) + .convertBodyTo( String.class ) + .to( "activemq:topic:nsd.instance.termination.fail" ); + + from("seda:nsd.instance.deletion.success?multipleConsumers=true") + .bean( deploymentDescriptorService, "getDeploymentEagerDataJson" ) + .convertBodyTo( String.class ) + .to( "activemq:topic:nsd.instance.deletion.success" ); + + from("seda:nsd.instance.deletion.fail?multipleConsumers=true") + .bean( deploymentDescriptorService, "getDeploymentEagerDataJson" ) + .convertBodyTo( String.class ) + .to( "activemq:topic:nsd.instance.deletion.fail" ); + + from("seda:nsd.scalealert?multipleConsumers=true") + .to("activemq:topic:nsd.scalealert"); + + /** + * Response message queues + */ + + from("activemq:queue:getVxFByID") + .log( "activemq:queue:getVxFByID for ${body} !" ) + .bean( vxfService, "getProductByIDDataJson" ) + .to("log:DEBUG?showBody=true&showHeaders=true"); + + from("activemq:queue:getVxFByUUIDDataJson") + .log( "activemq:queue:getVxFByUUDataJson for ${body} !" ) + .bean( vxfService, "getVxFByUUIDDataJson" ) + .to("log:DEBUG?showBody=true&showHeaders=true"); + + from("activemq:queue:getVxFByUUID") + .log("activemq:queue:getVxFByUUID for ${body} !" ) + .bean( vxfService , "getVxFByUUID" ) + .to("log:DEBUG?showBody=true&showHeaders=true"); + + from("activemq:queue:getVxFByName") + .log( "activemq:queue:getVxFByName for ${body} !" ) + .bean( vxfService, "getProductByNameEagerDataJson" ) + .to("log:DEBUG?showBody=true&showHeaders=true"); + + from("activemq:queue:getNSDByID") + .log( "activemq:queue:getNSDByID for ${body} !" ) + .bean( nsdService, "getProductByIDDataJson" ) + .to("log:DEBUG?showBody=true&showHeaders=true"); + + from("activemq:queue:getRunningInstantiatingAndTerminatingDeployments") + .log( "activemq:queue:getRunningInstantiatingAndTerminatingDeployments !" ) + .bean( deploymentDescriptorService, "getRunningInstantiatingAndTerminatingDeploymentsEagerDataJson" ) + .to("log:DEBUG?showBody=true&showHeaders=true"); + + from("activemq:queue:getAllDeployments") + .log( "activemq:queue:getAllDeployments !" ) + .bean( deploymentDescriptorService, "getAllDeploymentsEagerDataJson" ) + .to("log:DEBUG?showBody=true&showHeaders=true"); + + from("activemq:queue:getDeploymentsToInstantiate") + .log( "activemq:queue:getDeploymentsToInstantiate !" ) + .bean( deploymentDescriptorService, "getDeploymentsToInstantiateEagerDataJson") + .to("log:DEBUG?showBody=true&showHeaders=true"); + + from("activemq:queue:getDeploymentsToBeCompleted") + .log( "activemq:queue:getDeploymentsToBeCompleted !" ) + .bean( deploymentDescriptorService, "getDeploymentsToBeCompletedEagerDataJson" ) + .to("log:DEBUG?showBody=true&showHeaders=true"); + + from("activemq:queue:getDeploymentsToBeDeleted") + .log( "activemq:queue:getDeploymentsToBeDeleted !" ) + .bean( deploymentDescriptorService, "getDeploymentsToBeDeletedEagerDataJson" ) + .to("log:DEBUG?showBody=true&showHeaders=true"); + + from("activemq:queue:getDeploymentByIdEager") + //.log( "activemq:queue:getDeploymentByIdEager !" ) + .log(LoggingLevel.INFO, log, "activemq:queue:getDeploymentByIdEager ${body} message received!") + .bean( deploymentDescriptorService, "getDeploymentByIdEagerDataJson" ) + .log(LoggingLevel.INFO, log, "activemq:queue:getDeploymentByIdEager replied with ${body} !") + .to("log:DEBUG?showBody=true&showHeaders=true"); + + from("activemq:queue:getDeploymentByInstanceIdEager") + .log( "activemq:queue:getDeploymentByInstanceIdEager !" ) + .bean( deploymentDescriptorService, "getDeploymentByInstanceIdEagerDataJson" ) + .to("log:DEBUG?showBody=true&showHeaders=true"); + + from("activemq:queue:updateDeploymentDescriptor") + .log( "activemq:queue:updateDeploymentDescriptor !" ) + .unmarshal().json( JsonLibrary.Jackson, org.etsi.osl.model.DeploymentDescriptor.class, true) + .bean( deploymentDescriptorService, "updateDeploymentEagerDataJson" ) + .to("log:DEBUG?showBody=true&showHeaders=true"); + + from("activemq:queue:getVxFOnBoardedDescriptorByVxFAndMP") + .log("activemq:queue:getVxFOnBoardedDescriptorByVxFAndMP for ${body} !" ) + .bean( vxfObdService , "getVxFOnBoardedDescriptorByVxFAndMP" ) + .to("log:DEBUG?showBody=true&showHeaders=true"); + + from("activemq:queue:getVxFOnBoardedDescriptorListDataJson") + .log("activemq:queue:getVxFOnBoardedDescriptorListDataJson!" ) + .bean( vxfObdService , "getVxFOnBoardedDescriptorListDataJson" ) + .log(LoggingLevel.INFO, log, "\"activemq:queue:getVxFOnBoardedDescriptorListDataJson replied with ${body} !") + .to("log:DEBUG?showBody=true&showHeaders=true"); + + from("activemq:queue:getExperimentOnBoardDescriptorsDataJson") + .log("activemq:queue:getExperimentOnBoardDescriptorsDataJson!" ) + .bean( nsdObdService , "getExperimentOnBoardDescriptorsDataJson" ) + .log(LoggingLevel.INFO, log, "activemq:queue:getExperimentOnBoardDescriptorsDataJson replied with ${body} !") + .to("log:DEBUG?showBody=true&showHeaders=true"); + + from("activemq:queue:updateVxFOnBoardedDescriptor") + .log( "activemq:queue:updateVxFOnBoardedDescriptor for ${body} !" ) + .unmarshal().json( JsonLibrary.Jackson, org.etsi.osl.model.VxFOnBoardedDescriptor.class, true) + .bean( vxfObdService , "updateVxFOBDEagerDataJson" ) + .to("log:DEBUG?showBody=true&showHeaders=true"); + + from("activemq:queue:addInfrastructure") + .log( "activemq:queue:addInfrastructure for ${body} !" ) + .unmarshal().json( JsonLibrary.Jackson, org.etsi.osl.model.Infrastructure.class, true) + .bean( infraStructureService , "addInfrastructureEagerDataJson" ) + .to("log:DEBUG?showBody=true&showHeaders=true"); + + from("activemq:queue:updateInfrastructure") + .log( "activemq:queue:updateInfrastructure for ${body} !" ) + .unmarshal().json( JsonLibrary.Jackson, org.etsi.osl.model.Infrastructure.class, true) + .bean( infraStructureService , "updateInfrastructureEagerDataJson" ) + .to("log:DEBUG?showBody=true&showHeaders=true"); + + from("activemq:queue:addVxFMetadata") + .log( "activemq:queue:addVxFMetadata for ${body} !" ) + .unmarshal().json( JsonLibrary.Jackson, org.etsi.osl.model.VxFMetadata.class, true) + .bean( vxfService , "addVxFMetadataEagerDataJson" ) + .to("log:DEBUG?showBody=true&showHeaders=true"); + + from("activemq:queue:addExperimentMetadata") + .log( "activemq:queue:addExperimentMetadata for ${body} !" ) + .unmarshal().json( JsonLibrary.Jackson, org.etsi.osl.model.ExperimentMetadata.class, true) + .bean( nsdService , "addNSDMetadataEagerDataJson" ) + .to("log:DEBUG?showBody=true&showHeaders=true"); + + from("activemq:queue:addVxFOnBoardedDescriptor") + .log( "activemq:queue:addVxFOnBoardedDescriptor for ${body} !" ) + .unmarshal().json( JsonLibrary.Jackson, org.etsi.osl.model.VxFOnBoardedDescriptor.class, true) + .bean( vxfObdService , "addVxFOnBoardedDescriptorEagerDataJson" ) + .to("log:DEBUG?showBody=true&showHeaders=true"); + + from("activemq:queue:addExperimentOnBoardedDescriptor") + .log( "activemq:queue:addExperimentOnBoardedDescriptor for ${body} !" ) + .unmarshal().json( JsonLibrary.Jackson, org.etsi.osl.model.ExperimentOnBoardDescriptor.class, true) + .bean( nsdObdService , "addExperimentOnBoardedDescriptorEagerDataJson" ) + .to("log:DEBUG?showBody=true&showHeaders=true"); + + from("activemq:queue:updateExperimentOnBoardDescriptor") + .log( "activemq:queue:updateExperimentOnBoardDescriptor for ${body} !" ) + .unmarshal().json( JsonLibrary.Jackson, org.etsi.osl.model.ExperimentOnBoardDescriptor.class, true) + .bean( nsdObdService , "updateNSDOBDEagerDataJson" ) + .to("log:DEBUG?showBody=true&showHeaders=true"); + + from("activemq:queue:getMANOProviderByID") + .log( "activemq:queue:getMANOproviderByID !" ) + .bean( manoProviderService, "getMANOproviderByIDEagerDataJson" ) + .to("log:DEBUG?showBody=true&showHeaders=true"); + + + from("activemq:queue:getMANOProviders") + .log( "activemq:queue:getMANOproviders !" ) + .bean( manoProviderService, "getMANOprovidersEagerDataJson" ) + .to("log:DEBUG?showBody=true&showHeaders=true"); + + from("activemq:queue:getMANOProvidersForSync") + .log( "activemq:queue:getMANOprovidersForSync !" ) + .bean( manoProviderService, "getMANOprovidersForSyncEagerDataJson" ) + .to("log:DEBUG?showBody=true&showHeaders=true"); + + from("activemq:queue:getInfrastructures") + .log( "activemq:queue:getInfrastructures !" ) + .bean( infraStructureService, "getInfrastructuresEagerDataJson" ) + .to("log:DEBUG?showBody=true&showHeaders=true"); + + from("activemq:queue:getExperiments") + .log( "activemq:queue:getExperiments !" ) + .bean( experimentService, "getExperimentsEagerDataJson" ) + .to("log:DEBUG?showBody=true&showHeaders=true"); + + from("activemq:queue:getVnfds") + .log( "activemq:queue:getVnfds !" ) + .bean( vxfService, "getVnfdsEagerDataJson" ) + .to("log:DEBUG?showBody=true&showHeaders=true"); + + from( "activemq:queue:putActionOnNS" ) + .log(LoggingLevel.INFO, log, "activemq:queue:putActionOnNS message received!") + .to("log:DEBUG?showBody=true&showHeaders=true") + .bean( nsdService, "getProductByIDEagerDataJson") + .convertBodyTo( String.class ); + + from( NFV_CATALOG_GET_NSD_BY_ID ) + .log(LoggingLevel.INFO, log, NFV_CATALOG_GET_NSD_BY_ID + " message received!") + .to("log:DEBUG?showBody=true&showHeaders=true") + .bean( nsdService, "getProductByIDEagerDataJson") + .convertBodyTo( String.class ); + + + from( NFV_CATALOG_DEPLOY_NSD_REQ ) + .log(LoggingLevel.INFO, log, NFV_CATALOG_DEPLOY_NSD_REQ + " message received!") + .to("log:DEBUG?showBody=true&showHeaders=true") + .unmarshal().json( JsonLibrary.Jackson, org.etsi.osl.model.DeploymentDescriptor.class, false) + .bean( deploymentDescriptorService, "createDeploymentRequestJson") + .convertBodyTo( String.class ); + + // + from( NFV_CATALOG_GET_DEPLOYMENT_BY_ID ) + .log(LoggingLevel.INFO, log, NFV_CATALOG_GET_DEPLOYMENT_BY_ID + " message received!") + .to("log:DEBUG?showBody=true&showHeaders=true") + .bean( deploymentDescriptorService, "getDeploymentByIdEagerDataJson" ) + .convertBodyTo( String.class ); + + + from( NFV_CATALOG_UPD_DEPLOYMENT_BY_ID ) + .log(LoggingLevel.INFO, log, NFV_CATALOG_UPD_DEPLOYMENT_BY_ID + " message received!") + .to("log:DEBUG?showBody=true&showHeaders=true") + .unmarshal().json( JsonLibrary.Jackson, org.etsi.osl.model.DeploymentDescriptor.class, false) + .bean( deploymentDescriptorService, "updateDeploymentEagerDataJson" ) + .convertBodyTo( String.class ); + + from( GET_USER_BY_USERNAME ) + .log(LoggingLevel.INFO, log, GET_USER_BY_USERNAME + " message received!") + .to("log:DEBUG?showBody=true&showHeaders=true") + .bean( usersService, "getPortalUserByUserNameDataJson" ) + .convertBodyTo( String.class ); + + from("activemq:queue:getPortalUserByUsername") + .log( "activemq:queue:getPortalUserByUsername for ${body} !" ) + .bean( usersService , "getPortalUserByUserNameDataJson" ) + .to("log:DEBUG?showBody=true&showHeaders=true"); + + } + +} diff --git a/src/main/java/portal/api/config/ActiveMQComponentConfig.java b/src/main/java/portal/api/config/ActiveMQComponentConfig.java new file mode 100644 index 0000000..8cbf3f0 --- /dev/null +++ b/src/main/java/portal/api/config/ActiveMQComponentConfig.java @@ -0,0 +1,50 @@ +/*- + * ========================LICENSE_START================================= + * org.etsi.osl.portal.api + * %% + * Copyright (C) 2019 openslice.io + * %% + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * =========================LICENSE_END================================== + */ +package portal.api.config; + +import jakarta.jms.ConnectionFactory; + +import org.apache.camel.component.activemq.ActiveMQComponent; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.jms.core.JmsTemplate; +import org.springframework.stereotype.Component; + +@Configuration +@Component +public class ActiveMQComponentConfig { + + + + @Bean(name = "activemq") + public ActiveMQComponent createComponent(ConnectionFactory factory) { + ActiveMQComponent activeMQComponent = new ActiveMQComponent(); + activeMQComponent.setConnectionFactory(factory); + return activeMQComponent; + } + + @Bean(name = "jmsTemplate") + public JmsTemplate jmsTemplate(ConnectionFactory factory){ + JmsTemplate template = new JmsTemplate(); + template.setConnectionFactory( factory ); + return template; + } + +} diff --git a/src/main/java/portal/api/config/BCryptPasswordEncoderConfig.java b/src/main/java/portal/api/config/BCryptPasswordEncoderConfig.java new file mode 100644 index 0000000..8e878b8 --- /dev/null +++ b/src/main/java/portal/api/config/BCryptPasswordEncoderConfig.java @@ -0,0 +1,35 @@ +/*- + * ========================LICENSE_START================================= + * org.etsi.osl.portal.api + * %% + * Copyright (C) 2019 openslice.io + * %% + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * =========================LICENSE_END================================== + */ +package portal.api.config; + + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; + + +@Configuration +public class BCryptPasswordEncoderConfig { + + @Bean + public BCryptPasswordEncoder passwordEncoder() { + return new BCryptPasswordEncoder(); + } +} diff --git a/src/main/java/portal/api/config/CustomClaimVerifier.java b/src/main/java/portal/api/config/CustomClaimVerifier.java new file mode 100644 index 0000000..cb4a38b --- /dev/null +++ b/src/main/java/portal/api/config/CustomClaimVerifier.java @@ -0,0 +1,37 @@ +/*- + * ========================LICENSE_START================================= + * org.etsi.osl.portal.api + * %% + * Copyright (C) 2019 openslice.io + * %% + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * =========================LICENSE_END================================== + */ +package portal.api.config; + +import java.util.Map; + +public class CustomClaimVerifier { + +} + + +//public class CustomClaimVerifier implements JwtClaimsSetVerifier { +// @Override +// public void verify(Map claims) throws InvalidTokenException { +// final String username = (String) claims.get("user_name"); +// if ((username == null) || (username.length() == 0)) { +// throw new InvalidTokenException("user_name claim is empty"); +// } +// } +//} diff --git a/src/main/java/portal/api/config/MethodSecurityConfig.java b/src/main/java/portal/api/config/MethodSecurityConfig.java new file mode 100644 index 0000000..4918a6e --- /dev/null +++ b/src/main/java/portal/api/config/MethodSecurityConfig.java @@ -0,0 +1,37 @@ +/*- + * ========================LICENSE_START================================= + * org.etsi.osl.portal.api + * %% + * Copyright (C) 2019 openslice.io + * %% + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * =========================LICENSE_END================================== + */ +package portal.api.config; + +import org.springframework.context.annotation.Configuration; +import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity; +import org.springframework.security.config.annotation.method.configuration.GlobalMethodSecurityConfiguration; + +@Configuration +@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true, jsr250Enabled = true) +public class MethodSecurityConfig extends GlobalMethodSecurityConfiguration { + +// +// @Override +// protected MethodSecurityExpressionHandler createExpressionHandler() { +// return new OAuth2MethodSecurityExpressionHandler(); +// } + + +} diff --git a/src/main/java/portal/api/config/RestAuthenticationEntryPoint.java b/src/main/java/portal/api/config/RestAuthenticationEntryPoint.java new file mode 100644 index 0000000..4052116 --- /dev/null +++ b/src/main/java/portal/api/config/RestAuthenticationEntryPoint.java @@ -0,0 +1,56 @@ +/*- + * ========================LICENSE_START================================= + * org.etsi.osl.portal.api + * %% + * Copyright (C) 2019 openslice.io + * %% + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * =========================LICENSE_END================================== + */ +package portal.api.config; + +import java.io.IOException; + +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; + +import org.springframework.security.core.AuthenticationException; +import org.springframework.security.web.AuthenticationEntryPoint; +import org.springframework.stereotype.Component; + +@Component +public final class RestAuthenticationEntryPoint implements AuthenticationEntryPoint { + + /** + * From https://www.baeldung.com/securing-a-restful-web-service-with-spring-security + * + * In a standard web application, the authentication process may + * automatically trigger when an un-authenticated client tries to access a + * secured resource. This process usually redirects to a login page so that + * the user can enter credentials. However, for a REST Web Service,this + * behaviour doesn’t make much sense. We should be able to authenticate only + * by a request to the correct URI and if the user is not authenticated all + * requests should simply fail with a 401 UNAUTHORIZED status code. Spring + * Security handles this automatic triggering of the authentication process + * with the concept of an Entry Point – this is a required part of the + * configuration, and can be injected via the authenticationEntryPoint + * method. + */ + + @Override + public void commence(HttpServletRequest request, HttpServletResponse response, + AuthenticationException authException) throws IOException { + + response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Unauthorized openslice user."); + } +} diff --git a/src/main/java/portal/api/config/WebSecurityConfigKeycloak.java b/src/main/java/portal/api/config/WebSecurityConfigKeycloak.java new file mode 100644 index 0000000..5b8c5ae --- /dev/null +++ b/src/main/java/portal/api/config/WebSecurityConfigKeycloak.java @@ -0,0 +1,253 @@ +/*- + * ========================LICENSE_START================================= + * org.etsi.osl.portal.api + * %% + * Copyright (C) 2019 openslice.io + * %% + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * =========================LICENSE_END================================== + */ +package portal.api.config; + + +import java.net.URL; +import java.util.Arrays; +import java.util.Collection; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import com.jayway.jsonpath.JsonPath; +import com.jayway.jsonpath.PathNotFoundException; + +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.autoconfigure.web.ServerProperties; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.boot.context.properties.NestedConfigurationProperty; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Profile; +import org.springframework.core.convert.converter.Converter; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpStatus; +import org.springframework.security.authentication.AbstractAuthenticationToken; +import org.springframework.security.authentication.AuthenticationManager; +import org.springframework.security.authentication.AuthenticationManagerResolver; +import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity; +import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; +import org.springframework.security.config.http.SessionCreationPolicy; +import org.springframework.security.core.GrantedAuthority; +import org.springframework.security.core.authority.SimpleGrantedAuthority; +import org.springframework.security.oauth2.jwt.Jwt; +import org.springframework.security.oauth2.jwt.JwtClaimNames; +import org.springframework.security.oauth2.jwt.JwtDecoder; +import org.springframework.security.oauth2.jwt.JwtDecoders; +import org.springframework.security.oauth2.server.resource.authentication.JwtAuthenticationProvider; +import org.springframework.security.oauth2.server.resource.authentication.JwtAuthenticationToken; +import org.springframework.security.oauth2.server.resource.authentication.JwtIssuerAuthenticationManagerResolver; +import org.springframework.security.web.SecurityFilterChain; +import org.springframework.stereotype.Component; +import org.springframework.web.cors.CorsConfiguration; +import org.springframework.web.cors.UrlBasedCorsConfigurationSource; + +import jakarta.servlet.http.HttpServletRequest; +import lombok.Data; +import lombok.RequiredArgsConstructor; + +@Configuration +@EnableWebSecurity +@EnableMethodSecurity +@Profile("!testing") +public class WebSecurityConfigKeycloak { + + @Bean + SecurityFilterChain filterChain(HttpSecurity http, ServerProperties serverProperties, + @Value("${origins:[]}") String[] origins, @Value("${permit-all:[]}") String[] permitAll, + AuthenticationManagerResolver authenticationManagerResolver) throws Exception { + + http.oauth2ResourceServer(oauth2 -> oauth2.authenticationManagerResolver(authenticationManagerResolver)); + + // Enable and configure CORS + http.cors(cors -> cors.configurationSource(corsConfigurationSource(origins))); + + // State-less session (state in access-token only) + http.sessionManagement(sm -> sm.sessionCreationPolicy(SessionCreationPolicy.STATELESS)); + + // Disable CSRF because of state-less session-management + http.csrf(csrf -> csrf.disable()); + + // Return 401 (unauthorized) instead of 302 (redirect to login) when + // authorization is missing or invalid + http.exceptionHandling(eh -> eh.authenticationEntryPoint((request, response, authException) -> { + response.addHeader(HttpHeaders.WWW_AUTHENTICATE, "Basic realm=\"Restricted Content\""); + response.sendError(HttpStatus.UNAUTHORIZED.value(), HttpStatus.UNAUTHORIZED.getReasonPhrase()); + })); + + // If SSL enabled, disable http (https only) + if (serverProperties.getSsl() != null && serverProperties.getSsl().isEnabled()) { + http.requiresChannel(channel -> channel.anyRequest().requiresSecure()); + } + + // @formatter:off + http.authorizeHttpRequests(requests -> requests + //.requestMatchers(permitAll).permitAll() + .anyRequest().permitAll()); + // @formatter:on + + return http.build(); + } + + private UrlBasedCorsConfigurationSource corsConfigurationSource(String[] origins) { + final var configuration = new CorsConfiguration(); + configuration.setAllowedOrigins(Arrays.asList(origins)); + configuration.setAllowedMethods(List.of("*")); + configuration.setAllowedHeaders(List.of("*")); + configuration.setExposedHeaders(List.of("*")); + configuration.setAllowCredentials(true); + final var source = new UrlBasedCorsConfigurationSource(); + source.registerCorsConfiguration("/**", configuration); + return source; + } + + @Data + @Configuration + @ConfigurationProperties(prefix = "spring-addons") + static class SpringAddonsProperties { + private IssuerProperties[] issuers = {}; + + @Data + static class IssuerProperties { + private URL uri; + + @NestedConfigurationProperty + private ClaimMappingProperties[] claims; + + private String usernameJsonPath = JwtClaimNames.SUB; + + @Data + static class ClaimMappingProperties { + private String jsonPath; + private CaseProcessing caseProcessing = CaseProcessing.UNCHANGED; + private String prefix = ""; + + static enum CaseProcessing { + UNCHANGED, TO_LOWER, TO_UPPER + } + } + } + + public IssuerProperties get(URL issuerUri) throws MisconfigurationException { + final var issuerProperties = Stream.of(issuers).filter(iss -> issuerUri.equals(iss.getUri())).toList(); + if (issuerProperties.size() == 0) { + throw new MisconfigurationException( + "Missing authorities mapping properties for %s".formatted(issuerUri.toString())); + } + if (issuerProperties.size() > 1) { + throw new MisconfigurationException( + "Too many authorities mapping properties for %s".formatted(issuerUri.toString())); + } + return issuerProperties.get(0); + } + + static class MisconfigurationException extends RuntimeException { + private static final long serialVersionUID = 5887967904749547431L; + + public MisconfigurationException(String msg) { + super(msg); + } + } + } + + @RequiredArgsConstructor + static class JwtGrantedAuthoritiesConverter implements Converter> { + private final SpringAddonsProperties.IssuerProperties properties; + + @Override + @SuppressWarnings({ "rawtypes", "unchecked" }) + public Collection convert(Jwt jwt) { + + + return Stream.of(properties.claims).flatMap(claimProperties -> { + Object claim; + try { + claim = JsonPath.read(jwt.getClaims(), claimProperties.jsonPath); + } catch (PathNotFoundException e) { + claim = null; + } + if (claim == null) { + return Stream.empty(); + } + if (claim instanceof String claimStr) { + return Stream.of(claimStr.split(",")); + } + if (claim instanceof String[] claimArr) { + return Stream.of(claimArr); + } + if (Collection.class.isAssignableFrom(claim.getClass())) { + final var iter = ((Collection) claim).iterator(); + if (!iter.hasNext()) { + return Stream.empty(); + } + final var firstItem = iter.next(); + if (firstItem instanceof String) { + return (Stream) ((Collection) claim).stream(); + } + if (Collection.class.isAssignableFrom(firstItem.getClass())) { + return (Stream) ((Collection) claim).stream() + .flatMap(colItem -> ((Collection) colItem).stream()).map(String.class::cast); + } + } + return Stream.empty(); + }) /* Insert some transformation here if you want to add a prefix like "ROLE_" or force upper-case authorities */ + + .map(s -> "ROLE_" + s) + .map(SimpleGrantedAuthority::new) + .map(GrantedAuthority.class::cast).toList(); + } + } + + @Component + @RequiredArgsConstructor + static class SpringAddonsJwtAuthenticationConverter implements Converter { + private final SpringAddonsProperties springAddonsProperties; + + @Override + public AbstractAuthenticationToken convert(Jwt jwt) { + final var issuerProperties = springAddonsProperties.get(jwt.getIssuer()); + final var authorities = new JwtGrantedAuthoritiesConverter(issuerProperties).convert(jwt); + final String username = JsonPath.read(jwt.getClaims(), issuerProperties.getUsernameJsonPath()); + return new JwtAuthenticationToken(jwt, authorities, username); + } + } + + @Bean + AuthenticationManagerResolver authenticationManagerResolver( + SpringAddonsProperties addonsProperties, SpringAddonsJwtAuthenticationConverter authenticationConverter) { + final Map authenticationProviders = Stream.of(addonsProperties.getIssuers()) + .map(SpringAddonsProperties.IssuerProperties::getUri).map(URL::toString) + .collect(Collectors.toMap(issuer -> issuer, + issuer -> authenticationProvider(issuer, authenticationConverter)::authenticate)); + return new JwtIssuerAuthenticationManagerResolver( + (AuthenticationManagerResolver) authenticationProviders::get); + } + + JwtAuthenticationProvider authenticationProvider(String issuer, + SpringAddonsJwtAuthenticationConverter authenticationConverter) { + JwtDecoder decoder = JwtDecoders.fromIssuerLocation(issuer); + var provider = new JwtAuthenticationProvider(decoder); + provider.setJwtAuthenticationConverter(authenticationConverter); + return provider; + } +} \ No newline at end of file diff --git a/src/main/java/portal/api/controller/ArtifactsAPIController.java b/src/main/java/portal/api/controller/ArtifactsAPIController.java new file mode 100644 index 0000000..f80d41b --- /dev/null +++ b/src/main/java/portal/api/controller/ArtifactsAPIController.java @@ -0,0 +1,3495 @@ +/*- + * ========================LICENSE_START================================= + * org.etsi.osl.portal.api + * %% + * Copyright (C) 2019 openslice.io + * %% + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * =========================LICENSE_END================================== + */ + +package portal.api.controller; + +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.net.URL; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; +import java.util.Set; +import java.util.UUID; + +import com.fasterxml.jackson.core.JsonParseException; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.JsonMappingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.dataformat.yaml.YAMLFactory; +import com.fasterxml.jackson.dataformat.yaml.YAMLGenerator.Feature; + +import org.apache.camel.ProducerTemplate; +import org.apache.commons.io.IOUtils; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.etsi.osl.centrallog.client.CLevel; +import org.etsi.osl.centrallog.client.CentralLogger; +import org.hibernate.Session; +import org.hibernate.SessionFactory; +import org.hibernate.Transaction; +import org.json.JSONObject; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.core.io.ByteArrayResource; +import org.springframework.http.CacheControl; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.authority.SimpleGrantedAuthority; +import org.springframework.security.core.context.SecurityContext; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.ModelAttribute; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.client.HttpClientErrorException; +import org.springframework.web.client.HttpStatusCodeException; +import org.springframework.web.multipart.MultipartFile; +import org.etsi.osl.model.Category; +import org.etsi.osl.model.CompositeExperimentOnBoardDescriptor; +import org.etsi.osl.model.CompositeVxFOnBoardDescriptor; +import org.etsi.osl.model.ConstituentVxF; +import org.etsi.osl.model.DeploymentDescriptor; +import org.etsi.osl.model.DeploymentDescriptorStatus; +import org.etsi.osl.model.DeploymentDescriptorVxFPlacement; +import org.etsi.osl.model.ExperimentMetadata; +import org.etsi.osl.model.ExperimentOnBoardDescriptor; +import org.etsi.osl.model.Infrastructure; +import org.etsi.osl.model.MANOplatform; +import org.etsi.osl.model.MANOprovider; +import org.etsi.osl.model.OnBoardingStatus; +import org.etsi.osl.model.PortalProperty; +import org.etsi.osl.model.PortalUser; +import org.etsi.osl.model.Product; +import org.etsi.osl.model.UserRoleType; +import org.etsi.osl.model.VFImage; +import org.etsi.osl.model.ValidationJob; +import org.etsi.osl.model.ValidationStatus; +import org.etsi.osl.model.VxFMetadata; +import org.etsi.osl.model.VxFOnBoardedDescriptor; +import jakarta.annotation.PostConstruct; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.validation.Valid; +import portal.api.bus.BusController; +//import portal.api.centrallog.CLevel; +//import portal.api.centrallog.CentralLogger; +import portal.api.mano.MANOController; +import portal.api.service.CategoryService; +import portal.api.service.DeploymentDescriptorService; +import portal.api.service.InfrastructureService; +import portal.api.service.ManoPlatformService; +import portal.api.service.ManoProviderService; +import portal.api.service.NSDOBDService; +import portal.api.service.NSDService; +import portal.api.service.PortalPropertiesService; +import portal.api.service.ProductService; +import portal.api.service.UsersService; +import portal.api.service.VFImageService; +import portal.api.service.VxFOBDService; +import portal.api.service.VxFService; +import portal.api.util.AttachmentUtil; +import portal.api.validation.ci.ValidationJobResult; + +/** + * @author ctranoris + * + */ +@RestController +//@RequestMapping("/repo") +public class ArtifactsAPIController { +// + +// private MANOController aMANOController; + + private static final transient Log logger = LogFactory.getLog(ArtifactsAPIController.class.getName()); + + private static final String METADATADIR = System.getProperty("user.home") + File.separator + ".portal" + + File.separator + "metadata" + File.separator; + +// @Resource(name="authenticationManager") +// private AuthenticationManager authManager; + + @Autowired + PortalPropertiesService propsService; + + @Autowired + UsersService usersService; + + @Autowired + ManoProviderService manoProviderService; + + @Autowired + VxFService vxfService; + + @Autowired + NSDService nsdService; + + @Autowired + VxFOBDService vxfOBDService; + @Autowired + NSDOBDService nsdOBDService; + + @Autowired + VFImageService vfImageService; + + @Autowired + ProductService productService; + + @Autowired + ManoPlatformService manoPlatformService; + + @Autowired + MANOController aMANOController; + + @Autowired + CategoryService categoryService; + + @Autowired + InfrastructureService infrastructureService; + + @Autowired + DeploymentDescriptorService deploymentDescriptorService; + + @Autowired + ObjectMapper objectMapper; + + @Autowired + BusController busController; + + @Autowired + ProducerTemplate template; + + @Value("${spring.application.name}") + private String compname; + + @Autowired + private CentralLogger centralLogger; + + /** + * update the properties to Bus + */ + @PostConstruct + private void sendPropertiesToBus() { + try { + ObjectMapper mapper = new ObjectMapper(new YAMLFactory().disable(Feature.WRITE_DOC_START_MARKER)); + String props; + props = mapper.writeValueAsString(propsService.getPropertiesAsMap()); + busController.propertiesUpdate(props); + } catch (JsonProcessingException e) { + e.printStackTrace(); + } + + } + + // VxFS API + + private Product addNewProductData(Product prod, MultipartFile image, MultipartFile submittedFile, + MultipartFile[] screenshots, HttpServletRequest request) throws IOException { + + String uuid = UUID.randomUUID().toString(); + + logger.info("prodname = " + prod.getName()); + logger.info("version = " + prod.getVersion()); + logger.info("shortDescription = " + prod.getShortDescription()); + logger.info("longDescription = " + prod.getLongDescription()); + + prod.setUuid(uuid); + prod.setDateCreated(new Date()); + prod.setDateUpdated(new Date()); + + // String[] catIDs = categories.split(","); + // for (String catid : catIDs) { + // Category category = portalRepositoryRef.getCategoryByID( + // Integer.valueOf(catid) ); + // prod.addCategory(category); + // } + + // for (ProductExtensionItem e : extensions) { + // + // } + // + // String[] exts = extensions.split(","); + // for (String extparmval : exts) { + // String[] i = extparmval.split("="); + // prod.addExtensionItem(i[0], i[1]); + // } + + String endpointUrl = request.getContextPath();// request.getRequestURI(); + + String tempDir = METADATADIR + uuid + File.separator; + + Files.createDirectories(Paths.get(tempDir)); + + // If an icon is submitted + if (image != null) { + // Get the icon filename + String imageFileNamePosted = image.getOriginalFilename();// AttachmentUtil.getFileName(image.getHeaders()); + logger.info("image = " + imageFileNamePosted); + // If there is an icon name + if (!imageFileNamePosted.equals("")) { + // Save the icon File + String imgfile = AttachmentUtil.saveFile(image, tempDir + imageFileNamePosted); + logger.info("imgfile saved to = " + imgfile); + // Save the icon file destination + prod.setIconsrc( + endpointUrl.toString().replace("http:", "") + "/images/" + uuid + "/" + imageFileNamePosted); + } + } + + if (submittedFile != null) { + // Get the filename + String aFileNamePosted = submittedFile.getOriginalFilename();// AttachmentUtil.getFileName(submittedFile.getHeaders()); + logger.info("vxfFile = " + aFileNamePosted); + // Is the filename is not an empty string + if (!aFileNamePosted.equals("")) { + // Save the file to the specified path and return the new path. + String descriptorFilePath = AttachmentUtil.saveFile(submittedFile, tempDir); + // Set the package location in Product instance + logger.info("vxffilepath saved to = " + descriptorFilePath); + prod.setPackageLocation( + endpointUrl.toString().replace("http:", "") + "/packages/" + uuid + "/" + aFileNamePosted); + + // If it is a VxF Object + if (prod instanceof VxFMetadata) { + try { + AttachmentUtil attachmentInfo = new AttachmentUtil(); + attachmentInfo.extractYAMLfileAndIcon(descriptorFilePath); + this.loadVxfMetadataFromOSMVxFDescriptorFile((VxFMetadata) prod, attachmentInfo, endpointUrl); + } catch (NullPointerException e) { + e.printStackTrace(); + return null; + } + logger.info("After " + prod.getPackageLocation()); + } else if (prod instanceof ExperimentMetadata) { + // If prod is an NS Descriptor + try { + AttachmentUtil attachmentInfo = new AttachmentUtil(); + attachmentInfo.extractYAMLfileAndIcon(descriptorFilePath); + this.loadNSMetadataFromOSMNSDescriptorFile((ExperimentMetadata) prod, attachmentInfo, + endpointUrl); + } catch (NullPointerException e) { + e.printStackTrace(); + return null; + } + } + } + } + // screenshots are provided during the call of the function + + if (screenshots != null) { + String screenshotsFilenames = ""; + int i = 1; + for (MultipartFile shot : screenshots) { + String shotFileNamePosted = shot.getOriginalFilename();// AttachmentUtil.getFileName(shot.getHeaders()); + logger.info("Found screenshot image shotFileNamePosted = " + shotFileNamePosted); + logger.info("shotFileNamePosted = " + shotFileNamePosted); + if (!shotFileNamePosted.equals("")) { + shotFileNamePosted = "shot" + i + "_" + shotFileNamePosted; + String shotfilepath = AttachmentUtil.saveFile(shot, tempDir + shotFileNamePosted); + logger.info("shotfilepath saved to = " + shotfilepath); + shotfilepath = endpointUrl.toString().replace("http:", "") + "/images/" + uuid + "/" + + shotFileNamePosted; + screenshotsFilenames += shotfilepath + ","; + i++; + } + } + if (screenshotsFilenames.length() > 0) + screenshotsFilenames = screenshotsFilenames.substring(0, screenshotsFilenames.length() - 1); + + prod.setScreenshots(screenshotsFilenames); + + } + +// // we must replace given product categories with the ones from our DB +// for (Category c : prod.getCategories()) { +// Category catToUpdate = categoryService.findById( c.getId() ); +// // logger.info("BEFORE PROD SAVE, category "+catToUpdate.getName()+" +// // contains Products: "+ catToUpdate.getProducts().size() ); +// //prod.getCategories().set(prod.getCategories().indexOf(c), catToUpdate); +// prod.getCategories().add(catToUpdate); +// +// } + + // if it's a VxF we need also to update the images that this VxF will use + if (prod instanceof VxFMetadata) { + VxFMetadata vxfm = (VxFMetadata) prod; + for (VFImage vfimg : vxfm.getVfimagesVDU()) { + vfimg.getUsedByVxFs().add(vxfm); + } + } + + // Save now vxf for User + PortalUser vxfOwner = usersService.findById(prod.getOwner().getId()); + vxfOwner.addProduct(prod); + prod.setOwner(vxfOwner); // replace given owner with the one from our DB + + PortalUser owner = usersService.updateUserInfo(vxfOwner, false); + + Product registeredProd = null; + if (prod instanceof VxFMetadata) { + registeredProd = vxfService.getVxFByUUID(uuid); + } else { + registeredProd = nsdService.getdNSDByUUID(uuid); + } + + // now fix category references + for (Category c : prod.getCategories()) { + Category catToUpdate = categoryService.findById(c.getId()); + catToUpdate.addProduct(registeredProd); + categoryService.updateCategoryInfo(catToUpdate); + } + + return registeredProd; + } + + private void loadVxfMetadataFromOSMVxFDescriptorFile(VxFMetadata prod, AttachmentUtil attachmentInfo, + String endpointUrl) throws IOException, NullPointerException { + VxFMetadata tmp_prod = busController.getVNFDMetadataFromMANO(prod.getPackagingFormat().name(), + attachmentInfo.getDescriptorYAMLfile()); + if (tmp_prod != null) { + // *************LOAD THE Product Object from the VNFD Descriptor + // START************************************ + // Check if a vnfd with this id already exists in the DB + List existingvxf = vxfService.getAllVxFByName(tmp_prod.getName()); + if (existingvxf != null && existingvxf.size()>0) { + throw new IOException( + "Descriptor with same name already exists. No updates were performed. Please change the name of the descriptor"); + } + // Get the name for the db + prod.setName(tmp_prod.getName()); + prod.setVersion(tmp_prod.getVersion()); + prod.setVendor(tmp_prod.getVendor()); + prod.setShortDescription(tmp_prod.getShortDescription()); + prod.setLongDescription(tmp_prod.getLongDescription()); + + prod.setValidationStatus(ValidationStatus.UNDER_REVIEW); + prod.getVfimagesVDU().clear();// clear previous referenced images + for (VFImage vfImage : ((VxFMetadata) tmp_prod).getVfimagesVDU()) { + String imageName = vfImage.getName(); + if ((imageName != null) && (!imageName.equals(""))) { + VFImage sm = vfImageService.getVFImageByName(imageName); + if (sm == null) { + sm = new VFImage(); + sm.setName(imageName); + PortalUser vfImagewner = usersService.findById(prod.getOwner().getId()); + sm.setOwner(vfImagewner); + sm.setShortDescription("Automatically created during vxf " + prod.getName() + + " submission. Owner must update."); + String uuidVFImage = UUID.randomUUID().toString(); + sm.setUuid(uuidVFImage); + sm.setDateCreated(new Date()); + sm = vfImageService.saveVFImage(sm); + } + prod.getVfimagesVDU().add(sm); + } + } + + // Store the requirements in HTML + prod.setDescriptorHTML(tmp_prod.getDescriptorHTML()); + // Store the YAML file + prod.setDescriptor(tmp_prod.getDescriptor()); + + // If we got an IconfilePath file from/through the vnfExtractor + if (attachmentInfo.getIconfilePath() != null && tmp_prod.getIconsrc() != null) { + Path path = Paths.get(tmp_prod.getIconsrc()); + String imageFileNamePosted = path.getFileName().toString(); + logger.info("image = " + imageFileNamePosted); + // If the name is not empty + if (!imageFileNamePosted.equals("")) { + String imgfile = AttachmentUtil.saveFile(attachmentInfo.getIconfilePath(), + METADATADIR + prod.getUuid() + File.separator + imageFileNamePosted); + logger.info("imgfile saved to = " + imgfile); + prod.setIconsrc( + endpointUrl.replace("http:", "") + "/images/" + prod.getUuid() + "/" + imageFileNamePosted); + } + } + // *************LOAD THE Product Object from the VNFD Descriptor + // END************************************ + } else { + throw new NullPointerException(); + } + } + + private void loadNSMetadataFromOSMNSDescriptorFile(ExperimentMetadata prod, AttachmentUtil attachmentInfo, + String endpointUrl) throws IOException, NullPointerException { + ExperimentMetadata tmp_prod = busController.getNSDMetadataFromMANO(prod.getPackagingFormat().name(), + attachmentInfo.getDescriptorYAMLfile()); + if (tmp_prod != null) { + // *************LOAD THE Product Object from the NSD Descriptor + // START************************************ + // Check if a vnfd with this id already exists in the DB + + ExperimentMetadata existingns = nsdService.getNSDByName(tmp_prod.getName()); + if ((existingns != null)) { + throw new IOException("Descriptor with same name already exists. No updates were performed."); + } + prod.setName(tmp_prod.getName()); + prod.setVersion(tmp_prod.getVersion()); + prod.setVendor(tmp_prod.getVendor()); + prod.setShortDescription(tmp_prod.getShortDescription()); + prod.setLongDescription(tmp_prod.getLongDescription()); + + for (ConstituentVxF cvxf : tmp_prod.getConstituentVxF()) { + cvxf.setVxfref(vxfService.getVxFByName(cvxf.getVnfdidRef())); + ((ExperimentMetadata) prod).getConstituentVxF().add(cvxf); + } + // Store the requirements in HTML + prod.setDescriptorHTML(tmp_prod.getDescriptorHTML()); + // Store the YAML file + prod.setDescriptor(tmp_prod.getDescriptor()); + + // If we got an IconfilePath file from/through the vnfExtractor + if (attachmentInfo.getIconfilePath() != null && tmp_prod.getIconsrc() != null) { + Path path = Paths.get(tmp_prod.getIconsrc()); + String imageFileNamePosted = path.getFileName().toString(); + logger.info("image = " + imageFileNamePosted); + // If the name is not empty + if (!imageFileNamePosted.equals("")) { + String imgfile = AttachmentUtil.saveFile(attachmentInfo.getIconfilePath(), + METADATADIR + prod.getUuid() + File.separator + imageFileNamePosted); + logger.info("imgfile saved to = " + imgfile); + prod.setIconsrc(endpointUrl + "/images/" + prod.getUuid() + "/" + imageFileNamePosted); + } + } + // *************LOAD THE Product Object from the NSD Descriptor + // END************************************ + } else { + throw new NullPointerException(); + } + } + + private void updateVxfMetadataFromOSMVxFDescriptorFile(VxFMetadata prevProduct, AttachmentUtil attachmentInfo, + String endpointUrl) throws IOException, NullPointerException { + VxFMetadata tmp_prod = busController.getVNFDMetadataFromMANO(prevProduct.getPackagingFormat().name(), + attachmentInfo.getDescriptorYAMLfile()); + if (tmp_prod != null) { + // on update we need to check if name and version are the same. Only then we + // will accept it + if (!prevProduct.getName().equals(tmp_prod.getName()) + || !prevProduct.getVersion().equals(tmp_prod.getVersion())) { + throw new IOException( + "Name and version are not equal to existing descriptor. No updates were performed."); + } + if (((VxFMetadata) prevProduct).isCertified()) { + throw new IOException("Descriptor is already Validated and cannot change! No updates were performed."); + } + + // Get the name for the db + prevProduct.setName(tmp_prod.getName()); + prevProduct.setVersion(tmp_prod.getVersion()); + prevProduct.setVendor(tmp_prod.getVendor()); + prevProduct.setShortDescription(tmp_prod.getShortDescription()); + prevProduct.setLongDescription(tmp_prod.getLongDescription()); + + ((VxFMetadata) prevProduct).setValidationStatus(ValidationStatus.UNDER_REVIEW); + + for (VFImage img : ((VxFMetadata) prevProduct).getVfimagesVDU()) { + logger.info("img.getUsedByVxFs().remove(prevProduct) = " + img.getUsedByVxFs().remove(prevProduct)); + vfImageService.updateVFImageInfo(img); + } + ((VxFMetadata) prevProduct).getVfimagesVDU().clear();// clear previous referenced images + for (VFImage vfImage : ((VxFMetadata) tmp_prod).getVfimagesVDU()) { + String imageName = vfImage.getName(); + if ((imageName != null) && (!imageName.equals(""))) { + VFImage sm = vfImageService.getVFImageByName(imageName); + if (sm == null) { + sm = new VFImage(); + sm.setName(imageName); + PortalUser vfImagewner = usersService.findById(prevProduct.getOwner().getId()); + sm.setOwner(vfImagewner); + sm.setShortDescription("Automatically created during vxf " + prevProduct.getName() + + " submission. Owner must update."); + String uuidVFImage = UUID.randomUUID().toString(); + sm.setUuid(uuidVFImage); + sm.setDateCreated(new Date()); + sm = vfImageService.saveVFImage(sm); + } + if (!((VxFMetadata) prevProduct).getVfimagesVDU().contains(sm)) { + ((VxFMetadata) prevProduct).getVfimagesVDU().add(sm); + sm.getUsedByVxFs().add(((VxFMetadata) prevProduct)); + vfImageService.updateVFImageInfo(sm); + } + } + } + // Store the requirements in HTML + prevProduct.setDescriptorHTML(tmp_prod.getDescriptorHTML()); + // Store the YAML file + prevProduct.setDescriptor(tmp_prod.getDescriptor()); + // If we got an IconfilePath file from/through the vnfExtractor + if (attachmentInfo.getIconfilePath() != null && tmp_prod.getIconsrc() != null) { + Path path = Paths.get(tmp_prod.getIconsrc()); + String imageFileNamePosted = path.getFileName().toString(); + logger.info("image = " + imageFileNamePosted); + // If the name is not empty + if (!imageFileNamePosted.equals("")) { + String imgfile = AttachmentUtil.saveFile(attachmentInfo.getIconfilePath(), + METADATADIR + prevProduct.getUuid() + File.separator + imageFileNamePosted); + logger.info("imgfile saved to = " + imgfile); + prevProduct.setIconsrc(endpointUrl.replace("http:", "") + "/images/" + prevProduct.getUuid() + "/" + + imageFileNamePosted); + } + } + // *************LOAD THE Product Object from the VNFD Descriptor + // END************************************ + } else { + throw new NullPointerException(); + } + } + + private void updateNSMetadataFromOSMNSDescriptorFile(ExperimentMetadata prevProduct, AttachmentUtil attachmentInfo, + String endpointUrl) throws IOException, NullPointerException { + ExperimentMetadata tmp_prod = busController.getNSDMetadataFromMANO(prevProduct.getPackagingFormat().name(), + attachmentInfo.getDescriptorYAMLfile()); + if (tmp_prod != null) { + + // *************LOAD THE Product Object from the NSD Descriptor + // START************************************ + // on update we need to check if name and version are the same. Only then we + // will accept it + if (!prevProduct.getName().equals(tmp_prod.getName()) + || !prevProduct.getVersion().equals(tmp_prod.getVersion())) { + throw new IOException( + "Name and version are not equal to existing descriptor. No updates were performed."); + } + if (((ExperimentMetadata) prevProduct).isValid()) { + throw new IOException("Descriptor is already Validated and cannot change! No updates were performed."); + } + prevProduct.setName(tmp_prod.getName()); + prevProduct.setVersion(tmp_prod.getVersion()); + prevProduct.setVendor(tmp_prod.getVendor()); + prevProduct.setShortDescription(tmp_prod.getShortDescription()); + prevProduct.setLongDescription(tmp_prod.getLongDescription()); + + for (ConstituentVxF cvxf : tmp_prod.getConstituentVxF()) { + ((ExperimentMetadata) prevProduct).getConstituentVxF().add(cvxf); + } + + // Store the requirements in HTML + prevProduct.setDescriptorHTML(tmp_prod.getDescriptorHTML()); + // Store the YAML file + prevProduct.setDescriptor(tmp_prod.getDescriptor()); + + // If we got an IconfilePath file from/through the vnfExtractor + if (attachmentInfo.getIconfilePath() != null && tmp_prod.getIconsrc() != null) { + Path path = Paths.get(tmp_prod.getIconsrc()); + String imageFileNamePosted = path.getFileName().toString(); + logger.info("image = " + imageFileNamePosted); + // If the name is not empty + if (!imageFileNamePosted.equals("")) { + String imgfile = AttachmentUtil.saveFile(attachmentInfo.getIconfilePath(), + METADATADIR + prevProduct.getUuid() + File.separator + imageFileNamePosted); + logger.info("imgfile saved to = " + imgfile); + prevProduct.setIconsrc(endpointUrl.replace("http:", "") + "/images/" + prevProduct.getUuid() + "/" + + imageFileNamePosted); + } + } + // *************LOAD THE Product Object from the NSD Descriptor + // END************************************ + } else { + throw new NullPointerException(); + } + + } + + /******************* VxFs API ***********************/ + + @GetMapping(value = "/vxfs", produces = "application/json") + public ResponseEntity getAllVxFs(@RequestParam(name = "categoryid", required = false) Long categoryid) { + + logger.info("getVxFs categoryid=" + categoryid); + List vxfs = vxfService.getPublishedVxFsByCategory(categoryid); // portalRepositoryRef.getVxFs(categoryid, + // true); + return ResponseEntity.ok(vxfs); + } + + // @PreAuthorize("#oauth2.hasScope('read') and #oauth2.hasScope('admin')") + @GetMapping(value = "/admin/vxfs", produces = "application/json") + @ResponseBody + public ResponseEntity getVxFs(@RequestParam(name = "categoryid", required = false) Long categoryid, + HttpServletRequest request) { + logger.info("getVxFs categoryid=" + categoryid); + + // Object attr = request.getSession().getAttribute("SPRING_SECURITY_CONTEXT"); + // SecurityContextHolder.setContext((SecurityContext) attr); + Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); + + PortalUser u = usersService.findByUsername(authentication.getName()); + + if (u != null) { + List vxfs; + + if (u.getRoles().contains(UserRoleType.ROLE_ADMIN)) { + vxfs = vxfService.getVxFsByCategory(categoryid); + } else { + vxfs = vxfService.getVxFsByUserID((long) u.getId()); + } + + return ResponseEntity.ok(vxfs); + + } else { + return (ResponseEntity) ResponseEntity.badRequest().body("User not found in registry"); + } + + } + + @PostMapping(value = "/admin/vxfs") + public ResponseEntity addVxFMetadata(@ModelAttribute("vxf") String avxf, + @RequestParam(name = "prodIcon", required = false) MultipartFile prodIcon, + @RequestParam("prodFile") MultipartFile prodFile, + @RequestParam(name = "screenshots", required = false) MultipartFile[] screenshots, + HttpServletRequest request) { + + VxFMetadata vxf = null; + try { + vxf = objectMapper.readValue(avxf, VxFMetadata.class); + } catch (JsonParseException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (JsonMappingException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + + // Object attr = request.getSession().getAttribute("SPRING_SECURITY_CONTEXT"); + // SecurityContextHolder.setContext((SecurityContext) attr); + + PortalUser u = usersService.findByUsername(SecurityContextHolder.getContext().getAuthentication().getName()); + + if (u == null) { + return (ResponseEntity) ResponseEntity.badRequest().body("User " + + SecurityContextHolder.getContext().getAuthentication().getName() + " not found in registry"); + } + + String emsg = ""; + + VxFMetadata vxfsaved = null; + try { + + logger.info("Received @POST for vxf : " + vxf.getName()); + logger.info("Received @POST for vxf.extensions : " + vxf.getExtensions()); + vxfsaved = (VxFMetadata) addNewProductData(vxf, prodIcon, prodFile, screenshots, request); + } catch (Exception e) { + vxfsaved = null; + e.printStackTrace(); + logger.error("Exception during adding New Product Data with message" + e.getMessage()); + emsg = e.getMessage(); + } + + if (vxfsaved != null) { + // ====================================================== + // AUTOMATIC ONBOARDING PROCESS -START + // Need to select MANO Provider, convert vxfMetadata to VxFOnBoardedDescriptor + // and pass it as an input. + + // Get the MANO providers which are set for automatic onboarding + + busController.newVxFUploadedToPortalRepo(vxf.getId()); + + List MANOprovidersEnabledForOnboarding = manoProviderService + .getMANOprovidersEnabledForOnboarding(); + + for (MANOprovider mp : MANOprovidersEnabledForOnboarding) { + logger.error(" ========> vxfsaved.getPackagingFormat() = " + vxfsaved.getPackagingFormat()); + if (vxfsaved.getPackagingFormat().toString().equals(mp.getSupportedMANOplatform().getVersion())) { + // Create VxfOnboardedDescriptor + VxFOnBoardedDescriptor obd = new VxFOnBoardedDescriptor(); + // Get the first one for now + obd.setObMANOprovider(mp); + obd.setUuid(UUID.randomUUID().toString()); + VxFMetadata refVxF = (VxFMetadata) vxfService.getVxFById(vxfsaved.getId()); + // Fill the VxFMetadata of VxFOnBoardedDescriptor + obd.setVxf(refVxF); + // save obd + obd = vxfOBDService.updateVxFOnBoardedDescriptor(obd); + + // Update the VxFMetadata Object with the obd Object + refVxF.getVxfOnBoardedDescriptors().add(obd); + + // save product + refVxF = (VxFMetadata) vxfService.updateProductInfo(refVxF); + + // save VxFonBoardedDescriptor or not ??? + + // set proper scheme (http or https) + // MANOController.setHTTPSCHEME( request.getRequestURL().toString() ); + + if (obd.getVxf().getOwner() == null) { + logger.error(" ========> obd.getVxf().getOwner() == null "); + } + + // ***************************************************************************************************************************\ + // Because in portal.api.mano we need the url for the package location in order + // not to ask back, if the package locations + // does not contain http add the default maindomain value. + // We can either add it here or change that where the pLocation is set initially + // for the object. + // Get the location of the package + String pLocation = obd.getVxf().getPackageLocation(); + logger.info("VxF Package Location: " + pLocation); + if (!pLocation.contains("http")) { + pLocation = propsService.getPropertyByName("maindomain").getValue() + pLocation; + obd.getVxf().setPackageLocation(pLocation); + vxfService.updateProductInfo(obd.getVxf()); + } + logger.info("PROPER VxF Package Location: " + pLocation); + // *************************************************************************************************************************** + + // Send the message for automatic onboarding + // busController.onBoardVxFAdded( obd ); + + try { + String[] fpath = obd.getVxf().getPackageLocation().split("/"); + logger.info("uuid: " + fpath[fpath.length - 2]); + logger.info("Package: " + fpath[fpath.length - 1]); + String vxfAbsfile = METADATADIR + fpath[fpath.length - 2] + File.separator + + fpath[fpath.length - 1]; + File afile = new File(vxfAbsfile); + Path path = Paths.get(afile.getAbsolutePath()); + // ByteArrayResource resource = new ByteArrayResource(Files.readAllBytes(path)); + // busController.onBoardVxFAdded( obd, afile, resource ); + + CompositeVxFOnBoardDescriptor compositeobdobj = new CompositeVxFOnBoardDescriptor(); + compositeobdobj.setFilename(afile.getName()); + compositeobdobj.setAllBytes(Files.readAllBytes(path)); + compositeobdobj.setObd(obd); + busController.onBoardVxFAddedByCompositeObj(compositeobdobj); + + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + } + // AUTOMATIC ONBOARDING PROCESS -END + // ====================================================== + VxFMetadata vxfr = (VxFMetadata) vxfService.getVxFById(vxfsaved.getId());// rereading this, seems to + // keep the DB connection + busController.validateVxF(vxfr); + return ResponseEntity.ok(vxfr); + } else { + return (ResponseEntity) ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR) + .body("{ \"message\" : \"Requested entity cannot be installed. " + emsg + "\"}"); + // return (ResponseEntity) ResponseEntity.badRequest().body( "Requested + // entity cannot be installed. " + emsg ); + } + + } + + /** + * @param userID + * @return true if user logged is equal to the requested id of owner, or is + * ROLE_ADMIN + */ + private boolean checkUserIDorIsAdmin(long userID) { + + Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); + + logger.info("principal 1= " + authentication.getAuthorities() + .contains(new SimpleGrantedAuthority(UserRoleType.ROLE_ADMIN.getValue()))); + logger.info("principal 2= " + authentication.getAuthorities() + .contains(new SimpleGrantedAuthority(UserRoleType.ROLE_TESTBED_PROVIDER.getValue()))); + logger.info("principal 2= " + authentication.getAuthorities() + .contains(new SimpleGrantedAuthority(UserRoleType.ROLE_MENTOR.getValue()))); + + if (authentication.getAuthorities().contains(new SimpleGrantedAuthority(UserRoleType.ROLE_ADMIN.getValue()))) { + logger.info("checkUserIDorIsAdmin, authentication role = " + authentication.getAuthorities() + .contains(new SimpleGrantedAuthority(UserRoleType.ROLE_ADMIN.getValue()))); + return true; + } + + PortalUser uToFind = usersService.findById(userID); + if ((uToFind != null) && (uToFind.getUsername() == authentication.getName())) { + logger.info("checkUserIDorIsAdmin, user is equal with request"); + return true; + } + + return false; + } + + @PutMapping(value = "/admin/vxfs/{bid}", produces = "application/json", consumes = "multipart/form-data") + public ResponseEntity updateVxFMetadata(@PathVariable("bid") int bid, @ModelAttribute("vxf") String avxf, + @RequestParam(name = "prodIcon", required = false) MultipartFile prodIcon, + @RequestParam(name = "prodFile", required = false) MultipartFile prodFile, + @RequestParam(name = "screenshots", required = false) MultipartFile[] screenshots, + HttpServletRequest request) throws ForbiddenException { + + VxFMetadata vxf = null; + try { + vxf = objectMapper.readValue(avxf, VxFMetadata.class); + } catch (JsonParseException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (JsonMappingException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + + PortalUser u = usersService.findByUsername(SecurityContextHolder.getContext().getAuthentication().getName()); + + if (u == null) { + return (ResponseEntity) ResponseEntity.badRequest().body("User not found in registry"); + } + + String emsg = ""; + VxFMetadata vxfsaved = null; + + try { + + if (!checkUserIDorIsAdmin(vxf.getOwner().getId())) { + throw new ForbiddenException("The requested page is forbidden"); // return (ResponseEntity) + // ResponseEntity.status(HttpStatus.FORBIDDEN); + + } + + logger.info("Received @PUT for vxf : " + vxf.getName()); + logger.info("Received @PUT for vxf.extensions : " + vxf.getExtensions()); + + vxfsaved = (VxFMetadata) updateProductMetadata(vxf, prodIcon, prodFile, screenshots, request); + } catch (IOException e) { + vxfsaved = null; + e.printStackTrace(); + logger.error(e.getMessage()); + emsg = e.getMessage(); + } + + if (vxfsaved != null) { + + busController.updatedVxF(vxfsaved); + // notify only if validation changed + + if (prodFile != null) { // if the descriptor changed then we must re-trigger validation + + String vxfFileNamePosted = prodFile.getName(); + if (!vxfFileNamePosted.equals("unknown")) { + + busController.validateVxF(vxf); + } + } + + return ResponseEntity.ok(vxf); + } else { + return (ResponseEntity) ResponseEntity.badRequest() + .body("Requested entity cannot be installed. " + emsg); + } + + } + + // VxFs related API + + private Product updateProductMetadata(Product prod, MultipartFile image, MultipartFile prodFile, + MultipartFile[] screenshots, HttpServletRequest request) throws IOException { + + logger.info("userid = " + prod.getOwner().getId()); + logger.info("prodname = " + prod.getName()); + logger.info("prodid = " + prod.getId()); + + logger.info("produuid = " + prod.getUuid()); + logger.info("version = " + prod.getVersion()); + logger.info("shortDescription = " + prod.getShortDescription()); + logger.info("longDescription = " + prod.getLongDescription()); + + // first remove all references of the product from the previous + // categories + + Product prevProduct = (Product) productService.getProductByID(prod.getId()); + + prevProduct.setDateUpdated(new Date()); + + String endpointUrl = request.getContextPath();// request.getRequestURI(); + + String tempDir = METADATADIR + prevProduct.getUuid() + File.separator; + + Files.createDirectories(Paths.get(tempDir)); + + // If an icon is submitted + if (image != null) { + // Get the icon filename + String imageFileNamePosted = image.getOriginalFilename();// AttachmentUtil.getFileName(image.getHeaders()); + logger.info("image = " + imageFileNamePosted); + // If there is an icon name + if (!imageFileNamePosted.equals("unknown")) { + // Save the icon File + String imgfile = AttachmentUtil.saveFile(image, tempDir + imageFileNamePosted); + logger.info("imgfile saved to = " + imgfile); + // Save the icon file destination + prevProduct.setIconsrc(endpointUrl.toString().replace("http:", "") + "/images/" + prevProduct.getUuid() + + "/" + imageFileNamePosted); + } + } + + if (prevProduct instanceof VxFMetadata) { + ((VxFMetadata) prevProduct).setPackagingFormat(((VxFMetadata) prod).getPackagingFormat()); + prevProduct.setTermsOfUse(prod.getTermsOfUse()); + prevProduct.setPublished(prod.isPublished()); + ((VxFMetadata) prevProduct).setCertifiedBy(((VxFMetadata) prod).getCertifiedBy()); + ((VxFMetadata) prevProduct).getSupportedMANOPlatforms().clear(); + for (MANOplatform mp : ((VxFMetadata) prod).getSupportedMANOPlatforms()) { + MANOplatform mpdb = manoPlatformService.getMANOplatformByID(mp.getId()); + ((VxFMetadata) prevProduct).getSupportedMANOPlatforms().add(mpdb); + } + // if ( !((VxFMetadata) prevProduct).isCertified() ){ //allow for now to change + // state + ((VxFMetadata) prevProduct).setCertified(((VxFMetadata) prod).isCertified()); + // } + ((VxFMetadata) prevProduct).setCertifiedBy(((VxFMetadata) prod).getCertifiedBy()); + + } else if (prevProduct instanceof ExperimentMetadata) { + + prevProduct.setTermsOfUse(prod.getTermsOfUse()); + prevProduct.setPublished(prod.isPublished()); + // if ( !((ExperimentMetadata) prevProduct).isValid() ){ //allow for now to + // change state + ((ExperimentMetadata) prevProduct).setValid(((ExperimentMetadata) prod).isValid()); + // } + ((ExperimentMetadata) prevProduct).setPackagingFormat(((ExperimentMetadata) prod).getPackagingFormat()); + } + + if (prodFile != null) { + // Get the filename + String aFileNamePosted = prodFile.getOriginalFilename();// AttachmentUtil.getFileName(prodFile.getHeaders()); + logger.info("vxfFile = " + aFileNamePosted); + // Is the filename is not an empty string + if (!aFileNamePosted.equals("unknown")) { + String descriptorFilePath = AttachmentUtil.saveFile(prodFile, tempDir + aFileNamePosted); + // Set the package location in Product instance + logger.info("vxffilepath saved to = " + descriptorFilePath); + prevProduct.setPackageLocation(endpointUrl.toString().replace("http:", "") + "/packages/" + + prevProduct.getUuid() + "/" + aFileNamePosted); + // If it is a VxF Object + if (prevProduct instanceof VxFMetadata) { + try { + AttachmentUtil attachmentInfo = new AttachmentUtil(); + attachmentInfo.extractYAMLfileAndIcon(descriptorFilePath); + this.updateVxfMetadataFromOSMVxFDescriptorFile((VxFMetadata) prevProduct, attachmentInfo, + endpointUrl); + } catch (NullPointerException e) { + logger.error("Null Pointer Exception during update VxF Metadata From OSM VxF Descriptor File"); + return null; + } + logger.info("After " + prod.getPackageLocation()); + // If prod is an NS Descriptor + } else if (prevProduct instanceof ExperimentMetadata) { + try { + AttachmentUtil attachmentInfo = new AttachmentUtil(); + attachmentInfo.extractYAMLfileAndIcon(descriptorFilePath); + this.loadNSMetadataFromOSMNSDescriptorFile((ExperimentMetadata) prod, attachmentInfo, + endpointUrl); + } catch (NullPointerException e) { + logger.error("Null Pointer Exception during loading NS Metadata From OSM NS Descriptor File"); + return null; + } + + } + + } + } + + String screenshotsFilenames = ""; + int i = 1; + if (screenshots != null){ + for (MultipartFile shot : screenshots) { + String shotFileNamePosted = shot.getOriginalFilename(); // AttachmentUtil.getFileName(shot.getHeaders()); + logger.info("Found screenshot image shotFileNamePosted = " + shotFileNamePosted); + logger.info("shotFileNamePosted = " + shotFileNamePosted); + if (!shotFileNamePosted.equals("")) { + shotFileNamePosted = "shot" + i + "_" + shotFileNamePosted; + String shotfilepath = AttachmentUtil.saveFile(shot, tempDir + shotFileNamePosted); + logger.info("shotfilepath saved to = " + shotfilepath); + shotfilepath = endpointUrl.toString().replace("http:", "") + "/images/" + prevProduct.getUuid() + "/" + + shotFileNamePosted; + screenshotsFilenames += shotfilepath + ","; + i++; + } + } + } + if (screenshotsFilenames.length() > 0) + screenshotsFilenames = screenshotsFilenames.substring(0, screenshotsFilenames.length() - 1); + + prevProduct.setScreenshots(screenshotsFilenames); + + // save product + prevProduct = productService.updateProductInfo(prevProduct); + + // now fix category product references + // first remove all + for (Category c : prevProduct.getCategories()) { + logger.info("Will remove product " + prevProduct.getName() + ", from Previous Category " + c.getName()); + c.removeProduct(prevProduct); + categoryService.updateCategoryInfo(c); + } + // add only the defined + for (Category catToUpdate : prod.getCategories()) { + // Product p = portalRepositoryRef.getProductByID(prod.getId()); + Category c = categoryService.findById(catToUpdate.getId()); + c.addProduct(prevProduct); + categoryService.updateCategoryInfo(c); + } + +// if (vxfOwner.getProductById(prod.getId()) == null) +// vxfOwner.addProduct(prod); +// portalRepositoryRef.updateUserInfo( vxfOwner); + return prevProduct; + } + + @GetMapping(value = "/images/{uuid}/{imgfile:.+}", produces = { "image/jpeg", "image/png" }) + public @ResponseBody ResponseEntity getEntityImage(@PathVariable("uuid") String uuid, + @PathVariable("imgfile") String imgfile) { + logger.info("getEntityImage of uuid: " + uuid); + String imgAbsfile = METADATADIR + uuid + File.separator + imgfile; + logger.info("Image RESOURCE FILE: " + imgAbsfile); + File file = new File(imgAbsfile); + try { + Path path = Paths.get(file.getAbsolutePath()); + // ByteArrayResource resource = new ByteArrayResource(Files.readAllBytes(path)); + HttpHeaders headers = new HttpHeaders(); + InputStream in = new FileInputStream(file); + + byte[] media = IOUtils.toByteArray(in); + headers.setCacheControl(CacheControl.noCache().getHeaderValue()); + headers.setContentType(MediaType.parseMediaType("image/jpeg;image/png")); + + ResponseEntity responseEntity = new ResponseEntity<>(media, headers, HttpStatus.OK); + return responseEntity; + + } catch (Exception e) { + logger.error("Couldn't serialize response ByteArrayResource", e); + return new ResponseEntity(HttpStatus.NOT_FOUND); + } + + } + + @GetMapping(value = "/packages/{uuid}/{vxffile:.+}") + public ResponseEntity downloadVxFPackage(@PathVariable("uuid") String uuid, + @PathVariable("vxffile") String vxffile) throws IOException { + + logger.info("vxffile: " + vxffile); + logger.info("uuid: " + uuid); + + String vxfAbsfile = METADATADIR + uuid + File.separator + vxffile; + logger.info("VxF RESOURCE FILE: " + vxfAbsfile); + File file = new File(vxfAbsfile); + + if ((uuid.equals("77777777-668b-4c75-99a9-39b24ed3d8be")) + || (uuid.equals("22cab8b8-668b-4c75-99a9-39b24ed3d8be"))) { + URL res = getClass().getResource("/files/" + vxffile); + logger.info("TEST LOCAL RESOURCE FILE: " + res); + file = new File(res.getFile()); + } + + Product avxf = productService.getProducttByUUID(uuid); +// PortalUser u = usersService.findByUsername( SecurityContextHolder.getContext().getAuthentication().getName() ); +// if ((u == null) && (!avxf.isPublished() )) { +// return (ResponseEntity) ResponseEntity.badRequest().build(); +// } + + Path path = Paths.get(file.getAbsolutePath()); + ByteArrayResource resource = new ByteArrayResource(Files.readAllBytes(path)); + + return ResponseEntity.ok().header("Content-Disposition", "attachment; filename=" + file.getName()) + .contentLength(file.length()).contentType(MediaType.parseMediaType("application/gzip")).body(resource); + +// ResponseBuilder response = (ResponseEntity).ok((Object) file); +// response.header("Content-Disposition", "attachment; filename=" + file.getName()); +// return response.build(); + } + + @DeleteMapping(value = "/admin/vxfs/{vxfid}", produces = "application/json") + public ResponseEntity deleteVxF(@PathVariable("vxfid") int vxfid, HttpServletRequest request) + throws ForbiddenException { + + // Object attr = request.getSession().getAttribute("SPRING_SECURITY_CONTEXT"); + // SecurityContextHolder.setContext((SecurityContext) attr); + + VxFMetadata vxf = (VxFMetadata) vxfService.getVxFById(vxfid); + + if (!checkUserIDorIsAdmin(vxf.getOwner().getId())) { + throw new ForbiddenException("The requested page is forbidden");// return (ResponseEntity) + // ResponseEntity.status(HttpStatus.FORBIDDEN); + } + // Get the OnBoarded Descriptors to OffBoard them + List vxfobds = vxf.getVxfOnBoardedDescriptors(); + if (vxf.isCertified()) { + return (ResponseEntity) ResponseEntity.badRequest() + .body("vxf with id=" + vxfid + " is Certified and will not be deleted"); + + } + if (vxfobds.size() > 0) { + for (VxFOnBoardedDescriptor vxfobd_tmp : vxfobds) { + if (vxfobd_tmp.getOnBoardingStatus() != OnBoardingStatus.ONBOARDED) { + // vxf.getVxfOnBoardedDescriptors().remove(vxfobd_tmp); + // vxfService.updateProductInfo(vxf); + // vxfobd_tmp.setObMANOprovider(null); + // vxfobd_tmp.setVxf(null); + // vxfOBDService.deleteVxFOnBoardedDescriptor(vxfobd_tmp); + continue; + } + OnBoardingStatus previous_status = vxfobd_tmp.getOnBoardingStatus(); + vxfobd_tmp.setOnBoardingStatus(OnBoardingStatus.OFFBOARDING); + centralLogger.log(CLevel.INFO, "Onboarding Status change of VxF " + vxfobd_tmp.getVxf().getName() + + " to " + vxfobd_tmp.getOnBoardingStatus(), compname); + + VxFOnBoardedDescriptor u = vxfOBDService.updateVxFOnBoardedDescriptor(vxfobd_tmp); + + ResponseEntity response = null; + try { + // response = aMANOController.offBoardVxFFromMANOProvider( vxfobd_tmp ); + response = busController.offBoardVxF(vxfobd_tmp); + logger.info("offBoard VxF response:" + response.toString()); + } catch (HttpClientErrorException e) { + logger.info("offBoard VxF exception:" + e.toString()); + logger.info("offBoard VxF exception response:" + response.toString()); +// vxfobd_tmp.setOnBoardingStatus(previous_status); +// centralLogger.log(CLevel.INFO, "Onboarding Status change of VxF " + vxfobd_tmp.getVxf().getName() +// + " to " + vxfobd_tmp.getOnBoardingStatus(), compname); +// vxfobd_tmp.setFeedbackMessage(e.getResponseBodyAsString()); +// u = vxfOBDService.updateVxFOnBoardedDescriptor(vxfobd_tmp); +// return ResponseEntity.status(e.getRawStatusCode()).headers(e.getResponseHeaders()) +// .body(e.getResponseBodyAsString()); + } + + if ((response.getStatusCode().is4xxClientError() || response.getStatusCode().is5xxServerError()) + && (!response.getStatusCode().equals(HttpStatus.NOT_FOUND))) // If response is 400like or + // 500like quit the deletion. + { + vxfobd_tmp.setOnBoardingStatus(previous_status); + vxfobd_tmp.setFeedbackMessage(response.getBody()); + u = vxfOBDService.updateVxFOnBoardedDescriptor(vxfobd_tmp); + return ResponseEntity.status(response.getStatusCode()).headers(response.getHeaders()) + .body(response.getBody()); + } else { + if (response.getBody() != null) { + vxfobd_tmp.setFeedbackMessage(response.getBody().toString()); + } else { + vxfobd_tmp.setFeedbackMessage(response.toString()); + } + } + // UnCertify Upon OffBoarding + // vxfobd_tmp.getVxf().setCertified(false); + vxfobd_tmp.setOnBoardingStatus(OnBoardingStatus.OFFBOARDED); + try { + centralLogger.log(CLevel.INFO, "Onboarding Status change of VxF " + vxfobd_tmp.getVxf().getName() + + " to " + vxfobd_tmp.getOnBoardingStatus(), compname); + } catch (Exception e) { + centralLogger.log(CLevel.INFO, "No related VxF found for " + vxfobd_tmp.getId() + " in status " + + vxfobd_tmp.getOnBoardingStatus(), compname); + } + u = vxfOBDService.updateVxFOnBoardedDescriptor(vxfobd_tmp); + // busController.offBoardVxFSucceded( u ); + } + } + busController.deletedVxF(vxf); + + // remove from categories + for (Category c : vxf.getCategories()) { + if (c.getProducts().contains(vxf)) { + c.getProducts().remove(vxf); + categoryService.updateCategoryInfo(c); + } + } + + vxf.getCategories().clear(); + + // remove from onboard descriptos + for (VxFOnBoardedDescriptor vxfobd_tmp : vxfobds) { + VxFOnBoardedDescriptor sm = vxfOBDService.getVxFOnBoardedDescriptorByID(vxfobd_tmp.getId()); + vxfOBDService.deleteVxFOnBoardedDescriptor(sm); + + } + vxf.getVxfOnBoardedDescriptors().clear(); + + // remove from constituent vxfs + // Get deployment descriptorvxfplacements. We need to get the deployment + // descriptors involved. + + PortalUser owner = usersService.findById(vxf.getOwner().getId()); + owner.getProducts().remove(vxf); + usersService.updateUserInfo(owner, false); + vxf.setOwner(null); + + // check also if deleted from consistuent VNFs + vxfService.deleteProduct(vxf); + return ResponseEntity.ok().body("{}"); + } + + @DeleteMapping(value = "/admin/vxfs/{vxfid}/softdelete", produces = "application/json") + public ResponseEntity softDeleteVxF(@PathVariable("vxfid") int vxfid, HttpServletRequest request) + throws ForbiddenException { + + + VxFMetadata vxf = (VxFMetadata) vxfService.getVxFById(vxfid); + + if (!checkUserIDorIsAdmin(vxf.getOwner().getId())) { + throw new ForbiddenException("The requested page is forbidden");// return (ResponseEntity) + // ResponseEntity.status(HttpStatus.FORBIDDEN); + } + // Get the OnBoarded Descriptors to OffBoard them + List vxfobds = vxf.getVxfOnBoardedDescriptors(); + if (vxf.isCertified()) { + return (ResponseEntity) ResponseEntity.badRequest() + .body("vxf with id=" + vxfid + " is Certified and will not be deleted"); + } + try + { + busController.deletedVxF(vxf); + // remove from categories + for (Category c : vxf.getCategories()) { + if (c.getProducts().contains(vxf)) { + c.getProducts().remove(vxf); + categoryService.updateCategoryInfo(c); + } + } + + vxf.getCategories().clear(); + + // remove from onboard descriptos + for (VxFOnBoardedDescriptor vxfobd_tmp : vxfobds) { + VxFOnBoardedDescriptor sm = vxfOBDService.getVxFOnBoardedDescriptorByID(vxfobd_tmp.getId()); + vxfOBDService.deleteVxFOnBoardedDescriptor(sm); + + } + vxf.getVxfOnBoardedDescriptors().clear(); + + PortalUser owner = usersService.findById(vxf.getOwner().getId()); + owner.getProducts().remove(vxf); + usersService.updateUserInfo(owner, false); + vxf.setOwner(null); + + // check also if deleted from consistuent VNFs + vxfService.deleteProduct(vxf); + } + catch(Exception e) + { + return (ResponseEntity) ResponseEntity.badRequest() + .body("vxf with id=" + vxfid + " could not be deleted. Please check for possible dependencies."); + } + return ResponseEntity.ok().body("{}"); + } + + + @GetMapping(value = "/vxfs/{vxfid}", produces = "application/json") + public ResponseEntity getVxFMetadataByID(@PathVariable("vxfid") int vxfid) throws ForbiddenException { + logger.info("getVxFMetadataByID vxfid=" + vxfid); + VxFMetadata vxf = (VxFMetadata) vxfService.getVxFById(vxfid); + + if (vxf != null) { + + if (!vxf.isPublished()) { + throw new ForbiddenException("The requested page is forbidden");// return (ResponseEntity) + // ResponseEntity.status(HttpStatus.FORBIDDEN); + } + + return ResponseEntity.ok(vxf); + } else { + return (ResponseEntity) ResponseEntity.badRequest() + .body("vxf with id=" + vxfid + " not found in portal registry"); + } + } + + @GetMapping(value = "/admin/vxfs/{vxfid}", produces = "application/json") + public ResponseEntity getAdminVxFMetadataByID(@PathVariable("vxfid") int vxfid) throws ForbiddenException { + + logger.info("getAdminVxFMetadataByID vxfid=" + vxfid); + VxFMetadata vxf = (VxFMetadata) vxfService.getVxFById(vxfid); + + if (vxf != null) { + + PortalUser u = usersService + .findByUsername(SecurityContextHolder.getContext().getAuthentication().getName()); + + if (!checkUserIDorIsAdmin(vxf.getOwner().getId()) + && !u.getRoles().contains(UserRoleType.ROLE_TESTBED_PROVIDER)) { + throw new ForbiddenException("The requested page is forbidden");// return (ResponseEntity) + // ResponseEntity.status(HttpStatus.FORBIDDEN); + } + + return ResponseEntity.ok(vxf); + } else { + return (ResponseEntity) ResponseEntity.badRequest() + .body("vxf with id=" + vxfid + " not found in portal registry"); + + } + } + + @GetMapping(value = "/vxfs/uuid/{uuid}", produces = "application/json") + public ResponseEntity getVxFMetadataByUUID(@PathVariable("uuid") String uuid, HttpServletRequest request) + throws ForbiddenException { + + logger.info("Received GET for vxf uuid: " + uuid); + VxFMetadata vxf = null; + + String endpointUrl = request.getRequestURI(); + if (uuid.equals("77777777-668b-4c75-99a9-39b24ed3d8be")) { + vxf = new VxFMetadata(); + vxf.setUuid(uuid); + vxf.setName("IntegrTestLocal example service"); + vxf.setShortDescription("An example local service"); + vxf.setVersion("1.0.0"); + vxf.setIconsrc(""); + vxf.setLongDescription(""); + + vxf.setPackageLocation(endpointUrl.toString().replace("http:", "") + + "/packages/77777777-668b-4c75-99a9-39b24ed3d8be/examplevxf.tar.gz"); + // }else if (uuid.equals("12cab8b8-668b-4c75-99a9-39b24ed3d8be")) { + // vxf = new VxFMetadata(uuid, "AN example service"); + // vxf.setShortDescription("An example local service"); + // vxf.setVersion("1.0.0rc1"); + // vxf.setIconsrc(""); + // vxf.setLongDescription(""); + // //URI endpointUrl = uri.getBaseUri(); + // + // vxf.setPackageLocation( endpointUrl + // +"repo/packages/12cab8b8-668b-4c75-99a9-39b24ed3d8be/examplevxf.tar.gz"); + } else if (uuid.equals("22cab8b8-668b-4c75-99a9-39b24ed3d8be")) { + vxf = new VxFMetadata(); + vxf.setUuid(uuid); + vxf.setName("IntegrTestLocal example ErrInstall service"); + vxf.setShortDescription("An example ErrInstall local service"); + vxf.setVersion("1.0.0"); + vxf.setIconsrc(""); + vxf.setLongDescription(""); + // URI endpointUrl = uri.getBaseUri(); + + vxf.setPackageLocation(endpointUrl.toString().replace("http:", "") + + "/packages/22cab8b8-668b-4c75-99a9-39b24ed3d8be/examplevxfErrInstall.tar.gz"); + } else { + vxf = (VxFMetadata) vxfService.getVxFByUUID(uuid); + } + + if (vxf != null) { + + if (!vxf.isPublished()) { + throw new ForbiddenException("The requested page is forbidden");// return (ResponseEntity) + // ResponseEntity.status(HttpStatus.FORBIDDEN); + } + + return ResponseEntity.ok(vxf); + } else { + return (ResponseEntity) ResponseEntity.badRequest() + .body("Installed vxf with uuid=" + uuid + " not found in local registry"); + + } + + } + + // Experiments related API + + @GetMapping(value = "/admin/experiments", produces = "application/json") + public ResponseEntity getApps(@RequestParam(name = "categoryid", required = false) Long categoryid, + HttpServletRequest request) { + + // Object attr = request.getSession().getAttribute("SPRING_SECURITY_CONTEXT"); + // SecurityContextHolder.setContext((SecurityContext) attr); + PortalUser u = usersService.findByUsername(SecurityContextHolder.getContext().getAuthentication().getName()); + + if (u != null) { + List apps; + + if (u.getRoles().contains(UserRoleType.ROLE_ADMIN)) { + apps = nsdService.getdNSDsByCategory(categoryid); + } else { + apps = nsdService.gedNSDsByUserID((long) u.getId()); + } + + return ResponseEntity.ok(apps); + + } else { + + return (ResponseEntity) ResponseEntity.notFound(); + } + + } + + @GetMapping(value = "/experiments", produces = "application/json") + public ResponseEntity getAllApps(@RequestParam(name = "categoryid", required = false) Long categoryid) { + + // + PortalUser u = usersService.findByUsername(SecurityContextHolder.getContext().getAuthentication().getName()); + + if (u != null) { + return getAllDeployableExperiments(); + } else { + + logger.info("getexperiments categoryid=" + categoryid); + List nsds = nsdService.getPublishedNSDsByCategory(categoryid); + return ResponseEntity.ok(nsds); + } + } + + /** + * @return all User's Valid experiments as well as all Public and Valid + * experiments + */ + @GetMapping(value = "/admin/experiments/deployable", produces = "application/json") + public ResponseEntity getAllDeployableExperiments() { + + // + PortalUser u = usersService.findByUsername(SecurityContextHolder.getContext().getAuthentication().getName()); + + if (u != null) { + List userexpr; + + if (u.getRoles().contains(UserRoleType.ROLE_ADMIN)) { + userexpr = nsdService.getdNSDsByCategory((long) -1); + } else { + userexpr = nsdService.gedNSDsByUserID((long) u.getId()); + } + + List deplExps = new ArrayList(userexpr); + List pubExps = new ArrayList( + nsdService.getPublishedNSDsByCategory((long) -1)); + List returnedExps = new ArrayList(); + for (ExperimentMetadata e : pubExps) { + + boolean found = false; + boolean onboarded = false; + for (ExperimentMetadata depl : deplExps) { + if (depl.getId() == e.getId()) { + found = true; + } + } + if (!found) { + deplExps.add(e);// add no duplicate public experiments + } + } + for (ExperimentMetadata depl : deplExps) { + // If it is not already included and it has been onboarded + if (depl.getExperimentOnBoardDescriptors().size() > 0) { + for (ExperimentOnBoardDescriptor eobd : depl.getExperimentOnBoardDescriptors()) { + if (eobd.getOnBoardingStatus() == OnBoardingStatus.ONBOARDED) { + returnedExps.add(depl); + } + } + } + } + +// for (Iterator iter = deplExps.listIterator(); iter.hasNext(); ) { //filter only valid +// ExperimentMetadata a = iter.next(); +// if ( !a.isValid() ) { +// iter.remove(); +// } +// } + + return ResponseEntity.ok(returnedExps); + + } else { + + return (ResponseEntity) ResponseEntity.notFound(); + } + } + + @PostMapping(value = "/admin/experimentobds/action", produces = "application/json") + public ResponseEntity postExperimentsOBDAction(@Valid @RequestBody String payload) { + + String ret = template.requestBody("jms:queue:ns.action.run", payload, String.class); + logger.info("Message Received from AMQ:" + ret); + // Get the response and Map object to ExperimentMetadata + ResponseEntity response = null; + logger.info("From ActiveMQ:" + ret.toString()); + // Map object to VxFOnBoardedDescriptor + JSONObject obj = new JSONObject(ret); + logger.info("Status Code of response:" + obj.get("statusCode")); + response = new ResponseEntity(obj.get("body").toString(), + HttpStatus.valueOf(obj.get("statusCode").toString())); + logger.info("Response from action " + response); + return response; + } + + /** + * @return all User's Valid experiments as well as all Public and Valid + * experiments + */ + @GetMapping(value = "/admin/experimentobds/deployable", produces = "application/json") + public ResponseEntity getAllDeployableExperimentsOBDs() { + + // + PortalUser u = usersService.findByUsername(SecurityContextHolder.getContext().getAuthentication().getName()); + + if (u != null) { + List userexpr; + + if (u.getRoles().contains(UserRoleType.ROLE_ADMIN)) { + userexpr = nsdService.getdNSDsByCategory((long) -1); + } else { + userexpr = nsdService.gedNSDsByUserID((long) u.getId()); + } + + List deplExps = new ArrayList(userexpr); + List pubExps = new ArrayList( + nsdService.getPublishedNSDsByCategory((long) -1)); + List returnedExpOBDs = new ArrayList(); + for (ExperimentMetadata e : pubExps) { + + boolean found = false; + boolean onboarded = false; + for (ExperimentMetadata depl : deplExps) { + if (depl.getId() == e.getId()) { + found = true; + } + } + if (!found) { + deplExps.add(e);// add no duplicate public experiments + } + } + for (ExperimentMetadata depl : deplExps) { + // If it is not already included and it has been onboarded + if (depl.getExperimentOnBoardDescriptors().size() > 0) { + for (ExperimentOnBoardDescriptor eobd : depl.getExperimentOnBoardDescriptors()) { + if (eobd.getOnBoardingStatus() == OnBoardingStatus.ONBOARDED) { + returnedExpOBDs.add(eobd); + } + } + } + } + +// for (Iterator iter = deplExps.listIterator(); iter.hasNext(); ) { //filter only valid +// ExperimentMetadata a = iter.next(); +// if ( !a.isValid() ) { +// iter.remove(); +// } +// } + + return ResponseEntity.ok(returnedExpOBDs); + + } else { + + return (ResponseEntity) ResponseEntity.notFound(); + } + } + + @GetMapping(value = "/experiments/{appid}", produces = "application/json") + public ResponseEntity getExperimentMetadataByID(@PathVariable("appid") int appid) throws ForbiddenException { + logger.info("getAppMetadataByID appid=" + appid); + ExperimentMetadata app = nsdService.getProductByID(appid); + + if (app != null) { + if (!app.isPublished()) { + throw new ForbiddenException("The requested page is forbidden"); + } + + return ResponseEntity.ok(app); + } else { + + return (ResponseEntity) ResponseEntity.notFound(); + } + } + + @GetMapping(value = "/admin/experiments/{appid}", produces = "application/json") + public ResponseEntity getAdminExperimentMetadataByID(@PathVariable("appid") int appid) + throws ForbiddenException { + + logger.info("getAppMetadataByID appid=" + appid); + ExperimentMetadata app = nsdService.getProductByID(appid); + + if (app != null) { + + if (!checkUserIDorIsAdmin(app.getOwner().getId())) { + throw new ForbiddenException("The requested page is forbidden");// return (ResponseEntity) + // ResponseEntity.status(HttpStatus.FORBIDDEN) + // ; + } + + return ResponseEntity.ok(app); + } else { + + return (ResponseEntity) ResponseEntity.notFound(); + } + } + + @GetMapping(value = "/experiments/uuid/{uuid}", produces = "application/json") + public ResponseEntity getAppMetadataByUUID(@PathVariable("uuid") String uuid) throws ForbiddenException { + logger.info("Received GET for app uuid: " + uuid); + + ExperimentMetadata app = nsdService.getdNSDByUUID(uuid); + + if (app != null) { + if (!app.isPublished()) { + throw new ForbiddenException("The requested page is forbidden");// return (ResponseEntity) + // ResponseEntity.status(HttpStatus.FORBIDDEN) + // ; + } + return ResponseEntity.ok(app); + } else { + + return (ResponseEntity) ResponseEntity.notFound(); + } + + } + + @PostMapping(value = "/admin/experiments", produces = "application/json", consumes = "multipart/form-data") + public ResponseEntity addExperimentMetadata(final @ModelAttribute("exprm") String exp, + @RequestParam(name = "prodIcon", required = false) MultipartFile prodIcon, + @RequestParam(name = "prodFile", required = false) MultipartFile prodFile, + @RequestParam(name = "screenshots", required = false) MultipartFile[] screenshots, + HttpServletRequest request) { + + ExperimentMetadata experiment = null; + + try { + experiment = objectMapper.readValue(exp, ExperimentMetadata.class); + } catch (JsonParseException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (JsonMappingException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + + // Object attr = request.getSession().getAttribute("SPRING_SECURITY_CONTEXT"); + // SecurityContextHolder.setContext((SecurityContext) attr); + PortalUser u = usersService.findByUsername(SecurityContextHolder.getContext().getAuthentication().getName()); + + if (u == null) { + + return (ResponseEntity) ResponseEntity.notFound(); + } + + String emsg = ""; + + ExperimentMetadata experimentSaved = null; + + try { + + logger.info("Received @POST for experiment : " + experiment.getName()); + + experimentSaved = (ExperimentMetadata) addNewProductData(experiment, prodIcon, prodFile, screenshots, + request); + + } catch (IOException e) { + experimentSaved = null; + e.printStackTrace(); + logger.error(e.getMessage()); + emsg = e.getMessage(); + } + + if (experimentSaved != null) { + + busController.newNSDAdded(experimentSaved); + busController.validateNSD(experimentSaved); + + // ====================================================== + // AUTOMATIC ONBOARDING PROCESS -START + // Need to select MANO Provider, convert vxfMetadata to VxFOnBoardedDescriptor + // and pass it as an input. + + // Get the MANO providers which are set for automatic onboarding + List MANOprovidersEnabledForOnboarding = manoProviderService + .getMANOprovidersEnabledForOnboarding(); + + for (MANOprovider mp : MANOprovidersEnabledForOnboarding) { + logger.info("check for ONBOARDING on " + mp.getName()); + logger.info("experimentSaved.getPackagingFormat().toString() = " + + experimentSaved.getPackagingFormat().toString()); + logger.info( + "mp.getSupportedMANOplatform().getVersion()) " + mp.getSupportedMANOplatform().getVersion()); + if (experimentSaved.getPackagingFormat().toString() + .equals(mp.getSupportedMANOplatform().getVersion())) { + // Create NSDOnboardDescriptor + ExperimentOnBoardDescriptor obd = new ExperimentOnBoardDescriptor(); + // Get the first one for now + obd.setObMANOprovider(mp); + obd.setUuid(UUID.randomUUID().toString()); + ExperimentMetadata refNSD = (ExperimentMetadata) nsdService.getProductByID(experimentSaved.getId()); + // Fill the NSDMetadata of NSDOnBoardedDescriptor + obd.setExperiment(refNSD); + // save VxFonBoardedDescriptor or not ??? + obd = nsdOBDService.updateExperimentOnBoardDescriptor(obd); + + // Update the NSDMetadata Object with the obd Object + refNSD.getExperimentOnBoardDescriptors().add(obd); + + // save product + refNSD = (ExperimentMetadata) nsdService.updateProductInfo(refNSD); + + // ***************************************************************************************************************************\ + // Because in portal.api.mano we need the url for the package location in order + // not to ask back, if the package locations + // does not contain http add the default maindomain value. + // We can either add it here or change that where the pLocation is set initially + // for the object. + // Get the location of the package + String pLocation = obd.getExperiment().getPackageLocation(); + logger.info("VxF Package Location: " + pLocation); + if (!pLocation.contains("http")) { + pLocation = propsService.getPropertyByName("maindomain").getValue() + pLocation; + obd.getExperiment().setPackageLocation(pLocation); + productService.updateProductInfo(obd.getExperiment()); + } + logger.info("PROPER VxF Package Location: " + pLocation); + // *************************************************************************************************************************** + + // Send the message for automatic onboarding + // busController.newNSDAdded( vxf ); + + // set proper scheme (http or https) + // MANOController.setHTTPSCHEME( request.getRequestURL().toString() ); + // busController.onBoardNSD( obd ); + try { + String[] fpath = obd.getExperiment().getPackageLocation().split("/"); + logger.info("uuid: " + fpath[fpath.length - 2]); + logger.info("Package: " + fpath[fpath.length - 1]); + String vxfAbsfile = METADATADIR + fpath[fpath.length - 2] + File.separator + + fpath[fpath.length - 1]; + File afile = new File(vxfAbsfile); + Path path = Paths.get(afile.getAbsolutePath()); +// ByteArrayResource resource = new ByteArrayResource(Files.readAllBytes(path)); +// busController.onBoardVxFAdded( vobd, afile, resource ); + + CompositeExperimentOnBoardDescriptor compositeobdobj = new CompositeExperimentOnBoardDescriptor(); + compositeobdobj.setFilename(afile.getName()); + compositeobdobj.setAllBytes(Files.readAllBytes(path)); + compositeobdobj.setObd(obd); + busController.onBoardNSDAddedByCompositeObj(compositeobdobj); + + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + } + + // AUTOMATIC ONBOARDING PROCESS -END + // ====================================================== + + ExperimentMetadata experimentr = (ExperimentMetadata) nsdService.getProductByID(experimentSaved.getId()); // rereading + // this, + // seems + // to + // keep + // the + // DB + // connection + + return ResponseEntity.ok(experimentr); + } else { + + return (ResponseEntity) ResponseEntity.badRequest().body("{ \"message\" : \"" + emsg + "\"}"); + } + + } + + @PutMapping(value = "/admin/experiments/{aid}", produces = "application/json", consumes = "multipart/form-data") + public ResponseEntity updateExperimentMetadata(@PathVariable("aid") int aid, + final @ModelAttribute("exprm") String ex, + @RequestParam(name = "prodIcon", required = false) MultipartFile prodIcon, + @RequestParam(name = "prodFile", required = false) MultipartFile prodFile, + @RequestParam(name = "screenshots", required = false) MultipartFile[] screenshots, + HttpServletRequest request) throws ForbiddenException { + + ExperimentMetadata expmeta = null; + try { + expmeta = objectMapper.readValue(ex, ExperimentMetadata.class); + } catch (JsonParseException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (JsonMappingException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + + String emsg = ""; + ExperimentMetadata expmetasaved = null; + try { + + if (!checkUserIDorIsAdmin(expmeta.getOwner().getId())) { + throw new ForbiddenException("The requested page is forbidden");// return (ResponseEntity) + // ResponseEntity.status(HttpStatus.FORBIDDEN) + // ; + } + + logger.info("Received @POST for experiment : " + expmeta.getName()); + // logger.info("Received @POST for app.containers : " + + // appmeta.getContainers().size()); + + expmetasaved = (ExperimentMetadata) updateProductMetadata(expmeta, prodIcon, prodFile, screenshots, + request); + + } catch (IOException e) { + expmetasaved = null; + e.printStackTrace(); + logger.error(e.getMessage()); + emsg = e.getMessage(); + } + + if (expmetasaved != null) { + + busController.updateNSD(expmetasaved); + + if (prodFile != null) { // if the descriptor changed then we must re-trigger validation + String a = prodFile.getName(); + if (!a.equals("unknown")) { + busController.validationUpdateNSD(expmetasaved); + } + } + + return ResponseEntity.ok(expmetasaved); + } else { + + return (ResponseEntity) ResponseEntity.badRequest().build(); + } + + } + + @DeleteMapping(value = "/admin/experiments/{appid}", produces = "application/json") + public ResponseEntity deleteExperiment(@PathVariable("appid") int appid, HttpServletRequest request) + throws ForbiddenException { + + // Object attr = request.getSession().getAttribute("SPRING_SECURITY_CONTEXT"); + // SecurityContextHolder.setContext((SecurityContext) attr); + + // Get the OnBoarded Descriptors to OffBoard them + Set expobds = null; + + ExperimentMetadata nsd = (ExperimentMetadata) nsdService.getProductByID(appid); + + if (!checkUserIDorIsAdmin(nsd.getOwner().getId())) { + throw new ForbiddenException("The requested page is forbidden");// return (ResponseEntity) + // ResponseEntity.status(HttpStatus.FORBIDDEN); + } + + // If the NSD is Valid exit + if (nsd.isValid()) { + return (ResponseEntity) ResponseEntity.badRequest() + .body("ExperimentMetadata with id=" + appid + " is Validated and will not be deleted"); + } + + try + { + expobds = nsd.getExperimentOnBoardDescriptors(); + } + catch(Exception e) + { + centralLogger.log(CLevel.INFO, "Unable to retrieve experiment onboard descriptors for NSD "+nsd.getUuid(), compname); + } + // If there are Experiment OnBoard Descriptors + if (expobds!=null && expobds.size() > 0) { + // Foreach Experiment OnBoard Descriptors + for (ExperimentOnBoardDescriptor expobd_tmp : expobds) { + if (expobd_tmp.getOnBoardingStatus() != OnBoardingStatus.ONBOARDED) { + continue; + } + OnBoardingStatus previous_status = expobd_tmp.getOnBoardingStatus(); + expobd_tmp.setOnBoardingStatus(OnBoardingStatus.OFFBOARDING); + centralLogger.log(CLevel.INFO, "Onboarding Status change of VxF " + expobd_tmp.getExperiment().getName() + + " to " + expobd_tmp.getOnBoardingStatus(), compname); + ExperimentOnBoardDescriptor u = nsdOBDService.updateExperimentOnBoardDescriptor(expobd_tmp); + + ResponseEntity response = null; + try { + // response = aMANOController.offBoardNSDFromMANOProvider( expobd_tmp ); + // Check response. If it not possible, quit the deletion. + response = busController.offBoardNSD(expobd_tmp); + logger.info("offBoard NSD response:" + response.toString()); + } catch (HttpStatusCodeException e) { + logger.info("offBoard NSD exception:" + e.toString()); + logger.info("offBoard NSD exception response:" + response.toString()); + //expobd_tmp.setOnBoardingStatus(previous_status); + //centralLogger.log(CLevel.INFO, "Boarding Status change of VxF " + // + expobd_tmp.getExperiment().getName() + " to " + expobd_tmp.getOnBoardingStatus(), + // compname); + //expobd_tmp.setFeedbackMessage(e.getResponseBodyAsString()); + //u = nsdOBDService.updateExperimentOnBoardDescriptor(expobd_tmp); + //return ResponseEntity.status(e.getRawStatusCode()).headers(e.getResponseHeaders()) + // .body(e.getResponseBodyAsString()); + } + // if the deletion fails with a 400like or 500like update the object. + if ((response.getStatusCode().is4xxClientError() || response.getStatusCode().is5xxServerError()) + && (!response.getStatusCode().equals(HttpStatus.NOT_FOUND))) // If response is 400like or + // 500like quit the deletion. + { + expobd_tmp.setOnBoardingStatus(previous_status); + expobd_tmp.setFeedbackMessage(response.getBody()); + u = nsdOBDService.updateExperimentOnBoardDescriptor(expobd_tmp); + return ResponseEntity.status(response.getStatusCode()).headers(response.getHeaders()) + .body(response.getBody()); + + } else { + if (response.getBody() != null) { + expobd_tmp.setFeedbackMessage(response.getBody().toString()); + } else { + expobd_tmp.setFeedbackMessage(response.toString()); + } + } + // UnCertify Upon OffBoarding + // vxfobd_tmp.getVxf().setCertified(false); + expobd_tmp.setOnBoardingStatus(OnBoardingStatus.OFFBOARDED); + try { + centralLogger.log(CLevel.INFO, "Onboarding Status change of NSD " + + expobd_tmp.getExperiment().getName() + " to " + expobd_tmp.getOnBoardingStatus(), + compname); + } catch (Exception e) { + centralLogger.log(CLevel.INFO, "No related NSD found for " + expobd_tmp.getId() + " in status " + + expobd_tmp.getOnBoardingStatus(), compname); + } + + u = nsdOBDService.updateExperimentOnBoardDescriptor(expobd_tmp); + // busController.offBoardNSDSucceded( u ); + } + } + else + { + centralLogger.log(CLevel.INFO, "No expobds found for "+nsd.getUuid(), compname); + } + busController.deletedExperiment(nsd); + + // Remove NS dependencies + for (DeploymentDescriptor d : deploymentDescriptorService.getDeploymentsByExperimentId(nsd.getId())) { + d.setExperiment(null); + // Clear VxFPlacement to be able to delete the related VxFs also after NSD + // deletion. + d.getVxfPlacements().clear(); + deploymentDescriptorService.updateDeploymentDescriptor(d); + } + // nsd.getDeploymentDescriptors().clear(); + + // Remove NSD from the categories + for (Category c : nsd.getCategories()) { + if (c.getProducts().contains(nsd)) { + c.getProducts().remove(nsd); + categoryService.updateCategoryInfo(c); + } + } + nsd.getCategories().clear(); + + // Remove NSD from OnBoarded descriptors + for (ExperimentOnBoardDescriptor expobd_tmp : expobds) { + ExperimentOnBoardDescriptor sm = nsdOBDService.getExperimentOnBoardDescriptorByID(expobd_tmp.getId()); + nsdOBDService.deleteExperimentOnBoardDescriptor(sm); + } + nsd.getExperimentOnBoardDescriptors().clear(); + + // Remove NSD from Portal Users + PortalUser owner = usersService.findById(nsd.getOwner().getId()); + owner.getProducts().remove(nsd); + usersService.updateUserInfo(owner, false); + nsd.setOwner(null); + + // Delete NSD from Products + nsdService.deleteProduct(nsd); + return ResponseEntity.ok().body("{}"); + } + + @DeleteMapping(value = "/admin/experiments/{appid}/softdelete", produces = "application/json") + public ResponseEntity softdeleteExperiment(@PathVariable("appid") int appid, HttpServletRequest request) + throws ForbiddenException { + + + // Get the OnBoarded Descriptors to OffBoard them + Set expobds = null; + + ExperimentMetadata nsd = (ExperimentMetadata) nsdService.getProductByID(appid); + + if (!checkUserIDorIsAdmin(nsd.getOwner().getId())) { + throw new ForbiddenException("The requested page is forbidden");// return (ResponseEntity) + // ResponseEntity.status(HttpStatus.FORBIDDEN); + } + + // If the NSD is Valid exit + if (nsd.isValid()) { + return (ResponseEntity) ResponseEntity.badRequest() + .body("ExperimentMetadata with id=" + appid + " is Validated and will not be deleted"); + } + + try + { + expobds = nsd.getExperimentOnBoardDescriptors(); + } + catch(Exception e) + { + centralLogger.log(CLevel.INFO, "Unable to retrieve experiment onboard descriptors for NSD "+nsd.getUuid(), compname); + } + + try + { + busController.deletedExperiment(nsd); + + // Remove NS dependencies + for (DeploymentDescriptor d : deploymentDescriptorService.getDeploymentsByExperimentId(nsd.getId())) { + d.setExperiment(null); + // Clear VxFPlacement to be able to delete the related VxFs also after NSD + // deletion. + d.getVxfPlacements().clear(); + deploymentDescriptorService.updateDeploymentDescriptor(d); + } + // nsd.getDeploymentDescriptors().clear(); + + // Remove NSD from the categories + for (Category c : nsd.getCategories()) { + if (c.getProducts().contains(nsd)) { + c.getProducts().remove(nsd); + categoryService.updateCategoryInfo(c); + } + } + nsd.getCategories().clear(); + + // Remove NSD from OnBoarded descriptors + for (ExperimentOnBoardDescriptor expobd_tmp : expobds) { + ExperimentOnBoardDescriptor sm = nsdOBDService.getExperimentOnBoardDescriptorByID(expobd_tmp.getId()); + nsdOBDService.deleteExperimentOnBoardDescriptor(sm); + } + nsd.getExperimentOnBoardDescriptors().clear(); + + // Remove NSD from Portal Users + PortalUser owner = usersService.findById(nsd.getOwner().getId()); + owner.getProducts().remove(nsd); + usersService.updateUserInfo(owner, false); + nsd.setOwner(null); + + // Delete NSD from Products + nsdService.deleteProduct(nsd); + } + catch(Exception e) + { + return (ResponseEntity) ResponseEntity.badRequest() + .body("ExperimentMetadata with id=" + appid + " could not be deleted. Please check for possible dependencies."); + } + return ResponseEntity.ok().body("{}"); + } + + @GetMapping(value = "/admin/properties", produces = "application/json") + public ResponseEntity getProperties() throws ForbiddenException { + + if (!checkUserIDorIsAdmin(-1)) { + throw new ForbiddenException("The requested page is forbidden");// return (ResponseEntity) + // ResponseEntity.status(HttpStatus.FORBIDDEN) + // ; + } + + List props = propsService.getProperties(); + for (PortalProperty portalProperty : props) { + if (portalProperty.getName().equals("mailpassword")) { + portalProperty.setValue("***"); + } + } + return ResponseEntity.ok(props); + } + + @PutMapping(value = "/admin/properties/{propid}", produces = "application/json", consumes = "application/json") + public ResponseEntity updateProperty(@PathVariable("propid") long propid, @Valid @RequestBody PortalProperty p) + throws ForbiddenException { + + if (!checkUserIDorIsAdmin(-1)) { + throw new ForbiddenException("The requested page is forbidden");// return (ResponseEntity) + // ResponseEntity.status(HttpStatus.FORBIDDEN) + // ; + } + + PortalProperty previousProperty = propsService.getPropertyByID(propid); + + PortalProperty u = propsService.updateProperty(p); + if (u != null) { + + sendPropertiesToBus(); + + return ResponseEntity.ok(u); + } else { + + return (ResponseEntity) ResponseEntity.badRequest().build(); + } + + } + + @GetMapping(value = "/admin/properties/{propid}", produces = "application/json") + public ResponseEntity getPropertyById(@PathVariable("propid") long propid) throws ForbiddenException { + + if (!checkUserIDorIsAdmin(-1)) { + throw new ForbiddenException("The requested page is forbidden");// return (ResponseEntity) + // ResponseEntity.status(HttpStatus.FORBIDDEN) + // ; + } + PortalProperty sm = propsService.getPropertyByID(propid); + + if (sm.getName().equals("mailpassword")) { + sm.setValue(""); + } + if (sm != null) { + return ResponseEntity.ok(sm); + } else { + + return (ResponseEntity) ResponseEntity.notFound(); + } + } + + @GetMapping(value = "/admin/deployments", produces = "application/json") + public ResponseEntity getAllDeployments(@RequestParam(name = "status", required = false) String status) { + + PortalUser u = usersService.findByUsername(SecurityContextHolder.getContext().getAuthentication().getName()); + if (u != null) { + logger.info("getAllDeployments for userid: " + u.getId()); + List deployments; + if ((u.getRoles().contains(UserRoleType.ROLE_ADMIN))) { + if ((status != null) && status.equals("COMPLETED")) { + deployments = deploymentDescriptorService.getAllCompletedDeploymentDescriptors(); + } else if ((status != null) && status.equals("REJECTED")) { + deployments = deploymentDescriptorService.getAllRejectedDeploymentDescriptors(); + } else if ((status != null) && status.equals("FAILED")) { + deployments = deploymentDescriptorService.getAllFailedDeploymentDescriptors(); + } else if ((status != null) && status.equals("FAILED_OSM_REMOVED")) { + deployments = deploymentDescriptorService.getAllRemovedDeploymentDescriptors(); + } else { + deployments = deploymentDescriptorService.getAllDeploymentDescriptors(); + } + } else if ((u.getRoles().contains(UserRoleType.ROLE_MENTOR))) { + if ((status != null) && status.equals("COMPLETED")) { + deployments = deploymentDescriptorService.getAllDeploymentDescriptorsByMentor((long) u.getId(), + "COMPLETED"); + } else if ((status != null) && status.equals("REJECTED")) { + deployments = deploymentDescriptorService.getAllDeploymentDescriptorsByMentor((long) u.getId(), + "REJECTED"); + } else if ((status != null) && status.equals("FAILED")) { + deployments = deploymentDescriptorService.getAllDeploymentDescriptorsByMentor((long) u.getId(), + "FAILED"); + } else if ((status != null) && status.equals("FAILED_OSM_REMOVED")) { + deployments = deploymentDescriptorService.getAllDeploymentDescriptorsByMentor((long) u.getId(), + "FAILED_OSM_REMOVED"); + } else { + deployments = deploymentDescriptorService.getAllDeploymentDescriptorsByMentor((long) u.getId(), + null); + } + } else { + + if ((status != null) && status.equals("COMPLETED")) { + deployments = deploymentDescriptorService.getAllDeploymentDescriptorsByUser((long) u.getId(), + "COMPLETED"); + } else if ((status != null) && status.equals("REJECTED")) { + deployments = deploymentDescriptorService.getAllDeploymentDescriptorsByUser((long) u.getId(), + "REJECTED"); + } else if ((status != null) && status.equals("FAILED")) { + deployments = deploymentDescriptorService.getAllDeploymentDescriptorsByUser((long) u.getId(), + "FAILED"); + } else if ((status != null) && status.equals("FAILED_OSM_REMOVED")) { + deployments = deploymentDescriptorService.getAllDeploymentDescriptorsByUser((long) u.getId(), + "FAILED_OSM_REMOVED"); + } else { + deployments = deploymentDescriptorService.getAllDeploymentDescriptorsByUser((long) u.getId(), null); + } + } + + return ResponseEntity.ok(deployments); + } else { + + return ResponseEntity.notFound().build(); + } + + } + +// @GET +// @Path("/admin/deployments/user") +// @Produces("application/json") +// public Response getAllDeploymentsofUser() { +// +// PortalUser u = portalRepositoryRef.getUserBySessionID(ws.getHttpServletRequest().getSession().getId()); +// +// if (u != null) { +// logger.info("getAllDeploymentsofUser for userid: " + u.getId()); +// List deployments; +// deployments = portalRepositoryRef.getAllDeploymentDescriptorsByUser( (long) u.getId() ); +// +// return Response.ok().entity(deployments).build(); +// } else { +// ResponseBuilder builder = Response.status(Status.NOT_FOUND); +// builder.entity("User not found in portal registry or not logged in"); +// throw new WebApplicationException(builder.build()); +// } +// +// } + + @GetMapping(value = "/admin/deployments/user", produces = "application/json") + public ResponseEntity getAllDeploymentsofUser(@RequestParam(name = "status", required = false) String status) { + + PortalUser u = usersService.findByUsername(SecurityContextHolder.getContext().getAuthentication().getName()); + + if (u != null) { + logger.info("getAllDeploymentsofUser for userid: " + u.getId()); + List deployments = new ArrayList(); + + if ((status != null) && status.equals("COMPLETED")) { + deployments = deploymentDescriptorService.getAllDeploymentDescriptorsByUser((long) u.getId(), + "COMPLETED"); + } else if ((status != null) && status.equals("REJECTED")) { + deployments = deploymentDescriptorService.getAllDeploymentDescriptorsByUser((long) u.getId(), + "REJECTED"); + } else if ((status != null) && status.equals("FAILED")) { + deployments = deploymentDescriptorService.getAllDeploymentDescriptorsByUser((long) u.getId(), "FAILED"); + } else if ((status != null) && status.equals("FAILED_OSM_REMOVED")) { + deployments = deploymentDescriptorService.getAllDeploymentDescriptorsByUser((long) u.getId(), + "FAILED_OSM_REMOVED"); + } else { + deployments = deploymentDescriptorService.getAllDeploymentDescriptorsByUser((long) u.getId(), null); + } + + return ResponseEntity.ok(deployments); + } else { + + return (ResponseEntity) ResponseEntity.notFound(); + } + + } + + @GetMapping(value = "/admin/deployments/scheduled", produces = "application/json") + public ResponseEntity getAllScheduledDeploymentsofUser() { + + PortalUser u = usersService.findByUsername(SecurityContextHolder.getContext().getAuthentication().getName()); + + if (u != null) { + logger.info("getAllDeploymentsofUser for userid: " + u.getId()); + List deployments; + + if ((u.getRoles().contains(UserRoleType.ROLE_ADMIN)) + || (u.getRoles().contains(UserRoleType.ROLE_TESTBED_PROVIDER))) { + deployments = deploymentDescriptorService.getAllDeploymentDescriptorsScheduled(); + } else { + deployments = deploymentDescriptorService.getAllDeploymentDescriptorsByUser((long) u.getId(), null); + } + + return ResponseEntity.ok(deployments); + } else { + return (ResponseEntity) ResponseEntity.notFound(); + + } + + } + + @PostMapping(value = "/admin/deployments", produces = "application/json", consumes = "application/json") + public ResponseEntity addDeployment(@Valid @RequestBody DeploymentDescriptor deployment, + HttpServletRequest request) { + + logger.info("AddDeployment request received:" + deployment.toJSON()); + + PortalUser u = usersService.findByUsername(SecurityContextHolder.getContext().getAuthentication().getName()); + + if (u != null) { + logger.info("addDeployment for userid: " + u.getId()); + +// for (DeploymentDescriptor d : u.getDeployments()) { +// logger.info("deployment already for userid: " + d.getId()); +// } + String uuid = deployment.getExperimentFullDetails().getUuid(); + deployment.setUuid(uuid); + deployment.setDateCreated(new Date()); + deployment.setStatus(DeploymentDescriptorStatus.UNDER_REVIEW); + centralLogger.log(CLevel.INFO, + "Status change of deployment " + deployment.getName() + " to " + deployment.getStatus(), compname); + logger.info("Status change of deployment " + deployment.getName() + " to " + deployment.getStatus()); + + logger.info("reattach user from the DB model"); + u = usersService.findById(u.getId()); + deployment.setOwner(u); // reattach from the DB model + + logger.info("reattach ExperimentMetadata from the DB model"); + // Get the Experiment Metadata from the id of the experiment from the deployment + // request + ExperimentMetadata baseApplication = (ExperimentMetadata) nsdService + .getProductByID(deployment.getExperiment().getId()); + deployment.setExperiment(baseApplication); // reattach from the DB model + + logger.info("reattach InfrastructureForAll from the DB model"); + deployment.setInfrastructureForAll(infrastructureService.getInfrastructureByID(deployment.getInfrastructureForAll().getId())); + + logger.info("deployment.getExperimentFullDetails().getUuid():"+deployment.getExperimentFullDetails().getExperimentOnBoardDescriptors().toArray(new ExperimentOnBoardDescriptor[deployment.getExperimentFullDetails().getExperimentOnBoardDescriptors().size()])[0].getDeployId()); + ExperimentOnBoardDescriptor tmp = nsdOBDService.getExperimentOnBoardedDescriptorByUUid(deployment.getExperimentFullDetails().getExperimentOnBoardDescriptors().toArray(new ExperimentOnBoardDescriptor[deployment.getExperimentFullDetails().getExperimentOnBoardDescriptors().size()])[0].getDeployId()); + logger.info("Fetched ExperimentOnBoardDescriptor with Deployid:"+tmp.getDeployId()+" and "+tmp.getId()); + deployment.setObddescriptor_uuid(tmp); + + logger.info("reattach Mentor from the DB model"); + deployment.setMentor(usersService.findById(deployment.getMentor().getId())); + + logger.info("reattach DeploymentDescriptorVxFPlacement from the DB model"); + for (DeploymentDescriptorVxFPlacement pl : deployment.getVxfPlacements()) { + Infrastructure infr = infrastructureService.getInfrastructureByID(pl.getInfrastructure().getId()); + pl.setInfrastructure(infr); + VxFMetadata vv = vxfOBDService.getVxFIdByVxFMANOProviderIDAndMP(pl.getConstituentVxF().getVnfdidRef(),infr.getMp().getId()); + pl.getConstituentVxF().setVxfref(vv); + + } + + logger.info("update deployment to the DB model"); + DeploymentDescriptor deploymentSaved = deploymentDescriptorService.updateDeploymentDescriptor(deployment); + + logger.info("update user owner to the DB model"); + u.getDeployments().add(deploymentSaved); + usersService.updateUserInfo(u, false); + + logger.info("NS status change is now " + deploymentSaved.getStatus()); + + //u = portalRepositoryRef.updateUserInfo(u); + //deployment = portalRepositoryRef.getDeploymentByUUID( deployment.getUuid() );//reattach from model + + //busController.newDeploymentRequest(deploymentSaved); + + //String adminemail = PortalRepository.getPropertyByName("adminEmail").getValue(); + //if ((adminemail != null) && (!adminemail.equals(""))) { + // String subj = "[5GinFIREPortal] New Deployment Request"; + // EmailUtil.SendRegistrationActivationEmail(adminemail, + // "5GinFIREPortal New Deployment Request by user : " + u.getUsername() + ", " + u.getEmail()+ "\n
Status: " + deployment.getStatus().name()+ "\n
Description: " + deployment.getDescription() , + // subj); + //} + + return ResponseEntity.ok(deploymentSaved); + } else { + return (ResponseEntity) ResponseEntity.notFound(); + } + } + + @DeleteMapping(value = "/admin/deployments/{id}", produces = "application/json") + public ResponseEntity deleteDeployment(@PathVariable("id") int id) { + PortalUser u = usersService.findByUsername(SecurityContextHolder.getContext().getAuthentication().getName()); + + DeploymentDescriptor dep = deploymentDescriptorService.getDeploymentByID(id); + if (u != null) { + if (u.getRoles().contains(UserRoleType.ROLE_ADMIN) || u.getId() == dep.getOwner().getId()) { + logger.info("deleteDeployment: Owner matches user for Deployment" + dep.getId()); + PortalUser owner = usersService.findById(dep.getOwner().getId()); + owner.getDeployments().remove(dep); + usersService.updateUserInfo(owner, false); + deploymentDescriptorService.deleteDeployment(dep); + return ResponseEntity.ok("{}"); + } + } + + return (ResponseEntity) ResponseEntity.notFound(); + } + + public void stripDeployment(int id) { + PortalUser u = usersService.findByUsername(SecurityContextHolder.getContext().getAuthentication().getName()); + + DeploymentDescriptor dep = deploymentDescriptorService.getDeploymentByID(id); + if (u != null) { + if (u.getRoles().contains(UserRoleType.ROLE_ADMIN) || u.getId() == dep.getOwner().getId()) { + logger.info("deleteDeployment: Owner matches user for Deployment" + dep.getId()); + PortalUser owner = usersService.findById(dep.getOwner().getId()); + owner.getDeployments().remove(dep); + usersService.updateUserInfo(owner, false); + // Get dependent records and delete them but keep the final record + + } + } + } + + @GetMapping(value = "/admin/deployments/{id}", produces = "application/json") + public ResponseEntity getDeploymentById(@PathVariable("id") long deploymentId) { + + PortalUser u = usersService.findByUsername(SecurityContextHolder.getContext().getAuthentication().getName()); + + if (u != null) { + logger.info("getDeploymentById for id: " + deploymentId); + DeploymentDescriptor deployment = null; + try { + deployment = deploymentDescriptorService.getDeploymentByID(deploymentId); + } catch (Exception e) { + logger.error(e.getMessage()); + } + logger.info("got Deployment for id: " + deployment.getId() + " with mentor id: " + + deployment.getMentor().getId() + " with owner id: " + deployment.getOwner().getId()); + logger.info("u.getId() is:" + u.getId()); + if ((u.getRoles().contains(UserRoleType.ROLE_ADMIN)) || (deployment.getMentor().getId() == u.getId()) + || (deployment.getOwner().getId() == u.getId())) { + + return ResponseEntity.ok(deployment); + } + } + + return (ResponseEntity) ResponseEntity.notFound(); + + } + + @Autowired + private SessionFactory sessionFactory; + + @PutMapping(value = "/admin/deployments/{id}", produces = "application/json", consumes = "application/json") + @Transactional + public ResponseEntity updateDeployment(@PathVariable("id") int id, + @Valid @RequestBody DeploymentDescriptor receivedDeployment) { + // Open a new session and begin a transaction + Session session = sessionFactory.openSession(); + Transaction transaction = session.beginTransaction(); + + try { + PortalUser u = usersService.findByUsername(SecurityContextHolder.getContext().getAuthentication().getName()); + + if ((u != null)) { + + if ((u.getRoles().contains(UserRoleType.ROLE_ADMIN)) + || u.getApikey().equals(receivedDeployment.getMentor().getApikey())) // only admin or Deployment + // Mentor can alter a + // deployment + { + DeploymentDescriptor aDeployment = deploymentDescriptorService + .getDeploymentByID(receivedDeployment.getId()); + + aDeployment.setName(receivedDeployment.getName()); + aDeployment.setFeedback(receivedDeployment.getFeedback()); + aDeployment.setStartDate(receivedDeployment.getStartDate()); + aDeployment.setEndDate(receivedDeployment.getEndDate()); + + logger.info("Previous Status is :" + aDeployment.getStatus() + ",New Status is:" + + receivedDeployment.getStatus() + " and Instance Id is " + aDeployment.getInstanceId()); + + if (receivedDeployment.getStatus() != aDeployment.getStatus()) { + aDeployment.setStatus(receivedDeployment.getStatus()); + centralLogger.log(CLevel.INFO, + "Status change of deployment " + aDeployment.getName() + " to " + aDeployment.getStatus(), + compname); + logger.info( + "Status change of deployment " + aDeployment.getName() + " to " + aDeployment.getStatus()); + aDeployment.getExperimentFullDetails(); + aDeployment.getInfrastructureForAll(); + + logger.info("updateDeployment for id: " + aDeployment.getId()); + + if (receivedDeployment.getStatus() == DeploymentDescriptorStatus.SCHEDULED + && aDeployment.getInstanceId() == null) { + for (ExperimentOnBoardDescriptor tmpExperimentOnBoardDescriptor : aDeployment.getExperimentFullDetails() + .getExperimentOnBoardDescriptors()) { + aDeployment.setStatus(receivedDeployment.getStatus()); + centralLogger.log(CLevel.INFO, "Status change of deployment " + aDeployment.getName() + + " to " + aDeployment.getStatus(), compname); + logger.info("Status change of deployment " + aDeployment.getName() + " to " + + aDeployment.getStatus()); + aDeployment = deploymentDescriptorService.updateDeploymentDescriptor(aDeployment); + logger.info("NS status change is now " + aDeployment.getStatus()); + aDeployment = deploymentDescriptorService.getDeploymentByIdEager( aDeployment.getId() ); + busController.scheduleExperiment(aDeployment); + } + } else if (receivedDeployment.getStatus() == DeploymentDescriptorStatus.RUNNING + && aDeployment.getInstanceId() == null) { + for (ExperimentOnBoardDescriptor tmpExperimentOnBoardDescriptor : aDeployment.getExperimentFullDetails() + .getExperimentOnBoardDescriptors()) { + aDeployment.setStatus(receivedDeployment.getStatus()); + centralLogger.log(CLevel.INFO, "Status change of deployment " + aDeployment.getName() + + " to " + aDeployment.getStatus(), compname); + logger.info("Status change of deployment " + aDeployment.getName() + " to " + + aDeployment.getStatus()); + aDeployment = deploymentDescriptorService.updateDeploymentDescriptor(aDeployment); + logger.info("NS status change is now " + aDeployment.getStatus()); + + busController.deployExperiment(aDeployment); + } + } else if (receivedDeployment.getStatus() == DeploymentDescriptorStatus.COMPLETED + && aDeployment.getInstanceId() != null) { + aDeployment.setStatus(receivedDeployment.getStatus()); + centralLogger.log(CLevel.INFO, "Status change of deployment " + aDeployment.getName() + " to " + + aDeployment.getStatus(), compname); + logger.info("Status change of deployment " + aDeployment.getName() + " to " + + aDeployment.getStatus()); + aDeployment = deploymentDescriptorService.updateDeploymentDescriptor(aDeployment); + logger.info("NS status change is now " + aDeployment.getStatus()); + busController.completeExperiment(aDeployment); + } else if (receivedDeployment.getStatus() == DeploymentDescriptorStatus.REJECTED + && aDeployment.getInstanceId() == null) { + aDeployment.setStatus(receivedDeployment.getStatus()); + centralLogger.log(CLevel.INFO, "Status change of deployment " + aDeployment.getName() + " to " + + aDeployment.getStatus(), compname); + logger.info("Status change of deployment " + aDeployment.getName() + " to " + + aDeployment.getStatus()); + aDeployment = deploymentDescriptorService.updateDeploymentDescriptor(aDeployment); + logger.info("NS status change is now " + aDeployment.getStatus()); + busController.rejectExperiment(aDeployment); + logger.info("Deployment Rejected"); + } else { + return (ResponseEntity) ResponseEntity.badRequest().body("Inconsistent status change"); + } + } else { + + logger.info("Previous status is the same so just update deployment info"); + aDeployment = deploymentDescriptorService.updateDeploymentDescriptor(aDeployment); + aDeployment = deploymentDescriptorService.getDeploymentByIdEager( aDeployment.getId() ); + busController.updateDeploymentRequest(aDeployment); + } + transaction.commit(); + + // Return the response + return ResponseEntity.ok(aDeployment); + } + + } + } catch (Exception e) { + // If an exception is thrown, rollback the transaction + if (transaction != null && transaction.isActive()) { + transaction.rollback(); + } + // Log the exception (optional) + logger.error("Error updating deployment", e); + // Return an error response + return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(e.getMessage()); + } finally { + // Close the session + if (session != null && session.isOpen()) { + session.close(); + } + } + return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("Request failed"); + } + + /******************************************************************************** + * + * admin MANO platforms + * + ********************************************************************************/ + + @GetMapping(value = "/manoplatforms", produces = "application/json") + public ResponseEntity getMANOplatforms() { + return ResponseEntity.ok(manoPlatformService.getMANOplatforms()); + } + + @GetMapping(value = "/admin/manoplatforms", produces = "application/json") + public ResponseEntity getAdminMANOplatforms() throws ForbiddenException { + + if (!checkUserIDorIsAdmin(-1)) { + throw new ForbiddenException("The requested page is forbidden");// return (ResponseEntity) + // ResponseEntity.status(HttpStatus.FORBIDDEN) + // ; + } + return ResponseEntity.ok(manoPlatformService.getMANOplatforms()); + } + + @PostMapping(value = "/admin/manoplatforms", produces = "application/json", consumes = "application/json") + public ResponseEntity addMANOplatform(@Valid @RequestBody MANOplatform c) throws ForbiddenException { + + if (!checkUserIDorIsAdmin(-1)) { + throw new ForbiddenException("The requested page is forbidden");// return (ResponseEntity) + // ResponseEntity.status(HttpStatus.FORBIDDEN) + // ; + } + + MANOplatform u = manoPlatformService.addMANOplatform(c); + + if (u != null) { + return ResponseEntity.ok(u); + } else { + + return (ResponseEntity) ResponseEntity.badRequest().build(); + } + } + + @PutMapping(value = "/admin/manoplatforms/{mpid}", produces = "application/json", consumes = "application/json") + public ResponseEntity updateMANOplatform(@PathVariable("mpid") int mpid, @Valid @RequestBody MANOplatform c) + throws ForbiddenException { + + if (!checkUserIDorIsAdmin(-1)) { + throw new ForbiddenException("The requested page is forbidden");// return (ResponseEntity) + // ResponseEntity.status(HttpStatus.FORBIDDEN) + // ; + } + MANOplatform previousMP = manoPlatformService.getMANOplatformByID(mpid); + + previousMP.setDescription(c.getDescription()); + previousMP.setName(c.getName()); + previousMP.setVersion(c.getVersion()); + + MANOplatform u = manoPlatformService.updateMANOplatformInfo(previousMP); + + if (u != null) { + return ResponseEntity.ok(u); + } else { + + return (ResponseEntity) ResponseEntity.badRequest().build(); + } + + } + + @DeleteMapping(value = "/admin/manoplatforms/{mpid}", produces = "application/json") + public ResponseEntity deleteMANOplatform(@PathVariable("mpid") int mpid) throws ForbiddenException { + + if (!checkUserIDorIsAdmin(-1)) { + throw new ForbiddenException("The requested page is forbidden");// return (ResponseEntity) + // ResponseEntity.status(HttpStatus.FORBIDDEN) + // ; + } + MANOplatform m = manoPlatformService.getMANOplatformByID(mpid); + + manoPlatformService.deleteMANOplatform(m); + return ResponseEntity.ok("{}"); + + } + + @GetMapping(value = "/manoplatforms/{mpid}", produces = "application/json") + public ResponseEntity getMANOplatformById(@PathVariable("mpid") int mpid) throws ForbiddenException { + + if (!checkUserIDorIsAdmin(-1)) { + throw new ForbiddenException("The requested page is forbidden");// return (ResponseEntity) + // ResponseEntity.status(HttpStatus.FORBIDDEN) + // ; + } + MANOplatform sm = manoPlatformService.getMANOplatformByID(mpid); + + if (sm != null) { + return ResponseEntity.ok(sm); + } else { + + return (ResponseEntity) ResponseEntity.notFound(); + } + } + + @GetMapping(value = "/admin/manoplatforms/{mpid}", produces = "application/json") + public ResponseEntity getAdminMANOplatformById(@PathVariable("mpid") int mpid) throws ForbiddenException { + return getMANOplatformById(mpid); + } + + /******************************************************************************** + * + * admin MANO providers + * + ********************************************************************************/ + + /** + * @return + * @throws ForbiddenException + */ + @GetMapping(value = "/admin/manoproviders", produces = "application/json") + public ResponseEntity getAdminMANOproviders() throws ForbiddenException { + + if (!checkUserIDorIsAdmin(-1)) { + throw new ForbiddenException("The requested page is forbidden");// return (ResponseEntity) + // ResponseEntity.status(HttpStatus.FORBIDDEN); + } + + return ResponseEntity.ok(manoProviderService.getMANOproviders()); + } + + @PostMapping(value = "/admin/manoproviders", produces = "application/json", consumes = "application/json") + public ResponseEntity addMANOprovider(@Valid @RequestBody MANOprovider c) throws ForbiddenException { + + if (!checkUserIDorIsAdmin(-1)) { + throw new ForbiddenException("The requested page is forbidden");// return (ResponseEntity) + // ResponseEntity.status(HttpStatus.FORBIDDEN) + // ; + } + + c.setSupportedMANOplatform(manoPlatformService.getMANOplatformByID(c.getSupportedMANOplatform().getId())); // to + // properly + // attach + // from + // the + // model + MANOprovider u = manoProviderService.addMANOprovider(c); + + if (u != null) { + return ResponseEntity.ok(u); + } else { + + return (ResponseEntity) ResponseEntity.badRequest().build(); + } + } + + @PutMapping(value = "/admin/manoproviders/{mpid}", produces = "application/json", consumes = "application/json") + public ResponseEntity updateMANOprovider(@PathVariable("mpid") int mpid, @Valid @RequestBody MANOprovider c) + throws ForbiddenException { + + if (!checkUserIDorIsAdmin(-1)) { + throw new ForbiddenException("The requested page is forbidden");// return (ResponseEntity) + // ResponseEntity.status(HttpStatus.FORBIDDEN) + // ; + } + + MANOprovider prev = manoProviderService.getMANOproviderByID(c.getId()); + prev.setApiEndpoint(c.getApiEndpoint()); + prev.setAuthorizationBasicHeader(c.getAuthorizationBasicHeader()); + prev.setDescription(c.getDescription()); + prev.setName(c.getName()); + prev.setSupportedMANOplatform(c.getSupportedMANOplatform()); + prev.setVims(c.getVims()); + + MANOprovider u = manoProviderService.updateMANOproviderInfo(c); + + if (u != null) { + return ResponseEntity.ok(u); + } else { + + return (ResponseEntity) ResponseEntity.badRequest().build(); + } + + } + + @DeleteMapping(value = "/admin/manoproviders/{mpid}", produces = "application/json") + public ResponseEntity deleteMANOprovider(@PathVariable("mpid") int mpid) throws ForbiddenException { + + if (!checkUserIDorIsAdmin(-1)) { + throw new ForbiddenException("The requested page is forbidden");// return (ResponseEntity) + // ResponseEntity.status(HttpStatus.FORBIDDEN) + // ; + } + + MANOprovider prev = manoProviderService.getMANOproviderByID(mpid); + + manoProviderService.deleteMANOprovider(prev); + return ResponseEntity.ok("{}"); + + } + + @GetMapping(value = "/admin/manoproviders/{mpid}", produces = "application/json") + public ResponseEntity getAdminMANOproviderById(@PathVariable("mpid") int mpid) throws ForbiddenException { + + if (!checkUserIDorIsAdmin(-1)) { + throw new ForbiddenException("The requested page is forbidden");// return (ResponseEntity) + // ResponseEntity.status(HttpStatus.FORBIDDEN) + // ; + } + MANOprovider sm = manoProviderService.getMANOproviderByID(mpid); + + if (sm != null) { + return ResponseEntity.ok(sm); + } else { + + return (ResponseEntity) ResponseEntity.notFound(); + } + } + + /******************************************************************************** + * + * admin VxFOnBoardedDescriptors + * + ********************************************************************************/ + + @GetMapping(value = "/admin/vxfobds", produces = "application/json") + public ResponseEntity getVxFOnBoardedDescriptors() { + return ResponseEntity.ok(vxfOBDService.getVxFOnBoardedDescriptors()); + } + + @PostMapping(value = "/admin/vxfobds/", produces = "application/json", consumes = "application/json") + public ResponseEntity addVxFOnBoardedDescriptor(@Valid @RequestBody VxFMetadata aVxF) throws ForbiddenException { + + if (!checkUserIDorIsAdmin(-1)) { + throw new ForbiddenException("The requested page is forbidden");// return (ResponseEntity) + // ResponseEntity.status(HttpStatus.FORBIDDEN) + // ; + } + + if (aVxF != null) { + + VxFMetadata refVxF = (VxFMetadata) vxfService.getVxFById(aVxF.getId()); + VxFOnBoardedDescriptor obd = new VxFOnBoardedDescriptor(); + obd.setVxf(refVxF); + obd.setUuid(UUID.randomUUID().toString()); + // ????? + refVxF.getVxfOnBoardedDescriptors().add(obd); + + // save product + refVxF = (VxFMetadata) vxfService.updateProductInfo(refVxF); + + if (refVxF != null) { + return ResponseEntity.ok(refVxF); + } else { + return (ResponseEntity) ResponseEntity.badRequest().build(); + } + + } else { + return (ResponseEntity) ResponseEntity.badRequest().build(); + } + } + + @PutMapping(value = "/admin/vxfobds/{mpid}", produces = "application/json", consumes = "application/json") + public ResponseEntity updateVxFOnBoardedDescriptor(@PathVariable("mpid") int mpid, + @Valid @RequestBody VxFOnBoardedDescriptor c) throws ForbiddenException { + + if (!checkUserIDorIsAdmin(-1)) { + throw new ForbiddenException("The requested page is forbidden");// return (ResponseEntity) + // ResponseEntity.status(HttpStatus.FORBIDDEN); + } + VxFOnBoardedDescriptor u = vxfOBDService.updateVxFOnBoardedDescriptor(c); + + if (u != null) { + return ResponseEntity.ok(u); + } else { + return (ResponseEntity) ResponseEntity.badRequest().build(); + } + + } + + @DeleteMapping(value = "/admin/vxfobds/{mpid}") + public ResponseEntity deleteVxFOnBoardedDescriptor(@PathVariable("mpid") int mpid) throws ForbiddenException { + + if (!checkUserIDorIsAdmin(-1)) { + throw new ForbiddenException("The requested page is forbidden");// return (ResponseEntity) + // ResponseEntity.status(HttpStatus.FORBIDDEN); + } + + VxFOnBoardedDescriptor sm = vxfOBDService.getVxFOnBoardedDescriptorByID(mpid); + + vxfOBDService.deleteVxFOnBoardedDescriptor(sm); + return ResponseEntity.ok("{}"); + + } + + @GetMapping(value = "/admin/vxfobds/{mpid}", produces = "application/json") + public ResponseEntity getVxFOnBoardedDescriptorById(@PathVariable("mpid") int mpid) throws ForbiddenException { + if (!checkUserIDorIsAdmin(-1)) { + throw new ForbiddenException("The requested page is forbidden");// return (ResponseEntity) + // ResponseEntity.status(HttpStatus.FORBIDDEN) + // ; + } + VxFOnBoardedDescriptor sm = vxfOBDService.getVxFOnBoardedDescriptorByID(mpid); + + if (sm != null) { + return ResponseEntity.ok(sm); + } else { + return (ResponseEntity) ResponseEntity.badRequest().build(); + // throw new WebApplicationException(builder.build()); + } + } + + @GetMapping(value = "/admin/vxfobds/{mpid}/status", produces = "application/json") + public ResponseEntity getVxFOnBoardedDescriptorByIdCheckMANOProvider(@PathVariable("mpid") int mpid) + throws ForbiddenException { + + if (!checkUserIDorIsAdmin(-1)) { + throw new ForbiddenException("The requested page is forbidden");// return (ResponseEntity) + // ResponseEntity.status(HttpStatus.FORBIDDEN) + // ; + } + VxFOnBoardedDescriptor obds = vxfOBDService.getVxFOnBoardedDescriptorByID(mpid); + + if (obds == null) { + return (ResponseEntity) ResponseEntity.notFound(); + } + + ///** + // * the following polling will be performed automatically by CAMEL with a timer + // */ + // + //if (obds.getOnBoardingStatus().equals(OnBoardingStatus.ONBOARDING)) { + // + // Vnfd vnfd = null; + // List vnfds = OSMClient.getInstance(obds.getObMANOprovider()).getVNFDs(); + // for (Vnfd v : vnfds) { + // if (v.getId().equalsIgnoreCase(obds.getVxfMANOProviderID()) + // || v.getName().equalsIgnoreCase(obds.getVxfMANOProviderID())) { + // vnfd = v; + // break; + // } + // } + // + // if (vnfd == null) { + // obds.setOnBoardingStatus(OnBoardingStatus.UNKNOWN); + // } else { + // obds.setOnBoardingStatus(OnBoardingStatus.ONBOARDED); + // } + // + // obds = portalRepositoryRef.updateVxFOnBoardedDescriptor(obds); + // + //} + + return ResponseEntity.ok(obds); + + } + + @PutMapping(value = "/admin/vxfobds/{mpid}/onboard", produces = "application/json", consumes = "application/json") + public ResponseEntity onBoardDescriptor(@PathVariable("mpid") int mpid, + @Valid @RequestBody final VxFOnBoardedDescriptor vxfobd) throws ForbiddenException { + + if (!checkUserIDorIsAdmin(-1)) { + throw new ForbiddenException("The requested page is forbidden");// return (ResponseEntity) + // ResponseEntity.status(HttpStatus.FORBIDDEN) + // ; + } + + try { + VxFOnBoardedDescriptor vobd = vxfOBDService.getVxFOnBoardedDescriptorByID(mpid); + MANOprovider mp = manoProviderService.getMANOproviderByID(vxfobd.getObMANOprovider().getId()); + + vobd.setObMANOprovider(mp); + vobd = vxfOBDService.updateVxFOnBoardedDescriptor(vobd); + // ***************************************************************************************************************************\ + // Because in portal.api.mano we need the url for the package location in order + // not to ask back, if the package locations + // does not contain http add the default maindomain value. + // We can either add it here or change that where the pLocation is set initially + // for the object. + // Get the location of the package + String pLocation = vobd.getVxf().getPackageLocation(); + logger.info("VxF Package Location: " + pLocation); + if (!pLocation.contains("http")) { + pLocation = propsService.getPropertyByName("maindomain").getValue() + pLocation; + vobd.getVxf().setPackageLocation(pLocation); + productService.updateProductInfo(vobd.getVxf()); + } + logger.info("PROPER VxF Package Location: " + pLocation); + // ***************************************************************************************************************************\ + // busController.onBoardVxFAdded( vobd ); + // aMANOController.onBoardVxFToMANOProvider( vxfobd.getId() ); + try { + String[] fpath = vobd.getVxf().getPackageLocation().split("/"); + logger.info("uuid: " + fpath[fpath.length - 2]); + logger.info("Package: " + fpath[fpath.length - 1]); + String vxfAbsfile = METADATADIR + fpath[fpath.length - 2] + File.separator + fpath[fpath.length - 1]; + File afile = new File(vxfAbsfile); + Path path = Paths.get(afile.getAbsolutePath()); + CompositeVxFOnBoardDescriptor compositeobdobj = new CompositeVxFOnBoardDescriptor(); + compositeobdobj.setFilename(afile.getName()); + compositeobdobj.setAllBytes(Files.readAllBytes(path)); + compositeobdobj.setObd(vobd); + busController.onBoardVxFAddedByCompositeObj(compositeobdobj); + + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + + } catch (Exception e) { + + return (ResponseEntity) ResponseEntity.badRequest() + .body("{ \"message\" : \"" + e.getStackTrace() + "\"}"); + } + + return ResponseEntity.ok(vxfobd); + + } + + @PutMapping(value = "/admin/vxfobds/{mpid}/offboard", produces = "application/json", consumes = "application/json") + public ResponseEntity offBoardDescriptor(@PathVariable("mpid") int mpid, + @Valid @RequestBody final VxFOnBoardedDescriptor clobd) throws ForbiddenException { + + if (!checkUserIDorIsAdmin(-1)) { + throw new ForbiddenException("The requested page is forbidden");// return (ResponseEntity) + // ResponseEntity.status(HttpStatus.FORBIDDEN) + // ; + } + OnBoardingStatus previous_status = clobd.getOnBoardingStatus(); + + VxFOnBoardedDescriptor obd = vxfOBDService.getVxFOnBoardedDescriptorByID(clobd.getId()); + obd.setOnBoardingStatus(OnBoardingStatus.OFFBOARDING); + centralLogger.log(CLevel.INFO, + "Onboarding Status change of VxF " + obd.getVxf().getName() + " to " + obd.getOnBoardingStatus(), + compname); + VxFOnBoardedDescriptor updatedObd = vxfOBDService.updateVxFOnBoardedDescriptor(obd); + + ResponseEntity response = null; + try { + // response = aMANOController.offBoardVxFFromMANOProvider( updatedObd ); + busController.offBoardVxF(updatedObd); + } catch (HttpClientErrorException e) { + updatedObd.setOnBoardingStatus(previous_status); + centralLogger.log(CLevel.INFO, "Onboarding Status change of VxF " + updatedObd.getVxf().getName() + " to " + + updatedObd.getOnBoardingStatus(), compname); + updatedObd.setFeedbackMessage(e.getResponseBodyAsString()); + updatedObd = vxfOBDService.updateVxFOnBoardedDescriptor(updatedObd); + JSONObject result = new JSONObject(e.getResponseBodyAsString()); // Convert String to JSON Object + + return (ResponseEntity) ResponseEntity.status(e.getRawStatusCode()).contentType(MediaType.TEXT_PLAIN) + .body("OffBoarding Failed! " + e.getStatusText() + ", " + result.getString("detail")); + } + + if (response == null) { + updatedObd.setOnBoardingStatus(previous_status); + updatedObd.setFeedbackMessage( + "Null Response on OffBoarding request.Requested VxFOnBoardedDescriptor with ID=\" + updatedObd.getId() + \" cannot be offboarded."); + updatedObd = vxfOBDService.updateVxFOnBoardedDescriptor(updatedObd); + + return (ResponseEntity) ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR) + .contentType(MediaType.TEXT_PLAIN) + .body("Requested VxFOnBoardedDescriptor with ID=" + updatedObd.getId() + " cannot be offboarded"); + } + + updatedObd.setOnBoardingStatus(OnBoardingStatus.OFFBOARDED); + centralLogger.log(CLevel.INFO, "Onboarding Status change of VxF " + updatedObd.getVxf().getName() + " to " + + updatedObd.getOnBoardingStatus(), compname); + updatedObd.setFeedbackMessage(response.getBody().toString()); + updatedObd = vxfOBDService.updateVxFOnBoardedDescriptor(updatedObd); + busController.offBoardVxF(updatedObd); + + return ResponseEntity.ok(updatedObd); + + } + + /******************************************************************************** + * + * admin ExperimentOnBoardDescriptors + * + * @throws ForbiddenException + * + ********************************************************************************/ + + @GetMapping(value = "/admin/experimentobds", produces = "application/json") + public ResponseEntity getExperimentOnBoardDescriptors() throws ForbiddenException { + if (!checkUserIDorIsAdmin(-1)) { + throw new ForbiddenException("The requested page is forbidden");// return (ResponseEntity) + // ResponseEntity.status(HttpStatus.FORBIDDEN) + // ; + } + + return ResponseEntity.ok(nsdOBDService.getExperimentOnBoardDescriptors()); + } + + @PostMapping(value = "/admin/experimentobds/", produces = "application/json", consumes = "application/json") + public ResponseEntity addExperimentOnBoardDescriptor(@Valid @RequestBody ExperimentMetadata exp) + throws ForbiddenException { + + if (!checkUserIDorIsAdmin(-1)) { + throw new ForbiddenException("The requested page is forbidden");// return (ResponseEntity) + // ResponseEntity.status(HttpStatus.FORBIDDEN) + // ; + } + + if (exp != null) { + + ExperimentMetadata refExp = (ExperimentMetadata) nsdService.getProductByID(exp.getId()); + ExperimentOnBoardDescriptor obd = new ExperimentOnBoardDescriptor(); + obd.setExperiment(refExp); + obd.setUuid(UUID.randomUUID().toString()); + refExp.getExperimentOnBoardDescriptors().add(obd); + + // save product + refExp = (ExperimentMetadata) nsdService.updateProductInfo(refExp); + + if (refExp != null) { + return ResponseEntity.ok(refExp); + } else { + return (ResponseEntity) ResponseEntity.badRequest().build(); + } + + } else { + return (ResponseEntity) ResponseEntity.badRequest().build(); + } + + } + + @PutMapping(value = "/admin/experimentobds/{mpid}", produces = "application/json", consumes = "application/json") + public ResponseEntity updateExperimentOnBoardDescriptor(@PathVariable("mpid") int mpid, + @Valid @RequestBody ExperimentOnBoardDescriptor c) throws ForbiddenException { + + if (!checkUserIDorIsAdmin(-1)) { + throw new ForbiddenException("The requested page is forbidden");// return (ResponseEntity) + // ResponseEntity.status(HttpStatus.FORBIDDEN) + // ; + } + ExperimentOnBoardDescriptor u = nsdOBDService.updateExperimentOnBoardDescriptor(c); + + if (u != null) { + return ResponseEntity.ok(u); + } else { + return (ResponseEntity) ResponseEntity.badRequest().build(); + } + + } + + @DeleteMapping(value = "/admin/experimentobds/{mpid}") + public ResponseEntity deleteExperimentOnBoardDescriptor(@PathVariable("mpid") int mpid) + throws ForbiddenException { + + if (!checkUserIDorIsAdmin(-1)) { + throw new ForbiddenException("The requested page is forbidden");// return (ResponseEntity) + // ResponseEntity.status(HttpStatus.FORBIDDEN) + // ; + } + + ExperimentOnBoardDescriptor u = nsdOBDService.getExperimentOnBoardDescriptorByID(mpid); + nsdOBDService.deleteExperimentOnBoardDescriptor(u); + return ResponseEntity.ok("{}"); + + } + + @GetMapping(value = "/admin/experimentobds/{mpid}", produces = "application/json") + public ResponseEntity getExperimentOnBoardDescriptorById(@PathVariable("mpid") int mpid) + throws ForbiddenException { + if (!checkUserIDorIsAdmin(-1)) { + throw new ForbiddenException("The requested page is forbidden");// return (ResponseEntity) + // ResponseEntity.status(HttpStatus.FORBIDDEN); + } + ExperimentOnBoardDescriptor sm = nsdOBDService.getExperimentOnBoardDescriptorByID(mpid); + + if (sm != null) { + return ResponseEntity.ok(sm); + } else { + return (ResponseEntity) ResponseEntity.notFound(); + } + } + + @GetMapping(value = "/admin/experimentobds/{mpid}/status", produces = "application/json") + public ResponseEntity getExperimentOnBoardDescriptorByIdCheckMANOProvider(@PathVariable("mpid") int mpid) + throws ForbiddenException { + + if (!checkUserIDorIsAdmin(-1)) { + throw new ForbiddenException("The requested page is forbidden");// return (ResponseEntity) + // ResponseEntity.status(HttpStatus.FORBIDDEN) + // ; + } + ExperimentOnBoardDescriptor sm = nsdOBDService.getExperimentOnBoardDescriptorByID(mpid); + + if (sm == null) { + return (ResponseEntity) ResponseEntity.notFound(); + } + +// +// if (sm.getOnBoardingStatus().equals(OnBoardingStatus.ONBOARDING)) { +// +// Nsd nsd = null; +// List nsds = OSMClient.getInstance(sm.getObMANOprovider()).getNSDs(); +// if ( nsds != null ) { +// for (Nsd v : nsds) { +// if (v.getId().equalsIgnoreCase(sm.getVxfMANOProviderID()) +// || v.getName().equalsIgnoreCase(sm.getVxfMANOProviderID())) { +// nsd = v; +// break; +// } +// } +// } +// +// if (nsd == null) { +// sm.setOnBoardingStatus(OnBoardingStatus.UNKNOWN); +// } else { +// sm.setOnBoardingStatus(OnBoardingStatus.ONBOARDED); +// } +// +// sm = portalRepositoryRef.updateExperimentOnBoardDescriptor(sm); +// +// } + + return ResponseEntity.ok(sm); + + } + + @PutMapping(value = "/admin/experimentobds/{mpid}/onboard", produces = "application/json", consumes = "application/json") + public ResponseEntity onExperimentBoardDescriptor(@PathVariable("mpid") int mpid, + @Valid @RequestBody final ExperimentOnBoardDescriptor ed) throws ForbiddenException { + + if (!checkUserIDorIsAdmin(-1)) { + throw new ForbiddenException("The requested page is forbidden");// return (ResponseEntity) + // ResponseEntity.status(HttpStatus.FORBIDDEN) + // ; + } + try { + ExperimentOnBoardDescriptor experimentonboarddescriptor = nsdOBDService + .getExperimentOnBoardDescriptorByID(ed.getId()); + MANOprovider mp = manoProviderService.getMANOproviderByID(ed.getObMANOprovider().getId()); + experimentonboarddescriptor.setObMANOprovider(mp); + experimentonboarddescriptor.getObMANOprovider().setId(ed.getObMANOprovider().getId()); + try { + + String[] fpath = experimentonboarddescriptor.getExperiment().getPackageLocation().split("/"); + logger.info("uuid: " + fpath[fpath.length - 2]); + logger.info("Package: " + fpath[fpath.length - 1]); + String vxfAbsfile = METADATADIR + fpath[fpath.length - 2] + File.separator + fpath[fpath.length - 1]; + File afile = new File(vxfAbsfile); + Path path = Paths.get(afile.getAbsolutePath()); + CompositeExperimentOnBoardDescriptor compositeobdobj = new CompositeExperimentOnBoardDescriptor(); + compositeobdobj.setFilename(afile.getName()); + compositeobdobj.setAllBytes(Files.readAllBytes(path)); + compositeobdobj.setObd(experimentonboarddescriptor); + busController.onBoardNSDAddedByCompositeObj(compositeobdobj); + + return ResponseEntity.ok(experimentonboarddescriptor); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } catch (Exception e) { + e.printStackTrace(); + logger.error("onExperimentBoardDescriptor, OSM4 fails authentication. Aborting Onboarding action."); + centralLogger.log(CLevel.ERROR, + "onExperimentBoardDescriptor, OSM4 fails authentication. Aborting Onboarding action.", compname); + + return (ResponseEntity) ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR) + .contentType(MediaType.TEXT_PLAIN) + .body("Requested Experiment Descriptor with ID=" + ed.getId() + " cannot be onboarded"); + } + + return (ResponseEntity) ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR) + .contentType(MediaType.TEXT_PLAIN) + .body("Requested Experiment Descriptor with ID=" + ed.getId() + " cannot be onboarded"); + } + + @PutMapping(value = "/admin/experimentobds/{mpid}/offboard", produces = "application/json", consumes = "application/json") + public ResponseEntity offBoardExperimentDescriptor(@PathVariable("mpid") int mpid, + @Valid @RequestBody final ExperimentOnBoardDescriptor c) throws ForbiddenException { + + if (!checkUserIDorIsAdmin(-1)) { + throw new ForbiddenException("The requested page is forbidden");// return (ResponseEntity) + // ResponseEntity.status(HttpStatus.FORBIDDEN) + // ; + } + + ExperimentOnBoardDescriptor u = nsdOBDService.getExperimentOnBoardDescriptorByID(c.getId()); + + OnBoardingStatus previous_status = u.getOnBoardingStatus(); + u.setOnBoardingStatus(OnBoardingStatus.OFFBOARDING); + centralLogger.log(CLevel.INFO, + "Onboarding Status change of VxF " + u.getExperiment().getName() + " to " + u.getOnBoardingStatus(), + compname); + ExperimentOnBoardDescriptor uExper = nsdOBDService.updateExperimentOnBoardDescriptor(u); + + ResponseEntity response = null; + try { + // response = aMANOController.offBoardNSDFromMANOProvider(uExper); + response = busController.offBoardNSD(uExper); + } catch (HttpClientErrorException e) { + uExper.setOnBoardingStatus(previous_status); + centralLogger.log(CLevel.INFO, "Onboarding Status change of VxF " + uExper.getExperiment().getName() + + " to " + uExper.getOnBoardingStatus(), compname); + uExper.setFeedbackMessage(e.getResponseBodyAsString()); + uExper = nsdOBDService.updateExperimentOnBoardDescriptor(uExper); + JSONObject result = new JSONObject(e.getResponseBodyAsString()); // Convert String to JSON Object + + return (ResponseEntity) ResponseEntity.status(e.getRawStatusCode()).contentType(MediaType.TEXT_PLAIN) + .body("OffBoarding Failed! " + e.getStatusText() + ", " + result.getString("detail")); + } + + if (response == null) { + uExper.setOnBoardingStatus(previous_status); + centralLogger.log(CLevel.INFO, "Onboarding Status change of VxF " + uExper.getExperiment().getName() + + " to " + uExper.getOnBoardingStatus(), compname); + uExper.setFeedbackMessage( + "Null response on OffBoarding request.Requested NSOnBoardedDescriptor with ID=\" + c.getId() + \" cannot be offboarded."); + uExper = nsdOBDService.updateExperimentOnBoardDescriptor(uExper); + + return (ResponseEntity) ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR) + .contentType(MediaType.TEXT_PLAIN) + .body("Requested NSOnBoardedDescriptor with ID=" + c.getId() + " cannot be offboarded"); + } + // Set Valid to false if it is OffBoarded + uExper.getExperiment().setValid(false); + uExper.setOnBoardingStatus(OnBoardingStatus.OFFBOARDED); + centralLogger.log(CLevel.INFO, "Onboarding Status change of VxF " + uExper.getExperiment().getName() + " to " + + uExper.getOnBoardingStatus(), compname); + uExper.setFeedbackMessage(response.getBody().toString()); + uExper = nsdOBDService.updateExperimentOnBoardDescriptor(uExper); + busController.offBoardNSD(uExper); + + return ResponseEntity.ok(uExper); + } + + /** + * + * Infrastructure object API + */ + + @GetMapping(value = "/admin/infrastructures", produces = "application/json") + public ResponseEntity getAdminInfrastructures() { + return ResponseEntity.ok(infrastructureService.getInfrastructures()); + } + + @PostMapping(value = "/admin/infrastructures", produces = "application/json", consumes = "application/json") + public ResponseEntity addInfrastructure(@Valid @RequestBody Infrastructure c, HttpServletRequest request) + throws ForbiddenException { + + if (!checkUserIDorIsAdmin(-1)) { + throw new ForbiddenException("The requested page is forbidden");// return (ResponseEntity) + // ResponseEntity.status(HttpStatus.FORBIDDEN) + // ; + } + Infrastructure infrastructure = new Infrastructure(); + int MPfoundByName=0; + + if(c.getMp() != null){ + MPfoundByName=1; + infrastructure.setMp(c.getMp()); + } + + infrastructure.setDatacentername(c.getDatacentername()); + infrastructure.setEmail(c.getEmail()); + infrastructure.setVIMid(c.getVIMid()); + infrastructure.setName(c.getName()); + infrastructure.setOrganization(c.getOrganization()); + Infrastructure u = infrastructureService.addInfrastructure(infrastructure); + + if (u != null && MPfoundByName==1) { + return ResponseEntity.ok(u); + } else { + return (ResponseEntity) ResponseEntity.badRequest().build(); + } + } + + @PutMapping(value = "/admin/infrastructures/{infraid}", produces = "application/json", consumes = "application/json") + public ResponseEntity updateInfrastructure(@PathVariable("infraid") int infraid, + @Valid @RequestBody Infrastructure c) throws ForbiddenException { + if (!checkUserIDorIsAdmin(-1)) { + throw new ForbiddenException("The requested page is forbidden");// return (ResponseEntity) + // ResponseEntity.status(HttpStatus.FORBIDDEN) + // ; + } + Infrastructure infrastructure = infrastructureService.getInfrastructureByID(infraid); + int MPfoundByName=0; + if(c.getMp() != null){ + MPfoundByName=1; + infrastructure.setMp(c.getMp()); + } + infrastructure.setDatacentername(c.getDatacentername()); + infrastructure.setEmail(c.getEmail()); + infrastructure.setVIMid(c.getVIMid()); + infrastructure.setName(c.getName()); + infrastructure.setOrganization(c.getOrganization()); + Infrastructure u = infrastructureService.updateInfrastructureInfo(infrastructure); + + if (u != null && MPfoundByName==1) { + return ResponseEntity.ok(u); + } else { + return (ResponseEntity) ResponseEntity.badRequest().build(); + } + + } + + @DeleteMapping(value = "/admin/infrastructures/{infraid}", produces = "application/json") + public ResponseEntity deleteInfrastructure(@PathVariable("infraid") int infraid) throws ForbiddenException { + if (!checkUserIDorIsAdmin(-1)) { + throw new ForbiddenException("The requested page is forbidden");// return (ResponseEntity) + // ResponseEntity.status(HttpStatus.FORBIDDEN) + // ; + } + Infrastructure infrastructure = infrastructureService.getInfrastructureByID(infraid); + infrastructureService.deleteInfrastructure(infrastructure); + return ResponseEntity.ok("{}"); + + } + + @GetMapping(value = "/admin/infrastructures/{infraid}", produces = "application/json") + public ResponseEntity getInfrastructureById(@PathVariable("infraid") int infraid) throws ForbiddenException { + if (!checkUserIDorIsAdmin(-1)) { + throw new ForbiddenException("The requested page is forbidden");// return (ResponseEntity) + // ResponseEntity.status(HttpStatus.FORBIDDEN) + // ; + } + Infrastructure sm = infrastructureService.getInfrastructureByID(infraid); + + if (sm != null) { + return ResponseEntity.ok(sm); + } else { + return (ResponseEntity) ResponseEntity.notFound(); + } + } + + @PostMapping(value = "/admin/infrastructures/{infraid}/images/{vfimageid}", produces = "application/json", consumes = "application/json") + public ResponseEntity addImageToInfrastructure(@PathVariable("infraid") int infraid, + @PathVariable("vfimageid") int vfimageid) throws ForbiddenException { + + PortalUser u = usersService.findByUsername(SecurityContextHolder.getContext().getAuthentication().getName()); + + if ((!u.getRoles().contains(UserRoleType.ROLE_ADMIN)) + && (!u.getRoles().contains(UserRoleType.ROLE_TESTBED_PROVIDER))) { + throw new ForbiddenException("The requested page is forbidden");// return (ResponseEntity) + // ResponseEntity.status(HttpStatus.FORBIDDEN); + + } + + Infrastructure infrs = infrastructureService.getInfrastructureByID(infraid); + VFImage vfimg = vfImageService.getVFImageByID(vfimageid); + + if ((infrs != null) && (vfimg != null)) { + + if (vfimg.getDeployedInfrastructureById(infrs.getId()) == null) { + vfimg.getDeployedInfrastructures().add(infrs); + } + if (infrs.getSupportedImageById(vfimg.getId()) == null) { + infrs.getSupportedImages().add(vfimg); + } + + vfImageService.updateVFImageInfo(vfimg); + infrastructureService.updateInfrastructureInfo(infrs); + return ResponseEntity.ok(infrs); + } else { + return (ResponseEntity) ResponseEntity.badRequest().build(); + } + } + + /** + * Validation Result + * + * @throws ForbiddenException + */ + + @PutMapping(value = "/admin/validationjobs/{vxf_id}", produces = "application/json", consumes = "application/json") + public ResponseEntity updateUvalidationjob(@PathVariable("vxf_id") int vxfid, + @Valid @RequestBody ValidationJobResult vresult) throws ForbiddenException { + logger.info("Received PUT ValidationJobResult for vxfid: " + vresult.getVxfid()); + + PortalUser u = usersService.findByUsername(SecurityContextHolder.getContext().getAuthentication().getName()); + + if ((!u.getRoles().contains(UserRoleType.ROLE_ADMIN)) + && (!u.getRoles().contains(UserRoleType.ROLE_TESTBED_PROVIDER))) { + throw new ForbiddenException("The requested page is forbidden");// return (ResponseEntity) + // ResponseEntity.status(HttpStatus.FORBIDDEN); + + } + + vxfid = vresult.getVxfid(); + + Product prod = productService.getProductByID(vxfid); + + if (prod == null) { + logger.info("updateUvalidationjob: prod == null for VXF with id=" + vxfid + ". Return Status NOT_FOUND"); + centralLogger.log(CLevel.INFO, + "updateUvalidationjob: prod == null for VXF with id=" + vxfid + ". Return Status NOT_FOUND", + compname); + + return (ResponseEntity) ResponseEntity.notFound(); + } + if (!(prod instanceof VxFMetadata)) { + logger.info("updateUvalidationjob: prod not instance of VxFMetadata for VXF with id=" + vxfid + + ". Return Status NOT_FOUND"); + centralLogger.log(CLevel.INFO, + "updateUvalidationjob: prod == null for VXF with id=" + vxfid + ". Return Status NOT_FOUND", + compname); + + return (ResponseEntity) ResponseEntity.notFound(); + } + + VxFMetadata vxf = (VxFMetadata) prod; + +// We select by desing not to certify upon Successful Validation. Thus we comment this. +// if ( vresult.getValidationStatus() ) { +// vxf.setCertified( true ); +// vxf.setCertifiedBy( "5GinFIRE " ); +// } + vxf.setValidationStatus(ValidationStatus.COMPLETED); + + ValidationJob validationJob = new ValidationJob(); + validationJob.setDateCreated(new Date()); + validationJob.setJobid(vresult.getBuildId() + ""); + validationJob.setOutputLog(vresult.getOutputLog()); + validationJob.setValidationStatus(vresult.getValidationStatus()); + validationJob.setVxfid(vxfid); + vxf.getValidationJobs().add(validationJob); + + // save product + vxf = (VxFMetadata) productService.updateProductInfo(vxf); + + busController.updatedVxF(vxf); + busController.updatedValidationJob(vxf); + + VxFMetadata vxfr = (VxFMetadata) productService.getProductByID(vxfid); // rereading this, seems to keep the DB + // connection + + return ResponseEntity.ok(vxfr); + } +} diff --git a/src/main/java/portal/api/controller/ForbiddenException.java b/src/main/java/portal/api/controller/ForbiddenException.java new file mode 100644 index 0000000..587da33 --- /dev/null +++ b/src/main/java/portal/api/controller/ForbiddenException.java @@ -0,0 +1,30 @@ +/*- + * ========================LICENSE_START================================= + * org.etsi.osl.portal.api + * %% + * Copyright (C) 2019 openslice.io + * %% + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * =========================LICENSE_END================================== + */ +package portal.api.controller; + +import org.springframework.web.bind.annotation.ResponseStatus; +import org.springframework.http.HttpStatus; + +@ResponseStatus(HttpStatus.FORBIDDEN) +public class ForbiddenException extends Exception { + public ForbiddenException(String message) { + super(message); + } +} diff --git a/src/main/java/portal/api/controller/HomeController.java b/src/main/java/portal/api/controller/HomeController.java new file mode 100644 index 0000000..0f88774 --- /dev/null +++ b/src/main/java/portal/api/controller/HomeController.java @@ -0,0 +1,35 @@ +/*- + * ========================LICENSE_START================================= + * org.etsi.osl.tmf.api + * %% + * Copyright (C) 2019 openslice.io + * %% + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * =========================LICENSE_END================================== + */ +package portal.api.controller; + +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.RequestMapping; + +/** + * Home redirection to swagger api documentation + */ +@Controller +public class HomeController { + @RequestMapping(value = "/") + public String index() { + System.out.println("swagger-ui.html"); + return "redirect:swagger-ui.html"; + } +} diff --git a/src/main/java/portal/api/controller/PortalRepositoryAPIImpl.java b/src/main/java/portal/api/controller/PortalRepositoryAPIImpl.java new file mode 100644 index 0000000..f793443 --- /dev/null +++ b/src/main/java/portal/api/controller/PortalRepositoryAPIImpl.java @@ -0,0 +1,709 @@ +/*- + * ========================LICENSE_START================================= + * org.etsi.osl.portal.api + * %% + * Copyright (C) 2019 openslice.io + * %% + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * =========================LICENSE_END================================== + */ + +package portal.api.controller; + +import java.io.IOException; +import java.security.Principal; +import java.util.ArrayList; +import java.util.List; +import java.util.UUID; + +import com.fasterxml.jackson.core.JsonParseException; +import com.fasterxml.jackson.databind.JsonMappingException; +import com.fasterxml.jackson.databind.ObjectMapper; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.security.access.annotation.Secured; +import org.springframework.security.access.prepost.PreAuthorize; +//import org.springframework.security.authentication.AuthenticationManager; +import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.authority.SimpleGrantedAuthority; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; +import org.springframework.security.oauth2.jwt.Jwt; +import org.springframework.security.oauth2.server.resource.authentication.JwtAuthenticationToken; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.ModelAttribute; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.bind.annotation.RestController; + +import org.etsi.osl.model.Category; +import org.etsi.osl.model.ExperimentMetadata; +import org.etsi.osl.model.PortalUser; +import org.etsi.osl.model.Product; +import org.etsi.osl.model.UserRoleType; +import org.etsi.osl.model.UserSession; +import org.etsi.osl.model.VxFMetadata; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.validation.Valid; +import portal.api.bus.BusController; +import portal.api.service.CategoryService; +import portal.api.service.PortalPropertiesService; +import portal.api.service.UsersService; +import portal.api.util.EmailUtil; + + +/** + * @author ctranoris + * + */ +@RestController +//@RequestMapping("/repo") +public class PortalRepositoryAPIImpl { +// /** */ +// private MANOController aMANOController; + + private static final transient Log logger = LogFactory.getLog(PortalRepositoryAPIImpl.class.getName()); +// +// private static final String METADATADIR = System.getProperty("user.home") + File.separator + ".portal" +// + File.separator + "metadata" + File.separator; +// +// +// + // PortalUser related API + + + @Autowired + ObjectMapper objectMapper; + + +// @Resource(name="authenticationManager") +// private AuthenticationManager authManager; + + + @Autowired + BCryptPasswordEncoder passwordEncoder; + + @Autowired + UsersService usersService; + + + @Autowired + CategoryService categoryService; + + @Autowired + PortalPropertiesService propsService; + + @Autowired + BusController busController; + +// @GetMapping +// public ResponseEntity getmain() { +// return ResponseEntity.ok( "ok-main" ); +// } + + /*************** Users API *************************/ + + @PreAuthorize("hasAnyAuthority('ROLE_ADMIN')" ) + @GetMapping( value = "/admin/users", produces = "application/json" ) + public ResponseEntity> getUsers(Principal principal) { + + logger.info("principal" + principal.toString() ); +// logger.info("getAuthorities" + principal.getAuthorities().toString() ); +// logger.info("getAuthorities" + principal.getDetails().toString() ); +// logger.info("getAuthorities" + principal.getAccount().toString() ); + + + return ResponseEntity.ok( usersService.findAll() ); + } + + @GetMapping( value = "/admin/users/mentors", produces = "application/json" ) + public ResponseEntity> getMentors() { + logger.info("GEt mentors"); + return ResponseEntity.ok( usersService.getUserMentorsValues()); + } + + @PreAuthorize("hasAnyAuthority('ROLE_ADMIN')" ) + @GetMapping( value = "/admin/users/{userid}", produces = "application/json" ) + public ResponseEntity getUserById( @PathVariable(required = true) long userid) { + + PortalUser u = usersService.findById( userid ); + return ResponseEntity.ok( u ); + } + + + + //@PreAuthorize("#oauth2.hasScope('read')") + @GetMapping( value = "/admin/users/myuser", produces = "application/json" ) + @ResponseBody + public PortalUser getUser( Principal principal ) { + + logger.debug("principal= " + principal.toString()); + + PortalUser u = usersService.findByUsername( principal.getName() ); + + + + if ( u == null ) { + logger.info("New user with username=" + principal.getName() + " cannot be found but is logged in. Will try to fetch from auth server"); + + + if ( principal instanceof JwtAuthenticationToken) { + JwtAuthenticationToken pr = ( JwtAuthenticationToken ) principal; + Jwt lp = (Jwt) pr.getPrincipal(); + u = usersService.addPortalUserToUsersFromAuthServer( principal.getName(), + lp.getClaimAsString("email"), + lp.getClaimAsString("given_name"), + lp.getClaimAsString("name") ); + + }else { + } + + + + + busController.newUserAdded( u ); //this will trigger also the user to be added in Bugzilla + } + + u.getRoles().clear(); + Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); + if ( authentication.getAuthorities().contains( new SimpleGrantedAuthority( UserRoleType.ROLE_ADMIN.getValue() ) ) ) { + u.addRole( UserRoleType.ROLE_ADMIN ); + } + if ( authentication.getAuthorities().contains( new SimpleGrantedAuthority( UserRoleType.ROLE_NFV_DEVELOPER.getValue() ) ) ) { + u.addRole( UserRoleType.ROLE_NFV_DEVELOPER ); + } + if ( authentication.getAuthorities().contains( new SimpleGrantedAuthority( UserRoleType.ROLE_EXPERIMENTER.getValue() ) ) ) { + u.addRole( UserRoleType.ROLE_EXPERIMENTER ); + } + if ( authentication.getAuthorities().contains( new SimpleGrantedAuthority( UserRoleType.ROLE_MENTOR.getValue() ) ) ) { + u.addRole( UserRoleType.ROLE_MENTOR ); + } + if ( authentication.getAuthorities().contains( new SimpleGrantedAuthority( UserRoleType.ROLE_TESTBED_PROVIDER.getValue() ) ) ) { + u.addRole( UserRoleType.ROLE_TESTBED_PROVIDER ); + } + u = usersService.updateUserInfo(u, null); + + return u ; + } + + + @PostMapping( value = "/admin/users", produces = "application/json", consumes = "application/json" ) + public ResponseEntity addUser( @Valid @RequestBody PortalUser user) { + + logger.info("Received POST for usergetUsername: " + user.getUsername()); + // logger.info("Received POST for usergetPassword: " + + // user.getPassword()); + // logger.info("Received POST for usergetOrganization: " + + // user.getOrganization()); + + if ((user.getUsername() == null) + || (user.getUsername().equals("") || (user.getEmail() == null) || (user.getEmail().equals("")))) { + + return (ResponseEntity) ResponseEntity.badRequest().body( "New user with username=" + user.getUsername() + " cannot be registered" ); + + } + + if ( user.getActive() ) { + + logger.info("New user with username=" + user.getUsername() + " cannot be registered BAD_REQUEST, seems ACTIVE already"); + return (ResponseEntity) ResponseEntity.badRequest().body( "New user with username=" + user.getUsername() + " cannot be registered, seems ACTIVE already"); + } + + PortalUser portaluser = usersService.findByUsername(user.getUsername()); + + if (portaluser != null) { + return (ResponseEntity) ResponseEntity.badRequest().body( "Username exists"); + } + + portaluser = usersService.findByEmail(user.getEmail() ); + if (portaluser != null) { + return (ResponseEntity) ResponseEntity.badRequest().body( "Email exists"); + } + + user.setApikey( UUID.randomUUID().toString() ); + //user.setPassword( passwordEncoder.encode( user.getPassword() ) ); + user.setPassword( user.getPassword() ); + portaluser = usersService.addPortalUserToUsers(user); + + if (portaluser != null) { + busController.newUserAdded( portaluser ); + return ResponseEntity.ok( portaluser ); + } else { + logger.info( "Requested user with username=" + user.getUsername() + " cannot be installed" ); + return (ResponseEntity) ResponseEntity.badRequest().body( "Requested user with username=" + user.getUsername() + " cannot be added" ); + } + } + + + @PostMapping( value = "/register", produces = "application/json", consumes = "multipart/form-data" ) + public ResponseEntity addNewRegisterUser( + @ModelAttribute("portaluser") String u, + @ModelAttribute("emailmessage") String emailmessage) { + + PortalUser user = null; + try { + user = objectMapper.readValue( u, PortalUser.class); + } catch (JsonParseException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (JsonMappingException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + + user.setActive(false);// in any case the user should be not active + user.getRoles().clear(); + user.addRole(UserRoleType.ROLE_EXPERIMENTER); // otherwise in post he can choose + user.addRole(UserRoleType.ROLE_NFV_DEVELOPER); // otherwise in post he can choose + + + String msg = emailmessage; + logger.info("Received register for usergetUsername: " + user.getUsername()); + + ResponseEntity r = addUser(user); + + + + if (r.getStatusCode() == HttpStatus.OK ) { + PortalUser us = usersService.findByUsername( user.getUsername() ); + String amsg = msg.replace("APIKEY_REPLACE", us.getApikey()); + logger.info("Email message: " + amsg); + String subj = "[" + propsService.getPropertyByName("portaltitle").getValue() + "] " + propsService.getPropertyByName("activationEmailSubject").getValue(); + EmailUtil.SendRegistrationActivationEmail(user.getEmail(), amsg, subj); + } + + return r; + } + + @PostMapping( value = "/register/verify", produces = "application/json", consumes = "multipart/form-data" ) + public ResponseEntity addNewRegisterUserVerify( + @ModelAttribute("username") String username, + @ModelAttribute("rid") String rid) { + + + PortalUser u = usersService.findByUsername(username); +// if (u.getOrganization().contains("^^")) { +// u.setOrganization(u.getOrganization().substring(0, u.getOrganization().indexOf("^^"))); +// } + + if ( (u != null) && ( rid.equals( u.getApikey())) ) { + + u.setActive(true); + u = usersService.updateUserInfo( u, true); + + return ResponseEntity.ok( u ); + } else { + + return (ResponseEntity) ResponseEntity.badRequest().body( "{ \"message\" : \"Requested user with username=" + u.getUsername() + " cannot be updated\"}"); + } + } + + + @PreAuthorize("hasAnyAuthority('ROLE_ADMIN')" ) + @PutMapping( value = "/admin/users/{userid}", produces = "application/json", consumes = "application/json" ) + public ResponseEntity updateUserInfo( @PathVariable(required = true) long userid , @Valid @RequestBody PortalUser user) { + logger.info("Received PUT for user: " + user.getUsername()); + + + PortalUser previousUser = usersService.findById(userid); + +// List previousProducts = previousUser.getProducts(); +// +// if (user.getProducts().size() == 0) { +// user.getProducts().addAll(previousProducts); +// } +// + previousUser.setActive( user.getActive() ); + previousUser.setEmail( user.getEmail() ); + previousUser.setFirstname( user.getFirstname()); + previousUser.setLastname( user.getLastname()); + previousUser.setOrganization( user.getOrganization() ); + if ( (user.getPassword()!=null) && (!user.getPassword().equals(""))){//else will not change it + //previousUser.setPasswordUnencrypted( user.getPassword() ); //the unmarshaled object user has already called setPassword, so getPassword provides the encrypted password + //previousUser.setPassword( passwordEncoder.encode( user.getPassword() ) ); + user.setPassword( user.getPassword() ); + } + + previousUser.getRoles().clear(); + for (UserRoleType rt : user.getRoles()) { + previousUser.getRoles().add(rt); + } + + if ( (user.getApikey()!=null) && ( !user.getApikey().equals("")) ){ + previousUser.setApikey( user.getApikey() ); + } else { + previousUser.setApikey( UUID.randomUUID().toString() ); + } + + + PortalUser u = usersService.updateUserInfo( previousUser, true ); + + + if (u != null) { + + return ResponseEntity.ok( u ); + } else { + return (ResponseEntity) ResponseEntity.badRequest().body( "Requested user with username=" + u.getUsername() + " cannot be updated"); + } + } + + @PreAuthorize("hasAnyAuthority('ROLE_ADMIN')" ) + @DeleteMapping( value = "/admin/users/{userid}" ) + public ResponseEntity deleteUser(@PathVariable("userid") int userid) { + logger.info("Received DELETE for userid: " + userid); + + PortalUser u = usersService.findById(userid); + + usersService.delete( u ); + + return ResponseEntity.ok().body("{}"); + //return (ResponseEntity) ResponseEntity.badRequest().body( "Requested user cannot be deleted"); + + /** + * do not allow for now to delete users! + */ + +// portalRepositoryRef.deleteUser(userid); +// return Response.ok().build(); + + } + + /** + * @param userID + * @return true if user logged is equal to the requested id of owner, or is ROLE_ADMIN + */ + private boolean checkUserIDorIsAdmin(long userID){ + + Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); + + logger.info("principal 1= " + authentication.getAuthorities().contains( new SimpleGrantedAuthority( UserRoleType.ROLE_ADMIN.getValue() ) )); + logger.info("principal 2= " + authentication.getAuthorities().contains( new SimpleGrantedAuthority( UserRoleType.ROLE_TESTBED_PROVIDER.getValue() ) )); + logger.info("principal 3= " + authentication.getAuthorities().contains( new SimpleGrantedAuthority( UserRoleType.ROLE_MENTOR.getValue() ) )); + logger.info("principal 4= " + authentication.getAuthorities().contains( new SimpleGrantedAuthority("ROLE_admin") )); + + + if ( authentication.getAuthorities().contains( new SimpleGrantedAuthority( UserRoleType.ROLE_ADMIN.getValue() ))){ + logger.info("checkUserIDorIsAdmin, authentication role = " + authentication.getAuthorities().contains( new SimpleGrantedAuthority( UserRoleType.ROLE_ADMIN.getValue() ) )); + return true; + } + PortalUser uToFind = usersService.findById( userID ); + if ( (uToFind !=null ) && ( uToFind.getUsername() == authentication.getName()) ){ + logger.info("checkUserIDorIsAdmin, user is equal with request"); + return true; + } + + + return false; + } + + @GetMapping( value = "/admin/users/{userid}/vxfs", produces = "application/json" ) + public ResponseEntity getAllVxFsofUser(@PathVariable("userid") int userid) throws ForbiddenException { + logger.info("getAllVxFsofUser for userid: " + userid); + + if ( !checkUserIDorIsAdmin( userid ) ){ + throw new ForbiddenException("The requested page is forbidden");//return (ResponseEntity) ResponseEntity.status(HttpStatus.FORBIDDEN); + } + PortalUser u = usersService.findById(userid); + + if (u != null) { + List prods = u.getProducts(); + List vxfs = new ArrayList(); + for (Product p : prods) { + if (p instanceof VxFMetadata) + vxfs.add((VxFMetadata) p); + } + + return ResponseEntity.ok( vxfs ); + } else { + return (ResponseEntity) ResponseEntity.badRequest().body( "User with id=" + userid + " not found in portal registry"); + + } + } + + + @GetMapping( value = "/admin/users/{userid}/experiments", produces = "application/json" ) + public ResponseEntity getAllAppsofUser(@PathVariable("userid") int userid) throws ForbiddenException { + logger.info("getAllAppsofUser for userid: " + userid); + + if ( !checkUserIDorIsAdmin( userid ) ){ + throw new ForbiddenException("The requested page is forbidden");//return (ResponseEntity) ResponseEntity.status(HttpStatus.FORBIDDEN); + } + + + PortalUser u = usersService.findById(userid); + + if (u != null) { + List prods = u.getProducts(); + List apps = new ArrayList(); + for (Product p : prods) { + if (p instanceof ExperimentMetadata) + apps.add((ExperimentMetadata) p); + } + + return ResponseEntity.ok( apps ); + } else { + return (ResponseEntity) ResponseEntity.badRequest().body( "User with id=" + userid + " not found in portal registry"); + } + } + + @GetMapping( value = "/admin/users/{userid}/vxfs/{vxfid}", produces = "application/json" ) + public ResponseEntity getVxFofUser(@PathVariable("userid") int userid, @PathVariable("vxfid") int vxfid) throws ForbiddenException { + logger.info("getVxFofUser for userid: " + userid + ", vxfid=" + vxfid); + + if ( !checkUserIDorIsAdmin( userid ) ){ + throw new ForbiddenException("The requested page is forbidden");//return (ResponseEntity) ResponseEntity.status(HttpStatus.FORBIDDEN); + } + + + PortalUser u = usersService.findById(userid); + + if (u != null) { + VxFMetadata vxf = (VxFMetadata) u.getProductById(vxfid); + return ResponseEntity.ok( vxf ); + } else { + return (ResponseEntity) ResponseEntity.badRequest().body( "User with id=" + userid + " not found in portal registry"); + } + } + + @GetMapping( value = "/admin/users/{userid}/experiments/{appid}", produces = "application/json" ) + public ResponseEntity getAppofUser( @PathVariable("userid") int userid, @PathVariable("appid") int appid ) throws ForbiddenException { + logger.info("getAppofUser for userid: " + userid + ", appid=" + appid); + if ( !checkUserIDorIsAdmin( userid ) ){ + throw new ForbiddenException("The requested page is forbidden");//return (ResponseEntity) ResponseEntity.status(HttpStatus.FORBIDDEN); + } + + PortalUser u = usersService.findById(userid); + + if (u != null) { + ExperimentMetadata appmeta = (ExperimentMetadata) u.getProductById(appid); + return ResponseEntity.ok( appmeta ); + } else { + return (ResponseEntity) ResponseEntity.badRequest().body( "User with id=" + userid + " not found in portal registry"); + } + } + + // Sessions related API + + // @OPTIONS + // @Path("/sessions/") + // @Produces("application/json") + // @Consumes("application/json") + // @LocalPreflight + // public ResponseEntity addUserSessionOption(){ + // + // + // logger.info("Received OPTIONS addUserSessionOption "); + // String origin = headers.getRequestHeader("Origin").get(0); + // if (origin != null) { + // return Response.ok() + // .header(CorsHeaderConstants.HEADER_AC_ALLOW_METHODS, "GET POST DELETE PUT + // HEAD OPTIONS") + // .header(CorsHeaderConstants.HEADER_AC_ALLOW_CREDENTIALS, "true") + // .header(CorsHeaderConstants.HEADER_AC_ALLOW_HEADERS, "Origin, + // X-Requested-With, Content-Type, Accept") + // .header(CorsHeaderConstants.HEADER_AC_ALLOW_ORIGIN, origin) + // .build(); + // } else { + // return Response.ok().build(); + // } + // } + + + @PostMapping( value = "/sessions", produces = "application/json", consumes = "application/json" ) + public ResponseEntity addUserSession(Principal principal, @Valid @RequestBody UserSession userSession, final HttpServletRequest request) { + + logger.info("Received POST addUserSession usergetUsername: " + userSession.getUsername()); + // logger.info("DANGER, REMOVE Received POST addUserSession password: " + // + userSession.getPassword()); + + Authentication authentication = + SecurityContextHolder.getContext().getAuthentication(); + + logger.info("authentication= " + authentication); + + + if (authentication != null) { + if (authentication.getPrincipal() != null) + logger.info(" securityContext.getPrincipal().toString() >" + + authentication.getPrincipal().toString() + "<"); + + } + + UsernamePasswordAuthenticationToken authReq = + new UsernamePasswordAuthenticationToken( userSession.getUsername(), userSession.getPassword() ); + + + + try { +// Authentication auth = authManager.authenticate(authReq); +// SecurityContext sc = SecurityContextHolder.getContext(); +// sc.setAuthentication(auth); +// HttpSession session = request.getSession(true); +// session.setAttribute("SPRING_SECURITY_CONTEXT", sc); + + PortalUser portalUser = usersService.findByUsername( principal.getName() ); + if (portalUser == null ) { + return (ResponseEntity) ResponseEntity.status(HttpStatus.NOT_FOUND ).body("user not found"); + } + + + logger.info(" securityContext.getPrincipal().toString() = " + + principal.toString() ); + + + if (!portalUser.getActive()) { + logger.info("User [" + portalUser.getUsername() + "] is not Active"); + + return (ResponseEntity) ResponseEntity.status(HttpStatus.UNAUTHORIZED); + } + + portalUser.setCurrentSessionID( request.getSession().getId() ); + userSession.setPortalUser(portalUser); + userSession.setPassword(""); + ;// so not tosend in response + + logger.info("User [" + portalUser.getUsername() + "] logged in successfully."); + PortalUser u = usersService.updateUserInfo( portalUser, false ); + +// if ( currentUser.getPrincipal().toString().length()>2 ){ +// CentralLogger.log( CLevel.INFO, "User [" + currentUser.getPrincipal().toString().substring(0, 3) + "xxx" + "] logged in"); +// } + + return ResponseEntity.ok( userSession ); + } catch (Exception ae) { + + return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body( "exception: " + ae.getMessage()); + } + + + } + + + @GetMapping( value = "/sessions/logout", produces = "application/json" ) + public ResponseEntity logoutUser() { + + logger.info("Received logoutUser " + SecurityContextHolder.getContext().getAuthentication().getName()); + + usersService.logout( SecurityContextHolder.getContext().getAuthentication().getName() ); + + SecurityContextHolder.getContext().getAuthentication().setAuthenticated(false); +// +// if (sc != null) { +// if (sc.getUserPrincipal() != null) +// logger.info(" securityContext.getUserPrincipal().toString() >" +// + sc.getUserPrincipal().toString() + "<"); +// +// SecurityUtils.getSubject().logout(); +// } + + return ResponseEntity.ok().body("{}"); + } + + + // categories API + + @GetMapping( value = "/categories", produces = "application/json" ) + public ResponseEntity> getCategories() { + return ResponseEntity.ok( categoryService.findAll() ); + } + + @GetMapping( value = "/admin/categories", produces = "application/json" ) + public ResponseEntity> getAdminCategories() { + return ResponseEntity.ok( categoryService.findAll() ); + } + + + @PreAuthorize("hasAnyAuthority('ROLE_ADMIN')" ) + @PostMapping( value = "/admin/categories", produces = "application/json", consumes = "application/json" ) + public ResponseEntity addCategory(@Valid @RequestBody Category c) { + + + Category u = categoryService.addCategory(c); + + if (u != null) { + return ResponseEntity.ok(u); + } else { + return (ResponseEntity) ResponseEntity.badRequest().body( "Requested category cannot be added" ); + } + } + + @PreAuthorize("hasAnyAuthority('ROLE_ADMIN')" ) + @PutMapping( value = "/admin/categories/{catid}", produces = "application/json", consumes = "application/json" ) + public ResponseEntity updateCategory(@PathVariable("catid") long catid, @Valid @RequestBody Category c) { + + + Category previousCategory = categoryService.findById(catid); + + previousCategory.setName( c.getName() ); + + Category u = categoryService.updateCategoryInfo( previousCategory ); + + if (u != null) { + return ResponseEntity.ok( u ); + } else { + return (ResponseEntity) ResponseEntity.badRequest().body( "Requested category cannot be updated" ); + } + + } + + @PreAuthorize("hasAnyAuthority('ROLE_ADMIN')" ) + @DeleteMapping( value = "/admin/categories/{catid}", produces = "application/json") + public ResponseEntity deleteCategory( @PathVariable("catid") long catid) { + + logger.info("deleteCategory catid=" + catid); + + Category previousCategory = categoryService.findById(catid); + if ( previousCategory == null ) { + return (ResponseEntity) ResponseEntity.notFound(); + } else { + try + { + categoryService.deleteCategory( previousCategory ); + return ResponseEntity.ok( "{}" ); + } catch (Exception e) { + + return (ResponseEntity) ResponseEntity.status( HttpStatus.INTERNAL_SERVER_ERROR ).body("{ \"message\" : \"Cannot delete category. There are elements linked.\"}"); + } + } + } + + + @GetMapping( value = "/categories/{catid}", produces = "application/json" ) + public ResponseEntity getCategoryById( @PathVariable("catid") int catid) { + Category c = categoryService.findById(catid); + + if (c != null) { + return ResponseEntity.ok( c ); + } else { + return (ResponseEntity) ResponseEntity.badRequest().body( "Requested category not found" ); + } + } + @GetMapping( value = "/admin/categories/{catid}", produces = "application/json" ) + public ResponseEntity getAdminCategoryById(@PathVariable("catid") int catid) { + return getCategoryById(catid); + } + + +} diff --git a/src/main/java/portal/api/controller/PortalRepositoryVFImageAPI.java b/src/main/java/portal/api/controller/PortalRepositoryVFImageAPI.java new file mode 100644 index 0000000..f0063cb --- /dev/null +++ b/src/main/java/portal/api/controller/PortalRepositoryVFImageAPI.java @@ -0,0 +1,432 @@ +/*- + * ========================LICENSE_START================================= + * org.etsi.osl.portal.api + * %% + * Copyright (C) 2019 openslice.io + * %% + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * =========================LICENSE_END================================== + */ + + +package portal.api.controller; + +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.util.Date; +import java.util.List; +import java.util.UUID; + +import com.fasterxml.jackson.core.JsonParseException; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.JsonMappingException; +import com.fasterxml.jackson.databind.ObjectMapper; + +import org.apache.commons.io.IOUtils; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.authority.SimpleGrantedAuthority; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.ModelAttribute; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.multipart.MultipartFile; + +import org.etsi.osl.model.PortalUser; +import org.etsi.osl.model.UserRoleType; +import org.etsi.osl.model.VFImage; +import org.etsi.osl.model.VxFMetadata; +import jakarta.servlet.http.HttpServletRequest; +import portal.api.bus.BusController; +import portal.api.service.PortalPropertiesService; +import portal.api.service.UsersService; +import portal.api.service.VFImageService; +import portal.api.service.VxFService; +import portal.api.util.AttachmentUtil; + + +/** + * @author ctranoris + * + */ + +@RestController +public class PortalRepositoryVFImageAPI { + + + + private static final String VFIMAGESDIR = System.getProperty("user.home") + File.separator + ".vfimages" + + File.separator ; + + private static final transient Log logger = LogFactory.getLog( PortalRepositoryVFImageAPI.class.getName()); + + @Autowired + PortalPropertiesService propsService; + + @Autowired + UsersService usersService; + + + @Autowired + VxFService vxfService; + + @Autowired + VFImageService vfImageService; + + + @Autowired + ObjectMapper objectMapper; + + + @Autowired + BusController busController; + + /** + * + * Image object API + */ + + @GetMapping( value = "/admin/vfimages", produces = "application/json" ) + public ResponseEntity getAdminVFImages() { + + // + PortalUser u = usersService.findByUsername( SecurityContextHolder.getContext().getAuthentication().getName() ); + + + + if (u != null) { + List vfimagess; + + if (u.getRoles().contains(UserRoleType.ROLE_ADMIN) || u.getRoles().contains(UserRoleType.ROLE_TESTBED_PROVIDER)) { + vfimagess = vfImageService.getVFImages(); + } else { + vfimagess = vfImageService.getVFImagesByUserID((long) u.getId()); + } + + return ResponseEntity.ok( vfimagess ); + + } else { + return (ResponseEntity) ResponseEntity.notFound().build(); + } + + } + + + @PostMapping( value = "/admin/vfimages" ) + public ResponseEntity addVFImage( + final @ModelAttribute("vfimage") String v, + @RequestParam(name = "prodFile", required = false) MultipartFile prodFile, + HttpServletRequest request + ) { + + // + PortalUser u = usersService.findByUsername( SecurityContextHolder.getContext().getAuthentication().getName() ); + + if (u == null) { + return (ResponseEntity) ResponseEntity.notFound().build(); + } + + VFImage vfimg = null; + + String emsg = ""; + + try { + + try { + vfimg = objectMapper.readValue( v, VFImage.class); + } catch (JsonParseException e) { + e.printStackTrace(); + } catch (JsonMappingException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } + + logger.info("Received @POST for VFImage : " + vfimg.getName()); + + String uuid = UUID.randomUUID().toString(); + vfimg.setUuid(uuid); + vfimg.setDateCreated(new Date()); + vfimg.setOwner(u); + vfimg = addNewVFImage(vfimg, prodFile, request); + + } catch (JsonProcessingException e) { + vfimg = null; + e.printStackTrace(); + logger.error( e.getMessage() ); + emsg = e.getMessage(); + } catch (IOException e) { + vfimg = null; + e.printStackTrace(); + logger.error( e.getMessage() ); + emsg = e.getMessage(); + } + + + if (vfimg != null) { + + busController.newVFImageAdded( vfimg ); + return ResponseEntity.ok( vfimg ); + } else { + return (ResponseEntity) ResponseEntity.status( HttpStatus.INTERNAL_SERVER_ERROR ).body( "Requested Image cannot be inserted" ); + } + + + } + + /** + * @param vfimg + * @param vfimagefile + * @return + * @throws IOException + */ + private VFImage addNewVFImage(VFImage vfimg, MultipartFile vfimagefile, HttpServletRequest request) throws IOException { + + logger.info("image name = " + vfimg.getName()); + logger.info("shortDescription = " +vfimg.getShortDescription()); + + String endpointUrl = request.getRequestURI(); + String tempDir = VFIMAGESDIR + vfimg.getUuid() + File.separator; + + if (vfimagefile != null) { + String imageFileNamePosted = vfimagefile.getOriginalFilename() ; //AttachmentUtil.getFileName(vfimagefile.getHeaders()); + logger.info("vfimagefile = " + imageFileNamePosted); + if (!imageFileNamePosted.equals("") && !imageFileNamePosted.equals("unknown")) { + Files.createDirectories(Paths.get(tempDir)); + String imgfile = AttachmentUtil.saveFile( vfimagefile, tempDir + imageFileNamePosted); + logger.info("vfimagefile saved to = " + imgfile); + + vfimg.setPackageLocation(endpointUrl.toString().replace("http:", "") + "repo/vfimages/image/" + vfimg.getUuid() + "/" + + imageFileNamePosted); + } + } + + VFImage registeredvfimg = vfImageService.saveVFImage( vfimg ); + + + return registeredvfimg; + } + + + /** + * @param vfimgnew + * @param vfimagefile + * @return + * @throws IOException + */ + private VFImage updateVFImage(VFImage vfimgnew, MultipartFile vfimagefile, HttpServletRequest request) throws IOException { + + logger.info("image name = " + vfimgnew.getName()); + logger.info("shortDescription = " +vfimgnew.getShortDescription()); + + String endpointUrl = request.getRequestURI(); + String tempDir = VFIMAGESDIR + vfimgnew.getUuid() + File.separator; + + VFImage prevfImage = vfImageService.getVFImageByID( vfimgnew.getId() ); + + + if (vfimagefile != null) { + String imageFileNamePosted = vfimagefile.getOriginalFilename() ; //AttachmentUtil.getFileName(vfimagefile.getHeaders()); + logger.info("vfimagefile = " + imageFileNamePosted); + if (!imageFileNamePosted.equals("") && !imageFileNamePosted.equals("unknown")) { + Files.createDirectories(Paths.get(tempDir)); + String imgfile = AttachmentUtil.saveFile( vfimagefile, tempDir + imageFileNamePosted); + logger.info("vfimagefile saved to = " + imgfile); + + prevfImage.setPackageLocation(endpointUrl.toString().replace("http:", "") + "repo/vfimages/image/" + prevfImage.getUuid() + "/" + + imageFileNamePosted); + } + } + + prevfImage.setShortDescription( vfimgnew.getShortDescription() ); + prevfImage.setDateUpdated( new Date() ); + prevfImage.setPublicURL( vfimgnew.getPublicURL()); + prevfImage.setPublished( vfimgnew.isPublished() ); + prevfImage.setTermsOfUse( vfimgnew.getTermsOfUse() ); + + VFImage registeredvfimg = vfImageService.updateVFImageInfo( prevfImage ); + + + return registeredvfimg; + } + + + @GetMapping( value = "/vfimages/image/{uuid}/{vfimagefile}", produces = "application/gzip" ) + public @ResponseBody byte[] downloadVxFPackage(@PathVariable("uuid") String uuid, @PathVariable("vfimagefile") String vfimagefile) throws IOException { + + logger.info("vfimagefile: " + vfimagefile); + logger.info("uuid: " + uuid); + + String vxfAbsfile = VFIMAGESDIR + uuid + File.separator + vfimagefile; + logger.info("VxF RESOURCE FILE: " + vxfAbsfile); + File file = new File(vxfAbsfile); + + + InputStream in = new FileInputStream( file ); + return IOUtils.toByteArray(in); + + } + + + + + @PutMapping( value = "/admin/vfimages", produces = "application/json", consumes = "multipart/form-data" ) + public ResponseEntity updateVFImage( + final @ModelAttribute("vfimage") String v, + @RequestParam(name = "prodFile", required = false) MultipartFile prodFile, + HttpServletRequest request) throws ForbiddenException { + + VFImage vfimg = null; + + String emsg = ""; + + try { + try { + vfimg = objectMapper.readValue( v, VFImage.class); + } catch (JsonParseException e) { + e.printStackTrace(); + } catch (JsonMappingException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } + + if ( !checkUserIDorIsAdmin( -1 ) ){ + throw new ForbiddenException("The requested page is forbidden");//return (ResponseEntity) ResponseEntity.status(HttpStatus.FORBIDDEN) ; + } + + logger.info("Received @PUT for VFImage : " + vfimg.getName()); + + vfimg = updateVFImage(vfimg, prodFile, request); + + } catch (JsonProcessingException e) { + vfimg = null; + e.printStackTrace(); + logger.error( e.getMessage() ); + emsg = e.getMessage(); + } catch (IOException e) { + vfimg = null; + e.printStackTrace(); + logger.error( e.getMessage() ); + emsg = e.getMessage(); + } + + + if (vfimg != null) { + + busController.aVFImageUpdated( vfimg ); + return ResponseEntity.ok( vfimg ); + } else { + return (ResponseEntity) ResponseEntity.status( HttpStatus.INTERNAL_SERVER_ERROR ).body( "Requested Image cannot be inserted" ); + + } + + } + + @DeleteMapping( value = "/admin/vfimages/{id}") + public ResponseEntity deleteVFImage(@PathVariable("id") int id) throws ForbiddenException { + + VFImage sm = vfImageService.getVFImageByID(id); + + if ( !checkUserIDorIsAdmin( -1 ) ){ + throw new ForbiddenException("The requested page is forbidden");//return (ResponseEntity) ResponseEntity.status(HttpStatus.FORBIDDEN) ; + } + + + for (VxFMetadata vxf : sm.getUsedByVxFs()) { + vxf.getVfimagesVDU().remove(sm); + vxfService.updateProductInfo(vxf); + } + + vfImageService.deleteVFImage( sm ); + + return ResponseEntity.ok( "{}" ); + + } + + + @GetMapping( value = "/admin/vfimages/{id}", produces = "application/json" ) + public ResponseEntity getVFImageById(@PathVariable("id") long id) throws ForbiddenException { + VFImage sm = vfImageService.getVFImageByID(id); + + if (sm != null) { + + if ( !checkUserIDorIsAdmin( -1 ) ){ + throw new ForbiddenException("The requested page is forbidden");//return (ResponseEntity) ResponseEntity.status(HttpStatus.FORBIDDEN) ; + } + + return ResponseEntity.ok( sm ); + } else { + return (ResponseEntity) ResponseEntity.notFound().build(); + } + } + + + @GetMapping( value = "/admin/vfimages/name/{imagename}", produces = "application/json" ) + public ResponseEntity getVFImageByName(@PathVariable("imagename") String imagename) throws ForbiddenException { + VFImage sm = vfImageService.getVFImageByName( imagename ); + + if (sm != null) { + if ( !checkUserIDorIsAdmin( -1 ) ){ + throw new ForbiddenException("The requested page is forbidden");//return (ResponseEntity) ResponseEntity.status(HttpStatus.FORBIDDEN) ; + } + + return ResponseEntity.ok( sm ); + } else { + return (ResponseEntity) ResponseEntity.notFound().build(); + } + } + + + /** + * @param userID + * @return true if user logged is equal to the requested id of owner, or is ROLE_ADMIN + */ + private boolean checkUserIDorIsAdmin(long userID){ + + Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); + + logger.info("principal 1= " + authentication.getAuthorities().contains( new SimpleGrantedAuthority( UserRoleType.ROLE_ADMIN.getValue() ) )); + logger.info("principal 2= " + authentication.getAuthorities().contains( new SimpleGrantedAuthority( UserRoleType.ROLE_TESTBED_PROVIDER.getValue() ) )); + logger.info("principal 2= " + authentication.getAuthorities().contains( new SimpleGrantedAuthority( UserRoleType.ROLE_MENTOR.getValue() ) )); + + if ( authentication.getAuthorities().contains( new SimpleGrantedAuthority( UserRoleType.ROLE_ADMIN.getValue() ))){ + logger.info("checkUserIDorIsAdmin, authentication role = " + authentication.getAuthorities().contains( new SimpleGrantedAuthority( UserRoleType.ROLE_ADMIN.getValue() ) )); + return true; + } + + PortalUser uToFind = usersService.findById( userID ); + if ( (uToFind !=null ) && ( uToFind.getUsername() == authentication.getName()) ){ + logger.info("checkUserIDorIsAdmin, user is equal with request"); + return true; + } + + + return false; + } + +} diff --git a/src/main/java/portal/api/mano/MANOController.java b/src/main/java/portal/api/mano/MANOController.java new file mode 100644 index 0000000..271c76a --- /dev/null +++ b/src/main/java/portal/api/mano/MANOController.java @@ -0,0 +1,405 @@ +/*- + * ========================LICENSE_START================================= + * org.etsi.osl.portal.api + * %% + * Copyright (C) 2019 openslice.io + * %% + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * =========================LICENSE_END================================== + */ + + +package portal.api.mano; + +import java.util.Date; +import java.util.List; +import java.util.UUID; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; + +import org.apache.camel.CamelContext; +import org.apache.camel.builder.RouteBuilder; +import org.apache.camel.impl.DefaultCamelContext; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.etsi.osl.centrallog.client.*; +import org.json.JSONException; +import org.json.JSONObject; +import org.springframework.context.annotation.Configuration; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Bean; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.stereotype.Component; +import org.springframework.web.client.HttpClientErrorException; +import org.springframework.web.client.HttpStatusCodeException; + +import portal.api.bus.BusController; +//import portal.api.centrallog.CLevel; +//import portal.api.centrallog.CentralLogger; +import portal.api.service.DeploymentDescriptorService; +import portal.api.service.ManoProviderService; +import portal.api.service.NSDOBDService; +import portal.api.service.NSDService; +import portal.api.service.PortalPropertiesService; +import portal.api.service.VxFOBDService; +import portal.api.service.VxFService; +import org.etsi.osl.model.DeploymentDescriptor; +import org.etsi.osl.model.DeploymentDescriptorStatus; +import org.etsi.osl.model.ExperimentMetadata; +import org.etsi.osl.model.ExperimentOnBoardDescriptor; +import org.etsi.osl.model.MANOprovider; +import org.etsi.osl.model.OnBoardDescriptor; +import org.etsi.osl.model.OnBoardingStatus; +import org.etsi.osl.model.VxFMetadata; +import org.etsi.osl.model.VxFOnBoardedDescriptor; + + + +/** + * @author ctranoris + * + */ + +@Configuration +public class MANOController { + + /** */ + private static final transient Log logger = LogFactory.getLog(MANOController.class.getName()); + + + @Autowired + VxFOBDService vxfOBDService; + + @Autowired + VxFService vxfService; + + @Autowired + DeploymentDescriptorService deploymentDescriptorService; + + @Autowired + ManoProviderService manoProviderService; + + @Autowired + NSDService nsdService; + + @Autowired + NSDOBDService nsdOBDService; + + @Autowired + PortalPropertiesService propsService; + + + @Autowired + BusController busController; + + @Autowired + MANOStatus aMANOStatus; + + public MANOController() { + + } + + + @Value("${spring.application.name}") + private String compname; + + + @Autowired + private CentralLogger centralLogger; + + + @Bean("aMANOController") + public MANOController aMANOControllerBean() { + return new MANOController(); + } + +// private static String HTTP_SCHEME = "https:"; + +// public static void setHTTPSCHEME(String url) { +// logger.info("setHTTPSCHEME url = " + url); +//// if (url.contains("localhost")) { +//// HTTP_SCHEME = "http:"; +//// } +// // HTTP_SCHEME = url + ":"; +// } + + + /** + * onBoard a VNF to MANO Provider, as described by this descriptor + * + * @param vxfobds + * @throws Exception + */ + public void onBoardVxFToMANOProvider( long vxfobdid ) throws Exception { + + if (vxfOBDService == null) { + throw new Exception("vxfOBDService is NULL. Cannot load VxFOnBoardedDescriptor"); + } + + VxFOnBoardedDescriptor vxfobd = vxfOBDService.getVxFOnBoardedDescriptorByID(vxfobdid); + // PortalRepository portalRepositoryRef = new PortalRepository(); + + if (vxfobd == null) { + throw new Exception("vxfobd is NULL. Cannot load VxFOnBoardedDescriptor"); + } + + if (vxfobd.getVxf() == null) { + throw new Exception("vxfobd.getVxf() is NULL. Cannot load VxFOnBoardedDescriptor"); + } + + if (vxfobd.getVxf().getName() == null) { + throw new Exception("vxfobd.getVxf() is NULL. Cannot load VxFOnBoardedDescriptor"); + } + + + vxfobd.setOnBoardingStatus(OnBoardingStatus.ONBOARDING); + // This is the Deployment ID for the portal + vxfobd.setDeployId(UUID.randomUUID().toString()); +// VxFMetadata vxf = vxfobd.getVxf(); +// if (vxf == null) { +// vxf = (VxFMetadata) vxfService.getProductByID(vxfobd.getVxfid()); +// } + centralLogger.log( CLevel.INFO, "Onboarding status change of VxF "+vxfobd.getVxf().getName()+" to "+vxfobd.getOnBoardingStatus(), compname); + // Set MANO Provider VxF ID + vxfobd.setVxfMANOProviderID( vxfobd.getVxf().getName()); + // Set onBoarding Date + vxfobd.setLastOnboarding(new Date()); + + VxFOnBoardedDescriptor vxfobds = vxfOBDService.updateVxFOnBoardedDescriptor(vxfobd); + if (vxfobds == null) { + throw new Exception("Cannot load VxFOnBoardedDescriptor"); + } + + + String pLocation = vxfobd.getVxf().getPackageLocation(); + logger.info("VxF Package Location: " + pLocation); + + if (!pLocation.contains("http")) { + pLocation = propsService.getPropertyByName( "maindomain" ).getValue() + pLocation; + } +// if (!pLocation.contains("http")) { +// pLocation = "http:" + pLocation; +// pLocation = pLocation.replace("\\", "/"); +// } + logger.info("PROPER VxF Package Location: " + pLocation); + + + + } + + public void checkAndDeleteTerminatedOrFailedDeployments() { + logger.info("Check and Delete Terminated and Failed Deployments"); + List DeploymentDescriptorsToDelete = deploymentDescriptorService.getDeploymentsToBeDeleted(); + for (DeploymentDescriptor d : DeploymentDescriptorsToDelete) { + // Launch the deployment + logger.info("Send to bus control to delete: " + d.getId()); + busController.deleteExperiment(d); + } + } + + public void checkAndDeployExperimentToMANOProvider() { + logger.info("This will trigger the check and Deploy Experiments"); + // Check the database for a new deployment in the next minutes + // If there is a deployment to be made and the status is Scheduled + List DeploymentDescriptorsToRun = deploymentDescriptorService.getDeploymentsToInstantiate(); + // Foreach deployment + for (DeploymentDescriptor d : DeploymentDescriptorsToRun) { + // Launch the deployment + busController.deployExperiment(d ); + } + } + + public void checkAndTerminateExperimentToMANOProvider() { + logger.info("This will trigger the check and Terminate Deployments"); + // Check the database for a deployment to be completed in the next minutes + // If there is a deployment to be made and the status is Scheduled + List DeploymentDescriptorsToComplete = deploymentDescriptorService.getDeploymentsToBeCompleted(); + // Foreach deployment + for (DeploymentDescriptor deployment_descriptor_tmp : DeploymentDescriptorsToComplete) { + logger.debug("Deployment with id" + deployment_descriptor_tmp.getName() + " with status " + deployment_descriptor_tmp.getStatus() +" is going to be terminated"); + // Terminate the deployment + busController.completeExperiment(deployment_descriptor_tmp ); + } + } + + public void checkAndUpdateRunningDeploymentDescriptors() { + logger.info("Update Deployment Descriptors"); + List runningDeploymentDescriptors = deploymentDescriptorService.getRunningInstantiatingAndTerminatingDeployments(); + // For each deployment get the status info and the IPs + for (int i = 0; i < runningDeploymentDescriptors.size(); i++) { + DeploymentDescriptor deployment_tmp = deploymentDescriptorService.getDeploymentByIdEager(runningDeploymentDescriptors.get(i).getId()); + try { + // Get the MANO Provider for each deployment + MANOprovider sm = manoProviderService.getMANOproviderByID( getExperimOBD( deployment_tmp ).getObMANOprovider().getId() ); + } catch (Exception e) { + logger.error(e.getMessage()); + } + } + checkAndDeployExperimentToMANOProvider(); + checkAndTerminateExperimentToMANOProvider(); + checkAndDeleteTerminatedOrFailedDeployments(); + } + + private ExperimentOnBoardDescriptor getExperimOBD(DeploymentDescriptor deployment_tmp) { + for (ExperimentOnBoardDescriptor e : deployment_tmp.getExperimentFullDetails().getExperimentOnBoardDescriptors()) { + return e; //return the first one found + } + return null; + } + + public void onBoardNSDToMANOProvider( long uexpobdid ) throws Exception { + ExperimentOnBoardDescriptor uexpobd = nsdOBDService.getExperimentOnBoardDescriptorByID(uexpobdid); + + if (uexpobd == null) { + throw new Exception("uexpobd is NULL. Cannot load VxFOnBoardedDescriptor"); + } + + uexpobd.setOnBoardingStatus(OnBoardingStatus.ONBOARDING); + centralLogger.log( CLevel.INFO, "Onboarding status change of Experiment "+uexpobd.getExperiment().getName()+" to "+uexpobd.getOnBoardingStatus(), compname); + // This is the Deployment ID for the portal + uexpobd.setDeployId(UUID.randomUUID().toString()); + ExperimentMetadata em = uexpobd.getExperiment(); + if (em == null) { + em = (ExperimentMetadata) nsdService.getProductByID(uexpobd.getExperimentid()); + } + + /** + * The following is not OK. When we submit to OSMClient the createOnBoardPackage + * we just get a response something like response = {"output": + * {"transaction-id": "b2718ef9-4391-4a9e-97ad-826593d5d332"}} which does not + * provide any information. The OSM RIFTIO API says that we could get + * information about onboarding (create or update) jobs see + * https://open.riftio.com/documentation/riftware/4.4/a/api/orchestration/pkt-mgmt/rw-pkg-mgmt-download-jobs.htm + * with /api/operational/download-jobs, but this does not return pending jobs. + * So the only solution is to ask again OSM if something is installed or not, so + * for now the client (the portal ) must check via the + * getVxFOnBoardedDescriptorByIdCheckMANOProvider giving the VNF ID in OSM. OSM + * uses the ID of the yaml description Thus we asume that the vxf name can be + * equal to the VNF ID in the portal, and we use it for now as the OSM ID. Later + * in future, either OSM API provide more usefull response or we extract info + * from the VNFD package + * + */ + + //uexpobd.setVxfMANOProviderID(em.getName()); // Possible Error. This probably needs to be + uexpobd.setExperimentMANOProviderID(em.getName()); + + uexpobd.setLastOnboarding(new Date()); + + ExperimentOnBoardDescriptor uexpobds = nsdOBDService.updateExperimentOnBoardDescriptor(uexpobd); + if (uexpobds == null) { + throw new Exception("Cannot load NSDOnBoardedDescriptor"); + } + + String pLocation = em.getPackageLocation(); + logger.info("NSD Package Location: " + pLocation); + if (!pLocation.contains("http")) { + pLocation = propsService.getPropertyByName( "maindomain" ).getValue() + pLocation; + } +// if (!pLocation.contains("http")) { +// pLocation = "http:" + pLocation; +// pLocation = pLocation.replace("\\", "/"); +// } + + + } + + /** + * offBoard a VNF to MANO Provider, as described by this descriptor + * + * @param c + */ + public ResponseEntity offBoardVxFFromMANOProvider(VxFOnBoardedDescriptor obd) + throws HttpClientErrorException { + // TODO Auto-generated method stub + ResponseEntity response = null; + + + return response; + } + + private void checkVxFStatus(VxFOnBoardedDescriptor obd) throws Exception { + + CamelContext tempcontext = new DefaultCamelContext(); + MANOController mcontroller = this; + try { + RouteBuilder rb = new RouteBuilder() { + @Override + public void configure() throws Exception { + from("timer://getVNFRepoTimer?delay=2000&period=3000&repeatCount=6&daemon=true") + .log("Will check VNF repo").setBody().constant(obd) + .bean(mcontroller, "getVxFStatusFromOSM2Client"); + } + }; + tempcontext.addRoutes(rb); + tempcontext.start(); + Thread.sleep(30000); + } finally { + tempcontext.stop(); + } + + } + + + public ResponseEntity offBoardNSDFromMANOProvider(ExperimentOnBoardDescriptor uexpobd) { + // TODO Auto-generated method stub + ResponseEntity response = null; + + + // return new ResponseEntity<>("Not found", HttpStatus.NOT_FOUND); + return response; + } + + public void deployNSDToMANOProvider(int deploymentdescriptorid) { + DeploymentDescriptor deploymentdescriptor = deploymentDescriptorService.getDeploymentByIdEager(deploymentdescriptorid); + + logger.info("deploymentdescriptor.getExperimentFullDetails() = " + getExperimOBD(deploymentdescriptor) ); + logger.info("deploymentdescriptor.getExperimentFullDetails() = " + getExperimOBD(deploymentdescriptor).getObMANOprovider()); + + return; + } + + public void terminateNSFromMANOProvider(int deploymentdescriptorid) { + DeploymentDescriptor deploymentdescriptor = deploymentDescriptorService.getDeploymentByIdEager(deploymentdescriptorid); + + + } + + public void deleteNSFromMANOProvider(int deploymentdescriptorid) { + DeploymentDescriptor deploymentdescriptor = deploymentDescriptorService.getDeploymentByIdEager(deploymentdescriptorid); + + logger.info("Will delete with deploymentdescriptorid : " + deploymentdescriptorid); + String aMANOplatform = ""; + try { + aMANOplatform = getExperimOBD(deploymentdescriptor).getObMANOprovider().getSupportedMANOplatform().getName(); + logger.info("MANOplatform: " + aMANOplatform); + }catch (Exception e) { + aMANOplatform = "UNKNOWN"; + } + + + + + //if this is not a suported OSM then just complete + logger.info("Descriptor targets an older not supported OSM deploymentdescriptorid: " + deploymentdescriptorid); + deploymentdescriptor.setStatus(DeploymentDescriptorStatus.FAILED_OSM_REMOVED); + logger.info( "Status change of deployment " + deploymentdescriptor.getId()+", "+deploymentdescriptor.getName()+" to "+deploymentdescriptor.getStatus()); + DeploymentDescriptor deploymentdescriptor_final = deploymentDescriptorService.updateDeploymentDescriptor(deploymentdescriptor); + logger.info("NS status changed is now :" + deploymentdescriptor_final.getStatus()); + + } + // OSM5 END + +} diff --git a/src/main/java/portal/api/mano/MANORouteBuilder.java b/src/main/java/portal/api/mano/MANORouteBuilder.java new file mode 100644 index 0000000..d2d01a0 --- /dev/null +++ b/src/main/java/portal/api/mano/MANORouteBuilder.java @@ -0,0 +1,130 @@ +/*- + * ========================LICENSE_START================================= + * org.etsi.osl.portal.api + * %% + * Copyright (C) 2019 openslice.io + * %% + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * =========================LICENSE_END================================== + */ + + +package portal.api.mano; + +import org.apache.camel.CamelContext; +import org.apache.camel.builder.RouteBuilder; +import org.apache.camel.impl.DefaultCamelContext; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Configuration; +import org.springframework.stereotype.Component; + + +/** + * @author ctranoris + * + */ +@Component +@Configuration +public class MANORouteBuilder extends RouteBuilder{ + + + @Autowired + MANOController aMANOController; + + + public static void main(String[] args) throws Exception { + //new Main().run(args); + + + CamelContext tempcontext = new DefaultCamelContext(); + try { + RouteBuilder rb = new RouteBuilder() { + @Override + public void configure() throws Exception { + from( "timer://getVNFRepoTimer?period=2000&repeatCount=3&daemon=true" ) + .log( "Will check VNF repo"); + + from( "timer://getNSDRepoTimer?period=2000&repeatCount=3&daemon=true" ) + .log( "Will check NSD repo"); + } + }; + tempcontext.addRoutes( rb); + tempcontext.start(); + Thread.sleep(30000); + } finally { + tempcontext.stop(); + } + + + + + } + + + public void configure() { + + /** + * OnBoard New Added VxF + */ + //We get the message here and we need to route it to the proper point. + //If onboarding is successfull we need to send a Bugzilla message + //If it is unsuccessful we need to send another Bugzilla message + + //************************************************************************************ + // DISABLING THIS TO OFFLOAD THE CALL TO org.etsi.osl.mano + //from("seda:vxf.onboard?multipleConsumers=true") + //.doTry() + //.bean( aMANOController,"onBoardVxFToMANOProvider") //returns exception or nothing + //.log("VNFD Onboarded handled") + //.doCatch(Exception.class) + //.log("VNFD Onboarding failed!"); + // + //from("seda:nsd.onboard?multipleConsumers=true") + //.doTry() + //.bean( aMANOController,"onBoardNSDToMANOProvider") //returns exception or nothing + //.log("NSD Onboarded handled") + //.doCatch(Exception.class) + //.log("NSD Onboarding failed!"); + // + //************************************************************************************ + + from("seda:nsd.deploy?multipleConsumers=true") + .doTry() + .bean( aMANOController,"deployNSDToMANOProvider") //returns exception or nothing + .log("NS deployed handled").stop() + .doCatch(Exception.class) + .log("NS deployment failed!").stop(); + + from("seda:nsd.deployment.complete?multipleConsumers=true") + .doTry() + .bean( aMANOController,"terminateNSFromMANOProvider") //returns exception or nothing + .log("NS completed handled") + .doCatch(Exception.class) + .log("NS completion failed!").stop(); + + from("seda:nsd.deployment.delete?multipleConsumers=true") + .doTry() + .bean( aMANOController,"deleteNSFromMANOProvider") //returns exception or nothing + .log("NS deleted handled") + .doCatch(Exception.class) + .log("NS deletion failed!").stop(); + + //from("timer://checkAndDeployTimer?delay=2m&period=120000").bean( aMANOController,"checkAndDeployExperimentToMANOProvider").stop(); + //from("timer://checkAndTerminateTimer?delay=2m&period=120000").bean( aMANOController,"checkAndTerminateExperimentToMANOProvider").stop(); + + //from("timer://checkAndUpdateRunningDeploymentDescriptors?delay=1m&period=60000").bean( aMANOController,"checkAndUpdateRunningDeploymentDescriptors").stop(); + + } + + +} diff --git a/src/main/java/portal/api/mano/MANOService.java b/src/main/java/portal/api/mano/MANOService.java new file mode 100644 index 0000000..4afecbd --- /dev/null +++ b/src/main/java/portal/api/mano/MANOService.java @@ -0,0 +1,57 @@ +/*- + * ========================LICENSE_START================================= + * org.etsi.osl.portal.api + * %% + * Copyright (C) 2019 openslice.io + * %% + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * =========================LICENSE_END================================== + */ + + +package portal.api.mano; + +import java.util.List; + +import javax.persistence.EntityManager; +import javax.persistence.TypedQuery; + +import org.etsi.osl.model.MANOprovider; + + + +/** + * @author ctranoris + * + */ +public class MANOService { + protected EntityManager em; + + public MANOService(EntityManager em) + { + this.em=em; + } + + public List getAllMANOproviders() + { + TypedQuery query = em.createQuery("SELECT mp FROM MANOprovider mp",MANOprovider.class); + return query.getResultList(); + } + + public List getMANOprovidersEnabledForOnboarding() + { + TypedQuery query = em.createQuery("SELECT mp FROM MANOprovider mp WHERE mp.enabledForONBOARDING=1",MANOprovider.class); + return query.getResultList(); + } + +} diff --git a/src/main/java/portal/api/mano/MANOStatus.java b/src/main/java/portal/api/mano/MANOStatus.java new file mode 100644 index 0000000..4ba0262 --- /dev/null +++ b/src/main/java/portal/api/mano/MANOStatus.java @@ -0,0 +1,149 @@ +/*- + * ========================LICENSE_START================================= + * org.etsi.osl.portal.api + * %% + * Copyright (C) 2019 openslice.io + * %% + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * =========================LICENSE_END================================== + */ + + +package portal.api.mano; +import java.util.UUID; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Configuration; + +import portal.api.bus.BusController; + +/** + * @author ctranoris + * + */ +@Configuration +public class MANOStatus +{ + @Autowired + BusController busController; + + + //1: Active, 0:Failed + private static Status osm4CommunicationStatus = Status.Active; + private static String osm4CommunicationStatusUUID = null; + private static Status osm5CommunicationStatus = Status.Active; + private static String osm5CommunicationStatusUUID = null; + private static String message; + public static enum Status {Failed,Active}; + private static java.util.concurrent.locks.ReadWriteLock lock = new java.util.concurrent.locks.ReentrantReadWriteLock(); + + public static Status getOsm5CommunicationStatus() { + lock.readLock().lock(); + try { + return osm5CommunicationStatus; + } finally { + lock.readLock().unlock(); + } + } + + public static void setOsm5CommunicationStatus(Status osm5CommunicationStatus) { + lock.writeLock().lock(); + try { + MANOStatus.osm5CommunicationStatus = osm5CommunicationStatus; + } finally { + lock.writeLock().unlock(); + } + } + + public static String getOsm5CommunicationStatusUUID() { + lock.readLock().lock(); + try { + return osm5CommunicationStatusUUID; + } finally { + lock.readLock().unlock(); + } + } + + public static void setOsm5CommunicationStatusUUID(String osm5CommunicationStatusUUID) { + lock.writeLock().lock(); + try { + MANOStatus.osm5CommunicationStatusUUID = osm5CommunicationStatusUUID; + } finally { + lock.writeLock().unlock(); + } + } + + public static String getMessage() { + lock.readLock().lock(); + try { + return message; + } finally { + lock.readLock().unlock(); + } + } + + public static void setMessage(String message) { + lock.writeLock().lock(); + try { + MANOStatus.message = message; + } finally { + lock.writeLock().unlock(); + } + } + + + + + + public void setOsm5CommunicationStatusFailed(String message) { + lock.writeLock().lock(); + try { + if(message == null) + { + message=""; + } + if(MANOStatus.osm5CommunicationStatus == Status.Active) + { + MANOStatus.osm5CommunicationStatus = Status.Failed ; + MANOStatus.setMessage("OSM5 communication failed." + message); + MANOStatus.setOsm5CommunicationStatusUUID(UUID.randomUUID().toString()); + System.out.println("Inside setOSM5CommunicationStatusFailed. "+MANOStatus.getOsm5CommunicationStatusUUID().toString()+","+MANOStatus.getMessage().toString()); + busController.osm5CommunicationFailed(MANOStatus.class); + } + } finally { + lock.writeLock().unlock(); + } + } + + + + public void setOsm5CommunicationStatusActive(String message) { + lock.writeLock().lock(); + try { + // TODO Auto-generated method stub + if(message == null) + { + message=""; + } + if(MANOStatus.osm5CommunicationStatus == Status.Failed) + { + MANOStatus.osm5CommunicationStatus = Status.Active ; + MANOStatus.setMessage("OSM5 communication restored." + message); + busController.osm5CommunicationRestored(MANOStatus.class); + } + } finally { + lock.writeLock().unlock(); + } + } +} + diff --git a/src/main/java/portal/api/mano/NSCreateInstanceRequestPayload.java b/src/main/java/portal/api/mano/NSCreateInstanceRequestPayload.java new file mode 100644 index 0000000..8909afe --- /dev/null +++ b/src/main/java/portal/api/mano/NSCreateInstanceRequestPayload.java @@ -0,0 +1,40 @@ +/*- + * ========================LICENSE_START================================= + * org.etsi.osl.portal.api + * %% + * Copyright (C) 2019 openslice.io + * %% + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * =========================LICENSE_END================================== + */ + + +package portal.api.mano; + +import org.etsi.osl.model.DeploymentDescriptor; + +/** + * @author ctranoris + * + */ +public class NSCreateInstanceRequestPayload extends NSInstantiateInstanceRequestPayload +{ + public String notificationType="NsIdentifierCreationNotification"; + + + public NSCreateInstanceRequestPayload(DeploymentDescriptor deploymentdescriptor) + { + super(deploymentdescriptor); + } +} + diff --git a/src/main/java/portal/api/mano/NSInstantiateInstanceRequestPayload.java b/src/main/java/portal/api/mano/NSInstantiateInstanceRequestPayload.java new file mode 100644 index 0000000..6c64cc6 --- /dev/null +++ b/src/main/java/portal/api/mano/NSInstantiateInstanceRequestPayload.java @@ -0,0 +1,103 @@ +/*- + * ========================LICENSE_START================================= + * org.etsi.osl.portal.api + * %% + * Copyright (C) 2019 openslice.io + * %% + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * =========================LICENSE_END================================== + */ + + +package portal.api.mano; + +import java.util.ArrayList; +import java.util.LinkedHashMap; +import java.util.List; + +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; + +import org.etsi.osl.model.DeploymentDescriptor; +import org.etsi.osl.model.DeploymentDescriptorVxFPlacement; +import org.etsi.osl.model.ExperimentOnBoardDescriptor; + +/** + * @author ctranoris + * + */ +public class NSInstantiateInstanceRequestPayload { + public String nsName; + public String vimAccountId; + public String nsdId; + + class VnF { + @JsonProperty("member-vnf-index") + public String memberVnFIndex; + @JsonProperty("vimAccountId") + public String vimAccount; + } + + class Vld { + public String name; + @JsonProperty("vim-network-name") + public LinkedHashMap vimNetworkName = new LinkedHashMap<>(); + } + + public List vnf = new ArrayList<>(); + // public List vld = new ArrayList<>(); + + public NSInstantiateInstanceRequestPayload(DeploymentDescriptor deploymentdescriptor) { + this.nsName = deploymentdescriptor.getName(); + this.vimAccountId = deploymentdescriptor.getInfrastructureForAll().getVIMid(); + // Here we need to get the ExperimentOnBoardDescriptor based on the Experiment. + // An Experiment might have multiple OnBoardDescriptors if it is OnBoarded to + // multiple OSM MANOs. + // We temporarily select the first (and most probably the only one). + // Otherwise the user needs to define the OSM MANO where the Experiment is + // OnBoarded in order to instantiate. + this.nsdId = getExperimOBD(deploymentdescriptor).getDeployId(); + + Integer count = 1; + for (DeploymentDescriptorVxFPlacement tmp : deploymentdescriptor.getVxfPlacements()) { + VnF vnf_tmp = new VnF(); + vnf_tmp.memberVnFIndex = count.toString(); + vnf_tmp.vimAccount = tmp.getInfrastructure().getVIMid(); + this.vnf.add(vnf_tmp); + count++; + } + } + + private ExperimentOnBoardDescriptor getExperimOBD(DeploymentDescriptor deployment_tmp) { + + for (ExperimentOnBoardDescriptor e : deployment_tmp.getExperimentFullDetails() + .getExperimentOnBoardDescriptors()) { + + return e; // return the first one found + } + return null; + } + + public String toJSON() { + String jsonInString = null; + ObjectMapper mapper = new ObjectMapper(); + try { + jsonInString = mapper.writeValueAsString(this); + } catch (JsonProcessingException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + return jsonInString; + } +} diff --git a/src/main/java/portal/api/repo/CategoriesRepository.java b/src/main/java/portal/api/repo/CategoriesRepository.java new file mode 100644 index 0000000..da3ee6f --- /dev/null +++ b/src/main/java/portal/api/repo/CategoriesRepository.java @@ -0,0 +1,35 @@ +/*- + * ========================LICENSE_START================================= + * org.etsi.osl.portal.api + * %% + * Copyright (C) 2019 openslice.io + * %% + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * =========================LICENSE_END================================== + */ +package portal.api.repo; + +import org.springframework.data.repository.CrudRepository; +import org.springframework.stereotype.Repository; + +import org.etsi.osl.model.Category; + + +/** + * @author ctranoris + * + */ +@Repository +public interface CategoriesRepository extends CrudRepository { + +} diff --git a/src/main/java/portal/api/repo/DeploymentDescriptorRepository.java b/src/main/java/portal/api/repo/DeploymentDescriptorRepository.java new file mode 100644 index 0000000..e9b0748 --- /dev/null +++ b/src/main/java/portal/api/repo/DeploymentDescriptorRepository.java @@ -0,0 +1,178 @@ +/*- + * ========================LICENSE_START================================= + * org.etsi.osl.portal.api + * %% + * Copyright (C) 2019 openslice.io + * %% + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * =========================LICENSE_END================================== + */ +package portal.api.repo; + +import java.util.List; + +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.CrudRepository; +import org.springframework.stereotype.Repository; + +import org.etsi.osl.model.DeploymentDescriptor; + + +/** + * @author ctranoris + * + */ +@Repository +public interface DeploymentDescriptorRepository extends CrudRepository { + + + @Query( value = "SELECT m FROM DeploymentDescriptor m WHERE " + + "( m.status=org.etsi.osl.model.DeploymentDescriptorStatus.COMPLETED " + + " OR m.status=org.etsi.osl.model.DeploymentDescriptorStatus.TERMINATED )" + + "ORDER BY m.id" ) + List getAllCompletedDeploymentDescriptors(); + + @Query( value = "SELECT m FROM DeploymentDescriptor m WHERE " + + "m.status=org.etsi.osl.model.DeploymentDescriptorStatus.REJECTED ORDER BY m.id" ) + List getAllRejectedDeploymentDescriptors(); + + @Query( value = "SELECT m FROM DeploymentDescriptor m WHERE " + + "( m.status=org.etsi.osl.model.DeploymentDescriptorStatus.FAILED ) " + + " ORDER BY m.id") + List getAllFailedDeploymentDescriptors(); + + @Query( value = "SELECT m FROM DeploymentDescriptor m WHERE " + + "( m.status=org.etsi.osl.model.DeploymentDescriptorStatus.FAILED " + + " OR m.status=org.etsi.osl.model.DeploymentDescriptorStatus.FAILED_OSM_REMOVED " + + " OR m.status=org.etsi.osl.model.DeploymentDescriptorStatus.DELETION_FAILED " + + " OR m.status=org.etsi.osl.model.DeploymentDescriptorStatus.TERMINATION_FAILED ) " + + " ORDER BY m.id") + List getAllRemovedDeploymentDescriptors(); + + @Query(value = "SELECT m FROM DeploymentDescriptor m " + + " WHERE m.status<>org.etsi.osl.model.DeploymentDescriptorStatus.COMPLETED " + + " AND m.status<>org.etsi.osl.model.DeploymentDescriptorStatus.TERMINATED " + + " AND m.status<>org.etsi.osl.model.DeploymentDescriptorStatus.REJECTED " + + " AND m.status<>org.etsi.osl.model.DeploymentDescriptorStatus.FAILED " + + " AND m.status<>org.etsi.osl.model.DeploymentDescriptorStatus.DELETION_FAILED " + + " AND m.status<>org.etsi.osl.model.DeploymentDescriptorStatus.TERMINATION_FAILED " + + " AND m.status<>org.etsi.osl.model.DeploymentDescriptorStatus.FAILED_OSM_REMOVED " + + " ORDER BY m.id") + List readDeploymentDescriptors(); + + @Query( value = "SELECT m FROM DeploymentDescriptor m WHERE m.owner.id=?1" + + " AND (m.status=org.etsi.osl.model.DeploymentDescriptorStatus.COMPLETED " + + " OR m.status=org.etsi.osl.model.DeploymentDescriptorStatus.TERMINATED ) " + + " ORDER BY m.id" ) + List getAllByUserCompleted(long id); + + @Query( value = "SELECT m FROM DeploymentDescriptor m WHERE m.owner.id=?1" + + " AND m.status=org.etsi.osl.model.DeploymentDescriptorStatus.REJECTED ORDER BY m.id") + List getAllByUserRejected(long id); + + @Query( value = "SELECT m FROM DeploymentDescriptor m WHERE m.owner.id=?1" + + " AND ( m.status=org.etsi.osl.model.DeploymentDescriptorStatus.FAILED_OSM_REMOVED " + + " OR m.status=org.etsi.osl.model.DeploymentDescriptorStatus.FAILED" + + " OR m.status=org.etsi.osl.model.DeploymentDescriptorStatus.DELETION_FAILED " + + " OR m.status=org.etsi.osl.model.DeploymentDescriptorStatus.TERMINATION_FAILED ) " + + " ORDER BY m.id") + List getAllByUserFAILED_OSM_REMOVEDd(long id); + + @Query( value = "SELECT m FROM DeploymentDescriptor m WHERE m.owner.id=?1" + + " AND m.status<>org.etsi.osl.model.DeploymentDescriptorStatus.COMPLETED " + + " AND m.status<>org.etsi.osl.model.DeploymentDescriptorStatus.TERMINATED " + + " AND m.status<>org.etsi.osl.model.DeploymentDescriptorStatus.REJECTED " + + " AND m.status<>org.etsi.osl.model.DeploymentDescriptorStatus.FAILED " + + " AND m.status<>org.etsi.osl.model.DeploymentDescriptorStatus.DELETION_FAILED " + + " AND m.status<>org.etsi.osl.model.DeploymentDescriptorStatus.TERMINATION_FAILED " + + " AND m.status<>org.etsi.osl.model.DeploymentDescriptorStatus.FAILED_OSM_REMOVED " + + " ORDER BY m.id") + List getAllByUserStatusUnknown(long id); + + @Query( value = "SELECT m FROM DeploymentDescriptor m WHERE m.owner.id=?1" + + " AND m.status=org.etsi.osl.model.DeploymentDescriptorStatus.FAILED" + + " ORDER BY m.id") + List getAllByUserFAILED(long id); + + + + @Query( value = "SELECT m FROM DeploymentDescriptor m WHERE " + + "( m.mentor.id=?1 OR m.owner.id=?1)" + + " AND (m.status=org.etsi.osl.model.DeploymentDescriptorStatus.COMPLETED " + + " OR m.status=org.etsi.osl.model.DeploymentDescriptorStatus.TERMINATED ) " + + " ORDER BY m.id") + List getAllByMentorCompleted(long id); + + @Query( value = "SELECT m FROM DeploymentDescriptor m WHERE " + + "( m.mentor.id=?1 OR m.owner.id=?1)" + + " AND m.status=org.etsi.osl.model.DeploymentDescriptorStatus.REJECTED ORDER BY m.id" ) + List getAllByMentorRejected(long id); + + @Query( value = "SELECT m FROM DeploymentDescriptor m WHERE " + + "( m.mentor.id=?1 OR m.owner.id=?1)" + + " AND m.status=org.etsi.osl.model.DeploymentDescriptorStatus.FAILED" + + " ORDER BY m.id") + List getAllByMentorFAILED(long id); + + @Query( value = "SELECT m FROM DeploymentDescriptor m WHERE " + + "( m.mentor.id=?1 OR m.owner.id=?1)" + + " AND ( m.status=org.etsi.osl.model.DeploymentDescriptorStatus.FAILED_OSM_REMOVED " + + " OR m.status=org.etsi.osl.model.DeploymentDescriptorStatus.DELETION_FAILED " + + " OR m.status=org.etsi.osl.model.DeploymentDescriptorStatus.TERMINATION_FAILED ) " + + " ORDER BY m.id") + List getAllByMentorFAILED_OSM_REMOVEDd(long id); + + @Query( value = "SELECT m FROM DeploymentDescriptor m WHERE " + + "( m.mentor.id=?1 OR m.owner.id=?1)" + + " AND m.status<>org.etsi.osl.model.DeploymentDescriptorStatus.COMPLETED " + + " AND m.status<>org.etsi.osl.model.DeploymentDescriptorStatus.TERMINATED " + + " AND m.status<>org.etsi.osl.model.DeploymentDescriptorStatus.REJECTED " + + " AND m.status<>org.etsi.osl.model.DeploymentDescriptorStatus.FAILED " + + " AND m.status<>org.etsi.osl.model.DeploymentDescriptorStatus.DELETION_FAILED " + + " AND m.status<>org.etsi.osl.model.DeploymentDescriptorStatus.TERMINATION_FAILED " + + " AND m.status<>org.etsi.osl.model.DeploymentDescriptorStatus.FAILED_OSM_REMOVED " + + "ORDER BY m.id") + List getAllByMentorStatusUnknown(long id); + + @Query( value = "SELECT m FROM DeploymentDescriptor m WHERE m.status=org.etsi.osl.model.DeploymentDescriptorStatus.SCHEDULED ORDER BY m.id" ) + List getAllScheduled(); + + + @Query( value = "SELECT m FROM DeploymentDescriptor m WHERE m.status = org.etsi.osl.model.DeploymentDescriptorStatus.TERMINATED " + + "OR m.status = org.etsi.osl.model.DeploymentDescriptorStatus.FAILED " + + "OR m.status = org.etsi.osl.model.DeploymentDescriptorStatus.TERMINATION_FAILED") + List readDeploymentsToBeDeleted(); + + @Query( value = "SELECT m FROM DeploymentDescriptor m") + List readAllDeployments(); + + @Query( value = "SELECT m FROM DeploymentDescriptor m WHERE m.status = org.etsi.osl.model.DeploymentDescriptorStatus.SCHEDULED") + List readScheduledDeployments(); + + @Query( value = "SELECT m FROM DeploymentDescriptor m WHERE m.status = org.etsi.osl.model.DeploymentDescriptorStatus.RUNNING " + + "OR m.status = org.etsi.osl.model.DeploymentDescriptorStatus.INSTANTIATING " + + "OR m.status = org.etsi.osl.model.DeploymentDescriptorStatus.TERMINATING") + List readRunningInstantiatingDeployments(); + + @Query( value = "SELECT m FROM DeploymentDescriptor m WHERE m.status = org.etsi.osl.model.DeploymentDescriptorStatus.RUNNING " + + "OR m.status = org.etsi.osl.model.DeploymentDescriptorStatus.INSTANTIATING " + + "OR m.status = org.etsi.osl.model.DeploymentDescriptorStatus.TERMINATING") + List readRunningInstantiatingAndTerminatingDeployments(); + + @Query( value = "SELECT m FROM DeploymentDescriptor m WHERE m.experiment.id = ?1") + List readDeploymentsByExperimentID(long id); + + @Query( value = "SELECT m FROM DeploymentDescriptor m WHERE m.instanceId = ?1") + DeploymentDescriptor readDeploymentByInstanceID(String id); + +} diff --git a/src/main/java/portal/api/repo/InfrastructureRepository.java b/src/main/java/portal/api/repo/InfrastructureRepository.java new file mode 100644 index 0000000..d12b966 --- /dev/null +++ b/src/main/java/portal/api/repo/InfrastructureRepository.java @@ -0,0 +1,37 @@ +/*- + * ========================LICENSE_START================================= + * org.etsi.osl.portal.api + * %% + * Copyright (C) 2019 openslice.io + * %% + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * =========================LICENSE_END================================== + */ +package portal.api.repo; + +import org.springframework.data.repository.CrudRepository; +import org.springframework.stereotype.Repository; + +import org.etsi.osl.model.Infrastructure; + + +/** + * @author ctranoris + * + */ +@Repository +public interface InfrastructureRepository extends CrudRepository { + + + +} diff --git a/src/main/java/portal/api/repo/ManoPlatformRepository.java b/src/main/java/portal/api/repo/ManoPlatformRepository.java new file mode 100644 index 0000000..51fb87f --- /dev/null +++ b/src/main/java/portal/api/repo/ManoPlatformRepository.java @@ -0,0 +1,36 @@ +/*- + * ========================LICENSE_START================================= + * org.etsi.osl.portal.api + * %% + * Copyright (C) 2019 openslice.io + * %% + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * =========================LICENSE_END================================== + */ +package portal.api.repo; + +import org.springframework.data.repository.CrudRepository; +import org.springframework.stereotype.Repository; + +import org.etsi.osl.model.MANOplatform; + + +/** + * @author ctranoris + * + */ +@Repository +public interface ManoPlatformRepository extends CrudRepository { + + +} diff --git a/src/main/java/portal/api/repo/ManoProvidersRepository.java b/src/main/java/portal/api/repo/ManoProvidersRepository.java new file mode 100644 index 0000000..3182731 --- /dev/null +++ b/src/main/java/portal/api/repo/ManoProvidersRepository.java @@ -0,0 +1,46 @@ +/*- + * ========================LICENSE_START================================= + * org.etsi.osl.portal.api + * %% + * Copyright (C) 2019 openslice.io + * %% + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * =========================LICENSE_END================================== + */ +package portal.api.repo; + +import java.util.Collection; + +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.CrudRepository; +import org.springframework.data.repository.PagingAndSortingRepository; +import org.springframework.stereotype.Repository; + +import org.etsi.osl.model.Category; +import org.etsi.osl.model.MANOprovider; + + +/** + * @author ctranoris + * + */ +@Repository +public interface ManoProvidersRepository extends CrudRepository { + + @Query( value="SELECT mp FROM MANOprovider mp WHERE mp.enabledForONBOARDING = TRUE") + Collection findAllEnabled(); + + @Query( value="SELECT mp FROM MANOprovider mp WHERE mp.enabledForSYNC = TRUE") + Collection findAllEnabledForSync(); + +} diff --git a/src/main/java/portal/api/repo/NSDOBDRepository.java b/src/main/java/portal/api/repo/NSDOBDRepository.java new file mode 100644 index 0000000..d6756bb --- /dev/null +++ b/src/main/java/portal/api/repo/NSDOBDRepository.java @@ -0,0 +1,37 @@ +/*- + * ========================LICENSE_START================================= + * org.etsi.osl.portal.api + * %% + * Copyright (C) 2019 openslice.io + * %% + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * =========================LICENSE_END================================== + */ +package portal.api.repo; + +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.CrudRepository; +import org.springframework.stereotype.Repository; + +import org.etsi.osl.model.ExperimentOnBoardDescriptor; + +/** + * @author ctranoris + * + */ +@Repository +public interface NSDOBDRepository extends CrudRepository { + + @Query( value ="SELECT a FROM ExperimentOnBoardDescriptor a WHERE a.deployId=?1" ) + ExperimentOnBoardDescriptor findByDeployId(String deployId); +} diff --git a/src/main/java/portal/api/repo/NSDsRepository.java b/src/main/java/portal/api/repo/NSDsRepository.java new file mode 100644 index 0000000..188dee3 --- /dev/null +++ b/src/main/java/portal/api/repo/NSDsRepository.java @@ -0,0 +1,69 @@ +/*- + * ========================LICENSE_START================================= + * org.etsi.osl.portal.api + * %% + * Copyright (C) 2019 openslice.io + * %% + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * =========================LICENSE_END================================== + */ +package portal.api.repo; + +import java.util.Collection; +import java.util.Optional; + +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.CrudRepository; +import org.springframework.stereotype.Repository; + +import org.etsi.osl.model.ExperimentMetadata; + + +/** + * @author ctranoris + * + */ +@Repository +public interface NSDsRepository extends CrudRepository { + + + @Query( value = "SELECT a FROM ExperimentMetadata a JOIN a.categories ac WHERE a.published=TRUE AND ac.id=?1 ORDER BY a.name" ) // + Collection getPublishedNSDsByCategory(Long categoryid); + + @Query( value = "SELECT a FROM ExperimentMetadata a WHERE a.published=TRUE ORDER BY a.name" ) // + Collection getPublishedNSDs(); + + @Query( value = "SELECT a FROM ExperimentMetadata a JOIN a.categories ac WHERE ac.id=?1 ORDER BY a.name" ) // + Collection getNSDsByCategory(Long categoryid); + + @Query( value ="SELECT a FROM ExperimentMetadata a WHERE a.owner.id=?1 ORDER BY a.id" ) + Collection getNSDsByUserID(long userid); + + @Query( value ="SELECT a FROM ExperimentMetadata a WHERE a.uuid=?1" ) + Optional findByUUID(String uuid); + + @Query( value ="SELECT a FROM ExperimentMetadata a WHERE a.name LIKE ?1" ) + Optional findByName(String name); + + @Query( value ="SELECT a FROM ExperimentMetadata a WHERE a.id LIKE ?1" ) + Optional findById(long id); + + @Query( value ="SELECT e FROM ExperimentMetadata e JOIN FETCH e.experimentOnBoardDescriptors " + + "JOIN FETCH e.experimentOnBoardDescriptors obd " + + "JOIN FETCH e.constituentVxF cvxf " + + "JOIN FETCH obd.obMANOprovider " + + "WHERE e.id = ?1" ) + Optional findByIdEager(long id); + + +} diff --git a/src/main/java/portal/api/repo/PortalPropertiesRepository.java b/src/main/java/portal/api/repo/PortalPropertiesRepository.java new file mode 100644 index 0000000..ff90483 --- /dev/null +++ b/src/main/java/portal/api/repo/PortalPropertiesRepository.java @@ -0,0 +1,39 @@ +/*- + * ========================LICENSE_START================================= + * org.etsi.osl.portal.api + * %% + * Copyright (C) 2019 openslice.io + * %% + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * =========================LICENSE_END================================== + */ +package portal.api.repo; + +import java.util.Optional; + +import org.springframework.data.repository.CrudRepository; +import org.springframework.stereotype.Repository; + +import org.etsi.osl.model.PortalProperty; + +/** + * @author ctranoris + * + */ +@Repository +public interface PortalPropertiesRepository extends CrudRepository { + + Optional findByName(String aname); + + +} diff --git a/src/main/java/portal/api/repo/ProductRepository.java b/src/main/java/portal/api/repo/ProductRepository.java new file mode 100644 index 0000000..ccb478e --- /dev/null +++ b/src/main/java/portal/api/repo/ProductRepository.java @@ -0,0 +1,44 @@ +/*- + * ========================LICENSE_START================================= + * org.etsi.osl.portal.api + * %% + * Copyright (C) 2019 openslice.io + * %% + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * =========================LICENSE_END================================== + */ +package portal.api.repo; + +import java.util.Optional; + +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.CrudRepository; +import org.springframework.stereotype.Repository; + +import org.etsi.osl.model.Product; + + +/** + * @author ctranoris + * + */ +@Repository +public interface ProductRepository extends CrudRepository { + + + @Query( value ="SELECT a FROM Product a WHERE a.uuid=?1" ) + Optional findByUUID(String uuid); + + + +} diff --git a/src/main/java/portal/api/repo/UsersRepository.java b/src/main/java/portal/api/repo/UsersRepository.java new file mode 100644 index 0000000..c711c36 --- /dev/null +++ b/src/main/java/portal/api/repo/UsersRepository.java @@ -0,0 +1,56 @@ +/*- + * ========================LICENSE_START================================= + * org.etsi.osl.portal.api + * %% + * Copyright (C) 2019 openslice.io + * %% + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * =========================LICENSE_END================================== + */ +package portal.api.repo; + +import java.util.Collection; +import java.util.Optional; + +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.CrudRepository; +import org.springframework.stereotype.Repository; + +import org.etsi.osl.model.PortalUser; + +/** + * + * @author ctranoris + * @see + * https://www.amitph.com/spring-data-jpa-query-methods/, + * https://www.amitph.com/pagination-sorting-spring-data-jpa/, + * https://www.baeldung.com/spring-data-jpa-query, + * for usefull methods on spring repository + * + * + */ +@Repository +public interface UsersRepository extends CrudRepository { + + PortalUser findDistinctFirstByUsername( String username ); + + @Query( value = "SELECT m FROM PortalUser m INNER JOIN m.roles r WHERE r = 'ROLE_MENTOR'" ) // + Collection findAllMentors(); + + Optional findByUsername(String username); + + Optional findByEmail(String email); + + + +} diff --git a/src/main/java/portal/api/repo/VFImageRepository.java b/src/main/java/portal/api/repo/VFImageRepository.java new file mode 100644 index 0000000..8d8ee02 --- /dev/null +++ b/src/main/java/portal/api/repo/VFImageRepository.java @@ -0,0 +1,47 @@ +/*- + * ========================LICENSE_START================================= + * org.etsi.osl.portal.api + * %% + * Copyright (C) 2019 openslice.io + * %% + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * =========================LICENSE_END================================== + */ +package portal.api.repo; + +import java.util.Collection; +import java.util.Optional; + +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.CrudRepository; +import org.springframework.stereotype.Repository; + +import org.etsi.osl.model.VFImage; + + +/** + * @author ctranoris + * + */ +@Repository +public interface VFImageRepository extends CrudRepository { + + + @Query( value ="SELECT a FROM VFImage a WHERE a.name LIKE ?1" ) + Optional findByName(String name); + + + @Query( value ="SELECT a FROM VFImage a JOIN a.owner aon WHERE aon.id LIKE ?1" ) + Collection findAllByUserid(long id); + +} diff --git a/src/main/java/portal/api/repo/VxFOBDRepository.java b/src/main/java/portal/api/repo/VxFOBDRepository.java new file mode 100644 index 0000000..a545c20 --- /dev/null +++ b/src/main/java/portal/api/repo/VxFOBDRepository.java @@ -0,0 +1,49 @@ +/*- + * ========================LICENSE_START================================= + * org.etsi.osl.portal.api + * %% + * Copyright (C) 2019 openslice.io + * %% + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * =========================LICENSE_END================================== + */ +package portal.api.repo; + +import java.util.List; + +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.CrudRepository; +import org.springframework.stereotype.Repository; + +import org.etsi.osl.model.MANOprovider; +import org.etsi.osl.model.VxFOnBoardedDescriptor; + +/** + * @author ctranoris + * + */ +@Repository +public interface VxFOBDRepository extends CrudRepository { + + @Query( value ="SELECT a FROM VxFOnBoardedDescriptor a WHERE a.vxfMANOProviderID=?1 and a.obMANOprovider=?2 and a.onBoardingStatus=2" ) + VxFOnBoardedDescriptor findByVxFAndMP(String vxf, MANOprovider mp); + + @Query( value ="SELECT a FROM VxFOnBoardedDescriptor a WHERE a.obMANOprovider=?1" ) + List findByMP(MANOprovider mp); + + @Query( value ="SELECT a FROM VxFOnBoardedDescriptor a WHERE 1=1" ) + List findAll(); + + @Query( value ="SELECT a FROM VxFOnBoardedDescriptor a WHERE a.vxfMANOProviderID=?1 and a.obMANOprovider=?2" ) + VxFOnBoardedDescriptor VxFIdByVxFMANOProviderIDAndMP(String vxf_id, MANOprovider mp); +} diff --git a/src/main/java/portal/api/repo/VxFsRepository.java b/src/main/java/portal/api/repo/VxFsRepository.java new file mode 100644 index 0000000..0de98ac --- /dev/null +++ b/src/main/java/portal/api/repo/VxFsRepository.java @@ -0,0 +1,61 @@ +/*- + * ========================LICENSE_START================================= + * org.etsi.osl.portal.api + * %% + * Copyright (C) 2019 openslice.io + * %% + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * =========================LICENSE_END================================== + */ +package portal.api.repo; + +import java.util.Collection; +import java.util.Optional; + +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.CrudRepository; +import org.springframework.stereotype.Repository; + +import org.etsi.osl.model.VxFMetadata; + + +/** + * @author ctranoris + * + */ +@Repository +public interface VxFsRepository extends CrudRepository { + + + @Query( value = "SELECT a FROM VxFMetadata a JOIN a.categories ac WHERE a.published=TRUE AND ac.id=?1 ORDER BY a.name" ) // + Collection getPublishedVxFsByCategory(long categoryid); + + @Query( value = "SELECT a FROM VxFMetadata a WHERE a.published=TRUE ORDER BY a.name" ) // + Collection getPublishedVxF(); + + @Query( value ="SELECT a FROM VxFMetadata a WHERE a.owner.id=?1 ORDER BY a.id" ) + Collection getVxFsByUserID(long userid); + + @Query( value = "SELECT a FROM VxFMetadata a JOIN a.categories ac WHERE ac.id=?1 ORDER BY a.name" ) // + Collection getVxFsByCategory(long categoryid); + + @Query( value ="SELECT a FROM VxFMetadata a WHERE a.uuid=?1" ) + Optional findByUUID(String uuid); + + @Query( value ="SELECT a FROM VxFMetadata a WHERE a.name LIKE ?1" ) + Optional findByName(String name); + + @Query( value ="SELECT a FROM VxFMetadata a WHERE a.name LIKE ?1" ) + Collection findAllByName(String name); + +} diff --git a/src/main/java/portal/api/service/CategoryService.java b/src/main/java/portal/api/service/CategoryService.java new file mode 100644 index 0000000..4495b5c --- /dev/null +++ b/src/main/java/portal/api/service/CategoryService.java @@ -0,0 +1,103 @@ +/*- + * ========================LICENSE_START================================= + * org.etsi.osl.portal.api + * %% + * Copyright (C) 2019 openslice.io + * %% + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * =========================LICENSE_END================================== + */ +package portal.api.service; + +import java.util.List; +import java.util.Optional; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import org.etsi.osl.model.Category; +import jakarta.annotation.PostConstruct; +import portal.api.repo.CategoriesRepository; + + +/** + * @author ctranoris + * + */ +@Service +public class CategoryService { + + + @Autowired + CategoriesRepository categsRepo; + + + private static final transient Log logger = LogFactory.getLog( CategoryService.class.getName() ); + + + public CategoryService() { + super(); + + } + + @PostConstruct + public void initRepo() { + + Category c = null; + try { + c = findById(1); + logger.info("======================== catgegory = " + c); + } catch (Exception e) { + logger.info("======================== catgegory NOT FOUND, initializing"); + } + + if (c == null) { + + c = new Category(); + c.setName("None"); + categsRepo.save( c ); + c = new Category(); + c.setName("Networking"); + categsRepo.save( c ); + c = new Category(); + c.setName("Service"); + categsRepo.save( c ); + + } + } + + public List findAll() { + return (List) this.categsRepo.findAll(); // findAll(new Sort(Sort.Direction.ASC, "name")); + } + + public Category addCategory(Category c) { + return this.categsRepo.save( c ); + } + + public Category findById(long catid) { + Optional optionalCat = this.categsRepo.findById( catid ); + return optionalCat + .orElse(null); + } + + public Category updateCategoryInfo(Category c) { + return this.categsRepo.save( c ); + } + + public void deleteCategory(Category c) { + this.categsRepo.delete(c); + + } +} diff --git a/src/main/java/portal/api/service/DeploymentDescriptorService.java b/src/main/java/portal/api/service/DeploymentDescriptorService.java new file mode 100644 index 0000000..5b78a1e --- /dev/null +++ b/src/main/java/portal/api/service/DeploymentDescriptorService.java @@ -0,0 +1,660 @@ +/*- + * ========================LICENSE_START================================= + * org.etsi.osl.portal.api + * %% + * Copyright (C) 2019 openslice.io + * %% + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * =========================LICENSE_END================================== + */ +package portal.api.service; + +import java.time.OffsetDateTime; +import java.time.ZoneOffset; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; +import java.util.Optional; +import java.util.UUID; + + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.datatype.hibernate5.jakarta.Hibernate5JakartaModule; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.etsi.osl.centrallog.client.CLevel; +import org.etsi.osl.centrallog.client.CentralLogger; +import org.hibernate.Hibernate; +import org.hibernate.Session; +import org.hibernate.SessionFactory; +import org.hibernate.Transaction; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import org.etsi.osl.model.ConstituentVxF; +import org.etsi.osl.model.DeploymentDescriptor; +import org.etsi.osl.model.DeploymentDescriptorStatus; +import org.etsi.osl.model.DeploymentDescriptorVxFPlacement; +import org.etsi.osl.model.ExperimentMetadata; +import org.etsi.osl.model.ExperimentOnBoardDescriptor; +import org.etsi.osl.model.Infrastructure; +import org.etsi.osl.model.MANOprovider; +import org.etsi.osl.model.PortalUser; +import jakarta.persistence.EntityManagerFactory; +//import portal.api.centrallog.CLevel; +//import portal.api.centrallog.CentralLogger; +import portal.api.repo.DeploymentDescriptorRepository; + +@Service +public class DeploymentDescriptorService { + + @Autowired + DeploymentDescriptorRepository ddRepo; + + @Autowired + UsersService usersService; + + @Autowired + NSDService nsdService; + + @Autowired + VxFOBDService vxfOBDService; + + @Autowired + InfrastructureService infrastructureService; + + + + @Autowired + NSDOBDService nsdOBDService; + + @Autowired + ManoProviderService manoProviderService; + + + @Value("${spring.application.name}") + private String compname; + + + @Autowired + VxFService vxfService; + + private SessionFactory sessionFactory; + + @Autowired + private CentralLogger centralLogger; + + + + private static final transient Log logger = LogFactory.getLog( DeploymentDescriptorService.class.getName()); + + + /** + * from https://stackoverflow.com/questions/25063995/spring-boot-handle-to-hibernate-sessionfactory + * @param factory + */ + @Autowired + public DeploymentDescriptorService(EntityManagerFactory factory) { + if(factory.unwrap(SessionFactory.class) == null){ + throw new NullPointerException("factory is not a hibernate factory"); + } + this.sessionFactory = factory.unwrap(SessionFactory.class); + } + + + + public List getAllCompletedDeploymentDescriptors() { + return this.ddRepo.getAllCompletedDeploymentDescriptors(); + } + + + + + public List getAllRejectedDeploymentDescriptors() { + return this.ddRepo.getAllRejectedDeploymentDescriptors(); + } + + + + + public List getAllFailedDeploymentDescriptors() { + return this.ddRepo.getAllFailedDeploymentDescriptors(); + } + + + + + public List getAllRemovedDeploymentDescriptors() { + return this.ddRepo.getAllRemovedDeploymentDescriptors(); + } + + + + + public List getAllDeploymentDescriptors() { + return (List) this.ddRepo.readDeploymentDescriptors(); + } + + + + public List getAllDeploymentDescriptorsByUser(long id, String status) { + + if ( (status!=null) && status.equals("COMPLETED") ){ + return this.ddRepo.getAllByUserCompleted( id ); + }else if ( (status!=null) && status.equals("REJECTED") ){ + return this.ddRepo.getAllByUserRejected( id ); + }else if ( (status!=null) && status.equals("FAILED") ){ + return this.ddRepo.getAllByUserFAILED( id ); + }else if ( (status!=null) && status.equals("FAILED_OSM_REMOVED") ){ + return this.ddRepo.getAllByUserFAILED_OSM_REMOVEDd( id ); + } + return this.ddRepo.getAllByUserStatusUnknown( id ); + } + + + public List getAllDeploymentDescriptorsByMentor(long id, String status) { + if ( (status!=null) && status.equals("COMPLETED") ){ + return this.ddRepo.getAllByMentorCompleted( id ); + }else if ( (status!=null) && status.equals("REJECTED") ){ + return this.ddRepo.getAllByMentorRejected( id ); + }else if ( (status!=null) && status.equals("FAILED") ){ + return this.ddRepo.getAllByMentorFAILED( id ); + }else if ( (status!=null) && status.equals("FAILED_OSM_REMOVED") ){ + return this.ddRepo.getAllByMentorFAILED_OSM_REMOVEDd( id ); + } + return this.ddRepo.getAllByMentorStatusUnknown( id ); + + } + + + + + public List getAllDeploymentDescriptorsScheduled() { + + return this.ddRepo.getAllScheduled(); + } + + + + + @Transactional + public DeploymentDescriptor updateDeploymentDescriptor(DeploymentDescriptor deployment) { + return this.ddRepo.save(deployment); + } + + + + + public DeploymentDescriptor getDeploymentByID(long id) { + + Optional o = this.ddRepo.findById(id); + + return o.orElseThrow(() -> new ItemNotFoundException("Couldn't find DeploymentDescriptor with id: " + id)); + } + + + + + /** + * @param id + * @return + */ + public DeploymentDescriptor getDeploymentByIdEager(long id) { + // Open a new session + try (Session session = sessionFactory.openSession()) { + // Begin a transaction + session.beginTransaction(); + DeploymentDescriptor dd = (DeploymentDescriptor) session.get(DeploymentDescriptor.class, id); + Hibernate.initialize(dd.getExperimentFullDetails()); + if (dd.getExperimentFullDetails() != null) { + Hibernate.initialize(dd.getExperimentFullDetails().getExperimentOnBoardDescriptors()); + } + Hibernate.initialize(dd.getVxfPlacements()); + Hibernate.initialize(dd.getDeploymentDescriptorVxFInstanceInfo()); + Hibernate.initialize(dd.getMentor().getRoles()); + Hibernate.initialize(dd.getInfrastructureForAll().getRefSupportedImages()); + Hibernate.initialize(dd.getExperiment().getConstituentVxF()); + Hibernate.initialize(dd.getExperimentFullDetails().getCategories()); + Hibernate.initialize(dd.getExperimentFullDetails().getExtensions()); + Hibernate.initialize(dd.getExperimentFullDetails().getValidationJobs()); + if (dd.getExperimentFullDetails() != null) { + dd.getExperimentFullDetails().getExperimentOnBoardDescriptors().size(); // This line forces initialization, consider revising if not necessary + } + session.getTransaction().commit(); + return dd; + } catch (Exception e) { + logger.error("getDeploymentByIdEager failed!"); + throw e; // Re-throw the exception (or handle it in some way) + } + } + + /** + * @param id + * @return + */ + public DeploymentDescriptor getDeploymentByInstanceIdEager(String id) { + DeploymentDescriptor dd = null; + dd = (DeploymentDescriptor) this.ddRepo.readDeploymentByInstanceID(id); + return this.getDeploymentByID(dd.getId()); + } + + /** + * @param d + * @return as json + * @throws JsonProcessingException + */ + public String getDeploymentByIdEagerDataJson( long id ) throws JsonProcessingException { + + DeploymentDescriptor dd = this.getDeploymentByIdEager( id ); + ObjectMapper mapper = new ObjectMapper(); + //Registering Hibernate4Module to support lazy objects + // this will fetch all lazy objects of VxF before marshaling + mapper.registerModule(new Hibernate5JakartaModule()); + String res = mapper.writeValueAsString( dd ); + + return res; + } + + /** + * @param d + * @return as json + * @throws JsonProcessingException + */ + public String getDeploymentByInstanceIdEagerDataJson( String id ) throws JsonProcessingException { + + logger.info("****************************"+id+"****************************"); + DeploymentDescriptor dd = this.getDeploymentByInstanceIdEager( id ); + ObjectMapper mapper = new ObjectMapper(); + //Registering Hibernate4Module to support lazy objects + // this will fetch all lazy objects of VxF before marshaling + mapper.registerModule(new Hibernate5JakartaModule()); + String res = mapper.writeValueAsString( dd ); + + return res; + } + + /** + * @param d + * @return as json + * @throws JsonProcessingException + */ + public String getDeploymentEagerDataJson( DeploymentDescriptor d ) throws JsonProcessingException { + + DeploymentDescriptor dd = this.getDeploymentByIdEager( d.getId() ); + ObjectMapper mapper = new ObjectMapper(); + //Registering Hibernate4Module to support lazy objects + // this will fetch all lazy objects of VxF before marshaling + mapper.registerModule(new Hibernate5JakartaModule()); + String res = mapper.writeValueAsString( dd ); + + return res; + } + + public void deleteDeployment(DeploymentDescriptor entity) { + this.ddRepo.delete(entity); + } + + public List getRunningInstantiatingAndTerminatingDeployments() { + List RunningDeploymentDescriptor_list = this.ddRepo.readRunningInstantiatingAndTerminatingDeployments(); + return RunningDeploymentDescriptor_list; + } + + public List getDeploymentsByExperimentId(long id) { + List DeploymentDescriptor_list = this.ddRepo.readDeploymentsByExperimentID(id); + return DeploymentDescriptor_list; + } + + public String getRunningInstantiatingAndTerminatingDeploymentsEagerDataJson() throws JsonProcessingException { + + List dds = this.getRunningInstantiatingAndTerminatingDeployments(); + ObjectMapper mapper = new ObjectMapper(); + + //Registering Hibernate4Module to support lazy objects + // this will fetch all lazy objects of VxF before marshaling + mapper.registerModule(new Hibernate5JakartaModule()); + String res = mapper.writeValueAsString( dds ); + + return res; + } + + public List getAllDeployments() { + List DeploymentDescriptors = new ArrayList<>(); + List DeploymentDescriptor_list = this.ddRepo.readAllDeployments(); + for(DeploymentDescriptor d : DeploymentDescriptor_list) + { + d.getExperimentFullDetails(); + d.getInfrastructureForAll(); + DeploymentDescriptors.add(d); + } + return DeploymentDescriptors; + } + + public List getDeploymentsToInstantiate() { + List DeploymentDescriptorsToRun = new ArrayList<>(); + List DeploymentDescriptor_list = this.ddRepo.readScheduledDeployments(); + for(DeploymentDescriptor d : DeploymentDescriptor_list) + { + d.getExperimentFullDetails(); + d.getInfrastructureForAll(); + //if(d.getStartDate().before(new Date(System.currentTimeMillis()))) + OffsetDateTime utc = OffsetDateTime.now(ZoneOffset.UTC); + if(d.getStartDate().before(Date.from(utc.toInstant()))) + { + logger.info("Deployment "+d.getName()+" is scheduled to run at "+d.getStartDate()+". It will be Deployed now."); + DeploymentDescriptorsToRun.add(d); + } + } + return DeploymentDescriptorsToRun; + } + + public String getAllDeploymentsEagerDataJson() throws JsonProcessingException { + + List dds = this.getAllDeployments(); + ObjectMapper mapper = new ObjectMapper(); + + //Registering Hibernate4Module to support lazy objects + // this will fetch all lazy objects of VxF before marshaling + mapper.registerModule(new Hibernate5JakartaModule()); + String res = mapper.writeValueAsString( dds ); + + return res; + } + + public String getDeploymentsToInstantiateEagerDataJson() throws JsonProcessingException { + + List dds = this.getDeploymentsToInstantiate(); + ObjectMapper mapper = new ObjectMapper(); + + //Registering Hibernate4Module to support lazy objects + // this will fetch all lazy objects of VxF before marshaling + mapper.registerModule(new Hibernate5JakartaModule()); + String res = mapper.writeValueAsString( dds ); + + return res; + } + + public List getDeploymentsToBeCompleted() { + List DeploymentDescriptorsToComplete = new ArrayList<>(); + //List DeploymentDescriptor_list = portalJpaController.readRunningInstantiatingAndTerminatingDeployments(); + List DeploymentDescriptor_list = this.ddRepo.readRunningInstantiatingDeployments(); + for(DeploymentDescriptor d : DeploymentDescriptor_list) + { + d.getExperimentFullDetails(); + d.getInfrastructureForAll(); + OffsetDateTime utc = OffsetDateTime.now(ZoneOffset.UTC); + if(d.getEndDate().before(Date.from(utc.toInstant()))) + { + logger.info("Deployment "+d.getName()+" is scheduled to be COMPLETED now."); + DeploymentDescriptorsToComplete.add(d); + } + } + return DeploymentDescriptorsToComplete; + } + + public String getDeploymentsToBeCompletedEagerDataJson() throws JsonProcessingException { + + List dds = this.getDeploymentsToBeCompleted(); + ObjectMapper mapper = new ObjectMapper(); + + //Registering Hibernate4Module to support lazy objects + // this will fetch all lazy objects of VxF before marshaling + mapper.registerModule(new Hibernate5JakartaModule()); + String res = mapper.writeValueAsString( dds ); + + return res; + } + + public List getDeploymentsToBeDeleted() { + List deploymentDescriptorsToDelete = new ArrayList<>(); + List deploymentDescriptor_list = this.ddRepo.readDeploymentsToBeDeleted(); + for(DeploymentDescriptor d : deploymentDescriptor_list) + { + d.getExperimentFullDetails(); + d.getInfrastructureForAll(); + OffsetDateTime utc = OffsetDateTime.now(ZoneOffset.UTC); + if(d.getEndDate().before(Date.from(utc.toInstant()))) + { + logger.info("Deployment id:" + d.getId() + ", name:"+ d.getName() + ", status:"+ d.getStatus() +" is scheduled to be DELETED now."); + deploymentDescriptorsToDelete.add(d); + } + + } + return deploymentDescriptorsToDelete; + } + + public String getDeploymentsToBeDeletedEagerDataJson() throws JsonProcessingException { + + List dds = this.getDeploymentsToBeDeleted(); + ObjectMapper mapper = new ObjectMapper(); + + //Registering Hibernate4Module to support lazy objects + // this will fetch all lazy objects of VxF before marshaling + mapper.registerModule(new Hibernate5JakartaModule()); + String res = mapper.writeValueAsString( dds ); + + return res; + } + + public DeploymentDescriptor updateDeploymentByJSON(DeploymentDescriptor receivedDeployment) { + + //DeploymentDescriptor aDeployment = getDeploymentByID( receivedDeployment.getId() ); + DeploymentDescriptor aDeployment = getDeploymentByIdEager( receivedDeployment.getId() ); + //logger.info("Existing deployment descriptor"+aDeployment.toJSON()); + logger.info("Received deployment descriptor"+receivedDeployment.toJSON()); + logger.info("Previous Status is :"+aDeployment.getStatus()+",New Status is:"+receivedDeployment.getStatus()+" and Instance Id is "+receivedDeployment.getInstanceId()); + + aDeployment.setConstituentVnfrIps(receivedDeployment.getConstituentVnfrIps()); + aDeployment.setConfigStatus(receivedDeployment.getConfigStatus()); + aDeployment.setDetailedStatus(receivedDeployment.getDetailedStatus()); + aDeployment.setOperationalStatus(receivedDeployment.getOperationalStatus()); + aDeployment.setNsr(receivedDeployment.getNsr()); + aDeployment.setNsLcmOpOccId(receivedDeployment.getNsLcmOpOccId()); + aDeployment.setNs_nslcm_details(receivedDeployment.getNs_nslcm_details()); + + logger.info("Update VxF Instance Info"); + try + { + logger.info(receivedDeployment.getDeploymentDescriptorVxFInstanceInfo().toArray().toString()); + aDeployment.setDeploymentDescriptorVxFInstanceInfo(receivedDeployment.getDeploymentDescriptorVxFInstanceInfo()); + } + catch(Exception e) + { + logger.info("Update of Vxf Instance Info failed with " + e.getMessage()); + } + if(receivedDeployment.getStatus() != aDeployment.getStatus() ) + { + aDeployment.setStatus( receivedDeployment.getStatus() ); + centralLogger.log( CLevel.INFO, "Status change of deployment "+aDeployment.getName()+" to "+aDeployment.getStatus(), compname ); + logger.info( "Status change of deployment "+aDeployment.getName()+" to "+aDeployment.getStatus() ); + aDeployment.setInstanceId( receivedDeployment.getInstanceId() ); + centralLogger.log( CLevel.INFO, "Instance Id of deployment set to"+aDeployment.getInstanceId(), compname ); + logger.info( "Instance Id of deployment set to"+aDeployment.getInstanceId() ); + aDeployment.setFeedback( receivedDeployment.getFeedback() ); + centralLogger.log( CLevel.INFO, "Feedback of deployment set to "+aDeployment.getFeedback(), compname ); + logger.info( "Feedback of deployment set to "+aDeployment.getFeedback() ); + aDeployment.getExperimentFullDetails(); + aDeployment.getInfrastructureForAll(); + logger.info("updateDeployment for id: " + aDeployment.getId()); + + if( receivedDeployment.getStatus() == DeploymentDescriptorStatus.SCHEDULED && aDeployment.getInstanceId() == null) + { + for (ExperimentOnBoardDescriptor tmpExperimentOnBoardDescriptor : aDeployment.getExperimentFullDetails().getExperimentOnBoardDescriptors()) + { + aDeployment.setStatus( receivedDeployment.getStatus() ); + centralLogger.log( CLevel.INFO, "Status change of deployment "+aDeployment.getName()+" to "+aDeployment.getStatus(), compname); + logger.info( "Status change of deployment "+aDeployment.getName()+" to "+aDeployment.getStatus()); + aDeployment = updateDeploymentDescriptor(aDeployment); + logger.info("NS status change is now "+aDeployment.getStatus()); + //BusController.getInstance().scheduleExperiment( aDeployment ); + } + } + else if( receivedDeployment.getStatus() == DeploymentDescriptorStatus.RUNNING && aDeployment.getInstanceId() == null) + { + for (ExperimentOnBoardDescriptor tmpExperimentOnBoardDescriptor : aDeployment.getExperimentFullDetails().getExperimentOnBoardDescriptors()) + { + aDeployment.setStatus( receivedDeployment.getStatus() ); + centralLogger.log( CLevel.INFO, "Status change of deployment "+aDeployment.getName()+" to "+aDeployment.getStatus(), compname); + logger.info( "Status change of deployment "+aDeployment.getName()+" to "+aDeployment.getStatus()); + aDeployment = updateDeploymentDescriptor(aDeployment); + logger.info("NS status change is now "+aDeployment.getStatus()); + //BusController.getInstance().deployExperiment( aDeployment ); + } + } + else if( receivedDeployment.getStatus() == DeploymentDescriptorStatus.COMPLETED && aDeployment.getInstanceId() != null) + { + aDeployment.setStatus( receivedDeployment.getStatus() ); + centralLogger.log( CLevel.INFO, "Status change of deployment "+aDeployment.getName()+" to "+aDeployment.getStatus(), compname); + logger.info( "Status change of deployment "+aDeployment.getName()+" to "+aDeployment.getStatus()); + aDeployment = updateDeploymentDescriptor(aDeployment); + logger.info("NS status change is now "+aDeployment.getStatus()); + //BusController.getInstance().completeExperiment( aDeployment ); + } + else if( receivedDeployment.getStatus() == DeploymentDescriptorStatus.REJECTED && aDeployment.getInstanceId() == null) + { + aDeployment.setStatus( receivedDeployment.getStatus() ); + centralLogger.log( CLevel.INFO, "Status change of deployment "+aDeployment.getName()+" to "+aDeployment.getStatus(), compname); + logger.info( "Status change of deployment "+aDeployment.getName()+" to "+aDeployment.getStatus()); + aDeployment = updateDeploymentDescriptor(aDeployment); + logger.info("NS status change is now "+aDeployment.getStatus()); + //BusController.getInstance().rejectExperiment( aDeployment ); + logger.info("Deployment Rejected"); + } + else + { + //Do Nothing + logger.info( "Inconsistent Status Change tried. Returning the Deployment unchanged."); + aDeployment = updateDeploymentDescriptor(aDeployment); + //BusController.getInstance().updateDeploymentRequest(aDeployment); + } + } else { + logger.info( "Previous status is the same so just update deployment info"); + aDeployment = updateDeploymentDescriptor(aDeployment); + //BusController.getInstance().updateDeploymentRequest(aDeployment); + } + return aDeployment; + } + + public String updateDeploymentEagerDataJson(DeploymentDescriptor receivedDeployment) throws JsonProcessingException { + + try (Session session = sessionFactory.openSession()) { // Use try-with-resources for Session + Transaction tx = null; // Declare a Transaction variable + try { + tx = session.beginTransaction(); // Start a new transaction + + DeploymentDescriptor dd = this.updateDeploymentByJSON(receivedDeployment); + ObjectMapper mapper = new ObjectMapper(); + + // Registering Hibernate5JakartaModule to support lazy objects + // this will fetch all lazy objects of VxF before marshaling + mapper.registerModule(new Hibernate5JakartaModule()); + String res = mapper.writeValueAsString(dd); + + tx.commit(); // Commit the transaction + return res; + + } catch (Exception e) { + if (tx != null && tx.isActive()) { + tx.rollback(); // Rollback the transaction in case of an exception + } + throw e; // Re-throw the exception + } + } // Session will be automatically closed after this block due to try-with-resources + } + + + @Transactional + public DeploymentDescriptor createDeploymentRequest(DeploymentDescriptor depl) { + PortalUser u; + if ( depl.getOwner() == null ) { + u = usersService.findByUsername("admin"); + } else { + u = usersService.findByUsername( depl.getOwner().getUsername() ); + } + + if ( depl.getExperiment() != null ) { + + } + + String uuid = UUID.randomUUID().toString(); + depl.setUuid(uuid); + depl.setDateCreated(new Date()); + + if ( depl.getStatus() == null ) { + depl.setStatus(DeploymentDescriptorStatus.UNDER_REVIEW); + } + + + ExperimentMetadata baseNSD = (ExperimentMetadata) nsdService.getProductByID(depl.getExperiment().getId()); + depl.setExperiment(baseNSD); // reattach from the DB model + + ExperimentOnBoardDescriptor uexpobd = nsdOBDService.getExperimentOnBoardDescriptorByID( depl.getObddescriptor_uuid().getId() ); + depl.setObddescriptor_uuid(uexpobd); // reattach from the DB model + + if (uexpobd == null) { + logger.error("uexpobd is NULL. Cannot load VxFOnBoardedDescriptor"); + } + + + logger.info("reattach InfrastructureForAll from the DB model"); + Infrastructure infrDefault = new Infrastructure(); + infrDefault.setVIMid("UNDEFINED-INFRASTRUCTUREID-INOPENSLICE"); + if ( infrastructureService.getInfrastructures().size()>0 ) { + infrDefault = infrastructureService.getInfrastructures().get(0); //first replace with any existing default infra + } + + MANOprovider provider = manoProviderService.getMANOproviderByID( uexpobd.getObMANOprovider().getId() ); //fetch one infra from provider + if ( provider!= null) { + if ( provider.getVims() != null && provider.getVims().size()>0 ){ + infrDefault = provider.getVims().get(0); + } + } + + depl.setInfrastructureForAll( infrDefault ); + + logger.info("reattach Mentor from the DB model"); + depl.setMentor( usersService.findByUsername("admin") ); + + logger.info("reattach DeploymentDescriptorVxFPlacement from the DB model"); + int member = 1; + for (ConstituentVxF cvf : baseNSD.getConstituentVxF()) { + DeploymentDescriptorVxFPlacement place = new DeploymentDescriptorVxFPlacement(); + place.setInfrastructure(infrDefault); + place.setConstituentVxF(cvf); + +// ConstituentVxF constituentVxF = new ConstituentVxF(); +// constituentVxF.setVxfref( cvf.getVxfref() ); +// constituentVxF.setMembervnfIndex(member); +// constituentVxF.setVnfdidRef( cvf.getVnfdidRef() ); +// place.setConstituentVxF(constituentVxF ); +// depl.getVxfPlacements().add(place); + } + + + depl.setOwner( u ); + return this.ddRepo.save( depl ); + } + + + @Transactional + public String createDeploymentRequestJson(DeploymentDescriptor depl) throws JsonProcessingException { + DeploymentDescriptor dd = this.createDeploymentRequest( depl ); + ObjectMapper mapper = new ObjectMapper(); + mapper.registerModule(new Hibernate5JakartaModule()); + String res = mapper.writeValueAsString( dd ); + return res; + } + +} diff --git a/src/main/java/portal/api/service/InfrastructureService.java b/src/main/java/portal/api/service/InfrastructureService.java new file mode 100644 index 0000000..8c5faf9 --- /dev/null +++ b/src/main/java/portal/api/service/InfrastructureService.java @@ -0,0 +1,130 @@ +/*- + * ========================LICENSE_START================================= + * org.etsi.osl.portal.api + * %% + * Copyright (C) 2019 openslice.io + * %% + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * =========================LICENSE_END================================== + */ +package portal.api.service; + +import java.util.List; +import java.util.Optional; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.datatype.hibernate5.jakarta.Hibernate5JakartaModule; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import org.etsi.osl.model.Infrastructure; +import portal.api.repo.InfrastructureRepository; + + + +@Service +public class InfrastructureService { + + @Autowired + InfrastructureRepository infraRepo; + + private static final transient Log logger = LogFactory.getLog( Infrastructure.class.getName()); + + public List getInfrastructures() { + return (List) this.infraRepo.findAll(); + } + + public Infrastructure addInfrastructure(Infrastructure c) { + return this.infraRepo.save(c); + } + + public Infrastructure updateInfrastructureInfo(Infrastructure infrastructure) { + return this.infraRepo.save(infrastructure); + } + + public Infrastructure getInfrastructureByID( long infraid) { + Optional o = this.infraRepo.findById(infraid); + + return o.orElse(null); + } + + public void deleteInfrastructure( Infrastructure infrastructure ) { + this.infraRepo.delete( infrastructure ); + + } + + /** + * @param d + * @return as json + * @throws JsonProcessingException + */ + public String getInfrastructuresEagerDataJson() throws JsonProcessingException { + + List il = this.getInfrastructures(); + ObjectMapper mapper = new ObjectMapper(); + // Registering Hibernate5Module to support lazy objects + // this will fetch all lazy objects of VxF before marshaling + mapper.registerModule(new Hibernate5JakartaModule()); + String res = mapper.writeValueAsString( il ); + + return res; + } + + /** + * @param d + * @return as json + * @throws JsonProcessingException + */ + public String addInfrastructureEagerDataJson(Infrastructure receivedInfrastructure) throws JsonProcessingException { + + Infrastructure infrastructure = this.addInfrastructure(receivedInfrastructure); + ObjectMapper mapper = new ObjectMapper(); + + //Registering Hibernate4Module to support lazy objects + // this will fetch all lazy objects before marshaling + mapper.registerModule(new Hibernate5JakartaModule()); + String res = mapper.writeValueAsString( infrastructure ); + + return res; + } + + public Infrastructure updateInfrastructureByJSON(Infrastructure infrastructure) { + + Infrastructure aInfrastructure = getInfrastructureByID( infrastructure.getId() ); + logger.info("Previous Infrastructure Status is :"+aInfrastructure.getInfrastructureStatus()+",New Status is:"+infrastructure.getInfrastructureStatus()+" and Instance Id is "+infrastructure.getId()); + + aInfrastructure.setInfrastructureStatus(infrastructure.getInfrastructureStatus()); + logger.info("updateInfrastructure for id: " + aInfrastructure.getId()); + aInfrastructure = updateInfrastructureInfo(aInfrastructure); + + return aInfrastructure; + } + + public String updateInfrastructureEagerDataJson(Infrastructure receivedInfrastructure) throws JsonProcessingException { + + Infrastructure infrastructure = this.updateInfrastructureByJSON(receivedInfrastructure); + ObjectMapper mapper = new ObjectMapper(); + + //Registering Hibernate4Module to support lazy objects + // this will fetch all lazy objects of VxF before marshaling + mapper.registerModule(new Hibernate5JakartaModule()); + String res = mapper.writeValueAsString( infrastructure ); + + return res; + } + +} diff --git a/src/main/java/portal/api/service/ItemNotFoundException.java b/src/main/java/portal/api/service/ItemNotFoundException.java new file mode 100644 index 0000000..d11ec7b --- /dev/null +++ b/src/main/java/portal/api/service/ItemNotFoundException.java @@ -0,0 +1,31 @@ +/*- + * ========================LICENSE_START================================= + * org.etsi.osl.portal.api + * %% + * Copyright (C) 2019 openslice.io + * %% + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * =========================LICENSE_END================================== + */ +package portal.api.service; + +import org.springframework.http.HttpStatus; +import org.springframework.web.bind.annotation.ResponseStatus; + +@ResponseStatus(code = HttpStatus.NOT_FOUND, reason = "not found") +public class ItemNotFoundException extends RuntimeException { + public ItemNotFoundException(String message) { + super(message); + } + +} diff --git a/src/main/java/portal/api/service/ManoPlatformService.java b/src/main/java/portal/api/service/ManoPlatformService.java new file mode 100644 index 0000000..0722dcb --- /dev/null +++ b/src/main/java/portal/api/service/ManoPlatformService.java @@ -0,0 +1,71 @@ +/*- + * ========================LICENSE_START================================= + * org.etsi.osl.portal.api + * %% + * Copyright (C) 2019 openslice.io + * %% + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * =========================LICENSE_END================================== + */ +package portal.api.service; + +import java.util.List; +import java.util.Optional; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import org.etsi.osl.model.MANOplatform; +import portal.api.repo.ManoPlatformRepository; + +@Service +public class ManoPlatformService { + + + @Autowired + ManoPlatformRepository manoPlatformRepo; + + + + public MANOplatform getMANOplatformByID(long id) { + Optional o = this.manoPlatformRepo.findById(id); + return o.orElse(null); + } + + + + public List getMANOplatforms() { + return (List) this.manoPlatformRepo.findAll(); + } + + + + public MANOplatform addMANOplatform(MANOplatform c) { + + return this.manoPlatformRepo.save(c); + } + + + + public void deleteMANOplatform(MANOplatform m) { + this.manoPlatformRepo.delete(m); + + } + + + + public MANOplatform updateMANOplatformInfo(MANOplatform c) { + return this.manoPlatformRepo.save(c); + } + +} diff --git a/src/main/java/portal/api/service/ManoProviderService.java b/src/main/java/portal/api/service/ManoProviderService.java new file mode 100644 index 0000000..5836144 --- /dev/null +++ b/src/main/java/portal/api/service/ManoProviderService.java @@ -0,0 +1,157 @@ +/*- + * ========================LICENSE_START================================= + * org.etsi.osl.portal.api + * %% + * Copyright (C) 2019 openslice.io + * %% + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * =========================LICENSE_END================================== + */ +package portal.api.service; + +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.datatype.hibernate5.jakarta.Hibernate5JakartaModule; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import org.etsi.osl.model.MANOprovider; +import portal.api.repo.ManoProvidersRepository; + +@Service +public class ManoProviderService { + + + @Autowired + ManoProvidersRepository manoProvidersRepo; + + public List getMANOprovidersEnabledForOnboarding() { + + List tmp_mp_list = new ArrayList(); + for(MANOprovider tmp : this.manoProvidersRepo.findAllEnabled()) + { + tmp.getVims(); + tmp_mp_list.add(tmp); + } + + return tmp_mp_list; + } + + public List getMANOprovidersForSync() { + List tmp_mp_list = new ArrayList(); + for(MANOprovider tmp : this.manoProvidersRepo.findAllEnabledForSync()) + { + tmp.getVims(); + tmp_mp_list.add(tmp); + } + + return tmp_mp_list; + } + + + @Transactional + public MANOprovider getMANOproviderByID(long id) { + Optional o = this.manoProvidersRepo.findById(id); + try + { + return (MANOprovider) o.get().getVims(); + } + catch(Exception e) + { + return o.orElse(null); + } + } + + /** + * @param d + * @return as json + * @throws JsonProcessingException + */ + + @Transactional + public String getMANOproviderByIDEagerDataJson( long id ) throws JsonProcessingException { + + MANOprovider dd = this.getMANOproviderByID( id ); + ObjectMapper mapper = new ObjectMapper(); + // Registering Hibernate5Module to support lazy objects + // this will fetch all lazy objects of MANOprovider before marshaling + mapper.registerModule(new Hibernate5JakartaModule()); + String res = mapper.writeValueAsString( dd ); + + return res; + } + + @Transactional + public String getMANOprovidersEagerDataJson() throws JsonProcessingException { + + List mps = this.getMANOproviders(); + ObjectMapper mapper = new ObjectMapper(); + // Registering Hibernate5Module to support lazy objects + // this will fetch all lazy objects of VxF before marshaling + mapper.registerModule(new Hibernate5JakartaModule()); + String res = mapper.writeValueAsString( mps ); + + return res; + } + + @Transactional + public String getMANOprovidersForSyncEagerDataJson() throws JsonProcessingException { + + List mps = this.getMANOprovidersForSync(); + List tmp_mp_list = new ArrayList(); + for(MANOprovider tmp : mps) + { + tmp.getVims(); + tmp_mp_list.add(tmp); + } + ObjectMapper mapper = new ObjectMapper(); + // Registering Hibernate5Module to support lazy objects + // this will fetch all lazy objects of VxF before marshaling + mapper.registerModule(new Hibernate5JakartaModule()); + String res = mapper.writeValueAsString( tmp_mp_list ); + + return res; + } + + public MANOprovider updateMANOproviderInfo(MANOprovider c) { + + return this.manoProvidersRepo.save(c); + } + + public void deleteMANOprovider(MANOprovider prev) { + this.manoProvidersRepo.delete(prev); + + } + + public MANOprovider addMANOprovider(MANOprovider c) { + return this.manoProvidersRepo.save(c); + } + + public List getMANOproviders() { + List tmp_mp_list = new ArrayList(); + for(MANOprovider tmp : this.manoProvidersRepo.findAll()) + { + tmp.getVims(); + tmp_mp_list.add(tmp); + } + + return tmp_mp_list; + } + +} diff --git a/src/main/java/portal/api/service/NSDOBDService.java b/src/main/java/portal/api/service/NSDOBDService.java new file mode 100644 index 0000000..9d287d9 --- /dev/null +++ b/src/main/java/portal/api/service/NSDOBDService.java @@ -0,0 +1,147 @@ +/*- + * ========================LICENSE_START================================= + * org.etsi.osl.portal.api + * %% + * Copyright (C) 2019 openslice.io + * %% + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * =========================LICENSE_END================================== + */ +package portal.api.service; + +import java.util.List; +import java.util.Optional; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.datatype.hibernate5.jakarta.Hibernate5JakartaModule; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import org.etsi.osl.model.ExperimentOnBoardDescriptor; +import portal.api.repo.NSDOBDRepository; + +@Service +public class NSDOBDService { + + @Autowired + NSDOBDRepository nsdOBDRepository; + @Autowired + NSDService nsdService; + + private static final transient Log logger = LogFactory.getLog( VxFOBDService.class.getName()); + + public ExperimentOnBoardDescriptor updateExperimentOnBoardDescriptor(ExperimentOnBoardDescriptor obd) { + + return nsdOBDRepository.save( obd ); + } + + public ExperimentOnBoardDescriptor getExperimentOnBoardDescriptorByID(long vxfobdid) { + Optional o = nsdOBDRepository.findById( vxfobdid ); + return o.orElse(null); + } + + public List getExperimentOnBoardDescriptors() { + + return (List) this.nsdOBDRepository.findAll(); + } + + /** + * @param d + * @return as json + * @throws JsonProcessingException + */ + public String getExperimentOnBoardDescriptorsDataJson() throws JsonProcessingException { + + List tmp = this.getExperimentOnBoardDescriptors(); + ObjectMapper mapper = new ObjectMapper(); + + //Registering Hibernate4Module to support lazy objects + // this will fetch all lazy objects before marshaling + mapper.registerModule(new Hibernate5JakartaModule()); + String res = mapper.writeValueAsString( tmp ); + + return res; + } + + public void deleteExperimentOnBoardDescriptor(ExperimentOnBoardDescriptor u) { + this.nsdOBDRepository.delete(u); + + } + + public ExperimentOnBoardDescriptor updateNSDOBDByJSON(ExperimentOnBoardDescriptor NSDOBD) { + + ExperimentOnBoardDescriptor aNSDOBD = getExperimentOnBoardDescriptorByID( NSDOBD.getId() ); + logger.info("Previous Status is :"+aNSDOBD.getOnBoardingStatus()+",New Status is:"+NSDOBD.getOnBoardingStatus()+" and Instance Id is "+NSDOBD.getId()); + + aNSDOBD.setExperimentMANOProviderID(NSDOBD.getExperimentMANOProviderID()); + aNSDOBD.setOnBoardingStatus(NSDOBD.getOnBoardingStatus()); + aNSDOBD.setDeployId(NSDOBD.getDeployId()); + aNSDOBD.setLastOnboarding(NSDOBD.getLastOnboarding()); + aNSDOBD.setFeedbackMessage(NSDOBD.getFeedbackMessage()); + aNSDOBD.setOnBoardingStatus(NSDOBD.getOnBoardingStatus()); + aNSDOBD.setObMANOprovider(NSDOBD.getObMANOprovider()); + //aNSDOBD.getExperiment().setCertified(NSDOBD.getExperiment().isCertified()); + + logger.info("updateExperimentODB for id: " + aNSDOBD.getId()); + aNSDOBD = updateExperimentOnBoardDescriptor(aNSDOBD); + + return aNSDOBD; + } + + + public String updateNSDOBDEagerDataJson(ExperimentOnBoardDescriptor receivedExperimentOBD) throws JsonProcessingException { + + ExperimentOnBoardDescriptor vxfobd = this.updateNSDOBDByJSON(receivedExperimentOBD); + ObjectMapper mapper = new ObjectMapper(); + + //Registering Hibernate4Module to support lazy objects + // this will fetch all lazy objects of VxF before marshaling + mapper.registerModule(new Hibernate5JakartaModule()); + String res = mapper.writeValueAsString( vxfobd ); + + return res; + } + + + public ExperimentOnBoardDescriptor addExperimentOnBoardedDescriptor(ExperimentOnBoardDescriptor aNSDOnBoardedDescriptor) { + + return this.nsdOBDRepository.save(aNSDOnBoardedDescriptor); + } + /** + * @param d + * @return as json + * @throws JsonProcessingException + */ + public String addExperimentOnBoardedDescriptorEagerDataJson(ExperimentOnBoardDescriptor receivedNSDOBD) throws JsonProcessingException { + + receivedNSDOBD.setExperiment(nsdService.getProductByID(receivedNSDOBD.getExperimentid())); + ExperimentOnBoardDescriptor nsdobd = this.addExperimentOnBoardedDescriptor(receivedNSDOBD); + ObjectMapper mapper = new ObjectMapper(); + + //Registering Hibernate4Module to support lazy objects + // this will fetch all lazy objects of VxF before marshaling + mapper.registerModule(new Hibernate5JakartaModule()); + String res = mapper.writeValueAsString( nsdobd ); + + return res; + } + + public ExperimentOnBoardDescriptor getExperimentOnBoardedDescriptorByUUid(String UUid) + { + return nsdOBDRepository.findByDeployId( UUid ); + } +} diff --git a/src/main/java/portal/api/service/NSDService.java b/src/main/java/portal/api/service/NSDService.java new file mode 100644 index 0000000..40e5991 --- /dev/null +++ b/src/main/java/portal/api/service/NSDService.java @@ -0,0 +1,171 @@ +/*- + * ========================LICENSE_START================================= + * org.etsi.osl.portal.api + * %% + * Copyright (C) 2019 openslice.io + * %% + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * =========================LICENSE_END================================== + */ +package portal.api.service; + +import java.util.List; +import java.util.Optional; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.datatype.hibernate5.jakarta.Hibernate5JakartaModule; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import org.etsi.osl.model.ExperimentMetadata; +import portal.api.repo.NSDsRepository; + +@Service +public class NSDService { + + @Autowired + NSDsRepository nsdRepo; + + /** + * @param d + * @return as json + * @throws JsonProcessingException + */ + public String getExperimentsEagerDataJson() throws JsonProcessingException { + + List il = this.getExperiments(); + ObjectMapper mapper = new ObjectMapper(); + // Registering Hibernate5Module to support lazy objects + // this will fetch all lazy objects of VxF before marshaling + mapper.registerModule(new Hibernate5JakartaModule()); + String res = mapper.writeValueAsString( il ); + + return res; + } + + public List getExperiments() { + return (List) this.nsdRepo.findAll(); + } + + /** + * @param id + * @return a Json containing all data + * @throws JsonProcessingException + */ + public String getProductByIDEagerDataJson(long id) throws JsonProcessingException { + + ObjectMapper mapper = new ObjectMapper(); + //Registering Hibernate4Module to support lazy objects + mapper.registerModule(new Hibernate5JakartaModule()); + + ExperimentMetadata o = this.getProductByIDEagerData(id); + + String res = mapper.writeValueAsString( o ); + + return res; + } + + public ExperimentMetadata getProductByIDEagerData(long id) { + Optional o = this.nsdRepo.findByIdEager(id); + + return o.orElse(null); + } + + /** + * @param id + * @return a Json containing all data + * @throws JsonProcessingException + */ + public String getProductByIDDataJson(long id) throws JsonProcessingException { + + ObjectMapper mapper = new ObjectMapper(); + //Registering Hibernate4Module to support lazy objects + mapper.registerModule(new Hibernate5JakartaModule()); + + ExperimentMetadata o = this.getProductByID(id); + + String res = mapper.writeValueAsString( o ); + + return res; + } + + public ExperimentMetadata getProductByID(long id) { + + Optional o = this.nsdRepo.findById(id); + + return o.orElse(null); + } + + public ExperimentMetadata updateProductInfo( ExperimentMetadata refNSD) { + return this.nsdRepo.save(refNSD); + } + + public List getPublishedNSDsByCategory(Long categoryid) { + if ((categoryid != null) && (categoryid >= 0)) { + return (List) this.nsdRepo.getPublishedNSDsByCategory(categoryid); + } else { + return (List) this.nsdRepo.getPublishedNSDs(); + } + } + + public List getdNSDsByCategory(Long categoryid) { + if ((categoryid != null) && (categoryid >= 0)) { + return (List) this.nsdRepo.getNSDsByCategory(categoryid); + } else { + return (List) this.nsdRepo.findAll(); + } + } + + public List gedNSDsByUserID(long userid) { + return (List) this.nsdRepo.getNSDsByUserID(userid); + } + + public ExperimentMetadata getdNSDByUUID(String uuid) { + Optional o = this.nsdRepo.findByUUID( uuid ); + return o.orElse(null); + } + + public void deleteProduct(ExperimentMetadata nsd) { + this.nsdRepo.delete( nsd ); + + } + + public ExperimentMetadata getNSDByName(String name) { + Optional o = this.nsdRepo.findByName( name ); + return o.orElse(null); + } + + public ExperimentMetadata addExperimentMetadata(ExperimentMetadata c) { + return this.nsdRepo.save(c); + } + + /** + * @param d + * @return as json + * @throws JsonProcessingException + */ + public String addNSDMetadataEagerDataJson(ExperimentMetadata receivedVxFMetadata) throws JsonProcessingException { + + ExperimentMetadata vxfmetadata = this.addExperimentMetadata(receivedVxFMetadata); + ObjectMapper mapper = new ObjectMapper(); + + //Registering Hibernate4Module to support lazy objects + // this will fetch all lazy objects before marshaling + mapper.registerModule(new Hibernate5JakartaModule()); + String res = mapper.writeValueAsString( vxfmetadata ); + + return res; + } +} diff --git a/src/main/java/portal/api/service/PortalPropertiesService.java b/src/main/java/portal/api/service/PortalPropertiesService.java new file mode 100644 index 0000000..5254dc1 --- /dev/null +++ b/src/main/java/portal/api/service/PortalPropertiesService.java @@ -0,0 +1,120 @@ +/*- + * ========================LICENSE_START================================= + * org.etsi.osl.portal.api + * %% + * Copyright (C) 2019 openslice.io + * %% + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * =========================LICENSE_END================================== + */ +package portal.api.service; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Optional; + +import org.springframework.core.env.Environment; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import org.etsi.osl.model.PortalProperty; +import jakarta.annotation.PostConstruct; +import portal.api.repo.PortalPropertiesRepository; + +/** + * @author ctranoris + * + */ +@Service +public class PortalPropertiesService { + + + @Autowired + PortalPropertiesRepository propsRepo; + + @Autowired + private Environment env; + + private static final transient Log logger = LogFactory.getLog( PortalPropertiesService.class.getName() ); + + public PortalProperty getPropertyByName(String aname) { + Optional optionalUser = this.propsRepo.findByName( aname ); + return optionalUser.orElse(null); + } + + public List getProperties() { + + return (List) propsRepo.findAll(); + } + + public PortalProperty getPropertyByID(long propid) { + Optional optionalUser = this.propsRepo.findById(propid); + return optionalUser.orElse(null); + } + + public PortalProperty updateProperty(PortalProperty p) { + return propsRepo.save(p); + } + + @PostConstruct + public void initRepo() { + PortalProperty pn = null; + try { + pn = getPropertyByID(1); + logger.info("======================== PortalProperty = " + pn); + } catch (Exception e) { + logger.info("======================== PortalProperty NOT FOUND, initializing"); + } + + if ( pn == null) { + PortalProperty p = new PortalProperty("adminEmail", env.getProperty("spring.portal.admin.email")); + propsRepo.save(p); + p = new PortalProperty("activationEmailSubject", env.getProperty("spring.portal.activation.email.subject")); + propsRepo.save(p); + p = new PortalProperty("mailhost", env.getProperty("spring.portal.mail.host")); + propsRepo.save(p); + p = new PortalProperty("mailuser", env.getProperty("spring.portal.mail.user")); + propsRepo.save(p); + p = new PortalProperty("mailpassword", env.getProperty("spring.portal.mail.password")); + propsRepo.save(p); + p = new PortalProperty("maindomain", env.getProperty("spring.portal.main.domain")); + propsRepo.save(p); + p = new PortalProperty("jenkinsciurl", env.getProperty("spring.portal.jenkins.ci.url")); + propsRepo.save(p); + p = new PortalProperty("jenkinscikey", env.getProperty("spring.portal.jenkins.ci.key")); + propsRepo.save(p); + p = new PortalProperty("pipelinetoken", env.getProperty("spring.portal.pipeline.token")); + propsRepo.save(p); + p = new PortalProperty("centrallogerurl", env.getProperty("spring.portal.central.loger.url")); + propsRepo.save(p); + p = new PortalProperty("portaltitle", env.getProperty("spring.portal.portal.title")); + propsRepo.save(p); + + } + + } + + public Map getPropertiesAsMap() { + Map m = new HashMap<>(); + + m.put( "maindomain" , getPropertyByName("maindomain").getValue() ); + m.put( "portaltitle" ,getPropertyByName("portaltitle").getValue() ); + m.put( "centrallogerurl" , getPropertyByName("centrallogerurl").getValue() ); + + + return m; + } +} diff --git a/src/main/java/portal/api/service/ProductService.java b/src/main/java/portal/api/service/ProductService.java new file mode 100644 index 0000000..25b001d --- /dev/null +++ b/src/main/java/portal/api/service/ProductService.java @@ -0,0 +1,55 @@ +/*- + * ========================LICENSE_START================================= + * org.etsi.osl.portal.api + * %% + * Copyright (C) 2019 openslice.io + * %% + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * =========================LICENSE_END================================== + */ +package portal.api.service; + +import java.util.Optional; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import org.etsi.osl.model.Product; +import portal.api.repo.ProductRepository; + +@Service +public class ProductService { + + @Autowired + ProductRepository productsRepo; + + public Product getProductByID(long id) { + + Optional o = this.productsRepo.findById(id); + + return o.orElse(null); + } + + public Product updateProductInfo(Product prevProduct) { + return this.productsRepo.save( prevProduct ) ; + } + + public Product getProducttByUUID(String uuid) { + + Optional o = this.productsRepo.findByUUID(uuid); + + return o.orElse(null); + } + + +} diff --git a/src/main/java/portal/api/service/UsersService.java b/src/main/java/portal/api/service/UsersService.java new file mode 100644 index 0000000..0d40df0 --- /dev/null +++ b/src/main/java/portal/api/service/UsersService.java @@ -0,0 +1,209 @@ +/*- + * ========================LICENSE_START================================= + * org.etsi.osl.portal.api + * %% + * Copyright (C) 2019 openslice.io + * %% + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * =========================LICENSE_END================================== + */ +package portal.api.service; + +import java.util.List; +import java.util.Optional; +import java.util.UUID; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.datatype.hibernate5.jakarta.Hibernate5JakartaModule; + +import org.apache.commons.lang3.RandomStringUtils; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.keycloak.representations.idm.UserRepresentation; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import org.etsi.osl.model.PortalUser; +import org.etsi.osl.model.UserRoleType; +import jakarta.annotation.PostConstruct; +import portal.api.repo.UsersRepository; + +/** + * @author ctranoris + * + */ +@Service +public class UsersService { + + @Autowired + UsersRepository usersRepo; + + + @Autowired + private BCryptPasswordEncoder passwordEncoder; + + + private static final transient Log logger = LogFactory.getLog( UsersService.class.getName() ); + + + public UsersService() { + super(); + + } + + @PostConstruct + public void initRepo() { + +// PortalUser admin = null; +// try { +// admin = findById(1); +// logger.info("======================== admin = " + admin); +// } catch (Exception e) { +// logger.info("======================== admin NOT FOUND, initializing"); +// } +// +// if (admin == null) { +// PortalUser bu = new PortalUser(); +// bu.setFirstname("Portal Administrator"); +// bu.setUsername( "admin" ); +// bu.setPassword( "changeme" ); +// bu.setApikey( UUID.randomUUID().toString() ); +// +// bu.setEmail(""); +// bu.setOrganization(""); +// bu.addRole( UserRoleType.ROLE_ADMIN ); +// bu.addRole( UserRoleType.ROLE_MENTOR ); +// bu.setActive(true); +// addPortalUserToUsers( bu ); +// +//// Category c = new Category(); +//// c.setName("None"); +//// saveCategory(c); +// } + + PortalUser manoService = null; + try + { + manoService = findByUsername("manoService"); + logger.info("======================== manoService = " + manoService); + } + catch(Exception e) + { + logger.info("======================== manoService NOT FOUND, initializing"); + } + if (manoService == null) { + PortalUser bu = new PortalUser(); + bu.setFirstname("MANO Service System User"); + bu.setUsername( "manoService" ); + int length = 16; + boolean useLetters = true; + boolean useNumbers = false; + String generatedString = RandomStringUtils.random(length, useLetters, useNumbers); + bu.setPassword( generatedString ); + bu.setApikey( UUID.randomUUID().toString() ); + + bu.setEmail(""); + bu.setOrganization(""); + bu.addRole( UserRoleType.ROLE_ADMIN ); + bu.addRole( UserRoleType.ROLE_MENTOR ); + bu.setActive(true); + usersRepo.save( bu ); + //addPortalUserToUsers( bu ); + } + } + + public List findAll() { + return (List) this.usersRepo.findAll(); // findAll(new Sort(Sort.Direction.ASC, "name")); + } + + public List getUserMentorsValues() { + return (List) this.usersRepo.findAllMentors(); + } + + public PortalUser findById( long id ) { + + Optional optionalUser = this.usersRepo.findById( id ); + return optionalUser + .orElse(null); + } + + public PortalUser findByUsername(String username) { + Optional optionalUser = this.usersRepo.findByUsername( username ); + return optionalUser.orElse(null); + } + + public PortalUser findByEmail(String email) { + Optional optionalUser = this.usersRepo.findByEmail( email ); + return optionalUser.orElse(null); + } + + public PortalUser addPortalUserToUsers(PortalUser user) { + + return usersRepo.save( user ); + + } + + public PortalUser addPortalUserToUsersFromAuthServer(String username, String email, String firstname, String lastname) { + + PortalUser userDTO = new PortalUser(); + + userDTO.setUsername( username ); + userDTO.setEmail( email ); + userDTO.setFirstname( firstname ); + userDTO.setLastname( lastname ); + userDTO.setActive( true ); + + userDTO.setApikey( UUID.randomUUID().toString() ); + usersRepo.save( userDTO ); + return updateUserInfo( userDTO, true ); + } + + /** + * @param user + * @param userInfoChanged + * @return + */ + public PortalUser updateUserInfo(PortalUser user, Boolean userInfoChanged) { + + return usersRepo.save( user ); + + + } + + + + public void delete(PortalUser u) { + usersRepo.delete(u); + } + + @Transactional + public String getPortalUserByUserNameDataJson(String username) throws JsonProcessingException { + PortalUser user = findByUsername( username ); + if ( user != null ) { + ObjectMapper mapper = new ObjectMapper(); + mapper.registerModule(new Hibernate5JakartaModule()); + String res = mapper.writeValueAsString( user ); + return res; + } + return ""; + } + + public void logout( String username ) { + //keyCloakService.logoutUser(username); + } + + +} diff --git a/src/main/java/portal/api/service/VFImageService.java b/src/main/java/portal/api/service/VFImageService.java new file mode 100644 index 0000000..c561f0a --- /dev/null +++ b/src/main/java/portal/api/service/VFImageService.java @@ -0,0 +1,77 @@ +/*- + * ========================LICENSE_START================================= + * org.etsi.osl.portal.api + * %% + * Copyright (C) 2019 openslice.io + * %% + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * =========================LICENSE_END================================== + */ +package portal.api.service; + +import java.util.List; +import java.util.Optional; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import org.etsi.osl.model.VFImage; +import portal.api.repo.VFImageRepository; + +@Service +public class VFImageService { + + @Autowired + VFImageRepository vfRepo; + + + public VFImage getVFImageByName(String imageName) { + Optional o = this.vfRepo.findByName( imageName ); + return o.orElse(null); + } + + + public VFImage saveVFImage(VFImage sm) { + + return this.vfRepo.save( sm ) ; + } + + + public VFImage updateVFImageInfo(VFImage img) { + return this.vfRepo.save( img ) ; + + } + + + public VFImage getVFImageByID( long vfimageid) { + Optional o = this.vfRepo.findById( vfimageid ); + return o.orElse(null); + } + + + public List getVFImages() { + return (List) this.vfRepo.findAll(); + } + + + public List getVFImagesByUserID(long id) { + return (List) this.vfRepo.findAllByUserid( id ); + } + + + public void deleteVFImage( VFImage sm ) { + this.vfRepo.delete( sm ); + + } + +} diff --git a/src/main/java/portal/api/service/VxFOBDService.java b/src/main/java/portal/api/service/VxFOBDService.java new file mode 100644 index 0000000..8c6e1b3 --- /dev/null +++ b/src/main/java/portal/api/service/VxFOBDService.java @@ -0,0 +1,180 @@ +/*- + * ========================LICENSE_START================================= + * org.etsi.osl.portal.api + * %% + * Copyright (C) 2019 openslice.io + * %% + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * =========================LICENSE_END================================== + */ +package portal.api.service; + +import java.util.List; +import java.util.Optional; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.datatype.hibernate5.jakarta.Hibernate5JakartaModule; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import org.etsi.osl.model.MANOprovider; +import org.etsi.osl.model.VxFMetadata; +import org.etsi.osl.model.VxFOnBoardedDescriptor; +import portal.api.repo.VxFOBDRepository; + +@Service +public class VxFOBDService { + + @Autowired + VxFOBDRepository vxfOBDRepository; + @Autowired + VxFService vxfService; + @Autowired + ManoProviderService mpService; + + private static final transient Log logger = LogFactory.getLog( VxFOBDService.class.getName()); + + public VxFOnBoardedDescriptor updateVxFOnBoardedDescriptor(VxFOnBoardedDescriptor obd) { + //Optional o = vxfOBDRepository. + return this.vxfOBDRepository.save( obd ); + } + + public VxFOnBoardedDescriptor getVxFOnBoardedDescriptorByID(long vxfobdid) { + Optional o = vxfOBDRepository.findById( vxfobdid ); + return o.orElse(null); + } + + public List getVxFOnBoardedDescriptors() { + return (List) this.vxfOBDRepository.findAll(); + } + + public void deleteVxFOnBoardedDescriptor(VxFOnBoardedDescriptor entity) { + this.vxfOBDRepository.delete(entity); + + } + + public VxFOnBoardedDescriptor updateVxFOBDByJSON(VxFOnBoardedDescriptor vxfOBD) { + + VxFOnBoardedDescriptor aVxFOBD = getVxFOnBoardedDescriptorByID( vxfOBD.getId() ); + logger.info("Previous Status is :"+aVxFOBD.getOnBoardingStatus()+",New Status is:"+vxfOBD.getOnBoardingStatus()+" and Instance Id is "+vxfOBD.getId()); + + aVxFOBD.setOnBoardingStatus(vxfOBD.getOnBoardingStatus()); + aVxFOBD.setDeployId(vxfOBD.getDeployId()); + aVxFOBD.setVxfMANOProviderID(vxfOBD.getVxfMANOProviderID()); + aVxFOBD.setLastOnboarding(vxfOBD.getLastOnboarding()); + aVxFOBD.setFeedbackMessage(vxfOBD.getFeedbackMessage()); + aVxFOBD.setOnBoardingStatus(vxfOBD.getOnBoardingStatus()); + //aVxFOBD.getVxf().setCertified(vxfOBD.getVxf().isCertified()); + logger.info("updateVxFODB for id: " + aVxFOBD.getId()); + aVxFOBD = updateVxFOnBoardedDescriptor(aVxFOBD); + + return aVxFOBD; + } + + + public String updateVxFOBDEagerDataJson(VxFOnBoardedDescriptor receivedVxFOBD) throws JsonProcessingException { + + VxFOnBoardedDescriptor vxfobd = this.updateVxFOBDByJSON(receivedVxFOBD); + ObjectMapper mapper = new ObjectMapper(); + + //Registering Hibernate4Module to support lazy objects + // this will fetch all lazy objects of VxF before marshaling + mapper.registerModule(new Hibernate5JakartaModule()); + String res = mapper.writeValueAsString( vxfobd ); + + return res; + } + + public VxFOnBoardedDescriptor addVxFOnBoardedDescriptor(VxFOnBoardedDescriptor aVxFOnBoardedDescriptor) { + + return this.vxfOBDRepository.save(aVxFOnBoardedDescriptor); + } + /** + * @param d + * @return as json + * @throws JsonProcessingException + */ + public String addVxFOnBoardedDescriptorEagerDataJson(VxFOnBoardedDescriptor receivedVxFOBD) throws JsonProcessingException { + + receivedVxFOBD.setVxf(vxfService.getVxFById(receivedVxFOBD.getVxfid())); + VxFOnBoardedDescriptor vxfobd = this.addVxFOnBoardedDescriptor(receivedVxFOBD); + ObjectMapper mapper = new ObjectMapper(); + + //Registering Hibernate4Module to support lazy objects + // this will fetch all lazy objects of VxF before marshaling + mapper.registerModule(new Hibernate5JakartaModule()); + String res = mapper.writeValueAsString( vxfobd ); + + return res; + } + + public String getVxFOnBoardedDescriptorByVxFAndMP(String input) + { + String vnfd_id=input.split("##")[0]; + long mp_id = Long.parseLong(input.split("##")[1]); + MANOprovider mp_obj=mpService.getMANOproviderByID(mp_id); + VxFOnBoardedDescriptor tmp = this.vxfOBDRepository.findByVxFAndMP(vnfd_id,mp_obj); + if(tmp!=null) + return tmp.getUuid(); + else + return null; + } + + public List getVxFOnBoardedDescriptorListByMP(Long mp_id) + { + MANOprovider mp_obj=mpService.getMANOproviderByID(mp_id); + List tmp = this.vxfOBDRepository.findByMP(mp_obj); + if(tmp!=null) + return tmp; + else + return null; + } + + public List getVxFOnBoardedDescriptorList() + { + List tmp = this.vxfOBDRepository.findAll(); + if(tmp!=null) + return tmp; + else + return null; + } + /** + * @param d + * @return as json + * @throws JsonProcessingException + */ + public String getVxFOnBoardedDescriptorListDataJson() throws JsonProcessingException { + + List tmp = this.getVxFOnBoardedDescriptorList(); + ObjectMapper mapper = new ObjectMapper(); + + //Registering Hibernate4Module to support lazy objects + // this will fetch all lazy objects before marshaling + mapper.registerModule(new Hibernate5JakartaModule()); + String res = mapper.writeValueAsString( tmp ); + + return res; + } + + public VxFMetadata getVxFIdByVxFMANOProviderIDAndMP(String vxf_mp_id,long mp_id) + { + MANOprovider mp_obj=mpService.getMANOproviderByID(mp_id); + VxFOnBoardedDescriptor tmp = this.vxfOBDRepository.VxFIdByVxFMANOProviderIDAndMP(vxf_mp_id,mp_obj); + return tmp.getVxf(); + } + +} diff --git a/src/main/java/portal/api/service/VxFService.java b/src/main/java/portal/api/service/VxFService.java new file mode 100644 index 0000000..d20c701 --- /dev/null +++ b/src/main/java/portal/api/service/VxFService.java @@ -0,0 +1,185 @@ +/*- + * ========================LICENSE_START================================= + * org.etsi.osl.portal.api + * %% + * Copyright (C) 2019 openslice.io + * %% + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * =========================LICENSE_END================================== + */ +package portal.api.service; + +import java.util.List; +import java.util.Optional; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.datatype.hibernate5.jakarta.Hibernate5JakartaModule; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import org.etsi.osl.model.VxFMetadata; +import portal.api.repo.VxFsRepository; + +@Service +public class VxFService { + + @Autowired + VxFsRepository vxfsRepo; + + /** + * @param d + * @return as json + * @throws JsonProcessingException + */ + public String getVnfdsEagerDataJson() throws JsonProcessingException { + + List il = this.getVxFs(); + ObjectMapper mapper = new ObjectMapper(); + // Registering Hibernate5Module to support lazy objects + // this will fetch all lazy objects of VxF before marshaling + mapper.registerModule(new Hibernate5JakartaModule()); + String res = mapper.writeValueAsString( il ); + + return res; + } + + public List getVxFs() { + return (List) this.vxfsRepo.findAll(); + } + + /** + * @param id + * @return a Json containing all data + * @throws JsonProcessingException + */ + public String getProductByIDDataJson(long id) throws JsonProcessingException { + + ObjectMapper mapper = new ObjectMapper(); + //Registering Hibernate4Module to support lazy objects + // this will fetch all lazy objects of VxF before marshaling + mapper.registerModule(new Hibernate5JakartaModule()); + + VxFMetadata o = this.getVxFById(id); + String res = mapper.writeValueAsString( o ); + return res; + } + + /** + * @param id + * @return a Json containing all data + * @throws JsonProcessingException + */ + public String getProductByNameEagerDataJson(String name) throws JsonProcessingException { + + ObjectMapper mapper = new ObjectMapper(); + //Registering Hibernate4Module to support lazy objects + // this will fetch all lazy objects of VxF before marshaling + mapper.registerModule(new Hibernate5JakartaModule()); + + VxFMetadata o = this.getVxFByName(name); + String res = mapper.writeValueAsString( o ); + return res; + } + + + public VxFMetadata updateProductInfo(VxFMetadata refVxF) { + return this.vxfsRepo.save(refVxF); + } + + public List getPublishedVxFsByCategory(Long categoryid) { + if ((categoryid != null) && (categoryid >= 0)) { + return (List) this.vxfsRepo.getPublishedVxFsByCategory(categoryid); + } else { + return (List) this.vxfsRepo.getPublishedVxF(); + } + } + + public List getVxFsByCategory(Long categoryid) { + if ((categoryid != null) && (categoryid >= 0)) { + return (List) this.vxfsRepo.getVxFsByCategory(categoryid); + } else { + return (List) this.vxfsRepo.findAll(); + } + } + + public List getVxFsByUserID(long userid) { + return (List) this.vxfsRepo.getVxFsByUserID(userid); + } + + public VxFMetadata getVxFByUUID(String uuid) { + Optional o = this.vxfsRepo.findByUUID( uuid ); + return o.orElse(null); + } + /** + * @param id + * @return a Json containing all data + * @throws JsonProcessingException + */ + public String getVxFByUUIDDataJson(String uuid) throws JsonProcessingException { + + ObjectMapper mapper = new ObjectMapper(); + //Registering Hibernate4Module to support lazy objects + // this will fetch all lazy objects of VxF before marshaling + mapper.registerModule(new Hibernate5JakartaModule()); + + VxFMetadata o = this.getVxFByUUID(uuid); + String res = mapper.writeValueAsString( o ); + return res; + } + + public void deleteProduct(VxFMetadata vxf) { + this.vxfsRepo.delete( vxf ); + + } + + public VxFMetadata getVxFByName(String name) { + Optional o = this.vxfsRepo.findByName( name ); + return o.orElse(null); + } + + public VxFMetadata getVxFById(long vxfId) { + Optional o = this.vxfsRepo.findById(vxfId); + return o.orElse(null); + } + + public List getAllVxFByName(String name) { + + List o = (List) this.vxfsRepo.findAllByName(name); + return o; + } + + + public VxFMetadata addVxFMetadata(VxFMetadata c) { + return this.vxfsRepo.save(c); + } + + /** + * @param d + * @return as json + * @throws JsonProcessingException + */ + public String addVxFMetadataEagerDataJson(VxFMetadata receivedVxFMetadata) throws JsonProcessingException { + + VxFMetadata vxfmetadata = this.addVxFMetadata(receivedVxFMetadata); + ObjectMapper mapper = new ObjectMapper(); + + //Registering Hibernate4Module to support lazy objects + // this will fetch all lazy objects before marshaling + mapper.registerModule(new Hibernate5JakartaModule()); + String res = mapper.writeValueAsString( vxfmetadata ); + + return res; + } +} diff --git a/src/main/java/portal/api/swagger2/SwaggerConfig.java b/src/main/java/portal/api/swagger2/SwaggerConfig.java new file mode 100644 index 0000000..c49190f --- /dev/null +++ b/src/main/java/portal/api/swagger2/SwaggerConfig.java @@ -0,0 +1,80 @@ +/*- + * ========================LICENSE_START================================= + * org.etsi.osl.portal.api + * %% + * Copyright (C) 2019 openslice.io + * %% + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * =========================LICENSE_END================================== + */ +package portal.api.swagger2; + +import java.util.Arrays; + +import org.springdoc.core.customizers.OpenApiCustomizer; +import org.springdoc.core.models.GroupedOpenApi; +import org.springdoc.core.utils.SpringDocUtils; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Profile; + +import io.swagger.v3.oas.annotations.enums.SecuritySchemeType; +import io.swagger.v3.oas.annotations.security.OAuthFlow; +import io.swagger.v3.oas.annotations.security.OAuthFlows; +import io.swagger.v3.oas.annotations.security.OAuthScope; +import io.swagger.v3.oas.annotations.security.SecurityScheme; +import io.swagger.v3.oas.models.ExternalDocumentation; +import io.swagger.v3.oas.models.SpecVersion; +import io.swagger.v3.oas.models.info.Info; +import io.swagger.v3.oas.models.info.License; +import io.swagger.v3.oas.models.security.SecurityRequirement; + +@Configuration +@SecurityScheme(name = "security_auth", type = SecuritySchemeType.OAUTH2, bearerFormat = "JWT", +scheme = "bearer", +flows = @OAuthFlows(authorizationCode = @OAuthFlow( + authorizationUrl = "${springdoc.oAuthFlow.authorizationUrl}" + , tokenUrl = "${springdoc.oAuthFlow.tokenUrl}", scopes = { + @OAuthScope(name = "read", description = "read scope"), + @OAuthScope(name = "write", description = "write scope") }))) +public class SwaggerConfig { + + + @Bean + public GroupedOpenApi customnfvportal(){ + + SpringDocUtils.getConfig().replaceWithClass(java.time.LocalDate.class, java.sql.Date.class); + SpringDocUtils.getConfig().replaceWithClass(java.time.OffsetDateTime.class, java.util.Date.class); + return GroupedOpenApi.builder() + .group("nfv-portal.api.controller-v1.0.0") + .addOpenApiCustomizer( this.apiInfoPortalAPI() ) + .packagesToScan("portal.api.controller") + .build(); + + } + + OpenApiCustomizer apiInfoPortalAPI() { + + + return openApi -> openApi + .specVersion( SpecVersion.V30 ).addSecurityItem(new SecurityRequirement().addList("security_auth")) + .info(new Info().title("NFV portal API") + .description("## NFV portal API") + + .version("1.0.0") + .license(new License().name("Apache 2.0").url("http://openslice.io"))); + } + + +} diff --git a/src/main/java/portal/api/util/AttachmentUtil.java b/src/main/java/portal/api/util/AttachmentUtil.java new file mode 100644 index 0000000..0771fa8 --- /dev/null +++ b/src/main/java/portal/api/util/AttachmentUtil.java @@ -0,0 +1,246 @@ +/*- + * ========================LICENSE_START================================= + * org.etsi.osl.portal.api + * %% + * Copyright (C) 2019 openslice.io + * %% + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * =========================LICENSE_END================================== + */ + +package portal.api.util; + +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.net.URL; + +import org.apache.commons.compress.archivers.tar.TarArchiveEntry; +import org.apache.commons.compress.archivers.tar.TarArchiveInputStream; +import org.apache.commons.compress.compressors.gzip.GzipCompressorInputStream; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.opendaylight.yang.gen.v1.urn.etsi.osm.yang.vnfd.rev170228.vnfd.catalog.Vnfd; +import org.springframework.web.multipart.MultipartFile; + +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.dataformat.yaml.YAMLFactory; + +/** + * @author ctranoris + * + */ + +public class AttachmentUtil { + + private static int BUFFER_SIZE = 4 * 1024; + private String descriptorYAMLfile; + private ByteArrayOutputStream iconfilePath; + + private static final transient Log logger = LogFactory.getLog(AttachmentUtil.class.getName()); + + /** + * @param att + * @param filePath + * @return + */ + public static String saveFile(MultipartFile att, String filePath) { + File file = new File(filePath + att.getOriginalFilename()); + try { + att.transferTo(file); + return file.getPath(); + + } catch (IllegalStateException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + +// DataHandler handler = att.getDataHandler(); +// try { +// InputStream stream = handler.getInputStream(); +// MultivaluedMap map = att.getHeaders(); +// File f = new File(filePath); +// OutputStream out = new FileOutputStream(f); +// +// int read = 0; +// byte[] bytes = new byte[1024]; +// while ((read = stream.read(bytes)) != -1) { +// out.write(bytes, 0, read); +// } +// stream.close(); +// out.flush(); +// out.close(); +// return f.getAbsolutePath(); +// +// } catch (Exception e) { +// e.printStackTrace(); +// } + return null; + } + + /** + * @param att + * @param filePath + * @return + * @throws IOException + */ + public static String saveFile(ByteArrayOutputStream att, String filePath) throws IOException { + + File f = new File(filePath); + FileOutputStream fos; + try { + fos = new FileOutputStream(f); + att.writeTo(fos); + fos.close(); + return f.getAbsolutePath(); + } catch (IOException ioe) { + // Handle exception here + ioe.printStackTrace(); + } finally { + } + + return null; + + } + + public static String extractYAMLfile(String filePath) throws IOException { + + String descriptorYAMLfile = null; + try (InputStream in = new FileInputStream(filePath); + //unzip + GzipCompressorInputStream gzipIn = new GzipCompressorInputStream(in); + //untar + TarArchiveInputStream tarIn = new TarArchiveInputStream(gzipIn)){ + TarArchiveEntry entry = null; + // Iterate through the files in the archive + while ((entry = tarIn.getNextTarEntry()) != null) { + // If the file ends in .yaml + if (entry.getName().endsWith(".yaml")) { + + logger.info("INFO: Examining " + entry.getName() + " for vnfd tag..." ); + // Create a new file + ByteArrayOutputStream file = new ByteArrayOutputStream(); + + int count; + byte data[] = new byte[BUFFER_SIZE]; + // Read in chunks of BUFFER SIZE + while((count = tarIn.read(data, 0, BUFFER_SIZE)) != -1) { + // Write in a separate file. + file.write(data, 0, count); + } + + // Set the file as the yaml file + String afile = new String(file.toByteArray()); + if ( afile.contains( "vnfd:") || afile.contains( "nsd:") ) { + descriptorYAMLfile = afile; + } + + } + } + } + return descriptorYAMLfile; + } + + public static ByteArrayOutputStream extractIcon(String filePath) throws IOException { + ByteArrayOutputStream iconfilePath = null; + try (InputStream in = new FileInputStream(filePath); + //unzip + GzipCompressorInputStream gzipIn = new GzipCompressorInputStream(in); + //untar + TarArchiveInputStream tarIn = new TarArchiveInputStream(gzipIn)){ + TarArchiveEntry entry = null; + // Iterate through the files in the archive + while ((entry = tarIn.getNextTarEntry()) != null) { + // If the file is a png or a jpg + if ( entry.getName().endsWith(".png") || entry.getName().endsWith(".jpg")) { + iconfilePath = new ByteArrayOutputStream(); + //Copy the file to iconfilePath + int count; + byte data[] = new byte[BUFFER_SIZE]; + while((count = tarIn.read(data, 0, BUFFER_SIZE)) != -1) { + iconfilePath.write(data, 0, count); + } + } + } + } + return iconfilePath; + } + + public void extractYAMLfileAndIcon(String filePath) throws IOException { + try (InputStream in = new FileInputStream(filePath); + //unzip + GzipCompressorInputStream gzipIn = new GzipCompressorInputStream(in); + //untar + TarArchiveInputStream tarIn = new TarArchiveInputStream(gzipIn)){ + TarArchiveEntry entry = null; + // Iterate through the files in the archive + while ((entry = tarIn.getNextTarEntry()) != null) { + // If the file ends in .yaml + if ( entry.getName().endsWith(".yaml") || entry.getName().endsWith(".yml")) { + + logger.info("INFO: Examining " + entry.getName() + " for vnfd tag..." ); + // Create a new file + ByteArrayOutputStream file = new ByteArrayOutputStream(); + + int count; + byte data[] = new byte[BUFFER_SIZE]; + // Read in chunks of BUFFER SIZE + while((count = tarIn.read(data, 0, BUFFER_SIZE)) != -1) { + // Write in a separate file. + file.write(data, 0, count); + } + // Set the file as the yaml file + String afile = new String(file.toByteArray()); + if ( afile.contains( "vnfd:") || afile.contains( "nsd:") ) { + this.setDescriptorYAMLfile( afile ); + } + + } + // If the file is a png or a jpg + if ( entry.getName().endsWith(".png") || entry.getName().endsWith(".jpg")) { + this.iconfilePath = new ByteArrayOutputStream(); + //Copy the file to iconfilePath + int count; + byte data[] = new byte[BUFFER_SIZE]; + while((count = tarIn.read(data, 0, BUFFER_SIZE)) != -1) { + this.iconfilePath.write(data, 0, count); + } + } + } + } + } + + public String getDescriptorYAMLfile() { + return descriptorYAMLfile; + } + + public void setDescriptorYAMLfile(String descriptorYAMLfile) { + this.descriptorYAMLfile = descriptorYAMLfile; + } + + public ByteArrayOutputStream getIconfilePath() { + return iconfilePath; + } + + public void setIconfilePath(ByteArrayOutputStream iconfilePath) { + this.iconfilePath = iconfilePath; + } + +} diff --git a/src/main/java/portal/api/util/EmailUtil.java b/src/main/java/portal/api/util/EmailUtil.java new file mode 100644 index 0000000..d63f289 --- /dev/null +++ b/src/main/java/portal/api/util/EmailUtil.java @@ -0,0 +1,133 @@ +/*- + * ========================LICENSE_START================================= + * org.etsi.osl.portal.api + * %% + * Copyright (C) 2019 openslice.io + * %% + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * =========================LICENSE_END================================== + */ + + +package portal.api.util; + +import java.io.UnsupportedEncodingException; +import java.util.Date; +import java.util.Properties; + +import javax.mail.Address; +import javax.mail.Message; +import javax.mail.MessagingException; +import javax.mail.NoSuchProviderException; +import javax.mail.PasswordAuthentication; +import javax.mail.Session; +import javax.mail.Transport; +import javax.mail.internet.InternetAddress; +import javax.mail.internet.MimeMessage; + +import org.apache.commons.lang3.ArrayUtils; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Configuration; + +import portal.api.service.PortalPropertiesService; + + +/** + * @author ctranoris + * + */ +@Configuration +public class EmailUtil { + + + @Autowired + static PortalPropertiesService propsService; + + private static final transient Log logger = LogFactory.getLog(EmailUtil.class.getName()); + + + @Autowired + public void setPortalPropertiesService( PortalPropertiesService srv ){ + EmailUtil.propsService = srv; + } + + + + public static void SendRegistrationActivationEmail(String email, String messageBody, String subj) { + + Properties props = new Properties(); + + // Session session = Session.getDefaultInstance(props, null); + + props.setProperty("mail.transport.protocol", "smtp"); + props.put("mail.smtp.auth", "true"); + if ((propsService.getPropertyByName("mailhost").getValue() != null) + && (!propsService.getPropertyByName("mailhost").getValue().isEmpty())) + props.setProperty("mail.host", propsService.getPropertyByName("mailhost").getValue()); + if ((propsService.getPropertyByName("mailuser").getValue() != null) + && (!propsService.getPropertyByName("mailuser").getValue().isEmpty())) + props.setProperty("mail.user", propsService.getPropertyByName("mailuser").getValue()); + if ((propsService.getPropertyByName("mailpassword").getValue() != null) + && (!propsService.getPropertyByName("mailpassword").getValue().isEmpty())) + props.setProperty("mail.password", propsService.getPropertyByName("mailpassword").getValue()); + + String adminemail = propsService.getPropertyByName("adminEmail").getValue(); + final String username = propsService.getPropertyByName("mailuser").getValue(); + final String password = propsService.getPropertyByName("mailpassword").getValue(); + + logger.info("adminemail = " + adminemail); + logger.info("subj = " + subj); + + Session mailSession = Session.getInstance(props, new javax.mail.Authenticator() { + protected PasswordAuthentication getPasswordAuthentication() { + return new PasswordAuthentication(username, password); + } + }); + + Transport transport; + try { + transport = mailSession.getTransport(); + + MimeMessage msg = new MimeMessage(mailSession); + msg.setSentDate(new Date()); + msg.setFrom(new InternetAddress(adminemail, adminemail)); + msg.setSubject(subj); + msg.setContent(messageBody, "text/html; charset=ISO-8859-1"); + msg.addRecipient(Message.RecipientType.TO, new InternetAddress(email, email)); + msg.addRecipient(Message.RecipientType.CC, new InternetAddress(adminemail, adminemail)); + + transport.connect(); + + Address[] recips = (Address[]) ArrayUtils.addAll(msg.getRecipients(Message.RecipientType.TO), + msg.getRecipients(Message.RecipientType.CC)); + + transport.sendMessage(msg, recips); + + transport.close(); + + } catch (NoSuchProviderException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (MessagingException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (UnsupportedEncodingException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + + } + +} diff --git a/src/main/java/portal/api/validation/ci/ValidationCIClient.java b/src/main/java/portal/api/validation/ci/ValidationCIClient.java new file mode 100644 index 0000000..181d8f1 --- /dev/null +++ b/src/main/java/portal/api/validation/ci/ValidationCIClient.java @@ -0,0 +1,54 @@ +/*- + * ========================LICENSE_START================================= + * org.etsi.osl.portal.api + * %% + * Copyright (C) 2019 openslice.io + * %% + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * =========================LICENSE_END================================== + */ + +package portal.api.validation.ci; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import org.etsi.osl.model.VxFMetadata; + +/** + * @author ctranoris + * + */ +public class ValidationCIClient { + + + private static final transient Log logger = LogFactory.getLog(ValidationCIClient.class.getName()); + + /** */ + private static ValidationCIClient instance; + + + + public static ValidationCIClient getInstance() { + if (instance == null) { + instance = new ValidationCIClient(); + } + return instance; + } + + + public static void transformVxF2ValidationRequest(VxFMetadata vxf) { + + } + +} diff --git a/src/main/java/portal/api/validation/ci/ValidationCIRouteBuilder.java b/src/main/java/portal/api/validation/ci/ValidationCIRouteBuilder.java new file mode 100644 index 0000000..c98ed07 --- /dev/null +++ b/src/main/java/portal/api/validation/ci/ValidationCIRouteBuilder.java @@ -0,0 +1,177 @@ +/*- + * ========================LICENSE_START================================= + * org.etsi.osl.portal.api + * %% + * Copyright (C) 2019 openslice.io + * %% + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * =========================LICENSE_END================================== + */ + + +package portal.api.validation.ci; + +import java.util.Base64; +import java.util.Date; +import java.util.Map; + +import org.apache.camel.Exchange; +import org.apache.camel.LoggingLevel; +import org.apache.camel.Processor; +import org.apache.camel.builder.RouteBuilder; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Configuration; +import org.springframework.stereotype.Component; + +import org.etsi.osl.model.ExperimentMetadata; +import org.etsi.osl.model.Product; +import org.etsi.osl.model.ValidationJob; +import org.etsi.osl.model.ValidationStatus; +import org.etsi.osl.model.VxFMetadata; +import portal.api.service.PortalPropertiesService; + + + +/** + * @author ctranoris + * + */ +@Component +@Configuration +public class ValidationCIRouteBuilder extends RouteBuilder { + + private static String JENKINSCIKEY = ""; + private static String PIPELINE_TOKEN = "test"; + private static String JENKINSCIURL = ""; + + + @Autowired + PortalPropertiesService propsService; + + public void configure() { + + if (propsService.getPropertyByName("jenkinsciurl").getValue() != null) { + JENKINSCIURL = propsService.getPropertyByName("jenkinsciurl").getValue(); + } + if (propsService.getPropertyByName("jenkinscikey").getValue() != null) { + JENKINSCIKEY = propsService.getPropertyByName("jenkinscikey").getValue(); + } + if (propsService.getPropertyByName("pipelinetoken").getValue() != null) { + PIPELINE_TOKEN = propsService.getPropertyByName("pipelinetoken").getValue(); + } + + if ( ( JENKINSCIURL == null ) || JENKINSCIURL.equals( "" ) ){ + return; //no routing towards JENKINS + } + if ( ( JENKINSCIKEY == null ) || JENKINSCIKEY.equals( "" ) ){ + return;//no routing towards JENKINS + } + + + /** + * Create VxF Validate New Route + */ + // This needs testing 12052019 + from("seda:vxf.new.validation?multipleConsumers=true") + .log( "Submit new validation request for VNF_ID=${body}" ) + .errorHandler(deadLetterChannel("direct:dlq_validations") + .maximumRedeliveries( 3 ) //let's try 3 times to send it.... + .redeliveryDelay( 30000 ).useOriginalMessage() + //.deadLetterHandleNewException( false ) + //.logExhaustedMessageHistory(false) + .logExhausted(true) + .logHandled(true) + //.retriesExhaustedLogLevel(LoggingLevel.WARN) + .retryAttemptedLogLevel( LoggingLevel.WARN) ) + .delay(30000) + .setHeader(Exchange.HTTP_METHOD, constant(org.apache.camel.component.http.HttpMethods.POST)) + .process( headerExtractProcessor ) + .toD( "http://" + JENKINSCIURL + "/job/validation_pipeline/buildWithParameters?token=" + PIPELINE_TOKEN + "&VNF_ID=${header.id}") + .to("stream:out"); + + + /** + * dead Letter Queue Users if everything fails to connect + */ + from("direct:dlq_validations") + //.setBody() + //.body(String.class) + .process( ErroneousValidationProcessor ) + .to( "seda:vxf.validationresult.update?multipleConsumers=true") + .to("stream:out"); + + } + + Processor ErroneousValidationProcessor = new Processor() { + + @Override + public void process(Exchange exchange) throws Exception { + + Map headers = exchange.getIn().getHeaders(); + Product aProd = exchange.getIn().getBody( Product.class ); + + + if (aProd instanceof VxFMetadata) { + ((VxFMetadata) aProd).setValidationStatus( ValidationStatus.COMPLETED ); + } else if (aProd instanceof ExperimentMetadata) { + ((ExperimentMetadata) aProd).setValidationStatus( ValidationStatus.COMPLETED ); + } + + + if ( aProd.getValidationJobs() != null ) { + ValidationJob j = new ValidationJob(); + j.setDateCreated( new Date() ); + j.setJobid("ERROR"); + j.setValidationStatus(false); + j.setOutputLog( "There is an error from the Validation Service" ); + aProd.getValidationJobs().add(j); + } + + exchange. getOut().setBody( aProd ); + // copy attachements from IN to OUT to propagate them + //exchange.getOut().setAttachments(exchange.getIn().getAttachments()); + + } + }; + + + Processor headerExtractProcessor = new Processor() { + + @Override + public void process(Exchange exchange) throws Exception { + + Map headers = exchange.getIn().getHeaders(); + //VxFMetadata m = exchange.getIn().getBody( VxFMetadata.class ); + //headers.put("id", m.getId() ); + long id = Long.parseLong(exchange.getIn().getBody().toString()); + headers.put("id", id); + String encoding = Base64.getEncoder().encodeToString( (JENKINSCIKEY).getBytes() ); + headers.put("Authorization", "Basic " + encoding ); + + exchange.getOut().setHeaders(headers); + +// //copy Description to Comment +// aBug.setComment( BugzillaClient.createComment( aBug.getDescription() ) ); +// //delete Description +// aBug.setDescription( null ); +// aBug.setAlias( null ); //dont put any Alias +// aBug.setCc( null ); + + exchange.getOut().setBody( "" ); + // copy attachements from IN to OUT to propagate them + //exchange.getOut().setAttachments(exchange.getIn().getAttachments()); + + } + }; + +} diff --git a/src/main/java/portal/api/validation/ci/ValidationJobResult.java b/src/main/java/portal/api/validation/ci/ValidationJobResult.java new file mode 100644 index 0000000..793ad70 --- /dev/null +++ b/src/main/java/portal/api/validation/ci/ValidationJobResult.java @@ -0,0 +1,98 @@ +/*- + * ========================LICENSE_START================================= + * org.etsi.osl.portal.api + * %% + * Copyright (C) 2019 openslice.io + * %% + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * =========================LICENSE_END================================== + */ + +package portal.api.validation.ci; + +import com.fasterxml.jackson.annotation.JsonProperty; + +/** + * @author ctranoris + * + */ +public class ValidationJobResult { + + /** */ + @JsonProperty("vnfd_id") + private int vxfid; + /** */ + @JsonProperty("validation_status") + private Boolean validationStatus; + /** */ + @JsonProperty("jenkins_output_log") + private String outputLog; + + /** */ + @JsonProperty("build_id") + private int buildId; + + + /** + * @return the vxfid + */ + public int getVxfid() { + return vxfid; + } + /** + * @param vxfid the vxfid to set + */ + public void setVxfid(int vxfid) { + this.vxfid = vxfid; + } + + + /** + * @return the validationStatus + */ + public Boolean getValidationStatus() { + return validationStatus; + } + /** + * @param validationStatus the validationStatus to set + */ + public void setValidationStatus(Boolean validationStatus) { + this.validationStatus = validationStatus; + } + /** + * @return the outputLog + */ + public String getOutputLog() { + return outputLog; + } + /** + * @param outputLog the outputLog to set + */ + public void setOutputLog(String outputLog) { + this.outputLog = outputLog; + } + /** + * @return the buildId + */ + public int getBuildId() { + return buildId; + } + /** + * @param buildId the buildId to set + */ + public void setBuildId(int buildId) { + this.buildId = buildId; + } + + +} diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml new file mode 100644 index 0000000..05b3027 --- /dev/null +++ b/src/main/resources/application.yml @@ -0,0 +1,117 @@ + +origins: http://localhost,http://localhost:13000,http://127.0.0.1:13000,https://localhost, + + +server: + port: 13000 + servlet: + context-path : /osapi + error: + include-message: always + ssl: + enabled: false + +springdoc: + version: '@springdoc.version@' + writer-with-default-pretty-printer: true + swagger-ui: + display-request-duration: true + groups-order: ASC + operationsSorter: method + disable-swagger-default-url: true + use-root-path: true + oauth: + client-id: osapiWebClientId + clientsecret: "secret" + use-pkce-with-authorization-code-grant: false + oAuthFlow: + authorizationUrl: http://keycloak:8080/auth/realms/openslice/protocol/openid-connect/auth + tokenUrl: http://keycloak:8080/auth/realms/openslice/protocol/openid-connect/token + show-actuator: true + +spring-addons: + issuers: + - uri: http://keycloak:8080/auth/realms/openslice + username-json-path: $.preferred_username + claims: + - jsonPath: $.realm_access.roles + - jsonPath: $.resource_access.*.roles + + +spring: + config: + activate: + on-profile: "default" + application: + name: openslice-portal-api + datasource: + url: jdbc:mysql://localhost:13306/osdb?createDatabaseIfNotExist=true + password: letmein + username: root + hikari: + minimumIdle: 2 + maximumPoolSize: 40 + idleTimeout: 120000 + connectionTimeout: 400000 + leakDetectionThreshold: 100000 + jpa: + database-platform: portal.api.LocalMysqlDialect + hibernate: + ddl-auto: update + show-sql: false + generate-ddl: true + properties.hibernate.current_session_context_class: org.springframework.orm.hibernate5.SpringSessionContext + properties: + hibernate: + connection: + characterEncoding: utf-8 + CharSet: utf-8 + useUnicode: true + activemq: + brokerUrl: tcp://localhost:61616?jms.watchTopicAdvisories=false + user: artemis + password: artemis + pool: + enabled: true + max-connections: 100 + packages: + trust-all: true + servlet: + multipart.max-file-size: 10MB + multipart.max-request-size: 10MB + resources: + add-mappings: true + portal: + admin.email: info@example.org + activation.email.subject: OpenSlice Activation Email + mail.host: localhost + mail.user: exampleusername + mail.password: pass + main.domain: http://localhost + jenkins.ci.url: http://ci.example.org + jenkins.ci.key: my_key + pipeline.token: my_token + central.loger.url: http://localhost + portal.title: OpenSlice + +logging: + level: + root: INFO + portal.api: INFO + org.springframework: INFO + org.apache.camel: INFO + pattern: + console: "%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n" + file: "%d %p %c{1.} [%t] %m%n" + security: + oauth2: + resourceserver: + jwt: + issuer-uri: ${keycloak-issuer} + +#QUEUE MESSSAGES WITH VNFNSD CATALOG +NFV_CATALOG_GET_NSD_BY_ID: "jms:queue:NFVCATALOG.GET.NSD_BY_ID" +NFV_CATALOG_DEPLOY_NSD_REQ: "jms:queue:NFVCATALOG.DEPLOY.NSD_REQ" +NFV_CATALOG_UPD_DEPLOYMENT_BY_ID: "jms:queue:NFVCATALOG.UPD.DEPLOYMENT_BY_ID" +NFV_CATALOG_GET_DEPLOYMENT_BY_ID: "jms:queue:NFVCATALOG.GET.DEPLOYMENT_BY_ID" +GET_USER_BY_USERNAME: "jms:queue:GET.USER_BY_USERNAME" diff --git a/src/main/resources/banner.txt b/src/main/resources/banner.txt new file mode 100644 index 0000000..74229cd --- /dev/null +++ b/src/main/resources/banner.txt @@ -0,0 +1,11 @@ + ___ ____ _ _ + / _ \ _ __ ___ _ __ / ___|| (_) ___ ___ + | | | | '_ \ / _ \ '_ \\___ \| | |/ __/ _ \ + | |_| | |_) | __/ | | |___) | | | (_| __/ + \___/| .__/ \___|_| |_|____/|_|_|\___\___| + |_| + __ __________________ + / / __ __ / __/_ __/ __/ _/ + / _ \/ // / / _/ / / _\ \_/ / + /_.__/\_, / /___/ /_/ /___/___/ + /___/ \ No newline at end of file diff --git a/src/main/resources/logback.xml b/src/main/resources/logback.xml new file mode 100644 index 0000000..1b9c9be --- /dev/null +++ b/src/main/resources/logback.xml @@ -0,0 +1,60 @@ + + + + + + + + + + + + + + + + + + app.log + + + logs/archived/app.%d{yyyy-MM-dd}.%i.log + + 10MB + + 20GB + + 60 + + + + %d %p %c{1.} [%t] %m%n + + + + + + + + + + + diff --git a/src/main/resources/public.txt b/src/main/resources/public.txt new file mode 100644 index 0000000..ad3af18 --- /dev/null +++ b/src/main/resources/public.txt @@ -0,0 +1,9 @@ +-----BEGIN PUBLIC KEY----- +MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAgIK2Wt4x2EtDl41C7vfp +OsMquZMyOyteO2RsVeMLF/hXIeYvicKr0SQzVkodHEBCMiGXQDz5prijTq3RHPy2 +/5WJBCYq7yHgTLvspMy6sivXN7NdYE7I5pXo/KHk4nz+Fa6P3L8+L90E/3qwf6j3 +DKWnAgJFRY8AbSYXt1d5ELiIG1/gEqzC0fZmNhhfrBtxwWXrlpUDT0Kfvf0QVmPR +xxCLXT+tEe1seWGEqeOLL5vXRLqmzZcBe1RZ9kQQm43+a9Qn5icSRnDfTAesQ3Cr +lAWJKl2kcWU1HwJqw+dZRSZ1X4kEXNMyzPdPBbGmU6MHdhpywI7SKZT7mX4BDnUK +eQIDAQAB +-----END PUBLIC KEY----- \ No newline at end of file diff --git a/src/test/java/portal/api/InMemoryDBIntegrationTest.java b/src/test/java/portal/api/InMemoryDBIntegrationTest.java new file mode 100644 index 0000000..bae002a --- /dev/null +++ b/src/test/java/portal/api/InMemoryDBIntegrationTest.java @@ -0,0 +1,608 @@ +/*- + * ========================LICENSE_START================================= + * org.etsi.osl.portal.api + * %% + * Copyright (C) 2019 openslice.io + * %% + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * =========================LICENSE_END================================== + */ +package portal.api; + + + +import static org.assertj.core.api.Assertions.assertThat; +import static org.hamcrest.CoreMatchers.is; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.delete; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.multipart; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.util.Enumeration; +import java.util.HashMap; +import java.util.Map; + +import org.apache.commons.io.IOUtils; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase; +import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.http.MediaType; +import org.springframework.mock.web.MockHttpSession; +import org.springframework.mock.web.MockMultipartFile; +import org.springframework.security.test.context.support.WithMockUser; +import org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors; +import org.springframework.test.context.ActiveProfiles; +import org.springframework.test.context.TestPropertySource; +import org.springframework.test.context.junit4.SpringRunner; +import org.springframework.test.web.servlet.MockMvc; +import org.springframework.test.web.servlet.request.MockMultipartHttpServletRequestBuilder; +import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; +import org.springframework.transaction.annotation.Transactional; + +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.databind.ObjectMapper; + +import org.etsi.osl.model.DeploymentDescriptor; +import org.etsi.osl.model.ExperimentMetadata; +import org.etsi.osl.model.Infrastructure; +import org.etsi.osl.model.UserSession; +import org.etsi.osl.model.VxFMetadata; +import portal.api.mano.MANOController; +import portal.api.service.CategoryService; +import portal.api.service.DeploymentDescriptorService; +import portal.api.service.InfrastructureService; +import portal.api.service.ManoPlatformService; +import portal.api.service.ManoProviderService; +import portal.api.service.NSDOBDService; +import portal.api.service.NSDService; +import portal.api.service.PortalPropertiesService; +import portal.api.service.ProductService; +import portal.api.service.UsersService; +import portal.api.service.VFImageService; +import portal.api.service.VxFOBDService; +import portal.api.service.VxFService; + + +@RunWith(SpringRunner.class) +@Transactional +@SpringBootTest( webEnvironment = SpringBootTest.WebEnvironment.MOCK , classes = PortalApplication.class) +//@AutoConfigureTestDatabase +@AutoConfigureMockMvc +@ActiveProfiles("testing") +@TestPropertySource(properties = {"spring.cloud.consul.config.enabled=false", + "spring.cloud.bus.enabled=false", + "spring.cloud.discovery.enabled=false", + "spring.cloud.consul.enabled=false"}) + + + +public class InMemoryDBIntegrationTest { + + + private static final transient Log logger = LogFactory.getLog( InMemoryDBIntegrationTest.class.getName()); + + @Autowired + private MockMvc mvc; + + @Autowired + PortalPropertiesService propsService; + + @Autowired + UsersService usersService; + + @Autowired + ManoProviderService manoProviderService; + + @Autowired + VxFService vxfService; + + @Autowired + NSDService nsdService; + + @Autowired + VxFOBDService vxfOBDService; + @Autowired + NSDOBDService nsdOBDService; + + @Autowired + VFImageService vfImageService; + + @Autowired + ProductService productService; + + @Autowired + ManoPlatformService manoPlatformService; + + @Autowired + MANOController aMANOController; + + @Autowired + CategoryService categoryService; + + @Autowired + InfrastructureService infrastructureService; + + @Autowired + DeploymentDescriptorService deploymentDescriptorService; + + + + @Test + public void whenFindByName_thenReturnVxF() { + // given + + VxFMetadata vxf = new VxFMetadata(); + vxf.setName("aTestVxF"); + vxfService.updateProductInfo(vxf); + + // when + VxFMetadata found = vxfService.getVxFByName(vxf.getName()); + + // then + assertThat(found.getName()).isEqualTo( vxf.getName() ); + } + + @Test + public void countDefaultProperties() { + assertThat( propsService.getProperties().size() ) + .isEqualTo( 11 ); + + assertThat( usersService.findAll().size() ) + .isEqualTo( 1 ); + } + + @Test + public void loginAdmin() throws Exception { + + /** + * no auth session + */ + mvc.perform(get("/admin/users") + .with( SecurityMockMvcRequestPostProcessors.csrf()) + .contentType(MediaType.APPLICATION_JSON) + ) + .andExpect(status().is(401) ); + + UserSession pu = new UserSession(); + pu.setUsername("admin"); + pu.setPassword("changeme"); + +// /** +// * auth +// */ +// HttpSession session = mvc.perform(post("/sessions") +// .with( SecurityMockMvcRequestPostProcessors.csrf()) +// .contentType(MediaType.APPLICATION_JSON) +// .content( toJson( pu ) )) +// .andExpect(status().isOk()) +// .andExpect(content() +// .contentTypeCompatibleWith(MediaType.APPLICATION_JSON)) +// .andExpect(jsonPath("username", is("admin"))) +// .andReturn().getRequest().getSession(); + + + + mvc.perform(get("/categories") + .with( SecurityMockMvcRequestPostProcessors.csrf()) + .with( SecurityMockMvcRequestPostProcessors.user("osadmin").roles("ADMIN") ) + .contentType(MediaType.APPLICATION_JSON)) + .andExpect(status().isOk()) + .andExpect(content() + .contentTypeCompatibleWith(MediaType.APPLICATION_JSON)) + .andExpect( jsonPath("$[0].name", is("None")) ); + + + + /** + * with auth session + */ + mvc.perform(get("/admin/categories") + .with( SecurityMockMvcRequestPostProcessors.csrf()) + .with( SecurityMockMvcRequestPostProcessors.user("osadmin").roles("ADMIN") ) + .contentType(MediaType.APPLICATION_JSON) + ) + .andExpect(status().isOk()) + .andExpect(content() + .contentTypeCompatibleWith(MediaType.APPLICATION_JSON)) + .andExpect( jsonPath("$[0].name", is("None")) ); + } + + static byte[] toJson(Object object) throws IOException { + ObjectMapper mapper = new ObjectMapper(); + mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL); + return mapper.writeValueAsBytes(object); + } + + static T toJsonObj(String content, Class valueType) throws IOException { + ObjectMapper mapper = new ObjectMapper(); + mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL); + return mapper.readValue( content, valueType); + } + + + @WithMockUser(username="admin", roles = {"ADMIN","USER"}) + @Test + public void addVxF() throws Exception { + + UserSession pu = new UserSession(); + pu.setUsername("admin"); + pu.setPassword("changeme"); + +// /** +// * auth +// */ +// HttpSession session = mvc.perform(post("/sessions") +// .with( SecurityMockMvcRequestPostProcessors.csrf()) +// .contentType(MediaType.APPLICATION_JSON) +// .content( toJson( pu ) )) +// .andExpect(status().isOk()) +// .andExpect(content() +// .contentTypeCompatibleWith(MediaType.APPLICATION_JSON)) +// .andExpect(jsonPath("username", is("admin"))) +// .andReturn().getRequest().getSession(); + + + + + File vxfFile = new File( "src/test/resources/testvxf.txt" ); + InputStream in = new FileInputStream( vxfFile ); + String resvxf = IOUtils.toString(in, "UTF-8"); + logger.info( "resvxf ========> " + resvxf ); + + File gz = new File( "src/test/resources/cirros_vnf.tar.gz" ); + InputStream ing = new FileInputStream( gz ); + MockMultipartFile prodFile = new MockMultipartFile("prodFile", "cirros_vnf.tar.gz", "application/x-gzip", IOUtils.toByteArray(ing)); + + +// Map sessionAttributes = new HashMap<>(); +// Enumeration attr = session.getAttributeNames(); +// while ( attr.hasMoreElements()) { +// String aname = attr.nextElement(); +// System.out.println("aname is: " + aname); +// System.out.println("Value is: " + session.getAttribute(aname)); +// sessionAttributes.put(aname, session.getAttribute(aname)); +// } + + + + + MockMultipartHttpServletRequestBuilder mockMultipartHttpServletRequestBuilder = + (MockMultipartHttpServletRequestBuilder) multipart("/admin/vxfs") + .with( SecurityMockMvcRequestPostProcessors.csrf()) + .with( SecurityMockMvcRequestPostProcessors.user("admin").roles("ADMIN") ) ; + + mockMultipartHttpServletRequestBuilder.file( prodFile ); + mockMultipartHttpServletRequestBuilder.param("vxf", resvxf); + + mvc.perform(mockMultipartHttpServletRequestBuilder).andExpect(status().isOk()); + +// mvc.perform(MockMvcRequestBuilders.multipart( "/admin/vxfs") +// .file(prodFile) +// .param("vxf", resvxf) +// .session( (MockHttpSession) session ) +// ) +// .andExpect(status().isOk()); + + assertThat( vxfService.getVxFsByCategory((long) -1) .size() ) + .isEqualTo( 1 ); + + mvc.perform(get("/categories") + .with( SecurityMockMvcRequestPostProcessors.csrf()) + .contentType(MediaType.APPLICATION_JSON)) + .andExpect(status().isOk()) + .andExpect(content() + .contentTypeCompatibleWith(MediaType.APPLICATION_JSON)) + .andExpect( jsonPath("$[0].name", is("None")) ) + .andExpect( jsonPath("$[1].name", is("Networking"))) + .andExpect( jsonPath("$[1].vxFscount", is( 1 ))); + + } + + + @WithMockUser(username="osadmin", roles = {"ADMIN","USER"}) + @Test + public void deleteVxF() throws Exception { + + addVxF(); + + UserSession pu = new UserSession(); + pu.setUsername("admin"); + pu.setPassword("changeme"); + +// /** +// * auth +// */ +// HttpSession session = mvc.perform(post("/sessions") +// .with( SecurityMockMvcRequestPostProcessors.csrf()) +// .contentType(MediaType.APPLICATION_JSON) +// .content( toJson( pu ) )) +// .andExpect(status().isOk()) +// .andExpect(content() +// .contentTypeCompatibleWith(MediaType.APPLICATION_JSON)) +// .andExpect(jsonPath("username", is("admin"))) +// .andReturn().getRequest().getSession(); + + assertThat( vxfService.getVxFsByCategory((long) -1) .size() ) + .isEqualTo( 1 ); + + mvc.perform(get("/categories") + .with( SecurityMockMvcRequestPostProcessors.csrf()) + .contentType(MediaType.APPLICATION_JSON)) + .andExpect(status().isOk()) + .andExpect(content() + .contentTypeCompatibleWith(MediaType.APPLICATION_JSON)) + .andExpect( jsonPath("$[0].name", is("None")) ) + .andExpect( jsonPath("$[1].name", is("Networking"))) + .andExpect( jsonPath("$[1].vxFscount", is( 1 ))) + .andExpect( jsonPath("$[2].name", is("Service"))) + .andExpect( jsonPath("$[2].vxFscount", is( 1 ))); + + String content = mvc.perform(get("/admin/vxfs") + .contentType(MediaType.APPLICATION_JSON) + .with( SecurityMockMvcRequestPostProcessors.csrf())) + .andExpect(status().isOk()) + .andExpect(content() + .contentTypeCompatibleWith(MediaType.APPLICATION_JSON)) + .andExpect(jsonPath("$[0].name", is( "cirros_vnfd" ))) + .andReturn().getResponse().getContentAsString(); + + VxFMetadata[] v = toJsonObj( content, VxFMetadata[].class); + + mvc.perform(delete("/admin/vxfs/" + v[0].getId()) + .with( SecurityMockMvcRequestPostProcessors.csrf())) + .andExpect(status().isOk()) + .andExpect(content() + .contentTypeCompatibleWith(MediaType.APPLICATION_JSON)); + + assertThat( vxfService.getVxFsByCategory((long) -1) .size() ) + .isEqualTo( 1 ); + + } + + + + @WithMockUser(username="admin", roles = {"ADMIN","USER"}) + @Test + public void addNSD() throws Exception { + + UserSession pu = new UserSession(); + pu.setUsername("admin"); + pu.setPassword("changeme"); + +// /** +// * auth +// */ +// HttpSession session = mvc.perform(post("/sessions") +// .with( SecurityMockMvcRequestPostProcessors.csrf()) +// .contentType(MediaType.APPLICATION_JSON) +// .content( toJson( pu ) )) +// .andExpect(status().isOk()) +// .andExpect(content() +// .contentTypeCompatibleWith(MediaType.APPLICATION_JSON)) +// .andExpect(jsonPath("username", is("admin"))) +// .andReturn().getRequest().getSession(); + + + + File vxfFile = new File( "src/test/resources/testvxf.txt" ); + InputStream invxf = new FileInputStream( vxfFile ); + String resvxf = IOUtils.toString( invxf, "UTF-8"); + logger.info( "resvxf ========> " + resvxf ); + + File gzvxf = new File( "src/test/resources/cirros_vnf.tar.gz" ); + InputStream inggzvxf = new FileInputStream( gzvxf ); + MockMultipartFile prodFilevxf = new MockMultipartFile("prodFile", "cirros_vnf.tar.gz", "application/x-gzip", IOUtils.toByteArray( inggzvxf )); + +// Map sessionAttributes = new HashMap<>(); +// Enumeration attr = session.getAttributeNames(); +// while ( attr.hasMoreElements()) { +// String aname = attr.nextElement(); +// System.out.println("aname is: " + aname); +// System.out.println("Value is: " + session.getAttribute(aname)); +// sessionAttributes.put(aname, session.getAttribute(aname)); +// } + + MockMultipartHttpServletRequestBuilder mockMultipartHttpServletRequestBuilder = + (MockMultipartHttpServletRequestBuilder) multipart("/admin/vxfs") + .with( SecurityMockMvcRequestPostProcessors.csrf()) + .with( SecurityMockMvcRequestPostProcessors.user("osadmin").roles("ADMIN") ) ; + + mockMultipartHttpServletRequestBuilder.file( prodFilevxf ); + mockMultipartHttpServletRequestBuilder.param("vxf", resvxf); + + mvc.perform(mockMultipartHttpServletRequestBuilder).andExpect(status().isOk()); + + + + File nsdFile = new File( "src/test/resources/testnsd.txt" ); + InputStream in = new FileInputStream( nsdFile ); + String resnsd = IOUtils.toString(in, "UTF-8"); + logger.info( "resnsd ========> " + resnsd ); + + File gz = new File( "src/test/resources/cirros_2vnf_ns.tar.gz" ); + InputStream ing = new FileInputStream( gz ); + MockMultipartFile prodFile = new MockMultipartFile("prodFile", "cirros_2vnf_ns.tar.gz", "application/x-gzip", IOUtils.toByteArray(ing)); + + + mvc.perform(MockMvcRequestBuilders.multipart("/admin/experiments") + .file(prodFile) + .param("exprm", resnsd)) + .andExpect(status().isOk()); + + assertThat( nsdService.getdNSDsByCategory((long) -1) .size() ) + .isEqualTo( 1 ); + + ExperimentMetadata ansd = nsdService.getNSDByName( "cirros_2vnf_nsd" ); + + + assertThat(ansd).isNotNull(); + + assertThat(ansd.getConstituentVxF().size()).isEqualTo(2); + + + mvc.perform(get("/categories") + .with( SecurityMockMvcRequestPostProcessors.csrf()) + .contentType(MediaType.APPLICATION_JSON)) + .andExpect(status().isOk()) + .andExpect(content() + .contentTypeCompatibleWith(MediaType.APPLICATION_JSON)) + .andExpect( jsonPath("$[0].name", is("None")) ) + .andExpect( jsonPath("$[1].name", is("Networking"))) + .andExpect( jsonPath("$[1].appscount", is( 1 ))); + + + + + //https://patras5g.eu/apiportal/services/api/repo/admin/deployments/ + +// session = mvc.perform(post("/sessions") +// .with( SecurityMockMvcRequestPostProcessors.csrf()) +// .contentType(MediaType.APPLICATION_JSON) +// .content( toJson( pu ) )) +// .andExpect(status().isOk()) +// .andExpect(content() +// .contentTypeCompatibleWith(MediaType.APPLICATION_JSON)) +// .andExpect(jsonPath("username", is("admin"))) +// .andReturn().getRequest().getSession(); + + Infrastructure infr = new Infrastructure(); + infr.setName( "Cloudville" ); + + mvc.perform(post("/admin/infrastructures") + .with( SecurityMockMvcRequestPostProcessors.csrf()) + .contentType(MediaType.APPLICATION_JSON) + .content( toJson( infr ) ) + ) + .andExpect(status().isOk()) + .andExpect(content() + .contentTypeCompatibleWith(MediaType.APPLICATION_JSON)); + + + gz = new File( "src/test/resources/deploymentReq.txt" ); + ing = new FileInputStream( gz ); + resnsd = IOUtils.toString( ing, "UTF-8"); + DeploymentDescriptor ddesc = toJsonObj( resnsd, DeploymentDescriptor.class ); + + String strddescResponse = mvc.perform(post("/admin/deployments") + .with( SecurityMockMvcRequestPostProcessors.csrf()) + .contentType(MediaType.APPLICATION_JSON) + .content( toJson( ddesc ) ) + ) + .andExpect(status().isOk()) + .andExpect(content() + .contentTypeCompatibleWith(MediaType.APPLICATION_JSON)) + .andReturn().getResponse().getContentAsString(); + + + logger.info( "strddescResponse ========> " + strddescResponse ); + DeploymentDescriptor ddescResponse = toJsonObj( strddescResponse, DeploymentDescriptor.class); + + assertThat(ddescResponse).isNotNull(); + assertThat(ddescResponse.getVxfPlacements().size()).isEqualTo(2); + assertThat(ddescResponse.getVxfPlacements().get(0).getConstituentVxF() ).isNotNull(); + assertThat(ddescResponse.getVxfPlacements().get(0).getInfrastructure() ).isNotNull(); + assertThat(ddescResponse.getVxfPlacements().get(1).getConstituentVxF() ).isNotNull(); + assertThat(ddescResponse.getVxfPlacements().get(1).getInfrastructure() ).isNotNull(); + + } + + + @WithMockUser(username="admin", roles = {"ADMIN","USER"}) + @Test + public void deleteNSD() throws Exception { + + + UserSession pu = new UserSession(); + pu.setUsername("admin"); + pu.setPassword("changeme"); + +// /** +// * auth +// */ +// HttpSession session = mvc.perform(post("/sessions") +// .with( SecurityMockMvcRequestPostProcessors.csrf()) +// .contentType(MediaType.APPLICATION_JSON) +// .content( toJson( pu ) )) +// .andExpect(status().isOk()) +// .andExpect(content() +// .contentTypeCompatibleWith(MediaType.APPLICATION_JSON)) +// .andExpect(jsonPath("username", is("admin"))) +// .andReturn().getRequest().getSession(); + + File nsdFile = new File( "src/test/resources/testnsd.txt" ); + InputStream in = new FileInputStream( nsdFile ); + String resnsd = IOUtils.toString(in, "UTF-8"); + logger.info( "resnsd ========> " + resnsd ); + + File gz = new File( "src/test/resources/cirros_2vnf_ns.tar.gz" ); + InputStream ing = new FileInputStream( gz ); + MockMultipartFile prodFile = new MockMultipartFile("prodFile", "cirros_2vnf_ns.tar.gz", "application/x-gzip", IOUtils.toByteArray(ing)); + + + mvc.perform(MockMvcRequestBuilders.multipart("/admin/experiments") + .file(prodFile) + .param("exprm", resnsd) + .with( SecurityMockMvcRequestPostProcessors.csrf())) + .andExpect(status().isOk()); + + assertThat( nsdService.getdNSDsByCategory((long) -1) .size() ) + .isEqualTo( 1 ); + + mvc.perform(get("/categories") + .with( SecurityMockMvcRequestPostProcessors.csrf()) + .contentType(MediaType.APPLICATION_JSON)) + .andExpect(status().isOk()) + .andExpect(content() + .contentTypeCompatibleWith(MediaType.APPLICATION_JSON)) + .andExpect( jsonPath("$[0].name", is("None")) ) + .andExpect( jsonPath("$[1].name", is("Networking"))) + .andExpect( jsonPath("$[1].appscount", is( 1 ))) + .andExpect( jsonPath("$[2].name", is("Service"))) + .andExpect( jsonPath("$[2].appscount", is( 1 ))); + + String content = mvc.perform(get("/admin/experiments") + .with( SecurityMockMvcRequestPostProcessors.csrf()) + .contentType(MediaType.APPLICATION_JSON)) + .andExpect(status().isOk()) + .andExpect(content() + .contentTypeCompatibleWith(MediaType.APPLICATION_JSON)) + .andExpect(jsonPath("$[0].name", is( "cirros_2vnf_nsd" ))) + .andReturn().getResponse().getContentAsString(); + + + ExperimentMetadata[] n = toJsonObj( content, ExperimentMetadata[].class ); + + mvc.perform(delete("/admin/experiments/" + n[0].getId() ) + .with( SecurityMockMvcRequestPostProcessors.csrf())) + .andExpect(status().isOk()) + .andExpect(content() + .contentTypeCompatibleWith(MediaType.APPLICATION_JSON)) + ; + + assertThat( nsdService.getdNSDsByCategory((long) -1) .size() ) + .isEqualTo( 0 ); + + } +} diff --git a/src/test/resources/application-testing.yml b/src/test/resources/application-testing.yml new file mode 100644 index 0000000..5ab1763 --- /dev/null +++ b/src/test/resources/application-testing.yml @@ -0,0 +1,81 @@ +server: + port: 13000 + servlet: + context-path : /osapi +spring: + application: + name: openslice-portal-api-testing + datasource: + url: jdbc:h2:mem:db;DB_CLOSE_DELAY=-1 + password: sa + username: sa + jpa: + database-platform: org.hibernate.dialect.H2Dialect + hibernate: + ddl-auto: create-drop + hbm2ddl.auto: create-drop + show-sql: true + generate-ddl: true + # Embedded ActiveMQ Configuration Example + activemq: + broker-url: vm://embedded?broker.persistent=false,useShutdownHook=false + in-memory: true + non-blocking-redelivery: true + pool: + block-if-full: true + block-if-full-timeout: -1 + create-connection-on-startup: true + enabled: false + expiry-timeout: 0 + idle-timeout: 30000 + max-connections: 1 + maximum-active-session-per-connection: 500 + reconnect-on-exception: true + time-between-expiration-check: -1 + use-anonymous-producers: true + # Spring JMS Settings + jms: + listener: + acknowledge-mode: auto + auto-startup: true + concurrency: 5 + max-concurrency: 10 + pub-sub-domain: false + template: + default-destination: + delivery-mode: non_persistent + priority: 100 + qos-enabled: true + receive-timeout: 1000 + time-to-live: 36000 + servlet: + multipart.max-file-size: 10MB + multipart.max-request-size: 10MB + mail: + host: localhost + port: 8025 + properties.mail.smtp.auth: false + + +logging: + level: + root: INFO + portal.api: INFO + org.springframework: INFO + org.apache.camel: INFO + pattern: + console: "%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n" + file: "%d %p %c{1.} [%t] %m%n" + + +oauthsign: + key: "EK97Y7Y9WPGG1MEG" + + + +#QUEUE MESSSAGES WITH VNFNSD CATALOG +NFV_CATALOG_GET_NSD_BY_ID: "jms:queue:NFVCATALOG.GET.NSD_BY_ID" +NFV_CATALOG_DEPLOY_NSD_REQ: "jms:queue:NFVCATALOG.DEPLOY.NSD_REQ" +NFV_CATALOG_GET_DEPLOYMENT_BY_ID : "jms:queue:NFVCATALOG.GET.DEPLOYMENT_BY_ID" +NFV_CATALOG_UPD_DEPLOYMENT_BY_ID: "jms:queue:NFVCATALOG.UPD.DEPLOYMENT_BY_ID" +GET_USER_BY_USERNAME: "jms:queue:GET.USER_BY_USERNAME" \ No newline at end of file diff --git a/src/test/resources/cirros_2vnf_ns.tar.gz b/src/test/resources/cirros_2vnf_ns.tar.gz new file mode 100644 index 0000000000000000000000000000000000000000..c92d9c6d2fede7aaa6490dc56ede5d4e14813104 GIT binary patch literal 18831 zcmb@LV{;{p0)uyJ+qP}nwryi;Z{1Vd*xI&j+qT_P_r5>ke$2N_p2Mmi~Jkz zts8zbXV#_q;q$o=o8ZOjV!y$~Fp$NpIo3mkFcQ_s)l+1uAA2>y8ch2B@>^b<7zi`<_=<^eh{FHO;xT5>M3+u4;ox!b*ZTzu| za54X#8hISWrhaZ-O#T(rkHf{w+i3Yw+1Rj@S@SYGGcz8dx6F7ZDDpFV{qvNq4HT0N zmpUIkI}cSonfCzYrvOCsoWzamiS3e1z+h_pV&+{B_cFGdQWCmk!ep#tpvugsY^76N z#iomjIai;YlltYdJJs9H~#HrDz;!9G5!%aXGhi*UBI{EzwFlDU~xZ9K%GL zPEc$~#y!?PUx(?|sZKq$T3psXWM$JnJi_@yUo2CpR*6RAR-=raWw@iMUChoc@=_ps_R0tJ&Asj?zoB0R9GUnp>%)dl8$B~$3TX< zUCl9Dp!hGu!nB2GjdG6l!dU|=dP(-xaHQO|Ns>tEj0)`%H$^Z5>u56TPVzK;H>(fl zyei$h42Qv)K2y!?erK&Ms&ut z5PpaoXr{hH$yBNCiZMbbCTO6!*?EKf;V3S8Mo7`v6k8eE2Aygc2_-47Y$0>T)B1Xt zdj!FdYcLI)X8dI}&Dqh9o2G%VR#Oapw2XNIBylZKk56kN)b_>vEd4}NC% z#Wt3r2VJ8`nC-|si-?}#-0*KEL&*Mx(q{wbr;wvjeDP$6rYV`6EnObgxJXFJ7h|5+Q;ApCiw@4hJ`_wX;_ZCI%pB9vx8vwX{^1D zw6uiubig5-*woExR-`-cLFQ4?uk^v@a6M`ANibA+fXFzWNeYV$4g~@_IOP8$7iNhT zYy&2&>DZ4-tK>42mq_(6YS-|@~wktz5GV-R$~oJSG#VC2@hnK zEK$r*(;GHg#knq=+8Igpf16YfGv2%NJip&-$21hll!=kb|3&Z48%rn{%Ns^HxOft{ zc`ae5hIRl6*QaTC^_R{X3dhElNC-(ZG0C{HHhg*qu3jmE!xHx3@L4 z$XADSTWuJZSs1?W(utJBg$5oPDisqq9NK8)&F@s7F7&2P?h@ z4k{%hBcf|dyG1s83v@}ZSD}tPnHtV)z9a@j?Cr$J$p==pBNGH5RWo4PFld;r)#Y1R zTL;RNi`h?;i_Lp8EWEZco7VmG`NI(k;KjhhM-X9)1pa!l;C+h1ba{lBGXM<~%6pS8d0pGt8y{M(>wV_?cAwoG>2|6D#pIng}(1zUGWmDi8E%JUUr; zDphU?pBrwx?Ws)_;*tZ{?-x`3;f|lew$zQw7vN2cO6ZY1Yx-%&_S3j9Yk{<4>h<($ zC$IdHDcgUrg>?X!O~eoWPCq5jaUKQ!*-!|ug*^F=Y(^5tfYM8NNJmc(+>y+>?;>R%I8k)+tH zAndkAa6GF^bJ%pfeN5V+?aa^J*)g0wbmLtvTLw>7G?B#IAt|XR^1rQZP7|)+rD`Ai z`ol+J92!tT8i;DjSYhu{5aC)#5NR-onfAQ<*=)gOzxN}xkJ#zcVBXf6d%u9!&o?2V zBp#M)MBi6M*s+bOq!5w_=+IsJl1&?=71A&I>4I%tf#wHFIb904IH!`fqzrVZ! z`qni`^+0f6zn?gJUfTA@ z0ghD+c%2~%B(bmo#IpW?j%MbF94^%xzLSJU$z4QF!8+I4&XU0PE}&A;<5etH;4S^@ zW~{2p({}8Ji!A&AgCQA8;oCs_Q82@5V{Abv;?Oobu^Oa~{+TZ6T9loPs(_6(E=NyX zKO%!f{Knb~+90YdQYAf+XpTq|MR-(C4VqIMQ5G{IsO2`KyYPP;{<&{ML@p%sl@0v% ze+vP~$A$r7ZepcMUno$T6zW)pb#m{AW2cwb}Xg>hi(~)_*|`4u~%(l+}O`WMn;#j zzH3;%9OI3~eBP2Dry)-sHE7-y3H~tAEmva=gN@E0hcOaGqbwGh>Vkp%=;i&bnN@!l|Cj zIpl#djB6f`Lh~UL#8f(LZ)NkS7aTiMB67Kt?+1I@zZt8fuy;BT_iU>Q9T*V!q}etxlk6ayZ+xXjVerrHc_J*2QIA3re6403mpYiX=THbS=GRweqj|;a}~3 zE^z3|4h-T(gOZmCN?cL0()gDWnkJ+we0nqDfYO#s8JwRmw80YL`G5OZJp*FO570QR ze2AMZg7dj{O&k}YYr!pi=9Q zK`B#mYsQ$>U5L7Pg?(FVcqg5#* zOLQQrlu+qSm~7e|a5^i`1CucmLr`eMz6e!W0C52|0&Irwo6asTU;uvg(;J-42Z6Y} z9sa%r14;+aRpKs`1aRbiU}BU+Ze%z}z2tw#Gped+@8J7pBLozSb57?$11l0#@wF*67WL$tWwpX1x7_x_Wtw zs;KX}^KJ20miq>XLD$m*ZEr=VPpUOhPRG}^!Pw5Xa%O%Zp`PVA-(4IjR+l-i887gl zkoFT5H`voH4gRCbB(K4lz!Mn*#6*S7=>R%7>!JLn>>Dp`)Zpyz4z!0IL# zZuoR(-hC@qdqMaZR1*(=Un?ZBE|3$=*9C!v&=l8%krMPN z`)1wy82W*j@9tuJcUrbxHzC1gXMNO`_+-7d=W=nVhV0+K*3)2nNGmX)mC{}MO)AU= znKY$f`C82Ak)o)#6S`4x?H@WNNow>SF(OcMQjVPV%7+cMAhccSsI(b^AZOBzBfyG#}% z)cCg`;gU63Xk#SiQpBM5`D7c0Df&W9G&juAiB5LYctRHCv~9A_EIKbZnT8l>hT>oxnHCcOegs2YHNe zmKK!e-01Pw3@@ZdIQcm<;x1l2b!|q4y6=Dy9Sj_V%L5qai~&PSHlIW_2e$oyS`AmD z%xwu6hd4X?!2#`Tu%y0zqA~WXvhvn@X74)+iHz=bFS4nv+2@c*M0m>r_OWjn|81yN zp%iuG#UerO(^6$XK+Uu<>=(-o57{2GpCE3-7dtNe%)9qac=m;VL0L#J+F|#>IRC`2O{iC-K}?tV1;ZgdKy&cTBo;n9mSnaY)^MD}P-$KvH76mn zX-b{_u1I)~#m(RGVw?@wycxx5SI?%~jj#|O3*tXhTs*!8_ui3YEvZ90?DdOZx_@nw z>|WGZ_R`Qo8@Yyo5_YV`}j zP(nbF%s;sC)5yv=U%gopDaeNc|Im|^;lee&t?hml_V{ZJeP16#=uaGfU(ueCKl z&yy(nB=P6t`2RJEKLbbao^Q4nf}MlEZRc)4LG$!FA%PS$dninIKT@Sj%3hM?Ws@NZ zdg17=(8>dUB$O^}ix%&3SVkfuz_ut!5h=^(?Z6VBNsH&x=Z7SpM{oCs(tpg4W&R#k z)Lfn4?Dk?l7Z^0luGrA0YSzK0ns)8|vN#})=dxoZ4gpaahf6{$m$R5uD`sKJ7?;x! z89<86{L2i@WoinGn>GAFVmBE@HknGUt81I)y?eT|nne7CGHiq4KR1mbdsYiP443E{Rm<>QaxvpPugxTG^9Y zs{dLH^~SA!SEo5;EKezdu^2OpQwK+bjp^&R#=RCT-||*A&$}N(fx*rrz*ERQZZr@# z;LY}Vi0EW>#?s;c4bss24nKju8{}Xx4u8W&47NRZ#J=+w141*Jq~#LLg_xvJY*9+o z2%}BQM_e5L+bW{a_1Mw>&h@gVmftgAy7GJP$vMTK755xZAP%#8n?DLE76Y8InXD^_ zqFQ6BT4KnHRBGJd8Jj~wyWCr41d=qZKI(P+P&-Pw+(l1wWO`r+R|ypk-;l}Tu3-=m zEu#{)%6siwL*>$DGB$Obt2Ur+c4)7Twee^g;;l=?SuBtiif)nKibjaA*28&rF`-5- zeYenfNto`8gi)j3oXuTpWBX$?-l*MrSf5?Yb$&h~Kw^W-BCA}}7}XW8ux8R}zD5hp z#Oy)1f2l?6*rot`8Ngu~$`qOLprVHr8^X9&A=Z#~uIHu=ejJW=DoJ{$&!-6Zm|UC` zIvn65t-P4xOew?vbMT{{u|mQg*wla z?ahB6qz=Q+)cpmQOwf{7S8zg&K%Fh17_H4QleoY!@RQBh zU@c>*|2ru^5p^}XcNEE+=wNuIM`DUHZq16CltHA7LBJ;`GG;G}o3?(~02V#;Uw~&P zK@9C}$g&w`_QkuObq@%E>Y9q~HGsr=Ayk<}#&>u(_3xVA;X`h%74fCowe;b5Hl9O+kA53Hd2A4vZB}L)t2OqoVSf^rv96=w)=f)p=1y7)+ssB z(luYnmclV&kmkH@K<)2$Jm!bQ#$GIhazQhUM9zdRmIWcsWuJ*CLQ~|CUWntgMz8%I z-uLy!sAuO-Ro$Nx2FLl!<_z*O)>%|DX9j_hUqLB$3s`k+rby3zm`FQLoN7rhaWX;u zq#u_6xfK|Z^u+bWPx2(}gg}9Zc+`-Nn@|dm-y-^!5sP|-&QnU~)lL2rV&(o5pC(Ya zQBMfKcH3ria7l8QD7?^DCBM@IO3SUowSWhyoQm%&-K<6%HM^M8ZiZx(Ok>znJd~0w zb)_*Kv#}BJpItYi#a3|=0IRwjNFT#TTT8^QmV5m_&pFXqW z*0(}5c$+R8CB!8lfFM*E9e0twB~Q3~`Pkklx%TmYX^kyz$fM{lil-dZGSrYthoZnk z@WkfWtk{R~s0Kk6xHHawU9_}K>N~0g$^Qm2UbLc;FGj}^^yffkzslo7^y$&lm zbGLfL6p@|?EE^u)o2;xPc=)`piL`r!6bK+;lR2>)eZrmRJh>UTcD(x939c9*A36oU zH+~16@gv8a6a!qZ2{Igi)6|LXyzMfpKosA*Z%S)7KLxwLN_)Qv1FsHzoDB*_QmIlTqJ=KLnPn(YKEJ8p-adGvx(BZZgN z|4w}dDli_GEhy|eINk#98!uQZcceLvo1VMWJj5NV#}i=btoeFNd(Az>jsnOWgxBTq2~p2i)Hz4X z8y!rRrSqil;KmuNXno-hAcoArV!B54gw(3RVCxDI)oABh5 zPUN}m{rPrucw0y_y}e$8){shu(qVhRT#e1yXzDAirH#F~^}1XT_Bk?v!u#b{J#FRnj;z-GO-V&9GqmVc z6P#Sia)I<5Z|OujG#w_ReB80R7CFvKBjrT^7x2pZ%7E{Lhu88YbsuGTMT7{Ds?UPa z*NK5B)zMw8h1uk|l-JpZPf8hfK*v%nJ0AlRe7&qPfAsvgJc?mhV;X6lQnBu*sUfCoJr~c-@FDDC2$P?^-k)64m-9F7i7nQ=B zhWH%U$Ng@9-4St8EJ=<*ZSd0SZon6rHvOTT?qlXM@ukf=5nztZ94Rw8Fp;D%Wqpr) zGa|J|kBVRbcTnF-7@H%_ANCSPukFfVz~mCY=oet5!x>RsZa~uWRBz^bIQ)5eph$KcyWJuXeF)=_w)-R)q z`JWuFnY1T$5kZC9iHBMf2hI1PnOmXh=sD#Db=ff5@vri;Oiln+h5vi~jP4WDrvQ1{+KzPW8`U~GjD4w}vStp}5Vq%k7)TG*Qq zgUczPuA}qry?Cw~TlMk%09Z>M<(O_J<{QD2DwdAqv+Rk-N@2!*_tY>}7XEfFH&Kr9 z%-aSY+yDvmpriQJg@Z7|fP^B_i50PJ!$0us`+!tI7}<8t+bB=}{>eQXH6k7tljL#U z*tZw(uH%|h{hTi-a8y4fW0P5mBxqC9b9>~i$h&MQVdtpf2WjVF-zinGPs+?J4s4o= zAqh1d(>w3s2yJJ0+gO7EV_9=oqAOM&k^Wyr2?=7s`f`6nJ2<-Pr8MIk{)^UxQHg?@ zh$Sk(vF_Mgc2>zs4oT>TZo=pmN*RwoKj6o{ll#$i^SA{USU7y(`E&XbKR#gU!Wpr6 zE~bs0z?ugv3}dCN8L6~|O(+p*i@-ue^-W+sxgmD#(XkvTPpv$mrDPPb>2MN8>IwWi zYQTlpDe5?<(k9bW+n3sx+jqL_s|(nvWH|u=o$eY1Y)lJ!cNGa-ITI;K{ud?r5at!^Os6_WcsZoCHDizveV;LzrjO z$xMLy{C+2gp!z!HHv1qX)HJTZrzLe8J8D#S6AfsC{j4EHwj=PgAka1Zx`Tc%L-O1L z5o+gX&e~5HdQ;0Yw`L^;mU${SE{-O`3b#PbG=?%!rg*-D2KC7XIuY1>Vyu`EZpF-2 zMb>JKS6_ihv2x6q1TFWl@1&O-TT-gZsUbQT_U-bad4De|aw@rOb}3dGQ$-3Cw2XknbEy1Yw^_ z0wd0vYFp!~dyYK_%0z{ot3 zcgr{>Bx438wX)26VOg%!4B3jk%h)Lv2&Iu?aaKmZiTCti@r)C76)iM*;w+^^q_lqM zFlp?3MUv=&doX?N>KTi*Ic)R%)>ox=4wCxQV9;O&@O)*{|5Hw^*nrP{FMaz~5_-}A zQx93Iq`=pjI2MJvorOuzj#(Hk5OPHqp8ZHcrW#8WQBap|5fnGaMK1nkdO0ckl{hXU zu_uvBaWSKKY9dWVMxvw+8(M*24&R~#0+jR;b{ulAk+1%<6=RRzi*7KG%ihkcApf^b zo@Xk`_eHx_;%XXy-IVxvD_O&rH6Nk>QM-Qp5Dd017V5YC{@AFoy$L*Ql z@hX+yewvfOCs@$7rZ}a{(kXH;Lw*qwPTK~8$Dp#aepxNL>F91qjVJi@@UQV~*y7YK z;yJEoN60SXXlEJ09rcKfBR(wT8R@dEl8UhadM`GvQYHfC=|lwSqIBQF5T~#jM@lE9I>;~<$qnK z%l-B$xWv?;#AagX3YA5@JCn&WC^6PH^|&4bf?!e3sM$ESG6$n?M;x1{cj1+_M$%^J z)T$^3Bm?S4BvUDwyICw#P?eUqo^lj&SnCBThsGh8x!r*Q2mnkCN~5!_kWmtHLJ~%} z1y7vAYmb4qlu;_}QPgLe`e!V3jM+Fotcu%z!~RemUQz!h>WFjGs4VYKKau|311goph_)T^CQnuNJbxfg*(JR(XsS={s0{Np}RE zn8-cbgVS6%8vE^;&#Tn}8FvS^YCLLLX-1B-g!e-GsCSZGO3HmaxV*mW>{~8NE<-+( zLvgi-W`Y@|b*D_VZR$4z`*RMhgsj#_Zm04yg6saTsyGs=@PrlfpFv zl?3kR_6hTVuiR*n?er1dr1!ryLqtWmtJ1aRU=1Jr#dHPxa&MwXSy-N87A6_La4ZG6 zE0nJY#pSZRjj@!SgK^U&aQO6MGQ>@$!g-ToD+dD|2!Kmdd zvUk+YX5b;L8}g1RX}b(+_b};D<6D}Vo>E7%;v<7T2XhMZIZ~!A;wZh=B&cQ20$gzO zE0>$b4C)mH^berL6_iUrXj~A;WCJ~84QBLz?H;RY9SqH6UR-!f!;Jm|P%l?#Yq2L$ zB3ieyrc*VG0czVoa+0?!6-TmJQ#V)kmhO1eKCa7px-l9be`JzN~!(#Xzzo$ zkUM6qguSj8oeX%5dY8PV8HH% z&!G%`(Zx|Tj1N&WnVUtXwG* zn^9{g82^122RAnzCg)kRRpN3&=bgNM%k05_;q*|Cxw?34Sx<&{DU!XcP_%=2QhxI? zIHFDX-Q|q!c~>+vu++AtlA~N1V>M|5=#;}yKfgpXa9izk9$b${*R&cS)*Hl&LSiNK67RIv z_mt5Gq{hkxk20TvGn{&ykE%2(m+SeN69TNO`a6OFYhvD_{Bs3yf@BJrQO#sT+~n}c z=3qPinEi&;b+QA4P^1T!sC~ZTOi+p@Fy-=jXErqNZCGYaz0V8-RAC$(4hIjxwg}+U zyMUq+hasDrzmn^vUG_I3&8{`ypV#cm?6mq~Zu)pE zcbYGznRMQGmY*r-7){sDR(T(55d9y7h zoz~ttA$li)o)dEr77N)pX;XI+(d6{S0Vc`w3~pDGc5}2ROS?x zs&Pv4HziF7B`34O{XA8(r}fEZQAkYD(W$eR#OAF%u{F_rkd;LCEbPwWVz9@Kmn0YR zy5sN=7FopI7(}pWNR|^E8^MD!0~&pc7*Al}FBg4DOG{V(L8yUI9v+^$>W=sE5!va> zV8<@$FhgkSM-`HhBv*;O_rf5}X~0l*E37IGAJc@!?`SS{J`@eAD_#!F1%6RDt-V77_ba6{K=2{skS-}P6p-vR% z3Wj$ta4AqsX-txJL5hnb2Wi}s@iI%F*7uGf%x&%G^dxflu8F^sXsa!n#5;tr#p#KQ zF^4ZC9|hmzB3l)g2^Q-I%qz3pKp16obvNb5hjAPuutF3l_2{p#Ej(mpWMJqpq7vtJ z5he3(xmzWZs{!E0ceN@gG1F~RLfmIeML+BLV;HY{UW2(*Mhv&W%?svg1Su9dRNDb? z^zR7Xqle8elz{uKjm_+Yj>i1qdzl0haekihKy4dmJ%kxqa;>CCKM^?sy@#d30$a`s zZ<;!`XaDqNXRy#w$Nf^FWLdO$@gTe?<`(>t&OC$r{mb6%y0hDj9yi)egvyoKu&zoy4skkSAmePFJ(viPVqK6U5-c+{Nfq7 z6uTf1TeN0knHpZR1LS@XvANi4!LVKb-;YWDzri`95IUtD%jYhypmJ<@R~WG&2lBDk zwVU~yPZcDB^4AMLrku}(YF>){h=Ecf=Snz?ow2?HG7NE_hZ($nhHoMz9A zmiCNDsPZw$hxI6NNj`?`MBNksJnjs4n65)TH6??ym*?@Fwhbwiv~O20b;iHqpg&#-M$|slDL!NygwZ@qRmo44k55SkZmKY&N7DZL{*h zvm?EbY^#Lag@y<8Tn}#NOXhX~$xqVxsb>=&}l*oG~g@_#UOML8$8l-Vw)7`c0?Q+ z4rlzSbF-)vk!|}4i<#=oXU&UwT!kYQV==CrR?mAH24Z4E z?`cdUxx)_eS}C_ft?OG&0!~lM-0?=M+Q8FMRLQokgIAr7=sg(x z;|_-DBWDw|@jenCYCmlux;(R|2ZrL1bo*`-XO?n*`k}3NCYf0Y;;R=4gL^9#kc4uQ zXSL4<;rauovd6}t7TWR<0YyxKN$FB>78KvVY+|5U4++Jbh~7xC$fOfWxE-cv1xU-A zGxMQKj?4%I%PJ}}&}DKs^y~n+*Im(v?Ab>%d}3IIJQzSrzE}uN_!qYuq=3_5#{4e| z<8l`xnh-06S~eIcFaVWyYKGMYs=u@0Aw~w*7dS~|q|upruLYA9s8_e>N||_AJI6*b zTdrLKJ3;GaQg%jbZ@%KYIFsda#o82h#Os(+@rP|9Y^ceJ+%xWc%5OH+XfsHzd`&alL?QwQ@yVCeOJR%#*!LL7@h`@|%sWWn>c z)-w}Qyvb&=e^Jxhnl(uOQFtG&RnUKR+#K$)d=4x7V=0~SFLAu%TI7|7r=<}qY0OhE z`?Hm#`RTdwCwkj{bEsaZ3=#486SIK(S(8E<1LnMf3j}H0>6LNud1Gu`brgQ3#`S5< z+qk*pV6Q(|tIKn|D9Y5+={(m!L$nfxvO=|_n$xnjqZW7vNzy&qb(Vqaie|viRiEG6 z`rA5SCw4e89LYkTT_Td%x{_{J5vfSF9C3X7iI?eIwXQq&frL)Z- zCBh`twXO^*Dv7U~z-`iLR@8)UF5Q9@x^f4)2{JB;*e9E(u)uc#2VEM;V zEK<%Xn#3i(^tnxUW5jlH%@s41(^;=}A5kYO5oJk0SF^$A7D4TD!$_|UVi@pi!HCcM zm5PSSZcEqoAtn`P^BpWn+tbIqgG(JIK^*(9Lep?MAK7vxTv>yrkj6PPr!n#jFlSKZ zvXQKTtOL0GClmS@#??gnf+wA=Tnct(tcE}BNju!_!$rG27M{!iRAxU71)EZ5V*sa_ zhw0O!WX*@D91W_?XDTL*m(Vt)ArE%en`ApZo<2y%cmX||a#$KNL5U6jGz=0HzM5bs ztTw*$5(~pxGpZ@CK7#l}iX%gIdnqlk?7QjypxEl>&-UA+X3iKR4vpN~^9idu;wP7i z#u=!VHTPP|IiP;r>Y{}A5jqQr=Gyhk-p<1V@Uax5t14B^ z82sZ~cjwt2PpK~)*Kr*YVd zl!yj$636M=<8Q^%`I0QhXbtyP2uw7QD`8g5MK)aWv+@V_;(b>*yJ(AOJeeha$k#MV ztu!GNBoD=3!PV-^jtk*Zli^3bD~Sx2T!7|yDpm38OnNRlKJ)b_i1 zd(HSMikFrBXM%u)$NV;SViqov7;0E~x%eE!iXuZWv=r5cH!O2TuW@iE4OTmVa`m1x zEzW&U$jNSi6LhcQ?*7uYT6d}IulGH#TYH@jBz4o4sNq1Mu;k@4-ffG_seZ$eEFSYU z%=RVx69Z0KQKq$2Jf=OiGKvy;LBxj6IR_x)c?~!zBJ;Y4C+GELQvNaqrYlcINYu_* zrimoCZ3#W}pHadvGN5XabvOr@pyH)uA)QrWTBhrVJ1Opb+zqhDYw*?!m{9LMxeFU^ zJV+?_fA;*no%pC+sn(@DKs2?#%AA=Tcgs;*Q`|&Qul)`qmvrk>j)`~YL1DWmC1NVX z)-Dzm2NGo8@CQLI5K1;=b66lnb$9c4_aDBfO3kA~gTQTxzqWL|UnUsS;R~1T2fN7@ zR*Li;?2~d^@FatAcC(0W=Q?@Bt)8WG#WX^$yUkeVm{NAYI}L`4)&<<#f_XCtTT2VK zb>M|HvO94VymPKAkrnt?v0~S_D5e9ZK+#>xo&&b@TNWOot2kcj$IL@#vTUX^*-73x zZcc!t^t_J)xjj)i9p0OfCW&e6#Gnl^i((wmi0**8!8=B>Fh1c@sMS9qOkA-drlN~g z^?S)*znWAS^lNd5&;YcK&01%2gH_IR(qd~I+9T^$Zh0i}^TYyS<@Hf_N*9x3_7p_( zO0c8F!CjqAgCf}mNS#=%lmVK)eAhcTdaeX$kIYD?w#gl3!-4}WX>-?h z5*H7!m$z+}_i5fazbzWQtdb~_uKVGcPHVMZPHJZy=X&PSzB;DcVcjQ5lqW`%MLT=5 zBI=RBOV0mWv|?BxsQo6&m1U8_+P=&Pu7o7ErwaWSQxool@*0MG1z~EwrRxEd( z--L6bJTbo*P>%GRfHKP)`M0G!{^J|!2-N7g2pvoo1V_G=$tftBYHr4 zF;|&{n5T3Ae@h`@@-Sg~5&sAhhs1JN>1OVqxea3HaKWHA8aGb`a-Iok57^W%Dz37Y z>OQwdym`E=?mM0Om>4$nKv5iI3RC}so3x60D|nbexxCH9)vcu|jiu69C2&jkYMBKl{} zKAdXq*zZz~30#KLU!cOybqXZOTwu1lh=u%qI>}wJ`u3w#W~pY9)NK z$}#UyK#h~)b?ZcEIQ-qCm~Z6)$`|333}Rko#eak{#wKAzY_i6H1;VpJ?-&fN@91-F z-4k?8H~=FjX>mNR*0@W8)s&T#oTf1`8M)?~#6M#~Ty!%T)oDdwysnp?2RdyNry^D< z7SkM1Qn@#Y>1MQcXd&>(K7;lHu|&*>qp&6hK`)Qvs5j6mH$OC)$s(N&s=ycs$~T!3U- zcN9fcLxcRNH0zGh1AToH1Mcq#*W@X{>qpr8$4yfc`0aDs?IB36B}P7WFdQYh?8QVm zG4EaF=G;Z%pZei)+R`9BiKfuP0R@I?T`eq;@gfmHWu^&IUgUrB%k??W0#@=pix0UX zxS`YqwbNn}usg5};4GM#MpRfD6HcOtO)&12%%84L!(OAl*BO)5>(etw?AZG<9=-J) zG^A# zp5kI=4RLv}8T%(fIY+z3BOM*`qBLbBysDYV?Df5VWd!v;{?MLA57oRZKxt< zL}jg1*U$xYI~%gXSvC$AZo|Oa=cOhm3%P4>NKFh2?tWffPTsr-IMGLtT-eUvKr{yI z5MT2mTS_D%*s}pLgNQ*J+`#nfW%9BY#`)bv+3Um~0S1%KfUq92cyKqI_&&08lqFY`Wj+=}9M>r)7!3Q9iWZ@IHtzDIN2x|1 zA>tRo3(!;fTFKyceGW!io>FFx_=BT`QIS9uLk7IAsStV%G+b!tuf{f6pqYrfz{`UIVhN5b!hzuTPe1tMfpA(S< z@1cV*v_6-~Y@}K?;`1W`u=2Xc*1ak-e_~UP8>LX)!!$KsippGC>Cf&}1$?h>h!53A z`Q`9a$%%3spy?kOBvF$_KGIeLb>&`6>gC=)ekH#wvc1&oTgYeu@(cNRv5;W(R#D8{ z7n%q4sIX?!z8#FxU%cKiydRuba*P*Uywn0;@r%N8EMbWOrZ{eB@v(9M#YRGzPn-3{ z>E^uoACvhp7Z-g3NZu%{$h(F{d;vrTyjh2T)XFl+3**s7n2~NVki@16&eRR+m>}(I z%mUDOPQFKLSLGi7OPRq>X=+u3w=UCNn5?-cAq_K?s;l>vzYmX5jMz5H>go=(EHzF!?|ob>c^*_Fr2GEy`51e31DKZXhE zB?5HnH8ml_WzRaX;&%hHBMOo$`&nfrVwGvTP?8~EbX z=WyC}1XY<6J+J9(F-J94M8Vo!e#Yq+ia^J(O*YyXJLNuz-W9I!{Sp|!`y6-ghEuSw z#go$VUb}bCn;Ds@n=@jQ{8Y-;heQ&ICN@L=;t(VVcKpC2hO8?x-`sw3TkU&X$JKBU4c*wd*ieV5+%uK7sOHBWglH;bL%2YA6M&T7PE8-bCo)-+2mYpC_u9X6G%|DDw7O$yscHVSw6s<_0ZfM4Lxi}9XB{JP$p}JVV(yKBWJRjI zJ>%rhHaY&ZVYl;>A8g&RMlRZ)nViLlpVV;;s)G5YE5qZUsrp!1j$(6kzzS8kRm;1DQ z>+ZMm5@J+2S@F4f_BO}#y=}WzHXh%b(d^jQbK{i79d3^+7MCBMYbmwhg>c%D=YJ~?d=|DY}^M$>S8$3 z)B-Z83^Frv*dmpVSpP2*AsjK6;^?t}k%OIX+&OngiRG^=X440^E?Qdlw;S*O@#P+v zfYHHVvRKU4a&298MR~P#wqXr#c+gr~Wu0YPXPc;d6d;O<=Fo3VabZFDZw5`F7Bo6- zfmS!CXpTk$1)3rqHs?lHJ8F!mwc7L+j)O|xqPG~$L$(|4`)?_Xh9X^IafwD-tk)J+ z7&OLWt&uM=%tflq(G<@uFQ` zT}g$`sO315!HoQ5wpNvE*UhS_uDozqTEJyOg#1@q%aLvsrpnn9cn^~C;^M*~bg}@a~;24I)|GE4}(4T%yI0KA<{>6nw0{t%qBItj|qJ?Ek7ESOyhO__Y(|=B3 zL6KnpF9jm#Z#7s}yi z0VHxM{-_Oln|`givQ)t#=tK608h=d2(#SOc`;Il#SMibG4t{A}W474T7i?nW0}97v zt}f+n=BsgzZM>0Ny`H=M&Lv!p-k^U_U&(Wofp5%~!3*p7YNOdwO3lJPvshV2(>1dS zrYik75IV4$}PRKZ15@? zfX!s9<*RLKoSfjipY8K5?5m2eTFqPNYqhD`$gkt7dESVfo4M6IS6gj*sFuH$BQ~~~ z@Ubc^<|z<>f{jcC85cCF1+vz8AZU+|d>`f9qbl|8J9 zKg$fnERjPkjTlMTI0l)5J{zVJ?Z`SgON_d;VKbS>E#+*bPY=;_XdxKl0^9l;Y`SRi!lmbZRaIGqT?HNmx!h){<)@$52x)Dq3bhK} zcz$h-5e4hID2;>MZW-)1N*jV1rE9Hzy*eKHXQ~?2lB1?iv zNWz{XBTOT*DI^d`AYp_Mf*`Akr7~m+DgtGR6$DuhKoA)+iik2qXb=@tmRe=1ebm-b zyT9t!uk}yfI_HgZ?tkyO=ic|+DRjDDpexhYa~tSG0f9gxR8>`h?T>h8`}00hMFovS zVGyb)K#oKpu__=K2J{gS6v!aZL4XDSPrSvyJDEVI1%7~P@aOnPA`nT@~qpLU^D^SXDI`>`e{vP!1u`sC;NN)&s3ZP*ZV7s**?q5{5(| zsw1#!YAOhIlm`(5gHhc5d;_<=x)6>>4CAl*we!g&jKZ-BomF8!y zFM&qVfRPwv1R#C`MuM+c~adjWdn`$gdH9|V7|o-j$i9>AkuR=X_T zlF=7us%r%7y&k1L^ESU(94xyPF+z7 zAmQ~laR>yi=wDel4CIfp03kQS)M5ws2lk*9m=1_PN)xzNrY?Y+Uf?ds;{^S%iUZSiT1kumuC zBHqXQ`i;{gGfNjDPUjqu+B1>+_UgrV`patTdK{f11??kmm6c8}W=w?g4{+9UoaM;i zY>9$gg*yMY@z zHRSp7R$%wq80n?CnHiqCoq59nxl4OOLNd1>Se;}p8z6CDPo1Tflw77caR`f3@U9Xs zeTdT5?z(!_x;1DYv>Oy`s$f+s!?DwCh(8Q`_FPGwj1V(`xFXp_0QIYLJ#A(cL?0s=}wE#$Eb zV4}IDnf zNpwl_mkF>VvZAbBOqeVi=o;~mU)F|7cAV+sycs`-GdojT*}2O~yScMdptrYo7+J_$ zYlmCd9|SQx@)FJ-Yss(|jZuQb%gf62WK#$%Rt6P&kmRtTl5frPoc5x6Cl4is`L>7L znGzOtC$JGBN(yC49HNYzLp)`iFrHL>p9;&sQn+3;FB&ICEebkqr&LVLW>KW+Lt{6i!?xVwnP%$Z~X~@Out5Y_dZk3+aCr$_;_xbFu?8&*i^(5TcZ1!poYUafQ z#pW1;hgHR zBD!Hi-XImFt80bIlu5Y)+czL^OK>?>&?9fz5(+t{8*$uRwrOHQULWcld#%L{%8I%K zD=UCa^SqcS6e+*Nxfqt{n2?JG zV46FH5{oZ3)W|a8A@E9nUQ)%JlpoHmYI&li{CREL(|%VgC`7XBLOPqF!@e*cmf-xj z7=y`EIOwC=ENa?vZuC47g3uUg&D@@Su?C+?7-+j%AQ-N#OGp>xja2MpU*s5jRgYwdZ3(0F$^sOt@12$e~9e>EUVbzk*j7RPxv^{=|0s?`2!BxjGo+j-B zCzV9NkQjxFo!rkvpSfyAeRq8z{muyID*kYh!$C!SCdH9!q)g}?BT8v|+WM^)!tUjB zK!Rzux1JXI%q}0g7|}PD{cTP10!E=})?Se>+V0F{z3isK$}YP0<@L$;^^XQSSk#xf z2@}=Q)~H=r_qgE^muj5d{6HgmsO7dKf2U`~E!J54F|~kbXJupM!#=Im8z!qw$tA@% zyv;2vg3edLY{F&?^mav&1pFj=Z#}A}oYR=v)HmF2p`3$9Zn$K1E1+V^s zZN2xi1Ut}`JB8?_XLlMJYWPF!PegNGD=*8pKg{VEA!zhvdSASBQrY}i_6Ab#_Jg-B zkOLaeLfWmL3Ve5@|5Pep*faQZs+buAJUTmz@cQ-`At)%Vv9Xcq9Z@y;?Nl{Q7@|Ku zim}@1;~mG*A!MGYcKPAt^KKTL!E;s{g6x>b_AQ$X(%u7vRt=)NJP|+K5B#L#t zlV~qM^WMG2ong$|B8q!@sQDxq;tM@wt`Qe6w=k?(v~ca{uI0gMan+&+mys}mZsn$$ z)#DWG7YUfH1tvwkXz}=IMS2A!-BG+kOj43WAmsKQxp@hiQkZp5L6KjWi(GP5(J%vA zmpgjjvi+uLc-xPet~4OL8nKez9gV zq|l{>@2ZipgHc&TCsBFp!rVb|*GA*xtJ^AC;+=>#tL7K4$hvAdb5nAPSuV=3BqnR7 zA6FZWFWV|-su4{ZEt468bMi!e2HAOE3CJ4w*DL2#P1{uOl%2QRFpu^xN~K%5x^4^% z3_PY8oFJDSmOSaETjM)DJ|dh<6i!IrGP7K`X&P?`l=h?U~M~ZBFQhMR!CIP|fzR7Q#Z_oKMGKWW6 zdk^Z6Et>64**JwdlqeXG%9`1tE*~i&&H8tz@+LjE%ni7S7#=0c2ens zXU@kZAL+^yn>LxJDx^-B@nWBjTc0FxgmQz!FuM&<11g6t=bJ{@y=Esv?`S2>be6C}x>;T8HE zI{F{gf`-Z`9wx4}8i3Saa`V5v`kLsG@Ne|#L~J@-({tmzbW7ya&4Gk4ePj6o*!SCU zK2kSu!U&n()q7V3Nc2C*HU+Mp zm(NV$VMAzss%v;pQbylmIC~1nS{2jOn3JM-T($4;R}VFICgzX@qf5;T;ATP)4#Ej& zG`V7ri+-=7&dpuN*KbJhzwu~balFUjo9A{o{*Gk(bPKKH?1k~{)*zQ>lY_n5MPV0H zAMe_xE_~f_4ahhid9(?U@2p&L_H5g=YeKPx(T$Dzi;Ih8w1Wt$psZPe&`QYaFLjBF zi-X1xh)YRrW#j^-65rX|#BQT)isCEj-}-)U%~#O6!`QXsuhnUfrJ!$}}(RwWy9A zP@4!VPa3$vl|S4+92i?Yi^oY6-H?{j4VUN-%FN0lxw+-g7K@^W3R1i4C(FNj6Tu-P(qU#$I$4i>i-<@&B;rfAbNW# zycN}P7nNxqlbI>DxU@91KVhB0@`l+Ze0!5_dR}=O#wbz;Cbl;wQk_j}$*`CbwEbqc zvTMEhIp@!dLORZ9q}k7fY!7{LRk<7;(q<|#$X(+mKv0wj{J$XxLd>JLgfleSwi zjSm>X23|}}wpTJzOxq-t7;Krosh_oOUS!rn;qF5A%}1>DYnhD8&-bwRHf&?4>P~q- z+JB!~_tKR#9Q3kg=HNbMj=5D4{94@Tg4D&L#qb6*s8FH_%SB{66O=jO0v67icrY;^ zx>ik`HvqfmfSara{i3Y+NKAtxW2T}Z58uAMu3zi*koe8YF8U?cOHwhMIL3Ph1i*BM zrD3UoTQuks{-bzn{_n?k3?E_w_|MJ%zWeeKfh9|dpmkKdthXt4wI&jaA}ukw#T sp+3$3ehj?D|Em|3A0PnyjrNa4fBOFK6F%V+KH-Dn2cRQ&WdJS!0FBqIcmMzZ literal 0 HcmV?d00001 diff --git a/src/test/resources/deploymentReq.txt b/src/test/resources/deploymentReq.txt new file mode 100644 index 0000000..a0d1ef2 --- /dev/null +++ b/src/test/resources/deploymentReq.txt @@ -0,0 +1,129 @@ +{ + "owner": { + "id": 1, + "organization": "University of Patras", + "name": "Portal Administrator", + "email": "tranoris@ece.upatras.gr", + "username": "admin", + "active": true, + "currentSessionID": "35382ff0-6947-411b-a806-4c2c53d8ac28", + "apikey": "b41717a1-192b-4843-8c2d-128ec7432bed", + "roles": [ + "ROLE_ADMIN", + "ROLE_MENTOR" + ] + }, + "mentor": { + "id": 1, + "organization": "University of Patras", + "name": "Portal Administrator", + "email": "tranoris@ece.upatras.gr", + "username": "admin", + "active": true, + "currentSessionID": "35382ff0-6947-411b-a806-4c2c53d8ac28", + "apikey": "b41717a1-192b-4843-8c2d-128ec7432bed", + "roles": [ + "ROLE_ADMIN", + "ROLE_MENTOR" + ] + }, + "startReqDate": "2019-12-10T00:00:00.000Z", + "endReqDate": "2019-12-23T00:00:00.000Z", + "startReqHour": "00", + "startReqMinute": "00", + "endReqHour": "00", + "endReqMinute": "00", + "experiment": { + "id": 26, + "name": "cirros_2vnf_nsd", + "iconsrc": "//patras5g.eu/apiportal/services/api/repo/images/22c41d0d-4706-4993-962f-ada27eea1c25/osm_2x.png", + "vendor": "OSM", + "published": false, + "termsOfUse": null, + "valid": false, + "validationStatus": "NOT_STARTED", + "packagingFormat": "OSMvFIVE", + "experimentOnBoardDescriptors": [ + { + "id": 56, + "obMANOprovider": { + "id": 1, + "name": "Patras 5G OSM FIVE", + "description": "OSM FIVE installed in Patras 5G testbed", + "supportedMANOplatform": { + "id": 1, + "name": "OSM FIVE", + "version": "FIVE", + "description": "OSM FIVE" + }, + "apiEndpoint": "https://10.10.10.5:9999", + "authorizationBasicHeader": null, + "username": "admin", + "password": "admin", + "enabledForONBOARDING": true + }, + "onBoardingStatus": "ONBOARDED", + "lastOnboarding": 1568639467000, + "deployId": "5eaa933a-3e78-4f16-9aad-09e060451e54", + "feedbackMessage": "NSD Onboarded Successfully", + "uuid": "44f8e956-275e-47f0-ab18-e58443fb8625", + "vxfMANOProviderID": "cirros_2vnf_nsd", + "experimentMANOProviderID": "cirros_2vnf_nsd", + "experimentid": 26 + } + ], + "constituentVxF": [ + { + "membervnfIndex": 1, + "vnfdidRef": "cirros_vnfd" + }, + { + "membervnfIndex": 2, + "vnfdidRef": "cirros_vnfd" + } + ] + }, + "vxfPlacements": [ + { + "constituentVxF": { + "membervnfIndex": 1, + "vnfdidRef": "cirros_vnfd" + }, + "infrastructure": { + "id": 1, + "organization": "University of Patras", + "name": "Cloudville", + "email": "tranoris@ece.upatras.gr", + "datacentername": "Cloudville", + "vimid": "691c8956-0369-4b91-b914-b61dccba74db", + "refSupportedImages": [] + } + }, + { + "constituentVxF": { + "membervnfIndex": 2, + "vnfdidRef": "cirros_vnfd" + }, + "infrastructure": { + "id": 1, + "organization": "University of Patras", + "name": "Cloudville", + "email": "tranoris@ece.upatras.gr", + "datacentername": "Cloudville", + "vimid": "691c8956-0369-4b91-b914-b61dccba74db", + "refSupportedImages": [] + } + } + ], + "infrastructureForAll": { + "id": 1, + "organization": "University of Patras", + "name": "Cloudville", + "email": "tranoris@ece.upatras.gr", + "datacentername": "Cloudville", + "vimid": "691c8956-0369-4b91-b914-b61dccba74db", + "refSupportedImages": [] + }, + "name": "test", + "description": "Description" +} \ No newline at end of file diff --git a/src/test/resources/logback-test.xml b/src/test/resources/logback-test.xml new file mode 100644 index 0000000..785d67e --- /dev/null +++ b/src/test/resources/logback-test.xml @@ -0,0 +1,32 @@ + + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + diff --git a/src/test/resources/test b/src/test/resources/test new file mode 100644 index 0000000..e69de29 diff --git a/src/test/resources/testnsd.txt b/src/test/resources/testnsd.txt new file mode 100644 index 0000000..c16dcf4 --- /dev/null +++ b/src/test/resources/testnsd.txt @@ -0,0 +1 @@ +{"owner":{"id":1,"organization":"","name":"Portal Administrator","email":"","username":"admin","active":true,"createdAt":1566834456000,"roles":["ROLE_ADMIN","ROLE_MENTOR"]},"extensions":[],"categories":[{"id":2,"name":"Networking","appscount":0,"vxFscount":0,"productsCount":0},{"id":3,"name":"Service","appscount":0,"vxFscount":0,"productsCount":0}],"packagingFormat":"OSMvFIVE"} \ No newline at end of file diff --git a/src/test/resources/testvxf.txt b/src/test/resources/testvxf.txt new file mode 100644 index 0000000..0919bd6 --- /dev/null +++ b/src/test/resources/testvxf.txt @@ -0,0 +1 @@ +{"owner":{"id":1,"organization":"","name":"Portal Administrator","email":"","username":"admin","active":true, "roles":["ROLE_ADMIN","ROLE_MENTOR"]},"extensions":[],"categories":[{"id":2,"name":"Networking","productsCount":0,"appscount":0,"vxFscount":0},{"id":3,"name":"Service","productsCount":0,"appscount":0,"vxFscount":0}],"packagingFormat":"OSMvFIVE"} \ No newline at end of file -- GitLab