diff --git a/client/pom.xml b/client/pom.xml index 7af3b38..021cca0 100644 --- a/client/pom.xml +++ b/client/pom.xml @@ -4,7 +4,7 @@ org.crucial dso - 1.0 + 2.0 ../ @@ -12,6 +12,10 @@ dso-client Client side of the DSO datastore. + + true + + @@ -29,7 +33,6 @@ info.picocli picocli - 4.0.4 @@ -79,30 +82,6 @@ - - org.codehaus.mojo - aspectj-maven-plugin - ${version.aspectj-maven} - - - - ${project.groupId} - dso-core - - - 1.8 - 1.8 - 1.8 - - - - - compile - test-compile - - - - maven-dependency-plugin @@ -129,6 +108,27 @@ + + org.codehaus.mojo + exec-maven-plugin + 1.6.0 + + ${maven.exec.skip} + + + + Unit test + test + + exec + + + bash + ${basedir}/src/test/bin/unit.sh + + + + diff --git a/client/src/main/java/org/crucial/dso/client/Client.java b/client/src/main/java/org/crucial/dso/client/Client.java index d19cc0e..a38fcff 100644 --- a/client/src/main/java/org/crucial/dso/client/Client.java +++ b/client/src/main/java/org/crucial/dso/client/Client.java @@ -3,6 +3,7 @@ import org.crucial.dso.*; import java.util.ArrayList; +import java.util.List; import java.util.Map; /** @@ -20,45 +21,58 @@ private Client(String server) { factory = Factory.get(server); } + private Client(String server, long seed) { factory = Factory.get(server, seed); } + /** * Return a client or create one if not already present. * @param server + * @param seed * @return */ - public synchronized static Client getClient(String server) { + public synchronized static Client getClient(String server, long seed) { if (client == null) { - client = new Client(server== null ? defaultServer : server); + client = new Client(server== null ? defaultServer : server, seed); } return client; } - public Logger getLog(String key) { - return factory.getInstanceOf(Logger.class, key); + public synchronized static Client getClient(String server) { + return getClient(server, 0); } - public Map getMap(String key) { - return factory.getInstanceOf(Map.class, key); + public Logger getLog(String key) { + return factory.getInstanceOf(Logger.class, key); } - public ArrayList getArrayList(String key) { - return factory.getInstanceOf(ArrayList.class, key); + public List getAtomicList(String key) { + return factory.getInstanceOf(AtomicList.class, key); } - public ArrayList getArrayList(String key, int initialCapacity) { - return factory.getInstanceOf(ArrayList.class, key); + public Future getFuture(String key, boolean forceNew) { + return forceNew ? factory.getInstanceOf(Future.class, key) + : factory.getInstanceOf(Future.class, key, false, false, false); } - public Future getCleanFuture(String key, boolean forceNew) { - return forceNew ? factory.getInstanceOf(Future.class, key) - : factory.getInstanceOf(Future.class, key, false, false, true); + public MonitorCyclicBarrier getMonitorCyclicBarrier(String key, int parties) { + return factory.getInstanceOf(MonitorCyclicBarrier.class, key, false, false, false, key, parties); } - public MonitorCyclicBarrier getMonitorCyclicBarrier(String key) { - return factory.getInstanceOf(MonitorCyclicBarrier.class, key); + public CyclicBarrier getCyclicBarrier(String key, int parties) { + AtomicCounter counter = client.getAtomicCounter(key+"-counter",0); + AtomicCounter generation = client.getAtomicCounter(key+"-generation",0); + return new CyclicBarrier(key, parties, counter, generation); } - public MonitorCyclicBarrier getMonitorCyclicBarrier(String key, int parties) { - return factory.getInstanceOf(MonitorCyclicBarrier.class, key, false, false, true); + public ScalableCyclicBarrier getScalableCyclicBarrier(String key, int parties) { + int logParties = (int)(Math.log(parties)/Math.log(2)); + AtomicBoolean[][] answers = new AtomicBoolean[parties][logParties]; + for(int p=0; p { public static void main(String[] args) { // 1 - parse - Interpreter client = new Interpreter(); - CommandLine commandLine = new CommandLine(client); + Interpreter interpreter = new Interpreter(); + CommandLine commandLine = new CommandLine(interpreter); AtomicCounter counter = newInstance(AtomicCounter.class); AtomicList list = newInstance(AtomicList.class); AtomicMap map = newInstance(AtomicMap.class); @@ -35,12 +35,12 @@ public static void main(String[] args) { 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)); + Client client = Client.getClient(interpreter.server); + commandLine = new CommandLine(interpreter); + commandLine.addSubcommand("counter",client.getAtomicCounter(counter.name, counter.count)); + commandLine.addSubcommand("list",client.getAtomicList(counter.name)); + commandLine.addSubcommand("map",client.getAtomicMap(map.name)); + commandLine.addSubcommand("barrier",client.getCyclicBarrier(barrier.name, barrier.parties)); commandLine.registerConverter(BiFunction.class, s -> new BiFunctionTypeConverter().convert(s)); commandLine.execute(args); diff --git a/client/src/test/bin/aliases.sh b/client/src/test/bin/aliases.sh new file mode 100644 index 0000000..55d3522 --- /dev/null +++ b/client/src/test/bin/aliases.sh @@ -0,0 +1,30 @@ +#!/usr/bin/env bash + +DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" +PROJDIR=${DIR}/../../.. + +source ${DIR}/utils.sh + +export SERVER=$(config crucial.server) +export CLASSPATH=${PROJDIR}/target/*:${PROJDIR}/target/lib/* + +counter(){ + java org.crucial.dso.client.Interpreter -s ${SERVER} counter $@ +} + +list(){ + java org.crucial.dso.client.Interpreter -s ${SERVER} list $@ +} + +map(){ + java org.crucial.dso.client.Interpreter -s ${SERVER} map $@ +} + +barrier(){ + java org.crucial.dso.client.Interpreter -s ${SERVER} barrier $@ +} + +export -f counter +export -f list +export -f map +export -f barrier diff --git a/client/src/test/bin/config.properties b/client/src/test/bin/config.properties new file mode 100644 index 0000000..f9ca979 --- /dev/null +++ b/client/src/test/bin/config.properties @@ -0,0 +1 @@ +crucial.server=localhost:11222 \ No newline at end of file diff --git a/client/src/test/bin/config.properties.tmpl b/client/src/test/bin/config.properties.tmpl new file mode 100644 index 0000000..335c120 --- /dev/null +++ b/client/src/test/bin/config.properties.tmpl @@ -0,0 +1 @@ +crucial.server=IP:PORT \ No newline at end of file diff --git a/client/src/test/bin/k8s/gcp/bootstrap.sh b/client/src/test/bin/k8s/gcp/bootstrap.sh index 32e7698..e18deb9 100755 --- a/client/src/test/bin/k8s/gcp/bootstrap.sh +++ b/client/src/test/bin/k8s/gcp/bootstrap.sh @@ -3,10 +3,12 @@ DIR=$(dirname "${BASH_SOURCE[0]}") MACHINE_TYPE=n1-standard-4 -NODE_NUMBER=3 GCP_PROJECT=$(gcloud config list --format='value(core.project)') NETWORK="projects/${GCP_PROJECT}/global/networks/default" +NODE_NUMBER=1 +USER=0track@gmail.com + create_cluster() { if [ $# -ne 3 ]; then echo "usage: create_cluster cluster_name cluster_zone sleep_time" @@ -19,9 +21,9 @@ create_cluster() { sleep ${seconds} gcloud container clusters create ${name} \ - --disk-size 30\ + --disk-size 15\ --zone ${zone} \ - --num-nodes ${NODE_NUMBER} \ + --num-nodes ${NODE_NUMBER} --enable-autoscaling --min-nodes 0 --max-nodes $((2*NODE_NUMBER)) \ --machine-type ${MACHINE_TYPE} \ --network ${NETWORK} \ --preemptible \ @@ -71,6 +73,6 @@ create_cluster ${name} ${zone} ${sleep_time} fetch_credentials ${name} ${zone} # RBAC -kubectl create clusterrolebinding cluster-admin-binding --clusterrole cluster-admin --user 0track@gmail.com -kubectl apply -f ${DIR}/../templates/service.yaml +kubectl create clusterrolebinding cluster-admin-binding --clusterrole cluster-admin --user ${USER} kubectl apply -f ${DIR}/../templates/role.yaml +# kubectl apply -f ${DIR}/../templates/service.yaml diff --git a/client/src/test/bin/k8s/templates/service.yaml b/client/src/test/bin/k8s/templates/service.yaml index 422ddd4..3236c2a 100644 --- a/client/src/test/bin/k8s/templates/service.yaml +++ b/client/src/test/bin/k8s/templates/service.yaml @@ -1,14 +1,12 @@ kind: Service apiVersion: v1 metadata: - name: "helloworldservice" + name: "dso-server" spec: selector: - app: "hello-world" + app: "dso-server" ports: - protocol: TCP - port: 8080 - targetPort: 80 - nodePort: 30001 + port: 11222 + targetPort: 11222 type: LoadBalancer - diff --git a/client/src/test/bin/k8s/test.sh b/client/src/test/bin/k8s/test.sh index 327b46c..380fb37 100755 --- a/client/src/test/bin/k8s/test.sh +++ b/client/src/test/bin/k8s/test.sh @@ -21,7 +21,7 @@ THREADS=1 if [[ "$1" == "-create" ]] then k8s_rs_create ${TMPLDIR}/replicaset.yaml.tmpl 1 0 "LAUNCHED" - k8s_rs_cp ${TMPLDIR}/replicaset.yaml.tmpl ${DIR}/../../../../target/dso-client-1.0.jar/ /tmp + # k8s_rs_cp ${TMPLDIR}/replicaset.yaml.tmpl ${DIR}/../../../../target/dso-client-1.0.jar/ /tmp kubectl create -f ${TMPLDIR}/service.yaml # kubectl create -f ${TMPLDIR}/autoscaler.yaml # kubectl autoscale replicaset dso-server --cpu-percent=50 --min=3 --max=8 # FIXME diff --git a/client/src/test/bin/local/test.sh b/client/src/test/bin/local/test.sh index a7bcad8..1677334 100755 --- a/client/src/test/bin/local/test.sh +++ b/client/src/test/bin/local/test.sh @@ -30,7 +30,12 @@ then for i in `seq 1 ${NSERVERS}` do port=$((11221+i)) - docker run --net host --rm --env EXTRA="-rf 2" --env CLOUD=local --env PORT=${port} ${IMAGE} 2>&1 > ${TARGETDIR}/${i}.log & + docker run --net host --rm \ + --env JVM_EXTRA="-XX:+UseG1GC -Xms64m -Xmx1024m -Dlog4j.configuration=log4j-debug.properties" \ + --env EXTRA="-rf 2" \ + --env CLOUD=local \ + --env PORT=${port} \ + ${IMAGE} 2>&1 > ${TARGETDIR}/${i}.log & done up=0 while [ ${up} != ${NSERVERS} ]; do @@ -38,10 +43,6 @@ then echo -n "." sleep 1 done - for container in $(docker ps | awk '{print $1}' | tail -n ${NSERVERS}) - do - docker cp ${PROJDIR}/target/${CLIENT}-${VERSION}.jar ${container}:/tmp - done echo " up!" elif [[ "$1" == "-delete" ]] then diff --git a/client/src/test/bin/unit.sh b/client/src/test/bin/unit.sh new file mode 100755 index 0000000..ba00bbd --- /dev/null +++ b/client/src/test/bin/unit.sh @@ -0,0 +1,42 @@ +#!/usr/bin/env bash + +DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" + +start(){ + ${DIR}/local/test.sh -create +} + +stop(){ + ${DIR}/local/test.sh -delete +} + +success(){ + echo "ALL PASSED" + stop + exit 0 +} + +fail(){ + echo "FAILURE" + stop + exit 1 +} + +start + +echo "Java tests" +${DIR}/local/test.sh -counters +${DIR}/local/test.sh -blobs +${DIR}/local/test.sh -barrier +${DIR}/local/test.sh -sbarrier +${DIR}/local/test.sh -countdownlatch + +echo "Shell tests" +source ${DIR}/aliases.sh +THREADS=4 +[[ ! -z $(counter -n test reset; counter -n test increment -1 1 | grep "1") ]] || fail +[[ ! -z $(counter -n test increment -1 1 | grep "2" ) ]] || fail +[[ ! -z $(for i in $(seq 1 1 ${THREADS}); do counter -n test increment -1 1 & done | tail -n 1 | grep 6) ]] || fail +[[ ! -z $(for i in $(seq 1 1 ${THREADS}); do barrier -n test -p ${THREADS} await & done | grep ${THREADS}) ]] || fail + +success \ No newline at end of file diff --git a/client/src/test/bin/utils.sh b/client/src/test/bin/utils.sh new file mode 100644 index 0000000..7c22686 --- /dev/null +++ b/client/src/test/bin/utils.sh @@ -0,0 +1,21 @@ +#!/bin/bash + +DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" +TMP_DIR=/tmp/$(whoami) +CODE_DIR=${TMP_DIR}/code +CONFIG_FILE=${DIR}/config.properties + +if [ ! -f ${CONFIG_FILE} ]; +then + echo "${CONFIG_FILE} is missing." + exit 0 +fi + +config() { + if [ $# -ne 1 ]; then + echo "usage: config key" + exit -1 + fi + local key=$1 + cat ${CONFIG_FILE} | grep -E "^${key}=" | cut -d= -f2 +} diff --git a/client/src/test/java/org/crucial/dso/AtomicCounterTask.java b/client/src/test/java/org/crucial/dso/AtomicCounterTask.java index bde4ae4..ac8f177 100644 --- a/client/src/test/java/org/crucial/dso/AtomicCounterTask.java +++ b/client/src/test/java/org/crucial/dso/AtomicCounterTask.java @@ -1,13 +1,15 @@ package org.crucial.dso; +import org.crucial.dso.client.Client; + import java.util.Random; public class AtomicCounterTask extends Task { private Random random; - public AtomicCounterTask(long taskId, String[] parameters, int calls, int threads, int parallelism) { - super(taskId, parameters, calls, threads, parallelism); + public AtomicCounterTask(long taskId, String[] parameters, int calls, int threads, int parallelism, Client client) { + super(taskId, parameters, calls, threads, parallelism, client); random = new Random(); } @@ -19,7 +21,7 @@ public void doCall() { @Override public Object newObject(int id) { - return new AtomicCounter("counter-test-"+id,0); + return client.getAtomicCounter("counter-test-"+id,0); } @Override diff --git a/client/src/test/java/org/crucial/dso/Benchmark.java b/client/src/test/java/org/crucial/dso/Benchmark.java index 5338136..2b0f47b 100644 --- a/client/src/test/java/org/crucial/dso/Benchmark.java +++ b/client/src/test/java/org/crucial/dso/Benchmark.java @@ -1,5 +1,6 @@ package org.crucial.dso; +import org.crucial.dso.client.Client; import org.kohsuke.args4j.CmdLineException; import org.kohsuke.args4j.CmdLineParser; import org.kohsuke.args4j.Option; @@ -71,15 +72,17 @@ public void doMain(String[] args) throws ClassNotFoundException, NoSuchMethodExc return; } - Factory factory = Factory.get(server, id); - barrier = new CyclicBarrier("benchmark", parallelism); + Client client = Client.getClient(server, id); + barrier = client.getCyclicBarrier("benchmark", parallelism); ExecutorService service = Executors.newFixedThreadPool(threads + 1); List clientTasks = new ArrayList<>(); // create threads Class taskClazz = (Class) ClassLoader.getSystemClassLoader().loadClass(className+"Task"); for (int i = 0; i < this.threads; i++) { - Task task = taskClazz.getConstructor(long.class, String[].class, int.class, int.class, int.class).newInstance(id, parameters, calls, threads, parallelism); + Task task = + taskClazz.getConstructor(long.class, String[].class, int.class, int.class, int.class, Client.class) + .newInstance(id, parameters, calls, threads, parallelism, client); clientTasks.add(task); } @@ -134,8 +137,8 @@ public void doMain(String[] args) throws ClassNotFoundException, NoSuchMethodExc } catch (InterruptedException e) { // ignore } - if (!persist) factory.clear(); - factory.close(); + if (!persist) client.clear(); + client.close(); } private static class TroughtputReporter implements Callable { diff --git a/client/src/test/java/org/crucial/dso/BlobTask.java b/client/src/test/java/org/crucial/dso/BlobTask.java index 1c559ae..ac26bda 100644 --- a/client/src/test/java/org/crucial/dso/BlobTask.java +++ b/client/src/test/java/org/crucial/dso/BlobTask.java @@ -1,5 +1,7 @@ package org.crucial.dso; +import org.crucial.dso.client.Client; + import java.util.Random; public class BlobTask extends Task { @@ -7,8 +9,8 @@ public class BlobTask extends Task { private Random random; private int size; - public BlobTask(long taskId, String[] parameters, int calls, int threads, int parallelism) { - super(taskId, parameters, calls, threads, parallelism); + public BlobTask(long taskId, String[] parameters, int calls, int threads, int parallelism, Client client) { + super(taskId, parameters, calls, threads, parallelism, client); assert parameters != null && parameters.length == 1; size = Integer.parseInt(parameters[0]); random = new Random(taskId); @@ -23,6 +25,6 @@ public void doCall() { @Override public Object newObject(int id) { - return new Blob("blob-test-"+id); + return client.getBlob("blob-test-"+id); } } diff --git a/client/src/test/java/org/crucial/dso/CountDownLatchTask.java b/client/src/test/java/org/crucial/dso/CountDownLatchTask.java index 9b23f43..c1c8057 100644 --- a/client/src/test/java/org/crucial/dso/CountDownLatchTask.java +++ b/client/src/test/java/org/crucial/dso/CountDownLatchTask.java @@ -1,9 +1,11 @@ package org.crucial.dso; +import org.crucial.dso.client.Client; + public class CountDownLatchTask extends Task{ - public CountDownLatchTask(long taskId, String[] parameters, int calls, int threads, int parallelism) { - super(taskId, parameters, calls, threads, parallelism); + public CountDownLatchTask(long taskId, String[] parameters, int calls, int threads, int parallelism, Client client) { + super(taskId, parameters, calls, threads, parallelism, client); } @Override @@ -13,7 +15,7 @@ public void doCall() { @Override public Object newObject(int id) { - return new CountDownLatch("barrier-"+id, threads); + return client.getCountDownLatch("barrier-"+id, parallelism*threads); } } diff --git a/client/src/test/java/org/crucial/dso/CyclicBarrierTask.java b/client/src/test/java/org/crucial/dso/CyclicBarrierTask.java index 8c257a6..8698463 100644 --- a/client/src/test/java/org/crucial/dso/CyclicBarrierTask.java +++ b/client/src/test/java/org/crucial/dso/CyclicBarrierTask.java @@ -1,9 +1,11 @@ package org.crucial.dso; +import org.crucial.dso.client.Client; + public class CyclicBarrierTask extends Task{ - public CyclicBarrierTask(long taskId, String[] parameters, int calls, int threads, int parallelism) { - super(taskId, parameters, calls, threads, parallelism); + public CyclicBarrierTask(long taskId, String[] parameters, int calls, int threads, int parallelism, Client client) { + super(taskId, parameters, calls, threads, parallelism, client); } @Override @@ -13,6 +15,6 @@ public void doCall() { @Override public Object newObject(int id) { - return new CyclicBarrier("barrier-"+id, parallelism*threads); + return client.getCyclicBarrier("barrier-"+id, parallelism*threads); } } diff --git a/client/src/test/java/org/crucial/dso/ScalableCyclicBarrierTask.java b/client/src/test/java/org/crucial/dso/ScalableCyclicBarrierTask.java index cc8d6f7..065a757 100644 --- a/client/src/test/java/org/crucial/dso/ScalableCyclicBarrierTask.java +++ b/client/src/test/java/org/crucial/dso/ScalableCyclicBarrierTask.java @@ -1,9 +1,11 @@ package org.crucial.dso; +import org.crucial.dso.client.Client; + public class ScalableCyclicBarrierTask extends Task{ - public ScalableCyclicBarrierTask(long taskId, String[] parameters, int calls, int threads, int parallelism) { - super(taskId, parameters, calls, threads, parallelism); + public ScalableCyclicBarrierTask(long taskId, String[] parameters, int calls, int threads, int parallelism, Client client) { + super(taskId, parameters, calls, threads, parallelism, client); } @Override @@ -13,6 +15,6 @@ public void doCall() { @Override public Object newObject(int id) { - return new ScalableCyclicBarrier("barrier-"+id, parallelism*threads); + return client.getScalableCyclicBarrier("barrier-"+id, parallelism*threads); } } diff --git a/client/src/test/java/org/crucial/dso/Task.java b/client/src/test/java/org/crucial/dso/Task.java index aefd42c..cddd9f2 100644 --- a/client/src/test/java/org/crucial/dso/Task.java +++ b/client/src/test/java/org/crucial/dso/Task.java @@ -1,5 +1,7 @@ package org.crucial.dso; +import org.crucial.dso.client.Client; + import java.util.ArrayList; import java.util.List; import java.util.concurrent.Callable; @@ -9,26 +11,29 @@ public abstract class Task implements Callable { private long taskId; - protected String[] parameters; private int calls; - protected int threads; - protected int parallelism; - protected List instances; - private List latencies; private Lock lock; private boolean isOver; - public Task(long taskId, String[] parameters, int calls, int threads, int parallelism) { + protected Client client; + protected String[] parameters; + protected int threads; + protected int parallelism; + protected List instances; + + public Task(long taskId, String[] parameters, int calls, int threads, int parallelism, Client client) { this.taskId = taskId; this.threads = threads; this.calls = calls; this.parameters = parameters; this.parallelism = parallelism; - latencies = new ArrayList<>(); - isOver = false; - lock = new ReentrantLock(); + this.latencies = new ArrayList<>(); + this.isOver = false; + this.lock = new ReentrantLock(); + + this.client = client; } public double getThroughput() { diff --git a/core/pom.xml b/core/pom.xml index 0915549..14ae7e2 100644 --- a/core/pom.xml +++ b/core/pom.xml @@ -4,7 +4,7 @@ org.crucial dso - 1.0 + 2.0 ../ @@ -51,9 +51,10 @@ javax.persistence-api + - org.aspectj - aspectjrt + info.picocli + picocli @@ -75,24 +76,6 @@ - - org.codehaus.mojo - aspectj-maven-plugin - ${version.aspectj-maven} - - 1.8 - 1.8 - 1.8 - - - - - compile - test-compile - - - - org.apache.maven.plugins maven-surefire-plugin diff --git a/core/src/main/aspect/org/crucial/dso/DistributionClass.aj b/core/src/main/aspect/org/crucial/dso/DistributionClass.aj deleted file mode 100644 index 4093c19..0000000 --- a/core/src/main/aspect/org/crucial/dso/DistributionClass.aj +++ /dev/null @@ -1,31 +0,0 @@ -package org.crucial.dso; - -import org.aspectj.lang.ProceedingJoinPoint; -import org.aspectj.lang.annotation.Around; -import org.aspectj.lang.annotation.Aspect; -import org.aspectj.lang.annotation.Pointcut; - -/** - * @author Pierre Sutra -*/ -@Aspect -public class DistributionClass { - - @Pointcut("call((@javax.persistence.Entity *).new(..)) " + - "&& ! within(org.crucial.dso.container.BaseContainer)") - public static void distributeEntity(ProceedingJoinPoint pjp) { - } - - @Around("distributeEntity(pjp)") - public Object distributionAdviceClass(ProceedingJoinPoint pjp) throws Throwable{ - Factory factory = Factory.getSingleton(); - return factory.getInstanceOf( - pjp.getStaticPart().getSignature().getDeclaringType(), - null, - false, - true, - false, - pjp.getArgs()); - } - -} diff --git a/core/src/main/aspect/org/crucial/dso/DistributionField.java b/core/src/main/aspect/org/crucial/dso/DistributionField.java deleted file mode 100644 index 71d326e..0000000 --- a/core/src/main/aspect/org/crucial/dso/DistributionField.java +++ /dev/null @@ -1,49 +0,0 @@ -package org.crucial.dso; - -import org.aspectj.lang.ProceedingJoinPoint; -import org.aspectj.lang.annotation.Around; -import org.aspectj.lang.annotation.Aspect; -import org.aspectj.lang.annotation.Pointcut; -import org.crucial.dso.object.Reference; - -import java.lang.reflect.Field; -import java.lang.reflect.Modifier; - -@Aspect -public class DistributionField { - - // FIXME constructor? - @Pointcut("set(@org.crucial.dso.Shared * *)") - public static void distributeField(ProceedingJoinPoint pjp) { - } - - @Around("distributeField(pjp)") - public void distributionAdviceField(ProceedingJoinPoint pjp) throws Throwable{ - Factory factory = Factory.getSingleton(); - String fieldName = pjp.getStaticPart().getSignature().getName(); - Class fieldClass = pjp.getArgs()[0].getClass(); - - // parent class name or key if referencable? - String parentClassOrReference = - Reference.isReferencable(pjp.getThis().getClass()) ? - Reference.of(pjp.getThis()).toString() : pjp.getThis().getClass().getCanonicalName(); - - Field field = pjp.getStaticPart().getSignature().getDeclaringType().getDeclaredField(fieldName); - if (!Modifier.isStatic(field.getModifiers())) { - String key = (!field.getAnnotation(Shared.class).key().equals(Shared.DEFAULT_KEY)) ? - field.getAnnotation(Shared.class).key() - : fieldName + Shared.SEPARATOR + parentClassOrReference; - field.setAccessible(true); - field.set(pjp.getTarget(), factory.getInstanceOf( - fieldClass, - key, - field.getAnnotation(Shared.class).readOptimization(), - field.getAnnotation(Shared.class).isIdempotent(), - field.getAnnotation(Shared.class).forceNew())); - return; - } - throw new IllegalStateException("Field "+fieldName+" should not be static."); - } - - -} diff --git a/core/src/main/aspect/org/crucial/dso/Marshalling.aj b/core/src/main/aspect/org/crucial/dso/Marshalling.aj deleted file mode 100644 index 1701435..0000000 --- a/core/src/main/aspect/org/crucial/dso/Marshalling.aj +++ /dev/null @@ -1,48 +0,0 @@ -package org.crucial.dso; - -import java.io.Externalizable; -import java.io.IOException; -import java.io.ObjectInput; -import java.io.ObjectOutput; -import java.lang.reflect.Field; -import java.lang.reflect.Modifier; - -/** - * @author Pierre Sutra - */ -public aspect Marshalling { - - public interface Marshallable extends Externalizable {} - - public void Marshallable.writeExternal(ObjectOutput objectOutput) throws IOException { - try { - for (Field field : this.getClass().getFields()) { - if (!Modifier.isTransient(field.getModifiers()) && - !Modifier.isStatic(field.getModifiers())) { - Object object = field.get(this); - objectOutput.writeObject(object); - } - } - } catch (IllegalAccessException e) { - e.printStackTrace(); - } - } - - public void Marshallable.readExternal(ObjectInput objectInput) throws IOException, ClassNotFoundException { - Factory factory = Factory.getSingleton(); - try { - for (Field field : this.getClass().getFields()) { // same order assumed across nodes - if (!Modifier.isTransient(field.getModifiers()) && - !Modifier.isStatic(field.getModifiers())){ - Object value = objectInput.readObject(); - field.set(this,value); - } - } - } catch (IllegalAccessException e) { - e.printStackTrace(); - } - } - - declare parents: @javax.persistence.Entity * implements Marshallable; - -} \ No newline at end of file diff --git a/client/src/main/java/org/crucial/dso/AtomicBoolean.java b/core/src/main/java/org/crucial/dso/AtomicBoolean.java similarity index 100% rename from client/src/main/java/org/crucial/dso/AtomicBoolean.java rename to core/src/main/java/org/crucial/dso/AtomicBoolean.java diff --git a/client/src/main/java/org/crucial/dso/AtomicByteArray.java b/core/src/main/java/org/crucial/dso/AtomicByteArray.java similarity index 100% rename from client/src/main/java/org/crucial/dso/AtomicByteArray.java rename to core/src/main/java/org/crucial/dso/AtomicByteArray.java diff --git a/client/src/main/java/org/crucial/dso/AtomicCounter.java b/core/src/main/java/org/crucial/dso/AtomicCounter.java similarity index 87% rename from client/src/main/java/org/crucial/dso/AtomicCounter.java rename to core/src/main/java/org/crucial/dso/AtomicCounter.java index b1e4f45..9f995ac 100644 --- a/client/src/main/java/org/crucial/dso/AtomicCounter.java +++ b/core/src/main/java/org/crucial/dso/AtomicCounter.java @@ -5,10 +5,11 @@ import javax.persistence.Entity; import javax.persistence.Id; +import java.io.Serializable; @Entity @Command(name = "counter") -public class AtomicCounter implements Comparable { +public class AtomicCounter implements Comparable, Serializable { @Id @Option(names = "-n" ) @@ -33,7 +34,7 @@ public int increment() { } @Command(name = "increment") - public int increment(@Option(names = "-i") int inc){ + public int increment(@Option(names = "-1") int inc){ count+=inc; return count; } diff --git a/client/src/main/java/org/crucial/dso/AtomicInteger.java b/core/src/main/java/org/crucial/dso/AtomicInteger.java similarity index 100% rename from client/src/main/java/org/crucial/dso/AtomicInteger.java rename to core/src/main/java/org/crucial/dso/AtomicInteger.java diff --git a/client/src/main/java/org/crucial/dso/AtomicList.java b/core/src/main/java/org/crucial/dso/AtomicList.java similarity index 95% rename from client/src/main/java/org/crucial/dso/AtomicList.java rename to core/src/main/java/org/crucial/dso/AtomicList.java index f962ef1..fde1f83 100644 --- a/client/src/main/java/org/crucial/dso/AtomicList.java +++ b/core/src/main/java/org/crucial/dso/AtomicList.java @@ -5,11 +5,12 @@ import javax.persistence.Entity; import javax.persistence.Id; +import java.io.Serializable; import java.util.*; @Entity @Command(name = "list") -public class AtomicList implements List { +public class AtomicList implements List, Serializable { @Id @Option(names = "-n" ) @@ -17,7 +18,9 @@ public class AtomicList implements List { private List delegate; - public AtomicList(){} + public AtomicList(){ + this.delegate = new ArrayList<>(); + } public AtomicList(String name){ this.name = name; diff --git a/client/src/main/java/org/crucial/dso/AtomicLong.java b/core/src/main/java/org/crucial/dso/AtomicLong.java similarity index 100% rename from client/src/main/java/org/crucial/dso/AtomicLong.java rename to core/src/main/java/org/crucial/dso/AtomicLong.java diff --git a/client/src/main/java/org/crucial/dso/AtomicMap.java b/core/src/main/java/org/crucial/dso/AtomicMap.java similarity index 92% rename from client/src/main/java/org/crucial/dso/AtomicMap.java rename to core/src/main/java/org/crucial/dso/AtomicMap.java index 58a83b0..03758ca 100644 --- a/client/src/main/java/org/crucial/dso/AtomicMap.java +++ b/core/src/main/java/org/crucial/dso/AtomicMap.java @@ -1,5 +1,6 @@ package org.crucial.dso; +import java.io.Serializable; import java.util.Collection; import java.util.Map; import java.util.Set; @@ -15,7 +16,7 @@ @Entity @Command(name = "map") -public class AtomicMap implements MergeableMap { +public class AtomicMap implements MergeableMap, Serializable { @Id @Option(names = "-n" ) @@ -23,7 +24,9 @@ public class AtomicMap implements MergeableMap { public Map delegate; - public AtomicMap(){} + public AtomicMap(){ + this.delegate = new HashMap<>(); + } public AtomicMap(String name){ this.name = name; @@ -44,7 +47,7 @@ public boolean isEmpty() { @Override @Command(name = "containsKey") - public boolean containsKey(@Option(names = "-a") Object o) { + public boolean containsKey(@Option(names = "-1") Object o) { return delegate.containsKey(o); } diff --git a/client/src/main/java/org/crucial/dso/AtomicMatrix.java b/core/src/main/java/org/crucial/dso/AtomicMatrix.java similarity index 95% rename from client/src/main/java/org/crucial/dso/AtomicMatrix.java rename to core/src/main/java/org/crucial/dso/AtomicMatrix.java index b105793..6540581 100644 --- a/client/src/main/java/org/crucial/dso/AtomicMatrix.java +++ b/core/src/main/java/org/crucial/dso/AtomicMatrix.java @@ -2,6 +2,7 @@ import javax.persistence.Entity; import javax.persistence.Id; +import java.io.Serializable; import java.lang.reflect.Array; import java.util.Arrays; import java.util.Map; @@ -9,7 +10,7 @@ import java.util.function.Function; @Entity -public class AtomicMatrix { +public class AtomicMatrix implements Serializable { @Id public String id; diff --git a/client/src/main/java/org/crucial/dso/AtomicReference.java b/core/src/main/java/org/crucial/dso/AtomicReference.java similarity index 78% rename from client/src/main/java/org/crucial/dso/AtomicReference.java rename to core/src/main/java/org/crucial/dso/AtomicReference.java index 40d5163..6ac8fae 100644 --- a/client/src/main/java/org/crucial/dso/AtomicReference.java +++ b/core/src/main/java/org/crucial/dso/AtomicReference.java @@ -1,6 +1,8 @@ package org.crucial.dso; -public class AtomicReference { +import java.io.Serializable; + +public class AtomicReference implements Serializable { public String name; private T value; diff --git a/core/src/main/java/org/crucial/dso/AtomicSet.java b/core/src/main/java/org/crucial/dso/AtomicSet.java new file mode 100644 index 0000000..e87feae --- /dev/null +++ b/core/src/main/java/org/crucial/dso/AtomicSet.java @@ -0,0 +1,101 @@ +package org.crucial.dso; + +import javax.persistence.Entity; +import java.io.Serializable; +import java.util.Collection; +import java.util.HashSet; +import java.util.Iterator; +import java.util.Set; + +import picocli.CommandLine.Command; +import picocli.CommandLine.Option; + +import javax.persistence.Id; + +@Entity +@Command(name = "set") +public class AtomicSet implements Set, Serializable { + + @Id + @Option(names = "-n" ) + public String name = "set"; + + public Set delegate; + + public AtomicSet(){ + delegate = new HashSet<>(); + } + + public AtomicSet(String name){ + this.name = name; + this.delegate = new HashSet<>(); + } + + @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("invalid operation"); + } + + @Override + public Object[] toArray() { + return delegate.toArray(); + } + + @Override + public T[] toArray(T[] ts) { + return delegate.toArray(ts); + } + + @Override + public boolean add(V v) { + return delegate.add(v); + } + + @Override + public boolean remove(Object o) { + return delegate.remove(o); + } + + @Override + public boolean containsAll(Collection collection) { + return delegate.containsAll(collection); + } + + @Override + public boolean addAll(Collection collection) { + return delegate.addAll(collection); + } + + @Override + public boolean retainAll(Collection collection) { + return delegate.retainAll(collection); + } + + @Override + public boolean removeAll(Collection collection) { + return delegate.removeAll(collection); + } + + @Override + public void clear() { + delegate.clear(); + } +} diff --git a/client/src/main/java/org/crucial/dso/Blob.java b/core/src/main/java/org/crucial/dso/Blob.java similarity index 85% rename from client/src/main/java/org/crucial/dso/Blob.java rename to core/src/main/java/org/crucial/dso/Blob.java index 8f33503..b2415d0 100644 --- a/client/src/main/java/org/crucial/dso/Blob.java +++ b/core/src/main/java/org/crucial/dso/Blob.java @@ -2,9 +2,10 @@ import javax.persistence.Entity; import javax.persistence.Id; +import java.io.Serializable; @Entity -public class Blob { +public class Blob implements Serializable { @Id public String id; diff --git a/client/src/main/java/org/crucial/dso/CountDownLatch.java b/core/src/main/java/org/crucial/dso/CountDownLatch.java similarity index 71% rename from client/src/main/java/org/crucial/dso/CountDownLatch.java rename to core/src/main/java/org/crucial/dso/CountDownLatch.java index 37f9afb..d7aa69d 100644 --- a/client/src/main/java/org/crucial/dso/CountDownLatch.java +++ b/core/src/main/java/org/crucial/dso/CountDownLatch.java @@ -1,13 +1,13 @@ package org.crucial.dso; -public class CountDownLatch { +public class CountDownLatch{ private AtomicCounter counter; private int parties; - public CountDownLatch(String name, int parties){ + public CountDownLatch(String name, int parties, AtomicCounter counter){ this.parties = parties; - this.counter = new AtomicCounter(name, parties); + this.counter = counter; } public int await(){ @@ -24,7 +24,7 @@ public int countDown(){ } public int getCount(){ - return counter.tally(); + return this.counter.tally(); } } diff --git a/client/src/main/java/org/crucial/dso/CyclicBarrier.java b/core/src/main/java/org/crucial/dso/CyclicBarrier.java similarity index 79% rename from client/src/main/java/org/crucial/dso/CyclicBarrier.java rename to core/src/main/java/org/crucial/dso/CyclicBarrier.java index 9213df3..48a5831 100644 --- a/client/src/main/java/org/crucial/dso/CyclicBarrier.java +++ b/core/src/main/java/org/crucial/dso/CyclicBarrier.java @@ -3,6 +3,8 @@ import picocli.CommandLine.Command; import picocli.CommandLine.Option; +import java.io.Serializable; + @Command(name = "barrier") public class CyclicBarrier { @@ -16,12 +18,13 @@ public class CyclicBarrier { private AtomicCounter counter; private AtomicCounter generation; + @Deprecated public CyclicBarrier(){} - public CyclicBarrier(String name, int parties){ + public CyclicBarrier(String name, int parties, AtomicCounter counter, AtomicCounter generation){ this.name = name; - this.counter = new AtomicCounter(name+"-counter",0); - this.generation = new AtomicCounter(name+"-generation",0); + this.counter = counter; + this.generation = generation; this.parties = parties; } @@ -42,14 +45,12 @@ public int await(){ int current = generation.tally(); int backoff = (parties - Math.abs(ret % parties))/MAGIC; - // System.out.println(ret+" - ("+current+","+previous+")"); while (previous == current) { try { Thread.currentThread().sleep(backoff); } catch (InterruptedException e) { // ignore } - // System.out.println(ret+" - ("+current+","+previous+")"); current = generation.tally(); } return ret; diff --git a/core/src/main/java/org/crucial/dso/Factory.java b/core/src/main/java/org/crucial/dso/Factory.java index b3b4ebd..c3f25ff 100644 --- a/core/src/main/java/org/crucial/dso/Factory.java +++ b/core/src/main/java/org/crucial/dso/Factory.java @@ -14,6 +14,7 @@ import org.infinispan.commons.logging.Log; import org.infinispan.commons.logging.LogFactory; import org.crucial.dso.container.BaseContainer; +import org.infinispan.commons.marshall.JavaSerializationMarshaller; import java.util.Arrays; import java.util.HashMap; @@ -81,6 +82,7 @@ public synchronized static Factory get(String server) { .port(port) .forceReturnValues(true) .addJavaSerialWhiteList(".*") + .marshaller(new JavaSerializationMarshaller()).addJavaSerialWhiteList(".*") .connectionTimeout(3000) .maxRetries(5); RemoteCacheManager manager = new RemoteCacheManager(cb.build()); diff --git a/client/src/main/java/org/crucial/dso/Future.java b/core/src/main/java/org/crucial/dso/Future.java similarity index 100% rename from client/src/main/java/org/crucial/dso/Future.java rename to core/src/main/java/org/crucial/dso/Future.java diff --git a/client/src/main/java/org/crucial/dso/Logger.java b/core/src/main/java/org/crucial/dso/Logger.java similarity index 82% rename from client/src/main/java/org/crucial/dso/Logger.java rename to core/src/main/java/org/crucial/dso/Logger.java index 20a1c6a..ab96688 100644 --- a/client/src/main/java/org/crucial/dso/Logger.java +++ b/core/src/main/java/org/crucial/dso/Logger.java @@ -2,13 +2,14 @@ import javax.persistence.Entity; import javax.persistence.Id; +import java.io.Serializable; /** * @author Daniel */ @Entity -public class Logger { +public class Logger implements Serializable { @Id public String name; diff --git a/client/src/main/java/org/crucial/dso/MergeableMap.java b/core/src/main/java/org/crucial/dso/MergeableMap.java similarity index 78% rename from client/src/main/java/org/crucial/dso/MergeableMap.java rename to core/src/main/java/org/crucial/dso/MergeableMap.java index 82102b6..db7387d 100644 --- a/client/src/main/java/org/crucial/dso/MergeableMap.java +++ b/core/src/main/java/org/crucial/dso/MergeableMap.java @@ -1,5 +1,6 @@ package org.crucial.dso; +import java.io.Serializable; import java.util.Map; import java.util.function.BiFunction; @@ -10,7 +11,7 @@ * * @author Daniel */ -public interface MergeableMap extends Map{ +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/crucial/dso/MonitorCyclicBarrier.java b/core/src/main/java/org/crucial/dso/MonitorCyclicBarrier.java similarity index 100% rename from client/src/main/java/org/crucial/dso/MonitorCyclicBarrier.java rename to core/src/main/java/org/crucial/dso/MonitorCyclicBarrier.java diff --git a/core/src/main/java/org/crucial/dso/ReadOnly.java b/core/src/main/java/org/crucial/dso/ReadOnly.java deleted file mode 100644 index 7ebf6b9..0000000 --- a/core/src/main/java/org/crucial/dso/ReadOnly.java +++ /dev/null @@ -1,15 +0,0 @@ -package org.crucial.dso; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - - -/** - * @author Pierre Sutra - */ - -@Target(ElementType.METHOD) -@Retention(value = RetentionPolicy.RUNTIME) -public @interface ReadOnly {} diff --git a/client/src/main/java/org/crucial/dso/RemoteBiFunction.java b/core/src/main/java/org/crucial/dso/RemoteBiFunction.java similarity index 100% rename from client/src/main/java/org/crucial/dso/RemoteBiFunction.java rename to core/src/main/java/org/crucial/dso/RemoteBiFunction.java diff --git a/client/src/main/java/org/crucial/dso/RemoteFunction.java b/core/src/main/java/org/crucial/dso/RemoteFunction.java similarity index 100% rename from client/src/main/java/org/crucial/dso/RemoteFunction.java rename to core/src/main/java/org/crucial/dso/RemoteFunction.java diff --git a/client/src/main/java/org/crucial/dso/ScalableCyclicBarrier.java b/core/src/main/java/org/crucial/dso/ScalableCyclicBarrier.java similarity index 85% rename from client/src/main/java/org/crucial/dso/ScalableCyclicBarrier.java rename to core/src/main/java/org/crucial/dso/ScalableCyclicBarrier.java index 2d22a01..0cc2352 100644 --- a/client/src/main/java/org/crucial/dso/ScalableCyclicBarrier.java +++ b/core/src/main/java/org/crucial/dso/ScalableCyclicBarrier.java @@ -1,5 +1,7 @@ package org.crucial.dso; +import java.io.Serializable; + /** * From "Two Algorithms for Barrier Synchronization", Hensgen et al. */ @@ -13,16 +15,15 @@ public class ScalableCyclicBarrier { private AtomicCounter identity; private ThreadLocal myIdentifier; - public ScalableCyclicBarrier(final String name, final int parties){ + public ScalableCyclicBarrier(final String name, final int parties, AtomicBoolean[][] answers, AtomicCounter identity){ this.parties = parties; this.logParties = (int)(Math.log(parties)/Math.log(2)); - this.answers = new AtomicBoolean[parties][parties]; + this.answers = answers; + assert answers.length == parties; for(int p=0; p(); } diff --git a/client/src/main/java/org/crucial/dso/Semaphore.java b/core/src/main/java/org/crucial/dso/Semaphore.java similarity index 58% rename from client/src/main/java/org/crucial/dso/Semaphore.java rename to core/src/main/java/org/crucial/dso/Semaphore.java index 4881bfe..9ee0b08 100644 --- a/client/src/main/java/org/crucial/dso/Semaphore.java +++ b/core/src/main/java/org/crucial/dso/Semaphore.java @@ -1,13 +1,25 @@ package org.crucial.dso; +import javax.persistence.Entity; +import javax.persistence.Id; +import java.io.Serializable; + /** * @author Daniel */ -public class Semaphore { + +@Entity +public class Semaphore implements Serializable { + private int permits; + + @Id + private String name; + public Semaphore(){} - public Semaphore(int permits){ + public Semaphore(String name, int permits){ + this.name = name; this.permits = permits; } diff --git a/core/src/main/java/org/crucial/dso/Shared.java b/core/src/main/java/org/crucial/dso/Shared.java deleted file mode 100644 index 934c289..0000000 --- a/core/src/main/java/org/crucial/dso/Shared.java +++ /dev/null @@ -1,19 +0,0 @@ -package org.crucial.dso; - -import java.lang.annotation.Documented; -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -@Documented -@Target({ElementType.FIELD}) -@Retention(RetentionPolicy.RUNTIME) -public @interface Shared { - String DEFAULT_KEY = "__none"; - String SEPARATOR = "#"; - boolean readOptimization() default false; - boolean forceNew() default false; - boolean isIdempotent() default true; - String key() default DEFAULT_KEY; -} diff --git a/client/src/main/java/org/crucial/dso/Sum.java b/core/src/main/java/org/crucial/dso/Sum.java similarity index 100% rename from client/src/main/java/org/crucial/dso/Sum.java rename to core/src/main/java/org/crucial/dso/Sum.java diff --git a/core/src/main/java/org/crucial/dso/container/AbstractContainer.java b/core/src/main/java/org/crucial/dso/container/AbstractContainer.java index 3527f95..b28d595 100644 --- a/core/src/main/java/org/crucial/dso/container/AbstractContainer.java +++ b/core/src/main/java/org/crucial/dso/container/AbstractContainer.java @@ -39,11 +39,11 @@ public abstract class AbstractContainer { public AbstractContainer( Class clazz, - final boolean readOptimization, + @Deprecated final boolean readOptimization, final boolean isIdempotent, final boolean forceNew, final Object... initArgs){ - this.readOptimization = readOptimization && Reflection.hasReadOnlyMethods(clazz); + this.readOptimization = readOptimization; this.isIdempotent = isIdempotent; this.forceNew = forceNew; this.initArgs = initArgs; diff --git a/core/src/main/java/org/crucial/dso/container/BaseContainer.java b/core/src/main/java/org/crucial/dso/container/BaseContainer.java index 37a8705..e870353 100644 --- a/core/src/main/java/org/crucial/dso/container/BaseContainer.java +++ b/core/src/main/java/org/crucial/dso/container/BaseContainer.java @@ -3,7 +3,6 @@ import javassist.util.proxy.MethodHandler; import javassist.util.proxy.ProxyFactory; import javassist.util.proxy.ProxyObject; -import org.crucial.dso.ReadOnly; import org.crucial.dso.utils.Context; import org.crucial.dso.utils.ContextManager; import org.crucial.dso.utils.Reflection; @@ -29,7 +28,7 @@ public class BaseContainer extends AbstractContainer { private Reference reference; private BasicCache cache; - public BaseContainer(BasicCache cache, Class clazz, java.lang.Object key, boolean readOptimization, boolean isIdempotent, + public BaseContainer(BasicCache cache, Class clazz, java.lang.Object key, @Deprecated boolean readOptimization, boolean isIdempotent, boolean forceNew, java.lang.Object... initArgs) throws IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException { @@ -73,19 +72,6 @@ public BaseContainer(BasicCache cache, Class clazz, java.lang.Object key, boolea throw new IllegalArgumentException("Unsupported method " + m.getName() + " in " + reference.getClazz()); } - if (this.readOptimization - && state != null - && (m.isAnnotationPresent(ReadOnly.class))) { - if (log.isTraceEnabled()) log.trace("local call: " + m.getName()); - return Reflection.callObject(state, m.getName(), args); - } else { - if (log.isTraceEnabled()) - log.trace("remote call: " + m.getName() + ";reason: +" - + "null state=" + new Boolean(state == null) + ", " - + "isAnnotationPresent=" + new Boolean(m.isAnnotationPresent(ReadOnly.class))); - } - - open(); Object ret = execute( diff --git a/core/src/main/java/org/crucial/dso/object/Reference.java b/core/src/main/java/org/crucial/dso/object/Reference.java index 4efc783..fcc67c4 100644 --- a/core/src/main/java/org/crucial/dso/object/Reference.java +++ b/core/src/main/java/org/crucial/dso/object/Reference.java @@ -1,6 +1,5 @@ package org.crucial.dso.object; -import org.crucial.dso.Shared; import org.crucial.dso.utils.Reflection; import javax.persistence.Id; @@ -15,6 +14,8 @@ */ public class Reference implements Externalizable { + public static final String SEPARATOR="#"; + // Class methods @Deprecated @@ -86,7 +87,7 @@ public int hashCode() { @Override public String toString() { - return getKey().toString() + Shared.SEPARATOR + getClazz().getCanonicalName(); + return getKey().toString() + SEPARATOR + getClazz().getCanonicalName(); } public Object getKey() { diff --git a/core/src/main/java/org/crucial/dso/utils/Reflection.java b/core/src/main/java/org/crucial/dso/utils/Reflection.java index 6492fcd..c3beb30 100644 --- a/core/src/main/java/org/crucial/dso/utils/Reflection.java +++ b/core/src/main/java/org/crucial/dso/utils/Reflection.java @@ -2,7 +2,6 @@ import org.infinispan.commons.logging.Log; import org.infinispan.commons.logging.LogFactory; -import org.crucial.dso.ReadOnly; import org.crucial.dso.object.Reference; import javax.persistence.Entity; @@ -113,15 +112,6 @@ public static boolean isMethodSynchronized(java.lang.Object obj, String method, return (findMethod(obj,method,args).getModifiers() & Modifier.SYNCHRONIZED) == Modifier.SYNCHRONIZED; } - - public static boolean hasReadOnlyMethods(Class clazz) { - for (Method m : clazz.getMethods()) { - if (m.isAnnotationPresent(ReadOnly.class)) - return true; - } - return false; - } - public static boolean isMethodSupported(Class clazz, Method method) { if (clazz.equals(java.lang.Object.class)) diff --git a/core/src/test/java/org/crucial/dso/test/FakeCache.java b/core/src/test/java/org/crucial/dso/test/FakeCache.java index 7017b8c..6add218 100644 --- a/core/src/test/java/org/crucial/dso/test/FakeCache.java +++ b/core/src/test/java/org/crucial/dso/test/FakeCache.java @@ -232,6 +232,11 @@ public CompletableFuture clearAsync() { return null; } + @Override + public CompletableFuture sizeAsync() { + return null; + } + @Override public CompletableFuture putIfAbsentAsync(Object o, Object o2) { return null; diff --git a/core/src/test/java/org/crucial/dso/test/TestAspectJ.java b/core/src/test/java/org/crucial/dso/test/TestAspectJ.java deleted file mode 100644 index 29ddde7..0000000 --- a/core/src/test/java/org/crucial/dso/test/TestAspectJ.java +++ /dev/null @@ -1,49 +0,0 @@ -package org.crucial.dso.test; - -import javassist.util.proxy.Proxy; -import org.crucial.dso.Shared; -import org.crucial.dso.Factory; -import org.testng.annotations.Test; - -import javax.persistence.Entity; -import javax.persistence.Id; -import java.util.ArrayList; -import java.util.List; - -/** - * @author Pierre Sutra - */ - -@Test(testName = "TestAspectJ") -public class TestAspectJ { - - static{ - Factory.forCache(new FakeCache()); - } - - @Shared - private List list; - - @Test - public void sharedAnnotation() { - list = new ArrayList(); - assert list instanceof Proxy; - } - - @Test - public void entityAnnotation(){ - A a = new A(); - assert a instanceof Proxy; - } - - @Entity - private static class A{ - - private A(){} - - @Id - private String f = "a"; - - } - -} diff --git a/pom.xml b/pom.xml index 9fa76be..f017633 100644 --- a/pom.xml +++ b/pom.xml @@ -6,27 +6,26 @@ org.crucial dso - 1.0 + 2.0 dso pom A distributed shared objects (DSO) datastore. - 1.8 - 1.8 + 1.11 + 1.11 3.8.1 UTF-8 3.5.1 18.0 3.1.3 2.2 - 1.8.9 - 1.10 2.32 3.23.1-GA 6.14.3 - 9.4.16.Final + 11.0.4.Final 4.0.0 + 4.0.4 log4j2.xml @@ -77,6 +76,12 @@ ${version.infinispan} + + org.infinispan + infinispan-jboss-marshalling + ${version.infinispan} + + org.javassist javassist @@ -101,26 +106,7 @@ ${version.javax-persistance-api} - - - org.aspectj - aspectjrt - ${version.aspectjrt} - - - - org.slf4j - slf4j-api - 1.7.7 - - - - org.slf4j - slf4j-simple - 1.7.7 - - args4j args4j @@ -153,6 +139,12 @@ test-jar + + info.picocli + picocli + ${version.picocli} + + @@ -190,4 +182,17 @@ + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.8.0 + + 11 + + + + + diff --git a/python/pom.xml b/python/pom.xml index b3b8129..6773980 100644 --- a/python/pom.xml +++ b/python/pom.xml @@ -4,7 +4,7 @@ org.crucial dso - 1.0 + 2.0 ../ @@ -45,29 +45,6 @@ - - org.codehaus.mojo - aspectj-maven-plugin - ${version.aspectj-maven} - - - - ${project.groupId} - dso-core - - - 1.8 - 1.8 - 1.8 - - - - - compile - - - - diff --git a/python/setup.py b/python/setup.py index fa81509..1dbf08c 100644 --- a/python/setup.py +++ b/python/setup.py @@ -12,7 +12,7 @@ rmtree("src/main/python/dso/java",ignore_errors=True) copytree("target/lib","src/main/python/dso/java") -copy("target/dso-python-9.4.16.Final.jar","src/main/python/dso/java") +copy("target/dso-python-2.0.jar","src/main/python/dso/java") setup( name='dso', @@ -20,7 +20,7 @@ url='https://github.com/crucial-project/dso', author='Pierre Sutra', description='Python bindings for the DSO datastore', - long_description="Python bindings for the DSO datastore', + long_description='Python bindings for the DSO datastore', author_email='pierre.sutra@telecom-sudparis.eu', package_dir={'':'src/main/python'}, packages=find_packages('src/main/python'), diff --git a/python/src/main/java/org/crucial/dso/PythonFactory.java b/python/src/main/java/org/crucial/dso/PythonFactory.java index f847d19..7602cb0 100644 --- a/python/src/main/java/org/crucial/dso/PythonFactory.java +++ b/python/src/main/java/org/crucial/dso/PythonFactory.java @@ -1,20 +1,26 @@ package org.crucial.dso; +import org.crucial.dso.client.Client; + public class PythonFactory { - private Factory factory; + private Client client; public PythonFactory(String server){ - factory = Factory.get(server); + client = Client.getClient(server); } public AtomicCounter createCounter(String name, int value){ - return new AtomicCounter(name,value); + return client.getAtomicCounter(name,value); } - public AtomicMap createMap(String name){ return new AtomicMap(name);} + public AtomicMap createMap(String name){ + return client.getAtomicMap(name); + } - public AtomicMatrix createMatrix(String name, Class clazz, int n, int m) { return new AtomicMatrix(name, clazz, n, m);} + public AtomicMatrix createMatrix(String name, Class clazz, int n, int m) { + return client.getAtomicMatrix(name, clazz, n, m); + } } diff --git a/python/src/main/python/crucial/__init__.py b/python/src/main/python/dso/__init__.py similarity index 100% rename from python/src/main/python/crucial/__init__.py rename to python/src/main/python/dso/__init__.py diff --git a/python/src/main/python/crucial/factory.py b/python/src/main/python/dso/factory.py similarity index 100% rename from python/src/main/python/crucial/factory.py rename to python/src/main/python/dso/factory.py diff --git a/python/src/main/python/crucial/version.py b/python/src/main/python/dso/version.py similarity index 69% rename from python/src/main/python/crucial/version.py rename to python/src/main/python/dso/version.py index 2ccded5..8d97a65 100644 --- a/python/src/main/python/crucial/version.py +++ b/python/src/main/python/dso/version.py @@ -1,4 +1,4 @@ -__version__ = "0.0.2" +__version__ = "0.0.3" if __name__ == "__main__": print(__version__) diff --git a/python/src/test/python/sample.py b/python/src/test/python/sample.py index 5de77fe..af6638f 100644 --- a/python/src/test/python/sample.py +++ b/python/src/test/python/sample.py @@ -1,8 +1,8 @@ -from crucial.factory import Factory +from dso.factory import Factory from jpype import * from jpype import java -factory = Factory() +factory = Factory("35.245.240.1:11222") c = factory.createCounter("cnt") c.reset() diff --git a/server/pom.xml b/server/pom.xml index 252f98f..f92a69e 100644 --- a/server/pom.xml +++ b/server/pom.xml @@ -4,7 +4,7 @@ org.crucial dso - 1.0 + 2.0 ../ @@ -47,6 +47,11 @@ test-jar + + org.infinispan + infinispan-jboss-marshalling + + args4j args4j @@ -65,21 +70,11 @@ 1.0.9.Final - - org.aspectj - aspectjrt - - com.fasterxml.uuid java-uuid-generator - - org.slf4j - slf4j-simple - - @@ -104,6 +99,13 @@ test + + org.infinispan + infinispan-component-annotations + ${version.infinispan} + test + + org.testng testng @@ -126,58 +128,6 @@ - - org.codehaus.mojo - aspectj-maven-plugin - ${version.aspectj-maven} - - - - ${project.groupId} - dso-core - - - 1.8 - 1.8 - 1.8 - - - - - compile - test-compile - - - - - - org.scala-tools - maven-scala-plugin - 2.15.2 - - - generate-blueprint - prepare-package - - - - - org.apache.felix - maven-bundle-plugin - ${version.apache.felix.plugin} - - - - ${project.groupId}.query.*;version=${project.version};-split-package:=merge-last - - - {maven-resources}, - /META-INF/services=${project.basedir}/target/classes/META-INF/services, - /OSGI-INF/blueprint/blueprint.xml=${project.basedir}/target/classes/OSGI-INF/blueprint/blueprint.xml - - - - maven-dependency-plugin diff --git a/server/src/main/bin/image.sh b/server/src/main/bin/image.sh index 7cc39f4..279fd88 100755 --- a/server/src/main/bin/image.sh +++ b/server/src/main/bin/image.sh @@ -29,5 +29,5 @@ docker build \ -t "${IMAGE}" -f "${DOCKERFILE}" . # push image -docker push "${IMAGE}" +# docker push "${IMAGE}" diff --git a/server/src/main/bin/server.sh b/server/src/main/bin/server.sh index b001d81..202e90e 100755 --- a/server/src/main/bin/server.sh +++ b/server/src/main/bin/server.sh @@ -53,7 +53,7 @@ fi cp ${CONFIG} jgroups.xml -JVM="${JVM_EXTRA} -Djava.net.preferIPv4Stack=true -Djgroups.tcp.address=${IP} -Dlog4j.configurationFile=\"${DIR}/log4j2.xml\"" +JVM="${JVM_EXTRA} -Djava.net.preferIPv4Stack=true -Djgroups.tcp.address=${IP}" CMD="java -ea -cp \"${CLASSPATH}\" ${JVM} org.crucial.dso.Server -server ${IP}:${PORT} ${EXTRA}" echo ${CMD} bash -c "$CMD" diff --git a/server/src/main/docker/Dockerfile b/server/src/main/docker/Dockerfile index 8ff73cc..8e05ec8 100644 --- a/server/src/main/docker/Dockerfile +++ b/server/src/main/docker/Dockerfile @@ -1,9 +1,9 @@ -FROM openjdk:8-slim +FROM openjdk:11-slim MAINTAINER otrack ENV NAME=dso-server -ENV VERSION=1.0 +ENV VERSION=2.0 ENV CLOUD=local ENV BUCKET=undefined ENV BUCKET_KEY=undefined @@ -12,7 +12,7 @@ ENV IP=127.0.0.1 ENV PORT=11222 ENV JAR=$NAME-${VERSION}.jar ENV EXTRA="-rf 1" -ENV JVM_EXTRA="-XX:+UseConcMarkSweepGC -Xms64m -Xmx1024m" +ENV JVM_EXTRA="-XX:+UseG1GC -Xms64m -Xmx1024m" WORKDIR $NAME @@ -22,7 +22,8 @@ ADD src/main/resources/jgroups-dso-tcp.xml . ADD src/main/resources/jgroups-dso-ec2.xml . ADD src/main/resources/jgroups-dso-gcp.xml . ADD src/main/resources/jgroups-dso-k8s.xml . -ADD src/main/resources/log4j2.xml . +ADD src/main/resources/log4j.properties . +ADD src/main/resources/log4j-debug.properties . ADD src/main/bin/server.sh . RUN chmod +x . diff --git a/server/src/main/java/org/crucial/dso/Server.java b/server/src/main/java/org/crucial/dso/Server.java index bf719f6..39342e9 100644 --- a/server/src/main/java/org/crucial/dso/Server.java +++ b/server/src/main/java/org/crucial/dso/Server.java @@ -1,6 +1,7 @@ package org.crucial.dso; import org.crucial.dso.utils.ConfigurationHelper; +import org.infinispan.commons.marshall.JavaSerializationMarshaller; import org.infinispan.configuration.cache.CacheMode; import org.infinispan.configuration.cache.ConfigurationBuilder; import org.infinispan.configuration.global.GlobalConfigurationBuilder; @@ -112,10 +113,21 @@ public void doMain(String[] args) { ? server.split(":")[1] : "11222"); GlobalConfigurationBuilder gbuilder = GlobalConfigurationBuilder.defaultClusteredBuilder(); + + //FIXME the DSO cache should be the default one. + gbuilder.defaultCacheName("__DEFAULT_CACHE"); + + // transport gbuilder.transport().clusterName("dso-cluster"); gbuilder.transport().nodeName("dso-server-" + host); gbuilder.transport().addProperty("configurationFile", "jgroups.xml"); + // marshalling + gbuilder.serialization() + .marshaller(new JavaSerializationMarshaller()) + .whiteList() + .addRegexps(".*"); + ConfigurationBuilder cBuilder = AbstractCacheTest.getDefaultClusteredCacheConfig(CacheMode.DIST_ASYNC, false); diff --git a/server/src/main/java/org/crucial/dso/server/Marshalling.java b/server/src/main/java/org/crucial/dso/server/Marshalling.java deleted file mode 100644 index e3f36b4..0000000 --- a/server/src/main/java/org/crucial/dso/server/Marshalling.java +++ /dev/null @@ -1,64 +0,0 @@ -package org.crucial.dso.server; - -import org.infinispan.commons.marshall.Marshaller; -import org.infinispan.marshall.core.JBossMarshaller; - -/** - * @author Pierre Sutra - */ -public class Marshalling { - - private static boolean DEFAULT_BOOLEAN; - private static byte DEFAULT_BYTE; - private static short DEFAULT_SHORT; - private static int DEFAULT_INT; - private static long DEFAULT_LONG; - private static float DEFAULT_FLOAT; - private static double DEFAULT_DOUBLE; - - public static Object getDefaultValue(Class clazz) { - if (clazz.equals(boolean.class)) { - return DEFAULT_BOOLEAN; - } else if (clazz.equals(byte.class)) { - return DEFAULT_BYTE; - } else if (clazz.equals(short.class)) { - return DEFAULT_SHORT; - } else if (clazz.equals(int.class)) { - return DEFAULT_INT; - } else if (clazz.equals(long.class)) { - return DEFAULT_LONG; - } else if (clazz.equals(float.class)) { - return DEFAULT_FLOAT; - } else if (clazz.equals(double.class)) { - return DEFAULT_DOUBLE; - } else { - throw new IllegalArgumentException( - "Class type " + clazz + " not supported"); - } - } - - public static byte[] marshall(Object object) { - Marshaller marshaller = new JBossMarshaller(); - try { - if (object instanceof byte[]) - return (byte[]) object; - return marshaller.objectToByteBuffer(object); - } catch (Exception e) { - e.printStackTrace(); - } - return null; - } - - public static Object unmarshall(Object object) { - Marshaller marshaller = new JBossMarshaller(); - try { - if (object instanceof byte[]) - return marshaller.objectFromByteBuffer((byte[]) object); - return object; - } catch (Exception e) { - e.printStackTrace(); - } - return null; - } - -} diff --git a/server/src/main/java/org/crucial/dso/server/StateMachineInterceptor.java b/server/src/main/java/org/crucial/dso/server/StateMachineInterceptor.java index 334f6b8..dbe7cb4 100644 --- a/server/src/main/java/org/crucial/dso/server/StateMachineInterceptor.java +++ b/server/src/main/java/org/crucial/dso/server/StateMachineInterceptor.java @@ -130,27 +130,11 @@ public java.lang.Object visitPutKeyValueCommand(InvocationContext ctx, PutKeyVal // save return value if (withIdempotence) responseCache.put(call,response); - // save state if required - if (Reflection.hasReadOnlyMethods(reference.getClazz())) { // FIXME state = byte array - synchronized (object) { // synchronization contract - byte[] buf = Marshalling.marshall(object); - response.setState(Marshalling.unmarshall(buf)); - if (log.isTraceEnabled()) { - log.trace(" keeping state "+buf.length+"B"); - } - } - } + command.setValue(object); + invokeNext(ctx, command); - PutKeyValueCommand clone = cf.buildPutKeyValueCommand( - command.getKey(), - object, - command.getSegment(), - command.getMetadata(), - command.getFlagsBitSet()); - invokeNext(ctx, clone); - - if (log.isTraceEnabled()) { - log.trace(" Executed [" + call.toString() + "] = "+response.toString()); + if (log.isDebugEnabled()) { + log.debug("" + call.toString() + " = "+response.getResult()); } return response; diff --git a/server/src/main/java/org/crucial/dso/server/StoreModuleLifeCycle.java b/server/src/main/java/org/crucial/dso/server/StoreModuleLifeCycle.java deleted file mode 100644 index 26d7368..0000000 --- a/server/src/main/java/org/crucial/dso/server/StoreModuleLifeCycle.java +++ /dev/null @@ -1,21 +0,0 @@ -package org.crucial.dso.server; - -import org.infinispan.configuration.global.GlobalConfiguration; -import org.infinispan.factories.ComponentRegistry; -import org.infinispan.factories.GlobalComponentRegistry; -import org.infinispan.lifecycle.AbstractModuleLifecycle; -import org.infinispan.marshall.core.ExternallyMarshallable; - -public class StoreModuleLifeCycle extends AbstractModuleLifecycle { - - @Override - public void cacheManagerStarting(GlobalComponentRegistry gcr, GlobalConfiguration globalConfiguration) { - ExternallyMarshallable.addToWhiteList("org.crucial.dso"); - } - - @Override - public void cacheManagerStarted(GlobalComponentRegistry gcr) {} - - @Override - public void cacheStarted(ComponentRegistry cr, String cacheName) {} -} diff --git a/server/src/main/java/org/crucial/dso/utils/ConfigurationHelper.java b/server/src/main/java/org/crucial/dso/utils/ConfigurationHelper.java index b1c7ed4..16f2bc1 100644 --- a/server/src/main/java/org/crucial/dso/utils/ConfigurationHelper.java +++ b/server/src/main/java/org/crucial/dso/utils/ConfigurationHelper.java @@ -28,12 +28,10 @@ public static void installCache( boolean withIndexing, boolean withIdempotence) { - manager.getClassWhiteList().addRegexps(".*"); - ConfigurationBuilder builder = new ConfigurationBuilder(); builder.clustering().cacheMode(mode); builder.transaction().transactionMode(TransactionMode.NON_TRANSACTIONAL); - builder.compatibility().enabled(true); // for HotRod + // builder.compatibility().enabled(true); // for HotRod builder.expiration().lifespan(-1); builder.memory().size(maxEntries); @@ -51,9 +49,7 @@ public static void installCache( // indexing if (withIndexing) { System.out.println("indexing cannot be used w. blocking objects!"); - builder.indexing().index(Index.LOCAL) - .addProperty("default.directory_provider", "ram") - .addProperty("lucene_version", "LUCENE_CURRENT"); + builder.indexing().enable(); } // persistence @@ -68,6 +64,7 @@ public static void installCache( } // installation + manager.getClassWhiteList().addRegexps(".*"); manager.defineConfiguration(DSO_CACHE_NAME,builder.build()); stateMachineInterceptor.setup(Factory.forCache(manager.getCache(DSO_CACHE_NAME)),withIdempotence); diff --git a/server/src/main/resources/META-INF/services/org.infinispan.lifecycle.ModuleLifecycle b/server/src/main/resources/META-INF/services/org.infinispan.lifecycle.ModuleLifecycle deleted file mode 100644 index 111b7c7..0000000 --- a/server/src/main/resources/META-INF/services/org.infinispan.lifecycle.ModuleLifecycle +++ /dev/null @@ -1 +0,0 @@ -org.crucial.dso.server.StoreModuleLifeCycle diff --git a/server/src/main/resources/log4j-debug.properties b/server/src/main/resources/log4j-debug.properties new file mode 100644 index 0000000..894bf77 --- /dev/null +++ b/server/src/main/resources/log4j-debug.properties @@ -0,0 +1,10 @@ +### direct log messages to stdout ### +log4j.appender.stdout=org.apache.log4j.ConsoleAppender +log4j.appender.stdout.Target=System.out +log4j.appender.stdout.layout=org.apache.log4j.PatternLayout +log4j.appender.stdout.layout.ConversionPattern=%m%n +### set log levels - for more verbose logging change 'info' to 'debug' ### +log4j.rootLogger=debug, stdout +log4j.logger.org.jboss=info +log4j.logger.org.infinispan=debug +log4j.logger.org.crucial=debug diff --git a/server/src/main/resources/log4j.properties b/server/src/main/resources/log4j.properties new file mode 100644 index 0000000..bc22473 --- /dev/null +++ b/server/src/main/resources/log4j.properties @@ -0,0 +1,11 @@ +### direct log messages to stdout ### +log4j.appender.stdout=org.apache.log4j.ConsoleAppender +log4j.appender.stdout.Target=System.out +log4j.appender.stdout.layout=org.apache.log4j.PatternLayout +log4j.appender.stdout.layout.ConversionPattern=%d{ABSOLUTE} (%t) %5p %c{1}:%L - %m%n +### set log levels - for more verbose logging change 'info' to 'debug' ### +log4j.rootLogger=info, stdout +log4j.logger.org.infinispan=info +log4j.logger.org.crucial=info +log4j.logger.org.jboss=error +log4j.logger.org.infinispan.server=error diff --git a/server/src/main/resources/log4j2.xml b/server/src/main/resources/log4j2.xml deleted file mode 100644 index 3a1fccc..0000000 --- a/server/src/main/resources/log4j2.xml +++ /dev/null @@ -1,32 +0,0 @@ - - - - - - . - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/server/src/test/java/org/crucial/dso/test/AbstractTest.java b/server/src/test/java/org/crucial/dso/test/AbstractTest.java index c55d990..806afe2 100644 --- a/server/src/test/java/org/crucial/dso/test/AbstractTest.java +++ b/server/src/test/java/org/crucial/dso/test/AbstractTest.java @@ -3,36 +3,22 @@ import com.fasterxml.uuid.Generators; import com.fasterxml.uuid.impl.RandomBasedGenerator; import javassist.util.proxy.Proxy; -import org.crucial.dso.Shared; +import org.crucial.dso.*; import org.crucial.dso.utils.Context; import org.crucial.dso.utils.ContextManager; import org.crucial.dso.utils.ID; import org.infinispan.Cache; import org.infinispan.commons.api.BasicCache; import org.infinispan.commons.api.BasicCacheContainer; -import org.infinispan.commons.marshall.Marshaller; import org.infinispan.configuration.cache.CacheMode; -import org.crucial.dso.Factory; import org.infinispan.manager.EmbeddedCacheManager; -import org.infinispan.marshall.core.JBossMarshaller; import org.infinispan.test.MultipleCacheManagersTest; import org.infinispan.test.TestingUtil; import org.testng.annotations.AfterClass; import org.testng.annotations.Test; -import java.util.ArrayList; -import java.util.Collection; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.Random; -import java.util.Set; -import java.util.concurrent.Callable; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; +import java.util.*; +import java.util.concurrent.*; import java.util.concurrent.Future; import static org.crucial.dso.Factory.DSO_CACHE_NAME; @@ -47,8 +33,8 @@ public abstract class AbstractTest extends MultipleCacheManagersTest { protected static final CacheMode CACHE_MODE = CacheMode.DIST_SYNC; protected static final int NCALLS = 5000; protected static final long MAX_ENTRIES = -1; - protected static final int REPLICATION_FACTOR = 2; - protected static final int NMANAGERS = 3; + protected static final int REPLICATION_FACTOR = 3; + protected static final int NMANAGERS = 2; protected static final boolean PASSIVATION = false; protected static final String PERSISTENT_STORAGE_DIR = "/tmp/dso"; @@ -60,15 +46,12 @@ public void baseUsage() throws Exception { Factory factory = Factory.forCache(cache); // 1 - basic call - Set set = factory.getInstanceOf(HashSet.class, "set"); + Set set = factory.getInstanceOf(AtomicSet.class, "set"); set.add("smthing"); + System.out.println(set.size()); assert set.contains("smthing"); assert set.size() == 1; - // 2 - proxy marshalling - Marshaller marshaller = new JBossMarshaller(); - assert marshaller.objectFromByteBuffer((marshaller.objectToByteBuffer(set))).equals(set); - factory.close(); } @@ -82,7 +65,7 @@ public void basePerformance() throws Exception { int f = 1; // multiplicative factor - Map map = factory.getInstanceOf(HashMap.class, "map"); + Map map = factory.getInstanceOf(AtomicMap.class, "map"); long start = System.currentTimeMillis(); for (int i = 0; i < NCALLS * f; i++) { @@ -108,67 +91,40 @@ public void persistence() throws Exception { BasicCache cache2 = container2.getCache(DSO_CACHE_NAME); Factory factory2 = Factory.forCache(cache2); - HashSet set1, set2; + Set set1, set2; // 0 - Base persistence - set1 = factory1.getInstanceOf(HashSet.class, "persist1", false, false, true); + set1 = factory1.getInstanceOf(AtomicSet.class, "persist1", false, false, true); set1.add("smthing"); - factory1.disposeInstanceOf(HashSet.class, "persist1"); - set1 = factory1.getInstanceOf(HashSet.class, "persist1", false, false, false); + factory1.disposeInstanceOf(AtomicSet.class, "persist1"); + set1 = factory1.getInstanceOf(AtomicSet.class, "persist1", false, false, false); assert set1.contains("smthing"); - factory1.disposeInstanceOf(HashSet.class, "persist1"); + factory1.disposeInstanceOf(AtomicSet.class, "persist1"); // 1 - Concurrent retrieval - set1 = factory1.getInstanceOf(HashSet.class, "persist2"); + set1 = factory1.getInstanceOf(AtomicSet.class, "persist2"); set1.add("smthing"); - set2 = factory2.getInstanceOf(HashSet.class, "persist2", false, false, false); + set2 = factory2.getInstanceOf(AtomicSet.class, "persist2", false, false, false); assert set2.contains("smthing"); - factory1.disposeInstanceOf(HashSet.class, "persist2"); - factory2.disposeInstanceOf(HashSet.class, "persist2"); + factory1.disposeInstanceOf(AtomicSet.class, "persist2"); + factory2.disposeInstanceOf(AtomicSet.class, "persist2"); // 2 - Serial storing then retrieval - set1 = factory1.getInstanceOf(HashSet.class, "persist3"); + set1 = factory1.getInstanceOf(AtomicSet.class, "persist3"); set1.add("smthing"); - factory1.disposeInstanceOf(HashSet.class, "persist3"); - set2 = factory2.getInstanceOf(HashSet.class, "persist3", false, false, false); + factory1.disposeInstanceOf(AtomicSet.class, "persist3"); + set2 = factory2.getInstanceOf(AtomicSet.class, "persist3", false, false, false); assert set2.contains("smthing"); - factory1.disposeInstanceOf(HashSet.class, "persist3"); - factory2.disposeInstanceOf(HashSet.class, "persist3"); + factory1.disposeInstanceOf(AtomicSet.class, "persist3"); + factory2.disposeInstanceOf(AtomicSet.class, "persist3"); // 3 - Re-creation - set1 = factory1.getInstanceOf(HashSet.class, "persist4"); + set1 = factory1.getInstanceOf(AtomicSet.class, "persist4"); set1.add("smthing"); - factory1.disposeInstanceOf(HashSet.class, "persist4"); - set2 = factory2.getInstanceOf(HashSet.class, "persist4", false, false, true); + factory1.disposeInstanceOf(AtomicSet.class, "persist4"); + set2 = factory2.getInstanceOf(AtomicSet.class, "persist4", false, false, true); assert !set2.contains("smthing"); - factory2.disposeInstanceOf(HashSet.class, "persist4"); - - } - - @Test(groups = {"dso"}) - public void baseReadOptimization() throws Exception { - SimpleObject object = new SimpleObject("baseReadOptimization"); - object.setField("something"); - String field = object.getField(); - assert field.equals("something"); - } - - @Test(groups = {"dso", "stress"}) - public void advancedReadOptimization() throws Exception { - - SimpleObject object = new SimpleObject("performance"); - - long start = System.currentTimeMillis(); - for (int i = 0; i < NCALLS; i++) { - object.setField(Integer.toString(i)); - } - System.out.println("op/sec:" + ((float) (NCALLS)) / ((float) (System.currentTimeMillis() - start)) * 1000); - - start = System.currentTimeMillis(); - for (int i = 0; i < NCALLS; i++) { - object.getField(); - } - System.out.println("op/sec:" + ((float) (NCALLS)) / ((float) (System.currentTimeMillis() - start)) * 1000); + factory2.disposeInstanceOf(AtomicSet.class, "persist4"); } @@ -180,18 +136,18 @@ public void baseCacheTest() throws Exception { BasicCache cache1 = container1.getCache(DSO_CACHE_NAME); Factory factory1 = Factory.forCache(cache1, 1, false); - HashSet set1, set2; + Set set1, set2; // 0 - Base caching - set1 = factory1.getInstanceOf(HashSet.class, "aset", false, false, true); + set1 = factory1.getInstanceOf(AtomicSet.class, "aset", false, false, true); set1.add("smthing"); - set2 = factory1.getInstanceOf(HashSet.class, "aset2", false, false, true); + set2 = factory1.getInstanceOf(AtomicSet.class, "aset2", false, false, true); assert set1.contains("smthing"); // 1 - Caching multiple instances of the same object - set1 = factory1.getInstanceOf(HashSet.class, "aset3", false, false, true); + set1 = factory1.getInstanceOf(AtomicSet.class, "aset3", false, false, true); set1.add("smthing"); - set2 = factory1.getInstanceOf(HashSet.class, "aset3", false, false, false); + set2 = factory1.getInstanceOf(AtomicSet.class, "aset3", false, false, false); assert set1.contains("smthing"); assert set2.contains("smthing"); @@ -205,7 +161,7 @@ public void concurrentUpdates() throws Exception { for (BasicCacheContainer manager : containers()) { Set set = Factory.forCache(manager.getCache(DSO_CACHE_NAME)) - .getInstanceOf(HashSet.class, "concurrent"); + .getInstanceOf(AtomicSet.class, "concurrent"); futures.add(service.submit( new SetTask(set, NCALLS))); } @@ -238,101 +194,51 @@ public void multipleCreation() throws Exception { int n = 100; for (int i = 0; i < n; i++) { - ArrayList list = factory2.getInstanceOf(ArrayList.class, "list" + i); + List list = factory2.getInstanceOf(AtomicList.class, "list" + i); list.add(i); } for (int i = 0; i < n; i++) { - ArrayList list = factory1.getInstanceOf(ArrayList.class, "list" + i); + List list = factory1.getInstanceOf(AtomicList.class, "list" + i); assert (list.get(0).equals(i)) : list.get(0); } } - @Test(groups = {"dso"}) - public void baseAspectJ() throws Exception { - - // 1 - constructor - SimpleObject object = new SimpleObject("aspectj"); - String field = object.getField(); - assert field.equals("aspectj"); - - // 2 - constructor w. arguments - SimpleObject object1 = new SimpleObject("aspectj2"); - assert object1.getField().equals("aspectj2"); - - // 3 - equals() - ShardedObject object2 = new ShardedObject(); - assert object2.equals(object2); - - } - @Test(groups = {"dso"}) public void baseComposition() throws Exception { assert ShardedObject.class.isAssignableFrom(ShardedObject.class); - ShardedObject object = new ShardedObject(); - ShardedObject object2 = new ShardedObject(object); - ShardedObject object3 = object2.getShard(); - assert object3.equals(object); - List list = new ArrayList<>(); - Random random = new Random(System.currentTimeMillis()); - for (int i = 0; i < 10; i++) { - list.add(new SimpleObject(Integer.toString(random.nextInt(10)))); - } - for (SimpleObject simpleObject1 : list) { - for (SimpleObject simpleObject2 : list) { - if (simpleObject1.equals(simpleObject2)) - assert simpleObject1.getField().equals(simpleObject2.getField()); - } - } - - } + Iterator it = containers().iterator(); + BasicCacheContainer container1 = it.next(); + BasicCache cache1 = container1.getCache(DSO_CACHE_NAME); + Factory factory1 = Factory.forCache(cache1); - @Test(groups = {"dso"}) - public void advancedComposition() throws Exception { - ShardedObject object1 = new ShardedObject(); - ShardedObject object2 = new ShardedObject(object1); - - ShardedObject shard = object2.getShard(); - assert shard.equals(object1); - assert object1.flipValue(); - assert !(object2.getShard()).flipValue(); - assert object2.flipValue(); - - ShardedObject object3 = new ShardedObject(); - ShardedObject object4 = new ShardedObject(object3); - object3.addShard(object4); + ShardedObject object = factory1.getInstanceOf(ShardedObject.class, "o1"); + ShardedObject object2 = factory1.getInstanceOf(ShardedObject.class, "o2", + false, + false, + true, + "o2", object); + ShardedObject object3 = object2.getShard(); + assert object3.equals(object); } - @Shared - List l1; - - @Test(groups = {"dso"}) - public void baseAnnotation() throws Exception{ - l1 = new ArrayList<>(); - SimpleObject object1 = new SimpleObject(); - l1.add(object1); - assert l1 instanceof Proxy; - assert l1.size() == 1; - l1.remove(0); - assert l1.size() == 1; - } @Test(groups = {"dso", "stress"}, enabled = false) public void baseElasticity() throws Exception { - advancedComposition(); + baseComposition(); baseUsage(); addContainer(); persistence(); - advancedComposition(); + baseComposition(); baseUsage(); deleteContainer(); baseUsage(); - advancedComposition(); + baseComposition(); } @Test(groups = {"dso", "stress"}, enabled = false) @@ -341,8 +247,7 @@ public void advancedElasticity() throws Exception { ExecutorService service = Executors.newCachedThreadPool(); List> futures = new ArrayList<>(); - Set set = Factory.forCache(manager(0).getCache(DSO_CACHE_NAME)) - .getInstanceOf(HashSet.class, "elastic"); + Set set = Factory.forCache(manager(0).getCache(DSO_CACHE_NAME)).getInstanceOf(AtomicSet.class, "elastic"); futures.add(service.submit( new SetTask(set, NCALLS))); @@ -370,21 +275,14 @@ public void advancedElasticity() throws Exception { } - @Shared MyMap map; - - static class MyMap extends HashMap { - - @Override - public V put (K k, V v) { - super.put(k,v); - return null; - } - - } - @Test(groups = {"dso", "stress"}) public void memoryUsage(){ - map = new MyMap<>(); + Iterator it = containers().iterator(); + BasicCacheContainer container1 = it.next(); + BasicCache cache1 = container1.getCache(DSO_CACHE_NAME); + Factory factory1 = Factory.forCache(cache1); + + Map map = factory1.getInstanceOf(AtomicMap.class, "map"); final int threads = 1; final int operations = 15; @@ -416,17 +314,22 @@ public void memoryUsage(){ @Test(groups = {"dso"}) public void idempotence() throws IllegalAccessException { - SimpleObject object = new SimpleObject("idempotence"); + Iterator it = containers().iterator(); + BasicCacheContainer container1 = it.next(); + BasicCache cache1 = container1.getCache(DSO_CACHE_NAME); + Factory factory1 = Factory.forCache(cache1); + + SimpleObject object = factory1.getInstanceOf(SimpleObject.class,"idempotence"); object.getCount(); // to open it. RandomBasedGenerator generator = null; generator = Generators.randomBasedGenerator(new Random(42)); - ContextManager.set(new Context(ID.threadID(), generator, Factory.forCache(cache(0)))); + ContextManager.set(new Context(ID.threadID(), generator, Factory.forCache(this.manager(0).getCache(DSO_CACHE_NAME)))); object.setField("a"); generator = Generators.randomBasedGenerator(new Random(42)); - ContextManager.set(new Context(ID.threadID(), generator, Factory.forCache(cache(0)))); + ContextManager.set(new Context(ID.threadID(), generator, Factory.forCache(this.manager(0).getCache(DSO_CACHE_NAME)))); object.setField("a"); assert object.getCount() == 1; diff --git a/server/src/test/java/org/crucial/dso/test/BaseTest.java b/server/src/test/java/org/crucial/dso/test/BaseTest.java index f728cfc..b8a0ba8 100644 --- a/server/src/test/java/org/crucial/dso/test/BaseTest.java +++ b/server/src/test/java/org/crucial/dso/test/BaseTest.java @@ -50,6 +50,7 @@ public synchronized boolean addContainer() { true); waitForClusterToForm(DSO_CACHE_NAME); Cache cache = cm.getCache(DSO_CACHE_NAME); + cache.start(); caches.add(cache); Factory.forCache(cache); System.out.println("Node " + cm + " added."); diff --git a/server/src/test/java/org/crucial/dso/test/RemoteTest.java b/server/src/test/java/org/crucial/dso/test/RemoteTest.java index 28b4faf..a9a0fe7 100644 --- a/server/src/test/java/org/crucial/dso/test/RemoteTest.java +++ b/server/src/test/java/org/crucial/dso/test/RemoteTest.java @@ -3,12 +3,16 @@ import org.crucial.dso.utils.ConfigurationHelper; import org.infinispan.client.hotrod.RemoteCacheManager; import org.infinispan.commons.api.BasicCacheContainer; +import org.infinispan.commons.marshall.JavaSerializationMarshaller; import org.infinispan.commons.marshall.Marshaller; import org.crucial.dso.Factory; +import org.infinispan.configuration.cache.ConfigurationBuilder; +import org.infinispan.configuration.global.GlobalConfigurationBuilder; import org.infinispan.lifecycle.ComponentStatus; import org.infinispan.manager.EmbeddedCacheManager; import org.infinispan.server.hotrod.HotRodServer; import org.infinispan.server.hotrod.test.HotRodTestingUtil; +import org.infinispan.test.fwk.TestCacheManagerFactory; import org.infinispan.test.fwk.TransportFlags; import org.testng.annotations.Test; @@ -45,9 +49,19 @@ public boolean addContainer() { int index = servers.size(); // embedded cache manager + GlobalConfigurationBuilder gbuilder = GlobalConfigurationBuilder.defaultClusteredBuilder(); + gbuilder.serialization() + .marshaller(new JavaSerializationMarshaller()) + .whiteList() + .addRegexps(".*"); TransportFlags flags = new TransportFlags(); flags.withFD(true).withMerge(true); - EmbeddedCacheManager cm = addClusterEnabledCacheManager(flags); + EmbeddedCacheManager cm = TestCacheManagerFactory.createClusteredCacheManager( + false, + gbuilder, + (ConfigurationBuilder)null, + flags); + this.cacheManagers.add(cm); ConfigurationHelper.installCache( cm, CACHE_MODE, @@ -70,7 +84,7 @@ public boolean addContainer() { RemoteCacheManager manager = new RemoteCacheManager( new org.infinispan.client.hotrod.configuration.ConfigurationBuilder() .addServers(server.getHost() + ":" + server.getPort()) - .marshaller((Marshaller) null) + .marshaller(new JavaSerializationMarshaller()).addJavaSerialWhiteList(".*") .forceReturnValues(true) .build()); remoteCacheManagers.add(manager); @@ -117,7 +131,7 @@ protected void createCacheManagers() throws Throwable { manager(j).getCache(DSO_CACHE_NAME), ComponentStatus.RUNNING, 10000); } - waitForClusterToForm(); + waitForClusterToForm(DSO_CACHE_NAME); assertEquals(manager(0).getTransport().getMembers().size(), NMANAGERS); diff --git a/server/src/test/java/org/crucial/dso/test/ShardedObject.java b/server/src/test/java/org/crucial/dso/test/ShardedObject.java index 41faf16..114992d 100644 --- a/server/src/test/java/org/crucial/dso/test/ShardedObject.java +++ b/server/src/test/java/org/crucial/dso/test/ShardedObject.java @@ -2,28 +2,27 @@ import javax.persistence.Entity; import javax.persistence.Id; +import java.io.Serializable; import java.util.UUID; /** * @author Pierre Sutra */ @Entity -public class ShardedObject { +public class ShardedObject implements Serializable { - @Id public UUID id; + @Id public String id; private boolean value; private ShardedObject shard; - public ShardedObject() { - id = UUID.randomUUID(); - } + public ShardedObject() {} - public ShardedObject(UUID id) { + public ShardedObject(String id) { this.id = id; } - public ShardedObject(ShardedObject shard) { - id = UUID.randomUUID(); + public ShardedObject(String id, ShardedObject shard) { + this.id = id; this.shard = shard; } @@ -35,7 +34,7 @@ public ShardedObject getShard() { return shard; } - public UUID getID() { + public String getID() { return id; } diff --git a/server/src/test/java/org/crucial/dso/test/SimpleObject.java b/server/src/test/java/org/crucial/dso/test/SimpleObject.java index 93ab10a..45424fd 100644 --- a/server/src/test/java/org/crucial/dso/test/SimpleObject.java +++ b/server/src/test/java/org/crucial/dso/test/SimpleObject.java @@ -2,12 +2,13 @@ import javax.persistence.Entity; import javax.persistence.Id; +import java.io.Serializable; /** * @author Pierre Sutra */ @Entity -public class SimpleObject { +public class SimpleObject implements Serializable { @Id public String field; public int count;