Fix some compatible problem for 1.x client (#4397)

* Adapt list service v1 open API

* Adapt push all logic

* Fix NPE if register Instance without metadata for v1.x.

* Add some comment for Metadata event

* Fix can't auto register instance after auto deregister when different service with same ip port.
This commit is contained in:
KomachiSion 2020-12-03 18:30:53 +08:00
parent 37a6dd991d
commit f1ee1ba968
11 changed files with 91 additions and 33 deletions

View File

@ -42,7 +42,6 @@ import com.alibaba.nacos.naming.pojo.Subscriber;
import com.alibaba.nacos.naming.selector.LabelSelector;
import com.alibaba.nacos.naming.selector.NoneSelector;
import com.alibaba.nacos.naming.selector.Selector;
import com.alibaba.nacos.naming.utils.ServiceUtil;
import com.alibaba.nacos.naming.web.NamingResourceParser;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.ArrayNode;
@ -61,7 +60,6 @@ import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletRequest;
import java.net.URLDecoder;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
@ -213,28 +211,11 @@ public class ServiceController {
String namespaceId = WebUtils.optional(request, CommonParams.NAMESPACE_ID, Constants.DEFAULT_NAMESPACE_ID);
String groupName = WebUtils.optional(request, CommonParams.GROUP_NAME, Constants.DEFAULT_GROUP);
String selectorString = WebUtils.optional(request, "selector", StringUtils.EMPTY);
Map<String, Service> serviceMap = serviceManager.chooseServiceMap(namespaceId);
ObjectNode result = JacksonUtils.createEmptyJsonNode();
if (serviceMap == null || serviceMap.isEmpty()) {
result.replace("doms", JacksonUtils.transferToJsonNode(Collections.emptyList()));
result.put("count", 0);
return result;
}
serviceMap = ServiceUtil.selectServiceWithGroupName(serviceMap, groupName);
serviceMap = ServiceUtil.selectServiceBySelector(serviceMap, selectorString);
if (!Constants.ALL_PATTERN.equals(groupName)) {
serviceMap.entrySet()
.removeIf(entry -> !entry.getKey().startsWith(groupName + Constants.SERVICE_INFO_SPLITER));
}
List<String> serviceNameList = ServiceUtil.pageServiceName(pageNo, pageSize, serviceMap);
List<String> serviceNameList = serviceOperatorV2
.listService(namespaceId, groupName, selectorString, pageSize, pageNo);
result.replace("doms", JacksonUtils.transferToJsonNode(serviceNameList));
result.put("count", serviceNameList.size());
return result;
}

View File

@ -144,8 +144,9 @@ public class InstanceOperatorClientImpl implements InstanceOperator {
String groupName = NamingUtils.getGroupName(serviceName);
String serviceNameNoGrouped = NamingUtils.getServiceName(serviceName);
String clientId = ip + ":" + port;
Service service = Service.newService(namespaceId, groupName, serviceNameNoGrouped);
IpPortBasedClient client = (IpPortBasedClient) clientManager.getClient(clientId);
if (null == client) {
if (null == client || !client.getAllPublishedService().contains(service)) {
if (null == clientBeat) {
return NamingResponseCode.RESOURCE_NOT_FOUND;
}
@ -161,7 +162,6 @@ public class InstanceOperatorClientImpl implements InstanceOperator {
registerInstance(namespaceId, serviceName, instance);
client = (IpPortBasedClient) clientManager.getClient(clientId);
}
Service service = Service.newService(namespaceId, groupName, serviceNameNoGrouped);
if (!ServiceManager.getInstance().containSingleton(service)) {
throw new NacosException(NacosException.SERVER_ERROR,
"service not found: " + serviceName + "@" + namespaceId);

View File

@ -21,7 +21,6 @@ import com.alibaba.nacos.api.naming.NamingResponseCode;
import com.alibaba.nacos.api.naming.PreservedMetadataKeys;
import com.alibaba.nacos.api.naming.pojo.Instance;
import com.alibaba.nacos.api.naming.pojo.ServiceInfo;
import com.alibaba.nacos.api.naming.utils.NamingUtils;
import com.alibaba.nacos.common.utils.JacksonUtils;
import com.alibaba.nacos.naming.healthcheck.RsInfo;
import com.alibaba.nacos.naming.misc.Loggers;
@ -102,8 +101,7 @@ public class InstanceOperatorServiceImpl implements InstanceOperator {
}
@Override
public void updateInstance(String namespaceId, String serviceName, Instance instance)
throws NacosException {
public void updateInstance(String namespaceId, String serviceName, Instance instance) throws NacosException {
com.alibaba.nacos.naming.core.Instance coreInstance = (com.alibaba.nacos.naming.core.Instance) instance;
serviceManager.updateInstance(namespaceId, serviceName, coreInstance);
}

View File

@ -20,6 +20,8 @@ import com.alibaba.nacos.api.exception.NacosException;
import com.alibaba.nacos.naming.core.v2.metadata.ServiceMetadata;
import com.alibaba.nacos.naming.core.v2.pojo.Service;
import java.util.List;
/**
* Service operator.
*
@ -36,4 +38,18 @@ public interface ServiceOperator {
* @throws NacosException nacos exception during update
*/
void update(Service service, ServiceMetadata metadata) throws NacosException;
/**
* Page list service name.
*
* @param namespaceId namespace id of services
* @param groupName group name of services
* @param selector selector
* @param pageSize page size
* @param pageNo page number
* @return services name list
* @throws NacosException nacos exception during query
*/
List<String> listService(String namespaceId, String groupName, String selector, int pageSize, int pageNo)
throws NacosException;
}

View File

@ -16,11 +16,17 @@
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.core.v2.metadata.ServiceMetadata;
import com.alibaba.nacos.naming.core.v2.pojo.Service;
import com.alibaba.nacos.naming.utils.ServiceUtil;
import org.springframework.stereotype.Component;
import java.util.Collections;
import java.util.List;
import java.util.Map;
/**
* Implementation of service operator for v1.x.
*
@ -50,4 +56,20 @@ public class ServiceOperatorV1Impl implements ServiceOperator {
serviceV1.validate();
serviceManager.addOrReplaceService(serviceV1);
}
@Override
public List<String> listService(String namespaceId, String groupName, String selector, int pageSize, int pageNo)
throws NacosException {
Map<String, com.alibaba.nacos.naming.core.Service> serviceMap = serviceManager.chooseServiceMap(namespaceId);
if (serviceMap == null || serviceMap.isEmpty()) {
return Collections.emptyList();
}
serviceMap = ServiceUtil.selectServiceWithGroupName(serviceMap, groupName);
serviceMap = ServiceUtil.selectServiceBySelector(serviceMap, selector);
if (!Constants.ALL_PATTERN.equals(groupName)) {
serviceMap.entrySet()
.removeIf(entry -> !entry.getKey().startsWith(groupName + Constants.SERVICE_INFO_SPLITER));
}
return ServiceUtil.pageServiceName(pageNo, pageSize, serviceMap);
}
}

View File

@ -21,8 +21,15 @@ import com.alibaba.nacos.naming.core.v2.ServiceManager;
import com.alibaba.nacos.naming.core.v2.metadata.NamingMetadataOperateService;
import com.alibaba.nacos.naming.core.v2.metadata.ServiceMetadata;
import com.alibaba.nacos.naming.core.v2.pojo.Service;
import com.alibaba.nacos.naming.utils.ServiceUtil;
import org.springframework.stereotype.Component;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Objects;
/**
* Implementation of service operator for v2.x.
*
@ -45,4 +52,27 @@ public class ServiceOperatorV2Impl implements ServiceOperator {
}
metadataOperateService.updateServiceMetadata(service, metadata);
}
@Override
@SuppressWarnings("unchecked")
public List<String> listService(String namespaceId, String groupName, String selector, int pageSize, int pageNo)
throws NacosException {
Collection<Service> services = ServiceManager.getInstance().getSingletons(namespaceId);
if (services.isEmpty()) {
return Collections.EMPTY_LIST;
}
Collection<String> serviceNameSet = selectServiceWithGroupName(services, groupName);
// TODO select service by selector
return ServiceUtil.pageServiceName(pageNo, pageSize, serviceNameSet);
}
private Collection<String> selectServiceWithGroupName(Collection<Service> serviceSet, String groupName) {
Collection<String> result = new HashSet<>(serviceSet.size());
for (Service each : serviceSet) {
if (Objects.equals(groupName, each.getGroup())) {
result.add(each.getGroupedServiceName());
}
}
return result;
}
}

View File

@ -30,6 +30,15 @@ public class MetadataEvent extends SlowEvent {
private final Service service;
/**
* Mark this metadata whether is expired.
*
* <p>If value is {@code true}, means that the original object (service or instance) has been removed, so the
* metadata has been expired, need be delete.
*
* <p>If value is {code false}, means that the original object (service or instance) is registered, The metadata
* should stop to delete.
*/
private final boolean expired;
public MetadataEvent(Service service, boolean expired) {

View File

@ -77,7 +77,9 @@ public class EphemeralClientOperationServiceImpl implements ClientOperationServi
private InstancePublishInfo getPublishInfo(Instance instance) {
InstancePublishInfo result = new InstancePublishInfo(instance.getIp(), instance.getPort());
if (null != instance.getMetadata() && !instance.getMetadata().isEmpty()) {
result.getExtendDatum().putAll(instance.getMetadata());
}
String clusterName = StringUtils.isBlank(instance.getClusterName()) ? UtilsAndCommons.DEFAULT_CLUSTER_NAME
: instance.getClusterName();
result.setHealthy(instance.isHealthy());

View File

@ -44,7 +44,7 @@ public class PushExecuteTask extends AbstractExecuteTask {
public void run() {
try {
ServiceInfo serviceInfo = delayTaskEngine.getServiceStorage().getPushData(service);
serviceInfo = ServiceUtil.selectInstances(serviceInfo, true, true);
serviceInfo = ServiceUtil.selectInstances(serviceInfo, false, true);
for (String each : delayTaskEngine.getIndexesManager().getAllClientsSubscribeService(service)) {
Subscriber subscriber = delayTaskEngine.getClientManager().getClient(each).getSubscriber(service);
delayTaskEngine.getPushExecuteService().doPush(each, subscriber, handleClusterData(serviceInfo, subscriber));

View File

@ -46,6 +46,7 @@ public class ServiceListRequestHandler extends RequestHandler<ServiceListRequest
ServiceListResponse result = ServiceListResponse.buildSuccessResponse(0, new LinkedList<>());
if (!serviceSet.isEmpty()) {
Collection<String> serviceNameSet = selectServiceWithGroupName(serviceSet, request.getGroupName());
// TODO select service by selector
List<String> serviceNameList = ServiceUtil
.pageServiceName(request.getPageNo(), request.getPageSize(), serviceNameSet);
result.setCount(serviceNameList.size());

View File

@ -21,7 +21,6 @@ import com.alibaba.nacos.common.model.RestResult;
import com.alibaba.nacos.common.utils.ExceptionUtil;
import com.alibaba.nacos.common.utils.IoUtils;
import com.alibaba.nacos.core.code.ControllerMethodsCache;
import com.alibaba.nacos.core.utils.OverrideParameterRequestWrapper;
import com.alibaba.nacos.core.utils.ReuseHttpServletRequest;
import com.alibaba.nacos.core.utils.WebUtils;
import com.alibaba.nacos.naming.core.DistroMapper;