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