----初始化项目

This commit is contained in:
2025-09-19 20:49:14 +08:00
parent b345d2828d
commit df7765c400
2867 changed files with 359313 additions and 89 deletions

85
consistency/pom.xml Normal file
View File

@ -0,0 +1,85 @@
<?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:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<artifactId>nacos-consistency</artifactId>
<build>
<extensions>
<extension>
<groupId>kr.motd.maven</groupId>
<artifactId>os-maven-plugin</artifactId>
<version>1.5.0.Final</version>
</extension>
</extensions>
<plugins>
<!-- Grpc coding plug-in-->
<plugin>
<groupId>org.xolstice.maven.plugins</groupId>
<artifactId>protobuf-maven-plugin</artifactId>
<version>0.6.1</version>
<configuration>
<protocArtifact>com.google.protobuf:protoc:${protobuf-java.version}:exe:${os.detected.classifier}</protocArtifact>
<pluginId>grpc-java</pluginId>
<pluginArtifact>io.grpc:protoc-gen-grpc-java:${grpc-java.version}:exe:${os.detected.classifier}</pluginArtifact>
</configuration>
<executions>
<execution>
<goals>
<goal>compile</goal>
<goal>compile-custom</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>nacos-common</artifactId>
</dependency>
<dependency>
<groupId>org.javatuples</groupId>
<artifactId>javatuples</artifactId>
</dependency>
<dependency>
<groupId>com.caucho</groupId>
<artifactId>hessian</artifactId>
</dependency>
<dependency>
<groupId>com.google.protobuf</groupId>
<artifactId>protobuf-java</artifactId>
</dependency>
</dependencies>
<modelVersion>4.0.0</modelVersion>
<name>nacos-consistency ${project.version}</name>
<packaging>jar</packaging>
<parent>
<groupId>com.alibaba.nacos</groupId>
<artifactId>nacos-all</artifactId>
<relativePath>../pom.xml</relativePath>
<version>${revision}</version>
</parent>
<url>https://nacos.io</url>
</project>

View File

@ -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.consistency;
import com.alibaba.nacos.common.model.RestResult;
import com.alibaba.nacos.common.model.RestResultUtils;
import java.util.Map;
/**
* Operation and maintenance command interface.
*
* @author <a href="mailto:liaochuntao@live.com">liaochuntao</a>
*/
public interface CommandOperations {
/**
* Operation and maintenance interface operation entry.
*
* @param commands commands
* @return execute success
*/
default RestResult<String> execute(Map<String, String> commands) {
return RestResultUtils.success();
}
}

View File

@ -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.consistency;
import java.io.Serializable;
import java.util.Set;
/**
* Consistent protocol related configuration objects.
*
* <p>{@link RequestProcessor} : The consistency protocol provides services for all businesses, but each business only cares
* about the transaction information belonging to that business, and the transaction processing between the various
* services should not block each other. Therefore, the LogProcessor is abstracted to implement the parallel processing
* of transactions of different services. Corresponding LogProcessor sub-interface: LogProcessor4AP or LogProcessor4CP,
* different consistency protocols will actively discover the corresponding LogProcessor
*
* @author <a href="mailto:liaochuntao@live.com">liaochuntao</a>
*/
public interface Config<L extends RequestProcessor> extends Serializable {
/**
* Set the cluster node information to initializelike [ip:port, ip:port, ip:port].
*
* @param self local node address information, ip:port
* @param members {@link Set}
*/
void setMembers(String self, Set<String> members);
/**
* members join.
*
* @param members {@link Set}
*/
void addMembers(Set<String> members);
/**
* members leave.
*
* @param members {@link Set}
*/
void removeMembers(Set<String> members);
/**
* get local node address info.
*
* @return address
*/
String getSelfMember();
/**
* get the cluster node information.
*
* @return members info, like [ip:port, ip:port, ip:port]
*/
Set<String> getMembers();
/**
* Add configuration content.
*
* @param key config key
* @param value config value
*/
void setVal(String key, String value);
/**
* get configuration content by key.
*
* @param key config key
* @return config value
*/
String getVal(String key);
/**
* get configuration content by key, if not found, use default-val.
*
* @param key config key
* @param defaultVal default value
* @return config value
*/
String getValOfDefault(String key, String defaultVal);
}

View File

@ -0,0 +1,116 @@
/*
* 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.consistency;
import com.alibaba.nacos.consistency.entity.ReadRequest;
import com.alibaba.nacos.consistency.entity.Response;
import com.alibaba.nacos.consistency.entity.WriteRequest;
import java.util.Collection;
import java.util.Set;
import java.util.concurrent.CompletableFuture;
/**
* Has nothing to do with the specific implementation of the consistency protocol Initialization sequence init(Config).
*
* <ul>
* <li>{@link Config} : Relevant configuration information required by the consistency protocol,
* for example, the Raft protocol needs to set the election timeout time, the location where
* the Log is stored, and the snapshot task execution interval</li>
* <li>{@link ConsistencyProtocol#protocolMetaData()} : Returns metadata information of the consistency
* protocol, such as leader, term, and other metadata information in the Raft protocol</li>
* </ul>
*
* @author <a href="mailto:liaochuntao@live.com">liaochuntao</a>
*/
public interface ConsistencyProtocol<T extends Config, P extends RequestProcessor> extends CommandOperations {
/**
* Consistency protocol initialization: perform initialization operations based on the incoming.
* Config 一致性协议初始化根据Config 实现类
*
* @param config {@link Config}
*/
void init(T config);
/**
* Add a request handler.
*
* @param processors {@link RequestProcessor}
*/
void addRequestProcessors(Collection<P> processors);
/**
* Copy of metadata information for this consensus protocol.
* 该一致性协议的元数据信息
*
* @return metaData {@link ProtocolMetaData}
*/
ProtocolMetaData protocolMetaData();
/**
* Obtain data according to the request.
*
* @param request request
* @return data {@link Response}
* @throws Exception {@link Exception}
*/
Response getData(ReadRequest request) throws Exception;
/**
* Get data asynchronously.
*
* @param request request
* @return data {@link CompletableFuture}
*/
CompletableFuture<Response> aGetData(ReadRequest request);
/**
* Data operation, returning submission results synchronously.
* 同步数据提交,在 Datum 中已携带相应的数据操作信息
*
* @param request {@link com.alibaba.nacos.consistency.entity.WriteRequest}
* @return submit operation result {@link Response}
* @throws Exception {@link Exception}
*/
Response write(WriteRequest request) throws Exception;
/**
* Data submission operation, returning submission results asynchronously.
* 异步数据提交,在 Datum中已携带相应的数据操作信息返回一个Future自行操作提交发生的异常会在CompleteFuture中
*
* @param request {@link com.alibaba.nacos.consistency.entity.WriteRequest}
* @return {@link CompletableFuture} submit result
* @throws Exception when submit throw Exception
*/
CompletableFuture<Response> writeAsync(WriteRequest request);
/**
* New member list .
* 新的成员节点列表,一致性协议自行处理相应的成员节点是加入还是离开
*
* @param addresses [ip:port, ip:port, ...]
*/
void memberChange(Set<String> addresses);
/**
* Consistency agreement service shut down .
* 一致性协议服务关闭
*/
void shutdown();
}

View File

@ -0,0 +1,49 @@
/*
* 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.consistency;
/**
* Apply action.
*
* @author nkorange
*/
public enum DataOperation {
/**
* Data add.
*/
ADD,
/**
* Data changed.
*/
CHANGE,
/**
* Data deleted.
*/
DELETE,
/**
* Data verify.
*/
VERIFY,
/**
* Data Snapshot.
*/
SNAPSHOT,
/**
* Data query.
*/
QUERY;
}

View File

@ -0,0 +1,61 @@
/*
* 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.consistency;
import java.util.Map;
/**
* Id generator.
*
* @author <a href="mailto:liaochuntao@live.com">liaochuntao</a>
*/
public interface IdGenerator {
/**
* Perform the corresponding initialization operation.
*/
void init();
/**
* current id info.
*
* @return current id
*/
long currentId();
/**
* worker id info.
*
* @return worker id
*/
long workerId();
/**
* Get next id.
*
* @return next id
*/
long nextId();
/**
* Returns information for the current IDGenerator.
*
* @return {@link Map}
*/
Map<Object, Object> info();
}

View File

@ -0,0 +1,107 @@
/*
* 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.consistency;
import com.alibaba.nacos.consistency.entity.GetRequest;
import com.alibaba.nacos.consistency.entity.Log;
import com.alibaba.nacos.consistency.entity.ReadRequest;
import com.alibaba.nacos.consistency.entity.WriteRequest;
import com.alibaba.nacos.consistency.exception.ConsistencyException;
import com.google.protobuf.Message;
/**
* protobuf message utils.
*
* @author <a href="mailto:liaochuntao@live.com">liaochuntao</a>
*/
public class ProtoMessageUtil {
/**
* should be different from field tags of ReadRequest or WriteQuest.
*/
public static final int REQUEST_TYPE_FIELD_TAG = 7 << 3;
public static final int REQUEST_TYPE_READ = 1;
public static final int REQUEST_TYPE_WRITE = 2;
/**
* Converts the byte array to a specific Protobuf object.
* Internally, the protobuf new and old objects are compatible.
*
* @param bytes An array of bytes
* @return Message
*/
public static Message parse(byte[] bytes) {
Message result;
try {
if (bytes[0] == REQUEST_TYPE_FIELD_TAG) {
if (bytes[1] == REQUEST_TYPE_READ) {
result = ReadRequest.parseFrom(bytes);
} else {
result = WriteRequest.parseFrom(bytes);
}
return result;
}
} catch (Throwable ignore) {
}
// old consistency entity, will be @Deprecated in future
try {
GetRequest request = GetRequest.parseFrom(bytes);
return convertToReadRequest(request);
} catch (Throwable ignore) {
}
try {
Log log = Log.parseFrom(bytes);
return convertToWriteRequest(log);
} catch (Throwable ignore) {
}
throw new ConsistencyException("The current array cannot be serialized to the corresponding object");
}
/**
* convert Log to WriteRequest.
*
* @param log log
* @return {@link WriteRequest}
*/
public static WriteRequest convertToWriteRequest(Log log) {
return WriteRequest.newBuilder().setKey(log.getKey()).setGroup(log.getGroup())
.setData(log.getData())
.setType(log.getType())
.setOperation(log.getOperation())
.putAllExtendInfo(log.getExtendInfoMap())
.build();
}
/**
* convert Log to ReadRequest.
*
* @param request request
* @return {@link ReadRequest}
*/
public static ReadRequest convertToReadRequest(GetRequest request) {
return ReadRequest.newBuilder()
.setGroup(request.getGroup())
.setData(request.getData())
.putAllExtendInfo(request.getExtendInfoMap())
.build();
}
}

View File

@ -0,0 +1,173 @@
/*
* 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.consistency;
import com.alibaba.nacos.common.utils.Observable;
import com.alibaba.nacos.common.utils.Observer;
import com.alibaba.nacos.common.utils.StringUtils;
import org.javatuples.Pair;
import java.util.Map;
import java.util.TreeMap;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.locks.ReentrantReadWriteLock;
/**
* Consistent protocol metadata information, &lt;Key, &lt;Key, Value &gt;&gt; structure Listeners that can register to
* listen to changes in value.
*
* @author <a href="mailto:liaochuntao@live.com">liaochuntao</a>
*/
@SuppressWarnings("PMD.Rule:CollectionInitShouldAssignCapacityRule")
public final class ProtocolMetaData {
private final Map<String, MetaData> metaDataMap = new ConcurrentHashMap<>(4);
public Map<String, Map<Object, Object>> getMetaDataMap() {
return metaDataMap.entrySet().stream().map(entry -> Pair.with(entry.getKey(),
entry.getValue().getItemMap().entrySet().stream()
.collect(TreeMap::new, (m, e) -> m.put(e.getKey(), e.getValue().getData()), TreeMap::putAll)))
.collect(TreeMap::new, (m, e) -> m.put(e.getValue0(), e.getValue1()), TreeMap::putAll);
}
// Does not guarantee thread safety, there may be two updates of
// time-1 and time-2 (time-1 <time-2), but time-1 data overwrites time-2
/**
* save target consistency protocol metadata.
*
* @param mapMap {@link Map}
*/
public void load(final Map<String, Map<String, Object>> mapMap) {
mapMap.forEach((s, map) -> {
metaDataMap.computeIfAbsent(s, MetaData::new);
final MetaData data = metaDataMap.get(s);
map.forEach(data::put);
});
}
/**
* get protocol metadata by group and key.
*
* @param group group name
* @param subKey key
* @return target value
*/
public Object get(String group, String subKey) {
if (StringUtils.isBlank(subKey)) {
return metaDataMap.get(group);
} else {
if (metaDataMap.containsKey(group)) {
return metaDataMap.get(group).get(subKey);
}
return null;
}
}
/**
* If MetaData does not exist, actively create a MetaData.
*/
public void subscribe(final String group, final String key, final Observer observer) {
metaDataMap.computeIfAbsent(group, s -> new MetaData(group)).subscribe(key, observer);
}
public void unSubscribe(final String group, final String key, final Observer observer) {
metaDataMap.computeIfAbsent(group, s -> new MetaData(group)).unSubscribe(key, observer);
}
@SuppressWarnings("PMD.ThreadPoolCreationRule")
public static final class MetaData {
private final Map<String, ValueItem> itemMap = new ConcurrentHashMap<>(8);
private final transient String group;
public MetaData(String group) {
this.group = group;
}
public Map<String, ValueItem> getItemMap() {
return itemMap;
}
void put(String key, Object value) {
ValueItem item = itemMap.computeIfAbsent(key, s -> new ValueItem(group + "/" + key));
item.setData(value);
}
public ValueItem get(String key) {
return itemMap.get(key);
}
// If ValueItem does not exist, actively create a ValueItem
void subscribe(final String key, final Observer observer) {
final ValueItem item = itemMap.computeIfAbsent(key, s -> new ValueItem(group + "/" + key));
item.addObserver(observer);
}
void unSubscribe(final String key, final Observer observer) {
final ValueItem item = itemMap.get(key);
if (item == null) {
return;
}
item.deleteObserver(observer);
}
}
public static final class ValueItem extends Observable {
private final transient String path;
private final transient ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
private final transient ReentrantReadWriteLock.ReadLock readLock = lock.readLock();
private final transient ReentrantReadWriteLock.WriteLock writeLock = lock.writeLock();
private volatile Object data;
public ValueItem(String path) {
this.path = path;
}
public Object getData() {
readLock.lock();
try {
return data;
} finally {
readLock.unlock();
}
}
void setData(Object data) {
writeLock.lock();
try {
this.data = data;
setChanged();
notifyObservers();
} finally {
writeLock.unlock();
}
}
public String getPath() {
return path;
}
}
}

View File

@ -0,0 +1,65 @@
/*
* 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.consistency;
import com.alibaba.nacos.consistency.entity.ReadRequest;
import com.alibaba.nacos.consistency.entity.Response;
import com.alibaba.nacos.consistency.entity.WriteRequest;
/**
* Can be discovered through SPI or Spring, This interface is just a function definition interface. Different
* consistency protocols have their pwd
* LogDispatcher. It is not recommended to directly implement this interface.
*
* @author <a href="mailto:liaochuntao@live.com">liaochuntao</a>
*/
@SuppressWarnings("PMD.AbstractClassShouldStartWithAbstractNamingRule")
public abstract class RequestProcessor {
/**
* get data by key.
*
* @param request request {@link com.alibaba.nacos.consistency.entity.ReadRequest}
* @return target type data
*/
public abstract Response onRequest(ReadRequest request);
/**
* Process Submitted Log.
*
* @param log {@link WriteRequest}
* @return {@link boolean}
*/
public abstract Response onApply(WriteRequest log);
/**
* Irremediable errors that need to trigger business price cuts.
*
* @param error {@link Throwable}
*/
public void onError(Throwable error) {
}
/**
* In order for the state machine that handles the transaction to be able to route the Log to the correct
* LogProcessor, the LogProcessor needs to have an identity information.
*
* @return Business unique identification name
*/
public abstract String group();
}

View File

@ -0,0 +1,53 @@
/*
* 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.consistency;
import com.alibaba.nacos.common.spi.NacosServiceLoader;
import com.alibaba.nacos.consistency.serialize.HessianSerializer;
import java.util.HashMap;
import java.util.Map;
/**
* Serialization factory.
*
* @author <a href="mailto:liaochuntao@live.com">liaochuntao</a>
*/
public class SerializeFactory {
public static final String HESSIAN_INDEX = "Hessian".toLowerCase();
private static final Map<String, Serializer> SERIALIZER_MAP = new HashMap<>(4);
public static String defaultSerializer = HESSIAN_INDEX;
static {
Serializer serializer = new HessianSerializer();
SERIALIZER_MAP.put(HESSIAN_INDEX, serializer);
for (Serializer item : NacosServiceLoader.load(Serializer.class)) {
SERIALIZER_MAP.put(item.name().toLowerCase(), item);
}
}
public static Serializer getDefault() {
return SERIALIZER_MAP.get(defaultSerializer);
}
public static Serializer getSerializer(String type) {
return SERIALIZER_MAP.get(type.toLowerCase());
}
}

View File

@ -0,0 +1,99 @@
/*
* 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.consistency;
import java.lang.reflect.Type;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
/**
* Serialization interface.
*
* @author <a href="mailto:liaochuntao@live.com">liaochuntao</a>
*/
public interface Serializer {
Map<String, Class<?>> CLASS_CACHE = new ConcurrentHashMap<>(8);
/**
* Deserialize the data.
*
* @param data byte[]
* @param <T> class type
* @return target object instance
*/
<T> T deserialize(byte[] data);
/**
* Deserialize the data.
*
* @param data byte[]
* @param cls class
* @param <T> class type
* @return target object instance
*/
<T> T deserialize(byte[] data, Class<T> cls);
/**
* Deserialize the data.
*
* @param data byte[]
* @param type data type
* @param <T> class type
* @return target object instance
*/
<T> T deserialize(byte[] data, Type type);
/**
* Deserialize the data.
*
* @param data byte[]
* @param classFullName class full name
* @param <T> class type
* @return target object instance
*/
default <T> T deserialize(byte[] data, String classFullName) {
try {
Class<?> cls = CLASS_CACHE.computeIfAbsent(classFullName, name -> {
try {
return Class.forName(classFullName);
} catch (ClassNotFoundException e) {
throw new RuntimeException(e);
}
});
return (T) deserialize(data, cls);
} catch (Exception ignore) {
return null;
}
}
/**
* Serialize the object.
*
* @param obj target obj
* @return byte[]
*/
<T> byte[] serialize(T obj);
/**
* The name of the serializer implementer.
*
* @return name
*/
String name();
}

View 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.consistency.ap;
import com.alibaba.nacos.consistency.Config;
import com.alibaba.nacos.consistency.ConsistencyProtocol;
/**
* ap protocol.
*
* @author <a href="mailto:liaochuntao@live.com">liaochuntao</a>
*/
@SuppressWarnings("all")
public interface APProtocol<C extends Config, P extends RequestProcessor4AP> extends ConsistencyProtocol<C, P> {
}

View File

@ -0,0 +1,29 @@
/*
* 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.consistency.ap;
import com.alibaba.nacos.consistency.RequestProcessor;
/**
* log processor for ap.
*
* @author <a href="mailto:liaochuntao@live.com">liaochuntao</a>
*/
@SuppressWarnings("all")
public abstract class RequestProcessor4AP extends RequestProcessor {
}

View File

@ -0,0 +1,38 @@
/*
* 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.consistency.cp;
import com.alibaba.nacos.consistency.Config;
import com.alibaba.nacos.consistency.ConsistencyProtocol;
/**
* cp protocol.
*
* @author <a href="mailto:liaochuntao@live.com">liaochuntao</a>
*/
@SuppressWarnings("all")
public interface CPProtocol<C extends Config, P extends RequestProcessor4CP> extends ConsistencyProtocol<C, P> {
/**
* Returns whether this node is a leader node
*
* @param group business module info
* @return is leader
*/
boolean isLeader(String group);
}

View File

@ -0,0 +1,34 @@
/*
* 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.consistency.cp;
/**
* Key value of metadata information of CP protocol.
*
* @author <a href="mailto:liaochuntao@live.com">liaochuntao</a>
*/
public class MetadataKey {
public static final String LEADER_META_DATA = "leader";
public static final String TERM_META_DATA = "term";
public static final String RAFT_GROUP_MEMBER = "raftGroupMember";
public static final String ERR_MSG = "errMsg";
}

View File

@ -0,0 +1,44 @@
/*
* 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.consistency.cp;
import com.alibaba.nacos.consistency.RequestProcessor;
import com.alibaba.nacos.consistency.snapshot.SnapshotOperation;
import java.util.Collections;
import java.util.List;
/**
* log processor for cp.
*
* @author <a href="mailto:liaochuntao@live.com">liaochuntao</a>
*/
@SuppressWarnings("all")
public abstract class RequestProcessor4CP extends RequestProcessor {
/**
* Discovery snapshot handler It is up to LogProcessor to decide which SnapshotOperate should be loaded and saved by
* itself.
*
* @return {@link List <SnapshotOperate>}
*/
public List<SnapshotOperation> loadSnapshotOperate() {
return Collections.emptyList();
}
}

View File

@ -0,0 +1,49 @@
/*
* 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.consistency.exception;
/**
* Conformance protocol internal exceptions.
*
* @author <a href="mailto:liaochuntao@live.com">liaochuntao</a>
*/
public class ConsistencyException extends RuntimeException {
private static final long serialVersionUID = 1935132712388069418L;
public ConsistencyException() {
super();
}
public ConsistencyException(String message) {
super(message);
}
public ConsistencyException(String message, Throwable cause) {
super(message, cause);
}
public ConsistencyException(Throwable cause) {
super(cause);
}
protected ConsistencyException(String message, Throwable cause, boolean enableSuppression,
boolean writableStackTrace) {
super(message, cause, enableSuppression, writableStackTrace);
}
}

View File

@ -0,0 +1,106 @@
/*
* 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.consistency.serialize;
import com.alibaba.nacos.api.exception.runtime.NacosDeserializationException;
import com.alibaba.nacos.common.utils.ByteUtils;
import com.alibaba.nacos.consistency.Serializer;
import com.caucho.hessian.io.Hessian2Input;
import com.caucho.hessian.io.Hessian2Output;
import com.caucho.hessian.io.SerializerFactory;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.lang.reflect.Type;
/**
* Serializer implement by hessian.
*
* @author <a href="mailto:liaochuntao@live.com">liaochuntao</a>
*/
@SuppressWarnings("all")
public class HessianSerializer implements Serializer {
private static final String NAME = "Hessian";
private SerializerFactory serializerFactory = new NacosHessianSerializerFactory();
public HessianSerializer() {
}
@Override
public <T> T deserialize(byte[] data) {
return deseiralize0(data);
}
@Override
public <T> T deserialize(byte[] data, Class<T> cls) {
T result = deserialize(data);
if (result == null) {
return null;
}
if (cls.isAssignableFrom(result.getClass())) {
return result;
}
throw new NacosDeserializationException(cls, new ClassCastException(
"%s cannot be cast to %s".format(result.getClass().getCanonicalName(), cls.getCanonicalName())));
}
@Override
public <T> T deserialize(byte[] data, Type type) {
return deserialize(data);
}
private <T> T deseiralize0(byte[] data) {
if (ByteUtils.isEmpty(data)) {
return null;
}
Hessian2Input input = new Hessian2Input(new ByteArrayInputStream(data));
input.setSerializerFactory(serializerFactory);
Object resultObject;
try {
resultObject = input.readObject();
input.close();
} catch (IOException e) {
throw new RuntimeException("IOException occurred when Hessian serializer decode!", e);
}
return (T) resultObject;
}
@Override
public <T> byte[] serialize(T obj) {
ByteArrayOutputStream byteArray = new ByteArrayOutputStream();
Hessian2Output output = new Hessian2Output(byteArray);
output.setSerializerFactory(serializerFactory);
try {
output.writeObject(obj);
output.close();
} catch (IOException e) {
throw new RuntimeException("IOException occurred when Hessian serializer encode!", e);
}
return byteArray.toByteArray();
}
@Override
public String name() {
return NAME;
}
}

View File

@ -0,0 +1,64 @@
/*
* 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.consistency.serialize;
import com.alibaba.nacos.common.utils.ByteUtils;
import com.alibaba.nacos.common.utils.JacksonUtils;
import com.alibaba.nacos.consistency.Serializer;
import java.lang.reflect.Type;
/**
* Serializer implement by jackson.
*
* @author xiweng.yy
*/
public class JacksonSerializer implements Serializer {
private static final String NAME = "JSON";
@Override
public <T> T deserialize(byte[] data) {
throw new UnsupportedOperationException("Jackson serializer can't support deserialize json without type");
}
@Override
public <T> T deserialize(byte[] data, Class<T> cls) {
if (ByteUtils.isEmpty(data)) {
return null;
}
return JacksonUtils.toObj(data, cls);
}
@Override
public <T> T deserialize(byte[] data, Type type) {
if (ByteUtils.isEmpty(data)) {
return null;
}
return JacksonUtils.toObj(data, type);
}
@Override
public <T> byte[] serialize(T obj) {
return JacksonUtils.toJsonBytes(obj);
}
@Override
public String name() {
return NAME;
}
}

View File

@ -0,0 +1,146 @@
/*
* Copyright 1999-2023 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.consistency.serialize;
import com.caucho.hessian.io.SerializerFactory;
import java.text.SimpleDateFormat;
import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
import java.util.TreeSet;
import java.util.WeakHashMap;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.ConcurrentSkipListMap;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.atomic.AtomicReference;
/**
* Nacos Hessian Serializer Factory.
*
* @author xiweng.yy
*/
public class NacosHessianSerializerFactory extends SerializerFactory {
NacosHessianSerializerFactory() {
super();
super.getClassFactory().setWhitelist(true);
allowBasicType();
allowCollections();
allowConcurrent();
allowTime();
super.getClassFactory().allow("com.alibaba.nacos.*");
}
private void allowBasicType() {
super.getClassFactory().allow(boolean.class.getCanonicalName());
super.getClassFactory().allow(byte.class.getCanonicalName());
super.getClassFactory().allow(char.class.getCanonicalName());
super.getClassFactory().allow(double.class.getCanonicalName());
super.getClassFactory().allow(float.class.getCanonicalName());
super.getClassFactory().allow(int.class.getCanonicalName());
super.getClassFactory().allow(long.class.getCanonicalName());
super.getClassFactory().allow(short.class.getCanonicalName());
super.getClassFactory().allow(Boolean.class.getCanonicalName());
super.getClassFactory().allow(Byte.class.getCanonicalName());
super.getClassFactory().allow(Character.class.getCanonicalName());
super.getClassFactory().allow(Double.class.getCanonicalName());
super.getClassFactory().allow(Float.class.getCanonicalName());
super.getClassFactory().allow(Integer.class.getCanonicalName());
super.getClassFactory().allow(Long.class.getCanonicalName());
super.getClassFactory().allow(Short.class.getCanonicalName());
super.getClassFactory().allow(Number.class.getCanonicalName());
super.getClassFactory().allow(Class.class.getCanonicalName());
super.getClassFactory().allow(String.class.getCanonicalName());
}
private void allowCollections() {
super.getClassFactory().allow(List.class.getCanonicalName());
super.getClassFactory().allow(ArrayList.class.getCanonicalName());
super.getClassFactory().allow(LinkedList.class.getCanonicalName());
super.getClassFactory().allow(Set.class.getCanonicalName());
super.getClassFactory().allow(HashSet.class.getCanonicalName());
super.getClassFactory().allow(LinkedHashSet.class.getCanonicalName());
super.getClassFactory().allow(TreeSet.class.getCanonicalName());
super.getClassFactory().allow(Map.class.getCanonicalName());
super.getClassFactory().allow(HashMap.class.getCanonicalName());
super.getClassFactory().allow(LinkedHashMap.class.getCanonicalName());
super.getClassFactory().allow(TreeMap.class.getCanonicalName());
super.getClassFactory().allow(WeakHashMap.class.getCanonicalName());
super.getClassFactory().allow("java.util.Arrays$ArrayList");
super.getClassFactory().allow("java.util.Collections$EmptyList");
super.getClassFactory().allow("java.util.Collections$EmptyMap");
super.getClassFactory().allow("java.util.Collections$SingletonSet");
super.getClassFactory().allow("java.util.Collections$SingletonList");
super.getClassFactory().allow("java.util.Collections$UnmodifiableCollection");
super.getClassFactory().allow("java.util.Collections$UnmodifiableList");
super.getClassFactory().allow("java.util.Collections$UnmodifiableMap");
super.getClassFactory().allow("java.util.Collections$UnmodifiableNavigableMap");
super.getClassFactory().allow("java.util.Collections$UnmodifiableNavigableSet");
super.getClassFactory().allow("java.util.Collections$UnmodifiableRandomAccessList");
super.getClassFactory().allow("java.util.Collections$UnmodifiableSet");
super.getClassFactory().allow("java.util.Collections$UnmodifiableSortedMap");
super.getClassFactory().allow("java.util.Collections$UnmodifiableSortedSet");
}
private void allowConcurrent() {
super.getClassFactory().allow(AtomicBoolean.class.getCanonicalName());
super.getClassFactory().allow(AtomicInteger.class.getCanonicalName());
super.getClassFactory().allow(AtomicLong.class.getCanonicalName());
super.getClassFactory().allow(AtomicReference.class.getCanonicalName());
super.getClassFactory().allow(ConcurrentMap.class.getCanonicalName());
super.getClassFactory().allow(ConcurrentHashMap.class.getCanonicalName());
super.getClassFactory().allow(ConcurrentSkipListMap.class.getCanonicalName());
super.getClassFactory().allow(CopyOnWriteArrayList.class.getCanonicalName());
}
private void allowTime() {
super.getClassFactory().allow(SimpleDateFormat.class.getCanonicalName());
super.getClassFactory().allow(DateTimeFormatter.class.getCanonicalName());
super.getClassFactory().allow(Instant.class.getCanonicalName());
super.getClassFactory().allow(LocalDate.class.getCanonicalName());
super.getClassFactory().allow(LocalDateTime.class.getCanonicalName());
super.getClassFactory().allow(LocalTime.class.getCanonicalName());
super.getClassFactory().allow(TimeUnit.class.getCanonicalName());
super.getClassFactory().allow(Date.class.getCanonicalName());
super.getClassFactory().allow(Calendar.class.getCanonicalName());
}
}

View File

@ -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.consistency.snapshot;
import java.util.Properties;
/**
* Meta information for the snapshot file.
*
* @author <a href="mailto:liaochuntao@live.com">liaochuntao</a>
*/
public class LocalFileMeta {
private final Properties fileMeta;
public LocalFileMeta() {
this.fileMeta = new Properties();
}
public LocalFileMeta(Properties properties) {
this.fileMeta = properties;
}
public LocalFileMeta append(Object key, Object value) {
fileMeta.put(key, value);
return this;
}
public Object get(String key) {
return fileMeta.getProperty(key);
}
public Properties getFileMeta() {
return fileMeta;
}
@Override
public String toString() {
return "LocalFileMeta{" + "fileMeta=" + fileMeta + '}';
}
}

View File

@ -0,0 +1,49 @@
/*
* 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.consistency.snapshot;
import java.util.Collections;
import java.util.Map;
/**
* Read the snapshot file interface.
*
* @author <a href="mailto:liaochuntao@live.com">liaochuntao</a>
*/
public class Reader {
private final String path;
private final Map<String, LocalFileMeta> allFiles;
public Reader(String path, Map<String, LocalFileMeta> allFiles) {
this.path = path;
this.allFiles = Collections.unmodifiableMap(allFiles);
}
public String getPath() {
return path;
}
public Map<String, LocalFileMeta> listFiles() {
return allFiles;
}
public LocalFileMeta getFileMeta(String fileName) {
return allFiles.get(fileName);
}
}

View File

@ -0,0 +1,44 @@
/*
* 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.consistency.snapshot;
import java.util.function.BiConsumer;
/**
* Custom snapshot operation interface Discovery via SPI.
*
* @author <a href="mailto:liaochuntao@live.com">liaochuntao</a>
*/
public interface SnapshotOperation {
/**
* do snapshot save operation.
*
* @param writer {@link Writer}
* @param callFinally Callback {@link BiConsumer} when the snapshot operation is complete
*/
void onSnapshotSave(Writer writer, BiConsumer<Boolean, Throwable> callFinally);
/**
* do snapshot load operation.
*
* @param reader {@link Reader}
* @return operation label
*/
boolean onSnapshotLoad(Reader reader);
}

View File

@ -0,0 +1,79 @@
/*
* 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.consistency.snapshot;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
/**
* Snapshot write interface.
*
* @author <a href="mailto:liaochuntao@live.com">liaochuntao</a>
*/
public class Writer {
private final Map<String, LocalFileMeta> files = new HashMap<>();
private String path;
public Writer(String path) {
this.path = path;
}
public String getPath() {
return path;
}
/**
* Adds a snapshot file without metadata.
*
* @param fileName file name
* @return true on success
*/
public boolean addFile(final String fileName) {
files.put(fileName, new LocalFileMeta().append("file-name", fileName));
return true;
}
/**
* Adds a snapshot file with metadata.
*
* @param fileName file name
* @return true on success
*/
public boolean addFile(final String fileName, final LocalFileMeta meta) {
files.put(fileName, meta);
return true;
}
/**
* Remove a snapshot file.
*
* @param fileName file name
* @return true on success
*/
public boolean removeFile(final String fileName) {
files.remove(fileName);
return true;
}
public Map<String, LocalFileMeta> listFiles() {
return Collections.unmodifiableMap(files);
}
}

View File

@ -0,0 +1,38 @@
/*
* 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.
*/
syntax = "proto3";
option java_multiple_files = true;
option java_package = "com.alibaba.nacos.consistency.entity";
//Deprecated
message Log {
string group = 1;
string key = 2;
bytes data = 3;
string type = 4;
string operation = 5;
map<string, string> extendInfo = 6;
}
//Deprecated
message GetRequest {
string group = 1;
bytes data = 2;
map<string, string> extendInfo = 3;
}

View File

@ -0,0 +1,42 @@
/*
* 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.
*/
syntax = "proto3";
option java_multiple_files = true;
option java_package = "com.alibaba.nacos.consistency.entity";
message WriteRequest {
string group = 1;
string key = 2;
bytes data = 3;
string type = 4;
string operation = 5;
map<string, string> extendInfo = 6;
}
message ReadRequest {
string group = 1;
bytes data = 2;
map<string, string> extendInfo = 3;
}
message Response {
bytes data = 1;
string errMsg = 2;
bool success = 3;
}

View File

@ -0,0 +1,17 @@
#
# 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.
#
com.alibaba.nacos.consistency.serialize.JacksonSerializer

View File

@ -0,0 +1,135 @@
/*
* 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.consistency;
import com.alibaba.nacos.consistency.entity.GetRequest;
import com.alibaba.nacos.consistency.entity.Log;
import com.alibaba.nacos.consistency.entity.ReadRequest;
import com.alibaba.nacos.consistency.entity.WriteRequest;
import com.google.protobuf.ByteString;
import org.junit.Test;
import static org.junit.Assert.assertEquals;
import java.nio.ByteBuffer;
public class ProtoMessageUtilTest {
@Test
public void testProto() throws Exception {
WriteRequest request = WriteRequest.newBuilder().setKey("test-proto-new").build();
byte[] bytes = request.toByteArray();
Log log = Log.parseFrom(bytes);
assertEquals(request.getKey(), log.getKey());
}
@Test
public void testParseReadRequestWithRequestTypeField() {
String group = "test";
ByteString data = ByteString.copyFrom("data".getBytes());
ReadRequest testCase = ReadRequest.newBuilder().setGroup(group).setData(data).build();
byte[] requestTypeFieldBytes = new byte[2];
requestTypeFieldBytes[0] = ProtoMessageUtil.REQUEST_TYPE_FIELD_TAG;
requestTypeFieldBytes[1] = ProtoMessageUtil.REQUEST_TYPE_READ;
byte[] dataBytes = testCase.toByteArray();
ByteBuffer byteBuffer = (ByteBuffer) ByteBuffer.allocate(requestTypeFieldBytes.length + dataBytes.length)
.put(requestTypeFieldBytes).put(dataBytes).position(0);
Object actual = ProtoMessageUtil.parse(byteBuffer.array());
assertEquals(ReadRequest.class, testCase.getClass());
assertEquals(group, ((ReadRequest) actual).getGroup());
assertEquals(data, ((ReadRequest) actual).getData());
}
@Test
public void testParseWriteRequestWithRequestTypeField() {
String group = "test";
ByteString data = ByteString.copyFrom("data".getBytes());
WriteRequest testCase = WriteRequest.newBuilder().setGroup(group).setData(data).build();
byte[] requestTypeFieldBytes = new byte[2];
requestTypeFieldBytes[0] = ProtoMessageUtil.REQUEST_TYPE_FIELD_TAG;
requestTypeFieldBytes[1] = ProtoMessageUtil.REQUEST_TYPE_WRITE;
byte[] dataBytes = testCase.toByteArray();
ByteBuffer byteBuffer = (ByteBuffer) ByteBuffer.allocate(requestTypeFieldBytes.length + dataBytes.length)
.put(requestTypeFieldBytes).put(dataBytes).position(0);
Object actual = ProtoMessageUtil.parse(byteBuffer.array());
assertEquals(WriteRequest.class, testCase.getClass());
assertEquals(group, ((WriteRequest) actual).getGroup());
assertEquals(data, ((WriteRequest) actual).getData());
}
@Test
public void testParseReadRequest() {
String group = "test";
ByteString data = ByteString.copyFrom("data".getBytes());
ReadRequest testCase = ReadRequest.newBuilder().setGroup(group).setData(data).build();
Object actual = ProtoMessageUtil.parse(testCase.toByteArray());
assertEquals(ReadRequest.class, testCase.getClass());
assertEquals(group, ((ReadRequest) actual).getGroup());
assertEquals(data, ((ReadRequest) actual).getData());
}
@Test
public void testParseWriteRequest() {
String group = "test";
ByteString data = ByteString.copyFrom("data".getBytes());
WriteRequest testCase = WriteRequest.newBuilder().setGroup(group).setData(data).build();
Object actual = ProtoMessageUtil.parse(testCase.toByteArray());
assertEquals(WriteRequest.class, testCase.getClass());
assertEquals(group, ((WriteRequest) actual).getGroup());
assertEquals(data, ((WriteRequest) actual).getData());
}
@Test
public void testConvertToReadRequest() {
ByteString data = ByteString.copyFrom("data".getBytes());
String group = "test";
GetRequest getRequest = GetRequest.newBuilder().setGroup(group).setData(data).putExtendInfo("k", "v").build();
ReadRequest readRequest = ProtoMessageUtil.convertToReadRequest(getRequest);
assertEquals(group, readRequest.getGroup());
assertEquals(data, readRequest.getData());
assertEquals(1, readRequest.getExtendInfoCount());
}
@Test
public void testConvertToWriteRequest() {
ByteString data = ByteString.copyFrom("data".getBytes());
Log log = Log.newBuilder().setKey("key").setGroup("group").setData(data).setOperation("o")
.putExtendInfo("k", "v").build();
WriteRequest writeRequest = ProtoMessageUtil.convertToWriteRequest(log);
assertEquals(1, writeRequest.getExtendInfoCount());
assertEquals(data, writeRequest.getData());
assertEquals("key", writeRequest.getKey());
assertEquals("group", writeRequest.getGroup());
assertEquals("o", writeRequest.getOperation());
}
}

View File

@ -0,0 +1,75 @@
/*
* 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.consistency;
import com.alibaba.nacos.common.utils.JacksonUtils;
import org.junit.Assert;
import org.junit.Test;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
public class ProtocolMetaDataTest {
@Test
public void testProtocolMetaData() throws Exception {
Map<String, Map<String, Object>> map = new HashMap<>();
Map<String, Object> data = new HashMap<>();
data.put("test-1", new Date());
data.put("test_2", new Date());
map.put("global", data);
ProtocolMetaData metaData = new ProtocolMetaData();
metaData.load(map);
String json = JacksonUtils.toJson(metaData);
AtomicInteger count = new AtomicInteger(0);
CountDownLatch latch = new CountDownLatch(2);
metaData.subscribe("global", "test-1", o -> {
ProtocolMetaData.ValueItem item = (ProtocolMetaData.ValueItem) o;
System.out.println(item.getData());
count.incrementAndGet();
latch.countDown();
});
System.out.println(json);
map = new HashMap<>();
data = new HashMap<>();
data.put("test-1", new Date());
data.put("test_2", new Date());
map.put("global", data);
metaData.load(map);
json = JacksonUtils.toJson(metaData);
System.out.println(json);
latch.await(10_000L, TimeUnit.MILLISECONDS);
Assert.assertEquals(2, count.get());
}
}

View File

@ -0,0 +1,79 @@
/*
* 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.consistency;
import com.alibaba.nacos.consistency.serialize.JacksonSerializer;
import org.junit.Assert;
import org.junit.Test;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.CopyOnWriteArraySet;
public class SerializeFactoryTest {
@Test
public void testListSerialize() {
Serializer serializer = SerializeFactory.getDefault();
List<Integer> logsList = new ArrayList<>();
for (int i = 0; i < 4; i++) {
logsList.add(i);
}
byte[] data = serializer.serialize(logsList);
Assert.assertNotEquals(0, data.length);
ArrayList<Integer> list = serializer.deserialize(data, ArrayList.class);
System.out.println(list);
}
@Test
public void testMapSerialize() {
Serializer serializer = SerializeFactory.getDefault();
Map<Integer, Integer> logsMap = new HashMap<>();
for (int i = 0; i < 4; i++) {
logsMap.put(i, i);
}
byte[] data = serializer.serialize(logsMap);
Assert.assertNotEquals(0, data.length);
Map<Integer, Integer> result = serializer.deserialize(data, HashMap.class);
System.out.println(result);
}
@Test
public void testSetSerialize() {
Serializer serializer = SerializeFactory.getDefault();
Set<Integer> logsMap = new CopyOnWriteArraySet<>();
for (int i = 0; i < 4; i++) {
logsMap.add(i);
}
byte[] data = serializer.serialize(logsMap);
Assert.assertNotEquals(0, data.length);
Set<Integer> result = serializer.deserialize(data, CopyOnWriteArraySet.class);
System.out.println(result);
}
@Test
public void testGetSerializer() {
Serializer serializer = SerializeFactory.getSerializer("JSON");
Assert.assertTrue(serializer instanceof JacksonSerializer);
}
}

View File

@ -0,0 +1,84 @@
/*
* Copyright 1999-2021 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.consistency.serialize;
import com.alibaba.nacos.api.exception.runtime.NacosDeserializationException;
import org.apache.http.HttpException;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import java.io.Serializable;
/**
* {@link HessianSerializer} unit test.
*
* @author Chenhao26
* @date 2022-08-13
*/
public class HessianSerializerTest {
private HessianSerializer hessianSerializer;
@Before
public void setUp() {
hessianSerializer = new HessianSerializer();
}
@Test
public void testSerializerAndDeserialize() {
String data = "xxx";
byte[] bytes = hessianSerializer.serialize(data);
try {
hessianSerializer.deserialize(bytes);
} catch (Exception e) {
Assert.assertTrue(e instanceof RuntimeException);
}
String res1 = hessianSerializer.deserialize(bytes, String.class);
Assert.assertEquals(data, res1);
String res2 = hessianSerializer.deserialize(bytes, "java.lang.String");
Assert.assertEquals(data, res2);
}
@Test
public void testSerializerAndDeserializeForNotAllowClass() {
Serializable data = new HttpException();
byte[] bytes = hessianSerializer.serialize(data);
try {
HttpException res = hessianSerializer.deserialize(bytes);
Assert.fail("deserialize success which is not expected");
} catch (Exception e) {
Assert.assertTrue(e instanceof ClassCastException);
}
try {
HttpException res1 = hessianSerializer.deserialize(bytes, HttpException.class);
} catch (Exception e) {
Assert.assertTrue(e instanceof NacosDeserializationException);
}
}
@Test
public void testName() {
Assert.assertEquals("Hessian", hessianSerializer.name());
}
}

View File

@ -0,0 +1,61 @@
/*
* Copyright 1999-2021 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.consistency.serialize;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
/**
* {@link JacksonSerializer} unit test.
*
* @author chenglu
* @date 2021-07-27 18:32
*/
public class JacksonSerializerTest {
private JacksonSerializer jacksonSerializer;
@Before
public void setUp() {
jacksonSerializer = new JacksonSerializer();
}
@Test
public void testSerializerAndDeserialize() {
String data = "xxx";
byte[] bytes = jacksonSerializer.serialize(data);
try {
jacksonSerializer.deserialize(bytes);
} catch (Exception e) {
Assert.assertTrue(e instanceof UnsupportedOperationException);
}
String res1 = jacksonSerializer.deserialize(bytes, String.class);
Assert.assertEquals(data, res1);
String res2 = jacksonSerializer.deserialize(bytes, "java.lang.String");
Assert.assertEquals(data, res2);
}
@Test
public void testName() {
Assert.assertEquals("JSON", jacksonSerializer.name());
}
}

View File

@ -0,0 +1,44 @@
/*
* Copyright 1999-2021 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.consistency.snapshot;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
/**
* {@link LocalFileMeta} unit test.
*
* @author chenglu
* @date 2021-07-27 18:43
*/
public class LocalFileMetaTest {
private LocalFileMeta fileMeta;
@Before
public void setUp() {
fileMeta = new LocalFileMeta();
}
@Test
public void testAppendAndGet() {
fileMeta.append("key", "value");
Assert.assertEquals("value", fileMeta.get("key"));
}
}

View File

@ -0,0 +1,55 @@
/*
* Copyright 1999-2021 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.consistency.snapshot;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
/**
* {@link Reader} unit test.
*
* @author chenglu
* @date 2021-07-27 18:46
*/
public class ReaderTest {
private Reader reader;
@Before
public void setUp() {
Map<String, LocalFileMeta> map = new HashMap<>(2);
Properties properties = new Properties();
properties.put("k", "v");
map.put("a", new LocalFileMeta(properties));
reader = new Reader("test", map);
}
@Test
public void test() {
Assert.assertEquals("test", reader.getPath());
Assert.assertEquals(1, reader.listFiles().size());
Assert.assertEquals("v", reader.getFileMeta("a").getFileMeta().getProperty("k"));
}
}

View File

@ -0,0 +1,53 @@
/*
* Copyright 1999-2021 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.consistency.snapshot;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
/**
* {@link Writer} unit test.
*
* @author chenglu
* @date 2021-07-28 18:50
*/
public class WriterTest {
private Writer writer;
@Before
public void setUp() {
writer = new Writer("test");
}
@Test
public void test() {
Assert.assertEquals("test", writer.getPath());
Assert.assertTrue(writer.addFile("a"));
Assert.assertTrue(writer.addFile("b", new LocalFileMeta()));
Assert.assertEquals(2, writer.listFiles().size());
Assert.assertTrue(writer.removeFile("a"));
Assert.assertEquals(1, writer.listFiles().size());
}
}