blob: 41943fc58725fee5a1e9a4d2f0c663359188d898 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.dubbo.config;
import demo.MultiClassLoaderService;
import demo.MultiClassLoaderServiceImpl;
import demo.MultiClassLoaderServiceRequest;
import demo.MultiClassLoaderServiceResult;
import javassist.CannotCompileException;
import javassist.CtClass;
import javassist.NotFoundException;
import org.apache.dubbo.common.URL;
import org.apache.dubbo.common.Version;
import org.apache.dubbo.common.compiler.support.CtClassBuilder;
import org.apache.dubbo.common.compiler.support.JavassistCompiler;
import org.apache.dubbo.common.extension.ExtensionLoader;
import org.apache.dubbo.common.utils.ConfigUtils;
import org.apache.dubbo.common.utils.NetUtils;
import org.apache.dubbo.common.utils.StringUtils;
import org.apache.dubbo.config.annotation.Argument;
import org.apache.dubbo.config.annotation.Method;
import org.apache.dubbo.config.annotation.Reference;
import org.apache.dubbo.config.api.DemoService;
import org.apache.dubbo.config.bootstrap.DubboBootstrap;
import org.apache.dubbo.config.context.ModuleConfigManager;
import org.apache.dubbo.config.provider.impl.DemoServiceImpl;
import org.apache.dubbo.registry.client.migration.MigrationInvoker;
import org.apache.dubbo.rpc.Exporter;
import org.apache.dubbo.rpc.Invoker;
import org.apache.dubbo.rpc.ProxyFactory;
import org.apache.dubbo.rpc.cluster.support.registry.ZoneAwareClusterInvoker;
import org.apache.dubbo.rpc.cluster.support.wrapper.MockClusterInvoker;
import org.apache.dubbo.rpc.listener.ListenerInvokerWrapper;
import org.apache.dubbo.rpc.model.ApplicationModel;
import org.apache.dubbo.rpc.model.FrameworkModel;
import org.apache.dubbo.rpc.model.ModuleModel;
import org.apache.dubbo.rpc.model.ServiceMetadata;
import org.apache.dubbo.rpc.protocol.injvm.InjvmInvoker;
import org.apache.dubbo.rpc.protocol.injvm.InjvmProtocol;
import org.apache.dubbo.rpc.service.GenericService;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledForJreRange;
import org.junit.jupiter.api.condition.JRE;
import org.mockito.Mockito;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.lang.reflect.Constructor;
import java.net.URLDecoder;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicReference;
import java.util.stream.Collectors;
import static org.apache.dubbo.common.constants.CommonConstants.APPLICATION_KEY;
import static org.apache.dubbo.common.constants.CommonConstants.APPLICATION_VERSION_KEY;
import static org.apache.dubbo.common.constants.CommonConstants.BROADCAST_CLUSTER;
import static org.apache.dubbo.common.constants.CommonConstants.CLUSTER_KEY;
import static org.apache.dubbo.common.constants.CommonConstants.CONSUMER_SIDE;
import static org.apache.dubbo.common.constants.CommonConstants.DEFAULT_METADATA_STORAGE_TYPE;
import static org.apache.dubbo.common.constants.CommonConstants.DUBBO_VERSION_KEY;
import static org.apache.dubbo.common.constants.CommonConstants.DUMP_DIRECTORY;
import static org.apache.dubbo.common.constants.CommonConstants.GENERIC_KEY;
import static org.apache.dubbo.common.constants.CommonConstants.INTERFACE_KEY;
import static org.apache.dubbo.common.constants.CommonConstants.LIVENESS_PROBE_KEY;
import static org.apache.dubbo.common.constants.CommonConstants.METADATA_KEY;
import static org.apache.dubbo.common.constants.CommonConstants.METADATA_SERVICE_PORT_KEY;
import static org.apache.dubbo.common.constants.CommonConstants.METADATA_SERVICE_PROTOCOL_KEY;
import static org.apache.dubbo.common.constants.CommonConstants.METHODS_KEY;
import static org.apache.dubbo.common.constants.CommonConstants.PID_KEY;
import static org.apache.dubbo.common.constants.CommonConstants.READINESS_PROBE_KEY;
import static org.apache.dubbo.common.constants.CommonConstants.REFER_ASYNC_KEY;
import static org.apache.dubbo.common.constants.CommonConstants.REFER_BACKGROUND_KEY;
import static org.apache.dubbo.common.constants.CommonConstants.REFER_THREAD_NUM_KEY;
import static org.apache.dubbo.common.constants.CommonConstants.REGISTRY_LOCAL_FILE_CACHE_ENABLED;
import static org.apache.dubbo.common.constants.CommonConstants.RELEASE_KEY;
import static org.apache.dubbo.common.constants.CommonConstants.REVISION_KEY;
import static org.apache.dubbo.common.constants.CommonConstants.SIDE_KEY;
import static org.apache.dubbo.common.constants.CommonConstants.STARTUP_PROBE;
import static org.apache.dubbo.common.constants.CommonConstants.TIMESTAMP_KEY;
import static org.apache.dubbo.common.constants.CommonConstants.URL_MERGE_PROCESSOR_KEY;
import static org.apache.dubbo.common.constants.QosConstants.ACCEPT_FOREIGN_IP;
import static org.apache.dubbo.common.constants.QosConstants.QOS_ENABLE;
import static org.apache.dubbo.common.constants.QosConstants.QOS_HOST;
import static org.apache.dubbo.common.constants.QosConstants.QOS_PORT;
import static org.apache.dubbo.registry.Constants.REGISTER_IP_KEY;
import static org.apache.dubbo.rpc.Constants.DEFAULT_STUB_EVENT;
import static org.apache.dubbo.rpc.Constants.LOCAL_KEY;
import static org.apache.dubbo.rpc.Constants.LOCAL_PROTOCOL;
import static org.apache.dubbo.rpc.Constants.SCOPE_KEY;
import static org.apache.dubbo.rpc.Constants.SCOPE_LOCAL;
import static org.apache.dubbo.rpc.Constants.SCOPE_REMOTE;
import static org.apache.dubbo.rpc.cluster.Constants.PEER_KEY;
public class ReferenceConfigTest {
private static String zkUrl1;
private static String zkUrl2;
private static String registryUrl1;
@BeforeAll
public static void beforeAll() {
int zkServerPort1 = 2181;
int zkServerPort2 = 2182;
zkUrl1 = "zookeeper://localhost:" + zkServerPort1;
zkUrl2 = "zookeeper://localhost:" + zkServerPort2;
registryUrl1 = "registry://localhost:" + zkServerPort1 + "?registry=zookeeper";
}
@BeforeEach
public void setUp() throws Exception {
DubboBootstrap.reset();
ApplicationModel.defaultModel().getApplicationConfigManager();
DubboBootstrap.getInstance();
}
@AfterEach
public void tearDown() throws IOException {
DubboBootstrap.reset();
Mockito.framework().clearInlineMocks();
}
/**
* Test whether the configuration required for the aggregation service reference meets expectations
*/
@Test
public void testAppendConfig() {
ApplicationConfig applicationConfig = new ApplicationConfig();
applicationConfig.setName("application1");
applicationConfig.setVersion("v1");
applicationConfig.setOwner("owner1");
applicationConfig.setOrganization("bu1");
applicationConfig.setArchitecture("architecture1");
applicationConfig.setEnvironment("test");
applicationConfig.setCompiler("javassist");
applicationConfig.setLogger("log4j");
applicationConfig.setDumpDirectory("/");
applicationConfig.setQosEnable(false);
applicationConfig.setQosHost("127.0.0.1");
applicationConfig.setQosPort(77777);
applicationConfig.setQosAcceptForeignIp(false);
Map<String, String> parameters = new HashMap<>();
parameters.put("key1", "value1");
parameters.put("key2", "value2");
applicationConfig.setParameters(parameters);
applicationConfig.setShutwait("5");
applicationConfig.setMetadataType("local");
applicationConfig.setRegisterConsumer(false);
applicationConfig.setRepository("repository1");
applicationConfig.setEnableFileCache(false);
applicationConfig.setProtocol("dubbo");
applicationConfig.setMetadataServicePort(88888);
applicationConfig.setMetadataServiceProtocol("tri");
applicationConfig.setLivenessProbe("livenessProbe");
applicationConfig.setReadinessProbe("readinessProb");
applicationConfig.setStartupProbe("startupProbe");
ReferenceConfig<DemoService> referenceConfig = new ReferenceConfig<>();
referenceConfig.setClient("netty");
referenceConfig.setGeneric(Boolean.FALSE.toString());
referenceConfig.setProtocol("dubbo");
referenceConfig.setInit(true);
referenceConfig.setLazy(false);
referenceConfig.setInjvm(false);
referenceConfig.setReconnect("reconnect");
referenceConfig.setSticky(false);
referenceConfig.setStub(DEFAULT_STUB_EVENT);
referenceConfig.setRouter("default");
referenceConfig.setReferAsync(true);
MonitorConfig monitorConfig = new MonitorConfig();
applicationConfig.setMonitor(monitorConfig);
ModuleConfig moduleConfig = new ModuleConfig();
moduleConfig.setMonitor("default");
moduleConfig.setName("module1");
moduleConfig.setOrganization("application1");
moduleConfig.setVersion("v1");
moduleConfig.setOwner("owner1");
ConsumerConfig consumerConfig = new ConsumerConfig();
consumerConfig.setClient("netty");
consumerConfig.setThreadpool("fixed");
consumerConfig.setCorethreads(200);
consumerConfig.setQueues(500);
consumerConfig.setThreads(300);
consumerConfig.setShareconnections(10);
consumerConfig.setUrlMergeProcessor("default");
consumerConfig.setReferThreadNum(20);
consumerConfig.setReferBackground(false);
referenceConfig.setConsumer(consumerConfig);
MethodConfig methodConfig = new MethodConfig();
methodConfig.setName("sayName");
methodConfig.setStat(1);
methodConfig.setRetries(0);
methodConfig.setExecutes(10);
methodConfig.setDeprecated(false);
methodConfig.setSticky(false);
methodConfig.setReturn(false);
methodConfig.setService("service");
methodConfig.setServiceId(DemoService.class.getName());
methodConfig.setParentPrefix("demo");
referenceConfig.setMethods(Collections.singletonList(methodConfig));
referenceConfig.setInterface(DemoService.class);
referenceConfig.getInterfaceClass();
referenceConfig.setCheck(false);
RegistryConfig registry = new RegistryConfig();
registry.setAddress(zkUrl1);
applicationConfig.setRegistries(Collections.singletonList(registry));
applicationConfig.setRegistryIds(registry.getId());
moduleConfig.setRegistries(Collections.singletonList(registry));
referenceConfig.setRegistry(registry);
DubboBootstrap dubboBootstrap = DubboBootstrap.newInstance(FrameworkModel.defaultModel());
dubboBootstrap.application(applicationConfig)
.reference(referenceConfig)
.registry(registry)
.module(moduleConfig)
.initialize();
referenceConfig.init();
ServiceMetadata serviceMetadata = referenceConfig.getServiceMetadata();
// verify additional side parameter
Assertions.assertEquals(CONSUMER_SIDE, serviceMetadata.getAttachments().get(SIDE_KEY));
// verify additional interface parameter
Assertions.assertEquals(DemoService.class.getName(), serviceMetadata.getAttachments().get(INTERFACE_KEY));
// verify additional metadata-type parameter
Assertions.assertEquals(DEFAULT_METADATA_STORAGE_TYPE, serviceMetadata.getAttachments().get(METADATA_KEY));
// verify additional register.ip parameter
Assertions.assertEquals(NetUtils.getLocalHost(), serviceMetadata.getAttachments().get(REGISTER_IP_KEY));
// verify additional runtime parameters
Assertions.assertEquals(Version.getProtocolVersion(), serviceMetadata.getAttachments().get(DUBBO_VERSION_KEY));
Assertions.assertEquals(Version.getVersion(), serviceMetadata.getAttachments().get(RELEASE_KEY));
Assertions.assertTrue(serviceMetadata.getAttachments().containsKey(TIMESTAMP_KEY));
Assertions.assertEquals(String.valueOf(ConfigUtils.getPid()), serviceMetadata.getAttachments().get(PID_KEY));
// verify additional application config
Assertions.assertEquals(applicationConfig.getName(), serviceMetadata.getAttachments().get(APPLICATION_KEY));
Assertions.assertEquals(applicationConfig.getOwner(), serviceMetadata.getAttachments().get("owner"));
Assertions.assertEquals(applicationConfig.getVersion(),
serviceMetadata.getAttachments().get(APPLICATION_VERSION_KEY));
Assertions.assertEquals(applicationConfig.getOrganization(),
serviceMetadata.getAttachments().get("organization"));
Assertions.assertEquals(applicationConfig.getArchitecture(),
serviceMetadata.getAttachments().get("architecture"));
Assertions.assertEquals(applicationConfig.getEnvironment(),
serviceMetadata.getAttachments().get("environment"));
Assertions.assertEquals(applicationConfig.getCompiler(), serviceMetadata.getAttachments().get("compiler"));
Assertions.assertEquals(applicationConfig.getLogger(), serviceMetadata.getAttachments().get("logger"));
Assertions.assertFalse(serviceMetadata.getAttachments().containsKey("registries"));
Assertions.assertFalse(serviceMetadata.getAttachments().containsKey("registry.ids"));
Assertions.assertFalse(serviceMetadata.getAttachments().containsKey("monitor"));
Assertions.assertEquals(applicationConfig.getDumpDirectory(),
serviceMetadata.getAttachments().get(DUMP_DIRECTORY));
Assertions.assertEquals(applicationConfig.getQosEnable().toString(),
serviceMetadata.getAttachments().get(QOS_ENABLE));
Assertions.assertEquals(applicationConfig.getQosHost(),
serviceMetadata.getAttachments().get(QOS_HOST));
Assertions.assertEquals(applicationConfig.getQosPort().toString(),
serviceMetadata.getAttachments().get(QOS_PORT));
Assertions.assertEquals(applicationConfig.getQosAcceptForeignIp().toString(),
serviceMetadata.getAttachments().get(ACCEPT_FOREIGN_IP));
Assertions.assertEquals(applicationConfig.getParameters().get("key1"),
serviceMetadata.getAttachments().get("key1"));
Assertions.assertEquals(applicationConfig.getParameters().get("key2"),
serviceMetadata.getAttachments().get("key2"));
Assertions.assertEquals(applicationConfig.getShutwait(),
serviceMetadata.getAttachments().get("shutwait"));
Assertions.assertEquals(applicationConfig.getMetadataType(),
serviceMetadata.getAttachments().get(METADATA_KEY));
Assertions.assertEquals(applicationConfig.getRegisterConsumer().toString(),
serviceMetadata.getAttachments().get("register.consumer"));
Assertions.assertEquals(applicationConfig.getRepository(),
serviceMetadata.getAttachments().get("repository"));
Assertions.assertEquals(applicationConfig.getEnableFileCache().toString(),
serviceMetadata.getAttachments().get(REGISTRY_LOCAL_FILE_CACHE_ENABLED));
Assertions.assertEquals(applicationConfig.getMetadataServicePort().toString(),
serviceMetadata.getAttachments().get(METADATA_SERVICE_PORT_KEY));
Assertions.assertEquals(applicationConfig.getMetadataServiceProtocol().toString(),
serviceMetadata.getAttachments().get(METADATA_SERVICE_PROTOCOL_KEY));
Assertions.assertEquals(applicationConfig.getLivenessProbe(),
serviceMetadata.getAttachments().get(LIVENESS_PROBE_KEY));
Assertions.assertEquals(applicationConfig.getReadinessProbe(),
serviceMetadata.getAttachments().get(READINESS_PROBE_KEY));
Assertions.assertEquals(applicationConfig.getStartupProbe(),
serviceMetadata.getAttachments().get(STARTUP_PROBE));
// verify additional module config
Assertions.assertEquals(moduleConfig.getName(), serviceMetadata.getAttachments().get("module"));
Assertions.assertFalse(serviceMetadata.getAttachments().containsKey("monitor"));
Assertions.assertEquals(moduleConfig.getOrganization(),
serviceMetadata.getAttachments().get("module.organization"));
Assertions.assertEquals(moduleConfig.getOwner(), serviceMetadata.getAttachments().get("module.owner"));
Assertions.assertFalse(serviceMetadata.getAttachments().containsKey("registries"));
Assertions.assertEquals(moduleConfig.getVersion(), serviceMetadata.getAttachments().get("module.version"));
// verify additional consumer config
Assertions.assertEquals(consumerConfig.getClient(), serviceMetadata.getAttachments().get("client"));
Assertions.assertEquals(consumerConfig.getThreadpool(), serviceMetadata.getAttachments().get("threadpool"));
Assertions.assertEquals(consumerConfig.getCorethreads().toString(),
serviceMetadata.getAttachments().get("corethreads"));
Assertions.assertEquals(consumerConfig.getQueues().toString(),
serviceMetadata.getAttachments().get("queues"));
Assertions.assertEquals(consumerConfig.getThreads().toString(),
serviceMetadata.getAttachments().get("threads"));
Assertions.assertEquals(consumerConfig.getShareconnections().toString(),
serviceMetadata.getAttachments().get("shareconnections"));
Assertions.assertEquals(consumerConfig.getUrlMergeProcessor(),
serviceMetadata.getAttachments().get(URL_MERGE_PROCESSOR_KEY));
Assertions.assertFalse(serviceMetadata.getAttachments().containsKey(REFER_THREAD_NUM_KEY));
Assertions.assertFalse(serviceMetadata.getAttachments().containsKey(REFER_BACKGROUND_KEY));
// verify additional reference config
Assertions.assertEquals(referenceConfig.getClient(), serviceMetadata.getAttachments().get("client"));
Assertions.assertEquals(referenceConfig.getGeneric(), serviceMetadata.getAttachments().get("generic"));
Assertions.assertEquals(referenceConfig.getProtocol(), serviceMetadata.getAttachments().get("protocol"));
Assertions.assertEquals(referenceConfig.isInit().toString(), serviceMetadata.getAttachments().get("init"));
Assertions.assertEquals(referenceConfig.getLazy().toString(), serviceMetadata.getAttachments().get("lazy"));
Assertions.assertEquals(referenceConfig.isInjvm().toString(), serviceMetadata.getAttachments().get("injvm"));
Assertions.assertEquals(referenceConfig.getReconnect(), serviceMetadata.getAttachments().get("reconnect"));
Assertions.assertEquals(referenceConfig.getSticky().toString(), serviceMetadata.getAttachments().get("sticky"));
Assertions.assertEquals(referenceConfig.getStub(), serviceMetadata.getAttachments().get("stub"));
Assertions.assertEquals(referenceConfig.getProvidedBy(), serviceMetadata.getAttachments().get("provided-by"));
Assertions.assertEquals(referenceConfig.getRouter(), serviceMetadata.getAttachments().get("router"));
Assertions.assertEquals(referenceConfig.getReferAsync().toString(),
serviceMetadata.getAttachments().get(REFER_ASYNC_KEY));
// verify additional method config
Assertions.assertFalse(serviceMetadata.getAttachments().containsKey("name"));
Assertions.assertEquals(methodConfig.getStat().toString(),
serviceMetadata.getAttachments().get("sayName.stat"));
Assertions.assertEquals(methodConfig.getRetries().toString(),
serviceMetadata.getAttachments().get("sayName.retries"));
Assertions.assertFalse(serviceMetadata.getAttachments().containsKey("sayName.reliable"));
Assertions.assertEquals(methodConfig.getExecutes().toString(),
serviceMetadata.getAttachments().get("sayName.executes"));
Assertions.assertEquals(methodConfig.getDeprecated().toString(),
serviceMetadata.getAttachments().get("sayName.deprecated"));
Assertions.assertFalse(serviceMetadata.getAttachments().containsKey("sayName.stick"));
Assertions.assertEquals(methodConfig.isReturn().toString(),
serviceMetadata.getAttachments().get("sayName.return"));
Assertions.assertFalse(serviceMetadata.getAttachments().containsKey("sayName.service"));
Assertions.assertFalse(serviceMetadata.getAttachments().containsKey("sayName.service.id"));
Assertions.assertFalse(serviceMetadata.getAttachments().containsKey("sayName.parent.prefix"));
// verify additional revision and methods parameter
Assertions.assertEquals(Version.getVersion(referenceConfig.getInterfaceClass(), referenceConfig.getVersion()),
serviceMetadata.getAttachments().get(REVISION_KEY));
Assertions.assertTrue(serviceMetadata.getAttachments().containsKey(METHODS_KEY));
Assertions.assertEquals(DemoService.class.getMethods().length,
StringUtils.split((String) serviceMetadata.getAttachments().get(METHODS_KEY), ',').length);
dubboBootstrap.stop();
}
@Test
public void testShouldJvmRefer() {
Map<String, String> parameters = new HashMap<>();
ReferenceConfig<DemoService> referenceConfig = new ReferenceConfig<>();
// verify that if injvm is configured as true, local references should be made
referenceConfig.setInjvm(true);
Assertions.assertTrue(referenceConfig.shouldJvmRefer(parameters));
// verify that if injvm is configured as false, local references should not be made
referenceConfig.setInjvm(false);
Assertions.assertFalse(referenceConfig.shouldJvmRefer(parameters));
// verify that if url is configured, local reference should not be made
referenceConfig.setInjvm(null);
referenceConfig.setUrl("dubbo://127.0.0.1:20880/DemoService");
parameters.put(INTERFACE_KEY, DemoService.class.getName());
Assertions.assertFalse(referenceConfig.shouldJvmRefer(parameters));
parameters.clear();
// verify that if scope is configured as local, local references should be made
referenceConfig.setInjvm(null);
referenceConfig.setUrl(null);
parameters.put(SCOPE_KEY, SCOPE_LOCAL);
Assertions.assertTrue(referenceConfig.shouldJvmRefer(parameters));
parameters.clear();
// verify that if url protocol is configured as injvm, local references should be made
referenceConfig.setInjvm(null);
referenceConfig.setUrl(null);
parameters.put(LOCAL_PROTOCOL, "true");
Assertions.assertTrue(referenceConfig.shouldJvmRefer(parameters));
parameters.clear();
// verify that if generic is configured as true, local references should not be made
referenceConfig.setInjvm(null);
referenceConfig.setUrl(null);
parameters.put(GENERIC_KEY, "true");
Assertions.assertFalse(referenceConfig.shouldJvmRefer(parameters));
parameters.clear();
// verify that if the service has been exposed, and the cluster is not configured with broadcast, local reference should be made
referenceConfig.setInjvm(null);
referenceConfig.setUrl(null);
ProxyFactory proxy = ExtensionLoader.getExtensionLoader(ProxyFactory.class).getAdaptiveExtension();
DemoService service = new DemoServiceImpl();
URL url = URL.valueOf("dubbo://127.0.0.1/DemoService")
.addParameter(INTERFACE_KEY, DemoService.class.getName());
parameters.put(INTERFACE_KEY, DemoService.class.getName());
Exporter<?> exporter = InjvmProtocol.getInjvmProtocol(FrameworkModel.defaultModel()).export(proxy.getInvoker(service, DemoService.class, url));
InjvmProtocol.getInjvmProtocol(FrameworkModel.defaultModel()).getExporterMap().put(DemoService.class.getName(), exporter);
Assertions.assertTrue(referenceConfig.shouldJvmRefer(parameters));
// verify that if the service has been exposed, and the cluster is configured with broadcast, local reference should not be made
parameters.put(CLUSTER_KEY, BROADCAST_CLUSTER);
Assertions.assertFalse(referenceConfig.shouldJvmRefer(parameters));
parameters.clear();
InjvmProtocol.getInjvmProtocol(FrameworkModel.defaultModel()).destroy();
}
@Test
public void testCreateInvokerForLocalRefer() {
ReferenceConfig<DemoService> referenceConfig = new ReferenceConfig<>();
referenceConfig.setScope(LOCAL_KEY);
ApplicationConfig applicationConfig = new ApplicationConfig();
applicationConfig.setName("application1");
Map<String, String> parameters = new HashMap<>();
parameters.put("key1", "value1");
parameters.put("key2", "value2");
applicationConfig.setParameters(parameters);
referenceConfig.setInterface(DemoService.class);
referenceConfig.getInterfaceClass();
referenceConfig.setCheck(false);
DubboBootstrap dubboBootstrap = DubboBootstrap.newInstance(FrameworkModel.defaultModel());
dubboBootstrap.application(applicationConfig)
.reference(referenceConfig)
.initialize();
referenceConfig.init();
Invoker<?> withFilter = ((ListenerInvokerWrapper<?>) referenceConfig.getInvoker()).getInvoker();
withFilter = ((MockClusterInvoker<?>) withFilter).getDirectory().getAllInvokers().get(0);
Assertions.assertTrue(withFilter instanceof InjvmInvoker);
URL url = withFilter.getUrl();
Assertions.assertEquals("application1", url.getParameter("application"));
Assertions.assertEquals("value1", url.getParameter("key1"));
Assertions.assertEquals("value2", url.getParameter("key2"));
dubboBootstrap.stop();
}
/**
* Verify the configuration of the registry protocol for remote reference
*/
@Test
public void testCreateInvokerForRemoteRefer() {
ReferenceConfig<DemoService> referenceConfig = new ReferenceConfig<>();
referenceConfig.setGeneric(Boolean.FALSE.toString());
referenceConfig.setProtocol("dubbo");
referenceConfig.setInit(true);
referenceConfig.setLazy(false);
referenceConfig.setInjvm(false);
DubboBootstrap dubboBootstrap = DubboBootstrap.newInstance(FrameworkModel.defaultModel());
ApplicationConfig applicationConfig = new ApplicationConfig();
applicationConfig.setName("application1");
Map<String, String> parameters = new HashMap<>();
parameters.put("key1", "value1");
parameters.put("key2", "value2");
applicationConfig.setParameters(parameters);
referenceConfig.refreshed.set(true);
referenceConfig.setInterface(DemoService.class);
referenceConfig.getInterfaceClass();
referenceConfig.setCheck(false);
RegistryConfig registry = new RegistryConfig();
registry.setAddress(zkUrl1);
applicationConfig.setRegistries(Collections.singletonList(registry));
applicationConfig.setRegistryIds(registry.getId());
referenceConfig.setRegistry(registry);
dubboBootstrap
.application(applicationConfig)
.reference(referenceConfig)
.initialize();
referenceConfig.init();
Assertions.assertTrue(referenceConfig.getInvoker() instanceof MigrationInvoker);
dubboBootstrap.destroy();
}
/**
* Verify that the remote url is directly configured for remote reference
*/
@Test
public void testCreateInvokerWithRemoteUrlForRemoteRefer() {
ReferenceConfig<DemoService> referenceConfig = new ReferenceConfig<>();
referenceConfig.setGeneric(Boolean.FALSE.toString());
referenceConfig.setProtocol("dubbo");
referenceConfig.setInit(true);
referenceConfig.setLazy(false);
referenceConfig.setInjvm(false);
DubboBootstrap dubboBootstrap = DubboBootstrap.newInstance(FrameworkModel.defaultModel());
ApplicationConfig applicationConfig = new ApplicationConfig();
applicationConfig.setName("application1");
Map<String, String> parameters = new HashMap<>();
parameters.put("key1", "value1");
parameters.put("key2", "value2");
applicationConfig.setParameters(parameters);
referenceConfig.refreshed.set(true);
referenceConfig.setInterface(DemoService.class);
referenceConfig.getInterfaceClass();
referenceConfig.setCheck(false);
referenceConfig.setUrl("dubbo://127.0.0.1:20880");
dubboBootstrap
.application(applicationConfig)
.reference(referenceConfig)
.initialize();
referenceConfig.init();
Assertions.assertTrue(referenceConfig.getInvoker() instanceof MockClusterInvoker);
Assertions.assertEquals(Boolean.TRUE, referenceConfig.getInvoker().getUrl().getAttribute(PEER_KEY));
dubboBootstrap.destroy();
}
/**
* Verify that the registry url is directly configured for remote reference
*/
@Test
public void testCreateInvokerWithRegistryUrlForRemoteRefer() {
ReferenceConfig<DemoService> referenceConfig = new ReferenceConfig<>();
referenceConfig.setGeneric(Boolean.FALSE.toString());
referenceConfig.setProtocol("dubbo");
referenceConfig.setInit(true);
referenceConfig.setLazy(false);
referenceConfig.setInjvm(false);
DubboBootstrap dubboBootstrap = DubboBootstrap.newInstance(FrameworkModel.defaultModel());
ApplicationConfig applicationConfig = new ApplicationConfig();
applicationConfig.setName("application1");
Map<String, String> parameters = new HashMap<>();
parameters.put("key1", "value1");
parameters.put("key2", "value2");
applicationConfig.setParameters(parameters);
referenceConfig.refreshed.set(true);
referenceConfig.setInterface(DemoService.class);
referenceConfig.getInterfaceClass();
referenceConfig.setCheck(false);
referenceConfig.setUrl(registryUrl1);
dubboBootstrap
.application(applicationConfig)
.reference(referenceConfig)
.initialize();
referenceConfig.init();
Assertions.assertTrue(referenceConfig.getInvoker() instanceof MigrationInvoker);
dubboBootstrap.destroy();
}
/**
* Verify the service reference of multiple registries
*/
@Test
public void testMultipleRegistryForRemoteRefer() {
ReferenceConfig<DemoService> referenceConfig = new ReferenceConfig<>();
referenceConfig.setGeneric(Boolean.FALSE.toString());
referenceConfig.setProtocol("dubbo");
referenceConfig.setInit(true);
referenceConfig.setLazy(false);
referenceConfig.setInjvm(false);
DubboBootstrap dubboBootstrap = DubboBootstrap.newInstance(FrameworkModel.defaultModel());
ApplicationConfig applicationConfig = new ApplicationConfig();
applicationConfig.setName("application1");
Map<String, String> parameters = new HashMap<>();
parameters.put("key1", "value1");
parameters.put("key2", "value2");
applicationConfig.setParameters(parameters);
referenceConfig.refreshed.set(true);
referenceConfig.setInterface(DemoService.class);
referenceConfig.getInterfaceClass();
referenceConfig.setCheck(false);
RegistryConfig registry1 = new RegistryConfig();
registry1.setAddress(zkUrl1);
registry1.setId("zk1");
RegistryConfig registry2 = new RegistryConfig();
registry2.setAddress(zkUrl2);
registry2.setId("zk2");
List<RegistryConfig> registryConfigs = new ArrayList<>();
registryConfigs.add(registry1);
registryConfigs.add(registry2);
applicationConfig.setRegistries(registryConfigs);
applicationConfig.setRegistryIds("zk1,zk2");
referenceConfig.setRegistries(registryConfigs);
dubboBootstrap
.application(applicationConfig)
.reference(referenceConfig)
.initialize();
referenceConfig.init();
Assertions.assertTrue(referenceConfig.getInvoker() instanceof ZoneAwareClusterInvoker);
dubboBootstrap.destroy();
}
@Test
@Disabled("Disabled due to Github Actions environment")
public void testInjvm() throws Exception {
ApplicationConfig application = new ApplicationConfig();
application.setName("test-protocol-random-port");
application.setEnableFileCache(false);
ApplicationModel.defaultModel().getApplicationConfigManager().setApplication(application);
RegistryConfig registry = new RegistryConfig();
registry.setAddress(zkUrl1);
ProtocolConfig protocol = new ProtocolConfig();
protocol.setName("dubbo");
ServiceConfig<DemoService> demoService;
demoService = new ServiceConfig<>();
demoService.setInterface(DemoService.class);
demoService.setRef(new DemoServiceImpl());
demoService.setRegistry(registry);
demoService.setProtocol(protocol);
ReferenceConfig<DemoService> rc = new ReferenceConfig<>();
rc.setRegistry(registry);
rc.setInterface(DemoService.class.getName());
rc.setScope(SCOPE_REMOTE);
try {
System.setProperty("java.net.preferIPv4Stack", "true");
demoService.export();
rc.get();
Assertions.assertFalse(LOCAL_PROTOCOL.equalsIgnoreCase(
rc.getInvoker().getUrl().getProtocol()));
} finally {
System.clearProperty("java.net.preferIPv4Stack");
rc.destroy();
demoService.unexport();
}
// Manually trigger dubbo resource recycling.
DubboBootstrap.getInstance().destroy();
}
/**
* unit test for dubbo-1765
*/
@Test
public void test1ReferenceRetry() {
ApplicationConfig application = new ApplicationConfig();
application.setName("test-reference-retry");
application.setEnableFileCache(false);
ApplicationModel.defaultModel().getApplicationConfigManager().setApplication(application);
RegistryConfig registry = new RegistryConfig();
registry.setAddress(zkUrl1);
ReferenceConfig<DemoService> rc = new ReferenceConfig<>();
rc.setRegistry(registry);
rc.setInterface(DemoService.class.getName());
boolean success = false;
DemoService demoService = null;
try {
demoService = rc.get();
success = true;
} catch (Exception e) {
// ignore
}
Assertions.assertFalse(success);
Assertions.assertNull(demoService);
try {
System.setProperty("java.net.preferIPv4Stack", "true");
ProxyFactory proxy = ExtensionLoader.getExtensionLoader(ProxyFactory.class).getAdaptiveExtension();
DemoService service = new DemoServiceImpl();
URL url = URL.valueOf("dubbo://127.0.0.1/DemoService")
.addParameter(INTERFACE_KEY, DemoService.class.getName());
InjvmProtocol.getInjvmProtocol(FrameworkModel.defaultModel()).export(proxy.getInvoker(service, DemoService.class, url));
demoService = rc.get();
success = true;
} catch (Exception e) {
// ignore
} finally {
rc.destroy();
InjvmProtocol.getInjvmProtocol(FrameworkModel.defaultModel()).destroy();
System.clearProperty("java.net.preferIPv4Stack");
}
Assertions.assertTrue(success);
Assertions.assertNotNull(demoService);
}
@Test
public void test2ReferenceRetry() {
ApplicationConfig application = new ApplicationConfig();
application.setName("test-reference-retry2");
application.setEnableFileCache(false);
ApplicationModel.defaultModel().getApplicationConfigManager().setApplication(application);
RegistryConfig registry = new RegistryConfig();
registry.setAddress(zkUrl1);
ProtocolConfig protocol = new ProtocolConfig();
protocol.setName("mockprotocol");
ReferenceConfig<DemoService> rc = new ReferenceConfig<>();
rc.setRegistry(registry);
rc.setInterface(DemoService.class.getName());
boolean success = false;
DemoService demoService = null;
try {
demoService = rc.get();
success = true;
} catch (Exception e) {
// ignore
}
Assertions.assertFalse(success);
Assertions.assertNull(demoService);
ServiceConfig<DemoService> sc = new ServiceConfig<>();
sc.setInterface(DemoService.class.getName());
sc.setRef(new DemoServiceImpl());
sc.setRegistry(registry);
sc.setProtocol(protocol);
try {
System.setProperty("java.net.preferIPv4Stack", "true");
sc.export();
demoService = rc.get();
success = true;
} catch (Exception e) {
// ignore
} finally {
rc.destroy();
sc.unexport();
System.clearProperty("java.net.preferIPv4Stack");
}
Assertions.assertTrue(success);
Assertions.assertNotNull(demoService);
}
@Test
public void testMetaData() {
ReferenceConfig config = new ReferenceConfig();
Map<String, String> metaData = config.getMetaData();
Assertions.assertEquals(0, metaData.size(), "Expect empty metadata but found: " + metaData);
// test merged and override consumer attributes
ConsumerConfig consumerConfig = new ConsumerConfig();
consumerConfig.setAsync(true);
consumerConfig.setActives(10);
config.setConsumer(consumerConfig);
config.setAsync(false);// override
metaData = config.getMetaData();
Assertions.assertEquals(2, metaData.size());
Assertions.assertEquals(String.valueOf(consumerConfig.getActives()), metaData.get("actives"));
Assertions.assertEquals(String.valueOf(config.isAsync()), metaData.get("async"));
}
@Test
public void testGetPrefixes() {
ReferenceConfig referenceConfig = new ReferenceConfig();
referenceConfig.setInterface(DemoService.class);
List<String> prefixes = referenceConfig.getPrefixes();
Assertions.assertTrue(prefixes.contains("dubbo.reference." + referenceConfig.getInterface()));
long start = System.currentTimeMillis();
for (int i = 0; i < 1000; i++) {
referenceConfig.getPrefixes();
}
long end = System.currentTimeMillis();
System.out.println("ReferenceConfig get prefixes cost: " + (end - start));
}
@Test
public void testGenericAndInterfaceConflicts() {
ReferenceConfig referenceConfig = new ReferenceConfig();
referenceConfig.setInterface(DemoService.class);
referenceConfig.setGeneric("true");
DubboBootstrap.getInstance()
.application("demo app")
.reference(referenceConfig)
.initialize();
Assertions.assertEquals(GenericService.class, referenceConfig.getInterfaceClass());
}
@Test
public void testLargeReferences() throws InterruptedException {
int amount = 10000;
ModuleConfigManager configManager = DubboBootstrap.getInstance().getApplicationModel().getDefaultModule().getConfigManager();
ApplicationConfig applicationConfig = new ApplicationConfig();
applicationConfig.setName("test-app");
MetadataReportConfig metadataReportConfig = new MetadataReportConfig();
metadataReportConfig.setAddress("metadata://");
ConfigCenterConfig configCenterConfig = new ConfigCenterConfig();
configCenterConfig.setAddress("diamond://");
testInitReferences(0, amount, applicationConfig, metadataReportConfig, configCenterConfig);
configManager.clear();
testInitReferences(0, 1, applicationConfig, metadataReportConfig, configCenterConfig);
configManager.clear();
long t1 = System.currentTimeMillis();
int nThreads = 8;
ExecutorService executorService = Executors.newFixedThreadPool(nThreads);
for (int i = 0; i < nThreads; i++) {
int perCount = (int) (1.0 * amount / nThreads);
int start = perCount * i;
int end = start + perCount;
if (i == nThreads - 1) {
end = amount;
}
int finalEnd = end;
System.out.println(String.format("start thread %s: range: %s - %s, count: %s", i, start, end, (end - start)));
executorService.submit(() -> {
testInitReferences(start, finalEnd, applicationConfig, metadataReportConfig, configCenterConfig);
});
}
executorService.shutdown();
executorService.awaitTermination(100, TimeUnit.SECONDS);
long t2 = System.currentTimeMillis();
long cost = t2 - t1;
System.out.println("Init large references cost: " + cost + "ms");
Assertions.assertEquals(amount, configManager.getReferences().size());
Assertions.assertTrue(cost < 1000, "Init large references too slowly: " + cost);
//test equals
testSearchReferences();
}
private void testSearchReferences() {
long t1 = System.currentTimeMillis();
Collection<ReferenceConfigBase<?>> references = DubboBootstrap.getInstance().getApplicationModel().getDefaultModule().getConfigManager().getReferences();
List<ReferenceConfigBase<?>> results = references.stream().filter(rc -> rc.equals(references.iterator().next()))
.collect(Collectors.toList());
long t2 = System.currentTimeMillis();
long cost = t2 - t1;
System.out.println("Search large references cost: " + cost + "ms");
Assertions.assertEquals(1, results.size());
Assertions.assertTrue(cost < 1000, "Search large references too slowly: " + cost);
}
private long testInitReferences(int start, int end, ApplicationConfig applicationConfig, MetadataReportConfig metadataReportConfig, ConfigCenterConfig configCenterConfig) {
// test add large number of references
long t1 = System.currentTimeMillis();
try {
for (int i = start; i < end; i++) {
ReferenceConfig referenceConfig = new ReferenceConfig();
referenceConfig.setInterface("com.test.TestService" + i);
referenceConfig.setApplication(applicationConfig);
referenceConfig.setMetadataReportConfig(metadataReportConfig);
referenceConfig.setConfigCenter(configCenterConfig);
DubboBootstrap.getInstance().reference(referenceConfig);
//ApplicationModel.defaultModel().getConfigManager().getConfigCenters();
}
} catch (Throwable e) {
e.printStackTrace();
}
long t2 = System.currentTimeMillis();
return t2 - t1;
}
@Test
public void testConstructWithReferenceAnnotation() throws NoSuchFieldException {
Reference reference = getClass().getDeclaredField("innerTest").getAnnotation(Reference.class);
ReferenceConfig referenceConfig = new ReferenceConfig(reference);
Assertions.assertEquals(1, referenceConfig.getMethods().size());
Assertions.assertEquals((referenceConfig.getMethods().get(0)).getName(), "sayHello");
Assertions.assertEquals(1300, (int) (referenceConfig.getMethods().get(0)).getTimeout());
Assertions.assertEquals(4, (int) (referenceConfig.getMethods().get(0)).getRetries());
Assertions.assertEquals((referenceConfig.getMethods().get(0)).getLoadbalance(), "random");
Assertions.assertEquals(3, (int) (referenceConfig.getMethods().get(0)).getActives());
Assertions.assertEquals(5, (int) (referenceConfig.getMethods().get(0)).getExecutes());
Assertions.assertTrue((referenceConfig.getMethods().get(0)).isAsync());
Assertions.assertEquals((referenceConfig.getMethods().get(0)).getOninvokeMethod(), "i");
Assertions.assertEquals((referenceConfig.getMethods().get(0)).getOnreturnMethod(), "r");
Assertions.assertEquals((referenceConfig.getMethods().get(0)).getOnthrowMethod(), "t");
Assertions.assertEquals((referenceConfig.getMethods().get(0)).getCache(), "c");
}
@Test
public void testDifferentClassLoader() throws Exception {
ApplicationConfig applicationConfig = new ApplicationConfig("TestApp");
ApplicationModel applicationModel = new ApplicationModel(FrameworkModel.defaultModel());
applicationModel.getApplicationConfigManager().setApplication(applicationConfig);
ModuleModel moduleModel = new ModuleModel(applicationModel);
DemoService demoService = new DemoServiceImpl();
ServiceConfig<DemoService> serviceConfig = new ServiceConfig<>();
serviceConfig.setInterface(DemoService.class);
serviceConfig.setRegistry(new RegistryConfig(zkUrl1));
serviceConfig.setScopeModel(moduleModel);
serviceConfig.setRef(demoService);
serviceConfig.export();
String basePath = DemoService.class.getProtectionDomain().getCodeSource().getLocation().getFile();
basePath = URLDecoder.decode(basePath, "UTF-8");
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
TestClassLoader classLoader1 = new TestClassLoader(classLoader, basePath);
TestClassLoader classLoader2 = new TestClassLoader(classLoader, basePath);
Class<?> class1 = classLoader1.loadClass(DemoService.class.getName(), false);
Class<?> class2 = classLoader2.loadClass(DemoService.class.getName(), false);
Assertions.assertNotEquals(class1, class2);
ReferenceConfig<DemoService> referenceConfig1 = new ReferenceConfig<>();
referenceConfig1.setInterface(class1);
referenceConfig1.setRegistry(new RegistryConfig(zkUrl1));
referenceConfig1.setScopeModel(moduleModel);
referenceConfig1.setScope("remote");
Object demoService1 = referenceConfig1.get();
for (Class<?> anInterface : demoService1.getClass().getInterfaces()) {
Assertions.assertNotEquals(DemoService.class, anInterface);
}
Assertions.assertTrue(Arrays.stream(demoService1.getClass().getInterfaces()).anyMatch((clazz) -> clazz.getClassLoader().equals(classLoader1)));
java.lang.reflect.Method callBean1 = demoService1.getClass().getDeclaredMethod("callInnerClass");
callBean1.setAccessible(true);
Object result1 = callBean1.invoke(demoService1);
Assertions.assertNotEquals(result1.getClass(), DemoService.InnerClass.class);
Assertions.assertEquals(classLoader1, result1.getClass().getClassLoader());
ReferenceConfig<DemoService> referenceConfig2 = new ReferenceConfig<>();
referenceConfig2.setInterface(class2);
referenceConfig2.setRegistry(new RegistryConfig(zkUrl1));
referenceConfig2.setScopeModel(moduleModel);
referenceConfig2.setScope("remote");
Object demoService2 = referenceConfig2.get();
for (Class<?> anInterface : demoService2.getClass().getInterfaces()) {
Assertions.assertNotEquals(DemoService.class, anInterface);
}
Assertions.assertTrue(Arrays.stream(demoService2.getClass().getInterfaces()).anyMatch((clazz) -> clazz.getClassLoader().equals(classLoader2)));
java.lang.reflect.Method callBean2 = demoService2.getClass().getDeclaredMethod("callInnerClass");
callBean2.setAccessible(true);
Object result2 = callBean2.invoke(demoService2);
Assertions.assertNotEquals(callBean1, callBean2);
Assertions.assertNotEquals(result2.getClass(), DemoService.InnerClass.class);
Assertions.assertEquals(classLoader2, result2.getClass().getClassLoader());
Assertions.assertNotEquals(result1.getClass(), result2.getClass());
applicationModel.destroy();
DubboBootstrap.getInstance().destroy();
Thread.currentThread().setContextClassLoader(classLoader);
Thread.currentThread().getContextClassLoader().loadClass(DemoService.class.getName());
}
@Test
@DisabledForJreRange(min = JRE.JAVA_16)
public void testDifferentClassLoaderRequest() throws Exception {
String basePath = DemoService.class.getProtectionDomain().getCodeSource().getLocation().getFile();
basePath = java.net.URLDecoder.decode(basePath, "UTF-8");
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
TestClassLoader1 classLoader1 = new TestClassLoader1(basePath);
TestClassLoader1 classLoader2 = new TestClassLoader1(basePath);
TestClassLoader2 classLoader3 = new TestClassLoader2(classLoader2, basePath);
ApplicationConfig applicationConfig = new ApplicationConfig("TestApp");
ApplicationModel applicationModel = new ApplicationModel(FrameworkModel.defaultModel());
applicationModel.getApplicationConfigManager().setApplication(applicationConfig);
ModuleModel moduleModel = new ModuleModel(applicationModel);
Class<?> clazz1 = classLoader1.loadClass(MultiClassLoaderService.class.getName(), false);
Class<?> clazz1impl = classLoader1.loadClass(MultiClassLoaderServiceImpl.class.getName(), false);
Class<?> requestClazzCustom1 = compileCustomRequest(classLoader1);
Class<?> resultClazzCustom1 = compileCustomResult(classLoader1);
classLoader1.loadedClass.put(requestClazzCustom1.getName(), requestClazzCustom1);
classLoader1.loadedClass.put(resultClazzCustom1.getName(), resultClazzCustom1);
AtomicReference innerRequestReference = new AtomicReference();
AtomicReference innerResultReference = new AtomicReference();
innerResultReference.set(resultClazzCustom1.newInstance());
Constructor<?> declaredConstructor = clazz1impl.getDeclaredConstructor(AtomicReference.class, AtomicReference.class);
ServiceConfig serviceConfig = new ServiceConfig<>();
serviceConfig.setInterfaceClassLoader(classLoader1);
serviceConfig.setInterface(clazz1);
serviceConfig.setRegistry(new RegistryConfig(zkUrl1));
serviceConfig.setScopeModel(moduleModel);
serviceConfig.setRef(declaredConstructor.newInstance(innerRequestReference, innerResultReference));
serviceConfig.export();
Class<?> clazz2 = classLoader2.loadClass(MultiClassLoaderService.class.getName(), false);
Class<?> requestClazzOrigin = classLoader2.loadClass(MultiClassLoaderServiceRequest.class.getName(), false);
Class<?> requestClazzCustom2 = compileCustomRequest(classLoader2);
Class<?> resultClazzCustom3 = compileCustomResult(classLoader3);
classLoader2.loadedClass.put(requestClazzCustom2.getName(), requestClazzCustom2);
classLoader3.loadedClass.put(resultClazzCustom3.getName(), resultClazzCustom3);
ReferenceConfig<DemoService> referenceConfig1 = new ReferenceConfig<>();
referenceConfig1.setInterface(clazz2);
referenceConfig1.setInterfaceClassLoader(classLoader3);
referenceConfig1.setRegistry(new RegistryConfig(zkUrl1));
referenceConfig1.setScopeModel(moduleModel);
referenceConfig1.setScope("remote");
Object object1 = referenceConfig1.get();
java.lang.reflect.Method callBean1 = object1.getClass().getDeclaredMethod("call", requestClazzOrigin);
callBean1.setAccessible(true);
Object result1 = callBean1.invoke(object1, requestClazzCustom2.newInstance());
Assertions.assertEquals(resultClazzCustom3, result1.getClass());
Assertions.assertNotEquals(classLoader2, result1.getClass().getClassLoader());
Assertions.assertEquals(classLoader1, innerRequestReference.get().getClass().getClassLoader());
applicationModel.destroy();
DubboBootstrap.getInstance().destroy();
Thread.currentThread().setContextClassLoader(classLoader);
Thread.currentThread().getContextClassLoader().loadClass(DemoService.class.getName());
}
private Class<?> compileCustomRequest(ClassLoader classLoader) throws NotFoundException, CannotCompileException {
CtClassBuilder builder = new CtClassBuilder();
builder.setClassName(MultiClassLoaderServiceRequest.class.getName() + "A");
builder.setSuperClassName(MultiClassLoaderServiceRequest.class.getName());
CtClass cls = builder.build(classLoader);
// FIXME support JDK 17
return cls.toClass(classLoader, JavassistCompiler.class.getProtectionDomain());
}
private Class<?> compileCustomResult(ClassLoader classLoader) throws NotFoundException, CannotCompileException {
CtClassBuilder builder = new CtClassBuilder();
builder.setClassName(MultiClassLoaderServiceResult.class.getName() + "A");
builder.setSuperClassName(MultiClassLoaderServiceResult.class.getName());
CtClass cls = builder.build(classLoader);
return cls.toClass(classLoader, JavassistCompiler.class.getProtectionDomain());
}
@Reference(methods = {@Method(name = "sayHello", timeout = 1300, retries = 4, loadbalance = "random", async = true,
actives = 3, executes = 5, deprecated = true, sticky = true, oninvoke = "instance.i", onthrow = "instance.t", onreturn = "instance.r", cache = "c", validation = "v",
arguments = {@Argument(index = 24, callback = true, type = "sss")})})
private InnerTest innerTest;
private class InnerTest {
}
private static class TestClassLoader extends ClassLoader {
private String basePath;
public TestClassLoader(ClassLoader parent, String basePath) {
super(parent);
this.basePath = basePath;
}
@Override
protected Class<?> findClass(String name) throws ClassNotFoundException {
try {
byte[] bytes = loadClassData(name);
return defineClass(name, bytes, 0, bytes.length);
} catch (Exception e) {
throw new ClassNotFoundException();
}
}
@Override
public Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException {
Class<?> loadedClass = this.findLoadedClass(name);
if (loadedClass != null) {
return loadedClass;
} else {
try {
if (name.equals("org.apache.dubbo.config.api.DemoService") || name.equals("org.apache.dubbo.config.api.DemoService$InnerClass")) {
Class<?> aClass = this.findClass(name);
if (resolve) {
this.resolveClass(aClass);
}
return aClass;
} else {
return super.loadClass(name, resolve);
}
} catch (Exception e) {
return super.loadClass(name, resolve);
}
}
}
public byte[] loadClassData(String className) throws IOException {
className = className.replaceAll("\\.", "/");
String path = basePath + File.separator + className + ".class";
FileInputStream fileInputStream;
byte[] classBytes;
fileInputStream = new FileInputStream(path);
int length = fileInputStream.available();
classBytes = new byte[length];
fileInputStream.read(classBytes);
fileInputStream.close();
return classBytes;
}
}
private static class TestClassLoader1 extends ClassLoader {
private String basePath;
public TestClassLoader1(String basePath) {
this.basePath = basePath;
}
Map<String, Class<?>> loadedClass = new ConcurrentHashMap<>();
@Override
protected Class<?> findClass(String name) throws ClassNotFoundException {
try {
byte[] bytes = loadClassData(name);
return defineClass(name, bytes, 0, bytes.length);
} catch (Exception e) {
throw new ClassNotFoundException();
}
}
@Override
public Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException {
if (loadedClass.containsKey(name)) {
return loadedClass.get(name);
}
if (name.startsWith("demo")) {
Class<?> aClass = this.findClass(name);
this.loadedClass.put(name, aClass);
if (resolve) {
this.resolveClass(aClass);
}
return aClass;
} else {
Class<?> loadedClass = this.findLoadedClass(name);
if (loadedClass != null) {
return loadedClass;
} else {
return super.loadClass(name, resolve);
}
}
}
public byte[] loadClassData(String className) throws IOException {
className = className.replaceAll("\\.", "/");
String path = basePath + File.separator + className + ".class";
FileInputStream fileInputStream;
byte[] classBytes;
fileInputStream = new FileInputStream(path);
int length = fileInputStream.available();
classBytes = new byte[length];
fileInputStream.read(classBytes);
fileInputStream.close();
return classBytes;
}
}
private static class TestClassLoader2 extends ClassLoader {
private String basePath;
private TestClassLoader1 testClassLoader;
Map<String, Class<?>> loadedClass = new ConcurrentHashMap<>();
public TestClassLoader2(TestClassLoader1 testClassLoader, String basePath) {
this.testClassLoader = testClassLoader;
this.basePath = basePath;
}
@Override
protected Class<?> findClass(String name) throws ClassNotFoundException {
try {
byte[] bytes = loadClassData(name);
return defineClass(name, bytes, 0, bytes.length);
} catch (Exception e) {
throw new ClassNotFoundException();
}
}
@Override
public Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException {
if (loadedClass.containsKey(name)) {
return loadedClass.get(name);
}
if (name.startsWith("demo.MultiClassLoaderServiceRe")) {
Class<?> aClass = this.findClass(name);
this.loadedClass.put(name, aClass);
if (resolve) {
this.resolveClass(aClass);
}
return aClass;
} else {
return testClassLoader.loadClass(name, resolve);
}
}
public byte[] loadClassData(String className) throws IOException {
className = className.replaceAll("\\.", "/");
String path = basePath + File.separator + className + ".class";
FileInputStream fileInputStream;
byte[] classBytes;
fileInputStream = new FileInputStream(path);
int length = fileInputStream.available();
classBytes = new byte[length];
fileInputStream.read(classBytes);
fileInputStream.close();
return classBytes;
}
}
}