From 73227b815270c5a8427125f3d759ac6192fe7778 Mon Sep 17 00:00:00 2001 From: Maximilian Junker Date: Wed, 3 Apr 2019 05:48:50 +0200 Subject: [PATCH] fix: jira problems --- .../connectors/internal/ConnectorTask.java | 65 +++++++++++-------- .../jira/internal/services/JiraConnector.java | 64 +++++++++--------- 2 files changed, 71 insertions(+), 58 deletions(-) diff --git a/bundles/specmate-connectors/src/com/specmate/connectors/internal/ConnectorTask.java b/bundles/specmate-connectors/src/com/specmate/connectors/internal/ConnectorTask.java index 1ec27f0c7..99dadcdc1 100644 --- a/bundles/specmate-connectors/src/com/specmate/connectors/internal/ConnectorTask.java +++ b/bundles/specmate-connectors/src/com/specmate/connectors/internal/ConnectorTask.java @@ -18,6 +18,7 @@ import com.specmate.model.base.BaseFactory; import com.specmate.model.base.Folder; import com.specmate.model.base.IContainer; +import com.specmate.model.base.IContentElement; import com.specmate.model.requirements.Requirement; import com.specmate.model.support.util.SpecmateEcoreUtil; import com.specmate.persistency.IChange; @@ -45,10 +46,10 @@ public void run() { } private void syncRequirementsFromSources() { - logService.log(LogService.LOG_INFO, "Synchronizing requirements"); - Resource resource = transaction.getResource(); - for (IRequirementsSource source : requirementsSources) { - logService.log(LogService.LOG_INFO, "Retrieving requirements from " + source.getId()); + this.logService.log(LogService.LOG_INFO, "Synchronizing requirements"); + Resource resource = this.transaction.getResource(); + for (IRequirementsSource source : this.requirementsSources) { + this.logService.log(LogService.LOG_INFO, "Retrieving requirements from " + source.getId()); try { Collection requirements = source.getRequirements(); if (requirements == null) { @@ -65,7 +66,7 @@ private void syncRequirementsFromSources() { List tosync = Arrays.asList(current); try { - transaction.doAndCommit(new IChange() { + this.transaction.doAndCommit(new IChange() { @Override public Object doChange() throws SpecmateException { syncContainers(localContainer, tosync, source); @@ -73,14 +74,14 @@ public Object doChange() throws SpecmateException { } }); } catch (Exception e) { - logService.log(LogService.LOG_ERROR, e.getMessage()); - transaction.rollback(); + this.logService.log(LogService.LOG_ERROR, e.getMessage()); + this.transaction.rollback(); } } } catch (Exception e) { - logService.log(LogService.LOG_ERROR, e.getMessage()); - transaction.rollback(); + this.logService.log(LogService.LOG_ERROR, e.getMessage()); + this.transaction.rollback(); } } @@ -96,56 +97,64 @@ private void syncContainers(IContainer localContainer, Collection r // Build hashset (extid -> requirement) for remote requirements HashMap remoteRequirementsMap = new HashMap<>(); buildExtIdMap(requirements.iterator(), remoteRequirementsMap); - logService.log(LogService.LOG_INFO, "Retrieved " + remoteRequirementsMap.entrySet().size() + " requirements."); + this.logService.log(LogService.LOG_INFO, + "Retrieved " + remoteRequirementsMap.entrySet().size() + " requirements."); // find new requirements remoteRequirementsMap.keySet().removeAll(localRequirementsMap.keySet()); - logService.log(LogService.LOG_INFO, "Adding " + remoteRequirementsMap.size() + " new requirements."); + this.logService.log(LogService.LOG_INFO, "Adding " + remoteRequirementsMap.size() + " new requirements."); // add new requirements to local container and all folders on the way for (Entry entry : remoteRequirementsMap.entrySet()) { Requirement requirementToAdd = (Requirement) entry.getValue(); boolean valid = ensureValid(requirementToAdd); if (!valid) { - logService.log(LogService.LOG_WARNING, "Found invalid requirement with id " + requirementToAdd.getId()); + this.logService.log(LogService.LOG_WARNING, + "Found invalid requirement with id " + requirementToAdd.getId()); continue; } IContainer reqContainer; try { reqContainer = source.getContainerForRequirement((Requirement) entry.getValue()); + } catch (SpecmateException e) { - logService.log(LogService.LOG_ERROR, e.getMessage()); + this.logService.log(LogService.LOG_ERROR, e.getMessage()); continue; } IContainer foundContainer = (IContainer) SpecmateEcoreUtil.getEObjectWithId(reqContainer.getId(), localContainer.eContents()); if (foundContainer == null) { - logService.log(LogService.LOG_DEBUG, "Creating new folder " + reqContainer.getName()); + this.logService.log(LogService.LOG_DEBUG, "Creating new folder " + reqContainer.getName()); foundContainer = BaseFactory.eINSTANCE.createFolder(); SpecmateEcoreUtil.copyAttributeValues(reqContainer, foundContainer); + valid = ensureValid(foundContainer); + if (!valid) { + this.logService.log(LogService.LOG_WARNING, + "Found invalid folder with id " + foundContainer.getId()); + continue; + } localContainer.getContents().add(foundContainer); } - logService.log(LogService.LOG_DEBUG, "Adding requirement " + requirementToAdd.getId()); + this.logService.log(LogService.LOG_DEBUG, "Adding requirement " + requirementToAdd.getId()); foundContainer.getContents().add(requirementToAdd); } } - private boolean ensureValid(Requirement requirementToAdd) { - if (StringUtils.isEmpty(requirementToAdd.getId())) { + private boolean ensureValid(IContentElement element) { + if (StringUtils.isEmpty(element.getId())) { return false; } - if (StringUtils.isEmpty(requirementToAdd.getName())) { - requirementToAdd.setName(requirementToAdd.getId()); + if (StringUtils.isEmpty(element.getName())) { + element.setName(element.getId()); } - if (requirementToAdd.getName().length() > MAX_FIELD_LENGTH) { - requirementToAdd.setName(requirementToAdd.getName().substring(0, MAX_FIELD_LENGTH - 1)); + if (element.getName().length() > MAX_FIELD_LENGTH) { + element.setName(element.getName().substring(0, MAX_FIELD_LENGTH - 1)); } - requirementToAdd.setName(requirementToAdd.getName().replaceAll("[,\\|;]", " ")); - if (requirementToAdd.getDescription() != null - && requirementToAdd.getDescription().length() > MAX_FIELD_LENGTH) { - requirementToAdd.setDescription(requirementToAdd.getDescription().substring(0, MAX_FIELD_LENGTH - 1)); + element.setName(element.getName().replaceAll("[,\\|;]", " ")); + if (element.getDescription() != null && element.getDescription().length() > MAX_FIELD_LENGTH) { + element.setDescription(element.getDescription().substring(0, MAX_FIELD_LENGTH - 1)); } return true; } @@ -159,9 +168,9 @@ private IContainer getOrCreateLocalContainer(Resource resource, String name) { } Folder folder = BaseFactory.eINSTANCE.createFolder(); - folder.setName(name); - // TODO: sanitize id - folder.setId(name); + String validName = name.replaceAll("[,\\|;]", " "); + folder.setName(validName); + folder.setId(validName); resource.getContents().add(folder); return folder; } diff --git a/bundles/specmate-jira-connector/src/com/specmate/connectors/jira/internal/services/JiraConnector.java b/bundles/specmate-jira-connector/src/com/specmate/connectors/jira/internal/services/JiraConnector.java index 03ee110b4..9bde65db2 100644 --- a/bundles/specmate-jira-connector/src/com/specmate/connectors/jira/internal/services/JiraConnector.java +++ b/bundles/specmate-jira-connector/src/com/specmate/connectors/jira/internal/services/JiraConnector.java @@ -27,6 +27,7 @@ import com.atlassian.jira.rest.client.api.JiraRestClient; import com.atlassian.jira.rest.client.api.RestClientException; import com.atlassian.jira.rest.client.api.domain.Issue; +import com.atlassian.jira.rest.client.api.domain.IssueField; import com.atlassian.jira.rest.client.api.domain.SearchResult; import com.atlassian.jira.rest.client.internal.async.AsynchronousJiraRestClientFactory; import com.specmate.common.cache.ICache; @@ -75,20 +76,20 @@ public class JiraConnector extends DetailsService implements IRequirementsSource public void activate(Map properties) throws SpecmateException { validateConfig(properties); - id = (String) properties.get(IProjectConfigService.KEY_CONNECTOR_ID); - url = (String) properties.get(JiraConnectorConfig.KEY_JIRA_URL); - projectName = (String) properties.get(JiraConnectorConfig.KEY_JIRA_PROJECT); + this.id = (String) properties.get(IProjectConfigService.KEY_CONNECTOR_ID); + this.url = (String) properties.get(JiraConnectorConfig.KEY_JIRA_URL); + this.projectName = (String) properties.get(JiraConnectorConfig.KEY_JIRA_PROJECT); String username = (String) properties.get(JiraConnectorConfig.KEY_JIRA_USERNAME); String password = (String) properties.get(JiraConnectorConfig.KEY_JIRA_PASSWORD); try { - jiraClient = new AsynchronousJiraRestClientFactory().createWithBasicHttpAuthentication(new URI(url), - username, password); + this.jiraClient = new AsynchronousJiraRestClientFactory() + .createWithBasicHttpAuthentication(new URI(this.url), username, password); } catch (URISyntaxException e) { throw new SpecmateInternalException(ErrorCode.JIRA, e); } - defaultFolder = createFolder(projectName + "-Default", projectName + "-Default"); + this.defaultFolder = createFolder(this.projectName + "-Default", this.projectName + "-Default"); this.cache = this.cacheService.createCache(JIRA_STORY_CACHE_NAME, 500, 3600, new ICacheLoader() { @@ -105,7 +106,7 @@ public Issue load(String key) throws SpecmateException { @Deactivate public void deactivate() throws SpecmateInternalException { try { - jiraClient.close(); + this.jiraClient.close(); this.cacheService.removeCache(JIRA_STORY_CACHE_NAME); } catch (IOException e) { throw new SpecmateInternalException(ErrorCode.INTERNAL_PROBLEM, "Could not close JIRA client.", e); @@ -149,7 +150,7 @@ public Collection getRequirements() throws SpecmateException { List stories = getStoriesForEpic(epic); for (Issue story : stories) { Requirement requirement = createRequirement(story); - requirmentEpics.put(requirement, epic); + this.requirmentEpics.put(requirement, epic); requirements.add(requirement); } } @@ -158,21 +159,21 @@ public Collection getRequirements() throws SpecmateException { } private List getStoriesForEpic(Issue epic) throws SpecmateException { - return this.getIssues("project=" + projectName + " AND issueType=story AND \"Epic Link\"=\"" + epic.getKey() - + "\" ORDER BY assignee, resolutiondate"); + return this.getIssues("project=" + this.projectName + " AND issueType=story AND \"Epic Link\"=\"" + + epic.getKey() + "\" ORDER BY assignee, resolutiondate"); } private List getStoriesWithoutEpic() throws SpecmateException { - return this.getIssues("project=" + projectName + return this.getIssues("project=" + this.projectName + " AND issueType=story AND \"Epic Link\" IS EMPTY ORDER BY assignee, resolutiondate"); } private List getEpics() throws SpecmateException { - return this.getIssues("project=" + projectName + " AND issueType=epic ORDER BY id"); + return this.getIssues("project=" + this.projectName + " AND issueType=epic ORDER BY id"); } private Issue getStory(String id) throws SpecmateException { - List issues = this.getIssues("project=" + projectName + " AND id=" + id); + List issues = this.getIssues("project=" + this.projectName + " AND id=" + id); if (issues == null || issues.size() == 0) { throw new SpecmateInternalException(ErrorCode.INTERNAL_PROBLEM, "JIRA Issue not found: " + id); } @@ -185,12 +186,12 @@ private List getIssues(String jql) throws SpecmateException { int maxResults = Integer.MAX_VALUE; while (issues.size() < maxResults) { try { - SearchResult searchResult = jiraClient.getSearchClient().searchJql(jql, -1, issues.size(), null) + SearchResult searchResult = this.jiraClient.getSearchClient().searchJql(jql, -1, issues.size(), null) .claim(); maxResults = searchResult.getTotal(); searchResult.getIssues().forEach(issue -> issues.add(issue)); - logService.log(LogService.LOG_DEBUG, "Loaded ~" + searchResult.getMaxResults() + " issues from Jira " - + url + " project: " + projectName); + this.logService.log(LogService.LOG_DEBUG, "Loaded ~" + searchResult.getMaxResults() + + " issues from Jira " + this.url + " project: " + this.projectName); } catch (RestClientException e) { if (e.getStatusCode().get() == 400) { return issues; @@ -202,34 +203,34 @@ private List getIssues(String jql) throws SpecmateException { } - logService.log(LogService.LOG_INFO, - "Finished loading of " + issues.size() + " issues from Jira " + url + " project: " + projectName); + this.logService.log(LogService.LOG_INFO, "Finished loading of " + issues.size() + " issues from Jira " + + this.url + " project: " + this.projectName); return issues; } @Override public IContainer getContainerForRequirement(Requirement requirement) throws SpecmateException { - Issue epic = requirmentEpics.get(requirement); + Issue epic = this.requirmentEpics.get(requirement); if (epic == null) { - return defaultFolder; + return this.defaultFolder; } - return epicFolders.get(epic); + return this.epicFolders.get(epic); } @Override public boolean authenticate(String username, String password) throws SpecmateException { try { JiraRestClient client = new AsynchronousJiraRestClientFactory() - .createWithBasicHttpAuthentication(new URI(url), username, password); - client.getProjectClient().getProject(projectName).claim(); + .createWithBasicHttpAuthentication(new URI(this.url), username, password); + client.getProjectClient().getProject(this.projectName).claim(); } catch (URISyntaxException e) { e.printStackTrace(); throw new SpecmateAuthorizationException("Jira authentication failed.", e); } catch (RestClientException e) { Integer status = e.getStatusCode().get(); if (status == 401) { - logService.log(LogService.LOG_INFO, + this.logService.log(LogService.LOG_INFO, "Invalid credentials provided for jira project " + this.projectName + '.'); return false; } @@ -252,10 +253,13 @@ private static Requirement createRequirement(Issue story) throws SpecmateExcepti requirement.setStatus(story.getStatus().getName()); requirement.setLive(true); try { - JSONObject teamObject = (JSONObject) story.getFieldByName("Team").getValue(); - if (teamObject != null) { - String team = (String) teamObject.get("value"); - requirement.setImplementingITTeam(team); + IssueField teamField = story.getFieldByName("Team"); + if (teamField != null) { + JSONObject teamObject = (JSONObject) teamField.getValue(); + if (teamObject != null) { + String team = (String) teamObject.get("value"); + requirement.setImplementingITTeam(team); + } } } catch (JSONException e) { throw new SpecmateInternalException(ErrorCode.JIRA, e); @@ -264,11 +268,11 @@ private static Requirement createRequirement(Issue story) throws SpecmateExcepti } private void createFolderIfNotExists(Issue epic) { - if (!epicFolders.containsKey(epic)) { + if (!this.epicFolders.containsKey(epic)) { String folderId = epic.getKey(); String folderName = folderId + ": " + epic.getSummary(); Folder folder = createFolder(folderId, folderName); - epicFolders.put(epic, folder); + this.epicFolders.put(epic, folder); } }