Merge branch 'feature_cmdb' into 0.7.0
# Conflicts: # api/pom.xml # api/src/main/java/com/alibaba/nacos/api/exception/NacosException.java # client/pom.xml # client/src/main/java/com/alibaba/nacos/client/config/impl/HttpSimpleClient.java # client/src/main/java/com/alibaba/nacos/client/naming/net/NamingProxy.java # common/pom.xml # config/pom.xml # console/pom.xml # core/pom.xml # distribution/conf/application.properties # distribution/conf/nacos-logback.xml # distribution/pom.xml # distribution/release-nacos.xml # example/pom.xml # naming/pom.xml # naming/src/main/java/com/alibaba/nacos/naming/web/ApiCommands.java # pom.xml # test/pom.xml
This commit is contained in:
commit
d2e4f4e6b4
@ -0,0 +1,52 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 1999-2018 Alibaba Group Holding Ltd.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package com.alibaba.nacos.api.cmdb.pojo;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author <a href="mailto:zpf.073@gmail.com">nkorange</a>
|
||||||
|
*/
|
||||||
|
public class Entity {
|
||||||
|
|
||||||
|
private String type;
|
||||||
|
private String name;
|
||||||
|
private Map<String, String> labels;
|
||||||
|
|
||||||
|
public String getType() {
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setType(String type) {
|
||||||
|
this.type = type;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setName(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Map<String, String> getLabels() {
|
||||||
|
return labels;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLabels(Map<String, String> labels) {
|
||||||
|
this.labels = labels;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,50 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 1999-2018 Alibaba Group Holding Ltd.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package com.alibaba.nacos.api.cmdb.pojo;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author <a href="mailto:zpf.073@gmail.com">nkorange</a>
|
||||||
|
*/
|
||||||
|
public class EntityEvent {
|
||||||
|
|
||||||
|
private EntityEventType type;
|
||||||
|
private String entityName;
|
||||||
|
private String entityType;
|
||||||
|
|
||||||
|
public EntityEventType getType() {
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setType(EntityEventType type) {
|
||||||
|
this.type = type;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getEntityName() {
|
||||||
|
return entityName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setEntityName(String entityName) {
|
||||||
|
this.entityName = entityName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getEntityType() {
|
||||||
|
return entityType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setEntityType(String entityType) {
|
||||||
|
this.entityType = entityType;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,30 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 1999-2018 Alibaba Group Holding Ltd.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package com.alibaba.nacos.api.cmdb.pojo;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author <a href="mailto:zpf.073@gmail.com">nkorange</a>
|
||||||
|
*/
|
||||||
|
public enum EntityEventType {
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
ENTITY_ADD_OR_UPDATE,
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
ENTITY_REMOVE
|
||||||
|
}
|
52
api/src/main/java/com/alibaba/nacos/api/cmdb/pojo/Label.java
Normal file
52
api/src/main/java/com/alibaba/nacos/api/cmdb/pojo/Label.java
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 1999-2018 Alibaba Group Holding Ltd.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package com.alibaba.nacos.api.cmdb.pojo;
|
||||||
|
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author <a href="mailto:zpf.073@gmail.com">nkorange</a>
|
||||||
|
*/
|
||||||
|
public class Label {
|
||||||
|
|
||||||
|
private String name;
|
||||||
|
private Set<String> values;
|
||||||
|
private String description;
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setName(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Set<String> getValues() {
|
||||||
|
return values;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setValues(Set<String> values) {
|
||||||
|
this.values = values;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDescription() {
|
||||||
|
return description;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDescription(String description) {
|
||||||
|
this.description = description;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,30 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 1999-2018 Alibaba Group Holding Ltd.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package com.alibaba.nacos.api.cmdb.pojo;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author <a href="mailto:zpf.073@gmail.com">nkorange</a>
|
||||||
|
*/
|
||||||
|
public enum PreservedEntityTypes {
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
ip,
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
service
|
||||||
|
}
|
@ -0,0 +1,97 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 1999-2018 Alibaba Group Holding Ltd.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package com.alibaba.nacos.api.cmdb.spi;
|
||||||
|
|
||||||
|
import com.alibaba.nacos.api.cmdb.pojo.Entity;
|
||||||
|
import com.alibaba.nacos.api.cmdb.pojo.EntityEvent;
|
||||||
|
import com.alibaba.nacos.api.cmdb.pojo.Label;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Service to visit CMDB store
|
||||||
|
*
|
||||||
|
* @author <a href="mailto:zpf.073@gmail.com">nkorange</a>
|
||||||
|
*/
|
||||||
|
public interface CmdbService {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get all label names stored in CMDB
|
||||||
|
*
|
||||||
|
* @return label name set
|
||||||
|
*/
|
||||||
|
Set<String> getLabelNames();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get all possible entity types in CMDB
|
||||||
|
*
|
||||||
|
* @return all entity types
|
||||||
|
*/
|
||||||
|
Set<String> getEntityTypes();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get label info
|
||||||
|
*
|
||||||
|
* @param labelName label name
|
||||||
|
* @return label info
|
||||||
|
*/
|
||||||
|
Label getLabel(String labelName);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get label value of label name of ip
|
||||||
|
*
|
||||||
|
* @param entityType entity type
|
||||||
|
* @param entityValue entity value
|
||||||
|
* @param labelName target label name
|
||||||
|
* @return label value
|
||||||
|
*/
|
||||||
|
String getLabelValue(String entityValue, String entityType, String labelName);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get all label value of ip
|
||||||
|
*
|
||||||
|
* @param entityType entity type
|
||||||
|
* @param entityValue entity value
|
||||||
|
* @return all label values
|
||||||
|
*/
|
||||||
|
Map<String, String> getLabelValues(String entityValue, String entityType);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Dump all entities in CMDB
|
||||||
|
*
|
||||||
|
* @return all entities
|
||||||
|
*/
|
||||||
|
Map<String, Map<String, Entity>> getAllEntities();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* get label change events
|
||||||
|
*
|
||||||
|
* @param timestamp start time of generated events
|
||||||
|
* @return label events
|
||||||
|
*/
|
||||||
|
List<EntityEvent> getEntityEvents(long timestamp);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get single entity
|
||||||
|
*
|
||||||
|
* @param entityName name of entity
|
||||||
|
* @param entityType type of entity
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
Entity getEntity(String entityName, String entityType);
|
||||||
|
}
|
@ -20,6 +20,7 @@ import com.alibaba.nacos.api.naming.listener.EventListener;
|
|||||||
import com.alibaba.nacos.api.naming.pojo.Instance;
|
import com.alibaba.nacos.api.naming.pojo.Instance;
|
||||||
import com.alibaba.nacos.api.naming.pojo.ListView;
|
import com.alibaba.nacos.api.naming.pojo.ListView;
|
||||||
import com.alibaba.nacos.api.naming.pojo.ServiceInfo;
|
import com.alibaba.nacos.api.naming.pojo.ServiceInfo;
|
||||||
|
import com.alibaba.nacos.api.selector.AbstractSelector;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@ -186,6 +187,17 @@ public interface NamingService {
|
|||||||
*/
|
*/
|
||||||
ListView<String> getServicesOfServer(int pageNo, int pageSize) throws NacosException;
|
ListView<String> getServicesOfServer(int pageNo, int pageSize) throws NacosException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get all service names from server
|
||||||
|
*
|
||||||
|
* @param pageNo page index
|
||||||
|
* @param pageSize page size
|
||||||
|
* @param selector selector to filter the resource
|
||||||
|
* @return list of service names
|
||||||
|
* @throws NacosException
|
||||||
|
*/
|
||||||
|
ListView<String> getServicesOfServer(int pageNo, int pageSize, AbstractSelector selector) throws NacosException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get all subscribed services of current client
|
* Get all subscribed services of current client
|
||||||
*
|
*
|
||||||
|
@ -15,8 +15,6 @@
|
|||||||
*/
|
*/
|
||||||
package com.alibaba.nacos.api.naming.pojo;
|
package com.alibaba.nacos.api.naming.pojo;
|
||||||
|
|
||||||
import com.alibaba.nacos.api.common.Constants;
|
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
@ -15,6 +15,8 @@
|
|||||||
*/
|
*/
|
||||||
package com.alibaba.nacos.api.naming.pojo;
|
package com.alibaba.nacos.api.naming.pojo;
|
||||||
|
|
||||||
|
import com.alibaba.nacos.api.selector.AbstractSelector;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
@ -39,15 +41,20 @@ public class Service {
|
|||||||
private String app;
|
private String app;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Service group is meant to classify services into different sets.
|
* Service group is meant to classify services into different sets
|
||||||
*/
|
*/
|
||||||
private String group;
|
private String group;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Health check mode.
|
* Health check mode
|
||||||
*/
|
*/
|
||||||
private String healthCheckMode;
|
private String healthCheckMode;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Selector name of this service
|
||||||
|
*/
|
||||||
|
private AbstractSelector selector;
|
||||||
|
|
||||||
private Map<String, String> metadata = new HashMap<String, String>();
|
private Map<String, String> metadata = new HashMap<String, String>();
|
||||||
|
|
||||||
public Service(String name) {
|
public Service(String name) {
|
||||||
@ -105,4 +112,12 @@ public class Service {
|
|||||||
public void addMetadata(String key, String value) {
|
public void addMetadata(String key, String value) {
|
||||||
this.metadata.put(key, value);
|
this.metadata.put(key, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public AbstractSelector getSelector() {
|
||||||
|
return selector;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSelector(AbstractSelector selector) {
|
||||||
|
this.selector = selector;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,37 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 1999-2018 Alibaba Group Holding Ltd.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package com.alibaba.nacos.api.selector;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Abstract selector that only contains a type
|
||||||
|
*
|
||||||
|
* @author <a href="mailto:zpf.073@gmail.com">nkorange</a>
|
||||||
|
*/
|
||||||
|
public abstract class AbstractSelector {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The type of this selector, each child class should announce its own unique type.
|
||||||
|
*/
|
||||||
|
private String type;
|
||||||
|
|
||||||
|
public String getType() {
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void setType(String type) {
|
||||||
|
this.type = type;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,41 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 1999-2018 Alibaba Group Holding Ltd.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package com.alibaba.nacos.api.selector;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The selector to filter resource with flexible expression.
|
||||||
|
*
|
||||||
|
* @author <a href="mailto:zpf.073@gmail.com">nkorange</a>
|
||||||
|
*/
|
||||||
|
public class ExpressionSelector extends AbstractSelector {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Label expression of this selector.
|
||||||
|
*/
|
||||||
|
private String expression;
|
||||||
|
|
||||||
|
public ExpressionSelector() {
|
||||||
|
this.setType(SelectorType.label.name());
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getExpression() {
|
||||||
|
return expression;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setExpression(String expression) {
|
||||||
|
this.expression = expression;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,36 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 1999-2018 Alibaba Group Holding Ltd.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package com.alibaba.nacos.api.selector;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The types of selector accepted by Nacos
|
||||||
|
*
|
||||||
|
* @author <a href="mailto:zpf.073@gmail.com">nkorange</a>
|
||||||
|
*/
|
||||||
|
public enum SelectorType {
|
||||||
|
/**
|
||||||
|
* not match any type
|
||||||
|
*/
|
||||||
|
unknown,
|
||||||
|
/**
|
||||||
|
* not filter out any entity
|
||||||
|
*/
|
||||||
|
none,
|
||||||
|
/**
|
||||||
|
* select by label
|
||||||
|
*/
|
||||||
|
label
|
||||||
|
}
|
@ -20,7 +20,7 @@ import com.alibaba.nacos.api.exception.NacosException;
|
|||||||
import com.alibaba.nacos.client.config.utils.IOUtils;
|
import com.alibaba.nacos.client.config.utils.IOUtils;
|
||||||
import com.alibaba.nacos.client.config.utils.MD5;
|
import com.alibaba.nacos.client.config.utils.MD5;
|
||||||
import com.alibaba.nacos.client.utils.ParamUtil;
|
import com.alibaba.nacos.client.utils.ParamUtil;
|
||||||
import com.alibaba.nacos.common.util.UuidUtil;
|
import com.alibaba.nacos.common.util.UuidUtils;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.UnsupportedEncodingException;
|
import java.io.UnsupportedEncodingException;
|
||||||
@ -36,6 +36,7 @@ import java.util.Map;
|
|||||||
* Http tool
|
* Http tool
|
||||||
*
|
*
|
||||||
* @author Nacos
|
* @author Nacos
|
||||||
|
*
|
||||||
*/
|
*/
|
||||||
public class HttpSimpleClient {
|
public class HttpSimpleClient {
|
||||||
|
|
||||||
|
@ -24,6 +24,7 @@ import com.alibaba.nacos.api.naming.pojo.Cluster;
|
|||||||
import com.alibaba.nacos.api.naming.pojo.Instance;
|
import com.alibaba.nacos.api.naming.pojo.Instance;
|
||||||
import com.alibaba.nacos.api.naming.pojo.ListView;
|
import com.alibaba.nacos.api.naming.pojo.ListView;
|
||||||
import com.alibaba.nacos.api.naming.pojo.ServiceInfo;
|
import com.alibaba.nacos.api.naming.pojo.ServiceInfo;
|
||||||
|
import com.alibaba.nacos.api.selector.AbstractSelector;
|
||||||
import com.alibaba.nacos.client.naming.beat.BeatInfo;
|
import com.alibaba.nacos.client.naming.beat.BeatInfo;
|
||||||
import com.alibaba.nacos.client.naming.beat.BeatReactor;
|
import com.alibaba.nacos.client.naming.beat.BeatReactor;
|
||||||
import com.alibaba.nacos.client.naming.core.Balancer;
|
import com.alibaba.nacos.client.naming.core.Balancer;
|
||||||
@ -263,6 +264,11 @@ public class NacosNamingService implements NamingService {
|
|||||||
return serverProxy.getServiceList(pageNo, pageSize);
|
return serverProxy.getServiceList(pageNo, pageSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ListView<String> getServicesOfServer(int pageNo, int pageSize, AbstractSelector selector) throws NacosException {
|
||||||
|
return serverProxy.getServiceList(pageNo, pageSize, selector);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<ServiceInfo> getSubscribeServices() {
|
public List<ServiceInfo> getSubscribeServices() {
|
||||||
return new ArrayList<ServiceInfo>(hostReactor.getServiceInfoMap().values());
|
return new ArrayList<ServiceInfo>(hostReactor.getServiceInfoMap().values());
|
||||||
|
@ -21,8 +21,11 @@ import com.alibaba.fastjson.TypeReference;
|
|||||||
import com.alibaba.nacos.api.exception.NacosException;
|
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.ListView;
|
import com.alibaba.nacos.api.naming.pojo.ListView;
|
||||||
|
import com.alibaba.nacos.api.selector.AbstractSelector;
|
||||||
|
import com.alibaba.nacos.api.selector.SelectorType;
|
||||||
|
import com.alibaba.nacos.api.selector.ExpressionSelector;
|
||||||
import com.alibaba.nacos.client.naming.utils.*;
|
import com.alibaba.nacos.client.naming.utils.*;
|
||||||
import com.alibaba.nacos.common.util.UuidUtil;
|
import com.alibaba.nacos.common.util.UuidUtils;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.StringReader;
|
import java.io.StringReader;
|
||||||
@ -93,9 +96,9 @@ public class NamingProxy {
|
|||||||
String urlString = "http://" + endpoint + "/nacos/serverlist";
|
String urlString = "http://" + endpoint + "/nacos/serverlist";
|
||||||
|
|
||||||
List<String> headers = Arrays.asList("Client-Version", UtilAndComs.VERSION,
|
List<String> headers = Arrays.asList("Client-Version", UtilAndComs.VERSION,
|
||||||
"Accept-Encoding", "gzip,deflate,sdch",
|
"Accept-Encoding", "gzip,deflate,sdch",
|
||||||
"Connection", "Keep-Alive",
|
"Connection", "Keep-Alive",
|
||||||
"RequestId", UuidUtil.generateUuid());
|
"RequestId", UuidUtils.generateUuid());
|
||||||
|
|
||||||
HttpClient.HttpResult result = HttpClient.httpGet(urlString, headers, null, UtilAndComs.ENCODING);
|
HttpClient.HttpResult result = HttpClient.httpGet(urlString, headers, null, UtilAndComs.ENCODING);
|
||||||
if (HttpURLConnection.HTTP_OK != result.code) {
|
if (HttpURLConnection.HTTP_OK != result.code) {
|
||||||
@ -193,11 +196,6 @@ public class NamingProxy {
|
|||||||
return reqAPI(UtilAndComs.NACOS_URL_BASE + "/instance/list", params, "GET");
|
return reqAPI(UtilAndComs.NACOS_URL_BASE + "/instance/list", params, "GET");
|
||||||
}
|
}
|
||||||
|
|
||||||
private String doRegDom(Map<String, String> params) throws Exception {
|
|
||||||
String api = UtilAndComs.NACOS_URL_BASE + "/api/regService";
|
|
||||||
return reqAPI(api, params);
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean serverHealthy() {
|
public boolean serverHealthy() {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@ -210,11 +208,28 @@ public class NamingProxy {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public ListView<String> getServiceList(int pageNo, int pageSize) throws NacosException {
|
public ListView<String> getServiceList(int pageNo, int pageSize) throws NacosException {
|
||||||
|
return getServiceList(pageNo, pageSize, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ListView<String> getServiceList(int pageNo, int pageSize, AbstractSelector selector) throws NacosException {
|
||||||
|
|
||||||
Map<String, String> params = new HashMap<String, String>(4);
|
Map<String, String> params = new HashMap<String, String>(4);
|
||||||
params.put("pageNo", String.valueOf(pageNo));
|
params.put("pageNo", String.valueOf(pageNo));
|
||||||
params.put("pageSize", String.valueOf(pageSize));
|
params.put("pageSize", String.valueOf(pageSize));
|
||||||
|
|
||||||
|
if (selector != null) {
|
||||||
|
switch (SelectorType.valueOf(selector.getType())) {
|
||||||
|
case none:
|
||||||
|
break;
|
||||||
|
case label:
|
||||||
|
ExpressionSelector expressionSelector = (ExpressionSelector) selector;
|
||||||
|
params.put("selector", JSON.toJSONString(expressionSelector));
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
String result = reqAPI(UtilAndComs.NACOS_URL_BASE + "/service/list", params);
|
String result = reqAPI(UtilAndComs.NACOS_URL_BASE + "/service/list", params);
|
||||||
|
|
||||||
JSONObject json = JSON.parseObject(result);
|
JSONObject json = JSON.parseObject(result);
|
||||||
@ -249,6 +264,7 @@ public class NamingProxy {
|
|||||||
|
|
||||||
public String reqAPI(String api, Map<String, String> params) throws NacosException {
|
public String reqAPI(String api, Map<String, String> params) throws NacosException {
|
||||||
|
|
||||||
|
|
||||||
List<String> snapshot = serversFromEndpoint;
|
List<String> snapshot = serversFromEndpoint;
|
||||||
if (!CollectionUtils.isEmpty(serverList)) {
|
if (!CollectionUtils.isEmpty(serverList)) {
|
||||||
snapshot = serverList;
|
snapshot = serverList;
|
||||||
|
@ -18,6 +18,8 @@ package com.alibaba.nacos.client;
|
|||||||
import com.alibaba.nacos.api.NacosFactory;
|
import com.alibaba.nacos.api.NacosFactory;
|
||||||
import com.alibaba.nacos.api.naming.NamingService;
|
import com.alibaba.nacos.api.naming.NamingService;
|
||||||
import com.alibaba.nacos.api.naming.pojo.Instance;
|
import com.alibaba.nacos.api.naming.pojo.Instance;
|
||||||
|
import com.alibaba.nacos.api.naming.pojo.ListView;
|
||||||
|
import com.alibaba.nacos.api.selector.ExpressionSelector;
|
||||||
import org.junit.Ignore;
|
import org.junit.Ignore;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
@ -46,6 +48,10 @@ public class NamingTest {
|
|||||||
|
|
||||||
namingService.registerInstance("dungu.test.1", instance);
|
namingService.registerInstance("dungu.test.1", instance);
|
||||||
|
|
||||||
|
ExpressionSelector expressionSelector = new ExpressionSelector();
|
||||||
|
expressionSelector.setExpression("INSTANCE.metadata.registerSource = 'dubbo'");
|
||||||
|
ListView<String> serviceList = namingService.getServicesOfServer(1, 10, expressionSelector);
|
||||||
|
|
||||||
Thread.sleep(1000000000L);
|
Thread.sleep(1000000000L);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
106
cmdb/pom.xml
Normal file
106
cmdb/pom.xml
Normal file
@ -0,0 +1,106 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!--
|
||||||
|
Copyright 1999-2018 Alibaba Group Holding Ltd.
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
-->
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
|
||||||
|
<parent>
|
||||||
|
<artifactId>nacos-all</artifactId>
|
||||||
|
<groupId>com.alibaba.nacos</groupId>
|
||||||
|
<version>0.5.0-cmdb-SNAPSHOT</version>
|
||||||
|
<relativePath>../pom.xml</relativePath>
|
||||||
|
</parent>
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
<artifactId>nacos-cmdb</artifactId>
|
||||||
|
<packaging>jar</packaging>
|
||||||
|
|
||||||
|
<name>nacos-cmdb ${project.version}</name>
|
||||||
|
<!-- FIXME change it to the project's website -->
|
||||||
|
<url>http://www.example.com</url>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
|
<maven.compiler.source>1.7</maven.compiler.source>
|
||||||
|
<maven.compiler.target>1.7</maven.compiler.target>
|
||||||
|
</properties>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>junit</groupId>
|
||||||
|
<artifactId>junit</artifactId>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>${project.groupId}</groupId>
|
||||||
|
<artifactId>nacos-common</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>${project.groupId}</groupId>
|
||||||
|
<artifactId>nacos-api</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-web</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-test</artifactId>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-surefire-plugin</artifactId>
|
||||||
|
<configuration>
|
||||||
|
<skipTests>true</skipTests>
|
||||||
|
<argLine>-Dnacos.standalone=true</argLine>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-assembly-plugin</artifactId>
|
||||||
|
<configuration>
|
||||||
|
<archive>
|
||||||
|
<manifest>
|
||||||
|
<mainClass>com.alibaba.nacos.cmdb.CmdbApp</mainClass>
|
||||||
|
</manifest>
|
||||||
|
</archive>
|
||||||
|
<descriptorRefs>
|
||||||
|
<descriptorRef>jar-with-dependencies</descriptorRef>
|
||||||
|
</descriptorRefs>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
<resources>
|
||||||
|
<resource>
|
||||||
|
<directory>src/main/resources</directory>
|
||||||
|
<excludes>
|
||||||
|
<exclude>application.properties</exclude>
|
||||||
|
</excludes>
|
||||||
|
</resource>
|
||||||
|
</resources>
|
||||||
|
</build>
|
||||||
|
</project>
|
30
cmdb/src/main/java/com/alibaba/nacos/cmdb/CmdbApp.java
Normal file
30
cmdb/src/main/java/com/alibaba/nacos/cmdb/CmdbApp.java
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 1999-2018 Alibaba Group Holding Ltd.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package com.alibaba.nacos.cmdb;
|
||||||
|
|
||||||
|
import org.springframework.boot.SpringApplication;
|
||||||
|
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author <a href="mailto:zpf.073@gmail.com">nkorange</a>
|
||||||
|
*/
|
||||||
|
@SpringBootApplication
|
||||||
|
public class CmdbApp {
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
SpringApplication.run(CmdbApp.class, args);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,70 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 1999-2018 Alibaba Group Holding Ltd.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package com.alibaba.nacos.cmdb.controllers;
|
||||||
|
|
||||||
|
import com.alibaba.nacos.cmdb.core.SwitchAndOptions;
|
||||||
|
import com.alibaba.nacos.cmdb.memory.CmdbProvider;
|
||||||
|
import com.alibaba.nacos.cmdb.utils.UtilsAndCommons;
|
||||||
|
import com.alibaba.nacos.common.util.WebUtils;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMethod;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author <a href="mailto:zpf.073@gmail.com">nkorange</a>
|
||||||
|
*/
|
||||||
|
@RestController
|
||||||
|
@RequestMapping(UtilsAndCommons.NACOS_CMDB_CONTEXT + "/ops")
|
||||||
|
public class OperationController {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private SwitchAndOptions switches;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private CmdbProvider cmdbProvider;
|
||||||
|
|
||||||
|
@RequestMapping(value = "/updateSwitch", method = RequestMethod.POST)
|
||||||
|
public String updateSwitch(HttpServletRequest request) throws Exception {
|
||||||
|
|
||||||
|
String entry = WebUtils.required(request, "entry");
|
||||||
|
String value = WebUtils.required(request, "value");
|
||||||
|
|
||||||
|
switch (entry) {
|
||||||
|
case "dumpTaskInterval":
|
||||||
|
switches.setDumpTaskInterval(Integer.parseInt(value));
|
||||||
|
break;
|
||||||
|
case "eventTaskInterval":
|
||||||
|
switches.setEventTaskInterval(Integer.parseInt(value));
|
||||||
|
break;
|
||||||
|
case "loadDataAtStart":
|
||||||
|
switches.setLoadDataAtStart(Boolean.parseBoolean(value));
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return "ok";
|
||||||
|
}
|
||||||
|
|
||||||
|
@RequestMapping(value = "/queryLabel", method = RequestMethod.GET)
|
||||||
|
public String queryLabel(HttpServletRequest request) throws Exception {
|
||||||
|
String entry = WebUtils.required(request, "entry");
|
||||||
|
String label = WebUtils.required(request, "label");
|
||||||
|
return cmdbProvider.queryLabel(entry, "ip", label);
|
||||||
|
}
|
||||||
|
}
|
@ -13,10 +13,10 @@
|
|||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package com.alibaba.nacos.naming.controllers;
|
package com.alibaba.nacos.cmdb.core;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author <a href="mailto:zpf.073@gmail.com">nkorange</a>
|
* @author <a href="mailto:zpf.073@gmail.com">nkorange</a>
|
||||||
*/
|
*/
|
||||||
public class CmdbController {
|
public class CmdbManager {
|
||||||
}
|
}
|
@ -0,0 +1,59 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 1999-2018 Alibaba Group Holding Ltd.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package com.alibaba.nacos.cmdb.core;
|
||||||
|
|
||||||
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author <a href="mailto:zpf.073@gmail.com">nkorange</a>
|
||||||
|
*/
|
||||||
|
@Component
|
||||||
|
public class SwitchAndOptions {
|
||||||
|
|
||||||
|
@Value("${nacos.cmdb.dumpTaskInterval}")
|
||||||
|
private int dumpTaskInterval;
|
||||||
|
|
||||||
|
@Value("${nacos.cmdb.eventTaskInterval}")
|
||||||
|
private int eventTaskInterval;
|
||||||
|
|
||||||
|
@Value("${nacos.cmdb.loadDataAtStart}")
|
||||||
|
private boolean loadDataAtStart;
|
||||||
|
|
||||||
|
public int getDumpTaskInterval() {
|
||||||
|
return dumpTaskInterval;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDumpTaskInterval(int dumpTaskInterval) {
|
||||||
|
this.dumpTaskInterval = dumpTaskInterval;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getEventTaskInterval() {
|
||||||
|
return eventTaskInterval;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setEventTaskInterval(int eventTaskInterval) {
|
||||||
|
this.eventTaskInterval = eventTaskInterval;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isLoadDataAtStart() {
|
||||||
|
return loadDataAtStart;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLoadDataAtStart(boolean loadDataAtStart) {
|
||||||
|
this.loadDataAtStart = loadDataAtStart;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,192 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 1999-2018 Alibaba Group Holding Ltd.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package com.alibaba.nacos.cmdb.memory;
|
||||||
|
|
||||||
|
import com.alibaba.nacos.api.cmdb.spi.CmdbService;
|
||||||
|
import com.alibaba.nacos.api.cmdb.pojo.Entity;
|
||||||
|
import com.alibaba.nacos.api.cmdb.pojo.EntityEvent;
|
||||||
|
import com.alibaba.nacos.api.cmdb.pojo.Label;
|
||||||
|
import com.alibaba.nacos.api.exception.NacosException;
|
||||||
|
import com.alibaba.nacos.cmdb.core.SwitchAndOptions;
|
||||||
|
import com.alibaba.nacos.cmdb.service.CmdbReader;
|
||||||
|
import com.alibaba.nacos.cmdb.service.CmdbWriter;
|
||||||
|
import com.alibaba.nacos.cmdb.utils.Loggers;
|
||||||
|
import com.alibaba.nacos.cmdb.utils.UtilsAndCommons;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import javax.annotation.PostConstruct;
|
||||||
|
import java.util.*;
|
||||||
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author <a href="mailto:zpf.073@gmail.com">nkorange</a>
|
||||||
|
*/
|
||||||
|
@Component
|
||||||
|
public class CmdbProvider implements CmdbReader, CmdbWriter {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private SwitchAndOptions switches;
|
||||||
|
|
||||||
|
private CmdbService cmdbService;
|
||||||
|
|
||||||
|
ServiceLoader<CmdbService> serviceLoader = ServiceLoader.load(CmdbService.class);
|
||||||
|
|
||||||
|
private Map<String, Map<String, Entity>> entityMap = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
|
private Map<String, Label> labelMap = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
|
private Set<String> entityTypeSet = new HashSet<>();
|
||||||
|
|
||||||
|
private List<EntityEvent> eventList = new ArrayList<>();
|
||||||
|
|
||||||
|
private long eventTimestamp = System.currentTimeMillis();
|
||||||
|
|
||||||
|
public CmdbProvider() throws NacosException {
|
||||||
|
}
|
||||||
|
|
||||||
|
private void initCmdbService() throws NacosException {
|
||||||
|
Iterator<CmdbService> iterator = serviceLoader.iterator();
|
||||||
|
if (iterator.hasNext()) {
|
||||||
|
cmdbService = iterator.next();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cmdbService == null && switches.isLoadDataAtStart()) {
|
||||||
|
throw new NacosException(NacosException.SERVER_ERROR, "Cannot initialize CmdbService!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void load() {
|
||||||
|
|
||||||
|
if (!switches.isLoadDataAtStart()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO load data on disk:
|
||||||
|
|
||||||
|
// init label map:
|
||||||
|
Set<String> labelNames = cmdbService.getLabelNames();
|
||||||
|
if (labelNames == null || labelNames.isEmpty()) {
|
||||||
|
Loggers.MAIN.warn("[LOAD] init label names failed!");
|
||||||
|
} else {
|
||||||
|
for (String labelName : labelNames) {
|
||||||
|
// If get null label, it's still ok. We will try it later when we meet this label:
|
||||||
|
labelMap.put(labelName, cmdbService.getLabel(labelName));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// init entity type set:
|
||||||
|
entityTypeSet = cmdbService.getEntityTypes();
|
||||||
|
|
||||||
|
// init entity map:
|
||||||
|
entityMap = cmdbService.getAllEntities();
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostConstruct
|
||||||
|
public void init() throws NacosException {
|
||||||
|
|
||||||
|
initCmdbService();
|
||||||
|
load();
|
||||||
|
|
||||||
|
UtilsAndCommons.GLOBAL_EXECUTOR.schedule(new CmdbDumpTask(), switches.getDumpTaskInterval(), TimeUnit.SECONDS);
|
||||||
|
UtilsAndCommons.GLOBAL_EXECUTOR.schedule(new CmdbEventTask(), switches.getEventTaskInterval(), TimeUnit.SECONDS);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Entity queryEntity(String entityName, String entityType) {
|
||||||
|
if (!entityMap.containsKey(entityType)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return entityMap.get(entityType).get(entityName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String queryLabel(String entityName, String entityType, String labelName) {
|
||||||
|
Entity entity = queryEntity(entityName, entityType);
|
||||||
|
if (entity == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return entity.getLabels().get(labelName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<Entity> queryEntitiesByLabel(String labelName, String labelValue) {
|
||||||
|
throw new UnsupportedOperationException("Not available now!");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void removeEntity(String entityName, String entityType) {
|
||||||
|
if (!entityMap.containsKey(entityType)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
entityMap.get(entityType).remove(entityName);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void updateEntity(Entity entity) {
|
||||||
|
if (!entityTypeSet.contains(entity.getType())) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
entityMap.get(entity.getType()).put(entity.getName(), entity);
|
||||||
|
}
|
||||||
|
|
||||||
|
public class CmdbDumpTask implements Runnable {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
try {
|
||||||
|
// refresh entity map:
|
||||||
|
entityMap = cmdbService.getAllEntities();
|
||||||
|
} catch (Exception e) {
|
||||||
|
Loggers.MAIN.error("CMDB-DUMP {}", "dump failed!", e);
|
||||||
|
} finally {
|
||||||
|
UtilsAndCommons.GLOBAL_EXECUTOR.schedule(this, switches.getDumpTaskInterval(), TimeUnit.SECONDS);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class CmdbEventTask implements Runnable {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
try {
|
||||||
|
long current = System.currentTimeMillis();
|
||||||
|
List<EntityEvent> events = cmdbService.getEntityEvents(eventTimestamp);
|
||||||
|
eventTimestamp = current;
|
||||||
|
|
||||||
|
if (events != null && !events.isEmpty()) {
|
||||||
|
|
||||||
|
for (EntityEvent event : events) {
|
||||||
|
switch (event.getType()) {
|
||||||
|
case ENTITY_REMOVE:
|
||||||
|
removeEntity(event.getEntityName(), event.getEntityType());
|
||||||
|
break;
|
||||||
|
case ENTITY_ADD_OR_UPDATE:
|
||||||
|
updateEntity(cmdbService.getEntity(event.getEntityName(), event.getEntityType()));
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
Loggers.MAIN.error("CMDB-EVENT {}", "event task failed!", e);
|
||||||
|
} finally {
|
||||||
|
UtilsAndCommons.GLOBAL_EXECUTOR.schedule(this, switches.getEventTaskInterval(), TimeUnit.SECONDS);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,55 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 1999-2018 Alibaba Group Holding Ltd.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package com.alibaba.nacos.cmdb.service;
|
||||||
|
|
||||||
|
|
||||||
|
import com.alibaba.nacos.api.cmdb.pojo.Entity;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author <a href="mailto:zpf.073@gmail.com">nkorange</a>
|
||||||
|
*/
|
||||||
|
public interface CmdbReader {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get entity
|
||||||
|
*
|
||||||
|
* @param entityName name of entity
|
||||||
|
* @param entityType type of entity
|
||||||
|
* @return entity
|
||||||
|
*/
|
||||||
|
Entity queryEntity(String entityName, String entityType);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get label of entity
|
||||||
|
*
|
||||||
|
* @param entityName name of entity
|
||||||
|
* @param entityType type of entity
|
||||||
|
* @param labelName label name
|
||||||
|
* @return label value
|
||||||
|
*/
|
||||||
|
String queryLabel(String entityName, String entityType, String labelName);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get entities of selected label
|
||||||
|
*
|
||||||
|
* @param labelName name of label
|
||||||
|
* @param labelValue value of label
|
||||||
|
* @return list of entiy
|
||||||
|
*/
|
||||||
|
List<Entity> queryEntitiesByLabel(String labelName, String labelValue);
|
||||||
|
}
|
@ -0,0 +1,22 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 1999-2018 Alibaba Group Holding Ltd.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package com.alibaba.nacos.cmdb.service;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author <a href="mailto:zpf.073@gmail.com">nkorange</a>
|
||||||
|
*/
|
||||||
|
public interface CmdbWriter {
|
||||||
|
}
|
27
cmdb/src/main/java/com/alibaba/nacos/cmdb/utils/Loggers.java
Normal file
27
cmdb/src/main/java/com/alibaba/nacos/cmdb/utils/Loggers.java
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 1999-2018 Alibaba Group Holding Ltd.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package com.alibaba.nacos.cmdb.utils;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author nacos
|
||||||
|
*/
|
||||||
|
public class Loggers {
|
||||||
|
|
||||||
|
public static final Logger MAIN = LoggerFactory.getLogger("com.alibaba.nacos.cmdb.main");
|
||||||
|
}
|
@ -0,0 +1,46 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 1999-2018 Alibaba Group Holding Ltd.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package com.alibaba.nacos.cmdb.utils;
|
||||||
|
|
||||||
|
import java.util.concurrent.ScheduledExecutorService;
|
||||||
|
import java.util.concurrent.ScheduledThreadPoolExecutor;
|
||||||
|
import java.util.concurrent.ThreadFactory;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author <a href="mailto:zpf.073@gmail.com">nkorange</a>
|
||||||
|
*/
|
||||||
|
public class UtilsAndCommons {
|
||||||
|
|
||||||
|
public static final String NACOS_SERVER_VERSION = "/v1";
|
||||||
|
|
||||||
|
public static final String NACOS_CMDB_CONTEXT = NACOS_SERVER_VERSION + "/cmdb";
|
||||||
|
|
||||||
|
public static final ScheduledExecutorService GLOBAL_EXECUTOR;
|
||||||
|
|
||||||
|
static {
|
||||||
|
|
||||||
|
GLOBAL_EXECUTOR
|
||||||
|
= new ScheduledThreadPoolExecutor(Runtime.getRuntime().availableProcessors(), new ThreadFactory() {
|
||||||
|
@Override
|
||||||
|
public Thread newThread(Runnable r) {
|
||||||
|
Thread t = new Thread(r);
|
||||||
|
t.setName("nacos.cmdb.global.executor");
|
||||||
|
t.setDaemon(true);
|
||||||
|
return t;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
6
cmdb/src/main/resources/application.properties
Normal file
6
cmdb/src/main/resources/application.properties
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
server.port=8848
|
||||||
|
server.servlet.context-path=/nacos
|
||||||
|
|
||||||
|
nacos.cmdb.dumpTaskInterval=3600
|
||||||
|
nacos.cmdb.eventTaskInterval=10
|
||||||
|
nacos.cmdb.loadDataAtStart=true
|
@ -35,6 +35,12 @@
|
|||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>javax.servlet</groupId>
|
||||||
|
<artifactId>servlet-api</artifactId>
|
||||||
|
<scope>provided</scope>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.slf4j</groupId>
|
<groupId>org.slf4j</groupId>
|
||||||
<artifactId>slf4j-api</artifactId>
|
<artifactId>slf4j-api</artifactId>
|
||||||
|
@ -20,7 +20,7 @@ import java.util.UUID;
|
|||||||
/**
|
/**
|
||||||
* @author <a href="mailto:zpf.073@gmail.com">nkorange</a>
|
* @author <a href="mailto:zpf.073@gmail.com">nkorange</a>
|
||||||
*/
|
*/
|
||||||
public class UuidUtil {
|
public class UuidUtils {
|
||||||
|
|
||||||
public static String generateUuid() {
|
public static String generateUuid() {
|
||||||
return UUID.randomUUID().toString();
|
return UUID.randomUUID().toString();
|
@ -13,8 +13,7 @@
|
|||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package com.alibaba.nacos.naming.web;
|
package com.alibaba.nacos.common.util;
|
||||||
|
|
||||||
|
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
|
||||||
@ -22,9 +21,9 @@ import javax.servlet.http.HttpServletRequest;
|
|||||||
import java.io.UnsupportedEncodingException;
|
import java.io.UnsupportedEncodingException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author nacos
|
* @author <a href="mailto:zpf.073@gmail.com">nkorange</a>
|
||||||
*/
|
*/
|
||||||
public class BaseServlet {
|
public class WebUtils {
|
||||||
|
|
||||||
public static String required(HttpServletRequest req, String key) {
|
public static String required(HttpServletRequest req, String key) {
|
||||||
String value = req.getParameter(key);
|
String value = req.getParameter(key);
|
||||||
@ -67,5 +66,4 @@ public class BaseServlet {
|
|||||||
encode = encode.contains(",") ? encode.substring(0, encode.indexOf(",")) : encode;
|
encode = encode.contains(",") ? encode.substring(0, encode.indexOf(",")) : encode;
|
||||||
return encode.contains(";") ? encode.substring(0, encode.indexOf(";")) : encode;
|
return encode.contains(";") ? encode.substring(0, encode.indexOf(";")) : encode;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -63,6 +63,7 @@ else
|
|||||||
JAVA_OPT="${JAVA_OPT} -Xloggc:${BASE_DIR}/logs/nacos_gc.log -verbose:gc -XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+PrintGCTimeStamps -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=10 -XX:GCLogFileSize=100M"
|
JAVA_OPT="${JAVA_OPT} -Xloggc:${BASE_DIR}/logs/nacos_gc.log -verbose:gc -XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+PrintGCTimeStamps -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=10 -XX:GCLogFileSize=100M"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
JAVA_OPT="${JAVA_OPT} -Djava.ext.dirs=${BASE_DIR}/plugins/cmdb"
|
||||||
JAVA_OPT="${JAVA_OPT} -Dnacos.home=${BASE_DIR}"
|
JAVA_OPT="${JAVA_OPT} -Dnacos.home=${BASE_DIR}"
|
||||||
JAVA_OPT="${JAVA_OPT} -jar ${BASE_DIR}/target/nacos-server.jar"
|
JAVA_OPT="${JAVA_OPT} -jar ${BASE_DIR}/target/nacos-server.jar"
|
||||||
JAVA_OPT="${JAVA_OPT} ${JAVA_OPT_EXT}"
|
JAVA_OPT="${JAVA_OPT} ${JAVA_OPT_EXT}"
|
||||||
|
@ -4,7 +4,9 @@ server.contextPath=/nacos
|
|||||||
server.servlet.contextPath=/nacos
|
server.servlet.contextPath=/nacos
|
||||||
server.port=8848
|
server.port=8848
|
||||||
|
|
||||||
#spring.datasource.platform=mysql
|
nacos.cmdb.dumpTaskInterval=3600
|
||||||
|
nacos.cmdb.eventTaskInterval=10
|
||||||
|
nacos.cmdb.loadDataAtStart=true
|
||||||
|
|
||||||
#db.num=2
|
#db.num=2
|
||||||
#db.url.0=jdbc:mysql://11.162.196.16:3306/nacos_devtest?characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true
|
#db.url.0=jdbc:mysql://11.162.196.16:3306/nacos_devtest?characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true
|
||||||
|
@ -4,6 +4,23 @@
|
|||||||
<springProperty scope="context" name="logPath" source="nacos.logs.path" defaultValue="${nacos.home}/logs"/>
|
<springProperty scope="context" name="logPath" source="nacos.logs.path" defaultValue="${nacos.home}/logs"/>
|
||||||
<property name="LOG_HOME" value="${logPath}"/>
|
<property name="LOG_HOME" value="${logPath}"/>
|
||||||
|
|
||||||
|
<appender name="cmdb-main"
|
||||||
|
class="ch.qos.logback.core.rolling.RollingFileAppender">
|
||||||
|
<file>${nacos.home}/logs/cmdb-main.log</file>
|
||||||
|
<append>true</append>
|
||||||
|
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
|
||||||
|
<fileNamePattern>${nacos.home}/logs/cmdb-main.log.%d{yyyy-MM-dd}.%i</fileNamePattern>
|
||||||
|
<maxFileSize>2GB</maxFileSize>
|
||||||
|
<MaxHistory>15</MaxHistory>
|
||||||
|
<totalSizeCap>7GB</totalSizeCap>
|
||||||
|
<cleanHistoryOnStart>true</cleanHistoryOnStart>
|
||||||
|
</rollingPolicy>
|
||||||
|
<encoder>
|
||||||
|
<Pattern>%date %level %msg%n%n</Pattern>
|
||||||
|
<charset>UTF-8</charset>
|
||||||
|
</encoder>
|
||||||
|
</appender>
|
||||||
|
|
||||||
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
|
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
|
||||||
<encoder>
|
<encoder>
|
||||||
<Pattern>%date %level %msg%n%n</Pattern>
|
<Pattern>%date %level %msg%n%n</Pattern>
|
||||||
@ -454,6 +471,11 @@
|
|||||||
</encoder>
|
</encoder>
|
||||||
</appender>
|
</appender>
|
||||||
|
|
||||||
|
<logger name="com.alibaba.nacos.cmdb.main" additivity="false">
|
||||||
|
<level value="INFO"/>
|
||||||
|
<appender-ref ref="cmdb-main"/>
|
||||||
|
</logger>
|
||||||
|
|
||||||
<logger name="com.alibaba.nacos.naming.main" additivity="false">
|
<logger name="com.alibaba.nacos.naming.main" additivity="false">
|
||||||
<level value="INFO"/>
|
<level value="INFO"/>
|
||||||
<appender-ref ref="async-naming-server"/>
|
<appender-ref ref="async-naming-server"/>
|
||||||
|
BIN
distribution/plugins/cmdb/nacos-cmdb-plugin-example.jar
Normal file
BIN
distribution/plugins/cmdb/nacos-cmdb-plugin-example.jar
Normal file
Binary file not shown.
@ -154,6 +154,10 @@
|
|||||||
<groupId>com.github.spotbugs</groupId>
|
<groupId>com.github.spotbugs</groupId>
|
||||||
<artifactId>spotbugs-annotations</artifactId>
|
<artifactId>spotbugs-annotations</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.alibaba.nacos</groupId>
|
||||||
|
<artifactId>nacos-cmdb</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
|
@ -15,11 +15,11 @@
|
|||||||
*/
|
*/
|
||||||
package com.alibaba.nacos.naming.acl;
|
package com.alibaba.nacos.naming.acl;
|
||||||
|
|
||||||
|
import com.alibaba.nacos.common.util.WebUtils;
|
||||||
import com.alibaba.nacos.naming.core.Domain;
|
import com.alibaba.nacos.naming.core.Domain;
|
||||||
import com.alibaba.nacos.naming.core.DomainsManager;
|
import com.alibaba.nacos.naming.core.DomainsManager;
|
||||||
import com.alibaba.nacos.naming.misc.Switch;
|
import com.alibaba.nacos.naming.misc.Switch;
|
||||||
import com.alibaba.nacos.naming.misc.UtilsAndCommons;
|
import com.alibaba.nacos.naming.misc.UtilsAndCommons;
|
||||||
import com.alibaba.nacos.naming.web.BaseServlet;
|
|
||||||
import org.apache.commons.lang3.ArrayUtils;
|
import org.apache.commons.lang3.ArrayUtils;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
@ -56,13 +56,13 @@ public class AuthChecker {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void doAuth(Map<String, String[]> params, HttpServletRequest req) throws Exception {
|
public void doAuth(Map<String, String[]> params, HttpServletRequest req) throws Exception {
|
||||||
String dom = BaseServlet.optional(req, "name", "");
|
String dom = WebUtils.optional(req, "name", "");
|
||||||
if (StringUtils.isEmpty(dom)) {
|
if (StringUtils.isEmpty(dom)) {
|
||||||
dom = BaseServlet.optional(req, "dom", "");
|
dom = WebUtils.optional(req, "dom", "");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (StringUtils.isEmpty(dom)) {
|
if (StringUtils.isEmpty(dom)) {
|
||||||
dom = BaseServlet.optional(req, "tag", "");
|
dom = WebUtils.optional(req, "tag", "");
|
||||||
}
|
}
|
||||||
|
|
||||||
Domain domObj;
|
Domain domObj;
|
||||||
@ -101,7 +101,7 @@ public class AuthChecker {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// if token failed, try AuthInfo
|
// if token failed, try AuthInfo
|
||||||
AuthInfo authInfo = AuthInfo.fromString(auth, BaseServlet.getAcceptEncoding(req));
|
AuthInfo authInfo = AuthInfo.fromString(auth, WebUtils.getAcceptEncoding(req));
|
||||||
if (authInfo == null) {
|
if (authInfo == null) {
|
||||||
throw new IllegalAccessException("invalid token or malformed auth info");
|
throw new IllegalAccessException("invalid token or malformed auth info");
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,41 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 1999-2018 Alibaba Group Holding Ltd.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package com.alibaba.nacos.naming.boot;
|
||||||
|
|
||||||
|
import org.springframework.beans.BeansException;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.context.ApplicationContext;
|
||||||
|
import org.springframework.context.ApplicationContextAware;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author <a href="mailto:zpf.073@gmail.com">nkorange</a>
|
||||||
|
*/
|
||||||
|
@Component
|
||||||
|
public class SpringContext implements ApplicationContextAware {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
static ApplicationContext context;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
|
||||||
|
context = applicationContext;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ApplicationContext getAppContext() {
|
||||||
|
return context;
|
||||||
|
}
|
||||||
|
}
|
@ -20,6 +20,8 @@ import com.alibaba.fastjson.JSONObject;
|
|||||||
import com.alibaba.nacos.api.naming.pojo.Cluster;
|
import com.alibaba.nacos.api.naming.pojo.Cluster;
|
||||||
import com.alibaba.nacos.api.naming.pojo.Instance;
|
import com.alibaba.nacos.api.naming.pojo.Instance;
|
||||||
import com.alibaba.nacos.api.naming.pojo.Service;
|
import com.alibaba.nacos.api.naming.pojo.Service;
|
||||||
|
import com.alibaba.nacos.api.selector.SelectorType;
|
||||||
|
import com.alibaba.nacos.common.util.WebUtils;
|
||||||
import com.alibaba.nacos.naming.core.Domain;
|
import com.alibaba.nacos.naming.core.Domain;
|
||||||
import com.alibaba.nacos.naming.core.DomainsManager;
|
import com.alibaba.nacos.naming.core.DomainsManager;
|
||||||
import com.alibaba.nacos.naming.core.IpAddress;
|
import com.alibaba.nacos.naming.core.IpAddress;
|
||||||
@ -30,9 +32,10 @@ import com.alibaba.nacos.naming.misc.UtilsAndCommons;
|
|||||||
import com.alibaba.nacos.naming.pojo.ClusterInfo;
|
import com.alibaba.nacos.naming.pojo.ClusterInfo;
|
||||||
import com.alibaba.nacos.naming.pojo.IpAddressInfo;
|
import com.alibaba.nacos.naming.pojo.IpAddressInfo;
|
||||||
import com.alibaba.nacos.naming.pojo.ServiceDetailInfo;
|
import com.alibaba.nacos.naming.pojo.ServiceDetailInfo;
|
||||||
|
import com.alibaba.nacos.naming.selector.LabelSelector;
|
||||||
|
import com.alibaba.nacos.naming.selector.NoneSelector;
|
||||||
import com.alibaba.nacos.naming.view.ServiceDetailView;
|
import com.alibaba.nacos.naming.view.ServiceDetailView;
|
||||||
import com.alibaba.nacos.naming.view.ServiceView;
|
import com.alibaba.nacos.naming.view.ServiceView;
|
||||||
import com.alibaba.nacos.naming.web.BaseServlet;
|
|
||||||
import org.apache.commons.collections.CollectionUtils;
|
import org.apache.commons.collections.CollectionUtils;
|
||||||
import org.apache.commons.collections.map.HashedMap;
|
import org.apache.commons.collections.map.HashedMap;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
@ -63,9 +66,9 @@ public class CatalogController {
|
|||||||
|
|
||||||
JSONObject result = new JSONObject();
|
JSONObject result = new JSONObject();
|
||||||
|
|
||||||
int page = Integer.parseInt(BaseServlet.required(request, "startPg"));
|
int page = Integer.parseInt(WebUtils.required(request, "startPg"));
|
||||||
int pageSize = Integer.parseInt(BaseServlet.required(request, "pgSize"));
|
int pageSize = Integer.parseInt(WebUtils.required(request, "pgSize"));
|
||||||
String keyword = BaseServlet.optional(request, "keyword", StringUtils.EMPTY);
|
String keyword = WebUtils.optional(request, "keyword", StringUtils.EMPTY);
|
||||||
|
|
||||||
List<Domain> doms = new ArrayList<>();
|
List<Domain> doms = new ArrayList<>();
|
||||||
int total = domainsManager.getPagedDom(page - 1, pageSize, keyword, doms);
|
int total = domainsManager.getPagedDom(page - 1, pageSize, keyword, doms);
|
||||||
@ -106,7 +109,7 @@ public class CatalogController {
|
|||||||
@RequestMapping(value = "/serviceDetail")
|
@RequestMapping(value = "/serviceDetail")
|
||||||
public ServiceDetailView serviceDetail(HttpServletRequest request) throws Exception {
|
public ServiceDetailView serviceDetail(HttpServletRequest request) throws Exception {
|
||||||
|
|
||||||
String serviceName = BaseServlet.required(request, "serviceName");
|
String serviceName = WebUtils.required(request, "serviceName");
|
||||||
VirtualClusterDomain domain = (VirtualClusterDomain) domainsManager.getDomain(serviceName);
|
VirtualClusterDomain domain = (VirtualClusterDomain) domainsManager.getDomain(serviceName);
|
||||||
if (domain == null) {
|
if (domain == null) {
|
||||||
throw new NacosException(NacosException.NOT_FOUND, "serivce " + serviceName + " is not found!");
|
throw new NacosException(NacosException.NOT_FOUND, "serivce " + serviceName + " is not found!");
|
||||||
@ -125,6 +128,18 @@ public class CatalogController {
|
|||||||
service.setHealthCheckMode(HealthCheckMode.client.name());
|
service.setHealthCheckMode(HealthCheckMode.client.name());
|
||||||
}
|
}
|
||||||
service.setMetadata(domain.getMetadata());
|
service.setMetadata(domain.getMetadata());
|
||||||
|
|
||||||
|
switch (SelectorType.valueOf(domain.getSelector().getType())) {
|
||||||
|
case label:
|
||||||
|
service.setSelector((LabelSelector) domain.getSelector());
|
||||||
|
break;
|
||||||
|
case none:
|
||||||
|
case unknown:
|
||||||
|
default:
|
||||||
|
service.setSelector((NoneSelector) domain.getSelector());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
detailView.setService(service);
|
detailView.setService(service);
|
||||||
|
|
||||||
List<Cluster> clusters = new ArrayList<>();
|
List<Cluster> clusters = new ArrayList<>();
|
||||||
@ -149,10 +164,10 @@ public class CatalogController {
|
|||||||
@RequestMapping(value = "/instanceList")
|
@RequestMapping(value = "/instanceList")
|
||||||
public JSONObject instanceList(HttpServletRequest request) throws Exception {
|
public JSONObject instanceList(HttpServletRequest request) throws Exception {
|
||||||
|
|
||||||
String serviceName = BaseServlet.required(request, "serviceName");
|
String serviceName = WebUtils.required(request, "serviceName");
|
||||||
String clusterName = BaseServlet.required(request, "clusterName");
|
String clusterName = WebUtils.required(request, "clusterName");
|
||||||
int page = Integer.parseInt(BaseServlet.required(request, "startPg"));
|
int page = Integer.parseInt(WebUtils.required(request, "startPg"));
|
||||||
int pageSize = Integer.parseInt(BaseServlet.required(request, "pgSize"));
|
int pageSize = Integer.parseInt(WebUtils.required(request, "pgSize"));
|
||||||
|
|
||||||
VirtualClusterDomain domain = (VirtualClusterDomain) domainsManager.getDomain(serviceName);
|
VirtualClusterDomain domain = (VirtualClusterDomain) domainsManager.getDomain(serviceName);
|
||||||
if (domain == null) {
|
if (domain == null) {
|
||||||
|
@ -18,13 +18,13 @@ package com.alibaba.nacos.naming.controllers;
|
|||||||
import com.alibaba.fastjson.JSON;
|
import com.alibaba.fastjson.JSON;
|
||||||
import com.alibaba.fastjson.JSONObject;
|
import com.alibaba.fastjson.JSONObject;
|
||||||
import com.alibaba.nacos.api.naming.pojo.AbstractHealthChecker;
|
import com.alibaba.nacos.api.naming.pojo.AbstractHealthChecker;
|
||||||
|
import com.alibaba.nacos.common.util.WebUtils;
|
||||||
import com.alibaba.nacos.naming.core.Cluster;
|
import com.alibaba.nacos.naming.core.Cluster;
|
||||||
import com.alibaba.nacos.naming.core.DomainsManager;
|
import com.alibaba.nacos.naming.core.DomainsManager;
|
||||||
import com.alibaba.nacos.naming.core.VirtualClusterDomain;
|
import com.alibaba.nacos.naming.core.VirtualClusterDomain;
|
||||||
import com.alibaba.nacos.naming.exception.NacosException;
|
import com.alibaba.nacos.naming.exception.NacosException;
|
||||||
import com.alibaba.nacos.naming.misc.Loggers;
|
import com.alibaba.nacos.naming.misc.Loggers;
|
||||||
import com.alibaba.nacos.naming.misc.UtilsAndCommons;
|
import com.alibaba.nacos.naming.misc.UtilsAndCommons;
|
||||||
import com.alibaba.nacos.naming.web.BaseServlet;
|
|
||||||
import org.apache.commons.lang3.BooleanUtils;
|
import org.apache.commons.lang3.BooleanUtils;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.apache.commons.lang3.math.NumberUtils;
|
import org.apache.commons.lang3.math.NumberUtils;
|
||||||
@ -48,12 +48,12 @@ public class ClusterController {
|
|||||||
@RequestMapping(value = {"/update", "/add"}, method = RequestMethod.POST)
|
@RequestMapping(value = {"/update", "/add"}, method = RequestMethod.POST)
|
||||||
public String update(HttpServletRequest request) throws Exception {
|
public String update(HttpServletRequest request) throws Exception {
|
||||||
|
|
||||||
String clusterName = BaseServlet.required(request, "clusterName");
|
String clusterName = WebUtils.required(request, "clusterName");
|
||||||
String serviceName = BaseServlet.required(request, "serviceName");
|
String serviceName = WebUtils.required(request, "serviceName");
|
||||||
String healthChecker = BaseServlet.required(request, "healthChecker");
|
String healthChecker = WebUtils.required(request, "healthChecker");
|
||||||
String metadata = BaseServlet.optional(request, "metadata", StringUtils.EMPTY);
|
String metadata = WebUtils.optional(request, "metadata", StringUtils.EMPTY);
|
||||||
String checkPort = BaseServlet.required(request, "checkPort");
|
String checkPort = WebUtils.required(request, "checkPort");
|
||||||
String useInstancePort4Check = BaseServlet.required(request, "useInstancePort4Check");
|
String useInstancePort4Check = WebUtils.required(request, "useInstancePort4Check");
|
||||||
|
|
||||||
VirtualClusterDomain domain = (VirtualClusterDomain) domainsManager.getDomain(serviceName);
|
VirtualClusterDomain domain = (VirtualClusterDomain) domainsManager.getDomain(serviceName);
|
||||||
if (domain == null) {
|
if (domain == null) {
|
||||||
|
@ -17,13 +17,13 @@ package com.alibaba.nacos.naming.controllers;
|
|||||||
|
|
||||||
import com.alibaba.fastjson.JSON;
|
import com.alibaba.fastjson.JSON;
|
||||||
import com.alibaba.fastjson.JSONObject;
|
import com.alibaba.fastjson.JSONObject;
|
||||||
|
import com.alibaba.nacos.common.util.WebUtils;
|
||||||
import com.alibaba.nacos.naming.core.IpAddress;
|
import com.alibaba.nacos.naming.core.IpAddress;
|
||||||
import com.alibaba.nacos.naming.core.VirtualClusterDomain;
|
import com.alibaba.nacos.naming.core.VirtualClusterDomain;
|
||||||
import com.alibaba.nacos.naming.exception.NacosException;
|
import com.alibaba.nacos.naming.exception.NacosException;
|
||||||
import com.alibaba.nacos.naming.healthcheck.HealthCheckMode;
|
import com.alibaba.nacos.naming.healthcheck.HealthCheckMode;
|
||||||
import com.alibaba.nacos.naming.misc.UtilsAndCommons;
|
import com.alibaba.nacos.naming.misc.UtilsAndCommons;
|
||||||
import com.alibaba.nacos.naming.web.ApiCommands;
|
import com.alibaba.nacos.naming.web.ApiCommands;
|
||||||
import com.alibaba.nacos.naming.web.BaseServlet;
|
|
||||||
import com.alibaba.nacos.naming.web.MockHttpRequest;
|
import com.alibaba.nacos.naming.web.MockHttpRequest;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
@ -49,8 +49,8 @@ public class InstanceController extends ApiCommands {
|
|||||||
Map<String, String[]> params = new HashMap<>(request.getParameterMap());
|
Map<String, String[]> params = new HashMap<>(request.getParameterMap());
|
||||||
MockHttpRequest mockHttpRequest = MockHttpRequest.buildRequest(params);
|
MockHttpRequest mockHttpRequest = MockHttpRequest.buildRequest(params);
|
||||||
|
|
||||||
String serviceJson = BaseServlet.optional(request, "service", StringUtils.EMPTY);
|
String serviceJson = WebUtils.optional(request, "service", StringUtils.EMPTY);
|
||||||
String clusterJson = BaseServlet.optional(request, "cluster", StringUtils.EMPTY);
|
String clusterJson = WebUtils.optional(request, "cluster", StringUtils.EMPTY);
|
||||||
|
|
||||||
// set service info:
|
// set service info:
|
||||||
if (StringUtils.isNotEmpty(serviceJson)) {
|
if (StringUtils.isNotEmpty(serviceJson)) {
|
||||||
@ -77,7 +77,7 @@ public class InstanceController extends ApiCommands {
|
|||||||
|
|
||||||
mockHttpRequest.addParameter("serviceMetadata", service.getString("metadata"));
|
mockHttpRequest.addParameter("serviceMetadata", service.getString("metadata"));
|
||||||
} else {
|
} else {
|
||||||
mockHttpRequest.addParameter("dom", BaseServlet.required(request, "serviceName"));
|
mockHttpRequest.addParameter("dom", WebUtils.required(request, "serviceName"));
|
||||||
}
|
}
|
||||||
|
|
||||||
// set cluster info:
|
// set cluster info:
|
||||||
@ -114,9 +114,9 @@ public class InstanceController extends ApiCommands {
|
|||||||
return deRegService(request);
|
return deRegService(request);
|
||||||
}
|
}
|
||||||
|
|
||||||
@RequestMapping(value = "/instance/update", method = RequestMethod.POST)
|
@RequestMapping(value = {"/instance/update", "instance"}, method = RequestMethod.POST)
|
||||||
public String update(HttpServletRequest request) throws Exception {
|
public String update(HttpServletRequest request) throws Exception {
|
||||||
String serviceName = BaseServlet.required(request, "serviceName");
|
String serviceName = WebUtils.required(request, "serviceName");
|
||||||
Map<String, String[]> params = new HashMap<>(request.getParameterMap());
|
Map<String, String[]> params = new HashMap<>(request.getParameterMap());
|
||||||
MockHttpRequest mockHttpRequest = MockHttpRequest.buildRequest(params);
|
MockHttpRequest mockHttpRequest = MockHttpRequest.buildRequest(params);
|
||||||
mockHttpRequest.addParameter("dom", serviceName);
|
mockHttpRequest.addParameter("dom", serviceName);
|
||||||
@ -136,10 +136,10 @@ public class InstanceController extends ApiCommands {
|
|||||||
@RequestMapping(value = "/instance", method = RequestMethod.GET)
|
@RequestMapping(value = "/instance", method = RequestMethod.GET)
|
||||||
public JSONObject queryDetail(HttpServletRequest request) throws Exception {
|
public JSONObject queryDetail(HttpServletRequest request) throws Exception {
|
||||||
|
|
||||||
String serviceName = BaseServlet.required(request, "serviceName");
|
String serviceName = WebUtils.required(request, "serviceName");
|
||||||
String cluster = BaseServlet.optional(request, "cluster", UtilsAndCommons.DEFAULT_CLUSTER_NAME);
|
String cluster = WebUtils.optional(request, "cluster", UtilsAndCommons.DEFAULT_CLUSTER_NAME);
|
||||||
String ip = BaseServlet.required(request, "ip");
|
String ip = WebUtils.required(request, "ip");
|
||||||
int port = Integer.parseInt(BaseServlet.required(request, "port"));
|
int port = Integer.parseInt(WebUtils.required(request, "port"));
|
||||||
|
|
||||||
VirtualClusterDomain domain = (VirtualClusterDomain) domainsManager.getDomain(serviceName);
|
VirtualClusterDomain domain = (VirtualClusterDomain) domainsManager.getDomain(serviceName);
|
||||||
if (domain == null) {
|
if (domain == null) {
|
||||||
|
@ -15,14 +15,19 @@
|
|||||||
*/
|
*/
|
||||||
package com.alibaba.nacos.naming.controllers;
|
package com.alibaba.nacos.naming.controllers;
|
||||||
|
|
||||||
|
import com.alibaba.fastjson.JSON;
|
||||||
import com.alibaba.fastjson.JSONObject;
|
import com.alibaba.fastjson.JSONObject;
|
||||||
import com.alibaba.nacos.api.naming.pojo.Service;
|
import com.alibaba.nacos.api.selector.SelectorType;
|
||||||
|
import com.alibaba.nacos.common.util.WebUtils;
|
||||||
import com.alibaba.nacos.naming.core.DomainsManager;
|
import com.alibaba.nacos.naming.core.DomainsManager;
|
||||||
|
import com.alibaba.nacos.naming.core.IpAddress;
|
||||||
import com.alibaba.nacos.naming.core.VirtualClusterDomain;
|
import com.alibaba.nacos.naming.core.VirtualClusterDomain;
|
||||||
import com.alibaba.nacos.naming.exception.NacosException;
|
import com.alibaba.nacos.naming.exception.NacosException;
|
||||||
import com.alibaba.nacos.naming.healthcheck.HealthCheckMode;
|
import com.alibaba.nacos.naming.healthcheck.HealthCheckMode;
|
||||||
import com.alibaba.nacos.naming.misc.UtilsAndCommons;
|
import com.alibaba.nacos.naming.misc.UtilsAndCommons;
|
||||||
import com.alibaba.nacos.naming.web.BaseServlet;
|
import com.alibaba.nacos.naming.selector.LabelSelector;
|
||||||
|
import com.alibaba.nacos.naming.selector.NoneSelector;
|
||||||
|
import com.alibaba.nacos.naming.selector.Selector;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.apache.commons.lang3.math.NumberUtils;
|
import org.apache.commons.lang3.math.NumberUtils;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
@ -31,9 +36,7 @@ import org.springframework.web.bind.annotation.RequestMethod;
|
|||||||
import org.springframework.web.bind.annotation.RestController;
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
import java.util.HashMap;
|
import java.util.*;
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author <a href="mailto:zpf.073@gmail.com">nkorange</a>
|
* @author <a href="mailto:zpf.073@gmail.com">nkorange</a>
|
||||||
@ -45,17 +48,18 @@ public class ServiceController {
|
|||||||
@Autowired
|
@Autowired
|
||||||
protected DomainsManager domainsManager;
|
protected DomainsManager domainsManager;
|
||||||
|
|
||||||
@RequestMapping(value = "/create", method = RequestMethod.PUT)
|
@RequestMapping(value = "", method = RequestMethod.PUT)
|
||||||
public String create(HttpServletRequest request) throws Exception {
|
public String create(HttpServletRequest request) throws Exception {
|
||||||
String serviceName = BaseServlet.required(request, "serviceName");
|
String serviceName = WebUtils.required(request, "serviceName");
|
||||||
|
|
||||||
if (domainsManager.getDomain(serviceName) != null) {
|
if (domainsManager.getDomain(serviceName) != null) {
|
||||||
throw new IllegalArgumentException("specified service already exists, serviceName : " + serviceName);
|
throw new IllegalArgumentException("specified service already exists, serviceName : " + serviceName);
|
||||||
}
|
}
|
||||||
|
|
||||||
float protectThreshold = NumberUtils.toFloat(BaseServlet.optional(request, "protectThreshold", "0"));
|
float protectThreshold = NumberUtils.toFloat(WebUtils.optional(request, "protectThreshold", "0"));
|
||||||
String healthCheckMode = BaseServlet.optional(request, "healthCheckMode", "client");
|
String healthCheckMode = WebUtils.optional(request, "healthCheckMode", "client");
|
||||||
String metadata = BaseServlet.optional(request, "metadata", StringUtils.EMPTY);
|
String metadata = WebUtils.optional(request, "metadata", StringUtils.EMPTY);
|
||||||
|
String selector = WebUtils.optional(request, "selector", StringUtils.EMPTY);
|
||||||
Map<String, String> metadataMap = new HashMap<>(16);
|
Map<String, String> metadataMap = new HashMap<>(16);
|
||||||
if (StringUtils.isNotBlank(metadata)) {
|
if (StringUtils.isNotBlank(metadata)) {
|
||||||
metadataMap = UtilsAndCommons.parseMetadata(metadata);
|
metadataMap = UtilsAndCommons.parseMetadata(metadata);
|
||||||
@ -68,6 +72,7 @@ public class ServiceController {
|
|||||||
domObj.setEnabled(true);
|
domObj.setEnabled(true);
|
||||||
domObj.setEnableClientBeat(HealthCheckMode.client.name().equals(healthCheckMode.toLowerCase()));
|
domObj.setEnableClientBeat(HealthCheckMode.client.name().equals(healthCheckMode.toLowerCase()));
|
||||||
domObj.setMetadata(metadataMap);
|
domObj.setMetadata(metadataMap);
|
||||||
|
domObj.setSelector(parseSelector(selector));
|
||||||
|
|
||||||
// now valid the dom. if failed, exception will be thrown
|
// now valid the dom. if failed, exception will be thrown
|
||||||
domObj.setLastModifiedMillis(System.currentTimeMillis());
|
domObj.setLastModifiedMillis(System.currentTimeMillis());
|
||||||
@ -79,10 +84,10 @@ public class ServiceController {
|
|||||||
return "ok";
|
return "ok";
|
||||||
}
|
}
|
||||||
|
|
||||||
@RequestMapping(value = "/remove", method = RequestMethod.DELETE)
|
@RequestMapping(value = "", method = RequestMethod.DELETE)
|
||||||
public String remove(HttpServletRequest request) throws Exception {
|
public String remove(HttpServletRequest request) throws Exception {
|
||||||
|
|
||||||
String serviceName = BaseServlet.required(request, "serviceName");
|
String serviceName = WebUtils.required(request, "serviceName");
|
||||||
|
|
||||||
VirtualClusterDomain service = (VirtualClusterDomain) domainsManager.getDomain(serviceName);
|
VirtualClusterDomain service = (VirtualClusterDomain) domainsManager.getDomain(serviceName);
|
||||||
if (service == null) {
|
if (service == null) {
|
||||||
@ -98,41 +103,79 @@ public class ServiceController {
|
|||||||
return "ok";
|
return "ok";
|
||||||
}
|
}
|
||||||
|
|
||||||
@RequestMapping(value = "/detail")
|
@RequestMapping(value = "", method = RequestMethod.GET)
|
||||||
public Service detail(HttpServletRequest request) throws Exception {
|
public JSONObject detail(HttpServletRequest request) throws Exception {
|
||||||
|
|
||||||
String serviceName = BaseServlet.required(request, "serviceName");
|
String serviceName = WebUtils.required(request, "serviceName");
|
||||||
VirtualClusterDomain domain = (VirtualClusterDomain) domainsManager.getDomain(serviceName);
|
VirtualClusterDomain domain = (VirtualClusterDomain) domainsManager.getDomain(serviceName);
|
||||||
if (domain == null) {
|
if (domain == null) {
|
||||||
throw new NacosException(NacosException.NOT_FOUND, "serivce " + serviceName + " is not found!");
|
throw new NacosException(NacosException.NOT_FOUND, "serivce " + serviceName + " is not found!");
|
||||||
}
|
}
|
||||||
|
|
||||||
Service service = new Service(serviceName);
|
JSONObject res = new JSONObject();
|
||||||
service.setName(serviceName);
|
res.put("name", serviceName);
|
||||||
service.setProtectThreshold(domain.getProtectThreshold());
|
res.put("protectThreshold", domain.getProtectThreshold());
|
||||||
service.setHealthCheckMode(HealthCheckMode.none.name());
|
|
||||||
if (domain.getEnableHealthCheck()) {
|
|
||||||
service.setHealthCheckMode(HealthCheckMode.server.name());
|
|
||||||
}
|
|
||||||
if (domain.getEnableClientBeat()) {
|
|
||||||
service.setHealthCheckMode(HealthCheckMode.client.name());
|
|
||||||
}
|
|
||||||
service.setMetadata(domain.getMetadata());
|
|
||||||
|
|
||||||
return service;
|
res.put("healthCheckMode", HealthCheckMode.none.name());
|
||||||
|
|
||||||
|
if (domain.getEnableHealthCheck()) {
|
||||||
|
res.put("healthCheckMode", HealthCheckMode.server.name());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (domain.getEnableClientBeat()) {
|
||||||
|
res.put("healthCheckMode", HealthCheckMode.client.name());
|
||||||
|
}
|
||||||
|
|
||||||
|
res.put("metadata", domain.getMetadata());
|
||||||
|
|
||||||
|
res.put("selector", domain.getSelector());
|
||||||
|
|
||||||
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
@RequestMapping(value = "/list", method = RequestMethod.GET)
|
@RequestMapping(value = "/list", method = RequestMethod.GET)
|
||||||
public JSONObject list(HttpServletRequest request) throws Exception {
|
public JSONObject list(HttpServletRequest request) throws Exception {
|
||||||
|
|
||||||
int pageNo = NumberUtils.toInt(BaseServlet.required(request, "pageNo"));
|
int pageNo = NumberUtils.toInt(WebUtils.required(request, "pageNo"));
|
||||||
int pageSize = NumberUtils.toInt(BaseServlet.required(request, "pageSize"));
|
int pageSize = NumberUtils.toInt(WebUtils.required(request, "pageSize"));
|
||||||
|
String selectorString = WebUtils.optional(request, "selector", StringUtils.EMPTY);
|
||||||
|
|
||||||
|
List<String> doms = domainsManager.getAllDomNamesList();
|
||||||
|
|
||||||
|
if (StringUtils.isNotBlank(selectorString)) {
|
||||||
|
|
||||||
|
JSONObject selectorJson = JSON.parseObject(selectorString);
|
||||||
|
switch (SelectorType.valueOf(selectorJson.getString("type"))) {
|
||||||
|
case label:
|
||||||
|
String expression = selectorJson.getString("expression");
|
||||||
|
if (StringUtils.isBlank(expression)) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
expression = StringUtils.deleteWhitespace(expression);
|
||||||
|
// Now we only support the following expression:
|
||||||
|
// INSTANCE.metadata.xxx = 'yyy' or
|
||||||
|
// SERVICE.metadata.xxx = 'yyy'
|
||||||
|
String[] terms = expression.split("=");
|
||||||
|
String[] factors = terms[0].split("\\.");
|
||||||
|
switch (factors[0]) {
|
||||||
|
case "INSTANCE":
|
||||||
|
doms = filterInstanceMetadata(doms, factors[factors.length - 1], terms[1].replace("'", ""));
|
||||||
|
break;
|
||||||
|
case "SERVICE":
|
||||||
|
doms = filterServiceMetadata(doms, factors[factors.length - 1], terms[1].replace("'", ""));
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int start = (pageNo - 1) * pageSize;
|
int start = (pageNo - 1) * pageSize;
|
||||||
int end = start + pageSize;
|
int end = start + pageSize;
|
||||||
|
|
||||||
List<String> doms = domainsManager.getAllDomNamesList();
|
|
||||||
|
|
||||||
if (start < 0) {
|
if (start < 0) {
|
||||||
start = 0;
|
start = 0;
|
||||||
}
|
}
|
||||||
@ -150,14 +193,14 @@ public class ServiceController {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@RequestMapping(value = "", method = RequestMethod.POST)
|
||||||
@RequestMapping(value = "/update", method = RequestMethod.POST)
|
|
||||||
public String update(HttpServletRequest request) throws Exception {
|
public String update(HttpServletRequest request) throws Exception {
|
||||||
|
|
||||||
String serviceName = BaseServlet.required(request, "serviceName");
|
String serviceName = WebUtils.required(request, "serviceName");
|
||||||
float protectThreshold = NumberUtils.toFloat(BaseServlet.required(request, "protectThreshold"));
|
float protectThreshold = NumberUtils.toFloat(WebUtils.required(request, "protectThreshold"));
|
||||||
String healthCheckMode = BaseServlet.required(request, "healthCheckMode");
|
String healthCheckMode = WebUtils.required(request, "healthCheckMode");
|
||||||
String metadata = BaseServlet.optional(request, "metadata", StringUtils.EMPTY);
|
String metadata = WebUtils.optional(request, "metadata", StringUtils.EMPTY);
|
||||||
|
String selector = WebUtils.optional(request, "selector", StringUtils.EMPTY);
|
||||||
|
|
||||||
VirtualClusterDomain domain = (VirtualClusterDomain) domainsManager.getDomain(serviceName);
|
VirtualClusterDomain domain = (VirtualClusterDomain) domainsManager.getDomain(serviceName);
|
||||||
if (domain == null) {
|
if (domain == null) {
|
||||||
@ -184,6 +227,8 @@ public class ServiceController {
|
|||||||
Map<String, String> metadataMap = UtilsAndCommons.parseMetadata(metadata);
|
Map<String, String> metadataMap = UtilsAndCommons.parseMetadata(metadata);
|
||||||
domain.setMetadata(metadataMap);
|
domain.setMetadata(metadataMap);
|
||||||
|
|
||||||
|
domain.setSelector(parseSelector(selector));
|
||||||
|
|
||||||
domain.setLastModifiedMillis(System.currentTimeMillis());
|
domain.setLastModifiedMillis(System.currentTimeMillis());
|
||||||
domain.recalculateChecksum();
|
domain.recalculateChecksum();
|
||||||
domain.valid();
|
domain.valid();
|
||||||
@ -192,4 +237,60 @@ public class ServiceController {
|
|||||||
|
|
||||||
return "ok";
|
return "ok";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private List<String> filterInstanceMetadata(List<String> serivces, String key, String value) {
|
||||||
|
|
||||||
|
List<String> filteredServices = new ArrayList<>();
|
||||||
|
for (String service : serivces) {
|
||||||
|
VirtualClusterDomain serviceObj = (VirtualClusterDomain) domainsManager.getDomain(service);
|
||||||
|
if (serviceObj == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
for (IpAddress address : serviceObj.allIPs()) {
|
||||||
|
if (value.equals(address.getMetadata().get(key))) {
|
||||||
|
filteredServices.add(service);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return filteredServices;
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<String> filterServiceMetadata(List<String> serivces, String key, String value) {
|
||||||
|
|
||||||
|
List<String> filteredServices = new ArrayList<>();
|
||||||
|
for (String service : serivces) {
|
||||||
|
VirtualClusterDomain serviceObj = (VirtualClusterDomain) domainsManager.getDomain(service);
|
||||||
|
if (serviceObj == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (value.equals(serviceObj.getMetadata().get(key))) {
|
||||||
|
filteredServices.add(service);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
return filteredServices;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Selector parseSelector(String selectorJsonString) throws NacosException {
|
||||||
|
|
||||||
|
if (StringUtils.isBlank(selectorJsonString)) {
|
||||||
|
return new NoneSelector();
|
||||||
|
}
|
||||||
|
|
||||||
|
JSONObject selectorJson = JSON.parseObject(selectorJsonString);
|
||||||
|
switch (SelectorType.valueOf(selectorJson.getString("type"))) {
|
||||||
|
case none:
|
||||||
|
return new NoneSelector();
|
||||||
|
case label:
|
||||||
|
String expression = selectorJson.getString("expression");
|
||||||
|
Set<String> labels = LabelSelector.parseExpression(expression);
|
||||||
|
LabelSelector labelSelector = new LabelSelector();
|
||||||
|
labelSelector.setExpression(expression);
|
||||||
|
labelSelector.setLabels(labels);
|
||||||
|
return labelSelector;
|
||||||
|
default:
|
||||||
|
throw new NacosException(NacosException.INVALID_PARAM, "not match any type of selector!");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -49,8 +49,6 @@ public class Cluster extends com.alibaba.nacos.api.naming.pojo.Cluster implement
|
|||||||
|
|
||||||
private int defIPPort = -1;
|
private int defIPPort = -1;
|
||||||
|
|
||||||
private boolean useIPPort4Check = true;
|
|
||||||
|
|
||||||
@JSONField(name = "nodegroup")
|
@JSONField(name = "nodegroup")
|
||||||
private String legacySyncConfig;
|
private String legacySyncConfig;
|
||||||
|
|
||||||
@ -332,14 +330,6 @@ public class Cluster extends com.alibaba.nacos.api.naming.pojo.Cluster implement
|
|||||||
this.defCkport = defCkport;
|
this.defCkport = defCkport;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isUseIPPort4Check() {
|
|
||||||
return useIPPort4Check;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setUseIPPort4Check(boolean useIPPort4Check) {
|
|
||||||
this.useIPPort4Check = useIPPort4Check;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void update(Cluster cluster) {
|
public void update(Cluster cluster) {
|
||||||
|
|
||||||
if (!healthChecker.equals(cluster.getHealthChecker())) {
|
if (!healthChecker.equals(cluster.getHealthChecker())) {
|
||||||
@ -367,9 +357,9 @@ public class Cluster extends com.alibaba.nacos.api.naming.pojo.Cluster implement
|
|||||||
sitegroup = cluster.getSitegroup();
|
sitegroup = cluster.getSitegroup();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (useIPPort4Check != cluster.isUseIPPort4Check()) {
|
if (isUseIPPort4Check() != cluster.isUseIPPort4Check()) {
|
||||||
Loggers.SRV_LOG.info("[CLUSTER-UPDATE] " + cluster.getDom().getName() + ":" + cluster.getName() + ", useIPPort4Check: " + useIPPort4Check + " -> " + cluster.isUseIPPort4Check());
|
Loggers.SRV_LOG.info("[CLUSTER-UPDATE] " + cluster.getDom().getName() + ":" + cluster.getName() + ", useIPPort4Check: " + isUseIPPort4Check() + " -> " + cluster.isUseIPPort4Check());
|
||||||
useIPPort4Check = cluster.isUseIPPort4Check();
|
setUseIPPort4Check(cluster.isUseIPPort4Check());
|
||||||
}
|
}
|
||||||
|
|
||||||
metadata = cluster.getMetadata();
|
metadata = cluster.getMetadata();
|
||||||
|
@ -43,9 +43,8 @@ import java.util.concurrent.locks.ReentrantLock;
|
|||||||
*/
|
*/
|
||||||
@Component
|
@Component
|
||||||
public class DomainsManager {
|
public class DomainsManager {
|
||||||
private Map<String, Domain> domMap = new ConcurrentHashMap<>();
|
|
||||||
private Map<String, Domain> raftDomMap = new ConcurrentHashMap<>();
|
private Map<String, Domain> raftDomMap = new ConcurrentHashMap<>();
|
||||||
private static Map<String, Set<Domain>> appName2Doms = new ConcurrentHashMap<>();
|
|
||||||
|
|
||||||
private LinkedBlockingDeque<DomainKey> toBeUpdatedDomsQueue = new LinkedBlockingDeque<>(1024 * 1024);
|
private LinkedBlockingDeque<DomainKey> toBeUpdatedDomsQueue = new LinkedBlockingDeque<>(1024 * 1024);
|
||||||
|
|
||||||
@ -290,19 +289,11 @@ public class DomainsManager {
|
|||||||
|
|
||||||
public void easyAddIP4Dom(String domName, List<IpAddress> ips, long timestamp, long term) throws Exception {
|
public void easyAddIP4Dom(String domName, List<IpAddress> ips, long timestamp, long term) throws Exception {
|
||||||
|
|
||||||
|
|
||||||
VirtualClusterDomain dom = (VirtualClusterDomain) chooseDomMap().get(domName);
|
VirtualClusterDomain dom = (VirtualClusterDomain) chooseDomMap().get(domName);
|
||||||
if (dom == null) {
|
if (dom == null) {
|
||||||
throw new IllegalArgumentException("dom doesn't exist: " + domName);
|
throw new IllegalArgumentException("dom doesn't exist: " + domName);
|
||||||
}
|
}
|
||||||
|
|
||||||
// set default port and site info if missing
|
|
||||||
for (IpAddress ip : ips) {
|
|
||||||
if (ip.getPort() == 0) {
|
|
||||||
ip.setPort(dom.getClusterMap().get(ip.getClusterName()).getDefIPPort());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Datum datum1 = RaftCore.getDatum(UtilsAndCommons.getIPListStoreKey(dom));
|
Datum datum1 = RaftCore.getDatum(UtilsAndCommons.getIPListStoreKey(dom));
|
||||||
String oldJson = StringUtils.EMPTY;
|
String oldJson = StringUtils.EMPTY;
|
||||||
|
|
||||||
@ -672,10 +663,6 @@ public class DomainsManager {
|
|||||||
return condition;
|
return condition;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Map<String, Domain> getDomMap() {
|
|
||||||
return new HashMap<String, Domain>(domMap);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static class DomainKey {
|
private static class DomainKey {
|
||||||
private String domName;
|
private String domName;
|
||||||
private String serverIP;
|
private String serverIP;
|
||||||
|
@ -28,6 +28,8 @@ import com.alibaba.nacos.naming.misc.UtilsAndCommons;
|
|||||||
import com.alibaba.nacos.naming.push.PushService;
|
import com.alibaba.nacos.naming.push.PushService;
|
||||||
import com.alibaba.nacos.naming.raft.RaftCore;
|
import com.alibaba.nacos.naming.raft.RaftCore;
|
||||||
import com.alibaba.nacos.naming.raft.RaftListener;
|
import com.alibaba.nacos.naming.raft.RaftListener;
|
||||||
|
import com.alibaba.nacos.naming.selector.Selector;
|
||||||
|
import com.alibaba.nacos.naming.selector.NoneSelector;
|
||||||
import org.apache.commons.collections.CollectionUtils;
|
import org.apache.commons.collections.CollectionUtils;
|
||||||
import org.apache.commons.collections.ListUtils;
|
import org.apache.commons.collections.ListUtils;
|
||||||
import org.apache.commons.lang3.RandomStringUtils;
|
import org.apache.commons.lang3.RandomStringUtils;
|
||||||
@ -46,6 +48,14 @@ public class VirtualClusterDomain implements Domain, RaftListener {
|
|||||||
|
|
||||||
private static final String DOMAIN_NAME_SYNTAX = "[0-9a-zA-Z\\.:_-]+";
|
private static final String DOMAIN_NAME_SYNTAX = "[0-9a-zA-Z\\.:_-]+";
|
||||||
|
|
||||||
|
public static final int MINIMUM_IP_DELETE_TIMEOUT = 60 * 1000;
|
||||||
|
|
||||||
|
@JSONField(serialize = false)
|
||||||
|
private ClientBeatProcessor clientBeatProcessor = new ClientBeatProcessor();
|
||||||
|
|
||||||
|
@JSONField(serialize = false)
|
||||||
|
private ClientBeatCheckTask clientBeatCheckTask = new ClientBeatCheckTask(this);
|
||||||
|
|
||||||
private String name;
|
private String name;
|
||||||
private String token;
|
private String token;
|
||||||
private List<String> owners = new ArrayList<>();
|
private List<String> owners = new ArrayList<>();
|
||||||
@ -53,19 +63,13 @@ public class VirtualClusterDomain implements Domain, RaftListener {
|
|||||||
private Boolean enableHealthCheck = true;
|
private Boolean enableHealthCheck = true;
|
||||||
private Boolean enabled = true;
|
private Boolean enabled = true;
|
||||||
private Boolean enableClientBeat = false;
|
private Boolean enableClientBeat = false;
|
||||||
|
private Selector selector = new NoneSelector();
|
||||||
|
|
||||||
public static final int MINIMUM_IP_DELETE_TIMEOUT = 60 * 1000;
|
|
||||||
/**
|
/**
|
||||||
* IP will be deleted if it has not send beat for some time, default timeout is half an hour .
|
* IP will be deleted if it has not send beat for some time, default timeout is half an hour .
|
||||||
*/
|
*/
|
||||||
private long ipDeleteTimeout = 30 * 1000;
|
private long ipDeleteTimeout = 30 * 1000;
|
||||||
|
|
||||||
@JSONField(serialize = false)
|
|
||||||
private ClientBeatProcessor clientBeatProcessor = new ClientBeatProcessor();
|
|
||||||
|
|
||||||
@JSONField(serialize = false)
|
|
||||||
private ClientBeatCheckTask clientBeatCheckTask = new ClientBeatCheckTask(this);
|
|
||||||
|
|
||||||
private volatile long lastModifiedMillis = 0L;
|
private volatile long lastModifiedMillis = 0L;
|
||||||
|
|
||||||
private boolean useSpecifiedURL = false;
|
private boolean useSpecifiedURL = false;
|
||||||
@ -140,6 +144,14 @@ public class VirtualClusterDomain implements Domain, RaftListener {
|
|||||||
this.metadata = metadata;
|
this.metadata = metadata;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Selector getSelector() {
|
||||||
|
return selector;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSelector(Selector selector) {
|
||||||
|
this.selector = selector;
|
||||||
|
}
|
||||||
|
|
||||||
public VirtualClusterDomain() {
|
public VirtualClusterDomain() {
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -204,10 +216,6 @@ public class VirtualClusterDomain implements Domain, RaftListener {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ip.getPort() == 0) {
|
|
||||||
ip.setPort(getLegacyCkPort());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (StringUtils.isEmpty(ip.getClusterName())) {
|
if (StringUtils.isEmpty(ip.getClusterName())) {
|
||||||
ip.setClusterName(UtilsAndCommons.DEFAULT_CLUSTER_NAME);
|
ip.setClusterName(UtilsAndCommons.DEFAULT_CLUSTER_NAME);
|
||||||
}
|
}
|
||||||
@ -372,9 +380,6 @@ public class VirtualClusterDomain implements Domain, RaftListener {
|
|||||||
|
|
||||||
domain.put("protectThreshold", vDom.getProtectThreshold());
|
domain.put("protectThreshold", vDom.getProtectThreshold());
|
||||||
|
|
||||||
int totalCkRTMillis = 0;
|
|
||||||
int validCkRTCount = 0;
|
|
||||||
|
|
||||||
List<Object> clustersList = new ArrayList<Object>();
|
List<Object> clustersList = new ArrayList<Object>();
|
||||||
|
|
||||||
for (Map.Entry<String, Cluster> entry : vDom.getClusterMap().entrySet()) {
|
for (Map.Entry<String, Cluster> entry : vDom.getClusterMap().entrySet()) {
|
||||||
@ -397,15 +402,6 @@ public class VirtualClusterDomain implements Domain, RaftListener {
|
|||||||
return JSON.toJSONString(domain);
|
return JSON.toJSONString(domain);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* the legacy check port is the default check port for old domain format
|
|
||||||
*/
|
|
||||||
@JSONField(serialize = false)
|
|
||||||
public int getLegacyCkPort() {
|
|
||||||
return clusterMap.get(UtilsAndCommons.DEFAULT_CLUSTER_NAME).getDefCkport();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getName() {
|
public String getName() {
|
||||||
return name;
|
return name;
|
||||||
@ -503,6 +499,8 @@ public class VirtualClusterDomain implements Domain, RaftListener {
|
|||||||
enabled = vDom.getEnabled();
|
enabled = vDom.getEnabled();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
selector = vDom.getSelector();
|
||||||
|
|
||||||
metadata = vDom.getMetadata();
|
metadata = vDom.getMetadata();
|
||||||
|
|
||||||
updateOrAddCluster(vDom.getClusterMap().values());
|
updateOrAddCluster(vDom.getClusterMap().values());
|
||||||
|
@ -24,6 +24,8 @@ import com.alibaba.nacos.api.naming.pojo.AbstractHealthChecker;
|
|||||||
import com.alibaba.nacos.naming.core.Domain;
|
import com.alibaba.nacos.naming.core.Domain;
|
||||||
import com.alibaba.nacos.naming.exception.NacosException;
|
import com.alibaba.nacos.naming.exception.NacosException;
|
||||||
import com.alibaba.nacos.naming.healthcheck.JsonAdapter;
|
import com.alibaba.nacos.naming.healthcheck.JsonAdapter;
|
||||||
|
import com.alibaba.nacos.naming.selector.Selector;
|
||||||
|
import com.alibaba.nacos.naming.selector.SelectorJsonAdapter;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
@ -123,6 +125,11 @@ public class UtilsAndCommons {
|
|||||||
ParserConfig.getGlobalInstance()
|
ParserConfig.getGlobalInstance()
|
||||||
.putDeserializer(AbstractHealthChecker.class, JsonAdapter.getInstance());
|
.putDeserializer(AbstractHealthChecker.class, JsonAdapter.getInstance());
|
||||||
|
|
||||||
|
SerializeConfig.getGlobalInstance()
|
||||||
|
.put(Selector.class, SelectorJsonAdapter.getInstance());
|
||||||
|
ParserConfig.getGlobalInstance()
|
||||||
|
.putDeserializer(Selector.class, SelectorJsonAdapter.getInstance());
|
||||||
|
|
||||||
// write null values, otherwise will cause compatibility issues
|
// write null values, otherwise will cause compatibility issues
|
||||||
JSON.DEFAULT_GENERATE_FEATURE |= SerializerFeature.WriteNullStringAsEmpty.getMask();
|
JSON.DEFAULT_GENERATE_FEATURE |= SerializerFeature.WriteNullStringAsEmpty.getMask();
|
||||||
JSON.DEFAULT_GENERATE_FEATURE |= SerializerFeature.WriteNullListAsEmpty.getMask();
|
JSON.DEFAULT_GENERATE_FEATURE |= SerializerFeature.WriteNullListAsEmpty.getMask();
|
||||||
|
@ -0,0 +1,294 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 1999-2018 Alibaba Group Holding Ltd.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package com.alibaba.nacos.naming.selector;
|
||||||
|
|
||||||
|
|
||||||
|
import com.alibaba.nacos.api.cmdb.pojo.PreservedEntityTypes;
|
||||||
|
import com.alibaba.nacos.api.selector.SelectorType;
|
||||||
|
import com.alibaba.nacos.api.selector.ExpressionSelector;
|
||||||
|
import com.alibaba.nacos.cmdb.service.CmdbReader;
|
||||||
|
import com.alibaba.nacos.naming.boot.SpringContext;
|
||||||
|
import com.alibaba.nacos.naming.core.IpAddress;
|
||||||
|
import com.alibaba.nacos.naming.exception.NacosException;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.springframework.context.ApplicationContext;
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A selector to implement a so called same-label-prior rule for service discovery.
|
||||||
|
* <h2>Backgroup</h2>
|
||||||
|
* Consider service providers are deployed in two sites i.e. site A and site B, and consumers
|
||||||
|
* of this service provider are also deployed in site A and site B. So the consumers may want to
|
||||||
|
* visit the service provider in current site, thus consumers in site A visit service providers
|
||||||
|
* in site A and consumers in site B visit service providers in site B. This is quite useful to
|
||||||
|
* reduce the transfer delay of RPC. This is called same-site-prior strategy.
|
||||||
|
* <h2>Same Label Prior</h2>
|
||||||
|
* The same-site-prior strategy covers many circumstances in large companies and we can abstract
|
||||||
|
* it to a higher level strategy: same-label-prior.
|
||||||
|
* <p>
|
||||||
|
* So the idea is that presumed we have built a self-defined or integrated a third-party idc CMDB
|
||||||
|
* which stores all the labels of all IPs. Then we can filter provider IPs by the consumer IP and
|
||||||
|
* we only return the providers who have the same label values with consumer. We can define the
|
||||||
|
* labels we want to include in the comparison.
|
||||||
|
* <p>
|
||||||
|
* If no provider has the same label value with the consumer, we fall back to give all providers
|
||||||
|
* to the consumer. Note that this fallback strategy may also be abstracted in future to introduce
|
||||||
|
* more kinds of behaviors.
|
||||||
|
*
|
||||||
|
* @author <a href="mailto:zpf.073@gmail.com">nkorange</a>
|
||||||
|
* @see CmdbReader
|
||||||
|
*/
|
||||||
|
public class LabelSelector extends ExpressionSelector implements Selector {
|
||||||
|
|
||||||
|
private CmdbReader cmdbReader;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The labels relevant to this the selector.
|
||||||
|
*
|
||||||
|
* @see com.alibaba.nacos.api.cmdb.pojo.Label
|
||||||
|
*/
|
||||||
|
private Set<String> labels;
|
||||||
|
|
||||||
|
private static final Set<String> SUPPORTED_INNER_CONNCETORS = new HashSet<>();
|
||||||
|
|
||||||
|
private static final Set<String> SUPPORTED_OUTER_CONNCETORS = new HashSet<>();
|
||||||
|
|
||||||
|
private static final String CONSUMER_PREFIX = "CONSUMER.label.";
|
||||||
|
|
||||||
|
private static final String PROVIDER_PREFIX = "PROVIDER.label.";
|
||||||
|
|
||||||
|
private static final char CEQUAL = '=';
|
||||||
|
|
||||||
|
private static final char CAND = '&';
|
||||||
|
|
||||||
|
static {
|
||||||
|
SUPPORTED_INNER_CONNCETORS.add(String.valueOf(CEQUAL));
|
||||||
|
SUPPORTED_OUTER_CONNCETORS.add(String.valueOf(CAND));
|
||||||
|
}
|
||||||
|
|
||||||
|
public Set<String> getLabels() {
|
||||||
|
return labels;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLabels(Set<String> labels) {
|
||||||
|
this.labels = labels;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LabelSelector() {
|
||||||
|
setType(SelectorType.label.name());
|
||||||
|
ApplicationContext context = SpringContext.getAppContext();
|
||||||
|
cmdbReader = context.getBean(CmdbReader.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static Set<String> parseExpression(String expression) throws NacosException {
|
||||||
|
return ExpressionInterpreter.parseExpression(expression);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<IpAddress> select(String consumer, List<IpAddress> providers) {
|
||||||
|
|
||||||
|
if (labels.isEmpty()) {
|
||||||
|
return providers;
|
||||||
|
}
|
||||||
|
|
||||||
|
List<IpAddress> ipAddressList = new ArrayList<>();
|
||||||
|
for (IpAddress ipAddress : providers) {
|
||||||
|
|
||||||
|
boolean matched = true;
|
||||||
|
for (String labelName : getLabels()) {
|
||||||
|
|
||||||
|
String consumerLabelValue = cmdbReader.queryLabel(consumer, PreservedEntityTypes.ip.name(), labelName);
|
||||||
|
|
||||||
|
if (StringUtils.isNotBlank(consumerLabelValue) &&
|
||||||
|
!StringUtils.equals(consumerLabelValue,
|
||||||
|
cmdbReader.queryLabel(ipAddress.getIp(), PreservedEntityTypes.ip.name(), labelName))) {
|
||||||
|
matched = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (matched) {
|
||||||
|
ipAddressList.add(ipAddress);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ipAddressList.isEmpty()) {
|
||||||
|
return providers;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ipAddressList;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Expression interpreter for label selector.
|
||||||
|
* <p>
|
||||||
|
* For now it supports very limited set of syntax rules.
|
||||||
|
*/
|
||||||
|
public static class ExpressionInterpreter {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parse the label expression.
|
||||||
|
* <p>
|
||||||
|
* Currently we support the very single type of expression:
|
||||||
|
* <pre>
|
||||||
|
* consumer.labelA = provider.labelA & consumer.labelB = provider.labelB
|
||||||
|
* </pre>
|
||||||
|
* Later we will implement a interpreter to parse this expression in a standard LL parser way.
|
||||||
|
*
|
||||||
|
* @param expression the label expression to parse
|
||||||
|
* @return collection of labels
|
||||||
|
*/
|
||||||
|
public static Set<String> parseExpression(String expression) throws NacosException {
|
||||||
|
|
||||||
|
if (StringUtils.isBlank(expression)) {
|
||||||
|
return new HashSet<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
expression = StringUtils.deleteWhitespace(expression);
|
||||||
|
|
||||||
|
List<String> elements = getTerms(expression);
|
||||||
|
Set<String> gotLabels = new HashSet<>();
|
||||||
|
int index = 0;
|
||||||
|
|
||||||
|
index = checkInnerSyntax(elements, index);
|
||||||
|
|
||||||
|
if (index == -1) {
|
||||||
|
throw new NacosException(NacosException.INVALID_PARAM, "parse expression failed!");
|
||||||
|
}
|
||||||
|
|
||||||
|
gotLabels.add(elements.get(index++).split(PROVIDER_PREFIX)[1]);
|
||||||
|
|
||||||
|
while (index < elements.size()) {
|
||||||
|
|
||||||
|
index = checkOuterSyntax(elements, index);
|
||||||
|
|
||||||
|
if (index >= elements.size()) {
|
||||||
|
return gotLabels;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (index == -1) {
|
||||||
|
throw new NacosException(NacosException.INVALID_PARAM, "parse expression failed!");
|
||||||
|
}
|
||||||
|
|
||||||
|
gotLabels.add(elements.get(index++).split(PROVIDER_PREFIX)[1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return gotLabels;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static List<String> getTerms(String expression) {
|
||||||
|
|
||||||
|
List<String> terms = new ArrayList<>();
|
||||||
|
|
||||||
|
Set<Character> characters = new HashSet<>();
|
||||||
|
characters.add(CEQUAL);
|
||||||
|
characters.add(CAND);
|
||||||
|
|
||||||
|
char[] chars = expression.toCharArray();
|
||||||
|
|
||||||
|
int lastIndex = 0;
|
||||||
|
for (int index = 0; index < chars.length; index++) {
|
||||||
|
char ch = chars[index];
|
||||||
|
if (characters.contains(ch)) {
|
||||||
|
terms.add(expression.substring(lastIndex, index));
|
||||||
|
terms.add(expression.substring(index, index+1));
|
||||||
|
index ++;
|
||||||
|
lastIndex = index;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
terms.add(expression.substring(lastIndex, chars.length));
|
||||||
|
|
||||||
|
return terms;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int skipEmpty(List<String> elements, int start) {
|
||||||
|
while (start < elements.size() && StringUtils.isBlank(elements.get(start))) {
|
||||||
|
start++;
|
||||||
|
}
|
||||||
|
return start;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int checkOuterSyntax(List<String> elements, int start) {
|
||||||
|
|
||||||
|
int index = start;
|
||||||
|
|
||||||
|
index = skipEmpty(elements, index);
|
||||||
|
if (index >= elements.size()) {
|
||||||
|
return index;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!SUPPORTED_OUTER_CONNCETORS.contains(elements.get(index++))) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return checkInnerSyntax(elements, index);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int checkInnerSyntax(List<String> elements, int start) {
|
||||||
|
|
||||||
|
int index = start;
|
||||||
|
|
||||||
|
index = skipEmpty(elements, index);
|
||||||
|
if (index >= elements.size()) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!elements.get(index).startsWith(CONSUMER_PREFIX)) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
String labelConsumer = elements.get(index++).split(CONSUMER_PREFIX)[1];
|
||||||
|
|
||||||
|
index = skipEmpty(elements, index);
|
||||||
|
if (index >= elements.size()) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!SUPPORTED_INNER_CONNCETORS.contains(elements.get(index++))) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
index = skipEmpty(elements, index);
|
||||||
|
if (index >= elements.size()) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!elements.get(index).startsWith(PROVIDER_PREFIX)) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
String labelProvider = elements.get(index).split(PROVIDER_PREFIX)[1];
|
||||||
|
|
||||||
|
if (!labelConsumer.equals(labelProvider)) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return index;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main(String[] args) throws NacosException {
|
||||||
|
|
||||||
|
String expression = "CONSUMER.label.A=PROVIDER.label.A &CONSUMER.label.B=PROVIDER.label.B";
|
||||||
|
expression = StringUtils.deleteWhitespace(expression);
|
||||||
|
System.out.println(ExpressionInterpreter.getTerms(expression));
|
||||||
|
|
||||||
|
System.out.println(LabelSelector.parseExpression(expression));
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,36 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 1999-2018 Alibaba Group Holding Ltd.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package com.alibaba.nacos.naming.selector;
|
||||||
|
|
||||||
|
import com.alibaba.nacos.api.selector.SelectorType;
|
||||||
|
import com.alibaba.nacos.naming.core.IpAddress;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author <a href="mailto:zpf.073@gmail.com">nkorange</a>
|
||||||
|
*/
|
||||||
|
public class NoneSelector extends com.alibaba.nacos.api.selector.AbstractSelector implements Selector {
|
||||||
|
|
||||||
|
public NoneSelector() {
|
||||||
|
this.setType(SelectorType.none.name());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<IpAddress> select(String consumer, List<IpAddress> providers) {
|
||||||
|
return providers;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,55 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 1999-2018 Alibaba Group Holding Ltd.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package com.alibaba.nacos.naming.selector;
|
||||||
|
|
||||||
|
import com.alibaba.nacos.naming.core.IpAddress;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Selector defines a rule for load-balance for service discovery.
|
||||||
|
* <p>
|
||||||
|
* Every service in Nacos can apply an existing selector and uses it to give the consumer
|
||||||
|
* a subset of selected providers.
|
||||||
|
* <p>
|
||||||
|
* This selector itself does not implement any specific behavior of load-balance, every
|
||||||
|
* real life selector should extend this class and implement the select method.
|
||||||
|
* <p>
|
||||||
|
* Every extended selector should also register its type to class SelectorType so Nacos
|
||||||
|
* recognizes it and can correctly create this type of selector.
|
||||||
|
*
|
||||||
|
* @author <a href="mailto:zpf.073@gmail.com">nkorange</a>
|
||||||
|
* @see com.alibaba.nacos.api.selector.SelectorType
|
||||||
|
* @see SelectorJsonAdapter
|
||||||
|
*/
|
||||||
|
public interface Selector {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the type of this selector
|
||||||
|
*
|
||||||
|
* @return type of selector
|
||||||
|
*/
|
||||||
|
String getType();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Select qualified instances from providers
|
||||||
|
*
|
||||||
|
* @param consumer consumer address
|
||||||
|
* @param providers candidate provider addresses
|
||||||
|
* @return selected provider addresses
|
||||||
|
*/
|
||||||
|
List<IpAddress> select(String consumer, List<IpAddress> providers);
|
||||||
|
}
|
@ -0,0 +1,96 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 1999-2018 Alibaba Group Holding Ltd.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package com.alibaba.nacos.naming.selector;
|
||||||
|
|
||||||
|
import com.alibaba.fastjson.JSON;
|
||||||
|
import com.alibaba.fastjson.JSONObject;
|
||||||
|
import com.alibaba.fastjson.parser.DefaultJSONParser;
|
||||||
|
import com.alibaba.fastjson.parser.deserializer.ObjectDeserializer;
|
||||||
|
import com.alibaba.fastjson.serializer.JSONSerializer;
|
||||||
|
import com.alibaba.fastjson.serializer.ObjectSerializer;
|
||||||
|
import com.alibaba.fastjson.serializer.SerializeWriter;
|
||||||
|
import com.alibaba.nacos.api.selector.AbstractSelector;
|
||||||
|
import com.alibaba.nacos.api.selector.SelectorType;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.lang.reflect.Type;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Json adapter for class Selector.
|
||||||
|
* <p>
|
||||||
|
* When deserializing object for class Selector, we should consider to convert the selector to
|
||||||
|
* its runtime child class object. And this adapter helps us to finish it.
|
||||||
|
*
|
||||||
|
* @author <a href="mailto:zpf.073@gmail.com">nkorange</a>
|
||||||
|
*/
|
||||||
|
public class SelectorJsonAdapter implements ObjectDeserializer, ObjectSerializer {
|
||||||
|
|
||||||
|
private static SelectorJsonAdapter INSTANCE = new SelectorJsonAdapter();
|
||||||
|
|
||||||
|
private SelectorJsonAdapter() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public static SelectorJsonAdapter getInstance() {
|
||||||
|
return INSTANCE;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public <T> T deserialze(DefaultJSONParser parser, Type type, Object fieldName) {
|
||||||
|
|
||||||
|
JSONObject jsonObj = (JSONObject) parser.parse();
|
||||||
|
|
||||||
|
if (jsonObj == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
String checkType = jsonObj.getString("type");
|
||||||
|
|
||||||
|
if (StringUtils.equals(checkType, SelectorType.label.name())) {
|
||||||
|
return (T) JSON.parseObject(jsonObj.toJSONString(), LabelSelector.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (StringUtils.equals(checkType, SelectorType.none.name())) {
|
||||||
|
return (T) JSON.parseObject(jsonObj.toJSONString(), NoneSelector.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getFastMatchToken() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void write(JSONSerializer serializer, Object object, Object fieldName, Type fieldType, int features) throws IOException {
|
||||||
|
|
||||||
|
SerializeWriter writer = serializer.getWriter();
|
||||||
|
if (object == null) {
|
||||||
|
writer.writeNull();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Selector selector = (Selector) object;
|
||||||
|
|
||||||
|
writer.writeFieldValue(',', "type", selector.getType());
|
||||||
|
|
||||||
|
if (StringUtils.equals(selector.getType(), SelectorType.label.name())) {
|
||||||
|
LabelSelector labelSelector = (LabelSelector) selector;
|
||||||
|
writer.writeFieldValue(',', "labels", JSON.toJSONString(labelSelector.getLabels()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
File diff suppressed because it is too large
Load Diff
@ -34,7 +34,6 @@ import java.util.concurrent.ConcurrentMap;
|
|||||||
/**
|
/**
|
||||||
* @author <a href="mailto:zpf.073@gmail.com">nkorange</a>
|
* @author <a href="mailto:zpf.073@gmail.com">nkorange</a>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
public class AuthFilter implements Filter {
|
public class AuthFilter implements Filter {
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
|
@ -19,29 +19,24 @@ import com.alibaba.fastjson.JSON;
|
|||||||
import com.alibaba.fastjson.JSONArray;
|
import com.alibaba.fastjson.JSONArray;
|
||||||
import com.alibaba.fastjson.JSONObject;
|
import com.alibaba.fastjson.JSONObject;
|
||||||
import com.alibaba.nacos.common.util.IoUtils;
|
import com.alibaba.nacos.common.util.IoUtils;
|
||||||
|
import com.alibaba.nacos.common.util.WebUtils;
|
||||||
import com.alibaba.nacos.naming.core.DomainsManager;
|
import com.alibaba.nacos.naming.core.DomainsManager;
|
||||||
import com.alibaba.nacos.naming.core.VirtualClusterDomain;
|
import com.alibaba.nacos.naming.core.VirtualClusterDomain;
|
||||||
import com.alibaba.nacos.naming.misc.NetUtils;
|
import com.alibaba.nacos.naming.misc.NetUtils;
|
||||||
import com.alibaba.nacos.naming.misc.UtilsAndCommons;
|
import com.alibaba.nacos.naming.misc.UtilsAndCommons;
|
||||||
import com.alibaba.nacos.naming.raft.Datum;
|
import com.alibaba.nacos.naming.raft.*;
|
||||||
import com.alibaba.nacos.naming.raft.RaftCore;
|
|
||||||
import com.alibaba.nacos.naming.raft.RaftListener;
|
|
||||||
import com.alibaba.nacos.naming.raft.RaftPeer;
|
|
||||||
import com.alibaba.nacos.naming.raft.RaftStore;
|
|
||||||
|
|
||||||
import org.apache.commons.io.IOUtils;
|
import org.apache.commons.io.IOUtils;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import javax.servlet.http.HttpServletRequest;
|
|
||||||
import javax.servlet.http.HttpServletResponse;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author nacos
|
* @author nacos
|
||||||
*/
|
*/
|
||||||
@ -57,7 +52,7 @@ public class RaftCommands {
|
|||||||
public JSONObject vote(HttpServletRequest request, HttpServletResponse response) throws Exception {
|
public JSONObject vote(HttpServletRequest request, HttpServletResponse response) throws Exception {
|
||||||
|
|
||||||
RaftPeer peer = RaftCore.MasterElection.receivedVote(
|
RaftPeer peer = RaftCore.MasterElection.receivedVote(
|
||||||
JSON.parseObject(BaseServlet.required(request, "vote"), RaftPeer.class));
|
JSON.parseObject(WebUtils.required(request, "vote"), RaftPeer.class));
|
||||||
|
|
||||||
return JSON.parseObject(JSON.toJSONString(peer));
|
return JSON.parseObject(JSON.toJSONString(peer));
|
||||||
}
|
}
|
||||||
@ -101,7 +96,7 @@ public class RaftCommands {
|
|||||||
@NeedAuth
|
@NeedAuth
|
||||||
@RequestMapping("/reloadDatum")
|
@RequestMapping("/reloadDatum")
|
||||||
public String reloadDatum(HttpServletRequest request, HttpServletResponse response) throws Exception {
|
public String reloadDatum(HttpServletRequest request, HttpServletResponse response) throws Exception {
|
||||||
String key = BaseServlet.required(request, "key");
|
String key = WebUtils.required(request, "key");
|
||||||
RaftStore.load(key);
|
RaftStore.load(key);
|
||||||
return "ok";
|
return "ok";
|
||||||
}
|
}
|
||||||
@ -148,7 +143,7 @@ public class RaftCommands {
|
|||||||
response.setHeader("Content-Type", "application/json; charset=" + getAcceptEncoding(request));
|
response.setHeader("Content-Type", "application/json; charset=" + getAcceptEncoding(request));
|
||||||
response.setHeader("Cache-Control", "no-cache");
|
response.setHeader("Cache-Control", "no-cache");
|
||||||
response.setHeader("Content-Encode", "gzip");
|
response.setHeader("Content-Encode", "gzip");
|
||||||
RaftCore.signalDelete(BaseServlet.required(request, "key"));
|
RaftCore.signalDelete(WebUtils.required(request, "key"));
|
||||||
return "ok";
|
return "ok";
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -159,7 +154,7 @@ public class RaftCommands {
|
|||||||
response.setHeader("Content-Type", "application/json; charset=" + getAcceptEncoding(request));
|
response.setHeader("Content-Type", "application/json; charset=" + getAcceptEncoding(request));
|
||||||
response.setHeader("Cache-Control", "no-cache");
|
response.setHeader("Cache-Control", "no-cache");
|
||||||
response.setHeader("Content-Encode", "gzip");
|
response.setHeader("Content-Encode", "gzip");
|
||||||
String keysString = BaseServlet.required(request, "keys");
|
String keysString = WebUtils.required(request, "keys");
|
||||||
String[] keys = keysString.split(",");
|
String[] keys = keysString.split(",");
|
||||||
List<Datum> datums = new ArrayList<Datum>();
|
List<Datum> datums = new ArrayList<Datum>();
|
||||||
|
|
||||||
|
6
pom.xml
6
pom.xml
@ -460,6 +460,7 @@
|
|||||||
<module>common</module>
|
<module>common</module>
|
||||||
<module>distribution</module>
|
<module>distribution</module>
|
||||||
<module>console</module>
|
<module>console</module>
|
||||||
|
<module>cmdb</module>
|
||||||
</modules>
|
</modules>
|
||||||
|
|
||||||
<!-- 所有的子项目默认依赖 -->
|
<!-- 所有的子项目默认依赖 -->
|
||||||
@ -521,6 +522,11 @@
|
|||||||
<artifactId>nacos-common</artifactId>
|
<artifactId>nacos-common</artifactId>
|
||||||
<version>${project.version}</version>
|
<version>${project.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>${project.groupId}</groupId>
|
||||||
|
<artifactId>nacos-cmdb</artifactId>
|
||||||
|
<version>${project.version}</version>
|
||||||
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>${project.groupId}</groupId>
|
<groupId>${project.groupId}</groupId>
|
||||||
<artifactId>nacos-console</artifactId>
|
<artifactId>nacos-console</artifactId>
|
||||||
|
@ -64,7 +64,6 @@ public class RegisterInstance_ITCase {
|
|||||||
@Test
|
@Test
|
||||||
@Ignore
|
@Ignore
|
||||||
public void regService() throws NacosException, InterruptedException {
|
public void regService() throws NacosException, InterruptedException {
|
||||||
|
|
||||||
String serviceName = "dungu.test.99";
|
String serviceName = "dungu.test.99";
|
||||||
naming.registerInstance(serviceName, "127.0.0.1", 80, "c1");
|
naming.registerInstance(serviceName, "127.0.0.1", 80, "c1");
|
||||||
naming.registerInstance(serviceName, "127.0.0.2", 80, "c2");
|
naming.registerInstance(serviceName, "127.0.0.2", 80, "c2");
|
||||||
|
@ -296,30 +296,9 @@ public class RestAPI_ITCase {
|
|||||||
Assert.assertEquals(NamingBase.TEST_PORT_4_DOM_1, hosts.getJSONObject(0).getString("port"));
|
Assert.assertEquals(NamingBase.TEST_PORT_4_DOM_1, hosts.getJSONObject(0).getString("port"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
|
||||||
public void srvIPXT() throws Exception {
|
|
||||||
|
|
||||||
ResponseEntity<String> response = request("/nacos/v1/ns/api/srvIPXT",
|
|
||||||
Params.newParams()
|
|
||||||
.appendParam("dom", NamingBase.TEST_DOM_1)
|
|
||||||
.done(), String.class);
|
|
||||||
|
|
||||||
assertTrue(response.getStatusCode().is2xxSuccessful());
|
|
||||||
|
|
||||||
JSONObject json = JSON.parseObject(response.getBody());
|
|
||||||
|
|
||||||
Assert.assertEquals(NamingBase.TEST_DOM_1, json.getString("dom"));
|
|
||||||
JSONArray hosts = json.getJSONArray("hosts");
|
|
||||||
Assert.assertNotNull(hosts);
|
|
||||||
Assert.assertEquals(1, hosts.size());
|
|
||||||
Assert.assertEquals(NamingBase.TEST_IP_4_DOM_1, hosts.getJSONObject(0).getString("ip"));
|
|
||||||
Assert.assertEquals(NamingBase.TEST_PORT_4_DOM_1, hosts.getJSONObject(0).getString("port"));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void remvIP4Dom() throws Exception {
|
public void remvIP4Dom() throws Exception {
|
||||||
|
|
||||||
|
|
||||||
ResponseEntity<String> response = request("/nacos/v1/ns/api/addIP4Dom",
|
ResponseEntity<String> response = request("/nacos/v1/ns/api/addIP4Dom",
|
||||||
Params.newParams()
|
Params.newParams()
|
||||||
.appendParam("dom", NamingBase.TEST_DOM_1)
|
.appendParam("dom", NamingBase.TEST_DOM_1)
|
||||||
|
@ -15,9 +15,12 @@
|
|||||||
*/
|
*/
|
||||||
package com.alibaba.nacos.test.naming;
|
package com.alibaba.nacos.test.naming;
|
||||||
|
|
||||||
|
import com.alibaba.nacos.api.exception.NacosException;
|
||||||
import com.alibaba.nacos.api.naming.NamingFactory;
|
import com.alibaba.nacos.api.naming.NamingFactory;
|
||||||
import com.alibaba.nacos.api.naming.NamingService;
|
import com.alibaba.nacos.api.naming.NamingService;
|
||||||
import com.alibaba.nacos.api.naming.pojo.Instance;
|
import com.alibaba.nacos.api.naming.pojo.Instance;
|
||||||
|
import com.alibaba.nacos.api.naming.pojo.ListView;
|
||||||
|
import com.alibaba.nacos.api.selector.ExpressionSelector;
|
||||||
import com.alibaba.nacos.naming.NamingApp;
|
import com.alibaba.nacos.naming.NamingApp;
|
||||||
import org.junit.Assert;
|
import org.junit.Assert;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
@ -29,7 +32,9 @@ import org.springframework.boot.web.server.LocalServerPort;
|
|||||||
import org.springframework.test.context.junit4.SpringRunner;
|
import org.springframework.test.context.junit4.SpringRunner;
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
import static com.alibaba.nacos.test.naming.NamingBase.*;
|
import static com.alibaba.nacos.test.naming.NamingBase.*;
|
||||||
@ -57,40 +62,6 @@ public class SelectInstances_ITCase {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void getAllInstances() throws Exception {
|
|
||||||
|
|
||||||
// final String serviceName = "dungu.test.100";
|
|
||||||
// naming.registerInstance(serviceName, "127.0.0.1", TEST_PORT);
|
|
||||||
//
|
|
||||||
//
|
|
||||||
//
|
|
||||||
// Thread thread = new Thread(new Runnable() {
|
|
||||||
// @Override
|
|
||||||
// public void run() {
|
|
||||||
// try {
|
|
||||||
// TimeUnit.SECONDS.sleep(10);
|
|
||||||
// naming.deregisterInstance(serviceName, "127.0.0.1", TEST_PORT);
|
|
||||||
// System.out.println("deregister ok!");
|
|
||||||
// } catch (Exception e) {
|
|
||||||
// e.printStackTrace();
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// });
|
|
||||||
//
|
|
||||||
// thread.start();
|
|
||||||
//
|
|
||||||
//
|
|
||||||
// while (true) {
|
|
||||||
//
|
|
||||||
// System.out.println(new Date());
|
|
||||||
// System.out.println(naming.getAllInstances("dungu.test.100"));
|
|
||||||
//
|
|
||||||
// TimeUnit.SECONDS.sleep(1);
|
|
||||||
// }
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取所有健康的Instance
|
* 获取所有健康的Instance
|
||||||
*
|
*
|
||||||
@ -388,5 +359,47 @@ public class SelectInstances_ITCase {
|
|||||||
Assert.assertTrue(verifyInstanceList(instances, instancesGet));
|
Assert.assertTrue(verifyInstanceList(instances, instancesGet));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void getServiceListWithSelector() throws NacosException, InterruptedException {
|
||||||
|
|
||||||
|
String serviceName = randomDomainName();
|
||||||
|
Instance instance = new Instance();
|
||||||
|
instance.setIp("128.0.0.1");
|
||||||
|
instance.setPort(999);
|
||||||
|
instance.setServiceName(serviceName);
|
||||||
|
|
||||||
|
Map<String, String> metadata = new HashMap<String, String>();
|
||||||
|
metadata.put("registerSource", "dubbo");
|
||||||
|
instance.setMetadata(metadata);
|
||||||
|
|
||||||
|
naming.registerInstance(serviceName, instance);
|
||||||
|
naming.registerInstance(serviceName, "127.0.0.1", 80, "c1");
|
||||||
|
naming.registerInstance(serviceName, "127.0.0.2", 80, "c2");
|
||||||
|
|
||||||
|
TimeUnit.SECONDS.sleep(10);
|
||||||
|
|
||||||
|
ExpressionSelector expressionSelector = new ExpressionSelector();
|
||||||
|
expressionSelector.setExpression("INSTANCE.metadata.registerSource = 'dubbo'");
|
||||||
|
ListView<String> serviceList = naming.getServicesOfServer(1, 10, expressionSelector);
|
||||||
|
|
||||||
|
Assert.assertTrue(serviceList.getData().contains(serviceName));
|
||||||
|
|
||||||
|
serviceName = randomDomainName();
|
||||||
|
|
||||||
|
instance.setServiceName(serviceName);
|
||||||
|
metadata.put("registerSource", "spring");
|
||||||
|
instance.setMetadata(metadata);
|
||||||
|
|
||||||
|
naming.registerInstance(serviceName, instance);
|
||||||
|
|
||||||
|
TimeUnit.SECONDS.sleep(10);
|
||||||
|
|
||||||
|
expressionSelector.setExpression("INSTANCE.metadata.registerSource = 'spring'");
|
||||||
|
serviceList = naming.getServicesOfServer(1, 10, expressionSelector);
|
||||||
|
|
||||||
|
Assert.assertTrue(serviceList.getData().contains(serviceName));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user