package com.lmitsoftware.ctf; import java.rmi.RemoteException; import java.util.Calendar; import java.util.Collection; import java.util.HashMap; import javax.xml.rpc.ServiceException; import mobi.jenkinsci.alm.ALMClient; import mobi.jenkinsci.alm.Item; import mobi.jenkinsci.alm.Project; import mobi.jenkinsci.alm.Sprint; import mobi.jenkinsci.alm.SprintSummary; import mobi.jenkinsci.plugin.PluginConfig; import org.apache.log4j.Logger; import com.collabnet.ce.soap53.webservices.planning.Artifact2SoapList; import com.collabnet.ce.soap53.webservices.planning.Artifact2SoapRow; import com.collabnet.ce.soap53.webservices.planning.ArtifactsInPlanningFolderSoapRow; import com.collabnet.ce.soap53.webservices.planning.CollabNetSoap; import com.collabnet.ce.soap53.webservices.planning.CollabNetSoapServiceLocator; import com.collabnet.ce.soap53.webservices.planning.FrsAppSoap; import com.collabnet.ce.soap53.webservices.planning.FrsAppSoapServiceLocator; import com.collabnet.ce.soap53.webservices.planning.InvalidSessionFault; import com.collabnet.ce.soap53.webservices.planning.NoSuchObjectFault; import com.collabnet.ce.soap53.webservices.planning.PermissionDeniedFault; import com.collabnet.ce.soap53.webservices.planning.PlanningAppSoap; import com.collabnet.ce.soap53.webservices.planning.PlanningAppSoapServiceLocator; import com.collabnet.ce.soap53.webservices.planning.PlanningFolderSoapRow; import com.collabnet.ce.soap53.webservices.planning.PlanningFolderSummarySoapDO; import com.collabnet.ce.soap53.webservices.planning.ProjectSoapRow; import com.collabnet.ce.soap53.webservices.planning.SystemFault; import com.google.inject.Inject; import com.google.inject.Singleton; @Singleton public class CTFClient implements ALMClient { private static Logger log = Logger.getLogger(CTFClient.class); private CollabNetSoap main; private PlanningAppSoap planning; private FrsAppSoap release; private String sessionid; private String url; private String username; @Inject public CTFClient(PluginConfig pluginConf) throws ServiceException { this.url = pluginConf.getUrl(); this.username = pluginConf.getUsername(); if (!url.endsWith("/")) url = url + "/"; String mainUrl = url + "ce-soap50/services/CollabNet"; String planningUrl = url + "ce-soap50/services/PlanningApp"; String releaseUrl = url + "ce-soap50/services/FrsApp"; log.info("Teamforge endpoints: \n" + "main=" + mainUrl + "\n" + "planning=" + planningUrl); CollabNetSoapServiceLocator mainLocator = new CollabNetSoapServiceLocator(); mainLocator.setCollabNetEndpointAddress(mainUrl); main = mainLocator.getCollabNet(); PlanningAppSoapServiceLocator planningServiceLocator = new PlanningAppSoapServiceLocator(); planningServiceLocator.setPlanningAppEndpointAddress(planningUrl); planning = planningServiceLocator.getPlanningApp(); FrsAppSoapServiceLocator releaseServiceLocator = new FrsAppSoapServiceLocator(); releaseServiceLocator.setFrsAppEndpointAddress(releaseUrl); release = releaseServiceLocator.getFrsApp(); try { String version = main.getApiVersion(); log.info("Teamforge remote version: " + version); login(username, pluginConf.getPassword()); log.info("Signed in as " + username); } catch (RemoteException ex) { log.warn("Unable to retrieve API version from url " + url, ex); } } /* * (non-Javadoc) * * @see com.lmitsoftware.ctf.ALMClient#login(java.lang.String, * java.lang.String) */ @Override public void login(String username, String password) throws RemoteException { try { logout(); this.username = username; this.sessionid = main.login(username, password); } catch (RemoteException e) { sessionid = null; throw e; } } /* * (non-Javadoc) * * @see com.lmitsoftware.ctf.ALMClient#logout() */ @Override public void logout() throws RemoteException { try { if (this.sessionid != null) { main.logoff(username, sessionid); } } finally { this.sessionid = null; this.username = null; } } /* * (non-Javadoc) * * @see com.lmitsoftware.ctf.ALMClient#getProjects() */ @Override public Project[] getProjects() throws RemoteException { ProjectSoapRow[] projectSoapRows = main.getProjectList(sessionid).getDataRows(); Project[] projects = new Project[projectSoapRows.length]; for (int i = 0; i < projectSoapRows.length; i++) { ProjectSoapRow projectRow = projectSoapRows[i]; projects[i] = new Project(projectRow.getId(), projectRow.getTitle(), projectRow.getPath()); } return projects; } @Override public SprintSummary getSprintSummary(String parentId) throws RemoteException { try { PlanningFolderSummarySoapDO folderSummary = planning.getPlanningFolderSummary(sessionid, parentId); return new SprintSummary(folderSummary.getTotalOpen(), folderSummary.getTotalClosed()); } catch (Exception e) { throw new RemoteException("Unable to get folder summary for " + parentId, e); } } @Override public Sprint[] getFolderList(String projectId) throws RemoteException { PlanningFolderSoapRow[] folders = planning.getPlanningFolderList(sessionid, projectId, false) .getDataRows(); Sprint[] sprints = new Sprint[folders.length]; for (int i = 0; i < folders.length; i++) { PlanningFolderSoapRow folder = folders[i]; sprints[i] = new Sprint(folder.getId(), folder.getTitle(), folder.getPath()); } return sprints; } @Override public String getProjectId(String projectPath) throws RemoteException { ProjectSoapRow[] projects = main.getProjectList(sessionid).getDataRows(); for (ProjectSoapRow projectSoapRow : projects) { if (projectSoapRow.getPath().equalsIgnoreCase(projectPath)) { return projectSoapRow.getId(); } } throw new RemoteException("Project with path " + projectPath + " was not found"); } @Override public String getFolderId(String projectId, String folderPath) throws RemoteException { PlanningFolderSoapRow[] folders = planning.getPlanningFolderList(sessionid, projectId, true) .getDataRows(); for (PlanningFolderSoapRow planningFolderSoapRow : folders) { String path = planningFolderSoapRow.getPath(); if (path.equalsIgnoreCase(folderPath)) { return planningFolderSoapRow.getId(); } } throw new RemoteException("Folder with path " + folderPath + " was not found in project " + projectId); } @Override public Item[] getFolderArtifacts(String folderId) throws RemoteException { ArtifactsInPlanningFolderSoapRow[] artifacts = planning.getArtifactListInPlanningFolder(sessionid, folderId, null, true).getDataRows(); Item[] items = new Item[artifacts.length]; for (int i = 0; i < artifacts.length; i++) { ArtifactsInPlanningFolderSoapRow artifact = artifacts[i]; items[i] = new Item(artifact.getId(), artifact.getStatus(), artifact.getTitle(), artifact.getPriority(), artifact.getDescription(), artifact.getSubmittedByFullname(), artifact.getAssignedToFullname(), artifact.getSubmittedDate(), artifact.getLastModifiedDate(), artifact.getFolderPathString()); } return items; } @Override public Sprint[] getSubSprintPlan(String sprintId) throws RemoteException { return getFolderList(sprintId); } public Collection<Item> getReportedOrFixedArtifacts(String relId) throws NoSuchObjectFault, InvalidSessionFault, SystemFault, PermissionDeniedFault, RemoteException { HashMap<String, Item> outItems = new HashMap<String, Item>(); if (relId != null && relId.trim().length() > 0) { getArtifactsById( release.getArtifactListReportedInRelease(sessionid, relId) .getDataRows(), outItems); getArtifactsById( release.getArtifactListResolvedInRelease(sessionid, relId) .getDataRows(), outItems); } return outItems.values(); } private void getArtifactsById(Artifact2SoapRow[] artifacts, HashMap<String, Item> outItems) throws RemoteException, NoSuchObjectFault, InvalidSessionFault, SystemFault, PermissionDeniedFault { for (Artifact2SoapRow artifact : artifacts) { String artifactId = artifact.getId(); Item outItem = outItems.get(artifactId); if (outItem == null) { outItem = new Item(artifact.getId(), artifact.getStatus(), artifact.getTitle(), artifact.getPriority(), artifact.getDescription(), artifact.getSubmittedByFullname(), artifact.getAssignedToFullname(), artifact.getSubmittedDate(), artifact.getLastModifiedDate(), artifact.getFolderPathString()); outItems.put(artifactId, outItem); } } } }