diff --git a/.gitignore b/.gitignore
index 07cd1b613bdc3e0245ff8dcc265fe2efb391b43f..1a1358c1526f7556049cd9f6d2ceeaf56f2ae69e 100644
--- a/.gitignore
+++ b/.gitignore
@@ -44,3 +44,7 @@ load-tests/*.pyc
# VSCode
.vscode/
+
+.DS_STORE
+
+dist/
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
index 4dd71ad62ba06f1d18e264580225ca22a691dacc..681fed9ba482f6bb008757d25707ae11c679283f 100644
--- a/pom.xml
+++ b/pom.xml
@@ -86,6 +86,7 @@
partition-core
provider/partition-azure
+ provider/partition-aws
@@ -128,5 +129,17 @@
provider/partition-azure
+
+ partition-aws
+
+
+ env
+ partition-aws
+
+
+
+ provider/partition-aws
+
+
diff --git a/provider/partition-aws/build-aws/Dockerfile b/provider/partition-aws/build-aws/Dockerfile
new file mode 100644
index 0000000000000000000000000000000000000000..40a867437a33371d1533caa82e8bf952e2772772
--- /dev/null
+++ b/provider/partition-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/partition-aws/target/*spring-boot.jar
+WORKDIR /
+COPY ${JAR_FILE} app.jar
+EXPOSE 8080
+ENTRYPOINT java $JAVA_OPTS -jar /app.jar
diff --git a/provider/partition-aws/build-aws/build-info.py b/provider/partition-aws/build-aws/build-info.py
new file mode 100644
index 0000000000000000000000000000000000000000..1ea9b54bde9216cd158e4ea43eef41f06b8da1be
--- /dev/null
+++ b/provider/partition-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/partition-aws/build-aws/buildspec.yaml b/provider/partition-aws/build-aws/buildspec.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..a85e849bd55074855115f23b54454557e6616bf6
--- /dev/null
+++ b/provider/partition-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/partition-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 partition-core,provider/partition-aws -Ddeployment.environment=prod
+
+ - echo "Building integration testing assemblies and gathering artifacts..."
+ - ./testing/partition-test-aws/build-aws/prepare-dist.sh
+
+ - echo "Building docker image..."
+ - docker build -f provider/partition-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/partition-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
+ - "partition-core/target/surefire-reports/**/*"
+ - "provider/partition-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/partition-aws/maven/settings.xml b/provider/partition-aws/maven/settings.xml
new file mode 100644
index 0000000000000000000000000000000000000000..b8192246c94558d4c2d65ce1caf42871542dd79e
--- /dev/null
+++ b/provider/partition-aws/maven/settings.xml
@@ -0,0 +1,76 @@
+
+
+
+
+
+
+
+ aws-osdu-dev-maven
+
+ true
+
+
+
+ aws-osdu-dev-maven
+ ${env.AWS_OSDU_DEV_MAVEN_URL}
+
+
+ gitlab-os-core-common-maven
+ https://community.opengroup.org/api/v4/projects/67/packages/maven
+
+
+
+
+ credentialsConfiguration
+
+ true
+
+
+ dev
+ no-default
+ no-default
+ Another-Access-Token-2021
+ no-default
+
+
+
+
+
+
+ aws-osdu-dev-maven
+ aws
+ ${env.AWS_OSDU_DEV_MAVEN_AUTH_TOKEN}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ credentialsConfiguration
+
+
+
\ No newline at end of file
diff --git a/provider/partition-aws/pom.xml b/provider/partition-aws/pom.xml
new file mode 100644
index 0000000000000000000000000000000000000000..f6b201832f9ff2e9c56a48f4e6f5b12ebd29411b
--- /dev/null
+++ b/provider/partition-aws/pom.xml
@@ -0,0 +1,191 @@
+
+
+
+
+
+
+
+ partition
+ org.opengroup.osdu
+ 1.0.0
+ ../../
+
+
+ 4.0.0
+ partition-aws
+ 1.0.0
+ Partition service on AWS
+ jar
+
+
+ 1.11.637
+ dev
+
+
+
+
+
+ com.amazonaws
+ aws-java-sdk-bom
+ ${aws.version}
+ pom
+ import
+
+
+
+
+
+
+
+ org.opengroup.osdu
+ os-core-common
+ ${os-core-common.version}
+
+
+ org.opengroup.osdu.core.aws
+ os-core-lib-aws
+ 0.3.7
+
+
+ org.opengroup.osdu
+ partition-core
+ 1.0.0
+
+
+
+
+ com.amazonaws
+ aws-java-sdk
+ ${aws.version}
+
+
+ com.amazonaws
+ aws-java-sdk-dynamodb
+
+
+ com.amazonaws
+ aws-java-sdk-s3
+
+
+ com.amazonaws
+ aws-java-sdk-sns
+
+
+ com.amazonaws
+ aws-java-sdk-cognitoidentity
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-security
+
+
+ org.springframework.boot
+ spring-boot-starter-actuator
+
+
+ org.springframework.security
+ spring-security-oauth2-client
+
+
+ org.springframework.security
+ spring-security-oauth2-jose
+
+
+ org.springframework.data
+ spring-data-commons
+ 2.1.10.RELEASE
+ compile
+
+
+ javax.inject
+ javax.inject
+ 1
+
+
+ org.projectlombok
+ lombok
+
+
+
+
+ junit
+ junit
+ 4.12
+ test
+
+
+ org.mockito
+ mockito-core
+ 2.25.0
+ test
+
+
+ org.powermock
+ powermock-module-junit4
+ 2.0.2
+
+
+ org.powermock
+ powermock-api-mockito2
+ 2.0.2
+ test
+
+
+ org.springframework.boot
+ spring-boot-starter-test
+ test
+
+
+ org.mockito
+ mockito-all
+
+
+ org.junit.vintage
+ junit-vintage-engine
+
+
+
+
+ org.springframework.security
+ spring-security-test
+ test
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+
+
+ repackage
+
+
+ spring-boot
+ org.opengroup.osdu.partition.provider.aws.PartitionApplication
+
+
+
+
+
+
+
+
diff --git a/provider/partition-aws/src/main/java/org/opengroup/osdu/partition/provider/aws/AwsServiceConfig.java b/provider/partition-aws/src/main/java/org/opengroup/osdu/partition/provider/aws/AwsServiceConfig.java
new file mode 100644
index 0000000000000000000000000000000000000000..005231193c09ea5f3c2bca498a4546a7a2ff1497
--- /dev/null
+++ b/provider/partition-aws/src/main/java/org/opengroup/osdu/partition/provider/aws/AwsServiceConfig.java
@@ -0,0 +1,34 @@
+// 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.partition.provider.aws;
+
+import javax.annotation.PostConstruct;
+
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Component;
+
+@Component
+public class AwsServiceConfig {
+
+ @Value("${aws.resource.prefix}")
+ public String environment;
+
+ public String ssmPartitionPrefix;
+
+ @PostConstruct
+ public void init() {
+ ssmPartitionPrefix = "/osdu/" + environment + "/partition/partitions/";
+ }
+}
diff --git a/provider/partition-aws/src/main/java/org/opengroup/osdu/partition/provider/aws/PartitionApplication.java b/provider/partition-aws/src/main/java/org/opengroup/osdu/partition/provider/aws/PartitionApplication.java
new file mode 100644
index 0000000000000000000000000000000000000000..1a36bf2ecd58bc4fc41ed0c16ab701411e052699
--- /dev/null
+++ b/provider/partition-aws/src/main/java/org/opengroup/osdu/partition/provider/aws/PartitionApplication.java
@@ -0,0 +1,28 @@
+// 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.partition.provider.aws;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.context.annotation.ComponentScan;
+
+@ComponentScan({"org.opengroup.osdu"})
+@SpringBootApplication
+public class PartitionApplication {
+
+ public static void main(String[] args) {
+ SpringApplication.run(PartitionApplication.class, args);
+ }
+}
\ No newline at end of file
diff --git a/provider/partition-aws/src/main/java/org/opengroup/osdu/partition/provider/aws/cache/GroupCache.java b/provider/partition-aws/src/main/java/org/opengroup/osdu/partition/provider/aws/cache/GroupCache.java
new file mode 100644
index 0000000000000000000000000000000000000000..497363457a0830cd4e716e7ed2f1cd4b1c282c54
--- /dev/null
+++ b/provider/partition-aws/src/main/java/org/opengroup/osdu/partition/provider/aws/cache/GroupCache.java
@@ -0,0 +1,40 @@
+// 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.partition.provider.aws.cache;
+
+import org.opengroup.osdu.core.common.model.http.DpsHeaders;
+import org.opengroup.osdu.core.common.model.entitlements.Groups;
+import org.opengroup.osdu.core.common.cache.RedisCache;
+import org.opengroup.osdu.core.common.util.Crc32c;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Component;
+
+@Component
+public class GroupCache extends RedisCache {
+ public GroupCache(@Value("${aws.elasticache.cluster.endpoint}") final String REDIS_GROUP_HOST, @Value("${aws.elasticache.cluster.port}") final String REDIS_GROUP_PORT) {
+ super(REDIS_GROUP_HOST, Integer.parseInt(REDIS_GROUP_PORT), 30, String.class, Groups.class);
+ }
+
+ public static String getGroupCacheKey(DpsHeaders headers) {
+ String key = String.format("entitlement-groups:%s:%s", headers.getPartitionIdWithFallbackToAccountId(),
+ headers.getAuthorization());
+ return Crc32c.hashToBase64EncodedString(key);
+ }
+
+ public static String getPartitionGroupsCacheKey(String dataPartitionId) {
+ String key = String.format("entitlement-groups:data-partition:%s", dataPartitionId);
+ return Crc32c.hashToBase64EncodedString(key);
+ }
+}
diff --git a/provider/partition-aws/src/main/java/org/opengroup/osdu/partition/provider/aws/security/AuthorizationService.java b/provider/partition-aws/src/main/java/org/opengroup/osdu/partition/provider/aws/security/AuthorizationService.java
new file mode 100644
index 0000000000000000000000000000000000000000..f17601a57730abb6a072cb91bf9cd9431957b4de
--- /dev/null
+++ b/provider/partition-aws/src/main/java/org/opengroup/osdu/partition/provider/aws/security/AuthorizationService.java
@@ -0,0 +1,61 @@
+// 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.partition.provider.aws.security;
+
+import org.opengroup.osdu.core.common.entitlements.IEntitlementsAndCacheService;
+import org.opengroup.osdu.core.common.model.http.AppException;
+import org.opengroup.osdu.core.common.model.http.DpsHeaders;
+import org.opengroup.osdu.partition.provider.interfaces.IAuthorizationService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpStatus;
+import org.springframework.stereotype.Component;
+import org.springframework.web.context.annotation.RequestScope;
+
+@Component
+@RequestScope
+public class AuthorizationService implements IAuthorizationService {
+
+ public static final java.lang.String PARTITION_GROUP = "reserved_aws_admin";
+ public static final java.lang.String PARTITION_ADMIN_ROLE = "service.partition.admin";
+
+ @Autowired
+ private IEntitlementsAndCacheService entitlementsAndCacheService;
+
+ @Autowired
+ private DpsHeaders headers;
+
+ @Override
+ public boolean isDomainAdminServiceAccount() {
+ try {
+ return hasRole(PARTITION_ADMIN_ROLE);
+ }
+ catch (AppException appE) {
+ throw appE;
+ }
+ catch (Exception e) {
+ throw new AppException(HttpStatus.INTERNAL_SERVER_ERROR.value(), "Authentication Failure", e.getMessage(), e);
+ }
+
+ }
+
+ private boolean hasRole(String requiredRole) {
+ headers.put(DpsHeaders.DATA_PARTITION_ID, PARTITION_GROUP);
+ String user = entitlementsAndCacheService.authorize(headers, requiredRole);
+ headers.put(DpsHeaders.USER_EMAIL, user);
+ return true;
+ }
+
+}
+
diff --git a/provider/partition-aws/src/main/java/org/opengroup/osdu/partition/provider/aws/security/BasicAuthSecurityConfig.java b/provider/partition-aws/src/main/java/org/opengroup/osdu/partition/provider/aws/security/BasicAuthSecurityConfig.java
new file mode 100644
index 0000000000000000000000000000000000000000..7193321fcc65b1ca2790d45cf1684ca3c9b96383
--- /dev/null
+++ b/provider/partition-aws/src/main/java/org/opengroup/osdu/partition/provider/aws/security/BasicAuthSecurityConfig.java
@@ -0,0 +1,30 @@
+// 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.partition.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 BasicAuthSecurityConfig extends WebSecurityConfigurerAdapter {
+ protected void configure(HttpSecurity http) throws Exception {
+ ((HttpSecurity)http.httpBasic().disable())
+ .csrf().disable();
+ }
+}
diff --git a/provider/partition-aws/src/main/java/org/opengroup/osdu/partition/provider/aws/security/EntitlementsClientFactory.java b/provider/partition-aws/src/main/java/org/opengroup/osdu/partition/provider/aws/security/EntitlementsClientFactory.java
new file mode 100644
index 0000000000000000000000000000000000000000..8420ca50232535f5d19180870e36fea4a2da1baa
--- /dev/null
+++ b/provider/partition-aws/src/main/java/org/opengroup/osdu/partition/provider/aws/security/EntitlementsClientFactory.java
@@ -0,0 +1,48 @@
+// Copyright © 2020 Amazon Web Services
+// Copyright 2017-2019, Schlumberger
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.opengroup.osdu.partition.provider.aws.security;
+
+import org.opengroup.osdu.core.common.entitlements.EntitlementsAPIConfig;
+import org.opengroup.osdu.core.common.entitlements.EntitlementsFactory;
+import org.opengroup.osdu.core.common.entitlements.IEntitlementsFactory;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.beans.factory.config.AbstractFactoryBean;
+import org.springframework.stereotype.Component;
+
+@Component
+public class EntitlementsClientFactory extends AbstractFactoryBean {
+
+ @Value("${AUTHORIZE_API}")
+ private String AUTHORIZE_API;
+
+ @Value("${AUTHORIZE_API_KEY:}")
+ private String AUTHORIZE_API_KEY;
+
+ @Override
+ protected IEntitlementsFactory createInstance() throws Exception {
+
+ return new EntitlementsFactory(EntitlementsAPIConfig
+ .builder()
+ .rootUrl(AUTHORIZE_API)
+ .apiKey(AUTHORIZE_API_KEY)
+ .build());
+ }
+
+ @Override
+ public Class> getObjectType() {
+ return IEntitlementsFactory.class;
+ }
+}
\ No newline at end of file
diff --git a/provider/partition-aws/src/main/java/org/opengroup/osdu/partition/provider/aws/service/EntitlementsAndCacheServiceImpl.java b/provider/partition-aws/src/main/java/org/opengroup/osdu/partition/provider/aws/service/EntitlementsAndCacheServiceImpl.java
new file mode 100644
index 0000000000000000000000000000000000000000..4c62bbf80209e8c97e6cc0369337e4052cfd28d3
--- /dev/null
+++ b/provider/partition-aws/src/main/java/org/opengroup/osdu/partition/provider/aws/service/EntitlementsAndCacheServiceImpl.java
@@ -0,0 +1,165 @@
+// Copyright © 2020 Amazon Web Services
+// Copyright 2017-2019, Schlumberger
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.opengroup.osdu.partition.provider.aws.service;
+
+import org.apache.http.HttpStatus;
+import org.opengroup.osdu.core.common.model.entitlements.Acl;
+import org.opengroup.osdu.core.common.model.http.DpsHeaders;
+import org.opengroup.osdu.core.common.cache.ICache;
+import org.opengroup.osdu.core.common.model.storage.RecordMetadata;
+import org.opengroup.osdu.core.common.util.Crc32c;
+import org.opengroup.osdu.core.common.model.entitlements.EntitlementsException;
+import org.opengroup.osdu.core.common.model.entitlements.Groups;
+import org.opengroup.osdu.core.common.model.http.AppException;
+import org.opengroup.osdu.core.common.http.HttpResponse;
+import org.opengroup.osdu.core.common.entitlements.IEntitlementsFactory;
+import org.opengroup.osdu.core.common.entitlements.IEntitlementsService;
+import org.opengroup.osdu.core.common.logging.JaxRsDpsLog;
+import org.opengroup.osdu.core.common.entitlements.IEntitlementsAndCacheService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+@Service
+public class EntitlementsAndCacheServiceImpl implements IEntitlementsAndCacheService {
+
+ private static final String ERROR_REASON = "Access denied";
+ private static final String ERROR_MSG = "The user is not authorized to perform this action";
+
+ @Autowired
+ private IEntitlementsFactory factory;
+
+ @Autowired
+ private ICache cache;
+
+ @Autowired
+ private JaxRsDpsLog logger;
+
+ @Override
+ public String authorize(DpsHeaders headers, String... roles) {
+ Groups groups = this.getGroups(headers);
+ if (groups.any(roles)) {
+ return groups.getDesId();
+ } else {
+ throw new AppException(HttpStatus.SC_FORBIDDEN, ERROR_REASON, ERROR_MSG);
+ }
+ }
+
+ @Override
+ public boolean isValidAcl(DpsHeaders headers, Set acls) {
+ Groups groups = this.getGroups(headers);
+ if (groups.getGroups() == null || groups.getGroups().isEmpty()) {
+ this.logger.error("Error on getting groups for user: " + headers.getUserEmail());
+ throw new AppException(HttpStatus.SC_INTERNAL_SERVER_ERROR, "Unknown error",
+ "Unknown error happened when validating ACL");
+ }
+ String email = groups.getGroups().get(0).getEmail();
+ if (!email.matches("^[a-zA-Z0-9_+&*-]+(?:\\.[a-zA-Z0-9_+&*-]+)*@(?:[a-zA-Z0-9-]+\\.)+[a-zA-Z]{2,7}$")) {
+ this.logger.error("Email address is invalid for this group: " + groups.getGroups().get(0));
+ throw new AppException(HttpStatus.SC_INTERNAL_SERVER_ERROR, "Unknown error",
+ "Unknown error happened when validating ACL");
+ }
+ String domain = email.split("@")[1];
+ for (String acl : acls) {
+ if (!acl.split("@")[1].equalsIgnoreCase(domain)) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ @Override
+ public boolean hasOwnerAccess(DpsHeaders headers, String[] ownerList) {
+ Groups groups = this.getGroups(headers);
+ Set aclList = new HashSet<>();
+
+ for (String owner : ownerList) {
+ aclList.add(owner.split("@")[0]);
+ }
+
+ String[] acls = new String[aclList.size()];
+ return groups.any(aclList.toArray(acls));
+ }
+
+ @Override
+ public List hasValidAccess(List recordsMetadata, DpsHeaders headers) {
+ Groups groups = this.getGroups(headers);
+ List result = new ArrayList<>();
+
+ for (RecordMetadata recordMetadata : recordsMetadata) {
+ Acl storageAcl = recordMetadata.getAcl();
+ if (hasAccess(storageAcl, groups)) {
+ result.add(recordMetadata);
+ } else {
+ this.logger.warning("Post ACL check fails: " + recordMetadata.getId());
+ }
+ }
+
+ return result;
+ }
+
+ private boolean hasAccess(Acl storageAcl, Groups groups) {
+ String[] viewers = storageAcl.getViewers();
+ String[] owners = storageAcl.getOwners();
+ Set aclList = new HashSet<>();
+
+ for (String viewer : viewers) {
+ aclList.add(viewer.split("@")[0]);
+ }
+ for (String owner : owners) {
+ aclList.add(owner.split("@")[0]);
+ }
+
+ String[] acls = new String[aclList.size()];
+ if (groups.any(aclList.toArray(acls))) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ protected Groups getGroups(DpsHeaders headers) {
+ String cacheKey = this.getGroupCacheKey(headers);
+ Groups groups = this.cache.get(cacheKey);
+
+ if (groups == null) {
+ IEntitlementsService service = this.factory.create(headers);
+ try {
+ groups = service.getGroups();
+ this.cache.put(cacheKey, groups);
+ this.logger.info("Entitlements cache miss");
+
+ } catch (EntitlementsException e) {
+ e.printStackTrace();
+ HttpResponse response = e.getHttpResponse();
+ this.logger.error(String.format("Error requesting entitlements service %s", response));
+ throw new AppException(e.getHttpResponse().getResponseCode(), ERROR_REASON, ERROR_MSG, e);
+ }
+ }
+
+ return groups;
+ }
+
+ protected static String getGroupCacheKey(DpsHeaders headers) {
+ String key = String.format("entitlement-groups:%s:%s", headers.getPartitionIdWithFallbackToAccountId(),
+ headers.getAuthorization());
+ return Crc32c.hashToBase64EncodedString(key);
+ }
+}
diff --git a/provider/partition-aws/src/main/java/org/opengroup/osdu/partition/provider/aws/service/PartitionServiceDummyCacheImpl.java b/provider/partition-aws/src/main/java/org/opengroup/osdu/partition/provider/aws/service/PartitionServiceDummyCacheImpl.java
new file mode 100644
index 0000000000000000000000000000000000000000..a5f93dda66dfaa8cca18e22eef1a393a568f6150
--- /dev/null
+++ b/provider/partition-aws/src/main/java/org/opengroup/osdu/partition/provider/aws/service/PartitionServiceDummyCacheImpl.java
@@ -0,0 +1,49 @@
+// 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.partition.provider.aws.service;
+
+import org.opengroup.osdu.partition.model.PartitionInfo;
+import org.opengroup.osdu.partition.provider.interfaces.IPartitionServiceCache;
+import org.springframework.stereotype.Service;
+
+/***
+ * We don't want to use cache. Implement a dummy service to always return a cache miss.
+ */
+@Service
+public class PartitionServiceDummyCacheImpl implements IPartitionServiceCache {
+ public PartitionServiceDummyCacheImpl() {
+
+ }
+
+ @Override
+ public void clearAll() {
+ return;
+ }
+
+ @Override
+ public void delete(String arg0) {
+ return;
+ }
+
+ @Override
+ public PartitionInfo get(String arg0) {
+ return null;
+ }
+
+ @Override
+ public void put(String arg0, PartitionInfo arg1) {
+ return;
+ }
+}
diff --git a/provider/partition-aws/src/main/java/org/opengroup/osdu/partition/provider/aws/service/PartitionServiceImpl.java b/provider/partition-aws/src/main/java/org/opengroup/osdu/partition/provider/aws/service/PartitionServiceImpl.java
new file mode 100644
index 0000000000000000000000000000000000000000..831120c34cd8f70f17148cc2187cda4a11c511cb
--- /dev/null
+++ b/provider/partition-aws/src/main/java/org/opengroup/osdu/partition/provider/aws/service/PartitionServiceImpl.java
@@ -0,0 +1,132 @@
+// 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.partition.provider.aws.service;
+
+import java.util.List;
+import java.util.Map;
+
+import com.amazonaws.partitions.model.Partition;
+
+import org.apache.http.HttpStatus;
+import org.opengroup.osdu.core.common.logging.JaxRsDpsLog;
+import org.opengroup.osdu.core.common.model.http.AppException;
+import org.opengroup.osdu.partition.model.PartitionInfo;
+import org.opengroup.osdu.partition.provider.aws.util.SSMHelper;
+import org.opengroup.osdu.partition.provider.interfaces.IPartitionService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+@Service
+public class PartitionServiceImpl implements IPartitionService {
+
+ @Autowired
+ private JaxRsDpsLog logger;
+
+ @Autowired
+ private SSMHelper ssmHelper;
+
+ public PartitionServiceImpl() {
+
+ }
+
+ @Override
+ public PartitionInfo createPartition(String partitionId, PartitionInfo partitionInfo) {
+
+ if (ssmHelper.partitionExists(partitionId)) {
+ throw new AppException(HttpStatus.SC_CONFLICT, "partition exist", "Partition with same id exist");
+ }
+
+ try {
+ for (Map.Entry entry : partitionInfo.getProperties().entrySet()) {
+ ssmHelper.createOrUpdateSecret(partitionId, entry.getKey(), entry.getValue());
+ }
+
+ /**
+ * SSM parameters are not immediately available after pushing to System Manager.
+ * This API is expected to return a 200 response meaning that the parameters should be available immediately.
+ * This logic is added to validate when the parameters become available before returning the 200 response.
+ * The performance hit is acceptable because partitions are only created as an early operation and shouldn't affect
+ * the performance of runtime workflows
+ */
+ int retryCount = 10;
+ boolean partitionReady = false;
+ while (!partitionReady && retryCount > 0) {
+ retryCount--;
+ List partitionCheck = ssmHelper.getSsmParamsPathsForPartition(partitionId);
+ if (partitionCheck.size() == partitionInfo.getProperties().size())
+ partitionReady = true;
+ else
+ Thread.sleep(500);
+ }
+
+ String rollbackSuccess = "Failed";
+ if (!partitionReady) {
+ try {
+ ssmHelper.deletePartitionSecrets(partitionId);
+ rollbackSuccess = "Succeeded";
+ }
+ catch (Exception e){
+
+ }
+
+ throw new AppException(HttpStatus.SC_INTERNAL_SERVER_ERROR, "Partition Creation Failed", "One or more secrets couldn't be stored. Rollback " + rollbackSuccess);
+
+ }
+ }
+ catch (AppException appE) {
+ throw appE;
+ }
+ catch (Exception e) {
+
+ try {
+ Thread.sleep(2000); //wait for any existing ssm parameters that got added to normalize
+ ssmHelper.deletePartitionSecrets(partitionId);
+ }
+ catch (Exception deleteE) {
+ //if the partition didnt get created at all deletePartition will throw an exception. Eat it so we return the creation exception.
+ }
+
+ logger.error("Failed to create partition due to key creation failure in ssm", e.getMessage());
+ throw new AppException(HttpStatus.SC_INTERNAL_SERVER_ERROR, "Partition Creation Failure", e.getMessage(), e);
+ }
+
+ return partitionInfo;
+ }
+
+ @Override
+ public PartitionInfo getPartition(String partitionId) {
+
+ Map secrets = ssmHelper.getPartitionSecrets(partitionId);
+
+
+ //throw error if partition doesn't exist
+ if (secrets.size() <= 0) {
+ throw new AppException(HttpStatus.SC_NOT_FOUND, "partition not found", String.format("%s partition not found", partitionId));
+ }
+
+ return PartitionInfo.builder().properties(secrets).build();
+ }
+
+ @Override
+ public boolean deletePartition(String partitionId) {
+
+ if (!ssmHelper.partitionExists(partitionId)) {
+ throw new AppException(HttpStatus.SC_NOT_FOUND, "partition not found", String.format("%s partition not found", partitionId));
+ }
+
+ return ssmHelper.deletePartitionSecrets(partitionId);
+ }
+
+}
diff --git a/provider/partition-aws/src/main/java/org/opengroup/osdu/partition/provider/aws/util/SSMHelper.java b/provider/partition-aws/src/main/java/org/opengroup/osdu/partition/provider/aws/util/SSMHelper.java
new file mode 100644
index 0000000000000000000000000000000000000000..9c658529ecfd521c6b8e06d09276ad09d936785d
--- /dev/null
+++ b/provider/partition-aws/src/main/java/org/opengroup/osdu/partition/provider/aws/util/SSMHelper.java
@@ -0,0 +1,198 @@
+// 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.partition.provider.aws.util;
+
+import java.net.URI;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+import javax.inject.Inject;
+
+import com.amazonaws.auth.AWSCredentialsProvider;
+import com.amazonaws.services.simplesystemsmanagement.AWSSimpleSystemsManagement;
+import com.amazonaws.services.simplesystemsmanagement.AWSSimpleSystemsManagementClientBuilder;
+import com.amazonaws.services.simplesystemsmanagement.model.DeleteParametersRequest;
+import com.amazonaws.services.simplesystemsmanagement.model.DeleteParametersResult;
+import com.amazonaws.services.simplesystemsmanagement.model.GetParametersByPathRequest;
+import com.amazonaws.services.simplesystemsmanagement.model.GetParametersByPathResult;
+import com.amazonaws.services.simplesystemsmanagement.model.ParameterType;
+import com.amazonaws.services.simplesystemsmanagement.model.PutParameterRequest;
+import com.amazonaws.services.simplesystemsmanagement.model.PutParameterResult;
+import com.amazonaws.services.simplesystemsmanagement.model.Parameter;
+
+import org.opengroup.osdu.core.aws.iam.IAMConfig;
+import org.opengroup.osdu.partition.provider.aws.AwsServiceConfig;
+import org.springframework.stereotype.Component;
+
+@Component
+public final class SSMHelper {
+
+ @Inject
+ private AwsServiceConfig awsServiceConfig;
+
+ private AWSCredentialsProvider amazonAWSCredentials;
+ private AWSSimpleSystemsManagement ssmManager;
+
+ public SSMHelper() {
+ amazonAWSCredentials = IAMConfig.amazonAWSCredentials();
+ ssmManager = AWSSimpleSystemsManagementClientBuilder.standard()
+ .withCredentials(amazonAWSCredentials)
+ .build();
+ }
+
+ // public boolean secretExists(String secretName) {
+ // GetParameterRequest request = new GetParameterRequest().withName(secretName);
+ // GetParameterResult result = ssmManager.getParameter(request);
+
+ // return result.getParameter() != null;
+ // }
+
+ private String getSsmPathForPartitition(String partitionName) {
+ return URI.create(getTenantPrefix() + '/' + partitionName + '/').normalize().toString();
+ }
+
+ private String getSsmPathForPartititionSecret(String partitionName, String secretName) {
+ return URI.create(getSsmPathForPartitition(partitionName) + '/' + secretName).normalize().toString();
+ }
+
+ private List getSsmParamsForPartition(String partitionName) {
+
+ String ssmPath = getSsmPathForPartitition(partitionName);
+
+ List params = new ArrayList();
+ String nextToken = null;
+
+ do {
+
+ GetParametersByPathRequest request = new GetParametersByPathRequest()
+ .withPath(ssmPath)
+ .withRecursive(true)
+ .withNextToken(nextToken)
+ .withWithDecryption(true);
+
+ GetParametersByPathResult result = ssmManager.getParametersByPath(request);
+ nextToken = result.getNextToken();
+
+ if (result.getParameters().size() > 0)
+ params.addAll(result.getParameters());
+ }
+ while (nextToken != null);
+
+ return params;
+ }
+
+ public List getSsmParamsPathsForPartition(String partitionName) {
+
+ List paramsToDelete = getSsmParamsForPartition(partitionName);
+
+ List ssmParamNames = paramsToDelete.stream().map(Parameter::getName).collect(Collectors.toList());
+
+ return ssmParamNames;
+ }
+
+ public boolean partitionExists(String partitionName) {
+
+ String ssmPath = getSsmPathForPartitition(partitionName);
+ String nextToken = null;
+
+ do {
+
+ GetParametersByPathRequest request = new GetParametersByPathRequest()
+ .withPath(ssmPath)
+ .withRecursive(true)
+ .withNextToken(nextToken);
+
+ GetParametersByPathResult result = ssmManager.getParametersByPath(request);
+ nextToken = result.getNextToken();
+
+ if (result.getParameters().size() > 0)
+ return true;
+ }
+ while (nextToken != null);
+
+ return false;
+ }
+
+ public Map getPartitionSecrets(String partitionName) {
+
+ List partitionSsmParameters = getSsmParamsForPartition(partitionName);
+
+ String ssmPath = getSsmPathForPartitition(partitionName);
+
+ Map kvMap = new HashMap<>();
+
+ for (Parameter parameter : partitionSsmParameters) {
+
+ String shortName = parameter.getName().substring(ssmPath.length());
+
+ kvMap.put(shortName, parameter.getValue());
+ }
+
+ return kvMap;
+ }
+
+ public boolean createOrUpdateSecret(String partitionName, String secretName, Object secretValue) {
+
+ String ssmPath = getSsmPathForPartititionSecret(partitionName, secretName);
+
+ PutParameterRequest request = new PutParameterRequest()
+ .withName(ssmPath)
+ .withType(ParameterType.SecureString)
+ .withValue(String.valueOf(secretValue));
+
+
+ PutParameterResult result = ssmManager.putParameter(request);
+
+ //secret creation throws an exception if there's an error so we wont hit here
+ return true;
+
+ }
+
+ public boolean deletePartitionSecrets(String partitionName) {
+
+ List ssmParamPaths = getSsmParamsPathsForPartition(partitionName);
+
+ int expectedNumOfDeletedParams = ssmParamPaths.size();
+ int totalDeletedParams = 0;
+
+ while (ssmParamPaths.size() > 0) {
+ int subListCount = ssmParamPaths.size();
+ if (subListCount > 10)
+ subListCount = 10;
+
+ List paramsToDelete = ssmParamPaths.subList(0, subListCount);
+ ssmParamPaths = ssmParamPaths.subList(subListCount, ssmParamPaths.size());
+
+ DeleteParametersRequest request = new DeleteParametersRequest()
+ .withNames(paramsToDelete);
+
+ DeleteParametersResult result = ssmManager.deleteParameters(request);
+
+ totalDeletedParams += result.getDeletedParameters().size();
+ }
+
+
+
+ return totalDeletedParams == expectedNumOfDeletedParams;
+
+ }
+
+ private String getTenantPrefix() {
+ return awsServiceConfig.ssmPartitionPrefix;
+ }
+}
diff --git a/provider/partition-aws/src/main/resources/application.properties b/provider/partition-aws/src/main/resources/application.properties
new file mode 100644
index 0000000000000000000000000000000000000000..ec8271b2c4f460dabaec09a75ae014e7817c2c9a
--- /dev/null
+++ b/provider/partition-aws/src/main/resources/application.properties
@@ -0,0 +1,39 @@
+# 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=partition
+server.servlet.contextPath=/api/partition/v1
+logging.level.org.springframework.web=${LOG_LEVEL:INFO}
+server.port=${APPLICATION_PORT:8080}
+spring.data.redis.repositories.enabled=false
+springfox.documentation.swagger.v2.path=/api-docs
+ACCEPT_HTTP=true
+
+AUTHORIZE_API=${ENTITLEMENTS_BASE_URL}/api/entitlements/v1
+
+#logging configuration
+logging.transaction.enabled=true
+logging.slf4jlogger.enabled=true
+
+aws.resource.prefix=${ENVIRONMENT}
+
+## AWS DynamoDB configuration
+## These are not used right now by partition service, but core-lib tenantfactory crashes if they're not set
+aws.dynamodb.key=id
+aws.dynamodb.table.prefix=${ENVIRONMENT}-
+aws.dynamodb.region=${AWS_REGION}
+aws.dynamodb.endpoint=dynamodb.${AWS_REGION}.amazonaws.com
+
+## AWS ElastiCache configuration
+aws.elasticache.cluster.endpoint=${CACHE_CLUSTER_ENDPOINT}
+aws.elasticache.cluster.port=${CACHE_CLUSTER_PORT}
\ No newline at end of file
diff --git a/provider/partition-aws/src/test/java/org/opengroup/osdu/partition/provider/aws/service/PartitionServiceImplTest.java b/provider/partition-aws/src/test/java/org/opengroup/osdu/partition/provider/aws/service/PartitionServiceImplTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..9dfe8123402f47fbba9d524ca1a00bd5ee3b2fe3
--- /dev/null
+++ b/provider/partition-aws/src/test/java/org/opengroup/osdu/partition/provider/aws/service/PartitionServiceImplTest.java
@@ -0,0 +1,164 @@
+// Copyright © 2020 Amazon Web Services
+// Copyright 2017-2020, Schlumberger
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.opengroup.osdu.partition.provider.aws.service;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.Spy;
+import org.opengroup.osdu.core.common.logging.JaxRsDpsLog;
+import org.opengroup.osdu.core.common.model.http.AppException;
+import org.opengroup.osdu.partition.model.PartitionInfo;
+import org.opengroup.osdu.partition.provider.aws.util.SSMHelper;
+import org.powermock.core.classloader.annotations.PrepareForTest;
+import org.powermock.modules.junit4.PowerMockRunner;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.Executors;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+import static org.powermock.api.mockito.PowerMockito.mockStatic;
+
+@RunWith(PowerMockRunner.class)
+public class PartitionServiceImplTest {
+
+ @Mock
+ private SSMHelper ssmHelper;
+
+ @InjectMocks
+ private PartitionServiceImpl partService;
+
+ private PartitionInfo partitionInfo = new PartitionInfo();
+
+ private Map partitionSecretMap = new HashMap<>();
+
+ @Before
+ public void setup() {
+
+ partitionSecretMap.put("id", "my-tenant");
+ partitionSecretMap.put("storageAccount", "storage-account");
+ partitionSecretMap.put("complianceRuleSet", "compliance-rule-set");
+ partitionInfo.setProperties(partitionSecretMap);
+
+ }
+
+ @Test
+ public void should_ThrowConflictError_when_createPartition_whenPartitionExists() {
+ when(ssmHelper.partitionExists(any())).thenReturn(true);
+
+ try {
+ partService.createPartition(this.partitionInfo.getProperties().get("id").toString(), this.partitionInfo);
+ //we should never hit this code because create partition should end in an error
+ assertTrue("Expected partService.createPartition to throw an exception, but passed",false);
+ } catch (AppException e) {
+ assertTrue(e.getError().getCode() == 409);
+ assertTrue(e.getError().getReason().equalsIgnoreCase("partition exist"));
+ assertTrue(e.getError().getMessage().equalsIgnoreCase("Partition with same id exist"));
+ }
+ }
+
+ @Test
+ public void should_returnPartitionInfo_when_createPartition_whenPartitionDoesntExist() {
+
+ when(ssmHelper.partitionExists(any())).thenReturn(false);
+ when(ssmHelper.createOrUpdateSecret(any(), any(), any())).thenReturn(true);
+ when(ssmHelper.getSsmParamsPathsForPartition(any())).thenReturn(new ArrayList(this.partitionInfo.getProperties().keySet()));
+
+ PartitionInfo partInfo = partService.createPartition(this.partitionInfo.getProperties().get("id").toString(), this.partitionInfo);
+ assertTrue(partInfo.getProperties().size() == 3);
+ assertTrue(partInfo.getProperties().containsKey("id"));
+ assertTrue(partInfo.getProperties().containsKey("complianceRuleSet"));
+ assertTrue(partInfo.getProperties().containsKey("storageAccount"));
+ }
+
+ @Test
+ public void should_returnPartition_when_partitionExists() {
+
+ String Key1 = "my-tenant-id";
+ String Key2 = "my-tenant-groups";
+ String Key3 = "my-tenant-complianceRuleSet";
+
+ HashMap propertiesMap = new HashMap<>();
+ propertiesMap.put("id", this.partitionInfo.getProperties().get("id").toString());
+ propertiesMap.put(Key1, null);
+ propertiesMap.put(Key2, null);
+ propertiesMap.put(Key3, null);
+
+
+ when(ssmHelper.getPartitionSecrets(any())).thenReturn(propertiesMap);
+
+ PartitionInfo partitionInfo = this.partService.getPartition(this.partitionInfo.getProperties().get("id").toString());
+ assertTrue(partitionInfo.getProperties().containsKey(Key1));
+ assertTrue(partitionInfo.getProperties().containsKey(Key2));
+ assertTrue(partitionInfo.getProperties().containsKey(Key3));
+ assertTrue(partitionInfo.getProperties().containsKey("id"));
+ }
+
+ @Test
+ public void should_throwNotFoundException_when_partitionDoesntExist() {
+
+ try {
+ partService.getPartition(this.partitionInfo.getProperties().get("id").toString());
+ //we should never hit this code because get partition should end in an error
+ assertTrue("Expected partService.getPartition to throw an exception, but passed",false);
+ } catch (AppException e) {
+ assertTrue(e.getError().getCode() == 404);
+ assertTrue(e.getError().getReason().equalsIgnoreCase("partition not found"));
+ assertTrue(e.getError().getMessage().equalsIgnoreCase("my-tenant partition not found"));
+ }
+ }
+
+ @Test
+ public void should_returnTrue_when_successfullyDeletingSecretes() {
+
+ when(ssmHelper.partitionExists(any())).thenReturn(true);
+ when(ssmHelper.getSsmParamsPathsForPartition(any())).thenReturn(Arrays.asList("/my-tenant/partition/partitions/dummy-param"));
+ when(ssmHelper.deletePartitionSecrets(any())).thenReturn(true);
+
+ assertTrue(this.partService.deletePartition("test-partition"));
+ }
+
+ @Test
+ public void should_throwException_when_deletingNonExistentPartition() {
+
+
+ try {
+ this.partService.deletePartition("some-invalid-partition");
+ //we should never hit this code because delete partition should end in an error
+ assertTrue("Expected partService.deletePartition to throw an exception, but passed",false);
+ } catch (AppException ae) {
+ assertTrue(ae.getError().getCode() == 404);
+ assertEquals("some-invalid-partition partition not found", ae.getError().getMessage());
+ }
+ }
+
+ @Test(expected = AppException.class)
+ public void should_throwException_when_deletingInvalidPartition() {
+
+ this.partService.deletePartition(null);
+ }
+}
\ No newline at end of file
diff --git a/provider/partition-aws/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker b/provider/partition-aws/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker
new file mode 100644
index 0000000000000000000000000000000000000000..ca6ee9cea8ec189a088d50559325d4e84ff8ad09
--- /dev/null
+++ b/provider/partition-aws/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker
@@ -0,0 +1 @@
+mock-maker-inline
\ No newline at end of file
diff --git a/testing/partition-test-aws/build-aws/prepare-dist.sh b/testing/partition-test-aws/build-aws/prepare-dist.sh
new file mode 100755
index 0000000000000000000000000000000000000000..6f3f4ff187db471906b5fcbd4ca4db49a0369326
--- /dev/null
+++ b/testing/partition-test-aws/build-aws/prepare-dist.sh
@@ -0,0 +1,48 @@
+# 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.
+
+# This script prepares the dist directory for the integration tests.
+# Must be run from the root of the repostiory
+
+# This script prepares the dist directory for the integration tests.
+# Must be run from the root of the repostiory
+
+set -e
+
+OUTPUT_DIR="${OUTPUT_DIR:-dist}"
+
+INTEGRATION_TEST_OUTPUT_DIR=${INTEGRATION_TEST_OUTPUT_DIR:-$OUTPUT_DIR}/testing/integration
+INTEGRATION_TEST_OUTPUT_BIN_DIR=${INTEGRATION_TEST_OUTPUT_DIR:-$INTEGRATION_TEST_OUTPUT_DIR}/bin
+INTEGRATION_TEST_SOURCE_DIR=testing
+INTEGRATION_TEST_SOURCE_DIR_AWS="$INTEGRATION_TEST_SOURCE_DIR"/partition-test-aws
+INTEGRATION_TEST_SOURCE_DIR_CORE="$INTEGRATION_TEST_SOURCE_DIR"/partition-test-core
+echo "--Source directories variables--"
+echo $INTEGRATION_TEST_SOURCE_DIR_AWS
+echo $INTEGRATION_TEST_SOURCE_DIR_CORE
+echo "--Output directories variables--"
+echo $OUTPUT_DIR
+echo $INTEGRATION_TEST_OUTPUT_DIR
+echo $INTEGRATION_TEST_OUTPUT_BIN_DIR
+
+rm -rf "$INTEGRATION_TEST_OUTPUT_DIR"
+mkdir -p "$INTEGRATION_TEST_OUTPUT_DIR" && mkdir -p "$INTEGRATION_TEST_OUTPUT_BIN_DIR"
+echo "Building integration testing assemblies and gathering artifacts..."
+mvn install -f "$INTEGRATION_TEST_SOURCE_DIR_CORE"/pom.xml
+mvn install dependency:copy-dependencies -DskipTests -f "$INTEGRATION_TEST_SOURCE_DIR_AWS"/pom.xml -DincludeGroupIds=org.opengroup.osdu -Dmdep.copyPom
+cp "$INTEGRATION_TEST_SOURCE_DIR_AWS"/target/dependency/* "${INTEGRATION_TEST_OUTPUT_BIN_DIR}"
+(cd "${INTEGRATION_TEST_OUTPUT_BIN_DIR}" && ls *.jar | sed -e 's/\.jar$//' | xargs -I {} echo mvn install:install-file -Dfile={}.jar -DpomFile={}.pom >> install-deps.sh)
+chmod +x "${INTEGRATION_TEST_OUTPUT_BIN_DIR}"/install-deps.sh
+mvn clean -f "$INTEGRATION_TEST_SOURCE_DIR_AWS"/pom.xml
+cp -R "$INTEGRATION_TEST_SOURCE_DIR_AWS"/* "${INTEGRATION_TEST_OUTPUT_DIR}"/
+
diff --git a/testing/partition-test-aws/build-aws/run-tests.sh b/testing/partition-test-aws/build-aws/run-tests.sh
new file mode 100755
index 0000000000000000000000000000000000000000..be59c88f8cd817790867ae6a93f969c73ebea9f8
--- /dev/null
+++ b/testing/partition-test-aws/build-aws/run-tests.sh
@@ -0,0 +1,62 @@
+# 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.
+
+# This script prepares the dist directory for the integration tests.
+# Must be run from the root of the repostiory
+
+# This script executes the test and copies reports to the provided output directory
+# To call this script from the service working directory
+# ./dist/testing/integration/build-aws/run-tests.sh "./reports/"
+
+echo "### Running Partition Service Integration Tests... ###"
+
+
+SCRIPT_SOURCE_DIR=$(dirname "$0")
+echo "Script source location"
+echo "$SCRIPT_SOURCE_DIR"
+(cd "$SCRIPT_SOURCE_DIR"/../bin && ./install-deps.sh)
+
+#### ADD REQUIRED ENVIRONMENT VARIABLES HERE ###############################################
+# The following variables are automatically populated from the environment during integration testing
+# see os-deploy-aws/build-aws/integration-test-env-variables.py for an updated list
+
+# AWS_COGNITO_CLIENT_ID
+# PARTITION_URL
+export AWS_COGNITO_AUTH_FLOW=USER_PASSWORD_AUTH
+export AWS_COGNITO_AUTH_PARAMS_PASSWORD=$ADMIN_PASSWORD
+export AWS_COGNITO_AUTH_PARAMS_USER=$ADMIN_USER
+export AWS_COGNITO_AUTH_PARAMS_USER_NO_ACCESS=$USER_NO_ACCESS
+export AWS_COGNITO_CLIENT_ID=$AWS_COGNITO_CLIENT_ID
+export DOMAIN=testing.com
+export PARTITION_BASE_URL=$PARTITION_BASE_URL
+export CLIENT_TENANT=common
+export MY_TENANT=opendes
+export ENVIRONMENT=$RESOURCE_PREFIX
+
+#### RUN INTEGRATION TEST #########################################################################
+
+mvn test -f "$SCRIPT_SOURCE_DIR"/../pom.xml
+TEST_EXIT_CODE=$?
+
+#### COPY TEST REPORTS #########################################################################
+
+if [ -n "$1" ]
+ then
+ mkdir -p "$1"
+ cp -R "$SCRIPT_SOURCE_DIR"/../target/surefire-reports "$1"
+fi
+
+echo "### Partition Service Integration Tests Finished ###"
+
+exit $TEST_EXIT_CODE
\ No newline at end of file
diff --git a/testing/partition-test-aws/pom.xml b/testing/partition-test-aws/pom.xml
new file mode 100644
index 0000000000000000000000000000000000000000..ebded165caa62ec08f396723195b989aa3b33223
--- /dev/null
+++ b/testing/partition-test-aws/pom.xml
@@ -0,0 +1,108 @@
+
+
+
+ 4.0.0
+ org.opengroup.osdu.partition
+ partition-test-aws
+ 0.0.1-SNAPSHOT
+ jar
+
+
+ 1.8
+ 1.8
+ 1.8
+ UTF-8
+
+
+
+
+ org.projectlombok
+ lombok
+ 1.18.8
+ provided
+
+
+
+ com.sun.jersey
+ jersey-client
+ 1.19.4
+
+
+
+ junit
+ junit
+ 4.12
+
+
+
+ com.google.code.gson
+ gson
+ 2.8.5
+
+
+
+ org.opengroup.osdu.partition
+ partition-test-core
+ 0.0.1-SNAPSHOT
+
+
+
+ org.opengroup.osdu.core.aws
+ os-core-lib-aws
+ 0.3.7
+
+
+
+ com.google.guava
+ guava
+ 27.1-jre
+
+
+
+ io.jsonwebtoken
+ jjwt
+ 0.9.1
+
+
+ com.fasterxml.jackson.core
+ jackson-databind
+
+
+
+
+
+
+
+ ${gitlab-server}
+ https://community.opengroup.org/api/v4/groups/17/-/packages/maven
+
+
+
+
+
+ ${gitlab-server}
+ https://community.opengroup.org/api/v4/projects/221/packages/maven
+
+
+ ${gitlab-server}
+ https://community.opengroup.org/api/v4/projects/221/packages/maven
+
+
+
+
diff --git a/testing/partition-test-aws/src/test/java/org/opengroup/osdu/partition/api/TestCreatePartition.java b/testing/partition-test-aws/src/test/java/org/opengroup/osdu/partition/api/TestCreatePartition.java
new file mode 100644
index 0000000000000000000000000000000000000000..9288b19e57aab5ae9aee214891021fc55a0889f6
--- /dev/null
+++ b/testing/partition-test-aws/src/test/java/org/opengroup/osdu/partition/api/TestCreatePartition.java
@@ -0,0 +1,41 @@
+// 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.partition.api;
+
+import org.junit.After;
+import org.junit.Before;
+import org.opengroup.osdu.partition.util.AwsTestUtils;
+
+public class TestCreatePartition extends CreatePartitionTest {
+
+ @Before
+ @Override
+ public void setup() {
+ this.testUtils = new AwsTestUtils();
+ }
+
+ @After
+ @Override
+ public void tearDown() {
+ try {
+ this.deleteResource();
+ }
+ catch (Exception e) {
+
+ }
+ this.testUtils = null;
+ }
+
+}
diff --git a/testing/partition-test-aws/src/test/java/org/opengroup/osdu/partition/api/TestDeletePartition.java b/testing/partition-test-aws/src/test/java/org/opengroup/osdu/partition/api/TestDeletePartition.java
new file mode 100644
index 0000000000000000000000000000000000000000..6a8ff15debbc0b0ce9b65a482400fb6862d93d8d
--- /dev/null
+++ b/testing/partition-test-aws/src/test/java/org/opengroup/osdu/partition/api/TestDeletePartition.java
@@ -0,0 +1,41 @@
+// 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.partition.api;
+
+import org.junit.After;
+import org.junit.Before;
+import org.opengroup.osdu.partition.util.AwsTestUtils;
+
+public class TestDeletePartition extends DeletePartitionTest {
+
+ @Before
+ @Override
+ public void setup() {
+ this.testUtils = new AwsTestUtils();
+ }
+
+ @After
+ @Override
+ public void tearDown() {
+
+ try {
+ this.deleteResource();
+ }
+ catch (Exception e) {
+
+ }
+ this.testUtils = null;
+ }
+}
diff --git a/testing/partition-test-aws/src/test/java/org/opengroup/osdu/partition/api/TestGetPartitionById.java b/testing/partition-test-aws/src/test/java/org/opengroup/osdu/partition/api/TestGetPartitionById.java
new file mode 100644
index 0000000000000000000000000000000000000000..00f97e5c0c020e47d1b70d7c93b20127f1bdf9d4
--- /dev/null
+++ b/testing/partition-test-aws/src/test/java/org/opengroup/osdu/partition/api/TestGetPartitionById.java
@@ -0,0 +1,40 @@
+// 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.partition.api;
+
+import org.junit.After;
+import org.junit.Before;
+import org.opengroup.osdu.partition.util.AwsTestUtils;
+
+public class TestGetPartitionById extends GetPartitionByIdApitTest {
+
+ @Before
+ @Override
+ public void setup() {
+ this.testUtils = new AwsTestUtils();
+ }
+
+ @After
+ @Override
+ public void tearDown() {
+ // try {
+ // this.deleteResource();
+ // }
+ // catch (Exception e) {
+
+ // }
+ this.testUtils = null;
+ }
+}
diff --git a/testing/partition-test-aws/src/test/java/org/opengroup/osdu/partition/util/AwsTestUtils.java b/testing/partition-test-aws/src/test/java/org/opengroup/osdu/partition/util/AwsTestUtils.java
new file mode 100644
index 0000000000000000000000000000000000000000..7f5feabd320f7d0cf7c90d4050d004fec3d87318
--- /dev/null
+++ b/testing/partition-test-aws/src/test/java/org/opengroup/osdu/partition/util/AwsTestUtils.java
@@ -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.
+ */
+
+package org.opengroup.osdu.partition.util;
+
+import com.google.common.base.Strings;
+import org.opengroup.osdu.core.aws.cognito.AWSCognitoClient;
+
+import io.jsonwebtoken.Claims;
+import io.jsonwebtoken.Jws;
+import io.jsonwebtoken.Jwts;
+import io.jsonwebtoken.SignatureAlgorithm;
+
+import java.security.KeyPair;
+import java.security.KeyPairGenerator;
+import java.security.NoSuchAlgorithmException;
+import java.security.PrivateKey;
+import java.security.PublicKey;
+import java.util.Base64;
+import java.util.Date;
+
+public class AwsTestUtils extends TestUtils {
+
+ private AWSCognitoClient cognitoClient;
+
+ public AwsTestUtils() {
+ cognitoClient = new AWSCognitoClient();
+ }
+
+ @Override
+ public synchronized String getAccessToken() throws Exception {
+ if (Strings.isNullOrEmpty(token)) {
+ token = cognitoClient.getTokenForUserWithAccess();
+ }
+
+ return "Bearer " + token;
+ }
+
+ @Override
+ public synchronized String getNoAccessToken() throws Exception {
+ if (Strings.isNullOrEmpty(noAccessToken)) {
+
+ noAccessToken = createInvalidToken("baduser@example.com");
+ }
+ return "Bearer " + noAccessToken;
+ }
+
+ private static String createInvalidToken(String username) {
+
+ try {
+ KeyPairGenerator keyGenerator = KeyPairGenerator.getInstance("RSA");
+ keyGenerator.initialize(2048);
+
+ KeyPair kp = keyGenerator.genKeyPair();
+ PublicKey publicKey = (PublicKey) kp.getPublic();
+ PrivateKey privateKey = (PrivateKey) kp.getPrivate();
+
+
+ String token = Jwts.builder()
+ .setSubject(username)
+ .setExpiration(new Date())
+ .setIssuer("info@example.com")
+ // RS256 with privateKey
+ .signWith(SignatureAlgorithm.RS256, privateKey)
+ .compact();
+
+ return token;
+ }
+ catch (NoSuchAlgorithmException ex) {
+ return null;
+ }
+
+
+ }
+}
\ No newline at end of file
diff --git a/testing/pom.xml b/testing/pom.xml
index e768a3f793a0d1bd88d66eda8fc3f2cee5a62120..22ac051d00b642ccbc00258262e9649b2e5041ae 100644
--- a/testing/pom.xml
+++ b/testing/pom.xml
@@ -34,6 +34,7 @@
partition-test-core
partition-test-azure
+ partition-test-aws