Skip to content
Snippets Groups Projects
Commit 4210b0fb authored by Dmitrii Novikov (EPAM)'s avatar Dmitrii Novikov (EPAM) Committed by Riabokon Stanislav(EPAM)[GCP]
Browse files

Remove datastore tenant info provisioning from Notification service (EPAM GONRG-4242)

parent 6520034e
No related branches found
No related tags found
3 merge requests!232Update os-core-lib-azure,!231initial commit,!178Remove datastore tenant info provisioning from Notification service (EPAM GONRG-4242)
Showing
with 416 additions and 632 deletions
...@@ -83,6 +83,7 @@ The following software have components provided under the terms of this license: ...@@ -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) - 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) - 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) - 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) - Hop (from https://github.com/rabbitmq/hop, https://www.rabbitmq.com)
- HttpClient (from http://hc.apache.org/httpcomponents-client) - HttpClient (from http://hc.apache.org/httpcomponents-client)
- HttpClient Cache (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: ...@@ -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 :: 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 :: 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) - 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 :: 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 :: 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) - 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: ...@@ -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) - 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) - OpenCensus (from https://github.com/census-instrumentation/opencensus-java)
- PWDB :: Database (from https://repo1.maven.org/maven2/org/linguafranca/pwdb/database) - 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) - 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) - 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) - 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: ...@@ -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) - RabbitMQ Java Client (from http://www.rabbitmq.com, https://www.rabbitmq.com)
- Reactive Streams Netty driver (from https://github.com/reactor/reactor-netty) - 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) - 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) - 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 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) - 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: ...@@ -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 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 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 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 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 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) - 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: ...@@ -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) - 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-core (from https://github.com/micrometer-metrics/micrometer)
- micrometer-registry-azure-monitor (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.apiguardian:apiguardian-api (from https://github.com/apiguardian-team/apiguardian)
- org.conscrypt:conscrypt-openjdk-uber (from https://conscrypt.org/) - org.conscrypt:conscrypt-openjdk-uber (from https://conscrypt.org/)
- org.opentest4j:opentest4j (from https://github.com/ota4j-team/opentest4j) - 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: ...@@ -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) - 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) - resilience4j (from https://github.com/resilience4j/resilience4j, https://resilience4j.readme.io, ttps://resilience4j.readme.io)
- rxjava (from https://github.com/ReactiveX/RxJava) - 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-bean-validators (from https://github.com/springfox/springfox)
- springfox-boot-starter (from https://github.com/springfox/springfox) - springfox-boot-starter (from https://github.com/springfox/springfox)
- springfox-core (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: ...@@ -311,6 +319,7 @@ The following software have components provided under the terms of this license:
- Hamcrest (from http://hamcrest.org/JavaHamcrest/) - Hamcrest (from http://hamcrest.org/JavaHamcrest/)
- Hamcrest Core (from https://repo1.maven.org/maven2/org/hamcrest/hamcrest-core) - Hamcrest Core (from https://repo1.maven.org/maven2/org/hamcrest/hamcrest-core)
- HdrHistogram (from http://hdrhistogram.github.io/HdrHistogram/) - HdrHistogram (from http://hdrhistogram.github.io/HdrHistogram/)
- PostgreSQL JDBC Driver
- Reflections (from http://code.google.com/p/reflections/, http://github.com/ronmamo/reflections) - Reflections (from http://code.google.com/p/reflections/, http://github.com/ronmamo/reflections)
- Stax2 API (from http://github.com/FasterXML/stax2-api) - Stax2 API (from http://github.com/FasterXML/stax2-api)
- ThreeTen backport (from https://github.com/ThreeTen/threetenbp, https://www.threeten.org/threetenbp) - 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: ...@@ -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) - 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/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) - 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 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) - 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) - 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: ...@@ -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 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 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) - 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) - Checker Qual (from https://checkerframework.org)
- ClassGraph (from https://github.com/classgraph/classgraph) - ClassGraph (from https://github.com/classgraph/classgraph)
- Extensions on Apache Proton-J library (from https://github.com/Azure/qpid-proton-j-extensions) - 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: ...@@ -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) - 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) - 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) - 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/) - 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/) - 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: ...@@ -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 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 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) - 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) - Project Lombok (from http://projectlombok.org, https://projectlombok.org)
- RabbitMQ Java Client (from http://www.rabbitmq.com, https://www.rabbitmq.com) - 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) - 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 ...@@ -683,6 +696,7 @@ unknown
======================================================================== ========================================================================
The following software have components provided under the terms of this license: 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) - Byte Buddy (without dependencies) (from https://repo1.maven.org/maven2/net/bytebuddy/byte-buddy)
- Checker Qual (from https://checkerframework.org) - Checker Qual (from https://checkerframework.org)
- JSON in Java (from https://github.com/douglascrockford/JSON-java) - JSON in Java (from https://github.com/douglascrockford/JSON-java)
......
...@@ -10,6 +10,7 @@ data: ...@@ -10,6 +10,7 @@ data:
APP_PROJECT: "{{ .Values.data.app_project }}" APP_PROJECT: "{{ .Values.data.app_project }}"
APP_ENTITLEMENTS: "{{ .Values.data.app_entitlements }}" APP_ENTITLEMENTS: "{{ .Values.data.app_entitlements }}"
APP_REGISTER: "{{ .Values.data.app_register }}" APP_REGISTER: "{{ .Values.data.app_register }}"
APP_GOOGLEAUDIENCE: "{{ .Values.data.app_googleaudience }}"
PARTITION_API: "{{ .Values.data.partition_api }}" PARTITION_API: "{{ .Values.data.partition_api }}"
GOOGLE_AUDIENCES: "{{ .Values.data.google_audiences }}" GOOGLE_AUDIENCES: "{{ .Values.data.google_audiences }}"
SERVICE_TOKEN_PROVIDER: "{{ .Values.data.token_provider }}"
PARTITION_AUTH_ENABLED: "{{ .Values.data.partition_auth_enabled }}"
...@@ -3,9 +3,10 @@ data: ...@@ -3,9 +3,10 @@ data:
app_project: "" app_project: ""
app_entitlements: "http://entitlements/api/entitlements/v2/" app_entitlements: "http://entitlements/api/entitlements/v2/"
app_register: "http://register/api/register/v1" app_register: "http://register/api/register/v1"
app_googleaudience: ""
partition_api: "http://partition/api/partition/v1/" partition_api: "http://partition/api/partition/v1/"
google_audiences: "" google_audiences: ""
token_provider: "GCP"
partition_auth_enabled: "true"
conf: conf:
configmap: "notification-config" configmap: "notification-config"
app_name: "notification" app_name: "notification"
# Notification Service # 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. 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 ## 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. 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. This is a universal solution created using EPAM OQM mapper technology.
It allows you to work with various implementations of message brokers. 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: In the current version, the OQM mapper is equipped with 2 drivers to the message brokers:
- Google PubSub;
- Google PubSub;
- RabbitMQ - RabbitMQ
## Extensibility ## Settings and Configuration
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
### for native Google Cloud technologies: #### Requirements
- for PubSub: mappers/oqm/PsTenantOqmDestinationResolver.java
#### Their algorithms are similar, 1. Mandatory
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. - 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 ### Anthos Service Configuration:
In order to run the service locally or remotely, define the following environment variables. [Anthos service configuration ](docs/anthos/README.md)
Most of them are common to all hosting environments, but there are properties that are only necessary when running in Google Cloud. ### GCP Service Configuration:
[Gcp service configuration ](docs/gcp/README.md)
#### Common properties for all environments ## Run service
| name | value | description | sensitive? | source | ### Running Locally
| --- | --- | --- | --- | --- |
| `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
Check that maven is installed: Check that maven is installed:
```bash ```bash
$ mvn --version $ mvn --version
...@@ -298,7 +122,7 @@ Navigate to notification service's root folder and run all the tests: ...@@ -298,7 +122,7 @@ Navigate to notification service's root folder and run all the tests:
$ (cd notification-core/ && mvn clean install) $ (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. 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 ...@@ -340,6 +164,18 @@ Above variables should be configured in the release pipeline to run integration
# above are already exported in your environment. # above are already exported in your environment.
$ (cd testing/notification-test-gcp/ && mvn clean test) $ (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 ## License
Copyright © Google LLC Copyright © Google LLC
......
# 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`
![Screenshot](./pics/rabbit.PNG)
## 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”.
![Screenshot](./pics/client.png)
Each Client has embedded Service Account (SA) option. Enable SAs for Clients, make “Authorization enabled”:
![Screenshot](./pics/sa.png)
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
provider/notification-gcp/docs/anthos/pics/client.png

89.9 KiB

provider/notification-gcp/docs/anthos/pics/rabbit.PNG

9.38 KiB

provider/notification-gcp/docs/anthos/pics/sa.png

51.7 KiB

# 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
provider/notification-gcp/docs/gcp/pics/namespace.PNG

2.25 KiB

...@@ -37,12 +37,6 @@ ...@@ -37,12 +37,6 @@
</properties> </properties>
<dependencies> <dependencies>
<dependency>
<groupId>org.opengroup.osdu</groupId>
<artifactId>oqm</artifactId>
<version>0.13.0</version>
</dependency>
<dependency> <dependency>
<groupId>org.opengroup.osdu</groupId> <groupId>org.opengroup.osdu</groupId>
<artifactId>os-core-common</artifactId> <artifactId>os-core-common</artifactId>
...@@ -50,7 +44,7 @@ ...@@ -50,7 +44,7 @@
<dependency> <dependency>
<groupId>org.opengroup.osdu</groupId> <groupId>org.opengroup.osdu</groupId>
<artifactId>core-lib-gcp</artifactId> <artifactId>core-lib-gcp</artifactId>
<version>0.13.0</version> <version>0.14.0-rc1</version>
</dependency> </dependency>
<dependency> <dependency>
......
...@@ -14,42 +14,35 @@ ...@@ -14,42 +14,35 @@
* limitations under the License. * limitations under the License.
*/ */
package org.opengroup.osdu.notification.provider.gcp.util; package org.opengroup.osdu.notification.provider.gcp.config;
import lombok.Getter;
import lombok.Setter;
import org.opengroup.osdu.notification.provider.interfaces.IAppProperties; import org.opengroup.osdu.notification.provider.interfaces.IAppProperties;
import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component; import org.springframework.context.annotation.Configuration;
@Component @Configuration
@ConfigurationProperties(prefix = "app")
@Getter
@Setter
public class AppProperties implements IAppProperties { public class AppProperties implements IAppProperties {
@Value("${app.entitlements}") private String entitlements;
private String authorizeAPI; private String register;
@Value("${app.register}") private String project;
private String registerAPI; private int expireTime;
@Value("${app.project}") private int maxCacheSize;
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 this.entitlements;
}
public String getAuthorizeAPI() { public String getRegisterAPI() {
return authorizeAPI; return this.register;
} }
public String getRegisterAPI() { public String getPubSubServiceAccountEmail() {
return registerAPI; return String.format("de-notification-service@%s.iam.gserviceaccount.com", this.project);
} }
public String getPubSubServiceAccountEmail() {
return String.format("de-notification-service@%s.iam.gserviceaccount.com", this.projectId);
}
public String getGoogleAudiences() {
return this.googleAudience;
}
} }
/* /*
Copyright 2020 Google LLC Copyright 2020 Google LLC
Copyright 2020 EPAM Systems, Inc Copyright 2020 EPAM Systems, Inc
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.
You may obtain a copy of the License at 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 Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS, distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
*/ */
package org.opengroup.osdu.notification.provider.gcp.mappers.oqm; package org.opengroup.osdu.notification.provider.gcp.config;
import lombok.Getter; import lombok.Getter;
import lombok.Setter; import lombok.Setter;
...@@ -28,7 +28,6 @@ import org.springframework.context.annotation.Configuration; ...@@ -28,7 +28,6 @@ import org.springframework.context.annotation.Configuration;
@Getter @Getter
@Setter @Setter
public class OqmConfigurationProperties { public class OqmConfigurationProperties {
private String registerSubscriberControlTopicName = "register-subscriber-control";
private String registerSubscriberControlTopicName = "register-subscriber-control"; private int waitingTime = 30000;
} }
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
/*
* 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;
}
}
/*
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";
}
/*
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.");
}
}
/*
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();
}
}
}
...@@ -24,7 +24,7 @@ import org.opengroup.osdu.core.common.provider.interfaces.ITenantFactory; ...@@ -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.OqmDriver;
import org.opengroup.osdu.core.gcp.oqm.driver.OqmDriverRuntimeException; import org.opengroup.osdu.core.gcp.oqm.driver.OqmDriverRuntimeException;
import org.opengroup.osdu.core.gcp.oqm.model.*; 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.opengroup.osdu.notification.provider.gcp.pubsub.di.OqmNotificationHandler;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Scope; import org.springframework.context.annotation.Scope;
......
...@@ -16,6 +16,9 @@ ...@@ -16,6 +16,9 @@
package org.opengroup.osdu.notification.provider.gcp.pubsub.di; 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.HttpClient;
import org.opengroup.osdu.core.common.http.HttpRequest; import org.opengroup.osdu.core.common.http.HttpRequest;
import org.opengroup.osdu.core.common.http.HttpResponse; import org.opengroup.osdu.core.common.http.HttpResponse;
...@@ -24,48 +27,51 @@ import org.opengroup.osdu.core.common.model.notification.Secret; ...@@ -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.core.common.model.notification.Subscription;
import org.opengroup.osdu.notification.auth.factory.AuthFactory; import org.opengroup.osdu.notification.auth.factory.AuthFactory;
import org.opengroup.osdu.notification.auth.interfaces.SecretAuth; import org.opengroup.osdu.notification.auth.interfaces.SecretAuth;
import org.slf4j.Logger; import org.opengroup.osdu.notification.provider.gcp.config.OqmConfigurationProperties;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import java.util.Map;
@Component @Component
@ConditionalOnProperty(name = "oqmDriver") @ConditionalOnProperty(name = "oqmDriver")
@RequiredArgsConstructor
@Slf4j
public class OqmNotificationHandler { 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 { private final OqmConfigurationProperties oqmConfigurationProperties;
Subscription subscription = subscriptionHandler.getSubscriptionFromCache(notificationId, headerAttributes); private final HttpClient httpClient;
Secret secret = subscription.getSecret(); private final OqmSubscriptionHandler subscriptionHandler;
String endpoint = subscription.getPushEndpoint(); private final AuthFactory authFactory;
String secretType = secret.getSecretType();
String pushUrl; 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 // Authentication Secret
SecretAuth secretAuth = authFactory.getSecretAuth(secretType); SecretAuth secretAuth = authFactory.getSecretAuth(secretType);
secretAuth.setSecret(secret); secretAuth.setSecret(secret);
pushUrl = secretAuth.getPushUrl(endpoint); pushUrl = secretAuth.getPushUrl(endpoint);
Map<String, String> requestHeader = secretAuth.getRequestHeaders(); Map<String, String> requestHeader = secretAuth.getRequestHeaders();
requestHeader.put(DpsHeaders.CONTENT_TYPE, "application/json"); requestHeader.put(DpsHeaders.CONTENT_TYPE, "application/json");
requestHeader.put(DpsHeaders.CORRELATION_ID, headerAttributes.get(DpsHeaders.CORRELATION_ID)); requestHeader.put(DpsHeaders.CORRELATION_ID, headerAttributes.get(DpsHeaders.CORRELATION_ID));
requestHeader.put(DpsHeaders.DATA_PARTITION_ID, headerAttributes.get(DpsHeaders.DATA_PARTITION_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(); HttpRequest request =
HttpResponse response = httpClient.send(request); HttpRequest.post()
LOGGER.debug("Sending out notification to endpoint: " + endpoint); .url(pushUrl)
return response; .headers(requestHeader)
} .body(pubsubMessage)
.connectionTimeout(oqmConfigurationProperties.getWaitingTime())
.build();
HttpResponse response = httpClient.send(request);
log.debug("Sending out notification to endpoint: " + endpoint);
return response;
}
} }
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment