示例#1
0
  /** Returns {@link MethodDescriptor method descriptor} identified by name and parameters. */
  public MethodDescriptor getMethodDescriptor(String name, Class[] params, boolean declared) {
    MethodDescriptor methodDescriptor = getMethods().getMethodDescriptor(name, params);

    if ((methodDescriptor != null) && methodDescriptor.matchDeclared(declared)) {
      return methodDescriptor;
    }

    return null;
  }
 public CheckedTreeNode append(CheckedTreeNode node) {
   final TreeDescriptor descriptor = getDescriptor(node);
   if (!(descriptor instanceof MethodDescriptor)) {
     return node;
   }
   final MethodDescriptor methodDescriptor = (MethodDescriptor) descriptor;
   final String packageName = methodDescriptor.getPackageName();
   return attachNodeToParent(new PackageDescriptor(packageName), node);
 }
示例#3
0
  @Test
  public void testInvoke() throws Exception {
    MethodDescriptor<? super PdefTestInterface, ?> method = method();
    assert method != null;

    PdefTestInterface object = mock(PdefTestInterface.class);
    method.invoke(object, new Object[] {1, 2});
    verify(object).method(1, 2);
  }
示例#4
0
  @Test(expected = PdefTestException.class)
  public void testInvoke_exception() throws Exception {
    MethodDescriptor<? super PdefTestInterface, ?> method =
        PdefTestInterface.DESCRIPTOR.getMethod("exc0");
    assert method != null;

    PdefTestInterface object = mock(PdefTestInterface.class);
    doThrow(new PdefTestException()).when(object).exc0();

    method.invoke(object, null);
  }
 public CheckedTreeNode append(CheckedTreeNode node) {
   if (!myGroupByClasses) {
     return node;
   }
   final TreeDescriptor descriptor = getDescriptor(node);
   if (!(descriptor instanceof MethodDescriptor)) {
     return node;
   }
   final MethodDescriptor methodDescriptor = (MethodDescriptor) descriptor;
   final String className = methodDescriptor.getClassName();
   final String packageName = methodDescriptor.getPackageName();
   return attachNodeToParent(new ClassDescriptor(className, packageName), node);
 }
示例#6
0
 public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
   MethodDescriptor methodDescriptor = JobContextHelper.getJobDescriptor(jobExecutionContext);
   JobParameter jobParameter = JobContextHelper.getJobParameter(jobExecutionContext);
   try {
     LoggerHelper.info("begin execute job : " + methodDescriptor);
     LoggerHelper.info("job parameter : " + JsonHelper.toJson(jobParameter));
     Context context = JobContextHelper.getContext(jobExecutionContext);
     if (methodDescriptor.hasParameter()) {
       methodDescriptor
           .method()
           .invoke(
               context.jobBeanFactory().getJobBean(methodDescriptor.clazz()),
               new Object[] {jobParameter});
     } else {
       methodDescriptor
           .method()
           .invoke(context.jobBeanFactory().getJobBean(methodDescriptor.clazz()), new Object[] {});
     }
     LoggerHelper.info("execute job success: " + methodDescriptor);
   } catch (IllegalAccessException e) {
     LoggerHelper.info("execute job failed: " + methodDescriptor);
     throw new NiubiException(e);
   } catch (InvocationTargetException e) {
     LoggerHelper.info("execute job failed: " + methodDescriptor);
     throw new NiubiException(e);
   }
 }
  /**
   * Interprets the body of a method
   *
   * @param c the declaring class of the method
   * @param md the method descriptor
   * @param obj the object (this)
   * @param params the arguments
   */
  protected Object interpretMethod(
      final Class c, final MethodDescriptor md, final Object obj, final Object[] params) {
    final MethodDeclaration meth = md.method;
    final List mparams = meth.getParameters();
    final List stmts = meth.getBody().getStatements();
    final String name = meth.getName();

    Context context = null;

    if (Modifier.isStatic(md.method.getAccessFlags())) {
      if (md.variables == null) {
        md.importationManager.setClassLoader(this.classLoader);

        // pass 1: names resolution
        Context ctx = new StaticContext(this, c, md.importationManager);
        ctx.setAdditionalClassLoaderContainer(this.classLoader);
        Visitor v = new NameVisitor(ctx);

        ListIterator it = mparams.listIterator();
        while (it.hasNext()) {
          ((Node) it.next()).acceptVisitor(v);
        }

        it = stmts.listIterator();
        while (it.hasNext()) {
          final Object o = ((Node) it.next()).acceptVisitor(v);
          if (o != null) {
            it.set(o);
          }
        }

        // pass 2: type checking
        ctx = new StaticContext(this, c, md.importationManager);
        ctx.setAdditionalClassLoaderContainer(this.classLoader);
        v = new TypeChecker(ctx);

        it = mparams.listIterator();
        while (it.hasNext()) {
          ((Node) it.next()).acceptVisitor(v);
        }

        it = stmts.listIterator();
        while (it.hasNext()) {
          ((Node) it.next()).acceptVisitor(v);
        }

        md.variables = ctx.getCurrentScopeVariables();

        // Test of the additional context existence
        if (!name.equals("<clinit>") && !name.equals("<init>")) {
          try {
            md.contextField = c.getField("local$Variables$Reference$0");
          } catch (final NoSuchFieldException e) {
          }
        }
      }

      // pass 3: evaluation
      context = new StaticContext(this, c, md.variables);
    } else {
      if (md.variables == null) {
        md.importationManager.setClassLoader(this.classLoader);

        // pass 1: names resolution
        Context ctx = new MethodContext(this, c, c, md.importationManager);
        ctx.setAdditionalClassLoaderContainer(this.classLoader);
        Visitor v = new NameVisitor(ctx);

        Context ctx2 = new MethodContext(this, c, c, md.importationManager);
        ctx2.setAdditionalClassLoaderContainer(this.classLoader);
        Visitor v2 = new NameVisitor(ctx2);

        // Initializes the context with the outerclass variables
        Object[][] cc = null;
        try {
          final Field f = c.getField("local$Variables$Class$0");
          cc = (Object[][]) f.get(obj);
          for (int i = 0; i < cc.length; i++) {
            final Object[] cell = cc[i];
            if (!((String) cell[0]).equals("this")) {
              ctx.defineConstant((String) cell[0], cell[1]);
            }
          }
        } catch (final Exception e) {
        }

        // Visit the parameters and the body of the method
        ListIterator it = mparams.listIterator();
        while (it.hasNext()) {
          ((Node) it.next()).acceptVisitor(v);
        }

        it = stmts.listIterator();
        while (it.hasNext()) {
          final Node n = (Node) it.next();
          Object o = null;
          if (n.hasProperty(NodeProperties.INSTANCE_INITIALIZER)) {
            o = n.acceptVisitor(v2);
          } else {
            o = n.acceptVisitor(v);
          }
          if (o != null) {
            it.set(o);
          }
        }

        // pass 2: type checking
        ctx = new MethodContext(this, c, c, md.importationManager);
        ctx.setAdditionalClassLoaderContainer(this.classLoader);
        v = new TypeChecker(ctx);

        ctx2 = new MethodContext(this, c, c, md.importationManager);
        ctx2.setAdditionalClassLoaderContainer(this.classLoader);
        v2 = new TypeChecker(ctx2);

        // Initializes the context with outerclass variables
        if (cc != null) {
          for (int i = 0; i < cc.length; i++) {
            final Object[] cell = cc[i];
            if (!((String) cell[0]).equals("this")) {
              ctx.defineConstant((String) cell[0], cell[1]);
            }
          }
        }

        // Visit the parameters and the body of the method
        it = mparams.listIterator();
        while (it.hasNext()) {
          ((Node) it.next()).acceptVisitor(v);
        }

        it = stmts.listIterator();
        while (it.hasNext()) {
          final Node n = (Node) it.next();
          if (n.hasProperty(NodeProperties.INSTANCE_INITIALIZER)) {
            n.acceptVisitor(v2);
          } else {
            n.acceptVisitor(v);
          }
        }

        md.variables = ctx.getCurrentScopeVariables();

        // Test of the additional context existence
        if (!name.equals("<clinit>") && !name.equals("<init>")) {
          try {
            md.contextField = c.getField("local$Variables$Reference$0");
          } catch (final NoSuchFieldException e) {
          }
        }
      }

      // pass 3: evaluation
      context = new MethodContext(this, c, obj, md.variables);
    }

    context.setAdditionalClassLoaderContainer(this.classLoader);

    // Set the arguments values
    Iterator it = mparams.iterator();
    int i = 0;
    while (it.hasNext()) {
      context.set(((FormalParameter) it.next()).getName(), params[i++]);
    }

    // Set the final local variables values
    if (md.contextField != null) {
      Map vars = null;
      try {
        vars = (Map) md.contextField.get(obj);
      } catch (final IllegalAccessException e) {
      }
      if (vars != null) {
        it = vars.keySet().iterator();
        while (it.hasNext()) {
          final String s = (String) it.next();
          if (!s.equals("this")) {
            context.setConstant(s, vars.get(s));
          }
        }
      }
    }

    final Visitor v = new EvaluationVisitor(context);
    it = stmts.iterator();

    try {
      while (it.hasNext()) {
        ((Node) it.next()).acceptVisitor(v);
      }
    } catch (final ReturnException e) {
      return e.getValue();
    }
    return null;
  }
示例#8
0
 public static MethodHandle interfaceCaller(String className, MethodDescriptor desc) {
   return interfaceCaller(className, desc.getName(), desc.getSignature());
 }
示例#9
0
 public static MethodHandle constructorCaller(String className, MethodDescriptor desc) {
   return constructorCaller(className, desc.getName(), desc.getSignature());
 }
示例#10
0
 public static MethodHandle specialCaller(String className, MethodDescriptor desc) {
   return specialCaller(className, desc.getName(), desc.getSignature());
 }
示例#11
0
/** Unit tests for {@link ChannelImpl}. */
@RunWith(JUnit4.class)
public class ChannelImplTest {
  private MethodDescriptor<String, Integer> method =
      MethodDescriptor.create(
          MethodDescriptor.MethodType.UNKNOWN,
          "/service/method",
          new StringMarshaller(),
          new IntegerMarshaller());
  private ExecutorService executor = Executors.newSingleThreadExecutor();

  @Mock private ClientTransport mockTransport;
  @Mock private ClientTransportFactory mockTransportFactory;
  private ChannelImpl channel;

  @Mock private ClientCall.Listener<Integer> mockCallListener;
  @Mock private ClientCall.Listener<Integer> mockCallListener2;
  @Mock private ClientCall.Listener<Integer> mockCallListener3;

  private ArgumentCaptor<ClientTransport.Listener> transportListenerCaptor =
      ArgumentCaptor.forClass(ClientTransport.Listener.class);
  private ArgumentCaptor<ClientStreamListener> streamListenerCaptor =
      ArgumentCaptor.forClass(ClientStreamListener.class);

  @Before
  public void setUp() {
    MockitoAnnotations.initMocks(this);
    channel =
        new ChannelImpl(
            mockTransportFactory, executor, null, Collections.<ClientInterceptor>emptyList());
    when(mockTransportFactory.newClientTransport()).thenReturn(mockTransport);
  }

  @After
  public void tearDown() {
    executor.shutdownNow();
  }

  @Test
  public void timeoutTest() {
    ChannelImpl.TimeoutMarshaller marshaller = new ChannelImpl.TimeoutMarshaller();
    assertEquals("1000u", marshaller.toAsciiString(1000L));
    assertEquals(1000L, (long) marshaller.parseAsciiString("1000u"));

    assertEquals("100000m", marshaller.toAsciiString(100000000L));
    assertEquals(100000000L, (long) marshaller.parseAsciiString("100000m"));

    assertEquals("100000S", marshaller.toAsciiString(100000000000L));
    assertEquals(100000000000L, (long) marshaller.parseAsciiString("100000S"));

    // 1,666,667 * 60 has 9 digits
    assertEquals("1666666M", marshaller.toAsciiString(100000000000000L));
    assertEquals(60000000000000L, (long) marshaller.parseAsciiString("1000000M"));

    // 1,666,667 * 60 has 9 digits
    assertEquals("1666666H", marshaller.toAsciiString(6000000000000000L));
    assertEquals(3600000000000000L, (long) marshaller.parseAsciiString("1000000H"));
  }

  @Test
  public void immediateDeadlineExceeded() {
    ClientCall<String, Integer> call =
        channel.newCall(method, CallOptions.DEFAULT.withDeadlineNanoTime(System.nanoTime()));
    call.start(mockCallListener, new Metadata.Headers());
    verify(mockCallListener, timeout(1000))
        .onClose(same(Status.DEADLINE_EXCEEDED), any(Metadata.Trailers.class));
  }

  @Test
  public void shutdownWithNoTransportsEverCreated() {
    verifyNoMoreInteractions(mockTransportFactory);
    channel.shutdown();
    assertTrue(channel.isShutdown());
    assertTrue(channel.isTerminated());
  }

  @Test
  public void twoCallsAndGracefulShutdown() {
    verifyNoMoreInteractions(mockTransportFactory);
    ClientCall<String, Integer> call = channel.newCall(method, CallOptions.DEFAULT);
    verifyNoMoreInteractions(mockTransportFactory);

    // Create transport and call
    ClientTransport mockTransport = mock(ClientTransport.class);
    ClientStream mockStream = mock(ClientStream.class);
    Metadata.Headers headers = new Metadata.Headers();
    when(mockTransportFactory.newClientTransport()).thenReturn(mockTransport);
    when(mockTransport.newStream(same(method), same(headers), any(ClientStreamListener.class)))
        .thenReturn(mockStream);
    call.start(mockCallListener, headers);
    verify(mockTransportFactory).newClientTransport();
    verify(mockTransport).start(transportListenerCaptor.capture());
    ClientTransport.Listener transportListener = transportListenerCaptor.getValue();
    verify(mockTransport).newStream(same(method), same(headers), streamListenerCaptor.capture());
    ClientStreamListener streamListener = streamListenerCaptor.getValue();

    // Second call
    ClientCall<String, Integer> call2 = channel.newCall(method, CallOptions.DEFAULT);
    ClientStream mockStream2 = mock(ClientStream.class);
    Metadata.Headers headers2 = new Metadata.Headers();
    when(mockTransport.newStream(same(method), same(headers2), any(ClientStreamListener.class)))
        .thenReturn(mockStream2);
    call2.start(mockCallListener2, headers2);
    verify(mockTransport).newStream(same(method), same(headers2), streamListenerCaptor.capture());
    ClientStreamListener streamListener2 = streamListenerCaptor.getValue();
    Metadata.Trailers trailers = new Metadata.Trailers();
    streamListener2.closed(Status.CANCELLED, trailers);
    verify(mockCallListener2, timeout(1000)).onClose(Status.CANCELLED, trailers);

    // Shutdown
    channel.shutdown();
    assertTrue(channel.isShutdown());
    assertFalse(channel.isTerminated());
    verify(mockTransport).shutdown();

    // Further calls should fail without going to the transport
    ClientCall<String, Integer> call3 = channel.newCall(method, CallOptions.DEFAULT);
    call3.start(mockCallListener3, new Metadata.Headers());
    ArgumentCaptor<Status> statusCaptor = ArgumentCaptor.forClass(Status.class);
    verify(mockCallListener3, timeout(1000))
        .onClose(statusCaptor.capture(), any(Metadata.Trailers.class));
    assertSame(Status.Code.UNAVAILABLE, statusCaptor.getValue().getCode());

    // Finish shutdown
    transportListener.transportShutdown(Status.CANCELLED);
    assertFalse(channel.isTerminated());
    streamListener.closed(Status.CANCELLED, trailers);
    verify(mockCallListener, timeout(1000)).onClose(Status.CANCELLED, trailers);
    assertFalse(channel.isTerminated());

    transportListener.transportTerminated();
    assertTrue(channel.isTerminated());

    verifyNoMoreInteractions(mockTransportFactory);
    verifyNoMoreInteractions(mockTransport);
    verifyNoMoreInteractions(mockStream);
  }

  @Test
  public void transportFailsOnStart() {
    Status goldenStatus = Status.INTERNAL.withDescription("wanted it to fail");

    // Have transport throw exception on start
    ClientCall<String, Integer> call = channel.newCall(method, CallOptions.DEFAULT);
    ClientTransport mockTransport = mock(ClientTransport.class);
    when(mockTransportFactory.newClientTransport()).thenReturn(mockTransport);
    doThrow(goldenStatus.asRuntimeException())
        .when(mockTransport)
        .start(any(ClientTransport.Listener.class));
    call.start(mockCallListener, new Metadata.Headers());
    verify(mockTransportFactory).newClientTransport();
    verify(mockTransport).start(any(ClientTransport.Listener.class));
    ArgumentCaptor<Status> statusCaptor = ArgumentCaptor.forClass(Status.class);
    verify(mockCallListener, timeout(1000))
        .onClose(statusCaptor.capture(), any(Metadata.Trailers.class));
    assertSame(goldenStatus, statusCaptor.getValue());

    // Have transport shutdown immediately during start
    call = channel.newCall(method, CallOptions.DEFAULT);
    ClientTransport mockTransport2 = mock(ClientTransport.class);
    ClientStream mockStream2 = mock(ClientStream.class);
    Metadata.Headers headers2 = new Metadata.Headers();
    when(mockTransportFactory.newClientTransport()).thenReturn(mockTransport2);
    doAnswer(
            new Answer<Void>() {
              @Override
              public Void answer(InvocationOnMock invocation) {
                ClientTransport.Listener listener =
                    (ClientTransport.Listener) invocation.getArguments()[0];
                listener.transportShutdown(Status.INTERNAL);
                listener.transportTerminated();
                return null;
              }
            })
        .when(mockTransport2)
        .start(any(ClientTransport.Listener.class));
    when(mockTransport2.newStream(same(method), same(headers2), any(ClientStreamListener.class)))
        .thenReturn(mockStream2);
    call.start(mockCallListener2, headers2);
    verify(mockTransportFactory, times(2)).newClientTransport();
    verify(mockTransport2).start(any(ClientTransport.Listener.class));
    verify(mockTransport2).newStream(same(method), same(headers2), streamListenerCaptor.capture());
    Metadata.Trailers trailers2 = new Metadata.Trailers();
    streamListenerCaptor.getValue().closed(Status.CANCELLED, trailers2);
    verify(mockCallListener2, timeout(1000)).onClose(Status.CANCELLED, trailers2);

    // Make sure the Channel can still handle new calls
    call = channel.newCall(method, CallOptions.DEFAULT);
    ClientTransport mockTransport3 = mock(ClientTransport.class);
    ClientStream mockStream3 = mock(ClientStream.class);
    Metadata.Headers headers3 = new Metadata.Headers();
    when(mockTransportFactory.newClientTransport()).thenReturn(mockTransport3);
    when(mockTransport3.newStream(same(method), same(headers3), any(ClientStreamListener.class)))
        .thenReturn(mockStream3);
    call.start(mockCallListener3, headers3);
    verify(mockTransportFactory, times(3)).newClientTransport();
    verify(mockTransport3).start(transportListenerCaptor.capture());
    verify(mockTransport3).newStream(same(method), same(headers3), streamListenerCaptor.capture());
    Metadata.Trailers trailers3 = new Metadata.Trailers();
    streamListenerCaptor.getValue().closed(Status.CANCELLED, trailers3);
    verify(mockCallListener3, timeout(1000)).onClose(Status.CANCELLED, trailers3);

    // Make sure shutdown still works
    channel.shutdown();
    assertTrue(channel.isShutdown());
    assertFalse(channel.isTerminated());
    verify(mockTransport3).shutdown();
    transportListenerCaptor.getValue().transportShutdown(Status.CANCELLED);
    assertFalse(channel.isTerminated());

    transportListenerCaptor.getValue().transportTerminated();
    assertTrue(channel.isTerminated());

    verifyNoMoreInteractions(mockTransportFactory);
    verifyNoMoreInteractions(mockTransport);
    verifyNoMoreInteractions(mockTransport2);
    verifyNoMoreInteractions(mockTransport3);
    verifyNoMoreInteractions(mockStream2);
    verifyNoMoreInteractions(mockStream3);
  }

  @Test
  public void interceptor() {
    final AtomicLong atomic = new AtomicLong();
    ClientInterceptor interceptor =
        new ClientInterceptor() {
          @Override
          public <RequestT, ResponseT> ClientCall<RequestT, ResponseT> interceptCall(
              MethodDescriptor<RequestT, ResponseT> method, CallOptions callOptions, Channel next) {
            atomic.set(1);
            return next.newCall(method, callOptions);
          }
        };
    channel = new ChannelImpl(mockTransportFactory, executor, null, Arrays.asList(interceptor));
    assertNotNull(channel.newCall(method, CallOptions.DEFAULT));
    assertEquals(1, atomic.get());
  }

  @Test
  public void testNoDeadlockOnShutdown() {
    // Force creation of transport
    ClientCall<String, Integer> call = channel.newCall(method, CallOptions.DEFAULT);
    call.start(mockCallListener, new Metadata.Headers());
    call.cancel();

    verify(mockTransport).start(transportListenerCaptor.capture());
    final ClientTransport.Listener transportListener = transportListenerCaptor.getValue();
    final Object lock = new Object();
    final CyclicBarrier barrier = new CyclicBarrier(2);
    new Thread() {
      @Override
      public void run() {
        synchronized (lock) {
          try {
            barrier.await();
          } catch (Exception ex) {
            throw new AssertionError(ex);
          }
          // To deadlock, a lock would be needed for this call to proceed.
          transportListener.transportShutdown(Status.CANCELLED);
        }
      }
    }.start();
    doAnswer(
            new Answer<Void>() {
              @Override
              public Void answer(InvocationOnMock invocation) {
                // To deadlock, a lock would need to be held while this method is in progress.
                try {
                  barrier.await();
                } catch (Exception ex) {
                  throw new AssertionError(ex);
                }
                // If deadlock is possible with this setup, this sychronization completes the loop
                // because
                // the transportShutdown needs a lock that Channel is holding while calling this
                // method.
                synchronized (lock) {
                }
                return null;
              }
            })
        .when(mockTransport)
        .shutdown();
    channel.shutdown();

    transportListener.transportTerminated();
  }
}
示例#12
0
  @Test
  public void testIndexPostTerminal() throws Exception {
    MethodDescriptor<?, ?> index = method();
    MethodDescriptor<?, ?> query = PdefTestInterface.DESCRIPTOR.getMethod("query");
    MethodDescriptor<?, ?> post = PdefTestInterface.DESCRIPTOR.getMethod("post");
    MethodDescriptor<?, ?> iface = PdefTestInterface.DESCRIPTOR.getMethod("interface0");

    assertTrue(index.isTerminal());
    assertFalse(index.isPost());

    assertTrue(query.isTerminal());
    assertFalse(query.isPost());

    assertTrue(post.isTerminal());
    assertTrue(post.isPost());

    assertFalse(iface.isTerminal());
    assertFalse(iface.isPost());
  }
示例#13
0
 @Test
 public void testGetName() throws Exception {
   MethodDescriptor<?, ?> method = method();
   assertNotNull(method);
   assertEquals("method", method.getName());
 }