[ISSUE#6272] Refactor Instance builder to build and handler request from http. (#6298)

* Add InstanceBuilder and IdGenerator

* Add new builder for http request and client beat

* Use new builder to build api instance.

* Modified according review comment.
This commit is contained in:
杨翊 SionYang 2021-07-07 17:01:40 +08:00 committed by GitHub
parent 71f170a7a5
commit 5e545c8d37
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
22 changed files with 1086 additions and 290 deletions

View File

@ -0,0 +1,151 @@
/*
* 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.api.naming.pojo.builder;
import com.alibaba.nacos.api.naming.pojo.Instance;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
/**
* Builder for {@link Instance}.
*
* @author xiweng.yy
*/
public class InstanceBuilder {
private String instanceId;
private String ip;
private Integer port;
private Double weight;
private Boolean healthy;
private Boolean enabled;
private Boolean ephemeral;
private String clusterName;
private String serviceName;
private Map<String, String> metadata = new HashMap<>();
private InstanceBuilder() {
}
public InstanceBuilder setInstanceId(String instanceId) {
this.instanceId = instanceId;
return this;
}
public InstanceBuilder setIp(String ip) {
this.ip = ip;
return this;
}
public InstanceBuilder setPort(Integer port) {
this.port = port;
return this;
}
public InstanceBuilder setWeight(Double weight) {
this.weight = weight;
return this;
}
public InstanceBuilder setHealthy(Boolean healthy) {
this.healthy = healthy;
return this;
}
public InstanceBuilder setEnabled(Boolean enabled) {
this.enabled = enabled;
return this;
}
public InstanceBuilder setEphemeral(Boolean ephemeral) {
this.ephemeral = ephemeral;
return this;
}
public InstanceBuilder setClusterName(String clusterName) {
this.clusterName = clusterName;
return this;
}
public InstanceBuilder setServiceName(String serviceName) {
this.serviceName = serviceName;
return this;
}
public InstanceBuilder setMetadata(Map<String, String> metadata) {
this.metadata = metadata;
return this;
}
public InstanceBuilder addMetadata(String metaKey, String metaValue) {
this.metadata.put(metaKey, metaValue);
return this;
}
/**
* Build a new {@link Instance}.
*
* @return new instance
*/
public Instance build() {
Instance result = new Instance();
if (!Objects.isNull(instanceId)) {
result.setInstanceId(instanceId);
}
if (!Objects.isNull(ip)) {
result.setIp(ip);
}
if (!Objects.isNull(port)) {
result.setPort(port);
}
if (!Objects.isNull(weight)) {
result.setWeight(weight);
}
if (!Objects.isNull(healthy)) {
result.setHealthy(healthy);
}
if (!Objects.isNull(enabled)) {
result.setEnabled(enabled);
}
if (!Objects.isNull(ephemeral)) {
result.setEphemeral(ephemeral);
}
if (!Objects.isNull(clusterName)) {
result.setClusterName(clusterName);
}
if (!Objects.isNull(serviceName)) {
result.setServiceName(serviceName);
}
result.setMetadata(metadata);
return result;
}
public static InstanceBuilder newBuilder() {
return new InstanceBuilder();
}
}

View File

@ -0,0 +1,32 @@
/*
* 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.api.naming.spi.generator;
/**
* Generator SPI for Instance Id.
*
* @author xiweng.yy
*/
public interface IdGenerator {
/**
* Generate instance id.
*
* @return instance id
*/
String generateInstanceId();
}

View File

@ -0,0 +1,85 @@
/*
* 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.api.naming.pojo.builder;
import com.alibaba.nacos.api.naming.pojo.Instance;
import org.junit.Test;
import static org.hamcrest.CoreMatchers.is;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;
public class InstanceBuilderTest {
private static final String SERVICE_NAME = "testService";
private static final String CLUSTER_NAME = "testCluster";
private static final String INSTANCE_ID = "ID";
private static final String IP = "127.0.0.1";
private static final int PORT = 8848;
private static final double WEIGHT = 2.0;
private static final boolean HEALTHY = false;
private static final boolean ENABLED = false;
private static final boolean EPHEMERAL = false;
private static final String META_KEY = "key";
private static final String META_VALUE = "value";
@Test
public void testBuildFullInstance() {
InstanceBuilder builder = InstanceBuilder.newBuilder();
Instance actual = builder.setServiceName(SERVICE_NAME).setClusterName(CLUSTER_NAME).setInstanceId(INSTANCE_ID)
.setIp(IP).setPort(PORT).setWeight(WEIGHT).setHealthy(HEALTHY).setEnabled(ENABLED)
.setEphemeral(EPHEMERAL).addMetadata(META_KEY, META_VALUE).build();
assertThat(actual.getServiceName(), is(SERVICE_NAME));
assertThat(actual.getClusterName(), is(CLUSTER_NAME));
assertThat(actual.getInstanceId(), is(INSTANCE_ID));
assertThat(actual.getIp(), is(IP));
assertThat(actual.getPort(), is(PORT));
assertThat(actual.getWeight(), is(WEIGHT));
assertThat(actual.isHealthy(), is(HEALTHY));
assertThat(actual.isEnabled(), is(ENABLED));
assertThat(actual.isEphemeral(), is(EPHEMERAL));
assertThat(actual.getMetadata().size(), is(1));
assertThat(actual.getMetadata().get(META_KEY), is(META_VALUE));
}
@Test
public void testBuildEmptyInstance() {
InstanceBuilder builder = InstanceBuilder.newBuilder();
Instance actual = builder.build();
assertNull(actual.getServiceName());
assertNull(actual.getClusterName());
assertNull(actual.getInstanceId());
assertNull(actual.getIp());
assertThat(actual.getPort(), is(0));
assertThat(actual.getWeight(), is(1.0));
assertTrue(actual.isHealthy());
assertTrue(actual.isEnabled());
assertTrue(actual.isEphemeral());
assertTrue(actual.getMetadata().isEmpty());
}
}

View File

@ -121,4 +121,19 @@ public final class Constants {
* Whether enabled for instance according to instance self publish.
*/
public static final String PUBLISH_INSTANCE_ENABLE = "publishInstanceEnable";
/**
* Max value of instance weight.
*/
public static final double MAX_WEIGHT_VALUE = 10000.0D;
/**
* Min positive value of instance weight.
*/
public static final double MIN_POSITIVE_WEIGHT_VALUE = 0.01D;
/**
* Min value of instance weight.
*/
public static final double MIN_WEIGHT_VALUE = 0.00D;
}

View File

@ -19,26 +19,28 @@ package com.alibaba.nacos.naming.controllers;
import com.alibaba.nacos.api.common.Constants;
import com.alibaba.nacos.api.exception.NacosException;
import com.alibaba.nacos.api.naming.CommonParams;
import com.alibaba.nacos.api.naming.pojo.Instance;
import com.alibaba.nacos.api.naming.utils.NamingUtils;
import com.alibaba.nacos.auth.annotation.Secured;
import com.alibaba.nacos.auth.common.ActionTypes;
import com.alibaba.nacos.common.spi.NacosServiceLoader;
import com.alibaba.nacos.common.utils.JacksonUtils;
import com.alibaba.nacos.core.utils.WebUtils;
import com.alibaba.nacos.naming.core.Instance;
import com.alibaba.nacos.naming.core.InstanceOperator;
import com.alibaba.nacos.naming.core.InstanceOperatorClientImpl;
import com.alibaba.nacos.naming.core.InstanceOperatorServiceImpl;
import com.alibaba.nacos.naming.core.InstancePatchObject;
import com.alibaba.nacos.naming.core.v2.upgrade.UpgradeJudgement;
import com.alibaba.nacos.naming.healthcheck.RsInfo;
import com.alibaba.nacos.naming.healthcheck.heartbeat.ClientBeatExtensionHandler;
import com.alibaba.nacos.naming.misc.Loggers;
import com.alibaba.nacos.naming.misc.SwitchDomain;
import com.alibaba.nacos.naming.misc.SwitchEntry;
import com.alibaba.nacos.naming.misc.UtilsAndCommons;
import com.alibaba.nacos.naming.pojo.InstanceOperationInfo;
import com.alibaba.nacos.naming.pojo.Subscriber;
import com.alibaba.nacos.naming.pojo.instance.BeatInfoInstanceBuilder;
import com.alibaba.nacos.naming.pojo.instance.HttpRequestInstanceBuilder;
import com.alibaba.nacos.naming.pojo.instance.InstanceExtensionHandler;
import com.alibaba.nacos.naming.web.CanDistro;
import com.alibaba.nacos.naming.web.NamingResourceParser;
import com.fasterxml.jackson.core.type.TypeReference;
@ -87,7 +89,8 @@ public class InstanceController {
private UpgradeJudgement upgradeJudgement;
public InstanceController() {
NacosServiceLoader.load(ClientBeatExtensionHandler.class);
Collection<InstanceExtensionHandler> handlers = NacosServiceLoader.load(InstanceExtensionHandler.class);
Loggers.SRV_LOG.info("Load instance extension handler {}", handlers);
}
/**
@ -107,7 +110,8 @@ public class InstanceController {
final String serviceName = WebUtils.required(request, CommonParams.SERVICE_NAME);
NamingUtils.checkServiceNameFormat(serviceName);
final Instance instance = parseInstance(request);
final Instance instance = HttpRequestInstanceBuilder.newBuilder()
.setDefaultInstanceEphemeral(switchDomain.isDefaultInstanceEphemeral()).setRequest(request).build();
getInstanceOperator().registerInstance(namespaceId, serviceName, instance);
return "ok";
@ -124,7 +128,8 @@ public class InstanceController {
@DeleteMapping
@Secured(parser = NamingResourceParser.class, action = ActionTypes.WRITE)
public String deregister(HttpServletRequest request) throws Exception {
Instance instance = getIpAddress(request);
Instance instance = HttpRequestInstanceBuilder.newBuilder()
.setDefaultInstanceEphemeral(switchDomain.isDefaultInstanceEphemeral()).setRequest(request).build();
String namespaceId = WebUtils.optional(request, CommonParams.NAMESPACE_ID, Constants.DEFAULT_NAMESPACE_ID);
String serviceName = WebUtils.required(request, CommonParams.SERVICE_NAME);
NamingUtils.checkServiceNameFormat(serviceName);
@ -147,7 +152,9 @@ public class InstanceController {
String namespaceId = WebUtils.optional(request, CommonParams.NAMESPACE_ID, Constants.DEFAULT_NAMESPACE_ID);
String serviceName = WebUtils.required(request, CommonParams.SERVICE_NAME);
NamingUtils.checkServiceNameFormat(serviceName);
getInstanceOperator().updateInstance(namespaceId, serviceName, parseInstance(request));
Instance instance = HttpRequestInstanceBuilder.newBuilder()
.setDefaultInstanceEphemeral(switchDomain.isDefaultInstanceEphemeral()).setRequest(request).build();
getInstanceOperator().updateInstance(namespaceId, serviceName, instance);
return "ok";
}
@ -388,13 +395,10 @@ public class InstanceController {
NamingUtils.checkServiceNameFormat(serviceName);
Loggers.SRV_LOG.debug("[CLIENT-BEAT] full arguments: beat: {}, serviceName: {}, namespaceId: {}", clientBeat,
serviceName, namespaceId);
Collection<ClientBeatExtensionHandler> extensionHandlers = NacosServiceLoader
.newServiceInstances(ClientBeatExtensionHandler.class);
for (ClientBeatExtensionHandler each : extensionHandlers) {
each.configExtensionInfoFromRequest(request);
}
BeatInfoInstanceBuilder builder = BeatInfoInstanceBuilder.newBuilder();
builder.setRequest(request);
int resultCode = getInstanceOperator()
.handleBeat(namespaceId, serviceName, ip, port, clusterName, clientBeat, extensionHandlers);
.handleBeat(namespaceId, serviceName, ip, port, clusterName, clientBeat, builder);
result.put(CommonParams.CODE, resultCode);
result.put(SwitchEntry.CLIENT_BEAT_INTERVAL,
getInstanceOperator().getHeartBeatInterval(namespaceId, serviceName, ip, port, clusterName));
@ -436,68 +440,6 @@ public class InstanceController {
return result;
}
private Instance parseInstance(HttpServletRequest request) throws Exception {
String serviceName = WebUtils.required(request, CommonParams.SERVICE_NAME);
String app = WebUtils.optional(request, "app", "DEFAULT");
Instance instance = getIpAddress(request);
instance.setApp(app);
instance.setServiceName(serviceName);
// Generate simple instance id first. This value would be updated according to
// INSTANCE_ID_GENERATOR.
instance.setInstanceId(instance.generateInstanceId());
instance.setLastBeat(System.currentTimeMillis());
String metadata = WebUtils.optional(request, "metadata", StringUtils.EMPTY);
if (StringUtils.isNotEmpty(metadata)) {
instance.setMetadata(UtilsAndCommons.parseMetadata(metadata));
}
instance.validate();
return instance;
}
private Instance getIpAddress(HttpServletRequest request) {
String enabledString = WebUtils.optional(request, "enabled", StringUtils.EMPTY);
boolean enabled;
if (StringUtils.isBlank(enabledString)) {
enabled = BooleanUtils.toBoolean(WebUtils.optional(request, "enable", "true"));
} else {
enabled = BooleanUtils.toBoolean(enabledString);
}
String weight = WebUtils.optional(request, "weight", "1");
boolean healthy = BooleanUtils.toBoolean(WebUtils.optional(request, "healthy", "true"));
Instance instance = getBasicIpAddress(request);
instance.setWeight(Double.parseDouble(weight));
instance.setHealthy(healthy);
instance.setEnabled(enabled);
return instance;
}
private Instance getBasicIpAddress(HttpServletRequest request) {
final String ip = WebUtils.required(request, "ip");
final String port = WebUtils.required(request, "port");
String cluster = WebUtils.optional(request, CommonParams.CLUSTER_NAME, StringUtils.EMPTY);
if (StringUtils.isBlank(cluster)) {
cluster = WebUtils.optional(request, "cluster", UtilsAndCommons.DEFAULT_CLUSTER_NAME);
}
boolean ephemeral = BooleanUtils.toBoolean(
WebUtils.optional(request, "ephemeral", String.valueOf(switchDomain.isDefaultInstanceEphemeral())));
Instance instance = new Instance();
instance.setPort(Integer.parseInt(port));
instance.setIp(ip);
instance.setEphemeral(ephemeral);
instance.setClusterName(cluster);
return instance;
}
private InstanceOperator getInstanceOperator() {
return upgradeJudgement.isUseGrpcFeatures() ? instanceServiceV2 : instanceServiceV1;
}

View File

@ -19,6 +19,7 @@ package com.alibaba.nacos.naming.controllers;
import com.alibaba.nacos.api.common.Constants;
import com.alibaba.nacos.api.exception.NacosException;
import com.alibaba.nacos.api.naming.CommonParams;
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.api.selector.SelectorType;
@ -26,7 +27,6 @@ import com.alibaba.nacos.auth.annotation.Secured;
import com.alibaba.nacos.auth.common.ActionTypes;
import com.alibaba.nacos.common.utils.JacksonUtils;
import com.alibaba.nacos.core.utils.WebUtils;
import com.alibaba.nacos.naming.core.Instance;
import com.alibaba.nacos.naming.core.InstanceOperator;
import com.alibaba.nacos.naming.core.InstanceOperatorClientImpl;
import com.alibaba.nacos.naming.core.InstanceOperatorServiceImpl;
@ -42,6 +42,7 @@ import com.alibaba.nacos.naming.misc.SwitchDomain;
import com.alibaba.nacos.naming.misc.UtilsAndCommons;
import com.alibaba.nacos.naming.monitor.MetricsMonitor;
import com.alibaba.nacos.naming.pojo.Subscriber;
import com.alibaba.nacos.naming.pojo.instance.HttpRequestInstanceBuilder;
import com.alibaba.nacos.naming.selector.LabelSelector;
import com.alibaba.nacos.naming.selector.NoneSelector;
import com.alibaba.nacos.naming.selector.Selector;
@ -81,41 +82,36 @@ import static com.alibaba.nacos.naming.misc.UtilsAndCommons.NAMESPACE_SERVICE_CO
*
* <p>Helping to resolve some unexpected problems when upgrading.
*
* @author gengtuo.ygt
* on 2021/5/14
* @author gengtuo.ygt on 2021/5/14
* @deprecated will be removed at 2.1.x
*/
@RestController
@RequestMapping(UtilsAndCommons.NACOS_NAMING_CONTEXT + "/upgrade/ops")
public class UpgradeOpsController {
private final SwitchDomain switchDomain;
private final ServiceManager serviceManager;
private final ServiceOperatorV1Impl serviceOperatorV1;
private final ServiceOperatorV2Impl serviceOperatorV2;
private final InstanceOperatorServiceImpl instanceServiceV1;
private final InstanceOperatorClientImpl instanceServiceV2;
private final ServiceStorage serviceStorage;
private final DoubleWriteDelayTaskEngine doubleWriteDelayTaskEngine;
private final UpgradeJudgement upgradeJudgement;
public UpgradeOpsController(SwitchDomain switchDomain,
ServiceManager serviceManager,
ServiceOperatorV1Impl serviceOperatorV1,
ServiceOperatorV2Impl serviceOperatorV2,
InstanceOperatorServiceImpl instanceServiceV1,
InstanceOperatorClientImpl instanceServiceV2,
ServiceStorage serviceStorage,
DoubleWriteDelayTaskEngine doubleWriteDelayTaskEngine,
UpgradeJudgement upgradeJudgement) {
public UpgradeOpsController(SwitchDomain switchDomain, ServiceManager serviceManager,
ServiceOperatorV1Impl serviceOperatorV1, ServiceOperatorV2Impl serviceOperatorV2,
InstanceOperatorServiceImpl instanceServiceV1, InstanceOperatorClientImpl instanceServiceV2,
ServiceStorage serviceStorage, DoubleWriteDelayTaskEngine doubleWriteDelayTaskEngine,
UpgradeJudgement upgradeJudgement) {
this.switchDomain = switchDomain;
this.serviceManager = serviceManager;
this.serviceOperatorV1 = serviceOperatorV1;
@ -126,7 +122,7 @@ public class UpgradeOpsController {
this.doubleWriteDelayTaskEngine = doubleWriteDelayTaskEngine;
this.upgradeJudgement = upgradeJudgement;
}
/**
* Get metrics information for upgrading view.
*
@ -158,7 +154,7 @@ public class UpgradeOpsController {
return sb.toString();
}
}
private ObjectNode getMetrics() throws NacosException {
ObjectNode result = JacksonUtils.createEmptyJsonNode();
Set<String> serviceNamesV2 = new HashSet<>();
@ -168,11 +164,11 @@ public class UpgradeOpsController {
int ephemeralInstanceCountV2 = 0;
Set<String> allNamespaces = com.alibaba.nacos.naming.core.v2.ServiceManager.getInstance().getAllNamespaces();
for (String ns : allNamespaces) {
Set<com.alibaba.nacos.naming.core.v2.pojo.Service> services
= com.alibaba.nacos.naming.core.v2.ServiceManager.getInstance().getSingletons(ns);
Set<com.alibaba.nacos.naming.core.v2.pojo.Service> services = com.alibaba.nacos.naming.core.v2.ServiceManager
.getInstance().getSingletons(ns);
for (com.alibaba.nacos.naming.core.v2.pojo.Service service : services) {
String nameWithNs = service.getNamespace()
+ NAMESPACE_SERVICE_CONNECTOR + service.getGroupedServiceName();
String nameWithNs =
service.getNamespace() + NAMESPACE_SERVICE_CONNECTOR + service.getGroupedServiceName();
serviceNamesV2.add(nameWithNs);
if (service.isEphemeral()) {
ephemeralServiceNamesV2.add(nameWithNs);
@ -204,22 +200,21 @@ public class UpgradeOpsController {
result.put("persistentServiceCountV2", persistentServiceNamesV2.size());
result.put("ephemeralInstanceCountV2", ephemeralInstanceCountV2);
result.put("persistentInstanceCountV2", persistentInstanceCountV2);
Set<String> serviceNamesV1 = serviceManager.getAllServiceNames().entrySet().stream()
.flatMap(e -> e.getValue().stream().map(name -> {
if (!name.contains(SERVICE_INFO_SPLITER)) {
name = NamingUtils.getGroupedName(name, DEFAULT_GROUP);
}
return e.getKey() + NAMESPACE_SERVICE_CONNECTOR + name;
}))
.collect(Collectors.toSet());
result.put("service.V1.not.in.V2", String.join("\n",
(Collection<String>) CollectionUtils.subtract(serviceNamesV1, serviceNamesV2)));
result.put("service.V2.not.in.V1", String.join("\n",
(Collection<String>) CollectionUtils.subtract(serviceNamesV2, serviceNamesV1)));
})).collect(Collectors.toSet());
result.put("service.V1.not.in.V2",
String.join("\n", (Collection<String>) CollectionUtils.subtract(serviceNamesV1, serviceNamesV2)));
result.put("service.V2.not.in.V1",
String.join("\n", (Collection<String>) CollectionUtils.subtract(serviceNamesV2, serviceNamesV1)));
return result;
}
/**
* Create a new service. This API will create a persistence service.
*
@ -234,12 +229,11 @@ public class UpgradeOpsController {
@PostMapping("/service")
@Secured(parser = NamingResourceParser.class, action = ActionTypes.WRITE)
public String createService(@RequestParam(defaultValue = "v2", required = false) String ver,
HttpServletRequest request,
@RequestParam(defaultValue = Constants.DEFAULT_NAMESPACE_ID) String namespaceId,
@RequestParam String serviceName,
@RequestParam(required = false, defaultValue = "0.0F") float protectThreshold,
@RequestParam(defaultValue = StringUtils.EMPTY) String metadata,
@RequestParam(defaultValue = StringUtils.EMPTY) String selector) throws Exception {
HttpServletRequest request, @RequestParam(defaultValue = Constants.DEFAULT_NAMESPACE_ID) String namespaceId,
@RequestParam String serviceName,
@RequestParam(required = false, defaultValue = "0.0F") float protectThreshold,
@RequestParam(defaultValue = StringUtils.EMPTY) String metadata,
@RequestParam(defaultValue = StringUtils.EMPTY) String selector) throws Exception {
ServiceMetadata serviceMetadata = new ServiceMetadata();
serviceMetadata.setProtectThreshold(protectThreshold);
serviceMetadata.setSelector(parseSelector(selector));
@ -250,7 +244,7 @@ public class UpgradeOpsController {
getServiceOperator(ver).create(namespaceId, serviceName, serviceMetadata);
return "ok";
}
/**
* Remove service.
*
@ -262,16 +256,16 @@ public class UpgradeOpsController {
@DeleteMapping("/service")
@Secured(parser = NamingResourceParser.class, action = ActionTypes.WRITE)
public String removeService(@RequestParam(defaultValue = "v2", required = false) String ver,
@RequestParam(defaultValue = Constants.DEFAULT_NAMESPACE_ID) String namespaceId,
@RequestParam String serviceName) throws Exception {
@RequestParam(defaultValue = Constants.DEFAULT_NAMESPACE_ID) String namespaceId,
@RequestParam String serviceName) throws Exception {
getServiceOperator(ver).delete(namespaceId, serviceName);
return "ok";
}
private ServiceOperator getServiceOperator(String ver) {
return "v2".equals(ver) ? serviceOperatorV2 : serviceOperatorV1;
}
/**
* Get detail of service.
*
@ -283,11 +277,11 @@ public class UpgradeOpsController {
@GetMapping("/service")
@Secured(parser = NamingResourceParser.class, action = ActionTypes.READ)
public ObjectNode detailService(@RequestParam(defaultValue = "v2", required = false) String ver,
@RequestParam(defaultValue = Constants.DEFAULT_NAMESPACE_ID) String namespaceId,
@RequestParam String serviceName) throws NacosException {
@RequestParam(defaultValue = Constants.DEFAULT_NAMESPACE_ID) String namespaceId,
@RequestParam String serviceName) throws NacosException {
return getServiceOperator(ver).queryService(namespaceId, serviceName);
}
/**
* List all service names.
*
@ -298,7 +292,7 @@ public class UpgradeOpsController {
@GetMapping("/service/list")
@Secured(parser = NamingResourceParser.class, action = ActionTypes.READ)
public ObjectNode listService(@RequestParam(defaultValue = "v2", required = false) String ver,
HttpServletRequest request) throws Exception {
HttpServletRequest request) throws Exception {
final int pageNo = NumberUtils.toInt(WebUtils.required(request, "pageNo"));
final int pageSize = NumberUtils.toInt(WebUtils.required(request, "pageSize"));
String namespaceId = WebUtils.optional(request, CommonParams.NAMESPACE_ID, Constants.DEFAULT_NAMESPACE_ID);
@ -311,7 +305,7 @@ public class UpgradeOpsController {
result.put("count", serviceNameList.size());
return result;
}
/**
* Update service.
*
@ -322,7 +316,7 @@ public class UpgradeOpsController {
@PutMapping("/service")
@Secured(parser = NamingResourceParser.class, action = ActionTypes.WRITE)
public String updateService(@RequestParam(defaultValue = "v2", required = false) String ver,
HttpServletRequest request) throws Exception {
HttpServletRequest request) throws Exception {
String namespaceId = WebUtils.optional(request, CommonParams.NAMESPACE_ID, Constants.DEFAULT_NAMESPACE_ID);
String serviceName = WebUtils.required(request, CommonParams.SERVICE_NAME);
ServiceMetadata serviceMetadata = new ServiceMetadata();
@ -336,7 +330,7 @@ public class UpgradeOpsController {
getServiceOperator(ver).update(service, serviceMetadata);
return "ok";
}
/**
* Search service names.
*
@ -348,9 +342,9 @@ public class UpgradeOpsController {
@RequestMapping("/service/names")
@Secured(parser = NamingResourceParser.class, action = ActionTypes.READ)
public ObjectNode searchService(@RequestParam(defaultValue = "v2", required = false) String ver,
@RequestParam(defaultValue = StringUtils.EMPTY) String namespaceId,
@RequestParam(defaultValue = StringUtils.EMPTY) String expr,
@RequestParam(required = false) boolean responsibleOnly) throws NacosException {
@RequestParam(defaultValue = StringUtils.EMPTY) String namespaceId,
@RequestParam(defaultValue = StringUtils.EMPTY) String expr,
@RequestParam(required = false) boolean responsibleOnly) throws NacosException {
Map<String, Collection<String>> serviceNameMap = new HashMap<>(16);
int totalCount = 0;
ServiceOperator serviceOperator = getServiceOperator(ver);
@ -370,13 +364,13 @@ public class UpgradeOpsController {
result.put("count", totalCount);
return result;
}
private Selector parseSelector(String selectorJsonString) throws Exception {
if (StringUtils.isBlank(selectorJsonString)) {
return new NoneSelector();
}
JsonNode selectorJson = JacksonUtils.toObj(URLDecoder.decode(selectorJsonString, "UTF-8"));
switch (SelectorType.valueOf(selectorJson.get("type").asText())) {
case none:
@ -392,8 +386,8 @@ public class UpgradeOpsController {
throw new NacosException(NacosException.INVALID_PARAM, "not match any type of selector!");
}
}
/**
* Register new instance.
*
@ -405,19 +399,20 @@ public class UpgradeOpsController {
@PostMapping("/instance")
@Secured(parser = NamingResourceParser.class, action = ActionTypes.WRITE)
public String registerInstance(@RequestParam(defaultValue = "v2", required = false) String ver,
HttpServletRequest request) throws Exception {
HttpServletRequest request) throws Exception {
final String namespaceId = WebUtils
.optional(request, CommonParams.NAMESPACE_ID, Constants.DEFAULT_NAMESPACE_ID);
final String serviceName = WebUtils.required(request, CommonParams.SERVICE_NAME);
NamingUtils.checkServiceNameFormat(serviceName);
final Instance instance = parseInstance(request);
final Instance instance = HttpRequestInstanceBuilder.newBuilder()
.setDefaultInstanceEphemeral(switchDomain.isDefaultInstanceEphemeral()).setRequest(request).build();
getInstanceOperator(ver).registerInstance(namespaceId, serviceName, instance);
return "ok";
}
/**
* Deregister instances.
*
@ -429,16 +424,17 @@ public class UpgradeOpsController {
@DeleteMapping("/instance")
@Secured(parser = NamingResourceParser.class, action = ActionTypes.WRITE)
public String deregisterInstance(@RequestParam(defaultValue = "v2", required = false) String ver,
HttpServletRequest request) throws Exception {
Instance instance = getIpAddress(request);
HttpServletRequest request) throws Exception {
Instance instance = HttpRequestInstanceBuilder.newBuilder()
.setDefaultInstanceEphemeral(switchDomain.isDefaultInstanceEphemeral()).setRequest(request).build();
String namespaceId = WebUtils.optional(request, CommonParams.NAMESPACE_ID, Constants.DEFAULT_NAMESPACE_ID);
String serviceName = WebUtils.required(request, CommonParams.SERVICE_NAME);
NamingUtils.checkServiceNameFormat(serviceName);
getInstanceOperator(ver).removeInstance(namespaceId, serviceName, instance);
return "ok";
}
/**
* Update instance.
*
@ -450,15 +446,17 @@ public class UpgradeOpsController {
@PutMapping("/instance")
@Secured(parser = NamingResourceParser.class, action = ActionTypes.WRITE)
public String updateInstance(@RequestParam(defaultValue = "v2", required = false) String ver,
HttpServletRequest request) throws Exception {
HttpServletRequest request) throws Exception {
String namespaceId = WebUtils.optional(request, CommonParams.NAMESPACE_ID, Constants.DEFAULT_NAMESPACE_ID);
String serviceName = WebUtils.required(request, CommonParams.SERVICE_NAME);
NamingUtils.checkServiceNameFormat(serviceName);
getInstanceOperator(ver).updateInstance(namespaceId, serviceName, parseInstance(request));
Instance instance = HttpRequestInstanceBuilder.newBuilder()
.setDefaultInstanceEphemeral(switchDomain.isDefaultInstanceEphemeral()).setRequest(request).build();
getInstanceOperator(ver).updateInstance(namespaceId, serviceName, instance);
return "ok";
}
/**
* Get all instance of input service.
*
@ -469,29 +467,29 @@ public class UpgradeOpsController {
@GetMapping("/instance/list")
@Secured(parser = NamingResourceParser.class, action = ActionTypes.READ)
public Object listInstance(@RequestParam(defaultValue = "v2", required = false) String ver,
HttpServletRequest request) throws Exception {
HttpServletRequest request) throws Exception {
String namespaceId = WebUtils.optional(request, CommonParams.NAMESPACE_ID, Constants.DEFAULT_NAMESPACE_ID);
String serviceName = WebUtils.required(request, CommonParams.SERVICE_NAME);
NamingUtils.checkServiceNameFormat(serviceName);
String agent = WebUtils.getUserAgent(request);
String clusters = WebUtils.optional(request, "clusters", StringUtils.EMPTY);
String clientIP = WebUtils.optional(request, "clientIP", StringUtils.EMPTY);
int udpPort = Integer.parseInt(WebUtils.optional(request, "udpPort", "0"));
boolean healthyOnly = Boolean.parseBoolean(WebUtils.optional(request, "healthyOnly", "false"));
boolean isCheck = Boolean.parseBoolean(WebUtils.optional(request, "isCheck", "false"));
String app = WebUtils.optional(request, "app", StringUtils.EMPTY);
String env = WebUtils.optional(request, "env", StringUtils.EMPTY);
String tenant = WebUtils.optional(request, "tid", StringUtils.EMPTY);
Subscriber subscriber = new Subscriber(clientIP + ":" + udpPort, agent, app, clientIP, namespaceId, serviceName,
udpPort, clusters);
return getInstanceOperator(ver).listInstance(namespaceId, serviceName, subscriber, clusters, healthyOnly);
}
/**
* Get detail information of specified instance.
*
@ -502,15 +500,15 @@ public class UpgradeOpsController {
@GetMapping("/instance")
@Secured(parser = NamingResourceParser.class, action = ActionTypes.READ)
public ObjectNode detailInstance(@RequestParam(defaultValue = "v2", required = false) String ver,
HttpServletRequest request) throws Exception {
HttpServletRequest request) throws Exception {
String namespaceId = WebUtils.optional(request, CommonParams.NAMESPACE_ID, Constants.DEFAULT_NAMESPACE_ID);
String serviceName = WebUtils.required(request, CommonParams.SERVICE_NAME);
NamingUtils.checkServiceNameFormat(serviceName);
String cluster = WebUtils.optional(request, CommonParams.CLUSTER_NAME, UtilsAndCommons.DEFAULT_CLUSTER_NAME);
String ip = WebUtils.required(request, "ip");
int port = Integer.parseInt(WebUtils.required(request, "port"));
com.alibaba.nacos.api.naming.pojo.Instance instance = getInstanceOperator(ver)
.getInstance(namespaceId, serviceName, cluster, ip, port);
ObjectNode result = JacksonUtils.createEmptyJsonNode();
@ -524,71 +522,9 @@ public class UpgradeOpsController {
result.set("metadata", JacksonUtils.transferToJsonNode(instance.getMetadata()));
return result;
}
private Instance parseInstance(HttpServletRequest request) throws Exception {
String serviceName = WebUtils.required(request, CommonParams.SERVICE_NAME);
String app = WebUtils.optional(request, "app", "DEFAULT");
Instance instance = getIpAddress(request);
instance.setApp(app);
instance.setServiceName(serviceName);
// Generate simple instance id first. This value would be updated according to
// INSTANCE_ID_GENERATOR.
instance.setInstanceId(instance.generateInstanceId());
instance.setLastBeat(System.currentTimeMillis());
String metadata = WebUtils.optional(request, "metadata", StringUtils.EMPTY);
if (StringUtils.isNotEmpty(metadata)) {
instance.setMetadata(UtilsAndCommons.parseMetadata(metadata));
}
instance.validate();
return instance;
}
private Instance getIpAddress(HttpServletRequest request) {
String enabledString = WebUtils.optional(request, "enabled", StringUtils.EMPTY);
boolean enabled;
if (StringUtils.isBlank(enabledString)) {
enabled = BooleanUtils.toBoolean(WebUtils.optional(request, "enable", "true"));
} else {
enabled = BooleanUtils.toBoolean(enabledString);
}
String weight = WebUtils.optional(request, "weight", "1");
boolean healthy = BooleanUtils.toBoolean(WebUtils.optional(request, "healthy", "true"));
Instance instance = getBasicIpAddress(request);
instance.setWeight(Double.parseDouble(weight));
instance.setHealthy(healthy);
instance.setEnabled(enabled);
return instance;
}
private Instance getBasicIpAddress(HttpServletRequest request) {
final String ip = WebUtils.required(request, "ip");
final String port = WebUtils.required(request, "port");
String cluster = WebUtils.optional(request, CommonParams.CLUSTER_NAME, StringUtils.EMPTY);
if (StringUtils.isBlank(cluster)) {
cluster = WebUtils.optional(request, "cluster", UtilsAndCommons.DEFAULT_CLUSTER_NAME);
}
boolean ephemeral = BooleanUtils.toBoolean(
WebUtils.optional(request, "ephemeral", String.valueOf(switchDomain.isDefaultInstanceEphemeral())));
Instance instance = new Instance();
instance.setPort(Integer.parseInt(port));
instance.setIp(ip);
instance.setEphemeral(ephemeral);
instance.setClusterName(cluster);
return instance;
}
private InstanceOperator getInstanceOperator(String ver) {
return "v2".equals(ver) ? instanceServiceV2 : instanceServiceV1;
}
}

View File

@ -41,12 +41,6 @@ import java.util.regex.Pattern;
@JsonInclude(Include.NON_NULL)
public class Instance extends com.alibaba.nacos.api.naming.pojo.Instance implements Comparable {
private static final double MAX_WEIGHT_VALUE = 10000.0D;
private static final double MIN_POSITIVE_WEIGHT_VALUE = 0.01D;
private static final double MIN_WEIGHT_VALUE = 0.00D;
private static final long serialVersionUID = -6527721638428975306L;
private volatile long lastBeat = System.currentTimeMillis();
@ -124,7 +118,8 @@ public class Instance extends com.alibaba.nacos.api.naming.pojo.Instance impleme
}
int port = 0;
if (providerAddr.length == InternetAddressUtil.SPLIT_IP_PORT_RESULT_LENGTH && NumberUtils.isNumber(providerAddr[1])) {
if (providerAddr.length == InternetAddressUtil.SPLIT_IP_PORT_RESULT_LENGTH && NumberUtils
.isNumber(providerAddr[1])) {
port = Integer.parseInt(providerAddr[1]);
}
@ -212,13 +207,14 @@ public class Instance extends com.alibaba.nacos.api.naming.pojo.Instance impleme
throw new IllegalArgumentException("malformed ip config: " + json);
}
if (ip.getWeight() > MAX_WEIGHT_VALUE) {
ip.setWeight(MAX_WEIGHT_VALUE);
if (ip.getWeight() > com.alibaba.nacos.naming.constants.Constants.MAX_WEIGHT_VALUE) {
ip.setWeight(com.alibaba.nacos.naming.constants.Constants.MAX_WEIGHT_VALUE);
}
if (ip.getWeight() < MIN_POSITIVE_WEIGHT_VALUE && ip.getWeight() > MIN_WEIGHT_VALUE) {
ip.setWeight(MIN_POSITIVE_WEIGHT_VALUE);
} else if (ip.getWeight() < MIN_WEIGHT_VALUE) {
if (ip.getWeight() < com.alibaba.nacos.naming.constants.Constants.MIN_POSITIVE_WEIGHT_VALUE
&& ip.getWeight() > com.alibaba.nacos.naming.constants.Constants.MIN_WEIGHT_VALUE) {
ip.setWeight(com.alibaba.nacos.naming.constants.Constants.MIN_POSITIVE_WEIGHT_VALUE);
} else if (ip.getWeight() < com.alibaba.nacos.naming.constants.Constants.MIN_WEIGHT_VALUE) {
ip.setWeight(0.0D);
}
@ -363,9 +359,11 @@ public class Instance extends com.alibaba.nacos.api.naming.pojo.Instance impleme
}
}
if (getWeight() > MAX_WEIGHT_VALUE || getWeight() < MIN_WEIGHT_VALUE) {
throw new NacosException(NacosException.INVALID_PARAM,
"instance format invalid: The weights range from " + MIN_WEIGHT_VALUE + " to " + MAX_WEIGHT_VALUE);
if (getWeight() > com.alibaba.nacos.naming.constants.Constants.MAX_WEIGHT_VALUE
|| getWeight() < com.alibaba.nacos.naming.constants.Constants.MIN_WEIGHT_VALUE) {
throw new NacosException(NacosException.INVALID_PARAM, "instance format invalid: The weights range from "
+ com.alibaba.nacos.naming.constants.Constants.MIN_WEIGHT_VALUE + " to "
+ com.alibaba.nacos.naming.constants.Constants.MAX_WEIGHT_VALUE);
}
}

View File

@ -20,11 +20,10 @@ import com.alibaba.nacos.api.exception.NacosException;
import com.alibaba.nacos.api.naming.pojo.Instance;
import com.alibaba.nacos.api.naming.pojo.ServiceInfo;
import com.alibaba.nacos.naming.healthcheck.RsInfo;
import com.alibaba.nacos.naming.healthcheck.heartbeat.ClientBeatExtensionHandler;
import com.alibaba.nacos.naming.pojo.InstanceOperationInfo;
import com.alibaba.nacos.naming.pojo.Subscriber;
import com.alibaba.nacos.naming.pojo.instance.BeatInfoInstanceBuilder;
import java.util.Collection;
import java.util.List;
import java.util.Map;
@ -112,18 +111,19 @@ public interface InstanceOperator {
/**
* Handle beat request.
*
* @param namespaceId namespace
* @param serviceName grouped service name group@@service
* @param ip ip of instance
* @param port port of instance
* @param cluster cluster of instance
* @param clientBeat client beat info
* @param extensionHandlers client beat extension handlers
* @param namespaceId namespace
* @param serviceName grouped service name group@@service
* @param ip ip of instance
* @param port port of instance
* @param cluster cluster of instance
* @param clientBeat client beat info
* @param builder client beat instance builder, will be used when current instance is not exist and clientBeat
* exist
* @return result code
* @throws NacosException nacos exception when service non-exist and client beat info is null
*/
int handleBeat(String namespaceId, String serviceName, String ip, int port, String cluster, RsInfo clientBeat,
Collection<ClientBeatExtensionHandler> extensionHandlers) throws NacosException;
BeatInfoInstanceBuilder builder) throws NacosException;
/**
* Get heart beat interval for specified instance.

View File

@ -41,17 +41,16 @@ import com.alibaba.nacos.naming.core.v2.service.ClientOperationService;
import com.alibaba.nacos.naming.core.v2.service.ClientOperationServiceProxy;
import com.alibaba.nacos.naming.healthcheck.HealthCheckReactor;
import com.alibaba.nacos.naming.healthcheck.RsInfo;
import com.alibaba.nacos.naming.healthcheck.heartbeat.ClientBeatExtensionHandler;
import com.alibaba.nacos.naming.healthcheck.heartbeat.ClientBeatProcessorV2;
import com.alibaba.nacos.naming.misc.Loggers;
import com.alibaba.nacos.naming.misc.SwitchDomain;
import com.alibaba.nacos.naming.misc.UtilsAndCommons;
import com.alibaba.nacos.naming.pojo.InstanceOperationInfo;
import com.alibaba.nacos.naming.pojo.Subscriber;
import com.alibaba.nacos.naming.pojo.instance.BeatInfoInstanceBuilder;
import com.alibaba.nacos.naming.push.UdpPushService;
import com.alibaba.nacos.naming.utils.ServiceUtil;
import java.util.Collection;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
@ -213,7 +212,7 @@ public class InstanceOperatorClientImpl implements InstanceOperator {
@Override
public int handleBeat(String namespaceId, String serviceName, String ip, int port, String cluster,
RsInfo clientBeat, Collection<ClientBeatExtensionHandler> extensionHandlers) throws NacosException {
RsInfo clientBeat, BeatInfoInstanceBuilder builder) throws NacosException {
Service service = getService(namespaceId, serviceName, true);
String clientId = IpPortBasedClient.getClientId(ip + InternetAddressUtil.IP_PORT_SPLITER + port, true);
IpPortBasedClient client = (IpPortBasedClient) clientManager.getClient(clientId);
@ -221,18 +220,7 @@ public class InstanceOperatorClientImpl implements InstanceOperator {
if (null == clientBeat) {
return NamingResponseCode.RESOURCE_NOT_FOUND;
}
Instance instance = new Instance();
instance.setPort(clientBeat.getPort());
instance.setIp(clientBeat.getIp());
instance.setWeight(clientBeat.getWeight());
instance.setMetadata(clientBeat.getMetadata());
instance.setClusterName(clientBeat.getCluster());
instance.setServiceName(serviceName);
instance.setInstanceId(instance.getInstanceId());
instance.setEphemeral(clientBeat.isEphemeral());
for (ClientBeatExtensionHandler each : extensionHandlers) {
each.handleExtensionInfo(instance);
}
Instance instance = builder.setBeatInfo(clientBeat).setServiceName(serviceName).build();
registerInstance(namespaceId, serviceName, instance);
client = (IpPortBasedClient) clientManager.getClient(clientId);
}

View File

@ -22,13 +22,14 @@ 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.common.utils.JacksonUtils;
import com.alibaba.nacos.naming.core.v2.upgrade.doublewrite.execute.InstanceUpgradeHelper;
import com.alibaba.nacos.naming.healthcheck.RsInfo;
import com.alibaba.nacos.naming.healthcheck.heartbeat.ClientBeatExtensionHandler;
import com.alibaba.nacos.naming.misc.Loggers;
import com.alibaba.nacos.naming.misc.SwitchDomain;
import com.alibaba.nacos.naming.pojo.InstanceOperationContext;
import com.alibaba.nacos.naming.pojo.InstanceOperationInfo;
import com.alibaba.nacos.naming.pojo.Subscriber;
import com.alibaba.nacos.naming.pojo.instance.BeatInfoInstanceBuilder;
import com.alibaba.nacos.naming.push.UdpPushService;
import com.alibaba.nacos.naming.push.v1.ClientInfo;
import com.alibaba.nacos.naming.push.v1.DataSource;
@ -72,6 +73,8 @@ public class InstanceOperatorServiceImpl implements InstanceOperator {
private final NamingSubscriberServiceV1Impl subscriberServiceV1;
private final InstanceUpgradeHelper instanceUpgradeHelper;
private DataSource pushDataSource = new DataSource() {
@Override
@ -94,22 +97,24 @@ public class InstanceOperatorServiceImpl implements InstanceOperator {
};
public InstanceOperatorServiceImpl(ServiceManager serviceManager, SwitchDomain switchDomain,
UdpPushService pushService, NamingSubscriberServiceV1Impl subscriberServiceV1) {
UdpPushService pushService, NamingSubscriberServiceV1Impl subscriberServiceV1,
InstanceUpgradeHelper instanceUpgradeHelper) {
this.serviceManager = serviceManager;
this.switchDomain = switchDomain;
this.pushService = pushService;
this.subscriberServiceV1 = subscriberServiceV1;
this.instanceUpgradeHelper = instanceUpgradeHelper;
}
@Override
public void registerInstance(String namespaceId, String serviceName, Instance instance) throws NacosException {
com.alibaba.nacos.naming.core.Instance coreInstance = (com.alibaba.nacos.naming.core.Instance) instance;
com.alibaba.nacos.naming.core.Instance coreInstance = parseInstance(instance);
serviceManager.registerInstance(namespaceId, serviceName, coreInstance);
}
@Override
public void removeInstance(String namespaceId, String serviceName, Instance instance) throws NacosException {
com.alibaba.nacos.naming.core.Instance coreInstance = (com.alibaba.nacos.naming.core.Instance) instance;
com.alibaba.nacos.naming.core.Instance coreInstance = parseInstance(instance);
Service service = serviceManager.getService(namespaceId, serviceName);
if (service == null) {
Loggers.SRV_LOG.warn("remove instance from non-exist service: {}", serviceName);
@ -120,7 +125,7 @@ public class InstanceOperatorServiceImpl implements InstanceOperator {
@Override
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;
com.alibaba.nacos.naming.core.Instance coreInstance = parseInstance(instance);
serviceManager.updateInstance(namespaceId, serviceName, coreInstance);
}
@ -145,9 +150,6 @@ public class InstanceOperatorServiceImpl implements InstanceOperator {
if (null != patchObject.getHealthy()) {
instance.setHealthy(patchObject.getHealthy());
}
if (null != patchObject.getApp()) {
instance.setApp(patchObject.getApp());
}
instance.setLastBeat(System.currentTimeMillis());
instance.validate();
serviceManager.updateInstance(namespaceId, serviceName, instance);
@ -275,7 +277,7 @@ public class InstanceOperatorServiceImpl implements InstanceOperator {
@Override
public int handleBeat(String namespaceId, String serviceName, String ip, int port, String cluster,
RsInfo clientBeat, Collection<ClientBeatExtensionHandler> extensionHandlers) throws NacosException {
RsInfo clientBeat, BeatInfoInstanceBuilder builder) throws NacosException {
com.alibaba.nacos.naming.core.Instance instance = serviceManager
.getInstance(namespaceId, serviceName, cluster, ip, port);
@ -286,19 +288,7 @@ public class InstanceOperatorServiceImpl implements InstanceOperator {
Loggers.SRV_LOG.warn("[CLIENT-BEAT] The instance has been removed for health mechanism, "
+ "perform data compensation operations, beat: {}, serviceName: {}", clientBeat, serviceName);
instance = new com.alibaba.nacos.naming.core.Instance();
instance.setPort(clientBeat.getPort());
instance.setIp(clientBeat.getIp());
instance.setWeight(clientBeat.getWeight());
instance.setMetadata(clientBeat.getMetadata());
instance.setClusterName(cluster);
instance.setServiceName(serviceName);
instance.setInstanceId(instance.getInstanceId());
instance.setEphemeral(clientBeat.isEphemeral());
for (ClientBeatExtensionHandler each : extensionHandlers) {
each.handleExtensionInfo(instance);
}
instance = parseInstance(builder.setBeatInfo(clientBeat).setServiceName(serviceName).build());
serviceManager.registerInstance(namespaceId, serviceName, instance);
}
@ -371,4 +361,11 @@ public class InstanceOperatorServiceImpl implements InstanceOperator {
};
return serviceManager.batchOperate(namespace, instanceOperationInfo, operateFunction);
}
private com.alibaba.nacos.naming.core.Instance parseInstance(Instance apiInstance) throws NacosException {
com.alibaba.nacos.naming.core.Instance result = instanceUpgradeHelper.toV1(apiInstance);
result.setApp(apiInstance.getMetadata().getOrDefault("app", "DEFAULT"));
result.validate();
return result;
}
}

View File

@ -36,7 +36,6 @@ public class DefaultSelfUpgradeChecker implements SelfUpgradeChecker {
@Override
public boolean isReadyToUpgrade(ServiceManager serviceManager, DoubleWriteDelayTaskEngine taskEngine) {
System.out.println("test");
return checkServiceAndInstanceNumber(serviceManager) && checkDoubleWriteStatus(taskEngine);
}

View File

@ -0,0 +1,49 @@
/*
* 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.pojo.instance;
import com.alibaba.nacos.api.naming.pojo.Instance;
import com.alibaba.nacos.common.utils.StringUtils;
import com.alibaba.nacos.core.utils.WebUtils;
import javax.servlet.http.HttpServletRequest;
/**
* Instance extension handler for app field.
*
* @author xiweng.yy
*/
public class AppExtensionHandler implements InstanceExtensionHandler {
private static final String APP_FIELD = "app";
private static final String DEFAULT_APP = "DEFAULT";
private String app;
@Override
public void configExtensionInfoFromRequest(HttpServletRequest request) {
app = WebUtils.optional(request, APP_FIELD, DEFAULT_APP);
}
@Override
public void handleExtensionInfo(Instance needHandleInstance) {
if (StringUtils.isNotEmpty(app)) {
needHandleInstance.getMetadata().putIfAbsent(APP_FIELD, app);
}
}
}

View File

@ -0,0 +1,95 @@
/*
* 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.pojo.instance;
import com.alibaba.nacos.api.naming.pojo.Instance;
import com.alibaba.nacos.api.naming.pojo.builder.InstanceBuilder;
import com.alibaba.nacos.common.spi.NacosServiceLoader;
import com.alibaba.nacos.naming.healthcheck.RsInfo;
import javax.servlet.http.HttpServletRequest;
import java.util.Collection;
/**
* Client beatInfo instance builder.
*
* @author xiweng.yy
*/
public class BeatInfoInstanceBuilder {
private final InstanceBuilder actualBuilder;
private final Collection<InstanceExtensionHandler> handlers;
private BeatInfoInstanceBuilder() {
this.actualBuilder = InstanceBuilder.newBuilder();
this.handlers = NacosServiceLoader.newServiceInstances(InstanceExtensionHandler.class);
}
public static BeatInfoInstanceBuilder newBuilder() {
return new BeatInfoInstanceBuilder();
}
/**
* Build a new {@link Instance} and chain handled by {@link InstanceExtensionHandler}.
*
* @return new instance
*/
public Instance build() {
Instance result = actualBuilder.build();
for (InstanceExtensionHandler each : handlers) {
each.handleExtensionInfo(result);
}
setInstanceId(result);
return result;
}
public BeatInfoInstanceBuilder setRequest(HttpServletRequest request) {
for (InstanceExtensionHandler each : handlers) {
each.configExtensionInfoFromRequest(request);
}
return this;
}
public BeatInfoInstanceBuilder setServiceName(String serviceName) {
actualBuilder.setServiceName(serviceName);
return this;
}
public BeatInfoInstanceBuilder setBeatInfo(RsInfo beatInfo) {
setAttributesToBuilder(beatInfo);
return this;
}
private void setAttributesToBuilder(RsInfo beatInfo) {
actualBuilder.setPort(beatInfo.getPort());
actualBuilder.setIp(beatInfo.getIp());
actualBuilder.setWeight(beatInfo.getWeight());
actualBuilder.setMetadata(beatInfo.getMetadata());
actualBuilder.setClusterName(beatInfo.getCluster());
actualBuilder.setEphemeral(beatInfo.isEphemeral());
}
/**
* TODO use spi and metadata info to generate instanceId.
*/
private void setInstanceId(Instance instance) {
DefaultInstanceIdGenerator idGenerator = new DefaultInstanceIdGenerator(instance.getServiceName(),
instance.getClusterName(), instance.getIp(), instance.getPort());
instance.setInstanceId(idGenerator.generateInstanceId());
}
}

View File

@ -0,0 +1,49 @@
/*
* 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.pojo.instance;
import com.alibaba.nacos.api.naming.spi.generator.IdGenerator;
/**
* Default instance id generator.
*
* @author xiweng.yy
*/
public class DefaultInstanceIdGenerator implements IdGenerator {
public static final String ID_DELIMITER = "#";
private final String serviceName;
private final String clusterName;
private final String ip;
private final int port;
public DefaultInstanceIdGenerator(String serviceName, String clusterName, String ip, int port) {
this.serviceName = serviceName;
this.clusterName = clusterName;
this.ip = ip;
this.port = port;
}
@Override
public String generateInstanceId() {
return ip + ID_DELIMITER + port + ID_DELIMITER + clusterName + ID_DELIMITER + serviceName;
}
}

View File

@ -0,0 +1,149 @@
/*
* 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.pojo.instance;
import com.alibaba.nacos.api.exception.NacosException;
import com.alibaba.nacos.api.naming.CommonParams;
import com.alibaba.nacos.api.naming.pojo.Instance;
import com.alibaba.nacos.api.naming.pojo.builder.InstanceBuilder;
import com.alibaba.nacos.common.spi.NacosServiceLoader;
import com.alibaba.nacos.common.utils.ConvertUtils;
import com.alibaba.nacos.common.utils.StringUtils;
import com.alibaba.nacos.core.utils.WebUtils;
import com.alibaba.nacos.naming.constants.Constants;
import com.alibaba.nacos.naming.misc.UtilsAndCommons;
import javax.servlet.http.HttpServletRequest;
import java.util.Collection;
/**
* Http instance builder.
*
* <p>
* The http openAPI will split each attributes of {@link Instance} as parameters of http parameters. This Builder can
* set an http request and get necessary parameters to build {@link Instance}.
* </p>
*
* <p>
* This builder is a wrapper for {@link com.alibaba.nacos.api.naming.pojo.builder.InstanceBuilder} and will inject some
* extension handler by spi.
* </p>
*
* @author xiweng.yy
*/
public class HttpRequestInstanceBuilder {
private final InstanceBuilder actualBuilder;
private final Collection<InstanceExtensionHandler> handlers;
private boolean defaultInstanceEphemeral = true;
private HttpRequestInstanceBuilder() {
this.actualBuilder = InstanceBuilder.newBuilder();
this.handlers = NacosServiceLoader.newServiceInstances(InstanceExtensionHandler.class);
}
public static HttpRequestInstanceBuilder newBuilder() {
return new HttpRequestInstanceBuilder();
}
/**
* Build a new {@link Instance} and chain handled by {@link InstanceExtensionHandler}.
*
* @return new instance
*/
public Instance build() {
Instance result = actualBuilder.build();
for (InstanceExtensionHandler each : handlers) {
each.handleExtensionInfo(result);
}
setInstanceId(result);
return result;
}
public HttpRequestInstanceBuilder setDefaultInstanceEphemeral(boolean defaultInstanceEphemeral) {
this.defaultInstanceEphemeral = defaultInstanceEphemeral;
return this;
}
public HttpRequestInstanceBuilder setRequest(HttpServletRequest request) throws NacosException {
for (InstanceExtensionHandler each : handlers) {
each.configExtensionInfoFromRequest(request);
}
setAttributesToBuilder(request);
return this;
}
private void setAttributesToBuilder(HttpServletRequest request) throws NacosException {
actualBuilder.setServiceName(WebUtils.required(request, CommonParams.SERVICE_NAME));
actualBuilder.setIp(WebUtils.required(request, "ip"));
actualBuilder.setPort(Integer.parseInt(WebUtils.required(request, "port")));
actualBuilder.setHealthy(ConvertUtils.toBoolean(WebUtils.optional(request, "healthy", "true")));
actualBuilder.setEphemeral(ConvertUtils
.toBoolean(WebUtils.optional(request, "ephemeral", String.valueOf(defaultInstanceEphemeral))));
setWeight(request);
setCluster(request);
setEnabled(request);
setMetadata(request);
}
private void setWeight(HttpServletRequest request) throws NacosException {
double weight = Double.parseDouble(WebUtils.optional(request, "weight", "1"));
if (weight > Constants.MAX_WEIGHT_VALUE || weight < Constants.MIN_WEIGHT_VALUE) {
throw new NacosException(NacosException.INVALID_PARAM,
"instance format invalid: The weights range from " + Constants.MIN_WEIGHT_VALUE + " to "
+ Constants.MAX_WEIGHT_VALUE);
}
actualBuilder.setWeight(weight);
}
private void setCluster(HttpServletRequest request) {
String cluster = WebUtils.optional(request, CommonParams.CLUSTER_NAME, StringUtils.EMPTY);
if (StringUtils.isBlank(cluster)) {
cluster = WebUtils.optional(request, "cluster", UtilsAndCommons.DEFAULT_CLUSTER_NAME);
}
actualBuilder.setClusterName(cluster);
}
private void setEnabled(HttpServletRequest request) {
String enabledString = WebUtils.optional(request, "enabled", StringUtils.EMPTY);
boolean enabled;
if (StringUtils.isBlank(enabledString)) {
enabled = ConvertUtils.toBoolean(WebUtils.optional(request, "enable", "true"));
} else {
enabled = ConvertUtils.toBoolean(enabledString);
}
actualBuilder.setEnabled(enabled);
}
private void setMetadata(HttpServletRequest request) throws NacosException {
String metadata = WebUtils.optional(request, "metadata", StringUtils.EMPTY);
if (StringUtils.isNotEmpty(metadata)) {
actualBuilder.setMetadata(UtilsAndCommons.parseMetadata(metadata));
}
}
/**
* TODO use spi and metadata info to generate instanceId.
*/
private void setInstanceId(Instance instance) {
DefaultInstanceIdGenerator idGenerator = new DefaultInstanceIdGenerator(instance.getServiceName(),
instance.getClusterName(), instance.getIp(), instance.getPort());
instance.setInstanceId(idGenerator.generateInstanceId());
}
}

View File

@ -14,20 +14,20 @@
* limitations under the License.
*/
package com.alibaba.nacos.naming.healthcheck.heartbeat;
package com.alibaba.nacos.naming.pojo.instance;
import com.alibaba.nacos.api.naming.pojo.Instance;
import javax.servlet.http.HttpServletRequest;
/**
* Client beat extension handler.
* Instance extension handler.
*
* <p>An extension handler for client beat, which is to handle some specified beat request for 1.x client.
* <p>An extension handler for {@link Instance}, which is to handle some specified request for 1.x client.
*
* @author xiweng.yy
*/
public interface ClientBeatExtensionHandler {
public interface InstanceExtensionHandler {
/**
* Config extension info from http request.

View File

@ -0,0 +1,17 @@
#
# 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.
#
com.alibaba.nacos.naming.pojo.instance.AppExtensionHandler

View File

@ -0,0 +1,82 @@
/*
* 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.pojo.instance;
import com.alibaba.nacos.api.naming.pojo.Instance;
import com.alibaba.nacos.common.spi.NacosServiceLoader;
import com.alibaba.nacos.naming.healthcheck.RsInfo;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnitRunner;
import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import static org.hamcrest.CoreMatchers.is;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.verify;
@RunWith(MockitoJUnitRunner.class)
public class BeatInfoInstanceBuilderTest {
@Mock
private HttpServletRequest request;
private RsInfo beatInfo;
private BeatInfoInstanceBuilder builder;
@BeforeClass
public static void setUpBeforeClass() {
NacosServiceLoader.load(InstanceExtensionHandler.class);
}
@Before
public void setUp() throws Exception {
builder = BeatInfoInstanceBuilder.newBuilder();
builder.setRequest(request);
beatInfo = new RsInfo();
beatInfo.setServiceName("g@@s");
beatInfo.setCluster("c");
beatInfo.setIp("1.1.1.1");
beatInfo.setPort(8848);
beatInfo.setWeight(10);
beatInfo.setMetadata(new HashMap<>());
}
@Test
public void testBuild() {
Instance actual = builder.setServiceName("g@@s").setBeatInfo(beatInfo).build();
assertThat(actual.getServiceName(), is("g@@s"));
assertThat(actual.getIp(), is("1.1.1.1"));
assertThat(actual.getPort(), is(8848));
assertThat(actual.getClusterName(), is("c"));
assertThat(actual.getWeight(), is(10.0));
assertTrue(actual.isEphemeral());
assertTrue(actual.isEnabled());
assertTrue(actual.isHealthy());
assertThat(actual.getInstanceId(), is("1.1.1.1#8848#c#g@@s"));
assertThat(actual.getMetadata().size(), is(2));
assertThat(actual.getMetadata().get("mock"), is("mock"));
assertThat(actual.getMetadata().get("app"), is("DEFAULT"));
verify(request).getParameter("mock");
}
}

View File

@ -0,0 +1,31 @@
/*
* 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.pojo.instance;
import org.junit.Test;
import static org.hamcrest.CoreMatchers.is;
import static org.junit.Assert.assertThat;
public class DefaultInstanceIdGeneratorTest {
@Test
public void testGenerateInstanceId() {
DefaultInstanceIdGenerator idGenerator = new DefaultInstanceIdGenerator("service", "cluster", "1.1.1.1", 1000);
assertThat(idGenerator.generateInstanceId(), is("1.1.1.1#1000#cluster#service"));
}
}

View File

@ -0,0 +1,130 @@
/*
* 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.pojo.instance;
import com.alibaba.nacos.api.exception.NacosException;
import com.alibaba.nacos.api.naming.CommonParams;
import com.alibaba.nacos.api.naming.pojo.Instance;
import com.alibaba.nacos.common.spi.NacosServiceLoader;
import com.alibaba.nacos.naming.misc.UtilsAndCommons;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnitRunner;
import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.Map;
import static org.hamcrest.CoreMatchers.is;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@RunWith(MockitoJUnitRunner.class)
public class HttpRequestInstanceBuilderTest {
private static final String SERVICE = "service";
private static final String IP = "127.0.0.1";
private static final String PORT = "8848";
@Mock
private HttpServletRequest request;
private HttpRequestInstanceBuilder builder;
@BeforeClass
public static void setUpBeforeClass() {
NacosServiceLoader.load(InstanceExtensionHandler.class);
}
@Before
public void setUp() throws Exception {
builder = HttpRequestInstanceBuilder.newBuilder();
when(request.getParameter(CommonParams.SERVICE_NAME)).thenReturn("service");
when(request.getParameter("ip")).thenReturn(IP);
when(request.getParameter("port")).thenReturn(PORT);
builder.setDefaultInstanceEphemeral(true);
}
@Test
public void testBuildSimple() throws NacosException {
Instance actual = builder.setRequest(request).build();
assertThat(actual.getServiceName(), is(SERVICE));
assertThat(actual.getIp(), is(IP));
assertThat(actual.getPort(), is(Integer.parseInt(PORT)));
assertThat(actual.getClusterName(), is(UtilsAndCommons.DEFAULT_CLUSTER_NAME));
assertThat(actual.getWeight(), is(1.0));
assertTrue(actual.isEphemeral());
assertTrue(actual.isEnabled());
assertTrue(actual.isHealthy());
assertThat(actual.getInstanceId(),
is(IP + "#" + PORT + "#" + UtilsAndCommons.DEFAULT_CLUSTER_NAME + "#" + SERVICE));
assertThat(actual.getMetadata().size(), is(2));
assertThat(actual.getMetadata().get("app"), is("DEFAULT"));
assertThat(actual.getMetadata().get("mock"), is("mock"));
verify(request).getParameter("mock");
}
@Test
public void testBuildFull() throws NacosException {
Map<String, String[]> mockMap = new HashMap<>();
mockMap.put("weight", new String[] {""});
mockMap.put("healthy", new String[] {""});
mockMap.put("enabled", new String[] {""});
mockMap.put("ephemeral", new String[] {""});
mockMap.put("metadata", new String[] {""});
mockMap.put(CommonParams.CLUSTER_NAME, new String[] {""});
when(request.getParameterMap()).thenReturn(mockMap);
when(request.getParameter("weight")).thenReturn("2");
when(request.getParameter("healthy")).thenReturn("false");
when(request.getParameter("enabled")).thenReturn("false");
when(request.getParameter("ephemeral")).thenReturn("false");
when(request.getParameter("metadata")).thenReturn("{\"a\":\"b\"}");
when(request.getParameter(CommonParams.CLUSTER_NAME)).thenReturn("cluster");
Instance actual = builder.setRequest(request).build();
assertThat(actual.getServiceName(), is(SERVICE));
assertThat(actual.getIp(), is(IP));
assertThat(actual.getPort(), is(Integer.parseInt(PORT)));
assertThat(actual.getClusterName(), is("cluster"));
assertThat(actual.getWeight(), is(2.0));
assertFalse(actual.isEphemeral());
assertFalse(actual.isEnabled());
assertFalse(actual.isHealthy());
assertThat(actual.getInstanceId(), is(IP + "#" + PORT + "#" + "cluster" + "#" + SERVICE));
assertThat(actual.getMetadata().size(), is(3));
assertThat(actual.getMetadata().get("mock"), is("mock"));
assertThat(actual.getMetadata().get("app"), is("DEFAULT"));
assertThat(actual.getMetadata().get("a"), is("b"));
verify(request).getParameter("mock");
}
@Test(expected = NacosException.class)
public void testBuildWithIllegalWeight() throws NacosException {
Map<String, String[]> mockMap = new HashMap<>();
mockMap.put("weight", new String[] {""});
when(request.getParameterMap()).thenReturn(mockMap);
when(request.getParameter("weight")).thenReturn("10001");
Instance actual = builder.setRequest(request).build();
}
}

View File

@ -0,0 +1,34 @@
/*
* 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.pojo.instance;
import com.alibaba.nacos.api.naming.pojo.Instance;
import javax.servlet.http.HttpServletRequest;
public class MockInstanceExtensionHandler implements InstanceExtensionHandler {
@Override
public void configExtensionInfoFromRequest(HttpServletRequest request) {
request.getParameter("mock");
}
@Override
public void handleExtensionInfo(Instance needHandleInstance) {
needHandleInstance.getMetadata().put("mock", "mock");
}
}

View File

@ -0,0 +1,17 @@
#
# 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.
#
com.alibaba.nacos.naming.pojo.instance.MockInstanceExtensionHandler