From 12de740173914632a03af56d0c3625760238f20a Mon Sep 17 00:00:00 2001 From: Maxwell Brown <55033421+Galactus22625@users.noreply.github.com> Date: Mon, 11 Nov 2024 20:47:41 -0800 Subject: [PATCH] Jira source fixes (#5175) * switch logs to trace Signed-off-by: Maxwell Brown <mxwelwbr@amazon.com> * remove Jira Project Cache (null pointer bug) Signed-off-by: Maxwell Brown <mxwelwbr@amazon.com> * fix accountUrl with no ending / issue Signed-off-by: Maxwell Brown <mxwelwbr@amazon.com> * better slash changes handling Signed-off-by: Maxwell Brown <mxwelwbr@amazon.com> * better logic Signed-off-by: Maxwell Brown <mxwelwbr@amazon.com> * fix tests Signed-off-by: Maxwell Brown <mxwelwbr@amazon.com> * Jira Iterator HasNext test Signed-off-by: Maxwell Brown <mxwelwbr@amazon.com> --------- Signed-off-by: Maxwell Brown <mxwelwbr@amazon.com> --- .../plugins/source/jira/JiraIterator.java | 9 ++++-- .../plugins/source/jira/JiraService.java | 29 ++----------------- .../source/jira/rest/JiraRestClient.java | 6 +--- .../jira/rest/auth/JiraBasicAuthConfig.java | 7 ++++- .../plugins/source/jira/JiraIteratorTest.java | 15 +++++++++- .../plugins/source/jira/JiraServiceTest.java | 2 +- .../source/jira/rest/JiraRestClientTest.java | 1 + .../jira/rest/auth/JiraAuthFactoryTest.java | 1 + .../rest/auth/JiraBasicAuthConfigTest.java | 6 +++- 9 files changed, 39 insertions(+), 37 deletions(-) diff --git a/data-prepper-plugins/saas-source-plugins/jira-source/src/main/java/org/opensearch/dataprepper/plugins/source/jira/JiraIterator.java b/data-prepper-plugins/saas-source-plugins/jira-source/src/main/java/org/opensearch/dataprepper/plugins/source/jira/JiraIterator.java index 1e033581b4..cd5d422047 100644 --- a/data-prepper-plugins/saas-source-plugins/jira-source/src/main/java/org/opensearch/dataprepper/plugins/source/jira/JiraIterator.java +++ b/data-prepper-plugins/saas-source-plugins/jira-source/src/main/java/org/opensearch/dataprepper/plugins/source/jira/JiraIterator.java @@ -10,6 +10,7 @@ import javax.inject.Named; import java.time.Instant; import java.util.Iterator; +import java.util.NoSuchElementException; import java.util.Queue; import java.util.concurrent.ConcurrentLinkedQueue; import java.util.concurrent.ExecutorService; @@ -38,7 +39,7 @@ public JiraIterator(final JiraService service, @Override public boolean hasNext() { if (firstTime) { - log.info("Crawling has been started"); + log.trace("Crawling has been started"); itemInfoQueue = service.getJiraEntities(sourceConfig, lastPollTime); firstTime = false; } @@ -47,7 +48,11 @@ public boolean hasNext() { @Override public ItemInfo next() { - return this.itemInfoQueue.remove(); + if (hasNext()) { + return this.itemInfoQueue.remove(); + } else { + throw new NoSuchElementException(); + } } /** 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 1eaf67e1df..f2fead1b54 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 @@ -8,31 +8,23 @@ import org.opensearch.dataprepper.plugins.source.jira.models.SearchResults; import org.opensearch.dataprepper.plugins.source.jira.rest.JiraRestClient; import org.opensearch.dataprepper.plugins.source.jira.utils.JiraConfigHelper; -import org.opensearch.dataprepper.plugins.source.jira.utils.JiraContentType; import org.opensearch.dataprepper.plugins.source.source_crawler.model.ItemInfo; import org.springframework.util.CollectionUtils; import javax.inject.Named; import java.time.Instant; import java.util.ArrayList; -import java.util.HashMap; import java.util.List; import java.util.Map; -import java.util.Objects; import java.util.Queue; -import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentLinkedQueue; import java.util.regex.Matcher; import java.util.regex.Pattern; import java.util.stream.Collectors; import static org.opensearch.dataprepper.plugins.source.jira.utils.Constants.ISSUE_KEY; -import static org.opensearch.dataprepper.plugins.source.jira.utils.Constants.KEY; -import static org.opensearch.dataprepper.plugins.source.jira.utils.Constants.LIVE; -import static org.opensearch.dataprepper.plugins.source.jira.utils.Constants.PROJECT; import static org.opensearch.dataprepper.plugins.source.jira.utils.Constants.PROJECT_KEY; import static org.opensearch.dataprepper.plugins.source.jira.utils.Constants.UPDATED; -import static org.opensearch.dataprepper.plugins.source.jira.utils.Constants._PROJECT; import static org.opensearch.dataprepper.plugins.source.jira.utils.JqlConstants.CLOSING_ROUND_BRACKET; import static org.opensearch.dataprepper.plugins.source.jira.utils.JqlConstants.DELIMITER; import static org.opensearch.dataprepper.plugins.source.jira.utils.JqlConstants.GREATER_THAN_EQUALS; @@ -54,7 +46,6 @@ public class JiraService { public static final String CONTENT_TYPE = "ContentType"; private static final String SEARCH_RESULTS_FOUND = "searchResultsFound"; - private static final Map<String, String> jiraProjectCache = new ConcurrentHashMap<>(); private final JiraSourceConfig jiraSourceConfig; private final JiraRestClient jiraRestClient; @@ -75,17 +66,10 @@ public JiraService(JiraSourceConfig jiraSourceConfig, JiraRestClient jiraRestCli * @param timestamp timestamp. */ public Queue<ItemInfo> getJiraEntities(JiraSourceConfig configuration, Instant timestamp) { - log.info("Started to fetch entities"); + log.trace("Started to fetch entities"); Queue<ItemInfo> itemInfoQueue = new ConcurrentLinkedQueue<>(); - jiraProjectCache.clear(); searchForNewTicketsAndAddToQueue(configuration, timestamp, itemInfoQueue); log.trace("Creating item information and adding in queue"); - jiraProjectCache.keySet().forEach(key -> { - Map<String, Object> metadata = new HashMap<>(); - metadata.put(CONTENT_TYPE, JiraContentType.PROJECT.getType()); - ItemInfo itemInfo = createItemInfo(_PROJECT + key, metadata); - itemInfoQueue.add(itemInfo); - }); return itemInfoQueue; } @@ -125,13 +109,6 @@ private void searchForNewTicketsAndAddToQueue(JiraSourceConfig configuration, In private void addItemsToQueue(List<IssueBean> issueList, Queue<ItemInfo> itemInfoQueue) { issueList.forEach(issue -> { itemInfoQueue.add(JiraItemInfo.builder().withEventTime(Instant.now()).withIssueBean(issue).build()); - - if (Objects.nonNull(((Map) issue.getFields().get(PROJECT)).get(KEY))) { - String projectKey = ((Map) issue.getFields().get(PROJECT)).get(KEY).toString(); - if (!jiraProjectCache.containsKey(projectKey)) { - jiraProjectCache.put(projectKey, LIVE); - } - } }); } @@ -165,7 +142,7 @@ private StringBuilder createIssueFilterCriteria(JiraSourceConfig configuration, .collect(Collectors.joining(DELIMITER, PREFIX, SUFFIX))) .append(CLOSING_ROUND_BRACKET); } - log.info("Created issue filter criteria JiraQl query: {}", jiraQl); + log.trace("Created issue filter criteria JiraQl query: {}", jiraQl); return jiraQl; } @@ -175,7 +152,7 @@ private StringBuilder createIssueFilterCriteria(JiraSourceConfig configuration, * @param configuration Input Parameter */ private void validateProjectFilters(JiraSourceConfig configuration) { - log.info("Validating project filters"); + log.trace("Validating project filters"); List<String> badFilters = new ArrayList<>(); Pattern regex = Pattern.compile("[^A-Z0-9]"); JiraConfigHelper.getProjectKeyFilter(configuration).forEach(projectFilter -> { 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 d87985c6fd..c87c7019e6 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 @@ -21,7 +21,6 @@ import java.util.List; import static org.opensearch.dataprepper.logging.DataPrepperMarkers.NOISY; -import static org.opensearch.dataprepper.plugins.source.jira.utils.Constants.OAUTH2; 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; @@ -69,10 +68,7 @@ public JiraRestClient(RestTemplate restTemplate, JiraAuthConfig authConfig) { public SearchResults getAllIssues(StringBuilder jql, int startAt, JiraSourceConfig configuration) { - String url = configuration.getAccountUrl() + REST_API_SEARCH; - if (configuration.getAuthType().equals(OAUTH2)) { - url = authConfig.getUrl() + REST_API_SEARCH; - } + String url = authConfig.getUrl() + REST_API_SEARCH; URI uri = UriComponentsBuilder.fromHttpUrl(url) .queryParam(MAX_RESULT, FIFTY) 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 index 751f56f6d1..233cbf9f49 100644 --- 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 @@ -6,14 +6,19 @@ 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 jiraSourceConfig.getAccountUrl(); + return accountUrl; } @Override diff --git a/data-prepper-plugins/saas-source-plugins/jira-source/src/test/java/org/opensearch/dataprepper/plugins/source/jira/JiraIteratorTest.java b/data-prepper-plugins/saas-source-plugins/jira-source/src/test/java/org/opensearch/dataprepper/plugins/source/jira/JiraIteratorTest.java index b8560d69a4..9c47bf8e51 100644 --- a/data-prepper-plugins/saas-source-plugins/jira-source/src/test/java/org/opensearch/dataprepper/plugins/source/jira/JiraIteratorTest.java +++ b/data-prepper-plugins/saas-source-plugins/jira-source/src/test/java/org/opensearch/dataprepper/plugins/source/jira/JiraIteratorTest.java @@ -15,6 +15,7 @@ import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.NoSuchElementException; import java.util.UUID; import static org.junit.jupiter.api.Assertions.assertFalse; @@ -98,8 +99,20 @@ void testItemInfoQueueNotEmpty() { jiraIterator.setCrawlerQWaitTimeMillis(1); assertTrue(jiraIterator.hasNext()); assertNotNull(jiraIterator.next()); - assertNotNull(jiraIterator.next()); + } + + @Test + void testItemInfoQueueEmpty(){ + jiraIterator = createObjectUnderTest(); + List<IssueBean> mockIssues = new ArrayList<>(); + when(mockSearchResults.getIssues()).thenReturn(mockIssues); + when(mockSearchResults.getTotal()).thenReturn(0); + doReturn(mockSearchResults).when(jiraRestClient).getAllIssues(any(StringBuilder.class), anyInt(), any(JiraSourceConfig.class)); + + jiraIterator.initialize(Instant.ofEpochSecond(0)); + jiraIterator.setCrawlerQWaitTimeMillis(1); assertFalse(jiraIterator.hasNext()); + assertThrows(NoSuchElementException.class, () -> jiraIterator.next()); } 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 cfa8a32733..8900936400 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 @@ -142,7 +142,7 @@ public void testGetJiraEntities() throws JsonProcessingException { Instant timestamp = Instant.ofEpochSecond(0); Queue<ItemInfo> itemInfoQueue = jiraService.getJiraEntities(jiraSourceConfig, timestamp); - assertEquals(mockIssues.size() + 1, itemInfoQueue.size()); + assertEquals(mockIssues.size(), itemInfoQueue.size()); } @Test 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 c9bdb39625..d79372c65b 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 @@ -123,6 +123,7 @@ public void testGetAllIssuesBasic() throws JsonProcessingException { JiraSourceConfig jiraSourceConfig = JiraServiceTest.createJiraConfiguration(BASIC, issueType, issueStatus, projectKey); JiraRestClient jiraRestClient = new JiraRestClient(restTemplate, authConfig); SearchResults mockSearchResults = mock(SearchResults.class); + when(authConfig.getUrl()).thenReturn("https://example.com"); doReturn(new ResponseEntity<>(mockSearchResults, HttpStatus.OK)).when(restTemplate).getForEntity(any(URI.class), any(Class.class)); SearchResults results = jiraRestClient.getAllIssues(jql, 0, jiraSourceConfig); assertNotNull(results); 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 index d006f8df3f..566b3ae8ed 100644 --- 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 @@ -33,6 +33,7 @@ void testGetObjectOauth2() { @Test void testGetObjectBasicAuth() { + when(sourceConfig.getAccountUrl()).thenReturn("https://example.com"); assertInstanceOf(JiraBasicAuthConfig.class, jiraAuthFactory.getObject()); } 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 index 0028525127..60dad25507 100644 --- 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 @@ -8,6 +8,7 @@ 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 { @@ -16,15 +17,18 @@ public class JiraBasicAuthConfigTest { 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(), jiraSourceConfig.getAccountUrl()); + assertEquals(jiraBasicAuthConfig.getUrl(), url + '/'); + } @Test