test_class.declarator: contextFilter = new ContextFilter()
test_class.original_string: Filter contextFilter = new ContextFilter();
test_class.type: Filter
test_class.var_name: contextFilter
test_class.declarator: invoker
test_class.original_string: Invoker<DemoService> invoker;
test_class.type: Invoker<DemoService>
test_class.var_name: invoker
test_class.declarator: invocation
test_class.original_string: Invocation invocation;
test_class.type: Invocation
test_class.var_name: invocation
test_class.file: dubbo-rpc/dubbo-rpc-api/src/test/java/org/apache/dubbo/rpc/filter/ContextFilterTest.java
test_class.identifier: ContextFilterTest
test_case.body: @Test
      public void testWithAttachments() {
          URL url = URL.valueOf("test://test:11/test?group=dubbo&version=1.1");
          Invoker<DemoService> invoker = new MyInvoker<DemoService>(url);
          Invocation invocation = new MockInvocation();
          Result result = contextFilter.invoke(invoker, invocation);
          assertNull(RpcContext.getContext().getInvoker());
      }
test_case.class_method_signature: ContextFilterTest.testWithAttachments()
test_case.full_signature: @Test public void testWithAttachments()
test_case.identifier: testWithAttachments
test_case.invocations: valueOf invoke assertNull getInvoker getContext
test_case.modifiers: @Test public
test_case.parameters: ()
test_case.return: void
test_case.signature: void testWithAttachments()
focal_class.declarator: TAG_KEY = "dubbo.tag"
focal_class.modifier: private static final
focal_class.original_string: private static final String TAG_KEY = "dubbo.tag";
focal_class.type: String
focal_class.var_name: TAG_KEY
focal_class.declarator: UNLOADING_KEYS
focal_class.modifier: private static final
focal_class.original_string: private static final Set<String> UNLOADING_KEYS;
focal_class.type: Set<String>
focal_class.var_name: UNLOADING_KEYS
focal_class.file: dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/filter/ContextFilter.java
focal_class.identifier: ContextFilter
focal_class.interfaces: implements Filter, Filter.Listener
focal_class.class_method_signature: ContextFilter.invoke(Invoker<?> invoker, Invocation invocation)
focal_class.full_signature: @Override public Result invoke(Invoker<?> invoker, Invocation invocation)
focal_class.identifier: invoke
focal_class.modifiers: @Override public
focal_class.parameters: (Invoker<?> invoker, Invocation invocation)
focal_class.return: Result
focal_class.signature: Result invoke(Invoker<?> invoker, Invocation invocation)
focal_class.class_method_signature: ContextFilter.onResponse(Result appResponse, Invoker<?> invoker, Invocation invocation)
focal_class.full_signature: @Override public void onResponse(Result appResponse, Invoker<?> invoker, Invocation invocation)
focal_class.identifier: onResponse
focal_class.modifiers: @Override public
focal_class.parameters: (Result appResponse, Invoker<?> invoker, Invocation invocation)
focal_class.return: void
focal_class.signature: void onResponse(Result appResponse, Invoker<?> invoker, Invocation invocation)
focal_class.class_method_signature: ContextFilter.onError(Throwable t, Invoker<?> invoker, Invocation invocation)
focal_class.full_signature: @Override public void onError(Throwable t, Invoker<?> invoker, Invocation invocation)
focal_class.identifier: onError
focal_class.modifiers: @Override public
focal_class.parameters: (Throwable t, Invoker<?> invoker, Invocation invocation)
focal_class.return: void
focal_class.signature: void onError(Throwable t, Invoker<?> invoker, Invocation invocation)
focal_method.body: @Override
      public Result invoke(Invoker<?> invoker, Invocation invocation) throws RpcException {
          Map<String, Object> attachments = invocation.getObjectAttachments();
          if (attachments != null) {
              Map<String, Object> newAttach = new HashMap<>(attachments.size());
              for (Map.Entry<String, Object> entry : attachments.entrySet()) {
                  String key = entry.getKey();
                  if (!UNLOADING_KEYS.contains(key)) {
                      newAttach.put(key, entry.getValue());
                  }
              }
              attachments = newAttach;
          }
  
          RpcContext context = RpcContext.getContext();
          context.setInvoker(invoker)
                  .setInvocation(invocation)
  //                .setAttachments(attachments)  // merged from dubbox
                  .setLocalAddress(invoker.getUrl().getHost(), invoker.getUrl().getPort());
          String remoteApplication = (String) invocation.getAttachment(REMOTE_APPLICATION_KEY);
          if (StringUtils.isNotEmpty(remoteApplication)) {
              context.setRemoteApplicationName(remoteApplication);
          } else {
              context.setRemoteApplicationName((String) context.getAttachment(REMOTE_APPLICATION_KEY));
          }
  
          long timeout = RpcUtils.getTimeout(invocation, -1);
          if (timeout != -1) {
              context.set(TIME_COUNTDOWN_KEY, TimeoutCountDown.newCountDown(timeout, TimeUnit.MILLISECONDS));
          }
  
          // merged from dubbox
          // we may already added some attachments into RpcContext before this filter (e.g. in rest protocol)
          if (attachments != null) {
              if (context.getObjectAttachments() != null) {
                  context.getObjectAttachments().putAll(attachments);
              } else {
                  context.setObjectAttachments(attachments);
              }
          }
  
          if (invocation instanceof RpcInvocation) {
              ((RpcInvocation) invocation).setInvoker(invoker);
          }
  
          try {
              context.clearAfterEachInvoke(false);
              return invoker.invoke(invocation);
          } finally {
              context.clearAfterEachInvoke(true);
              // IMPORTANT! For async scenario, we must remove context from current thread, so we always create a new RpcContext for the next invoke for the same thread.
              RpcContext.removeContext(true);
              RpcContext.removeServerContext();
          }
      }
focal_method.class_method_signature: ContextFilter.invoke(Invoker<?> invoker, Invocation invocation)
focal_method.full_signature: @Override public Result invoke(Invoker<?> invoker, Invocation invocation)
focal_method.identifier: invoke
focal_method.invocations: getObjectAttachments size entrySet getKey contains put getValue getContext setLocalAddress setInvocation setInvoker getHost getUrl getPort getUrl getAttachment isNotEmpty setRemoteApplicationName setRemoteApplicationName getAttachment getTimeout set newCountDown getObjectAttachments putAll getObjectAttachments setObjectAttachments setInvoker clearAfterEachInvoke invoke clearAfterEachInvoke removeContext removeServerContext
focal_method.modifiers: @Override public
focal_method.parameters: (Invoker<?> invoker, Invocation invocation)
focal_method.return: Result
focal_method.signature: Result invoke(Invoker<?> invoker, Invocation invocation)