Skip to content
Snippets Groups Projects
Commit ffe6dfc2 authored by Riabokon Stanislav(EPAM)[GCP]'s avatar Riabokon Stanislav(EPAM)[GCP]
Browse files

Moved GC to CImpl (GONRG-10420)

parent 7499211e
No related branches found
No related tags found
1 merge request!988Moved GC to CImpl (GONRG-10420)
Showing
with 96 additions and 1384 deletions
...@@ -12,3 +12,36 @@ gc-dev2-test: ...@@ -12,3 +12,36 @@ gc-dev2-test:
gc-test: gc-test:
variables: variables:
OPA_INTEGRATION_ENABLED: "true" OPA_INTEGRATION_ENABLED: "true"
download_gc_plugins:
image: maven:3.8.3-openjdk-17-slim
stage: build
variables:
GC_OSM_PACKAGE_REGISTRY_URL: "https://community.opengroup.org/api/v4/projects/1476/packages/maven"
GC_OSM_VERSION: "0.27.2"
GC_OBM_PACKAGE_REGISTRY_URL: "https://community.opengroup.org/api/v4/projects/1475/packages/maven"
GC_OBM_VERSION: "0.27.2"
GC_OQM_PACKAGE_REGISRTY_URL: "https://community.opengroup.org/api/v4/projects/1477/packages/maven"
GC_OQM_VERSION: "0.27.2"
GC_APD_PACKAGE_REGISTRY_URL: "https://community.opengroup.org/api/v4/projects/1480/packages/maven"
GC_APD_VERSION: "0.27.2"
artifacts:
paths:
- ./tmp-gc/*.jar
when: always
expire_in: 1 days
script:
- mvn dependency:copy -DrepoUrl=$GC_OSM_PACKAGE_REGISTRY_URL -Dartifact="org.opengroup.osdu:gc-osm-datastore:$GC_OSM_VERSION:jar:plugin" -Dtransitive=false -DoutputDirectory="./tmp-gc"
- mvn dependency:copy -DrepoUrl=$GC_OBM_PACKAGE_REGISTRY_URL -Dartifact="org.opengroup.osdu:gc-obm-gs:$GC_OBM_VERSION:jar:plugin" -Dtransitive=false -DoutputDirectory="./tmp-gc"
- mvn dependency:copy -DrepoUrl=$GC_OQM_PACKAGE_REGISRTY_URL -Dartifact="org.opengroup.osdu:gc-oqm-pubsub:$GC_OQM_VERSION:jar:plugin" -Dtransitive=false -DoutputDirectory="./tmp-gc"
- mvn dependency:copy -DrepoUrl=$GC_APD_PACKAGE_REGISRTY_URL -Dartifact="org.opengroup.osdu:gc-apd-acc:$GC_APD_VERSION:jar:plugin" -Dtransitive=false -DoutputDirectory="./tmp-gc"
only:
variables:
- $GC == '1'
gc-containerize-gitlab:
needs: ["gc-compile-and-unit-test", "download_gc_plugins"]
gc-containerize-gcr:
needs: ["gc-compile-and-unit-test", "download_gc_plugins"]
...@@ -5,7 +5,6 @@ entire metadata life-cycle such as ingestion (persistence), modification, deleti ...@@ -5,7 +5,6 @@ entire metadata life-cycle such as ingestion (persistence), modification, deleti
## Table of Contents <a name="TOC"></a> ## Table of Contents <a name="TOC"></a>
* [Getting started](#Getting-started) * [Getting started](#Getting-started)
* [Mappers](#Mappers)
* [Settings and Configuration](#Settings-and-Configuration) * [Settings and Configuration](#Settings-and-Configuration)
* [Run service](#Run-service) * [Run service](#Run-service)
* [Testing](#Testing) * [Testing](#Testing)
...@@ -19,24 +18,6 @@ entire metadata life-cycle such as ingestion (persistence), modification, deleti ...@@ -19,24 +18,6 @@ entire metadata life-cycle such as ingestion (persistence), modification, deleti
These instructions will get you a copy of the project up and running on your local machine for development and testing 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. purposes. See deployment for notes on how to deploy the project on a live system.
## Mappers
This is a universal solution created using EPAM OSM, OBM and OQM mappers technology. It allows you to work with various
implementations of KV stores, Blob stores and message brokers.
For more information about mappers:
- [OSM Readme](https://community.opengroup.org/osdu/platform/system/lib/cloud/gcp/osm/-/blob/main/README.md)
- [OBM Readme](https://community.opengroup.org/osdu/platform/system/lib/cloud/gcp/obm/-/blob/master/README.md)
- [OQM Readme](https://community.opengroup.org/osdu/platform/system/lib/cloud/gcp/oqm/-/blob/master/README.md)
### Limitations of the current version
In the current version, the mappers are equipped with several drivers to the stores and the message broker:
- OSM (mapper for KV-data): Google Datastore; Postgres
- OBM (mapper to Blob stores): Google Cloud Storage (GCS); MinIO
- OQM (mapper to message brokers): Google PubSub; RabbitMQ
## Settings and Configuration ## Settings and Configuration
### Requirements: ### Requirements:
...@@ -48,8 +29,6 @@ In the current version, the mappers are equipped with several drivers to the sto ...@@ -48,8 +29,6 @@ In the current version, the mappers are equipped with several drivers to the sto
2. For Google Cloud only 2. For Google Cloud only
- GCloud SDK with java (latest version) - GCloud SDK with java (latest version)
### Baremetal Service Configuration:
[Baremetal service configuration ](docs/baremetal/README.md)
### Google Cloud Service Configuration: ### Google Cloud Service Configuration:
[Google Cloud service configuration ](docs/gc/README.md) [Google Cloud service configuration ](docs/gc/README.md)
...@@ -139,12 +118,9 @@ cd provider/storage-gc/ && mvn spring-boot:run ...@@ -139,12 +118,9 @@ cd provider/storage-gc/ && mvn spring-boot:run
This section describes how to run cloud OSDU E2E tests. This section describes how to run cloud OSDU E2E tests.
### Baremetal test configuration:
[Baremetal service configuration ](docs/baremetal/README.md)
### Google Cloud test configuration: ### Google Cloud test configuration:
[Google Cloud service configuration ](docs/gc/README.md) [Google Cloud service configuration ](docs/gc/README.md)
## Deployment ## Deployment
Storage Service is compatible with App Engine Flexible Environment and Cloud Run. Storage Service is compatible with App Engine Flexible Environment and Cloud Run.
...@@ -152,8 +128,8 @@ Storage Service is compatible with App Engine Flexible Environment and Cloud Run ...@@ -152,8 +128,8 @@ Storage Service is compatible with App Engine Flexible Environment and Cloud Run
* To deploy into Cloud run, please, use this documentation: * To deploy into Cloud run, please, use this documentation:
https://cloud.google.com/run/docs/quickstarts/build-and-deploy https://cloud.google.com/run/docs/quickstarts/build-and-deploy
* To deploy into App Engine, please, use this documentation: * To deploy into GKE, please, use this documentation:
https://cloud.google.com/appengine/docs/flexible/java/quickstart https://cloud.google.com/kubernetes-engine/docs/deploy-app-cluster
## Tutorial ## Tutorial
......
...@@ -8,6 +8,13 @@ ENV PROVIDER_NAME $PROVIDER_NAME ...@@ -8,6 +8,13 @@ ENV PROVIDER_NAME $PROVIDER_NAME
ARG PORT ARG PORT
ENV PORT $PORT ENV PORT $PORT
ENV LOADER_PATH="gc/"
COPY tmp-gc/gc-oqm-pubsub-*.jar gc/oqm-pubsub.jar
COPY tmp-gc/gc-obm-gs-*.jar gc/obm-gs.jar
COPY tmp-gc/gc-osm-datastore-*.jar gc/osm-datastore.jar
COPY tmp-gc/gc-apd-acc-*.jar gc/apd-acc.jar
# Copy the jar to the production image from the builder stage. # Copy the jar to the production image from the builder stage.
COPY provider/storage-${PROVIDER_NAME}/target/storage-${PROVIDER_NAME}-*-spring-boot.jar storage-${PROVIDER_NAME}.jar COPY provider/storage-${PROVIDER_NAME}/target/storage-${PROVIDER_NAME}-*-spring-boot.jar storage-${PROVIDER_NAME}.jar
...@@ -18,4 +25,10 @@ RUN groupadd -g 10001 -r nonroot \ ...@@ -18,4 +25,10 @@ RUN groupadd -g 10001 -r nonroot \
USER 10001:10001 USER 10001:10001
# Run the web service on container startup. # Run the web service on container startup.
CMD java -Djava.security.egd=file:/dev/./urandom -Dserver.port=${PORT} -Dlog4j.formatMsgNoLookups=true -jar /app/storage-${PROVIDER_NAME}.jar CMD java --add-opens java.base/java.lang=ALL-UNNAMED \
--add-opens java.base/java.lang.reflect=ALL-UNNAMED \
-Djava.security.egd=file:/dev/./urandom \
-Dserver.port=${PORT} \
-Dlog4j.formatMsgNoLookups=true \
-Dloader.main=org.opengroup.osdu.storage.provider.gcp.StorageApplicationGCP \
-jar /app/storage-${PROVIDER_NAME}.jar
\ No newline at end of file
This diff is collapsed.
provider/storage-gc/docs/anthos/pics/client.png

89.9 KiB

provider/storage-gc/docs/anthos/pics/rabbit.PNG

9.38 KiB

provider/storage-gc/docs/anthos/pics/sa.png

51.7 KiB

...@@ -4,12 +4,14 @@ ...@@ -4,12 +4,14 @@
* [Environment variables](#Environment-variables) * [Environment variables](#Environment-variables)
* [Common properties for all environments](#Common-properties-for-all-environments) * [Common properties for all environments](#Common-properties-for-all-environments)
* [For Mappers to activate drivers](#For-Mappers-to-activate-drivers)
* [Datastore configuration](#Datastore-configuration) * [Datastore configuration](#Datastore-configuration)
* [Pubsub configuration](#Pubsub-configuration) * [Pub/Sub configuration](#Pubsub-configuration)
* [Google Cloud service configuration](#ObjectStoreConfig) * [Google Cloud service configuration](#ObjectStoreConfig)
* [Google loud service account configuration](#Google-cloud-service-account-configuration) * [Google_Cloud service account configuration](#Google-cloud-service-account-configuration)
* [Run args](#run-args)
* [Running E2E Tests](#running-e2e-tests)
* [License](#License) * [License](#License)
*
## Environment variables ## Environment variables
Define the following environment variables. Define the following environment variables.
...@@ -50,7 +52,6 @@ Defined in default application property file but possible to override: ...@@ -50,7 +52,6 @@ Defined in default application property file but possible to override:
| `PARTITION_API` | ex `http://localhost:8081/api/partition/v1` | Partition service endpoint | no | - | | `PARTITION_API` | ex `http://localhost:8081/api/partition/v1` | Partition service endpoint | no | - |
| `GOOGLE_APPLICATION_CREDENTIALS` | ex `/path/to/directory/service-key.json` | Service account credentials, you only need this if running locally | yes | <https://console.cloud.google.com/iam-admin/serviceaccounts> | | `GOOGLE_APPLICATION_CREDENTIALS` | ex `/path/to/directory/service-key.json` | Service account credentials, you only need this if running locally | yes | <https://console.cloud.google.com/iam-admin/serviceaccounts> |
| `PARTITION_PROPERTIES_STORAGE_BUCKET_NAME` | ex `storage.bucket.name` | Name of partition property for storage bucket name value | yes | - | | `PARTITION_PROPERTIES_STORAGE_BUCKET_NAME` | ex `storage.bucket.name` | Name of partition property for storage bucket name value | yes | - |
| `SYSTEM_PARTITION_ID` | ex `system` | System partition ID |
These variables define service behavior, and are used to switch between `Reference` or `Google Cloud` environments, their overriding and usage in mixed mode was not tested. These variables define service behavior, and are used to switch between `Reference` or `Google Cloud` environments, their overriding and usage in mixed mode was not tested.
Usage of spring profiles is preferred. Usage of spring profiles is preferred.
...@@ -58,22 +59,8 @@ Usage of spring profiles is preferred. ...@@ -58,22 +59,8 @@ Usage of spring profiles is preferred.
| name | value | description | sensitive? | source | | name | value | description | sensitive? | source |
|--------------------------|---------------------------|---------------------------------------------------------------------------------------------------------------------------|------------|--------| |--------------------------|---------------------------|---------------------------------------------------------------------------------------------------------------------------|------------|--------|
| `PARTITION_AUTH_ENABLED` | ex `true` or `false` | Disable or enable auth token provisioning for requests to Partition service | no | - | | `PARTITION_AUTH_ENABLED` | ex `true` or `false` | Disable or enable auth token provisioning for requests to Partition service | no | - |
| `OQMDRIVER` | `rabbitmq` or `pubsub` | Oqm driver mode that defines which message broker will be used | no | - |
| `OSMDRIVER` | `datastore` or `postgres` | Osm driver mode that defines which KV storage will be used | no | - |
| `OBMDRIVER` | `gcs` or `minio` | Obm driver mode that defines which object storage will be used | no | - |
| `SERVICE_TOKEN_PROVIDER` | `GCP` or `OPENID` | Service account token provider, `GCP` means use Google service account `OPEIND` means use OpenId provider like `Keycloak` | no | - | | `SERVICE_TOKEN_PROVIDER` | `GCP` or `OPENID` | Service account token provider, `GCP` means use Google service account `OPEIND` means use OpenId provider like `Keycloak` | no | - |
### For Mappers to activate drivers
| name | value | description |
|-----------|-----------|---------------------------------------------------------|
| OSMDRIVER | datastore | to activate **OSM** driver for **Google Datastore** |
| OSMDRIVER | postgres | to activate **OSM** driver for **PostgreSQL** |
| OBMDRIVER | gcs | to activate **OBM** driver for **Google Cloud Storage** |
| OBMDRIVER | minio | to activate **OBM** driver for **MinIO** |
| OQMDRIVER | pubsub | to activate **OQM** driver for **Google PubSub** |
| OQMDRIVER | rabbitmq | to activate **OQM** driver for **Rabbit MQ** |
## Datastore configuration ## Datastore configuration
There must be a namespace for each tenant, which is the same as the tenant name. There must be a namespace for each tenant, which is the same as the tenant name.
...@@ -100,9 +87,9 @@ indexes: ...@@ -100,9 +87,9 @@ indexes:
``` ```
## PubSub configuration ## Pub/Sub configuration
At PubSub should be created set of topics and subscriptions. At Pub/Sub should be created set of topics and subscriptions.
| topic name | subscription name | description | sensitive? | env var to override | | topic name | subscription name | description | sensitive? | env var to override |
|------------------------------------|---------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|------------|-------------------------------------------------------------------------| |------------------------------------|---------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|------------|-------------------------------------------------------------------------|
...@@ -154,6 +141,21 @@ TBD ...@@ -154,6 +141,21 @@ TBD
|----------------| |----------------|
| - | | - |
### Run args
In order to run Legal with Java 17 additional run args must be provided:
```bash
--add-opens java.base/java.lang=ALL-UNNAMED --add-opens java.base/java.lang.reflect=ALL-UNNAMED
```
```bash
CMD java --add-opens java.base/java.lang=ALL-UNNAMED \
--add-opens java.base/java.lang.reflect=ALL-UNNAMED \
-Dloader.main=org.opengroup.osdu.storage.provider.gcp.StorageApplicationGCP \
-jar /app/secret-${PROVIDER_NAME}.jar
```
### Running E2E Tests ### Running E2E Tests
You will need to have the following environment variables defined. You will need to have the following environment variables defined.
......
<?xml version="1.0" encoding="UTF-8"?>
<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0 http://maven.apache.org/xsd/settings-1.0.0.xsd">
<servers>
<server>
<id>os-core</id>
<username>slb-des-ext-collaboration</username>
<!-- Treat this auth token like a password. Do not share it with anyone, including Microsoft support. -->
<!-- The generated token expires on or before 11/14/2019 -->
<password>${VSTS_FEED_TOKEN}</password>
</server>
</servers>
</settings>
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<!-- <!--
~ Copyright 2020-2023 Google LLC ~ Copyright 2020-2025 Google LLC
~ Copyright 2020-2023 EPAM Systems, Inc ~ Copyright 2020-2025 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.
...@@ -16,8 +16,8 @@ ...@@ -16,8 +16,8 @@
~ limitations under the License. ~ limitations under the License.
--> -->
<project xmlns="http://maven.apache.org/POM/4.0.0" <project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<parent> <parent>
...@@ -28,7 +28,7 @@ ...@@ -28,7 +28,7 @@
</parent> </parent>
<artifactId>storage-gc</artifactId> <artifactId>storage-gc</artifactId>
<description>Google cloud related implementation staff.</description> <description>Storage Service</description>
<packaging>jar</packaging> <packaging>jar</packaging>
<properties> <properties>
...@@ -58,79 +58,15 @@ ...@@ -58,79 +58,15 @@
<dependencies> <dependencies>
<dependency> <dependency>
<groupId>org.opengroup.osdu</groupId> <groupId>org.opengroup.osdu</groupId>
<artifactId>core-lib-gc</artifactId> <artifactId>storage-core-plus</artifactId>
<version>0.27.0-rc8</version>
</dependency>
<!-- Mappers -->
<dependency>
<groupId>org.opengroup.osdu</groupId>
<artifactId>osm</artifactId>
<version>0.27.0-rc3</version>
</dependency>
<dependency>
<groupId>org.opengroup.osdu</groupId>
<artifactId>oqm</artifactId>
<version>0.26.0</version>
</dependency>
<dependency>
<groupId>org.opengroup.osdu</groupId>
<artifactId>obm</artifactId>
<version>0.27.2</version>
</dependency>
<dependency>
<groupId>org.opengroup.osdu</groupId>
<artifactId>storage-core</artifactId>
<version>0.28.0-SNAPSHOT</version> <version>0.28.0-SNAPSHOT</version>
<exclusions>
<exclusion>
<groupId>org.mockito</groupId>
<artifactId>mockito-all</artifactId>
</exclusion>
<exclusion>
<groupId>org.powermock</groupId>
<artifactId>powermock-api-mockito</artifactId>
</exclusion>
</exclusions>
</dependency> </dependency>
<dependency> <dependency>
<groupId>ch.qos.logback.contrib</groupId> <groupId>ch.qos.logback.contrib</groupId>
<artifactId>logback-json-classic</artifactId> <artifactId>logback-jackson</artifactId>
<version>0.1.5</version> <version>0.1.5</version>
</dependency> </dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-config</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${spring-webmvc.version}</version>
</dependency>
<dependency>
<groupId>jakarta.annotation</groupId>
<artifactId>jakarta.annotation-api</artifactId>
<version>2.1.1</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!-- Testing packages -->
<dependency>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
<version>5.10.2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
</dependencies> </dependencies>
<build> <build>
...@@ -139,7 +75,7 @@ ...@@ -139,7 +75,7 @@
<plugin> <plugin>
<groupId>org.springframework.boot</groupId> <groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId> <artifactId>spring-boot-maven-plugin</artifactId>
<version>3.0.0</version> <version>3.2.2</version>
<configuration> <configuration>
<profiles> <profiles>
<profile> <profile>
...@@ -151,12 +87,6 @@ ...@@ -151,12 +87,6 @@
<spring.profiles.active>local</spring.profiles.active> <spring.profiles.active>local</spring.profiles.active>
</properties> </properties>
</profile> </profile>
<profile>
<id>dev</id>
<properties>
<spring.profiles.active>dev</spring.profiles.active>
</properties>
</profile>
</profiles> </profiles>
</configuration> </configuration>
<executions> <executions>
...@@ -167,20 +97,13 @@ ...@@ -167,20 +97,13 @@
<configuration> <configuration>
<classifier>spring-boot</classifier> <classifier>spring-boot</classifier>
<mainClass> <mainClass>
org.opengroup.osdu.storage.provider.gcp.StorageApplicationGCP org.springframework.boot.loader.launch.PropertiesLauncher
</mainClass> </mainClass>
</configuration> </configuration>
</execution> </execution>
</executions> </executions>
</plugin> </plugin>
<plugin>
<artifactId>maven-war-plugin</artifactId>
<configuration>
<failOnMissingWebXml>false</failOnMissingWebXml>
</configuration>
</plugin>
<plugin> <plugin>
<groupId>org.jacoco</groupId> <groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId> <artifactId>jacoco-maven-plugin</artifactId>
...@@ -203,4 +126,4 @@ ...@@ -203,4 +126,4 @@
</plugins> </plugins>
</build> </build>
</project> </project>
\ No newline at end of file
/* /*
* Copyright 2020-2022 Google LLC * Copyright 2020-2025 Google LLC
* Copyright 2020-2022 EPAM Systems, Inc * Copyright 2020-2025 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.
......
/* /*
* Copyright 2020-2022 Google LLC * Copyright 2020-2025 Google LLC
* Copyright 2020-2022 EPAM Systems, Inc * Copyright 2020-2025 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.
...@@ -15,19 +15,16 @@ ...@@ -15,19 +15,16 @@
* limitations under the License. * limitations under the License.
*/ */
package org.opengroup.osdu.storage.provider.gcp.messaging.config; package org.opengroup.osdu.storage.provider.gcp.logging.formatter;
import lombok.Data; import ch.qos.logback.contrib.jackson.JacksonJsonFormatter;
import org.springframework.boot.context.properties.ConfigurationProperties; import java.io.IOException;
import org.springframework.context.annotation.Configuration; import java.util.Map;
@Configuration
@ConfigurationProperties
@Data
public class MessagingConfigurationProperties {
private String legalTagsChangedTopicName;
private String legalTagsChangedSubscriptionName;
private String storageServiceAccountEmail;
public class GoogleJsonFormatter extends JacksonJsonFormatter {
@Override
public String toJsonString(Map map) throws IOException {
map.put("severity", map.remove("level"));
return super.toJsonString(map);
}
} }
/*
* Copyright 2020-2023 Google LLC
* Copyright 2020-2023 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.storage.provider.gcp.messaging.config;
import java.util.Arrays;
import jakarta.annotation.PostConstruct;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.opengroup.osdu.storage.StorageApplication;
import org.opengroup.osdu.storage.provider.gcp.web.config.WebAppMainContextConfiguration;
import org.opengroup.osdu.storage.swagger.SwaggerConfiguration;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.FilterType;
import org.springframework.context.annotation.PropertySource;
/**
* This context configuration serves for message receiving configuration not bounded to request scope.
* Also, configured context does not serve incoming requests.
*/
@Slf4j
@Configuration
@EnableConfigurationProperties
@PropertySource("classpath:application.properties")
@RequiredArgsConstructor
@ComponentScan(value = {
"org.opengroup.osdu"
},
excludeFilters = {
@ComponentScan.Filter(
type = FilterType.ASSIGNABLE_TYPE,
value = {
StorageApplication.class,
WebAppMainContextConfiguration.class,
SwaggerConfiguration.class
}
)
}
)
public class MessagingCustomContextConfiguration {
private final ApplicationContext applicationContext;
@PostConstruct
public void setUp() {
log.debug("Messaging context initialized with id: {}.", applicationContext.getId());
log.debug("Messaging context status: {}.", applicationContext);
String[] allBeansNames = applicationContext.getBeanDefinitionNames();
log.debug("Messaging context beans definitions: {}.", Arrays.toString(allBeansNames));
}
}
/*
* Copyright 2020-2022 Google LLC
* Copyright 2020-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
*
* 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.storage.provider.gcp.messaging.jobs;
import static java.util.Collections.singletonList;
import java.util.AbstractMap;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import lombok.RequiredArgsConstructor;
import org.opengroup.osdu.core.common.cache.ICache;
import org.opengroup.osdu.core.common.logging.JaxRsDpsLog;
import org.opengroup.osdu.core.common.model.http.DpsHeaders;
import org.opengroup.osdu.core.common.model.indexer.OperationType;
import org.opengroup.osdu.core.common.model.legal.LegalCompliance;
import org.opengroup.osdu.core.common.model.legal.jobs.ComplianceChangeInfo;
import org.opengroup.osdu.core.common.model.legal.jobs.ComplianceUpdateStoppedException;
import org.opengroup.osdu.core.common.model.legal.jobs.ILegalComplianceChangeService;
import org.opengroup.osdu.core.common.model.legal.jobs.LegalTagChanged;
import org.opengroup.osdu.core.common.model.legal.jobs.LegalTagChangedCollection;
import org.opengroup.osdu.core.common.model.storage.PubSubInfo;
import org.opengroup.osdu.core.common.model.storage.RecordMetadata;
import org.opengroup.osdu.core.common.model.storage.RecordState;
import org.opengroup.osdu.storage.logging.StorageAuditLogger;
import org.opengroup.osdu.storage.provider.interfaces.IMessageBus;
import org.opengroup.osdu.storage.provider.interfaces.IRecordsMetadataRepository;
import org.springframework.stereotype.Service;
@Service
@RequiredArgsConstructor
public class LegalComplianceChangeServiceGcpImpl implements ILegalComplianceChangeService {
private final IRecordsMetadataRepository recordsRepo;
private final IMessageBus messageBus;
private final StorageAuditLogger auditLogger;
private final JaxRsDpsLog logger;
// not conventional field name due to bean qualifiers in a core module
private final ICache<String, String> LegalTagCache;
private final long maxRunningTimeMills = 115000;
@Override
public Map<String, LegalCompliance> updateComplianceOnRecords(LegalTagChangedCollection legalTagsChanged,
DpsHeaders headers) throws ComplianceUpdateStoppedException {
Map<String, LegalCompliance> output = new HashMap<>();
long currentTimeMills;
long start = System.currentTimeMillis();
for (LegalTagChanged lt : legalTagsChanged.getStatusChangedTags()) {
ComplianceChangeInfo complianceChangeInfo = this.getComplianceChangeInfo(lt);
if (complianceChangeInfo == null) {
continue;
}
AbstractMap.SimpleEntry<String, List<RecordMetadata>> results = this.recordsRepo
.queryByLegal(lt.getChangedTagName(), complianceChangeInfo.getCurrent(), 500);
while (results.getValue() != null && !results.getValue().isEmpty()) {
currentTimeMills = System.currentTimeMillis() - start;
if (currentTimeMills >= maxRunningTimeMills) {
throw new ComplianceUpdateStoppedException(currentTimeMills / 1000);
}
List<RecordMetadata> recordsMetadata = results.getValue();
PubSubInfo[] pubsubInfos = this.updateComplianceStatus(complianceChangeInfo, recordsMetadata, output);
StringBuilder recordsId = new StringBuilder();
for (RecordMetadata recordMetadata : recordsMetadata) {
recordsId.append(", ").append(recordMetadata.getId());
}
this.recordsRepo.createOrUpdate(recordsMetadata, Optional.empty());
this.messageBus.publishMessage(headers, pubsubInfos);
this.auditLogger.updateRecordsComplianceStateSuccess(
singletonList("[" + recordsId.substring(2) + "]"));
results = this.recordsRepo.queryByLegal(lt.getChangedTagName(), complianceChangeInfo.getCurrent(), 500);
}
}
return output;
}
private PubSubInfo[] updateComplianceStatus(ComplianceChangeInfo complianceChangeInfo,
List<RecordMetadata> recordMetadata, Map<String, LegalCompliance> output) {
PubSubInfo[] pubsubInfo = new PubSubInfo[recordMetadata.size()];
int i = 0;
for (RecordMetadata rm : recordMetadata) {
rm.getLegal().setStatus(complianceChangeInfo.getNewState());
rm.setStatus(complianceChangeInfo.getNewRecordState());
pubsubInfo[i] = new PubSubInfo(rm.getId(), rm.getKind(), complianceChangeInfo.getPubSubEvent());
output.put(rm.getId(), complianceChangeInfo.getNewState());
i++;
}
return pubsubInfo;
}
private ComplianceChangeInfo getComplianceChangeInfo(LegalTagChanged lt) {
ComplianceChangeInfo output = null;
if (lt.getChangedTagStatus().equalsIgnoreCase("compliant")) {
output = new ComplianceChangeInfo(LegalCompliance.compliant, OperationType.update, RecordState.active);
} else if (lt.getChangedTagStatus().equalsIgnoreCase("incompliant")) {
this.LegalTagCache.delete(lt.getChangedTagName());
output = new ComplianceChangeInfo(LegalCompliance.incompliant, OperationType.delete, RecordState.deleted);
} else {
this.logger.warning(String.format("Unknown LegalTag compliance status received %s %s",
lt.getChangedTagStatus(), lt.getChangedTagName()));
}
return output;
}
}
/*
* Copyright 2020-2022 Google LLC
* Copyright 2020-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
*
* 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.storage.provider.gcp.messaging.jobs;
import com.google.gson.Gson;
import java.util.Map;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.opengroup.osdu.core.common.model.legal.LegalCompliance;
import org.opengroup.osdu.core.common.model.legal.jobs.ComplianceUpdateStoppedException;
import org.opengroup.osdu.core.common.model.legal.jobs.LegalTagChangedCollection;
import org.opengroup.osdu.core.common.model.legal.jobs.LegalTagConsistencyValidator;
import org.opengroup.osdu.core.gcp.oqm.model.OqmMessage;
import org.opengroup.osdu.storage.provider.gcp.messaging.scope.override.ThreadDpsHeaders;
@Slf4j
@RequiredArgsConstructor
public class LegalTagChangedProcessing {
private final LegalTagConsistencyValidator legalTagConsistencyValidator;
private final LegalComplianceChangeServiceGcpImpl legalComplianceChangeServiceGcp;
private final ThreadDpsHeaders dpsHeaders;
public void process(OqmMessage oqmMessage) throws ComplianceUpdateStoppedException {
String pubsubMessage = oqmMessage.getData();
LegalTagChangedCollection dto = (new Gson()).fromJson(pubsubMessage, LegalTagChangedCollection.class);
LegalTagChangedCollection validDto = this.legalTagConsistencyValidator.checkLegalTagStatusWithLegalService(dto);
log.debug("LegalTags changed status validation via Legal service: {}.", validDto);
Map<String, LegalCompliance> stringLegalComplianceMap = this.legalComplianceChangeServiceGcp.updateComplianceOnRecords(validDto, dpsHeaders);
log.debug("Updated compliance on records: {}.", stringLegalComplianceMap);
}
}
/*
* Copyright 2020-2023 Google LLC
* Copyright 2020-2023 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.storage.provider.gcp.messaging.jobs;
import static org.springframework.beans.factory.config.BeanDefinition.SCOPE_SINGLETON;
import java.util.Map;
import jakarta.annotation.PostConstruct;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.opengroup.osdu.core.common.model.http.AppException;
import org.opengroup.osdu.core.common.model.legal.jobs.LegalTagConsistencyValidator;
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.OqmDriver;
import org.opengroup.osdu.core.gcp.oqm.model.OqmDestination;
import org.opengroup.osdu.core.gcp.oqm.model.OqmMessageReceiver;
import org.opengroup.osdu.core.gcp.oqm.model.OqmSubscriber;
import org.opengroup.osdu.core.gcp.oqm.model.OqmSubscription;
import org.opengroup.osdu.core.gcp.oqm.model.OqmSubscriptionQuery;
import org.opengroup.osdu.core.gcp.oqm.model.OqmTopic;
import org.opengroup.osdu.storage.provider.gcp.messaging.config.MessagingConfigurationProperties;
import org.opengroup.osdu.storage.provider.gcp.messaging.scope.override.ThreadDpsHeaders;
import org.opengroup.osdu.storage.provider.gcp.messaging.thread.ThreadScopeContextHolder;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Scope;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;
/**
* Runs once on the service start. Fetches all tenants' oqm destinations for TOPIC existence. If exists - searches for pull SUBSCRIPTION existence. Creates
* SUBSCRIPTION if doesn't exist. Then subscribe itself on SUBSCRIPTION.
*/
@Slf4j
@Component
@Scope(SCOPE_SINGLETON)
@ConditionalOnProperty(name = "oqmDriver")
@RequiredArgsConstructor
public class OqmSubscriberManager {
private final MessagingConfigurationProperties configurationProperties;
private final ITenantFactory tenantInfoFactory;
private final OqmDriver driver;
private final LegalTagConsistencyValidator legalTagConsistencyValidator;
private final LegalComplianceChangeServiceGcpImpl legalComplianceChangeServiceGcp;
private final ThreadDpsHeaders dpsHeaders;
@PostConstruct
void postConstruct() {
log.debug("OqmSubscriberManager bean constructed. Provisioning STARTED.");
//Get all Tenant infos
for (TenantInfo tenantInfo : tenantInfoFactory.listTenantInfo()) {
String dataPartitionId = tenantInfo.getDataPartitionId();
String tagsChangedTopicName = configurationProperties.getLegalTagsChangedTopicName();
log.debug("* OqmSubscriberManager on provisioning tenant {}:", dataPartitionId);
log.debug("* * OqmSubscriberManager on check for topic {} existence:",
tagsChangedTopicName);
OqmTopic topic = driver.getTopic(tagsChangedTopicName, getDestination(tenantInfo)).orElse(null);
if (topic == null) {
log.error("* * OqmSubscriberManager on check for topic {} existence: ABSENT.",
tagsChangedTopicName);
throw new AppException(
HttpStatus.INTERNAL_SERVER_ERROR.value(),
"Required topic not exists.",
String.format(
"Required topic not exists. Create topic: %s for tenant: %s and restart service.",
tagsChangedTopicName, dataPartitionId
)
);
}
String legalTagsChangedSubscriptionName = configurationProperties.getLegalTagsChangedSubscriptionName();
log.debug("* * OqmSubscriberManager on check for subscription {} existence:", legalTagsChangedSubscriptionName);
OqmSubscriptionQuery query = OqmSubscriptionQuery.builder()
.namePrefix(legalTagsChangedSubscriptionName)
.subscriberable(true)
.build();
OqmSubscription subscription = driver.listSubscriptions(topic, query, getDestination(tenantInfo)).stream().findAny().orElse(null);
if (subscription == null) {
log.error("* * OqmSubscriberManager on check for subscription {} existence: ABSENT. Will create.", legalTagsChangedSubscriptionName);
throw new AppException(
HttpStatus.INTERNAL_SERVER_ERROR.value(),
"Required subscription not exists.",
String.format(
"Required subscription not exists. Create subscription: %s for tenant: %s and restart service.",
legalTagsChangedSubscriptionName,
dataPartitionId
)
);
} else {
log.debug("* * OqmSubscriberManager on check for subscription {} existence: PRESENT.", legalTagsChangedSubscriptionName);
}
log.debug("* * OqmSubscriberManager on registering Subscriber for tenant {}, subscription {}",
dataPartitionId,
legalTagsChangedSubscriptionName);
registerSubscriber(tenantInfo, subscription);
log.debug("* * OqmSubscriberManager on provisioning for tenant {}, subscription {}: Subscriber REGISTERED.",
dataPartitionId,
subscription.getName());
log.debug("* OqmSubscriberManager on provisioning tenant {}: COMPLETED.",
dataPartitionId);
}
log.debug("OqmSubscriberManager bean constructed. Provisioning COMPLETED.");
}
private void registerSubscriber(TenantInfo tenantInfo, OqmSubscription subscription) {
OqmDestination destination = getDestination(tenantInfo);
OqmMessageReceiver receiver = (oqmMessage, oqmAckReplier) -> {
String pubsubMessage = oqmMessage.getData();
Map<String, String> headerAttributes = oqmMessage.getAttributes();
log.debug(pubsubMessage + " " + headerAttributes + " " + oqmMessage.getId());
boolean ackedNacked = false;
try {
dpsHeaders.setThreadContext(headerAttributes);
LegalTagChangedProcessing legalTagChangedProcessing =
new LegalTagChangedProcessing(legalTagConsistencyValidator, legalComplianceChangeServiceGcp, dpsHeaders);
legalTagChangedProcessing.process(oqmMessage);
log.debug("OQM message handling for tenant {} topic {} subscription {}. ACK. Message: -data: {}, attributes: {}.",
dpsHeaders.getPartitionId(),
configurationProperties.getLegalTagsChangedTopicName(),
configurationProperties.getLegalTagsChangedSubscriptionName(),
pubsubMessage,
StringUtils.join(headerAttributes)
);
oqmAckReplier.ack();
ackedNacked = true;
} catch (Exception e) {
log.error("OQM message handling error for tenant {} topic {} subscription {}. Message: -data: {}, attributes: {}, error: {}.",
dpsHeaders.getPartitionId(),
configurationProperties.getLegalTagsChangedTopicName(),
configurationProperties.getLegalTagsChangedSubscriptionName(),
pubsubMessage,
StringUtils.join(headerAttributes),
e
);
} finally {
if (!ackedNacked) {
oqmAckReplier.nack();
}
ThreadScopeContextHolder.currentThreadScopeAttributes().clear();
}
};
OqmSubscriber subscriber = OqmSubscriber.builder().subscription(subscription).messageReceiver(receiver).build();
driver.subscribe(subscriber, destination);
log.debug("Just subscribed at topic {} subscription {} for tenant {}.",
subscription.getTopics().get(0).getName(), subscription.getName(), tenantInfo.getDataPartitionId());
}
private OqmDestination getDestination(TenantInfo tenantInfo) {
return OqmDestination.builder().partitionId(tenantInfo.getDataPartitionId()).build();
}
}
/*
* Copyright 2020-2022 Google LLC
* Copyright 2020-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
*
* 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.storage.provider.gcp.messaging.scope.override;
import java.util.Objects;
import lombok.extern.slf4j.Slf4j;
import org.opengroup.osdu.storage.provider.gcp.messaging.thread.ThreadScope;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.stereotype.Component;
@Slf4j
@Component
public class ScopeModifierPostProcessor implements BeanFactoryPostProcessor {
public static final String SCOPE_THREAD = "scope_thread";
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory factory) throws BeansException {
factory.registerScope(SCOPE_THREAD, new ThreadScope());
for (String beanName : factory.getBeanDefinitionNames()) {
BeanDefinition beanDef = factory.getBeanDefinition(beanName);
if (Objects.equals(beanDef.getScope(), "request")) {
beanDef.setScope(SCOPE_THREAD);
log.debug("Scope has been overridden for bean: {}", beanDef.getBeanClassName());
}
}
}
}
/*
* Copyright 2020-2022 Google LLC
* Copyright 2020-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
*
* 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.storage.provider.gcp.messaging.scope.override;
import static org.springframework.context.annotation.ScopedProxyMode.TARGET_CLASS;
import java.util.Map;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.opengroup.osdu.core.auth.TokenProvider;
import org.opengroup.osdu.core.common.model.http.DpsHeaders;
import org.opengroup.osdu.storage.provider.gcp.messaging.config.MessagingConfigurationProperties;
import org.springframework.context.annotation.Primary;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
/**
* Original class bean configuration bounded to request scope, extend purpose is to unbound it. Due to OQM specific, we cannot rely on events transferred via
* HTTP requests, only pull subscriptions works with OQM. But this bean is configured only for Messaging context, original bean keeps working as usual for the
* web app context.
*/
@Slf4j
@Primary
@Component
@Scope(value = ScopeModifierPostProcessor.SCOPE_THREAD, proxyMode = TARGET_CLASS)
@RequiredArgsConstructor
public class ThreadDpsHeaders extends DpsHeaders {
private final MessagingConfigurationProperties properties;
private final TokenProvider tokenProvider;
public void setThreadContext(Map<String, String> headers) {
this.put(DpsHeaders.AUTHORIZATION, "Bearer " + tokenProvider.getIdToken());
this.put(DpsHeaders.USER_EMAIL, properties.getStorageServiceAccountEmail());
this.addFromMap(headers);
}
}
/*
* Copyright 2020-2022 Google LLC
* Copyright 2020-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
*
* 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.storage.provider.gcp.messaging.thread;
import java.util.Map;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.ObjectFactory;
import org.springframework.beans.factory.config.Scope;
@Slf4j
public class ThreadScope implements Scope {
public Object get(String name, ObjectFactory<?> factory) {
log.trace("Get bean:{} with factory: {} current Thread: {}", name, factory, Thread.currentThread().getName());
Object result = null;
Map<String, Object> hBeans = ThreadScopeContextHolder.currentThreadScopeAttributes().getBeanMap();
if (!hBeans.containsKey(name)) {
result = factory.getObject();
log.trace("No bean in context with name: {} factory provisioning result is: {} current Thread: {}", name, result, Thread.currentThread().getName());
hBeans.put(name, result);
} else {
result = hBeans.get(name);
}
return result;
}
public Object remove(String name) {
log.trace("Removing bean : {} current Thread: {}", name, Thread.currentThread().getName());
Object result = null;
Map<String, Object> hBeans = ThreadScopeContextHolder.currentThreadScopeAttributes().getBeanMap();
if (hBeans.containsKey(name)) {
result = hBeans.get(name);
hBeans.remove(name);
}
return result;
}
public void registerDestructionCallback(String name, Runnable callback) {
ThreadScopeContextHolder.currentThreadScopeAttributes().registerRequestDestructionCallback(name, callback);
}
public Object resolveContextualObject(String key) {
return null;
}
public String getConversationId() {
return Thread.currentThread().getName();
}
}
/*
* Copyright 2020-2022 Google LLC
* Copyright 2020-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
*
* 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.storage.provider.gcp.messaging.thread;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.lang.NonNull;
@Slf4j
@RequiredArgsConstructor
public class ThreadScopeAttributes {
protected final Map<String, Object> hBeans = new HashMap();
protected final Map<String, Runnable> hRequestDestructionCallbacks = new LinkedHashMap();
protected final Map<String, Object> getBeanMap() {
return this.hBeans;
}
protected final void registerRequestDestructionCallback(@NonNull String name, @NonNull Runnable callback) {
log.trace("Registering callback for: {} on runnable: {}", name, callback);
this.hRequestDestructionCallbacks.put(name, callback);
}
public final void clear() {
this.processDestructionCallbacks();
this.hBeans.clear();
}
private void processDestructionCallbacks() {
for (Map.Entry<String, Runnable> mapEntry : this.hRequestDestructionCallbacks.entrySet()) {
Runnable callback = mapEntry.getValue();
log.trace("Performing destruction callback for: {} on thread: {}", mapEntry.getKey(), Thread.currentThread().getName());
callback.run();
}
this.hRequestDestructionCallbacks.clear();
}
}
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