Repository: incubator-ratis
Updated Branches:
  refs/heads/master e914e7afa -> dfeb671f0


RATIS-95. Executable Jar for the ratis example.  Contributed by Elek, Marton


Project: http://git-wip-us.apache.org/repos/asf/incubator-ratis/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-ratis/commit/dfeb671f
Tree: http://git-wip-us.apache.org/repos/asf/incubator-ratis/tree/dfeb671f
Diff: http://git-wip-us.apache.org/repos/asf/incubator-ratis/diff/dfeb671f

Branch: refs/heads/master
Commit: dfeb671f04dc5fd091011476861c67cc8972d42d
Parents: e914e7a
Author: Tsz-Wo Nicholas Sze <[email protected]>
Authored: Fri Nov 17 13:51:19 2017 -0800
Committer: Tsz-Wo Nicholas Sze <[email protected]>
Committed: Fri Nov 17 13:51:19 2017 -0800

----------------------------------------------------------------------
 pom.xml                                         |   6 ++
 ratis-examples/pom.xml                          |  42 +++++---
 ratis-examples/src/main/bin/client.sh           |  23 ++++
 ratis-examples/src/main/bin/common.sh           |  23 ++++
 ratis-examples/src/main/bin/server.sh           |  24 +++++
 ratis-examples/src/main/bin/start-all.sh        |  23 ++++
 .../ratis/examples/arithmetic/Runner.java       |  79 ++++++++++++++
 .../ratis/examples/arithmetic/cli/Assign.java   | 104 +++++++++++++++++++
 .../ratis/examples/arithmetic/cli/Client.java   |  56 ++++++++++
 .../ratis/examples/arithmetic/cli/Get.java      |  49 +++++++++
 .../ratis/examples/arithmetic/cli/Server.java   |  88 ++++++++++++++++
 .../examples/arithmetic/cli/SubCommandBase.java |  53 ++++++++++
 .../arithmetic/expression/BinaryExpression.java |  20 ++++
 .../arithmetic/expression/DoubleValue.java      |  14 +++
 .../arithmetic/expression/UnaryExpression.java  |  19 ++++
 .../examples/arithmetic/cli/AssignTest.java     |  53 ++++++++++
 16 files changed, 664 insertions(+), 12 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-ratis/blob/dfeb671f/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
index d98ef50..1f8ceb7 100644
--- a/pom.xml
+++ b/pom.xml
@@ -312,6 +312,12 @@
       </dependency>
 
       <dependency>
+        <groupId>com.beust</groupId>
+        <artifactId>jcommander</artifactId>
+        <version>1.72</version>
+      </dependency>
+
+      <dependency>
         <groupId>junit</groupId>
         <artifactId>junit</artifactId>
         <version>4.11</version>

http://git-wip-us.apache.org/repos/asf/incubator-ratis/blob/dfeb671f/ratis-examples/pom.xml
----------------------------------------------------------------------
diff --git a/ratis-examples/pom.xml b/ratis-examples/pom.xml
index fd8df7c..1fddd1f 100644
--- a/ratis-examples/pom.xml
+++ b/ratis-examples/pom.xml
@@ -27,13 +27,11 @@
     <dependency>
       <artifactId>ratis-proto-shaded</artifactId>
       <groupId>org.apache.ratis</groupId>
-      <scope>provided</scope>
     </dependency>
 
     <dependency>
       <artifactId>ratis-common</artifactId>
       <groupId>org.apache.ratis</groupId>
-      <scope>provided</scope>
     </dependency>
     <dependency>
       <artifactId>ratis-common</artifactId>
@@ -45,7 +43,6 @@
     <dependency>
       <artifactId>ratis-client</artifactId>
       <groupId>org.apache.ratis</groupId>
-      <scope>provided</scope>
     </dependency>
     <dependency>
       <artifactId>ratis-client</artifactId>
@@ -57,7 +54,10 @@
     <dependency>
       <artifactId>ratis-server</artifactId>
       <groupId>org.apache.ratis</groupId>
-      <scope>provided</scope>
+    </dependency>
+    <dependency>
+      <groupId>com.beust</groupId>
+      <artifactId>jcommander</artifactId>
     </dependency>
     <dependency>
       <artifactId>ratis-server</artifactId>
@@ -69,7 +69,6 @@
     <dependency>
       <artifactId>ratis-hadoop</artifactId>
       <groupId>org.apache.ratis</groupId>
-      <scope>provided</scope>
     </dependency>
     <dependency>
       <artifactId>ratis-hadoop</artifactId>
@@ -77,16 +76,10 @@
       <scope>test</scope>
       <type>test-jar</type>
     </dependency>
-    <dependency>
-      <artifactId>ratis-hadoop-shaded</artifactId>
-      <groupId>org.apache.ratis</groupId>
-      <scope>provided</scope>
-    </dependency>
 
     <dependency>
       <artifactId>ratis-grpc</artifactId>
       <groupId>org.apache.ratis</groupId>
-      <scope>provided</scope>
     </dependency>
     <dependency>
       <artifactId>ratis-grpc</artifactId>
@@ -98,7 +91,6 @@
     <dependency>
       <artifactId>ratis-netty</artifactId>
       <groupId>org.apache.ratis</groupId>
-      <scope>provided</scope>
     </dependency>
     <dependency>
       <artifactId>ratis-netty</artifactId>
@@ -123,5 +115,31 @@
       <scope>test</scope>
     </dependency>
   </dependencies>
+  <build>
+    <plugins>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-shade-plugin</artifactId>
+        <version>3.1.0</version>
+        <executions>
+          <execution>
+            <phase>package</phase>
+            <goals>
+              <goal>shade</goal>
+            </goals>
+            <configuration>
+              <transformers>
+                <transformer
+                        
implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
+                  <mainClass>org.apache.ratis.examples.arithmetic.Runner
+                  </mainClass>
+                </transformer>
+              </transformers>
+            </configuration>
+          </execution>
+        </executions>
+      </plugin>
+    </plugins>
+  </build>
 </project>
     

http://git-wip-us.apache.org/repos/asf/incubator-ratis/blob/dfeb671f/ratis-examples/src/main/bin/client.sh
----------------------------------------------------------------------
diff --git a/ratis-examples/src/main/bin/client.sh 
b/ratis-examples/src/main/bin/client.sh
new file mode 100644
index 0000000..60946a3
--- /dev/null
+++ b/ratis-examples/src/main/bin/client.sh
@@ -0,0 +1,23 @@
+#!/usr/bin/env bash
+# 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.
+
+DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
+source $DIR/common.sh
+
+subcommand=$1
+shift
+java -jar $ARTIFACT $subcommand --peers 
n0:localhost:6000,n1:localhost:6001,n2:localhost:6002 "$@"
+

http://git-wip-us.apache.org/repos/asf/incubator-ratis/blob/dfeb671f/ratis-examples/src/main/bin/common.sh
----------------------------------------------------------------------
diff --git a/ratis-examples/src/main/bin/common.sh 
b/ratis-examples/src/main/bin/common.sh
new file mode 100644
index 0000000..d00eb1e
--- /dev/null
+++ b/ratis-examples/src/main/bin/common.sh
@@ -0,0 +1,23 @@
+#!/usr/bin/env bash
+# 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.
+
+DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
+
+ARTIFACT=`ls -1 $DIR/../../../target/ratis-examples-*.jar | grep -v test`
+if [ ! -f "$ARTIFACT" ]; then
+   echo "Jar file is missing. Please do a full build (mvn clean package) 
first."
+   exit -1
+fi
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-ratis/blob/dfeb671f/ratis-examples/src/main/bin/server.sh
----------------------------------------------------------------------
diff --git a/ratis-examples/src/main/bin/server.sh 
b/ratis-examples/src/main/bin/server.sh
new file mode 100644
index 0000000..564daa1
--- /dev/null
+++ b/ratis-examples/src/main/bin/server.sh
@@ -0,0 +1,24 @@
+#!/usr/bin/env bash
+# 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.
+
+DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
+source $DIR/common.sh
+if [ -z "$1" ]; then
+   echo "Usage: server.sh <nodeid>"
+   exit -1
+fi
+java -jar $ARTIFACT server --storage /tmp/ratis-arithmentic-$1 --id $1 --peers 
n0:localhost:6000,n1:localhost:6001,n2:localhost:6002
+

http://git-wip-us.apache.org/repos/asf/incubator-ratis/blob/dfeb671f/ratis-examples/src/main/bin/start-all.sh
----------------------------------------------------------------------
diff --git a/ratis-examples/src/main/bin/start-all.sh 
b/ratis-examples/src/main/bin/start-all.sh
new file mode 100644
index 0000000..923ff04
--- /dev/null
+++ b/ratis-examples/src/main/bin/start-all.sh
@@ -0,0 +1,23 @@
+#!/usr/bin/env bash
+# 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.
+
+DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
+source $DIR/common.sh
+
+$DIR/server.sh n0 &
+$DIR/server.sh n1 &
+$DIR/server.sh n2 &
+echo "Waiting for the servers"

http://git-wip-us.apache.org/repos/asf/incubator-ratis/blob/dfeb671f/ratis-examples/src/main/java/org/apache/ratis/examples/arithmetic/Runner.java
----------------------------------------------------------------------
diff --git 
a/ratis-examples/src/main/java/org/apache/ratis/examples/arithmetic/Runner.java 
b/ratis-examples/src/main/java/org/apache/ratis/examples/arithmetic/Runner.java
new file mode 100644
index 0000000..ab189a8
--- /dev/null
+++ 
b/ratis-examples/src/main/java/org/apache/ratis/examples/arithmetic/Runner.java
@@ -0,0 +1,79 @@
+/**
+ * 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.examples.arithmetic;
+
+import com.beust.jcommander.JCommander;
+import com.beust.jcommander.ParameterException;
+import org.apache.log4j.Level;
+import org.apache.ratis.client.RaftClient;
+import org.apache.ratis.examples.arithmetic.cli.Assign;
+import org.apache.ratis.examples.arithmetic.cli.Get;
+import org.apache.ratis.examples.arithmetic.cli.SubCommandBase;
+import org.apache.ratis.examples.arithmetic.cli.Server;
+import org.apache.ratis.server.impl.RaftServerImpl;
+import org.apache.ratis.util.LogUtils;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Optional;
+
+/**
+ * Standalone arithmetic raft server.
+ */
+public class Runner {
+
+  private static List<SubCommandBase> commands = new ArrayList<>();
+
+  static {
+    LogUtils.setLogLevel(RaftServerImpl.LOG, Level.DEBUG);
+    LogUtils.setLogLevel(RaftClient.LOG, Level.DEBUG);
+  }
+
+  public static void main(String[] args) throws Exception {
+    initializeCommands();
+    Runner runner = new Runner();
+    Server server = new Server();
+
+    JCommander.Builder builder = JCommander.newBuilder().addObject(runner);
+    commands.forEach(command -> builder
+        .addCommand(command.getClass().getSimpleName().toLowerCase(), 
command));
+    JCommander jc = builder.build();
+    try {
+      jc.parse(args);
+      Optional<SubCommandBase> selectedCommand = commands.stream().filter(
+          command -> command.getClass().getSimpleName().toLowerCase()
+              .equals(jc.getParsedCommand())).findFirst();
+      if (selectedCommand.isPresent()) {
+        selectedCommand.get().run();
+      } else {
+        jc.usage();
+      }
+    } catch (ParameterException exception) {
+      System.err.println("Wrong parameters: " + exception.getMessage());
+      jc.usage();
+    }
+
+  }
+
+  private static void initializeCommands() {
+    commands.add(new Server());
+    commands.add(new Assign());
+    commands.add(new Get());
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-ratis/blob/dfeb671f/ratis-examples/src/main/java/org/apache/ratis/examples/arithmetic/cli/Assign.java
----------------------------------------------------------------------
diff --git 
a/ratis-examples/src/main/java/org/apache/ratis/examples/arithmetic/cli/Assign.java
 
b/ratis-examples/src/main/java/org/apache/ratis/examples/arithmetic/cli/Assign.java
new file mode 100644
index 0000000..7496647
--- /dev/null
+++ 
b/ratis-examples/src/main/java/org/apache/ratis/examples/arithmetic/cli/Assign.java
@@ -0,0 +1,104 @@
+/**
+ * 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.examples.arithmetic.cli;
+
+import com.beust.jcommander.Parameter;
+import com.beust.jcommander.Parameters;
+import org.apache.ratis.client.RaftClient;
+import org.apache.ratis.examples.arithmetic.AssignmentMessage;
+import org.apache.ratis.examples.arithmetic.expression.*;
+import org.apache.ratis.protocol.RaftClientReply;
+import org.apache.ratis.shaded.com.google.common.annotations.VisibleForTesting;
+
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.Optional;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * Subcommand to assign new value in arithmetic state machine.
+ */
+@Parameters(commandDescription = "Assign value to a variable.")
+public class Assign extends Client {
+
+  Pattern binaryOperationPattern = 
Pattern.compile("([a-z1-9]+)([\\*\\-/\\+])([a-z1-9])");
+  Pattern unaryOperationPattern = Pattern.compile("([√~])([a-z1-9]+)");
+
+  @Parameter(names = {
+      "--name"}, description = "Name of the variable to set", required = true)
+  String name;
+
+  @Parameter(names = {"--value"}, description = "Value to set", required = 
true)
+  String value;
+
+  @Override
+  protected void operation(RaftClient client) throws IOException {
+    RaftClientReply send = client.send(
+        new AssignmentMessage(new Variable(name), createExpression(value)));
+    System.out.println("Success: " + send.isSuccess());
+    System.out.println("Response: " + send.getMessage().getClass());
+  }
+
+  @VisibleForTesting
+  protected Expression createExpression(String value) {
+    if (value.matches("\\d(\\.\\d*)?")) {
+      return new DoubleValue(Double.valueOf(value));
+    } else if (value.matches("[a-zA-Z]+")) {
+      return new Variable(value);
+    }
+    Matcher binaryMatcher = binaryOperationPattern.matcher(value);
+    Matcher unaryMatcher = unaryOperationPattern.matcher(value);
+
+    if (binaryMatcher.matches()) {
+      return createBinaryExpression(binaryMatcher);
+    } else if (unaryMatcher.matches()) {
+      return createUnaryExpression(unaryMatcher);
+    } else {
+      throw new IllegalArgumentException("Invalid expression " + value + " Try 
something like: 'a+b' or '2'");
+    }
+  }
+
+  private Expression createBinaryExpression(Matcher binaryMatcher) {
+    String operator = binaryMatcher.group(2);
+    String firstElement = binaryMatcher.group(1);
+    String secondElement = binaryMatcher.group(3);
+    Optional<BinaryExpression.Op> selectedOp =
+        Arrays.stream(BinaryExpression.Op.values()).filter(op -> 
op.getSymbol().equals(operator)).findAny();
+
+    if (!selectedOp.isPresent()) {
+      throw new IllegalArgumentException("Unknown binary operator: " + 
operator);
+    } else {
+      return new BinaryExpression(selectedOp.get(), 
createExpression(firstElement), createExpression(secondElement));
+    }
+  }
+
+  private Expression createUnaryExpression(Matcher binaryMatcher) {
+    String operator = binaryMatcher.group(1);
+    String element = binaryMatcher.group(2);
+    Optional<UnaryExpression.Op> selectedOp =
+        Arrays.stream(UnaryExpression.Op.values()).filter(op -> 
op.getSymbol().equals(operator)).findAny();
+
+    if (!selectedOp.isPresent()) {
+      throw new IllegalArgumentException("Unknown unary operator:" + operator);
+    } else {
+      return new UnaryExpression(selectedOp.get(), createExpression(element));
+    }
+  }
+
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-ratis/blob/dfeb671f/ratis-examples/src/main/java/org/apache/ratis/examples/arithmetic/cli/Client.java
----------------------------------------------------------------------
diff --git 
a/ratis-examples/src/main/java/org/apache/ratis/examples/arithmetic/cli/Client.java
 
b/ratis-examples/src/main/java/org/apache/ratis/examples/arithmetic/cli/Client.java
new file mode 100644
index 0000000..aa89b25
--- /dev/null
+++ 
b/ratis-examples/src/main/java/org/apache/ratis/examples/arithmetic/cli/Client.java
@@ -0,0 +1,56 @@
+/**
+ * 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
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * 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.examples.arithmetic.cli;
+
+import org.apache.ratis.client.RaftClient;
+import org.apache.ratis.conf.Parameters;
+import org.apache.ratis.conf.RaftProperties;
+import org.apache.ratis.grpc.GrpcFactory;
+import org.apache.ratis.protocol.ClientId;
+import org.apache.ratis.protocol.RaftGroup;
+import org.apache.ratis.protocol.RaftGroupId;
+import org.apache.ratis.shaded.com.google.protobuf.ByteString;
+
+import java.io.IOException;
+
+/**
+ * Client to connect arithmetic example cluster.
+ */
+public abstract class Client extends SubCommandBase {
+
+
+  @Override
+  public void run() throws Exception {
+    RaftProperties raftProperties = new RaftProperties();
+
+    RaftGroup raftGroup = new 
RaftGroup(RaftGroupId.valueOf(ByteString.copyFromUtf8(raftGroupId)),
+        parsePeers(peers));
+
+    RaftClient.Builder builder =
+        RaftClient.newBuilder().setProperties(raftProperties);
+    builder.setRaftGroup(raftGroup);
+    builder.setClientRpc(new GrpcFactory(new 
Parameters()).newRaftClientRpc(ClientId.randomId(), raftProperties));
+    RaftClient client = builder.build();
+
+    operation(client);
+
+
+  }
+
+  protected abstract void operation(RaftClient client) throws IOException;
+}

http://git-wip-us.apache.org/repos/asf/incubator-ratis/blob/dfeb671f/ratis-examples/src/main/java/org/apache/ratis/examples/arithmetic/cli/Get.java
----------------------------------------------------------------------
diff --git 
a/ratis-examples/src/main/java/org/apache/ratis/examples/arithmetic/cli/Get.java
 
b/ratis-examples/src/main/java/org/apache/ratis/examples/arithmetic/cli/Get.java
new file mode 100644
index 0000000..4cad380
--- /dev/null
+++ 
b/ratis-examples/src/main/java/org/apache/ratis/examples/arithmetic/cli/Get.java
@@ -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
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * 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.examples.arithmetic.cli;
+
+import com.beust.jcommander.Parameter;
+import com.beust.jcommander.Parameters;
+import org.apache.ratis.client.RaftClient;
+import org.apache.ratis.examples.arithmetic.AssignmentMessage;
+import org.apache.ratis.examples.arithmetic.expression.DoubleValue;
+import org.apache.ratis.examples.arithmetic.expression.Expression;
+import org.apache.ratis.examples.arithmetic.expression.Variable;
+import org.apache.ratis.protocol.RaftClientReply;
+
+import java.io.IOException;
+
+/**
+ * Subcommand to get value from the state machine.
+ */
+@Parameters(commandDescription = "Assign value to a variable.")
+public class Get extends Client {
+
+  @Parameter(names = {
+      "--name"}, description = "Name of the variable to set", required = true)
+  String name;
+
+  @Override
+  protected void operation(RaftClient client) throws IOException {
+    RaftClientReply getValue =
+        client.sendReadOnly(Expression.Utils.toMessage(new Variable(name)));
+    Expression response =
+        
Expression.Utils.bytes2Expression(getValue.getMessage().getContent().toByteArray(),
 0);
+    System.out.println(String.format("%s=%s", name, (DoubleValue) 
response).toString());
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-ratis/blob/dfeb671f/ratis-examples/src/main/java/org/apache/ratis/examples/arithmetic/cli/Server.java
----------------------------------------------------------------------
diff --git 
a/ratis-examples/src/main/java/org/apache/ratis/examples/arithmetic/cli/Server.java
 
b/ratis-examples/src/main/java/org/apache/ratis/examples/arithmetic/cli/Server.java
new file mode 100644
index 0000000..be3b2bd
--- /dev/null
+++ 
b/ratis-examples/src/main/java/org/apache/ratis/examples/arithmetic/cli/Server.java
@@ -0,0 +1,88 @@
+/**
+ * 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
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * 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.examples.arithmetic.cli;
+
+import com.beust.jcommander.Parameter;
+import com.beust.jcommander.Parameters;
+import org.apache.ratis.conf.RaftProperties;
+import org.apache.ratis.examples.arithmetic.ArithmeticStateMachine;
+import org.apache.ratis.grpc.GrpcConfigKeys;
+import org.apache.ratis.protocol.RaftGroup;
+import org.apache.ratis.protocol.RaftGroupId;
+import org.apache.ratis.protocol.RaftPeer;
+import org.apache.ratis.protocol.RaftPeerId;
+import org.apache.ratis.server.RaftServer;
+import org.apache.ratis.server.RaftServerConfigKeys;
+import org.apache.ratis.shaded.com.google.protobuf.ByteString;
+import org.apache.ratis.statemachine.StateMachine;
+import org.apache.ratis.util.NetUtils;
+
+import java.io.File;
+import java.util.Objects;
+
+/**
+ * Class to start a ratis arithmetic example server.
+ */
+@Parameters(commandDescription = "Start an arithmetic server")
+public class Server extends SubCommandBase {
+
+  @Parameter(names = {"--id",
+      "-i"}, description = "Raft id of this server", required = true)
+  private String id;
+
+  @Parameter(names = {"--storage",
+      "-s"}, description = "Storage dir", required = true)
+  private File storageDir;
+
+
+  @Override
+  public void run() throws Exception {
+    RaftPeerId peerId = RaftPeerId.valueOf(id);
+    RaftProperties properties = new RaftProperties();
+
+    RaftPeer[] peers = getPeers();
+    final int port = 
NetUtils.createSocketAddr(getPeer(peerId).getAddress()).getPort();
+    GrpcConfigKeys.Server.setPort(properties, port);
+    properties.setInt(GrpcConfigKeys.OutputStream.RETRY_TIMES_KEY, 
Integer.MAX_VALUE);
+    RaftServerConfigKeys.setStorageDir(properties, storageDir);
+    StateMachine stateMachine = new ArithmeticStateMachine();
+
+    RaftGroup raftGroup = new 
RaftGroup(RaftGroupId.valueOf(ByteString.copyFromUtf8(raftGroupId)), peers);
+    RaftServer raftServer = RaftServer.newBuilder()
+        .setServerId(RaftPeerId.valueOf(id))
+        .setStateMachine(stateMachine).setProperties(properties)
+        .setGroup(raftGroup)
+        .build();
+    raftServer.start();
+  }
+
+  /**
+   * @return the peer with the given id if it is in this group; otherwise, 
return null.
+   */
+  public RaftPeer getPeer(RaftPeerId id) {
+    Objects.requireNonNull(id, "id == null");
+    for (RaftPeer p : getPeers()) {
+      if (id.equals(p.getId())) {
+        return p;
+      }
+    }
+    throw new IllegalArgumentException("Raft peer id " + id + " is not part of 
the raft group definitions " + peers);
+  }
+
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-ratis/blob/dfeb671f/ratis-examples/src/main/java/org/apache/ratis/examples/arithmetic/cli/SubCommandBase.java
----------------------------------------------------------------------
diff --git 
a/ratis-examples/src/main/java/org/apache/ratis/examples/arithmetic/cli/SubCommandBase.java
 
b/ratis-examples/src/main/java/org/apache/ratis/examples/arithmetic/cli/SubCommandBase.java
new file mode 100644
index 0000000..0c982e4
--- /dev/null
+++ 
b/ratis-examples/src/main/java/org/apache/ratis/examples/arithmetic/cli/SubCommandBase.java
@@ -0,0 +1,53 @@
+/**
+ * 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.examples.arithmetic.cli;
+
+import com.beust.jcommander.Parameter;
+import org.apache.ratis.protocol.RaftPeer;
+import org.apache.ratis.protocol.RaftPeerId;
+
+import java.util.stream.Stream;
+
+/**
+ * Base subcommand class which includes the basic raft properties.
+ */
+public abstract class SubCommandBase {
+
+  @Parameter(names = {"--raftGroup",
+      "-g"}, description = "Raft group identifier")
+  protected String raftGroupId = "demoRaftGroup123";
+
+  @Parameter(names = {"--peers", "-r"}, description =
+      "Raft peers (format: name:host:port,"
+          + "name:host:port)", required = true)
+  protected String peers;
+
+  public static RaftPeer[] parsePeers(String peers) {
+    return Stream.of(peers.split(",")).map(address -> {
+      String[] addressParts = address.split(":");
+      return new RaftPeer(RaftPeerId.valueOf(addressParts[0]),
+          addressParts[1] + ":" + addressParts[2]);
+    }).toArray(RaftPeer[]::new);
+  }
+
+  public RaftPeer[] getPeers() {
+    return parsePeers(peers);
+  }
+
+  public abstract void run() throws Exception;
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-ratis/blob/dfeb671f/ratis-examples/src/main/java/org/apache/ratis/examples/arithmetic/expression/BinaryExpression.java
----------------------------------------------------------------------
diff --git 
a/ratis-examples/src/main/java/org/apache/ratis/examples/arithmetic/expression/BinaryExpression.java
 
b/ratis-examples/src/main/java/org/apache/ratis/examples/arithmetic/expression/BinaryExpression.java
index ca2d88e..c8f3537 100644
--- 
a/ratis-examples/src/main/java/org/apache/ratis/examples/arithmetic/expression/BinaryExpression.java
+++ 
b/ratis-examples/src/main/java/org/apache/ratis/examples/arithmetic/expression/BinaryExpression.java
@@ -20,6 +20,7 @@ package org.apache.ratis.examples.arithmetic.expression;
 import org.apache.ratis.util.Preconditions;
 
 import java.util.Map;
+import java.util.Objects;
 import java.util.function.BinaryOperator;
 
 public class BinaryExpression implements Expression {
@@ -64,6 +65,10 @@ public class BinaryExpression implements Expression {
       Preconditions.assertTrue(b < VALUES.length);
       return VALUES[b];
     }
+
+    public String getSymbol() {
+      return symbol;
+    }
   }
 
   private final Op op;
@@ -118,4 +123,19 @@ public class BinaryExpression implements Expression {
   public String toString() {
     return "(" + left + " " + op + " " + right + ")";
   }
+
+  @Override
+  public boolean equals(Object o) {
+    if (this == o) return true;
+    if (o == null || getClass() != o.getClass()) return false;
+    BinaryExpression that = (BinaryExpression) o;
+    return op == that.op &&
+        Objects.equals(left, that.left) &&
+        Objects.equals(right, that.right);
+  }
+
+  @Override
+  public int hashCode() {
+    return Objects.hash(op);
+  }
 }

http://git-wip-us.apache.org/repos/asf/incubator-ratis/blob/dfeb671f/ratis-examples/src/main/java/org/apache/ratis/examples/arithmetic/expression/DoubleValue.java
----------------------------------------------------------------------
diff --git 
a/ratis-examples/src/main/java/org/apache/ratis/examples/arithmetic/expression/DoubleValue.java
 
b/ratis-examples/src/main/java/org/apache/ratis/examples/arithmetic/expression/DoubleValue.java
index 0d58996..9edf8d6 100644
--- 
a/ratis-examples/src/main/java/org/apache/ratis/examples/arithmetic/expression/DoubleValue.java
+++ 
b/ratis-examples/src/main/java/org/apache/ratis/examples/arithmetic/expression/DoubleValue.java
@@ -20,6 +20,7 @@ package org.apache.ratis.examples.arithmetic.expression;
 import org.apache.ratis.util.Preconditions;
 
 import java.util.Map;
+import java.util.Objects;
 
 public class DoubleValue implements Expression {
   public static final DoubleValue ZERO = new DoubleValue(0);
@@ -59,4 +60,17 @@ public class DoubleValue implements Expression {
     final long n = (long)value;
     return n == value? String.valueOf(n): String.valueOf(value);
   }
+
+  @Override
+  public boolean equals(Object o) {
+    if (this == o) return true;
+    if (o == null || getClass() != o.getClass()) return false;
+    DoubleValue that = (DoubleValue) o;
+    return Double.compare(that.value, value) == 0;
+  }
+
+  @Override
+  public int hashCode() {
+    return Objects.hash(value);
+  }
 }

http://git-wip-us.apache.org/repos/asf/incubator-ratis/blob/dfeb671f/ratis-examples/src/main/java/org/apache/ratis/examples/arithmetic/expression/UnaryExpression.java
----------------------------------------------------------------------
diff --git 
a/ratis-examples/src/main/java/org/apache/ratis/examples/arithmetic/expression/UnaryExpression.java
 
b/ratis-examples/src/main/java/org/apache/ratis/examples/arithmetic/expression/UnaryExpression.java
index 888c87b..74b6ba8 100644
--- 
a/ratis-examples/src/main/java/org/apache/ratis/examples/arithmetic/expression/UnaryExpression.java
+++ 
b/ratis-examples/src/main/java/org/apache/ratis/examples/arithmetic/expression/UnaryExpression.java
@@ -20,6 +20,7 @@ package org.apache.ratis.examples.arithmetic.expression;
 import org.apache.ratis.util.Preconditions;
 
 import java.util.Map;
+import java.util.Objects;
 import java.util.function.BiFunction;
 import java.util.function.DoubleFunction;
 import java.util.function.UnaryOperator;
@@ -71,6 +72,10 @@ public class UnaryExpression implements Expression {
       Preconditions.assertTrue(b < VALUES.length);
       return VALUES[b];
     }
+
+    public String getSymbol() {
+      return symbol;
+    }
   }
 
   final Op op;
@@ -116,6 +121,20 @@ public class UnaryExpression implements Expression {
   }
 
   @Override
+  public boolean equals(Object o) {
+    if (this == o) return true;
+    if (o == null || getClass() != o.getClass()) return false;
+    UnaryExpression that = (UnaryExpression) o;
+    return op == that.op &&
+        Objects.equals(expression, that.expression);
+  }
+
+  @Override
+  public int hashCode() {
+    return Objects.hash(expression);
+  }
+
+  @Override
   public String toString() {
     return op.toString(expression);
   }

http://git-wip-us.apache.org/repos/asf/incubator-ratis/blob/dfeb671f/ratis-examples/src/test/java/org/apache/ratis/examples/arithmetic/cli/AssignTest.java
----------------------------------------------------------------------
diff --git 
a/ratis-examples/src/test/java/org/apache/ratis/examples/arithmetic/cli/AssignTest.java
 
b/ratis-examples/src/test/java/org/apache/ratis/examples/arithmetic/cli/AssignTest.java
new file mode 100644
index 0000000..e8f1e66
--- /dev/null
+++ 
b/ratis-examples/src/test/java/org/apache/ratis/examples/arithmetic/cli/AssignTest.java
@@ -0,0 +1,53 @@
+/**
+ * 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.examples.arithmetic.cli;
+
+import org.apache.ratis.examples.arithmetic.expression.BinaryExpression;
+import org.apache.ratis.examples.arithmetic.expression.DoubleValue;
+import org.apache.ratis.examples.arithmetic.expression.UnaryExpression;
+import org.apache.ratis.examples.arithmetic.expression.Variable;
+import org.junit.Assert;
+import org.junit.Test;
+
+public class AssignTest {
+  @Test
+  public void createExpression() throws Exception {
+    //  Assert.assertEquals(new DoubleValue(2.0), new 
Assign().createExpression("2.0"));
+
+    Assert.assertEquals(
+        new BinaryExpression(BinaryExpression.Op.MULT, new DoubleValue(2.0), 
new Variable("a")),
+        new Assign().createExpression("2*a"));
+
+    Assert.assertEquals(
+        new BinaryExpression(BinaryExpression.Op.ADD, new DoubleValue(2.0), 
new DoubleValue(1.0)),
+        new Assign().createExpression("2+1"));
+
+    Assert.assertEquals(
+        new BinaryExpression(BinaryExpression.Op.ADD, new Variable("a"), new 
Variable("b")),
+        new Assign().createExpression("a+b"));
+
+    Assert.assertEquals(
+        new UnaryExpression(UnaryExpression.Op.SQRT, new Variable("a")),
+        new Assign().createExpression("√a"));
+
+    Assert.assertEquals(
+        new UnaryExpression(UnaryExpression.Op.SQRT, new DoubleValue(2.0)),
+        new Assign().createExpression("√2"));
+  }
+
+}
\ No newline at end of file


Reply via email to