package com.coverity.ps.common.plugins.bugtracking; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.net.MalformedURLException; import java.net.URL; import java.rmi.RemoteException; import java.security.KeyManagementException; import java.security.NoSuchAlgorithmException; import java.security.SecureRandom; import java.security.cert.X509Certificate; import java.util.Calendar; import java.util.Date; import java.util.Map; import javax.net.ssl.HostnameVerifier; import javax.net.ssl.HttpsURLConnection; import javax.net.ssl.SSLContext; import javax.net.ssl.SSLSession; import javax.net.ssl.TrustManager; import javax.net.ssl.X509TrustManager; import javax.xml.rpc.ServiceException; import com.atlassian.jira.rpc.soap.beans.RemoteComponent; import com.atlassian.jira.rpc.soap.beans.RemoteCustomFieldValue; import com.atlassian.jira.rpc.soap.beans.RemoteField; import com.atlassian.jira.rpc.soap.beans.RemoteIssue; import com.atlassian.jira.rpc.soap.beans.RemoteVersion; import com.atlassian.jira.rpc.soap.jirasoapservice_v2.JiraSoapService; import com.atlassian.jira.rpc.soap.jirasoapservice_v2.JiraSoapServiceService; import com.atlassian.jira.rpc.soap.jirasoapservice_v2.JiraSoapServiceServiceLocator; import com.coverity.ps.common.CimProxy; import com.coverity.ps.common.config.ConfigurationManager; import com.coverity.ws.v4.CovRemoteServiceException_Exception; import com.coverity.ws.v4.MergedDefectDataObj; public class Jira implements BugTracking { // Constants for issue creation static TrustManager[] trustAllCerts; static HostnameVerifier hv; String jiraProject; private JiraSoapServiceService jiraSoapServiceLocator; private JiraSoapService jiraSoapService; private String token; private MergedDefectDataObj defect; private String project; // set proxy settings static { // proxy settings System.setProperty("https.proxyHost", "proxy.jf.intel.com"); System.setProperty("https.proxyPort", "911"); System.setProperty("https.proxySet", "true"); } public Jira(String webServicePort, String userName, String password) throws RemoteException, MalformedURLException, NoSuchAlgorithmException, KeyManagementException { // disabling certificate validation disableCertificateValidation(); SSLContext sc = SSLContext.getInstance("SSL"); sc.init(null, trustAllCerts, new SecureRandom()); HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory()); HttpsURLConnection.setDefaultHostnameVerifier(hv); createService(new URL(webServicePort), userName, password); } public Jira() throws RemoteException, MalformedURLException { ConfigurationManager configurationManager = ConfigurationManager.getInstance(); URL webServicePort = new URL(configurationManager.getBugTrackingAddress()); String userName = configurationManager.getBugTrackingUser(); String password = configurationManager.getBugTrackingPassword(); createService(webServicePort, userName, password); } public void createService(URL webServicePort, String userName, String password) throws RemoteException, MalformedURLException { jiraSoapServiceLocator = new JiraSoapServiceServiceLocator(); try { this.jiraSoapService = jiraSoapServiceLocator.getJirasoapserviceV2(webServicePort); this.token = jiraSoapService.login(userName, password); } catch (ServiceException e) { throw new RuntimeException("ServiceException during SOAPClient contruction", e); } } public String createBug(String project, MergedDefectDataObj defect, boolean isDryRun) throws Exception { this.defect = defect; this.project = project; Map<String, String> properties = ConfigurationManager.getInstance().getBugProperties(); return createIssue(properties); } private RemoteComponent getComponent(String name) throws java.rmi.RemoteException { RemoteComponent[] components = jiraSoapService.getComponents(token, jiraProject); for(RemoteComponent component : components) { if(component.getName().equals(name)) { return component; } } return null; } private RemoteVersion getVersion(String name) throws java.rmi.RemoteException { RemoteVersion[] versions = jiraSoapService.getVersions(token, jiraProject); for(RemoteVersion version : versions) { if(version.getName().equals(name)) { return version; } } return new RemoteVersion(); } private RemoteCustomFieldValue createCustomFieldValue(String name, String value) throws java.rmi.RemoteException { return new RemoteCustomFieldValue(getCustomField(name).getId(), "", new String[] { value }); } private RemoteField getCustomField(String name) throws java.rmi.RemoteException { RemoteField[] fields = jiraSoapService.getCustomFields(token); for(RemoteField field : fields) { if(field.getName().equals(name)) { return field; } } return null; } private String createIssue(Map<String, String> properties) throws java.rmi.RemoteException, CovRemoteServiceException_Exception { final String issueId = properties.get("issue-type"); final String summary; if(this.defect != null) { summary = properties.get("summary") + " : " + this.defect.getCheckerName() + " : " + this.defect.getCid(); } else { summary = properties.get("summary") + " : " + new Date(); } final String priority = properties.get("priority"); final String component = properties.get("component"); final String version = properties.get("version"); final String assignee = properties.get("assignee"); final String environment = properties.get("environment"); this.jiraProject = properties.get("project"); if(!validInput(issueId) || !validInput(summary) || !validInput(priority) || !validInput(component) || !validInput(version) || !validInput(assignee) || !validInput(environment) || !validInput(this.jiraProject)) { return null; } // Create the issue RemoteIssue issue = new RemoteIssue(); issue.setProject(jiraProject); issue.setType(issueId); issue.setSummary(summary); issue.setPriority(priority); if(this.defect != null) { StringBuilder defectUrl = new StringBuilder("http://"); defectUrl.append( ConfigurationManager.getInstance().getAddress()); defectUrl.append(':'); defectUrl.append( ConfigurationManager.getInstance().getPort()); defectUrl.append("/sourcebrowser.htm?projectId="); defectUrl.append(CimProxy.getInstance().getProject(this.project).getProjectKey()); defectUrl.append("#mergedDefectId="); defectUrl.append(this.defect.getCid()); StringBuilder description = new StringBuilder("A "); description.append(this.defect.getCheckerName()); description.append(" Coverity defect was found in the "); description.append(this.jiraProject); description.append(" project. This defect was detected in file the '"); description.append(this.defect.getFilePathname()); description.append("' within function '"); description.append(this.defect.getFunctionDisplayName()); description.append(".\n\nA link to the defect is below\n"); description.append(defectUrl.toString()); issue.setDescription(description.toString()); } else { issue.setDescription("Coverity JIRA plug-in testing"); } issue.setDuedate(Calendar.getInstance()); issue.setAssignee(assignee); issue.setEnvironment(environment); // Add remote components issue.setComponents(new RemoteComponent[] { getComponent(component) }); // Add remote versions issue.setAffectsVersions(new RemoteVersion[] { getVersion(version) } ); // Add custom fields // TODO: map custom values that defect RemoteCustomFieldValue[] customFieldValues = new RemoteCustomFieldValue[] { createCustomFieldValue("Reproducibility", "10606"), // 100% createCustomFieldValue("Profile/s", "10811"), // smart phone createCustomFieldValue("Defect Classification", "10836"), // security createCustomFieldValue("Severity", "10006") // normal }; issue.setCustomFieldValues(customFieldValues); // Run the create issue code RemoteIssue returnedIssue = jiraSoapService.createIssue(token, issue); final String issueKey = returnedIssue.getKey(); // System.out.println("\tSuccessfully created issue " + issueKey); // dumpIssue(returnedIssue); return issueKey; } private boolean validInput(String field) { if(field == null || field.length() == 0) { return false; } return true; } private static void dumpIssue(RemoteIssue issue) { System.out.println("Issue Details : "); Method[] declaredMethods = issue.getClass().getDeclaredMethods(); for (int i = 0; i < declaredMethods.length; i++) { Method declaredMethod = declaredMethods[i]; if (declaredMethod.getName().startsWith("get") && declaredMethod.getParameterTypes().length == 0) { System.out.print("\t Issue." + declaredMethod.getName() + "() -> "); try { Object obj = declaredMethod.invoke(issue, new Object[] {}); if (obj instanceof Object[]) { obj = arrayToStr((Object[]) obj); } System.out.println(obj); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } } } } private static String arrayToStr(Object[] o) { StringBuffer sb = new StringBuffer(); for (int i = 0; i < o.length; i++) { sb.append(o[i]).append(" "); } return sb.toString(); } public static void disableCertificateValidation() { // Create a trust manager that does not validate certificate chains trustAllCerts = new TrustManager[] { new X509TrustManager() { public X509Certificate[] getAcceptedIssuers() { return new X509Certificate[0]; } public void checkClientTrusted(X509Certificate[] certs, String authType) {} public void checkServerTrusted(X509Certificate[] certs, String authType) {} }}; // Ignore differences between given hostname and certificate hostname hv = new HostnameVerifier() { public boolean verify(String hostname, SSLSession session) { return true; } }; } /* * Main command line driver. Please see class constructor for required arguments. */ public static void main(String[] args) { try { Map<String, String> properties = ConfigurationManager.getInstance().getBugProperties(); Jira jira = new Jira( "https://tz.otcshare.org/jira/rpc/soap/jirasoapservice-v2?wsdl", "coverityuser", "COVERITY.123"); jira.createIssue(properties); } catch (Exception e) { e.printStackTrace(); } } }