use of com.newrelic.agent.extension.beans.Extension in project newrelic-java-agent by newrelic.
the class ExtensionDomParser method parseDocument.
/**
* Reads in the XML file and returns an extension.
*
* @param extensionXML The input xml
* @param setSchema whether or not to set the schema
*/
public static Extension parseDocument(String extensionXML, boolean setSchema) throws SAXException, IOException, ParserConfigurationException, NoSuchMethodException, SecurityException {
Document doc = getDocument(extensionXML, setSchema);
trimTextNodeWhitespace(doc.getDocumentElement());
doc = fixNamespace(doc);
// validate the document
Schema schema = schemaDocumentFactory.getSchema();
Validator validator = schema.newValidator();
validator.validate(new DOMSource(doc));
try {
Extension extension = new Extension();
NodeList extensionElements = doc.getElementsByTagNameNS("*", "extension");
if (extensionElements != null && extensionElements.getLength() == 1) {
Node extensionElement = extensionElements.item(0);
extension.setName(getAttribute("name", extensionElement, null));
extension.setVersion(Double.parseDouble(getAttribute("version", extensionElement, "1.0")));
extension.setEnabled(Boolean.valueOf(getAttribute("enabled", extensionElement, "true")));
NodeList extensionChildNodes = extensionElement.getChildNodes();
Node instrumentationElement = getFirstInstrumentationNode(extensionChildNodes);
if (instrumentationElement != null) {
Extension.Instrumentation instrumentation = new Extension.Instrumentation();
instrumentation.setMetricPrefix(getAttribute("metricPrefix", instrumentationElement, null));
extension.setInstrumentation(instrumentation);
List<Extension.Instrumentation.Pointcut> pointcuts = instrumentation.getPointcut();
NodeList instrumentationChildNodes = instrumentationElement.getChildNodes();
for (int i = 0; i < instrumentationChildNodes.getLength(); i++) {
Node instrumentationChildNode = instrumentationChildNodes.item(i);
if (instrumentationChildNode.getNodeName().equals("pointcut") || instrumentationChildNode.getNodeName().endsWith(":pointcut")) {
Extension.Instrumentation.Pointcut pointcut = new Extension.Instrumentation.Pointcut();
pointcut.setExcludeFromTransactionTrace(Boolean.valueOf(getAttribute("excludeFromTransactionTrace", instrumentationChildNode, "false")));
pointcut.setLeaf(Boolean.valueOf(getAttribute("leaf", instrumentationChildNode, "false")));
pointcut.setIgnoreTransaction(Boolean.valueOf(getAttribute("ignoreTransaction", instrumentationChildNode, "false")));
pointcut.setMetricNameFormat(getAttribute("metricNameFormat", instrumentationChildNode, null));
pointcut.setTransactionStartPoint(Boolean.valueOf(getAttribute("transactionStartPoint", instrumentationChildNode, "false")));
pointcut.setTransactionType(getAttribute("transactionType", instrumentationChildNode, null));
List<Extension.Instrumentation.Pointcut.Method> methods = pointcut.getMethod();
List<String> traceReturnTypeDescriptors = pointcut.getTraceReturnTypeDescriptors();
NodeList pointcutChildNodes = instrumentationChildNode.getChildNodes();
for (int p = 0; p < pointcutChildNodes.getLength(); p++) {
Node node = pointcutChildNodes.item(p);
if (node.getNodeName().equals("className") || node.getNodeName().endsWith(":className")) {
Extension.Instrumentation.Pointcut.ClassName className = new Extension.Instrumentation.Pointcut.ClassName();
className.setIncludeSubclasses(Boolean.valueOf(getAttribute("includeSubclasses", node, "false")));
className.setValue(node.getTextContent());
pointcut.setClassName(className);
} else if (node.getNodeName().equals("interfaceName") || node.getNodeName().endsWith(":interfaceName")) {
pointcut.setInterfaceName(node.getTextContent());
} else if (node.getNodeName().equals("methodAnnotation") || node.getNodeName().endsWith(":methodAnnotation")) {
pointcut.setMethodAnnotation(node.getTextContent());
} else if (node.getNodeName().equals("traceLambda") || node.getNodeName().endsWith(":traceLambda")) {
pointcut.setTraceLambda(Boolean.valueOf(node.getTextContent()));
pointcut.setPattern(getAttribute("pattern", node, "^\\$?(lambda|anonfun)\\$(?<name>.*)"));
pointcut.setIncludeNonstatic(Boolean.parseBoolean(getAttribute("includeNonstatic", node, "false")));
} else if (node.getNodeName().equals("traceByReturnType") || node.getNodeName().endsWith(":traceByReturnType")) {
traceReturnTypeDescriptors.add(node.getTextContent());
} else if (node.getNodeName().equals("method") || node.getNodeName().endsWith(":method")) {
NodeList methodChildNodes = node.getChildNodes();
Extension.Instrumentation.Pointcut.Method method = new Extension.Instrumentation.Pointcut.Method();
for (int m = 0; m < methodChildNodes.getLength(); m++) {
Node methodChildNode = methodChildNodes.item(m);
if (methodChildNode.getNodeName().equals("name") || methodChildNode.getNodeName().endsWith(":name")) {
method.setName(methodChildNode.getTextContent());
} else if (methodChildNode.getNodeName().equals("returnType") || methodChildNode.getNodeName().endsWith(":returnType")) {
method.setReturnType(methodChildNode.getTextContent());
} else if (methodChildNode.getNodeName().equals("parameters") || methodChildNode.getNodeName().endsWith(":parameters")) {
Extension.Instrumentation.Pointcut.Method.Parameters parameters = new Extension.Instrumentation.Pointcut.Method.Parameters();
List<Extension.Instrumentation.Pointcut.Method.Parameters.Type> types = parameters.getType();
NodeList parametersChildNodes = methodChildNode.getChildNodes();
for (int p1 = 0; p1 < parametersChildNodes.getLength(); p1++) {
Node typeNode = parametersChildNodes.item(p1);
if (typeNode.getNodeName().equals("type") || typeNode.getNodeName().endsWith(":type")) {
Extension.Instrumentation.Pointcut.Method.Parameters.Type type = new Extension.Instrumentation.Pointcut.Method.Parameters.Type();
type.setAttributeName(getAttribute("attributeName", typeNode, null));
type.setValue(typeNode.getTextContent());
types.add(type);
}
}
method.setParameters(parameters);
}
}
methods.add(method);
} else if (node.getNodeName().equals("nameTransaction") || node.getNodeName().endsWith(":nameTransaction")) {
pointcut.setNameTransaction(new Extension.Instrumentation.Pointcut.NameTransaction());
}
}
pointcuts.add(pointcut);
}
}
}
}
return extension;
} catch (Exception ex) {
try {
Transformer transformer = TransformerFactory.newInstance().newTransformer();
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
// initialize StreamResult with File object to save to file
StreamResult result = new StreamResult(new StringWriter());
DOMSource source = new DOMSource(doc);
transformer.transform(source, result);
String xmlString = result.getWriter().toString();
System.out.println(xmlString);
} catch (Exception e) {
e.printStackTrace();
}
throw new IOException(ex);
}
}
use of com.newrelic.agent.extension.beans.Extension in project newrelic-java-agent by newrelic.
the class ReinstrumentUtilsTest method checkInputMildCardClasses.
@Test
public void checkInputMildCardClasses() {
SampleObject obj = new SampleObject();
ReinstrumentResult result = new ReinstrumentResult();
obj.getClass().getClassLoader();
Set<ClassLoader> loaders = new HashSet<>();
loaders.add(this.getClass().getClassLoader());
Extension ext = new Extension();
Instrumentation inst = new Instrumentation();
ext.setInstrumentation(inst);
Pointcut pc = new Pointcut();
inst.getPointcut().add(pc);
setClassName(pc, SampleObject.class);
// this should match
Method m1 = new Method();
m1.setName("yada");
pc.getMethod().add(m1);
Map<String, Class<?>> daClasses = new HashMap<>();
daClasses.put(SampleObject.class.getName(), SampleObject.class);
ReinstrumentUtils.checkInputClasses(result, loaders, ext, daClasses);
Object actual = result.getStatusMap().get(ReinstrumentResult.ERROR_KEY);
Assert.assertNull("There should not have been an error. Errors: " + actual, actual);
}
use of com.newrelic.agent.extension.beans.Extension in project newrelic-java-agent by newrelic.
the class ReinstrumentUtilsTest method checkInputMatchesClasses.
@Test
public void checkInputMatchesClasses() {
SampleObject obj = new SampleObject();
ReinstrumentResult result = new ReinstrumentResult();
obj.getClass().getClassLoader();
Set<ClassLoader> loaders = new HashSet<>();
loaders.add(this.getClass().getClassLoader());
Extension ext = new Extension();
Instrumentation inst = new Instrumentation();
ext.setInstrumentation(inst);
Pointcut pc = new Pointcut();
inst.getPointcut().add(pc);
setClassName(pc, SampleObject.class);
Method m1 = new Method();
m1.setName("getHello");
MethodParameters params1 = new MethodParameters(new ArrayList<String>());
m1.setParameters(params1);
Method m2 = new Method();
m2.setName("setHello");
MethodParameters params2 = new MethodParameters(Arrays.asList("boolean"));
m2.setParameters(params2);
Method m3 = new Method();
m3.setName("doTheWork");
MethodParameters params3 = new MethodParameters(Arrays.asList("java.lang.String", "int"));
m3.setParameters(params3);
pc.getMethod().addAll(Arrays.asList(m1, m2, m3));
Map<String, Class<?>> daClasses = new HashMap<>();
daClasses.put(SampleObject.class.getName(), SampleObject.class);
ReinstrumentUtils.checkInputClasses(result, loaders, ext, daClasses);
Object actual = result.getStatusMap().get(ReinstrumentResult.ERROR_KEY);
Assert.assertNull("There should not have been an error. Errors: " + actual, actual);
}
use of com.newrelic.agent.extension.beans.Extension in project newrelic-java-agent by newrelic.
the class XmlInstrumentValidator method validateInstrumentation.
/**
* Validates the instrumentation.
*
* @param params The command line parameters.
* @throws ClassNotFoundException Thrown if the class is not found.
* @throws RuntimeException Thrown if a problem when converting the xml.
* @throws IllegalArgumentException Thrown when the method or class can not be found on the class path.
* @throws IOException Thrown if the file can not be read.
* @throws SAXException Thrown if a problem parsing the document.
*/
protected static void validateInstrumentation(final XmlInstrumentParams params) throws Exception {
// read in the file - DOM Exception potentially thrown
Extension extension = ExtensionDomParser.readFile(params.getFile());
if (params.isDebug()) {
System.out.println("Xml was successfully read. Starting processing.");
}
// attempt to convert to point cuts - RuntimeException
// potentially thrown
List<ExtensionClassAndMethodMatcher> convertedPcs = ExtensionConversionUtility.convertToPointCutsForValidation(extension);
Instrumentation inst = extension.getInstrumentation();
// this really has already been checked
if (inst == null) {
throw new RuntimeException("The instrumentation propery must be set for the extension.");
}
List<Pointcut> origPcs = inst.getPointcut();
if (convertedPcs.size() != origPcs.size()) {
throw new IllegalArgumentException("The processed number of point cuts does not match the" + "original number of point cuts in the xml. Remove duplicates.");
}
for (int i = 0; i < convertedPcs.size(); i++) {
MethodHolder holder = sortData(origPcs.get(i), params.isDebug());
verifyPointCut(convertedPcs.get(i), holder);
verifyAllMethodsAccounted(holder);
}
}
use of com.newrelic.agent.extension.beans.Extension in project newrelic-java-agent by newrelic.
the class ExtensionDomParserTest method testPrimitiveReturnType.
@Test
public void testPrimitiveReturnType() throws Exception {
Extension ext = ExtensionDomParser.readFile(getFile(PRIMITIVE_RETURN_TYPE_FILE_PATH));
Instrumentation inst = ext.getInstrumentation();
List<Pointcut> thePcs = inst.getPointcut();
Assert.assertEquals(1, thePcs.size());
Pointcut pc = thePcs.get(0);
Assert.assertNull(pc.getClassName());
Assert.assertEquals("com.company.SomeInterface", pc.getInterfaceName());
Assert.assertEquals(1, pc.getMethod().size());
Assert.assertEquals("boolean", pc.getMethod().iterator().next().getReturnType());
try {
ExtensionConversionUtility.convertToPointCutsForValidation(ext);
Assert.fail();
} catch (XmlException ex) {
Assert.assertEquals("The return type 'boolean' is not valid. Primitive types are not allowed.", ex.getMessage());
}
}
Aggregations