You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ratis.apache.org by ji...@apache.org on 2017/01/31 21:17:07 UTC
[22/54] [abbrv] incubator-ratis git commit: Renamed the packages from
raft to ratis in preperation for Apache Incubation - Moved all java packages
from org.apache.raft to org.apache.ratis. - Moved native package to
org_apache_ratis, and native lib to l
http://git-wip-us.apache.org/repos/asf/incubator-ratis/blob/7e71a2e0/ratis-project-dist/pom.xml
----------------------------------------------------------------------
diff --git a/ratis-project-dist/pom.xml b/ratis-project-dist/pom.xml
new file mode 100644
index 0000000..5af489d
--- /dev/null
+++ b/ratis-project-dist/pom.xml
@@ -0,0 +1,169 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ 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. See accompanying LICENSE file.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <artifactId>ratis-project</artifactId>
+ <groupId>org.apache.ratis</groupId>
+ <version>1.0-SNAPSHOT</version>
+ <relativePath>../ratis-project</relativePath>
+ </parent>
+
+ <artifactId>ratis-project-dist</artifactId>
+ <groupId>org.apache.ratis</groupId>
+ <name>Ratis Project Dist POM</name>
+ <version>1.0-SNAPSHOT</version>
+
+ <packaging>pom</packaging>
+
+ <properties>
+ <ratis.tmp.dir>${project.build.directory}/test</ratis.tmp.dir>
+ <test.build.data>${project.build.directory}/test/data</test.build.data>
+ <ratis.log.dir>${project.build.directory}/log</ratis.log.dir>
+ <test.build.webapps>${project.build.directory}/test-classes/webapps</test.build.webapps>
+ <test.cache.data>${project.build.directory}/test-classes</test.cache.data>
+ <test.build.classes>${project.build.directory}/test-classes</test.build.classes>
+ </properties>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-jar-plugin</artifactId>
+ <executions>
+ <execution>
+ <id>default-jar</id>
+ <phase>never</phase>
+ </execution>
+ <execution>
+ <id>prepare-jar</id>
+ <phase>prepare-package</phase>
+ <goals>
+ <goal>jar</goal>
+ </goals>
+ </execution>
+ <execution>
+ <id>prepare-test-jar</id>
+ <phase>prepare-package</phase>
+ <goals>
+ <goal>test-jar</goal>
+ </goals>
+ <configuration>
+ <includes>
+ <include>**/*.class</include>
+ <include>webapps/**</include>
+ </includes>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-source-plugin</artifactId>
+ <version>${maven-source-plugin.version}</version>
+ <executions>
+ <execution>
+ <phase>prepare-package</phase>
+ <goals>
+ <goal>jar</goal>
+ <goal>test-jar</goal>
+ </goals>
+ </execution>
+ </executions>
+ <configuration>
+ <attach>true</attach>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>findbugs-maven-plugin</artifactId>
+ <configuration>
+ <excludeFilterFile>${basedir}/dev-support/findbugsExcludeFile.xml</excludeFilterFile>
+ <fork>true</fork>
+ <maxHeap>2048</maxHeap>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+
+ <profiles>
+ <profile>
+ <id>dist</id>
+ <activation>
+ <activeByDefault>false</activeByDefault>
+ </activation>
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-antrun-plugin</artifactId>
+ <executions>
+ <execution>
+ <id>tar</id>
+ <phase>package</phase>
+ <goals>
+ <goal>run</goal>
+ </goals>
+ <configuration>
+ <target if="tar">
+ <!-- Using Unix script to preserve symlinks -->
+ <echo file="${project.build.directory}/dist-maketar.sh">
+ cd "${project.build.directory}"
+ tar cf - ${project.artifactId}-${project.version} | gzip > ${project.artifactId}-${project.version}.tar.gz
+ </echo>
+ <exec executable="${shell-executable}" dir="${project.build.directory}" failonerror="true">
+ <arg line="./dist-maketar.sh"/>
+ </exec>
+ </target>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-assembly-plugin</artifactId>
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.hadoop</groupId>
+ <artifactId>hadoop-assemblies</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ </dependencies>
+ <executions>
+ <execution>
+ <id>dist</id>
+ <phase>prepare-package</phase>
+ <goals>
+ <goal>single</goal>
+ </goals>
+ <configuration>
+ <appendAssemblyId>false</appendAssemblyId>
+ <attach>false</attach>
+ <finalName>${project.artifactId}-${project.version}</finalName>
+ <descriptorRefs>
+ <descriptorRef>hadoop-dist</descriptorRef>
+ </descriptorRefs>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+ </profile>
+ </profiles>
+</project>
http://git-wip-us.apache.org/repos/asf/incubator-ratis/blob/7e71a2e0/ratis-project/pom.xml
----------------------------------------------------------------------
diff --git a/ratis-project/pom.xml b/ratis-project/pom.xml
new file mode 100644
index 0000000..8abf5af
--- /dev/null
+++ b/ratis-project/pom.xml
@@ -0,0 +1,409 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ 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. See accompanying LICENSE file.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <artifactId>ratis-main</artifactId>
+ <groupId>org.apache.ratis</groupId>
+ <version>1.0-SNAPSHOT</version>
+ </parent>
+
+ <artifactId>ratis-project</artifactId>
+ <groupId>org.apache.ratis</groupId>
+ <name>Ratis Project</name>
+ <packaging>pom</packaging>
+
+ <modules>
+ <module>../ratis-project-dist</module>
+ <module>../ratis-common</module>
+ <module>../ratis-client</module>
+ <module>../ratis-server</module>
+ <module>../ratis-hadoop</module>
+ <module>../ratis-grpc</module>
+ <module>../ratis-netty</module>
+ <module>../ratis-examples</module>
+ </modules>
+
+ <properties>
+ <!-- Set the Release year during release -->
+ <release-year>2016</release-year>
+
+ <maven.test.redirectTestOutputToFile>true
+ </maven.test.redirectTestOutputToFile>
+ <test.exclude>_</test.exclude>
+ <test.exclude.pattern>_</test.exclude.pattern>
+
+ <!-- number of threads/forks to use when running tests in parallel, see parallel-tests profile -->
+ <testsThreadCount>4</testsThreadCount>
+
+ <test.build.dir>${project.build.directory}/test-dir</test.build.dir>
+ <test.build.data>${test.build.dir}</test.build.data>
+
+ <findbugs.version>3.0.0</findbugs.version>
+
+ <maven-pdf-plugin.version>1.2</maven-pdf-plugin.version>
+ <build-helper-maven-plugin.version>1.9</build-helper-maven-plugin.version>
+ <exec-maven-plugin.version>1.3.1</exec-maven-plugin.version>
+ <make-maven-plugin.version>1.0-beta-1</make-maven-plugin.version>
+ <native-maven-plugin.version>1.0-alpha-8</native-maven-plugin.version>
+
+ <hadoop.version>3.0.0-alpha1</hadoop.version>
+ </properties>
+
+ <dependencyManagement>
+ <dependencies>
+ <dependency>
+ <artifactId>ratis-proto-shaded</artifactId>
+ <groupId>org.apache.ratis</groupId>
+ <version>${project.version}</version>
+ </dependency>
+
+ <dependency>
+ <artifactId>ratis-common</artifactId>
+ <groupId>org.apache.ratis</groupId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <artifactId>ratis-common</artifactId>
+ <groupId>org.apache.ratis</groupId>
+ <version>${project.version}</version>
+ <type>test-jar</type>
+ </dependency>
+
+ <dependency>
+ <artifactId>ratis-client</artifactId>
+ <groupId>org.apache.ratis</groupId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <artifactId>ratis-client</artifactId>
+ <groupId>org.apache.ratis</groupId>
+ <version>${project.version}</version>
+ <type>test-jar</type>
+ </dependency>
+
+ <dependency>
+ <artifactId>ratis-hadoop</artifactId>
+ <groupId>org.apache.ratis</groupId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <artifactId>ratis-hadoop</artifactId>
+ <groupId>org.apache.ratis</groupId>
+ <version>${project.version}</version>
+ <type>test-jar</type>
+ </dependency>
+
+ <dependency>
+ <artifactId>ratis-grpc</artifactId>
+ <groupId>org.apache.ratis</groupId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <artifactId>ratis-grpc</artifactId>
+ <groupId>org.apache.ratis</groupId>
+ <version>${project.version}</version>
+ <type>test-jar</type>
+ </dependency>
+
+ <dependency>
+ <artifactId>ratis-netty</artifactId>
+ <groupId>org.apache.ratis</groupId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <artifactId>ratis-netty</artifactId>
+ <groupId>org.apache.ratis</groupId>
+ <version>${project.version}</version>
+ <type>test-jar</type>
+ </dependency>
+
+ <dependency>
+ <artifactId>ratis-server</artifactId>
+ <groupId>org.apache.ratis</groupId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <artifactId>ratis-server</artifactId>
+ <groupId>org.apache.ratis</groupId>
+ <version>${project.version}</version>
+ <type>test-jar</type>
+ </dependency>
+
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-api</artifactId>
+ <version>1.7.10</version>
+ </dependency>
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-log4j12</artifactId>
+ <version>1.7.10</version>
+ </dependency>
+
+ <dependency>
+ <groupId>com.google.guava</groupId>
+ <artifactId>guava</artifactId>
+ <version>20.0</version>
+ </dependency>
+
+ <dependency>
+ <groupId>io.netty</groupId>
+ <artifactId>netty-all</artifactId>
+ <version>4.1.6.Final</version>
+ </dependency>
+
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <version>4.11</version>
+ </dependency>
+ <dependency>
+ <groupId>org.mockito</groupId>
+ <artifactId>mockito-all</artifactId>
+ <version>1.8.5</version>
+ </dependency>
+ </dependencies>
+ </dependencyManagement>
+
+ <build>
+ <pluginManagement>
+ <plugins>
+ <plugin>
+ <artifactId>maven-clean-plugin</artifactId>
+ <version>${maven-clean-plugin.version}</version>
+ </plugin>
+ <plugin>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>build-helper-maven-plugin</artifactId>
+ <version>${build-helper-maven-plugin.version}</version>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-install-plugin</artifactId>
+ <version>${maven-install-plugin.version}</version>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-jar-plugin</artifactId>
+ <version>${maven-jar-plugin.version}</version>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-javadoc-plugin</artifactId>
+ <version>${maven-javadoc-plugin.version}</version>
+ <configuration>
+ <additionalparam>-Xmaxwarns 10000</additionalparam>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>findbugs-maven-plugin</artifactId>
+ <version>${findbugs.version}</version>
+ </plugin>
+ <plugin>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>native-maven-plugin</artifactId>
+ <version>${native-maven-plugin.version}</version>
+ </plugin>
+ <plugin>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>make-maven-plugin</artifactId>
+ <version>${make-maven-plugin.version}</version>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-resources-plugin</artifactId>
+ <version>${maven-resources-plugin.version}</version>
+ </plugin>
+ <plugin>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>exec-maven-plugin</artifactId>
+ <version>${exec-maven-plugin.version}</version>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-pdf-plugin</artifactId>
+ <version>${maven-pdf-plugin.version}</version>
+ </plugin>
+
+ <plugin>
+ <groupId>org.apache.hadoop</groupId>
+ <artifactId>hadoop-maven-plugins</artifactId>
+ <version>${hadoop.version}</version>
+ </plugin>
+ </plugins>
+ </pluginManagement>
+
+ <plugins>
+ <plugin>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>findbugs-maven-plugin</artifactId>
+ </plugin>
+
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-antrun-plugin</artifactId>
+ <executions>
+ <execution>
+ <id>create-testdirs</id>
+ <phase>validate</phase>
+ <goals>
+ <goal>run</goal>
+ </goals>
+ <configuration>
+ <target>
+ <mkdir dir="${test.build.dir}"/>
+ <mkdir dir="${test.build.data}"/>
+ </target>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-pdf-plugin</artifactId>
+ <configuration>
+ <outputDirectory>${project.reporting.outputDirectory}
+ </outputDirectory>
+ <includeReports>false</includeReports>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+
+
+ <profiles>
+ <profile>
+ <id>os.linux</id>
+ <activation>
+ <os>
+ <family>!Mac</family>
+ </os>
+ </activation>
+ <properties>
+ <build.platform>${os.name}-${os.arch}-${sun.arch.data.model}
+ </build.platform>
+ </properties>
+ </profile>
+ <profile>
+ <id>os.mac</id>
+ <activation>
+ <os>
+ <family>Mac</family>
+ </os>
+ </activation>
+ <properties>
+ <build.platform>Mac_OS_X-${sun.arch.data.model}</build.platform>
+ </properties>
+ </profile>
+ <profile>
+ <id>native-win</id>
+ <activation>
+ <os>
+ <family>Windows</family>
+ </os>
+ </activation>
+ <properties>
+ <!-- We must use this exact string for egd on Windows, because the -->
+ <!-- JVM will check for an exact string match on this. If found, it -->
+ <!-- will use a native entropy provider. This will not really -->
+ <!-- attempt to open a file at this path. -->
+ <java.security.egd>file:/dev/urandom</java.security.egd>
+ <bundle.snappy.in.bin>true</bundle.snappy.in.bin>
+ <bundle.openssl.in.bin>true</bundle.openssl.in.bin>
+ </properties>
+ </profile>
+ <profile>
+ <id>test-patch</id>
+ <activation>
+ <activeByDefault>false</activeByDefault>
+ </activation>
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <configuration>
+ <fork>true</fork>
+ <source>${javac.version}</source>
+ <target>${javac.version}</target>
+ <compilerArguments>
+ <Xlint/>
+ <Xmaxwarns>9999</Xmaxwarns>
+ </compilerArguments>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+ </profile>
+ <profile>
+ <id>dist</id>
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-javadoc-plugin</artifactId>
+ <executions>
+ <execution>
+ <!-- build javadoc jars per jar for publishing to maven -->
+ <id>module-javadocs</id>
+ <phase>package</phase>
+ <goals>
+ <goal>jar</goal>
+ </goals>
+ <configuration>
+ <destDir>${project.build.directory}</destDir>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-source-plugin</artifactId>
+ <executions>
+ <execution>
+ <!-- builds source jars and attaches them to the project for publishing -->
+ <id>ratis-java-sources</id>
+ <phase>package</phase>
+ <goals>
+ <goal>jar-no-fork</goal>
+ <goal>test-jar-no-fork</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-enforcer-plugin</artifactId>
+ <executions>
+ <execution>
+ <id>dist-enforce</id>
+ <phase>package</phase>
+ <goals>
+ <goal>enforce</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+ </profile>
+ </profiles>
+
+</project>
http://git-wip-us.apache.org/repos/asf/incubator-ratis/blob/7e71a2e0/ratis-proto-shaded/.gitignore
----------------------------------------------------------------------
diff --git a/ratis-proto-shaded/.gitignore b/ratis-proto-shaded/.gitignore
new file mode 100644
index 0000000..ce50505
--- /dev/null
+++ b/ratis-proto-shaded/.gitignore
@@ -0,0 +1,2 @@
+src/main/java
+dependency-reduced-pom.xml
http://git-wip-us.apache.org/repos/asf/incubator-ratis/blob/7e71a2e0/ratis-proto-shaded/README.md
----------------------------------------------------------------------
diff --git a/ratis-proto-shaded/README.md b/ratis-proto-shaded/README.md
new file mode 100644
index 0000000..f7a25d4
--- /dev/null
+++ b/ratis-proto-shaded/README.md
@@ -0,0 +1,23 @@
+# Raft Proto Shaded
+
+This module is to shade protos, protobuf and other libraries such as Netty, gRPC and Hadoop
+so that applications using Raft may use protobuf and other libraries with versions different
+from the versions used here.
+
+Other modules require the shaded sources for compilation. To generate them,
+run the following command under `ratis-proto-shaded/`
+
+- `mvn package -Dcompile-protobuf -DskipTests`
+
+The generated sources are stored in `ratis-proto-shaded/src/main/java/`.
+
+## What are shaded?
+
+| Original packages | Shaded packages |
+| ----------------------------------|----------------------------------------------------------|
+| `com.google.protobuf` | `org.apache.ratis.shaded.com.google.protobuf` |
+| `io.grpc` | `org.apache.ratis.shaded.io.grpc` |
+| `io.netty.handler.codec.protobuf` | `org.apache.ratis.shaded.io.netty.handler.codec.protobuf` |
+| `org.apache.hadoop.ipc.protobuf` | `org.apache.ratis.shaded.org.apache.hadoop.ipc.protobuf` |
+
+The protos defined in this project are stored in the `org.apache.ratis.shaded.proto` package.
http://git-wip-us.apache.org/repos/asf/incubator-ratis/blob/7e71a2e0/ratis-proto-shaded/pom.xml
----------------------------------------------------------------------
diff --git a/ratis-proto-shaded/pom.xml b/ratis-proto-shaded/pom.xml
new file mode 100644
index 0000000..a196811
--- /dev/null
+++ b/ratis-proto-shaded/pom.xml
@@ -0,0 +1,426 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ 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. See accompanying LICENSE file.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <artifactId>ratis-main</artifactId>
+ <groupId>org.apache.ratis</groupId>
+ <version>1.0-SNAPSHOT</version>
+ <relativePath>..</relativePath>
+ </parent>
+
+ <artifactId>ratis-proto-shaded</artifactId>
+ <name>Ratis Proto Shaded</name>
+ <properties>
+ <maven.javadoc.skip>true</maven.javadoc.skip>
+ <!--The Default target dir-->
+ <classes.dir>${project.build.directory}/classes</classes.dir>
+ <!--The Default location for sources-->
+ <sources.dir>src/main/java</sources.dir>
+
+ <!--Version of protobuf to be shaded -->
+ <shaded.protobuf.version>3.1.0</shaded.protobuf.version>
+ <!--Version of grpc to be shaded -->
+ <shaded.grpc.version>1.0.1</shaded.grpc.version>
+ <!--Version of Hadoop to be shaded -->
+ <shaded.hadoop.version>3.0.0-alpha1</shaded.hadoop.version>
+ </properties>
+
+ <build>
+ <!--I want to override these in profile so define them
+ with variables up here-->
+ <sourceDirectory>${sources.dir}</sourceDirectory>
+ <outputDirectory>${classes.dir}</outputDirectory>
+ <plugins>
+ <!-- Make a jar and put the sources in the jar -->
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-source-plugin</artifactId>
+ <version>${maven-source-plugin.version}</version>
+ </plugin>
+ <plugin>
+ <!--Make it so assembly:single does nothing in here-->
+ <artifactId>maven-assembly-plugin</artifactId>
+ <version>${maven-assembly-plugin.version}</version>
+ <configuration>
+ <skipAssembly>true</skipAssembly>
+ </configuration>
+ </plugin>
+ <plugin>
+ <artifactId>maven-surefire-plugin</artifactId>
+ <!-- Always skip the second part executions
+ since we only run simple unit tests in this module -->
+ <executions>
+ <execution>
+ <id>secondPartTestsExecution</id>
+ <phase>test</phase>
+ <goals>
+ <goal>test</goal>
+ </goals>
+ <configuration>
+ <skip>true</skip>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+
+ <dependencies>
+ <dependency>
+ <groupId>com.google.protobuf</groupId>
+ <artifactId>protobuf-java</artifactId>
+ <version>${shaded.protobuf.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>com.google.protobuf.nano</groupId>
+ <artifactId>protobuf-javanano</artifactId>
+ <version>${shaded.protobuf.version}</version>
+ </dependency>
+
+ <dependency>
+ <groupId>io.grpc</groupId>
+ <artifactId>grpc-netty</artifactId>
+ <version>${shaded.grpc.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>io.grpc</groupId>
+ <artifactId>grpc-protobuf</artifactId>
+ <version>${shaded.grpc.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>io.grpc</groupId>
+ <artifactId>grpc-stub</artifactId>
+ <version>${shaded.grpc.version}</version>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.hadoop</groupId>
+ <artifactId>hadoop-common</artifactId>
+ <version>${shaded.hadoop.version}</version>
+ </dependency>
+ </dependencies>
+
+ <profiles>
+ <!-- Skip the tests in this module -->
+ <profile>
+ <id>skip-proto-shaded-tests</id>
+ <activation>
+ <property>
+ <name>skip-proto-shaded-tests</name>
+ </property>
+ </activation>
+ <properties>
+ <surefire.skipFirstPart>true</surefire.skipFirstPart>
+ </properties>
+ </profile>
+
+ <profile>
+ <id>compile-protobuf</id>
+ <!--
+ Generate and shade proto files. Drops generated java files
+ under src/main/java. Check in the generated files so available
+ at build time. Run this profile/step everytime you change proto
+ files or update the protobuf version.
+
+ The below does a bunch of ugly stuff. It purges current content
+ of the generated and shaded com.google.protobuf java files first.
+ It does this because later we apply patches later and patches
+ fail they've already been applied. We remove too because we
+ overlay the shaded protobuf and if files have been removed or
+ added, it'll be more plain if we have first done this delete.
+
+ Next up we generate proto, build a jar, shade it (which
+ includes the referenced protobuf), undo it over the src/main/java
+ directory, and then apply patches.
+
+ The result needs to be checked in.
+ -->
+ <activation>
+ <property>
+ <name>compile-protobuf</name>
+ </property>
+ </activation>
+ <properties>
+ <profile.id>compile-protobuf</profile.id>
+ <sources.dir>${project.build.directory}/protoc-generated-sources</sources.dir>
+ <classes.dir>${project.build.directory}/protoc-generated-classes</classes.dir>
+ <!--When the compile for this profile runs, make sure it makes jars that
+ can be related back to this shading profile. Give them a shading prefix.
+ -->
+ <jar.finalName>${profile.id}.${project.artifactId}-${project.version}</jar.finalName>
+ </properties>
+ <build>
+ <finalName>${jar.finalName}</finalName>
+ <plugins>
+ <plugin>
+ <artifactId>maven-clean-plugin</artifactId>
+ <version>${maven-clean-plugin.version}</version>
+ <executions>
+ <execution>
+ <id>pre-compile-protoc</id>
+ <phase>generate-sources</phase>
+ <goals>
+ <goal>clean</goal>
+ </goals>
+ <configuration>
+ <filesets>
+ <fileset>
+ <directory>
+ ${basedir}/src/main/java/
+ </directory>
+ <followSymlinks>false</followSymlinks>
+ </fileset>
+ </filesets>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+
+ <plugin>
+ <groupId>org.xolstice.maven.plugins</groupId>
+ <artifactId>protobuf-maven-plugin</artifactId>
+ <version>${maven-xolstice-plugin.version}</version>
+ <configuration>
+ <protocArtifact>
+ com.google.protobuf:protoc:${shaded.protobuf.version}:exe:${os.detected.classifier}
+ </protocArtifact>
+ </configuration>
+ <executions>
+ <execution>
+ <id>1</id>
+ <goals>
+ <goal>compile</goal>
+ <goal>test-compile</goal>
+ </goals>
+ </execution>
+ <execution>
+ <id>2</id>
+ <phase>generate-sources</phase>
+ <goals>
+ <goal>compile-custom</goal>
+ <goal>test-compile-custom</goal>
+ </goals>
+ <configuration>
+ <pluginId>grpc-java</pluginId>
+ <pluginArtifact>
+ io.grpc:protoc-gen-grpc-java:${shaded.grpc.version}:exe:${os.detected.classifier}
+ </pluginArtifact>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-shade-plugin</artifactId>
+ <version>2.4.3</version>
+ <executions>
+ <execution>
+ <phase>package</phase>
+ <goals>
+ <goal>shade</goal>
+ </goals>
+ <configuration>
+ <shadeSourcesContent>true</shadeSourcesContent>
+ <createSourcesJar>true</createSourcesJar>
+ <relocations>
+ <relocation>
+ <pattern>com.google.protobuf</pattern>
+ <shadedPattern>org.apache.ratis.shaded.com.google.protobuf</shadedPattern>
+ </relocation>
+ <relocation>
+ <pattern>io.grpc</pattern>
+ <shadedPattern>org.apache.ratis.shaded.io.grpc</shadedPattern>
+ </relocation>
+ <relocation>
+ <pattern>io.netty.handler.codec.protobuf</pattern>
+ <shadedPattern>org.apache.ratis.shaded.io.netty.handler.codec.protobuf</shadedPattern>
+ </relocation>
+
+ <relocation>
+ <pattern>org.apache.hadoop.ipc.protobuf</pattern>
+ <shadedPattern>org.apache.ratis.shaded.org.apache.hadoop.ipc.protobuf</shadedPattern>
+ </relocation>
+ </relocations>
+
+ <filters>
+ <filter>
+ <artifact>io.netty:netty-codec</artifact>
+ <includes>
+ <include>io/netty/handler/codec/protobuf/**</include>
+ </includes>
+ </filter>
+ <filter>
+ <artifact>org.apache.hadoop:hadoop-common</artifact>
+ <includes>
+ <include>org/apache/hadoop/ipc/protobuf/**</include>
+ </includes>
+ </filter>
+ </filters>
+
+ <artifactSet>
+ <excludes>
+ <exclude>asm:asm</exclude>
+
+ <exclude>com.google.code.findbugs</exclude>
+ <exclude>com.google.code.gson:gson</exclude>
+ <exclude>com.google.guava:guava</exclude>
+ com.google.re2j:re2j
+
+ <exclude>com.jamesmurty.utils:java-xmlbuilder</exclude>
+ <exclude>com.jcraft:jsch</exclude>
+
+ <exclude>com.sun.jersey:jersey-core</exclude>
+ <exclude>com.sun.jersey:jersey-json</exclude>
+ <exclude>com.sun.jersey:jersey-server</exclude>
+ <exclude>com.sun.jersey:jersey-servlet</exclude>
+ <exclude>com.sun.xml.bind:jaxb-impl</exclude>
+
+ <exclude>com.thoughtworks.paranamer:paranamer</exclude>
+
+ <exclude>commons-beanutils:commons-beanutils-core</exclude>
+ <exclude>commons-beanutils:commons-beanutils</exclude>
+ <exclude>commons-cli:commons-cli</exclude>
+ <exclude>commons-codec:commons-codec</exclude>
+ <exclude>commons-collections:commons-collections</exclude>
+ <exclude>commons-configuration:commons-configuration</exclude>
+ <exclude>commons-digester:commons-digester</exclude>
+ <exclude>commons-httpclient:commons-httpclient</exclude>
+ <exclude>commons-io:commons-io</exclude>
+ <exclude>commons-lang:commons-lang</exclude>
+ <exclude>commons-logging:commons-logging</exclude>
+ <exclude>commons-net:commons-net</exclude>
+
+ <exclude>io.netty:netty-buffer</exclude>
+ <exclude>io.netty:netty-codec-http2</exclude>
+ <exclude>io.netty:netty-codec-http</exclude>
+ <exclude>io.netty:netty-common</exclude>
+ <exclude>io.netty:netty-handler</exclude>
+ <exclude>io.netty:netty-resolver</exclude>
+ <exclude>io.netty:netty-transport</exclude>
+ <exclude>io.netty:netty</exclude>
+
+ <exclude>javax.activation:activation</exclude>
+ <exclude>javax.servlet.jsp:jsp-api</exclude>
+ <exclude>javax.servlet:servlet-api</exclude>
+ <exclude>javax.xml.bind:jaxb-api</exclude>
+ <exclude>javax.xml.stream:stax-api</exclude>
+ <exclude>javax.servlet:javax.servlet-api</exclude>
+ <exclude>javax.ws.rs:jsr311-api</exclude>
+
+ <exclude>log4j:log4j</exclude>
+ <exclude>net.java.dev.jets3t:jets3t</exclude>
+
+ <exclude>org.apache.avro:avro</exclude>
+ <exclude>org.apache.commons:commons-compress</exclude>
+ <exclude>org.apache.commons:commons-math3</exclude>
+ <exclude>org.apache.curator:curator-client</exclude>
+ <exclude>org.apache.curator:curator-framework</exclude>
+ <exclude>org.apache.curator:curator-recipes</exclude>
+ <exclude>org.apache.directory.api:api-asn1-api</exclude>
+ <exclude>org.apache.directory.api:api-util</exclude>
+ <exclude>org.apache.directory.server:apacheds-i18n</exclude>
+ <exclude>org.apache.directory.server:apacheds-kerberos-codec</exclude>
+ <exclude>org.apache.hadoop:hadoop-annotations</exclude>
+ <exclude>org.apache.hadoop:hadoop-auth</exclude>
+ <exclude>org.apache.htrace:htrace-core</exclude>
+ <exclude>org.apache.httpcomponents:httpclient</exclude>
+ <exclude>org.apache.httpcomponents:httpcore</exclude>
+ <exclude>org.apache.zookeeper:zookeeper</exclude>
+
+ <exclude>org.codehaus.jackson:jackson-core-asl</exclude>
+ <exclude>org.codehaus.jackson:jackson-jaxrs</exclude>
+ <exclude>org.codehaus.jackson:jackson-mapper-asl</exclude>
+ <exclude>org.codehaus.jackson:jackson-xc</exclude>
+ <exclude>org.codehaus.jettison:jettison</exclude>
+
+ <exclude>org.mortbay.jetty:jetty-util</exclude>
+ <exclude>org.mortbay.jetty:jetty</exclude>
+ <exclude>org.eclipse.jetty:jetty-server</exclude>
+ <exclude>org.eclipse.jetty:jetty-util</exclude>
+ <exclude>org.eclipse.jetty:jetty-servlet</exclude>
+ <exclude>org.eclipse.jetty:jetty-webapp</exclude>
+ <exclude>org.eclipse.jetty:jetty-util-ajax</exclude>
+ <exclude>org.mortbay.jetty:jetty-sslengine</exclude>
+
+ <exclude>org.slf4j:slf4j-api</exclude>
+ <exclude>org.slf4j:slf4j-log4j12</exclude>
+ <exclude>org.tukaani:xz</exclude>
+ <exclude>org.xerial.snappy:snappy-java</exclude>
+ <exclude>xmlenc:xmlenc</exclude>
+
+ <exclude>com.nimbusds:nimbus-jose-jwt</exclude>
+ <exclude>net.jcip:jcip-annotations</exclude>
+ <exclude>net.minidev:json-smart</exclude>
+
+ <exclude>org.apache.htrace:htrace-core4</exclude>
+ <exclude>org.apache.kerby:kerb-simplekdc</exclude>
+ <exclude>org.apache.kerby:kerby-config</exclude>
+ <exclude>org.apache.kerby:kerb-core</exclude>
+ <exclude>org.apache.kerby:kerby-asn1</exclude>
+ <exclude>org.apache.kerby:kerby-pkix</exclude>
+ <exclude>org.apache.kerby:kerby-util</exclude>
+ <exclude>org.apache.kerby:kerb-client</exclude>
+ <exclude>org.apache.kerby:kerb-common</exclude>
+ <exclude>org.apache.kerby:kerb-util</exclude>
+ <exclude>org.apache.kerby:kerb-crypto</exclude>
+ <exclude>org.apache.kerby:kerb-server</exclude>
+ <exclude>org.apache.kerby:kerb-identity</exclude>
+ <exclude>org.apache.kerby:kerb-admin</exclude>
+ </excludes>
+ </artifactSet>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ <!--Now unpack the shaded jar made above so the shaded classes
+ are available to subsequent modules-->
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-dependency-plugin</artifactId>
+ <version>${maven-dependency-plugin.version}</version>
+ <executions>
+ <execution>
+ <id>unpack</id>
+ <phase>package</phase>
+ <goals>
+ <goal>unpack</goal>
+ </goals>
+ <configuration>
+ <artifactItems>
+ <artifactItem>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>${project.artifactId}</artifactId>
+ <version>${project.version}</version>
+ <classifier>sources</classifier>
+ <type>jar</type>
+ <overWrite>true</overWrite>
+ <outputDirectory>${basedir}/src/main/java
+ </outputDirectory>
+ <includes>**/*.java</includes>
+ </artifactItem>
+ </artifactItems>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+ </profile>
+ </profiles>
+</project>
http://git-wip-us.apache.org/repos/asf/incubator-ratis/blob/7e71a2e0/ratis-proto-shaded/src/main/proto/GRpc.proto
----------------------------------------------------------------------
diff --git a/ratis-proto-shaded/src/main/proto/GRpc.proto b/ratis-proto-shaded/src/main/proto/GRpc.proto
new file mode 100644
index 0000000..267f579
--- /dev/null
+++ b/ratis-proto-shaded/src/main/proto/GRpc.proto
@@ -0,0 +1,45 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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_package = "org.apache.ratis.shaded.proto.grpc";
+option java_outer_classname = "GRpcProtos";
+option java_generate_equals_and_hash = true;
+package ratis.grpc;
+
+import "Raft.proto";
+
+service RaftClientProtocolService {
+ // A client-to-server RPC to set new raft configuration
+ rpc setConfiguration(ratis.common.SetConfigurationRequestProto)
+ returns(ratis.common.RaftClientReplyProto) {}
+
+ // A client-to-server stream RPC to append data
+ rpc append(stream ratis.common.RaftClientRequestProto)
+ returns (stream ratis.common.RaftClientReplyProto) {}
+}
+
+service RaftServerProtocolService {
+ rpc requestVote(ratis.common.RequestVoteRequestProto)
+ returns(ratis.common.RequestVoteReplyProto) {}
+
+ rpc appendEntries(stream ratis.common.AppendEntriesRequestProto)
+ returns(stream ratis.common.AppendEntriesReplyProto) {}
+
+ rpc installSnapshot(stream ratis.common.InstallSnapshotRequestProto)
+ returns(ratis.common.InstallSnapshotReplyProto) {}
+}
http://git-wip-us.apache.org/repos/asf/incubator-ratis/blob/7e71a2e0/ratis-proto-shaded/src/main/proto/Hadoop.proto
----------------------------------------------------------------------
diff --git a/ratis-proto-shaded/src/main/proto/Hadoop.proto b/ratis-proto-shaded/src/main/proto/Hadoop.proto
new file mode 100644
index 0000000..b85b9a2
--- /dev/null
+++ b/ratis-proto-shaded/src/main/proto/Hadoop.proto
@@ -0,0 +1,44 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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_package = "org.apache.ratis.shaded.proto.hadoop";
+option java_outer_classname = "HadoopProtos";
+option java_generic_services = true;
+option java_generate_equals_and_hash = true;
+package ratis.hadoop;
+
+import "Raft.proto";
+
+service RaftClientProtocolService {
+ rpc submitClientRequest(ratis.common.RaftClientRequestProto)
+ returns(ratis.common.RaftClientReplyProto);
+
+ rpc setConfiguration(ratis.common.SetConfigurationRequestProto)
+ returns(ratis.common.RaftClientReplyProto);
+}
+
+service RaftServerProtocolService {
+ rpc requestVote(ratis.common.RequestVoteRequestProto)
+ returns(ratis.common.RequestVoteReplyProto);
+
+ rpc appendEntries(ratis.common.AppendEntriesRequestProto)
+ returns(ratis.common.AppendEntriesReplyProto);
+
+ rpc installSnapshot(ratis.common.InstallSnapshotRequestProto)
+ returns(ratis.common.InstallSnapshotReplyProto);
+}
http://git-wip-us.apache.org/repos/asf/incubator-ratis/blob/7e71a2e0/ratis-proto-shaded/src/main/proto/Netty.proto
----------------------------------------------------------------------
diff --git a/ratis-proto-shaded/src/main/proto/Netty.proto b/ratis-proto-shaded/src/main/proto/Netty.proto
new file mode 100644
index 0000000..d1634d7
--- /dev/null
+++ b/ratis-proto-shaded/src/main/proto/Netty.proto
@@ -0,0 +1,49 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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_package = "org.apache.ratis.shaded.proto.netty";
+option java_outer_classname = "NettyProtos";
+option java_generate_equals_and_hash = true;
+package ratis.netty;
+
+import "Raft.proto";
+
+message RaftNettyExceptionReplyProto {
+ ratis.common.RaftRpcReplyProto rpcReply = 1;
+ bytes exception = 2;
+}
+
+message RaftNettyServerRequestProto {
+ oneof raftNettyServerRequest {
+ ratis.common.RequestVoteRequestProto requestVoteRequest = 1;
+ ratis.common.AppendEntriesRequestProto appendEntriesRequest = 2;
+ ratis.common.InstallSnapshotRequestProto installSnapshotRequest = 3;
+ ratis.common.RaftClientRequestProto raftClientRequest = 4;
+ ratis.common.SetConfigurationRequestProto setConfigurationRequest = 5;
+ }
+}
+
+message RaftNettyServerReplyProto {
+ oneof raftNettyServerReply {
+ ratis.common.RequestVoteReplyProto requestVoteReply = 1;
+ ratis.common.AppendEntriesReplyProto appendEntriesReply = 2;
+ ratis.common.InstallSnapshotReplyProto installSnapshotReply = 3;
+ ratis.common.RaftClientReplyProto raftClientReply = 4;
+ RaftNettyExceptionReplyProto exceptionReply = 5;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-ratis/blob/7e71a2e0/ratis-proto-shaded/src/main/proto/Raft.proto
----------------------------------------------------------------------
diff --git a/ratis-proto-shaded/src/main/proto/Raft.proto b/ratis-proto-shaded/src/main/proto/Raft.proto
new file mode 100644
index 0000000..80c4b8c
--- /dev/null
+++ b/ratis-proto-shaded/src/main/proto/Raft.proto
@@ -0,0 +1,165 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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_package = "org.apache.ratis.shaded.proto";
+option java_outer_classname = "RaftProtos";
+option java_generate_equals_and_hash = true;
+package ratis.common;
+
+message RaftPeerProto {
+ string id = 1; // id of the peer
+ string address = 2; // e.g. IP address, hostname etc.
+}
+
+message RaftConfigurationProto {
+ repeated RaftPeerProto peers = 1; // the peers in the current or new conf
+ repeated RaftPeerProto oldPeers = 2; // the peers in the old conf
+}
+
+message SMLogEntryProto {
+ // TODO: This is not super efficient if the SM itself uses PB to serialize its own data for a
+ // log entry. Data will be copied twice. We should directly support having any Message from SM
+ bytes data = 1;
+}
+
+message LeaderNoOp {
+ // empty
+}
+
+message LogEntryProto {
+ uint64 term = 1;
+ uint64 index = 2;
+
+ oneof LogEntryBody {
+ SMLogEntryProto smLogEntry = 3;
+ RaftConfigurationProto configurationEntry = 4;
+ LeaderNoOp noOp = 5;
+ }
+}
+
+message TermIndexProto {
+ uint64 term = 1;
+ uint64 index = 2;
+}
+
+message RaftRpcRequestProto {
+ string requestorId = 1;
+ string replyId = 2;
+ uint64 seqNum = 3;
+}
+
+message RaftRpcReplyProto {
+ string requestorId = 1;
+ string replyId = 2;
+ uint64 seqNum = 3;
+ bool success = 4;
+}
+
+message FileChunkProto {
+ string filename = 1; // relative to root
+ uint64 totalSize = 2;
+ bytes fileDigest = 3;
+ uint32 chunkIndex = 4;
+ uint64 offset = 5;
+ bytes data = 6;
+ bool done = 7;
+}
+
+enum InstallSnapshotResult {
+ SUCCESS = 0;
+ NOT_LEADER = 1;
+}
+
+message RequestVoteRequestProto {
+ RaftRpcRequestProto serverRequest = 1;
+ uint64 candidateTerm = 2;
+ TermIndexProto candidateLastEntry = 3;
+}
+
+message RequestVoteReplyProto {
+ RaftRpcReplyProto serverReply = 1;
+ uint64 term = 2;
+ bool shouldShutdown = 3;
+}
+
+message AppendEntriesRequestProto {
+ RaftRpcRequestProto serverRequest = 1;
+ uint64 leaderTerm = 2;
+ TermIndexProto previousLog = 3;
+ repeated LogEntryProto entries = 4;
+ uint64 leaderCommit = 5;
+ bool initializing = 6;
+}
+
+message AppendEntriesReplyProto {
+ enum AppendResult {
+ SUCCESS = 0;
+ NOT_LEADER = 1; // the requester's term is not large enough
+ INCONSISTENCY = 2; // gap between the local log and the entries
+ }
+
+ RaftRpcReplyProto serverReply = 1;
+ uint64 term = 2;
+ uint64 nextIndex = 3;
+ AppendResult result = 4;
+}
+
+message InstallSnapshotRequestProto {
+ RaftRpcRequestProto serverRequest = 1;
+ string requestId = 2; // an identifier for chunked-requests.
+ uint32 requestIndex = 3; // the index for this request chunk. Starts from 0.
+ RaftConfigurationProto raftConfiguration = 4;
+ uint64 leaderTerm = 5;
+ TermIndexProto termIndex = 6;
+ repeated FileChunkProto fileChunks = 7;
+ uint64 totalSize = 8;
+ bool done = 9; // whether this is the final chunk for the same req.
+}
+
+message InstallSnapshotReplyProto {
+ RaftRpcReplyProto serverReply = 1;
+ uint32 requestIndex = 2;
+ uint64 term = 3;
+ InstallSnapshotResult result = 4;
+}
+
+message ClientMessageEntryProto {
+ bytes content = 1;
+}
+
+// normal client request
+message RaftClientRequestProto {
+ RaftRpcRequestProto rpcRequest = 1;
+ ClientMessageEntryProto message = 2;
+ bool readOnly = 3;
+}
+
+message RaftClientReplyProto {
+ RaftRpcReplyProto rpcReply = 1;
+ ClientMessageEntryProto message = 2;
+ // the following 3 fields are used to indicate the server is not leader
+ bool isNotLeader = 3;
+ RaftPeerProto suggestedLeader = 4;
+ repeated RaftPeerProto peersInConf = 5;
+}
+
+// setConfiguration request
+message SetConfigurationRequestProto {
+ RaftRpcRequestProto rpcRequest = 1;
+ repeated RaftPeerProto peers = 2;
+}
http://git-wip-us.apache.org/repos/asf/incubator-ratis/blob/7e71a2e0/ratis-proto-shaded/src/main/resources/META-INF/services/org.apache.ratis.shaded.io.grpc.ManagedChannelProvider
----------------------------------------------------------------------
diff --git a/ratis-proto-shaded/src/main/resources/META-INF/services/org.apache.ratis.shaded.io.grpc.ManagedChannelProvider b/ratis-proto-shaded/src/main/resources/META-INF/services/org.apache.ratis.shaded.io.grpc.ManagedChannelProvider
new file mode 100644
index 0000000..dbf2d84
--- /dev/null
+++ b/ratis-proto-shaded/src/main/resources/META-INF/services/org.apache.ratis.shaded.io.grpc.ManagedChannelProvider
@@ -0,0 +1,16 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You 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.
+
+org.apache.ratis.shaded.io.grpc.netty.NettyChannelProvider
http://git-wip-us.apache.org/repos/asf/incubator-ratis/blob/7e71a2e0/ratis-proto-shaded/src/main/resources/META-INF/services/org.apache.ratis.shaded.io.grpc.NameResolverProvider
----------------------------------------------------------------------
diff --git a/ratis-proto-shaded/src/main/resources/META-INF/services/org.apache.ratis.shaded.io.grpc.NameResolverProvider b/ratis-proto-shaded/src/main/resources/META-INF/services/org.apache.ratis.shaded.io.grpc.NameResolverProvider
new file mode 100644
index 0000000..439b1d8
--- /dev/null
+++ b/ratis-proto-shaded/src/main/resources/META-INF/services/org.apache.ratis.shaded.io.grpc.NameResolverProvider
@@ -0,0 +1,16 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You 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.
+
+org.apache.ratis.shaded.io.grpc.internal.DnsNameResolverProvider
http://git-wip-us.apache.org/repos/asf/incubator-ratis/blob/7e71a2e0/ratis-proto-shaded/src/main/resources/META-INF/services/org.apache.ratis.shaded.io.grpc.ServerProvider
----------------------------------------------------------------------
diff --git a/ratis-proto-shaded/src/main/resources/META-INF/services/org.apache.ratis.shaded.io.grpc.ServerProvider b/ratis-proto-shaded/src/main/resources/META-INF/services/org.apache.ratis.shaded.io.grpc.ServerProvider
new file mode 100644
index 0000000..f251467
--- /dev/null
+++ b/ratis-proto-shaded/src/main/resources/META-INF/services/org.apache.ratis.shaded.io.grpc.ServerProvider
@@ -0,0 +1,16 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You 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.
+
+org.apache.ratis.shaded.io.grpc.netty.NettyServerProvider
http://git-wip-us.apache.org/repos/asf/incubator-ratis/blob/7e71a2e0/ratis-server/pom.xml
----------------------------------------------------------------------
diff --git a/ratis-server/pom.xml b/ratis-server/pom.xml
new file mode 100644
index 0000000..af9afd0
--- /dev/null
+++ b/ratis-server/pom.xml
@@ -0,0 +1,80 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ 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. See accompanying LICENSE file.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <artifactId>ratis-project-dist</artifactId>
+ <groupId>org.apache.ratis</groupId>
+ <version>1.0-SNAPSHOT</version>
+ <relativePath>../ratis-project-dist</relativePath>
+ </parent>
+
+ <artifactId>ratis-server</artifactId>
+ <name>Ratis Server</name>
+
+ <dependencies>
+ <dependency>
+ <artifactId>ratis-proto-shaded</artifactId>
+ <groupId>org.apache.ratis</groupId>
+ </dependency>
+
+ <dependency>
+ <artifactId>ratis-common</artifactId>
+ <groupId>org.apache.ratis</groupId>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <artifactId>ratis-common</artifactId>
+ <groupId>org.apache.ratis</groupId>
+ <scope>test</scope>
+ <type>test-jar</type>
+ </dependency>
+
+ <dependency>
+ <artifactId>ratis-client</artifactId>
+ <groupId>org.apache.ratis</groupId>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <artifactId>ratis-client</artifactId>
+ <groupId>org.apache.ratis</groupId>
+ <scope>test</scope>
+ <type>test-jar</type>
+ </dependency>
+
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-api</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>com.google.guava</groupId>
+ <artifactId>guava</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.mockito</groupId>
+ <artifactId>mockito-all</artifactId>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+</project>
http://git-wip-us.apache.org/repos/asf/incubator-ratis/blob/7e71a2e0/ratis-server/src/main/java/org/apache/ratis/server/RaftServer.java
----------------------------------------------------------------------
diff --git a/ratis-server/src/main/java/org/apache/ratis/server/RaftServer.java b/ratis-server/src/main/java/org/apache/ratis/server/RaftServer.java
new file mode 100644
index 0000000..06967ce
--- /dev/null
+++ b/ratis-server/src/main/java/org/apache/ratis/server/RaftServer.java
@@ -0,0 +1,44 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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 org.apache.ratis.server;
+
+import org.apache.ratis.protocol.RaftClientAsynchronousProtocol;
+import org.apache.ratis.protocol.RaftClientProtocol;
+import org.apache.ratis.server.protocol.RaftServerProtocol;
+import org.apache.ratis.statemachine.StateMachine;
+
+import java.io.Closeable;
+
+/** Raft server interface */
+public interface RaftServer extends Closeable, RaftServerProtocol,
+ RaftClientProtocol, RaftClientAsynchronousProtocol {
+ /** @return the server ID. */
+ String getId();
+
+ /** Set server RPC service. */
+ void setServerRpc(RaftServerRpc serverRpc);
+
+ /** Start this server. */
+ void start();
+
+ /**
+ * Returns the StateMachine instance.
+ * @return the StateMachine instance.
+ */
+ StateMachine getStateMachine();
+}
http://git-wip-us.apache.org/repos/asf/incubator-ratis/blob/7e71a2e0/ratis-server/src/main/java/org/apache/ratis/server/RaftServerConfigKeys.java
----------------------------------------------------------------------
diff --git a/ratis-server/src/main/java/org/apache/ratis/server/RaftServerConfigKeys.java b/ratis-server/src/main/java/org/apache/ratis/server/RaftServerConfigKeys.java
new file mode 100644
index 0000000..cdf7651
--- /dev/null
+++ b/ratis-server/src/main/java/org/apache/ratis/server/RaftServerConfigKeys.java
@@ -0,0 +1,150 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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 org.apache.ratis.server;
+
+import org.apache.ratis.server.impl.LogAppenderFactory;
+import org.apache.ratis.util.NetUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.net.InetSocketAddress;
+
+public interface RaftServerConfigKeys {
+
+ String PREFIX = "raft.server";
+
+ /** IPC server configurations */
+ interface Ipc {
+ String PREFIX = RaftServerConfigKeys.PREFIX + ".ipc";
+
+ String ADDRESS_KEY = PREFIX + ".address";
+ int DEFAULT_PORT = 10718;
+ String ADDRESS_DEFAULT = "0.0.0.0:" + DEFAULT_PORT;
+
+ String HANDLERS_KEY = PREFIX + ".handlers";
+ int HANDLERS_DEFAULT = 10;
+
+ class Getters {
+ private final Get get;
+
+ Getters(Get get) {
+ this.get = get;
+ }
+
+ public int handlers() {
+ return get.getInt(HANDLERS_KEY, HANDLERS_DEFAULT, 1, null);
+ }
+
+ public InetSocketAddress address() {
+ return get.getInetSocketAddress(ADDRESS_KEY, ADDRESS_DEFAULT);
+ }
+ }
+ }
+
+ String RAFT_SERVER_USE_MEMORY_LOG_KEY = "raft.server.use.memory.log";
+ boolean RAFT_SERVER_USE_MEMORY_LOG_DEFAULT = false;
+
+ String RAFT_SERVER_STORAGE_DIR_KEY = "raft.server.storage.dir";
+ String RAFT_SERVER_STORAGE_DIR_DEFAULT = "file:///tmp/raft-server/";
+
+ String RAFT_SERVER_LOG_APPENDER_FACTORY_CLASS_KEY = "raft.server.log.appender.factory.class";
+ Class<? extends LogAppenderFactory> RAFT_SERVER_LOG_APPENDER_FACTORY_CLASS_DEFAULT
+ = LogAppenderFactory.SynchronousLogAppenderFactory.class;
+
+ /** whether trigger snapshot when log size exceeds limit */
+ String RAFT_SERVER_AUTO_SNAPSHOT_ENABLED_KEY = "raft.server.auto.snapshot.enabled";
+ /** by default let the state machine to decide when to do checkpoint */
+ boolean RAFT_SERVER_AUTO_SNAPSHOT_ENABLED_DEFAULT = false;
+
+ /** log size limit (in number of log entries) that triggers the snapshot */
+ String RAFT_SERVER_SNAPSHOT_TRIGGER_THRESHOLD_KEY = "raft.server.snapshot.trigger.threshold";
+ long RAFT_SERVER_SNAPSHOT_TRIGGER_THRESHOLD_DEFAULT = 400000;
+
+ String RAFT_LOG_SEGMENT_MAX_SIZE_KEY = "raft.log.segment.max.size";
+ long RAFT_LOG_SEGMENT_MAX_SIZE_DEFAULT = 1024L * 1024 * 1024 * 2; // 2GB
+
+ String RAFT_LOG_SEGMENT_PREALLOCATED_SIZE_KEY = "raft.log.segment.preallocated.size";
+ int RAFT_LOG_SEGMENT_PREALLOCATED_SIZE_DEFAULT = 1024 * 1024 * 16; // 16MB
+
+ String RAFT_LOG_WRITE_BUFFER_SIZE_KEY = "raft.log.write.buffer.size";
+ int RAFT_LOG_WRITE_BUFFER_SIZE_DEFAULT = 64 * 1024;
+
+ String RAFT_SNAPSHOT_CHUNK_MAX_SIZE_KEY = "raft.snapshot.chunk.max.size";
+ int RAFT_SNAPSHOT_CHUNK_MAX_SIZE_DEFAULT = 1024 * 1024 * 16;
+
+ String RAFT_LOG_FORCE_SYNC_NUM_KEY = "raft.log.force.sync.num";
+ int RAFT_LOG_FORCE_SYNC_NUM_DEFAULT = 128;
+
+ /** server rpc timeout related */
+ String RAFT_SERVER_RPC_TIMEOUT_MIN_MS_KEY = "raft.server.rpc.timeout.min.ms";
+ int RAFT_SERVER_RPC_TIMEOUT_MIN_MS_DEFAULT = 150;
+
+ String RAFT_SERVER_RPC_TIMEOUT_MAX_MS_KEY = "raft.server.rpc.timeout.max.ms";
+ int RAFT_SERVER_RPC_TIMEOUT_MAX_MS_DEFAULT = 300;
+
+ String RAFT_SERVER_RPC_SLEEP_TIME_MS_KEY = "raft.server.rpc.sleep.time.ms";
+ int RAFT_SERVER_RPC_SLEEP_TIME_MS_DEFAULT = 25;
+
+ /**
+ * When bootstrapping a new peer, If the gap between the match index of the
+ * peer and the leader's latest committed index is less than this gap, we
+ * treat the peer as caught-up.
+ */
+ String RAFT_SERVER_STAGING_CATCHUP_GAP_KEY = "raft.server.staging.catchup.gap";
+ int RAFT_SERVER_STAGING_CATCHUP_GAP_DEFAULT = 1000; // increase this number when write throughput is high
+
+ String RAFT_SERVER_LOG_APPENDER_BUFFER_CAPACITY_KEY = "raft.server.log.appender.buffer.capacity";
+ int RAFT_SERVER_LOG_APPENDER_BUFFER_CAPACITY_DEFAULT = 4 * 1024 * 1024; // 4MB
+
+ String RAFT_SERVER_LOG_APPENDER_BATCH_ENABLED_KEY = "raft.server.log.appender.batch.enabled";
+ boolean RAFT_SERVER_LOG_APPENDER_BATCH_ENABLED_DEFAULT = false;
+
+ /** An utility class to get conf values. */
+ abstract class Get {
+ static Logger LOG = LoggerFactory.getLogger(RaftServerConfigKeys.class);
+
+ private final Ipc.Getters ipc = new Ipc.Getters(this);
+
+ protected abstract int getInt(String key, int defaultValue);
+
+ int getInt(String key, int defaultValue, Integer min, Integer max) {
+ final int value = getInt(key, defaultValue);
+ final String s = key + " = " + value;
+ if (min != null && value < min) {
+ throw new IllegalArgumentException(s + " < min = " + min);
+ }
+ if (max != null && value > max) {
+ throw new IllegalArgumentException(s + " > max = " + max);
+ }
+ LOG.info(s);
+ return value;
+ }
+
+ protected abstract String getTrimmed(String key, String defaultValue);
+
+ InetSocketAddress getInetSocketAddress(String key, String defaultValue) {
+ final String address = getTrimmed(key, defaultValue);
+ LOG.info(key + " = " + address);
+ return NetUtils.createSocketAddr(address);
+ }
+
+ public Ipc.Getters ipc() {
+ return ipc;
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-ratis/blob/7e71a2e0/ratis-server/src/main/java/org/apache/ratis/server/RaftServerRpc.java
----------------------------------------------------------------------
diff --git a/ratis-server/src/main/java/org/apache/ratis/server/RaftServerRpc.java b/ratis-server/src/main/java/org/apache/ratis/server/RaftServerRpc.java
new file mode 100644
index 0000000..5fecce3
--- /dev/null
+++ b/ratis-server/src/main/java/org/apache/ratis/server/RaftServerRpc.java
@@ -0,0 +1,39 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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 org.apache.ratis.server;
+
+import org.apache.ratis.protocol.RaftPeer;
+import org.apache.ratis.server.protocol.RaftServerProtocol;
+
+import java.io.Closeable;
+import java.net.InetSocketAddress;
+
+/**
+ * An server-side interface for supporting different RPC implementations
+ * such as Netty, gRPC and Hadoop.
+ */
+public interface RaftServerRpc extends RaftServerProtocol, Closeable {
+ /** Start the RPC service. */
+ void start();
+
+ /** @return the address where this RPC server is listening to. */
+ InetSocketAddress getInetSocketAddress();
+
+ /** add information of the given peers */
+ void addPeers(Iterable<RaftPeer> peers);
+}
http://git-wip-us.apache.org/repos/asf/incubator-ratis/blob/7e71a2e0/ratis-server/src/main/java/org/apache/ratis/server/impl/ConfigurationManager.java
----------------------------------------------------------------------
diff --git a/ratis-server/src/main/java/org/apache/ratis/server/impl/ConfigurationManager.java b/ratis-server/src/main/java/org/apache/ratis/server/impl/ConfigurationManager.java
new file mode 100644
index 0000000..f495c28
--- /dev/null
+++ b/ratis-server/src/main/java/org/apache/ratis/server/impl/ConfigurationManager.java
@@ -0,0 +1,91 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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 org.apache.ratis.server.impl;
+
+import com.google.common.annotations.VisibleForTesting;
+import com.google.common.base.Preconditions;
+
+import java.util.*;
+
+/**
+ * Maintain the mappings between log index and corresponding raft configuration.
+ * Initialized when starting the raft peer. The mappings are loaded from the
+ * raft log, and updated while appending/truncating configuration related log
+ * entries.
+ */
+public class ConfigurationManager {
+ private RaftConfiguration initialConf;
+ private final NavigableMap<Long, RaftConfiguration> configurations =
+ new TreeMap<>();
+ /**
+ * The current raft configuration. If configurations is not empty, should be
+ * the last entry of the map. Otherwise is initialConf.
+ */
+ private RaftConfiguration currentConf;
+
+ public ConfigurationManager(RaftConfiguration initialConf) {
+ setInitialConf(initialConf);
+ }
+
+ @VisibleForTesting
+ public synchronized void setInitialConf(RaftConfiguration initialConf) {
+ /**
+ * initialConf should actually be defined as "final". But for tests we want
+ * to change the initial configuration to reflect the correct port binding.
+ */
+ this.initialConf = initialConf;
+ this.currentConf = initialConf;
+ }
+
+ public synchronized void addConfiguration(long logIndex,
+ RaftConfiguration conf) {
+ Preconditions.checkArgument(configurations.isEmpty() ||
+ configurations.lastEntry().getKey() < logIndex);
+ configurations.put(logIndex, conf);
+ this.currentConf = conf;
+ }
+
+ synchronized RaftConfiguration getCurrent() {
+ return currentConf;
+ }
+
+ /**
+ * Remove all the configurations whose log index is >= the given index.
+ * @param index The given index. All the configurations whose log index is >=
+ * this value will be removed.
+ * @return The configuration with largest log index < the given index.
+ */
+ synchronized RaftConfiguration removeConfigurations(long index) {
+ SortedMap<Long, RaftConfiguration> toRemove = configurations.tailMap(index);
+ for (Iterator<Map.Entry<Long, RaftConfiguration>> iter =
+ toRemove.entrySet().iterator(); iter.hasNext();) {
+ iter.next();
+ iter.remove();
+ }
+ currentConf = configurations.isEmpty() ? initialConf :
+ configurations.lastEntry().getValue();
+ return currentConf;
+ }
+
+ @VisibleForTesting
+ synchronized int numOfConf() {
+ return 1 + configurations.size();
+ }
+
+ // TODO: remove Configuration entries after they are committed
+}
http://git-wip-us.apache.org/repos/asf/incubator-ratis/blob/7e71a2e0/ratis-server/src/main/java/org/apache/ratis/server/impl/FollowerInfo.java
----------------------------------------------------------------------
diff --git a/ratis-server/src/main/java/org/apache/ratis/server/impl/FollowerInfo.java b/ratis-server/src/main/java/org/apache/ratis/server/impl/FollowerInfo.java
new file mode 100644
index 0000000..f72e037
--- /dev/null
+++ b/ratis-server/src/main/java/org/apache/ratis/server/impl/FollowerInfo.java
@@ -0,0 +1,103 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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 org.apache.ratis.server.impl;
+
+import java.util.concurrent.atomic.AtomicLong;
+import java.util.concurrent.atomic.AtomicReference;
+
+import org.apache.ratis.protocol.RaftPeer;
+import org.apache.ratis.util.Timestamp;
+
+public class FollowerInfo {
+ private final RaftPeer peer;
+ private final AtomicReference<Timestamp> lastRpcResponseTime;
+ private final AtomicReference<Timestamp> lastRpcSendTime;
+ private long nextIndex;
+ private final AtomicLong matchIndex;
+ private volatile boolean attendVote;
+
+ FollowerInfo(RaftPeer peer, Timestamp lastRpcTime, long nextIndex,
+ boolean attendVote) {
+ this.peer = peer;
+ this.lastRpcResponseTime = new AtomicReference<>(lastRpcTime);
+ this.lastRpcSendTime = new AtomicReference<>(lastRpcTime);
+ this.nextIndex = nextIndex;
+ this.matchIndex = new AtomicLong(0);
+ this.attendVote = attendVote;
+ }
+
+ public void updateMatchIndex(final long matchIndex) {
+ this.matchIndex.set(matchIndex);
+ }
+
+ long getMatchIndex() {
+ return matchIndex.get();
+ }
+
+ public synchronized long getNextIndex() {
+ return nextIndex;
+ }
+
+ public synchronized void updateNextIndex(long i) {
+ nextIndex = i;
+ }
+
+ public synchronized void decreaseNextIndex(long targetIndex) {
+ if (nextIndex > 0) {
+ nextIndex = Math.min(nextIndex - 1, targetIndex);
+ }
+ }
+
+ @Override
+ public String toString() {
+ return peer.getId() + "(next=" + nextIndex + ", match=" + matchIndex + "," +
+ " attendVote=" + attendVote +
+ ", lastRpcSendTime=" + lastRpcSendTime +
+ ", lastRpcResponseTime=" + lastRpcResponseTime + ")";
+ }
+
+ void startAttendVote() {
+ attendVote = true;
+ }
+
+ public boolean isAttendingVote() {
+ return attendVote;
+ }
+
+ public RaftPeer getPeer() {
+ return peer;
+ }
+
+ /** Update lastRpcResponseTime to the current time. */
+ public void updateLastRpcResponseTime() {
+ lastRpcResponseTime.set(new Timestamp());
+ }
+
+ public Timestamp getLastRpcResponseTime() {
+ return lastRpcResponseTime.get();
+ }
+
+ /** Update lastRpcSendTime to the current time. */
+ public void updateLastRpcSendTime() {
+ lastRpcSendTime.set(new Timestamp());
+ }
+
+ public Timestamp getLastRpcTime() {
+ return Timestamp.latest(lastRpcResponseTime.get(), lastRpcSendTime.get());
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-ratis/blob/7e71a2e0/ratis-server/src/main/java/org/apache/ratis/server/impl/FollowerState.java
----------------------------------------------------------------------
diff --git a/ratis-server/src/main/java/org/apache/ratis/server/impl/FollowerState.java b/ratis-server/src/main/java/org/apache/ratis/server/impl/FollowerState.java
new file mode 100644
index 0000000..1e57fa2
--- /dev/null
+++ b/ratis-server/src/main/java/org/apache/ratis/server/impl/FollowerState.java
@@ -0,0 +1,91 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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 org.apache.ratis.server.impl;
+
+import org.apache.ratis.util.Daemon;
+import org.apache.ratis.util.Timestamp;
+import org.slf4j.Logger;
+
+/**
+ * Used when the peer is a follower. Used to track the election timeout.
+ */
+class FollowerState extends Daemon {
+ static final Logger LOG = RaftServerImpl.LOG;
+
+ private final RaftServerImpl server;
+
+ private volatile Timestamp lastRpcTime = new Timestamp();
+ private volatile boolean monitorRunning = true;
+ private volatile boolean inLogSync = false;
+
+ FollowerState(RaftServerImpl server) {
+ this.server = server;
+ }
+
+ void updateLastRpcTime(boolean inLogSync) {
+ lastRpcTime = new Timestamp();
+ LOG.trace("{} update last rpc time to {}", server.getId(), lastRpcTime);
+ this.inLogSync = inLogSync;
+ }
+
+ Timestamp getLastRpcTime() {
+ return lastRpcTime;
+ }
+
+ boolean shouldWithholdVotes() {
+ return lastRpcTime.elapsedTimeMs() < server.getMinTimeoutMs();
+ }
+
+ void stopRunning() {
+ this.monitorRunning = false;
+ }
+
+ @Override
+ public void run() {
+ while (monitorRunning && server.isFollower()) {
+ final long electionTimeout = server.getRandomTimeoutMs();
+ try {
+ Thread.sleep(electionTimeout);
+ if (!monitorRunning || !server.isFollower()) {
+ LOG.info("{} heartbeat monitor quit", server.getId());
+ break;
+ }
+ synchronized (server) {
+ if (!inLogSync && lastRpcTime.elapsedTimeMs() >= electionTimeout) {
+ LOG.info("{} changes to CANDIDATE, lastRpcTime:{}, electionTimeout:{}ms",
+ server.getId(), lastRpcTime, electionTimeout);
+ // election timeout, should become a candidate
+ server.changeToCandidate();
+ break;
+ }
+ }
+ } catch (InterruptedException e) {
+ LOG.info(this + " was interrupted: " + e);
+ LOG.trace("TRACE", e);
+ return;
+ } catch (Exception e) {
+ LOG.warn(this + " caught an exception", e);
+ }
+ }
+ }
+
+ @Override
+ public String toString() {
+ return server.getId() + ": " + getClass().getSimpleName();
+ }
+}