Search in sources :

Example 1 with Extension

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);
    }
}
Also used : DOMSource(javax.xml.transform.dom.DOMSource) Transformer(javax.xml.transform.Transformer) Schema(javax.xml.validation.Schema) Node(org.w3c.dom.Node) Document(org.w3c.dom.Document) StringWriter(java.io.StringWriter) NodeList(org.w3c.dom.NodeList) List(java.util.List) StreamResult(javax.xml.transform.stream.StreamResult) NodeList(org.w3c.dom.NodeList) Method(java.lang.reflect.Method) IOException(java.io.IOException) IOException(java.io.IOException) SAXParseException(org.xml.sax.SAXParseException) ParserConfigurationException(javax.xml.parsers.ParserConfigurationException) SAXException(org.xml.sax.SAXException) Extension(com.newrelic.agent.extension.beans.Extension) Validator(javax.xml.validation.Validator)

Example 2 with Extension

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);
}
Also used : HashMap(java.util.HashMap) Instrumentation(com.newrelic.agent.extension.beans.Extension.Instrumentation) Method(com.newrelic.agent.extension.beans.Extension.Instrumentation.Pointcut.Method) Extension(com.newrelic.agent.extension.beans.Extension) Pointcut(com.newrelic.agent.extension.beans.Extension.Instrumentation.Pointcut) HashSet(java.util.HashSet) Test(org.junit.Test)

Example 3 with Extension

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);
}
Also used : HashMap(java.util.HashMap) Instrumentation(com.newrelic.agent.extension.beans.Extension.Instrumentation) Method(com.newrelic.agent.extension.beans.Extension.Instrumentation.Pointcut.Method) Extension(com.newrelic.agent.extension.beans.Extension) Pointcut(com.newrelic.agent.extension.beans.Extension.Instrumentation.Pointcut) MethodParameters(com.newrelic.agent.extension.beans.MethodParameters) HashSet(java.util.HashSet) Test(org.junit.Test)

Example 4 with Extension

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);
    }
}
Also used : Extension(com.newrelic.agent.extension.beans.Extension) Pointcut(com.newrelic.agent.extension.beans.Extension.Instrumentation.Pointcut) ExtensionClassAndMethodMatcher(com.newrelic.agent.instrumentation.custom.ExtensionClassAndMethodMatcher) Instrumentation(com.newrelic.agent.extension.beans.Extension.Instrumentation)

Example 5 with Extension

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());
    }
}
Also used : Extension(com.newrelic.agent.extension.beans.Extension) Pointcut(com.newrelic.agent.extension.beans.Extension.Instrumentation.Pointcut) XmlException(com.newrelic.agent.extension.util.XmlException) Instrumentation(com.newrelic.agent.extension.beans.Extension.Instrumentation) Test(org.junit.Test)

Aggregations

Extension (com.newrelic.agent.extension.beans.Extension)27 Test (org.junit.Test)23 Instrumentation (com.newrelic.agent.extension.beans.Extension.Instrumentation)17 Pointcut (com.newrelic.agent.extension.beans.Extension.Instrumentation.Pointcut)16 Method (com.newrelic.agent.extension.beans.Extension.Instrumentation.Pointcut.Method)11 ExtensionClassAndMethodMatcher (com.newrelic.agent.instrumentation.custom.ExtensionClassAndMethodMatcher)11 HashMap (java.util.HashMap)8 HashSet (java.util.HashSet)8 AgentHelper.getFile (com.newrelic.agent.AgentHelper.getFile)7 File (java.io.File)7 MethodParameters (com.newrelic.agent.extension.beans.MethodParameters)4 AgentConfig (com.newrelic.agent.config.AgentConfig)1 XmlException (com.newrelic.agent.extension.util.XmlException)1 ChildClassMatcher (com.newrelic.agent.instrumentation.classmatchers.ChildClassMatcher)1 InterfaceMatcher (com.newrelic.agent.instrumentation.classmatchers.InterfaceMatcher)1 ExactReturnTypeMethodMatcher (com.newrelic.agent.instrumentation.methodmatchers.ExactReturnTypeMethodMatcher)1 ParameterAttributeName (com.newrelic.agent.instrumentation.tracing.ParameterAttributeName)1 IOException (java.io.IOException)1 StringWriter (java.io.StringWriter)1 Method (java.lang.reflect.Method)1