Skip to content
Snippets Groups Projects
Commit ba3aad52 authored by Faid Luqman's avatar Faid Luqman
Browse files

Merge branch 'master' into faid/transitionSinglePipeline

parents 4871970c 4a32ae57
No related branches found
No related tags found
1 merge request!560Gradual transition to one CI pipeline for Notification
Showing
with 1826 additions and 0 deletions
......@@ -19,6 +19,8 @@ variables:
IBM_HELM_CONFIG_PATH: devops/ibm/ibm-notification-config
IBM_HELM_DEPLOY_PATH: devops/ibm/ibm-notification-deploy
ACCEPTANCE_TEST_DIR: "notification-acceptance-test"
include:
- project: "osdu/platform/ci-cd-pipelines"
file: "standard-setup.yml"
......
variables:
CORE_SERVICE: notification
GSA_TEST_ENABLED: "true"
core-test:
variables:
......
### Running E2E Tests
You will need to have the following environment variables defined.
| name | value | description | sensitive? | source |
|---------------------------------|------------------------------------------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------|------------|--------|
| `CLIENT_TENANT` | eg. `osdu` | Client tenant used for testing | no | - |
| `OSDU_TENANT` | eg. `osdu` | OSDU tenant used for testing | no | - |
| `GROUP_ID` | eg. `group` | Group ID used for testing. Group id, used in storage record ACL. Full group will be "data.default.viewers@{{data-partition-id}}.{{group_id}}" | no | - |
| `TOPIC_ID` | eg. `records-changed` | Topic ID | no | - |
| `HMAC_SECRET` | eg. `123456789` | String in hex , must match pattern ^[a-zA-Z0-9]{8,30}+$ & be in register variable SUBSCRIBER_SECRET | yes | - |
| `NOTIFICATION_BASE_URL` | eg. `https://osdu.core-dev.gcp.gnrg-osdu.projects.epam.com/api/notification/v1/` | Endpoint of notification service | no | - |
| `REGISTER_BASE_URL` | eg. `https://osdu.core-dev.gcp.gnrg-osdu.projects.epam.com/api/register/v1` | Endpoint of register service | no | - |
| `REGISTER_CUSTOM_PUSH_URL_HMAC` | eg. `https://osdu.core-dev.gcp.gnrg-osdu.projects.epam.com/api/register/v1/test/challenge/hmac-integration-test` | Endpoint of register custom push URL HMAC | no | - |
| `LEGAL_HOST` | eg. `https://osdu.core-dev.gcp.gnrg-osdu.projects.epam.com/api/legal/v1` | Endpoint of legal service | no | - |
| `STORAGE_HOST` | eg. `https://osdu.core-dev.gcp.gnrg-osdu.projects.epam.com/api/storage/v2` | Endpoint of storage service | no | - |
| `GSA_TEST_ENABLED` | eg. `true` or `false` | Enabler for GSA tests | no | - |
Authentication can be provided as OIDC config:
| name | value | description | sensitive? | source |
|------------------------------------------------|-----------------------------------------|-------------------------------------------------------|------------|--------|
| `TEST_DE_ADMIN_OPENID_PROVIDER_CLIENT_ID` | `********` | Service account client id which has admins api access | yes | - |
| `TEST_DE_ADMIN_OPENID_PROVIDER_CLIENT_SECRET` | `********` | Service account secret which has admins api access | yes | - |
| `TEST_DE_EDITOR_OPENID_PROVIDER_CLIENT_ID` | `********` | Service account client id which has editor api access | yes | - |
| `TEST_DE_EDITOR_OPENID_PROVIDER_CLIENT_SECRET` | `********` | Service account secret which has editor api access | yes | - |
| `TEST_DE_OPS_OPENID_PROVIDER_CLIENT_ID` | `********` | Service account client id which has full api access | yes | - |
| `TEST_DE_OPS_OPENID_PROVIDER_CLIENT_SECRET` | `********` | Service account secret which has full api access | yes | - |
| `TEST_NO_ACCESS_OPENID_PROVIDER_CLIENT_ID` | `********` | Service account client id which has not api access | yes | - |
| `TEST_NO_ACCESS_OPENID_PROVIDER_CLIENT_SECRET` | `********` | Service account secret which has not api access | yes | - |
| `TEST_OPENID_PROVIDER_URL` | `https://keycloak.com/auth/realms/osdu` | OpenID provider url | yes | - |
Or tokens can be used directly from env variables:
| name | value | description | sensitive? | source |
|------------------------|------------|----------------------|------------|--------|
| `DE_ADMIN_USER_TOKEN` | `********` | DE_ADMIN_USER Token | yes | - |
| `DE_EDITOR_USER_TOKEN` | `********` | DE_EDITOR_USER Token | yes | - |
| `DE_OPS_USER_TOKEN` | `********` | DE_OPS_USER Token | yes | - |
| `NO_ACCESS_USER_TOKEN` | `********` | NO_ACCESS_USER Token | yes | - |
**Entitlements configuration for integration accounts**
| DE_OPS_TESTER | DE_ADMIN_TESTER | DE_EDITOR_TESTER | DE_NO_ACCESS_TESTER |
|-----------------------------------------------------------------------------------------|---------------------------------------------------------------------------------------|---------------------------------------------------------------------|------------------------------------------|
| notification.pubsub<br/>service.entitlements.user<br/>users<br/>users.datalake.ops</br> | service.entitlements.user<br/>users<br/>users.datalake.admins</br>service.legal.admin | service.entitlements.user<br/>users<br/>users.datalake.editors</br> | service.entitlements.user<br/>users<br/> |
Above variables should be configured in the release pipeline to run integration tests. You should also replace them with proper values if you wish to run tests locally.
### Commands to run tests
Execute following command to build code and run all the integration tests:
```bash
# Note: this assumes that the environment variables for acceptance tests as outlined
# above are already exported in your environment.
# build + install integration test core
$ (cd notification-acceptance-test && mvn clean verify)
```
## License
Copyright © Google LLC
Copyright © EPAM Systems
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](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.
<?xml version="1.0" encoding="UTF-8"?>
<!--
~ 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.
-->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.opengroup.osdu.notification</groupId>
<artifactId>notification-acceptance-test</artifactId>
<version>0.28.0-SNAPSHOT</version>
<name>notification-acceptance-test</name>
<parent>
<groupId>org.opengroup.osdu</groupId>
<artifactId>os-notification</artifactId>
<version>0.28.0-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<properties>
<java.version>17</java.version>
<maven.compiler.target>${java.version}</maven.compiler.target>
<maven.compiler.source>${java.version}</maven.compiler.source>
<jackson-databind.version>2.15.2</jackson-databind.version>
<jackson.version>2.15.2</jackson.version>
</properties>
<dependencies>
<dependency>
<groupId>org.opengroup.osdu</groupId>
<artifactId>os-core-common</artifactId>
<version>0.25.0-rc2</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.26</version>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<version>5.10.4</version>
</dependency>
<dependency>
<groupId>org.junit.platform</groupId>
<artifactId>junit-platform-console</artifactId>
<version>1.10.4</version>
</dependency>
<dependency>
<groupId>com.nimbusds</groupId>
<artifactId>oauth2-oidc-sdk</artifactId>
<version>9.15</version>
</dependency>
<dependency>
<groupId>jakarta.xml.bind</groupId>
<artifactId>jakarta.xml.bind-api</artifactId>
<version>4.0.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.sun.xml.bind</groupId>
<artifactId>jaxb-core</artifactId>
<version>4.0.0</version>
</dependency>
<dependency>
<groupId>com.sun.xml.bind</groupId>
<artifactId>jaxb-impl</artifactId>
<version>4.0.0</version>
</dependency>
<dependency>
<groupId>org.opengroup.osdu</groupId>
<artifactId>os-core-common</artifactId>
<version>0.25.0-rc2</version>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</exclusion>
<exclusion>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>javax.json</groupId>
<artifactId>javax.json-api</artifactId>
<version>1.1.4</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>${jackson.version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>${jackson-databind.version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>${jackson.version}</version>
</dependency>
<dependency>
<groupId>org.glassfish</groupId>
<artifactId>javax.json</artifactId>
<version>1.1.4</version>
</dependency>
<dependency>
<groupId>com.google.oauth-client</groupId>
<artifactId>google-oauth-client</artifactId>
<version>1.34.1</version>
</dependency>
<dependency>
<groupId>com.google.api-client</groupId>
<artifactId>google-api-client</artifactId>
<version>2.2.0</version>
<exclusions>
<exclusion>
<groupId>com.google.guava</groupId>
<artifactId>guava-jdk5</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-client</artifactId>
<version>1.19.4</version>
</dependency>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.10.1</version>
</dependency>
<dependency>
<groupId>com.google.auth</groupId>
<artifactId>google-auth-library-oauth2-http</artifactId>
<version>0.19.0</version>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>0.9.1</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.13.0</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.22</version>
<scope>compile</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>3.0.0</version>
<configuration>
<systemPropertyVariables>
<DE_OPS_TESTER>${DE_OPS_TESTER}</DE_OPS_TESTER>
<DE_ADMIN_TESTER>${DE_ADMIN_TESTER}</DE_ADMIN_TESTER>
<DE_EDITOR_TESTER>${DE_EDITOR_TESTER}</DE_EDITOR_TESTER>
<DE_NO_ACCESS_TESTER>${DE_NO_ACCESS_TESTER}</DE_NO_ACCESS_TESTER>
</systemPropertyVariables>
</configuration>
</plugin>
</plugins>
</build>
</project>
/*
* Copyright 2017-2020, Schlumberger
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.opengroup.osdu.notification.api;
import org.opengroup.osdu.notification.util.Config;
import org.opengroup.osdu.notification.util.RestDescriptor;
import org.opengroup.osdu.notification.util.TestUtils;
import java.util.HashMap;
import java.util.Map;
public class PubsubEndpointGSADescriptor extends RestDescriptor {
@Override
public String getPath() {
return "push-handlers/records-changed";
}
@Override
public String getHttpMethod() {
return "POST";
}
@Override
public String getValidBody() {
return "{\n" +
"\t\"message\": {\n" +
"\t\"attributes\": {\n" +
"\t\"correlation-id\": \"39137f49-67d6-4001-a6aa-15521ef4f49e\",\n" +
"\t\"data-partition-id\": \"" + TestUtils.getOsduTenant() + "\"},\n" +
"\t\"data\": \"W3sia2luZCI6InRlc3RraW5kIiwiaWQiOiJ0ZXN0aWQiLCJvcGVyYXRpb250eXBlIjoiY3JlYXRlIn0seyJraW5kIjoidGVzdGtpbmQyIiwiaWQiOiJ0ZXN0aWQyIiwib3BlcmF0aW9udHlwZSI6InVwZGF0ZSJ9XQ\",\n" +
"\t\"messageId\": \"136969346945\"},\n" +
"\t\"subscription\":\"" + Config.Instance().NotificationId + "\"\n" +
"}";
}
@Override
public Map<String,String> getOsduTenantHeaders(){
Map<String, String> headers = new HashMap<>();
headers.put("data-partition-id", Config.Instance().OsduTenant);
return headers;
}
@Override
public Map<String,String> getCustomerTenantHeaders(){
Map<String, String> headers = new HashMap<>();
headers.put("data-partition-id", Config.Instance().ClientTenant);
return headers;
}
}
/*
* Copyright 2017-2020, Schlumberger
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.opengroup.osdu.notification.api;
import org.opengroup.osdu.notification.util.Config;
import org.opengroup.osdu.notification.util.RestDescriptor;
import org.opengroup.osdu.notification.util.TestUtils;
import java.util.HashMap;
import java.util.Map;
public class PubsubEndpointHMACDescriptor extends RestDescriptor {
@Override
public String getPath() {
return "push-handlers/records-changed";
}
@Override
public String getHttpMethod() {
return "POST";
}
@Override
public String getValidBody() {
return "{\n" +
"\t\"message\": {\n" +
"\t\"attributes\": {\n" +
"\t\"correlation-id\": \"39137f49-67d6-4001-a6aa-15521ef4f49e\",\n" +
"\t\"data-partition-id\": \"" + TestUtils.getOsduTenant() + "\"\n" +
"\t},\n" +
"\t\"data\": \"W3sia2luZCI6InRlc3RraW5kIiwiaWQiOiJ0ZXN0aWQiLCJvcGVyYXRpb250eXBlIjoiY3JlYXRlIn0seyJraW5kIjoidGVzdGtpbmQyIiwiaWQiOiJ0ZXN0aWQyIiwib3BlcmF0aW9udHlwZSI6InVwZGF0ZSJ9XQ\",\n" +
"\t\"messageId\": \"136969346945\"\n" +
"\t},\n" +
"\t\"subscription\": \""+ arg() +"\"\n" +
"}\n";
}
@Override
public Map<String,String> getOsduTenantHeaders(){
Map<String, String> headers = new HashMap<>();
headers.put("data-partition-id", Config.Instance().OsduTenant);
return headers;
}
@Override
public Map<String,String> getCustomerTenantHeaders(){
Map<String, String> headers = new HashMap<>();
headers.put("data-partition-id", Config.Instance().ClientTenant);
return headers;
}
}
/*
* Copyright 2020-2023 Google LLC
* Copyright 2020-2023 EPAM Systems, Inc
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.opengroup.osdu.notification.api;
import static org.junit.jupiter.api.Assumptions.assumeTrue;
import static org.opengroup.osdu.notification.util.Constants.GROUP_ID;
import com.google.common.base.Strings;
import com.sun.jersey.api.client.ClientResponse;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.function.Predicate;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertTrue;
import org.opengroup.osdu.core.common.model.http.DpsHeaders;
import org.opengroup.osdu.core.common.model.notification.GsaSecret;
import org.opengroup.osdu.core.common.model.notification.GsaSecretValue;
import org.opengroup.osdu.core.common.model.notification.Secret;
import org.opengroup.osdu.core.common.model.notification.Subscription;
import org.opengroup.osdu.core.common.notification.ISubscriptionService;
import org.opengroup.osdu.core.common.notification.SubscriptionAPIConfig;
import org.opengroup.osdu.core.common.notification.SubscriptionException;
import org.opengroup.osdu.core.common.notification.SubscriptionFactory;
import org.opengroup.osdu.notification.util.*;
public class TestPushEndpointGsa{
public static final String REGISTER_BASE_URL = "REGISTER_BASE_URL";
public static final String TOPIC_ID = "TOPIC_ID";
public static final String INTEGRATION_AUDIENCE = "INTEGRATION_AUDIENCE";
public static final String OSDU_TENANT = "OSDU_TENANT";
public static final String STORAGE_HOST = "STORAGE_HOST";
public static final String LEGAL_HOST = "LEGAL_HOST";
public static final String DE_OPS_TESTER = "DE_OPS_TESTER";
private final static Predicate<String> contentAcceptanceTester = s -> s.trim().startsWith("{");
private String subscriptionId = null;
private String notificationId = null;
private static ISubscriptionService subscriptionService;
private static SubscriptionFactory factory;
private TestUtils testUtils = new TokenTestUtils();
private final String suffix = String.valueOf(System.currentTimeMillis());
private String baseRegisterUrl;
private String topic;
private String tenant;
private String integrationAudience;
private String storageHost;
private String legalHost;
private String groupId;
private static final String LEGAL_TAG_NAME = "notification-test-gsa";
private ServicesUtils servicesUtils;
@BeforeAll
public static void classSetup() throws Exception {
// Check if GSA tests are enabled
assumeTrue(Config.Instance().GSATestIsEnabled);
}
@AfterEach
public void deleteResource() throws Exception {
if (Objects.isNull(subscriptionService)) {
Map<String, String> headers = new HashMap<>();
headers.put(DpsHeaders.DATA_PARTITION_ID, System.getProperty(OSDU_TENANT, System.getenv(OSDU_TENANT)));
headers.put(DpsHeaders.AUTHORIZATION, testUtils.getOpsToken());
DpsHeaders dpsHeaders = DpsHeaders.createFromMap(headers);
subscriptionService = factory.create(dpsHeaders);
}
subscriptionService.delete(subscriptionId);
servicesUtils.deleteStorageRecords(3, suffix);
servicesUtils.deleteLegalTag(LEGAL_TAG_NAME);
}
@BeforeEach
public void createResource() throws Exception {
baseRegisterUrl = System.getProperty(REGISTER_BASE_URL, System.getenv(REGISTER_BASE_URL));
topic = System.getProperty(TOPIC_ID, System.getenv(TOPIC_ID));
integrationAudience = System.getProperty(INTEGRATION_AUDIENCE, System.getenv(INTEGRATION_AUDIENCE));
tenant = System.getProperty(OSDU_TENANT, System.getenv(OSDU_TENANT));
if (Strings.isNullOrEmpty(integrationAudience)) {
integrationAudience = tenant;
}
storageHost = System.getProperty(STORAGE_HOST, System.getenv(STORAGE_HOST));
legalHost = System.getProperty(LEGAL_HOST, System.getenv(LEGAL_HOST));
groupId = System.getProperty(GROUP_ID, System.getenv(GROUP_ID));
servicesUtils = new ServicesUtils(storageHost, legalHost, testUtils, tenant, groupId);
servicesUtils.createLegalTag(LEGAL_TAG_NAME);
createResourceInPartition(tenant);
}
@Test
public void testPushEndpoint() throws Exception {
servicesUtils.createStorageRecords(suffix, 3, LEGAL_TAG_NAME);
Thread.sleep(10000);
assertNotNull(subscriptionId);
assertNotNull(notificationId);
Map<String, String> headers = new HashMap<>();
headers.put(DpsHeaders.DATA_PARTITION_ID, tenant);
ClientResponse clientResponse = testUtils.send(baseRegisterUrl, "/test-state/state", "GET", testUtils.getOpsToken(), null, "",
headers, false);
Map<String, Number> response = new HashMap<>();
response = testUtils.getResult(clientResponse, 200, response.getClass());
assertNotNull(response);
assertTrue(response.containsKey(suffix));
assertTrue(response.get(suffix).longValue() >= 3);
}
private void createResourceInPartition(String partitionId) throws Exception {
SubscriptionAPIConfig config = SubscriptionAPIConfig.builder().rootUrl(baseRegisterUrl).build();
factory = new SubscriptionFactory(config);
Map<String, String> headers = new HashMap<>();
headers.put(DpsHeaders.DATA_PARTITION_ID, partitionId);
headers.put(DpsHeaders.AUTHORIZATION, testUtils.getOpsToken());
DpsHeaders dpsHeaders = DpsHeaders.createFromMap(headers);
subscriptionService = factory.create(dpsHeaders);
Subscription subscription = new Subscription();
subscription.setName("subscription-integration-test-gsa-" + suffix);
subscription.setDescription("subscription created for gsa integration test " + suffix);
subscription.setTopic(topic);
subscription.setPushEndpoint(getPushUrl());
Secret gsaSecret = new GsaSecret();
GsaSecretValue gsaSecretValue = new GsaSecretValue();
gsaSecretValue.setAudience(integrationAudience);
String opsTester = new DecodedContentExtractor(System.getProperty(DE_OPS_TESTER, System.getenv(DE_OPS_TESTER)),
contentAcceptanceTester).getContent();
gsaSecretValue.setKey(opsTester);
gsaSecret.setSecretType("GSA");
((GsaSecret) gsaSecret).setValue(gsaSecretValue);
subscription.setSecret(gsaSecret);
try {
Subscription subscriptionCreated = subscriptionService.create(subscription);
notificationId = subscriptionCreated.getNotificationId();
subscriptionId = subscriptionCreated.getId();
} catch (SubscriptionException e) {
System.out.println("Subscription exception inner response : " + e.getHttpResponse());
throw e;
}
}
private String getPushUrl() {
return baseRegisterUrl + "/test-state/gsa-challenge/" + suffix;
}
}
/*
* Copyright 2020-2023 Google LLC
* Copyright 2020-2023 EPAM Systems, Inc
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.opengroup.osdu.notification.api;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.opengroup.osdu.notification.util.Constants.GROUP_ID;
import com.sun.jersey.api.client.ClientResponse;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.opengroup.osdu.core.common.model.http.DpsHeaders;
import org.opengroup.osdu.core.common.model.notification.HmacSecret;
import org.opengroup.osdu.core.common.model.notification.Subscription;
import org.opengroup.osdu.core.common.notification.ISubscriptionService;
import org.opengroup.osdu.core.common.notification.SubscriptionAPIConfig;
import org.opengroup.osdu.core.common.notification.SubscriptionException;
import org.opengroup.osdu.core.common.notification.SubscriptionFactory;
import org.opengroup.osdu.notification.util.*;
public class TestPushEndpointHMAC{
public static final String REGISTER_BASE_URL = "REGISTER_BASE_URL";
public static final String TOPIC_ID = "TOPIC_ID";
public static final String HMAC_SECRET = "HMAC_SECRET";
public static final String OSDU_TENANT = "OSDU_TENANT";
public static final String STORAGE_HOST = "STORAGE_HOST";
public static final String LEGAL_HOST = "LEGAL_HOST";
private String subscriptionId = null;
private String notificationId = null;
private ISubscriptionService subscriptionService;
private static SubscriptionFactory factory;
private TestUtils testUtils = new TokenTestUtils();
private final String suffix = String.valueOf(System.currentTimeMillis());
private String baseRegisterUrl;
private String topic;
private String hmacSecretValue;
private String tenant;
private String storageHost;
private String legalHost;
private String groupId;
private static final String LEGAL_TAG_NAME = "notification-test-hmac";
private ServicesUtils servicesUtils;
@AfterEach
public void deleteResource() throws Exception {
if (Objects.isNull(subscriptionService)) {
Map<String, String> headers = new HashMap<>();
headers.put(DpsHeaders.DATA_PARTITION_ID, System.getProperty(OSDU_TENANT, System.getenv(OSDU_TENANT)));
headers.put(DpsHeaders.AUTHORIZATION, testUtils.getOpsToken());
DpsHeaders dpsHeaders = DpsHeaders.createFromMap(headers);
subscriptionService = factory.create(dpsHeaders);
}
subscriptionService.delete(subscriptionId);
servicesUtils.deleteStorageRecords(3, suffix);
servicesUtils.deleteLegalTag(LEGAL_TAG_NAME);
}
@BeforeEach
public void createResource() throws Exception {
baseRegisterUrl = System.getProperty(REGISTER_BASE_URL, System.getenv(REGISTER_BASE_URL));
topic = System.getProperty(TOPIC_ID, System.getenv(TOPIC_ID));
hmacSecretValue = System.getProperty(HMAC_SECRET, System.getenv(HMAC_SECRET));
tenant = System.getProperty(OSDU_TENANT, System.getenv(OSDU_TENANT));
storageHost = System.getProperty(STORAGE_HOST, System.getenv(STORAGE_HOST));
legalHost = System.getProperty(LEGAL_HOST, System.getenv(LEGAL_HOST));
groupId = System.getProperty(GROUP_ID, System.getenv(GROUP_ID));
servicesUtils = new ServicesUtils(storageHost, legalHost, testUtils, tenant, groupId);
servicesUtils.createLegalTag(LEGAL_TAG_NAME);
createResourceInPartition(tenant);
}
@Test
public void testPushEndpoint() throws Exception {
servicesUtils.createStorageRecords(suffix, 3, LEGAL_TAG_NAME);
Thread.sleep(10000);
assertNotNull(subscriptionId);
assertNotNull(notificationId);
Map<String, String> headers = new HashMap<>();
headers.put(DpsHeaders.DATA_PARTITION_ID, tenant);
ClientResponse clientResponse = testUtils.send(baseRegisterUrl, "/test-state/state", "GET", testUtils.getOpsToken(), null, "",
headers, false);
Map<String, Number> response = new HashMap<>();
response = testUtils.getResult(clientResponse, 200, response.getClass());
assertNotNull(response);
assertTrue(response.containsKey(suffix));
assertTrue(response.get(suffix).longValue() >= 3);
}
private void createResourceInPartition(String partitionId) throws Exception {
SubscriptionAPIConfig config = SubscriptionAPIConfig.builder().rootUrl(baseRegisterUrl).build();
factory = new SubscriptionFactory(config);
Map<String, String> headers = new HashMap<>();
headers.put(DpsHeaders.DATA_PARTITION_ID, partitionId);
headers.put(DpsHeaders.AUTHORIZATION, testUtils.getOpsToken());
DpsHeaders dpsHeaders = DpsHeaders.createFromMap(headers);
subscriptionService = factory.create(dpsHeaders);
Subscription subscription = new Subscription();
subscription.setName("subscription-integration-test-hmac-" + suffix);
subscription.setDescription("subscription created for hmac integration test " + suffix);
subscription.setTopic(topic);
subscription.setPushEndpoint(getPushUrl());
HmacSecret secret = new HmacSecret();
secret.setValue(hmacSecretValue);
subscription.setSecret(secret);
try {
Subscription subscriptionCreated = subscriptionService.create(subscription);
notificationId = subscriptionCreated.getNotificationId();
subscriptionId = subscriptionCreated.getId();
} catch (SubscriptionException e) {
System.out.println("Subscription exception inner response : " + e.getHttpResponse());
throw e;
}
}
private String getPushUrl() {
return baseRegisterUrl + "/test-state/challenge/" + suffix;
}
}
/*
Copyright 2002-2022 Google LLC
Copyright 2002-2022 EPAM Systems, Inc
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package org.opengroup.osdu.notification.config;
import com.nimbusds.oauth2.sdk.http.HTTPRequest;
import com.nimbusds.oauth2.sdk.http.HTTPResponse;
import com.nimbusds.oauth2.sdk.id.Issuer;
import com.nimbusds.openid.connect.sdk.op.OIDCProviderConfigurationRequest;
import com.nimbusds.openid.connect.sdk.op.OIDCProviderMetadata;
import lombok.extern.slf4j.Slf4j;
@Slf4j
public class OpenIDProviderConfig {
private String opsClientId;
private String opsClientSecret;
private String adminClientId;
private String adminClientSecret;
private String editorClientId;
private String editorClientSecret;
private String noAccessClientId;
private String noAccessClientSecret;
private String url;
private final String[] scopes = {"openid"};
private static final OpenIDProviderConfig openIDProviderConfig = new OpenIDProviderConfig();
private static OIDCProviderMetadata providerMetadata;
public static OpenIDProviderConfig Instance() {
try {
openIDProviderConfig.opsClientId = System.getProperty("TEST_DE_OPS_OPENID_PROVIDER_CLIENT_ID",
System.getenv("TEST_DE_OPS_OPENID_PROVIDER_CLIENT_ID"));
openIDProviderConfig.opsClientSecret = System.getProperty(
"TEST_DE_OPS_OPENID_PROVIDER_CLIENT_SECRET",
System.getenv("TEST_DE_OPS_OPENID_PROVIDER_CLIENT_SECRET"));
openIDProviderConfig.adminClientId = System.getProperty(
"TEST_DE_ADMIN_OPENID_PROVIDER_CLIENT_ID",
System.getenv("TEST_DE_ADMIN_OPENID_PROVIDER_CLIENT_ID"));
openIDProviderConfig.adminClientSecret = System.getProperty(
"TEST_DE_ADMIN_OPENID_PROVIDER_CLIENT_SECRET",
System.getenv("TEST_DE_ADMIN_OPENID_PROVIDER_CLIENT_SECRET"));
openIDProviderConfig.editorClientId = System.getProperty(
"TEST_DE_EDITOR_OPENID_PROVIDER_CLIENT_ID",
System.getenv("TEST_DE_EDITOR_OPENID_PROVIDER_CLIENT_ID"));
openIDProviderConfig.editorClientSecret = System.getProperty(
"TEST_DE_EDITOR_OPENID_PROVIDER_CLIENT_SECRET",
System.getenv("TEST_DE_EDITOR_OPENID_PROVIDER_CLIENT_SECRET"));
openIDProviderConfig.noAccessClientId = System.getProperty(
"TEST_NO_ACCESS_OPENID_PROVIDER_CLIENT_ID",
System.getenv("TEST_NO_ACCESS_OPENID_PROVIDER_CLIENT_ID"));
openIDProviderConfig.noAccessClientSecret = System.getProperty(
"TEST_NO_ACCESS_OPENID_PROVIDER_CLIENT_SECRET",
System.getenv("TEST_NO_ACCESS_OPENID_PROVIDER_CLIENT_SECRET"));
openIDProviderConfig.url =
System.getProperty("TEST_OPENID_PROVIDER_URL", System.getenv("TEST_OPENID_PROVIDER_URL"));
Issuer issuer = new Issuer(openIDProviderConfig.url);
OIDCProviderConfigurationRequest request = new OIDCProviderConfigurationRequest(issuer);
HTTPRequest httpRequest = request.toHTTPRequest();
HTTPResponse httpResponse = httpRequest.send();
providerMetadata = OIDCProviderMetadata.parse(httpResponse.getContentAsJSONObject());
} catch (Exception e) {
throw new RuntimeException("Malformed token provider configuration", e);
}
return openIDProviderConfig;
}
public String getOpsClientId() {
return opsClientId;
}
public String getOpsClientSecret() {
return opsClientSecret;
}
public String getAdminClientId() {
return adminClientId;
}
public String getAdminClientSecret() {
return adminClientSecret;
}
public String getEditorClientId() {
return editorClientId;
}
public String getEditorClientSecret() {
return editorClientSecret;
}
public String getNoAccessClientId() {
return noAccessClientId;
}
public String getNoAccessClientSecret() {
return noAccessClientSecret;
}
public String getUrl() {
return url;
}
public String[] getScopes() {
return scopes;
}
public OIDCProviderMetadata getProviderMetadata() {
return providerMetadata;
}
}
/*
* Copyright 2017-2020, Schlumberger
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.opengroup.osdu.notification.util;
public class Config {
public String HostUrl;
public String OsduTenant;
public String ClientTenant;
public String IntegrationAudience;
public String GSAPushUrl;
public String HMACPushUrl;
public String RegisterServicePath;
public String StorageServicePath;
public String LegalServicePath;
public String Topic;
public String hmacSecretValue;
public String NotificationId;
public String DE_OPS_TESTER = System.getProperty("DE_OPS_TESTER", System.getenv("DE_OPS_TESTER"));
public String RetryCount;
public String TimeOutSeconds;
public Boolean GSATestIsEnabled;
private static Config config = new Config();
public static Config Instance() {
String env = getEnvironment();
config.ClientTenant = getEnvironmentVariableOrDefaultValue("CLIENT_TENANT", "nonexistenttenant");
config.IntegrationAudience = "osdu";
config.OsduTenant = getEnvironmentVariableOrDefaultValue("OSDU_TENANT", "opendes");
config.Topic = getEnvironmentVariableOrDefaultValue("TOPIC_ID", "records-changed");
config.TimeOutSeconds = getEnvironmentVariableOrDefaultValue("TIME_OUT_SECONDS", "60");
config.RetryCount = getEnvironmentVariableOrDefaultValue("RETRY_COUNT", "3");
config.hmacSecretValue = System.getProperty("HMAC_SECRET", System.getenv("HMAC_SECRET"));
config.GSATestIsEnabled = Boolean.parseBoolean(getEnvironmentVariableOrDefaultValue("GSA_TEST_ENABLED", "false").trim().toLowerCase());
String registerUrl = System.getProperty("REGISTER_BASE_URL", System.getenv("REGISTER_BASE_URL"));
config.HostUrl = System.getProperty("NOTIFICATION_BASE_URL", System.getenv("NOTIFICATION_BASE_URL"));
config.GSAPushUrl = registerUrl + "/test/gsa-challenge/";
//Adding this so CPs can point to custom HMAC push endpoints
config.HMACPushUrl = getEnvironmentVariableOrDefaultValue("REGISTER_CUSTOM_PUSH_URL_HMAC", registerUrl + "/test/challenge/");
//Adding a new variable NOTIFICATION_REGISTER_BASE_URL since REGISTER_BASE_URL is used by Register integration tests which needs a trailing \
String regUrl = getEnvironmentVariable("NOTIFICATION_REGISTER_BASE_URL");
config.StorageServicePath = getEnvironmentVariable("STORAGE_HOST");
config.LegalServicePath = System.getProperty("LEGAL_URL", System.getenv("LEGAL_URL"));
if (regUrl == null) {
config.RegisterServicePath = registerUrl;
} else {
config.RegisterServicePath = regUrl + "/api/register/v1";
}
System.out.println("HostUrl=" + config.HostUrl);
System.out.println("config.Topic=" + config.Topic);
System.out.println("config.HMACPushUrl=" + config.HMACPushUrl);
System.out.println("config.RegisterServicePath=" + config.RegisterServicePath);
System.out.println("config.StorageServicePath=" + config.StorageServicePath);
return config;
}
public boolean isLocalHost() {
return HostUrl.contains("//localhost");
}
public static boolean isGke() {
return "DEV_GKE".equalsIgnoreCase(getEnvironment());
}
private static String getEnvironment() {
return System.getProperty("ENVIRONMENT", System.getenv("ENVIRONMENT"));
}
private static String getEnvironmentVariableOrDefaultValue(String key, String defaultValue) {
String environmentVariable = getEnvironmentVariable(key);
if (environmentVariable == null) {
environmentVariable = defaultValue;
}
return environmentVariable;
}
private static String getEnvironmentVariable(String propertyKey) {
return System.getProperty(propertyKey, System.getenv(propertyKey));
}
}
package org.opengroup.osdu.notification.util;
public class Constants {
public static final String GROUP_ID = "GROUP_ID";
}
/*
* Copyright 2020-2024 Google LLC
* Copyright 2020-2024 EPAM Systems, Inc
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.opengroup.osdu.notification.util;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.InvalidPathException;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Base64;
import java.util.function.Predicate;
import lombok.RequiredArgsConstructor;
import lombok.extern.java.Log;
@Log
@RequiredArgsConstructor
public class DecodedContentExtractor {
private final String inputFilenameOrContent;
private final Predicate<String> contentAcceptanceTester;
private boolean validOutputContentFound;
private String outputContent;
public String getContent() {
validOutputContentFound = false;
outputContent = null;
log.info("Treat value as a content");
if (inputFilenameOrContent.trim().isEmpty()) {
log.info("provided value is empty. Output as is.");
return setValidOutputContent(inputFilenameOrContent);
}
if (!treatValueAsAContent(inputFilenameOrContent)) {
log.info("Value is not a valid content. Treat value as a filename");
if (!treatValueAsAFileName(inputFilenameOrContent)){
log.info("Value is not a filename with a valid content");
}
}
return getValidOutputContentIfFound();
}
private boolean treatValueAsAContent(String input) {
if (contentAcceptanceTester.test(input)) {
log.info("the value is a valid content. Output as is.");
setValidOutputContent(input);
return true;
}
String output;
try {
output = new String(Base64.getDecoder().decode(input));
log.info("the value is probably Base64 encoded. Just decoded");
if (contentAcceptanceTester.test(output)) {
log.info("the decoded value is a valid content. Output decoded value.");
setValidOutputContent(output);
} else {
log.info("the decoded value is not a valid content.");
}
} catch (IllegalArgumentException e) {
log.info("the value is not Base64 encoded. ");
}
return validOutputContentFound;
}
private boolean treatValueAsAFileName(String filename) {
if (treatFileContent(filename)) return true;
try {
filename = new String(Base64.getDecoder().decode(filename));
log.info("the filename is probably Base64 encoded. Just decoded");
if (treatFileContent(filename)) return true;
} catch (IllegalArgumentException e) {
log.info("the filename is not Base64 encoded. ");
}
return validOutputContentFound;
}
private boolean treatFileContent(String filename) {
try {
Path path = Paths.get(filename);
if (Files.exists(path)) {
log.info("the filename is of existing file. Read file.");
try {
String fileContent = new String(Files.readAllBytes(path));
if (treatValueAsAContent(fileContent)) {
return true;
}
} catch (IOException | SecurityException | OutOfMemoryError ex) {
log.info(() -> ("unable to read the file: " + ex.getClass().getSimpleName()));
}
}
} catch (InvalidPathException ex) {
log.info("the filename is not valid or the file doesn't exist.");
}
return false;
}
private String setValidOutputContent(String outputContent) {
this.outputContent = outputContent;
this.validOutputContentFound = true;
return getValidOutputContentIfFound();
}
public String getValidOutputContentIfFound() {
return validOutputContentFound ? outputContent : null;
}
}
/*
* Copyright 2020-2023 Google LLC
* Copyright 2020-2023 EPAM Systems, Inc
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.opengroup.osdu.notification.util;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
public class FileUtils {
public String readFromLocalFilePath(String filePath) throws IOException {
InputStream inStream = this.getClass().getResourceAsStream(filePath);
BufferedReader br = new BufferedReader(new InputStreamReader(inStream));
StringBuilder stringBuilder = new StringBuilder();
String eachLine = "";
while ((eachLine = br.readLine()) != null) {
stringBuilder.append(eachLine);
}
return stringBuilder.toString();
}
}
/*
* Copyright 2020-2023 Google LLC
* Copyright 2020-2023 EPAM Systems, Inc
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.opengroup.osdu.notification.util;
import static org.junit.jupiter.api.Assertions.assertEquals;
import com.google.gson.Gson;
import com.sun.jersey.api.client.Client;
import com.sun.jersey.api.client.ClientResponse;
import com.sun.jersey.api.client.WebResource;
import java.net.URI;
import java.security.SecureRandom;
import java.security.cert.X509Certificate;
import java.util.Map;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import javax.ws.rs.core.MediaType;
import org.apache.commons.lang3.StringUtils;
public class HttpClient {
private HttpClient(){
}
public static ClientResponse send(String url, String path, String httpMethod,
Map<String, String> headers,
String requestBody, String query) throws Exception {
String normalizedUrl = new URI(String.format("%s/%s", url, path)).normalize().toString();
normalizedUrl = StringUtils.removeEnd(normalizedUrl, "/");
log(httpMethod, normalizedUrl + query, headers, requestBody);
Client client = getClient();
WebResource webResource = client.resource(normalizedUrl + query);
WebResource.Builder builder = webResource.accept(MediaType.APPLICATION_JSON)
.type(MediaType.APPLICATION_JSON);
headers.forEach(builder::header);
if ("POST".equals(httpMethod) && StringUtils.isEmpty(requestBody)) {
requestBody = "{}"; //solves 411 error when sending empty-body POST request
}
return builder.method(httpMethod, ClientResponse.class, requestBody);
}
private static void log(String method, String url, Map<String, String> headers, String body) {
System.out.println(String.format("%s: %s", method, url));
System.out.println(body);
}
@SuppressWarnings("unchecked")
public static <T> T getResult(ClientResponse response, int exepectedStatus, Class<T> classOfT) {
assertEquals(exepectedStatus, response.getStatus());
if (exepectedStatus == 204) {
return null;
}
assertEquals("application/json; charset=UTF-8", response.getType().toString());
String json = response.getEntity(String.class);
if (classOfT == String.class) {
return (T) json;
}
Gson gson = new Gson();
return gson.fromJson(json, classOfT);
}
protected static Client getClient() {
TrustManager[] trustAllCerts = new TrustManager[]{new X509TrustManager() {
@Override
public X509Certificate[] getAcceptedIssuers() {
return null;
}
@Override
public void checkClientTrusted(X509Certificate[] certs, String authType) {
}
@Override
public void checkServerTrusted(X509Certificate[] certs, String authType) {
}
}};
try {
SSLContext sc = SSLContext.getInstance("TLS");
sc.init(null, trustAllCerts, new SecureRandom());
HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
} catch (Exception e) {
}
return Client.create();
}
}
/*
Copyright 2002-2022 Google LLC
Copyright 2002-2022 EPAM Systems, Inc
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package org.opengroup.osdu.notification.util;
import com.nimbusds.oauth2.sdk.AuthorizationGrant;
import com.nimbusds.oauth2.sdk.ClientCredentialsGrant;
import com.nimbusds.oauth2.sdk.ParseException;
import com.nimbusds.oauth2.sdk.Scope;
import com.nimbusds.oauth2.sdk.TokenRequest;
import com.nimbusds.oauth2.sdk.TokenResponse;
import com.nimbusds.oauth2.sdk.auth.ClientAuthentication;
import com.nimbusds.oauth2.sdk.auth.ClientSecretBasic;
import com.nimbusds.oauth2.sdk.auth.Secret;
import com.nimbusds.oauth2.sdk.id.ClientID;
import com.nimbusds.openid.connect.sdk.OIDCTokenResponseParser;
import java.io.IOException;
import java.net.URI;
import java.util.Objects;
import net.minidev.json.JSONObject;
import org.opengroup.osdu.notification.config.OpenIDProviderConfig;
public class OpenIDTokenProvider {
private static final OpenIDProviderConfig openIDProviderConfig = OpenIDProviderConfig.Instance();
private static final String ID_TOKEN = "id_token";
private final AuthorizationGrant clientGrant = new ClientCredentialsGrant();
private final URI tokenEndpointURI;
private final Scope scope;
private final ClientAuthentication opsClientAuthentication;
private final ClientAuthentication adminClientAuthentication;
private final ClientAuthentication editorClientAuthentication;
private final ClientAuthentication noAccessClientAuthentication;
public OpenIDTokenProvider() {
this.tokenEndpointURI = openIDProviderConfig.getProviderMetadata().getTokenEndpointURI();
this.scope = new Scope(openIDProviderConfig.getScopes());
this.opsClientAuthentication =
new ClientSecretBasic(
new ClientID(openIDProviderConfig.getOpsClientId()),
new Secret(openIDProviderConfig.getOpsClientSecret())
);
this.adminClientAuthentication =
new ClientSecretBasic(
new ClientID(openIDProviderConfig.getAdminClientId()),
new Secret(openIDProviderConfig.getAdminClientSecret())
);
this.editorClientAuthentication =
new ClientSecretBasic(
new ClientID(openIDProviderConfig.getEditorClientId()),
new Secret(openIDProviderConfig.getEditorClientSecret())
);
this.noAccessClientAuthentication =
new ClientSecretBasic(
new ClientID(openIDProviderConfig.getNoAccessClientId()),
new Secret(openIDProviderConfig.getNoAccessClientSecret())
);
}
public String getOpsAccessToken() {
try {
TokenRequest request =
new TokenRequest(this.tokenEndpointURI, this.opsClientAuthentication, this.clientGrant,
this.scope);
return requestToken(request);
} catch (ParseException | IOException e) {
throw new RuntimeException(
"Unable get credentials from TEST_DE_OPS_OPENID_PROVIDER_CLIENT_ID variables", e);
}
}
public String getAdminAccessToken() {
try {
TokenRequest request =
new TokenRequest(this.tokenEndpointURI, this.adminClientAuthentication, this.clientGrant,
this.scope);
return requestToken(request);
} catch (ParseException | IOException e) {
throw new RuntimeException(
"Unable get credentials from TEST_DE_ADMIN_OPENID_PROVIDER_CLIENT_ID variables", e);
}
}
public String getEditorAccessToken() {
try {
TokenRequest request =
new TokenRequest(this.tokenEndpointURI, this.editorClientAuthentication, this.clientGrant,
this.scope);
return requestToken(request);
} catch (ParseException | IOException e) {
throw new RuntimeException(
"Unable get credentials from TEST_DE_EDITOR_OPENID_PROVIDER_CLIENT_ID variables", e);
}
}
public String getNoAccessToken() {
try {
TokenRequest request =
new TokenRequest(this.tokenEndpointURI, this.noAccessClientAuthentication,
this.clientGrant, this.scope);
return requestToken(request);
} catch (ParseException | IOException e) {
throw new RuntimeException(
"Unable get credentials from TEST_NO_ACCESS_OPENID_PROVIDER_CLIENT_ID variables", e);
}
}
private String requestToken(TokenRequest tokenRequest) throws ParseException, IOException {
TokenResponse parse = OIDCTokenResponseParser.parse(tokenRequest.toHTTPRequest().send());
if (!parse.indicatesSuccess()) {
throw new RuntimeException("Unable get credentials variables");
}
JSONObject jsonObject = parse.toSuccessResponse().toJSONObject();
String idTokenValue = jsonObject.getAsString(ID_TOKEN);
if (Objects.isNull(idTokenValue) || idTokenValue.isEmpty()) {
throw new RuntimeException("Unable get credentials variables");
}
return idTokenValue;
}
}
/*
* Copyright 2017-2020, Schlumberger
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.opengroup.osdu.notification.util;
import com.sun.jersey.api.client.ClientResponse;
import java.util.Map;
public abstract class RestDescriptor {
public RestDescriptor() {
}
private String arg = "";
public String arg() {
return arg;
}
public abstract String getPath();
public abstract String getHttpMethod();
public abstract String getValidBody();
public abstract Map<String, String> getOsduTenantHeaders();
public abstract Map<String, String> getCustomerTenantHeaders();
public String getQuery() {
return "";
}
public ClientResponse runHttp(String arg, String token) throws Exception {
this.arg = arg;
return TestUtils.send(getPath(), getHttpMethod(), token, getValidBody(), getQuery(), getOsduTenantHeaders(), true);
}
public ClientResponse run(String arg, String token) throws Exception {
this.arg = arg;
return TestUtils.send(getPath(), getHttpMethod(), token, getValidBody(), getQuery(), getOsduTenantHeaders(), false);
}
public ClientResponse runOnCustomerTenant(String arg, String token) throws Exception {
this.arg = arg;
return TestUtils.send(getPath(), getHttpMethod(), token, getValidBody(), getQuery(), getCustomerTenantHeaders(), false);
}
public ClientResponse runOptions(String arg, String token) throws Exception {
this.arg = arg;
return TestUtils.send(getPath(), "OPTIONS", token, "", "", getOsduTenantHeaders(), false);
}
public ClientResponse run(String url, String arg, String token) throws Exception {
this.arg = arg;
return TestUtils.send(url, getPath(), getHttpMethod(), token, getValidBody(), getQuery(), getOsduTenantHeaders(), false);
}
}
\ No newline at end of file
/*
* Copyright 2020-2023 Google LLC
* Copyright 2020-2023 EPAM Systems, Inc
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.opengroup.osdu.notification.util;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;
import com.sun.jersey.api.client.ClientResponse;
import java.util.HashMap;
import java.util.Map;
import org.opengroup.osdu.core.common.model.http.DpsHeaders;
public class ServicesUtils {
private String storageHost;
private String legalHost;
private TestUtils testUtils;
private String partitionId;
private String groupId;
private FileUtils fileUtils;
public ServicesUtils(String storageHost, String legalHost, TestUtils testUtils, String partitionId, String groupId) {
this.storageHost = storageHost;
this.legalHost = legalHost;
this.testUtils = testUtils;
this.partitionId = partitionId;
this.groupId = groupId;
this.fileUtils = new FileUtils();
}
public ClientResponse createLegalTag(String tagName) throws Exception {
String legalBody = fileUtils.readFromLocalFilePath("/LegalTag.json");
legalBody = legalBody.replace("{{tagName}}", tagName);
Map<String, String> headers = new HashMap<>();
headers.put(DpsHeaders.DATA_PARTITION_ID, partitionId);
headers.put(DpsHeaders.AUTHORIZATION, testUtils.getAdminToken());
ClientResponse legalResponse = HttpClient.send(legalHost, "legaltags", "POST", headers, legalBody, "");
boolean createdOrAlreadyExists = legalResponse.getStatus() == 201 || legalResponse.getStatus() == 409;
assertTrue(createdOrAlreadyExists);
return legalResponse;
}
public void deleteLegalTag(String tagName) throws Exception{
Map<String, String> headers = new HashMap<>();
headers.put(DpsHeaders.DATA_PARTITION_ID, partitionId);
headers.put(DpsHeaders.AUTHORIZATION, testUtils.getAdminToken());
ClientResponse legalResponse = HttpClient.send(legalHost, String.format("legaltags/%s", tagName), "DELETE",
headers, "", "");
assertEquals(204, legalResponse.getStatus());
}
public void createStorageRecords(String suffix, int count, String legalTag) throws Exception{
String body = fileUtils.readFromLocalFilePath("/StorageRecord.json");
body = body.replace("{{data-partition-id}}", partitionId);
body = body.replace("{{legal-tag}}", partitionId + "-" + legalTag);
body = body.replace("{{group_id}}", groupId);
for (int i = 0; i < count; i++) {
String actualBody = body.replace("{{ids-suffix}}", suffix + String.valueOf(i));
Map<String, String> headers = new HashMap<>();
headers.put(DpsHeaders.DATA_PARTITION_ID, partitionId);
headers.put(DpsHeaders.AUTHORIZATION, testUtils.getAdminToken());
ClientResponse storageResponse = HttpClient.send(storageHost, "records", "PUT",
headers, actualBody, "");
assertEquals(201, storageResponse.getStatus());
}
}
public void deleteStorageRecords(int count, String suffix) throws Exception{
for (int i = 0; i < count; i++) {
Map<String, String> headers = new HashMap<>();
headers.put(DpsHeaders.DATA_PARTITION_ID, partitionId);
headers.put(DpsHeaders.AUTHORIZATION, testUtils.getAdminToken());
String recordId = partitionId + ":dataset--ConnectedSource.Generic:notification-test-" + suffix + i;
ClientResponse storageResponse = HttpClient.send(storageHost, "records/" + recordId, "DELETE",
headers, "", "");
assertEquals(204, storageResponse.getStatus());
}
}
}
/*
* Copyright 2017-2020, Schlumberger
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.opengroup.osdu.notification.util;
import static org.junit.jupiter.api.Assertions.assertEquals;
import java.net.URL;
import java.security.SecureRandom;
import java.security.cert.X509Certificate;
import java.util.*;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonElement;
import com.google.gson.JsonParser;
import com.sun.jersey.api.client.Client;
import com.sun.jersey.api.client.ClientResponse;
import com.sun.jersey.api.client.WebResource;
import lombok.extern.slf4j.Slf4j;
@Slf4j
public abstract class TestUtils {
protected String serviceAccountFile;
protected static String opsToken = null;
protected static String adminToken = null;
protected static String editorToken = null;
protected static String noAccessToken = null;
public static String getApiPath(String api, boolean enforceHttp) throws Exception {
String baseUrl = Config.Instance().HostUrl;
if (enforceHttp)
baseUrl = baseUrl.replaceFirst("https", "http");
URL mergedURL = new URL(baseUrl + api);
return mergedURL.toString();
}
public static String getApiPath(String baseUrl, String api, boolean enforceHttp) throws Exception {
if (enforceHttp)
baseUrl = baseUrl.replaceFirst("https", "http");
URL mergedURL = new URL(baseUrl + api);
return mergedURL.toString();
}
public static String getOsduTenant() {
return Config.Instance().OsduTenant;
}
public static String getCustomerTenant() {
return Config.Instance().ClientTenant;
}
public abstract String getOpsToken() throws Exception;
public abstract String getAdminToken() throws Exception;
public abstract String getEditorToken() throws Exception;
public abstract String getNoAccessToken() throws Exception;
public static ClientResponse send(String path, String httpMethod, String token, String requestBody, String query,
Map<String, String> headers, boolean enforceHttp)
throws Exception {
ClientResponse response = null;
Client client = getClient();
client.setConnectTimeout(300000);
client.setReadTimeout(300000);
client.setFollowRedirects(false);
String url = getApiPath(path + query, enforceHttp);
WebResource webResource = client.resource(url);
int count = 1;
int MaxRetry = 3;
while (count < MaxRetry) {
try {
headers.put("correlation-id", headers.getOrDefault("correlation-id", UUID.randomUUID().toString()));
WebResource.Builder builder = webResource.type(MediaType.APPLICATION_JSON)
.header("Authorization", token);
headers.forEach((k, v) -> builder.header(k, v));
//removing Auth header before logging
headers.remove("Authorization");
log.info(String.format("\nRequest URL: %s %s\nRequest Headers: %s\nRequest Body: %s", httpMethod, url, headers, indentatedBody(requestBody)));
log.info(String.format("Attempt: #%s/%s, CorrelationId: %s", count, MaxRetry, headers.get("correlation-id")));
response = builder.method(httpMethod, ClientResponse.class, requestBody);
if (response.getStatusInfo().getFamily().equals(Response.Status.Family.valueOf("SERVER_ERROR"))) {
count++;
Thread.sleep(5000);
continue;
} else {
break;
}
} catch (Exception ex) {
log.error("Exception While Making Request: ", ex);
count++;
if (count == MaxRetry) {
throw new AssertionError("Error: Send request error", ex);
}
} finally {
//log response body
log.info("sending response from TestUtils send method");
if(response!=null)
log.info(String.format("\nThis is the response received : %s\nResponse Headers: %s\nResponse Status code: %s", response, response.getHeaders(), response.getStatus()));
}
}
return response;
}
public static ClientResponse send(String url, String path, String httpMethod, String token, String requestBody,
String query, Map<String, String> headers, boolean enforceHttp)
throws Exception {
ClientResponse response = null;
Client client = getClient();
client.setConnectTimeout(300000);
client.setReadTimeout(300000);
client.setFollowRedirects(false);
String URL = getApiPath(url, path + query, enforceHttp);
WebResource webResource = client.resource(URL);
int count = 1;
int MaxRetry = 3;
while (count < MaxRetry) {
try {
headers.put("correlation-id", headers.getOrDefault("correlation-id", UUID.randomUUID().toString()));
WebResource.Builder builder = webResource.type(MediaType.APPLICATION_JSON);
if (!token.isEmpty()) {
log.info("Token is not empty so adding to request header");
builder.header("Authorization", token);
}
headers.forEach((k, v) -> builder.header(k, v));
//removing Auth header before logging
headers.remove("Authorization");
log.info(String.format("\nRequest URL: %s %s\nRequest Headers: %s\nRequest Body: %s", httpMethod, URL, headers, indentatedBody(requestBody)));
log.info(String.format("Attempt: #%s/%s, CorrelationId: %s", count, MaxRetry, headers.get("correlation-id")));
response = builder.method(httpMethod, ClientResponse.class, requestBody);
if (response.getStatusInfo().getFamily().equals(Response.Status.Family.valueOf("SERVER_ERROR"))) {
count++;
Thread.sleep(5000);
continue;
} else {
break;
}
} catch (Exception ex) {
log.error("Exception While Making Request: ", ex);
count++;
if (count == MaxRetry) {
throw new AssertionError("Error: Send request error", ex);
}
} finally {
//log response body
log.info("sending response from TestUtils send method");
if(response!=null)
log.info(String.format("\nThis is the response received : %s\nResponse Headers: %s\nResponse Status code: %s", response, response.getHeaders(), response.getStatus()));
}
}
return response;
}
public static String indentatedBody(String responseBody) {
JsonParser jsonParser = new JsonParser();
if( responseBody== null)
return responseBody;
JsonElement jsonElement = jsonParser.parse(responseBody);
String indentedResponseEntity =new GsonBuilder().setPrettyPrinting().create().toJson(jsonElement);
return indentedResponseEntity;
}
@SuppressWarnings("unchecked")
public <T> T getResult(ClientResponse response, int exepectedStatus, Class<T> classOfT) {
String json = response.getEntity(String.class);
assertEquals(exepectedStatus, response.getStatus());
if (exepectedStatus == 204) {
return null;
}
assertEquals(MediaType.APPLICATION_JSON, response.getType().toString());
if (classOfT == String.class) {
return (T) json;
}
Gson gson = new Gson();
return gson.fromJson(json, classOfT);
}
public static Client getClient() {
TrustManager[] trustAllCerts = new TrustManager[]{new X509TrustManager() {
@Override
public X509Certificate[] getAcceptedIssuers() {
return null;
}
@Override
public void checkClientTrusted(X509Certificate[] certs, String authType) {
}
@Override
public void checkServerTrusted(X509Certificate[] certs, String authType) {
}
}};
try {
SSLContext sc = SSLContext.getInstance("TLS");
sc.init(null, trustAllCerts, new SecureRandom());
HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
} catch (Exception e) {
log.error("Exception occurred", e);
}
log.info("Creating client");
return Client.create();
}
}
\ No newline at end of file
/*
Copyright 2002-2022 Google LLC
Copyright 2002-2022 EPAM Systems, Inc
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package org.opengroup.osdu.notification.util;
import com.google.common.base.Strings;
import lombok.extern.slf4j.Slf4j;
@Slf4j
public class TokenTestUtils extends TestUtils {
public static final String DE_ADMIN_USER_TOKEN = "DE_ADMIN_USER_TOKEN";
public static final String DE_EDITOR_USER_TOKEN = "DE_EDITOR_USER_TOKEN";
public static final String DE_OPS_USER_TOKEN = "DE_OPS_USER_TOKEN";
public static final String NO_ACCESS_USER_TOKEN = "NO_ACCESS_USER_TOKEN";
private OpenIDTokenProvider tokenProvider;
public TokenTestUtils() {
adminToken = System.getProperty(DE_ADMIN_USER_TOKEN, System.getenv(DE_ADMIN_USER_TOKEN));
editorToken = System.getProperty(DE_EDITOR_USER_TOKEN, System.getenv(DE_EDITOR_USER_TOKEN));
opsToken = System.getProperty(DE_OPS_USER_TOKEN, System.getenv(DE_OPS_USER_TOKEN));
noAccessToken = System.getProperty(NO_ACCESS_USER_TOKEN, System.getenv(NO_ACCESS_USER_TOKEN));
if (Strings.isNullOrEmpty(adminToken) || Strings.isNullOrEmpty(editorToken) || Strings.isNullOrEmpty(opsToken) || Strings.isNullOrEmpty(noAccessToken)) {
tokenProvider = new OpenIDTokenProvider();
adminToken = getAdminToken();
editorToken = getEditorToken();
opsToken = getOpsToken();
noAccessToken = getNoAccessToken();
}
}
@Override
public synchronized String getOpsToken() {
return "Bearer " + tokenProvider.getOpsAccessToken();
}
@Override
public synchronized String getAdminToken() {
return "Bearer " + tokenProvider.getAdminAccessToken();
}
@Override
public synchronized String getEditorToken() {
return "Bearer " + tokenProvider.getEditorAccessToken();
}
@Override
public synchronized String getNoAccessToken() {
return "Bearer " + tokenProvider.getNoAccessToken();
}
}
\ No newline at end of file
{
"name": "{{tagName}}",
"properties": {
"countryOfOrigin": [
"US"
],
"contractId": "A1234",
"expirationDate": 2222222222222,
"originator": "Default",
"dataType": "Public Domain Data",
"securityClassification": "Public",
"personalData": "No Personal Data",
"exportClassification": "EAR99"
},
"description": "Test legal tag for notification"
}
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment