├── src └── main │ ├── config │ ├── com.aspectsecurity.contrast.integration.newrelic.contrast.json │ ├── template_newrelic.properties │ └── example_logging.properties │ ├── script │ └── contrast-newrelic-plugin.sh │ └── java │ └── com │ └── aspectsecurity │ └── contrast │ └── integration │ └── newrelic │ ├── Main.java │ ├── ContrastAgentFactory.java │ ├── ContrastConfig.java │ └── ContrastAgent.java ├── .gitignore ├── README.md ├── LICENSE └── pom.xml /src/main/config/com.aspectsecurity.contrast.integration.newrelic.contrast.json: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/main/config/template_newrelic.properties: -------------------------------------------------------------------------------- 1 | licenseKey = YOUR_LICENSE_KEY_HERE -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.class 2 | 3 | # Package Files # 4 | *.jar 5 | *.war 6 | *.ear 7 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | contrast-newrelic-plugin 2 | ======================== 3 | 4 | A plugin for monitoring Contrast Metrics in the New Relic Platform 5 | -------------------------------------------------------------------------------- /src/main/script/contrast-newrelic-plugin.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Ensure JAVA_HOME is set 4 | 5 | # Build the Classpath 6 | CP="./contrast-newrelic-plugin.jar" 7 | 8 | for f in `ls lib` 9 | do 10 | CP="$CP:lib/$f" 11 | done 12 | 13 | java -cp "$CP" com.aspectsecurity.contrast.integration.newrelic.Main -------------------------------------------------------------------------------- /src/main/java/com/aspectsecurity/contrast/integration/newrelic/Main.java: -------------------------------------------------------------------------------- 1 | package com.aspectsecurity.contrast.integration.newrelic; 2 | 3 | import com.newrelic.metrics.publish.Runner; 4 | import com.newrelic.metrics.publish.configuration.ConfigurationException; 5 | 6 | import java.io.File; 7 | 8 | public class Main { 9 | public static void main(String[] args) { 10 | Runner runner = new Runner(); 11 | runner.add(new ContrastAgentFactory()); 12 | 13 | try { 14 | //Never returns 15 | runner.setupAndRun(); 16 | } catch (ConfigurationException e) { 17 | e.printStackTrace(); 18 | System.err.println("Error configuring"); 19 | System.exit(-1); 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/main/java/com/aspectsecurity/contrast/integration/newrelic/ContrastAgentFactory.java: -------------------------------------------------------------------------------- 1 | package com.aspectsecurity.contrast.integration.newrelic; 2 | 3 | import com.newrelic.metrics.publish.Agent; 4 | import com.newrelic.metrics.publish.AgentFactory; 5 | import com.newrelic.metrics.publish.configuration.ConfigurationException; 6 | 7 | import java.util.Map; 8 | 9 | public class ContrastAgentFactory extends AgentFactory { 10 | public ContrastAgentFactory() { 11 | super(ContrastAgent.AGENT_CONFIG_FILE); 12 | } 13 | 14 | @Override 15 | public Agent createConfiguredAgent(Map stringObjectMap) throws ConfigurationException { 16 | ContrastConfig config = new ContrastConfig(); 17 | config.setAppName(stringObjectMap.get("appname").toString()); 18 | config.setApiKey(stringObjectMap.get("apikey").toString()); 19 | config.setServiceKey(stringObjectMap.get("servicekey").toString()); 20 | config.setHostname(stringObjectMap.get("hostname").toString()); 21 | config.setUsername(stringObjectMap.get("username").toString()); 22 | return new ContrastAgent(config); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/main/java/com/aspectsecurity/contrast/integration/newrelic/ContrastConfig.java: -------------------------------------------------------------------------------- 1 | package com.aspectsecurity.contrast.integration.newrelic; 2 | 3 | public class ContrastConfig { 4 | private String appName; 5 | private String username; 6 | private String serviceKey; 7 | private String apiKey; 8 | private String hostname; 9 | 10 | public String getAppName() { 11 | return appName; 12 | } 13 | 14 | public void setAppName(String appName) { 15 | this.appName = appName; 16 | } 17 | 18 | public String getUsername() { 19 | return username; 20 | } 21 | 22 | public void setUsername(String username) { 23 | this.username = username; 24 | } 25 | 26 | public String getServiceKey() { 27 | return serviceKey; 28 | } 29 | 30 | public void setServiceKey(String serviceKey) { 31 | this.serviceKey = serviceKey; 32 | } 33 | 34 | public String getApiKey() { 35 | return apiKey; 36 | } 37 | 38 | public void setApiKey(String apiKey) { 39 | this.apiKey = apiKey; 40 | } 41 | 42 | public String getHostname() { 43 | return hostname; 44 | } 45 | 46 | public void setHostname(String hostname) { 47 | this.hostname = hostname; 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/main/config/example_logging.properties: -------------------------------------------------------------------------------- 1 | 2 | # The com.newrelic.metrics.publish logger has been set to the log level ALL which will send all log records to the below handlers. 3 | # Adjust the FileHandler and ConsoleHandler log levels below to filter the amount of data to be logged to their respective locations. 4 | 5 | # Valid Log Levels for New Relic Logging 6 | # OFF - No Logging -- If no logging is set, errors will not be logged. Use this setting with care. 7 | # SEVERE - Logging only exceptions 8 | # INFO - Logging informational data -- default level 9 | # FINE - Logging debug level data -- sent metrics are logged at this level 10 | # ALL - Logging at all available levels 11 | 12 | # Uncomment the following 'java.util.logging.FileHandler' lines to enable logging to file 13 | # Setting the FileHandler log level to OFF will still create an empty log file. Comment out the following lines to turn file logging off completely. 14 | #java.util.logging.FileHandler.level = FINE 15 | #java.util.logging.FileHandler.pattern = newrelic.log 16 | #java.util.logging.FileHandler.formatter = java.util.logging.SimpleFormatter 17 | #java.util.logging.FileHandler.append = true 18 | 19 | # Log Level for Console -- Set level to OFF for no logging to Console, or one of the other valid log levels described above. 20 | java.util.logging.ConsoleHandler.level = INFO 21 | 22 | # Default Logger Handlers 23 | com.newrelic.metrics.publish.handlers = java.util.logging.FileHandler, java.util.logging.ConsoleHandler -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2013, Contrast-Security-OSS 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without modification, 5 | are permitted provided that the following conditions are met: 6 | 7 | Redistributions of source code must retain the above copyright notice, this 8 | list of conditions and the following disclaimer. 9 | 10 | Redistributions in binary form must reproduce the above copyright notice, this 11 | list of conditions and the following disclaimer in the documentation and/or 12 | other materials provided with the distribution. 13 | 14 | Neither the name of the {organization} nor the names of its 15 | contributors may be used to endorse or promote products derived from 16 | this software without specific prior written permission. 17 | 18 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 19 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 20 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 21 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR 22 | ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 23 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 24 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 25 | ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 27 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | -------------------------------------------------------------------------------- /src/main/java/com/aspectsecurity/contrast/integration/newrelic/ContrastAgent.java: -------------------------------------------------------------------------------- 1 | package com.aspectsecurity.contrast.integration.newrelic; 2 | 3 | import com.contrastsecurity.rest.*; 4 | import com.newrelic.metrics.publish.Agent; 5 | 6 | import java.util.logging.Logger; 7 | 8 | public class ContrastAgent extends Agent { 9 | private static final Logger LOG = Logger.getLogger(ContrastAgent.class.getName()); 10 | 11 | public static final String AGENT_CONFIG_FILE = "com.aspectsecurity.contrast.integration.newrelic.contrast.json"; 12 | 13 | private static final String CONTRAST = "Contrast"; 14 | 15 | private ContrastConfig contrastConfig; 16 | 17 | private ContrastConnection contrast; 18 | 19 | public ContrastAgent(ContrastConfig contrastConfig) { 20 | // Initialize the New Relic Agent API 21 | super("com.aspectsecurity.contrast.integration.newrelic", "1.0.0"); 22 | 23 | this.contrastConfig = contrastConfig; 24 | 25 | // Initialize the Contrast Client API 26 | try { 27 | contrast = new ContrastConnection( 28 | this.contrastConfig.getUsername(), 29 | this.contrastConfig.getServiceKey(), 30 | this.contrastConfig.getApiKey(), 31 | this.contrastConfig.getHostname() 32 | ); 33 | } catch (Exception e) { 34 | LOG.severe("Unable to initialize the Contrast SDK"); 35 | System.exit(1); 36 | } 37 | } 38 | 39 | @Override 40 | public void pollCycle() { 41 | /* 42 | List apps = contrast.getApplications(); 43 | 44 | if (apps == null) { 45 | LOG.severe("No applications found for account. Please check your configuration."); 46 | System.exit(0); 47 | } 48 | 49 | reportMetric(CONTRAST, "value", apps.getApps().size()); 50 | 51 | for (Application application : apps) 52 | if (application.getName().equals(contrastConfig.getAppName())) { 53 | try { 54 | List traces = contrast.getTraces(application.getId()); 55 | List libraries = contrast.getLibraries(application.getId()); 56 | Coverage coverage = contrast.getCoverage(application.getId()); 57 | 58 | // Total Traces 59 | reportMetric(getComponentLabel("Traces"), "traces", traces.size()); 60 | 61 | // Libraries 62 | int stale, unknown, total; 63 | for (Library lib : libraries) { 64 | lib. 65 | } 66 | 67 | reportMetric(getComponentLabel("Libraries/Stale"), "libraries", ); 68 | reportMetric(getComponentLabel("Libraries/Total"), "libraries", application.getAppStats().getAppLibraries().getTotal()); 69 | reportMetric(getComponentLabel("Libraries/Unknown"), "libraries", application.getAppStats().getAppLibraries().getUnknown()); 70 | 71 | // Coverage 72 | reportMetric(getComponentLabel("Coverage/Total"), "methods", application.getAppStats().getMethodsTotal()); 73 | reportMetric(getComponentLabel("Coverage/Seen"), "methods", application.getAppStats().getMethodsSeen()); 74 | 75 | // Vulnerabilities (By Severity) 76 | reportMetric(getComponentLabel("Vulnerabilities/Severity/Critical"), "vulnerabilities", application.getAppStats().getAppVulns().getCriticals()); 77 | reportMetric(getComponentLabel("Vulnerabilities/Severity/High"), "vulnerabilities", application.getAppStats().getAppVulns().getHighs()); 78 | reportMetric(getComponentLabel("Vulnerabilities/Severity/Medium"), "vulnerabilities", application.getAppStats().getAppVulns().getMediums()); 79 | reportMetric(getComponentLabel("Vulnerabilities/Severity/Low"), "vulnerabilities", application.getAppStats().getAppVulns().getLows()); 80 | reportMetric(getComponentLabel("Vulnerabilities/Severity/Note"), "vulnerabilities", application.getAppStats().getAppVulns().getNotes()); 81 | 82 | // Vulnerabilities (By Type) 83 | for (String key : application.getUniqueTraceTypes().keySet()) { 84 | reportMetric(getComponentLabel("Vulnerabilities/Category/" + key), "vulnerabilities", application.getUniqueTraceTypes().get(key).size()); 85 | } 86 | } catch (Exception e) { 87 | 88 | } 89 | } 90 | */ 91 | } 92 | 93 | @Override 94 | public String getComponentHumanLabel() { 95 | return contrastConfig.getAppName(); 96 | } 97 | 98 | private String getComponentLabel(String metric) { 99 | return CONTRAST + "/" + metric; 100 | } 101 | } 102 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | com.contrastsecurity 8 | contrast-newrelic-plugin 9 | 1.0.0-SNAPSHOT 10 | 11 | Contrast Metrics 12 | 13 | 14 | 15 | cloudbees-contrast-snapshot 16 | https://repository-contrast.forge.cloudbees.com/snapshot 17 | 18 | false 19 | 20 | 21 | true 22 | 23 | 24 | 25 | cloudbees-contrast-release 26 | https://repository-contrast.forge.cloudbees.com/release 27 | 28 | true 29 | 30 | 31 | false 32 | 33 | 34 | 35 | 36 | 37 | 1.0.0-SNAPSHOT 38 | 39 | 40 | 41 | 42 | com.contrastsecurity 43 | contrast-sdk-java 44 | ${contrast.sdk.version} 45 | 46 | 47 | com.newrelic.plugin 48 | metrics-publish 49 | 1.0.2 50 | 51 | 52 | com.newrelic.agent.java 53 | newrelic-api 54 | 3.2.1 55 | compile 56 | 57 | 58 | org.testng 59 | testng 60 | 6.8 61 | test 62 | 63 | 64 | org.mockito 65 | mockito-all 66 | 1.9.5 67 | test 68 | 69 | 70 | org.apache.httpcomponents 71 | httpclient 72 | 4.2.4 73 | 74 | 75 | org.apache.httpcomponents 76 | httpcore 77 | 4.2.4 78 | 79 | 80 | commons-codec 81 | commons-codec 82 | 1.7 83 | 84 | 85 | commons-io 86 | commons-io 87 | 2.4 88 | 89 | 90 | com.google.code.gson 91 | gson 92 | 2.2.4 93 | 94 | 95 | 96 | 97 | 98 | 99 | maven-jar-plugin 100 | 2.4 101 | 102 | ${project.basedir}/target/dist 103 | contrast-newrelic-plugin 104 | 105 | 106 | 107 | maven-compiler-plugin 108 | 109 | 1.6 110 | 1.6 111 | 112 | 113 | 114 | maven-resources-plugin 115 | 2.6 116 | 117 | 118 | copy-config 119 | generate-resources 120 | 121 | copy-resources 122 | 123 | 124 | ${project.basedir}/target/dist/config 125 | 126 | 127 | ${project.build.sourceDirectory}/config 128 | 129 | **/* 130 | 131 | 132 | 133 | 134 | 135 | 136 | copy-script 137 | generate-sources 138 | 139 | copy-resources 140 | 141 | 142 | ${project.basedir}/target/dist 143 | 144 | 145 | ${project.basedir}/src/main/script 146 | 147 | **/* 148 | 149 | true 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | maven-dependency-plugin 158 | 2.7 159 | 160 | 161 | copy-dependencies 162 | install 163 | 164 | copy-dependencies 165 | 166 | 167 | ${project.basedir}/target/dist/lib 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | test-config 178 | 179 | 180 | 181 | maven-resources-plugin 182 | 2.6 183 | 184 | 185 | copy-test-config 186 | generate-resources 187 | 188 | copy-resources 189 | 190 | 191 | ${project.basedir}/target/dist/config 192 | 193 | 194 | ${user.home}/contrast-newrelic-plugin/config 195 | 196 | **/* 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | --------------------------------------------------------------------------------