Remove EmptyServiceAutoCleaner.java

This commit is contained in:
KomachiSion 2022-08-26 14:55:35 +08:00
parent 49e12c8b8e
commit 989922600c
7 changed files with 0 additions and 923 deletions

View File

@ -1,137 +0,0 @@
/*
* Copyright 1999-2018 Alibaba Group Holding Ltd.
*
* Licensed 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 com.alibaba.nacos.naming.consistency.persistent;
import com.alibaba.nacos.common.utils.StringUtils;
import com.alibaba.nacos.common.utils.VersionUtils;
import com.alibaba.nacos.core.cluster.Member;
import com.alibaba.nacos.core.cluster.MemberMetaDataConstants;
import com.alibaba.nacos.core.cluster.ServerMemberManager;
import com.alibaba.nacos.naming.misc.GlobalExecutor;
import com.alibaba.nacos.sys.env.EnvUtil;
import org.springframework.stereotype.Component;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.TimeUnit;
import java.util.function.Consumer;
/**
* An automated task that determines whether all nodes in the current cluster meet the requirements of a particular
* version.
*
* <p>This will be removed in a future release, just to smooth the transition.
*
* @author <a href="mailto:liaochuntao@live.com">liaochuntao</a>
*/
@Component
public class ClusterVersionJudgement {
private volatile boolean allMemberIsNewVersion = false;
private final ServerMemberManager memberManager;
private final List<ConsumerWithPriority> observers = new CopyOnWriteArrayList<>();
public ClusterVersionJudgement(ServerMemberManager memberManager) {
this.memberManager = memberManager;
GlobalExecutor.submitClusterVersionJudge(this::runVersionListener, TimeUnit.SECONDS.toMillis(5));
}
/**
* register member version watcher.
*
* @param observer Listens for the latest version of all current nodes
* @param priority The higher the priority, the first to be notified
*/
public void registerObserver(Consumer<Boolean> observer, int priority) {
observers.add(new ConsumerWithPriority(observer, priority));
}
protected void runVersionListener() {
// Single machine mode or close upgrade feature, do upgrade operation directly.
if (EnvUtil.getStandaloneMode() || !EnvUtil.isSupportUpgradeFrom1X()) {
notifyAllListener();
return;
}
boolean finish = false;
try {
finish = judge();
} finally {
if (!finish) {
GlobalExecutor.submitClusterVersionJudge(this::runVersionListener, TimeUnit.SECONDS.toMillis(5));
}
}
}
protected boolean judge() {
boolean finish = false;
Collection<Member> members = memberManager.allMembers();
final String oldVersion = "1.4.0";
boolean allMemberIsNewVersion = true;
for (Member member : members) {
final String curV = (String) member.getExtendVal(MemberMetaDataConstants.VERSION);
if (StringUtils.isBlank(curV) || VersionUtils.compareVersion(oldVersion, curV) > 0) {
allMemberIsNewVersion = false;
}
}
// can only trigger once
if (allMemberIsNewVersion && !this.allMemberIsNewVersion) {
notifyAllListener();
finish = true;
}
return finish;
}
private void notifyAllListener() {
this.allMemberIsNewVersion = true;
Collections.sort(observers);
for (ConsumerWithPriority consumer : observers) {
consumer.consumer.accept(true);
}
}
public boolean allMemberIsNewVersion() {
return allMemberIsNewVersion;
}
/**
* Only used for upgrade to 2.0.0
*/
public void reset() {
allMemberIsNewVersion = false;
}
private static class ConsumerWithPriority implements Comparable<ConsumerWithPriority> {
private final Consumer<Boolean> consumer;
private final int priority;
public ConsumerWithPriority(Consumer<Boolean> consumer, int priority) {
this.consumer = consumer;
this.priority = priority;
}
@Override
public int compareTo(ConsumerWithPriority o) {
return o.priority - this.priority;
}
}
}

View File

@ -29,7 +29,6 @@ import com.alibaba.nacos.naming.consistency.ConsistencyService;
import com.alibaba.nacos.naming.consistency.Datum;
import com.alibaba.nacos.naming.consistency.KeyBuilder;
import com.alibaba.nacos.naming.consistency.RecordListener;
import com.alibaba.nacos.naming.core.v2.cleaner.EmptyServiceAutoCleaner;
import com.alibaba.nacos.naming.misc.GlobalExecutor;
import com.alibaba.nacos.naming.misc.Loggers;
import com.alibaba.nacos.naming.misc.Message;
@ -43,7 +42,6 @@ import com.alibaba.nacos.naming.pojo.InstanceOperationInfo;
import com.alibaba.nacos.naming.push.UdpPushService;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.ArrayNode;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
@ -96,15 +94,6 @@ public class ServiceManager implements RecordListener<Service> {
private final UdpPushService pushService;
@Value("${nacos.naming.empty-service.auto-clean:false}")
private boolean emptyServiceAutoClean;
@Value("${nacos.naming.empty-service.clean.initial-delay-ms:60000}")
private int cleanEmptyServiceDelay;
@Value("${nacos.naming.empty-service.clean.period-time-ms:20000}")
private int cleanEmptyServicePeriod;
public ServiceManager(SwitchDomain switchDomain, DistroMapper distroMapper, ServerMemberManager memberManager,
UdpPushService pushService) {
this.switchDomain = switchDomain;
@ -122,22 +111,6 @@ public class ServiceManager implements RecordListener<Service> {
GlobalExecutor.submitServiceUpdateManager(new UpdatedServiceProcessor());
if (emptyServiceAutoClean) {
Loggers.SRV_LOG.info("open empty service auto clean job, initialDelay : {} ms, period : {} ms",
cleanEmptyServiceDelay, cleanEmptyServicePeriod);
// delay 60s, period 20s;
// This task is not recommended to be performed frequently in order to avoid
// the possibility that the service cache information may just be deleted
// and then created due to the heartbeat mechanism
GlobalExecutor
.scheduleServiceAutoClean(new EmptyServiceAutoCleaner(this, distroMapper), cleanEmptyServiceDelay,
cleanEmptyServicePeriod);
}
try {
Loggers.SRV_LOG.info("listen for service meta change");
consistencyService.listen(KeyBuilder.SERVICE_META_KEY_PREFIX, this);

View File

@ -1,103 +0,0 @@
/*
* Copyright 1999-2020 Alibaba Group Holding Ltd.
*
* Licensed 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 com.alibaba.nacos.naming.core.v2.cleaner;
import com.alibaba.nacos.naming.core.DistroMapper;
import com.alibaba.nacos.naming.core.Service;
import com.alibaba.nacos.naming.core.ServiceManager;
import com.alibaba.nacos.naming.misc.Loggers;
import java.util.Map;
import java.util.stream.Stream;
/**
* Empty Service Auto Cleaner.
*
* @author xiweng.yy
*/
public class EmptyServiceAutoCleaner extends AbstractNamingCleaner {
private static final int MAX_FINALIZE_COUNT = 3;
private final ServiceManager serviceManager;
private final DistroMapper distroMapper;
public EmptyServiceAutoCleaner(ServiceManager serviceManager, DistroMapper distroMapper) {
this.serviceManager = serviceManager;
this.distroMapper = distroMapper;
}
@Override
public void run() {
// Parallel flow opening threshold
int parallelSize = 100;
for (String each : serviceManager.getAllNamespaces()) {
Map<String, Service> serviceMap = serviceManager.chooseServiceMap(each);
Stream<Map.Entry<String, Service>> stream;
if (serviceMap.size() > parallelSize) {
stream = serviceMap.entrySet().parallelStream();
} else {
stream = serviceMap.entrySet().stream();
}
stream.filter(entry -> {
final String serviceName = entry.getKey();
return distroMapper.responsible(serviceName);
}).forEach(entry -> serviceMap.computeIfPresent(entry.getKey(), (serviceName, service) -> {
if (service.isEmpty()) {
// To avoid violent Service removal, the number of times the Service
// experiences Empty is determined by finalizeCnt, and if the specified
// value is reached, it is removed
if (service.getFinalizeCount() > MAX_FINALIZE_COUNT) {
Loggers.SRV_LOG
.warn("namespace : {}, [{}] services are automatically cleaned", each, serviceName);
try {
serviceManager.easyRemoveService(each, serviceName);
} catch (Exception e) {
Loggers.SRV_LOG
.error("namespace : {}, [{}] services are automatically clean has " + "error : {}",
each, serviceName, e);
}
}
service.setFinalizeCount(service.getFinalizeCount() + 1);
Loggers.SRV_LOG.debug("namespace : {}, [{}] The number of times the current service experiences "
+ "an empty instance is : {}", each, serviceName, service.getFinalizeCount());
} else {
service.setFinalizeCount(0);
}
return service;
}));
}
}
@Override
public String getType() {
return null;
}
@Override
public void doClean() {
}
}

View File

@ -89,24 +89,6 @@ public class GlobalExecutor {
.newFixedExecutorService(ClassUtils.getCanonicalName(NamingApp.class), 2,
new NameThreadFactory("com.alibaba.nacos.naming.service.update.http.handler"));
/**
* Empty service auto clean executor.
*
* @deprecated will remove in v2.1.x.
*/
@Deprecated
private static final ScheduledExecutorService EMPTY_SERVICE_AUTO_CLEAN_EXECUTOR = ExecutorFactory.Managed
.newSingleScheduledExecutorService(ClassUtils.getCanonicalName(NamingApp.class),
new NameThreadFactory("com.alibaba.nacos.naming.service.empty.auto-clean"));
private static final ScheduledExecutorService DISTRO_NOTIFY_EXECUTOR = ExecutorFactory.Managed
.newSingleScheduledExecutorService(ClassUtils.getCanonicalName(NamingApp.class),
new NameThreadFactory("com.alibaba.nacos.naming.distro.notifier"));
private static final ScheduledExecutorService NAMING_HEALTH_CHECK_EXECUTOR = ExecutorFactory.Managed
.newSingleScheduledExecutorService(ClassUtils.getCanonicalName(NamingApp.class),
new NameThreadFactory("com.alibaba.nacos.naming.health-check.notifier"));
private static final ExecutorService MYSQL_CHECK_EXECUTOR = ExecutorFactory.Managed
.newFixedExecutorService(ClassUtils.getCanonicalName(NamingApp.class), DEFAULT_THREAD_COUNT,
new NameThreadFactory("com.alibaba.nacos.naming.mysql.checker"));
@ -175,18 +157,6 @@ public class GlobalExecutor {
return NAMING_TIMER_EXECUTOR.scheduleWithFixedDelay(runnable, 0, TICK_PERIOD_MS, TimeUnit.MILLISECONDS);
}
public static void scheduleMcpPushTask(Runnable runnable, long initialDelay, long period) {
NAMING_TIMER_EXECUTOR.scheduleAtFixedRate(runnable, initialDelay, period, TimeUnit.MILLISECONDS);
}
public static ScheduledFuture submitClusterVersionJudge(Runnable runnable, long delay) {
return NAMING_TIMER_EXECUTOR.schedule(runnable, delay, TimeUnit.MILLISECONDS);
}
public static void submitDistroNotifyTask(Runnable runnable) {
DISTRO_NOTIFY_EXECUTOR.submit(runnable);
}
/**
* Submit service update for v1.x.
*
@ -198,19 +168,6 @@ public class GlobalExecutor {
SERVICE_UPDATE_EXECUTOR.execute(runnable);
}
/**
* Schedule empty service auto clean for v1.x.
*
* @param runnable runnable
* @param initialDelay initial delay milliseconds
* @param period period between twice clean
* @deprecated will remove in v2.1.x.
*/
@Deprecated
public static void scheduleServiceAutoClean(Runnable runnable, long initialDelay, long period) {
EMPTY_SERVICE_AUTO_CLEAN_EXECUTOR.scheduleAtFixedRate(runnable, initialDelay, period, TimeUnit.MILLISECONDS);
}
/**
* submitServiceUpdateManager.
*
@ -235,10 +192,6 @@ public class GlobalExecutor {
SERVICE_SYNCHRONIZATION_EXECUTOR.schedule(command, delay, unit);
}
public static void scheduleNamingHealthCheck(Runnable command, long delay, TimeUnit unit) {
NAMING_HEALTH_CHECK_EXECUTOR.schedule(command, delay, unit);
}
public static void executeMysqlCheckTask(Runnable runnable) {
MYSQL_CHECK_EXECUTOR.execute(runnable);
}

View File

@ -1,61 +0,0 @@
/*
* Copyright 1999-2018 Alibaba Group Holding Ltd.
*
* Licensed 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 com.alibaba.nacos.naming.core;
import com.alibaba.nacos.api.common.Constants;
import com.alibaba.nacos.api.exception.NacosException;
import com.alibaba.nacos.naming.BaseTest;
import org.junit.Assert;
import org.junit.Test;
import org.mockito.InjectMocks;
import org.mockito.Spy;
import java.util.List;
public class DomainsManagerTest extends BaseTest {
@Spy
@InjectMocks
private ServiceManager manager;
@Test
public void easyRemoveDom() throws Exception {
Service service = new Service(TEST_SERVICE_NAME);
service.setNamespaceId(TEST_NAMESPACE);
manager.putService(service);
manager.easyRemoveService(TEST_NAMESPACE, TEST_SERVICE_NAME);
}
@Test
public void easyRemoveDomNotExist() throws Exception {
expectedException.expect(NacosException.class);
expectedException.expectMessage("specified service not exist, serviceName : " + TEST_SERVICE_NAME);
manager.easyRemoveService(Constants.DEFAULT_NAMESPACE_ID, TEST_SERVICE_NAME);
}
@Test
public void searchDom() {
Service service = new Service(TEST_SERVICE_NAME);
service.setNamespaceId(TEST_NAMESPACE);
manager.putService(service);
List<Service> list = manager.searchServices(TEST_NAMESPACE, "(.*)test(.*)");
Assert.assertNotNull(list);
Assert.assertEquals(1, list.size());
Assert.assertEquals(TEST_SERVICE_NAME, list.get(0).getName());
}
}

View File

@ -1,473 +0,0 @@
/*
* Copyright 1999-2018 Alibaba Group Holding Ltd.
*
* Licensed 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 com.alibaba.nacos.naming.core;
import com.alibaba.nacos.api.common.Constants;
import com.alibaba.nacos.api.exception.NacosException;
import com.alibaba.nacos.api.naming.PreservedMetadataKeys;
import com.alibaba.nacos.common.utils.CollectionUtils;
import com.alibaba.nacos.common.utils.JacksonUtils;
import com.alibaba.nacos.common.utils.StringUtils;
import com.alibaba.nacos.core.cluster.ServerMemberManager;
import com.alibaba.nacos.naming.BaseTest;
import com.alibaba.nacos.naming.consistency.ConsistencyService;
import com.alibaba.nacos.naming.consistency.Datum;
import com.alibaba.nacos.naming.consistency.KeyBuilder;
import com.alibaba.nacos.naming.core.ServiceManager.ServiceChecksum;
import com.alibaba.nacos.naming.misc.Message;
import com.alibaba.nacos.naming.misc.Synchronizer;
import com.alibaba.nacos.naming.misc.UtilsAndCommons;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.mockito.Mock;
import org.springframework.test.util.ReflectionTestUtils;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import static com.alibaba.nacos.naming.misc.UtilsAndCommons.UPDATE_INSTANCE_METADATA_ACTION_REMOVE;
import static com.alibaba.nacos.naming.misc.UtilsAndCommons.UPDATE_INSTANCE_METADATA_ACTION_UPDATE;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
public class ServiceManagerTest extends BaseTest {
private ServiceManager serviceManager;
@Mock
private ConsistencyService consistencyService;
@Mock
private Synchronizer synchronizer;
@Mock
private ServerMemberManager serverMemberManager;
private Service service;
private Cluster cluster;
private Instance instance;
private Instance instance2;
private List<String> serviceNames;
@Before
public void before() {
super.before();
serviceManager = new ServiceManager(switchDomain, distroMapper, serverMemberManager, pushService);
ReflectionTestUtils.setField(serviceManager, "consistencyService", consistencyService);
ReflectionTestUtils.setField(serviceManager, "synchronizer", synchronizer);
mockInjectSwitchDomain();
mockInjectDistroMapper();
mockService();
mockCluster();
mockInstance();
mockServiceName();
}
@After
public void tearDown() throws Exception {
service.destroy();
}
private void mockService() {
service = new Service(TEST_SERVICE_NAME);
service.setNamespaceId(TEST_NAMESPACE);
}
private void mockCluster() {
cluster = new Cluster(TEST_CLUSTER_NAME, service);
}
private void mockInstance() {
instance = new Instance("1.1.1.1", 1, TEST_CLUSTER_NAME);
Map<String, String> metadata = new HashMap<>();
metadata.put("key1", "value1");
instance.setMetadata(metadata);
instance2 = new Instance("2.2.2.2", 2);
}
private void mockServiceName() {
serviceNames = new ArrayList<>(5);
for (int i = 0; i < 32; i++) {
serviceNames.add(String.valueOf(i));
}
}
@Test
public void testGetAllNamespaces() throws NacosException {
assertTrue(serviceManager.getAllNamespaces().isEmpty());
serviceManager.createEmptyService(TEST_NAMESPACE, TEST_SERVICE_NAME, true);
assertFalse(serviceManager.getAllNamespaces().isEmpty());
assertEquals(1, serviceManager.getAllNamespaces().size());
assertEquals(TEST_NAMESPACE, serviceManager.getAllNamespaces().iterator().next());
}
@Test
public void testGetAllServiceNames() throws NacosException {
assertTrue(serviceManager.getAllServiceNames().isEmpty());
serviceManager.createEmptyService(TEST_NAMESPACE, TEST_SERVICE_NAME, true);
assertFalse(serviceManager.getAllServiceNames().isEmpty());
assertEquals(1, serviceManager.getAllServiceNames().size());
assertEquals(1, serviceManager.getAllServiceNames(TEST_NAMESPACE).size());
assertEquals(TEST_SERVICE_NAME, serviceManager.getAllServiceNames(TEST_NAMESPACE).iterator().next());
}
@Test
public void testGetAllServiceNamesOrder() throws NacosException {
assertTrue(serviceManager.getAllServiceNames().isEmpty());
for (String serviceName : serviceNames) {
serviceManager.createEmptyService(TEST_NAMESPACE, serviceName, true);
}
assertFalse(serviceManager.getAllServiceNames().isEmpty());
assertEquals(1, serviceManager.getAllServiceNames().size());
assertEquals(serviceNames.size(), serviceManager.getAllServiceNames(TEST_NAMESPACE).size());
Collections.sort(serviceNames);
Iterator<String> iterator = serviceManager.getAllServiceNames(TEST_NAMESPACE).iterator();
int index = 0;
while (iterator.hasNext()) {
String next = iterator.next();
assertEquals(next, serviceNames.get(index));
index++;
}
}
@Test
public void testGetAllServiceNameList() throws NacosException {
assertTrue(serviceManager.getAllServiceNameList(TEST_NAMESPACE).isEmpty());
serviceManager.createEmptyService(TEST_NAMESPACE, TEST_SERVICE_NAME, true);
assertFalse(serviceManager.getAllServiceNameList(TEST_NAMESPACE).isEmpty());
assertEquals(1, serviceManager.getAllServiceNameList(TEST_NAMESPACE).size());
assertEquals(TEST_SERVICE_NAME, serviceManager.getAllServiceNameList(TEST_NAMESPACE).get(0));
}
@Test
public void testGetAllServiceNameListOrder() throws NacosException {
assertTrue(serviceManager.getAllServiceNameList(TEST_NAMESPACE).isEmpty());
for (String serviceName : serviceNames) {
serviceManager.createEmptyService(TEST_NAMESPACE, serviceName, true);
}
assertFalse(serviceManager.getAllServiceNameList(TEST_NAMESPACE).isEmpty());
assertEquals(serviceNames.size(), serviceManager.getAllServiceNameList(TEST_NAMESPACE).size());
List<String> allServiceNameList = serviceManager.getAllServiceNameList(TEST_NAMESPACE);
Collections.sort(serviceNames);
for (int i = 0; i < allServiceNameList.size(); i++) {
assertEquals(allServiceNameList.get(i), serviceNames.get(i));
}
}
@Test
public void testGetResponsibleServices() throws NacosException {
when(distroMapper.responsible(TEST_SERVICE_NAME)).thenReturn(true);
assertEquals(0, serviceManager.getResponsibleServiceCount());
serviceManager.createEmptyService(TEST_NAMESPACE, TEST_SERVICE_NAME, true);
assertEquals(1, serviceManager.getResponsibleServiceCount());
assertEquals(TEST_SERVICE_NAME,
serviceManager.getResponsibleServices().get(TEST_NAMESPACE).iterator().next().getName());
}
@Test
public void getResponsibleInstanceCount() throws NacosException {
when(distroMapper.responsible(TEST_SERVICE_NAME)).thenReturn(true);
assertEquals(0, serviceManager.getResponsibleInstanceCount());
serviceManager.createEmptyService(TEST_NAMESPACE, TEST_SERVICE_NAME, true);
Service service = serviceManager.getService(TEST_NAMESPACE, TEST_SERVICE_NAME);
service.addCluster(cluster);
((Set<Instance>) ReflectionTestUtils.getField(cluster, "ephemeralInstances")).add(instance);
assertEquals(1, serviceManager.getResponsibleInstanceCount());
}
@Test
public void testCreateEmptyServiceForEphemeral() throws NacosException {
assertFalse(serviceManager.containService(TEST_NAMESPACE, TEST_SERVICE_NAME));
assertEquals(0, serviceManager.getServiceCount());
serviceManager.createServiceIfAbsent(TEST_NAMESPACE, TEST_SERVICE_NAME, true,
new Cluster(TEST_CLUSTER_NAME, service));
assertTrue(serviceManager.containService(TEST_NAMESPACE, TEST_SERVICE_NAME));
assertEquals(1, serviceManager.getServiceCount());
verify(consistencyService).listen(eq(KeyBuilder.buildInstanceListKey(TEST_NAMESPACE, TEST_SERVICE_NAME, true)),
any(Service.class));
verify(consistencyService).listen(eq(KeyBuilder.buildInstanceListKey(TEST_NAMESPACE, TEST_SERVICE_NAME, false)),
any(Service.class));
verify(consistencyService, never())
.put(eq(KeyBuilder.buildServiceMetaKey(TEST_NAMESPACE, TEST_SERVICE_NAME)), any(Service.class));
}
@Test
public void testCreateEmptyServiceForPersistent() throws NacosException {
assertFalse(serviceManager.containService(TEST_NAMESPACE, TEST_SERVICE_NAME));
assertEquals(0, serviceManager.getServiceCount());
serviceManager.createServiceIfAbsent(TEST_NAMESPACE, TEST_SERVICE_NAME, false,
new Cluster(TEST_CLUSTER_NAME, service));
assertTrue(serviceManager.containService(TEST_NAMESPACE, TEST_SERVICE_NAME));
assertEquals(1, serviceManager.getServiceCount());
verify(consistencyService).listen(eq(KeyBuilder.buildInstanceListKey(TEST_NAMESPACE, TEST_SERVICE_NAME, true)),
any(Service.class));
verify(consistencyService).listen(eq(KeyBuilder.buildInstanceListKey(TEST_NAMESPACE, TEST_SERVICE_NAME, false)),
any(Service.class));
verify(consistencyService)
.put(eq(KeyBuilder.buildServiceMetaKey(TEST_NAMESPACE, TEST_SERVICE_NAME)), any(Service.class));
}
@Test
public void testEasyRemoveServiceSuccessfully() throws Exception {
serviceManager.createEmptyService(TEST_NAMESPACE, TEST_SERVICE_NAME, true);
serviceManager.easyRemoveService(TEST_NAMESPACE, TEST_SERVICE_NAME);
verify(consistencyService).remove(KeyBuilder.buildServiceMetaKey(TEST_NAMESPACE, TEST_SERVICE_NAME));
}
@Test
public void testEasyRemoveServiceFailed() throws Exception {
expectedException.expect(NacosException.class);
expectedException.expectMessage("specified service not exist, serviceName : " + TEST_SERVICE_NAME);
serviceManager.easyRemoveService(TEST_NAMESPACE, TEST_SERVICE_NAME);
}
@Test
public void testRegisterInstance() throws NacosException {
assertEquals(0, serviceManager.getInstanceCount());
serviceManager.registerInstance(TEST_NAMESPACE, TEST_SERVICE_NAME, instance);
String instanceListKey = KeyBuilder.buildInstanceListKey(TEST_NAMESPACE, TEST_SERVICE_NAME, true);
verify(consistencyService).put(eq(instanceListKey), any(Instances.class));
}
@Test
public void testUpdateInstance() throws NacosException {
serviceManager.createEmptyService(TEST_NAMESPACE, TEST_SERVICE_NAME, true);
Service service = serviceManager.getService(TEST_NAMESPACE, TEST_SERVICE_NAME);
service.addCluster(cluster);
((Set<Instance>) ReflectionTestUtils.getField(cluster, "ephemeralInstances")).add(instance);
serviceManager.updateInstance(TEST_NAMESPACE, TEST_SERVICE_NAME, instance);
String instanceListKey = KeyBuilder.buildInstanceListKey(TEST_NAMESPACE, TEST_SERVICE_NAME, true);
verify(consistencyService).put(eq(instanceListKey), any(Instances.class));
}
@Test
public void testUpdateMetadata() throws NacosException {
serviceManager.createEmptyService(TEST_NAMESPACE, TEST_SERVICE_NAME, true);
List<Instance> instanceList = new LinkedList<>();
Datum datam = new Datum();
datam.key = KeyBuilder.buildInstanceListKey(TEST_NAMESPACE, TEST_SERVICE_NAME, true);
Instances instances = new Instances();
instanceList.add(instance);
instanceList.add(instance2);
instances.setInstanceList(instanceList);
datam.value = instances;
when(consistencyService.get(KeyBuilder.buildInstanceListKey(TEST_NAMESPACE, TEST_SERVICE_NAME, true)))
.thenReturn(datam);
Instance updateMetadataInstance = new Instance();
updateMetadataInstance.setIp(instance.getIp());
updateMetadataInstance.setPort(instance.getPort());
updateMetadataInstance.setClusterName(cluster.getName());
updateMetadataInstance.setEphemeral(instance.isEphemeral());
Map<String, String> updateMetadata = new HashMap<>(16);
updateMetadata.put("key1", "new-value1");
updateMetadata.put("key2", "value2");
updateMetadataInstance.setMetadata(updateMetadata);
//all=false, update input instances
serviceManager
.updateMetadata(TEST_NAMESPACE, TEST_SERVICE_NAME, true, UPDATE_INSTANCE_METADATA_ACTION_UPDATE, false,
CollectionUtils.list(updateMetadataInstance), updateMetadata);
assertEquals(instance.getMetadata().get("key1"), "new-value1");
assertEquals(instance.getMetadata().get("key2"), "value2");
//all=true, update all instances
serviceManager
.updateMetadata(TEST_NAMESPACE, TEST_SERVICE_NAME, true, UPDATE_INSTANCE_METADATA_ACTION_UPDATE, true,
null, updateMetadata);
assertEquals(instance2.getMetadata().get("key1"), "new-value1");
assertEquals(instance2.getMetadata().get("key2"), "value2");
Instance deleteMetadataInstance = new Instance();
deleteMetadataInstance.setIp(instance.getIp());
deleteMetadataInstance.setPort(instance.getPort());
deleteMetadataInstance.setClusterName(cluster.getName());
deleteMetadataInstance.setEphemeral(instance.isEphemeral());
Map<String, String> deleteMetadata = new HashMap<>(16);
deleteMetadata.put("key2", null);
deleteMetadata.put("key3", null);
updateMetadataInstance.setMetadata(deleteMetadata);
serviceManager
.updateMetadata(TEST_NAMESPACE, TEST_SERVICE_NAME, true, UPDATE_INSTANCE_METADATA_ACTION_REMOVE, false,
CollectionUtils.list(deleteMetadataInstance), deleteMetadata);
assertEquals(instance.getMetadata().get("key1"), "new-value1");
assertNull(instance.getMetadata().get("key2"));
assertNull(instance.getMetadata().get("key3"));
serviceManager
.updateMetadata(TEST_NAMESPACE, TEST_SERVICE_NAME, true, UPDATE_INSTANCE_METADATA_ACTION_REMOVE, true,
null, deleteMetadata);
assertEquals(instance2.getMetadata().get("key1"), "new-value1");
assertNull(instance2.getMetadata().get("key2"));
assertNull(instance2.getMetadata().get("key3"));
}
@Test
public void testRemoveInstance() throws NacosException {
serviceManager.createEmptyService(TEST_NAMESPACE, TEST_SERVICE_NAME, true);
serviceManager.removeInstance(TEST_NAMESPACE, TEST_SERVICE_NAME, true, instance);
String instanceListKey = KeyBuilder.buildInstanceListKey(TEST_NAMESPACE, TEST_SERVICE_NAME, true);
verify(consistencyService).put(eq(instanceListKey), any(Instances.class));
}
@Test
public void testGetInstance() throws NacosException {
assertNull(serviceManager.getInstance(TEST_NAMESPACE, TEST_SERVICE_NAME, TEST_CLUSTER_NAME, "1.1.1.1", 1));
serviceManager.createEmptyService(TEST_NAMESPACE, TEST_SERVICE_NAME, true);
assertNull(serviceManager.getInstance(TEST_NAMESPACE, TEST_SERVICE_NAME, TEST_CLUSTER_NAME, "1.1.1.1", 1));
Service service = serviceManager.getService(TEST_NAMESPACE, TEST_SERVICE_NAME);
service.addCluster(cluster);
((Set<Instance>) ReflectionTestUtils.getField(cluster, "ephemeralInstances")).add(instance);
assertEquals(instance,
serviceManager.getInstance(TEST_NAMESPACE, TEST_SERVICE_NAME, TEST_CLUSTER_NAME, "1.1.1.1", 1));
assertNull(serviceManager.getInstance(TEST_NAMESPACE, TEST_SERVICE_NAME, TEST_CLUSTER_NAME, "2.2.2.2", 2));
}
@Test
public void testUpdateIpAddresses() throws Exception {
List<Instance> instanceList = serviceManager
.updateIpAddresses(service, UtilsAndCommons.UPDATE_INSTANCE_ACTION_ADD, true, instance);
Assert.assertEquals(1, instanceList.size());
Assert.assertEquals(instance, instanceList.get(0));
Assert.assertEquals(1, service.getClusterMap().size());
Assert.assertEquals(new Cluster(instance.getClusterName(), service),
service.getClusterMap().get(TEST_CLUSTER_NAME));
Datum datam = new Datum();
datam.key = KeyBuilder.buildInstanceListKey(TEST_NAMESPACE, TEST_SERVICE_NAME, true);
Instances instances = new Instances();
instanceList.add(instance2);
instances.setInstanceList(instanceList);
datam.value = instances;
when(consistencyService.get(KeyBuilder.buildInstanceListKey(TEST_NAMESPACE, TEST_SERVICE_NAME, true)))
.thenReturn(datam);
service.getClusterMap().get(TEST_CLUSTER_NAME).updateIps(instanceList, true);
instanceList = serviceManager
.updateIpAddresses(service, UtilsAndCommons.UPDATE_INSTANCE_ACTION_REMOVE, true, instance);
Assert.assertEquals(1, instanceList.size());
Assert.assertEquals(instance2, instanceList.get(0));
Assert.assertEquals(1, service.getClusterMap().size());
Assert.assertEquals(new Cluster(instance.getClusterName(), service),
service.getClusterMap().get(TEST_CLUSTER_NAME));
}
@Test
public void testUpdateIpAddressesNoInstance() throws Exception {
expectedException.expect(IllegalArgumentException.class);
expectedException
.expectMessage(String.format("ip list can not be empty, service: %s, ip list: []", TEST_SERVICE_NAME));
serviceManager.updateIpAddresses(service, UtilsAndCommons.UPDATE_INSTANCE_ACTION_ADD, true);
}
@Test
public void testSearchServices() throws NacosException {
serviceManager.createEmptyService(TEST_NAMESPACE, TEST_SERVICE_NAME, true);
List<Service> actual = serviceManager
.searchServices(TEST_NAMESPACE, Constants.ANY_PATTERN + TEST_SERVICE_NAME + Constants.ANY_PATTERN);
assertEquals(1, actual.size());
assertEquals(TEST_SERVICE_NAME, actual.get(0).getName());
}
@Test
public void testGetPagedService() throws NacosException {
serviceManager.createEmptyService(TEST_NAMESPACE, TEST_SERVICE_NAME, true);
Service service = serviceManager.getService(TEST_NAMESPACE, TEST_SERVICE_NAME);
service.addCluster(cluster);
((Set<Instance>) ReflectionTestUtils.getField(cluster, "ephemeralInstances")).add(instance);
List<Service> actualServices = new ArrayList<>(8);
int actualSize = serviceManager
.getPagedService(TEST_NAMESPACE, 0, 10, StringUtils.EMPTY, "1.1.1.1:1", actualServices, true);
assertEquals(1, actualSize);
assertEquals(TEST_SERVICE_NAME, actualServices.get(0).getName());
}
@Test
public void testSnowflakeInstanceId() throws Exception {
Map<String, String> metaData = new HashMap<>();
metaData.put(PreservedMetadataKeys.INSTANCE_ID_GENERATOR, Constants.SNOWFLAKE_INSTANCE_ID_GENERATOR);
instance.setMetadata(metaData);
instance2.setClusterName(TEST_CLUSTER_NAME);
instance2.setMetadata(metaData);
List<Instance> instanceList = serviceManager
.updateIpAddresses(service, UtilsAndCommons.UPDATE_INSTANCE_ACTION_ADD, true, instance, instance2);
Assert.assertNotNull(instanceList);
Assert.assertEquals(2, instanceList.size());
int instanceId1 = Integer.parseInt(instance.getInstanceId());
int instanceId2 = Integer.parseInt(instance2.getInstanceId());
Assert.assertNotEquals(instanceId1, instanceId2);
}
@Test
public void testUpdatedHealthStatus() {
String namespaceId = "namespaceId";
String serviceName = "testService";
String serverIp = "127.0.0.1";
String example = "{\"ips\":[\"127.0.0.1:8848_true\"]}";
Message message = new Message();
message.setData(example);
when(synchronizer.get(serverIp, UtilsAndCommons.assembleFullServiceName(namespaceId, serviceName)))
.thenReturn(message);
serviceManager.updatedHealthStatus(namespaceId, serviceName, serverIp);
}
@Test
public void testSerializeServiceChecksum() {
ServiceChecksum checksum = new ServiceChecksum();
checksum.addItem("test", "1234567890");
String actual = JacksonUtils.toJson(checksum);
assertTrue(actual.contains("\"namespaceId\":\"public\""));
assertTrue(actual.contains("\"serviceName2Checksum\":{\"test\":\"1234567890\"}"));
}
@Test(expected = NacosException.class)
public void testCheckServiceIsNull() throws NacosException {
serviceManager.createEmptyService(TEST_NAMESPACE, TEST_SERVICE_NAME, true);
String serviceName = "order-service";
Service service = serviceManager.getService(TEST_NAMESPACE, serviceName);
serviceManager.checkServiceIsNull(service, TEST_NAMESPACE, serviceName);
}
}

View File

@ -1,75 +0,0 @@
/*
* Copyright 1999-2021 Alibaba Group Holding Ltd.
*
* Licensed 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 com.alibaba.nacos.naming.core.v2.cleaner;
import com.alibaba.nacos.naming.core.DistroMapper;
import com.alibaba.nacos.naming.core.Service;
import com.alibaba.nacos.naming.core.ServiceManager;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.junit.MockitoJUnitRunner;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
/**
* {@link EmptyServiceAutoCleaner} unit test.
*
* @author chenglu
* @date 2021-07-21 12:31
*/
@RunWith(MockitoJUnitRunner.class)
public class EmptyServiceAutoCleanerTest {
@Mock
private ServiceManager serviceManager;
@Mock
private DistroMapper distroMapper;
private EmptyServiceAutoCleaner emptyServiceAutoCleaner;
@Before
public void setUp() {
emptyServiceAutoCleaner = new EmptyServiceAutoCleaner(serviceManager, distroMapper);
}
@Test
public void testRun() {
try {
Mockito.when(serviceManager.getAllNamespaces()).thenReturn(Collections.singleton("test"));
Map<String, Service> serviceMap = new HashMap<>(2);
Service service = new Service();
serviceMap.put("test", service);
Mockito.when(serviceManager.chooseServiceMap(Mockito.anyString())).thenReturn(serviceMap);
Mockito.when(distroMapper.responsible(Mockito.anyString())).thenReturn(true);
emptyServiceAutoCleaner.run();
} catch (Exception e) {
e.printStackTrace();
Assert.fail(e.getMessage());
}
}
}