diff --git a/pom.xml b/pom.xml index 0f755893b6418314f3b8cbf4e1a9fa28b017c072..f5de14bf902ddb5d449eef435611d2831cb7438a 100644 --- a/pom.xml +++ b/pom.xml @@ -92,6 +92,7 @@ <module>provider/register-gcp</module> <module>provider/register-ibm</module> <module>provider/register-azure</module> + <module>provider/register-aws</module> </modules> <distributionManagement> diff --git a/provider/register-aws/build-aws/Dockerfile b/provider/register-aws/build-aws/Dockerfile new file mode 100644 index 0000000000000000000000000000000000000000..94a5511ff04fd6ce83326cc213d8bb41496673d3 --- /dev/null +++ b/provider/register-aws/build-aws/Dockerfile @@ -0,0 +1,22 @@ +# Copyright © 2020 Amazon Web Services +# +# 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. + +# https://docs.spring.io/spring-boot/docs/current/reference/html/deployment.html +FROM amazoncorretto:8 + +ARG JAR_FILE=provider/register-aws/target/*spring-boot.jar +WORKDIR / +COPY ${JAR_FILE} app.jar +EXPOSE 8080 +ENTRYPOINT java $JAVA_OPTS -jar /app.jar diff --git a/provider/register-aws/build-aws/build-info.py b/provider/register-aws/build-aws/build-info.py new file mode 100644 index 0000000000000000000000000000000000000000..1ea9b54bde9216cd158e4ea43eef41f06b8da1be --- /dev/null +++ b/provider/register-aws/build-aws/build-info.py @@ -0,0 +1,88 @@ +# Copyright © 2020 Amazon Web Services +# +# 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. +import boto3 +import json +import os +import argparse + +# Create the build-info.json +parser = argparse.ArgumentParser(description="") + +# env - CODEBUILD_SOURCE_VERSION +parser.add_argument("--branch", type=str, help="") + +# env - CODEBUILD_RESOLVED_SOURCE_VERSION +parser.add_argument("--commit", type=str, help="") + +# env - CODEBUILD_BUILD_ID +parser.add_argument("--buildid", type=str, help="") + +# env - CODEBUILD_BUILD_NUMBER +parser.add_argument("--buildnumber", type=str, help="") + +# Get from directory name +parser.add_argument("--reponame", type=str, help="") + +# env OUTPUT_DIR +parser.add_argument("--outdir", type=str, help="") + +# full ecr image and tag, and any other artifacts +parser.add_argument("--artifact", type=str, action="append", help="") + + + +args = parser.parse_args() + +branch = args.branch +commitId = args.commit +buildId = args.buildid +buildNumber = args.buildnumber +repoName = args.reponame +outputDir = args.outdir +artifacts = args.artifact + +buildInfoFilePath = os.path.join(".", outputDir, "build-info.json") + +print(buildInfoFilePath) + +commitArgs = { + "repositoryName": repoName, + "commitId": commitId +} + +commitDetail = { + "commit": "" +} + +# get the commit detail +try: + codecommit = boto3.client("codecommit") + commitDetail = codecommit.get_commit(**commitArgs) +except Exception as e: + print("Getting commit information from codecommit failed") + +buildInfo = { + "branch": branch, + "build-id": buildId, + "build-number": buildNumber, + "repo": repoName, + "artifacts": artifacts, + "commit": commitDetail["commit"] +} +print(json.dumps(buildInfo, sort_keys=True, indent=4)) + +# write the build.json file to dist +f = open(buildInfoFilePath, "w") +f.write(json.dumps(buildInfo, sort_keys=True, indent=4)) +f.close() diff --git a/provider/register-aws/build-aws/buildspec.yaml b/provider/register-aws/build-aws/buildspec.yaml new file mode 100644 index 0000000000000000000000000000000000000000..b9d2a2ca645bda8a27613f9a34b53ac4317fd9eb --- /dev/null +++ b/provider/register-aws/build-aws/buildspec.yaml @@ -0,0 +1,84 @@ +# Copyright © 2020 Amazon Web Services +# +# 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. + +# https://docs.aws.amazon.com/codebuild/latest/userguide/build-spec-ref.html + +# https://docs.aws.amazon.com/codebuild/latest/userguide/build-env-ref-env-vars.html +version: 0.2 + +phases: + install: + runtime-versions: + java: corretto8 + commands: + - if [ $(echo $CODEBUILD_SOURCE_VERSION | grep -c ^refs/heads.*) -eq 1 ]; then echo "Branch name found"; else echo "This build only supports branch builds" && exit 1; fi + - apt-get update -y + - apt-get install -y maven + - java -version + - mvn -version + - mkdir -p /root/.m2 + - cp ./provider/register-aws/maven/settings.xml /root/.m2/settings.xml # copy the AWS-specific settings.xml to the CodeBuild instance's .m2 folder + - export AWS_ACCOUNT_ID=`aws sts get-caller-identity | grep Account | cut -d':' -f 2 | cut -d'"' -f 2` + - export AWS_OSDU_DEV_MAVEN_AUTH_TOKEN=`aws codeartifact get-authorization-token --domain $AWS_OSDU_DEV_MAVEN_DOMAIN --domain-owner $AWS_ACCOUNT_ID --query authorizationToken --output text` + pre_build: + commands: + - echo "Logging in to Amazon ECR..." + - $(aws ecr get-login --no-include-email --region $AWS_REGION) # authenticate with ECR via the AWS CLI + build: + commands: + - export REPO_NAME=${PWD##*/} + - export OUTPUT_DIR="dist" + - export BRANCH_NAME=`echo ${CODEBUILD_SOURCE_VERSION} | awk '{gsub("refs/heads/","");gsub("\\.","-");gsub("[[:space:]]","-")}1' | sed 's/\//-/g' | awk '{print tolower($0)}'` + - export ECR_TAG=`echo build.${BRANCH_NAME}.${CODEBUILD_BUILD_NUMBER}.${CODEBUILD_RESOLVED_SOURCE_VERSION} | cut -c 1-120` + - export ECR_IMAGE=${ECR_REGISTRY}:${ECR_TAG} + - export ECR_IMAGE_BRANCH_LATEST=${ECR_REGISTRY}:${BRANCH_NAME} + - export INTEGRATION_TEST_OUTPUT=${OUTPUT_DIR}/testing/integration + - export INTEGRATION_TEST_OUTPUT_BIN=${INTEGRATION_TEST_OUTPUT}/bin + - mkdir -p ${OUTPUT_DIR}/bin + - mkdir -p ${OUTPUT_DIR}/testing && mkdir -p ${INTEGRATION_TEST_OUTPUT} && mkdir -p ${INTEGRATION_TEST_OUTPUT}/bin + - echo "Placeholder" >> ${OUTPUT_DIR}/build-info.json # touched so that the output directory has some content incase the build fails so that testing reports are uploaded + - printenv + + - echo "Building primary service assemblies..." + - mvn -B test install -pl register-core,provider/register-aws -Ddeployment.environment=prod + + #- echo "Building integration testing assemblies and gathering artifacts..." + #- ./testing/storage-test-aws/build-aws/prepare-dist.sh + + - echo "Building docker image..." + - docker build -f provider/register-aws/build-aws/Dockerfile -t ${ECR_IMAGE} . + - docker tag ${ECR_IMAGE} ${ECR_IMAGE_BRANCH_LATEST} + - echo "Pushing docker image..." + - docker push ${ECR_IMAGE} + - docker push ${ECR_IMAGE_BRANCH_LATEST} + + - echo "Generate build-info.json" + - | + python provider/register-aws/build-aws/build-info.py --branch ${CODEBUILD_SOURCE_VERSION} --commit ${CODEBUILD_RESOLVED_SOURCE_VERSION} \ + --buildid ${CODEBUILD_BUILD_ID} --buildnumber ${CODEBUILD_BUILD_NUMBER} --reponame ${REPO_NAME} --outdir ${OUTPUT_DIR} \ + --artifact ${ECR_IMAGE} +reports: + SurefireReports: # CodeBuild will create a report group called "SurefireReports". + files: #Store all of the files + - "register-core/target/surefire-reports/**/*" + - "provider/register-aws/target/surefire-reports/**/*" + base-directory: "." # Location of the reports +artifacts: + files: + - "**/*" + base-directory: "dist" + name: ${REPO_NAME}_${BRANCH_NAME}_$(date +%F)_${CODEBUILD_BUILD_NUMBER}.zip +cache: + paths: + - "/root/.m2/**/*" \ No newline at end of file diff --git a/provider/register-aws/build-aws/os-register.build.json b/provider/register-aws/build-aws/os-register.build.json new file mode 100644 index 0000000000000000000000000000000000000000..a957e1b9b4bb6053187ecc28d724f53b712e1028 --- /dev/null +++ b/provider/register-aws/build-aws/os-register.build.json @@ -0,0 +1,83 @@ +{ + "name": "os-register", + "description": "Build of the os-register repository", + "source": { + "type": "CODECOMMIT", + "location": "https://git-codecommit.us-east-1.amazonaws.com/v1/repos/os-register", + "gitCloneDepth": 1, + "gitSubmodulesConfig": { + "fetchSubmodules": false + }, + "buildspec": "./provider/register-aws/build-aws/buildspec.yaml", + "insecureSsl": false + }, + "secondarySources": [], + "sourceVersion": "refs/heads/dev", + "secondarySourceVersions": [], + "artifacts": { + "type": "S3", + "location": "888733619319-devops-build-artifacts", + "path": "os-register", + "namespaceType": "NONE", + "name": "os-register", + "packaging": "ZIP", + "overrideArtifactName": true, + "encryptionDisabled": false + }, + "secondaryArtifacts": [], + "cache": { + "type": "LOCAL", + "modes": [ + "LOCAL_CUSTOM_CACHE" + ] + }, + "environment": { + "type": "LINUX_CONTAINER", + "image": "aws/codebuild/standard:4.0", + "computeType": "BUILD_GENERAL1_SMALL", + "environmentVariables": [ + { + "name": "ECR_REGISTRY", + "value": "888733619319.dkr.ecr.us-east-1.amazonaws.com/os-register_dev", + "type": "PLAINTEXT" + }, + { + "name": "AWS_OSDU_DEV_MAVEN_URL", + "value": "https://osdu-dev-888733619319.d.codeartifact.us-east-1.amazonaws.com/maven/osdu-maven/", + "type": "PLAINTEXT" + }, + { + "name": "AWS_OSDU_DEV_MAVEN_DOMAIN", + "value": "osdu-dev", + "type": "PLAINTEXT" + } + ], + "privilegedMode": true, + "imagePullCredentialsType": "CODEBUILD" + }, + "serviceRole": "arn:aws:iam::888733619319:role/service-role/dev-CodeBuildRole", + "timeoutInMinutes": 60, + "queuedTimeoutInMinutes": 480, + "encryptionKey": "arn:aws:kms:us-east-1:888733619319:alias/aws/s3", + "tags": [], + "vpcConfig": { + "vpcId": "vpc-0f273733df61bc541", + "subnets": [ + "subnet-03963a50e77043e12", + "subnet-04a975f0e6e0c9279" + ], + "securityGroupIds": [ + "sg-0dee4e811c2062e26" + ] + }, + "badgeEnabled": true, + "logsConfig": { + "cloudWatchLogs": { + "status": "ENABLED" + }, + "s3Logs": { + "status": "DISABLED", + "encryptionDisabled": false + } + } +} diff --git a/provider/register-aws/maven/settings.xml b/provider/register-aws/maven/settings.xml new file mode 100644 index 0000000000000000000000000000000000000000..b8192246c94558d4c2d65ce1caf42871542dd79e --- /dev/null +++ b/provider/register-aws/maven/settings.xml @@ -0,0 +1,76 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + Copyright © 2020 Amazon Web Services + + 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. +--> + +<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"> + + <profiles> + <profile> + <id>aws-osdu-dev-maven</id> + <activation> + <activeByDefault>true</activeByDefault> + </activation> + <repositories> + <repository> + <id>aws-osdu-dev-maven</id> + <url>${env.AWS_OSDU_DEV_MAVEN_URL}</url> + </repository> + <repository> + <id>gitlab-os-core-common-maven</id> + <url>https://community.opengroup.org/api/v4/projects/67/packages/maven</url> + </repository> + </repositories> + </profile> + <profile> + <id>credentialsConfiguration</id> + <activation> + <activeByDefault>true</activeByDefault> + </activation> + <properties> + <deployment.environment>dev</deployment.environment> + <aws.accessKeyId>no-default</aws.accessKeyId> + <aws.secretKey>no-default</aws.secretKey> + <azure.devops.username>Another-Access-Token-2021</azure.devops.username> + <azure.devops.token>no-default</azure.devops.token> + </properties> + </profile> + </profiles> + + <servers> + <server> + <id>aws-osdu-dev-maven</id> + <username>aws</username> + <password>${env.AWS_OSDU_DEV_MAVEN_AUTH_TOKEN}</password> + </server> + </servers> + + <!-- CodeArtifact doesn't support external repos yet that aren't Maven Central. ETA Q4 2020. --> + <!-- <mirrors> --> + <!-- <mirror> --> + <!-- <id>aws-osdu-dev-maven</id> --> + <!-- <name>aws-osdu-dev-maven</name> --> + <!-- <url>https://osdu-dev-888733619319.d.codeartifact.us-east-1.amazonaws.com/maven/osdu-maven/</url> --> + <!-- <mirrorOf>*,!gitlab-os-core-common-maven</mirrorOf> --> + <!-- </mirror> --> + <!-- </mirrors> --> + + <activeProfiles> + <activeProfile>credentialsConfiguration</activeProfile> + </activeProfiles> + +</settings> \ No newline at end of file diff --git a/provider/register-aws/pom.xml b/provider/register-aws/pom.xml new file mode 100644 index 0000000000000000000000000000000000000000..942cff85192423333f0bff1a03fc415ef52fc5c3 --- /dev/null +++ b/provider/register-aws/pom.xml @@ -0,0 +1,171 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + Copyright © 2020 Amazon Web Services + + 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. +--> + +<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" + xmlns="http://maven.apache.org/POM/4.0.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> + <modelVersion>4.0.0</modelVersion> + <groupId>org.opengroup.osdu</groupId> + <artifactId>register-aws</artifactId> + <version>1.0.0</version> + <description>Register service on AWS</description> + <packaging>jar</packaging> + + <parent> + <groupId>org.opengroup.osdu</groupId> + <artifactId>os-register</artifactId> + <version>1.0.0</version> + <relativePath>../../</relativePath> + </parent> + <properties> + <aws.version>1.11.637</aws.version> + </properties> + <dependencies> + + <!-- AWS managed packages --> + <!--<dependency> + <groupId>com.amazonaws</groupId> + <artifactId>aws-java-sdk</artifactId> + <version>${aws.version}</version> + </dependency>--> + <dependency> + <groupId>com.amazonaws</groupId> + <artifactId>aws-java-sdk-dynamodb</artifactId> + <version>${aws.version}</version> + </dependency> + <dependency> + <groupId>com.amazonaws</groupId> + <artifactId>aws-java-sdk-cognitoidentity</artifactId> + <version>${aws.version}</version> + </dependency> + <dependency> + <groupId>com.amazonaws</groupId> + <artifactId>aws-java-sdk-sns</artifactId> + <version>${aws.version}</version> + </dependency> + <dependency> + <groupId>com.amazonaws</groupId> + <artifactId>aws-java-sdk-kms</artifactId> + <version>${aws.version}</version> + </dependency> + + <dependency> + <groupId>org.opengroup.osdu.core.aws</groupId> + <artifactId>os-core-lib-aws</artifactId> + <version>0.3.7</version> + </dependency> + <dependency> + <groupId>org.opengroup.osdu</groupId> + <artifactId>register-core</artifactId> + <version>1.0.0</version> + </dependency> + <dependency> + <groupId>org.opengroup.osdu</groupId> + <artifactId>os-core-common</artifactId> + </dependency> + + + + <dependency> + <groupId>org.springframework.security</groupId> + <artifactId>spring-security-config</artifactId> + </dependency> + + <dependency> + <groupId>org.springframework.boot</groupId> + <artifactId>spring-boot-starter-test</artifactId> + <scope>test</scope> + </dependency> + + <!-- Third party Apache 2.0 license packages --> + <dependency> + <groupId>org.springframework.boot</groupId> + <artifactId>spring-boot-starter-security</artifactId> + </dependency> + <dependency> + <groupId>org.springframework.boot</groupId> + <artifactId>spring-boot-starter-actuator</artifactId> + </dependency> + <dependency> + <groupId>org.springframework.security</groupId> + <artifactId>spring-security-oauth2-client</artifactId> + </dependency> + <dependency> + <groupId>org.springframework.security</groupId> + <artifactId>spring-security-oauth2-jose</artifactId> + </dependency> + + <dependency> + <groupId>org.powermock</groupId> + <artifactId>powermock-module-junit4</artifactId> + <version>2.0.2</version> + <scope>test</scope> + </dependency> + + <dependency> + <groupId>org.powermock</groupId> + <artifactId>powermock-api-mockito2</artifactId> + <version>2.0.2</version> + <scope>test</scope> + </dependency> + <dependency> + <groupId>com.amazonaws</groupId> + <artifactId>aws-java-sdk-sns</artifactId> + <version>1.11.651</version> + <scope>compile</scope> + </dependency> + + </dependencies> + + <repositories> + <repository> + <id>${gitlab-server}</id> + <url>https://community.opengroup.org/api/v4/groups/17/-/packages/maven</url> + </repository> + </repositories> + + <distributionManagement> + <repository> + <id>${gitlab-server}</id> + <url>https://community.opengroup.org/api/v4/projects/157/packages/maven</url> + </repository> + <snapshotRepository> + <id>${gitlab-server}</id> + <url>https://community.opengroup.org/api/v4/projects/157/packages/maven</url> + </snapshotRepository> + </distributionManagement> + + <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.register.provider.aws.RegisterApplication</mainClass> + </configuration> + </execution> + </executions> + </plugin> + </plugins> + </build> +</project> \ No newline at end of file diff --git a/provider/register-aws/src/main/java/org/opengroup/osdu/register/provider/aws/RegisterApplication.java b/provider/register-aws/src/main/java/org/opengroup/osdu/register/provider/aws/RegisterApplication.java new file mode 100644 index 0000000000000000000000000000000000000000..4997a8656ba28c71cb9ab5e0ef08fece86c8b5d3 --- /dev/null +++ b/provider/register-aws/src/main/java/org/opengroup/osdu/register/provider/aws/RegisterApplication.java @@ -0,0 +1,32 @@ +// Copyright © 2020 Amazon Web Services +// +// 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.register.provider.aws; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.context.annotation.ComponentScan; + + +@ComponentScan(value = { + "org.opengroup.osdu.register", + "org.opengroup.osdu.core", + "org.opengroup.osdu.aws" +}) +@SpringBootApplication +public class RegisterApplication { + public static void main(String[] args) { + SpringApplication.run(RegisterApplication.class, args); + } +} + diff --git a/provider/register-aws/src/main/java/org/opengroup/osdu/register/provider/aws/action/ActionDoc.java b/provider/register-aws/src/main/java/org/opengroup/osdu/register/provider/aws/action/ActionDoc.java new file mode 100644 index 0000000000000000000000000000000000000000..78025fb7ed695c1d93f4b808f8927adf5664e315 --- /dev/null +++ b/provider/register-aws/src/main/java/org/opengroup/osdu/register/provider/aws/action/ActionDoc.java @@ -0,0 +1,116 @@ +// Copyright © 2020 Amazon Web Services +// +// 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.register.provider.aws.action; + +import com.amazonaws.services.dynamodbv2.datamodeling.*; +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.ObjectMapper; +import lombok.*; +import org.opengroup.osdu.register.action.model.Action; +import org.opengroup.osdu.register.action.model.Filter; + +import java.sql.Timestamp; + + +@Data +@AllArgsConstructor +@NoArgsConstructor +@Builder +@DynamoDBTable(tableName = "Register.Action") +public class ActionDoc { + + @DynamoDBHashKey(attributeName = "id") + private String id; + + @DynamoDBAttribute(attributeName = "name") + private String name; + + @DynamoDBAttribute(attributeName = "description") + private String description; + + @DynamoDBAttribute(attributeName = "img") + private String img; + + @DynamoDBAttribute(attributeName = "url") + private String url; + + @DynamoDBAttribute(attributeName = "contactEmail") + private String contactEmail; + + @DynamoDBAttribute(attributeName = "createdOnEpoch") + private Timestamp createdOnEpoch; + + @DynamoDBAttribute(attributeName = "dataPartitionId") + private String dataPartitionId; + + + @DynamoDBTypeConverted(converter = ActionDoc.ActionConverter.class) + @DynamoDBAttribute(attributeName = "filter") + private Filter filter; + + + + public static class ActionConverter implements DynamoDBTypeConverter<String, Filter> { + + @SneakyThrows + @Override + public String convert(Filter object) { + ObjectMapper mapper = new ObjectMapper(); + return mapper.writeValueAsString(object); + } + + @SneakyThrows + @Override + public Filter unconvert(String object) { + ObjectMapper mapper = new ObjectMapper(); + return mapper.readValue(object, new TypeReference<Filter>() { + }); + } + } + + + + public static ActionDoc mapFrom(Action action, String dataPartitionId) { + + ActionDocBuilder actionDocBuilder = new ActionDoc().builder() + .id(action.getId()) + .name(action.getName()) + .description(action.getDescription()) + .img(action.getImg()) + .url(action.getUrl()) + .contactEmail(action.getContactEmail()) + .filter(action.getFilter()) + .createdOnEpoch(new Timestamp(System.currentTimeMillis())) + .dataPartitionId(dataPartitionId); + + return actionDocBuilder.build(); + } + + public static Action mapto(ActionDoc actionDoc) { + + Action action = new Action(); + action.setId(actionDoc.getId()); + action.setName(actionDoc.getName()); + action.setDescription(actionDoc.getDescription()); + action.setImg(actionDoc.getImg()); + action.setUrl(actionDoc.getUrl()); + action.setContactEmail(actionDoc.getContactEmail()); + action.setCreatedOnEpoch(com.google.cloud.Timestamp.of(actionDoc.getCreatedOnEpoch())); + action.setFilter(actionDoc.getFilter()); + return action; + } +} + + diff --git a/provider/register-aws/src/main/java/org/opengroup/osdu/register/provider/aws/action/AwsActionRepo.java b/provider/register-aws/src/main/java/org/opengroup/osdu/register/provider/aws/action/AwsActionRepo.java new file mode 100644 index 0000000000000000000000000000000000000000..0612c6e49104f2e5f7207cdde7f7d3ff6bcc32a4 --- /dev/null +++ b/provider/register-aws/src/main/java/org/opengroup/osdu/register/provider/aws/action/AwsActionRepo.java @@ -0,0 +1,139 @@ +// Copyright © 2020 Amazon Web Services +// +// 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.register.provider.aws.action; + + +import com.amazonaws.services.dynamodbv2.model.AttributeValue; +import org.opengroup.osdu.core.aws.dynamodb.DynamoDBQueryHelper; +import org.opengroup.osdu.core.common.logging.JaxRsDpsLog; +import org.opengroup.osdu.core.common.model.http.AppException; +import org.opengroup.osdu.core.common.model.http.DpsHeaders; +import org.opengroup.osdu.register.action.model.Action; +import org.opengroup.osdu.register.provider.aws.config.AwsServiceConfig; +import org.opengroup.osdu.register.provider.interfaces.action.IActionRepo; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Repository; + +import javax.annotation.PostConstruct; +import javax.inject.Inject; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +@Repository +public class AwsActionRepo implements IActionRepo { + + + @Autowired + private DpsHeaders dpsHeaders; + + @Autowired + private JaxRsDpsLog logger; + + @Inject + private AwsServiceConfig serviceConfig; + + private DynamoDBQueryHelper queryHelper; + + @PostConstruct + public void init() { + queryHelper = new DynamoDBQueryHelper(serviceConfig.getDynamoDbEndpoint(), + serviceConfig.getAmazonRegion(), + serviceConfig.getDynamoDbTablePrefix()); + } + + + @Override + public List<Action> getAllActions() { + + List<String> filters = new ArrayList<>(); + Map<String, AttributeValue> valueMap = new HashMap<>(); + + filters.add("dataPartitionId = :dataPartitionId"); + valueMap.put(":dataPartitionId", new AttributeValue().withS(dpsHeaders.getPartitionId())); + + String filterExpression = String.join(" and ", filters); + logger.info(String.format("Action query filter expression: %s", filterExpression)); + + List<ActionDoc> results = queryHelper.scanTable(ActionDoc.class, filterExpression, valueMap); + + List<Action> actionsList = results.stream().map(ActionDoc::mapto).collect(Collectors.toList()); + + //Alternative implementation + /* List<Action> actionsList = new ArrayList<Action>(); + for (ActionDoc actionDoc : results){ + actionsList.add(ActionDoc.mapto(actionDoc)); + }*/ + + return actionsList; + } + + @Override + public Action createAction(Action action) { + if(action.getId() == null){ + logger.error("Action id cannot be null"); + throw new AppException(400, "Bad Request", "Action id cannot be null"); + } + + ActionDoc doc = ActionDoc.mapFrom(action, dpsHeaders.getPartitionId()); + + try { + queryHelper.save(doc); + } + catch (AppException e) { + if(e.getError().getCode() == 409) { + logger.error(String.format("An action already exists with the id: %s", action.getId())); + throw new AppException(409, "Conflict", String.format("An action already exists with the id: %s", action.getId())); + } + else { + logger.error(e.getMessage()); + throw new AppException(e.getError().getCode(), e.getError().getReason(), e.getMessage()); + } + } + return action; + } + + @Override + public boolean delete(String id) { + try { + queryHelper.deleteByPrimaryKey(ActionDoc.class, id); + }catch (AppException e) { + if(e.getError().getCode() == 404) { + logger.error(String.format("Action with id %s does not exist.", id)); + } + else { + logger.error(e.getMessage()); + throw new AppException(e.getError().getCode(), e.getError().getReason(), e.getMessage()); + } + return false; + } + return true; + + } + + @Override + public Action get(String id){ + ActionDoc doc = queryHelper.loadByPrimaryKey(ActionDoc.class, id); + if (doc == null) { + logger.error(String.format("Action with id %s does not exist.", id)); + throw new AppException(404, "Not found", String.format("Action with id %s does not exist.", id)); + } else { + return ActionDoc.mapto(doc); + } + } + + +} diff --git a/provider/register-aws/src/main/java/org/opengroup/osdu/register/provider/aws/config/AwsServiceConfig.java b/provider/register-aws/src/main/java/org/opengroup/osdu/register/provider/aws/config/AwsServiceConfig.java new file mode 100644 index 0000000000000000000000000000000000000000..1712a037d84e832d7d20bf45849f97cc41487e20 --- /dev/null +++ b/provider/register-aws/src/main/java/org/opengroup/osdu/register/provider/aws/config/AwsServiceConfig.java @@ -0,0 +1,102 @@ +// Copyright © 2020 Amazon Web Services +// +// 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.register.provider.aws.config; + +import lombok.AccessLevel; +import lombok.Getter; +import lombok.Setter; +import org.opengroup.osdu.core.aws.ssm.ParameterStorePropertySource; +import org.opengroup.osdu.core.aws.ssm.SSMConfig; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Component; + +import javax.annotation.PostConstruct; + +@Component +public class AwsServiceConfig { + + @Value("${aws.region}") + @Getter() + @Setter(AccessLevel.PROTECTED) + public String amazonRegion; + + + @Value("${aws.dynamodb.table.prefix}") + @Getter() + @Setter(AccessLevel.PROTECTED) + public String dynamoDbTablePrefix; + + @Value("${aws.dynamodb.endpoint}") + @Getter() + @Setter(AccessLevel.PROTECTED) + public String dynamoDbEndpoint; + + + @Value("${aws.ssm}") + @Getter() + @Setter(AccessLevel.PROTECTED) + public Boolean ssmEnabled; + + + @Value("${aws.register.sns.topic.arn}") + @Getter() + private String snsTopicArn; + + + /*@Value("${aws.register.kms.key.arn}") + @Getter() + private String kmsKeyArn;*/ + + @Value("${aws.register.kms.key.id}") + @Getter() + @Setter(AccessLevel.PROTECTED) + private String kmsKeyId; + + + @Value("${aws.kms.endpoint}") + @Getter() + @Setter(AccessLevel.PROTECTED) + public String kmsEndpoint; + + + @Value("${aws.environment}") + @Getter() + @Setter(AccessLevel.PROTECTED) + public String environment; + + + /*@Inject + protected JaxRsDpsLog logger;*/ + + @PostConstruct + public void init() { + if (ssmEnabled) { + //Can be used to retrieve ssm parameters + SSMConfig ssmConfig = new SSMConfig(); + ParameterStorePropertySource ssm = ssmConfig.amazonSSM(); + String keyssmparameter = "/osdu/" + environment + "/register/register-kms-key-id"; + try { + kmsKeyId = ssm.getProperty(keyssmparameter).toString(); + } catch (Exception e) { + + System.out.println(String.format("SSM property %s not found", keyssmparameter)); + } + + + } + } + +} + diff --git a/provider/register-aws/src/main/java/org/opengroup/osdu/register/provider/aws/ddms/AwsDdmsRepo.java b/provider/register-aws/src/main/java/org/opengroup/osdu/register/provider/aws/ddms/AwsDdmsRepo.java new file mode 100644 index 0000000000000000000000000000000000000000..a8004860d5fadf7b1dbddb00066e41a54bdc5511 --- /dev/null +++ b/provider/register-aws/src/main/java/org/opengroup/osdu/register/provider/aws/ddms/AwsDdmsRepo.java @@ -0,0 +1,124 @@ +// Copyright © 2020 Amazon Web Services +// +// 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.register.provider.aws.ddms; + + +import com.amazonaws.services.dynamodbv2.datamodeling.PaginatedQueryList; +import org.opengroup.osdu.core.aws.dynamodb.DynamoDBQueryHelper; +import org.opengroup.osdu.core.common.logging.JaxRsDpsLog; +import org.opengroup.osdu.core.common.model.http.AppException; +import org.opengroup.osdu.core.common.model.http.DpsHeaders; +import org.opengroup.osdu.register.ddms.model.Ddms; +import org.opengroup.osdu.register.provider.aws.action.ActionDoc; +import org.opengroup.osdu.register.provider.aws.config.AwsServiceConfig; +import org.opengroup.osdu.register.provider.aws.util.DocUtil; +import org.opengroup.osdu.register.provider.interfaces.ddms.IDdmsRepository; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Repository; + +import javax.annotation.PostConstruct; +import javax.inject.Inject; +import java.util.ArrayList; +import java.util.List; + +@Repository +public class AwsDdmsRepo implements IDdmsRepository { + + + @Autowired + private DpsHeaders dpsHeaders; + + @Autowired + private JaxRsDpsLog logger; + + @Inject + private AwsServiceConfig serviceConfig; + + private DynamoDBQueryHelper queryHelper; + + DocUtil docUtil = new DocUtil(); + + @PostConstruct + public void init() { + + queryHelper = new DynamoDBQueryHelper(serviceConfig.getDynamoDbEndpoint(), + serviceConfig.getAmazonRegion(), + serviceConfig.getDynamoDbTablePrefix()); + } + + @Override + public Ddms create(Ddms ddms) { + DdmsDoc doc = DdmsDoc.mapFrom(ddms, dpsHeaders.getPartitionId()); + try { + queryHelper.save(doc); + } + catch (AppException e) { + if(e.getError().getCode() == 409) { + logger.error(String.format("A DDMS already exists with the same id: %s", ddms.getId())); + throw new AppException(409, "Conflict", String.format("A DDMS already exists with the same id: %s", ddms.getId())); + } + else { + logger.error(e.getMessage()); + throw new AppException(e.getError().getCode(), e.getError().getReason(), e.getMessage()); + } + } + + return ddms; + } + + @Override + public Ddms get(String id) { + + DdmsDoc doc = queryHelper.loadByPrimaryKey(DdmsDoc.class, id); + if (doc == null) { + logger.error(String.format("Ddms with id %s does not exist.", id)); + throw new AppException(404, "Not found", String.format("Ddms with id %s does not exist.", id)); + } else { + return DdmsDoc.mapto(doc); + } + + } + + @Override + public List<Ddms> query(String entityType) { + + String dataPartitionId = dpsHeaders.getPartitionId(); + DdmsDoc gsiQuery = new DdmsDoc(); + String key = String.format("%s:%s",dataPartitionId,entityType); + gsiQuery.setPartitionIdEntityType(key); + List<Ddms> ddmsList = docUtil.getDdmsList(queryHelper,gsiQuery); + + return ddmsList; + + + } + + @Override + public boolean delete(String id){ + try { + queryHelper.deleteByPrimaryKey(DdmsDoc.class, id); + }catch (AppException e) { + if(e.getError().getCode() == 404) { + logger.error(String.format("Ddms with id %s does not exist.", id)); + } + else { + logger.error(e.getMessage()); + throw new AppException(e.getError().getCode(), e.getError().getReason(), e.getMessage()); + } + return false; + } + return true; + + } +} diff --git a/provider/register-aws/src/main/java/org/opengroup/osdu/register/provider/aws/ddms/DdmsDoc.java b/provider/register-aws/src/main/java/org/opengroup/osdu/register/provider/aws/ddms/DdmsDoc.java new file mode 100644 index 0000000000000000000000000000000000000000..5cfdefece451f017b242b94972d169e7720271e4 --- /dev/null +++ b/provider/register-aws/src/main/java/org/opengroup/osdu/register/provider/aws/ddms/DdmsDoc.java @@ -0,0 +1,147 @@ +// Copyright © 2020 Amazon Web Services +// +// 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.register.provider.aws.ddms; + +import com.amazonaws.services.dynamodbv2.datamodeling.*; +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.ObjectMapper; +import lombok.*; +import org.opengroup.osdu.register.ddms.model.Ddms; +import org.opengroup.osdu.register.ddms.model.RegisteredInterface; + +import java.sql.Timestamp; +import java.util.Set; +import java.util.stream.Collectors; + +@Data +@AllArgsConstructor +@NoArgsConstructor +@Builder +@DynamoDBTable(tableName = "Register.Ddms") +public class DdmsDoc { + + @DynamoDBHashKey(attributeName = "id") + private String id; + + @DynamoDBAttribute(attributeName = "name") + private String name; + + @DynamoDBAttribute(attributeName = "description") + private String description; + + + @DynamoDBAttribute(attributeName = "contactEmail") + private String contactEmail; + + @DynamoDBAttribute(attributeName = "createdDateTimeEpoch") + private Timestamp createdDateTimeEpoch; + + @DynamoDBAttribute(attributeName = "dataPartitionId") + private String dataPartitionId; + + @DynamoDBIndexHashKey(attributeName = "partitionIdEntityType", globalSecondaryIndexName = "entityType-index") //Added this for query api + private String partitionIdEntityType; + + + + @DynamoDBTypeConverted(converter = DdmsDoc.DdmsConverter.class) + @DynamoDBAttribute(attributeName = "interfaces") + // private Set<RegInterfaceDoc> interfaces; + private Set<RegisteredInterface> interfaces; + + + + public static class DdmsConverter implements DynamoDBTypeConverter<String, Set<RegisteredInterface>> { + + @SneakyThrows + @Override + public String convert(Set<RegisteredInterface> object) { + ObjectMapper mapper = new ObjectMapper(); + return mapper.writeValueAsString(object); + } + + @SneakyThrows + @Override + public Set<RegisteredInterface> unconvert(String object) { + ObjectMapper mapper = new ObjectMapper(); + return mapper.readValue(object, new TypeReference<Set<RegisteredInterface>>() { + }); + } + } + + + + public static DdmsDoc mapFrom(Ddms ddms, String dataPartitionId) { + + DdmsDocBuilder ddmsDocBuilder = new DdmsDoc().builder() + .id(ddms.getId()) + .name(ddms.getName()) + .description(ddms.getDescription()) + .contactEmail(ddms.getContactEmail()) + .createdDateTimeEpoch(new Timestamp(System.currentTimeMillis())) + .interfaces(ddms.getInterfaces()) + .dataPartitionId(dataPartitionId) + .partitionIdEntityType(String.format("%s:%s",dataPartitionId,getEntityType(ddms))); + + return ddmsDocBuilder.build(); + } + + public static Ddms mapto(DdmsDoc ddmsDoc) { + + Ddms ddms = new Ddms(); + ddms.setId(ddmsDoc.getId()); + ddms.setName(ddmsDoc.getName()); + ddms.setDescription(ddmsDoc.getDescription()); + ddms.setContactEmail(ddmsDoc.getContactEmail()); + ddms.setCreatedDateTimeEpoch(com.google.cloud.Timestamp.of(ddmsDoc.getCreatedDateTimeEpoch())); + // ddms.setInterfaces(ddmsDoc.getInterfaces().stream().map(DdmsDoc::getRegisteredInterface).collect(Collectors.toSet())); + ddms.setInterfaces(ddmsDoc.getInterfaces()); + return ddms; + } + + + + + + + private static RegInterfaceDoc getRegisteredInterfaceDoc(RegisteredInterface reginterface){ + return new RegInterfaceDoc(reginterface.getEntityType(), reginterface.getSchema()); + } + + private static RegisteredInterface getRegisteredInterface(RegInterfaceDoc doc){ + RegisteredInterface registeredInterface = new RegisteredInterface(); + registeredInterface.setEntityType(doc.getEntityType()); + registeredInterface.setSchema(doc.getSchema()); + return registeredInterface; + } + + private static String getEntityType(Ddms ddms){ + + String entityType=""; + + //get the first element from the set + RegisteredInterface ri = ddms.getInterfaces().iterator().next(); + if(ri!=null) { + RegInterfaceDoc regIntDoc = DdmsDoc.getRegisteredInterfaceDoc(ri); + entityType = regIntDoc.getEntityType(); + } + + + return entityType; + + } + +} + + diff --git a/provider/register-aws/src/main/java/org/opengroup/osdu/register/provider/aws/ddms/RegInterfaceDoc.java b/provider/register-aws/src/main/java/org/opengroup/osdu/register/provider/aws/ddms/RegInterfaceDoc.java new file mode 100644 index 0000000000000000000000000000000000000000..f124592588e622fbb4279a8d6cd97e2adc52c51a --- /dev/null +++ b/provider/register-aws/src/main/java/org/opengroup/osdu/register/provider/aws/ddms/RegInterfaceDoc.java @@ -0,0 +1,29 @@ +// Copyright © 2020 Amazon Web Services +// +// 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.register.provider.aws.ddms; + + +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +import java.util.Map; + +@Getter +@AllArgsConstructor +@NoArgsConstructor +public class RegInterfaceDoc { + private String entityType; + private Map<String, Object> schema; +} \ No newline at end of file diff --git a/provider/register-aws/src/main/java/org/opengroup/osdu/register/provider/aws/security/AwsSecurityConfig.java b/provider/register-aws/src/main/java/org/opengroup/osdu/register/provider/aws/security/AwsSecurityConfig.java new file mode 100644 index 0000000000000000000000000000000000000000..a5c9656a99606f3e467642efeedac0e7281197ad --- /dev/null +++ b/provider/register-aws/src/main/java/org/opengroup/osdu/register/provider/aws/security/AwsSecurityConfig.java @@ -0,0 +1,33 @@ +// Copyright © 2020 Amazon Web Services +// 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.register.provider.aws.security; + + +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.configuration.EnableWebSecurity; +import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; + + +@EnableWebSecurity +@EnableGlobalMethodSecurity(prePostEnabled = true) +public class AwsSecurityConfig extends WebSecurityConfigurerAdapter { + @Override + protected void configure(HttpSecurity http) throws Exception { + http.httpBasic().disable() + .csrf().disable(); //disable default authN. AuthN handled by endpoints proxy + } +} + + diff --git a/provider/register-aws/src/main/java/org/opengroup/osdu/register/provider/aws/subscriber/AwsSubscriptionRepo.java b/provider/register-aws/src/main/java/org/opengroup/osdu/register/provider/aws/subscriber/AwsSubscriptionRepo.java new file mode 100644 index 0000000000000000000000000000000000000000..0bf6fdaa01a8ce8611a8b689bc40a3ffb9b3895a --- /dev/null +++ b/provider/register-aws/src/main/java/org/opengroup/osdu/register/provider/aws/subscriber/AwsSubscriptionRepo.java @@ -0,0 +1,247 @@ +// Copyright © 2020 Amazon Web Services +// +// 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.register.provider.aws.subscriber; + +import com.amazonaws.services.dynamodbv2.datamodeling.PaginatedQueryList; +import com.amazonaws.services.dynamodbv2.model.AttributeValue; +import com.google.cloud.Timestamp; +import org.opengroup.osdu.core.aws.dynamodb.DynamoDBQueryHelper; +import org.opengroup.osdu.core.aws.ssm.ParameterStorePropertySource; +import org.opengroup.osdu.core.aws.ssm.SSMConfig; +import org.opengroup.osdu.core.common.logging.JaxRsDpsLog; +import org.opengroup.osdu.core.common.model.http.AppException; +import org.opengroup.osdu.core.common.model.http.DpsHeaders; +import org.opengroup.osdu.register.provider.aws.config.AwsServiceConfig; +import org.opengroup.osdu.register.provider.aws.util.DocUtil; +import org.opengroup.osdu.register.provider.interfaces.subscriber.ISubscriptionRepository; +import org.opengroup.osdu.register.subscriber.model.*; +import org.opengroup.osdu.register.utils.Constants; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Repository; + +import javax.annotation.PostConstruct; +import javax.inject.Inject; +import java.text.MessageFormat; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +@Repository +public class AwsSubscriptionRepo implements ISubscriptionRepository { + + @Autowired + private DpsHeaders dpsHeaders; + + @Autowired + private JaxRsDpsLog logger; + + private DynamoDBQueryHelper queryHelper; + + @Inject + private AwsServiceConfig serviceConfig; + + + private String amazonSNSTopicArn; + + private SSMConfig ssmConfig; + + private ParameterStorePropertySource ssm; + + + private SubscriptionHelper snsHelper; + + + private KmsHelper kmsHelper; + + DocUtil docUtil = new DocUtil(); + + @PostConstruct + public void init() { + // TODO: serviceConfig.environment isn't correct and needs to be table prefix. Maybe the "-" will fix it + queryHelper = new DynamoDBQueryHelper(serviceConfig.getDynamoDbEndpoint(), + serviceConfig.getAmazonRegion(), + serviceConfig.getDynamoDbTablePrefix()); + } + + @Override + public Subscription create(Subscription s) throws Exception { + + + //amazonSNSTopicArn = ssm.getProperty(serviceConfig.getSnsTopicArn()).toString(); + //temporarily hardcodimng the topic name until TopicRepository is sorted out + amazonSNSTopicArn = "aws-topic-name"; + + //We create the SNS subscription first so that it's ARN can be stored in DynamoDB + + //There is no way in aws java sdk to look up sns topic arn by name. So we call createTopic, + // if it exists, it returns the arn without creating the topic + //CreateTopicResult createRes = sns.createTopic("HelloTopic"); + //We might want to create a separate table for Topic -- TopicArn + + // For now retrieving the single topic created by cloudformation. This miht change in the future if + //multiple topics are created using Topics APIS. + //See Gitlab issue:https://community.opengroup.org/osdu/platform/system/register/-/issues/14 + + + String subscriptionArn = snsHelper.createPushSubscription(amazonSNSTopicArn); + String encryptedSecretValue = kmsHelper.encrypt(s.getSecret().toString()); + SubscriptionDoc doc = SubscriptionDoc.mapFrom(s, dpsHeaders.getPartitionId(),subscriptionArn,encryptedSecretValue); + + try { + queryHelper.save(doc); + } + catch (AppException e) { + if(e.getError().getCode() == 409) { + logger.error(String.format("A subscription already exists with the id: %s", s.getId())); + throw new AppException(409, "Conflict", String.format("A subscription already exists with the id: %s", s.getId())); + } + else { + logger.error(e.getMessage()); + throw new AppException(e.getError().getCode(), e.getError().getReason(), e.getMessage()); + } + } + return s; + + } + + @Override + public Subscription get(String id) { + SubscriptionDoc doc = queryHelper.loadByPrimaryKey(SubscriptionDoc.class, id); + if (doc == null) { + logger.error(String.format("Subscription with id %s does not exist.", id)); + throw new AppException(404, "Not found", String.format("Subscription with id %s does not exist.", id)); + } else { + String secretValue = kmsHelper.decrypt(doc.getSecretValue()); + Secret secret = docUtil.createSecret(doc.getSecretType(),secretValue); + Subscription s = SubscriptionDoc.mapTo(doc,secret); + + return s; + } + } + + @Override + public List<Subscription> query(String notificationId) { + String key=String.format("%s:%s",dpsHeaders.getPartitionId(),notificationId); + + SubscriptionDoc gsiQuery = new SubscriptionDoc(); + gsiQuery.setPartitionIdNotificationId(key); + + List<Subscription> subsList = docUtil.getSubscriptionList(queryHelper,gsiQuery); + + return subsList; + + + } + + @Override + public boolean delete(String id) { + + SubscriptionDoc doc=null; + String snsSubscriptionArn=""; + + try { + doc = queryHelper.loadByPrimaryKey(SubscriptionDoc.class, id); + snsSubscriptionArn = doc.getSnssubscriptionArn(); + queryHelper.deleteByPrimaryKey(SubscriptionDoc.class, id); + } + catch(AppException e) + { + if(e.getError().getCode() == 404) { + logger.error("Could not find subscription with Id %s for delete operation", id); + throw e; + } + else { + logger.error("Error while deleting subscription with Id %s ", id); + logger.error(e.getMessage()); + throw new AppException(e.getError().getCode(), e.getError().getReason(), e.getMessage()); + } + } + + + //delete the SNS subscription + snsHelper.deletePushSubscription(snsSubscriptionArn); + return true; + + } + + @Override + public boolean patch(Subscription subscription, Secret secret) { + SubscriptionDoc doc=null; + String id = subscription.getId(); + try { + doc = queryHelper.loadByPrimaryKey(SubscriptionDoc.class, id); + }catch(AppException e) + { + if(e.getError().getCode() == 404) { + logger.error("Could not find subscription with Id %s ", id); + throw e; + } + else { + logger.error(e.getMessage()); + throw new AppException(e.getError().getCode(), e.getError().getReason(), e.getMessage()); + } + } + //update the secret + doc.setSecretType(secret.getSecretType()); + doc.setSecretValue(kmsHelper.encrypt(secret.toString())); + try{ + queryHelper.save(doc); + + } catch (AppException e) { + String msg="Error while saving the updated secret"; + throw new AppException(e.getError().getCode(), e.getError().getReason(), msg); + } + return true; + } + + @Override + public List<Subscription> getAll() throws Exception { + + List<String> filters = new ArrayList<>(); + Map<String, AttributeValue> valueMap = new HashMap<>(); + List<SubscriptionDoc> results=null; + + filters.add("dataPartitionId = :dataPartitionId"); + valueMap.put(":dataPartitionId", new AttributeValue().withS(dpsHeaders.getPartitionId())); + + String filterExpression = String.join(" and ", filters); + logger.info(String.format("Subscription query filter expression: %s", filterExpression)); + + try { + + results = queryHelper.scanTable(SubscriptionDoc.class, filterExpression, valueMap); + } + catch(AppException e) + { + String msg="Error while getting ALL subscriptions"; + throw new AppException(e.getError().getCode(), e.getError().getReason(), msg); + } + // List<Subscription> subsList = results.stream().map(SubscriptionDoc::mapTo).collect(Collectors.toList()); + + //Alternative implementation + List<Subscription> subsList = new ArrayList<Subscription>(); + for (SubscriptionDoc subsDoc : results){ + String secretValue = kmsHelper.decrypt(subsDoc.getSecretValue()); + Secret secret = docUtil.createSecret(subsDoc.getSecretType(),secretValue); + subsList.add(SubscriptionDoc.mapTo(subsDoc,secret)); + + } + + return subsList; + } + + +} diff --git a/provider/register-aws/src/main/java/org/opengroup/osdu/register/provider/aws/subscriber/KmsConfig.java b/provider/register-aws/src/main/java/org/opengroup/osdu/register/provider/aws/subscriber/KmsConfig.java new file mode 100644 index 0000000000000000000000000000000000000000..083af7d47df7a35ec24f759355c0ad404d81e4af --- /dev/null +++ b/provider/register-aws/src/main/java/org/opengroup/osdu/register/provider/aws/subscriber/KmsConfig.java @@ -0,0 +1,51 @@ +// Copyright © 2020 Amazon Web Services +// +// 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.register.provider.aws.subscriber; + +import com.amazonaws.auth.AWSCredentialsProvider; +import com.amazonaws.client.builder.AwsClientBuilder; +import com.amazonaws.services.kms.AWSKMS; +import com.amazonaws.services.kms.AWSKMSClientBuilder; +import org.opengroup.osdu.core.aws.iam.IAMConfig; + +//This class should be moved to os-core-lib-aws. Keeping it here temporarily till testing is complete +public class KmsConfig { + + private String amazonKmsEndpoint; + + private String amazonKmsRegion; + + private AWSCredentialsProvider amazonAWSCredentials; + + public KmsConfig(String amazonKmsEndpoint, String amazonKmsRegion){ + amazonAWSCredentials = IAMConfig.amazonAWSCredentials(); + this.amazonKmsEndpoint = amazonKmsEndpoint; + this.amazonKmsRegion = amazonKmsRegion; + } + + public AWSKMS awsKMS() { + // Generate the KMS client + return AWSKMSClientBuilder.standard() + .withCredentials(amazonAWSCredentials) + .withEndpointConfiguration(amazonKmsEndpointConfiguration()) + .build(); + } + + public AwsClientBuilder.EndpointConfiguration amazonKmsEndpointConfiguration() { + // Create an endpoint configuration for KMS with region and service endpoint from application.properties + return new AwsClientBuilder.EndpointConfiguration( + amazonKmsEndpoint, amazonKmsRegion + ); + } +} diff --git a/provider/register-aws/src/main/java/org/opengroup/osdu/register/provider/aws/subscriber/KmsHelper.java b/provider/register-aws/src/main/java/org/opengroup/osdu/register/provider/aws/subscriber/KmsHelper.java new file mode 100644 index 0000000000000000000000000000000000000000..80ff6cb26401015bdcba946a06303ca1b063716c --- /dev/null +++ b/provider/register-aws/src/main/java/org/opengroup/osdu/register/provider/aws/subscriber/KmsHelper.java @@ -0,0 +1,115 @@ +// Copyright © 2020 Amazon Web Services +// +// 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.register.provider.aws.subscriber; + + + +import com.amazonaws.services.kms.model.DecryptRequest; +import com.amazonaws.services.kms.model.EncryptRequest; +import org.opengroup.osdu.core.aws.dynamodb.DynamoDBQueryHelper; +import org.opengroup.osdu.core.aws.ssm.ParameterStorePropertySource; +import org.opengroup.osdu.core.aws.ssm.SSMConfig; +import org.opengroup.osdu.core.common.logging.JaxRsDpsLog; +import org.opengroup.osdu.core.common.model.http.DpsHeaders; +import org.opengroup.osdu.register.provider.aws.config.AwsServiceConfig; +import org.springframework.beans.factory.annotation.Autowired; +import com.amazonaws.services.kms.*; +import org.springframework.stereotype.Component; + + +import javax.annotation.PostConstruct; +import javax.inject.Inject; +import java.nio.ByteBuffer; +import java.util.Collections; + +@Component +public class KmsHelper { + + @Autowired + private DpsHeaders dpsHeaders; + + @Autowired + private JaxRsDpsLog logger; + + private DynamoDBQueryHelper queryHelper; + + @Inject + private AwsServiceConfig serviceConfig; + + private AWSKMS kmsClient; + + private String kmsKeyId; + + @PostConstruct + public void init() { + queryHelper = new DynamoDBQueryHelper(serviceConfig.getDynamoDbEndpoint(), + serviceConfig.getAmazonRegion(), + serviceConfig.getDynamoDbTablePrefix()); + + + + + + } + + public String encrypt(String plaintext){ + + //this needs to go in init + /*SSMConfig ssmConfig = new SSMConfig(); + ParameterStorePropertySource ssm = ssmConfig.amazonSSM();*/ + //kmsKeyId = ssm.getProperty(serviceConfig.getKmsKeyId()).toString(); + + kmsKeyId =serviceConfig.getKmsKeyId(); + + KmsConfig config = new KmsConfig(serviceConfig.getKmsEndpoint(), serviceConfig.getAmazonRegion() ); + kmsClient = config.awsKMS(); + + //DataPartitionId used as encryption context? Adds some level of security per tenant. That is the only info we get through the headers.. no emailid of + //user available for higher security + //see https://aws.amazon.com/blogs/security/how-to-protect-the-integrity-of-your-encrypted-data-by-using-aws-key-management-service-and-encryptioncontext/ + + + EncryptRequest encReq = new EncryptRequest(); + encReq.setKeyId(kmsKeyId); + encReq.setPlaintext(ByteBuffer.wrap(plaintext.getBytes())); + encReq.setEncryptionContext(Collections.singletonMap("dataPartitionId", dpsHeaders.getPartitionId())); + ByteBuffer ciphertext = kmsClient.encrypt(encReq).getCiphertextBlob(); + return new String(ciphertext.array()); + } + + public String decrypt(String ciphertext){ + + //this needs to go in init + /*SSMConfig ssmConfig = new SSMConfig(); + ParameterStorePropertySource ssm = ssmConfig.amazonSSM(); + kmsKeyId = ssm.getProperty(serviceConfig.getKmsKeyId()).toString();*/ + + kmsKeyId =serviceConfig.getKmsKeyId(); + + KmsConfig config = new KmsConfig(serviceConfig.getKmsEndpoint(), serviceConfig.getAmazonRegion() ); + kmsClient = config.awsKMS(); + + //DataPartitionId used as encryption context? Adds some level of security per tenant. That is the only info we get through the headers.. no emailid of + //user available for higher security + //see https://aws.amazon.com/blogs/security/how-to-protect-the-integrity-of-your-encrypted-data-by-using-aws-key-management-service-and-encryptioncontext/ + DecryptRequest decReq = new DecryptRequest(); + ByteBuffer b = ByteBuffer.wrap(ciphertext.getBytes()); + decReq.setCiphertextBlob(b); + decReq.setEncryptionContext(Collections.singletonMap("dataPartitionId", dpsHeaders.getPartitionId())); + ByteBuffer decrypted = kmsClient.decrypt(decReq).getPlaintext(); + String decryptedStr = new String(decrypted.array()); + return decryptedStr; + } + +} diff --git a/provider/register-aws/src/main/java/org/opengroup/osdu/register/provider/aws/subscriber/SubscriptionDoc.java b/provider/register-aws/src/main/java/org/opengroup/osdu/register/provider/aws/subscriber/SubscriptionDoc.java new file mode 100644 index 0000000000000000000000000000000000000000..b8da455bb1f50f39fb84f98aa21b0eb4fe9703f5 --- /dev/null +++ b/provider/register-aws/src/main/java/org/opengroup/osdu/register/provider/aws/subscriber/SubscriptionDoc.java @@ -0,0 +1,119 @@ +// Copyright © 2020 Amazon Web Services +// +// 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.register.provider.aws.subscriber; + +import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBAttribute; +import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBHashKey; +import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBIndexHashKey; +import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBTable; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; +import org.opengroup.osdu.register.subscriber.model.*; +import java.sql.Timestamp; + +@Data +@AllArgsConstructor +@NoArgsConstructor +@Builder +@DynamoDBTable(tableName = "Register.Subscription") +public class SubscriptionDoc { + + + @DynamoDBHashKey(attributeName = "id") + private String id; + + @DynamoDBAttribute(attributeName = "name") + private String name; + + @DynamoDBAttribute(attributeName = "description") + private String description; + + @DynamoDBAttribute(attributeName = "topic") + private String topic; + + @DynamoDBAttribute(attributeName = "pushEndpoint") + private String pushEndpoint; + + @DynamoDBAttribute(attributeName = "createdBy") + private String createdBy; + + @DynamoDBAttribute(attributeName = "createdOnEpoch") + private Timestamp createdOnEpoch; + + @DynamoDBAttribute(attributeName = "notificationId") + private String notificationId; + + @DynamoDBAttribute(attributeName = "secretType") + private String secretType; + + @DynamoDBAttribute(attributeName = "secretValue") + private String secretValue; + + @DynamoDBAttribute(attributeName = "dataPartitionId") + private String dataPartitionId; + + @DynamoDBAttribute(attributeName = "snssubscriptionArn") //Storing this info so that the subscription in SNS can be looked up + private String snssubscriptionArn; + + + @DynamoDBIndexHashKey(attributeName = "partitionIdNotificationId", globalSecondaryIndexName = "notification-index") //Added this for query api + private String partitionIdNotificationId; + + + + public static SubscriptionDoc mapFrom(Subscription sub, String dataPartitionId,String snssubscriptionArn, String encryptedSecretValue) { + + + SubscriptionDocBuilder subDocBuilder = new SubscriptionDoc().builder() + .id(sub.getId()) + .name(sub.getName()) + .description(sub.getDescription()) + .topic(sub.getTopic()) + .pushEndpoint(sub.getPushEndpoint()) + .createdBy(sub.getCreatedBy()) + .createdOnEpoch(new Timestamp(System.currentTimeMillis())) + .notificationId(sub.getNotificationId()) + .secretType(sub.getSecret().getSecretType()) + .secretValue(encryptedSecretValue) + .dataPartitionId(dataPartitionId) + .snssubscriptionArn(snssubscriptionArn) + .partitionIdNotificationId(String.format("%s:%s",dataPartitionId,sub.getNotificationId())); + + return subDocBuilder.build(); + } + + + public static Subscription mapTo(SubscriptionDoc subDoc, Secret secret) { + + Subscription sub = new Subscription(); + sub.setId(subDoc.getId()); + sub.setName(subDoc.getName()); + sub.setDescription(subDoc.getDescription()); + sub.setTopic(subDoc.getTopic()); + sub.setPushEndpoint(subDoc.getPushEndpoint()); + sub.setCreatedBy(subDoc.getCreatedBy()); + sub.setCreatedOnEpoch( com.google.cloud.Timestamp.of(subDoc.getCreatedOnEpoch())); + sub.setNotificationId(subDoc.getNotificationId()); + sub.setSecret(secret); + + + + + return sub; + } + + +} diff --git a/provider/register-aws/src/main/java/org/opengroup/osdu/register/provider/aws/subscriber/SubscriptionHelper.java b/provider/register-aws/src/main/java/org/opengroup/osdu/register/provider/aws/subscriber/SubscriptionHelper.java new file mode 100644 index 0000000000000000000000000000000000000000..3cdbaef76a3a4b5825bbd461945fbbd0537d9062 --- /dev/null +++ b/provider/register-aws/src/main/java/org/opengroup/osdu/register/provider/aws/subscriber/SubscriptionHelper.java @@ -0,0 +1,136 @@ +// Copyright © 2020 Amazon Web Services +// +// 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.register.provider.aws.subscriber; + +import com.amazonaws.services.sns.AmazonSNS; +import com.amazonaws.services.sns.model.*; +import org.opengroup.osdu.core.aws.sns.AmazonSNSConfig; +import org.opengroup.osdu.core.aws.ssm.ParameterStorePropertySource; +import org.opengroup.osdu.core.aws.ssm.SSMConfig; +import org.opengroup.osdu.core.common.logging.JaxRsDpsLog; +import org.opengroup.osdu.core.common.model.http.AppException; +import org.opengroup.osdu.register.provider.aws.config.AwsServiceConfig; +import org.opengroup.osdu.register.utils.AppServiceConfig; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import javax.annotation.PostConstruct; +import javax.inject.Inject; +import java.util.List; + +@Component +public class SubscriptionHelper { + + private AmazonSNS snsClient; + + private ParameterStorePropertySource ssm; + + private String amazonSNSTopicArn; + + @Autowired + private AppServiceConfig serviceConfig; + + @Inject + private AwsServiceConfig awsServiceConfig; + + @Autowired + private JaxRsDpsLog logger; + + @PostConstruct + public void init(){ + AmazonSNSConfig config = new AmazonSNSConfig(awsServiceConfig.getAmazonRegion()); + snsClient = config.AmazonSNS(); + + + } + + public String createPushSubscription(String topicArn) { + //There is no way in aws java sdk to look up sns topic arn by name. So we call createTopic, + // if it exists, it returns the arn without creating the topic + //CreateTopicResult createRes = sns.createTopic("HelloTopic"); + //We might want to create a separate table for Topic -- TopicArn + + // For now retrieving the single topic created by cloudformation. This miht change in the future if + //multiple topics are created using Topics APIS. + //See Gitlab issue:https://community.opengroup.org/osdu/platform/system/register/-/issues/14 + /* SSMConfig ssmConfig = new SSMConfig(); + ParameterStorePropertySource ssm = ssmConfig.amazonSSM(); + amazonSNSTopicArn = ssm.getProperty(AwsServiceConfig.getSnsTopicArn()).toString(); +*/ + String pushEndpoint = serviceConfig.getRecordsChangePubsubEndpoint(); + try { + SubscribeRequest subscribeRequest = new SubscribeRequest(amazonSNSTopicArn, "https", pushEndpoint); + subscribeRequest.setReturnSubscriptionArn(true); + SubscribeResult subscriptionResult = snsClient.subscribe(subscribeRequest); + String subscriptionArn = subscriptionResult.getSubscriptionArn(); + return subscriptionArn; + } + catch(Exception e){ + logger.error("Create subscription failed for topic name"+topicArn ); + throw e; + } + + } + + public void deletePushSubscription(String subscriptionArn) { + + UnsubscribeRequest unsubscribeRequest = new UnsubscribeRequest(subscriptionArn); + try { + UnsubscribeResult unSubscribeResult = snsClient.unsubscribe(unsubscribeRequest); + }catch(Exception e) + { + throw new AppException(500, "Server Error", "Error deleting SNS subscription"); + } + + + } + + public boolean doesSubscriptionExist(String subscriptionArn, String topicName) { + + //There is no way in aws java sdk to look up sns topic arn by name. So we call createTopic, + // if it exists, it returns the arn without creating the topic + //CreateTopicResult createRes = sns.createTopic("HelloTopic"); + //We might want to create a separate table for Topic -- TopicArn + + // For now retrieving the single topic created by cloudformation. This miht change in the future if + //multiple topics are created using Topics APIS. + //See Gitlab issue:https://community.opengroup.org/osdu/platform/system/register/-/issues/14 + SSMConfig ssmConfig = new SSMConfig(); + ParameterStorePropertySource ssm = ssmConfig.amazonSSM(); + amazonSNSTopicArn = ssm.getProperty(awsServiceConfig.getSnsTopicArn()).toString(); + + ListSubscriptionsByTopicRequest listSubsRequest = new ListSubscriptionsByTopicRequest(amazonSNSTopicArn); + //only returns the first 100, for the next lot pass nextToken + + ListSubscriptionsByTopicResult listSubsResult = snsClient.listSubscriptionsByTopic(listSubsRequest); + List<Subscription> allSubsByTopic = listSubsResult.getSubscriptions(); + for(Subscription s: allSubsByTopic) + { + if(s.getSubscriptionArn().equals(subscriptionArn)){ + return true; + }else{ + continue; + } + + } + + return false; + + + + } + + +} diff --git a/provider/register-aws/src/main/java/org/opengroup/osdu/register/provider/aws/util/DocUtil.java b/provider/register-aws/src/main/java/org/opengroup/osdu/register/provider/aws/util/DocUtil.java new file mode 100644 index 0000000000000000000000000000000000000000..cbb7c859aa4f9c2285701e4ce7e64486d4d27e70 --- /dev/null +++ b/provider/register-aws/src/main/java/org/opengroup/osdu/register/provider/aws/util/DocUtil.java @@ -0,0 +1,77 @@ +// Copyright © 2020 Amazon Web Services +// +// 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.register.provider.aws.util; + +import com.amazonaws.services.dynamodbv2.datamodeling.PaginatedQueryList; +import org.opengroup.osdu.core.aws.dynamodb.DynamoDBQueryHelper; + +import org.opengroup.osdu.register.ddms.model.Ddms; +import org.opengroup.osdu.register.provider.aws.ddms.DdmsDoc; +import org.opengroup.osdu.register.provider.aws.subscriber.KmsHelper; +import org.opengroup.osdu.register.provider.aws.subscriber.SubscriptionDoc; +import org.opengroup.osdu.register.subscriber.model.*; +import org.opengroup.osdu.register.utils.Constants; + +import java.util.ArrayList; +import java.util.List; + + + +public class DocUtil { + + private KmsHelper kmsHelper; + + public List<Ddms> getDdmsList(DynamoDBQueryHelper queryHelper, DdmsDoc gsiQuery) { + + PaginatedQueryList<DdmsDoc> results = queryHelper.queryByGSI(DdmsDoc.class, gsiQuery); + List<Ddms> ddmsList = new ArrayList<Ddms>(); + if(results!=null) { + for (DdmsDoc ddmsDoc : results) { + ddmsList.add(DdmsDoc.mapto(ddmsDoc)); + } + } + return ddmsList; + } + + public List<Subscription> getSubscriptionList(DynamoDBQueryHelper queryHelper, SubscriptionDoc gsiQuery) { + PaginatedQueryList<SubscriptionDoc> results = queryHelper.queryByGSI(SubscriptionDoc.class,gsiQuery); + List<Subscription> subsList = new ArrayList<Subscription>(); + if(results!=null) { + for (SubscriptionDoc subsDoc : results) { + String secretValue = kmsHelper.decrypt(subsDoc.getSecretValue()); + Secret secret = createSecret(subsDoc.getSecretType(), secretValue); + subsList.add(SubscriptionDoc.mapTo(subsDoc, secret)); + } + } + return subsList; + } + public Secret createSecret(String secretType, String secretValue) + { + Secret secret; + if (secretType.equals(Constants.GSASecret)) { + GsaSecret gsaSecret = new GsaSecret(); + String[] splitSecret = secretValue.split("`"); + gsaSecret.setValue(new GsaSecretValue(splitSecret[0], splitSecret[1])); + secret = gsaSecret; + } else { + HmacSecret hmacSecret = new HmacSecret(); + hmacSecret.setValue(secretValue); + secret = hmacSecret; + } + + return secret; + } + +} diff --git a/provider/register-aws/src/main/java/org/opengroup/osdu/register/provider/aws/util/GoogleServiceAccountImpl.java b/provider/register-aws/src/main/java/org/opengroup/osdu/register/provider/aws/util/GoogleServiceAccountImpl.java new file mode 100644 index 0000000000000000000000000000000000000000..ef07e95214f63fe01e75464c5c2faaa6e80d1c96 --- /dev/null +++ b/provider/register-aws/src/main/java/org/opengroup/osdu/register/provider/aws/util/GoogleServiceAccountImpl.java @@ -0,0 +1,38 @@ +// Copyright © 2020 Amazon Web Services +// +// 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.register.provider.aws.util; + +import lombok.SneakyThrows; +import org.opengroup.osdu.register.utils.IGoogleServiceAccount; +import org.springframework.stereotype.Component; +//Should be removed from core and then from here... adding temporarily to get the application started + +@Component +public class GoogleServiceAccountImpl implements IGoogleServiceAccount { + + @SneakyThrows + @Override + public String getIdToken(String keyString, String audience) { + // TODO Add implementation for generating GSA Tokens + return "Token"; + } + + @SneakyThrows + @Override + public String getPrivateKeyId(String keyString) { + // TODO Add implementation for fetching GSA Private Keys + return "Private-Key"; + } +} diff --git a/provider/register-aws/src/main/resources/application.properties b/provider/register-aws/src/main/resources/application.properties new file mode 100644 index 0000000000000000000000000000000000000000..a5dc896557201a662aa866d7706b416848dd4463 --- /dev/null +++ b/provider/register-aws/src/main/resources/application.properties @@ -0,0 +1,47 @@ +# Copyright © 2020 Amazon Web Services +# +# 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. + +LOG_PREFIX=register +logging.level.org.springframework.web=${LOG_LEVEL:INFO} +server.servlet.contextPath=/api/register/v1 +server.port=${APPLICATION_PORT:8080} +ACCEPT_HTTP=true + +##AUTHORIZE_API=${ENTITLEMENTS_BASE_URL}/api/entitlements/v1 +#Register service is using AppServiceConfig to define all env. variables. Here ENTITLEMENTS_API is used instead of AUTHORIZE_API +ENTITLEMENTS_API=${ENTITLEMENTS_BASE_URL}/api/entitlements/v1 +## AWS DynamoDB configuration + +aws.dynamodb.table.prefix=${ENVIRONMENT}- +aws.dynamodb.endpoint=dynamodb.${AWS_REGION}.amazonaws.com +aws.region=${AWS_REGION} + + +aws.kms.endpoint=kms.${AWS_REGION}.amazonaws.com + + +aws.ssm=${SSM_ENABLED:True} +aws.environment = ${ENVIRONMENT} +aws.parameter.prefix=/osdu/${ENVIRONMENT} +aws.register.sns.topic.arn=${aws.parameter.prefix}/register/register-sns-topic-arn +aws.register.kms.key.id=${aws.parameter.prefix}/register/register-kms-key-id + + +#logging configuration +logging.transaction.enabled=true +logging.slf4jlogger.enabled=true +logging.mdccontext.enabled=true + +# if this is turned on then the service tries to connect to elastic search +management.health.elasticsearch.enabled=false \ No newline at end of file diff --git a/provider/register-aws/src/test/java/org/opengroup/osdu/register/provider/aws/action/AwsActionRepoTest.java b/provider/register-aws/src/test/java/org/opengroup/osdu/register/provider/aws/action/AwsActionRepoTest.java new file mode 100644 index 0000000000000000000000000000000000000000..9907e10026fb58a904463c8bc72162adbb8e1dea --- /dev/null +++ b/provider/register-aws/src/test/java/org/opengroup/osdu/register/provider/aws/action/AwsActionRepoTest.java @@ -0,0 +1,185 @@ +// Copyright © 2020 Amazon Web Services +// +// 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.register.provider.aws.action; + + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.mockito.runners.MockitoJUnitRunner; +import org.opengroup.osdu.core.aws.dynamodb.DynamoDBQueryHelper; + +import org.opengroup.osdu.core.common.logging.JaxRsDpsLog; +import org.opengroup.osdu.core.common.model.http.AppException; +import org.opengroup.osdu.core.common.model.http.DpsHeaders; +import org.opengroup.osdu.register.action.model.Action; +import org.opengroup.osdu.register.provider.aws.util.TestUtils; + +import java.util.ArrayList; + +import java.util.List; + + +import static org.junit.Assert.assertEquals; + + +import static org.mockito.Mockito.lenient; + +@RunWith(MockitoJUnitRunner.class) +public class AwsActionRepoTest { + + @Mock + private DpsHeaders dpsHeaders; + + @Mock + DynamoDBQueryHelper dynamoDBQueryHelper; + + @Mock + private JaxRsDpsLog logger; + + @InjectMocks + private AwsActionRepo repo; + + @Before + public void init() { + lenient().doReturn(TestUtils.getDataPartitionId()).when(dpsHeaders).getPartitionId(); + + } + + @Test + public void createAction_success(){ + Action action = createMockAction(); + Mockito.doNothing().when(dynamoDBQueryHelper).save(Mockito.any(ActionDoc.class)); + Action resultAction = repo.createAction(action); + assertEquals(action, resultAction); + + } + + + @Test + public void createAction_throw400_whenIdNull(){ + Action action = createMockAction(); + action.setId(null); + + try { + Action resultAction = repo.createAction(action); + } catch (AppException e) { + assertEquals(400, e.getError().getCode()); + } + } + + @Test + public void createAction_throw409_whenIdAlreadyExists(){ + Action action = createMockAction(); + AppException e = new AppException(409, "Conflict", String.format("An action already exists with the id: %s", action.getId())); + Mockito.doThrow(e).when(dynamoDBQueryHelper).save(Mockito.any(ActionDoc.class)); + + try { + Action resultAction = repo.createAction(action); + } catch (AppException ex) { + assertEquals(409, ex.getError().getCode()); + } + } + + @Test + public void deleteAction_success(){ + String id = TestUtils.getAction_id(); + Mockito.doNothing().when(dynamoDBQueryHelper).deleteByPrimaryKey(ActionDoc.class, id); + Boolean result = repo.delete(id); + assertEquals(result, true); + } + + @Test + public void deleteAction_throw404_whenIdoesNotExist(){ + String id = TestUtils.getAction_id(); + AppException e = new AppException(404,"",""); + Mockito.doThrow(e).when(dynamoDBQueryHelper).deleteByPrimaryKey(ActionDoc.class, id); + Boolean result=true; + try { + result = repo.delete(id); + } catch (AppException ex) { + assertEquals(404, ex.getError().getCode()); + assertEquals(false, result); + } + } + + @Test + public void getAction_success(){ + Action action = createMockAction(); + String id = TestUtils.getAction_id(); + ActionDoc doc = ActionDoc.mapFrom(action, TestUtils.getDataPartitionId()); + Mockito.when(dynamoDBQueryHelper.loadByPrimaryKey(ActionDoc.class, id)).thenReturn(doc); + + Action resultAction = repo.get(id); + action.setCreatedOnEpoch(resultAction.getCreatedOnEpoch()); + assertEquals(action, resultAction); + + } + + @Test + public void getAction_throw404_whenIdoesNotExist(){ + String id = TestUtils.getAction_id(); + AppException e = new AppException(404,"",""); + Mockito.doThrow(e).when(dynamoDBQueryHelper).loadByPrimaryKey(ActionDoc.class, id); + Boolean result=true; + try { + Action resultAction = repo.get(id); + } catch (AppException ex) { + assertEquals(404, ex.getError().getCode()); + + } + } + + @Test + public void getAllActions_success(){ + Action action1 = createMockAction(); + Action action2 = createMockAction(); + action2.setId("ActionId2"); + + ActionDoc doc1 = ActionDoc.mapFrom(action1,TestUtils.getDataPartitionId()); + ActionDoc doc2 = ActionDoc.mapFrom(action2,TestUtils.getDataPartitionId()); + + ArrayList<ActionDoc> actionDocs = new ArrayList<ActionDoc>(); + actionDocs.add(doc1); + actionDocs.add(doc2); + Mockito.when(dynamoDBQueryHelper.scanTable(Mockito.any(Class.class),Mockito.anyString(),Mockito.anyMap())).thenReturn(actionDocs); + List<Action> resultActions = repo.getAllActions(); + action1.setCreatedOnEpoch(resultActions.get(0).getCreatedOnEpoch()); + action2.setCreatedOnEpoch(resultActions.get(1).getCreatedOnEpoch()); + List<Action> actions =new ArrayList<Action>(); + actions.add(action1); + actions.add(action2); + assertEquals(actions, resultActions); + + } + + private Action createMockAction() { + Action action = new Action(); + action.setId(TestUtils.getAction_id()); + action.setName(TestUtils.getAction_name()); + action.setDescription(TestUtils.getAction_description()); + action.setImg(TestUtils.getAction_img()); + action.setUrl(TestUtils.getAction_url()); + action.setContactEmail(TestUtils.getAction_contactEmail()); + action.setFilter(TestUtils.getAction_filter()); + + return action; + } + + +} diff --git a/provider/register-aws/src/test/java/org/opengroup/osdu/register/provider/aws/ddms/AwsDdmsRepoTest.java b/provider/register-aws/src/test/java/org/opengroup/osdu/register/provider/aws/ddms/AwsDdmsRepoTest.java new file mode 100644 index 0000000000000000000000000000000000000000..c332091cb595edb808038132bcc4cf3c2f250819 --- /dev/null +++ b/provider/register-aws/src/test/java/org/opengroup/osdu/register/provider/aws/ddms/AwsDdmsRepoTest.java @@ -0,0 +1,178 @@ +// Copyright © 2020 Amazon Web Services +// +// 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.register.provider.aws.ddms; + + + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.mockito.runners.MockitoJUnitRunner; +import org.opengroup.osdu.core.aws.dynamodb.DynamoDBQueryHelper; +import org.opengroup.osdu.core.common.logging.JaxRsDpsLog; +import org.opengroup.osdu.core.common.model.http.AppException; +import org.opengroup.osdu.core.common.model.http.DpsHeaders; +import org.opengroup.osdu.register.ddms.model.Ddms; +import org.opengroup.osdu.register.ddms.model.RegisteredInterface; +import org.opengroup.osdu.register.provider.aws.util.DocUtil; +import org.opengroup.osdu.register.provider.aws.util.TestUtils; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +import static org.junit.Assert.assertEquals; +import static org.mockito.Mockito.lenient; + + +@RunWith(MockitoJUnitRunner.class) +public class AwsDdmsRepoTest { + + @Mock + private DpsHeaders dpsHeaders; + + @Mock + DynamoDBQueryHelper dynamoDBQueryHelper; + + @Mock + private JaxRsDpsLog logger; + + @InjectMocks + private AwsDdmsRepo repo; + + + @Mock + private DocUtil docUtil; + + + + + @Before + public void init() { + lenient().doReturn(TestUtils.getDataPartitionId()).when(dpsHeaders).getPartitionId(); + + } + + @Test + public void createDdms_success(){ + Ddms ddms = createMockDdms(); + Mockito.doNothing().when(dynamoDBQueryHelper).save(Mockito.any(DdmsDoc.class)); + Ddms resultDdms = repo.create(ddms); + assertEquals(ddms, resultDdms); + + } + @Test + public void createDdms_throw409_whenIdAlreadyExists(){ + Ddms ddms = createMockDdms(); + AppException e =new AppException(409, "Conflict", String.format("A DDMS already exists with the same id: %s", ddms.getId())); + Mockito.doThrow(e).when(dynamoDBQueryHelper).save(Mockito.any(DdmsDoc.class)); + + try { + Ddms resultDdms = repo.create(ddms); + } catch (AppException ex) { + assertEquals(409, ex.getError().getCode()); + } + } + + @Test + public void getDdms_success(){ + Ddms ddms = createMockDdms(); + String id = TestUtils.getDdms_id(); + DdmsDoc doc = DdmsDoc.mapFrom(ddms, TestUtils.getDataPartitionId()); + Mockito.when(dynamoDBQueryHelper.loadByPrimaryKey(DdmsDoc.class, id)).thenReturn(doc); + + Ddms resultDdms = repo.get(id); + ddms.setCreatedDateTimeEpoch(resultDdms.getCreatedDateTimeEpoch()); + assertEquals(ddms, resultDdms); + + } + + @Test + public void getDdms_throw404_whenIdoesNotExist(){ + String id = TestUtils.getDdms_id(); + AppException e = new AppException(404,"",""); + Mockito.doThrow(e).when(dynamoDBQueryHelper).loadByPrimaryKey(DdmsDoc.class, id); + Boolean result=true; + try { + Ddms resultDdms = repo.get(id); + } catch (AppException ex) { + assertEquals(404, ex.getError().getCode()); + + } + } + + @Test + public void deleteDdms_success(){ + String id = TestUtils.getDdms_id(); + Mockito.doNothing().when(dynamoDBQueryHelper).deleteByPrimaryKey(DdmsDoc.class, id); + Boolean result = repo.delete(id); + assertEquals(result, true); + } + + @Test + public void deleteDdms_throw404_whenIdoesNotExist(){ + String id = TestUtils.getDdms_id(); + AppException e = new AppException(404,"",""); + Mockito.doThrow(e).when(dynamoDBQueryHelper).deleteByPrimaryKey(DdmsDoc.class, id); + Boolean result=true; + try { + result = repo.delete(id); + } catch (AppException ex) { + assertEquals(404, ex.getError().getCode()); + assertEquals(false, result); + } + } + + @Test + public void query_success(){ + Ddms ddms1 = createMockDdms(); + Ddms ddms2 = createMockDdms(); + ddms2.setId("DdmsId2"); + List<Ddms> ddmsList = new ArrayList<Ddms>(); + ddmsList.add(ddms1); + ddmsList.add(ddms2); + + DdmsDoc doc1 = DdmsDoc.mapFrom(ddms1,TestUtils.getDataPartitionId()); + DdmsDoc doc2 = DdmsDoc.mapFrom(ddms2,TestUtils.getDataPartitionId()); + + + List<DdmsDoc> ddmsDocsList = new ArrayList<DdmsDoc>(); + ddmsDocsList.add(doc1); + ddmsDocsList.add(doc2); + Mockito.when(docUtil.getDdmsList(Mockito.any(DynamoDBQueryHelper.class),Mockito.any(DdmsDoc.class))).thenReturn(ddmsList); + + List<Ddms> resultDdmsList = repo.query("type"); + + + ddmsList.get(0).setCreatedDateTimeEpoch(resultDdmsList.get(0).getCreatedDateTimeEpoch()); + ddmsList.get(1).setCreatedDateTimeEpoch(resultDdmsList.get(1).getCreatedDateTimeEpoch()); + + assertEquals(ddmsList, resultDdmsList); + + } + private Ddms createMockDdms() { + Ddms ddms = new Ddms(); + RegisteredInterface ri = new RegisteredInterface(); + ri.setEntityType("type"); + ri.setSchema(Collections.singletonMap("first", "second")); + ddms.setId(TestUtils.getDdms_id()); + ddms.setName(TestUtils.getDdms_name()); + ddms.setDescription(TestUtils.getDdms_description()); + ddms.setContactEmail(TestUtils.getAction_contactEmail()); + ddms.getInterfaces().add(ri); + return ddms; + } +} diff --git a/provider/register-aws/src/test/java/org/opengroup/osdu/register/provider/aws/subscriber/AwsSubscriptionRepoTest.java b/provider/register-aws/src/test/java/org/opengroup/osdu/register/provider/aws/subscriber/AwsSubscriptionRepoTest.java new file mode 100644 index 0000000000000000000000000000000000000000..65added948a53390853e956ea0a56ee32b3c6b6c --- /dev/null +++ b/provider/register-aws/src/test/java/org/opengroup/osdu/register/provider/aws/subscriber/AwsSubscriptionRepoTest.java @@ -0,0 +1,352 @@ +// Copyright © 2020 Amazon Web Services +// +// 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.register.provider.aws.subscriber; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.mockito.runners.MockitoJUnitRunner; +import org.opengroup.osdu.core.aws.dynamodb.DynamoDBQueryHelper; +import org.opengroup.osdu.core.common.logging.JaxRsDpsLog; +import org.opengroup.osdu.core.common.model.http.AppException; +import org.opengroup.osdu.core.common.model.http.DpsHeaders; +import org.opengroup.osdu.register.ddms.model.Ddms; +import org.opengroup.osdu.register.provider.aws.config.AwsServiceConfig; +import org.opengroup.osdu.register.provider.aws.ddms.DdmsDoc; +import org.opengroup.osdu.register.provider.aws.util.DocUtil; +import org.opengroup.osdu.register.provider.aws.util.TestUtils; +import org.opengroup.osdu.register.subscriber.model.*; +import org.opengroup.osdu.register.utils.Constants; + +import java.sql.Timestamp; +import java.util.ArrayList; +import java.util.List; + +import static org.junit.Assert.assertEquals; +import static org.mockito.Mockito.lenient; +import static org.mockito.Mockito.when; + +@RunWith(MockitoJUnitRunner.class) +public class AwsSubscriptionRepoTest { + + @Mock + private DpsHeaders dpsHeaders; + + @Mock + DynamoDBQueryHelper dynamoDBQueryHelper; + + @Mock + private JaxRsDpsLog logger; + + @InjectMocks + private AwsSubscriptionRepo repo; + + + @Mock + private DocUtil docUtil; + + + @Mock + private KmsHelper kmsHelper; + + @Mock + private AwsServiceConfig serviceConfig; + + @Mock + private SubscriptionDoc subscriptionDoc; + + @Mock + private SubscriptionHelper snsHelper; + + + @Before + public void init() { + lenient().doReturn(TestUtils.getDataPartitionId()).when(dpsHeaders).getPartitionId(); + + + + } + + @Test + public void getSubscription_success(){ + Subscription sub = createMockSubscription(); + SubscriptionDoc subDoc = createMockSubscriptionDoc(); + String id = TestUtils.getSub_id(); + + Mockito.when(dynamoDBQueryHelper.loadByPrimaryKey(SubscriptionDoc.class, id)).thenReturn(subDoc); + Mockito.when(kmsHelper.decrypt(Mockito.anyString())).thenReturn(TestUtils.getSub_secretValue()); + Mockito.when((docUtil.createSecret(Mockito.anyString(),Mockito.anyString()))).thenReturn(createTestSecret()); + + + Subscription resultSub = repo.get(id); + sub.setCreatedOnEpoch(resultSub.getCreatedOnEpoch()); + assertEquals(sub, resultSub); + + } + + @Test + public void getSubscription_throw404_whenIdoesNotExist(){ + String id = TestUtils.getSub_id(); + AppException e = new AppException(404,"",""); + Mockito.doThrow(e).when(dynamoDBQueryHelper).loadByPrimaryKey(SubscriptionDoc.class, id); + Boolean result=true; + try { + Subscription resultSub = repo.get(id); + } catch (AppException ex) { + assertEquals(404, ex.getError().getCode()); + + } + } + + @Test + public void createSubscription_success() throws Exception { + Subscription s = createMockSubscription(); + Mockito.when(snsHelper.createPushSubscription(Mockito.anyString())).thenReturn(TestUtils.getSub_sns_subscriptionArn()); + Mockito.when(kmsHelper.encrypt(Mockito.anyString())).thenReturn(TestUtils.getSub_encrypted_secret_value()); + Mockito.doNothing().when(dynamoDBQueryHelper).save(Mockito.any(SubscriptionDoc.class)); + + + + Subscription resultSub = repo.create(s); + s.setCreatedOnEpoch(resultSub.getCreatedOnEpoch()); + assertEquals(s, resultSub); + } + + @Test + public void createSubscription_throw409_ifIdalreadyexists() throws Exception { + Subscription s = createMockSubscription(); + AppException e =new AppException(409, "Conflict", String.format("A Subscription already exists with the same id: %s", s.getId())); + Mockito.doThrow(e).when(dynamoDBQueryHelper).save(Mockito.any(SubscriptionDoc.class)); + try { + Subscription resultSub = repo.create(s); + } + catch (AppException ex) { + assertEquals(409, ex.getError().getCode()); + } + + + } + + @Test + public void delete_success() { + + SubscriptionDoc subDoc = createMockSubscriptionDoc(); + String id = TestUtils.getSub_id(); + Mockito.when(dynamoDBQueryHelper.loadByPrimaryKey(SubscriptionDoc.class, id)).thenReturn(subDoc); + Mockito.doNothing().when(dynamoDBQueryHelper).deleteByPrimaryKey(SubscriptionDoc.class, id); + Mockito.doNothing().when(snsHelper).deletePushSubscription(Mockito.anyString()); + + boolean result = repo.delete(id); + assertEquals(true,result); + } + + @Test + public void delete_throws404_whenIddoesNotExist() { + String id = TestUtils.getSub_id(); + AppException e = new AppException(404,"",""); + Mockito.doThrow(e).when(dynamoDBQueryHelper).loadByPrimaryKey(SubscriptionDoc.class, id); + Boolean result=true; + try { + result = repo.delete(id); + } catch (AppException ex) { + assertEquals(404, ex.getError().getCode()); + } + } + + + @Test + public void patch_success() { + + Subscription s = createMockSubscription(); + SubscriptionDoc subDoc = createMockSubscriptionDoc(); + String id = TestUtils.getSub_id(); + + Secret secret = Mockito.mock(Secret.class); + Mockito.when(dynamoDBQueryHelper.loadByPrimaryKey(SubscriptionDoc.class, id)).thenReturn(subDoc); + Mockito.when(secret.getSecretType()).thenReturn(TestUtils.getSub_secretType()); + Mockito.when(kmsHelper.encrypt(Mockito.anyString())).thenReturn(TestUtils.getSub_updated_encrypted_secretValue()); + Mockito.doNothing().when(dynamoDBQueryHelper).save(Mockito.any(SubscriptionDoc.class)); + + boolean result = repo.patch(s,secret); + assertEquals(true,result); + + } + + @Test + public void patch_throwException_ifcannotBeUpdated() { + + Subscription s = createMockSubscription(); + SubscriptionDoc subDoc = createMockSubscriptionDoc(); + String id = TestUtils.getSub_id(); + AppException e = new AppException(500,"","Error while saving the updated secret"); + + Secret secret = Mockito.mock(Secret.class); + Mockito.when(dynamoDBQueryHelper.loadByPrimaryKey(SubscriptionDoc.class, id)).thenReturn(subDoc); + Mockito.when(secret.getSecretType()).thenReturn(TestUtils.getSub_secretType()); + Mockito.when(kmsHelper.encrypt(Mockito.anyString())).thenReturn(TestUtils.getSub_updated_encrypted_secretValue()); + Mockito.doThrow(e).when(dynamoDBQueryHelper).save(Mockito.any(SubscriptionDoc.class)); + + try { + boolean result = repo.patch(s,secret); + } catch (AppException ex) { + assertEquals(500, ex.getError().getCode()); + assertEquals("Error while saving the updated secret", ex.getError().getMessage()); + } + + + } + + @Test + public void patch_throw404_ifIdoesNotExist() { + Subscription s = createMockSubscription(); + String id = TestUtils.getSub_id(); + + Secret secret = Mockito.mock(Secret.class); + + AppException e = new AppException(404,"",""); + Mockito.doThrow(e).when(dynamoDBQueryHelper).loadByPrimaryKey(SubscriptionDoc.class, id); + Boolean result=true; + try { + result = repo.patch(s,secret); + } catch (AppException ex) { + assertEquals(404, ex.getError().getCode()); + } + + } + @Test + public void getAll_success() throws Exception { + + Subscription s1 = createMockSubscription(); + Subscription s2 = createMockSubscription(); + s2.setId("SubTestId2"); + List<Subscription> subList = new ArrayList<Subscription>(); + SubscriptionDoc doc1 = SubscriptionDoc.mapFrom(s1,TestUtils.getDataPartitionId(),TestUtils.getSub_sns_subscriptionArn(), TestUtils.getSub_encrypted_secret_value()); + SubscriptionDoc doc2 = SubscriptionDoc.mapFrom(s2,TestUtils.getDataPartitionId(),TestUtils.getSub_sns_subscriptionArn(), TestUtils.getSub_encrypted_secret_value()); + + + ArrayList<SubscriptionDoc> subDocs = new ArrayList<SubscriptionDoc>(); + subDocs.add(doc1); + subDocs.add(doc2); + + Mockito.when(dynamoDBQueryHelper.scanTable(Mockito.any(Class.class),Mockito.anyString(),Mockito.anyMap())).thenReturn(subDocs); + Mockito.when(kmsHelper.decrypt(Mockito.anyString())).thenReturn(TestUtils.getSub_secretValue()); + Mockito.when((docUtil.createSecret(Mockito.anyString(),Mockito.anyString()))).thenReturn(createTestSecret()); + + List<Subscription> resultSubs = repo.getAll(); + s1.setCreatedOnEpoch(resultSubs.get(0).getCreatedOnEpoch()); + s2.setCreatedOnEpoch(resultSubs.get(1).getCreatedOnEpoch()); + + subList.add(s1); + subList.add(s2); + assertEquals(subList, resultSubs); + + + } + + @Test + public void getAll_fail() throws Exception { + + Subscription s1 = createMockSubscription(); + Subscription s2 = createMockSubscription(); + s2.setId("SubTestId2"); + List<Subscription> subList = new ArrayList<Subscription>(); + SubscriptionDoc doc1 = SubscriptionDoc.mapFrom(s1,TestUtils.getDataPartitionId(),TestUtils.getSub_sns_subscriptionArn(), TestUtils.getSub_encrypted_secret_value()); + SubscriptionDoc doc2 = SubscriptionDoc.mapFrom(s2,TestUtils.getDataPartitionId(),TestUtils.getSub_sns_subscriptionArn(), TestUtils.getSub_encrypted_secret_value()); + + + ArrayList<SubscriptionDoc> subDocs = new ArrayList<SubscriptionDoc>(); + subDocs.add(doc1); + subDocs.add(doc2); + AppException e = new AppException(500,"","Error while getting ALL subscriptions"); + Mockito.doThrow(e).when(dynamoDBQueryHelper).scanTable(Mockito.any(Class.class),Mockito.anyString(),Mockito.anyMap()); + try { + List<Subscription> resultSubs = repo.getAll(); + } catch (AppException ex) { + assertEquals(500, ex.getError().getCode()); + assertEquals("Error while getting ALL subscriptions", ex.getError().getMessage()); + } + + + + } + + @Test + public void query_success() throws Exception { + Subscription s1 = createMockSubscription(); + Subscription s2 = createMockSubscription(); + s2.setId("SubTestId2"); + List<Subscription> subList = new ArrayList<Subscription>(); + subList.add(s1); + subList.add(s2); + + SubscriptionDoc doc1 = SubscriptionDoc.mapFrom(s1,TestUtils.getDataPartitionId(),TestUtils.getSub_sns_subscriptionArn(),TestUtils.getSub_encrypted_secret_value()); + SubscriptionDoc doc2 = SubscriptionDoc.mapFrom(s2,TestUtils.getDataPartitionId(),TestUtils.getSub_sns_subscriptionArn(),TestUtils.getSub_encrypted_secret_value()); + + + List<SubscriptionDoc> subDocsList = new ArrayList<SubscriptionDoc>(); + subDocsList.add(doc1); + subDocsList.add(doc2); + //Mockito.when(kmsHelper.decrypt(Mockito.anyString())).thenReturn(TestUtils.getSub_secretValue()); + Mockito.when(docUtil.getSubscriptionList(Mockito.any(DynamoDBQueryHelper.class),Mockito.any(SubscriptionDoc.class))).thenReturn(subList); + + List<Subscription> resultSubList = repo.query(TestUtils.getSub_notificationId()); + + + subList.get(0).setCreatedOnEpoch(resultSubList.get(0).getCreatedOnEpoch()); + subList.get(1).setCreatedOnEpoch(resultSubList.get(1).getCreatedOnEpoch()); + + assertEquals(subList, resultSubList); + + } + + private Subscription createMockSubscription() { + Subscription sub = new Subscription(); + sub.setId(TestUtils.getSub_id()); + sub.setSecret(new HmacSecret(TestUtils.getSub_secretValue())); + sub.setNotificationId(TestUtils.getSub_id()); + sub.setTopic(TestUtils.getSub_topicName()); + + + + return sub; + } + + + + private SubscriptionDoc createMockSubscriptionDoc() { + SubscriptionDoc subDoc = new SubscriptionDoc(); + subDoc.setId(TestUtils.getSub_id()); + subDoc.setSecretType(TestUtils.getSub_secretType()); + subDoc.setNotificationId(TestUtils.getSub_id()); + subDoc.setTopic(TestUtils.getSub_topicName()); + subDoc.setSecretValue(TestUtils.getSub_secretValue()); + subDoc.setCreatedOnEpoch(new Timestamp(System.currentTimeMillis())); + subDoc.setSnssubscriptionArn(TestUtils.getSub_sns_subscriptionArn()); + + return subDoc; + } + + public Secret createTestSecret() + { + Secret secret; + HmacSecret hmacSecret = new HmacSecret(); + hmacSecret.setValue(TestUtils.getSub_secretValue()); + secret = hmacSecret; + return secret; + } + +} diff --git a/provider/register-aws/src/test/java/org/opengroup/osdu/register/provider/aws/util/TestUtils.java b/provider/register-aws/src/test/java/org/opengroup/osdu/register/provider/aws/util/TestUtils.java new file mode 100644 index 0000000000000000000000000000000000000000..5f7e6d92979720466b0a628688e9fef395b0372a --- /dev/null +++ b/provider/register-aws/src/test/java/org/opengroup/osdu/register/provider/aws/util/TestUtils.java @@ -0,0 +1,152 @@ +// Copyright © 2020 Amazon Web Services +// Copyright © Microsoft Corporation +// +// 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.register.provider.aws.util; + +import org.opengroup.osdu.register.action.model.Filter; + +import java.sql.Timestamp; + +public class TestUtils { + + private TestUtils() { + } + + private static final String dataPartitionId = "opendes"; + + //Action + private static final String action_id = "ActionTestId1"; + private static final String action_name = "ActionTestName"; + private static final String action_description = "ActionTestDescription"; + private static final String action_img = "https://mycdn.com/img.png"; + private static final String action_url = "https://myapp.osdu.opengroup.org/action/{id}/{data.project}"; + private static final String action_contactEmail = "testuser@test.com"; + private static Filter action_filter = new Filter(); + + + //Ddms + + private static final String ddms_id = "DdmsTestId1"; + private static final String ddms_name = "DdmsTestName"; + private static final String ddms_description = "ddmsTestDescription"; + private static final String ddms_contactEmail = "testuser@test.com"; + + //Subscription + private static final String sub_id = "SubTestid1"; + private static final String sub_secretValue = "test-secret-value"; + private static final String sub_secretType = "test-secret-type"; + private static final String sub_topicName = "aws-topic-name"; + + private static final String sub_notificationId= "testNotificationId"; + + + private static final String sub_sns_subscriptionArn = "testArn"; + + + + private static final String sub_encrypted_secret_value = "test-encrypted-value"; + + + + private static final String sub_updated_encrypted_secretValue = "test-updated-encrypted-secret-value"; + + + public static String getAction_id() { + return action_id; + } + + public static String getAction_name() { + return action_name; + } + + public static String getAction_description() { + return action_description; + } + + public static String getAction_img() { + return action_img; + } + + public static String getAction_url() { + return action_url; + } + + public static Filter getAction_filter() { + return action_filter; + } + + public static String getDataPartitionId() { + return dataPartitionId; + } + + public static String getAction_contactEmail() { return action_contactEmail; } + + public static String getDdms_id() { + return ddms_id; + } + + public static String getDdms_name() { + return ddms_name; + } + + public static String getDdms_description() { + return ddms_description; + } + + public static String getDdms_contactEmail() { + return ddms_contactEmail; + } + + + public static String getSub_secretValue() { + return sub_secretValue; + } + + public static String getSub_secretType() { + return sub_secretType; + } + + public static String getSub_topicName() { + return sub_topicName; + } + + public static String getSub_id() { + return sub_id; + } + + + public static String getSub_encrypted_secret_value() { + return sub_encrypted_secret_value; + } + + public static String getSub_sns_subscriptionArn() { + return sub_sns_subscriptionArn; + } + + public static String getSub_updated_encrypted_secretValue() { + return sub_updated_encrypted_secretValue; + } + + public static String getSub_notificationId() { + return sub_notificationId; + } + +} + + + + + + diff --git a/provider/register-azure/src/test/java/org/opengroup/osdu/register/provider/azure/ddms/DdmsRepositoryTest.java b/provider/register-azure/src/test/java/org/opengroup/osdu/register/provider/azure/ddms/DdmsRepositoryTest.java index 256e9320ac4690dd0a4dd44301eb920f8b735baa..638ace3bb4b390790db3f00ecde69a30d0d9dec0 100644 --- a/provider/register-azure/src/test/java/org/opengroup/osdu/register/provider/azure/ddms/DdmsRepositoryTest.java +++ b/provider/register-azure/src/test/java/org/opengroup/osdu/register/provider/azure/ddms/DdmsRepositoryTest.java @@ -74,6 +74,7 @@ public class DdmsRepositoryTest { @InjectMocks private DdmsRepository repo; + @BeforeEach void init() { lenient().doReturn(dataPartitionId).when(dpsHeaders).getPartitionId();