Search in sources :

Example 1 with WeavePackageType

use of com.newrelic.api.agent.weaver.internal.WeavePackageType in project newrelic-java-agent by newrelic.

the class AgentPostprocessorsTest method testFieldModuleApiCalls.

@Test
public void testFieldModuleApiCalls() throws Exception {
    final ClassLoader classloader = Thread.currentThread().getContextClassLoader();
    final String classname = "com.newrelic.agent.instrumentation.weaver.preprocessors.AgentPostprocessorsTest$ApiTestClass";
    byte[] bytes = getClassBytesFromClassLoaderResource(classname, classloader);
    Assert.assertNotNull(bytes);
    ClassNode source = WeaveUtils.convertToClassNode(bytes);
    ClassNode result = new ClassNode(WeaveUtils.ASM_API_LEVEL);
    ClassVisitor cv = new CheckClassAdapter(result);
    ConcurrentMap<String, Set<TracedWeaveInstrumentationTracker>> weaveTraceDetailsTrackers = new ConcurrentHashMap<>();
    Map<String, Object> confProps = new HashMap<>();
    AgentConfig agentConfig = AgentConfigImpl.createAgentConfig(confProps);
    AgentPreprocessors preprocessors = new AgentPreprocessors(agentConfig, weaveTraceDetailsTrackers);
    AgentPostprocessors postprocessors = new AgentPostprocessors();
    preprocessors.setInstrumentationTitle("com.newrelic.some-field-module");
    // These are here so we can have additional test coverage even though we don't want these to be tracked for real
    postprocessors.addTrackedApiMethods(ImmutableMultimap.<String, Method>builder().put(Type.getType(NewRelic.class).getInternalName(), new Method("recordResponseTimeMetric", Type.VOID_TYPE, new Type[] { Type.getType(String.class), Type.LONG_TYPE })).put(Type.getType(ApiTestClass.ExceptionClass.class).getInternalName(), new Method("throwException", Type.VOID_TYPE, new Type[] {})).build());
    WeavePackageType weavePackageType = WeavePackageType.FIELD;
    postprocessors.setWeavePackageType(weavePackageType);
    cv = postprocessors.wrapApiCallsForSupportability(cv);
    source.accept(cv);
    Class<?> clazz = addToClassloader(result, classloader);
    Assert.assertNotNull(clazz);
    testApiTestClass(clazz, weavePackageType);
}
Also used : ClassNode(org.objectweb.asm.tree.ClassNode) WeavePackageType(com.newrelic.api.agent.weaver.internal.WeavePackageType) Set(java.util.Set) HashMap(java.util.HashMap) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) NewRelic(com.newrelic.api.agent.NewRelic) ClassVisitor(org.objectweb.asm.ClassVisitor) Method(org.objectweb.asm.commons.Method) AgentConfig(com.newrelic.agent.config.AgentConfig) Type(org.objectweb.asm.Type) WeavePackageType(com.newrelic.api.agent.weaver.internal.WeavePackageType) CheckClassAdapter(org.objectweb.asm.util.CheckClassAdapter) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) Test(org.junit.Test)

Example 2 with WeavePackageType

use of com.newrelic.api.agent.weaver.internal.WeavePackageType in project newrelic-java-agent by newrelic.

the class AgentPostprocessors method wrapApiCallsForSupportability.

ClassVisitor wrapApiCallsForSupportability(ClassVisitor cv) {
    return new ClassVisitor(WeaveUtils.ASM_API_LEVEL, cv) {

        @Override
        public MethodVisitor visitMethod(int access, final String methodName, String methodDesc, String signature, String[] exceptions) {
            final MethodVisitor mv = super.visitMethod(access, methodName, methodDesc, signature, exceptions);
            return new GeneratorAdapter(WeaveUtils.ASM_API_LEVEL, mv, access, methodName, methodDesc) {

                @Override
                public void visitMethodInsn(int opcode, String owner, String name, String desc, boolean itf) {
                    Method currentMethod = new Method(name, desc);
                    Collection<Method> methods = TRACKED_API_INTERNAL_NAME_TO_METHOD_NAMES.get(owner);
                    if (methods != null && methods.contains(currentMethod)) {
                        // Set the thread local to the current type of caller (e.g. - FIELD, INTERNAL, CUSTOM, etc)
                        setCurrentApiSource(weavePackageType);
                        // Make the original API call
                        super.visitMethodInsn(opcode, owner, name, desc, itf);
                        // Remove the thread local. If we hit an exception before we get here it will just be
                        // overwritten before the next call. So we don't need to worry about a try/catch/finally
                        unsetCurrentApiSource();
                    } else {
                        super.visitMethodInsn(opcode, owner, name, desc, itf);
                    }
                }

                /**
                 * Generate the instructions required to set the value of the api source thread local.
                 *
                 * e.g: <code>AgentBridge.currentApiSource.set(WeavePackageType.INTERNAL);</code>
                 *
                 * NOTE: If you modify this method you MUST also update "visitMaxs" above to specify the correct
                 * number of parameters that the "currentApiSource" method call pushes on to the stack.
                 *
                 * @param weavePackageType the source of the API caller to set
                 */
                private void setCurrentApiSource(WeavePackageType weavePackageType) {
                    getStatic(Type.getType(AgentBridge.class), "currentApiSource", Type.getType(ThreadLocal.class));
                    getStatic(Type.getType(WeavePackageType.class), weavePackageType.name(), Type.getType(WeavePackageType.class));
                    invokeVirtual(Type.getType(ThreadLocal.class), new Method("set", "(Ljava/lang/Object;)V"));
                }

                /**
                 * Generate the instructions required to unset the value of the api source thread local.
                 *
                 * e.g: <code>AgentBridge.currentApiSource.remove();</code>
                 */
                private void unsetCurrentApiSource() {
                    getStatic(Type.getType(AgentBridge.class), "currentApiSource", Type.getType(ThreadLocal.class));
                    invokeVirtual(Type.getType(ThreadLocal.class), new Method("remove", "()V"));
                }

                @Override
                public void visitMaxs(int maxStack, int maxLocals) {
                    // We add two variables to the stack when we push the "currentApiSource" static field on the
                    // stack and when we push the "weavePackageType" parameter on the stack (maxStack = 2).
                    super.visitMaxs(maxStack + 2, maxLocals);
                }
            };
        }
    };
}
Also used : WeavePackageType(com.newrelic.api.agent.weaver.internal.WeavePackageType) AgentBridge(com.newrelic.agent.bridge.AgentBridge) GeneratorAdapter(org.objectweb.asm.commons.GeneratorAdapter) ClassVisitor(org.objectweb.asm.ClassVisitor) TraceClassVisitor(com.newrelic.agent.instrumentation.tracing.TraceClassVisitor) Method(org.objectweb.asm.commons.Method) TracedMethod(com.newrelic.api.agent.TracedMethod) MethodVisitor(org.objectweb.asm.MethodVisitor)

Example 3 with WeavePackageType

use of com.newrelic.api.agent.weaver.internal.WeavePackageType in project newrelic-java-agent by newrelic.

the class AgentPostprocessorsTest method testApiTestClass.

private void testApiTestClass(Class<?> clazz, WeavePackageType weavePackageType) throws Exception {
    ThreadLocal<WeavePackageType> weavePackageTypeSpy = new ThreadLocal<WeavePackageType>() {

        @Override
        protected WeavePackageType initialValue() {
            return null;
        }
    };
    AgentBridge.currentApiSource = spy(weavePackageTypeSpy);
    ApiTestClass testClass = (ApiTestClass) clazz.newInstance();
    // Token API
    assertBeforeApi();
    Token token = testClass.getToken();
    assertNotNull(token);
    assertAfterApi(1, weavePackageType);
    assertBeforeApi();
    com.newrelic.api.agent.Transaction transaction = testClass.getTransaction();
    assertNotNull(transaction);
    assertAfterApi(0, weavePackageType);
    assertBeforeApi();
    testClass.getTokenNoReturn();
    assertAfterApi(2, weavePackageType);
    assertBeforeApi();
    testClass.getTokenNoReturnException();
    assertAfterApi(2, weavePackageType);
    assertBeforeApi();
    testClass.getTokenSeparateLinkExpireNoReturn();
    assertAfterApi(3, weavePackageType);
    assertBeforeApi();
    testClass.getTokenSeparateLinkExpireNoReturnException();
    assertAfterApi(3, weavePackageType);
    // Token API (Bridge)
    assertBeforeApi();
    com.newrelic.agent.bridge.Token tokenBridge = testClass.getTokenBridge();
    assertNotNull(tokenBridge);
    assertAfterApi(1, weavePackageType);
    assertBeforeApi();
    Transaction transactionBridge = testClass.getTransactionBridge();
    assertNotNull(transactionBridge);
    assertAfterApi(0, weavePackageType);
    assertBeforeApi();
    testClass.getTokenNoReturnBridge();
    assertAfterApi(2, weavePackageType);
    assertBeforeApi();
    testClass.getTokenNoReturnExceptionBridge();
    assertAfterApi(2, weavePackageType);
    assertBeforeApi();
    testClass.getTokenSeparateLinkExpireNoReturnBridge();
    assertAfterApi(3, weavePackageType);
    assertBeforeApi();
    testClass.getTokenSeparateLinkExpireNoReturnExceptionBridge();
    assertAfterApi(3, weavePackageType);
    // Segment API
    assertBeforeApi();
    testClass.startSegmentNoArgsWithTx(NewRelic.getAgent().getTransaction());
    assertAfterApi(2, weavePackageType);
    assertBeforeApi();
    testClass.startSegmentNoArgs();
    assertAfterApi(1, weavePackageType);
    assertBeforeApi();
    testClass.startSegmentNoArgsNoReturn();
    assertAfterApi(3, weavePackageType);
    assertBeforeApi();
    testClass.startSegmentNoArgsNoReturnException();
    assertAfterApi(3, weavePackageType);
    assertBeforeApi();
    testClass.startSegmentArgs();
    assertAfterApi(1, weavePackageType);
    assertBeforeApi();
    testClass.startSegmentArgsNoReturn();
    assertAfterApi(2, weavePackageType);
    assertBeforeApi();
    testClass.startSegmentArgsNoReturnException();
    assertAfterApi(2, weavePackageType);
    assertBeforeApi();
    testClass.startSegmentNoArgsWithGetToken();
    assertAfterApi(2, weavePackageType);
    assertBeforeApi();
    testClass.startSegmentNoArgsNoReturnWithGetToken();
    assertAfterApi(3, weavePackageType);
    assertBeforeApi();
    testClass.startSegmentNoArgsNoReturnExceptionWithGetToken();
    assertAfterApi(3, weavePackageType);
    assertBeforeApi();
    testClass.startSegmentArgsWithGetToken();
    assertAfterApi(2, weavePackageType);
    assertBeforeApi();
    testClass.startSegmentArgsNoReturnWithGetToken();
    assertAfterApi(4, weavePackageType);
    assertBeforeApi();
    testClass.startSegmentArgsNoReturnExceptionWithGetToken();
    assertAfterApi(3, weavePackageType);
    // TracedActivity API (Bridge)
    assertBeforeApi();
    testClass.createAndStartTracedActivity();
    assertAfterApi(1, weavePackageType);
    assertBeforeApi();
    testClass.createAndStartTracedActivityNoReturn();
    assertAfterApi(1, weavePackageType);
    assertBeforeApi();
    testClass.createAndStartTracedActivityNoReturnException();
    assertAfterApi(1, weavePackageType);
    // NewRelic API
    assertBeforeApi();
    testClass.noticeErrorWithStringAndEmptyMap();
    assertAfterApi(1, weavePackageType);
    assertBeforeApi();
    testClass.noticeErrorWithStringAndMap();
    assertAfterApi(1, weavePackageType);
    assertBeforeApi();
    testClass.noticeErrorWithThrowableAndEmptyMap();
    assertAfterApi(1, weavePackageType);
    assertBeforeApi();
    testClass.noticeErrorWithThrowableAndMap();
    assertAfterApi(1, weavePackageType);
    assertBeforeApi();
    testClass.noticeErrorExpectedWithStringAndEmptyMap();
    assertAfterApi(1, weavePackageType);
    assertBeforeApi();
    testClass.noticeErrorExpectedWithStringAndMap();
    assertAfterApi(1, weavePackageType);
    assertBeforeApi();
    testClass.noticeErrorExpectedWithThrowableAndEmptyMap();
    assertAfterApi(1, weavePackageType);
    assertBeforeApi();
    testClass.noticeErrorExpectedWithThrowableAndMap();
    assertAfterApi(1, weavePackageType);
    assertBeforeApi();
    testClass.addCustomParameter();
    assertAfterApi(2, weavePackageType);
    assertBeforeApi();
    testClass.ignoreApdexNewRelic();
    assertAfterApi(1, weavePackageType);
    assertBeforeApi();
    testClass.ignoreTransaction();
    assertAfterApi(1, weavePackageType);
    assertBeforeApi();
    testClass.setAppServerPort();
    assertAfterApi(1, weavePackageType);
    assertBeforeApi();
    testClass.setInstanceName();
    assertAfterApi(1, weavePackageType);
    assertBeforeApi();
    testClass.setServerInfo();
    assertAfterApi(1, weavePackageType);
    assertBeforeApi();
    testClass.setTransactionNameNewRelic();
    assertAfterApi(1, weavePackageType);
    assertBeforeApi();
    testClass.setUserName();
    assertAfterApi(1, weavePackageType);
    assertBeforeApi();
    testClass.setProductName();
    assertAfterApi(1, weavePackageType);
    assertBeforeApi();
    testClass.setAccountName();
    assertAfterApi(1, weavePackageType);
    // Transaction API
    assertBeforeApi();
    testClass.ignore();
    assertAfterApi(1, weavePackageType);
    assertBeforeApi();
    testClass.ignoreApdexTransaction();
    assertAfterApi(1, weavePackageType);
    assertBeforeApi();
    testClass.processRequestMetadata();
    assertAfterApi(1, weavePackageType);
    assertBeforeApi();
    testClass.processResponseMetadataWithURI();
    assertAfterApi(1, weavePackageType);
    assertBeforeApi();
    testClass.processResponseMetadata();
    assertAfterApi(1, weavePackageType);
    assertBeforeApi();
    testClass.setTransactionName();
    assertAfterApi(1, weavePackageType);
    // Transaction API (Bridge)
    assertBeforeApi();
    testClass.setTransactionNameBridge();
    assertAfterApi(1, weavePackageType);
    // TracedMethod API
    assertBeforeApi();
    testClass.reportAsExternal();
    assertAfterApi(1, weavePackageType);
    // TracedMethod API (Bridge)
    assertBeforeApi();
    testClass.reportAsExternalBridge();
    assertAfterApi(1, weavePackageType);
    // Insights API
    assertBeforeApi();
    testClass.recordCustomEvent();
    assertAfterApi(1, weavePackageType);
    // Public API
    assertBeforeApi();
    testClass.publicApiCustomParameter();
    assertAfterApi(2, weavePackageType);
    assertBeforeApi();
    testClass.publicApiBrowserHeaderFooter();
    assertAfterApi(0, weavePackageType);
    assertBeforeApi();
    testClass.publicApiIgnoreApdex();
    assertAfterApi(1, weavePackageType);
    assertBeforeApi();
    testClass.publicApiIgnoreTransaction();
    assertAfterApi(1, weavePackageType);
    assertBeforeApi();
    testClass.publicApiNoticeError();
    assertAfterApi(8, weavePackageType);
    assertBeforeApi();
    testClass.publicApiSetAccountName();
    assertAfterApi(1, weavePackageType);
    assertBeforeApi();
    testClass.publicApiSetAppServerPort();
    assertAfterApi(1, weavePackageType);
    assertBeforeApi();
    testClass.publicApiSetInstanceName();
    assertAfterApi(1, weavePackageType);
    assertBeforeApi();
    testClass.publicApiSetProductName();
    assertAfterApi(1, weavePackageType);
    assertBeforeApi();
    testClass.publicApiSetRequestAndResponse();
    assertAfterApi(0, weavePackageType);
    assertBeforeApi();
    testClass.publicApiSetServerInfo();
    assertAfterApi(1, weavePackageType);
    assertBeforeApi();
    testClass.publicApiSetTransactionName();
    assertAfterApi(1, weavePackageType);
    assertBeforeApi();
    testClass.publicApiSetUserName();
    assertAfterApi(1, weavePackageType);
    // Private API
    assertBeforeApi();
    testClass.privateApiCustomAttribute();
    assertAfterApi(3, weavePackageType);
    assertBeforeApi();
    testClass.privateApiMBeanServer();
    assertAfterApi(0, weavePackageType);
    assertBeforeApi();
    testClass.privateApiSampler();
    assertAfterApi(0, weavePackageType);
    assertBeforeApi();
    testClass.privateApiTracerParameter();
    assertAfterApi(0, weavePackageType);
    assertBeforeApi();
    testClass.privateApiReportError();
    assertAfterApi(0, weavePackageType);
    assertBeforeApi();
    testClass.privateApiSetServerInfo();
    assertAfterApi(1, weavePackageType);
    assertBeforeApi();
    testClass.privateApiSetAppServerPort();
    assertAfterApi(1, weavePackageType);
    assertBeforeApi();
    testClass.privateApiSetInstanceName();
    assertAfterApi(1, weavePackageType);
    assertBeforeApi();
    boolean exceptionThrown = false;
    try {
        testClass.throwExceptionTest();
    } catch (IOException e) {
        exceptionThrown = true;
    }
    if (!exceptionThrown) {
        fail("Exception was expected but not thrown");
    }
    assertAfterApi(1, exceptionThrown ? 0 : 1, weavePackageType);
}
Also used : WeavePackageType(com.newrelic.api.agent.weaver.internal.WeavePackageType) Token(com.newrelic.api.agent.Token) IOException(java.io.IOException) Transaction(com.newrelic.agent.bridge.Transaction)

Aggregations

WeavePackageType (com.newrelic.api.agent.weaver.internal.WeavePackageType)3 ClassVisitor (org.objectweb.asm.ClassVisitor)2 Method (org.objectweb.asm.commons.Method)2 AgentBridge (com.newrelic.agent.bridge.AgentBridge)1 Transaction (com.newrelic.agent.bridge.Transaction)1 AgentConfig (com.newrelic.agent.config.AgentConfig)1 TraceClassVisitor (com.newrelic.agent.instrumentation.tracing.TraceClassVisitor)1 NewRelic (com.newrelic.api.agent.NewRelic)1 Token (com.newrelic.api.agent.Token)1 TracedMethod (com.newrelic.api.agent.TracedMethod)1 IOException (java.io.IOException)1 HashMap (java.util.HashMap)1 Set (java.util.Set)1 ConcurrentHashMap (java.util.concurrent.ConcurrentHashMap)1 Test (org.junit.Test)1 MethodVisitor (org.objectweb.asm.MethodVisitor)1 Type (org.objectweb.asm.Type)1 GeneratorAdapter (org.objectweb.asm.commons.GeneratorAdapter)1 ClassNode (org.objectweb.asm.tree.ClassNode)1 CheckClassAdapter (org.objectweb.asm.util.CheckClassAdapter)1