Skip to content

Commit

Permalink
Merge pull request #24 from MicroFocus/support_request_integration_in…
Browse files Browse the repository at this point in the history
…_jira_connector

Support request integration in jira connector
  • Loading branch information
Elva-Zhu authored May 10, 2018
2 parents 4fdc76d + 784b0dc commit 301501c
Show file tree
Hide file tree
Showing 13 changed files with 843 additions and 65 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@

public class JIRAConstants {

public static final String JIRA_NAME_PREFIX = "#@#name#@#";

public static final String NULL_VALUE = "<null>";

public static final String REPLACE_PROJECT_KEY = "%PROJECT_KEY%";
Expand Down Expand Up @@ -83,10 +85,14 @@ public class JIRAConstants {

public static final String API_VERSION2_API_ROOT = "/rest/api/2/";

public static final String SEARCH_USER = API_VERSION2_API_ROOT + "user/search";

public static final String API_VERSION1_API_ROOT = "/rest/agile/1.0/";

public static final String PROJECT_SUFFIX = API_VERSION2_API_ROOT + "project";

public static final String CREATEMETA_SUFFIX = API_VERSION2_API_ROOT + "issue/createmeta";

public static final String BOARD_SUFFIX = API_VERSION1_API_ROOT + "board";

public static final String SPRINT_SUFFIX = API_VERSION1_API_ROOT + "sprint";
Expand Down Expand Up @@ -124,7 +130,7 @@ public class JIRAConstants {

public static final String JIRA_EPIC_NAME_CUSTOM = "com.pyxis.greenhopper.jira:gh-epic-label";

public static final String JIRA_CREATE_ISSUE_URL = API_VERSION2_API_ROOT + "issue/";
public static final String JIRA_REST_ISSUE_URL = API_VERSION2_API_ROOT + "issue/";

public static final String JIRA_GET_ISSUE_WORKLOG = API_VERSION2_API_ROOT + "issue/%issue%/worklog";

Expand Down Expand Up @@ -162,4 +168,6 @@ public class JIRAConstants {
public static final String TS_DAILY_HOURS = "ts_daily_hours";

public static final String JIRA_FIELD_RESOLUTION_DATE = "resolutiondate";


}
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ public List<FunctionIntegration> getIntegrations() {

@Override
public List<String> getIntegrationClasses() {
return Arrays.asList(new String[] {"com.ppm.integration.agilesdk.connector.jira.JIRAWorkPlanIntegration","com.ppm.integration.agilesdk.connector.jira.JIRATimeSheetIntegration", "com.ppm.integration.agilesdk.connector.jira.JIRAPortfolioEpicIntegration", "com.ppm.integration.agilesdk.connector.jira.JIRAAgileDataIntegration"});
return Arrays.asList(new String[] {"com.ppm.integration.agilesdk.connector.jira.JIRAWorkPlanIntegration","com.ppm.integration.agilesdk.connector.jira.JIRATimeSheetIntegration", "com.ppm.integration.agilesdk.connector.jira.JIRAPortfolioEpicIntegration", "com.ppm.integration.agilesdk.connector.jira.JIRAAgileDataIntegration", "com.ppm.integration.agilesdk.connector.jira.JIRARequestIntegration"});
}

private DynamicDropdown getUserDataDDL(String elementName,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,7 @@
package com.ppm.integration.agilesdk.connector.jira;

import com.ppm.integration.agilesdk.ValueSet;
import com.ppm.integration.agilesdk.connector.jira.model.JIRAEpic;
import com.ppm.integration.agilesdk.connector.jira.model.JIRAIssue;
import com.ppm.integration.agilesdk.connector.jira.model.JIRAProject;
import com.ppm.integration.agilesdk.connector.jira.model.JIRASubTaskableIssue;
import com.ppm.integration.agilesdk.connector.jira.model.*;
import com.ppm.integration.agilesdk.model.AgileProject;
import com.ppm.integration.agilesdk.epic.PortfolioEpicCreationInfo;
import com.ppm.integration.agilesdk.epic.PortfolioEpicIntegration;
Expand Down Expand Up @@ -40,13 +37,16 @@ public class JIRAPortfolioEpicIntegration extends PortfolioEpicIntegration {
}

// We want to retrieve the epic and all of its contents to be able to compute aggregated story points & percent SP complete
// That means retrieve all issue types except Sub-Tasks.

List<JIRAIssueType> jiraIssueTypes = service.get(instanceConfigurationParameters).getProjectIssueTypes(agileProjectValue);

Set<String> issueTypes = new HashSet<String>();
issueTypes.add(JIRAConstants.JIRA_ISSUE_TASK);
issueTypes.add(JIRAConstants.JIRA_ISSUE_STORY);
issueTypes.add(JIRAConstants.JIRA_ISSUE_BUG);
issueTypes.add(JIRAConstants.JIRA_ISSUE_EPIC);
issueTypes.add(JIRAConstants.JIRA_ISSUE_FEATURE);
for (JIRAIssueType jiraIssueType : jiraIssueTypes) {
if (!JIRAConstants.JIRA_ISSUE_SUB_TASK.equalsIgnoreCase(jiraIssueType.getName())) {
issueTypes.add(jiraIssueType.getName().toUpperCase());
}
}

List<JIRASubTaskableIssue> issues = null;

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,180 @@
package com.ppm.integration.agilesdk.connector.jira;

import com.ppm.integration.agilesdk.ValueSet;
import com.ppm.integration.agilesdk.connector.jira.model.JIRAFieldInfo;
import com.ppm.integration.agilesdk.connector.jira.model.JIRAIssueType;
import com.ppm.integration.agilesdk.dm.*;
import com.ppm.integration.agilesdk.model.*;
import org.apache.commons.lang.StringUtils;

import java.util.*;

import static com.ppm.integration.agilesdk.connector.jira.JIRAConstants.JIRA_NAME_PREFIX;

public class JIRARequestIntegration extends RequestIntegration {

private JIRAServiceProvider service = new JIRAServiceProvider().useAdminAccount();

@Override public List<AgileEntityInfo> getAgileEntitiesInfo(String agileProjectValue, ValueSet instanceConfigurationParameters) {

List<JIRAIssueType> issueTypes = service.get(instanceConfigurationParameters).getProjectIssueTypes(agileProjectValue);

List<AgileEntityInfo> entityList = new ArrayList<AgileEntityInfo>();
for (JIRAIssueType issueType : issueTypes) {
AgileEntityInfo feature = new AgileEntityInfo();
feature.setName(issueType.getName());
feature.setType(issueType.getId());
entityList.add(feature);
}

return entityList;
}

@Override public List<AgileEntityFieldInfo> getAgileEntityFieldsInfo(String agileProjectValue, String entityType,
ValueSet instanceConfigurationParameters)
{
List<AgileEntityFieldInfo> fieldsInfo = new ArrayList<>();

List<JIRAFieldInfo> fields = new ArrayList(service.get(instanceConfigurationParameters).getFields(agileProjectValue, entityType).values());

for (JIRAFieldInfo field: fields) {

// We support following JIRA fields types to map:
// - string
// - number
// - array type with non-empty allowedValues (i.e. drop down list)
// - User or array of User
// - priority (provided that allowedValues is non-empty)

if ("string".equals(field.getType())
|| "number".equals(field.getType())
|| "user".equals(field.getType())
|| "priority".equals(field.getType())
|| ("array".equals(field.getType()))) {

if (field.isList() && !"user".equals(field.getType()) && (field.getAllowedValues()== null || field.getAllowedValues().isEmpty())) {
// We only allow to select lists that have some static value options or are users lists.
continue;
}

AgileEntityFieldInfo fieldInfo = new AgileEntityFieldInfo();
fieldInfo.setId(field.getKey());
fieldInfo.setLabel(field.getName());
fieldInfo.setListType(field.isList());
fieldInfo.setFieldType(field.getType());
fieldsInfo.add(fieldInfo);
}
}

return fieldsInfo;
}

/*@Override public List<AgileEntityField> getAgileEntityFieldValueList(String agileProjectValue, String entityType, String listIdentifier,
ValueSet instanceConfigurationParameters)
{
// Not used.
List<JIRAFieldInfo> fields = service.get(instanceConfigurationParameters).getFields(agileProjectValue, entityType);
for (JIRAFieldInfo field : fields) {
if (listIdentifier.equals(field.getKey())) {
return field.getAllowedValues();
}
}
// Field not found.
return new ArrayList<AgileEntityField>();
}*/

@Override public AgileEntity updateEntity(String agileProjectValue, String entityType, AgileEntity entity,
ValueSet instanceConfigurationParameters)
{

JIRAServiceProvider.JIRAService jiraService = service.get(instanceConfigurationParameters);

Map<String, String> fields = getFieldsFromAgileEntity(entity, jiraService);


String issueKey = jiraService.updateIssue(agileProjectValue, entity.getId(), fields);

return jiraService.getSingleAgileEntityIssue(agileProjectValue, issueKey);
}

private Map<String,String> getFieldsFromAgileEntity(AgileEntity entity, JIRAServiceProvider.JIRAService service) {
Map<String, String> fields = new HashMap<>();

Iterator<Map.Entry<String, DataField>> fieldsIterator = entity.getAllFields();

while (fieldsIterator.hasNext()) {
Map.Entry<String, DataField> field = fieldsIterator.next();

DataField dataField = field.getValue();

// As of PPM 9.50, data fields coming from PPM can be either simple string, simple User, or list of Users.
if (dataField == null) {
fields.put(field.getKey(), null);
} else if (DataField.DATA_TYPE.USER.equals(dataField.getType())) {
// This is one or more user; however, in JIRA the user fields usually only take one user - or at least that's how we'll synch them.
User user = null;
if (dataField.isList()) {
// PPM Multi user field
List<User> users = (List<User>)dataField.get();
if (users != null && !users.isEmpty()) {
user = users.get(0);
}
} else {
// Single user
user = (User)dataField.get();
}

if (user == null) {
fields.put(field.getKey(), null);
} else {
// We need to retrieve the right Jira user matching the PPM user's email or username.
String jiraUsername = service.getJiraUsernameFromPpmUser(user);
fields.put(field.getKey(), jiraUsername == null ? null : JIRA_NAME_PREFIX + jiraUsername);
}

} else {
// we consider it a single String value.
fields.put(field.getKey(), dataField.get() == null ? null : dataField.get().toString());
}
}

return fields;
}

@Override public AgileEntity createEntity(String agileProjectValue, String entityType, AgileEntity entity,
ValueSet instanceConfigurationParameters)
{
JIRAServiceProvider.JIRAService jiraService = service.get(instanceConfigurationParameters);

Map<String, String> fields = getFieldsFromAgileEntity(entity, jiraService);

String issueKey = jiraService.createIssue(agileProjectValue, fields, null, entityType);

return jiraService.getSingleAgileEntityIssue(agileProjectValue, issueKey);
}

@Override public List<AgileEntity> getEntities(String agileProjectValue, String entityType,
ValueSet instanceConfigurationParameters, Set<String> entityIds, Date modifiedSinceDate)
{

if (entityIds == null || entityIds.isEmpty()) {
return new ArrayList<AgileEntity>();
}

return service.get(instanceConfigurationParameters).getAgileEntityIssuesModifiedSince(entityIds, modifiedSinceDate);
}

@Override public AgileEntity getEntity(String agileProjectValue, String entityType,
ValueSet instanceConfigurationParameters, String entityId)
{
if (StringUtils.isBlank(entityId)) {
return null;
}

return service.get(instanceConfigurationParameters).getSingleAgileEntityIssue(agileProjectValue, entityId);
}

}
Loading

0 comments on commit 301501c

Please sign in to comment.