diff --git a/NOTICE b/NOTICE index 8d189b26b1794959467749f5bdbf8303df4af348..3c4b837e574a4eaa084e382f1a3fb45b089de956 100644 --- a/NOTICE +++ b/NOTICE @@ -83,6 +83,7 @@ The following software have components provided under the terms of this license: - Guava: Google Core Libraries for Java (from http://code.google.com/p/guava-libraries, https://github.com/google/guava, https://repo1.maven.org/maven2/com/google/guava/guava) - HTTP functionality for the Reactor Netty library (from https://github.com/reactor/reactor-netty) - Hibernate Validator (from https://repo1.maven.org/maven2/org/hibernate/hibernate-validator, https://repo1.maven.org/maven2/org/hibernate/validator/hibernate-validator) +- HikariCP (from https://github.com/brettwooldridge/HikariCP) - Hop (from https://github.com/rabbitmq/hop, https://www.rabbitmq.com) - HttpClient (from http://hc.apache.org/httpcomponents-client) - HttpClient Cache (from http://hc.apache.org/httpcomponents-client) @@ -131,6 +132,8 @@ The following software have components provided under the terms of this license: - KeePassJava2 :: KDB (from https://repo1.maven.org/maven2/org/linguafranca/pwdb/KeePassJava2-kdb) - KeePassJava2 :: KDBX (from https://repo1.maven.org/maven2/org/linguafranca/pwdb/KeePassJava2-kdbx) - KeePassJava2 :: Simple (from https://repo1.maven.org/maven2/org/linguafranca/pwdb/KeePassJava2-simple) +- Kotlin Stdlib (from https://kotlinlang.org/, https://repo1.maven.org/maven2/org/jetbrains/kotlin/kotlin-stdlib) +- Kotlin Stdlib Common (from https://kotlinlang.org/) - Logback Contrib :: JSON :: Classic (from https://repo1.maven.org/maven2/ch/qos/logback/contrib/logback-json-classic) - Logback Contrib :: JSON :: Core (from https://repo1.maven.org/maven2/ch/qos/logback/contrib/logback-json-core) - Logback Contrib :: Jackson (from https://repo1.maven.org/maven2/ch/qos/logback/contrib/logback-jackson) @@ -175,6 +178,7 @@ The following software have components provided under the terms of this license: - Okio (from https://github.com/square/okio/, https://repo1.maven.org/maven2/com/squareup/okio/okio) - OpenCensus (from https://github.com/census-instrumentation/opencensus-java) - PWDB :: Database (from https://repo1.maven.org/maven2/org/linguafranca/pwdb/database) +- PostgreSQL JDBC Driver - PowerMock (from http://www.powermock.org, https://repo1.maven.org/maven2/org/powermock/powermock-api-mockito) - Protocol Buffer extensions to the Google HTTP Client Library for Java. (from https://repo1.maven.org/maven2/com/google/http-client/google-http-client-protobuf) - Proton-J (from https://repo1.maven.org/maven2/org/apache/qpid/proton-j) @@ -182,6 +186,7 @@ The following software have components provided under the terms of this license: - RabbitMQ Java Client (from http://www.rabbitmq.com, https://www.rabbitmq.com) - Reactive Streams Netty driver (from https://github.com/reactor/reactor-netty) - Retrofit (from https://github.com/square/retrofit, https://repo1.maven.org/maven2/com/squareup/retrofit2/retrofit) +- Simple XML (safe) (from https://github.com/dweiss/simplexml) - SnakeYAML (from http://code.google.com/p/snakeyaml/, http://www.snakeyaml.org) - Spring AMQP Core (from http://www.springsource.org/spring-amqp, https://github.com/spring-projects/spring-amqp, https://projects.spring.io/spring-amqp) - Spring AOP (from http://www.springframework.org, https://github.com/spring-projects/spring-framework, https://repo1.maven.org/maven2/org/springframework/spring-aop) @@ -194,6 +199,7 @@ The following software have components provided under the terms of this license: - Spring Boot Actuator Starter (from http://projects.spring.io/spring-boot/, https://projects.spring.io/spring-boot/#/spring-boot-parent/spring-boot-starters/spring-boot-starter-actuator, https://spring.io/projects/spring-boot) - Spring Boot AutoConfigure (from http://projects.spring.io/spring-boot/, https://projects.spring.io/spring-boot/#/spring-boot-parent/spring-boot-autoconfigure, https://spring.io/projects/spring-boot) - Spring Boot Dependencies (from http://projects.spring.io/spring-boot/, https://spring.io/projects/spring-boot) +- Spring Boot JDBC Starter (from http://projects.spring.io/spring-boot/, https://spring.io/projects/spring-boot) - Spring Boot Json Starter (from https://projects.spring.io/spring-boot/#/spring-boot-parent/spring-boot-starters/spring-boot-starter-json, https://spring.io/projects/spring-boot) - Spring Boot Log4j 2 Starter (from http://projects.spring.io/spring-boot/, https://projects.spring.io/spring-boot/#/spring-boot-parent/spring-boot-starters/spring-boot-starter-log4j2, https://spring.io/projects/spring-boot) - Spring Boot Logging Starter (from http://projects.spring.io/spring-boot/, https://projects.spring.io/spring-boot/#/spring-boot-parent/spring-boot-starters/spring-boot-starter-logging, https://spring.io/projects/spring-boot) @@ -264,6 +270,7 @@ The following software have components provided under the terms of this license: - lettuce (from http://github.com/mp911de/lettuce/wiki, https://github.com/lettuce-io/lettuce-core/wiki) - micrometer-core (from https://github.com/micrometer-metrics/micrometer) - micrometer-registry-azure-monitor (from https://github.com/micrometer-metrics/micrometer) +- minio (from https://github.com/minio/minio-java) - org.apiguardian:apiguardian-api (from https://github.com/apiguardian-team/apiguardian) - org.conscrypt:conscrypt-openjdk-uber (from https://conscrypt.org/) - org.opentest4j:opentest4j (from https://github.com/ota4j-team/opentest4j) @@ -280,6 +287,7 @@ The following software have components provided under the terms of this license: - proto-google-iam-v1 (from https://github.com/googleapis/googleapis, https://github.com/googleapis/java-iam/proto-google-iam-v1) - resilience4j (from https://github.com/resilience4j/resilience4j, https://resilience4j.readme.io, ttps://resilience4j.readme.io) - rxjava (from https://github.com/ReactiveX/RxJava) +- spring-jdbc (from https://repo1.maven.org/maven2/org/springframework/spring-jdbc) - springfox-bean-validators (from https://github.com/springfox/springfox) - springfox-boot-starter (from https://github.com/springfox/springfox) - springfox-core (from https://github.com/springfox/springfox) @@ -311,6 +319,7 @@ The following software have components provided under the terms of this license: - Hamcrest (from http://hamcrest.org/JavaHamcrest/) - Hamcrest Core (from https://repo1.maven.org/maven2/org/hamcrest/hamcrest-core) - HdrHistogram (from http://hdrhistogram.github.io/HdrHistogram/) +- PostgreSQL JDBC Driver - Reflections (from http://code.google.com/p/reflections/, http://github.com/ronmamo/reflections) - Stax2 API (from http://github.com/FasterXML/stax2-api) - ThreeTen backport (from https://github.com/ThreeTen/threetenbp, https://www.threeten.org/threetenbp) @@ -341,6 +350,7 @@ The following software have components provided under the terms of this license: - Mockito (from http://mockito.org, http://www.mockito.org, https://github.com/mockito/mockito) - Netty/Codec/HTTP (from https://repo1.maven.org/maven2/io/netty/netty-codec-http) - Netty/Transport/Classes/KQueue (from https://repo1.maven.org/maven2/io/netty/netty-transport-classes-kqueue) +- PostgreSQL JDBC Driver - Protocol Buffer Java API (from http://code.google.com/p/protobuf, https://repo1.maven.org/maven2/com/google/protobuf/protobuf-java) - Protocol Buffers [Util] (from https://repo1.maven.org/maven2/com/google/protobuf/protobuf-java-util) - Reflections (from http://code.google.com/p/reflections/, http://github.com/ronmamo/reflections) @@ -567,6 +577,7 @@ The following software have components provided under the terms of this license: - Azure Java Client Runtime for ARM (from https://github.com/Azure/autorest-clientruntime-for-java) - Azure Java Client Runtime for AutoRest (from https://github.com/Azure/autorest-clientruntime-for-java) - Azure Spring Boot AutoConfigure (from https://github.com/Azure/azure-sdk-for-java) +- Bouncy Castle Provider (from http://www.bouncycastle.org/java.html, https://www.bouncycastle.org/java.html) - Checker Qual (from https://checkerframework.org) - ClassGraph (from https://github.com/classgraph/classgraph) - Extensions on Apache Proton-J library (from https://github.com/Azure/qpid-proton-j-extensions) @@ -663,6 +674,7 @@ The following software have components provided under the terms of this license: - Apache Groovy (from http://groovy-lang.org, http://groovy.codehaus.org/, https://groovy-lang.org) - Asynchronous Http Client (from https://repo1.maven.org/maven2/org/asynchttpclient/async-http-client) +- Bouncy Castle Provider (from http://www.bouncycastle.org/java.html, https://www.bouncycastle.org/java.html) - Guava: Google Core Libraries for Java (from http://code.google.com/p/guava-libraries, https://github.com/google/guava, https://repo1.maven.org/maven2/com/google/guava/guava) - HdrHistogram (from http://hdrhistogram.github.io/HdrHistogram/) - Joda-Time (from http://joda-time.sourceforge.net, http://www.joda.org/joda-time/, https://www.joda.org/joda-time/) @@ -671,6 +683,7 @@ The following software have components provided under the terms of this license: - Microsoft Azure SDK for EventGrid Management (from https://github.com/Azure/azure-sdk-for-java) - Microsoft Azure SDK for SQL API of Azure Cosmos DB Service (from https://github.com/Azure/azure-sdk-for-java) - Microsoft Azure client library for Blob Storage (from https://github.com/Azure/azure-sdk-for-java) +- PostgreSQL JDBC Driver - Project Lombok (from http://projectlombok.org, https://projectlombok.org) - RabbitMQ Java Client (from http://www.rabbitmq.com, https://www.rabbitmq.com) - Spring Web (from http://www.springframework.org, https://github.com/spring-projects/spring-framework, https://repo1.maven.org/maven2/org/springframework/spring-web) @@ -683,6 +696,7 @@ unknown ======================================================================== The following software have components provided under the terms of this license: +- Bouncy Castle Provider (from http://www.bouncycastle.org/java.html, https://www.bouncycastle.org/java.html) - Byte Buddy (without dependencies) (from https://repo1.maven.org/maven2/net/bytebuddy/byte-buddy) - Checker Qual (from https://checkerframework.org) - JSON in Java (from https://github.com/douglascrockford/JSON-java) diff --git a/devops/gcp/configmap/templates/notification-configmap.yaml b/devops/gcp/configmap/templates/notification-configmap.yaml index 1c1ce1b79705a62cb36a1ab3db469f0b7e2347fc..61d38f0870287d300f923a4282ab9e86f52b2e86 100644 --- a/devops/gcp/configmap/templates/notification-configmap.yaml +++ b/devops/gcp/configmap/templates/notification-configmap.yaml @@ -10,6 +10,7 @@ data: APP_PROJECT: "{{ .Values.data.app_project }}" APP_ENTITLEMENTS: "{{ .Values.data.app_entitlements }}" APP_REGISTER: "{{ .Values.data.app_register }}" - APP_GOOGLEAUDIENCE: "{{ .Values.data.app_googleaudience }}" PARTITION_API: "{{ .Values.data.partition_api }}" GOOGLE_AUDIENCES: "{{ .Values.data.google_audiences }}" + SERVICE_TOKEN_PROVIDER: "{{ .Values.data.token_provider }}" + PARTITION_AUTH_ENABLED: "{{ .Values.data.partition_auth_enabled }}" diff --git a/devops/gcp/configmap/values.yaml b/devops/gcp/configmap/values.yaml index 36510b00e6b14022d3a4b1daf3b376c700bb9752..129e9d1c3ff24a3266e17f184d7b70d1e39281eb 100644 --- a/devops/gcp/configmap/values.yaml +++ b/devops/gcp/configmap/values.yaml @@ -3,9 +3,10 @@ data: app_project: "" app_entitlements: "http://entitlements/api/entitlements/v2/" app_register: "http://register/api/register/v1" - app_googleaudience: "" partition_api: "http://partition/api/partition/v1/" google_audiences: "" + token_provider: "GCP" + partition_auth_enabled: "true" conf: configmap: "notification-config" app_name: "notification" diff --git a/provider/notification-gcp/README.md b/provider/notification-gcp/README.md index 3f73c6807b45196421132241c087fd9690ae5d82..ba9b8b9f35ce64f29320ddfcf810a37ec95e0bb6 100644 --- a/provider/notification-gcp/README.md +++ b/provider/notification-gcp/README.md @@ -1,225 +1,49 @@ # Notification Service notification-gcp is a [Spring Boot](https://spring.io/projects/spring-boot) service that allow for interested consumers to subscribe to data and metadata changes using a publish/subscriber pattern. +## Table of Contents <a name="TOC"></a> +* [Getting started](#Getting-started) +* [Mappers](#Mappers) +* [Settings and Configuration](#Settings-and-Configuration) +* [Run service](#Run-service) +* [Testing](#Testing) +* [Tutorial](#Tutorial) +* [Licence](#License) + ## 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. -# Features of implementation +## Mappers This is a universal solution created using EPAM OQM mapper technology. It allows you to work with various implementations of message brokers. -## Limitations of the current version +For more information about mappers: +- [OQM Readme](https://community.opengroup.org/osdu/platform/system/lib/cloud/gcp/oqm/-/blob/master/README.md) In the current version, the OQM mapper is equipped with 2 drivers to the message brokers: - -- Google PubSub; +- Google PubSub; - RabbitMQ -## Extensibility - -To use any other message broker, implement a driver for it. With an extensible set of drivers, the solution is unrestrictedly universal and portable without modification to the main code. - -Mapper support "multitenancy" with flexibility in how it is implemented. -It switches between datasources of different tenants due to the work of a bunch of classes that implement the following interfaces: - -- Destination - takes a description of the current context, e.g., "data-partition-id = opendes" -- DestinationResolver – accepts Destination, finds the resource, connects, and returns Resolution -- DestinationResolution – contains a ready-made connection, the mapper uses it to get to data - -# Settings and Configuration -## Requirements -### Mandatory -* Java 8 -* [Maven 3.6.0+](https://maven.apache.org/download.cgi) - -### for Google Cloud only -* GCloud command line tool -* GCloud access to opendes project - -## General Tips - -**Environment Variable Management** -The following tools make environment variable configuration simpler - - [direnv](https://direnv.net/) - for a shell/terminal environment - - [EnvFile](https://plugins.jetbrains.com/plugin/7861-envfile) - for [Intellij IDEA](https://www.jetbrains.com/idea/) - -**Lombok** -This project uses [Lombok](https://projectlombok.org/) for code generation. You may need to configure your IDE to take advantage of this tool. - - [Intellij configuration](https://projectlombok.org/setup/intellij) - - [VSCode configuration](https://projectlombok.org/setup/vscode) - -## Mapper tuning mechanisms - -This service uses specific implementation of DestinationResolver based on the tenant information provided by the OSDU Partition service. -A total of 2 resolvers are implemented, which are divided into two groups: -### for universal technologies: -- for RabbitMQ: mappers/oqm/MqTenantOqmDestinationResolver.java - -#### Their algorithms are as follows: -- incoming Destination carries data-partition-id -- resolver accesses the Partition service and gets PartitionInfo -- from PartitionInfo resolver retrieves properties for the connection: URL, username, password etc. -- resolver creates a data source, connects to the resource, remembers the datasource -- resolver gives the datasource to the mapper in the Resolution object +## Settings and Configuration -### for native Google Cloud technologies: -- for PubSub: mappers/oqm/PsTenantOqmDestinationResolver.java +#### Requirements -#### Their algorithms are similar, -Except that they do not receive special properties from the Partition service for connection, because the location of the resources is unambiguously known - they are in the GCP project. And credentials are also not needed - access to data is made on behalf of the Google Identity SA under which the service itself is launched. Therefore, resolver takes only the value of the **projectId** property from PartitionInfo and uses it to connect to a resource in the corresponding GCP project. +1. Mandatory + - Java 8 + -[Maven 3.6.0+](https://maven.apache.org/download.cgi) -# Configuration +2. For Google Cloud only + - GCloud command line tool + - GCloud access to opendes project -## Service Configuration -In order to run the service locally or remotely, define the following environment variables. -Most of them are common to all hosting environments, but there are properties that are only necessary when running in Google Cloud. +### Anthos Service Configuration: +[Anthos service configuration ](docs/anthos/README.md) +### GCP Service Configuration: +[Gcp service configuration ](docs/gcp/README.md) -#### Common properties for all environments +## Run service -| name | value | description | sensitive? | source | -| --- | --- | --- | --- | --- | -| `APP_ENTITLEMENTS` | ex `https://entitlements.com/entitlements/v1` | Entitlements API endpoint | no | output of infrastructure deployment | -| `APP_REGISTER` | ex `https://register.com/api/register/v1` | Storage API endpoint | no | output of infrastructure deployment | -| `PARTITION_API` | ex `http://localhost:8081/api/partition/v1` | Partition service endpoint | no | - | - -#### For Mappers, to activate drivers - -| name | value | description | -|-----------|-----------|-----------------------------------------------------| -| OQMDRIVER | pubsub | to activate **OQM** driver for **Google PubSub** | -| OQMDRIVER | rabbitmq | to activate **OQM** driver for **Rabbit MQ** | - -#### For Google Cloud only -| name | value | description | sensitive? | source | -|------------------------------|---------------------------------------|--------------------------------------------------------------------|------------|---------------------------------------------------| -| `APP_PROJECT` | ex `opendes` | Google Cloud Project Id | no | output of infrastructure deployment | -| `APP_AUDIENCES` | ex `*****.apps.googleusercontent.com` | Client ID for getting access to cloud resources | yes | https://console.cloud.google.com/apis/credentials | - -##### service account IAM roles -Also, the following IAM roles should be assigned to the service's Google service account (SA) - -| IAM role | The purpose | -|----------|-------------------------------------------------------------------------------| -| Service Account Token Creator | To write yourself JWT for requesting neighbor microservices | -| Pub/Sub Editor | To fetch available PubSub topics and subscriptions and be able to create them | - - - -**System Environment required to run service** - -| name | value | description | sensitive? | source | -| --- | --- | --- | --- | --- | -| `SPRING_PROFILES_ACTIVE` | `local` | spring active profile | no | - -## Configuring mappers Datasources -When using non-Google-Cloud-native technologies, property sets must be defined on the Partition service as part of PartitionInfo for each Tenant. - -#### for OQM - RabbitMQ: -**prefix:** `oqm.rabbitmq` -It can be overridden by: - -- through the Spring Boot property `oqm.rabbitmq.partitionPropertiesPrefix` -- environment variable `OQM_RABBITMQ_PARTITIONPROPERTIESPREFIX` - -**Propertyset** (for two types of connection: messaging and admin operations): - -| Property | Description | -| --- | --- | -| oqm.rabbitmq.amqp.host | messaging hostnameorIP | -| oqm.rabbitmq.amqp.port | - port | -| oqm.rabbitmq.amqp.path | - path | -| oqm.rabbitmq.amqp.username | - username | -| oqm.rabbitmq.amqp.password | - password | -| oqm.rabbitmq.admin.schema | admin host schema | -| oqm.rabbitmq.admin.host | - host name | -| oqm.rabbitmq.admin.port | - port | -| oqm.rabbitmq.admin.path | - path | -| oqm.rabbitmq.admin.username | - username | -| oqm.rabbitmq.admin.password | - password | - -<details><summary>Example of a single tenant definition</summary> - -``` - -curl -L -X PATCH 'https://dev.osdu.club/api/partition/v1/partitions/opendes' -H 'data-partition-id: opendes' -H 'Authorization: Bearer ...' -H 'Content-Type: application/json' --data-raw '{ - "properties": { - "oqm.rabbitmq.amqp.host": { - "sensitive": false, - "value": "localhost" - }, - "oqm.rabbitmq.amqp.port": { - "sensitive": false, - "value": "5672" - }, - "oqm.rabbitmq.amqp.path": { - "sensitive": false, - "value": "" - }, - "oqm.rabbitmq.amqp.username": { - "sensitive": false, - "value": "guest" - }, - "oqm.rabbitmq.amqp.password": { - "sensitive": true, - "value": "guest" - }, - - "oqm.rabbitmq.admin.schema": { - "sensitive": false, - "value": "http" - }, - "oqm.rabbitmq.admin.host": { - "sensitive": false, - "value": "localhost" - }, - "oqm.rabbitmq.admin.port": { - "sensitive": false, - "value": "9002" - }, - "oqm.rabbitmq.admin.path": { - "sensitive": false, - "value": "/api" - }, - "oqm.rabbitmq.admin.username": { - "sensitive": false, - "value": "guest" - }, - "oqm.rabbitmq.admin.password": { - "sensitive": true, - "value": "guest" - } - } -}' - -``` - -</details> - -## Interaction with message brokers - -### Specifics of work through PULL subscription - -To receive messages from brokers, this solution uses the PULL-subscriber mechanism in the Notification service. -This is its cardinal difference from other implementations that use PUSH-subscribers (webhooks). -This opens a wide choice when choosing brokers. - -When using PULL-subscribers, there is a need to restore Notification service subscribers for each Subscription -at the start of Notification service, as well as in the runtime, -upon registration of a new Subscription by the Register service. - -To do this, a special "command" topic is involved: - -- the default topic name is `register-subscriber-control`. - -If necessary, the name of the topic can be overridden through: - -- Spring Boot property `oqm.registerSubscriberControlTopicName` -- environment variable `OQM_REGISTERSUBSCRIBERCONTROLTOPICNAME` - -A topic is created, in its absence, when any of Register or Notification services starts. - -# Run and test the service -## Running Locally +### Running Locally Check that maven is installed: ```bash $ mvn --version @@ -298,7 +122,7 @@ Navigate to notification service's root folder and run all the tests: $ (cd notification-core/ && mvn clean install) ``` -## Test the application +### Test the application After the service has started it should be accessible via a web browser by visiting [http://localhost:8080/api/notification/v1/swagger-ui.html](http://localhost:8080/swagger-ui.html). If the request does not fail, you can then run the integration tests. @@ -340,6 +164,18 @@ Above variables should be configured in the release pipeline to run integration # above are already exported in your environment. $ (cd testing/notification-test-gcp/ && mvn clean test) ``` + +## Tutorial + +- [Notification OpenAPI specification ](../../docs/api/notification_openapi.yaml) +- [Notification tutorial ](../../docs/tutorial/DataNotification.md) + +## Entitlements groups +Notification service account should have entitlements groups listed below: +- users +- users.datalake.editors +- service.entitlements.user + ## License Copyright © Google LLC diff --git a/provider/notification-gcp/docs/anthos/README.md b/provider/notification-gcp/docs/anthos/README.md new file mode 100644 index 0000000000000000000000000000000000000000..a1de38b5410036b50ae5caa57e785d2686984b00 --- /dev/null +++ b/provider/notification-gcp/docs/anthos/README.md @@ -0,0 +1,175 @@ +# Service Configuration for Anthos + +## Table of Contents <a name="TOC"></a> +* [Environment variables](#Environment-variables) + * [Common properties for all environments](#Common-properties-for-all-environments) + * [For Mappers to activate drivers](#For-Mappers-to-activate-drivers) +* [Requirements for requests](#Requirements-for-requests) +* [Configuring mappers Datasources](#Configuring-mappers-Datasources) + * [For OQM RabbitMQ](#For-OQM-RabbitMQ) + * [Exchanges and queues configuration](#Exchanges-and-queues-configuration) +* [Interaction with message brokers](#Interaction-with-message-brokers) +* [Keycloak configuration](#Keycloak-configuration) + +## Environment variables + +### Common properties for all environments + +| name | value | description | sensitive? | source | +| --- | --- | --- | --- | --- | +| `APP_ENTITLEMENTS` | ex `https://entitlements.com/entitlements/v1` | Entitlements API endpoint | no | output of infrastructure deployment | +| `APP_REGISTER` | ex `https://register.com/api/register/v1` | Storage API endpoint | no | output of infrastructure deployment | +| `APP_PROJECT` | ex `opendes` | Google Cloud Project Id | no | output of infrastructure deployment | +| `PARTITION_API` | ex `http://localhost:8081/api/partition/v1` | Partition service endpoint | no | - | +| `SERVICE_TOKEN_PROVIDER` | ex `GCP` or `OPENID` | Service token provider | no | - | + +**System Environment required to run service** + +| name | value | description | sensitive? | source | +| --- | --- | --- | --- | --- | +| `SPRING_PROFILES_ACTIVE` | `anthos` | spring active profile | no | + +### For Mappers to activate drivers + +| name | value | description | +|-----------|-----------|---------------------------------------------------------| +| OQMDRIVER | pubsub | to activate **OQM** driver for **Google PubSub** | +| OQMDRIVER | rabbitmq | to activate **OQM** driver for **Rabbit MQ** | + +## Requirements for requests + +Record identifiers cannot contain a space character. At the same time, they may contain a % character, which, when +combined with subsequent numeric characters, may cause the application to misinterpret that combination. For example, +the "%20" combination will be interpreted as a space " " character. To correctly transfer such an identifier, you should +additionally perform the url-encode operation on it. This functionality can be built into the front-end application, or +you can use an online url-encoder tool ( eg.: https://www.urlencoder.org/). Thus, having ID "osdu: +work-product-component--WellboreMarkerSet:3D%20Kirchhoff%20DepthMigration" (with %20 combination) +you should url-encode it and request +"osdu%3Awork-product-component--WellboreMarkerSet%3A3D%2520Kirchhoff%2520DepthMigration" instead. + +## Configuring mappers Datasources + +When using non-Google-Cloud-native technologies, property sets must be defined on the Partition service as part of +PartitionInfo for each Tenant. + +### For OQM RabbitMQ + +**prefix:** `oqm.rabbitmq` +It can be overridden by: + +- through the Spring Boot property `oqm.rabbitmq.partition-properties-prefix` +- environment variable `OQM_RABBITMQ_PARTITION_PROPERTIES_PREFIX`` + +**Propertyset** (for two types of connection: messaging and admin operations): + +| Property | Description | +| --- | --- | +| oqm.rabbitmq.amqp.host | messaging hostnameorIP | +| oqm.rabbitmq.amqp.port | - port | +| oqm.rabbitmq.amqp.path | - path | +| oqm.rabbitmq.amqp.username | - username | +| oqm.rabbitmq.amqp.password | - password | +| oqm.rabbitmq.admin.schema | admin host schema | +| oqm.rabbitmq.admin.host | - host name | +| oqm.rabbitmq.admin.port | - port | +| oqm.rabbitmq.admin.path | - path | +| oqm.rabbitmq.admin.username | - username | +| oqm.rabbitmq.admin.password | - password | + +<details><summary>Example of a single tenant definition</summary> + +``` + +curl -L -X PATCH 'https://dev.osdu.club/api/partition/v1/partitions/opendes' -H 'data-partition-id: opendes' -H 'Authorization: Bearer ...' -H 'Content-Type: application/json' --data-raw '{ + "properties": { + "oqm.rabbitmq.amqp.host": { + "sensitive": false, + "value": "localhost" + }, + "oqm.rabbitmq.amqp.port": { + "sensitive": false, + "value": "5672" + }, + "oqm.rabbitmq.amqp.path": { + "sensitive": false, + "value": "" + }, + "oqm.rabbitmq.amqp.username": { + "sensitive": false, + "value": "guest" + }, + "oqm.rabbitmq.amqp.password": { + "sensitive": true, + "value": "guest" + }, + + "oqm.rabbitmq.admin.schema": { + "sensitive": false, + "value": "http" + }, + "oqm.rabbitmq.admin.host": { + "sensitive": false, + "value": "localhost" + }, + "oqm.rabbitmq.admin.port": { + "sensitive": false, + "value": "9002" + }, + "oqm.rabbitmq.admin.path": { + "sensitive": false, + "value": "/api" + }, + "oqm.rabbitmq.admin.username": { + "sensitive": false, + "value": "guest" + }, + "oqm.rabbitmq.admin.password": { + "sensitive": true, + "value": "guest" + } + } +}' + +``` + +</details> + +#### Exchanges and queues configuration + +At RabbitMq should be created exchange with name: + +**name:** `register-subscriber-control` + +It can be overridden by: + +- through the Spring Boot property `oqm-register-subscriber-control-topic-name` +- environment variable `OQM_REGISTER_SUBSCRIBER_CONTROL_TOPIC_NAME` + + + +## Interaction with message brokers + +### Specifics of work through PULL subscription + +To receive messages from brokers, this solution uses the PULL-subscriber mechanism to get 'record_changed' messages. +This is its cardinal difference from other implementations that use PUSH-subscribers (webhooks). This opens a wide +choice when choosing brokers. + +When using PULL-subscribers, there is a need to restore Storage service subscribers at the start of Storage service. +This magic happens in the `OqmSubscriberManager.java` class from `core-lib-gcp` in the @PostConstruct method. + +## Keycloak configuration + +[Keycloak service accounts setup](https://www.keycloak.org/docs/latest/server_admin/#_service_accounts) + +Configure Clients. One Client per OSDU service. Set them “confidentialâ€. + + + +Each Client has embedded Service Account (SA) option. Enable SAs for Clients, make “Authorization enabledâ€: + + + +Add `partition-and-entitlements` scope to `Default Client Scopes` and generate Keys. + +Give `client-id` and `client-secret` to services, which should be authorized within the platform. \ No newline at end of file diff --git a/provider/notification-gcp/docs/anthos/pics/client.png b/provider/notification-gcp/docs/anthos/pics/client.png new file mode 100644 index 0000000000000000000000000000000000000000..8a2014e672b65ddf644558e2c9e8cb8823f549dd Binary files /dev/null and b/provider/notification-gcp/docs/anthos/pics/client.png differ diff --git a/provider/notification-gcp/docs/anthos/pics/rabbit.PNG b/provider/notification-gcp/docs/anthos/pics/rabbit.PNG new file mode 100644 index 0000000000000000000000000000000000000000..e1c67734b91a536659fdf0b940a93208d749e3c8 Binary files /dev/null and b/provider/notification-gcp/docs/anthos/pics/rabbit.PNG differ diff --git a/provider/notification-gcp/docs/anthos/pics/sa.png b/provider/notification-gcp/docs/anthos/pics/sa.png new file mode 100644 index 0000000000000000000000000000000000000000..b9c8124047b5834a2cf79baecbf751dc106feeff Binary files /dev/null and b/provider/notification-gcp/docs/anthos/pics/sa.png differ diff --git a/provider/notification-gcp/docs/gcp/README.md b/provider/notification-gcp/docs/gcp/README.md new file mode 100644 index 0000000000000000000000000000000000000000..a40859ab10fe2d8387dc2c571118ea81d8927774 --- /dev/null +++ b/provider/notification-gcp/docs/gcp/README.md @@ -0,0 +1,60 @@ +# Service Configuration for GCP + +## Table of Contents <a name="TOC"></a> +* [Environment variables](#Environment-variables) +* [Common properties for all environments](#Common-properties-for-all-environments) +* [For Mappers to activate drivers](#For-Mappers-to-activate-drivers) +* [For Google Cloud only](#For-Google-Cloud-only) +* [GCS configuration](#GCS-configuration) +* [Google cloud service account configuration](#Google-cloud-service-account-configuration) + +## Environment variables + +### Common properties for all environments + +| name | value | description | sensitive? | source | +| --- | --- | --- | --- | --- | +| `APP_ENTITLEMENTS` | ex `https://entitlements.com/entitlements/v1` | Entitlements API endpoint | no | output of infrastructure deployment | +| `APP_REGISTER` | ex `https://register.com/api/register/v1` | Storage API endpoint | no | output of infrastructure deployment | +| `APP_PROJECT` | ex `opendes` | Google Cloud Project Id | no | output of infrastructure deployment | +| `PARTITION_API` | ex `http://localhost:8081/api/partition/v1` | Partition service endpoint | no | - | +| `SERVICE_TOKEN_PROVIDER` | ex `GCP` or `OPENID` | Service token provider | no | - | + +**System Environment required to run service** + +| name | value | description | sensitive? | source | +| --- | --- | --- | --- | --- | +| `SPRING_PROFILES_ACTIVE` | `gcp` | spring active profile | no | + +### For Mappers to activate drivers + +| name | value | description | +|-----------|-----------|---------------------------------------------------------| +| OQMDRIVER | pubsub | to activate **OQM** driver for **Google PubSub** | +| OQMDRIVER | rabbitmq | to activate **OQM** driver for **Rabbit MQ** | + + +#### For Google Cloud only +| name | value | description | sensitive? | source | +|------------------------------|---------------------------------------|--------------------------------------------------------------------|------------|---------------------------------------------------| +| `APP_PROJECT` | ex `opendes` | 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 | + +##### service account IAM roles +Also, the following IAM roles should be assigned to the service's Google service account (SA) + +| IAM role | The purpose | +|----------|-------------------------------------------------------------------------------| +| Service Account Token Creator | To write yourself JWT for requesting neighbor microservices | +| Pub/Sub Editor | To fetch available PubSub topics and subscriptions and be able to create them | + +## Pubsub configuration: + +At Pubsub should be created topic with name: + +**name:** `register-subscriber-control` + +It can be overridden by: + +- through the Spring Boot property `oqm-register-subscriber-control-topic-name` +- environment variable `OQM_REGISTER_SUBSCRIBER_CONTROL_TOPIC_NAME` \ No newline at end of file diff --git a/provider/notification-gcp/docs/gcp/pics/namespace.PNG b/provider/notification-gcp/docs/gcp/pics/namespace.PNG new file mode 100644 index 0000000000000000000000000000000000000000..539d6a746febbd1787c80ec7a215f2b20bf21412 Binary files /dev/null and b/provider/notification-gcp/docs/gcp/pics/namespace.PNG differ diff --git a/provider/notification-gcp/pom.xml b/provider/notification-gcp/pom.xml index 0cf8e34d707f376aafca863bff548aa6f280b14d..fb042f28d819054bfb3ea9b981f96348f9df35f3 100644 --- a/provider/notification-gcp/pom.xml +++ b/provider/notification-gcp/pom.xml @@ -37,12 +37,6 @@ </properties> <dependencies> - <dependency> - <groupId>org.opengroup.osdu</groupId> - <artifactId>oqm</artifactId> - <version>0.13.0</version> - </dependency> - <dependency> <groupId>org.opengroup.osdu</groupId> <artifactId>os-core-common</artifactId> @@ -50,7 +44,7 @@ <dependency> <groupId>org.opengroup.osdu</groupId> <artifactId>core-lib-gcp</artifactId> - <version>0.13.0</version> + <version>0.14.0-rc1</version> </dependency> <dependency> diff --git a/provider/notification-gcp/src/main/java/org/opengroup/osdu/notification/provider/gcp/config/AppProperties.java b/provider/notification-gcp/src/main/java/org/opengroup/osdu/notification/provider/gcp/config/AppProperties.java new file mode 100644 index 0000000000000000000000000000000000000000..7f7ce4cb602714f0987157dbfb46067828af5b42 --- /dev/null +++ b/provider/notification-gcp/src/main/java/org/opengroup/osdu/notification/provider/gcp/config/AppProperties.java @@ -0,0 +1,48 @@ +/* + * Copyright 2017-2020, Schlumberger + * + * 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.notification.provider.gcp.config; + +import lombok.Getter; +import lombok.Setter; +import org.opengroup.osdu.notification.provider.interfaces.IAppProperties; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.context.annotation.Configuration; + +@Configuration +@ConfigurationProperties(prefix = "app") +@Getter +@Setter +public class AppProperties implements IAppProperties { + + private String entitlements; + private String register; + private String project; + private int expireTime; + private int maxCacheSize; + + public String getAuthorizeAPI() { + return this.entitlements; + } + + public String getRegisterAPI() { + return this.register; + } + + public String getPubSubServiceAccountEmail() { + return String.format("de-notification-service@%s.iam.gserviceaccount.com", this.project); + } +} diff --git a/provider/notification-gcp/src/main/java/org/opengroup/osdu/notification/provider/gcp/config/OqmConfigurationProperties.java b/provider/notification-gcp/src/main/java/org/opengroup/osdu/notification/provider/gcp/config/OqmConfigurationProperties.java new file mode 100644 index 0000000000000000000000000000000000000000..886e3d95d9c4a8c9c1350dc3c6367f927854d8a4 --- /dev/null +++ b/provider/notification-gcp/src/main/java/org/opengroup/osdu/notification/provider/gcp/config/OqmConfigurationProperties.java @@ -0,0 +1,33 @@ +/* + Copyright 2020 Google LLC + Copyright 2020 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.notification.provider.gcp.config; + +import lombok.Getter; +import lombok.Setter; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.context.annotation.Configuration; + +@Configuration +@ConditionalOnProperty(name = "oqmDriver") +@ConfigurationProperties(prefix = "oqm") +@Getter +@Setter +public class OqmConfigurationProperties { + private String registerSubscriberControlTopicName = "register-subscriber-control"; + private int waitingTime = 30000; +} diff --git a/provider/notification-gcp/src/main/java/org/opengroup/osdu/notification/provider/gcp/di/PartitionProviderConfig.java b/provider/notification-gcp/src/main/java/org/opengroup/osdu/notification/provider/gcp/di/PartitionProviderConfig.java deleted file mode 100644 index d051f6672b352a47e67f92bcad757fd7076799e1..0000000000000000000000000000000000000000 --- a/provider/notification-gcp/src/main/java/org/opengroup/osdu/notification/provider/gcp/di/PartitionProviderConfig.java +++ /dev/null @@ -1,33 +0,0 @@ -package org.opengroup.osdu.notification.provider.gcp.di; - -import org.opengroup.osdu.core.common.model.http.DpsHeaders; -import org.opengroup.osdu.core.common.partition.IPartitionFactory; -import org.opengroup.osdu.core.common.partition.IPartitionProvider; -import org.opengroup.osdu.core.gcp.googleidtoken.GcpServiceAccountJwtClient; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Primary; -import org.springframework.context.annotation.Scope; - -import static org.springframework.beans.factory.config.BeanDefinition.SCOPE_PROTOTYPE; -import static org.springframework.context.annotation.ScopedProxyMode.TARGET_CLASS; - -/** - * Enables partition info resolution outside of request scope - */ -@Configuration -public class PartitionProviderConfig { - - @Bean - @Primary - @Scope(value = SCOPE_PROTOTYPE, proxyMode = TARGET_CLASS) - public IPartitionProvider partitionProvider( - IPartitionFactory partitionFactory, - GcpServiceAccountJwtClient jwtClient - ) { - DpsHeaders partitionHeaders = new DpsHeaders(); - String idToken = jwtClient.getDefaultOrInjectedServiceAccountIdToken(); - partitionHeaders.put("authorization", idToken); - return partitionFactory.create(partitionHeaders); - } -} \ No newline at end of file diff --git a/provider/notification-gcp/src/main/java/org/opengroup/osdu/notification/provider/gcp/di/ServiceAccountJwtClientFactory.java b/provider/notification-gcp/src/main/java/org/opengroup/osdu/notification/provider/gcp/di/ServiceAccountJwtClientFactory.java deleted file mode 100644 index ad4a541f081362e8a46fdb84e5af5dcb6a13e381..0000000000000000000000000000000000000000 --- a/provider/notification-gcp/src/main/java/org/opengroup/osdu/notification/provider/gcp/di/ServiceAccountJwtClientFactory.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright 2017-2020, Schlumberger - * - * 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.notification.provider.gcp.di; -import org.opengroup.osdu.core.common.util.IServiceAccountJwtClient; -import org.opengroup.osdu.notification.provider.gcp.util.AppProperties; -import org.opengroup.osdu.notification.provider.gcp.util.ServiceAccountJwtGcpClientImpl; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.config.AbstractFactoryBean; -import org.springframework.context.annotation.Primary; -import org.springframework.stereotype.Component; - -@Component -@Primary -public class ServiceAccountJwtClientFactory extends AbstractFactoryBean<IServiceAccountJwtClient> { - - @Autowired - private AppProperties config; - - @Override - public IServiceAccountJwtClient createInstance() throws Exception { - return new ServiceAccountJwtGcpClientImpl(config); - } - - @Override - public Class<?> getObjectType() { - return IServiceAccountJwtClient.class; - } -} diff --git a/provider/notification-gcp/src/main/java/org/opengroup/osdu/notification/provider/gcp/mappers/oqm/MqOqmConfigurationProperties.java b/provider/notification-gcp/src/main/java/org/opengroup/osdu/notification/provider/gcp/mappers/oqm/MqOqmConfigurationProperties.java deleted file mode 100644 index f87188a274c46790734eb1da4375d1c2d6c5d2a5..0000000000000000000000000000000000000000 --- a/provider/notification-gcp/src/main/java/org/opengroup/osdu/notification/provider/gcp/mappers/oqm/MqOqmConfigurationProperties.java +++ /dev/null @@ -1,34 +0,0 @@ -/* - Copyright 2020 Google LLC - Copyright 2020 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.notification.provider.gcp.mappers.oqm; - -import lombok.Getter; -import lombok.Setter; -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; -import org.springframework.boot.context.properties.ConfigurationProperties; -import org.springframework.context.annotation.Configuration; - -@Configuration -@ConditionalOnProperty(name = "oqmDriver", havingValue = "rabbitmq") -@ConfigurationProperties(prefix = "oqm.rabbitmq") -@Getter -@Setter -public class MqOqmConfigurationProperties { - - private String partitionPropertiesPrefix = "oqm.rabbitmq"; - -} diff --git a/provider/notification-gcp/src/main/java/org/opengroup/osdu/notification/provider/gcp/mappers/oqm/MqTenantOqmDestinationResolver.java b/provider/notification-gcp/src/main/java/org/opengroup/osdu/notification/provider/gcp/mappers/oqm/MqTenantOqmDestinationResolver.java deleted file mode 100644 index c8da3f492875c162f68c1884e01724dcd0ba6c57..0000000000000000000000000000000000000000 --- a/provider/notification-gcp/src/main/java/org/opengroup/osdu/notification/provider/gcp/mappers/oqm/MqTenantOqmDestinationResolver.java +++ /dev/null @@ -1,165 +0,0 @@ -/* - Copyright 2020 Google LLC - Copyright 2020 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.notification.provider.gcp.mappers.oqm; - -import com.rabbitmq.client.ConnectionFactory; -import com.rabbitmq.http.client.Client; -import com.rabbitmq.http.client.ClientParameters; -import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; -import org.opengroup.osdu.core.common.partition.IPartitionProvider; -import org.opengroup.osdu.core.common.partition.PartitionException; -import org.opengroup.osdu.core.common.partition.PartitionInfo; -import org.opengroup.osdu.core.common.partition.Property; -import org.opengroup.osdu.core.gcp.oqm.driver.OqmDriverRuntimeException; -import org.opengroup.osdu.core.gcp.oqm.driver.rabbitmq.MqOqmDestinationResolution; -import org.opengroup.osdu.core.gcp.oqm.model.OqmDestination; -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; -import org.springframework.context.annotation.Scope; -import org.springframework.stereotype.Component; - -import javax.annotation.PreDestroy; -import java.net.MalformedURLException; -import java.net.URI; -import java.net.URISyntaxException; -import java.security.KeyManagementException; -import java.security.NoSuchAlgorithmException; -import java.util.HashMap; -import java.util.Map; -import java.util.Optional; - -import static org.springframework.beans.factory.config.BeanDefinition.SCOPE_SINGLETON; - -/** - * For RabbitMQ. Tenant Based OQM destination resolver - */ -@Component -@Scope(SCOPE_SINGLETON) -@ConditionalOnProperty(name = "oqmDriver", havingValue = "rabbitmq") -@RequiredArgsConstructor -@Slf4j -public class MqTenantOqmDestinationResolver implements org.opengroup.osdu.core.gcp.oqm.driver.rabbitmq.MqOqmDestinationResolver { - - private final MqOqmConfigurationProperties properties; - - //Compose names to get configuration properties from Partition - private static final String AMQP = ".amqp."; - private static final String AMQP_HOST = AMQP.concat("host"); - private static final String AMQP_PORT = AMQP.concat("port"); - private static final String AMQP_PATH = AMQP.concat("path"); - private static final String AMQP_USERNAME = AMQP.concat("username"); - private static final String AMQP_PASSWORD = AMQP.concat("password"); - - private static final String ADMIN = ".admin."; - private static final String ADMIN_SCHEMA = ADMIN.concat("schema"); - private static final String ADMIN_HOST = ADMIN.concat("host"); - private static final String ADMIN_PORT = ADMIN.concat("port"); - private static final String ADMIN_PATH = ADMIN.concat("path"); - private static final String ADMIN_USERNAME = ADMIN.concat("username"); - private static final String ADMIN_PASSWORD = ADMIN.concat("password"); - - private final IPartitionProvider partitionProvider; - - private final Map<String, ConnectionFactory> amqpConnectionFactoryCache = new HashMap<>(); - private final Map<String, Client> httpClientCache = new HashMap<>(); - - @Override - public MqOqmDestinationResolution resolve(OqmDestination destination) { - - String partitionId = destination.getPartitionId(); - - //noinspection SwitchStatementWithTooFewBranches - switch (partitionId) { - default: - - String virtualHost = "/"; - - ConnectionFactory amqpFactory = amqpConnectionFactoryCache.get(partitionId); - Client httpClient = httpClientCache.get(partitionId); - - if (amqpFactory == null || httpClient == null) { - - PartitionInfo partitionInfo; - try { - partitionInfo = partitionProvider.get(partitionId); - } catch (PartitionException e) { - throw new OqmDriverRuntimeException(e, "Partition '%s' destination resolution issue", destination.getPartitionId()); - } - Map<String, Property> partitionProperties = partitionInfo.getProperties(); - - if (amqpFactory == null) { - - String amqpHost = getPartitionProperty(partitionId, partitionProperties, AMQP_HOST); - String amqpPort = getPartitionProperty(partitionId, partitionProperties, AMQP_PORT); - String amqpPath = getPartitionProperty(partitionId, partitionProperties, AMQP_PATH); - String amqpUser = getPartitionProperty(partitionId, partitionProperties, AMQP_USERNAME); - String amqpPass = getPartitionProperty(partitionId, partitionProperties, AMQP_PASSWORD); - - URI amqpUri; - try { - amqpUri = new URI("amqp", amqpUser + ":" + amqpPass, amqpHost, Integer.parseInt(amqpPort), amqpPath, null, null); - amqpFactory = new ConnectionFactory(); - amqpFactory.setUri(amqpUri); - amqpConnectionFactoryCache.put(partitionId, amqpFactory); - - } catch (URISyntaxException | NoSuchAlgorithmException | KeyManagementException e) { - throw new OqmDriverRuntimeException("RabbitMQ amqp URI and ConnectionFactory", e); - } - } - - if (httpClient == null) { - - String adminSchm = getPartitionProperty(partitionId, partitionProperties, ADMIN_SCHEMA); - String adminHost = getPartitionProperty(partitionId, partitionProperties, ADMIN_HOST); - String adminPort = getPartitionProperty(partitionId, partitionProperties, ADMIN_PORT); - String adminPath = getPartitionProperty(partitionId, partitionProperties, ADMIN_PATH); - String adminUser = getPartitionProperty(partitionId, partitionProperties, ADMIN_USERNAME); - String adminPass = getPartitionProperty(partitionId, partitionProperties, ADMIN_PASSWORD); - - try { - URI httpUrl = new URI(adminSchm, null, adminHost, Integer.parseInt(adminPort), adminPath, null, null); - ClientParameters clientParameters = new ClientParameters().url(httpUrl.toURL()) - .username(adminUser).password(adminPass); - - httpClient = new Client(clientParameters); - httpClientCache.put(partitionId, httpClient); - - } catch (URISyntaxException | MalformedURLException e) { - throw new OqmDriverRuntimeException("RabbitMQ http(api) URI and Client", e); - } - } - } - return MqOqmDestinationResolution.builder() - .amqpFactory(amqpFactory) - .adminClient(httpClient) - .virtualHost(virtualHost) - .build(); - } - } - - private String getPartitionProperty(String partitionId, Map<String, Property> partitionProperties, String propertyName) { - String fullName = properties.getPartitionPropertiesPrefix().concat(propertyName); - return Optional.ofNullable(partitionProperties.get(fullName)).map(Property::getValue).map(Object::toString) - .orElseThrow(() -> new OqmDriverRuntimeException(null, - "Partition '%s' RabbitMQ OQM destination resolution configuration issue. Property '%s' is not provided in PartitionInfo.", - partitionId, fullName)); - } - - @PreDestroy - public void shutdown() { - log.info("On pre-destroy."); - } -} diff --git a/provider/notification-gcp/src/main/java/org/opengroup/osdu/notification/provider/gcp/mappers/oqm/OqmConfigurationProperties.java b/provider/notification-gcp/src/main/java/org/opengroup/osdu/notification/provider/gcp/mappers/oqm/OqmConfigurationProperties.java deleted file mode 100644 index f062ae3ee15b4352a904085b832a29e8418c452e..0000000000000000000000000000000000000000 --- a/provider/notification-gcp/src/main/java/org/opengroup/osdu/notification/provider/gcp/mappers/oqm/OqmConfigurationProperties.java +++ /dev/null @@ -1,34 +0,0 @@ -/* - Copyright 2020 Google LLC - Copyright 2020 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.notification.provider.gcp.mappers.oqm; - -import lombok.Getter; -import lombok.Setter; -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; -import org.springframework.boot.context.properties.ConfigurationProperties; -import org.springframework.context.annotation.Configuration; - -@Configuration -@ConditionalOnProperty(name = "oqmDriver") -@ConfigurationProperties(prefix = "oqm") -@Getter -@Setter -public class OqmConfigurationProperties { - - private String registerSubscriberControlTopicName = "register-subscriber-control"; - -} diff --git a/provider/notification-gcp/src/main/java/org/opengroup/osdu/notification/provider/gcp/mappers/oqm/PsTenantOqmDestinationResolver.java b/provider/notification-gcp/src/main/java/org/opengroup/osdu/notification/provider/gcp/mappers/oqm/PsTenantOqmDestinationResolver.java deleted file mode 100644 index 2ddca9bebde20fa4d434a966e85d69fd7c53db90..0000000000000000000000000000000000000000 --- a/provider/notification-gcp/src/main/java/org/opengroup/osdu/notification/provider/gcp/mappers/oqm/PsTenantOqmDestinationResolver.java +++ /dev/null @@ -1,110 +0,0 @@ -/* - Copyright 2020 Google LLC - Copyright 2020 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.notification.provider.gcp.mappers.oqm; - -import com.google.cloud.pubsub.v1.SubscriptionAdminClient; -import com.google.cloud.pubsub.v1.TopicAdminClient; -import com.google.cloud.pubsub.v1.TopicAdminSettings; -import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; -import org.opengroup.osdu.core.common.model.tenant.TenantInfo; -import org.opengroup.osdu.core.common.provider.interfaces.ITenantFactory; -import org.opengroup.osdu.core.gcp.oqm.driver.OqmDriverRuntimeException; -import org.opengroup.osdu.core.gcp.oqm.driver.pubsub.PsOqmDestinationResolution; -import org.opengroup.osdu.core.gcp.oqm.driver.pubsub.PsOqmDestinationResolver; -import org.opengroup.osdu.core.gcp.oqm.model.OqmDestination; -import org.opengroup.osdu.notification.provider.gcp.util.GcpAppServiceConfig; -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; -import org.springframework.context.annotation.Scope; -import org.springframework.stereotype.Component; - -import javax.annotation.PreDestroy; -import java.io.IOException; -import java.util.HashMap; -import java.util.Map; - -import static org.springframework.beans.factory.config.BeanDefinition.SCOPE_SINGLETON; - -/** - * For GCP PubSub. Tenant Based OQM destination resolver - */ -@Component -@Scope(SCOPE_SINGLETON) -@ConditionalOnProperty(name = "oqmDriver", havingValue = "pubsub") -@Slf4j -@RequiredArgsConstructor -public class PsTenantOqmDestinationResolver implements PsOqmDestinationResolver { - - private Map<OqmDestination, TopicAdminClient> topicClientCache = new HashMap<>(); - private Map<OqmDestination, SubscriptionAdminClient> subscriptionClientCache = new HashMap<>(); - - private final ITenantFactory tenantInfoFactory; - private final GcpAppServiceConfig config; - - @Override - public PsOqmDestinationResolution resolve(OqmDestination destination) { - TenantInfo ti = tenantInfoFactory.getTenantInfo(destination.getPartitionId()); - String partitionId = destination.getPartitionId(); - - //noinspection SwitchStatementWithTooFewBranches - switch (partitionId) { - default: - String servicesProjectId = config.getGoogleCloudProject(); - String dataProjectId = ti.getProjectId(); - - TopicAdminClient tac = topicClientCache.get(destination); - if (tac == null) { - try { - TopicAdminSettings tas = TopicAdminSettings.newBuilder().build(); - tac = TopicAdminClient.create(tas); - topicClientCache.put(destination, tac); - } catch (IOException e) { - throw new OqmDriverRuntimeException("PsOqmDestinationResolution#resolve TopicAdminClient", e); - } - } - - SubscriptionAdminClient sac = subscriptionClientCache.get(destination); - if (sac == null) { - try { - sac = SubscriptionAdminClient.create(); - subscriptionClientCache.put(destination, sac); - } catch (IOException e) { - throw new OqmDriverRuntimeException("PsOqmDestinationResolution#resolve SubscriptionAdminClient", e); - } - } - - return PsOqmDestinationResolution.builder() - .servicesProjectId(servicesProjectId) - .dataProjectId(dataProjectId) - .topicAdminClient(tac) - .subscriptionAdminClient(sac) - .build(); - } - } - - @PreDestroy - public void shutdown() { - log.info("On pre-destroy. {} topic client(s) & {} subscription clients to shutdown", - topicClientCache.size(), subscriptionClientCache.size()); - for (TopicAdminClient tac : topicClientCache.values()) { - tac.shutdown(); - } - for (SubscriptionAdminClient sac : subscriptionClientCache.values()) { - sac.shutdown(); - } - } -} diff --git a/provider/notification-gcp/src/main/java/org/opengroup/osdu/notification/provider/gcp/pubsub/OqmSubscriberManager.java b/provider/notification-gcp/src/main/java/org/opengroup/osdu/notification/provider/gcp/pubsub/OqmSubscriberManager.java index 36f57d916a8973e061d133ccf4b1e6c804853482..b57ac2db24b3481f1eabbc260a2e6c03040e4916 100644 --- a/provider/notification-gcp/src/main/java/org/opengroup/osdu/notification/provider/gcp/pubsub/OqmSubscriberManager.java +++ b/provider/notification-gcp/src/main/java/org/opengroup/osdu/notification/provider/gcp/pubsub/OqmSubscriberManager.java @@ -24,7 +24,7 @@ import org.opengroup.osdu.core.common.provider.interfaces.ITenantFactory; import org.opengroup.osdu.core.gcp.oqm.driver.OqmDriver; import org.opengroup.osdu.core.gcp.oqm.driver.OqmDriverRuntimeException; import org.opengroup.osdu.core.gcp.oqm.model.*; -import org.opengroup.osdu.notification.provider.gcp.mappers.oqm.OqmConfigurationProperties; +import org.opengroup.osdu.notification.provider.gcp.config.OqmConfigurationProperties; import org.opengroup.osdu.notification.provider.gcp.pubsub.di.OqmNotificationHandler; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.context.annotation.Scope; diff --git a/provider/notification-gcp/src/main/java/org/opengroup/osdu/notification/provider/gcp/pubsub/di/OqmNotificationHandler.java b/provider/notification-gcp/src/main/java/org/opengroup/osdu/notification/provider/gcp/pubsub/di/OqmNotificationHandler.java index 2235850d9ce603adc494b4b73af65c46b2165741..d764bf314d11cf95a25bedc18c4303dcfc0cdd96 100644 --- a/provider/notification-gcp/src/main/java/org/opengroup/osdu/notification/provider/gcp/pubsub/di/OqmNotificationHandler.java +++ b/provider/notification-gcp/src/main/java/org/opengroup/osdu/notification/provider/gcp/pubsub/di/OqmNotificationHandler.java @@ -16,6 +16,9 @@ package org.opengroup.osdu.notification.provider.gcp.pubsub.di; +import java.util.Map; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; import org.opengroup.osdu.core.common.http.HttpClient; import org.opengroup.osdu.core.common.http.HttpRequest; import org.opengroup.osdu.core.common.http.HttpResponse; @@ -24,48 +27,51 @@ import org.opengroup.osdu.core.common.model.notification.Secret; import org.opengroup.osdu.core.common.model.notification.Subscription; import org.opengroup.osdu.notification.auth.factory.AuthFactory; import org.opengroup.osdu.notification.auth.interfaces.SecretAuth; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Value; +import org.opengroup.osdu.notification.provider.gcp.config.OqmConfigurationProperties; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.stereotype.Component; -import java.util.Map; - @Component @ConditionalOnProperty(name = "oqmDriver") +@RequiredArgsConstructor +@Slf4j public class OqmNotificationHandler { - private final static Logger LOGGER = LoggerFactory.getLogger(OqmNotificationHandler.class); - @Autowired - private HttpClient httpClient; - @Autowired - private OqmSubscriptionHandler subscriptionHandler; - @Autowired - private AuthFactory authFactory; - @Value("${app.waitingTime:30000}") - private int WAITING_TIME; - public HttpResponse notifySubscriber(String notificationId, String pubsubMessage, Map<String, String> headerAttributes) throws Exception { - Subscription subscription = subscriptionHandler.getSubscriptionFromCache(notificationId, headerAttributes); - Secret secret = subscription.getSecret(); - String endpoint = subscription.getPushEndpoint(); - String secretType = secret.getSecretType(); - String pushUrl; + private final OqmConfigurationProperties oqmConfigurationProperties; + private final HttpClient httpClient; + private final OqmSubscriptionHandler subscriptionHandler; + private final AuthFactory authFactory; + + public HttpResponse notifySubscriber( + String notificationId, String pubsubMessage, Map<String, String> headerAttributes) + throws Exception { + Subscription subscription = + subscriptionHandler.getSubscriptionFromCache(notificationId, headerAttributes); + Secret secret = subscription.getSecret(); + String endpoint = subscription.getPushEndpoint(); + String secretType = secret.getSecretType(); + String pushUrl; - // Authentication Secret - SecretAuth secretAuth = authFactory.getSecretAuth(secretType); - secretAuth.setSecret(secret); - pushUrl = secretAuth.getPushUrl(endpoint); + // Authentication Secret + SecretAuth secretAuth = authFactory.getSecretAuth(secretType); + secretAuth.setSecret(secret); + pushUrl = secretAuth.getPushUrl(endpoint); - Map<String, String> requestHeader = secretAuth.getRequestHeaders(); - requestHeader.put(DpsHeaders.CONTENT_TYPE, "application/json"); - requestHeader.put(DpsHeaders.CORRELATION_ID, headerAttributes.get(DpsHeaders.CORRELATION_ID)); - requestHeader.put(DpsHeaders.DATA_PARTITION_ID, headerAttributes.get(DpsHeaders.DATA_PARTITION_ID)); + Map<String, String> requestHeader = secretAuth.getRequestHeaders(); + requestHeader.put(DpsHeaders.CONTENT_TYPE, "application/json"); + requestHeader.put(DpsHeaders.CORRELATION_ID, headerAttributes.get(DpsHeaders.CORRELATION_ID)); + requestHeader.put( + DpsHeaders.DATA_PARTITION_ID, headerAttributes.get(DpsHeaders.DATA_PARTITION_ID)); - HttpRequest request = HttpRequest.post().url(pushUrl).headers(requestHeader).body(pubsubMessage).connectionTimeout(WAITING_TIME).build(); - HttpResponse response = httpClient.send(request); - LOGGER.debug("Sending out notification to endpoint: " + endpoint); - return response; - } + HttpRequest request = + HttpRequest.post() + .url(pushUrl) + .headers(requestHeader) + .body(pubsubMessage) + .connectionTimeout(oqmConfigurationProperties.getWaitingTime()) + .build(); + HttpResponse response = httpClient.send(request); + log.debug("Sending out notification to endpoint: " + endpoint); + return response; + } } diff --git a/provider/notification-gcp/src/main/java/org/opengroup/osdu/notification/provider/gcp/util/AppProperties.java b/provider/notification-gcp/src/main/java/org/opengroup/osdu/notification/provider/gcp/util/AppProperties.java deleted file mode 100644 index 1aa85c59dc6133074d6e2c55e025c558f8f238f1..0000000000000000000000000000000000000000 --- a/provider/notification-gcp/src/main/java/org/opengroup/osdu/notification/provider/gcp/util/AppProperties.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright 2017-2020, Schlumberger - * - * 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.notification.provider.gcp.util; - -import org.opengroup.osdu.notification.provider.interfaces.IAppProperties; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.stereotype.Component; - -@Component -public class AppProperties implements IAppProperties { - - @Value("${app.entitlements}") - private String authorizeAPI; - @Value("${app.register}") - private String registerAPI; - @Value("${app.project}") - private String projectId; - @Value("${app.googleAudience}") - private String googleAudience; - @Value("${app.expireTime}") - private int expireTime; - @Value("${app.maxCacheSize}") - private int maxCacheSize; - - - public String getAuthorizeAPI() { - return authorizeAPI; - } - - public String getRegisterAPI() { - return registerAPI; - } - - public String getPubSubServiceAccountEmail() { - return String.format("de-notification-service@%s.iam.gserviceaccount.com", this.projectId); - } - - public String getGoogleAudiences() { - return this.googleAudience; - } -} diff --git a/provider/notification-gcp/src/main/java/org/opengroup/osdu/notification/provider/gcp/util/GoogleServiceAccountValidatorImpl.java b/provider/notification-gcp/src/main/java/org/opengroup/osdu/notification/provider/gcp/util/GoogleServiceAccountValidatorImpl.java index cd5617615747809cc46332e9a61002b96fbf87c3..af1dedf525c432bdc2684444ad0fab0c1c82e95b 100644 --- a/provider/notification-gcp/src/main/java/org/opengroup/osdu/notification/provider/gcp/util/GoogleServiceAccountValidatorImpl.java +++ b/provider/notification-gcp/src/main/java/org/opengroup/osdu/notification/provider/gcp/util/GoogleServiceAccountValidatorImpl.java @@ -21,6 +21,7 @@ import com.google.api.client.googleapis.auth.oauth2.GoogleIdTokenVerifier; import com.google.api.client.http.javanet.NetHttpTransport; import com.google.api.client.json.jackson2.JacksonFactory; import org.opengroup.osdu.core.common.logging.JaxRsDpsLog; +import org.opengroup.osdu.notification.provider.gcp.config.AppProperties; import org.opengroup.osdu.notification.provider.interfaces.IServiceAccountValidator; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; diff --git a/provider/notification-gcp/src/main/java/org/opengroup/osdu/notification/provider/gcp/util/ServiceAccountJwtGcpClientImpl.java b/provider/notification-gcp/src/main/java/org/opengroup/osdu/notification/provider/gcp/util/ServiceAccountJwtGcpClientImpl.java index b5b7d51ff2b241f0b6def88f1f99d0d05b2fbfb5..f05a02653d935c1cfe87885f0f38a6f0083f4ba7 100644 --- a/provider/notification-gcp/src/main/java/org/opengroup/osdu/notification/provider/gcp/util/ServiceAccountJwtGcpClientImpl.java +++ b/provider/notification-gcp/src/main/java/org/opengroup/osdu/notification/provider/gcp/util/ServiceAccountJwtGcpClientImpl.java @@ -17,188 +17,22 @@ package org.opengroup.osdu.notification.provider.gcp.util; -import com.google.api.client.googleapis.javanet.GoogleNetHttpTransport; -import com.google.api.client.http.HttpTransport; -import com.google.api.client.json.gson.GsonFactory; -import com.google.api.services.iam.v1.Iam; -import com.google.api.services.iam.v1.IamScopes; -import com.google.api.services.iam.v1.model.SignJwtRequest; -import com.google.api.services.iam.v1.model.SignJwtResponse; -import com.google.auth.http.HttpCredentialsAdapter; -import com.google.auth.oauth2.GoogleCredentials; -import com.google.common.base.Strings; -import com.google.gson.JsonObject; -import com.google.gson.JsonParser; -import org.apache.http.HttpHeaders; -import org.apache.http.HttpStatus; -import org.apache.http.NameValuePair; -import org.apache.http.client.entity.UrlEncodedFormEntity; -import org.apache.http.client.methods.CloseableHttpResponse; -import org.apache.http.client.methods.HttpPost; -import org.apache.http.entity.ContentType; -import org.apache.http.impl.client.CloseableHttpClient; -import org.apache.http.impl.client.HttpClients; -import org.apache.http.message.BasicNameValuePair; -import org.apache.http.util.EntityUtils; -import org.opengroup.osdu.core.common.model.http.AppException; -import org.opengroup.osdu.core.common.model.tenant.TenantInfo; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.opengroup.osdu.core.auth.TokenProvider; import org.opengroup.osdu.core.common.util.IServiceAccountJwtClient; -import org.opengroup.osdu.core.gcp.multitenancy.TenantFactory; - -import java.io.IOException; -import java.security.GeneralSecurityException; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; +import org.springframework.stereotype.Component; +@Component +@Slf4j +@RequiredArgsConstructor public class ServiceAccountJwtGcpClientImpl implements IServiceAccountJwtClient { - private AppProperties config; - private static final String JWT_AUDIENCE = "https://www.googleapis.com/oauth2/v4/token"; - private static final String SERVICE_ACCOUNT_NAME_FORMAT = "projects/%s/serviceAccounts/%s"; - private static final GsonFactory JSON_FACTORY = new GsonFactory(); - static final String INVALID_INPUT = "Invalid inputs provided to getIdToken function"; - static final String INVALID_DATA_PARTITION = "Invalid data partition id"; - - private static ConcurrentHashMap<String, JwtValidity> jwtCache = new ConcurrentHashMap<>(); - private Iam iam; - - public ServiceAccountJwtGcpClientImpl(AppProperties config) { - if (config == null) { - throw new IllegalArgumentException("AppProperties is null when initializing jwt client."); - } else { - this.config = config; - } - } - - public String getIdToken(String dataPartitionId) { - String googleAudience = this.config.getGoogleAudiences(); - String hostName = this.config.getRegisterAPI(); - if (Strings.isNullOrEmpty(dataPartitionId) || Strings.isNullOrEmpty(googleAudience) || Strings.isNullOrEmpty(hostName)) { - throw new AppException(HttpStatus.SC_BAD_REQUEST, "data partition id, audiences or hostname are null", INVALID_INPUT); - } - try { - // Check if there is already a valid jwt - String key = dataPartitionId + googleAudience + hostName; - String jwt = checkAndGetJwtIfValid(key); - if (!Strings.isNullOrEmpty(jwt)) - return jwt; - - TenantInfo tenantInfo = new TenantFactory().getTenantInfo(dataPartitionId); - if (tenantInfo == null) { - throw new AppException(HttpStatus.SC_BAD_REQUEST, "data partition id is invalid", INVALID_DATA_PARTITION); - } - long currentTime = System.currentTimeMillis() / 1000; - long expiryTime = currentTime + 3600; - - // get signed JWT - Map<String, Object> signJwtPayload = this.getJwtCreationPayload(tenantInfo, googleAudience, currentTime, expiryTime); - - SignJwtRequest signJwtRequest = new SignJwtRequest(); - signJwtRequest.setPayload(JSON_FACTORY.toString(signJwtPayload)); - - String serviceAccountName = String.format(SERVICE_ACCOUNT_NAME_FORMAT, tenantInfo.getProjectId(), - tenantInfo.getServiceAccount()); - - Iam.Projects.ServiceAccounts.SignJwt signJwt = this.getIam(hostName).projects().serviceAccounts() - .signJwt(serviceAccountName, signJwtRequest); - SignJwtResponse signJwtResponse = signJwt.execute(); - String signedJwt = signJwtResponse.getSignedJwt(); - - // get id token - List<NameValuePair> postParameters = new ArrayList<>(); - postParameters.add(new BasicNameValuePair("grant_type", "urn:ietf:params:oauth:grant-type:jwt-bearer")); - postParameters.add(new BasicNameValuePair("assertion", signedJwt)); - - HttpPost post = new HttpPost(JWT_AUDIENCE); - post.setHeader(HttpHeaders.CONTENT_TYPE, ContentType.APPLICATION_FORM_URLENCODED.getMimeType()); - post.setEntity(new UrlEncodedFormEntity(postParameters, "UTF-8")); - - try (CloseableHttpClient httpClient = HttpClients.createDefault()) { - CloseableHttpResponse httpResponse = httpClient.execute(post); - - JsonObject jsonContent = new JsonParser().parse(EntityUtils.toString(httpResponse.getEntity())) - .getAsJsonObject(); - - if (!jsonContent.has("id_token")) { - throw new AppException(HttpStatus.SC_UNAUTHORIZED, "User is not authorized to perform this operation.", "Unauthorized to generate token"); - } - - String token = "Bearer " + jsonContent.get("id_token").getAsString(); - jwtCache.put(key, new JwtValidity(token, expiryTime)); - return token; - } - } catch (Exception e) { - throw new AppException(HttpStatus.SC_INTERNAL_SERVER_ERROR, "Error happens when generating sauth token", "Error generating token", e); - } - - } - - Iam getIam(String hostName) throws GeneralSecurityException, IOException { - if (this.iam == null) { - HttpTransport httpTransport = GoogleNetHttpTransport.newTrustedTransport(); - - GoogleCredentials credential = GoogleCredentials.getApplicationDefault(); - if (credential.createScopedRequired()) { - List<String> scopes = new ArrayList<>(); - scopes.add(IamScopes.CLOUD_PLATFORM); - credential = credential.createScoped(scopes); - } - - this.iam = new Iam.Builder(httpTransport, JSON_FACTORY, new HttpCredentialsAdapter(credential)) - .setApplicationName(hostName).build(); - } - - return this.iam; - } - - // THIS METHOD IS ONLY TO ENABLE UNIT TESTING - boolean reduceTenantExpiry(String dataPartitionId, String googleAudience, String hostName, long keepDifference) { - JwtValidity jwtValidity = jwtCache.get(dataPartitionId + googleAudience + hostName); - if (jwtValidity == null) - return false; - - long currentTime = System.currentTimeMillis() / 1000; - jwtValidity.expiryTime = currentTime + keepDifference; - return true; - } - - // THIS METHOD IS ONLY TO ENABLE UNIT TESTING - void clearCache() { - jwtCache.clear(); - } - - private String checkAndGetJwtIfValid(String key) { - JwtValidity jwtValidity = jwtCache.get(key); - if (jwtValidity == null) - return null; - - // get current time - long currentTime = System.currentTimeMillis() / 1000; - - // If exipring in less than 5 minutes then need to renew the token - if (jwtValidity.expiryTime - 300 < currentTime) { - jwtCache.remove(key); - return null; - } - - return jwtValidity.token; - } - + private final TokenProvider tokenProvider; - private Map<String, Object> getJwtCreationPayload(TenantInfo tenantInfo, String googleAudience, long currentTime, long expiryTime) { - if (googleAudience.contains(",")) { - googleAudience = googleAudience.split(",")[0]; - } - Map<String, Object> payload = new HashMap<>(); - payload.put("target_audience", googleAudience); - payload.put("aud", JWT_AUDIENCE); - payload.put("exp", expiryTime); - payload.put("iat", currentTime); - payload.put("iss", tenantInfo.getServiceAccount()); - return payload; + public String getIdToken(String tenantName) { + log.info("Tenant name received for auth token is: {}", tenantName); + return tokenProvider.getIdToken(); } } diff --git a/provider/notification-gcp/src/main/resources/application-anthos.properties b/provider/notification-gcp/src/main/resources/application-anthos.properties new file mode 100644 index 0000000000000000000000000000000000000000..9aa4ecc28cc5e362dea756f7d1a5a975483e4c59 --- /dev/null +++ b/provider/notification-gcp/src/main/resources/application-anthos.properties @@ -0,0 +1,20 @@ +# +# Copyright 2022 Google LLC +# Copyright 2022 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. +# + +service.token.provider=OPENID +partition-auth-enabled=false +oqmDriver=rabbitmq \ No newline at end of file diff --git a/provider/notification-gcp/src/main/resources/application-dev.properties b/provider/notification-gcp/src/main/resources/application-dev.properties deleted file mode 100644 index 00e1abb14672781aa4bab9acc30cf4af824a96ad..0000000000000000000000000000000000000000 --- a/provider/notification-gcp/src/main/resources/application-dev.properties +++ /dev/null @@ -1,23 +0,0 @@ -# -# Copyright 2017-2020, Schlumberger -# -# 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. -# - -spring.profiles.active=dev -app.entitlements=https://entitlements-dot-opendes.appspot.com/entitlements/v1 -app.register=https://os-register-dot-opendes.appspot.com/api/register/v1 -app.project=opendes -app.googleAudience=245464679631-ktfdfpl147m1mjpbutl00b3cmffissgq.apps.googleusercontent.com -server.port=8080 -enable.appengine.log.factory=true \ No newline at end of file diff --git a/provider/notification-gcp/src/main/resources/application-gcp.properties b/provider/notification-gcp/src/main/resources/application-gcp.properties new file mode 100644 index 0000000000000000000000000000000000000000..aac090a9d1723802c6c789cd21ac1555fe63baa4 --- /dev/null +++ b/provider/notification-gcp/src/main/resources/application-gcp.properties @@ -0,0 +1,20 @@ +# +# Copyright 2022 Google LLC +# Copyright 2022 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. +# + +service.token.provider=GCP +partition-auth-enabled=true +oqmDriver=pubsub \ No newline at end of file diff --git a/provider/notification-gcp/src/main/resources/application-kuber.properties b/provider/notification-gcp/src/main/resources/application-kuber.properties deleted file mode 100644 index 856d60997214700045ca12c7f3b6d85163d7f140..0000000000000000000000000000000000000000 --- a/provider/notification-gcp/src/main/resources/application-kuber.properties +++ /dev/null @@ -1,23 +0,0 @@ -# -# Copyright 2017-2020, Schlumberger -# -# 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. -# - -app.entitlements=http://os-entitlement-service/entitlements/v1 -app.register=https://os-register-dot-opendes.appspot.com/api/register/v1 -app.project=${GOOGLE_CLOUD_PROJECT} -app.googleAudience=${GOOGLE_AUDIENCES} -server.port=8080 - -server.servlet.contextPath=/api/notification/v1/ diff --git a/provider/notification-gcp/src/main/resources/application-local.properties b/provider/notification-gcp/src/main/resources/application-local.properties index 58c982df57bb0618b75edadbfcf7d2a6c8878d2b..ec8e968641b1f3292063121e19e4241b6435d729 100644 --- a/provider/notification-gcp/src/main/resources/application-local.properties +++ b/provider/notification-gcp/src/main/resources/application-local.properties @@ -14,9 +14,14 @@ # limitations under the License. # -spring.profiles.active=local -app.entitlements=https://entitlements-dot-opendes.appspot.com/entitlements/v1 -app.register=https://os-register-dot-opendes.appspot.com/api/register/v1 -app.project=opendes -app.googleAudience=245464679631-ktfdfpl147m1mjpbutl00b3cmffissgq.apps.googleusercontent.com server.port=8080 +logging.level.org.springframework.web=${LOG_LEVEL:DEBUG} + +app.entitlements=https://community.gcp.gnrg-osdu.projects.epam.com/entitlements/v2 +app.register=https://community.gcp.gnrg-osdu.projects.epam.com/api/register/v1 +app.project=nice-etching-277309 +google-audiences=689762842995-pv217jo3k8j803kk6gqf52qb5amos3a9.apps.googleusercontent.com + +service.token.provider=GCP +partition-auth-enabled=true +oqmDriver=pubsub diff --git a/provider/notification-gcp/src/main/resources/application.properties b/provider/notification-gcp/src/main/resources/application.properties index 45946ed858f7666a2e981b026a911b0f66854b93..80608c45fc05d2d63dcfd205b997ac768ef0e5de 100644 --- a/provider/notification-gcp/src/main/resources/application.properties +++ b/provider/notification-gcp/src/main/resources/application.properties @@ -14,14 +14,21 @@ # limitations under the License. # +# Global defaults LOG_PREFIX=notification -logging.level.org.springframework.web=${LOG_LEVEL:DEBUG} +logging.level.org.springframework.web=${LOG_LEVEL:INFO} server.servlet.contextPath=/api/notification/v1 + app.expireTime=300 app.maxCacheSize=10 server.error.whitelabel.enabled=false -google.audiences=${APP_AUDIENCES} -partition.api=http://localhost:8081/api/partition/v1 +# External services +app.entitlements=http://entitlements/api/entitlements/v2/ +app.register=http://register/api/register/v1 +partition.api=http://partition/api/partition/v1/ +# No profile defaults +service.token.provider=GCP +partition-auth-enabled=true oqmDriver=pubsub \ No newline at end of file