diff --git a/NOTICE b/NOTICE index 8e4ead69bd711af2863921475ebd1a898f94b5d0..aa8b2ffffdf41e7a595a8eaecf694426f529ecbc 100644 --- a/NOTICE +++ b/NOTICE @@ -72,7 +72,6 @@ The following software have components provided under the terms of this license: - Commons Digester (from http://commons.apache.org/digester/) - Commons Lang (from http://commons.apache.org/lang/) - Converter: Jackson (from https://repo1.maven.org/maven2/com/squareup/retrofit2/converter-jackson) -- Core Reactor components (from https://github.com/reactor/reactor) - Core functionality for the Reactor Netty library (from https://github.com/reactor/reactor-netty) - Default Plexus Container (from https://repo1.maven.org/maven2/org/codehaus/plexus/plexus-container-default) - Doxia :: APT Module (from http://maven.apache.org/doxia/doxia/doxia-modules/doxia-module-apt/) @@ -82,7 +81,7 @@ The following software have components provided under the terms of this license: - Doxia :: XDoc Module (from http://maven.apache.org/doxia/doxia/doxia-modules/doxia-module-xdoc/) - Doxia :: XHTML Module (from http://maven.apache.org/doxia/doxia/doxia-modules/doxia-module-xhtml/) - Doxia Sitetools :: Decoration Model (from http://maven.apache.org/doxia/doxia-sitetools/doxia-decoration-model/) -- Doxia Sitetools :: Site Renderer Component (from http://maven.apache.org/doxia/doxia-sitetools/doxia-site-renderer/) +- Doxia Sitetools :: Site Renderer (from https://repo1.maven.org/maven2/org/apache/maven/doxia/doxia-site-renderer) - FindBugs-jsr305 (from http://findbugs.sourceforge.net/) - Google APIs Client Library for Java (from https://repo1.maven.org/maven2/com/google/api-client/google-api-client) - Google App Engine extensions to the Google HTTP Client Library for Java. (from https://repo1.maven.org/maven2/com/google/http-client/google-http-client-appengine) @@ -125,7 +124,6 @@ The following software have components provided under the terms of this license: - Jackson datatype: jdk8 (from https://repo1.maven.org/maven2/com/fasterxml/jackson/datatype/jackson-datatype-jdk8) - Jackson extensions to the Google HTTP Client Library for Java. (from https://repo1.maven.org/maven2/com/google/http-client/google-http-client-jackson) - Jackson module: Afterburner (from https://github.com/FasterXML/jackson-modules-base) -- Jackson module: JAXB Annotations (from https://github.com/FasterXML/jackson-modules-base) - Jackson-annotations (from http://github.com/FasterXML/jackson) - Jackson-annotations (from http://github.com/FasterXML/jackson) - Jackson-core (from https://github.com/FasterXML/jackson-core) @@ -133,6 +131,7 @@ The following software have components provided under the terms of this license: - Jackson-dataformat-XML (from http://wiki.fasterxml.com/JacksonExtensionXmlDataBinding) - Jackson-dataformat-YAML (from https://github.com/FasterXML/jackson-dataformats-text) - Jackson-datatype-JODA (from http://wiki.fasterxml.com/JacksonModuleJoda) +- Jackson-module-JAXB-annotations (from http://wiki.fasterxml.com/JacksonJAXBAnnotations) - Jackson-module-parameter-names (from https://repo1.maven.org/maven2/com/fasterxml/jackson/module/jackson-module-parameter-names) - Jakarta Bean Validation API (from https://beanvalidation.org) - Jakarta Expression Language Implementation (from https://projects.eclipse.org/projects/ee4j.el) @@ -209,6 +208,7 @@ The following software have components provided under the terms of this license: - Nimbus Content Type (from https://bitbucket.org/connect2id/nimbus-content-type) - Nimbus JOSE+JWT (from https://bitbucket.org/connect2id/nimbus-jose-jwt) - Nimbus LangTag (from https://bitbucket.org/connect2id/nimbus-language-tags) +- Non-Blocking Reactive Foundation for the JVM (from https://github.com/reactor/reactor-core) - OAuth 2.0 SDK with OpenID Connect extensions (from https://bitbucket.org/connect2id/oauth-2.0-sdk-with-openid-connect-extensions) - Objenesis (from http://objenesis.org) - OkHttp Logging Interceptor (from https://repo1.maven.org/maven2/com/squareup/okhttp3/logging-interceptor) @@ -224,15 +224,21 @@ The following software have components provided under the terms of this license: - Proton-J (from https://repo1.maven.org/maven2/org/apache/qpid/proton-j) - QpidJMS Client (from ) - Reactive Streams Netty driver (from https://github.com/reactor/reactor-netty) -- Retrofit (from https://github.com/square/retrofit) +- Retrofit (from https://repo1.maven.org/maven2/com/squareup/retrofit2/retrofit) - Servlet Specification 2.5 API (from http://jetty.mortbay.org) - SnakeYAML (from http://www.snakeyaml.org) - Spring AOP (from https://github.com/spring-projects/spring-framework) - Spring Beans (from https://github.com/spring-projects/spring-framework) -- Spring Boot Log4j 2 Starter (from http://projects.spring.io/spring-boot/) +- Spring Boot Actuator (from http://projects.spring.io/spring-boot/) +- Spring Boot Actuator Starter (from http://projects.spring.io/spring-boot/) +- Spring Boot Log4j 2 Starter (from https://projects.spring.io/spring-boot/#/spring-boot-parent/spring-boot-starters/spring-boot-starter-log4j2) - Spring Boot Security Starter (from http://projects.spring.io/spring-boot/) - Spring Boot Security Starter (from http://projects.spring.io/spring-boot/) -- Spring Boot Tomcat Starter (from https://projects.spring.io/spring-boot/#/spring-boot-parent/spring-boot-starters/spring-boot-starter-tomcat) +- Spring Boot Starter (from http://projects.spring.io/spring-boot/) +- Spring Boot Test Starter (from http://projects.spring.io/spring-boot/) +- Spring Boot Test Starter (from http://projects.spring.io/spring-boot/) +- Spring Boot Tomcat Starter (from http://projects.spring.io/spring-boot/) +- Spring Boot Web Starter (from http://projects.spring.io/spring-boot/) - Spring Cloud GCP Autoconfigure Module (from https://repo1.maven.org/maven2/org/springframework/cloud/spring-cloud-gcp-autoconfigure) - Spring Cloud GCP Core Module (from https://repo1.maven.org/maven2/org/springframework/cloud/spring-cloud-gcp-core) - Spring Cloud GCP Datastore Module (from https://repo1.maven.org/maven2/org/springframework/cloud/spring-cloud-gcp-data-datastore) @@ -248,6 +254,7 @@ The following software have components provided under the terms of this license: - Spring Messaging (from https://github.com/spring-projects/spring-framework) - Spring Plugin - Metadata Extension (from https://repo1.maven.org/maven2/org/springframework/plugin/spring-plugin-metadata) - Spring Plugin Core (from https://repo1.maven.org/maven2/org/springframework/plugin/spring-plugin-core) +- Spring Security - Core (from https://repo1.maven.org/maven2/org/springframework/security/spring-security-core) - Spring TestContext Framework (from https://github.com/spring-projects/spring-framework) - Spring Transaction (from https://github.com/spring-projects/spring-framework) - Spring Web (from https://github.com/spring-projects/spring-framework) @@ -311,23 +318,16 @@ The following software have components provided under the terms of this license: - proto-google-iam-v1 (from https://github.com/googleapis/java-iam/proto-google-iam-v1) - rxjava (from https://github.com/ReactiveX/RxJava) - spring-boot (from https://spring.io/projects/spring-boot) -- spring-boot-actuator (from https://spring.io/projects/spring-boot) - spring-boot-actuator-autoconfigure (from https://spring.io/projects/spring-boot) - spring-boot-autoconfigure (from https://spring.io/projects/spring-boot) -- spring-boot-starter (from https://spring.io/projects/spring-boot) -- spring-boot-starter-actuator (from https://spring.io/projects/spring-boot) - spring-boot-starter-json (from https://spring.io/projects/spring-boot) - spring-boot-starter-logging (from https://spring.io/projects/spring-boot) - spring-boot-starter-reactor-netty (from https://spring.io/projects/spring-boot) -- spring-boot-starter-test (from https://spring.io/projects/spring-boot) -- spring-boot-starter-test (from https://spring.io/projects/spring-boot) - spring-boot-starter-validation (from https://spring.io/projects/spring-boot) -- spring-boot-starter-web (from https://spring.io/projects/spring-boot) - spring-boot-starter-webflux (from https://spring.io/projects/spring-boot) - spring-boot-test (from https://spring.io/projects/spring-boot) - spring-boot-test-autoconfigure (from https://spring.io/projects/spring-boot) - spring-security-config (from https://spring.io/spring-security) -- spring-security-core (from https://spring.io/spring-security) - spring-security-oauth2-client (from https://spring.io/spring-security) - spring-security-oauth2-client (from https://spring.io/spring-security) - spring-security-oauth2-core (from https://spring.io/spring-security) @@ -623,6 +623,7 @@ The following software have components provided under the terms of this license: - Extensions on Apache Proton-J library (from https://github.com/Azure/qpid-proton-j-extensions) - JUL to SLF4J bridge (from http://www.slf4j.org) - Java Client Runtime for AutoRest (from https://github.com/Azure/autorest-clientruntime-for-java) +- Java JWT (from http://www.jwt.io) - Microsoft Application Insights Java SDK Core (from https://github.com/Microsoft/ApplicationInsights-Java) - Microsoft Application Insights Java SDK Spring Boot starter (from https://github.com/Microsoft/ApplicationInsights-Java) - Microsoft Application Insights Java SDK Web Module (from https://github.com/Microsoft/ApplicationInsights-Java) @@ -650,17 +651,16 @@ The following software have components provided under the terms of this license: - SLF4J API Module (from http://www.slf4j.org) - Spongy Castle (from http://rtyley.github.io/spongycastle/) - Spring Data for Azure Cosmos DB SQL API (from https://github.com/Azure/azure-sdk-for-java/tree/master/sdk/cosmos/azure-spring-data-cosmos) +- Spring Security - Core (from https://repo1.maven.org/maven2/org/springframework/security/spring-security-core) - adal4j (from https://github.com/AzureAD/azure-activedirectory-library-for-java) - azure-documentdb (from https://azure.microsoft.com/en-us/services/cosmos-db/) - documentdb-bulkexecutor (from http://azure.microsoft.com/en-us/services/documentdb/) -- java jwt (from https://github.com/auth0/java-jwt) - micrometer-core (from https://github.com/micrometer-metrics/micrometer) - mockito-core (from https://github.com/mockito/mockito) - mockito-core (from https://github.com/mockito/mockito) - mockito-junit-jupiter (from https://github.com/mockito/mockito) - msal4j (from https://github.com/AzureAD/microsoft-authentication-library-for-java) - msal4j-persistence-extension (from https://github.com/AzureAD/microsoft-authentication-extensions-for-java) -- spring-security-core (from https://spring.io/spring-security) ======================================================================== MPL-1.1 diff --git a/devops/gcp/configmap/templates/partition-variables.yml b/devops/gcp/configmap/templates/partition-variables.yml index 9896f5645e0c0a097b7ba24f180816fb2aa59d18..bed4dd794c937f1826eed8f85574fb809c406fa4 100644 --- a/devops/gcp/configmap/templates/partition-variables.yml +++ b/devops/gcp/configmap/templates/partition-variables.yml @@ -12,3 +12,4 @@ data: KEY_RING: "{{ .Values.data.key_ring }}" KMS_KEY: "{{ .Values.data.kms_key }}" LOG_LEVEL: "{{ .Values.data.log_level }}" + AUTHORIZE_API: "{{ .Values.data.authorize_api }}" diff --git a/pom.xml b/pom.xml index 1642932a7050e11cdb02d3d6d6b782d774b77dff..d17e7892d67a9fdcb6c41d185b9784263587add1 100644 --- a/pom.xml +++ b/pom.xml @@ -128,6 +128,7 @@ <module>provider/partition-aws</module> <module>provider/partition-ibm</module> <module>provider/partition-gcp</module> + <module>provider/partition-reference</module> </modules> <profiles> diff --git a/provider/partition-reference/Dockerfile b/provider/partition-reference/Dockerfile new file mode 100644 index 0000000000000000000000000000000000000000..325d26dc6e86b65be71a48afe3f172df6a0e5781 --- /dev/null +++ b/provider/partition-reference/Dockerfile @@ -0,0 +1,10 @@ +FROM openjdk:8-slim +WORKDIR /app +ARG PROVIDER_NAME +ENV PROVIDER_NAME $PROVIDER_NAME +ARG PORT +ENV PORT $PORT +# Copy the jar to the production image from the builder stage. +COPY provider/partition-${PROVIDER_NAME}/target/partition-${PROVIDER_NAME}-*-spring-boot.jar partition-${PROVIDER_NAME}.jar +# Run the web service on container startup. +CMD java -Djava.security.egd=file:/dev/./urandom -Dserver.port=${PORT} -jar /app/partition-${PROVIDER_NAME}.jar diff --git a/provider/partition-reference/README.md b/provider/partition-reference/README.md new file mode 100644 index 0000000000000000000000000000000000000000..262136fc0217dfbd176ce7b190695c3ea1e57549 --- /dev/null +++ b/provider/partition-reference/README.md @@ -0,0 +1,176 @@ +# Partition Service +os-partition-reference is a [Spring Boot](https://spring.io/projects/spring-boot) service that is responsible for creating and retrieving partition specific properties on behalf of other services whether they are secret values or not. + +## Getting Started +These instructions will get you a copy of the project up and running on your local machine for development and testing purposes. See deployment for notes on how to deploy the project on a live system. + +### Prerequisites +Pre-requisites + +* GCloud SDK with java (latest version) +* JDK 8 +* Lombok 1.16 or later +* Maven + +### Installation +In order to run the service locally or remotely, you will need to have the following environment variables defined. + +| name | value | description | sensitive? | source | +| --- | --- | --- | --- | --- | +| `LOG_PREFIX` | `service` | Logging prefix | no | - | +| `SERVER_SERVLET_CONTEXPATH` | `/api/partition/v1` | Servlet context path | no | - | +| `AUTHORIZE_API` | ex `https://entitlements.com/entitlements/v1` | Entitlements API endpoint | no | output of infrastructure deployment | +| `GOOGLE_CLOUD_PROJECT` | ex `osdu-cicd-epam` | Google Cloud Project Id| no | output of infrastructure deployment | +| `GOOGLE_AUDIENCES` | ex `*****.apps.googleusercontent.com` | Client ID for getting access to cloud resources | yes | https://console.cloud.google.com/apis/credentials | +| `PARTITION_ADMIN_ACCOUNTS` | ex `admin@domen.iam.gserviceaccount.com,osdu-gcp-sa,workload-identity` | List of partition admin account emails, could be in full form like `admin@domen.iam.gserviceaccount.com` or in `starts with` pattern like `osdu-gcp-sa`| no | - | +| `GOOGLE_APPLICATION_CREDENTIALS` | ex `/path/to/directory/service-key.json` | Service account credentials, you only need this if running locally | yes | https://console.cloud.google.com/iam-admin/serviceaccounts | +| `KEY_RING` | ex `csqp` | A key ring holds keys in a specific Google Cloud location and permit us to manage access control on groups of keys | yes | https://cloud.google.com/kms/docs/resource-hierarchy#key_rings | +| `KMS_KEY` | ex `partitionService` | A key exists on one key ring linked to a specific location. | yes | https://cloud.google.com/kms/docs/resource-hierarchy#key_rings | +| `MONGO_DB_URL` | ex `mongodb://localhost:27017` | Mongo DB Url| yes | output of infrastructure deployment | +| `MONGO_DB_USER` | ex `mongouser` | Mongo DB userName| yes | output of infrastructure deployment | +| `MONGO_DB_PASSWORD` | ex `mongopassword` | Mongo DB userPassword| yes | output of infrastructure deployment | +| `MONGO_DB_NAME` | ex `mongoDBName` | Mongo DB DbName| yes | output of infrastructure deployment | + +### Run Locally +Check that maven is installed: + +```bash +$ mvn --version +Apache Maven 3.6.0 +Maven home: /usr/share/maven +Java version: 1.8.0_212, vendor: AdoptOpenJDK, runtime: /usr/lib/jvm/jdk8u212-b04/jre +... +``` + +You may need to configure access to the remote maven repository that holds the OSDU dependencies. This file should live within `~/.mvn/community-maven.settings.xml`: + +```bash +$ cat ~/.m2/settings.xml +<?xml version="1.0" encoding="UTF-8"?> +<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0 http://maven.apache.org/xsd/settings-1.0.0.xsd"> + <servers> + <server> + <id>community-maven-via-private-token</id> + <!-- Treat this auth token like a password. Do not share it with anyone, including Microsoft support. --> + <!-- The generated token expires on or before 11/14/2019 --> + <configuration> + <httpHeaders> + <property> + <name>Private-Token</name> + <value>${env.COMMUNITY_MAVEN_TOKEN}</value> + </property> + </httpHeaders> + </configuration> + </server> + </servers> +</settings> +``` +* Update the Google cloud SDK to the latest version: + +```bash +gcloud components update +``` +* Set Google Project Id: + +```bash +gcloud config set project <YOUR-PROJECT-ID> +``` + +* Perform a basic authentication in the selected project: + +```bash +gcloud auth application-default login +``` + +* Navigate to partition service's root folder and run: + +```bash +mvn clean install +``` + +* If you wish to see the coverage report then go to target/site/jacoco/index.html and open index.html + +* If you wish to build the project without running tests + +```bash +mvn clean install -DskipTests +``` + +After configuring your environment as specified above, you can follow these steps to build and run the application. These steps should be invoked from the *repository root.* + +```bash +cd provider/partition-reference/ && mvn spring-boot:run +``` + +## Testing +Navigate to partition service's root folder and run all the tests: + +```bash +# build + install integration test core +$ (cd testing/partition-test-core/ && mvn clean install) +``` + +### Running E2E Tests +This section describes how to run cloud OSDU E2E tests (testing/partition-test-gcp). + +You will need to have the following environment variables defined. + +| name | value | description | sensitive? | source | +| --- | --- | --- | --- | --- | +| `ENVIRONMENT` | ex `dev` | | no | | +| `PARTITION_BASE_URL` | ex `http://localhost:8080/` | service base URL | yes | | +| `CLIENT_TENANT` | ex `opendes` | name of the client partition | yes | | +| `MY_TENANT` | ex `opendes` | name of the OSDU partition | yes | | +| `INTEGRATION_TESTER` | `********` | Service account for API calls. Note: this user must be `PARTITION_ADMIN_ACCOUNT` | yes | https://console.cloud.google.com/iam-admin/serviceaccounts | +| `NO_DATA_ACCESS_TESTER` | `********` | Service account base64 encoded string without data access | yes | https://console.cloud.google.com/iam-admin/serviceaccounts | +| `INTEGRATION_TEST_AUDIENCE` | `********` | client application ID | yes | https://console.cloud.google.com/apis/credentials | + +Execute following command to build code and run all the integration tests: + +```bash +# Note: this assumes that the environment variables for integration tests as outlined +# above are already exported in your environment. +$ (cd testing/partition-test-gcp/ && mvn clean test) +``` + +## Deployment +GKE Google Documentation: https://cloud.google.com/build/docs/deploying-builds/deploy-gke +Anthos Google Documentation: https://cloud.google.com/anthos/multicluster-management/gateway/tutorials/cloud-build-integration + +#### Cloud KMS Setup + +Enable cloud KMS on master project. + +Create king ring and key in the ***master project*** + +```bash + gcloud services enable cloudkms.googleapis.com + export KEYRING_NAME="csqp" + export CRYPTOKEY_NAME="partionService" + gcloud kms keyrings create $KEYRING_NAME --location global + gcloud kms keys create $CRYPTOKEY_NAME --location global \ + --keyring $KEYRING_NAME \ + --purpose encryption +``` + +Add **Cloud KMS CryptoKey Encrypter/Decrypter** role to the used **service account** by Partition Service of the ***master project*** through IAM - Role tab. + +Add "Cloud KMS Encrypt/Decrypt" role to the used **service account** by Partition Service of the ***master project*** through IAM - Role tab. + +## Licence +Copyright © Google LLC +Copyright © EPAM Systems + +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](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/provider/partition-reference/docker-compose.yml b/provider/partition-reference/docker-compose.yml new file mode 100644 index 0000000000000000000000000000000000000000..6dddee763f1007b120109e42ca361c1eaa25308b --- /dev/null +++ b/provider/partition-reference/docker-compose.yml @@ -0,0 +1,12 @@ +version: "3" +services: + os-storage-app: + build: + args: + JAR_FILE: target/partition-reference-0.12.0-SNAPSHOT-spring-boot.jar + context: "" + dockerfile: ../Dockerfile + image: us.gcr.io/osdu-anthos-02/os-partition/anthos-partition-reference + ports: + - "8080:8080" + diff --git a/provider/partition-reference/kubernetes/deployments/deployment-os-partition-service.yml b/provider/partition-reference/kubernetes/deployments/deployment-os-partition-service.yml new file mode 100644 index 0000000000000000000000000000000000000000..b53d96b59ef926c451c24f90dac615b3a0f68fda --- /dev/null +++ b/provider/partition-reference/kubernetes/deployments/deployment-os-partition-service.yml @@ -0,0 +1,120 @@ +apiVersion: v1 +data: + AUTHORIZE_API: ${AUTHORIZE_API} + MONGO_DB_URL: ${MONGO_DB_URL} + MONGO_DB_USER: ${MONGO_DB_USER} + MONGO_DB_NAME: ${MONGO_DB_NAME} + GOOGLE_CLOUD_PROJECT: ${GOOGLE_CLOUD_PROJECT} + GOOGLE_AUDIENCES: ${GOOGLE_AUDIENCES} + KEY_RING: ${KEY_RING} + KMS_KEY: ${KMS_KEY} + PARTITION_ADMIN_ACCOUNTS: ${PARTITION_ADMIN_ACCOUNTS} + LOG_LEVEL: ${LOG_LEVEL} + +kind: ConfigMap +metadata: + labels: + app: partition-reference + name: partition-config + namespace: default +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + generateName: partition-reference-anthos + labels: + app: partition-reference + name: partition-reference + namespace: default +spec: + selector: + matchLabels: + app: partition-reference + replicas: 1 + template: + metadata: + labels: + app: partition-reference + spec: + containers: + - env: + - name: AUTHORIZE_API + valueFrom: + configMapKeyRef: + key: AUTHORIZE_API + name: partition-config + - name: PARTITION_ADMIN_ACCOUNTS + valueFrom: + configMapKeyRef: + key: PARTITION_ADMIN_ACCOUNTS + name: partition-config + - name: LOG_LEVEL + valueFrom: + configMapKeyRef: + key: LOG_LEVEL + name: partition-config + - name: MONGO_DB_URL + valueFrom: + configMapKeyRef: + key: MONGO_DB_URL + name: partition-config + - name: MONGO_DB_USER + valueFrom: + configMapKeyRef: + key: MONGO_DB_USER + name: partition-config + - name: MONGO_DB_PASSWORD + valueFrom: + secretKeyRef: + name: partition-secret + key: mongo.db.password + - name: MONGO_DB_NAME + valueFrom: + configMapKeyRef: + key: MONGO_DB_NAME + name: partition-config + - name: GOOGLE_CLOUD_PROJECT + valueFrom: + configMapKeyRef: + key: GOOGLE_CLOUD_PROJECT + name: partition-config + - name: GOOGLE_AUDIENCES + valueFrom: + configMapKeyRef: + key: GOOGLE_AUDIENCES + name: partition-config + - name: KEY_RING + valueFrom: + configMapKeyRef: + key: KEY_RING + name: partition-config + - name: KMS_KEY + valueFrom: + configMapKeyRef: + key: KMS_KEY + name: partition-config + image: us.gcr.io/osdu-anthos-02/os-partition/anthos-partition-reference:9966597-dirty + name: partition-reference +--- +apiVersion: v1 +kind: Service +metadata: + name: partition-reference + namespace: default +spec: + ports: + - protocol: TCP + port: 80 + targetPort: 8080 + selector: + app: partition-reference + type: LoadBalancer +--- +apiVersion: v1 +data: + mongo.db.password: ${mongo.db.password} +kind: Secret +metadata: + name: partition-secret + namespace: default +type: Opaque \ No newline at end of file diff --git a/provider/partition-reference/pom.xml b/provider/partition-reference/pom.xml new file mode 100644 index 0000000000000000000000000000000000000000..cfdeb0b28db81172f3a4067ec3f74f2d443c17b7 --- /dev/null +++ b/provider/partition-reference/pom.xml @@ -0,0 +1,126 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project xmlns="http://maven.apache.org/POM/4.0.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + + <parent> + <groupId>org.opengroup.osdu</groupId> + <artifactId>partition</artifactId> + <version>0.12.0-SNAPSHOT</version> + <relativePath>../../pom.xml</relativePath> + </parent> + + <groupId>org.opengroup.osdu</groupId> + <artifactId>partition-reference</artifactId> + <description>Partition service on Hybrid Cloud</description> + <version>0.12.0-SNAPSHOT</version> + <packaging>jar</packaging> + + <dependencies> + <!-- Internal packages --> + <dependency> + <groupId>org.opengroup.osdu</groupId> + <artifactId>partition-core</artifactId> + <version>${project.version}</version> + </dependency> + + <dependency> + <groupId>org.opengroup.osdu</groupId> + <artifactId>core-lib-gcp</artifactId> + <version>0.10.0</version> + </dependency> + + <dependency> + <groupId>org.springframework.boot</groupId> + <artifactId>spring-boot-starter-data-mongodb</artifactId> + </dependency> + + <dependency> + <groupId>org.projectlombok</groupId> + <artifactId>lombok</artifactId> + </dependency> + + <dependency> + <groupId>ch.qos.logback.contrib</groupId> + <artifactId>logback-json-classic</artifactId> + <version>0.1.5</version> + </dependency> + + <!-- Test Dependencies --> + <dependency> + <groupId>org.springframework.boot</groupId> + <artifactId>spring-boot-starter-test</artifactId> + <scope>test</scope> + </dependency> + + <dependency> + <groupId>junit</groupId> + <artifactId>junit</artifactId> + <version>4.12</version> + <scope>test</scope> + </dependency> + + <dependency> + <groupId>org.powermock</groupId> + <artifactId>powermock-api-mockito2</artifactId> + <version>2.0.2</version> + <scope>test</scope> + </dependency> + + <dependency> + <groupId>org.powermock</groupId> + <artifactId>powermock-module-junit4</artifactId> + <version>2.0.2</version> + <scope>test</scope> + </dependency> + + <dependency> + <groupId>org.mockito</groupId> + <artifactId>mockito-core</artifactId> + <version>3.0.0</version> + <scope>test</scope> + </dependency> + </dependencies> + + <build> + <plugins> + <plugin> + <groupId>org.springframework.boot</groupId> + <artifactId>spring-boot-maven-plugin</artifactId> + <executions> + <execution> + <goals> + <goal>repackage</goal> + </goals> + <configuration> + <classifier>spring-boot</classifier> + <mainClass> + org.opengroup.osdu.partition.provider.reference.PartitionReferenceApplication + </mainClass> + </configuration> + </execution> + </executions> + </plugin> + <plugin> + <groupId>org.jacoco</groupId> + <artifactId>jacoco-maven-plugin</artifactId> + <version>0.7.7.201606060606</version> + <executions> + <execution> + <goals> + <goal>prepare-agent</goal> + </goals> + </execution> + <execution> + <id>report</id> + <phase>prepare-package</phase> + <goals> + <goal>report</goal> + </goals> + </execution> + </executions> + </plugin> + </plugins> + </build> +</project> \ No newline at end of file diff --git a/provider/partition-reference/src/main/java/org/opengroup/osdu/partition/provider/reference/PartitionReferenceApplication.java b/provider/partition-reference/src/main/java/org/opengroup/osdu/partition/provider/reference/PartitionReferenceApplication.java new file mode 100644 index 0000000000000000000000000000000000000000..75693d22b52d6c234794139da8cd6e951791096e --- /dev/null +++ b/provider/partition-reference/src/main/java/org/opengroup/osdu/partition/provider/reference/PartitionReferenceApplication.java @@ -0,0 +1,32 @@ +/* + Copyright 2002-2021 Google LLC + Copyright 2002-2021 EPAM Systems, Inc + + 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. + */ + +package org.opengroup.osdu.partition.provider.reference; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.autoconfigure.mongo.MongoAutoConfiguration; +import org.springframework.context.annotation.ComponentScan; + +@ComponentScan({"org.opengroup.osdu"}) +@SpringBootApplication(exclude = {MongoAutoConfiguration.class}) +public class PartitionReferenceApplication { + + public static void main(String[] args) { + SpringApplication.run(PartitionReferenceApplication.class, args); + } +} diff --git a/provider/partition-reference/src/main/java/org/opengroup/osdu/partition/provider/reference/cache/CredentialsCache.java b/provider/partition-reference/src/main/java/org/opengroup/osdu/partition/provider/reference/cache/CredentialsCache.java new file mode 100644 index 0000000000000000000000000000000000000000..b154aecbceaf1cbfcd6fa1408fcd248b74e5ef49 --- /dev/null +++ b/provider/partition-reference/src/main/java/org/opengroup/osdu/partition/provider/reference/cache/CredentialsCache.java @@ -0,0 +1,30 @@ +/* + Copyright 2002-2021 Google LLC + Copyright 2002-2021 EPAM Systems, Inc + + 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. + */ + +package org.opengroup.osdu.partition.provider.reference.cache; + +import org.opengroup.osdu.core.common.cache.VmCache; +import org.opengroup.osdu.core.gcp.multitenancy.credentials.GcsCredential; +import org.springframework.stereotype.Component; + +@Component +public class CredentialsCache extends VmCache<String, GcsCredential> { + + public CredentialsCache() { + super(30, 1000); + } +} diff --git a/provider/partition-reference/src/main/java/org/opengroup/osdu/partition/provider/reference/cache/GroupCache.java b/provider/partition-reference/src/main/java/org/opengroup/osdu/partition/provider/reference/cache/GroupCache.java new file mode 100644 index 0000000000000000000000000000000000000000..16315a83bb231b73b7db0d20f32e388567e68dc3 --- /dev/null +++ b/provider/partition-reference/src/main/java/org/opengroup/osdu/partition/provider/reference/cache/GroupCache.java @@ -0,0 +1,30 @@ +/* + Copyright 2002-2021 Google LLC + Copyright 2002-2021 EPAM Systems, Inc + + 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. + */ + +package org.opengroup.osdu.partition.provider.reference.cache; + +import org.opengroup.osdu.core.common.cache.VmCache; +import org.opengroup.osdu.core.common.model.entitlements.Groups; +import org.springframework.stereotype.Component; + +@Component +public class GroupCache extends VmCache<String, Groups> { + + public GroupCache() { + super(30, 1000); + } +} diff --git a/provider/partition-reference/src/main/java/org/opengroup/osdu/partition/provider/reference/cache/PartitionListCacheImpl.java b/provider/partition-reference/src/main/java/org/opengroup/osdu/partition/provider/reference/cache/PartitionListCacheImpl.java new file mode 100644 index 0000000000000000000000000000000000000000..83853f6c938857db57bdd0881e623e05be0f6259 --- /dev/null +++ b/provider/partition-reference/src/main/java/org/opengroup/osdu/partition/provider/reference/cache/PartitionListCacheImpl.java @@ -0,0 +1,53 @@ +/* + Copyright 2002-2021 Google LLC + Copyright 2002-2021 EPAM Systems, Inc + + 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. + */ + +package org.opengroup.osdu.partition.provider.reference.cache; + +import java.util.List; +import lombok.RequiredArgsConstructor; +import org.opengroup.osdu.core.common.cache.ICache; +import org.opengroup.osdu.partition.provider.interfaces.IPartitionServiceCache; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.stereotype.Service; + +@Service +@Qualifier("partitionListCache") +@RequiredArgsConstructor +public class PartitionListCacheImpl implements IPartitionServiceCache<String, List<String>> { + + private final ICache<String, List<String>> cache; + + @Override + public void put(String s, List<String> o) { + this.cache.put(s, o); + } + + @Override + public List<String> get(String s) { + return this.cache.get(s); + } + + @Override + public void delete(String s) { + this.cache.delete(s); + } + + @Override + public void clearAll() { + this.cache.clearAll(); + } +} diff --git a/provider/partition-reference/src/main/java/org/opengroup/osdu/partition/provider/reference/cache/PartitionServiceCacheImpl.java b/provider/partition-reference/src/main/java/org/opengroup/osdu/partition/provider/reference/cache/PartitionServiceCacheImpl.java new file mode 100644 index 0000000000000000000000000000000000000000..55a0c33ead57b2f6668c23b45790025932937b22 --- /dev/null +++ b/provider/partition-reference/src/main/java/org/opengroup/osdu/partition/provider/reference/cache/PartitionServiceCacheImpl.java @@ -0,0 +1,52 @@ +/* + Copyright 2002-2021 Google LLC + Copyright 2002-2021 EPAM Systems, Inc + + 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. + */ +package org.opengroup.osdu.partition.provider.reference.cache; + +import lombok.RequiredArgsConstructor; +import org.opengroup.osdu.core.common.cache.ICache; +import org.opengroup.osdu.partition.model.PartitionInfo; +import org.opengroup.osdu.partition.provider.interfaces.IPartitionServiceCache; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.stereotype.Service; + +@Service +@Qualifier("partitionServiceCache") +@RequiredArgsConstructor +public class PartitionServiceCacheImpl implements IPartitionServiceCache<String, PartitionInfo> { + + private final ICache<String, PartitionInfo> cache; + + @Override + public void put(String s, PartitionInfo o) { + this.cache.put(s, o); + } + + @Override + public PartitionInfo get(String s) { + return this.cache.get(s); + } + + @Override + public void delete(String s) { + this.cache.delete(s); + } + + @Override + public void clearAll() { + this.cache.clearAll(); + } +} diff --git a/provider/partition-reference/src/main/java/org/opengroup/osdu/partition/provider/reference/cache/VmCacheConfiguration.java b/provider/partition-reference/src/main/java/org/opengroup/osdu/partition/provider/reference/cache/VmCacheConfiguration.java new file mode 100644 index 0000000000000000000000000000000000000000..ba98db953e50f3ddbe841ff52a0f16892be0cbef --- /dev/null +++ b/provider/partition-reference/src/main/java/org/opengroup/osdu/partition/provider/reference/cache/VmCacheConfiguration.java @@ -0,0 +1,47 @@ +/* + Copyright 2002-2021 Google LLC + Copyright 2002-2021 EPAM Systems, Inc + + 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. + */ + +package org.opengroup.osdu.partition.provider.reference.cache; + +import java.util.List; +import lombok.RequiredArgsConstructor; +import org.opengroup.osdu.core.common.cache.VmCache; +import org.opengroup.osdu.partition.model.PartitionInfo; +import org.opengroup.osdu.partition.provider.reference.config.PropertiesConfiguration; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +@Configuration +@RequiredArgsConstructor +public class VmCacheConfiguration { + + private final PropertiesConfiguration properties; + + @Bean(name = "partitionListCache") + public VmCache<String, List<String>> partitionListCache() { + return new VmCache<>(this.properties.getCacheExpiration() * 60, + this.properties.getCacheMaxSize()); + } + + @ConfigurationProperties + @Bean(name = "partitionServiceCache") + public VmCache<String, PartitionInfo> partitionServiceCache() { + return new VmCache<>(this.properties.getCacheExpiration() * 60, + this.properties.getCacheMaxSize()); + } +} diff --git a/provider/partition-reference/src/main/java/org/opengroup/osdu/partition/provider/reference/config/IDTokenVerifierConfiguration.java b/provider/partition-reference/src/main/java/org/opengroup/osdu/partition/provider/reference/config/IDTokenVerifierConfiguration.java new file mode 100644 index 0000000000000000000000000000000000000000..eeb175e33a1e77a035c76abb0aa3823782726726 --- /dev/null +++ b/provider/partition-reference/src/main/java/org/opengroup/osdu/partition/provider/reference/config/IDTokenVerifierConfiguration.java @@ -0,0 +1,44 @@ +/* + * Copyright 2021 Google LLC + * Copyright 2021 EPAM Systems, Inc + * + * 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 + * + * https://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. + */ + +package org.opengroup.osdu.partition.provider.reference.config; + +import com.google.api.client.googleapis.auth.oauth2.GoogleIdTokenVerifier; +import com.google.api.client.googleapis.javanet.GoogleNetHttpTransport; +import com.google.api.client.json.jackson2.JacksonFactory; +import java.io.IOException; +import java.security.GeneralSecurityException; +import java.util.Collections; +import lombok.RequiredArgsConstructor; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +@Configuration +@RequiredArgsConstructor +public class IDTokenVerifierConfiguration { + + private final PropertiesConfiguration configuration; + + @Bean + public GoogleIdTokenVerifier buildTokenVerifier() throws GeneralSecurityException, IOException { + return new GoogleIdTokenVerifier.Builder( + GoogleNetHttpTransport.newTrustedTransport(), + JacksonFactory.getDefaultInstance()) + .setAudience(Collections.singleton(configuration.getGoogleAudiences())) + .build(); + } +} diff --git a/provider/partition-reference/src/main/java/org/opengroup/osdu/partition/provider/reference/config/MongoDBConfigProperties.java b/provider/partition-reference/src/main/java/org/opengroup/osdu/partition/provider/reference/config/MongoDBConfigProperties.java new file mode 100644 index 0000000000000000000000000000000000000000..848402ee4ac1fe9d5eb2b2ccbefa50b250db1dc9 --- /dev/null +++ b/provider/partition-reference/src/main/java/org/opengroup/osdu/partition/provider/reference/config/MongoDBConfigProperties.java @@ -0,0 +1,33 @@ +/* + * Copyright 2021 Google LLC + * Copyright 2021 EPAM Systems, Inc + * + * 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 + * + * https://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. + */ + +package org.opengroup.osdu.partition.provider.reference.config; + +import lombok.Data; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.context.annotation.Configuration; + +@Configuration +@ConfigurationProperties +@Data +public class MongoDBConfigProperties { + + private String mongoDbUrl; + private String mongoDbUser; + private String mongoDbPassword; + private String mongoDbName; +} diff --git a/provider/partition-reference/src/main/java/org/opengroup/osdu/partition/provider/reference/config/PropertiesConfiguration.java b/provider/partition-reference/src/main/java/org/opengroup/osdu/partition/provider/reference/config/PropertiesConfiguration.java new file mode 100644 index 0000000000000000000000000000000000000000..644ed5736a93646962d2ce55f9227da41133fbf8 --- /dev/null +++ b/provider/partition-reference/src/main/java/org/opengroup/osdu/partition/provider/reference/config/PropertiesConfiguration.java @@ -0,0 +1,51 @@ +/* + Copyright 2002-2021 Google LLC + Copyright 2002-2021 EPAM Systems, Inc + + 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. + */ + +package org.opengroup.osdu.partition.provider.reference.config; + +import java.util.List; +import java.util.Objects; +import javax.annotation.PostConstruct; +import lombok.Data; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.context.annotation.Configuration; + +@Configuration +@ConfigurationProperties +@Data +public class PropertiesConfiguration { + + private String googleAudiences; + + private List<String> partitionAdminAccounts; + + private String googleCloudProject; + + private int cacheExpiration; + + private int cacheMaxSize; + + private String serviceAccountTail; + + @PostConstruct + public void setUp() { + if (Objects.isNull(serviceAccountTail) || serviceAccountTail.isEmpty()) { + this.serviceAccountTail = googleCloudProject + ".iam.gserviceaccount.com"; + } + } + +} diff --git a/provider/partition-reference/src/main/java/org/opengroup/osdu/partition/provider/reference/model/PartitionPropertyDocument.java b/provider/partition-reference/src/main/java/org/opengroup/osdu/partition/provider/reference/model/PartitionPropertyDocument.java new file mode 100644 index 0000000000000000000000000000000000000000..93db9614107fdfecfe79cf236317f1004225da75 --- /dev/null +++ b/provider/partition-reference/src/main/java/org/opengroup/osdu/partition/provider/reference/model/PartitionPropertyDocument.java @@ -0,0 +1,36 @@ +/* + * Copyright 2021 Google LLC + * Copyright 2021 EPAM Systems, Inc + * + * 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 + * + * https://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. + */ + +package org.opengroup.osdu.partition.provider.reference.model; + +import java.util.HashMap; +import java.util.Map; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; +import org.opengroup.osdu.partition.model.Property; +import org.springframework.data.mongodb.core.mapping.Document; + +@Data +@AllArgsConstructor +@NoArgsConstructor +@Document(collection = "Partitions") +public class PartitionPropertyDocument { + + private String partitionId; + private Map<String, Property> properties = new HashMap<>(); +} \ No newline at end of file diff --git a/provider/partition-reference/src/main/java/org/opengroup/osdu/partition/provider/reference/persistence/MongoDdmsClient.java b/provider/partition-reference/src/main/java/org/opengroup/osdu/partition/provider/reference/persistence/MongoDdmsClient.java new file mode 100644 index 0000000000000000000000000000000000000000..c74ff5af8c2d70028e34051e816eec773d185568 --- /dev/null +++ b/provider/partition-reference/src/main/java/org/opengroup/osdu/partition/provider/reference/persistence/MongoDdmsClient.java @@ -0,0 +1,38 @@ +/* + * Copyright 2021 Google LLC + * Copyright 2021 EPAM Systems, Inc + * + * 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 + * + * https://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. + */ + +package org.opengroup.osdu.partition.provider.reference.persistence; + +import com.mongodb.client.MongoCollection; +import org.bson.Document; +import org.opengroup.osdu.partition.provider.reference.util.MongoClientHandler; +import org.springframework.stereotype.Component; + +@Component +public class MongoDdmsClient { + + private MongoClientHandler mongoClientHandler; + + public MongoDdmsClient(MongoClientHandler mongoClientHandler) { + this.mongoClientHandler = mongoClientHandler; + } + + public MongoCollection<Document> getMongoCollection(String dbName, String collectionName) { + return mongoClientHandler.getMongoClient().getDatabase(dbName) + .getCollection(collectionName); + } +} diff --git a/provider/partition-reference/src/main/java/org/opengroup/osdu/partition/provider/reference/repository/PartitionPropertyEntityRepository.java b/provider/partition-reference/src/main/java/org/opengroup/osdu/partition/provider/reference/repository/PartitionPropertyEntityRepository.java new file mode 100644 index 0000000000000000000000000000000000000000..cf339e64b27d960c9c4db45240a6b7e54e858710 --- /dev/null +++ b/provider/partition-reference/src/main/java/org/opengroup/osdu/partition/provider/reference/repository/PartitionPropertyEntityRepository.java @@ -0,0 +1,153 @@ +/* + Copyright 2002-2021 Google LLC + Copyright 2002-2021 EPAM Systems, Inc + + 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. + */ + +package org.opengroup.osdu.partition.provider.reference.repository; + +import static com.mongodb.client.model.Filters.eq; + +import com.google.gson.Gson; +import com.mongodb.client.FindIterable; +import com.mongodb.client.MongoCollection; +import com.mongodb.client.model.ReplaceOptions; +import com.mongodb.client.result.DeleteResult; +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; +import java.util.Optional; +import org.bson.Document; +import org.opengroup.osdu.partition.model.PartitionInfo; +import org.opengroup.osdu.partition.model.Property; +import org.opengroup.osdu.partition.provider.reference.model.PartitionPropertyDocument; +import org.opengroup.osdu.partition.provider.reference.persistence.MongoDdmsClient; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Repository; + +@Repository +public class PartitionPropertyEntityRepository { + + protected static final String PARTITIONS = "Partitions"; + protected static final String PARTITIONS_DATABASE = "PartitionsDB"; + protected static final String PARTITION_ID = "partitionId"; + private final MongoDdmsClient mongoDdmsClient; + + @Autowired + public PartitionPropertyEntityRepository(MongoDdmsClient mongoDdmsClient) { + this.mongoDdmsClient = mongoDdmsClient; + } + + public Optional<PartitionInfo> createPartition(String partitionId, PartitionInfo partitionInfo) { + if (Objects.nonNull(partitionInfo) && Objects.nonNull(partitionId)) { + MongoCollection<Document> mongoCollection = mongoDdmsClient + .getMongoCollection(PARTITIONS_DATABASE, PARTITIONS); + PartitionPropertyDocument partitionPropertyDocument = convertToPartitionPropertyDocument( + partitionId, partitionInfo); + mongoCollection.replaceOne(eq(PARTITION_ID, partitionId), + Document.parse(new Gson().toJson(partitionPropertyDocument)), + new ReplaceOptions().upsert(true)); + return Optional.ofNullable(partitionInfo); + } + return Optional.empty(); + } + + public Optional<PartitionInfo> updatePartition(String partitionId, PartitionInfo partitionInfo) { + if (Objects.nonNull(partitionInfo) && Objects.nonNull(partitionId)) { + MongoCollection<Document> mongoCollection = mongoDdmsClient + .getMongoCollection(PARTITIONS_DATABASE, PARTITIONS); + Document result = mongoCollection.find(eq(PARTITION_ID, partitionId)).first(); + PartitionPropertyDocument partitionPropertyDocument = new Gson().fromJson(result.toJson(), + PartitionPropertyDocument.class); + partitionPropertyDocument.getProperties().putAll(partitionInfo.getProperties()); + + mongoCollection.replaceOne(eq(PARTITION_ID, partitionId), + Document.parse(new Gson().toJson(partitionPropertyDocument)), + new ReplaceOptions().upsert(true)); + return Optional.ofNullable(partitionInfo); + } + return Optional.empty(); + } + + public Optional<PartitionInfo> findByPartitionId(String partitionId) { + if (Objects.nonNull(partitionId)) { + MongoCollection<Document> mongoCollection = mongoDdmsClient + .getMongoCollection(PARTITIONS_DATABASE, PARTITIONS); + Document result = mongoCollection.find(eq(PARTITION_ID, partitionId)).first(); + if (Objects.nonNull(result)) { + PartitionPropertyDocument partitionPropertyDocument = new Gson().fromJson(result.toJson(), + PartitionPropertyDocument.class); + PartitionInfo partitionInfo = convertToPartitionInfo(partitionPropertyDocument); + return Optional.ofNullable(partitionInfo); + } + } + return Optional.empty(); + } + + public List<String> getAllPartitions() { + MongoCollection<Document> mongoCollection = mongoDdmsClient + .getMongoCollection(PARTITIONS_DATABASE, PARTITIONS); + + FindIterable<Document> results = mongoCollection.find(); + List<String> partitionsIds = new ArrayList<>(); + for (Document document : results) { + PartitionPropertyDocument partitionPropertyDocument = new Gson().fromJson(document.toJson(), + PartitionPropertyDocument.class); + partitionsIds.add(partitionPropertyDocument.getPartitionId()); + } + return partitionsIds; + } + + public boolean isDeletedPartitionInfoByPartitionId(String partitionId) { + if (Objects.nonNull(partitionId)) { + MongoCollection<Document> mongoCollection = mongoDdmsClient + .getMongoCollection(PARTITIONS_DATABASE, PARTITIONS); + DeleteResult result = mongoCollection.deleteMany(eq(PARTITION_ID, partitionId)); + return result.wasAcknowledged(); + } + return false; + } + + public Optional<Property> findByPartitionIdAndName(String partitionId, String key) { + if (Objects.nonNull(partitionId) && Objects.nonNull(key)) { + MongoCollection<Document> mongoCollection = mongoDdmsClient + .getMongoCollection(PARTITIONS_DATABASE, PARTITIONS); + Document result = mongoCollection.find(eq(PARTITION_ID, partitionId)).first(); + if (Objects.nonNull(result)) { + PartitionPropertyDocument partitionPropertyDocument = new Gson().fromJson(result.toJson(), + PartitionPropertyDocument.class); + Property property = partitionPropertyDocument.getProperties().get(key); + if (Objects.nonNull(property)) { + return Optional.ofNullable(property); + } + } + } + return Optional.empty(); + } + + private PartitionPropertyDocument convertToPartitionPropertyDocument( + String partitionId, PartitionInfo partitionInfo) { + PartitionPropertyDocument partitionPropertyDocument = new PartitionPropertyDocument(); + partitionPropertyDocument.setPartitionId(partitionId); + partitionPropertyDocument.setProperties(partitionInfo.getProperties()); + return partitionPropertyDocument; + } + + private PartitionInfo convertToPartitionInfo( + PartitionPropertyDocument partitionPropertyDocument) { + PartitionInfo partitionInfo = new PartitionInfo(); + partitionInfo.setProperties(partitionPropertyDocument.getProperties()); + return partitionInfo; + } +} diff --git a/provider/partition-reference/src/main/java/org/opengroup/osdu/partition/provider/reference/security/AuthorizationService.java b/provider/partition-reference/src/main/java/org/opengroup/osdu/partition/provider/reference/security/AuthorizationService.java new file mode 100644 index 0000000000000000000000000000000000000000..30a6c7e2c5d7222243ba1dd83bed05e06b013f7a --- /dev/null +++ b/provider/partition-reference/src/main/java/org/opengroup/osdu/partition/provider/reference/security/AuthorizationService.java @@ -0,0 +1,93 @@ +/* + Copyright 2002-2021 Google LLC + Copyright 2002-2021 EPAM Systems, Inc + + 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. + */ + +package org.opengroup.osdu.partition.provider.reference.security; + +import com.google.api.client.googleapis.auth.oauth2.GoogleIdToken; +import com.google.api.client.googleapis.auth.oauth2.GoogleIdTokenVerifier; +import java.util.List; +import java.util.Objects; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import org.opengroup.osdu.core.common.model.http.AppException; +import org.opengroup.osdu.core.common.model.http.DpsHeaders; +import org.opengroup.osdu.partition.provider.interfaces.IAuthorizationService; +import org.opengroup.osdu.partition.provider.reference.config.PropertiesConfiguration; +import org.springframework.stereotype.Component; +import org.springframework.web.context.annotation.RequestScope; + +@Slf4j +@Component +@RequestScope +@RequiredArgsConstructor +public class AuthorizationService implements IAuthorizationService { + + private final PropertiesConfiguration configuration; + + private final DpsHeaders headers; + + private final GoogleIdTokenVerifier verifier; + + @Override + public boolean isDomainAdminServiceAccount() { + if (Objects.isNull(headers.getAuthorization()) || headers.getAuthorization().isEmpty()) { + throw AppException.createUnauthorized("No JWT token. Access is Forbidden"); + } + String email = null; + try { + String authorization = headers.getAuthorization().replace("Bearer ", ""); + GoogleIdToken googleIdToken = verifier.verify(authorization); + if (Objects.isNull(googleIdToken)) { + log.warn("Not valid token provided"); + throw AppException.createUnauthorized("Unauthorized. The JWT token could not be validated"); + } + email = googleIdToken.getPayload().getEmail(); + List<String> partitionAdminAccounts = configuration.getPartitionAdminAccounts(); + if (Objects.nonNull(partitionAdminAccounts) && !partitionAdminAccounts.isEmpty()) { + return isAllowedAccount(email); + } else { + if (StringUtils.endsWith(email, configuration.getServiceAccountTail())) { + return true; + } else { + throw AppException.createUnauthorized( + String.format("Unauthorized. The user %s is not Service Principal", email)); + } + } + } catch (AppException e){ + throw e; + } catch (Exception ex) { + log.warn(String.format("User %s is not unauthorized. %s.", email, ex)); + throw AppException.createUnauthorized("Unauthorized. The JWT token could not be validated"); + } + } + + private boolean isAllowedAccount(String accountEmail) { + if (StringUtils.endsWith(accountEmail, configuration.getServiceAccountTail())) { + for (String partitionAdmin : configuration.getPartitionAdminAccounts()) { + if (partitionAdmin.equals(accountEmail)) { + return true; + } + if (StringUtils.startsWith(accountEmail, partitionAdmin)) { + return true; + } + } + } + throw AppException + .createUnauthorized(String.format("Unauthorized. The user %s is untrusted.", accountEmail)); + } +} diff --git a/provider/partition-reference/src/main/java/org/opengroup/osdu/partition/provider/reference/security/SecurityConfigReference.java b/provider/partition-reference/src/main/java/org/opengroup/osdu/partition/provider/reference/security/SecurityConfigReference.java new file mode 100644 index 0000000000000000000000000000000000000000..046a2aeeb942e866d5f5b604940a401d3b8d0bf0 --- /dev/null +++ b/provider/partition-reference/src/main/java/org/opengroup/osdu/partition/provider/reference/security/SecurityConfigReference.java @@ -0,0 +1,43 @@ +/* + Copyright 2002-2021 Google LLC + Copyright 2002-2021 EPAM Systems, Inc + + 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. + */ + +package org.opengroup.osdu.partition.provider.reference.security; + +import org.springframework.context.annotation.Configuration; +import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity; +import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.config.annotation.web.builders.WebSecurity; +import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; +import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; + +@EnableWebSecurity +@Configuration +@EnableGlobalMethodSecurity(prePostEnabled = true) +public class SecurityConfigReference extends WebSecurityConfigurerAdapter { + + @Override + protected void configure(HttpSecurity http) throws Exception { + http.httpBasic().disable() + .csrf().disable(); + } + + @Override + public void configure(WebSecurity web) throws Exception { + web.ignoring().antMatchers("/api-docs") + .antMatchers("/swagger"); + } +} diff --git a/provider/partition-reference/src/main/java/org/opengroup/osdu/partition/provider/reference/service/PartitionServiceImpl.java b/provider/partition-reference/src/main/java/org/opengroup/osdu/partition/provider/reference/service/PartitionServiceImpl.java new file mode 100644 index 0000000000000000000000000000000000000000..32bf72832d9d711e5e1ada19bb4432c070fc79d1 --- /dev/null +++ b/provider/partition-reference/src/main/java/org/opengroup/osdu/partition/provider/reference/service/PartitionServiceImpl.java @@ -0,0 +1,124 @@ +/* + Copyright 2002-2021 Google LLC + Copyright 2002-2021 EPAM Systems, Inc + + 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. + */ + +package org.opengroup.osdu.partition.provider.reference.service; + +import java.util.Collections; +import java.util.List; +import java.util.Optional; +import lombok.RequiredArgsConstructor; +import org.apache.http.HttpStatus; +import org.opengroup.osdu.core.common.model.http.AppException; +import org.opengroup.osdu.core.common.provider.interfaces.IKmsClient; +import org.opengroup.osdu.partition.logging.AuditLogger; +import org.opengroup.osdu.partition.model.PartitionInfo; +import org.opengroup.osdu.partition.model.Property; +import org.opengroup.osdu.partition.provider.interfaces.IPartitionService; +import org.opengroup.osdu.partition.provider.reference.repository.PartitionPropertyEntityRepository; +import org.springframework.stereotype.Service; + +@Service +@RequiredArgsConstructor +public class PartitionServiceImpl implements IPartitionService { + + private static final String UNKNOWN_ERROR_REASON = "unknown error"; + + private final PartitionPropertyEntityRepository partitionPropertyEntityRepository; + + private final IKmsClient kmsClient; + + private final AuditLogger auditLogger; + + @Override + public PartitionInfo createPartition(String partitionId, PartitionInfo partitionInfo) { + if (partitionPropertyEntityRepository.findByPartitionId(partitionId).isPresent()) { + throw new AppException(HttpStatus.SC_CONFLICT, UNKNOWN_ERROR_REASON, + "Partition already exists."); + } + partitionInfo.getProperties() + .forEach((key, property) -> encryptPartitionPropertyEntityIfNeeded(property)); + partitionPropertyEntityRepository.createPartition(partitionId, partitionInfo); + return getPartition(partitionId); + } + + @Override + public PartitionInfo updatePartition(String partitionId, PartitionInfo partitionInfo) { + if (partitionInfo.getProperties().containsKey("id")) { + this.auditLogger.updatePartitionSecretFailure(Collections.singletonList(partitionId)); + throw new AppException(HttpStatus.SC_BAD_REQUEST, "can not update id", + "the field id can not be updated"); + } + if (!partitionPropertyEntityRepository.findByPartitionId(partitionId).isPresent()) { + this.auditLogger.updatePartitionSecretFailure(Collections.singletonList(partitionId)); + throw new AppException(HttpStatus.SC_NOT_FOUND, UNKNOWN_ERROR_REASON, + "An attempt to update not existing partition."); + } + partitionInfo.getProperties().forEach((key, value) -> { + Optional<Property> property = this.partitionPropertyEntityRepository + .findByPartitionIdAndName(partitionId, key); + if (property.isPresent()) { + property.get().setSensitive(value.isSensitive()); + property.get().setValue(value.getValue()); + encryptPartitionPropertyEntityIfNeeded(property.get()); + } + encryptPartitionPropertyEntityIfNeeded(value); + }); + partitionPropertyEntityRepository.updatePartition(partitionId, partitionInfo); + return getPartition(partitionId); + } + + @Override + public PartitionInfo getPartition(String partitionId) { + Optional<PartitionInfo> result = partitionPropertyEntityRepository.findByPartitionId( + partitionId); + if (result.isPresent()) { + result.get().getProperties() + .forEach((key, property) -> decryptPartitionPropertyIfNeeded(property)); + return result.get(); + } + return new PartitionInfo(); + } + + @Override + public boolean deletePartition(String partitionId) { + if (!partitionPropertyEntityRepository.findByPartitionId(partitionId).isPresent()) { + this.auditLogger.deletePartitionFailure(Collections.singletonList(partitionId)); + throw new AppException(HttpStatus.SC_NOT_FOUND, UNKNOWN_ERROR_REASON, + "An attempt to delete not existing partition."); + } + return partitionPropertyEntityRepository.isDeletedPartitionInfoByPartitionId(partitionId); + } + + @Override + public List<String> getAllPartitions() { + return partitionPropertyEntityRepository.getAllPartitions(); + } + + private void encryptPartitionPropertyEntityIfNeeded(Property property) { + if (property.isSensitive()) { + String propertyValue = property.getValue().toString(); + property.setValue("this.kmsClient.encryptString " + propertyValue); + } + } + + private void decryptPartitionPropertyIfNeeded(Property property) { + if (property.isSensitive()) { + String propertyValue = property.getValue().toString(); + property.setValue("this.kmsClient.decryptString " + propertyValue); + } + } +} diff --git a/provider/partition-reference/src/main/java/org/opengroup/osdu/partition/provider/reference/util/MongoClientHandler.java b/provider/partition-reference/src/main/java/org/opengroup/osdu/partition/provider/reference/util/MongoClientHandler.java new file mode 100644 index 0000000000000000000000000000000000000000..0a282164acc3a1c1f487e34f6fdadf7dfce6fc25 --- /dev/null +++ b/provider/partition-reference/src/main/java/org/opengroup/osdu/partition/provider/reference/util/MongoClientHandler.java @@ -0,0 +1,75 @@ +/* + * Copyright 2021 Google LLC + * Copyright 2021 EPAM Systems, Inc + * + * 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 + * + * https://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. + */ + +package org.opengroup.osdu.partition.provider.reference.util; + +import com.mongodb.ConnectionString; +import com.mongodb.MongoClientSettings; +import com.mongodb.client.MongoClient; +import com.mongodb.client.MongoClients; +import org.apache.http.HttpStatus; +import org.opengroup.osdu.core.common.model.http.AppException; +import org.opengroup.osdu.partition.provider.reference.config.MongoDBConfigProperties; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +@Component +public class MongoClientHandler { + + private static final String MONGO_PREFIX = "mongodb://"; + private static final String MONGO_OPTIONS = "retryWrites=true&w=majority&maxIdleTimeMS=10000"; + + private MongoClient mongoClient = null; + private MongoDBConfigProperties mongoDBConfigProperties; + + private MongoClient getOrInitMongoClient() { + if (mongoClient != null) { + return mongoClient; + } + + final String connectionString = String.format("%s%s:%s@%s/?%s", + MONGO_PREFIX, + mongoDBConfigProperties.getMongoDbUser(), + mongoDBConfigProperties.getMongoDbPassword(), + mongoDBConfigProperties.getMongoDbUrl(), + MONGO_OPTIONS); + ConnectionString connString = new ConnectionString(connectionString); + MongoClientSettings settings = MongoClientSettings.builder() + .applyConnectionString(connString) + .retryWrites(true) + .build(); + try { + mongoClient = MongoClients.create(settings); + } catch (Exception ex) { + throw new AppException(HttpStatus.SC_INTERNAL_SERVER_ERROR, "Error connecting MongoDB", + ex.getMessage(), ex); + } + return mongoClient; + } + + public MongoClient getMongoClient() { + if (mongoClient == null) { + getOrInitMongoClient(); + } + return mongoClient; + } + + @Autowired + public void setMongoDBConfigProperties(MongoDBConfigProperties mongoDBConfigProperties) { + this.mongoDBConfigProperties = mongoDBConfigProperties; + } +} diff --git a/provider/partition-reference/src/main/resources/application.properties b/provider/partition-reference/src/main/resources/application.properties new file mode 100644 index 0000000000000000000000000000000000000000..96e336328093735d92d0c6c17393fe769ee778b3 --- /dev/null +++ b/provider/partition-reference/src/main/resources/application.properties @@ -0,0 +1,35 @@ +LOG_PREFIX=partition +server.servlet.contextPath=/api/partition/v1 +logging.level.org.springframework.web=${LOG_LEVEL:DEBUG} +server.port=8080 +springfox.documentation.swagger.v2.path=/api-docs + +management.endpoint.health.show-details=always +management.health.diskspace.enabled=false + +authorize-api=https://os-entitlements-gcp-jvmvia5dea-uc.a.run.app/entitlements/v1 + +#ACCEPT_HTTP=true + +cache-expiration=1 +cache-maxSize=1000 + +key-ring=csqp +kms-key=searchService + +KEY_RING=${key-ring} +KMS_KEY=${kms-key} + +GOOGLE_CLOUD_PROJECT=${google-cloud-project} +google-cloud-project=osdu-cicd-epam + +google-audiences=123.apps.googleusercontent.com +GOOGLE_AUDIENCES=${google-audiences} + +partition-admin-accounts=osdu-gcp-sa + +mongo-db-url=localhost:27017 +mongo-db-user= +mongo-db-password= + +PARTITION_API=http://localhost:8080/ \ No newline at end of file diff --git a/provider/partition-reference/src/main/resources/logback.xml b/provider/partition-reference/src/main/resources/logback.xml new file mode 100644 index 0000000000000000000000000000000000000000..2f7a4d029a3d0568b4b6fbaa5d2db8bf21b33381 --- /dev/null +++ b/provider/partition-reference/src/main/resources/logback.xml @@ -0,0 +1,40 @@ +<?xml version="1.0" encoding="UTF-8"?> +<configuration> + <include resource="org/springframework/boot/logging/logback/defaults.xml"/> + <logger name="org.opengroup.osdu" level="${LOG_LEVEL}"/> + <springProfile name="local"> + <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender"> + <encoder> + <pattern>%yellow([%thread]) %highlight(| %-5level |) %green(%d) %cyan(| %logger{15} |) + %highlight(%msg) %n + </pattern> + <charset>utf8</charset> + </encoder> + </appender> + <root level="info"> + <appender-ref ref="CONSOLE"/> + </root> + </springProfile> + --> + + <springProfile name="!local"> + <appender name="stdout" class="ch.qos.logback.core.ConsoleAppender"> + <encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder"> + <layout class="ch.qos.logback.contrib.json.classic.JsonLayout"> + <timestampFormat>yyyy-MM-dd HH:mm:ss.SSS</timestampFormat> + <timestampFormatTimezoneId>Etc/UTC</timestampFormatTimezoneId> + <appendLineSeparator>true</appendLineSeparator> + + <jsonFormatter class="org.opengroup.osdu.core.gcp.logging.formatter.GoogleJsonFormatter"> + <prettyPrint>false</prettyPrint> + </jsonFormatter> + </layout> + </encoder> + </appender> + + <root level="info"> + <appender-ref ref="stdout"/> + </root> + </springProfile> + +</configuration> \ No newline at end of file diff --git a/provider/partition-reference/src/test/java/org/opengroup/osdu/partition/provider/reference/repository/PartitionPropertyEntityRepositoryTest.java b/provider/partition-reference/src/test/java/org/opengroup/osdu/partition/provider/reference/repository/PartitionPropertyEntityRepositoryTest.java new file mode 100644 index 0000000000000000000000000000000000000000..96415e7db89b4e4c56e9eee953be49f656a4522c --- /dev/null +++ b/provider/partition-reference/src/test/java/org/opengroup/osdu/partition/provider/reference/repository/PartitionPropertyEntityRepositoryTest.java @@ -0,0 +1,223 @@ +package org.opengroup.osdu.partition.provider.reference.repository; + +import static com.mongodb.client.model.Filters.eq; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; +import static org.opengroup.osdu.partition.provider.reference.repository.PartitionPropertyEntityRepository.PARTITIONS; +import static org.opengroup.osdu.partition.provider.reference.repository.PartitionPropertyEntityRepository.PARTITIONS_DATABASE; +import static org.opengroup.osdu.partition.provider.reference.repository.PartitionPropertyEntityRepository.PARTITION_ID; +import static org.powermock.api.mockito.PowerMockito.mock; +import static org.powermock.api.mockito.PowerMockito.when; + +import com.mongodb.client.FindIterable; +import com.mongodb.client.MongoClient; +import com.mongodb.client.MongoCollection; +import com.mongodb.client.result.DeleteResult; +import java.util.HashMap; +import java.util.Map; +import java.util.Optional; +import org.bson.Document; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.junit.MockitoJUnitRunner; +import org.opengroup.osdu.partition.model.PartitionInfo; +import org.opengroup.osdu.partition.model.Property; +import org.opengroup.osdu.partition.provider.reference.config.MongoDBConfigProperties; +import org.opengroup.osdu.partition.provider.reference.persistence.MongoDdmsClient; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.data.mongodb.core.MongoOperations; + +@RunWith(MockitoJUnitRunner.class) +@PrepareForTest({MongoOperations.class, MongoClient.class}) +public class PartitionPropertyEntityRepositoryTest { + + private static final String PARTITION_ID_VALUE = "PartitionId"; + + @Mock + private MongoDdmsClient mongoDdmsClient; + + @MockBean + private MongoOperations ops; + + @MockBean + private MongoDBConfigProperties mongoDBConfigProperties; + + @InjectMocks + private PartitionPropertyEntityRepository repo; + + @Test + public void testCreatePartition() { + when(mongoDdmsClient.getMongoCollection(PARTITIONS_DATABASE, PARTITIONS)).thenReturn( + mock(MongoCollection.class)); + + PartitionInfo expectedResult = buildPartitionInfo(); + Optional<PartitionInfo> actualResult = repo.createPartition(PARTITION_ID_VALUE, expectedResult); + + assertEquals(expectedResult, actualResult.get()); + } + + @Test + public void testCreatePartitionWithNullPartitionId() { + PartitionInfo expectedResult = buildPartitionInfo(); + Optional<PartitionInfo> partition = repo.createPartition(null, expectedResult); + + assertFalse(partition.isPresent()); + } + + @Test + public void testUpdatePartition() { + MongoCollection<Document> mongoCollection = mock(MongoCollection.class); + Document result = mock(Document.class); + when(mongoDdmsClient.getMongoCollection(PARTITIONS_DATABASE, PARTITIONS)).thenReturn( + mongoCollection); + when(mongoCollection.find(eq(PARTITION_ID, PARTITION_ID_VALUE))).thenReturn( + mock(FindIterable.class)); + when(mongoCollection.find(eq(PARTITION_ID, PARTITION_ID_VALUE)).first()).thenReturn(result); + when(result.toJson()).thenReturn( + "{\"_id\": {\"$oid\": \"ID\"}, \"partitionId\": \"PartitionId\", \"properties\": {\"bucket\": {\"sensitive\": false, \"value\": \"osdu-cicd-epam-records\"}, \"crmAccountID\": {\"sensitive\": false, \"value\": \"[\\\"cicd\\\",\\\"opendes1234\\\"]\"}, \"policy-service-enabled\": {\"sensitive\": false, \"value\": \"false\"}, \"name\": {\"sensitive\": false, \"value\": \"opendes1234\"}, \"compliance-ruleset\": {\"sensitive\": false, \"value\": \"shared\"}, \"projectId\": {\"sensitive\": false, \"value\": \"osdu\"}}}"); + + PartitionInfo expectedResult = buildPartitionInfo(); + Optional<PartitionInfo> actualResult = repo.updatePartition(PARTITION_ID_VALUE, + expectedResult); + + assertEquals(expectedResult, actualResult.get()); + } + + @Test + public void testUpdatePartitionWithNullPartitionInfo() { + Optional<PartitionInfo> actualResult = repo.updatePartition(PARTITION_ID_VALUE, null); + + assertFalse(actualResult.isPresent()); + } + + @Test + public void testDeletePartition() { + MongoCollection<Document> mongoCollection = mock(MongoCollection.class); + DeleteResult deleteResult = mock(DeleteResult.class); + when(mongoDdmsClient.getMongoCollection(PARTITIONS_DATABASE, PARTITIONS)).thenReturn( + mongoCollection); + when(mongoCollection.deleteMany(eq(PARTITION_ID, PARTITION_ID_VALUE))).thenReturn(deleteResult); + when(deleteResult.wasAcknowledged()).thenReturn(true); + + boolean result = repo.isDeletedPartitionInfoByPartitionId(PARTITION_ID_VALUE); + + assertTrue(result); + } + + @Test + public void testDeletePartitionWithNullPartitionId() { + boolean result = repo.isDeletedPartitionInfoByPartitionId(null); + + assertFalse(result); + } + + @Test + public void testFindByPartitionId() { + MongoCollection<Document> mongoCollection = mock(MongoCollection.class); + Document result = mock(Document.class); + when(mongoDdmsClient.getMongoCollection(PARTITIONS_DATABASE, PARTITIONS)).thenReturn( + mongoCollection); + when(mongoCollection.find(eq(PARTITION_ID, PARTITION_ID_VALUE))).thenReturn( + mock(FindIterable.class)); + when(mongoCollection.find(eq(PARTITION_ID, PARTITION_ID_VALUE)).first()).thenReturn(result); + when(result.toJson()).thenReturn( + "{\"_id\": {\"$oid\": \"ID\"}, \"partitionId\": \"PartitionId\", \"properties\": {\"bucket\": {\"sensitive\": false, \"value\": \"osdu-cicd-epam-records\"}, \"crmAccountID\": {\"sensitive\": false, \"value\": \"[\\\"cicd\\\",\\\"opendes1234\\\"]\"}, \"policy-service-enabled\": {\"sensitive\": false, \"value\": \"false\"}, \"name\": {\"sensitive\": false, \"value\": \"opendes1234\"}, \"compliance-ruleset\": {\"sensitive\": false, \"value\": \"shared\"}, \"projectId\": {\"sensitive\": false, \"value\": \"osdu\"}}}"); + + Optional<PartitionInfo> actualResult = repo.findByPartitionId(PARTITION_ID_VALUE); + + assertNotNull(actualResult.get()); + } + + @Test + public void testFindByPartitionIdWithoutFoundDocument() { + MongoCollection<Document> mongoCollection = mock(MongoCollection.class); + when(mongoDdmsClient.getMongoCollection(PARTITIONS_DATABASE, PARTITIONS)).thenReturn( + mongoCollection); + when(mongoCollection.find(eq(PARTITION_ID, PARTITION_ID_VALUE))).thenReturn( + mock(FindIterable.class)); + when(mongoCollection.find(eq(PARTITION_ID, PARTITION_ID_VALUE)).first()).thenReturn(null); + + Optional<PartitionInfo> actualResult = repo.findByPartitionId(PARTITION_ID_VALUE); + + assertFalse(actualResult.isPresent()); + } + + @Test + public void testFindByPartitionIdWithNullPartitionId() { + Optional<PartitionInfo> actualResult = repo.findByPartitionId(null); + + assertFalse(actualResult.isPresent()); + } + + @Test + public void testFindByPartitionIdAndName() { + MongoCollection<Document> mongoCollection = mock(MongoCollection.class); + Document result = mock(Document.class); + when(mongoDdmsClient.getMongoCollection(PARTITIONS_DATABASE, PARTITIONS)).thenReturn( + mongoCollection); + when(mongoCollection.find(eq(PARTITION_ID, PARTITION_ID_VALUE))).thenReturn( + mock(FindIterable.class)); + when(mongoCollection.find(eq(PARTITION_ID, PARTITION_ID_VALUE)).first()).thenReturn(result); + when(result.toJson()).thenReturn( + "{\"_id\": {\"$oid\": \"ID\"}, \"partitionId\": \"PartitionId\", \"properties\": {\"bucket\": {\"sensitive\": false, \"value\": \"osdu-cicd-epam-records\"}, \"crmAccountID\": {\"sensitive\": false, \"value\": \"[\\\"cicd\\\",\\\"opendes1234\\\"]\"}, \"policy-service-enabled\": {\"sensitive\": false, \"value\": \"false\"}, \"name\": {\"sensitive\": false, \"value\": \"opendes1234\"}, \"compliance-ruleset\": {\"sensitive\": false, \"value\": \"shared\"}, \"projectId\": {\"sensitive\": false, \"value\": \"osdu\"}}}"); + + Optional<Property> actualResult = repo.findByPartitionIdAndName(PARTITION_ID_VALUE, "bucket"); + + assertNotNull(actualResult.get()); + + } + + @Test + public void testFindByPartitionIdAndNameWithNullPartitionId() { + Optional<Property> actualResult = repo.findByPartitionIdAndName(null, "bucket"); + assertFalse(actualResult.isPresent()); + } + + @Test + public void testFindByPartitionIdAndNameWithoutFoundDocument() { + MongoCollection<Document> mongoCollection = mock(MongoCollection.class); + when(mongoDdmsClient.getMongoCollection(PARTITIONS_DATABASE, PARTITIONS)).thenReturn( + mongoCollection); + when(mongoCollection.find(eq(PARTITION_ID, PARTITION_ID_VALUE))).thenReturn( + mock(FindIterable.class)); + when(mongoCollection.find(eq(PARTITION_ID, PARTITION_ID_VALUE)).first()).thenReturn(null); + + Optional<Property> actualResult = repo.findByPartitionIdAndName(PARTITION_ID_VALUE, "nonExist"); + + assertFalse(actualResult.isPresent()); + } + + @Test + public void testFindByPartitionIdAndNameWithoutFoundProperty() { + MongoCollection<Document> mongoCollection = mock(MongoCollection.class); + Document result = mock(Document.class); + when(mongoDdmsClient.getMongoCollection(PARTITIONS_DATABASE, PARTITIONS)).thenReturn( + mongoCollection); + when(mongoCollection.find(eq(PARTITION_ID, PARTITION_ID_VALUE))).thenReturn( + mock(FindIterable.class)); + when(mongoCollection.find(eq(PARTITION_ID, PARTITION_ID_VALUE)).first()).thenReturn(result); + when(result.toJson()).thenReturn( + "{\"_id\": {\"$oid\": \"ID\"}, \"partitionId\": \"PartitionId\", \"properties\": {\"bucket\": {\"sensitive\": false, \"value\": \"osdu-cicd-epam-records\"}, \"crmAccountID\": {\"sensitive\": false, \"value\": \"[\\\"cicd\\\",\\\"opendes1234\\\"]\"}, \"policy-service-enabled\": {\"sensitive\": false, \"value\": \"false\"}, \"name\": {\"sensitive\": false, \"value\": \"opendes1234\"}, \"compliance-ruleset\": {\"sensitive\": false, \"value\": \"shared\"}, \"projectId\": {\"sensitive\": false, \"value\": \"osdu\"}}}"); + + Optional<Property> actualResult = repo.findByPartitionIdAndName(PARTITION_ID_VALUE, "nonExist"); + + assertFalse(actualResult.isPresent()); + } + + + private PartitionInfo buildPartitionInfo() { + PartitionInfo partitionInfo = new PartitionInfo(); + Map<String, Property> properties = new HashMap<>(); + properties.put("compliance-ruleset", new Property(true, "value")); + properties.put("dataPartitionId", new Property(false, "PartitionId")); + partitionInfo.setProperties(properties); + + return partitionInfo; + } +}