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();
+  }
+}