----初始化项目
This commit is contained in:
85
consistency/pom.xml
Normal file
85
consistency/pom.xml
Normal 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>
|
||||
@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
@ -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 initialize,like [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);
|
||||
|
||||
}
|
||||
@ -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();
|
||||
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
@ -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();
|
||||
|
||||
}
|
||||
@ -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();
|
||||
}
|
||||
}
|
||||
@ -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, <Key, <Key, Value >> 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -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();
|
||||
|
||||
}
|
||||
@ -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());
|
||||
}
|
||||
}
|
||||
@ -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();
|
||||
|
||||
}
|
||||
@ -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> {
|
||||
|
||||
}
|
||||
@ -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 {
|
||||
|
||||
}
|
||||
@ -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);
|
||||
|
||||
}
|
||||
@ -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";
|
||||
|
||||
}
|
||||
@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
@ -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());
|
||||
}
|
||||
}
|
||||
@ -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 + '}';
|
||||
}
|
||||
}
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
@ -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);
|
||||
|
||||
}
|
||||
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
38
consistency/src/main/proto/Data.proto
Normal file
38
consistency/src/main/proto/Data.proto
Normal 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;
|
||||
}
|
||||
|
||||
42
consistency/src/main/proto/consistency.proto
Normal file
42
consistency/src/main/proto/consistency.proto
Normal 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;
|
||||
}
|
||||
|
||||
@ -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
|
||||
@ -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());
|
||||
}
|
||||
}
|
||||
@ -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());
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
@ -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());
|
||||
}
|
||||
}
|
||||
@ -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());
|
||||
}
|
||||
}
|
||||
@ -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"));
|
||||
}
|
||||
}
|
||||
@ -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"));
|
||||
}
|
||||
}
|
||||
@ -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());
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user