[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. * Whether enabled for instance according to instance self publish.
*/ */
public static final String PUBLISH_INSTANCE_ENABLE = "publishInstanceEnable"; 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.common.Constants;
import com.alibaba.nacos.api.exception.NacosException; import com.alibaba.nacos.api.exception.NacosException;
import com.alibaba.nacos.api.naming.CommonParams; 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.api.naming.utils.NamingUtils;
import com.alibaba.nacos.auth.annotation.Secured; import com.alibaba.nacos.auth.annotation.Secured;
import com.alibaba.nacos.auth.common.ActionTypes; import com.alibaba.nacos.auth.common.ActionTypes;
import com.alibaba.nacos.common.spi.NacosServiceLoader; import com.alibaba.nacos.common.spi.NacosServiceLoader;
import com.alibaba.nacos.common.utils.JacksonUtils; import com.alibaba.nacos.common.utils.JacksonUtils;
import com.alibaba.nacos.core.utils.WebUtils; 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.InstanceOperator;
import com.alibaba.nacos.naming.core.InstanceOperatorClientImpl; import com.alibaba.nacos.naming.core.InstanceOperatorClientImpl;
import com.alibaba.nacos.naming.core.InstanceOperatorServiceImpl; import com.alibaba.nacos.naming.core.InstanceOperatorServiceImpl;
import com.alibaba.nacos.naming.core.InstancePatchObject; import com.alibaba.nacos.naming.core.InstancePatchObject;
import com.alibaba.nacos.naming.core.v2.upgrade.UpgradeJudgement; import com.alibaba.nacos.naming.core.v2.upgrade.UpgradeJudgement;
import com.alibaba.nacos.naming.healthcheck.RsInfo; 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.Loggers;
import com.alibaba.nacos.naming.misc.SwitchDomain; import com.alibaba.nacos.naming.misc.SwitchDomain;
import com.alibaba.nacos.naming.misc.SwitchEntry; import com.alibaba.nacos.naming.misc.SwitchEntry;
import com.alibaba.nacos.naming.misc.UtilsAndCommons; import com.alibaba.nacos.naming.misc.UtilsAndCommons;
import com.alibaba.nacos.naming.pojo.InstanceOperationInfo; import com.alibaba.nacos.naming.pojo.InstanceOperationInfo;
import com.alibaba.nacos.naming.pojo.Subscriber; 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.CanDistro;
import com.alibaba.nacos.naming.web.NamingResourceParser; import com.alibaba.nacos.naming.web.NamingResourceParser;
import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.core.type.TypeReference;
@ -87,7 +89,8 @@ public class InstanceController {
private UpgradeJudgement upgradeJudgement; private UpgradeJudgement upgradeJudgement;
public InstanceController() { 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); final String serviceName = WebUtils.required(request, CommonParams.SERVICE_NAME);
NamingUtils.checkServiceNameFormat(serviceName); NamingUtils.checkServiceNameFormat(serviceName);
final Instance instance = parseInstance(request); final Instance instance = HttpRequestInstanceBuilder.newBuilder()
.setDefaultInstanceEphemeral(switchDomain.isDefaultInstanceEphemeral()).setRequest(request).build();
getInstanceOperator().registerInstance(namespaceId, serviceName, instance); getInstanceOperator().registerInstance(namespaceId, serviceName, instance);
return "ok"; return "ok";
@ -124,7 +128,8 @@ public class InstanceController {
@DeleteMapping @DeleteMapping
@Secured(parser = NamingResourceParser.class, action = ActionTypes.WRITE) @Secured(parser = NamingResourceParser.class, action = ActionTypes.WRITE)
public String deregister(HttpServletRequest request) throws Exception { 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 namespaceId = WebUtils.optional(request, CommonParams.NAMESPACE_ID, Constants.DEFAULT_NAMESPACE_ID);
String serviceName = WebUtils.required(request, CommonParams.SERVICE_NAME); String serviceName = WebUtils.required(request, CommonParams.SERVICE_NAME);
NamingUtils.checkServiceNameFormat(serviceName); NamingUtils.checkServiceNameFormat(serviceName);
@ -147,7 +152,9 @@ public class InstanceController {
String namespaceId = WebUtils.optional(request, CommonParams.NAMESPACE_ID, Constants.DEFAULT_NAMESPACE_ID); String namespaceId = WebUtils.optional(request, CommonParams.NAMESPACE_ID, Constants.DEFAULT_NAMESPACE_ID);
String serviceName = WebUtils.required(request, CommonParams.SERVICE_NAME); String serviceName = WebUtils.required(request, CommonParams.SERVICE_NAME);
NamingUtils.checkServiceNameFormat(serviceName); 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"; return "ok";
} }
@ -388,13 +395,10 @@ public class InstanceController {
NamingUtils.checkServiceNameFormat(serviceName); NamingUtils.checkServiceNameFormat(serviceName);
Loggers.SRV_LOG.debug("[CLIENT-BEAT] full arguments: beat: {}, serviceName: {}, namespaceId: {}", clientBeat, Loggers.SRV_LOG.debug("[CLIENT-BEAT] full arguments: beat: {}, serviceName: {}, namespaceId: {}", clientBeat,
serviceName, namespaceId); serviceName, namespaceId);
Collection<ClientBeatExtensionHandler> extensionHandlers = NacosServiceLoader BeatInfoInstanceBuilder builder = BeatInfoInstanceBuilder.newBuilder();
.newServiceInstances(ClientBeatExtensionHandler.class); builder.setRequest(request);
for (ClientBeatExtensionHandler each : extensionHandlers) {
each.configExtensionInfoFromRequest(request);
}
int resultCode = getInstanceOperator() 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(CommonParams.CODE, resultCode);
result.put(SwitchEntry.CLIENT_BEAT_INTERVAL, result.put(SwitchEntry.CLIENT_BEAT_INTERVAL,
getInstanceOperator().getHeartBeatInterval(namespaceId, serviceName, ip, port, clusterName)); getInstanceOperator().getHeartBeatInterval(namespaceId, serviceName, ip, port, clusterName));
@ -436,68 +440,6 @@ public class InstanceController {
return result; 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() { private InstanceOperator getInstanceOperator() {
return upgradeJudgement.isUseGrpcFeatures() ? instanceServiceV2 : instanceServiceV1; 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.common.Constants;
import com.alibaba.nacos.api.exception.NacosException; import com.alibaba.nacos.api.exception.NacosException;
import com.alibaba.nacos.api.naming.CommonParams; 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.pojo.ServiceInfo;
import com.alibaba.nacos.api.naming.utils.NamingUtils; import com.alibaba.nacos.api.naming.utils.NamingUtils;
import com.alibaba.nacos.api.selector.SelectorType; 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.auth.common.ActionTypes;
import com.alibaba.nacos.common.utils.JacksonUtils; import com.alibaba.nacos.common.utils.JacksonUtils;
import com.alibaba.nacos.core.utils.WebUtils; 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.InstanceOperator;
import com.alibaba.nacos.naming.core.InstanceOperatorClientImpl; import com.alibaba.nacos.naming.core.InstanceOperatorClientImpl;
import com.alibaba.nacos.naming.core.InstanceOperatorServiceImpl; 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.misc.UtilsAndCommons;
import com.alibaba.nacos.naming.monitor.MetricsMonitor; import com.alibaba.nacos.naming.monitor.MetricsMonitor;
import com.alibaba.nacos.naming.pojo.Subscriber; 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.LabelSelector;
import com.alibaba.nacos.naming.selector.NoneSelector; import com.alibaba.nacos.naming.selector.NoneSelector;
import com.alibaba.nacos.naming.selector.Selector; import com.alibaba.nacos.naming.selector.Selector;
@ -81,8 +82,7 @@ import static com.alibaba.nacos.naming.misc.UtilsAndCommons.NAMESPACE_SERVICE_CO
* *
* <p>Helping to resolve some unexpected problems when upgrading. * <p>Helping to resolve some unexpected problems when upgrading.
* *
* @author gengtuo.ygt * @author gengtuo.ygt on 2021/5/14
* on 2021/5/14
* @deprecated will be removed at 2.1.x * @deprecated will be removed at 2.1.x
*/ */
@RestController @RestController
@ -107,14 +107,10 @@ public class UpgradeOpsController {
private final UpgradeJudgement upgradeJudgement; private final UpgradeJudgement upgradeJudgement;
public UpgradeOpsController(SwitchDomain switchDomain, public UpgradeOpsController(SwitchDomain switchDomain, ServiceManager serviceManager,
ServiceManager serviceManager, ServiceOperatorV1Impl serviceOperatorV1, ServiceOperatorV2Impl serviceOperatorV2,
ServiceOperatorV1Impl serviceOperatorV1, InstanceOperatorServiceImpl instanceServiceV1, InstanceOperatorClientImpl instanceServiceV2,
ServiceOperatorV2Impl serviceOperatorV2, ServiceStorage serviceStorage, DoubleWriteDelayTaskEngine doubleWriteDelayTaskEngine,
InstanceOperatorServiceImpl instanceServiceV1,
InstanceOperatorClientImpl instanceServiceV2,
ServiceStorage serviceStorage,
DoubleWriteDelayTaskEngine doubleWriteDelayTaskEngine,
UpgradeJudgement upgradeJudgement) { UpgradeJudgement upgradeJudgement) {
this.switchDomain = switchDomain; this.switchDomain = switchDomain;
this.serviceManager = serviceManager; this.serviceManager = serviceManager;
@ -168,11 +164,11 @@ public class UpgradeOpsController {
int ephemeralInstanceCountV2 = 0; int ephemeralInstanceCountV2 = 0;
Set<String> allNamespaces = com.alibaba.nacos.naming.core.v2.ServiceManager.getInstance().getAllNamespaces(); Set<String> allNamespaces = com.alibaba.nacos.naming.core.v2.ServiceManager.getInstance().getAllNamespaces();
for (String ns : allNamespaces) { for (String ns : allNamespaces) {
Set<com.alibaba.nacos.naming.core.v2.pojo.Service> services Set<com.alibaba.nacos.naming.core.v2.pojo.Service> services = com.alibaba.nacos.naming.core.v2.ServiceManager
= com.alibaba.nacos.naming.core.v2.ServiceManager.getInstance().getSingletons(ns); .getInstance().getSingletons(ns);
for (com.alibaba.nacos.naming.core.v2.pojo.Service service : services) { for (com.alibaba.nacos.naming.core.v2.pojo.Service service : services) {
String nameWithNs = service.getNamespace() String nameWithNs =
+ NAMESPACE_SERVICE_CONNECTOR + service.getGroupedServiceName(); service.getNamespace() + NAMESPACE_SERVICE_CONNECTOR + service.getGroupedServiceName();
serviceNamesV2.add(nameWithNs); serviceNamesV2.add(nameWithNs);
if (service.isEphemeral()) { if (service.isEphemeral()) {
ephemeralServiceNamesV2.add(nameWithNs); ephemeralServiceNamesV2.add(nameWithNs);
@ -211,12 +207,11 @@ public class UpgradeOpsController {
name = NamingUtils.getGroupedName(name, DEFAULT_GROUP); name = NamingUtils.getGroupedName(name, DEFAULT_GROUP);
} }
return e.getKey() + NAMESPACE_SERVICE_CONNECTOR + name; return e.getKey() + NAMESPACE_SERVICE_CONNECTOR + name;
})) })).collect(Collectors.toSet());
.collect(Collectors.toSet()); result.put("service.V1.not.in.V2",
result.put("service.V1.not.in.V2", String.join("\n", String.join("\n", (Collection<String>) CollectionUtils.subtract(serviceNamesV1, serviceNamesV2)));
(Collection<String>) CollectionUtils.subtract(serviceNamesV1, serviceNamesV2))); result.put("service.V2.not.in.V1",
result.put("service.V2.not.in.V1", String.join("\n", String.join("\n", (Collection<String>) CollectionUtils.subtract(serviceNamesV2, serviceNamesV1)));
(Collection<String>) CollectionUtils.subtract(serviceNamesV2, serviceNamesV1)));
return result; return result;
} }
@ -234,8 +229,7 @@ public class UpgradeOpsController {
@PostMapping("/service") @PostMapping("/service")
@Secured(parser = NamingResourceParser.class, action = ActionTypes.WRITE) @Secured(parser = NamingResourceParser.class, action = ActionTypes.WRITE)
public String createService(@RequestParam(defaultValue = "v2", required = false) String ver, public String createService(@RequestParam(defaultValue = "v2", required = false) String ver,
HttpServletRequest request, HttpServletRequest request, @RequestParam(defaultValue = Constants.DEFAULT_NAMESPACE_ID) String namespaceId,
@RequestParam(defaultValue = Constants.DEFAULT_NAMESPACE_ID) String namespaceId,
@RequestParam String serviceName, @RequestParam String serviceName,
@RequestParam(required = false, defaultValue = "0.0F") float protectThreshold, @RequestParam(required = false, defaultValue = "0.0F") float protectThreshold,
@RequestParam(defaultValue = StringUtils.EMPTY) String metadata, @RequestParam(defaultValue = StringUtils.EMPTY) String metadata,
@ -412,7 +406,8 @@ public class UpgradeOpsController {
final String serviceName = WebUtils.required(request, CommonParams.SERVICE_NAME); final String serviceName = WebUtils.required(request, CommonParams.SERVICE_NAME);
NamingUtils.checkServiceNameFormat(serviceName); 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); getInstanceOperator(ver).registerInstance(namespaceId, serviceName, instance);
return "ok"; return "ok";
@ -430,7 +425,8 @@ public class UpgradeOpsController {
@Secured(parser = NamingResourceParser.class, action = ActionTypes.WRITE) @Secured(parser = NamingResourceParser.class, action = ActionTypes.WRITE)
public String deregisterInstance(@RequestParam(defaultValue = "v2", required = false) String ver, public String deregisterInstance(@RequestParam(defaultValue = "v2", required = false) String ver,
HttpServletRequest request) throws Exception { 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 namespaceId = WebUtils.optional(request, CommonParams.NAMESPACE_ID, Constants.DEFAULT_NAMESPACE_ID);
String serviceName = WebUtils.required(request, CommonParams.SERVICE_NAME); String serviceName = WebUtils.required(request, CommonParams.SERVICE_NAME);
NamingUtils.checkServiceNameFormat(serviceName); NamingUtils.checkServiceNameFormat(serviceName);
@ -454,7 +450,9 @@ public class UpgradeOpsController {
String namespaceId = WebUtils.optional(request, CommonParams.NAMESPACE_ID, Constants.DEFAULT_NAMESPACE_ID); String namespaceId = WebUtils.optional(request, CommonParams.NAMESPACE_ID, Constants.DEFAULT_NAMESPACE_ID);
String serviceName = WebUtils.required(request, CommonParams.SERVICE_NAME); String serviceName = WebUtils.required(request, CommonParams.SERVICE_NAME);
NamingUtils.checkServiceNameFormat(serviceName); 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"; return "ok";
} }
@ -525,68 +523,6 @@ public class UpgradeOpsController {
return result; 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) { private InstanceOperator getInstanceOperator(String ver) {
return "v2".equals(ver) ? instanceServiceV2 : instanceServiceV1; return "v2".equals(ver) ? instanceServiceV2 : instanceServiceV1;
} }

View File

@ -41,12 +41,6 @@ import java.util.regex.Pattern;
@JsonInclude(Include.NON_NULL) @JsonInclude(Include.NON_NULL)
public class Instance extends com.alibaba.nacos.api.naming.pojo.Instance implements Comparable { 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 static final long serialVersionUID = -6527721638428975306L;
private volatile long lastBeat = System.currentTimeMillis(); 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; 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]); 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); throw new IllegalArgumentException("malformed ip config: " + json);
} }
if (ip.getWeight() > MAX_WEIGHT_VALUE) { if (ip.getWeight() > com.alibaba.nacos.naming.constants.Constants.MAX_WEIGHT_VALUE) {
ip.setWeight(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) { if (ip.getWeight() < com.alibaba.nacos.naming.constants.Constants.MIN_POSITIVE_WEIGHT_VALUE
ip.setWeight(MIN_POSITIVE_WEIGHT_VALUE); && ip.getWeight() > com.alibaba.nacos.naming.constants.Constants.MIN_WEIGHT_VALUE) {
} else if (ip.getWeight() < 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); 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) { if (getWeight() > com.alibaba.nacos.naming.constants.Constants.MAX_WEIGHT_VALUE
throw new NacosException(NacosException.INVALID_PARAM, || getWeight() < com.alibaba.nacos.naming.constants.Constants.MIN_WEIGHT_VALUE) {
"instance format invalid: The weights range from " + MIN_WEIGHT_VALUE + " to " + MAX_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.Instance;
import com.alibaba.nacos.api.naming.pojo.ServiceInfo; import com.alibaba.nacos.api.naming.pojo.ServiceInfo;
import com.alibaba.nacos.naming.healthcheck.RsInfo; 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.InstanceOperationInfo;
import com.alibaba.nacos.naming.pojo.Subscriber; 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.List;
import java.util.Map; import java.util.Map;
@ -118,12 +117,13 @@ public interface InstanceOperator {
* @param port port of instance * @param port port of instance
* @param cluster cluster of instance * @param cluster cluster of instance
* @param clientBeat client beat info * @param clientBeat client beat info
* @param extensionHandlers client beat extension handlers * @param builder client beat instance builder, will be used when current instance is not exist and clientBeat
* exist
* @return result code * @return result code
* @throws NacosException nacos exception when service non-exist and client beat info is null * @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, 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. * 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.core.v2.service.ClientOperationServiceProxy;
import com.alibaba.nacos.naming.healthcheck.HealthCheckReactor; import com.alibaba.nacos.naming.healthcheck.HealthCheckReactor;
import com.alibaba.nacos.naming.healthcheck.RsInfo; 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.healthcheck.heartbeat.ClientBeatProcessorV2;
import com.alibaba.nacos.naming.misc.Loggers; import com.alibaba.nacos.naming.misc.Loggers;
import com.alibaba.nacos.naming.misc.SwitchDomain; import com.alibaba.nacos.naming.misc.SwitchDomain;
import com.alibaba.nacos.naming.misc.UtilsAndCommons; import com.alibaba.nacos.naming.misc.UtilsAndCommons;
import com.alibaba.nacos.naming.pojo.InstanceOperationInfo; import com.alibaba.nacos.naming.pojo.InstanceOperationInfo;
import com.alibaba.nacos.naming.pojo.Subscriber; 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.UdpPushService;
import com.alibaba.nacos.naming.utils.ServiceUtil; import com.alibaba.nacos.naming.utils.ServiceUtil;
import java.util.Collection;
import java.util.HashMap; import java.util.HashMap;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.List; import java.util.List;
@ -213,7 +212,7 @@ public class InstanceOperatorClientImpl implements InstanceOperator {
@Override @Override
public int handleBeat(String namespaceId, String serviceName, String ip, int port, String cluster, 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); Service service = getService(namespaceId, serviceName, true);
String clientId = IpPortBasedClient.getClientId(ip + InternetAddressUtil.IP_PORT_SPLITER + port, true); String clientId = IpPortBasedClient.getClientId(ip + InternetAddressUtil.IP_PORT_SPLITER + port, true);
IpPortBasedClient client = (IpPortBasedClient) clientManager.getClient(clientId); IpPortBasedClient client = (IpPortBasedClient) clientManager.getClient(clientId);
@ -221,18 +220,7 @@ public class InstanceOperatorClientImpl implements InstanceOperator {
if (null == clientBeat) { if (null == clientBeat) {
return NamingResponseCode.RESOURCE_NOT_FOUND; return NamingResponseCode.RESOURCE_NOT_FOUND;
} }
Instance instance = new Instance(); Instance instance = builder.setBeatInfo(clientBeat).setServiceName(serviceName).build();
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);
}
registerInstance(namespaceId, serviceName, instance); registerInstance(namespaceId, serviceName, instance);
client = (IpPortBasedClient) clientManager.getClient(clientId); 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.Instance;
import com.alibaba.nacos.api.naming.pojo.ServiceInfo; import com.alibaba.nacos.api.naming.pojo.ServiceInfo;
import com.alibaba.nacos.common.utils.JacksonUtils; 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.RsInfo;
import com.alibaba.nacos.naming.healthcheck.heartbeat.ClientBeatExtensionHandler;
import com.alibaba.nacos.naming.misc.Loggers; import com.alibaba.nacos.naming.misc.Loggers;
import com.alibaba.nacos.naming.misc.SwitchDomain; import com.alibaba.nacos.naming.misc.SwitchDomain;
import com.alibaba.nacos.naming.pojo.InstanceOperationContext; import com.alibaba.nacos.naming.pojo.InstanceOperationContext;
import com.alibaba.nacos.naming.pojo.InstanceOperationInfo; import com.alibaba.nacos.naming.pojo.InstanceOperationInfo;
import com.alibaba.nacos.naming.pojo.Subscriber; 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.UdpPushService;
import com.alibaba.nacos.naming.push.v1.ClientInfo; import com.alibaba.nacos.naming.push.v1.ClientInfo;
import com.alibaba.nacos.naming.push.v1.DataSource; import com.alibaba.nacos.naming.push.v1.DataSource;
@ -72,6 +73,8 @@ public class InstanceOperatorServiceImpl implements InstanceOperator {
private final NamingSubscriberServiceV1Impl subscriberServiceV1; private final NamingSubscriberServiceV1Impl subscriberServiceV1;
private final InstanceUpgradeHelper instanceUpgradeHelper;
private DataSource pushDataSource = new DataSource() { private DataSource pushDataSource = new DataSource() {
@Override @Override
@ -94,22 +97,24 @@ public class InstanceOperatorServiceImpl implements InstanceOperator {
}; };
public InstanceOperatorServiceImpl(ServiceManager serviceManager, SwitchDomain switchDomain, public InstanceOperatorServiceImpl(ServiceManager serviceManager, SwitchDomain switchDomain,
UdpPushService pushService, NamingSubscriberServiceV1Impl subscriberServiceV1) { UdpPushService pushService, NamingSubscriberServiceV1Impl subscriberServiceV1,
InstanceUpgradeHelper instanceUpgradeHelper) {
this.serviceManager = serviceManager; this.serviceManager = serviceManager;
this.switchDomain = switchDomain; this.switchDomain = switchDomain;
this.pushService = pushService; this.pushService = pushService;
this.subscriberServiceV1 = subscriberServiceV1; this.subscriberServiceV1 = subscriberServiceV1;
this.instanceUpgradeHelper = instanceUpgradeHelper;
} }
@Override @Override
public void registerInstance(String namespaceId, String serviceName, Instance instance) throws NacosException { 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); serviceManager.registerInstance(namespaceId, serviceName, coreInstance);
} }
@Override @Override
public void removeInstance(String namespaceId, String serviceName, Instance instance) throws NacosException { 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); Service service = serviceManager.getService(namespaceId, serviceName);
if (service == null) { if (service == null) {
Loggers.SRV_LOG.warn("remove instance from non-exist service: {}", serviceName); Loggers.SRV_LOG.warn("remove instance from non-exist service: {}", serviceName);
@ -120,7 +125,7 @@ public class InstanceOperatorServiceImpl implements InstanceOperator {
@Override @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; com.alibaba.nacos.naming.core.Instance coreInstance = parseInstance(instance);
serviceManager.updateInstance(namespaceId, serviceName, coreInstance); serviceManager.updateInstance(namespaceId, serviceName, coreInstance);
} }
@ -145,9 +150,6 @@ public class InstanceOperatorServiceImpl implements InstanceOperator {
if (null != patchObject.getHealthy()) { if (null != patchObject.getHealthy()) {
instance.setHealthy(patchObject.getHealthy()); instance.setHealthy(patchObject.getHealthy());
} }
if (null != patchObject.getApp()) {
instance.setApp(patchObject.getApp());
}
instance.setLastBeat(System.currentTimeMillis()); instance.setLastBeat(System.currentTimeMillis());
instance.validate(); instance.validate();
serviceManager.updateInstance(namespaceId, serviceName, instance); serviceManager.updateInstance(namespaceId, serviceName, instance);
@ -275,7 +277,7 @@ public class InstanceOperatorServiceImpl implements InstanceOperator {
@Override @Override
public int handleBeat(String namespaceId, String serviceName, String ip, int port, String cluster, 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 com.alibaba.nacos.naming.core.Instance instance = serviceManager
.getInstance(namespaceId, serviceName, cluster, ip, port); .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, " Loggers.SRV_LOG.warn("[CLIENT-BEAT] The instance has been removed for health mechanism, "
+ "perform data compensation operations, beat: {}, serviceName: {}", clientBeat, serviceName); + "perform data compensation operations, beat: {}, serviceName: {}", clientBeat, serviceName);
instance = parseInstance(builder.setBeatInfo(clientBeat).setServiceName(serviceName).build());
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);
}
serviceManager.registerInstance(namespaceId, serviceName, instance); serviceManager.registerInstance(namespaceId, serviceName, instance);
} }
@ -371,4 +361,11 @@ public class InstanceOperatorServiceImpl implements InstanceOperator {
}; };
return serviceManager.batchOperate(namespace, instanceOperationInfo, operateFunction); 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 @Override
public boolean isReadyToUpgrade(ServiceManager serviceManager, DoubleWriteDelayTaskEngine taskEngine) { public boolean isReadyToUpgrade(ServiceManager serviceManager, DoubleWriteDelayTaskEngine taskEngine) {
System.out.println("test");
return checkServiceAndInstanceNumber(serviceManager) && checkDoubleWriteStatus(taskEngine); 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. * 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 com.alibaba.nacos.api.naming.pojo.Instance;
import javax.servlet.http.HttpServletRequest; 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 * @author xiweng.yy
*/ */
public interface ClientBeatExtensionHandler { public interface InstanceExtensionHandler {
/** /**
* Config extension info from http request. * 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