diff --git a/pom.xml b/pom.xml index f025a8d2773ea95f82e9515478160a7b7c9231e0..81a7b56fa923a6a7e28752bff26af60aae2c8bd7 100644 --- a/pom.xml +++ b/pom.xml @@ -43,6 +43,7 @@ <module>provider/legal-azure</module> <module>provider/legal-aws</module> <module>provider/legal-ibm</module> + <module>provider/legal-reference</module> </modules> <repositories> diff --git a/provider/legal-reference/Dockerfile b/provider/legal-reference/Dockerfile new file mode 100644 index 0000000000000000000000000000000000000000..b8dc68a58cb58f0f61c8e6c56239364aaa7141ae --- /dev/null +++ b/provider/legal-reference/Dockerfile @@ -0,0 +1,7 @@ +# Use the official AdoptOpenJDK for a base image. +# https://hub.docker.com/_/openjdk +FROM openjdk:8-slim +WORKDIR /app +COPY target/legal-reference-0.0.1-SNAPSHOT-spring-boot.jar legal.jar +# Run the web service on container startup. +CMD java -Djava.security.egd=file:/dev/./urandom -Dserver.port=8080 -jar /app/legal.jar diff --git a/provider/legal-reference/kubernetes/deployments/deployment-legal-service.yml b/provider/legal-reference/kubernetes/deployments/deployment-legal-service.yml new file mode 100644 index 0000000000000000000000000000000000000000..65fa3b4b7ec7c708f05e4b188e57fe51585ee5d7 --- /dev/null +++ b/provider/legal-reference/kubernetes/deployments/deployment-legal-service.yml @@ -0,0 +1,95 @@ +apiVersion: v1 +data: + AUTHORIZE_API: ${AUTHORIZE_API} + MONGO_DB_URL: ${MONGO_DB_URL} + MONGO_DB_USER: ${MONGO_DB_USER} + MONGO_DB_NAME: ${MONGO_DB_NAME} + REGION: ${REGION} +kind: ConfigMap +metadata: + labels: + app: legal + name: legal-config + namespace: default +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + generateName: legal-anthos + labels: + app: legal + name: legal + namespace: default +spec: + selector: + matchLabels: + app: legal + replicas: 1 + template: + metadata: + labels: + app: legal + spec: + containers: + - env: + - name: AUTHORIZE_API + valueFrom: + configMapKeyRef: + key: AUTHORIZE_API + name: legal-config + - name: MONGO_DB_URL + valueFrom: + configMapKeyRef: + key: MONGO_DB_URL + name: legal-config + - name: MONGO_DB_USER + valueFrom: + configMapKeyRef: + key: MONGO_DB_USER + name: legal-config + - name: MONGO_DB_PASSWORD + valueFrom: + secretKeyRef: + name: legal-secret + key: mongo.db.password + - name: MONGO_DB_NAME + valueFrom: + configMapKeyRef: + key: MONGO_DB_NAME + name: legal-config + - name: MB_RABBITMQ_URI + valueFrom: + secretKeyRef: + name: legal-secret + key: mb.rabbitmq.uri + - name: REGION + valueFrom: + configMapKeyRef: + key: REGION + name: legal-config + image: us.gcr.io/osdu-anthos-02/os-legal/anthos-legal:latest + name: os-legal-1-sha256-1 +--- +apiVersion: v1 +kind: Service +metadata: + name: legal + namespace: default +spec: + ports: + - protocol: TCP + port: 80 + targetPort: 8080 + selector: + app: legal + type: LoadBalancer +--- +apiVersion: v1 +data: + mongo.db.password: ${MONGO_DB_PASSWORD} + mb.rabbitmq.uri: ${MB_RABBITMQ_URI} +kind: Secret +metadata: + name: legal-secret + namespace: default +type: Opaque \ No newline at end of file diff --git a/provider/legal-reference/pom.xml b/provider/legal-reference/pom.xml new file mode 100644 index 0000000000000000000000000000000000000000..d1b0131f9977bc4521befd14654e9ecb8d3114fd --- /dev/null +++ b/provider/legal-reference/pom.xml @@ -0,0 +1,193 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + + <parent> + <groupId>org.opengroup.osdu.legal</groupId> + <artifactId>legal-service</artifactId> + <version>0.0.5-SNAPSHOT</version> + </parent> + + <artifactId>legal-reference</artifactId> + <version>0.0.1-SNAPSHOT</version> + <packaging>jar</packaging> + <name>legal-reference</name> + <description>Legal service for Anthos</description> + + <dependencies> + <dependency> + <groupId>org.projectlombok</groupId> + <artifactId>lombok</artifactId> + <optional>true</optional> + </dependency> + <dependency> + <groupId>org.opengroup.osdu.legal</groupId> + <artifactId>legal-core</artifactId> + <version>0.0.5-SNAPSHOT</version> + </dependency> + <dependency> + <groupId>org.opengroup.osdu</groupId> + <artifactId>os-core-common</artifactId> + </dependency> + <dependency> + <groupId>org.opengroup.osdu</groupId> + <artifactId>core-lib-gcp</artifactId> + <version>0.1.17</version> + </dependency> + <dependency> + <groupId>javax.servlet</groupId> + <artifactId>javax.servlet-api</artifactId> + <version>4.0.1</version> + <scope>provided</scope> + </dependency> + + <!-- https://mvnrepository.com/artifact/javax.inject/javax.inject --> + <dependency> + <groupId>javax.inject</groupId> + <artifactId>javax.inject</artifactId> + <version>1</version> + </dependency> + + <dependency> + <groupId>com.google.guava</groupId> + <artifactId>guava</artifactId> + <version>27.1-jre</version> + </dependency> + <dependency> + <groupId>com.google.code.gson</groupId> + <artifactId>gson</artifactId> + <version>2.8.5</version> + </dependency> + <dependency> + <groupId>commons-codec</groupId> + <artifactId>commons-codec</artifactId> + <version>1.12</version> + </dependency> + <dependency> + <groupId>com.fasterxml.jackson.core</groupId> + <artifactId>jackson-databind</artifactId> + <version>2.9.9.3</version> + </dependency> + <dependency> + <groupId>io.jsonwebtoken</groupId> + <artifactId>jjwt</artifactId> + <version>0.9.1</version> + <exclusions> + <exclusion> + <groupId>com.fasterxml.jackson.core</groupId> + <artifactId>jackson-databind</artifactId> + </exclusion> + </exclusions> + </dependency> + + <dependency> + <groupId>org.springframework.boot</groupId> + <artifactId>spring-boot-starter-data-mongodb</artifactId> + </dependency> + + <!-- https://mvnrepository.com/artifact/io.github.resilience4j/resilience4j-circuitbreaker --> + <dependency> + <groupId>io.github.resilience4j</groupId> + <artifactId>resilience4j-circuitbreaker</artifactId> + <version>0.17.0</version> + </dependency> + <!-- https://mvnrepository.com/artifact/io.github.resilience4j/resilience4j-retry --> + <dependency> + <groupId>io.github.resilience4j</groupId> + <artifactId>resilience4j-retry</artifactId> + <version>0.17.0</version> + </dependency> + <!-- https://mvnrepository.com/artifact/commons-lang/commons-lang --> + <dependency> + <groupId>commons-lang</groupId> + <artifactId>commons-lang</artifactId> + <version>2.6</version> + </dependency> + + <!-- Test Dependencies --> + <dependency> + <groupId>org.springframework.boot</groupId> + <artifactId>spring-boot-starter-test</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.springframework.security</groupId> + <artifactId>spring-security-test</artifactId> + <scope>test</scope> + </dependency> + + <!-- Test Dependencies --> + <dependency> + <groupId>junit</groupId> + <artifactId>junit</artifactId> + <version>4.12</version> + <scope>test</scope> + </dependency> + <!-- https://mvnrepository.com/artifact/org.powermock/powermock-api-mockito2 --> + <dependency> + <groupId>org.powermock</groupId> + <artifactId>powermock-api-mockito2</artifactId> + <version>2.0.2</version> + <scope>test</scope> + </dependency> + <!-- https://mvnrepository.com/artifact/org.powermock/powermock-module-junit4 --> + <dependency> + <groupId>org.powermock</groupId> + <artifactId>powermock-module-junit4</artifactId> + <version>2.0.2</version> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.mockito</groupId> + <artifactId>mockito-core</artifactId> + <version>3.0.0</version> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.codehaus.mojo</groupId> + <artifactId>cobertura-maven-plugin</artifactId> + <version>2.7</version> + <scope>test</scope> + </dependency> + + <!-- https://mvnrepository.com/artifact/com.github.stefanbirkner/system-rules --> + <dependency> + <groupId>com.github.stefanbirkner</groupId> + <artifactId>system-rules</artifactId> + <version>1.2.0</version> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.springframework.security</groupId> + <artifactId>spring-security-config</artifactId> + </dependency> + <dependency> + <groupId>com.rabbitmq</groupId> + <artifactId>amqp-client</artifactId> + </dependency> + + </dependencies> + + <build> + <plugins> + <plugin> + <groupId>org.springframework.boot</groupId> + <artifactId>spring-boot-maven-plugin</artifactId> + <executions> + <execution> + <goals> + <goal>repackage</goal> + </goals> + <configuration> + <classifier>spring-boot</classifier> + <mainClass> + org.opengroup.osdu.legal.LegalApplication + </mainClass> + </configuration> + </execution> + </executions> + </plugin> + </plugins> + </build> +</project> diff --git a/provider/legal-reference/skaffold.yaml b/provider/legal-reference/skaffold.yaml new file mode 100644 index 0000000000000000000000000000000000000000..ffc7dcaed691b475f40d58c87284955b87096d72 --- /dev/null +++ b/provider/legal-reference/skaffold.yaml @@ -0,0 +1,11 @@ +apiVersion: skaffold/v2beta5 +kind: Config +metadata: + name: legal-reference +build: + artifacts: + - image: us.gcr.io/osdu-anthos-02/os-legal/anthos-legal +deploy: + kubectl: + manifests: + - kubernetes/deployments/deployment-legal-service.yml diff --git a/provider/legal-reference/src/main/java/org/opengroup/osdu/legal/LegalApplication.java b/provider/legal-reference/src/main/java/org/opengroup/osdu/legal/LegalApplication.java new file mode 100644 index 0000000000000000000000000000000000000000..828947fda71bc1e77b4c2def19a4b5ca9a1d21f7 --- /dev/null +++ b/provider/legal-reference/src/main/java/org/opengroup/osdu/legal/LegalApplication.java @@ -0,0 +1,44 @@ +/* + * Copyright 2021 Google LLC + * Copyright 2021 EPAM Systems, Inc + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.opengroup.osdu.legal; + +import org.opengroup.osdu.core.gcp.multitenancy.TenantFactory; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.autoconfigure.mongo.MongoAutoConfiguration; +import org.springframework.boot.builder.SpringApplicationBuilder; +import org.springframework.boot.web.servlet.support.SpringBootServletInitializer; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.FilterType; + +@ComponentScan(value = {"org.opengroup.osdu"}, excludeFilters = { + @ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, value = TenantFactory.class) +}) +@SpringBootApplication(exclude = {MongoAutoConfiguration.class}) +public class LegalApplication extends SpringBootServletInitializer { + + @Override + protected SpringApplicationBuilder configure(SpringApplicationBuilder application) { + return application.sources(LegalApplication.class); + } + + public static void main(String[] args) { + SpringApplication.run(LegalApplication.class, args); + } + +} diff --git a/provider/legal-reference/src/main/java/org/opengroup/osdu/legal/config/MongoDBConfigProperties.java b/provider/legal-reference/src/main/java/org/opengroup/osdu/legal/config/MongoDBConfigProperties.java new file mode 100644 index 0000000000000000000000000000000000000000..27111c2508495c99e68d79db6cdb9c937efb00b6 --- /dev/null +++ b/provider/legal-reference/src/main/java/org/opengroup/osdu/legal/config/MongoDBConfigProperties.java @@ -0,0 +1,35 @@ +/* + * Copyright 2021 Google LLC + * Copyright 2021 EPAM Systems, Inc + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.opengroup.osdu.legal.config; + +import lombok.Getter; +import lombok.Setter; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.context.annotation.Configuration; + +@Configuration +@ConfigurationProperties +@Getter +@Setter +public class MongoDBConfigProperties { + + private String mongoDbUrl; + private String mongoDbUser; + private String mongoDbPassword; + private String mongoDbName; +} diff --git a/provider/legal-reference/src/main/java/org/opengroup/osdu/legal/config/RabbitMqConfigProperties.java b/provider/legal-reference/src/main/java/org/opengroup/osdu/legal/config/RabbitMqConfigProperties.java new file mode 100644 index 0000000000000000000000000000000000000000..5cb658fff09fd53ec2dbf0efbe9a117ebed348fe --- /dev/null +++ b/provider/legal-reference/src/main/java/org/opengroup/osdu/legal/config/RabbitMqConfigProperties.java @@ -0,0 +1,32 @@ +/* + * Copyright 2021 Google LLC + * Copyright 2021 EPAM Systems, Inc + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.opengroup.osdu.legal.config; + +import lombok.Getter; +import lombok.Setter; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.context.annotation.Configuration; + +@Configuration +@ConfigurationProperties +@Getter +@Setter +public class RabbitMqConfigProperties { + + private String mbRabbitMqUri; +} diff --git a/provider/legal-reference/src/main/java/org/opengroup/osdu/legal/countries/StorageReaderFactoryImpl.java b/provider/legal-reference/src/main/java/org/opengroup/osdu/legal/countries/StorageReaderFactoryImpl.java new file mode 100644 index 0000000000000000000000000000000000000000..95e4f5d8d0cc342f5c4cd8ebfb482318eb55fb89 --- /dev/null +++ b/provider/legal-reference/src/main/java/org/opengroup/osdu/legal/countries/StorageReaderFactoryImpl.java @@ -0,0 +1,47 @@ +/* + * Copyright 2021 Google LLC + * Copyright 2021 EPAM Systems, Inc + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.opengroup.osdu.legal.countries; + +import org.opengroup.osdu.core.common.model.tenant.TenantInfo; +import org.opengroup.osdu.legal.config.MongoDBConfigProperties; +import org.opengroup.osdu.legal.provider.interfaces.IStorageReader; +import org.opengroup.osdu.legal.provider.interfaces.IStorageReaderFactory; +import org.opengroup.osdu.legal.tags.dataaccess.MongoClientProvider; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +@Component +public class StorageReaderFactoryImpl implements IStorageReaderFactory { + + private static final String LEGAL_COLLECTION_NAME = "countries"; + + private final MongoDBConfigProperties mongoDBConfigProperties; + private final MongoClientProvider clientProvider; + + @Autowired + public StorageReaderFactoryImpl(MongoDBConfigProperties mongoDBConfigProperties, MongoClientProvider clientProvider) { + this.mongoDBConfigProperties = mongoDBConfigProperties; + this.clientProvider = clientProvider; + } + + @Override + public IStorageReader getReader(TenantInfo tenant, String projectRegion) { + return new StorageReaderImpl(tenant, projectRegion, mongoDBConfigProperties.getMongoDbName(), + LEGAL_COLLECTION_NAME, clientProvider); + } +} diff --git a/provider/legal-reference/src/main/java/org/opengroup/osdu/legal/countries/StorageReaderImpl.java b/provider/legal-reference/src/main/java/org/opengroup/osdu/legal/countries/StorageReaderImpl.java new file mode 100644 index 0000000000000000000000000000000000000000..9811957719f56b06c31ab998d809f162aaf9c90b --- /dev/null +++ b/provider/legal-reference/src/main/java/org/opengroup/osdu/legal/countries/StorageReaderImpl.java @@ -0,0 +1,72 @@ +/* + * Copyright 2021 Google LLC + * Copyright 2021 EPAM Systems, Inc + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.opengroup.osdu.legal.countries; + +import com.google.gson.Gson; +import com.google.gson.JsonArray; +import com.google.gson.JsonObject; +import java.util.List; +import org.opengroup.osdu.core.common.model.tenant.TenantInfo; +import org.opengroup.osdu.legal.provider.interfaces.IStorageReader; +import org.opengroup.osdu.legal.tags.dataaccess.MongoClientProvider; +import org.springframework.data.mongodb.core.MongoOperations; +import org.springframework.data.mongodb.core.MongoTemplate; +import org.springframework.data.mongodb.core.query.Criteria; +import org.springframework.data.mongodb.core.query.Query; + +public class StorageReaderImpl implements IStorageReader { + + private final TenantInfo tenantInfo; + private final String cloudRegion; + private final String dbName; + private final String collectionName; + private final MongoClientProvider client; + + public StorageReaderImpl(TenantInfo tenantInfo, String projectRegion, String dbName, + String collectionName, MongoClientProvider client) { + this.tenantInfo = tenantInfo; + this.cloudRegion = projectRegion; + this.collectionName = collectionName; + this.dbName = dbName; + this.client = client; + } + + @Override + public byte[] readAllBytes() { + MongoOperations ops = new MongoTemplate(client.getMongoClient(), dbName); + + Query query = new Query(Criteria + .where("tenant").is(tenantInfo.getName()) + .and("region").is(cloudRegion)); + + query.fields().include("name"); + query.fields().include("alpha2"); + query.fields().include("numeric"); + query.fields().include("residencyRisk"); + query.fields().include("typesNotApplyDataResidency"); + + List<JsonObject> objects = ops.find(query, JsonObject.class, collectionName); + + JsonArray array = new JsonArray(); + for (JsonObject s : objects) { + array.add(s); + } + + return new Gson().toJson(array).getBytes(); + } +} diff --git a/provider/legal-reference/src/main/java/org/opengroup/osdu/legal/di/PublisherFactoryService.java b/provider/legal-reference/src/main/java/org/opengroup/osdu/legal/di/PublisherFactoryService.java new file mode 100644 index 0000000000000000000000000000000000000000..d79843ba8f5bffe6a06be964ba1deaccfd97a881 --- /dev/null +++ b/provider/legal-reference/src/main/java/org/opengroup/osdu/legal/di/PublisherFactoryService.java @@ -0,0 +1,37 @@ +/* + * Copyright 2021 Google LLC + * Copyright 2021 EPAM Systems, Inc + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.opengroup.osdu.legal.di; + +import org.opengroup.osdu.core.gcp.multitenancy.IPublisherFactory; +import org.opengroup.osdu.core.gcp.multitenancy.PublisherFactory; +import org.springframework.beans.factory.config.AbstractFactoryBean; +import org.springframework.stereotype.Component; + +@Component +public class PublisherFactoryService extends AbstractFactoryBean<IPublisherFactory> { + + @Override + protected IPublisherFactory createInstance() throws Exception { + return new PublisherFactory(); + } + + @Override + public Class<?> getObjectType() { + return IPublisherFactory.class; + } +} \ No newline at end of file diff --git a/provider/legal-reference/src/main/java/org/opengroup/osdu/legal/di/RabbitMQFactoryImpl.java b/provider/legal-reference/src/main/java/org/opengroup/osdu/legal/di/RabbitMQFactoryImpl.java new file mode 100644 index 0000000000000000000000000000000000000000..d2e5306bb078152ecc1abd3af7acaf46bf29c18a --- /dev/null +++ b/provider/legal-reference/src/main/java/org/opengroup/osdu/legal/di/RabbitMQFactoryImpl.java @@ -0,0 +1,96 @@ +/* + * Copyright 2021 Google LLC + * Copyright 2021 EPAM Systems, Inc + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.opengroup.osdu.legal.di; + +import com.rabbitmq.client.Channel; +import com.rabbitmq.client.Connection; +import com.rabbitmq.client.ConnectionFactory; +import java.io.IOException; +import java.net.URISyntaxException; +import java.security.KeyManagementException; +import java.security.NoSuchAlgorithmException; +import java.util.Arrays; +import java.util.concurrent.TimeoutException; +import javax.annotation.PostConstruct; +import org.opengroup.osdu.legal.config.RabbitMqConfigProperties; +import org.opengroup.osdu.legal.messagebus.IMessageFactory; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +@Component +public class RabbitMQFactoryImpl implements IMessageFactory { + + private static final Logger LOGGER = LoggerFactory.getLogger(RabbitMQFactoryImpl.class); + + private final RabbitMqConfigProperties rabbitMqConfigProperties; + private Channel channel; + + @Autowired + public RabbitMQFactoryImpl(RabbitMqConfigProperties rabbitMqConfigProperties) { + this.rabbitMqConfigProperties = rabbitMqConfigProperties; + } + + @PostConstruct + private void init() { + ConnectionFactory factory = new ConnectionFactory(); + try { + String mbRabbitMqUri = rabbitMqConfigProperties.getMbRabbitMqUri(); + + LOGGER.debug(String.format("RabbitMQ Uri = %s", mbRabbitMqUri)); + + factory.setUri(mbRabbitMqUri); + factory.setAutomaticRecoveryEnabled(true); + Connection conn = factory.newConnection(); + this.channel = conn.createChannel(); + + LOGGER.debug("RabbitMQ Channel was created."); + + for (String queue : Arrays + .asList(DEFAULT_QUEUE_NAME, INDEXER_QUEUE_NAME, LEGAL_QUEUE_NAME)) { + channel.queueDeclare("os-legal-" + queue, false, false, false, null); + + LOGGER.debug(String.format("Queue [os-legal- %s ] was declared.", queue)); + } + } catch (KeyManagementException | NoSuchAlgorithmException | URISyntaxException | IOException | TimeoutException e) { + LOGGER.error(e.getMessage(), e); + } + + } + + @Override + public void sendMessage(String msg) { + this.sendMessage("records", msg); + } + + @Override + public void sendMessage(String queueName, String msg) { + String queueNameWithPrefix = "os-legal-" + queueName; + + try { + channel.basicPublish("", queueNameWithPrefix, null, msg.getBytes()); + + LOGGER.info(String.format("[x] Sent '%s' to queue [ %s]", msg, queueNameWithPrefix)); + + } catch (IOException e) { + LOGGER.error(String.format("Unable to publish message to [ %s ]", queueNameWithPrefix)); + LOGGER.error(e.getMessage(), e); + } + } +} diff --git a/provider/legal-reference/src/main/java/org/opengroup/osdu/legal/di/TenantFactoryImpl.java b/provider/legal-reference/src/main/java/org/opengroup/osdu/legal/di/TenantFactoryImpl.java new file mode 100644 index 0000000000000000000000000000000000000000..c1fcd83abb089745f92b4ad112974504bc4937b7 --- /dev/null +++ b/provider/legal-reference/src/main/java/org/opengroup/osdu/legal/di/TenantFactoryImpl.java @@ -0,0 +1,105 @@ +/* + * Copyright 2021 Google LLC + * Copyright 2021 EPAM Systems, Inc + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.opengroup.osdu.legal.di; + +import static java.util.Objects.isNull; + +import com.google.gson.Gson; +import com.mongodb.client.FindIterable; +import com.mongodb.client.MongoCollection; +import java.util.Collection; +import java.util.HashMap; +import java.util.Map; +import java.util.Objects; +import org.bson.Document; +import org.opengroup.osdu.core.common.cache.ICache; +import org.opengroup.osdu.core.common.model.tenant.TenantInfo; +import org.opengroup.osdu.core.common.provider.interfaces.ITenantFactory; +import org.opengroup.osdu.legal.tags.dataaccess.MongoClientProvider; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Primary; +import org.springframework.stereotype.Component; + +@Primary +@Component +public class TenantFactoryImpl implements ITenantFactory { + + private static final Logger LOG = LoggerFactory.getLogger(TenantFactoryImpl.class); + private static final String SCHEMA_DATABASE = "main"; + private static final String TENANT_INFO = "tenantinfo"; + + private final MongoClientProvider clientProvider; + + @Autowired + public TenantFactoryImpl(MongoClientProvider clientProvider) { + this.clientProvider = clientProvider; + } + + private Map<String, TenantInfo> tenants; + + public boolean exists(String tenantName) { + if (this.tenants == null) { + initTenants(); + } + return this.tenants.containsKey(tenantName); + } + + public TenantInfo getTenantInfo(String tenantName) { + if (Objects.isNull(tenants) || this.tenants.isEmpty()) { + initTenants(); + } + return this.tenants.get(tenantName); + } + + public Collection<TenantInfo> listTenantInfo() { + if (this.tenants == null) { + initTenants(); + } + return this.tenants.values(); + } + + public <V> ICache<String, V> createCache(String tenantName, String host, int port, + int expireTimeSeconds, Class<V> classOfV) { + return null; + } + + public void flushCache() { + } + + private void initTenants() { + this.tenants = new HashMap<>(); + MongoCollection<Document> mongoCollection = clientProvider + .getMongoClient() + .getDatabase(SCHEMA_DATABASE) + .getCollection(TENANT_INFO, Document.class); + + FindIterable<Document> results = mongoCollection.find(); + + if (isNull(results) || isNull(results.first())) { + LOG.error(String.format("Collection \'%s\' is empty.", results)); + } + for (Document document : results) { + TenantInfo tenantInfo = new Gson().fromJson(document.toJson(), TenantInfo.class); + this.tenants.put(tenantInfo.getName(), tenantInfo); + } + } + +} + diff --git a/provider/legal-reference/src/main/java/org/opengroup/osdu/legal/entity/LegalTagMongoEntity.java b/provider/legal-reference/src/main/java/org/opengroup/osdu/legal/entity/LegalTagMongoEntity.java new file mode 100644 index 0000000000000000000000000000000000000000..9c552b74d6b94d8052ad4f75db944d85708b9ffa --- /dev/null +++ b/provider/legal-reference/src/main/java/org/opengroup/osdu/legal/entity/LegalTagMongoEntity.java @@ -0,0 +1,132 @@ +/* + * Copyright 2021 Google LLC + * Copyright 2021 EPAM Systems, Inc + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.opengroup.osdu.legal.entity; + +import java.util.ArrayList; +import java.util.Date; +import java.util.List; +import lombok.Data; +import org.opengroup.osdu.core.common.model.legal.LegalTag; +import org.opengroup.osdu.core.common.model.legal.Properties; +import org.springframework.data.annotation.Id; + +@Data +public class LegalTagMongoEntity { + + @Id + private Long id; + private String name; + private String description; + private PropertiesMongoEntity properties; + private Boolean isValid; + + public LegalTagMongoEntity() { + + } + + public LegalTagMongoEntity(LegalTag legalTag) { + this.id = legalTag.getId(); + this.name = legalTag.getName(); + this.description = legalTag.getDescription(); + this.properties = new PropertiesMongoEntity(legalTag.getProperties()); + this.isValid = legalTag.getIsValid(); + } + + public static LegalTag convertTo(LegalTagMongoEntity entity) { + LegalTag legalTag = new LegalTag(); + + legalTag.setId(entity.getId()); + legalTag.setProperties(PropertiesMongoEntity.convertTo(entity.getProperties())); + legalTag.setDescription(entity.getDescription()); + legalTag.setName(entity.getName()); + legalTag.setIsValid(entity.getIsValid()); + + return legalTag; + } + + public static LegalTagMongoEntity convertFrom(LegalTag legalTag) { + LegalTagMongoEntity entity = new LegalTagMongoEntity(); + + entity.setId(legalTag.getId()); + entity.setProperties(new PropertiesMongoEntity(legalTag.getProperties())); + entity.setDescription(legalTag.getDescription()); + entity.setName(legalTag.getName()); + entity.setIsValid(legalTag.getIsValid()); + + return entity; + } + + @Data + private static class PropertiesMongoEntity { + + private List<String> countryOfOrigin = new ArrayList(); + private String contractId = ""; + private Date expirationDate; + private String originator = ""; + private String dataType = ""; + private String securityClassification = ""; + private String personalData = ""; + private String exportClassification = ""; + + public PropertiesMongoEntity() { + } + + public PropertiesMongoEntity(Properties properties) { + this.countryOfOrigin = properties.getCountryOfOrigin(); + this.contractId = properties.getContractId(); + this.expirationDate = new Date(properties.getExpirationDate().getTime()); + this.originator = properties.getOriginator(); + this.dataType = properties.getDataType(); + this.securityClassification = properties.getSecurityClassification(); + this.personalData = properties.getPersonalData(); + this.exportClassification = properties.getExportClassification(); + } + + public static Properties convertTo(PropertiesMongoEntity entity) { + Properties properties = new Properties(); + + properties.setCountryOfOrigin(entity.getCountryOfOrigin()); + properties.setContractId(entity.getContractId()); + + properties.setExpirationDate(new java.sql.Date(entity.getExpirationDate().getTime())); + + properties.setOriginator(entity.getOriginator()); + properties.setDataType(entity.getDataType()); + properties.setSecurityClassification(entity.getSecurityClassification()); + properties.setPersonalData(entity.getPersonalData()); + properties.setExportClassification(entity.getExportClassification()); + + return properties; + } + + public static PropertiesMongoEntity convertFrom(Properties properties) { + PropertiesMongoEntity entity = new PropertiesMongoEntity(); + + entity.countryOfOrigin = properties.getCountryOfOrigin(); + entity.contractId = properties.getContractId(); + entity.expirationDate = new Date(properties.getExpirationDate().getTime()); + entity.originator = properties.getOriginator(); + entity.dataType = properties.getDataType(); + entity.securityClassification = properties.getSecurityClassification(); + entity.personalData = properties.getPersonalData(); + entity.exportClassification = properties.getExportClassification(); + + return entity; + } + } +} diff --git a/provider/legal-reference/src/main/java/org/opengroup/osdu/legal/jobs/LegalTagPublisherImpl.java b/provider/legal-reference/src/main/java/org/opengroup/osdu/legal/jobs/LegalTagPublisherImpl.java new file mode 100644 index 0000000000000000000000000000000000000000..512f165a910b4b2b930513bd1e65a64efe312c1a --- /dev/null +++ b/provider/legal-reference/src/main/java/org/opengroup/osdu/legal/jobs/LegalTagPublisherImpl.java @@ -0,0 +1,62 @@ +/* + * Copyright 2021 Google LLC + * Copyright 2021 EPAM Systems, Inc + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.opengroup.osdu.legal.jobs; + +import com.google.gson.Gson; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import org.opengroup.osdu.core.common.model.http.DpsHeaders; +import org.opengroup.osdu.core.common.model.legal.StatusChangedTag; +import org.opengroup.osdu.core.common.model.legal.StatusChangedTags; +import org.opengroup.osdu.legal.messagebus.IMessageFactory; +import org.opengroup.osdu.legal.provider.interfaces.ILegalTagPublisher; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +@Component +public class LegalTagPublisherImpl implements ILegalTagPublisher { + + private final IMessageFactory mq; + + @Autowired + public LegalTagPublisherImpl(IMessageFactory mq) { + this.mq = mq; + } + + @Override + public void publish(String projectId, DpsHeaders headers, StatusChangedTags tags) { + + final int BATCH_SIZE = 50; + Gson gson = new Gson(); + Map<String, String> message = new HashMap<>(); + + for (int i = 0; i < tags.getStatusChangedTags().size(); i += BATCH_SIZE) { + + List<StatusChangedTag> batch = tags.getStatusChangedTags().subList(i, + Math.min(tags.getStatusChangedTags().size(), i + BATCH_SIZE)); + String json = gson.toJson(batch); + message.put("data", json); + message.put(DpsHeaders.ACCOUNT_ID, headers.getPartitionIdWithFallbackToAccountId()); + message.put(DpsHeaders.DATA_PARTITION_ID, headers.getPartitionIdWithFallbackToAccountId()); + headers.addCorrelationIdIfMissing(); + message.put(DpsHeaders.CORRELATION_ID, headers.getCorrelationId()); + mq.sendMessage(IMessageFactory.LEGAL_QUEUE_NAME, gson.toJson(message)); + } + } +} diff --git a/provider/legal-reference/src/main/java/org/opengroup/osdu/legal/messagebus/IMessageFactory.java b/provider/legal-reference/src/main/java/org/opengroup/osdu/legal/messagebus/IMessageFactory.java new file mode 100644 index 0000000000000000000000000000000000000000..6e88bcf11042c5c103ce8300c1c339ef43f48bfe --- /dev/null +++ b/provider/legal-reference/src/main/java/org/opengroup/osdu/legal/messagebus/IMessageFactory.java @@ -0,0 +1,28 @@ +/* + * Copyright 2021 Google LLC + * Copyright 2021 EPAM Systems, Inc + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.opengroup.osdu.legal.messagebus; + +public interface IMessageFactory { + String DEFAULT_QUEUE_NAME = "records"; + String LEGAL_QUEUE_NAME = "legal"; + String INDEXER_QUEUE_NAME = "indexer"; + + void sendMessage(String msg); + + void sendMessage(String queueName, String msg); +} diff --git a/provider/legal-reference/src/main/java/org/opengroup/osdu/legal/security/EntitlementsConfig.java b/provider/legal-reference/src/main/java/org/opengroup/osdu/legal/security/EntitlementsConfig.java new file mode 100644 index 0000000000000000000000000000000000000000..90caf6870a19fa521c072a58da14c513e5eb013a --- /dev/null +++ b/provider/legal-reference/src/main/java/org/opengroup/osdu/legal/security/EntitlementsConfig.java @@ -0,0 +1,32 @@ +/* + * Copyright 2021 Google LLC + * Copyright 2021 EPAM Systems, Inc + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.opengroup.osdu.legal.security; + +import lombok.Getter; +import lombok.Setter; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.context.annotation.Configuration; + +@Configuration +@ConfigurationProperties +@Getter +@Setter +public class EntitlementsConfig { + + private String authorizeApi; +} diff --git a/provider/legal-reference/src/main/java/org/opengroup/osdu/legal/security/SecurityConfiguration.java b/provider/legal-reference/src/main/java/org/opengroup/osdu/legal/security/SecurityConfiguration.java new file mode 100644 index 0000000000000000000000000000000000000000..bac5b7a9dc1a20814a1d52688cb96831fa47c07a --- /dev/null +++ b/provider/legal-reference/src/main/java/org/opengroup/osdu/legal/security/SecurityConfiguration.java @@ -0,0 +1,45 @@ +/* + * Copyright 2021 Google LLC + * Copyright 2021 EPAM Systems, Inc + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.opengroup.osdu.legal.security; + +import org.springframework.context.annotation.Configuration; +import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity; +import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.config.annotation.web.builders.WebSecurity; +import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; +import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; + +@Configuration +@EnableWebSecurity +@EnableGlobalMethodSecurity(prePostEnabled = true) +public class SecurityConfiguration extends WebSecurityConfigurerAdapter { + + @Override + protected void configure(HttpSecurity http) throws Exception { + http.httpBasic().disable() + .csrf().disable(); + + } + + @Override + public void configure(WebSecurity web) throws Exception { + web.ignoring().antMatchers("/api-docs") + .antMatchers("/index") + .antMatchers("/swagger"); + } +} diff --git a/provider/legal-reference/src/main/java/org/opengroup/osdu/legal/tags/LegalTagRepositoryFactoryMongoImpl.java b/provider/legal-reference/src/main/java/org/opengroup/osdu/legal/tags/LegalTagRepositoryFactoryMongoImpl.java new file mode 100644 index 0000000000000000000000000000000000000000..544d683df35e870cd273ecb1467e5231a032f51c --- /dev/null +++ b/provider/legal-reference/src/main/java/org/opengroup/osdu/legal/tags/LegalTagRepositoryFactoryMongoImpl.java @@ -0,0 +1,63 @@ +/* + * Copyright 2021 Google LLC + * Copyright 2021 EPAM Systems, Inc + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.opengroup.osdu.legal.tags; + +import java.util.HashMap; +import java.util.Map; +import org.apache.commons.lang3.StringUtils; +import org.opengroup.osdu.core.common.model.http.AppException; +import org.opengroup.osdu.core.common.model.http.DpsHeaders; +import org.opengroup.osdu.legal.provider.interfaces.ILegalTagRepository; +import org.opengroup.osdu.legal.provider.interfaces.ILegalTagRepositoryFactory; +import org.opengroup.osdu.legal.tags.dataaccess.MongoLegalTagRepository; +import org.opengroup.osdu.legal.tags.dataaccess.ResilientLegalTagRepository; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Primary; +import org.springframework.stereotype.Service; + +@Service +@Primary +public class LegalTagRepositoryFactoryMongoImpl implements ILegalTagRepositoryFactory { + + private final Map<String, ILegalTagRepository> tenantRepositories = new HashMap<>(); + + @Autowired + private MongoLegalTagRepository mongoLegalTagRepository; + + @Override + public ILegalTagRepository get(String tenantName) { + if (StringUtils.isBlank(tenantName)) { + throw invalidTenantGivenException(tenantName); + } + if (!tenantRepositories.containsKey(tenantName)) { + addRepository(tenantName); + } + return tenantRepositories.get(tenantName); + } + + private void addRepository(String tenantName) { + ILegalTagRepository repo = new ResilientLegalTagRepository(mongoLegalTagRepository); + tenantRepositories.put(tenantName, repo); + } + + private AppException invalidTenantGivenException(String tenantName) { + return new AppException(403, "Forbidden", + String.format("You do not have access to the %s value given %s", + DpsHeaders.ACCOUNT_ID, tenantName)); + } +} diff --git a/provider/legal-reference/src/main/java/org/opengroup/osdu/legal/tags/dataaccess/MongoClientProvider.java b/provider/legal-reference/src/main/java/org/opengroup/osdu/legal/tags/dataaccess/MongoClientProvider.java new file mode 100644 index 0000000000000000000000000000000000000000..d28b228d2b3ea9a19f8721714901f523032ca452 --- /dev/null +++ b/provider/legal-reference/src/main/java/org/opengroup/osdu/legal/tags/dataaccess/MongoClientProvider.java @@ -0,0 +1,81 @@ +/* + * Copyright 2021 Google LLC + * Copyright 2021 EPAM Systems, Inc + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.opengroup.osdu.legal.tags.dataaccess; + +import static java.util.Objects.isNull; + +import com.mongodb.ConnectionString; +import com.mongodb.MongoClientSettings; +import com.mongodb.client.MongoClient; +import com.mongodb.client.MongoClients; +import org.apache.http.HttpStatus; +import org.opengroup.osdu.core.common.model.http.AppException; +import org.opengroup.osdu.legal.config.MongoDBConfigProperties; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.mongodb.core.MongoOperations; +import org.springframework.data.mongodb.core.MongoTemplate; +import org.springframework.stereotype.Component; + +@Component +public class MongoClientProvider { + + private static final Logger LOG = LoggerFactory.getLogger(MongoClientProvider.class); + private static final String MONGO_PREFIX = "mongodb://"; + private static final String MONGO_OPTIONS = "retryWrites=true&w=majority&maxIdleTimeMS=10000"; + private final MongoDBConfigProperties mongoDBConfigProperties; + + private MongoClient mongoClient = null; + + @Autowired + public MongoClientProvider(MongoDBConfigProperties mongoDBConfigProperties) { + this.mongoDBConfigProperties = mongoDBConfigProperties; + } + + private MongoClient initMongoClient() throws RuntimeException { + final String connectionString = String.format("%s%s:%s@%s/?%s", + MONGO_PREFIX, + mongoDBConfigProperties.getMongoDbUser(), + mongoDBConfigProperties.getMongoDbPassword(), + mongoDBConfigProperties.getMongoDbUrl(), + MONGO_OPTIONS); + ConnectionString connString = new ConnectionString(connectionString); + MongoClientSettings settings = MongoClientSettings.builder() + .applyConnectionString(connString) + .retryWrites(true) + .build(); + try { + mongoClient = MongoClients.create(settings); + } catch (Exception ex) { + LOG.error("Error connecting MongoDB", ex); + throw new AppException(HttpStatus.SC_INTERNAL_SERVER_ERROR, "Error connecting MongoDB", + ex.getMessage(), ex); + } + return mongoClient; + } + + public MongoClient getMongoClient() { + return isNull(mongoClient) ? initMongoClient() : mongoClient; + } + + public MongoOperations getOps(String dbName) { + return new MongoTemplate(getMongoClient(), dbName); + } + +} diff --git a/provider/legal-reference/src/main/java/org/opengroup/osdu/legal/tags/dataaccess/MongoLegalTagRepository.java b/provider/legal-reference/src/main/java/org/opengroup/osdu/legal/tags/dataaccess/MongoLegalTagRepository.java new file mode 100644 index 0000000000000000000000000000000000000000..cc445e6c6bc2fd5a242f2640eab3c549a56468bf --- /dev/null +++ b/provider/legal-reference/src/main/java/org/opengroup/osdu/legal/tags/dataaccess/MongoLegalTagRepository.java @@ -0,0 +1,137 @@ +/* + * Copyright 2021 Google LLC + * Copyright 2021 EPAM Systems, Inc + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.opengroup.osdu.legal.tags.dataaccess; + +import static com.google.common.primitives.Longs.asList; +import static java.util.Objects.isNull; +import static org.apache.commons.lang3.BooleanUtils.negate; +import static org.opengroup.osdu.legal.entity.LegalTagMongoEntity.convertFrom; +import static org.opengroup.osdu.legal.entity.LegalTagMongoEntity.convertTo; + +import com.google.common.base.Preconditions; +import java.util.Collection; +import java.util.List; +import java.util.stream.Collectors; +import org.apache.commons.lang3.ArrayUtils; +import org.opengroup.osdu.core.common.model.http.AppException; +import org.opengroup.osdu.core.common.model.legal.LegalTag; +import org.opengroup.osdu.core.common.model.legal.ListLegalTagArgs; +import org.opengroup.osdu.legal.config.MongoDBConfigProperties; +import org.opengroup.osdu.legal.entity.LegalTagMongoEntity; +import org.opengroup.osdu.legal.provider.interfaces.ILegalTagRepository; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.mongodb.core.MongoOperations; +import org.springframework.data.mongodb.core.query.Criteria; +import org.springframework.data.mongodb.core.query.Query; +import org.springframework.stereotype.Repository; + +@Repository +public class MongoLegalTagRepository implements ILegalTagRepository { + + private final MongoDBConfigProperties mongoDBConfigProperties; + private final MongoClientProvider clientProvider; + + @Autowired + public MongoLegalTagRepository(MongoDBConfigProperties mongoDBConfigProperties, MongoClientProvider clientProvider) { + this.mongoDBConfigProperties = mongoDBConfigProperties; + this.clientProvider = clientProvider; + } + + @Override + public Long create(LegalTag legalTag) { + Preconditions.checkNotNull(legalTag, "Legal tag is null!"); + Preconditions.checkNotNull(legalTag.getId(), "Legal tag's id is null!"); + + MongoOperations ops = clientProvider.getOps(mongoDBConfigProperties.getMongoDbName()); + + LegalTagMongoEntity savedEntity = ops.save(convertFrom(legalTag), LEGAL_TAGS_ENTITYNAME); + + return savedEntity.getId(); + } + + @Override + public Collection<LegalTag> get(long[] ids) { + Preconditions.checkNotNull(ids, "List of legal tag ids is null!"); + Preconditions.checkArgument(ArrayUtils.isNotEmpty(ids), "List of legal tag ids is empty!"); + + MongoOperations ops = clientProvider.getOps(mongoDBConfigProperties.getMongoDbName()); + + Query query = new Query(Criteria.where("_id").in(asList(ids))); + List<LegalTagMongoEntity> entities = + ops.find(query, LegalTagMongoEntity.class, LEGAL_TAGS_ENTITYNAME); + + return entities.stream() + .map(LegalTagMongoEntity::convertTo) + .collect(Collectors.toList()); + } + + @Override + public Boolean delete(LegalTag legalTag) { + Preconditions.checkNotNull(legalTag, "Legal tag is null!"); + + MongoOperations ops = clientProvider.getOps(mongoDBConfigProperties.getMongoDbName()); + + Query query = new Query(Criteria.where("_id").is(legalTag.getId())); + + Boolean exists = ops.exists(query, LegalTagMongoEntity.class, LEGAL_TAGS_ENTITYNAME); + + if (exists) { + ops.remove(query, LegalTagMongoEntity.class, LEGAL_TAGS_ENTITYNAME); + exists = ops.exists(query, LegalTagMongoEntity.class, LEGAL_TAGS_ENTITYNAME); + } + + return negate(exists); + } + + @Override + public LegalTag update(LegalTag newLegalTag) { + Preconditions.checkNotNull(newLegalTag, "Legal tag is null!"); + + MongoOperations ops = clientProvider.getOps(mongoDBConfigProperties.getMongoDbName()); + + Query query = new Query(Criteria.where("_id").is(newLegalTag.getId())); + + Boolean exists = ops.exists(query, LegalTagMongoEntity.class, LEGAL_TAGS_ENTITYNAME); + + if (negate(exists)) { + throw AppException.legalTagDoesNotExistError(newLegalTag.getName()); + } + + LegalTagMongoEntity savedEntity = ops.save(convertFrom(newLegalTag), LEGAL_TAGS_ENTITYNAME); + + return convertTo(savedEntity); + } + + @Override + public Collection<LegalTag> list(ListLegalTagArgs args) { + MongoOperations ops = clientProvider.getOps(mongoDBConfigProperties.getMongoDbName()); + + Query query = new Query(); + + if (negate(isNull(args.getIsValid()))) { + query.addCriteria(Criteria.where("isValid").is(args.getIsValid())); + } + + List<LegalTagMongoEntity> entities = + ops.find(query, LegalTagMongoEntity.class, LEGAL_TAGS_ENTITYNAME); + + return entities.stream() + .map(LegalTagMongoEntity::convertTo) + .collect(Collectors.toList()); + } +} diff --git a/provider/legal-reference/src/main/resources/application.properties b/provider/legal-reference/src/main/resources/application.properties new file mode 100644 index 0000000000000000000000000000000000000000..76350ce894a8741dac613c52cc44b9c487834e4a --- /dev/null +++ b/provider/legal-reference/src/main/resources/application.properties @@ -0,0 +1,24 @@ +LOG_PREFIX=legal + +server.servlet.contextPath=/api/legal/v1/ +logging.level.org.springframework.web=DEBUG +server.port=8080 + +JAVA_HEAP_OPTS=-Xms4096M -Xmx4096M +JAVA_GC_OPTS=-XX:+UseG1GC -XX:+UseStringDeduplication -XX:InitiatingHeapOccupancyPercent=45 + +ACCEPT_HTTP=true +DEFAULT_DATA_COUNTRY=US + +#This must be overridden +mongo-db-url={MONGO_DB_URL} +mongo-db-user={MONGO_DB_USER} +mongo-db-password={MONGO_DB_PASSWORD} +mongo-db-name={MONGO_DB_NAME} +mb-rabbitmq-uri=amqp://guest:guest@localhost:5672 + +REGION=us-central1 +AUTHORIZE_API=https://entitlements-java-ckqkfalyaq-uc.a.run.app/entitlements/v1 + + + diff --git a/provider/legal-reference/src/test/java/org/opengroup/osdu/legal/InvalidCooRule.java b/provider/legal-reference/src/test/java/org/opengroup/osdu/legal/InvalidCooRule.java new file mode 100644 index 0000000000000000000000000000000000000000..71785a50ed5ce23c6759e8aea6debc6e6d69f8c6 --- /dev/null +++ b/provider/legal-reference/src/test/java/org/opengroup/osdu/legal/InvalidCooRule.java @@ -0,0 +1,36 @@ +/* + * Copyright 2021 Google LLC + * Copyright 2021 EPAM Systems, Inc + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.opengroup.osdu.legal; + +import org.opengroup.osdu.core.common.model.legal.Properties; +import org.opengroup.osdu.core.common.model.legal.validation.rules.Rule; + +public class InvalidCooRule extends Rule { + + @Override + public boolean shouldCheck(Properties properties) { + return true; + } + + @Override + protected String hasError(Properties properties) { + return String.format( + "Invalid country of origin set. It should match one of the ISO alpha 2 codes and be a country with no restriction on data residency. Found: %s.", + properties.getCountryOfOrigin()); + } +} diff --git a/provider/legal-reference/src/test/java/org/opengroup/osdu/legal/LegalApplicationTests.java b/provider/legal-reference/src/test/java/org/opengroup/osdu/legal/LegalApplicationTests.java new file mode 100644 index 0000000000000000000000000000000000000000..0be9240646df8551b109a53e8cdd47a08fea7fb5 --- /dev/null +++ b/provider/legal-reference/src/test/java/org/opengroup/osdu/legal/LegalApplicationTests.java @@ -0,0 +1,33 @@ +/* + * Copyright 2021 Google LLC + * Copyright 2021 EPAM Systems, Inc + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.opengroup.osdu.legal; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; + +@RunWith(SpringRunner.class) +@SpringBootTest +public class LegalApplicationTests { + + @Test + public void contextLoads() { + } + +} diff --git a/provider/legal-reference/src/test/java/org/opengroup/osdu/legal/MockRule.java b/provider/legal-reference/src/test/java/org/opengroup/osdu/legal/MockRule.java new file mode 100644 index 0000000000000000000000000000000000000000..bce261a49fe4c998da9c912e25fed90fe523f84c --- /dev/null +++ b/provider/legal-reference/src/test/java/org/opengroup/osdu/legal/MockRule.java @@ -0,0 +1,34 @@ +/* + * Copyright 2021 Google LLC + * Copyright 2021 EPAM Systems, Inc + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.opengroup.osdu.legal; + +import org.opengroup.osdu.core.common.model.legal.Properties; +import org.opengroup.osdu.core.common.model.legal.validation.rules.Rule; + +public class MockRule extends Rule { + + @Override + public boolean shouldCheck(Properties properties) { + return true; + } + + @Override + protected String hasError(Properties properties) { + return ""; + } +} \ No newline at end of file diff --git a/provider/legal-reference/src/test/java/org/opengroup/osdu/legal/MockValidationValidator.java b/provider/legal-reference/src/test/java/org/opengroup/osdu/legal/MockValidationValidator.java new file mode 100644 index 0000000000000000000000000000000000000000..7ee0847ec5e097efb9eeb78dca7018ca3227e126 --- /dev/null +++ b/provider/legal-reference/src/test/java/org/opengroup/osdu/legal/MockValidationValidator.java @@ -0,0 +1,85 @@ +/* + * Copyright 2021 Google LLC + * Copyright 2021 EPAM Systems, Inc + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.opengroup.osdu.legal; + +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import java.util.Arrays; +import javax.validation.Configuration; +import javax.validation.ConstraintValidator; +import javax.validation.Validation; +import javax.validation.Validator; +import javax.validation.ValidatorFactory; +import org.opengroup.osdu.core.common.model.http.RequestInfo; +import org.opengroup.osdu.core.common.model.legal.validation.rules.Rule; +import org.opengroup.osdu.core.common.model.tenant.TenantInfo; +import org.opengroup.osdu.legal.tags.LegalTagConstraintValidator; + +public class MockValidationValidator extends LegalTagConstraintValidator { + + private final String rulesetName; + + public MockValidationValidator(String ruleSet, RulesetProvider rsp) { + this.rulesetName = ruleSet; + this.ruleSetProvider = rsp; + } + + public MockValidationValidator() { + this.rulesetName = TenantInfo.ComplianceRuleSets.SHARED; + this.ruleSetProvider = CreateRsp(new MockRule()); + } + + @Override + public <T extends ConstraintValidator<?, ?>> T getInstance(Class<T> key) { + this.requestInfo = mock(RequestInfo.class); + when(requestInfo.getComplianceRuleSet()).thenReturn(rulesetName); + return super.getInstance(key); + } + + @Override + public void releaseInstance(ConstraintValidator<?, ?> instance) { + + } + + public static Validator GetValidator(String rulesetName, RulesetProvider rsp) { + Configuration<?> config = Validation.byDefaultProvider().configure(); + config.constraintValidatorFactory(new MockValidationValidator(rulesetName, rsp)); + ValidatorFactory factory = config.buildValidatorFactory(); + return factory.getValidator(); + } + + public static Validator GetValidator(String rulesetName) { + Configuration<?> config = Validation.byDefaultProvider().configure(); + config.constraintValidatorFactory( + new MockValidationValidator(rulesetName, CreateRsp(new MockRule()))); + ValidatorFactory factory = config.buildValidatorFactory(); + return factory.getValidator(); + } + + public static Validator GetValidator() { + Configuration<?> config = Validation.byDefaultProvider().configure(); + return GetValidator(TenantInfo.ComplianceRuleSets.SHARED); + } + + public static RulesetProvider CreateRsp(Rule... rules) { + RulesetProvider rsp = mock(RulesetProvider.class); + when(rsp.get()).thenReturn(Arrays.asList(rules)); + return rsp; + } +} diff --git a/provider/legal-reference/src/test/java/org/opengroup/osdu/legal/tags/LegalTestUtils.java b/provider/legal-reference/src/test/java/org/opengroup/osdu/legal/tags/LegalTestUtils.java new file mode 100644 index 0000000000000000000000000000000000000000..3126cc231ddb36d7abeb538cac01d3363e62daca --- /dev/null +++ b/provider/legal-reference/src/test/java/org/opengroup/osdu/legal/tags/LegalTestUtils.java @@ -0,0 +1,67 @@ +/* + * Copyright 2021 Google LLC + * Copyright 2021 EPAM Systems, Inc + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.opengroup.osdu.legal.tags; + +import static org.opengroup.osdu.core.common.model.legal.Properties.DEFAULT_EXPIRATIONDATE; + +import java.sql.Date; +import java.util.ArrayList; +import org.opengroup.osdu.core.common.model.legal.LegalTag; +import org.opengroup.osdu.core.common.model.legal.Properties; +import org.opengroup.osdu.legal.tags.dto.LegalTagDto; +import org.opengroup.osdu.legal.tags.dto.UpdateLegalTag; + +public class LegalTestUtils { + + public static LegalTag createValidLegalTag(String name) { + LegalTag legalTag = new LegalTag(); + legalTag.setProperties(createValidProperties()); + legalTag.setName(name); + legalTag.setIsValid(false); + legalTag.setDefaultId(); + return legalTag; + } + + public static Properties createValidProperties() { + Properties properties = new Properties(); + properties.setCountryOfOrigin(new ArrayList<String>() {{ + add("USA"); + }}); + properties.setExpirationDate(new Date(System.currentTimeMillis())); + properties.setOriginator("MyCompany"); + properties.setContractId("Unknown"); + properties.setDataType("Tranferred Data"); + properties.setPersonalData("Sensitive Personal Information"); + properties.setSecurityClassification("Confidential"); + properties.setExportClassification("ECCN"); + return properties; + } + + public static UpdateLegalTag createUpdateLegalTag(String name) { + UpdateLegalTag legalTag = new UpdateLegalTag(); + legalTag.setExpirationDate(DEFAULT_EXPIRATIONDATE); + legalTag.setContractId("abc123"); + legalTag.setName(name); + legalTag.setDescription("myDescription"); + return legalTag; + } + + public static LegalTagDto createValidLegalTagDto(String name) { + return LegalTagDto.convertTo(createValidLegalTag(name)); + } +} diff --git a/provider/legal-reference/src/test/java/org/opengroup/osdu/legal/tags/dataaccess/MongoLegalTagRepositoryTest.java b/provider/legal-reference/src/test/java/org/opengroup/osdu/legal/tags/dataaccess/MongoLegalTagRepositoryTest.java new file mode 100644 index 0000000000000000000000000000000000000000..5045b01044d7a7d1ae22d20ca324d4592c17eac0 --- /dev/null +++ b/provider/legal-reference/src/test/java/org/opengroup/osdu/legal/tags/dataaccess/MongoLegalTagRepositoryTest.java @@ -0,0 +1,355 @@ +/* + * Copyright 2021 Google LLC + * Copyright 2021 EPAM Systems, Inc + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.opengroup.osdu.legal.tags.dataaccess; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotEquals; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.MockitoAnnotations.initMocks; +import static org.opengroup.osdu.legal.tags.LegalTestUtils.createValidLegalTag; +import static org.powermock.api.mockito.PowerMockito.when; + +import com.mongodb.ConnectionString; +import com.mongodb.MongoClientSettings; +import com.mongodb.client.MongoClient; +import com.mongodb.client.MongoClients; +import java.util.Collection; +import java.util.Iterator; +import java.util.Set; +import java.util.stream.Collectors; +import org.junit.After; +import org.junit.Before; +import org.junit.Ignore; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.InjectMocks; +import org.opengroup.osdu.core.common.model.http.AppException; +import org.opengroup.osdu.core.common.model.legal.LegalTag; +import org.opengroup.osdu.core.common.model.legal.ListLegalTagArgs; +import org.opengroup.osdu.legal.config.MongoDBConfigProperties; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.data.mongodb.core.MongoOperations; +import org.springframework.data.mongodb.core.MongoTemplate; +import org.springframework.test.context.junit4.SpringRunner; +import org.springframework.test.util.ReflectionTestUtils; + +@Ignore +@RunWith(SpringRunner.class) +@PrepareForTest({MongoOperations.class, MongoClientProvider.class, MongoClient.class, + MongoLegalTagRepository.class}) +public class MongoLegalTagRepositoryTest { + + private static final String DB_NAME = "test"; + + @MockBean + private MongoClient client; + + @MockBean + private MongoOperations ops; + + @MockBean + private MongoClientProvider clientProvider; + + @MockBean + private MongoDBConfigProperties mongoDBConfigProperties; + + @InjectMocks + private MongoLegalTagRepository repo; + + @Before + public void setup() throws Exception { + final String connectionString = String.format("%s%s:%s@%s/?%s", + "mongodb://", + "admin", + "gonrg422", + "localhost:27017", + "retryWrites=true&w=majority"); + ConnectionString connString = new ConnectionString(connectionString); + MongoClientSettings settings = MongoClientSettings.builder() + .applyConnectionString(connString) + .retryWrites(true) + .build(); + + client = MongoClients.create(settings); + ops = new MongoTemplate(client, DB_NAME); + repo = new MongoLegalTagRepository(mongoDBConfigProperties, clientProvider); + + ReflectionTestUtils.setField(repo, "dbName", DB_NAME); + ReflectionTestUtils.setField(clientProvider, "mongoClient", client); + + initMocks(this); + } + + @After + public void teardown() throws Exception { + client.getDatabase(DB_NAME).drop(); + } + + @Test + public void testCreate() throws Exception { + when(clientProvider.getOps(anyString())).thenReturn(ops); + LegalTag tag1 = createValidLegalTag("tag1"); + Long id1 = tag1.getId(); + + Long saved_id1 = repo.create(tag1); + + assertEquals(id1, saved_id1); + + try { + LegalTag nullIdtag = createValidLegalTag("nulltag"); + nullIdtag.setId(null); + repo.create(nullIdtag); + fail("Expected exception"); + } catch (NullPointerException e) { + } + + LegalTag tag2 = createValidLegalTag("tag2"); + tag2.setIsValid(true); + Long id2 = tag2.getId(); + + Long saved_id2 = repo.create(tag2); + + assertEquals(id2, saved_id2); + + } + + @Test + public void testGet() throws Exception { + when(clientProvider.getOps(anyString())).thenReturn(ops); + LegalTag tag1 = createValidLegalTag("tag1"); + Long id1 = tag1.getId(); + + Long saved_id1 = repo.create(tag1); + assertEquals(id1, saved_id1); + + LegalTag tag2 = createValidLegalTag("tag2"); + tag2.setIsValid(true); + Long id2 = tag2.getId(); + + Long saved_id2 = repo.create(tag2); + + assertEquals(id2, saved_id2); + + Collection<LegalTag> retrv1 = repo.get(new long[]{id1}); + assertEquals(retrv1.size(), 1); + + LegalTag retrv1_tag1 = retrv1.iterator().next(); + assertEquals(tag1, retrv1_tag1); + } + + @Test + public void testNone() throws Exception { + when(clientProvider.getOps(anyString())).thenReturn(ops); + LegalTag tag1 = createValidLegalTag("tag1"); + Long id1 = tag1.getId(); + + Long saved_id1 = repo.create(tag1); + assertEquals(id1, saved_id1); + + LegalTag tag2 = createValidLegalTag("tag2"); + tag2.setIsValid(true); + Long id2 = tag2.getId(); + + Long saved_id2 = repo.create(tag2); + + assertEquals(id2, saved_id2); + + Collection<LegalTag> retrv1 = repo.get(new long[]{4324L}); + assertEquals(retrv1.size(), 0); + } + + + @Test + public void testGetMultiple() throws Exception { + when(clientProvider.getOps(anyString())).thenReturn(ops); + LegalTag tag1 = createValidLegalTag("tag1"); + Long id1 = tag1.getId(); + + Long saved_id1 = repo.create(tag1); + assertEquals(id1, saved_id1); + + LegalTag tag2 = createValidLegalTag("tag2"); + tag2.setIsValid(true); + Long id2 = tag2.getId(); + + Long saved_id2 = repo.create(tag2); + + assertEquals(id2, saved_id2); + + Collection<LegalTag> retrv1 = repo.get(new long[]{id1, id2}); + assertEquals(retrv1.size(), 2); + + Iterator<LegalTag> it = retrv1.iterator(); + + LegalTag retrv1_tag1 = it.next(); + assertEquals(tag1, retrv1_tag1); + LegalTag retrv1_tag2 = it.next(); + assertEquals(tag2, retrv1_tag2); + } + + @Test + public void testUpdate() throws Exception { + when(clientProvider.getOps(anyString())).thenReturn(ops); + LegalTag tag1 = createValidLegalTag("tag1"); + Long id1 = tag1.getId(); + tag1.setDescription("description1"); + + try { + repo.update(tag1); + fail("expected exception when updating object not present in the database"); + } catch (AppException ex) { + } + + Long saved_id1 = repo.create(tag1); + assertEquals(id1, saved_id1); + + Collection<LegalTag> retrv1 = repo.get(new long[]{id1}); + assertEquals(retrv1.size(), 1); + + Iterator<LegalTag> retrv1_it = retrv1.iterator(); + + LegalTag retrv1_tag1 = retrv1_it.next(); + assertEquals(tag1, retrv1_tag1); + + retrv1_tag1.setDescription("description2"); + + // This update will work without extra logic because retrv1_tag1 is + // actually a CloudantBackedLegalTag with a valid _rev + repo.update(retrv1_tag1); + + Collection<LegalTag> retrv2 = repo.get(new long[]{id1}); + assertEquals(retrv2.size(), 1); + + Iterator<LegalTag> retrv2_it = retrv2.iterator(); + + LegalTag retrv2_tag1 = retrv2_it.next(); + + assertNotEquals(tag1, retrv2_tag1); + assertEquals(retrv1_tag1, retrv2_tag1); + + LegalTag tag1_equivalent = createValidLegalTag("tag1"); + tag1.setDescription("description3"); + assertEquals(id1, tag1_equivalent.getId()); + + // This update would fail it the update method didn't handle the missing _rev + repo.update(tag1_equivalent); + + // This update would fail it the update method didn't handle the outdated _rev + repo.update(retrv2_tag1); + + } + + @Test + public void testDelete() throws Exception { + when(clientProvider.getOps(anyString())).thenReturn(ops); + LegalTag tag1 = createValidLegalTag("tag1"); + Long id1 = tag1.getId(); + tag1.setDescription("description1"); + + assertTrue(repo.delete(tag1)); + + Long saved_id1 = repo.create(tag1); + assertEquals(id1, saved_id1); + + Collection<LegalTag> retrv1 = repo.get(new long[]{id1}); + assertEquals(retrv1.size(), 1); + + assertTrue(repo.delete(tag1)); + + Collection<LegalTag> retrv2 = repo.get(new long[]{id1}); + assertEquals(retrv2.size(), 0); + + repo.create(tag1); + + Collection<LegalTag> retrv3 = repo.get(new long[]{id1}); + assertEquals(retrv3.size(), 1); + + Iterator<LegalTag> retrv3_it = retrv3.iterator(); + + LegalTag retrv3_tag1 = retrv3_it.next(); + assertEquals(tag1, retrv3_tag1); + + retrv3_tag1.setDescription("description2"); + assertNotEquals(tag1, retrv3_tag1); + + repo.update(retrv3_tag1); + + Collection<LegalTag> retrv4 = repo.get(new long[]{id1}); + assertEquals(retrv4.size(), 1); + + // This would fail without the retry on conflict logic + assertTrue(repo.delete(retrv3_tag1)); + + Collection<LegalTag> retrv5 = repo.get(new long[]{id1}); + assertEquals(retrv5.size(), 0); + + } + + @Test + public void testList() throws Exception { + when(clientProvider.getOps(anyString())).thenReturn(ops); + LegalTag tag1 = createValidLegalTag("tag1"); + tag1.setIsValid(false); + repo.create(tag1); + LegalTag tag2 = createValidLegalTag("tag2"); + tag2.setIsValid(true); + repo.create(tag2); + LegalTag tag3 = createValidLegalTag("tag3"); + tag3.setIsValid(false); + repo.create(tag3); + LegalTag tag4 = createValidLegalTag("tag4"); + tag4.setIsValid(true); + repo.create(tag4); + LegalTag tag5 = createValidLegalTag("tag5"); + tag5.setIsValid(false); + repo.create(tag5); + LegalTag tag6 = createValidLegalTag("tag6"); + tag6.setIsValid(true); + repo.create(tag6); + + ListLegalTagArgs allTagsNoPaging = new ListLegalTagArgs(); + allTagsNoPaging.setIsValid(null); + allTagsNoPaging.setLimit(0); + + Set<String> allNames = repo.list(allTagsNoPaging).stream().map(t -> t.getName()) + .collect(Collectors.toSet()); + + assertEquals(6, allNames.size()); + assertTrue(allNames.contains("tag1")); + assertTrue(allNames.contains("tag2")); + assertTrue(allNames.contains("tag3")); + assertTrue(allNames.contains("tag4")); + assertTrue(allNames.contains("tag5")); + assertTrue(allNames.contains("tag6")); + + ListLegalTagArgs validTagsNoPaging = new ListLegalTagArgs(); + validTagsNoPaging.setIsValid(true); + validTagsNoPaging.setLimit(0); + + Set<String> validNames = repo.list(validTagsNoPaging).stream().map(t -> t.getName()) + .collect(Collectors.toSet()); + + assertEquals(3, validNames.size()); + assertTrue(validNames.contains("tag2")); + assertTrue(validNames.contains("tag4")); + assertTrue(validNames.contains("tag6")); + } +} \ No newline at end of file