[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:
parent
71f170a7a5
commit
5e545c8d37
@ -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();
|
||||||
|
}
|
||||||
|
}
|
@ -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();
|
||||||
|
}
|
@ -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());
|
||||||
|
}
|
||||||
|
}
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -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.
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -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());
|
||||||
|
}
|
||||||
|
}
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
@ -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());
|
||||||
|
}
|
||||||
|
}
|
@ -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.
|
@ -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
|
@ -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");
|
||||||
|
}
|
||||||
|
}
|
@ -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"));
|
||||||
|
}
|
||||||
|
}
|
@ -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();
|
||||||
|
}
|
||||||
|
}
|
@ -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");
|
||||||
|
}
|
||||||
|
}
|
@ -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
|
Loading…
Reference in New Issue
Block a user