diff --git a/data-prepper-plugins/saas-source-plugins/atlassian-commons/src/main/java/org/opensearch/dataprepper/plugins/source/atlassian/AtlassianSourceConfig.java b/data-prepper-plugins/saas-source-plugins/atlassian-commons/src/main/java/org/opensearch/dataprepper/plugins/source/atlassian/AtlassianSourceConfig.java index bc661f96af..9cd941c23f 100644 --- a/data-prepper-plugins/saas-source-plugins/atlassian-commons/src/main/java/org/opensearch/dataprepper/plugins/source/atlassian/AtlassianSourceConfig.java +++ b/data-prepper-plugins/saas-source-plugins/atlassian-commons/src/main/java/org/opensearch/dataprepper/plugins/source/atlassian/AtlassianSourceConfig.java @@ -19,7 +19,7 @@ import java.util.List; @Getter -public class AtlassianSourceConfig implements CrawlerSourceConfig { +public abstract class AtlassianSourceConfig implements CrawlerSourceConfig { private static final int DEFAULT_BATCH_SIZE = 50; @@ -56,4 +56,6 @@ public String getAccountUrl() { public String getAuthType() { return this.getAuthenticationConfig().getAuthType(); } + + public abstract String getOauth2UrlContext(); } diff --git a/data-prepper-plugins/saas-source-plugins/atlassian-commons/src/main/java/org/opensearch/dataprepper/plugins/source/atlassian/rest/auth/AtlassianOauthConfig.java b/data-prepper-plugins/saas-source-plugins/atlassian-commons/src/main/java/org/opensearch/dataprepper/plugins/source/atlassian/rest/auth/AtlassianOauthConfig.java index 3608376259..dfd3e917d0 100644 --- a/data-prepper-plugins/saas-source-plugins/atlassian-commons/src/main/java/org/opensearch/dataprepper/plugins/source/atlassian/rest/auth/AtlassianOauthConfig.java +++ b/data-prepper-plugins/saas-source-plugins/atlassian-commons/src/main/java/org/opensearch/dataprepper/plugins/source/atlassian/rest/auth/AtlassianOauthConfig.java @@ -34,12 +34,12 @@ import static org.opensearch.dataprepper.plugins.source.atlassian.utils.Constants.SLASH; /** - * The type Jira service. + * The type Atlassian OAuth2 Service Config. */ public class AtlassianOauthConfig implements AtlassianAuthConfig { - public static final String OAuth2_URL = "https://api.atlassian.com/ex/jira/"; + public static final String OAuth2_URL = "https://api.atlassian.com/ex/"; public static final String ACCESSIBLE_RESOURCES = "https://api.atlassian.com/oauth/token/accessible-resources"; public static final String TOKEN_LOCATION = "https://auth.atlassian.com/oauth/token"; @@ -60,22 +60,22 @@ public class AtlassianOauthConfig implements AtlassianAuthConfig { private String cloudId = null; private final String clientId; private final String clientSecret; - private final AtlassianSourceConfig confluenceSourceConfig; + private final AtlassianSourceConfig atlassianSourceConfig; private final Object cloudIdFetchLock = new Object(); private final Object tokenRenewLock = new Object(); - public AtlassianOauthConfig(AtlassianSourceConfig confluenceSourceConfig) { - this.confluenceSourceConfig = confluenceSourceConfig; - this.accessToken = (String) confluenceSourceConfig.getAuthenticationConfig().getOauth2Config() + public AtlassianOauthConfig(AtlassianSourceConfig atlassianSourceConfig) { + this.atlassianSourceConfig = atlassianSourceConfig; + this.accessToken = (String) atlassianSourceConfig.getAuthenticationConfig().getOauth2Config() .getAccessToken().getValue(); - this.refreshToken = (String) confluenceSourceConfig.getAuthenticationConfig() + this.refreshToken = (String) atlassianSourceConfig.getAuthenticationConfig() .getOauth2Config().getRefreshToken().getValue(); - this.clientId = confluenceSourceConfig.getAuthenticationConfig().getOauth2Config().getClientId(); - this.clientSecret = confluenceSourceConfig.getAuthenticationConfig().getOauth2Config().getClientSecret(); + this.clientId = atlassianSourceConfig.getAuthenticationConfig().getOauth2Config().getClientId(); + this.clientSecret = atlassianSourceConfig.getAuthenticationConfig().getOauth2Config().getClientSecret(); } - public String getJiraAccountCloudId() { - log.info("Getting Jira Account Cloud ID"); + public String getAtlassianAccountCloudId() { + log.info("Getting Atlassian Account Cloud ID"); synchronized (cloudIdFetchLock) { if (this.cloudId != null) { //Someone else must have initialized it @@ -120,14 +120,14 @@ public void renewCredentials() { return; } - log.info("Renewing access token and refresh token pair for Jira Connector."); + log.info("Renewing access token and refresh token pair for Atlassian Connector."); HttpHeaders headers = new HttpHeaders(); headers.setContentType(MediaType.APPLICATION_JSON); String payloadTemplate = "{\"grant_type\": \"%s\", \"client_id\": \"%s\", \"client_secret\": \"%s\", \"refresh_token\": \"%s\"}"; String payload = String.format(payloadTemplate, "refresh_token", clientId, clientSecret, refreshToken); HttpEntity entity = new HttpEntity<>(payload, headers); - Oauth2Config oauth2Config = confluenceSourceConfig.getAuthenticationConfig().getOauth2Config(); + Oauth2Config oauth2Config = atlassianSourceConfig.getAuthenticationConfig().getOauth2Config(); try { ResponseEntity responseEntity = restTemplate.postForEntity(TOKEN_LOCATION, entity, Map.class); Map oauthClientResponse = responseEntity.getBody(); @@ -172,12 +172,12 @@ public String getUrl() { } /** - * Method for getting Jira url based on auth type. + * Method for getting source url based on auth type. */ @Override public void initCredentials() { - //For OAuth based flow, we use a different Jira url - this.cloudId = getJiraAccountCloudId(); - this.url = OAuth2_URL + this.cloudId + SLASH; + //For OAuth based flow, we use a different source url + this.cloudId = getAtlassianAccountCloudId(); + this.url = OAuth2_URL + atlassianSourceConfig.getOauth2UrlContext() + SLASH + this.cloudId + SLASH; } } diff --git a/data-prepper-plugins/saas-source-plugins/atlassian-commons/src/test/java/org/opensearch/dataprepper/plugins/source/atlassian/rest/auth/AtlassianOauthConfigTest.java b/data-prepper-plugins/saas-source-plugins/atlassian-commons/src/test/java/org/opensearch/dataprepper/plugins/source/atlassian/rest/auth/AtlassianOauthConfigTest.java index 640d6652be..919f8f26a6 100644 --- a/data-prepper-plugins/saas-source-plugins/atlassian-commons/src/test/java/org/opensearch/dataprepper/plugins/source/atlassian/rest/auth/AtlassianOauthConfigTest.java +++ b/data-prepper-plugins/saas-source-plugins/atlassian-commons/src/test/java/org/opensearch/dataprepper/plugins/source/atlassian/rest/auth/AtlassianOauthConfigTest.java @@ -124,7 +124,7 @@ void testFailedToRenewAccessToken_with_unauthorized_and_trigger_secrets_refresh( @Test - void testGetJiraAccountCloudId() throws InterruptedException { + void testGetTestAccountCloudId() throws InterruptedException { Map mockGetCallResponse = new HashMap<>(); mockGetCallResponse.put("id", "test_cloud_id"); when(restTemplateMock.exchange(any(String.class), any(HttpMethod.class), any(HttpEntity.class), any(Class.class))) @@ -141,8 +141,8 @@ void testGetJiraAccountCloudId() throws InterruptedException { } executor.shutdown(); - assertEquals("test_cloud_id", jiraOauthConfig.getJiraAccountCloudId()); - assertEquals("https://api.atlassian.com/ex/jira/test_cloud_id/", jiraOauthConfig.getUrl()); + assertEquals("test_cloud_id", jiraOauthConfig.getAtlassianAccountCloudId()); + assertEquals("https://api.atlassian.com/ex/test/test_cloud_id/", jiraOauthConfig.getUrl()); //calling second time shouldn't trigger rest call jiraOauthConfig.getUrl(); verify(restTemplateMock, times(1)) @@ -150,7 +150,7 @@ void testGetJiraAccountCloudId() throws InterruptedException { } @Test - void testGetJiraAccountCloudIdUnauthorizedCase() { + void testGetAtlassianAccountCloudIdUnauthorizedCase() { when(restTemplateMock.exchange(any(String.class), any(HttpMethod.class), any(HttpEntity.class), any(Class.class))) .thenThrow(new HttpClientErrorException(HttpStatus.UNAUTHORIZED)); diff --git a/data-prepper-plugins/saas-source-plugins/atlassian-commons/src/test/java/org/opensearch/dataprepper/plugins/source/atlassian/utils/AtlassianSourceConfigTest.java b/data-prepper-plugins/saas-source-plugins/atlassian-commons/src/test/java/org/opensearch/dataprepper/plugins/source/atlassian/utils/AtlassianSourceConfigTest.java new file mode 100644 index 0000000000..3df445a025 --- /dev/null +++ b/data-prepper-plugins/saas-source-plugins/atlassian-commons/src/test/java/org/opensearch/dataprepper/plugins/source/atlassian/utils/AtlassianSourceConfigTest.java @@ -0,0 +1,19 @@ +/* + * Copyright OpenSearch Contributors + * SPDX-License-Identifier: Apache-2.0 + * + * The OpenSearch Contributors require contributions made to + * this file be licensed under the Apache-2.0 license or a + * compatible open source license. + * + */ +package org.opensearch.dataprepper.plugins.source.atlassian.utils; + +import org.opensearch.dataprepper.plugins.source.atlassian.AtlassianSourceConfig; + +public class AtlassianSourceConfigTest extends AtlassianSourceConfig { + @Override + public String getOauth2UrlContext() { + return "test"; + } +} diff --git a/data-prepper-plugins/saas-source-plugins/atlassian-commons/src/test/java/org/opensearch/dataprepper/plugins/source/atlassian/utils/ConfigUtilForTests.java b/data-prepper-plugins/saas-source-plugins/atlassian-commons/src/test/java/org/opensearch/dataprepper/plugins/source/atlassian/utils/ConfigUtilForTests.java index 61d1889935..4034af86a1 100644 --- a/data-prepper-plugins/saas-source-plugins/atlassian-commons/src/test/java/org/opensearch/dataprepper/plugins/source/atlassian/utils/ConfigUtilForTests.java +++ b/data-prepper-plugins/saas-source-plugins/atlassian-commons/src/test/java/org/opensearch/dataprepper/plugins/source/atlassian/utils/ConfigUtilForTests.java @@ -1,3 +1,12 @@ +/* + * Copyright OpenSearch Contributors + * SPDX-License-Identifier: Apache-2.0 + * + * The OpenSearch Contributors require contributions made to + * this file be licensed under the Apache-2.0 license or a + * compatible open source license. + * + */ package org.opensearch.dataprepper.plugins.source.atlassian.utils; import com.fasterxml.jackson.databind.ObjectMapper; @@ -26,7 +35,7 @@ private static InputStream getResourceAsStream(String resourceName) { public static AtlassianSourceConfig createJiraConfigurationFromYaml(String fileName) { ObjectMapper objectMapper = new ObjectMapper(new YAMLFactory()); try (InputStream inputStream = getResourceAsStream(fileName)) { - AtlassianSourceConfig confluenceSourceConfig = objectMapper.readValue(inputStream, AtlassianSourceConfig.class); + AtlassianSourceConfig confluenceSourceConfig = objectMapper.readValue(inputStream, AtlassianSourceConfigTest.class); Oauth2Config oauth2Config = confluenceSourceConfig.getAuthenticationConfig().getOauth2Config(); if (oauth2Config != null) { ReflectivelySetField.setField(Oauth2Config.class, oauth2Config, "accessToken", diff --git a/data-prepper-plugins/saas-source-plugins/confluence-source/src/main/java/org/opensearch/dataprepper/plugins/source/confluence/ConfluenceService.java b/data-prepper-plugins/saas-source-plugins/confluence-source/src/main/java/org/opensearch/dataprepper/plugins/source/confluence/ConfluenceService.java index 2be6b26d00..7368aefe35 100644 --- a/data-prepper-plugins/saas-source-plugins/confluence-source/src/main/java/org/opensearch/dataprepper/plugins/source/confluence/ConfluenceService.java +++ b/data-prepper-plugins/saas-source-plugins/confluence-source/src/main/java/org/opensearch/dataprepper/plugins/source/confluence/ConfluenceService.java @@ -111,8 +111,8 @@ private void searchForNewContentAndAddToQueue(ConfluenceSourceConfig configurati addItemsToQueue(contentList, itemInfoQueue); log.debug("Content items fetched so far: {}", total); paginationLinks = searchContentItems.getLinks(); + searchResultsFoundCounter.increment(searchContentItems.getSize()); } while (paginationLinks != null && paginationLinks.getNext() != null); - searchResultsFoundCounter.increment(total); log.info("Number of content items found in search api call: {}", total); } diff --git a/data-prepper-plugins/saas-source-plugins/confluence-source/src/main/java/org/opensearch/dataprepper/plugins/source/confluence/ConfluenceSourceConfig.java b/data-prepper-plugins/saas-source-plugins/confluence-source/src/main/java/org/opensearch/dataprepper/plugins/source/confluence/ConfluenceSourceConfig.java index ce66677094..c1af943ec4 100644 --- a/data-prepper-plugins/saas-source-plugins/confluence-source/src/main/java/org/opensearch/dataprepper/plugins/source/confluence/ConfluenceSourceConfig.java +++ b/data-prepper-plugins/saas-source-plugins/confluence-source/src/main/java/org/opensearch/dataprepper/plugins/source/confluence/ConfluenceSourceConfig.java @@ -33,4 +33,8 @@ public class ConfluenceSourceConfig extends AtlassianSourceConfig implements Cra @JsonProperty("acknowledgments") private boolean acknowledgments = false; + @Override + public String getOauth2UrlContext() { + return "confluence"; + } } diff --git a/data-prepper-plugins/saas-source-plugins/confluence-source/src/test/java/org/opensearch/dataprepper/plugins/source/confluence/ConfluenceSourceConfigTest.java b/data-prepper-plugins/saas-source-plugins/confluence-source/src/test/java/org/opensearch/dataprepper/plugins/source/confluence/ConfluenceSourceConfigTest.java index 69535ae697..dc6a52b785 100644 --- a/data-prepper-plugins/saas-source-plugins/confluence-source/src/test/java/org/opensearch/dataprepper/plugins/source/confluence/ConfluenceSourceConfigTest.java +++ b/data-prepper-plugins/saas-source-plugins/confluence-source/src/test/java/org/opensearch/dataprepper/plugins/source/confluence/ConfluenceSourceConfigTest.java @@ -78,7 +78,6 @@ private ConfluenceSourceConfig createConfluenceSourceConfig(String authtype, boo Map filterMap = new HashMap<>(); Map projectMap = new HashMap<>(); Map issueTypeMap = new HashMap<>(); - Map statusMap = new HashMap<>(); issueTypeMap.put("include", contentTypeList); filterMap.put("page_type", issueTypeMap); @@ -127,4 +126,10 @@ void testFetchGivenOauthAtrribute() throws Exception { assertEquals(clientId, confluenceSourceConfig.getAuthenticationConfig().getOauth2Config().getClientId()); assertEquals(clientSecret, confluenceSourceConfig.getAuthenticationConfig().getOauth2Config().getClientSecret()); } + + @Test + void testGetOauth2UrlContext() throws Exception { + confluenceSourceConfig = createConfluenceSourceConfig(OAUTH2, false); + assertEquals("confluence", confluenceSourceConfig.getOauth2UrlContext()); + } } diff --git a/data-prepper-plugins/saas-source-plugins/jira-source/build.gradle b/data-prepper-plugins/saas-source-plugins/jira-source/build.gradle index 1cf3854ab4..68a390739f 100644 --- a/data-prepper-plugins/saas-source-plugins/jira-source/build.gradle +++ b/data-prepper-plugins/saas-source-plugins/jira-source/build.gradle @@ -5,6 +5,7 @@ plugins { dependencies { implementation project(path: ':data-prepper-plugins:saas-source-plugins:source-crawler') + implementation project(path: ':data-prepper-plugins:saas-source-plugins:atlassian-commons') implementation project(path: ':data-prepper-api') implementation project(path: ':data-prepper-plugins:aws-plugin-api') implementation project(path: ':data-prepper-plugins:buffer-common') @@ -15,7 +16,6 @@ dependencies { implementation 'com.fasterxml.jackson.core:jackson-core' implementation 'com.fasterxml.jackson.core:jackson-databind' implementation 'javax.inject:javax.inject:1' - implementation("org.springframework:spring-web:${libs.versions.spring.get()}") implementation 'org.projectlombok:lombok:1.18.30' annotationProcessor 'org.projectlombok:lombok:1.18.30' @@ -26,6 +26,7 @@ dependencies { implementation(libs.spring.context) { exclude group: 'commons-logging', module: 'commons-logging' } + implementation(libs.spring.web) } test { diff --git a/data-prepper-plugins/saas-source-plugins/jira-source/src/main/java/org/opensearch/dataprepper/plugins/source/jira/JiraService.java b/data-prepper-plugins/saas-source-plugins/jira-source/src/main/java/org/opensearch/dataprepper/plugins/source/jira/JiraService.java index ebeb503bd3..7062632e20 100644 --- a/data-prepper-plugins/saas-source-plugins/jira-source/src/main/java/org/opensearch/dataprepper/plugins/source/jira/JiraService.java +++ b/data-prepper-plugins/saas-source-plugins/jira-source/src/main/java/org/opensearch/dataprepper/plugins/source/jira/JiraService.java @@ -13,7 +13,7 @@ import io.micrometer.core.instrument.Counter; import lombok.extern.slf4j.Slf4j; import org.opensearch.dataprepper.metrics.PluginMetrics; -import org.opensearch.dataprepper.plugins.source.jira.exception.BadRequestException; +import org.opensearch.dataprepper.model.plugin.InvalidPluginConfigurationException; import org.opensearch.dataprepper.plugins.source.jira.models.IssueBean; import org.opensearch.dataprepper.plugins.source.jira.models.SearchResults; import org.opensearch.dataprepper.plugins.source.jira.rest.JiraRestClient; @@ -201,14 +201,14 @@ private void validateProjectFilters(JiraSourceConfig configuration) { if (!badFilters.isEmpty()) { String filters = String.join("\"" + badFilters + "\"", ", "); log.error("One or more invalid project keys found in filter configuration: {}", badFilters); - throw new BadRequestException("Bad request exception occurred " + + throw new InvalidPluginConfigurationException("Bad request exception occurred " + "Invalid project key found in filter configuration for " + filters); } if (!includedAndExcludedProjects.isEmpty()) { String filters = String.join("\"" + includedAndExcludedProjects + "\"", ", "); log.error("One or more project keys found in both include and exclude: {}", includedAndExcludedProjects); - throw new BadRequestException("Bad request exception occurred " + + throw new InvalidPluginConfigurationException("Bad request exception occurred " + "Project filters is invalid because the following projects are listed in both include and exclude" + filters); } diff --git a/data-prepper-plugins/saas-source-plugins/jira-source/src/main/java/org/opensearch/dataprepper/plugins/source/jira/JiraSource.java b/data-prepper-plugins/saas-source-plugins/jira-source/src/main/java/org/opensearch/dataprepper/plugins/source/jira/JiraSource.java index 2ffc7b3b53..a314ec680b 100644 --- a/data-prepper-plugins/saas-source-plugins/jira-source/src/main/java/org/opensearch/dataprepper/plugins/source/jira/JiraSource.java +++ b/data-prepper-plugins/saas-source-plugins/jira-source/src/main/java/org/opensearch/dataprepper/plugins/source/jira/JiraSource.java @@ -20,7 +20,8 @@ import org.opensearch.dataprepper.model.plugin.PluginFactory; import org.opensearch.dataprepper.model.record.Record; import org.opensearch.dataprepper.model.source.Source; -import org.opensearch.dataprepper.plugins.source.jira.rest.auth.JiraAuthConfig; +import org.opensearch.dataprepper.plugins.source.atlassian.AtlassianSourceConfig; +import org.opensearch.dataprepper.plugins.source.atlassian.rest.auth.AtlassianAuthConfig; import org.opensearch.dataprepper.plugins.source.jira.utils.JiraConfigHelper; import org.opensearch.dataprepper.plugins.source.source_crawler.CrawlerApplicationContextMarker; import org.opensearch.dataprepper.plugins.source.source_crawler.base.Crawler; @@ -39,18 +40,18 @@ @DataPrepperPlugin(name = PLUGIN_NAME, pluginType = Source.class, pluginConfigurationType = JiraSourceConfig.class, - packagesToScan = {CrawlerApplicationContextMarker.class, JiraSource.class} + packagesToScan = {CrawlerApplicationContextMarker.class, AtlassianSourceConfig.class, JiraSource.class} ) public class JiraSource extends CrawlerSourcePlugin { private static final Logger log = LoggerFactory.getLogger(JiraSource.class); private final JiraSourceConfig jiraSourceConfig; - private final JiraAuthConfig jiraOauthConfig; + private final AtlassianAuthConfig jiraOauthConfig; @DataPrepperPluginConstructor public JiraSource(final PluginMetrics pluginMetrics, final JiraSourceConfig jiraSourceConfig, - final JiraAuthConfig jiraOauthConfig, + final AtlassianAuthConfig jiraOauthConfig, final PluginFactory pluginFactory, final AcknowledgementSetManager acknowledgementSetManager, Crawler crawler, diff --git a/data-prepper-plugins/saas-source-plugins/jira-source/src/main/java/org/opensearch/dataprepper/plugins/source/jira/JiraSourceConfig.java b/data-prepper-plugins/saas-source-plugins/jira-source/src/main/java/org/opensearch/dataprepper/plugins/source/jira/JiraSourceConfig.java index 4328181fea..08b61e2b81 100644 --- a/data-prepper-plugins/saas-source-plugins/jira-source/src/main/java/org/opensearch/dataprepper/plugins/source/jira/JiraSourceConfig.java +++ b/data-prepper-plugins/saas-source-plugins/jira-source/src/main/java/org/opensearch/dataprepper/plugins/source/jira/JiraSourceConfig.java @@ -11,63 +11,36 @@ package org.opensearch.dataprepper.plugins.source.jira; import com.fasterxml.jackson.annotation.JsonProperty; -import jakarta.validation.Valid; import jakarta.validation.constraints.AssertTrue; import lombok.Getter; -import org.opensearch.dataprepper.plugins.source.jira.configuration.AuthenticationConfig; +import org.opensearch.dataprepper.plugins.source.atlassian.AtlassianSourceConfig; import org.opensearch.dataprepper.plugins.source.jira.configuration.FilterConfig; import org.opensearch.dataprepper.plugins.source.source_crawler.base.CrawlerSourceConfig; -import java.util.List; - @Getter -public class JiraSourceConfig implements CrawlerSourceConfig { +public class JiraSourceConfig extends AtlassianSourceConfig implements CrawlerSourceConfig { private static final int DEFAULT_BATCH_SIZE = 50; - /** - * Jira account url - */ - @JsonProperty("hosts") - private List hosts; - - @AssertTrue(message = "Jira hosts must be a list of length 1") - boolean isValidHosts() { - return hosts != null && hosts.size() == 1; - } - - /** - * Authentication Config to Access Jira - */ - @JsonProperty("authentication") - @Valid - private AuthenticationConfig authenticationConfig; - - /** - * Batch size for fetching tickets - */ - @JsonProperty("batch_size") - private int batchSize = DEFAULT_BATCH_SIZE; - - /** * Filter Config to filter what tickets get ingested */ @JsonProperty("filter") private FilterConfig filterConfig; - - /** * Boolean property indicating end to end acknowledgments state */ @JsonProperty("acknowledgments") private boolean acknowledgments = false; - public String getAccountUrl() { - return this.getHosts().get(0); + @AssertTrue(message = "Jira hosts must be a list of length 1") + boolean isValidHosts() { + return hosts != null && hosts.size() == 1; } - public String getAuthType() { - return this.getAuthenticationConfig().getAuthType(); + @Override + public String getOauth2UrlContext() { + return "jira"; } + } diff --git a/data-prepper-plugins/saas-source-plugins/jira-source/src/main/java/org/opensearch/dataprepper/plugins/source/jira/configuration/AuthenticationConfig.java b/data-prepper-plugins/saas-source-plugins/jira-source/src/main/java/org/opensearch/dataprepper/plugins/source/jira/configuration/AuthenticationConfig.java deleted file mode 100644 index 25cfd4185a..0000000000 --- a/data-prepper-plugins/saas-source-plugins/jira-source/src/main/java/org/opensearch/dataprepper/plugins/source/jira/configuration/AuthenticationConfig.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright OpenSearch Contributors - * SPDX-License-Identifier: Apache-2.0 - * - * The OpenSearch Contributors require contributions made to - * this file be licensed under the Apache-2.0 license or a - * compatible open source license. - * - */ - -package org.opensearch.dataprepper.plugins.source.jira.configuration; - -import com.fasterxml.jackson.annotation.JsonProperty; -import jakarta.validation.Valid; -import jakarta.validation.constraints.AssertTrue; -import lombok.Getter; - -import static org.opensearch.dataprepper.plugins.source.jira.utils.Constants.BASIC; -import static org.opensearch.dataprepper.plugins.source.jira.utils.Constants.OAUTH2; - -@Getter -public class AuthenticationConfig { - @JsonProperty("basic") - @Valid - private BasicConfig basicConfig; - - @JsonProperty("oauth2") - @Valid - private Oauth2Config oauth2Config; - - @AssertTrue(message = "Authentication config should have either basic or oauth2") - private boolean isValidAuthenticationConfig() { - boolean hasBasic = basicConfig != null; - boolean hasOauth = oauth2Config != null; - return hasBasic ^ hasOauth; - } - - public String getAuthType() { - if (basicConfig != null) { - return BASIC; - } else { - return OAUTH2; - } - } -} diff --git a/data-prepper-plugins/saas-source-plugins/jira-source/src/main/java/org/opensearch/dataprepper/plugins/source/jira/configuration/BasicConfig.java b/data-prepper-plugins/saas-source-plugins/jira-source/src/main/java/org/opensearch/dataprepper/plugins/source/jira/configuration/BasicConfig.java deleted file mode 100644 index b3a261f13a..0000000000 --- a/data-prepper-plugins/saas-source-plugins/jira-source/src/main/java/org/opensearch/dataprepper/plugins/source/jira/configuration/BasicConfig.java +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright OpenSearch Contributors - * SPDX-License-Identifier: Apache-2.0 - * - * The OpenSearch Contributors require contributions made to - * this file be licensed under the Apache-2.0 license or a - * compatible open source license. - * - */ - -package org.opensearch.dataprepper.plugins.source.jira.configuration; - -import com.fasterxml.jackson.annotation.JsonProperty; -import jakarta.validation.constraints.AssertTrue; -import lombok.Getter; - -@Getter -public class BasicConfig { - @JsonProperty("username") - private String username; - - @JsonProperty("password") - private String password; - - @AssertTrue(message = "Username and Password are both required for Basic Auth") - private boolean isBasicConfigValid() { - return username != null && password != null; - } -} diff --git a/data-prepper-plugins/saas-source-plugins/jira-source/src/main/java/org/opensearch/dataprepper/plugins/source/jira/configuration/Oauth2Config.java b/data-prepper-plugins/saas-source-plugins/jira-source/src/main/java/org/opensearch/dataprepper/plugins/source/jira/configuration/Oauth2Config.java deleted file mode 100644 index b013bb3527..0000000000 --- a/data-prepper-plugins/saas-source-plugins/jira-source/src/main/java/org/opensearch/dataprepper/plugins/source/jira/configuration/Oauth2Config.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright OpenSearch Contributors - * SPDX-License-Identifier: Apache-2.0 - * - * The OpenSearch Contributors require contributions made to - * this file be licensed under the Apache-2.0 license or a - * compatible open source license. - * - */ - -package org.opensearch.dataprepper.plugins.source.jira.configuration; - -import com.fasterxml.jackson.annotation.JsonProperty; -import jakarta.validation.constraints.AssertTrue; -import lombok.Getter; -import org.opensearch.dataprepper.model.plugin.PluginConfigVariable; - -@Getter -public class Oauth2Config { - @JsonProperty("client_id") - private String clientId; - - @JsonProperty("client_secret") - private String clientSecret; - - @JsonProperty("access_token") - private PluginConfigVariable accessToken; - - @JsonProperty("refresh_token") - private PluginConfigVariable refreshToken; - - @AssertTrue(message = "Client ID, Client Secret, Access Token, and Refresh Token are both required for Oauth2") - private boolean isOauth2ConfigValid() { - return clientId != null && clientSecret != null && accessToken != null && refreshToken != null; - } -} diff --git a/data-prepper-plugins/saas-source-plugins/jira-source/src/main/java/org/opensearch/dataprepper/plugins/source/jira/exception/BadRequestException.java b/data-prepper-plugins/saas-source-plugins/jira-source/src/main/java/org/opensearch/dataprepper/plugins/source/jira/exception/BadRequestException.java deleted file mode 100644 index 69c0cca638..0000000000 --- a/data-prepper-plugins/saas-source-plugins/jira-source/src/main/java/org/opensearch/dataprepper/plugins/source/jira/exception/BadRequestException.java +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Copyright OpenSearch Contributors - * SPDX-License-Identifier: Apache-2.0 - * - * The OpenSearch Contributors require contributions made to - * this file be licensed under the Apache-2.0 license or a - * compatible open source license. - * - */ - -package org.opensearch.dataprepper.plugins.source.jira.exception; - -/** - * Exception to indicate a bad REST call has been made. - * It could either be caused by bad user inputs or wrong url construction in the logic. - */ -public final class BadRequestException extends RuntimeException { - public BadRequestException(final String message, final Throwable throwable) { - super(message, throwable); - } - - public BadRequestException(final String message) { - super(message); - } -} diff --git a/data-prepper-plugins/saas-source-plugins/jira-source/src/main/java/org/opensearch/dataprepper/plugins/source/jira/exception/UnAuthorizedException.java b/data-prepper-plugins/saas-source-plugins/jira-source/src/main/java/org/opensearch/dataprepper/plugins/source/jira/exception/UnAuthorizedException.java deleted file mode 100644 index 441f966bd8..0000000000 --- a/data-prepper-plugins/saas-source-plugins/jira-source/src/main/java/org/opensearch/dataprepper/plugins/source/jira/exception/UnAuthorizedException.java +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Copyright OpenSearch Contributors - * SPDX-License-Identifier: Apache-2.0 - * - * The OpenSearch Contributors require contributions made to - * this file be licensed under the Apache-2.0 license or a - * compatible open source license. - * - */ - -package org.opensearch.dataprepper.plugins.source.jira.exception; - -/** - * Exception to indicate unauthorized access. - * It could either be caused by invalid credentials supplied by the user or failed renew the credentials. - */ -public final class UnAuthorizedException extends RuntimeException { - public UnAuthorizedException(final String message, final Throwable throwable) { - super(message, throwable); - } - - public UnAuthorizedException(final String message) { - super(message); - } -} diff --git a/data-prepper-plugins/saas-source-plugins/jira-source/src/main/java/org/opensearch/dataprepper/plugins/source/jira/rest/BasicAuthInterceptor.java b/data-prepper-plugins/saas-source-plugins/jira-source/src/main/java/org/opensearch/dataprepper/plugins/source/jira/rest/BasicAuthInterceptor.java deleted file mode 100644 index e3a1b992f0..0000000000 --- a/data-prepper-plugins/saas-source-plugins/jira-source/src/main/java/org/opensearch/dataprepper/plugins/source/jira/rest/BasicAuthInterceptor.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright OpenSearch Contributors - * SPDX-License-Identifier: Apache-2.0 - * - * The OpenSearch Contributors require contributions made to - * this file be licensed under the Apache-2.0 license or a - * compatible open source license. - * - */ - -package org.opensearch.dataprepper.plugins.source.jira.rest; - -import org.opensearch.dataprepper.plugins.source.jira.JiraSourceConfig; -import org.springframework.http.HttpHeaders; -import org.springframework.http.HttpRequest; -import org.springframework.http.client.ClientHttpRequestExecution; -import org.springframework.http.client.ClientHttpRequestInterceptor; -import org.springframework.http.client.ClientHttpResponse; - -import java.io.IOException; -import java.nio.charset.StandardCharsets; -import java.util.Base64; - - -public class BasicAuthInterceptor implements ClientHttpRequestInterceptor { - private final String username; - private final String password; - - public BasicAuthInterceptor(JiraSourceConfig config) { - this.username = config.getAuthenticationConfig().getBasicConfig().getUsername(); - this.password = config.getAuthenticationConfig().getBasicConfig().getPassword();; - } - - @Override - public ClientHttpResponse intercept(HttpRequest request, byte[] body, ClientHttpRequestExecution execution) throws IOException { - String auth = username + ":" + password; - byte[] encodedAuth = Base64.getEncoder().encode(auth.getBytes(StandardCharsets.US_ASCII)); - String authHeader = "Basic " + new String(encodedAuth); - request.getHeaders().set(HttpHeaders.AUTHORIZATION, authHeader); - return execution.execute(request, body); - } -} diff --git a/data-prepper-plugins/saas-source-plugins/jira-source/src/main/java/org/opensearch/dataprepper/plugins/source/jira/rest/CustomRestTemplateConfig.java b/data-prepper-plugins/saas-source-plugins/jira-source/src/main/java/org/opensearch/dataprepper/plugins/source/jira/rest/CustomRestTemplateConfig.java deleted file mode 100644 index 70cd189267..0000000000 --- a/data-prepper-plugins/saas-source-plugins/jira-source/src/main/java/org/opensearch/dataprepper/plugins/source/jira/rest/CustomRestTemplateConfig.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright OpenSearch Contributors - * SPDX-License-Identifier: Apache-2.0 - * - * The OpenSearch Contributors require contributions made to - * this file be licensed under the Apache-2.0 license or a - * compatible open source license. - * - */ - -package org.opensearch.dataprepper.plugins.source.jira.rest; - - -import org.opensearch.dataprepper.plugins.source.jira.JiraSourceConfig; -import org.opensearch.dataprepper.plugins.source.jira.rest.auth.JiraAuthConfig; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.http.client.ClientHttpRequestInterceptor; -import org.springframework.http.client.HttpComponentsClientHttpRequestFactory; -import org.springframework.web.client.RestTemplate; - -import static org.opensearch.dataprepper.plugins.source.jira.utils.Constants.OAUTH2; - -@Configuration -public class CustomRestTemplateConfig { - - @Bean - public RestTemplate basicAuthRestTemplate(JiraSourceConfig config, JiraAuthConfig authConfig) { - RestTemplate restTemplate = new RestTemplate(); - restTemplate.setRequestFactory(new HttpComponentsClientHttpRequestFactory()); - ClientHttpRequestInterceptor httpInterceptor; - if (OAUTH2.equals(config.getAuthType())) { - httpInterceptor = new OAuth2RequestInterceptor(authConfig); - } else { - httpInterceptor = new BasicAuthInterceptor(config); - } - restTemplate.getInterceptors().add(httpInterceptor); - return restTemplate; - } - - -} diff --git a/data-prepper-plugins/saas-source-plugins/jira-source/src/main/java/org/opensearch/dataprepper/plugins/source/jira/rest/JiraRestClient.java b/data-prepper-plugins/saas-source-plugins/jira-source/src/main/java/org/opensearch/dataprepper/plugins/source/jira/rest/JiraRestClient.java index 5271c6cfb5..5cb3009753 100644 --- a/data-prepper-plugins/saas-source-plugins/jira-source/src/main/java/org/opensearch/dataprepper/plugins/source/jira/rest/JiraRestClient.java +++ b/data-prepper-plugins/saas-source-plugins/jira-source/src/main/java/org/opensearch/dataprepper/plugins/source/jira/rest/JiraRestClient.java @@ -10,57 +10,46 @@ package org.opensearch.dataprepper.plugins.source.jira.rest; -import com.google.common.annotations.VisibleForTesting; import io.micrometer.core.annotation.Timed; import io.micrometer.core.instrument.Counter; import io.micrometer.core.instrument.Timer; import lombok.extern.slf4j.Slf4j; import org.opensearch.dataprepper.metrics.PluginMetrics; -import org.opensearch.dataprepper.plugins.source.jira.exception.BadRequestException; -import org.opensearch.dataprepper.plugins.source.jira.exception.UnAuthorizedException; +import org.opensearch.dataprepper.plugins.source.atlassian.rest.AtlassianRestClient; +import org.opensearch.dataprepper.plugins.source.atlassian.rest.auth.AtlassianAuthConfig; import org.opensearch.dataprepper.plugins.source.jira.models.SearchResults; -import org.opensearch.dataprepper.plugins.source.jira.rest.auth.JiraAuthConfig; -import org.opensearch.dataprepper.plugins.source.jira.utils.AddressValidation; -import org.springframework.http.HttpStatus; -import org.springframework.http.ResponseEntity; -import org.springframework.web.client.HttpClientErrorException; import org.springframework.web.client.RestTemplate; import org.springframework.web.util.UriComponentsBuilder; import javax.inject.Named; import java.net.URI; -import java.util.List; -import static org.opensearch.dataprepper.logging.DataPrepperMarkers.NOISY; -import static org.opensearch.dataprepper.plugins.source.jira.utils.Constants.RETRY_ATTEMPT; import static org.opensearch.dataprepper.plugins.source.jira.utils.JqlConstants.EXPAND_FIELD; import static org.opensearch.dataprepper.plugins.source.jira.utils.JqlConstants.EXPAND_VALUE; import static org.opensearch.dataprepper.plugins.source.jira.utils.JqlConstants.JQL_FIELD; @Slf4j @Named -public class JiraRestClient { +public class JiraRestClient extends AtlassianRestClient { public static final String REST_API_SEARCH = "rest/api/3/search"; public static final String REST_API_FETCH_ISSUE = "rest/api/3/issue"; - //public static final String REST_API_PROJECTS = "/rest/api/3/project/search"; public static final String FIFTY = "50"; public static final String START_AT = "startAt"; public static final String MAX_RESULT = "maxResults"; - public static final List RETRY_ATTEMPT_SLEEP_TIME = List.of(1, 2, 5, 10, 20, 40); private static final String TICKET_FETCH_LATENCY_TIMER = "ticketFetchLatency"; private static final String SEARCH_CALL_LATENCY_TIMER = "searchCallLatency"; private static final String PROJECTS_FETCH_LATENCY_TIMER = "projectFetchLatency"; private static final String ISSUES_REQUESTED = "issuesRequested"; - private int sleepTimeMultiplier = 1000; private final RestTemplate restTemplate; - private final JiraAuthConfig authConfig; + private final AtlassianAuthConfig authConfig; private final Timer ticketFetchLatencyTimer; private final Timer searchCallLatencyTimer; private final Timer projectFetchLatencyTimer; private final Counter issuesRequestedCounter; - public JiraRestClient(RestTemplate restTemplate, JiraAuthConfig authConfig, PluginMetrics pluginMetrics) { + public JiraRestClient(RestTemplate restTemplate, AtlassianAuthConfig authConfig, PluginMetrics pluginMetrics) { + super(restTemplate, authConfig); this.restTemplate = restTemplate; this.authConfig = authConfig; @@ -104,44 +93,4 @@ public String getIssue(String issueKey) { URI uri = UriComponentsBuilder.fromHttpUrl(url).buildAndExpand().toUri(); return invokeRestApi(uri, String.class).getBody(); } - - private ResponseEntity invokeRestApi(URI uri, Class responseType) throws BadRequestException { - AddressValidation.validateInetAddress(AddressValidation.getInetAddress(uri.toString())); - int retryCount = 0; - while (retryCount < RETRY_ATTEMPT) { - try { - return restTemplate.getForEntity(uri, responseType); - } catch (HttpClientErrorException ex) { - HttpStatus statusCode = ex.getStatusCode(); - String statusMessage = ex.getMessage(); - log.error(NOISY, "An exception has occurred while getting response from Jira search API with statusCode {} and error message: {}", statusCode, statusMessage); - if (statusCode == HttpStatus.FORBIDDEN) { - throw new UnAuthorizedException(statusMessage); - } else if (statusCode == HttpStatus.UNAUTHORIZED) { - log.warn(NOISY, "Token expired. We will try to renew the tokens now."); - authConfig.renewCredentials(); - } else if (statusCode == HttpStatus.TOO_MANY_REQUESTS || statusCode == HttpStatus.SERVICE_UNAVAILABLE || statusCode == HttpStatus.GATEWAY_TIMEOUT) { - log.error(NOISY, "Received {}. Backing off with sleep timer for {} seconds.", statusCode, RETRY_ATTEMPT_SLEEP_TIME.get(retryCount)); - } else { - log.error(NOISY, "Received an unexpected status code {} response from Jira.", statusCode, ex); - } - try { - Thread.sleep((long) RETRY_ATTEMPT_SLEEP_TIME.get(retryCount) * sleepTimeMultiplier); - } catch (InterruptedException e) { - throw new RuntimeException("Sleep in the retry attempt got interrupted."); - } - } catch (Exception ex) { - log.error(NOISY, "An exception has occurred while getting a response from the Jira search API", ex); - } - retryCount++; - } - String errorMessage = String.format("Exceeded max retry attempts. Failed to execute the Rest API call %s", uri); - log.error(errorMessage); - throw new RuntimeException(errorMessage); - } - - @VisibleForTesting - public void setSleepTimeMultiplier(int multiplier) { - sleepTimeMultiplier = multiplier; - } } diff --git a/data-prepper-plugins/saas-source-plugins/jira-source/src/main/java/org/opensearch/dataprepper/plugins/source/jira/rest/OAuth2RequestInterceptor.java b/data-prepper-plugins/saas-source-plugins/jira-source/src/main/java/org/opensearch/dataprepper/plugins/source/jira/rest/OAuth2RequestInterceptor.java deleted file mode 100644 index be71df7ac7..0000000000 --- a/data-prepper-plugins/saas-source-plugins/jira-source/src/main/java/org/opensearch/dataprepper/plugins/source/jira/rest/OAuth2RequestInterceptor.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright OpenSearch Contributors - * SPDX-License-Identifier: Apache-2.0 - * - * The OpenSearch Contributors require contributions made to - * this file be licensed under the Apache-2.0 license or a - * compatible open source license. - * - */ - -package org.opensearch.dataprepper.plugins.source.jira.rest; - -import org.opensearch.dataprepper.plugins.source.jira.rest.auth.JiraAuthConfig; -import org.opensearch.dataprepper.plugins.source.jira.rest.auth.JiraOauthConfig; -import org.springframework.http.HttpRequest; -import org.springframework.http.client.ClientHttpRequestExecution; -import org.springframework.http.client.ClientHttpRequestInterceptor; -import org.springframework.http.client.ClientHttpResponse; - -import java.io.IOException; - -public class OAuth2RequestInterceptor implements ClientHttpRequestInterceptor { - - private final JiraAuthConfig config; - - public OAuth2RequestInterceptor(JiraAuthConfig config) { - this.config = config; - } - - @Override - public ClientHttpResponse intercept(HttpRequest request, byte[] body, ClientHttpRequestExecution execution) throws IOException { - request.getHeaders().setBearerAuth(((JiraOauthConfig) config).getAccessToken()); - return execution.execute(request, body); - } - -} diff --git a/data-prepper-plugins/saas-source-plugins/jira-source/src/main/java/org/opensearch/dataprepper/plugins/source/jira/rest/auth/JiraAuthConfig.java b/data-prepper-plugins/saas-source-plugins/jira-source/src/main/java/org/opensearch/dataprepper/plugins/source/jira/rest/auth/JiraAuthConfig.java deleted file mode 100644 index cae78da954..0000000000 --- a/data-prepper-plugins/saas-source-plugins/jira-source/src/main/java/org/opensearch/dataprepper/plugins/source/jira/rest/auth/JiraAuthConfig.java +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright OpenSearch Contributors - * SPDX-License-Identifier: Apache-2.0 - * - * The OpenSearch Contributors require contributions made to - * this file be licensed under the Apache-2.0 license or a - * compatible open source license. - * - */ - -package org.opensearch.dataprepper.plugins.source.jira.rest.auth; - -/** - * The interface that defines the behaviour for Jira auth configs. - */ -public interface JiraAuthConfig { - - /** - * Returns the URL for the Jira instance. - * - * @return the URL for the Jira instance. - */ - String getUrl(); - - /** - * Initializes the credentials for the Jira instance. - */ - void initCredentials(); - - /** - * Renews the credentials for the Jira instance. - */ - void renewCredentials(); -} diff --git a/data-prepper-plugins/saas-source-plugins/jira-source/src/main/java/org/opensearch/dataprepper/plugins/source/jira/rest/auth/JiraAuthFactory.java b/data-prepper-plugins/saas-source-plugins/jira-source/src/main/java/org/opensearch/dataprepper/plugins/source/jira/rest/auth/JiraAuthFactory.java deleted file mode 100644 index f178d56812..0000000000 --- a/data-prepper-plugins/saas-source-plugins/jira-source/src/main/java/org/opensearch/dataprepper/plugins/source/jira/rest/auth/JiraAuthFactory.java +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright OpenSearch Contributors - * SPDX-License-Identifier: Apache-2.0 - * - * The OpenSearch Contributors require contributions made to - * this file be licensed under the Apache-2.0 license or a - * compatible open source license. - * - */ - -package org.opensearch.dataprepper.plugins.source.jira.rest.auth; - -import org.opensearch.dataprepper.plugins.source.jira.JiraSourceConfig; -import org.springframework.beans.factory.FactoryBean; -import org.springframework.context.annotation.Configuration; - -import static org.opensearch.dataprepper.plugins.source.jira.utils.Constants.OAUTH2; - -@Configuration -public class JiraAuthFactory implements FactoryBean { - - private final JiraSourceConfig sourceConfig; - - public JiraAuthFactory(JiraSourceConfig sourceConfig) { - this.sourceConfig = sourceConfig; - } - - @Override - public JiraAuthConfig getObject() { - String authType = sourceConfig.getAuthType(); - if (OAUTH2.equals(authType)) { - return new JiraOauthConfig(sourceConfig); - } - return new JiraBasicAuthConfig(sourceConfig); - } - - @Override - public Class getObjectType() { - return JiraAuthConfig.class; - } -} diff --git a/data-prepper-plugins/saas-source-plugins/jira-source/src/main/java/org/opensearch/dataprepper/plugins/source/jira/rest/auth/JiraBasicAuthConfig.java b/data-prepper-plugins/saas-source-plugins/jira-source/src/main/java/org/opensearch/dataprepper/plugins/source/jira/rest/auth/JiraBasicAuthConfig.java deleted file mode 100644 index 32509a2229..0000000000 --- a/data-prepper-plugins/saas-source-plugins/jira-source/src/main/java/org/opensearch/dataprepper/plugins/source/jira/rest/auth/JiraBasicAuthConfig.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright OpenSearch Contributors - * SPDX-License-Identifier: Apache-2.0 - * - * The OpenSearch Contributors require contributions made to - * this file be licensed under the Apache-2.0 license or a - * compatible open source license. - * - */ - -package org.opensearch.dataprepper.plugins.source.jira.rest.auth; - - -import org.opensearch.dataprepper.plugins.source.jira.JiraSourceConfig; - -public class JiraBasicAuthConfig implements JiraAuthConfig { - - private final JiraSourceConfig jiraSourceConfig; - private String accountUrl; - - public JiraBasicAuthConfig(JiraSourceConfig jiraSourceConfig) { - this.jiraSourceConfig = jiraSourceConfig; - accountUrl = jiraSourceConfig.getAccountUrl(); - if (!accountUrl.endsWith("/")) { - accountUrl += "/"; - } - } - - @Override - public String getUrl() { - return accountUrl; - } - - @Override - public void initCredentials() { - //do nothing for basic authentication - } - - @Override - public void renewCredentials() { - //do nothing for basic authentication - } - - -} diff --git a/data-prepper-plugins/saas-source-plugins/jira-source/src/main/java/org/opensearch/dataprepper/plugins/source/jira/rest/auth/JiraOauthConfig.java b/data-prepper-plugins/saas-source-plugins/jira-source/src/main/java/org/opensearch/dataprepper/plugins/source/jira/rest/auth/JiraOauthConfig.java deleted file mode 100644 index 9640ba3818..0000000000 --- a/data-prepper-plugins/saas-source-plugins/jira-source/src/main/java/org/opensearch/dataprepper/plugins/source/jira/rest/auth/JiraOauthConfig.java +++ /dev/null @@ -1,184 +0,0 @@ -/* - * Copyright OpenSearch Contributors - * SPDX-License-Identifier: Apache-2.0 - * - * The OpenSearch Contributors require contributions made to - * this file be licensed under the Apache-2.0 license or a - * compatible open source license. - * - */ - -package org.opensearch.dataprepper.plugins.source.jira.rest.auth; - -import lombok.Getter; -import org.opensearch.dataprepper.plugins.source.jira.JiraSourceConfig; -import org.opensearch.dataprepper.plugins.source.jira.configuration.Oauth2Config; -import org.opensearch.dataprepper.plugins.source.jira.exception.UnAuthorizedException; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.http.HttpEntity; -import org.springframework.http.HttpHeaders; -import org.springframework.http.HttpMethod; -import org.springframework.http.HttpStatus; -import org.springframework.http.MediaType; -import org.springframework.http.ResponseEntity; -import org.springframework.util.StringUtils; -import org.springframework.web.client.HttpClientErrorException; -import org.springframework.web.client.RestTemplate; - -import java.time.Instant; -import java.util.List; -import java.util.Map; - -import static org.opensearch.dataprepper.plugins.source.jira.utils.Constants.RETRY_ATTEMPT; -import static org.opensearch.dataprepper.plugins.source.jira.utils.JqlConstants.SLASH; - -/** - * The type Jira service. - */ - -public class JiraOauthConfig implements JiraAuthConfig { - - public static final String OAuth2_URL = "https://api.atlassian.com/ex/jira/"; - public static final String ACCESSIBLE_RESOURCES = "https://api.atlassian.com/oauth/token/accessible-resources"; - public static final String TOKEN_LOCATION = "https://auth.atlassian.com/oauth/token"; - - public static final String EXPIRES_IN = "expires_in"; - public static final String REFRESH_TOKEN = "refresh_token"; - public static final String ACCESS_TOKEN = "access_token"; - private static final Logger log = LoggerFactory.getLogger(JiraOauthConfig.class); - private final String clientId; - private final String clientSecret; - private final JiraSourceConfig jiraSourceConfig; - private final Object cloudIdFetchLock = new Object(); - private final Object tokenRenewLock = new Object(); - RestTemplate restTemplate = new RestTemplate(); - private String url; - @Getter - private int expiresInSeconds = 0; - @Getter - private Instant expireTime = Instant.ofEpochMilli(0); - @Getter - private String accessToken; - @Getter - private String refreshToken; - private String cloudId = null; - - public JiraOauthConfig(JiraSourceConfig jiraSourceConfig) { - this.jiraSourceConfig = jiraSourceConfig; - this.accessToken = (String) jiraSourceConfig.getAuthenticationConfig().getOauth2Config() - .getAccessToken().getValue(); - this.refreshToken = (String) jiraSourceConfig.getAuthenticationConfig() - .getOauth2Config().getRefreshToken().getValue(); - this.clientId = jiraSourceConfig.getAuthenticationConfig().getOauth2Config().getClientId(); - this.clientSecret = jiraSourceConfig.getAuthenticationConfig().getOauth2Config().getClientSecret(); - } - - public String getJiraAccountCloudId() { - log.info("Getting Jira Account Cloud ID"); - synchronized (cloudIdFetchLock) { - if (this.cloudId != null) { - //Someone else must have initialized it - return this.cloudId; - } - - int retryCount = 0; - while (retryCount < RETRY_ATTEMPT) { - retryCount++; - try { - HttpHeaders headers = new HttpHeaders(); - headers.setBearerAuth(accessToken); - headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED); - HttpEntity entity = new HttpEntity<>(headers); - ResponseEntity exchangeResponse = - restTemplate.exchange(ACCESSIBLE_RESOURCES, HttpMethod.GET, entity, Object.class); - List> listResponse = (List>) exchangeResponse.getBody(); - Map response = listResponse.get(0); - this.cloudId = (String) response.get("id"); - return this.cloudId; - } catch (HttpClientErrorException e) { - if (e.getRawStatusCode() == HttpStatus.UNAUTHORIZED.value()) { - renewCredentials(); - } - log.error("Error occurred while accessing resources. Status code: {}. Error message: {}", e.getStatusCode(), e.getMessage()); - } - } - throw new UnAuthorizedException(String.format("Access token expired. Unable to renew even after %s attempts", RETRY_ATTEMPT)); - } - } - - public void renewCredentials() { - Instant currentTime = Instant.now(); - if (expireTime.isAfter(currentTime)) { - //There is still time to renew or someone else must have already renewed it - return; - } - - synchronized (tokenRenewLock) { - if (expireTime.isAfter(currentTime)) { - //Someone else must have already renewed it - return; - } - - log.info("Renewing access token and refresh token pair for Jira Connector."); - HttpHeaders headers = new HttpHeaders(); - headers.setContentType(MediaType.APPLICATION_JSON); - String payloadTemplate = "{\"grant_type\": \"%s\", \"client_id\": \"%s\", \"client_secret\": \"%s\", \"refresh_token\": \"%s\"}"; - String payload = String.format(payloadTemplate, "refresh_token", clientId, clientSecret, refreshToken); - HttpEntity entity = new HttpEntity<>(payload, headers); - - Oauth2Config oauth2Config = jiraSourceConfig.getAuthenticationConfig().getOauth2Config(); - try { - ResponseEntity responseEntity = restTemplate.postForEntity(TOKEN_LOCATION, entity, Map.class); - Map oauthClientResponse = responseEntity.getBody(); - this.accessToken = (String) oauthClientResponse.get(ACCESS_TOKEN); - this.refreshToken = (String) oauthClientResponse.get(REFRESH_TOKEN); - this.expiresInSeconds = (int) oauthClientResponse.get(EXPIRES_IN); - this.expireTime = Instant.now().plusSeconds(expiresInSeconds); - // updating config object's PluginConfigVariable so that it updates the underlying Secret store - oauth2Config.getAccessToken().setValue(this.accessToken); - oauth2Config.getRefreshToken().setValue(this.refreshToken); - log.info("Access Token and Refresh Token pair is now refreshed. Corresponding Secret store key updated."); - } catch (HttpClientErrorException ex) { - this.expireTime = Instant.ofEpochMilli(0); - this.expiresInSeconds = 0; - HttpStatus statusCode = ex.getStatusCode(); - log.error("Failed to renew access token. Status code: {}, Error Message: {}", - statusCode, ex.getMessage()); - if (statusCode == HttpStatus.FORBIDDEN || statusCode == HttpStatus.UNAUTHORIZED) { - log.info("Trying to refresh the secrets"); - // Refreshing the secrets. It should help if someone already renewed the tokens. - // Refreshing one of the secret refreshes the entire store so triggering refresh on just one - oauth2Config.getAccessToken().refresh(); - this.accessToken = (String) oauth2Config.getAccessToken().getValue(); - this.refreshToken = (String) oauth2Config.getRefreshToken().getValue(); - this.expireTime = Instant.now().plusSeconds(10); - log.info("Access Token and Refresh Token pair is now refreshed."); - } - throw new RuntimeException("Failed to renew access token message:" + ex.getMessage(), ex); - } - } - } - - @Override - public String getUrl() { - if (!StringUtils.hasLength(url)) { - synchronized (cloudIdFetchLock) { - if (!StringUtils.hasLength(url)) { - initCredentials(); - } - } - } - return url; - } - - /** - * Method for getting Jira url based on auth type. - */ - @Override - public void initCredentials() { - //For OAuth based flow, we use a different Jira url - this.cloudId = getJiraAccountCloudId(); - this.url = OAuth2_URL + this.cloudId + SLASH; - } -} diff --git a/data-prepper-plugins/saas-source-plugins/jira-source/src/main/java/org/opensearch/dataprepper/plugins/source/jira/utils/AddressValidation.java b/data-prepper-plugins/saas-source-plugins/jira-source/src/main/java/org/opensearch/dataprepper/plugins/source/jira/utils/AddressValidation.java index 57a6c80aff..6dcf32f4a1 100644 --- a/data-prepper-plugins/saas-source-plugins/jira-source/src/main/java/org/opensearch/dataprepper/plugins/source/jira/utils/AddressValidation.java +++ b/data-prepper-plugins/saas-source-plugins/jira-source/src/main/java/org/opensearch/dataprepper/plugins/source/jira/utils/AddressValidation.java @@ -12,7 +12,7 @@ import lombok.NonNull; import lombok.extern.slf4j.Slf4j; -import org.opensearch.dataprepper.plugins.source.jira.exception.BadRequestException; +import org.opensearch.dataprepper.plugins.source.source_crawler.exception.BadRequestException; import java.net.InetAddress; import java.net.MalformedURLException; diff --git a/data-prepper-plugins/saas-source-plugins/jira-source/src/test/java/org/opensearch/dataprepper/plugins/source/jira/JiraConfigHelperTest.java b/data-prepper-plugins/saas-source-plugins/jira-source/src/test/java/org/opensearch/dataprepper/plugins/source/jira/JiraConfigHelperTest.java index ceadbaf65b..960027c659 100644 --- a/data-prepper-plugins/saas-source-plugins/jira-source/src/test/java/org/opensearch/dataprepper/plugins/source/jira/JiraConfigHelperTest.java +++ b/data-prepper-plugins/saas-source-plugins/jira-source/src/test/java/org/opensearch/dataprepper/plugins/source/jira/JiraConfigHelperTest.java @@ -15,12 +15,12 @@ import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; import org.opensearch.dataprepper.model.plugin.PluginConfigVariable; -import org.opensearch.dataprepper.plugins.source.jira.configuration.AuthenticationConfig; -import org.opensearch.dataprepper.plugins.source.jira.configuration.BasicConfig; +import org.opensearch.dataprepper.plugins.source.atlassian.configuration.AuthenticationConfig; +import org.opensearch.dataprepper.plugins.source.atlassian.configuration.BasicConfig; +import org.opensearch.dataprepper.plugins.source.atlassian.configuration.Oauth2Config; import org.opensearch.dataprepper.plugins.source.jira.configuration.FilterConfig; import org.opensearch.dataprepper.plugins.source.jira.configuration.IssueTypeConfig; import org.opensearch.dataprepper.plugins.source.jira.configuration.NameConfig; -import org.opensearch.dataprepper.plugins.source.jira.configuration.Oauth2Config; import org.opensearch.dataprepper.plugins.source.jira.configuration.ProjectConfig; import org.opensearch.dataprepper.plugins.source.jira.configuration.StatusConfig; import org.opensearch.dataprepper.plugins.source.jira.utils.JiraConfigHelper; diff --git a/data-prepper-plugins/saas-source-plugins/jira-source/src/test/java/org/opensearch/dataprepper/plugins/source/jira/JiraServiceTest.java b/data-prepper-plugins/saas-source-plugins/jira-source/src/test/java/org/opensearch/dataprepper/plugins/source/jira/JiraServiceTest.java index 80b5c50c71..5eb4230e4a 100644 --- a/data-prepper-plugins/saas-source-plugins/jira-source/src/test/java/org/opensearch/dataprepper/plugins/source/jira/JiraServiceTest.java +++ b/data-prepper-plugins/saas-source-plugins/jira-source/src/test/java/org/opensearch/dataprepper/plugins/source/jira/JiraServiceTest.java @@ -19,9 +19,9 @@ import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; import org.opensearch.dataprepper.metrics.PluginMetrics; +import org.opensearch.dataprepper.model.plugin.InvalidPluginConfigurationException; import org.opensearch.dataprepper.model.plugin.PluginConfigVariable; -import org.opensearch.dataprepper.plugins.source.jira.configuration.Oauth2Config; -import org.opensearch.dataprepper.plugins.source.jira.exception.BadRequestException; +import org.opensearch.dataprepper.plugins.source.atlassian.configuration.Oauth2Config; import org.opensearch.dataprepper.plugins.source.jira.models.IssueBean; import org.opensearch.dataprepper.plugins.source.jira.models.SearchResults; import org.opensearch.dataprepper.plugins.source.jira.rest.JiraRestClient; @@ -55,7 +55,7 @@ import static org.mockito.Mockito.mock; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.when; -import static org.opensearch.dataprepper.plugins.source.jira.rest.auth.JiraOauthConfig.ACCESSIBLE_RESOURCES; +import static org.opensearch.dataprepper.plugins.source.atlassian.rest.auth.AtlassianOauthConfig.ACCESSIBLE_RESOURCES; import static org.opensearch.dataprepper.plugins.source.jira.utils.Constants.BASIC; import static org.opensearch.dataprepper.plugins.source.jira.utils.Constants.CREATED; import static org.opensearch.dataprepper.plugins.source.jira.utils.Constants.KEY; @@ -258,7 +258,8 @@ public void testBadProjectKeys() throws JsonProcessingException { Instant timestamp = Instant.ofEpochSecond(0); Queue itemInfoQueue = new ConcurrentLinkedQueue<>(); - assertThrows(BadRequestException.class, () -> jiraService.getJiraEntities(jiraSourceConfig, timestamp, itemInfoQueue)); + assertThrows(InvalidPluginConfigurationException.class, + () -> jiraService.getJiraEntities(jiraSourceConfig, timestamp, itemInfoQueue)); } @Test diff --git a/data-prepper-plugins/saas-source-plugins/jira-source/src/test/java/org/opensearch/dataprepper/plugins/source/jira/JiraSourceConfigTest.java b/data-prepper-plugins/saas-source-plugins/jira-source/src/test/java/org/opensearch/dataprepper/plugins/source/jira/JiraSourceConfigTest.java index 94aa04c554..3202ef87c3 100644 --- a/data-prepper-plugins/saas-source-plugins/jira-source/src/test/java/org/opensearch/dataprepper/plugins/source/jira/JiraSourceConfigTest.java +++ b/data-prepper-plugins/saas-source-plugins/jira-source/src/test/java/org/opensearch/dataprepper/plugins/source/jira/JiraSourceConfigTest.java @@ -13,7 +13,7 @@ import com.fasterxml.jackson.databind.ObjectMapper; import org.junit.jupiter.api.Test; import org.opensearch.dataprepper.model.plugin.PluginConfigVariable; -import org.opensearch.dataprepper.plugins.source.jira.configuration.Oauth2Config; +import org.opensearch.dataprepper.plugins.source.atlassian.configuration.Oauth2Config; import org.opensearch.dataprepper.plugins.source.jira.utils.MockPluginConfigVariableImpl; import org.opensearch.dataprepper.test.helper.ReflectivelySetField; @@ -28,6 +28,7 @@ import static org.opensearch.dataprepper.plugins.source.jira.utils.Constants.OAUTH2; public class JiraSourceConfigTest { + private JiraSourceConfig jiraSourceConfig; private final PluginConfigVariable accessToken = new MockPluginConfigVariableImpl("access token test"); private final PluginConfigVariable refreshToken = new MockPluginConfigVariableImpl("refresh token test"); private final String clientId = "client id test"; @@ -38,7 +39,6 @@ public class JiraSourceConfigTest { private final List projectList = new ArrayList<>(); private final List issueTypeList = new ArrayList<>(); private final List statusList = new ArrayList<>(); - private JiraSourceConfig jiraSourceConfig; private JiraSourceConfig createJiraSourceConfig(String authtype, boolean hasToken) throws Exception { PluginConfigVariable pcvAccessToken = null; @@ -134,4 +134,10 @@ void testFetchGivenOauthAtrribute() throws Exception { assertEquals(clientId, jiraSourceConfig.getAuthenticationConfig().getOauth2Config().getClientId()); assertEquals(clientSecret, jiraSourceConfig.getAuthenticationConfig().getOauth2Config().getClientSecret()); } + + @Test + void testGetOauth2UrlContext() throws Exception { + jiraSourceConfig = createJiraSourceConfig(OAUTH2, false); + assertEquals("jira", jiraSourceConfig.getOauth2UrlContext()); + } } diff --git a/data-prepper-plugins/saas-source-plugins/jira-source/src/test/java/org/opensearch/dataprepper/plugins/source/jira/JiraSourceTest.java b/data-prepper-plugins/saas-source-plugins/jira-source/src/test/java/org/opensearch/dataprepper/plugins/source/jira/JiraSourceTest.java index 725c91b66e..b8322f5873 100644 --- a/data-prepper-plugins/saas-source-plugins/jira-source/src/test/java/org/opensearch/dataprepper/plugins/source/jira/JiraSourceTest.java +++ b/data-prepper-plugins/saas-source-plugins/jira-source/src/test/java/org/opensearch/dataprepper/plugins/source/jira/JiraSourceTest.java @@ -21,9 +21,9 @@ import org.opensearch.dataprepper.model.plugin.PluginFactory; import org.opensearch.dataprepper.model.record.Record; import org.opensearch.dataprepper.model.source.coordinator.enhanced.EnhancedSourceCoordinator; -import org.opensearch.dataprepper.plugins.source.jira.configuration.AuthenticationConfig; -import org.opensearch.dataprepper.plugins.source.jira.configuration.BasicConfig; -import org.opensearch.dataprepper.plugins.source.jira.rest.auth.JiraAuthConfig; +import org.opensearch.dataprepper.plugins.source.atlassian.configuration.AuthenticationConfig; +import org.opensearch.dataprepper.plugins.source.atlassian.configuration.BasicConfig; +import org.opensearch.dataprepper.plugins.source.atlassian.rest.auth.AtlassianAuthConfig; import org.opensearch.dataprepper.plugins.source.source_crawler.base.Crawler; import org.opensearch.dataprepper.plugins.source.source_crawler.base.PluginExecutorServiceProvider; @@ -35,48 +35,37 @@ import static org.mockito.Mockito.never; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; -import static org.opensearch.dataprepper.plugins.source.jira.rest.auth.JiraOauthConfig.ACCESSIBLE_RESOURCES; +import static org.opensearch.dataprepper.plugins.source.atlassian.rest.auth.AtlassianOauthConfig.ACCESSIBLE_RESOURCES; import static org.opensearch.dataprepper.plugins.source.jira.utils.Constants.BASIC; @ExtendWith(MockitoExtension.class) public class JiraSourceTest { + @Mock + Buffer> buffer; + @Mock + AuthenticationConfig authenticationConfig; + @Mock + BasicConfig basicConfig; @Mock private PluginMetrics pluginMetrics; - @Mock private JiraSourceConfig jiraSourceConfig; - @Mock - private JiraAuthConfig jiraOauthConfig; - + private AtlassianAuthConfig jiraOauthConfig; @Mock private PluginFactory pluginFactory; - @Mock private AcknowledgementSetManager acknowledgementSetManager; - @Mock private Crawler crawler; - @Mock private EnhancedSourceCoordinator sourceCooridinator; - - @Mock - Buffer> buffer; - @Mock private PluginExecutorServiceProvider executorServiceProvider; - @Mock private ExecutorService executorService; - @Mock - AuthenticationConfig authenticationConfig; - - @Mock - BasicConfig basicConfig; - @Test void initialization() { when(executorServiceProvider.get()).thenReturn(executorService); diff --git a/data-prepper-plugins/saas-source-plugins/jira-source/src/test/java/org/opensearch/dataprepper/plugins/source/jira/exception/BadRequestExceptionTest.java b/data-prepper-plugins/saas-source-plugins/jira-source/src/test/java/org/opensearch/dataprepper/plugins/source/jira/exception/BadRequestExceptionTest.java deleted file mode 100644 index 91578ec810..0000000000 --- a/data-prepper-plugins/saas-source-plugins/jira-source/src/test/java/org/opensearch/dataprepper/plugins/source/jira/exception/BadRequestExceptionTest.java +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright OpenSearch Contributors - * SPDX-License-Identifier: Apache-2.0 - * - * The OpenSearch Contributors require contributions made to - * this file be licensed under the Apache-2.0 license or a - * compatible open source license. - * - */ - -package org.opensearch.dataprepper.plugins.source.jira.exception; - -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Nested; -import org.junit.jupiter.api.Test; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNull; -import static org.mockito.Mockito.mock; - -public class BadRequestExceptionTest { - private String message; - private Throwable throwable; - - @BeforeEach - void setUp() { - message = "Bad Request"; - throwable = mock(Throwable.class); - } - - @Nested - class MessageOnlyConstructor { - private BadRequestException createObjectUnderTest() { - return new BadRequestException(message); - } - - @Test - void getMessage_returns_message() { - assertEquals(createObjectUnderTest().getMessage(), message); - } - - @Test - void getCause_returns_null() { - assertNull(createObjectUnderTest().getCause()); - } - } - - @Nested - class MessageThrowableConstructor { - private BadRequestException createObjectUnderTest() { - return new BadRequestException(message, throwable); - } - - @Test - void getMessage_returns_message() { - assertEquals(createObjectUnderTest().getMessage(), message); - } - - @Test - void getCause_returns_throwable() { - assertEquals(createObjectUnderTest().getCause(), throwable); - } - } -} diff --git a/data-prepper-plugins/saas-source-plugins/jira-source/src/test/java/org/opensearch/dataprepper/plugins/source/jira/exception/UnAuthorizedExceptionTest.java b/data-prepper-plugins/saas-source-plugins/jira-source/src/test/java/org/opensearch/dataprepper/plugins/source/jira/exception/UnAuthorizedExceptionTest.java deleted file mode 100644 index 87c06051e1..0000000000 --- a/data-prepper-plugins/saas-source-plugins/jira-source/src/test/java/org/opensearch/dataprepper/plugins/source/jira/exception/UnAuthorizedExceptionTest.java +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright OpenSearch Contributors - * SPDX-License-Identifier: Apache-2.0 - * - * The OpenSearch Contributors require contributions made to - * this file be licensed under the Apache-2.0 license or a - * compatible open source license. - * - */ - -package org.opensearch.dataprepper.plugins.source.jira.exception; - -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Nested; -import org.junit.jupiter.api.Test; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNull; -import static org.mockito.Mockito.mock; - -public class UnAuthorizedExceptionTest { - private String message; - private Throwable throwable; - - @BeforeEach - void setUp() { - message = "UnAuthorized Exception"; - throwable = mock(Throwable.class); - } - - @Nested - class MessageOnlyConstructor { - private UnAuthorizedException createObjectUnderTest() { - return new UnAuthorizedException(message); - } - - @Test - void getMessage_returns_message() { - assertEquals(createObjectUnderTest().getMessage(), message); - } - - @Test - void getCause_returns_null() { - assertNull(createObjectUnderTest().getCause()); - } - } - - @Nested - class MessageThrowableConstructor { - private UnAuthorizedException createObjectUnderTest() { - return new UnAuthorizedException(message, throwable); - } - - @Test - void getMessage_returns_message() { - assertEquals(createObjectUnderTest().getMessage(), message); - } - - @Test - void getCause_returns_throwable() { - assertEquals(createObjectUnderTest().getCause(), throwable); - } - } -} diff --git a/data-prepper-plugins/saas-source-plugins/jira-source/src/test/java/org/opensearch/dataprepper/plugins/source/jira/rest/BasicAuthInterceptorTest.java b/data-prepper-plugins/saas-source-plugins/jira-source/src/test/java/org/opensearch/dataprepper/plugins/source/jira/rest/BasicAuthInterceptorTest.java deleted file mode 100644 index a57b879d6d..0000000000 --- a/data-prepper-plugins/saas-source-plugins/jira-source/src/test/java/org/opensearch/dataprepper/plugins/source/jira/rest/BasicAuthInterceptorTest.java +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Copyright OpenSearch Contributors - * SPDX-License-Identifier: Apache-2.0 - * - * The OpenSearch Contributors require contributions made to - * this file be licensed under the Apache-2.0 license or a - * compatible open source license. - * - */ - -package org.opensearch.dataprepper.plugins.source.jira.rest; - -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.mockito.Mock; -import org.mockito.junit.jupiter.MockitoExtension; -import org.opensearch.dataprepper.plugins.source.jira.JiraSourceConfig; -import org.opensearch.dataprepper.plugins.source.jira.configuration.AuthenticationConfig; -import org.opensearch.dataprepper.plugins.source.jira.configuration.BasicConfig; -import org.springframework.http.HttpHeaders; -import org.springframework.http.HttpRequest; -import org.springframework.http.client.ClientHttpRequestExecution; -import org.springframework.http.client.ClientHttpResponse; - -import java.io.IOException; -import java.util.Base64; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.argThat; -import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -@ExtendWith(MockitoExtension.class) -public class BasicAuthInterceptorTest { - - @Mock - private HttpRequest mockRequest; - - @Mock - private ClientHttpRequestExecution mockExecution; - - @Mock - private ClientHttpResponse mockResponse; - - @Mock - private JiraSourceConfig mockConfig; - - @Mock - AuthenticationConfig authenticationConfig; - - @Mock - BasicConfig basicConfig; - - @Mock - private HttpHeaders mockHeaders; - - private BasicAuthInterceptor interceptor; - - @BeforeEach - void setUp() { - when(mockConfig.getAuthenticationConfig()).thenReturn(authenticationConfig); - when(authenticationConfig.getBasicConfig()).thenReturn(basicConfig); - when(basicConfig.getUsername()).thenReturn("testUser"); - when(basicConfig.getPassword()).thenReturn("testPassword"); - when(mockRequest.getHeaders()).thenReturn(mockHeaders); - interceptor = new BasicAuthInterceptor(mockConfig); - } - - @Test - void testInterceptAddsAuthorizationHeader() throws IOException { - when(mockExecution.execute(any(HttpRequest.class), any(byte[].class))).thenReturn(mockResponse); - - ClientHttpResponse response = interceptor.intercept(mockRequest, new byte[0], mockExecution); - - verify(mockHeaders).set(eq(HttpHeaders.AUTHORIZATION), argThat(value -> - value.startsWith("Basic ") && - new String(Base64.getDecoder().decode(value.substring(6))).equals("testUser:testPassword") - )); - assertEquals(mockResponse, response); - } - -} diff --git a/data-prepper-plugins/saas-source-plugins/jira-source/src/test/java/org/opensearch/dataprepper/plugins/source/jira/rest/CustomRestTemplateConfigTest.java b/data-prepper-plugins/saas-source-plugins/jira-source/src/test/java/org/opensearch/dataprepper/plugins/source/jira/rest/CustomRestTemplateConfigTest.java deleted file mode 100644 index 1f620c822a..0000000000 --- a/data-prepper-plugins/saas-source-plugins/jira-source/src/test/java/org/opensearch/dataprepper/plugins/source/jira/rest/CustomRestTemplateConfigTest.java +++ /dev/null @@ -1,105 +0,0 @@ -/* - * Copyright OpenSearch Contributors - * SPDX-License-Identifier: Apache-2.0 - * - * The OpenSearch Contributors require contributions made to - * this file be licensed under the Apache-2.0 license or a - * compatible open source license. - * - */ - -package org.opensearch.dataprepper.plugins.source.jira.rest; - -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.extension.ExtendWith; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.Arguments; -import org.junit.jupiter.params.provider.MethodSource; -import org.mockito.Mock; -import org.mockito.junit.jupiter.MockitoExtension; -import org.opensearch.dataprepper.model.plugin.PluginConfigVariable; -import org.opensearch.dataprepper.plugins.source.jira.JiraSourceConfig; -import org.opensearch.dataprepper.plugins.source.jira.configuration.AuthenticationConfig; -import org.opensearch.dataprepper.plugins.source.jira.configuration.BasicConfig; -import org.opensearch.dataprepper.plugins.source.jira.configuration.Oauth2Config; -import org.opensearch.dataprepper.plugins.source.jira.rest.auth.JiraAuthConfig; -import org.springframework.http.client.ClientHttpRequestInterceptor; -import org.springframework.http.client.InterceptingClientHttpRequestFactory; -import org.springframework.web.client.RestTemplate; - -import java.util.List; -import java.util.stream.Stream; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertInstanceOf; -import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.mockito.Mockito.lenient; -import static org.mockito.Mockito.when; -import static org.opensearch.dataprepper.plugins.source.jira.utils.Constants.BASIC; -import static org.opensearch.dataprepper.plugins.source.jira.utils.Constants.OAUTH2; - -@ExtendWith(MockitoExtension.class) -class CustomRestTemplateConfigTest { - - private CustomRestTemplateConfig config; - - @Mock - private JiraSourceConfig mockSourceConfig; - - @Mock - private JiraAuthConfig mockAuthConfig; - - @Mock - private BasicConfig mockBasicConfig; - - @Mock - private Oauth2Config mockOauth2Config; - - @Mock - private PluginConfigVariable accessTokenPluginConfigVariable; - - @Mock - private PluginConfigVariable refreshTokenPluginConfigVariable; - - @Mock - private AuthenticationConfig mockAuthenticationConfig; - - private static Stream provideAuthTypeAndExpectedInterceptorType() { - return Stream.of( - Arguments.of(OAUTH2, OAuth2RequestInterceptor.class), - Arguments.of(BASIC, BasicAuthInterceptor.class), - Arguments.of("Default", BasicAuthInterceptor.class), - Arguments.of(null, BasicAuthInterceptor.class) - ); - } - - @BeforeEach - void setUp() { - config = new CustomRestTemplateConfig(); - } - - @ParameterizedTest - @MethodSource("provideAuthTypeAndExpectedInterceptorType") - void testBasicAuthRestTemplateWithOAuth2(String authType, Class interceptorClassType) { - when(mockSourceConfig.getAuthType()).thenReturn(authType); - lenient().when(mockSourceConfig.getAuthenticationConfig()).thenReturn(mockAuthenticationConfig); - lenient().when(mockAuthenticationConfig.getOauth2Config()).thenReturn(mockOauth2Config); - lenient().when(mockOauth2Config.getAccessToken()).thenReturn(accessTokenPluginConfigVariable); - lenient().when(mockOauth2Config.getRefreshToken()).thenReturn(refreshTokenPluginConfigVariable); - lenient().when(accessTokenPluginConfigVariable.getValue()).thenReturn("accessToken"); - lenient().when(mockOauth2Config.getClientId()).thenReturn("clientId"); - lenient().when(mockOauth2Config.getClientSecret()).thenReturn("clientSecret"); - lenient().when(mockAuthenticationConfig.getBasicConfig()).thenReturn(mockBasicConfig); - lenient().when(mockBasicConfig.getUsername()).thenReturn("username"); - lenient().when(mockBasicConfig.getPassword()).thenReturn("password"); - - RestTemplate restTemplate = config.basicAuthRestTemplate(mockSourceConfig, mockAuthConfig); - assertNotNull(restTemplate); - assertInstanceOf(InterceptingClientHttpRequestFactory.class, restTemplate.getRequestFactory()); - List interceptors = restTemplate.getInterceptors(); - assertEquals(1, interceptors.size()); - assertInstanceOf(interceptorClassType, interceptors.get(0)); - } - -} - diff --git a/data-prepper-plugins/saas-source-plugins/jira-source/src/test/java/org/opensearch/dataprepper/plugins/source/jira/rest/JiraRestClientTest.java b/data-prepper-plugins/saas-source-plugins/jira-source/src/test/java/org/opensearch/dataprepper/plugins/source/jira/rest/JiraRestClientTest.java index a24b582e97..ada6d8b059 100644 --- a/data-prepper-plugins/saas-source-plugins/jira-source/src/test/java/org/opensearch/dataprepper/plugins/source/jira/rest/JiraRestClientTest.java +++ b/data-prepper-plugins/saas-source-plugins/jira-source/src/test/java/org/opensearch/dataprepper/plugins/source/jira/rest/JiraRestClientTest.java @@ -20,13 +20,13 @@ import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; import org.opensearch.dataprepper.metrics.PluginMetrics; +import org.opensearch.dataprepper.plugins.source.atlassian.rest.auth.AtlassianAuthConfig; +import org.opensearch.dataprepper.plugins.source.atlassian.rest.auth.AtlassianAuthFactory; import org.opensearch.dataprepper.plugins.source.jira.JiraServiceTest; import org.opensearch.dataprepper.plugins.source.jira.JiraSourceConfig; -import org.opensearch.dataprepper.plugins.source.jira.exception.BadRequestException; -import org.opensearch.dataprepper.plugins.source.jira.exception.UnAuthorizedException; import org.opensearch.dataprepper.plugins.source.jira.models.SearchResults; -import org.opensearch.dataprepper.plugins.source.jira.rest.auth.JiraAuthConfig; -import org.opensearch.dataprepper.plugins.source.jira.rest.auth.JiraAuthFactory; +import org.opensearch.dataprepper.plugins.source.source_crawler.exception.BadRequestException; +import org.opensearch.dataprepper.plugins.source.source_crawler.exception.UnauthorizedException; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.web.client.HttpClientErrorException; @@ -55,12 +55,12 @@ public class JiraRestClientTest { private RestTemplate restTemplate; @Mock - private JiraAuthConfig authConfig; + private AtlassianAuthConfig authConfig; private final PluginMetrics pluginMetrics = PluginMetrics.fromNames("JiraRestClientTest", "jira"); private static Stream provideHttpStatusCodesWithExceptionClass() { return Stream.of( - Arguments.of(HttpStatus.FORBIDDEN, UnAuthorizedException.class), + Arguments.of(HttpStatus.FORBIDDEN, UnauthorizedException.class), Arguments.of(HttpStatus.UNAUTHORIZED, RuntimeException.class), Arguments.of(HttpStatus.TOO_MANY_REQUESTS, RuntimeException.class), Arguments.of(HttpStatus.INSUFFICIENT_STORAGE, RuntimeException.class) @@ -73,7 +73,7 @@ public void testFetchingJiraIssue(String configFileName) { String exampleTicketResponse = "{\"id\":\"123\",\"key\":\"key\",\"self\":\"https://example.com/rest/api/2/issue/123\"}"; doReturn(new ResponseEntity<>(exampleTicketResponse, HttpStatus.OK)).when(restTemplate).getForEntity(any(URI.class), any(Class.class)); JiraSourceConfig jiraSourceConfig = JiraServiceTest.createJiraConfigurationFromYaml(configFileName); - JiraAuthConfig authConfig = new JiraAuthFactory(jiraSourceConfig).getObject(); + AtlassianAuthConfig authConfig = new AtlassianAuthFactory(jiraSourceConfig).getObject(); JiraRestClient jiraRestClient = new JiraRestClient(restTemplate, authConfig, pluginMetrics); String ticketDetails = jiraRestClient.getIssue("key"); assertEquals(exampleTicketResponse, ticketDetails); diff --git a/data-prepper-plugins/saas-source-plugins/jira-source/src/test/java/org/opensearch/dataprepper/plugins/source/jira/rest/OAuth2RequestInterceptorTest.java b/data-prepper-plugins/saas-source-plugins/jira-source/src/test/java/org/opensearch/dataprepper/plugins/source/jira/rest/OAuth2RequestInterceptorTest.java deleted file mode 100644 index 01e850fec9..0000000000 --- a/data-prepper-plugins/saas-source-plugins/jira-source/src/test/java/org/opensearch/dataprepper/plugins/source/jira/rest/OAuth2RequestInterceptorTest.java +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright OpenSearch Contributors - * SPDX-License-Identifier: Apache-2.0 - * - * The OpenSearch Contributors require contributions made to - * this file be licensed under the Apache-2.0 license or a - * compatible open source license. - * - */ - -package org.opensearch.dataprepper.plugins.source.jira.rest; - -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.mockito.Mock; -import org.mockito.junit.jupiter.MockitoExtension; -import org.opensearch.dataprepper.plugins.source.jira.rest.auth.JiraOauthConfig; -import org.springframework.http.HttpHeaders; -import org.springframework.http.HttpRequest; -import org.springframework.http.client.ClientHttpRequestExecution; -import org.springframework.http.client.ClientHttpResponse; - -import java.io.IOException; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.mockito.Mockito.any; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -@ExtendWith(MockitoExtension.class) -public class OAuth2RequestInterceptorTest { - - @Mock - private HttpRequest mockRequest; - - @Mock - private ClientHttpRequestExecution mockExecution; - - @Mock - private ClientHttpResponse mockResponse; - - @Mock - private JiraOauthConfig mockConfig; - - @Mock - private HttpHeaders mockHeaders; - - private OAuth2RequestInterceptor interceptor; - - @BeforeEach - void setUp() { - when(mockConfig.getAccessToken()).thenReturn("testAccessToken"); - when(mockRequest.getHeaders()).thenReturn(mockHeaders); - interceptor = new OAuth2RequestInterceptor(mockConfig); - } - - - @Test - void testInterceptAddsAuthorizationHeader() throws IOException { - when(mockExecution.execute(any(HttpRequest.class), any(byte[].class))).thenReturn(mockResponse); - ClientHttpResponse response = interceptor.intercept(mockRequest, new byte[0], mockExecution); - verify(mockHeaders).setBearerAuth("testAccessToken"); - assertEquals(mockResponse, response); - } -} diff --git a/data-prepper-plugins/saas-source-plugins/jira-source/src/test/java/org/opensearch/dataprepper/plugins/source/jira/rest/auth/JiraAuthFactoryTest.java b/data-prepper-plugins/saas-source-plugins/jira-source/src/test/java/org/opensearch/dataprepper/plugins/source/jira/rest/auth/JiraAuthFactoryTest.java deleted file mode 100644 index 7ae2fe588d..0000000000 --- a/data-prepper-plugins/saas-source-plugins/jira-source/src/test/java/org/opensearch/dataprepper/plugins/source/jira/rest/auth/JiraAuthFactoryTest.java +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright OpenSearch Contributors - * SPDX-License-Identifier: Apache-2.0 - * - * The OpenSearch Contributors require contributions made to - * this file be licensed under the Apache-2.0 license or a - * compatible open source license. - * - */ - -package org.opensearch.dataprepper.plugins.source.jira.rest.auth; - -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.mockito.Mock; -import org.mockito.junit.jupiter.MockitoExtension; -import org.opensearch.dataprepper.model.plugin.PluginConfigVariable; -import org.opensearch.dataprepper.plugins.source.jira.JiraSourceConfig; -import org.opensearch.dataprepper.plugins.source.jira.configuration.AuthenticationConfig; -import org.opensearch.dataprepper.plugins.source.jira.configuration.Oauth2Config; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertInstanceOf; -import static org.mockito.Mockito.when; -import static org.opensearch.dataprepper.plugins.source.jira.utils.Constants.OAUTH2; - -@ExtendWith(MockitoExtension.class) -public class JiraAuthFactoryTest { - - @Mock - private JiraSourceConfig sourceConfig; - - @Mock - private AuthenticationConfig authenticationConfig; - - @Mock - private Oauth2Config oauth2Config; - - @Mock - private PluginConfigVariable accessTokenPluginConfigVariable; - - @Mock - private PluginConfigVariable refreshTokenPluginConfigVariable; - - private JiraAuthFactory jiraAuthFactory; - - @BeforeEach - void setUp() { - jiraAuthFactory = new JiraAuthFactory(sourceConfig); - } - - @Test - void testGetObjectOauth2() { - when(sourceConfig.getAuthType()).thenReturn(OAUTH2); - when(sourceConfig.getAuthenticationConfig()).thenReturn(authenticationConfig); - when(authenticationConfig.getOauth2Config()).thenReturn(oauth2Config); - when(oauth2Config.getRefreshToken()).thenReturn(refreshTokenPluginConfigVariable); - when(oauth2Config.getAccessToken()).thenReturn(accessTokenPluginConfigVariable); - when(accessTokenPluginConfigVariable.getValue()).thenReturn("mockRefreshToken"); - assertInstanceOf(JiraOauthConfig.class, jiraAuthFactory.getObject()); - } - - @Test - void testGetObjectBasicAuth() { - when(sourceConfig.getAccountUrl()).thenReturn("https://example.com"); - assertInstanceOf(JiraBasicAuthConfig.class, jiraAuthFactory.getObject()); - } - - @Test - void testGetObjectType() { - assertEquals(JiraAuthConfig.class, jiraAuthFactory.getObjectType()); - } -} diff --git a/data-prepper-plugins/saas-source-plugins/jira-source/src/test/java/org/opensearch/dataprepper/plugins/source/jira/rest/auth/JiraBasicAuthConfigTest.java b/data-prepper-plugins/saas-source-plugins/jira-source/src/test/java/org/opensearch/dataprepper/plugins/source/jira/rest/auth/JiraBasicAuthConfigTest.java deleted file mode 100644 index 8ab10eb0bc..0000000000 --- a/data-prepper-plugins/saas-source-plugins/jira-source/src/test/java/org/opensearch/dataprepper/plugins/source/jira/rest/auth/JiraBasicAuthConfigTest.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright OpenSearch Contributors - * SPDX-License-Identifier: Apache-2.0 - * - * The OpenSearch Contributors require contributions made to - * this file be licensed under the Apache-2.0 license or a - * compatible open source license. - * - */ - -package org.opensearch.dataprepper.plugins.source.jira.rest.auth; - -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.mockito.Mock; -import org.mockito.junit.jupiter.MockitoExtension; -import org.opensearch.dataprepper.plugins.source.jira.JiraSourceConfig; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.mockito.Mockito.when; - -@ExtendWith(MockitoExtension.class) -public class JiraBasicAuthConfigTest { - - @Mock - private JiraSourceConfig jiraSourceConfig; - - private JiraBasicAuthConfig jiraBasicAuthConfig; - String url = "https://example.com"; - - @BeforeEach - void setUp() { - when(jiraSourceConfig.getAccountUrl()).thenReturn(url); - jiraBasicAuthConfig = new JiraBasicAuthConfig(jiraSourceConfig); - } - - @Test - void testGetUrl() { - assertEquals(jiraBasicAuthConfig.getUrl(), url + '/'); - - } - - @Test - void DoNothingForBasicAuthentication() { - jiraBasicAuthConfig.initCredentials(); - jiraBasicAuthConfig.renewCredentials(); - } -} \ No newline at end of file diff --git a/data-prepper-plugins/saas-source-plugins/jira-source/src/test/java/org/opensearch/dataprepper/plugins/source/jira/rest/auth/JiraOauthConfigTest.java b/data-prepper-plugins/saas-source-plugins/jira-source/src/test/java/org/opensearch/dataprepper/plugins/source/jira/rest/auth/JiraOauthConfigTest.java deleted file mode 100644 index 746dd41dff..0000000000 --- a/data-prepper-plugins/saas-source-plugins/jira-source/src/test/java/org/opensearch/dataprepper/plugins/source/jira/rest/auth/JiraOauthConfigTest.java +++ /dev/null @@ -1,187 +0,0 @@ -/* - * Copyright OpenSearch Contributors - * SPDX-License-Identifier: Apache-2.0 - * - * The OpenSearch Contributors require contributions made to - * this file be licensed under the Apache-2.0 license or a - * compatible open source license. - * - */ - -package org.opensearch.dataprepper.plugins.source.jira.rest.auth; - -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.mockito.Mock; -import org.mockito.junit.jupiter.MockitoExtension; -import org.opensearch.dataprepper.model.plugin.PluginConfigVariable; -import org.opensearch.dataprepper.plugins.source.jira.JiraSourceConfig; -import org.opensearch.dataprepper.plugins.source.jira.configuration.Oauth2Config; -import org.opensearch.dataprepper.plugins.source.jira.exception.UnAuthorizedException; -import org.opensearch.dataprepper.test.helper.ReflectivelySetField; -import org.springframework.http.HttpEntity; -import org.springframework.http.HttpMethod; -import org.springframework.http.HttpStatus; -import org.springframework.http.ResponseEntity; -import org.springframework.web.client.HttpClientErrorException; -import org.springframework.web.client.RestTemplate; - -import java.time.Instant; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; -import java.util.concurrent.Future; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.junit.jupiter.api.Assertions.assertThrows; -import static org.junit.jupiter.api.Assertions.assertTrue; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; -import static org.opensearch.dataprepper.plugins.source.jira.JiraServiceTest.createJiraConfigurationFromYaml; -import static org.opensearch.dataprepper.plugins.source.jira.utils.Constants.RETRY_ATTEMPT; - -@ExtendWith(MockitoExtension.class) -public class JiraOauthConfigTest { - - @Mock - RestTemplate restTemplateMock; - - - JiraSourceConfig jiraSourceConfig; - - @Mock - PluginConfigVariable accessTokenVariable; - - @BeforeEach - void setUp() { - jiraSourceConfig = createJiraConfigurationFromYaml("oauth2-auth-jira-pipeline.yaml"); - } - - @Test - void testRenewToken() throws InterruptedException { - Instant testStartTime = Instant.now(); - Map firstMockResponseMap = Map.of("access_token", "first_mock_access_token", - "refresh_token", "first_mock_refresh_token", - "expires_in", 3600); - JiraOauthConfig jiraOauthConfig = new JiraOauthConfig(jiraSourceConfig); - when(restTemplateMock.postForEntity(any(String.class), any(HttpEntity.class), any(Class.class))) - .thenReturn(new ResponseEntity<>(firstMockResponseMap, HttpStatus.OK)); - jiraOauthConfig.restTemplate = restTemplateMock; - ExecutorService executor = Executors.newFixedThreadPool(2); - Future firstCall = executor.submit(jiraOauthConfig::renewCredentials); - Future secondCall = executor.submit(jiraOauthConfig::renewCredentials); - while (!firstCall.isDone() || !secondCall.isDone()) { - // Do nothing. Wait for the calls to complete - Thread.sleep(10); - } - executor.shutdown(); - assertNotNull(jiraOauthConfig.getAccessToken()); - assertNotNull(jiraOauthConfig.getExpireTime()); - assertEquals(jiraOauthConfig.getRefreshToken(), "first_mock_refresh_token"); - assertEquals(jiraOauthConfig.getExpiresInSeconds(), 3600); - assertEquals(jiraOauthConfig.getAccessToken(), "first_mock_access_token"); - assertTrue(jiraOauthConfig.getExpireTime().isAfter(testStartTime)); - Instant expectedNewExpireTime = Instant.ofEpochMilli(testStartTime.toEpochMilli() + 3601 * 1000); - assertTrue(jiraOauthConfig.getExpireTime().isBefore(expectedNewExpireTime), - String.format("Expected that %s time should be before %s", jiraOauthConfig.getExpireTime(), expectedNewExpireTime)); - verify(restTemplateMock, times(1)).postForEntity(any(String.class), any(HttpEntity.class), any(Class.class)); - - } - - @Test - void testFailedToRenewAccessToken() throws NoSuchFieldException, IllegalAccessException { - JiraOauthConfig jiraOauthConfig = new JiraOauthConfig(jiraSourceConfig); - Oauth2Config oauth2Config = jiraSourceConfig.getAuthenticationConfig().getOauth2Config(); - ReflectivelySetField.setField(Oauth2Config.class, oauth2Config, "accessToken", accessTokenVariable); - when(restTemplateMock.postForEntity(any(String.class), any(HttpEntity.class), any(Class.class))) - .thenThrow(HttpClientErrorException.class); - jiraOauthConfig.restTemplate = restTemplateMock; - assertThrows(RuntimeException.class, jiraOauthConfig::renewCredentials); - verify(oauth2Config.getAccessToken(), times(0)) - .refresh(); - } - - @Test - void testFailedToRenewAccessToken_with_unauthorized_and_trigger_secrets_refresh() - throws NoSuchFieldException, IllegalAccessException { - JiraOauthConfig jiraOauthConfig = new JiraOauthConfig(jiraSourceConfig); - Oauth2Config oauth2Config = jiraSourceConfig.getAuthenticationConfig().getOauth2Config(); - ReflectivelySetField.setField(Oauth2Config.class, oauth2Config, "accessToken", accessTokenVariable); - HttpClientErrorException unAuthorizedException = new HttpClientErrorException(HttpStatus.UNAUTHORIZED); - when(restTemplateMock.postForEntity(any(String.class), any(HttpEntity.class), any(Class.class))) - .thenThrow(unAuthorizedException); - jiraOauthConfig.restTemplate = restTemplateMock; - assertThrows(RuntimeException.class, jiraOauthConfig::renewCredentials); - verify(oauth2Config.getAccessToken(), times(1)) - .refresh(); - } - - - @Test - void testGetJiraAccountCloudId() throws InterruptedException { - Map mockGetCallResponse = new HashMap<>(); - mockGetCallResponse.put("id", "test_cloud_id"); - when(restTemplateMock.exchange(any(String.class), any(HttpMethod.class), any(HttpEntity.class), any(Class.class))) - .thenReturn(new ResponseEntity<>(List.of(mockGetCallResponse), HttpStatus.OK)); - JiraOauthConfig jiraOauthConfig = new JiraOauthConfig(jiraSourceConfig); - jiraOauthConfig.restTemplate = restTemplateMock; - - ExecutorService executor = Executors.newFixedThreadPool(2); - Future firstCall = executor.submit(jiraOauthConfig::getUrl); - Future secondCall = executor.submit(jiraOauthConfig::getUrl); - while (!firstCall.isDone() || !secondCall.isDone()) { - // Do nothing. Wait for the calls to complete - Thread.sleep(10); - } - executor.shutdown(); - - assertEquals("test_cloud_id", jiraOauthConfig.getJiraAccountCloudId()); - assertEquals("https://api.atlassian.com/ex/jira/test_cloud_id/", jiraOauthConfig.getUrl()); - //calling second time shouldn't trigger rest call - jiraOauthConfig.getUrl(); - verify(restTemplateMock, times(1)) - .exchange(any(String.class), any(HttpMethod.class), any(HttpEntity.class), any(Class.class)); - } - - @Test - void testGetJiraAccountCloudIdUnauthorizedCase() { - - when(restTemplateMock.exchange(any(String.class), any(HttpMethod.class), any(HttpEntity.class), any(Class.class))) - .thenThrow(new HttpClientErrorException(HttpStatus.UNAUTHORIZED)); - Map mockRenewTokenResponse = Map.of("access_token", "first_mock_access_token", - "refresh_token", "first_mock_refresh_token", - "expires_in", 3600); - when(restTemplateMock.postForEntity(any(String.class), any(HttpEntity.class), any(Class.class))) - .thenReturn(new ResponseEntity<>(mockRenewTokenResponse, HttpStatus.OK)); - JiraOauthConfig jiraOauthConfig = new JiraOauthConfig(jiraSourceConfig); - jiraOauthConfig.restTemplate = restTemplateMock; - - - assertThrows(UnAuthorizedException.class, () -> jiraOauthConfig.initCredentials()); - verify(restTemplateMock, times(6)) - .exchange(any(String.class), any(HttpMethod.class), any(HttpEntity.class), any(Class.class)); - verify(restTemplateMock, times(1)) - .postForEntity(any(String.class), any(HttpEntity.class), any(Class.class)); - - } - - @Test - void testFailedToGetCloudId() { - when(restTemplateMock.exchange(any(String.class), any(HttpMethod.class), any(HttpEntity.class), any(Class.class))) - .thenThrow(new HttpClientErrorException(HttpStatus.UNAUTHORIZED)) - .thenThrow(HttpClientErrorException.class); - JiraOauthConfig jiraOauthConfig = new JiraOauthConfig(jiraSourceConfig); - jiraOauthConfig.restTemplate = restTemplateMock; - assertThrows(RuntimeException.class, jiraOauthConfig::getUrl); - for (int i = 0; i <= RETRY_ATTEMPT; i++) { - assertThrows(RuntimeException.class, jiraOauthConfig::getUrl); - } - } - -} diff --git a/data-prepper-plugins/saas-source-plugins/jira-source/src/test/java/org/opensearch/dataprepper/plugins/source/jira/utils/AddressValidationTest.java b/data-prepper-plugins/saas-source-plugins/jira-source/src/test/java/org/opensearch/dataprepper/plugins/source/jira/utils/AddressValidationTest.java index 3c346c8e0e..dedcbffdd7 100644 --- a/data-prepper-plugins/saas-source-plugins/jira-source/src/test/java/org/opensearch/dataprepper/plugins/source/jira/utils/AddressValidationTest.java +++ b/data-prepper-plugins/saas-source-plugins/jira-source/src/test/java/org/opensearch/dataprepper/plugins/source/jira/utils/AddressValidationTest.java @@ -11,7 +11,7 @@ package org.opensearch.dataprepper.plugins.source.jira.utils; import org.junit.jupiter.api.Test; -import org.opensearch.dataprepper.plugins.source.jira.exception.BadRequestException; +import org.opensearch.dataprepper.plugins.source.source_crawler.exception.BadRequestException; import java.net.InetAddress; import java.net.MalformedURLException;