diff --git a/client/pom.xml b/client/pom.xml index 9c22c74..1e9b15d 100644 --- a/client/pom.xml +++ b/client/pom.xml @@ -20,17 +20,35 @@ ${project.version} - - - org.testng - testng + args4j + args4j test - args4j - args4j + info.picocli + picocli + 4.0.4 + + + + org.reflections + reflections + 0.9.11 + + + + pl.joegreen + lambda-from-string + 1.6 + + + + + + org.testng + testng test @@ -43,6 +61,24 @@ + + org.apache.maven.plugins + maven-compiler-plugin + + ${maven-compiler-plugin-version} + + + + info.picocli + picocli-codegen + 4.0.4 + + + + -Aproject=${groupId}/${artifactId} + + + org.codehaus.mojo aspectj-maven-plugin @@ -97,4 +133,3 @@ - diff --git a/client/src/main/java/org/infinispan/creson/AtomicCounter.java b/client/src/main/java/org/infinispan/creson/AtomicCounter.java index 0634f64..3254d18 100644 --- a/client/src/main/java/org/infinispan/creson/AtomicCounter.java +++ b/client/src/main/java/org/infinispan/creson/AtomicCounter.java @@ -1,17 +1,28 @@ package org.infinispan.creson; +import picocli.CommandLine.Command; +import picocli.CommandLine.Option; + import javax.persistence.Entity; import javax.persistence.Id; @Entity +@Command(name = "counter") public class AtomicCounter implements Comparable { @Id - public String name; - public int count; + @Option(names = "-n" ) + public String name = "cnt"; + + @Option(names = "-c" ) + public int count = 0; public AtomicCounter(){} + public AtomicCounter(String name) { + this.name = name; + } + public AtomicCounter(String name, int value){ this.name = name; this.count = value; @@ -21,7 +32,8 @@ public int increment() { return increment(1); } - public int increment(int inc){ + @Command(name = "increment") + public int increment(@Option(names = "-i") int inc){ count+=inc; return count; } @@ -30,16 +42,19 @@ public int decrement() { return --count; } + @Command(name = "tally") public int tally() { return count; } + @Override public int compareTo(AtomicCounter that) { if (this.count < that.count) return -1; else if (this.count > that.count) return +1; else return 0; } + @Command(name = "reset") public void reset() { count=0; } diff --git a/client/src/main/java/org/infinispan/creson/AtomicList.java b/client/src/main/java/org/infinispan/creson/AtomicList.java new file mode 100644 index 0000000..1b6aa3c --- /dev/null +++ b/client/src/main/java/org/infinispan/creson/AtomicList.java @@ -0,0 +1,157 @@ +package org.infinispan.creson; + +import picocli.CommandLine.Command; +import picocli.CommandLine.Option; + +import javax.persistence.Entity; +import javax.persistence.Id; +import java.util.*; + +@Entity +@Command(name = "list") +public class AtomicList implements List { + + @Id + @Option(names = "-n" ) + public String name = "list"; + + private List delegate; + + public AtomicList(){} + + public AtomicList(String name){ + this.name = name; + this.delegate = new ArrayList<>(); + } + + @Override + @Command(name = "size") + public int size() { + return delegate.size(); + } + + @Override + @Command(name = "isEmpty") + public boolean isEmpty() { + return delegate.isEmpty(); + } + + @Override + @Command(name = "contains") + public boolean contains(@Option(names = "-1") Object o) { + return delegate.contains(o); + } + + @Override + public Iterator iterator() { + throw new IllegalStateException(); + } + + @Override + @Command(name = "toArray") + public Object[] toArray() { + return (Object[]) delegate.toArray(); + } + + @Override + public T[] toArray(T[] ts) { + throw new IllegalStateException(); + } + + @Override + @Command(name = "add") + public boolean add(@Option(names = "-1") E e) { + return delegate.add(e); + } + + @Override + @Command(name = "remove") + public boolean remove(@Option(names = "-1") Object o) { + return delegate.remove(o); + } + + @Override + @Command(name = "containsAll") + public boolean containsAll(@Option(names = "-1") Collection collection) { + return delegate.containsAll(collection); + } + + @Override + @Command(name = "addAll") + public boolean addAll(@Option(names = "-1") Collection collection) { + return delegate.addAll(collection); + } + + @Override + public boolean addAll(int i, Collection collection) { + throw new IllegalStateException(); + } + + @Override + @Command(name = "removeAll") + public boolean removeAll(@Option(names = "-1") Collection collection) { + return delegate.removeAll(collection); + } + + @Override + @Command(name = "retainAll") + public boolean retainAll(@Option(names = "-1") Collection collection) { + return delegate.retainAll(collection); + } + + @Override + @Command(name = "clear") + public void clear() { + delegate.clear(); + } + + @Override + @Command(name = "get") + public E get(@Option(names = "-1") int i) { + return delegate.get(i); + } + + @Override + @Command(name = "set") + public E set(@Option(names = "-1") int i, @Option(names = "-2") E e) { + return delegate.set(i,e); + } + + @Override + public void add(int i, E e) { + throw new IllegalStateException(); + } + + @Override + public E remove(int i) { + throw new IllegalStateException(); + } + + @Override + @Command(name = "indexOf") + public int indexOf(@Option(names = "-1") Object o) { + return delegate.indexOf(o); + } + + @Override + @Command(name = "lastIndexOf") + public int lastIndexOf(@Option(names = "-1") Object o) { + return delegate.lastIndexOf(o); + } + + @Override + public ListIterator listIterator() { + throw new IllegalStateException(); + } + + @Override + public ListIterator listIterator(int i) { + throw new IllegalStateException(); + } + + @Override + @Command(name = "subList") + public List subList(@Option(names = "-1") int i, @Option(names = "-2") int j) { + return new ArrayList<>(delegate.subList(i,j)); // inner class + } +} diff --git a/client/src/main/java/org/infinispan/creson/AtomicMap.java b/client/src/main/java/org/infinispan/creson/AtomicMap.java new file mode 100644 index 0000000..8b89480 --- /dev/null +++ b/client/src/main/java/org/infinispan/creson/AtomicMap.java @@ -0,0 +1,114 @@ +package org.infinispan.creson; + +import java.util.Collection; +import java.util.Map; +import java.util.Set; + +import picocli.CommandLine.Command; +import picocli.CommandLine.Option; + +import javax.persistence.Entity; +import javax.persistence.Id; +import java.util.*; +import java.util.function.BiFunction; + +@Entity +@Command(name = "map") +public class AtomicMap implements MergeableMap { + + @Id + @Option(names = "-n" ) + public String name = "map"; + + public Map delegate; + + public AtomicMap(){} + + public AtomicMap(String name){ + this.name = name; + this.delegate = new HashMap<>(); + } + + @Override + @Command(name = "size") + public int size() { + return delegate.size(); + } + + @Override + @Command(name = "isEmpty") + public boolean isEmpty() { + return delegate.isEmpty(); + } + + @Override + @Command(name = "containsKey") + public boolean containsKey(@Option(names = "-a") Object o) { + return delegate.containsKey(o); + } + + @Override + @Command(name = "containsValue") + public boolean containsValue(@Option(names = "-1") Object o) { + return delegate.containsValue(o); + } + + @Command(name = "get") + public V get(@Option(names = "-1") Object o) { + return delegate.get(o); + } + + @Override + @Command(name = "put") + public V put(@Option(names = "-1") K k, @Option(names = "-2") V v) { + return delegate.put(k,v); + } + + @Override + @Command(name = "remove") + public V remove(@Option(names = "-1") Object o) { + return delegate.remove(o); + } + + @Override + @Command(name = "putAll") + public void putAll(@Option(names = "-1") Map map) { + delegate.putAll(map); + } + + @Override + @Command(name = "clear") + public void clear() { + delegate.clear(); + } + + @Override + @Command(name = "keySet") + public Set keySet() { + return new HashSet<>(delegate.keySet()); // inner class + } + + @Override + @Command(name = "values") + public Collection values() { + return new ArrayList<>(delegate.values()); // inner class + } + + @Override + public Set> entrySet() { + throw new IllegalStateException(); + } + + @Override + @Command(name= "merge") + public V merge(@Option(names = "-1") K k, @Option(names = "-2") V v, @Option(names = "-3") BiFunction f) { + return delegate.merge(k, v, f); + } + + @Command(name= "mergeAll") + public void mergeAl(@Option(names = "-1") Map m, @Option(names = "-2") BiFunction f){ + MergeableMap.super.mergeAll(m, f); + } + + +} diff --git a/client/src/main/java/org/infinispan/creson/CyclicBarrier.java b/client/src/main/java/org/infinispan/creson/CyclicBarrier.java index 32a5f25..c4f5d13 100644 --- a/client/src/main/java/org/infinispan/creson/CyclicBarrier.java +++ b/client/src/main/java/org/infinispan/creson/CyclicBarrier.java @@ -1,19 +1,37 @@ package org.infinispan.creson; +import picocli.CommandLine.Command; +import picocli.CommandLine.Option; + +@Command(name = "barrier") public class CyclicBarrier { private static final int MAGIC = 10; + @Option(names = "-n" ) + public String name = "barrier"; + + @Option(names = "-p" ) + public int parties = 1; private AtomicCounter counter; private AtomicCounter generation; - private int parties; + + public CyclicBarrier(){} public CyclicBarrier(String name, int parties){ + this.name = name; this.counter = new AtomicCounter(name+"-counter",0); this.generation = new AtomicCounter(name+"-generation",0); this.parties = parties; } + @Command(name = "reset") + public void reset(){ + counter.reset(); + generation.reset(); + } + + @Command(name = "await") public int await(){ int previous = generation.tally(); int ret = counter.increment(); diff --git a/client/src/main/java/org/infinispan/creson/MergeableMap.java b/client/src/main/java/org/infinispan/creson/MergeableMap.java new file mode 100644 index 0000000..a08c88d --- /dev/null +++ b/client/src/main/java/org/infinispan/creson/MergeableMap.java @@ -0,0 +1,18 @@ +package org.infinispan.creson; + +import java.util.Map; +import java.util.function.BiFunction; + +/** + * ... + *

+ * Date: 2018-02-07 + * + * @author Daniel + */ +public interface MergeableMap extends Map{ + + default void mergeAll(Map m, BiFunction f){ + m.forEach((k, v) -> merge(k, v, f)); + } +} diff --git a/client/src/main/java/org/infinispan/creson/client/Interpreter.java b/client/src/main/java/org/infinispan/creson/client/Interpreter.java new file mode 100644 index 0000000..a87fefe --- /dev/null +++ b/client/src/main/java/org/infinispan/creson/client/Interpreter.java @@ -0,0 +1,114 @@ +package org.infinispan.creson.client; + +import com.google.common.collect.ImmutableMap; +import org.infinispan.creson.*; +import picocli.CommandLine; +import picocli.CommandLine.Command; +import picocli.CommandLine.Option; +import pl.joegreen.lambdaFromString.LambdaCreationException; +import pl.joegreen.lambdaFromString.LambdaFactory; +import pl.joegreen.lambdaFromString.TypeReference; + +import java.io.*; +import java.lang.invoke.*; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.Collection; +import java.util.Map; +import java.util.concurrent.Callable; +import java.util.function.BiFunction; +import java.util.function.Consumer; + +@Command(name = "interpreter") +public class Interpreter implements Callable { + + public static final String DEFAULT_SERVER = "localhost:11222"; + + @Option(names = "-s" ) String server = DEFAULT_SERVER; + + public static void main(String[] args) { + + // 1 - parse + Interpreter client = new Interpreter(); + CommandLine commandLine = new CommandLine(client); + AtomicCounter counter = newInstance(AtomicCounter.class); + AtomicList list = newInstance(AtomicList.class); + AtomicMap map = newInstance(AtomicMap.class); + CyclicBarrier barrier = newInstance(CyclicBarrier.class); + commandLine.addSubcommand("counter", counter); + commandLine.addSubcommand("list", list); + commandLine.addSubcommand("map", map); + commandLine.addSubcommand("barrier", barrier); + commandLine.registerConverter(BiFunction.class, s -> new BiFunctionTypeConverter().convert(s)); + commandLine.parseArgs(args); + + // 2 - execute + Factory.get(client.server); + commandLine = new CommandLine(client); + commandLine.addSubcommand("counter",new AtomicCounter(counter.name, counter.count)); + commandLine.addSubcommand("list",new AtomicList<>(counter.name)); + commandLine.addSubcommand("map",new AtomicMap<>(map.name)); + commandLine.addSubcommand("barrier",new CyclicBarrier(barrier.name, barrier.parties)); + commandLine.registerConverter(BiFunction.class, s -> new BiFunctionTypeConverter().convert(s)); + commandLine.execute(args); + + Object executionResult = commandLine.getExecutionResult(); + CommandLine.ParseResult parseResult = commandLine.getParseResult(); + while (parseResult.subcommand() != null) { + CommandLine sub = parseResult.subcommand().commandSpec().commandLine(); + executionResult = sub.getExecutionResult(); + parseResult = sub.getParseResult(); + } + + // 3 - print result (in Unix shell format) + String result = ""; + if (executionResult == null){ + result = null; + } else if (executionResult instanceof Object[]) { + for (Object o : (Object[]) executionResult) { + result += o.toString() + " "; + } + } else if (executionResult instanceof Collection) { + for (Object o : (Collection) executionResult) { + result += o.toString() + " "; + } + } else { + result = executionResult.toString(); + } + if (result != null) System.out.println(result); + + System.exit(0); + } + + @Override + public Integer call() throws Exception { + Factory.get(this.server); + return 0; + } + + + private static T newInstance(Class clazz) { + try { + return clazz.newInstance(); + } catch (IllegalAccessException | InstantiationException e) { + e.printStackTrace(); + } + return null; + } + + public static interface RemoteBiFunction extends BiFunction, Serializable{} + + public static final Map> BIFUNCTIONS = ImmutableMap.of( + "sum", (x,y) -> Integer.toString(Integer.valueOf(x) + Integer.valueOf(y)) + ); + + public static class BiFunctionTypeConverter implements CommandLine.ITypeConverter { + + @Override + public BiFunction convert(String s) throws Exception { + return BIFUNCTIONS.get(s); + } + + } + +} diff --git a/client/src/test/bin/k8s/gcp/bootstrap.sh b/client/src/test/bin/k8s/gcp/bootstrap.sh index 2e98f8e..9e58a8a 100755 --- a/client/src/test/bin/k8s/gcp/bootstrap.sh +++ b/client/src/test/bin/k8s/gcp/bootstrap.sh @@ -64,7 +64,7 @@ fetch_credentials() { } name="creson" -zone="europe-north1-c" +zone="us-east4-a" sleep_time=$((i * 2)) # avoid "gcp db locked" error create_cluster ${name} ${zone} ${sleep_time} diff --git a/client/src/test/bin/k8s/test.sh b/client/src/test/bin/k8s/test.sh index f9ab8b9..a4c79f9 100755 --- a/client/src/test/bin/k8s/test.sh +++ b/client/src/test/bin/k8s/test.sh @@ -20,8 +20,8 @@ THREADS=1 if [[ "$1" == "-create" ]] then - # k8s_rs_create ${TMPLDIR}/replicaset.yaml.tmpl 50 4 "LAUNCHED" - k8s_rs_cp ${TMPLDIR}/replicaset.yaml.tmpl ${DIR}/../../../../target/infinispan-creson-client-9.4.1.Final.jar/ /tmp + k8s_rs_create ${TMPLDIR}/replicaset.yaml.tmpl 1 1 "LAUNCHED" + k8s_rs_cp ${TMPLDIR}/replicaset.yaml.tmpl ${DIR}/../../../../target/infinispan-creson-client-9.4.16.Final.jar/ /tmp # kubectl create -f ${TMPLDIR}/autoscaler.yaml # kubectl autoscale replicaset infinispan-creson-server --cpu-percent=50 --min=3 --max=8 # FIXME elif [[ "$1" == "-delete" ]] diff --git a/pom.xml b/pom.xml index 6bb53bb..920435a 100644 --- a/pom.xml +++ b/pom.xml @@ -14,6 +14,7 @@ 1.8 1.8 + 3.8.1 UTF-8 3.5.1 18.0 diff --git a/server/src/main/docker/Dockerfile b/server/src/main/docker/Dockerfile index a751026..5710ac0 100644 --- a/server/src/main/docker/Dockerfile +++ b/server/src/main/docker/Dockerfile @@ -3,7 +3,7 @@ FROM openjdk:8-slim MAINTAINER otrack ENV NAME=infinispan-creson-server -ENV VERSION=9.4.1.Final +ENV VERSION=9.4.16.Final ENV CLOUD=local ENV BUCKET=undefined ENV BUCKET_KEY=undefined