Commit 84f2aaff authored by Nikhil Singh[MicroSoft]'s avatar Nikhil Singh[MicroSoft] Committed by Komal Makkar
Browse files

Storage-Notification Integration Test

parent 605a1205
// Copyright © Microsoft Corporation
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package org.opengroup.osdu.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;
import java.util.UUID;
public class StorageIntegrationDescriptor extends RestDescriptor {
protected static final String LEGAL_TAG = TestUtils.getOsduTenant() + "-test-tag";
@Override
public String getPath() {
return "records";
}
@Override
public String getHttpMethod() {
return "PUT";
}
@Override
public String getValidBody() {
return "[\n" +
" {\n" +
" \"data\":{\n" +
" \"Spuddate\":\"atspud\",\n" +
" \"UWI\":\"atuwi\",\n" +
" \"dlLatLongWGS84latitude\":\"latitude\",\n" +
" \"dlLatLongWGS84longitude\":\"longitude\"},\n" +
" \"version\":1591087431362345,\n" +
" \"kind\":\"opendes:at:wellbore:1.0.0\",\n" +
" \"acl\":{\n" +
" \"viewers\":[\n" +
" \"data.test1@opendes.contoso.com\"],\n" +
" \"owners\":[\n" +
" \"data.test1@opendes.contoso.com\"]},\n" +
" \"legal\":{\n" +
" \"legaltags\":[\n" +
" \"" + LEGAL_TAG + "\"],\n" +
" \"otherRelevantDataCountries\":[\n" +
" \"BR\"],\n" +
" \"status\":\"compliant\"},\n" +
" \"createUser\":\"integrationtest@opendes.iam.gserviceaccount.com\",\n" +
" \"createTime\":\"2020-06-01T18:32:52.054Z\",\n" +
" \"modifyUser\":\"integrationtest@opendes.iam.gserviceaccount.com\",\n" +
" \"modifyTime\":\"2020-06-02T08:43:51.553Z\"\n" +
" }\n" +
"]";
}
@Override
public Map<String, String> getOsduTenantHeaders() {
Map<String, String> headers = new HashMap<>();
headers.put("data-partition-id", Config.Instance().OsduTenant);
headers.put("correlation-id", UUID.randomUUID().toString());
return headers;
}
// Customer Tenant headers is not required by the current Storage -Notification
// Integration Test scenario.It might be useful in upcoming test scenarios/cases
@Override
public Map<String, String> getCustomerTenantHeaders() {
Map<String, String> headers = new HashMap<>();
headers.put("data-partition-id", Config.Instance().ClientTenant);
headers.put("correlation-id", UUID.randomUUID().toString());
return headers;
}
}
\ No newline at end of file
// Copyright © Microsoft Corporation
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package org.opengroup.osdu.notification.api;
import com.sun.jersey.api.client.ClientResponse;
import org.apache.catalina.connector.Response;
import org.apache.commons.lang3.time.StopWatch;
import org.asynchttpclient.util.Assertions;
import org.junit.*;
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.model.notification.SubscriptionInfo;
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.*;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.fail;
public class TestStorageIntegration extends BaseTestTemplate {
private String subscriptionId = null;
private String notificationId = null;
private final String ackSubscriptionId = "AckSubscription";
private final String ackNotificationId = "testingAcknowledgement";
private ISubscriptionService subscriptionService;
private static SubscriptionFactory factory;
protected static final String LEGAL_TAG = TestUtils.getOsduTenant() + "-test-tag";
@BeforeClass
public static void classSetup() throws Exception {
descriptor = new StorageIntegrationDescriptor();
//Configure Register Service Client Library
SubscriptionAPIConfig config = SubscriptionAPIConfig.builder().rootUrl(Config.Instance().RegisterServicePath).build();
factory = new SubscriptionFactory(config);
}
@AfterClass
public static void classTearDown() throws Exception {
}
@Before
@Override
public void setup() throws Exception {
this.testUtils = new AzureTestUtils();
}
@Override
protected void deleteResource() throws Exception {
subscriptionService.delete(subscriptionId);
}
@After
@Override
public void tearDown() throws Exception {
this.testUtils = null;
}
@Override
protected void createResource() throws Exception {
createResourceInPartition(TestUtils.getOsduTenant());
}
private void createResourceInPartition(String partitionId) throws Exception {
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);
// Create a new subscription
Subscription subscription = new Subscription();
subscription.setName("storage-integration-test-hmac");
subscription.setDescription("Subscription created for Storage Integration Tests");
subscription.setTopic(Config.Instance().Topic);
subscription.setPushEndpoint(Config.Instance().HMACPushUrl);
HmacSecret secret = new HmacSecret();
secret.setValue(Config.Instance().hmacSecretValue);
subscription.setSecret(secret);
try {
Subscription subscriptionCreated = subscriptionService.create(subscription);
notificationId = subscriptionCreated.getNotificationId();
subscriptionId = subscriptionCreated.getId();
Config.Instance().NotificationId = notificationId;
} catch (SubscriptionException e) {
System.out.println("Subscription exception inner response : " + e.getHttpResponse());
throw e;
}
}
private void deleteAckSubscription() throws SubscriptionException {
try {
subscriptionService.delete(ackSubscriptionId);
} catch (SubscriptionException e) {
if (e.getHttpResponse().getResponseCode() == Response.SC_NOT_FOUND) {
System.out.println("Test Ack Subscription Not Found for deletion.");
return;
}
Assert.fail("Unable to delete Test Ack Subscription. Deletion Failed." + e);
throw e;
}
}
@Override
protected String getArg() {
return null;
}
@Override
protected String getInvalidArg() {
return null;
}
@Override
protected int expectedOkResponseCode() {
return 200;
}
@Test
@Override
public void should_return20XResponseCode_when_makingValidHttpsRequest() throws Exception {
try {
// Creates an actual subscription with a test endpoint i.e REGISTER_CUSTOM_PUSH_URL_HMAC
this.createResource();
// Delete the Test Ack subscription if there exists any as a part of cleanup.
// The Test Ack Subscription gets created if the the test endpoint of actual subscription
// created above receives notification from Notification Service.
this.deleteAckSubscription();
// Create legal tag used in storage record
LegalTagUtils.create(LEGAL_TAG, this.testUtils.getAdminToken());
// Insert a storage Record.This will send a notification to the event grid/service bus topic
// subscriptions.From there it goes to the Notification Service.Finally from there it goes to the
// test endpoint i.e REGISTER_CUSTOM_PUSH_URL_HMAC which creates the Test ack Subscription.
String URL = Config.Instance().StorageServicePath;
ClientResponse response = descriptor.run(URL, "", this.testUtils.getAdminToken());
assertEquals(error(response.getEntity(String.class)), 201, response.getStatus());
// Verification of Test Ack Subscription creation from the above process.
StopWatch stopWatch = new StopWatch();
stopWatch.start();
// Retrieval of test ack subscription from Cosmos-DB.
long retryCount = Long.parseLong(Config.Instance().RetryCount);
long timeOut = Long.parseLong(Config.Instance().TimeOutSeconds);
SubscriptionInfo ackSubscription = subscriptionService.get(ackSubscriptionId);
while (ackSubscription == null && retryCount > 0) {
TimeUnit.SECONDS.sleep(timeOut);
ackSubscription = subscriptionService.get(ackSubscriptionId);
retryCount--;
}
Assertions.assertNotNull(ackSubscription, "Unable to retrieve test ack subscription. Elapsed time in minutes : " + (stopWatch.getTime(TimeUnit.MINUTES)));
if (ackSubscription != null) {
assertEquals("Unexpected Test Ack Subscription.", ackNotificationId, ackSubscription.getNotificationId());
}
stopWatch.stop();
} catch (Exception e) {
fail("An exception occurred :" + e);
} finally {
// Delete Actual Subscription
this.deleteResource();
// Deletion of Test Ack Subscription
this.deleteAckSubscription();
// Delete legal tag
LegalTagUtils.delete(LEGAL_TAG, this.testUtils.getAdminToken());
}
}
/* Keeping the No-op test cases implementation as ignored as the Storage-Notification Integration
Test scenario does not involves them. */
@Test
@Override
@Ignore
public void should_return400_when_makingHttpRequestWithoutToken() throws Exception {
}
@Test
@Override
@Ignore
public void should_return307_when_makingHttpRequest() throws Exception {
}
@Test
@Override
@Ignore
public void should_return401_when_accessingWithNoAccessCredentials() throws Exception {
}
@Test
@Override
@Ignore
public void should_return401_when_noAccessOnCustomerTenant() throws Exception {
}
@Test
@Override
@Ignore
public void should_return401_when_accessingWithEditorCredentials() throws Exception {
}
@Test
@Override
@Ignore
public void should_return401_when_accessingWithAdminCredentials() throws Exception {
}
@Test
@Override
@Ignore
public void should_return20X_when_usingCredentialsWithOpsPermission() throws Exception {
}
@Test
@Override
@Ignore
public void should_returnOk_when_makingHttpOptionsRequest() throws Exception {
}
}
\ No newline at end of file
// 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.notification.util;
import com.google.gson.JsonArray;
import com.google.gson.JsonObject;
import com.sun.jersey.api.client.ClientResponse;
import org.apache.http.HttpStatus;
import java.util.HashMap;
import java.util.Map;
import static org.junit.Assert.assertEquals;
public class LegalTagUtils {
public static ClientResponse create(String legalTagName, String token) throws Exception {
return create("US", legalTagName, "2099-01-25", "Public Domain Data", token);
}
protected static ClientResponse create(String countryOfOrigin, String name, String expDate, String dataType, String token)
throws Exception {
String body = getBody(countryOfOrigin, name, expDate, dataType);
Map<String, String> headers = new HashMap<>();
headers.put("Data-Partition-Id", TestUtils.getOsduTenant());
ClientResponse response = TestUtils.send(getLegalUrl(), "legaltags", "POST", token, body, "", headers, false);
assertEquals(HttpStatus.SC_CREATED, response.getStatus());
Thread.sleep(100);
return response;
}
public static ClientResponse delete(String legalTagName, String token) throws Exception {
Map<String, String> headers = new HashMap<>();
headers.put("Data-Partition-Id", TestUtils.getOsduTenant());
return TestUtils.send(getLegalUrl(), "legaltags/" + legalTagName, "DELETE", token, "", "", headers, false);
}
protected static String getLegalUrl() {
return Config.Instance().LegalServicePath;
}
protected static String getBody(String countryOfOrigin, String name, String expDate, String dataType) {
JsonArray coo = new JsonArray();
coo.add(countryOfOrigin);
JsonObject properties = new JsonObject();
properties.add("countryOfOrigin", coo);
properties.addProperty("contractId", "A1234");
properties.addProperty("expirationDate", expDate);
properties.addProperty("dataType", dataType);
properties.addProperty("originator", "MyCompany");
properties.addProperty("securityClassification", "Public");
properties.addProperty("exportClassification", "EAR99");
properties.addProperty("personalData", "No Personal Data");
JsonObject tag = new JsonObject();
tag.addProperty("name", name);
tag.addProperty("description", "test for " + name);
tag.add("properties", properties);
return tag.toString();
}
}
......@@ -24,55 +24,61 @@ public class Config {
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;
private static Config config = new Config();
public static Config Instance() {
String env = getEnvironment();
config.ClientTenant = getEnvironmentVariableOrDefaultValue("CLIENT_TENANT","nonexistenttenant");
config.IntegrationAudience = getEnvironmentVariableOrDefaultValue("INTEGRATION_TEST_AUDIENCE","245464679631-ktfdfpl147m1mjpbutl00b3cmffissgq.apps.googleusercontent.com");
config.OsduTenant = getEnvironmentVariableOrDefaultValue("OSDU_TENANT","opendes");
config.Topic = getEnvironmentVariableOrDefaultValue("TOPIC_ID","records-changed");
config.ClientTenant = getEnvironmentVariableOrDefaultValue("CLIENT_TENANT", "nonexistenttenant");
config.IntegrationAudience = getEnvironmentVariableOrDefaultValue("INTEGRATION_TEST_AUDIENCE", "245464679631-ktfdfpl147m1mjpbutl00b3cmffissgq.apps.googleusercontent.com");
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"));
if (env.equalsIgnoreCase("LOCAL")) {
//make sure to run register service on a different port. You can also choose to point to Register service that is running in cloud
String registerUrl = "http://localhost:8081/api/register/v1";
//must have notification and register services running on different ports
config.HostUrl = "http://localhost:8080/";
config.GSAPushUrl = registerUrl+"/test/gsa-challenge/";
config.HMACPushUrl = registerUrl+"/test/challenge/";
config.GSAPushUrl = registerUrl + "/test/gsa-challenge/";
config.HMACPushUrl = registerUrl + "/test/challenge/";
config.RegisterServicePath = registerUrl;
config.StorageServicePath = "http://localhost:8085/api/storage/v2/";
config.LegalServicePath = "http://localhost:8087/api/legal/v1/";
} else if (env.equalsIgnoreCase("DEV") || isGke() || env.equalsIgnoreCase("CLOUD")) {
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/";
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/");
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");
if(regUrl==null)
{
config.RegisterServicePath = registerUrl;
}
else
{
config.RegisterServicePath = regUrl+"/api/register/v1";
}
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";
}
}else
} else
throw new RuntimeException("$ENVIRONMENT environment variable not provided");
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("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;
}
......
......@@ -22,34 +22,51 @@ 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 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;