[infinispan-commits] Infinispan SVN: r1248 - in trunk/server/memcached: src and 12 other directories.
infinispan-commits at lists.jboss.org
infinispan-commits at lists.jboss.org
Wed Dec 2 15:18:04 EST 2009
Author: galder.zamarreno at jboss.com
Date: 2009-12-02 15:18:03 -0500 (Wed, 02 Dec 2009)
New Revision: 1248
Added:
trunk/server/memcached/pom.xml
trunk/server/memcached/src/
trunk/server/memcached/src/main/
trunk/server/memcached/src/main/java/
trunk/server/memcached/src/main/java/org/
trunk/server/memcached/src/main/java/org/infinispan/
trunk/server/memcached/src/main/java/org/infinispan/server/
trunk/server/memcached/src/main/java/org/infinispan/server/memcached/
trunk/server/memcached/src/main/java/org/infinispan/server/memcached/AddCommand.java
trunk/server/memcached/src/main/java/org/infinispan/server/memcached/AppendCommand.java
trunk/server/memcached/src/main/java/org/infinispan/server/memcached/CasCommand.java
trunk/server/memcached/src/main/java/org/infinispan/server/memcached/CasValue.java
trunk/server/memcached/src/main/java/org/infinispan/server/memcached/Command.java
trunk/server/memcached/src/main/java/org/infinispan/server/memcached/CommandFactory.java
trunk/server/memcached/src/main/java/org/infinispan/server/memcached/CommandType.java
trunk/server/memcached/src/main/java/org/infinispan/server/memcached/GetCommand.java
trunk/server/memcached/src/main/java/org/infinispan/server/memcached/MemcachedTextServer.java
trunk/server/memcached/src/main/java/org/infinispan/server/memcached/PrependCommand.java
trunk/server/memcached/src/main/java/org/infinispan/server/memcached/ReplaceCommand.java
trunk/server/memcached/src/main/java/org/infinispan/server/memcached/RetrievalCommand.java
trunk/server/memcached/src/main/java/org/infinispan/server/memcached/RetrievalParameters.java
trunk/server/memcached/src/main/java/org/infinispan/server/memcached/RetrievalReply.java
trunk/server/memcached/src/main/java/org/infinispan/server/memcached/SetCommand.java
trunk/server/memcached/src/main/java/org/infinispan/server/memcached/StorageCommand.java
trunk/server/memcached/src/main/java/org/infinispan/server/memcached/StorageParameters.java
trunk/server/memcached/src/main/java/org/infinispan/server/memcached/StorageReply.java
trunk/server/memcached/src/main/java/org/infinispan/server/memcached/TextCommandDecoder.java
trunk/server/memcached/src/main/java/org/infinispan/server/memcached/TextCommandHandler.java
trunk/server/memcached/src/main/java/org/infinispan/server/memcached/TextProtocolPipelineFactory.java
trunk/server/memcached/src/main/java/org/infinispan/server/memcached/TextProtocolUtil.java
trunk/server/memcached/src/main/java/org/infinispan/server/memcached/Value.java
trunk/server/memcached/src/test/
trunk/server/memcached/src/test/java/
trunk/server/memcached/src/test/java/org/
trunk/server/memcached/src/test/java/org/infinispan/
trunk/server/memcached/src/test/java/org/infinispan/server/
trunk/server/memcached/src/test/java/org/infinispan/server/memcached/
trunk/server/memcached/src/test/java/org/infinispan/server/memcached/FunctionalTest.java
Modified:
trunk/server/memcached/
Log:
[ISPN-173] (Build memcached server module) Initial commit with set, get, append, prepend, replace commands implemented. Test client used is provided Spy Memcached.
Property changes on: trunk/server/memcached
___________________________________________________________________
Name: svn:ignore
+ .classpath
.settings
.project
target
eclipse-output
test-output
output
temp-testng-customsuite.xml
Added: trunk/server/memcached/pom.xml
===================================================================
--- trunk/server/memcached/pom.xml (rev 0)
+++ trunk/server/memcached/pom.xml 2009-12-02 20:18:03 UTC (rev 1248)
@@ -0,0 +1,63 @@
+<?xml version="1.0"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>org.infinispan</groupId>
+ <artifactId>infinispan-parent</artifactId>
+ <version>4.0.0-SNAPSHOT</version>
+ <relativePath>../parent/pom.xml</relativePath>
+ </parent>
+
+ <artifactId>infinispan-server-memcached</artifactId>
+ <name>Infinispan Server Memcached Module</name>
+ <description>Infinispan server memcached module</description>
+
+ <properties>
+ <version.netty>3.1.5.GA</version.netty>
+ <version.spymemcached>2.4.2</version.spymemcached>
+ </properties>
+
+ <dependencies>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>infinispan-core</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>infinispan-core</artifactId>
+ <version>${project.version}</version>
+ <type>test-jar</type>
+ <scope>test</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>org.jboss.netty</groupId>
+ <artifactId>netty</artifactId>
+ <version>${version.netty}</version>
+ </dependency>
+
+ <dependency>
+ <groupId>spy</groupId>
+ <artifactId>memcached</artifactId>
+ <version>${version.spymemcached}</version>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+
+ <repositories>
+ <repository>
+ <id>spy</id>
+ <name>Spy Repository</name>
+ <layout>default</layout>
+ <url>http://bleu.west.spy.net/~dustin/m2repo/</url>
+ <snapshots>
+ <enabled>false</enabled>
+ </snapshots>
+ </repository>
+ </repositories>
+
+</project>
Added: trunk/server/memcached/src/main/java/org/infinispan/server/memcached/AddCommand.java
===================================================================
--- trunk/server/memcached/src/main/java/org/infinispan/server/memcached/AddCommand.java (rev 0)
+++ trunk/server/memcached/src/main/java/org/infinispan/server/memcached/AddCommand.java 2009-12-02 20:18:03 UTC (rev 1248)
@@ -0,0 +1,66 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2009, Red Hat, Inc. and/or its affiliates, and
+ * individual contributors as indicated by the @author tags. See the
+ * copyright.txt file in the distribution for a full listing of
+ * individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.infinispan.server.memcached;
+
+import java.util.concurrent.TimeUnit;
+
+import org.infinispan.Cache;
+
+/**
+ * AddCommand.
+ *
+ * @author Galder Zamarreño
+ * @since 4.0
+ */
+public class AddCommand extends SetCommand {
+
+ AddCommand(Cache cache, StorageParameters params, byte[] data) {
+ super(cache, CommandType.ADD, params, data);
+ }
+
+ @Override
+ protected StorageReply put(String key, Value value) {
+ Object prev = cache.putIfAbsent(params.key, value);
+ return reply(prev);
+ }
+
+ @Override
+ protected StorageReply putExpiry(String key, Value value, long expiry) {
+ Object prev = cache.putIfAbsent(params.key, value, expiry, TimeUnit.SECONDS);
+ return reply(prev);
+ }
+
+ @Override
+ protected StorageReply putExpiryUnixTime(String key, Value value, long expiry) {
+ Object prev = cache.putIfAbsent(params.key, value, expiry, TimeUnit.MILLISECONDS);
+ return reply(prev);
+ }
+
+ private StorageReply reply(Object prev) {
+ if (prev == null)
+ return StorageReply.STORED;
+ else
+ return StorageReply.NOT_STORED;
+ }
+
+}
Added: trunk/server/memcached/src/main/java/org/infinispan/server/memcached/AppendCommand.java
===================================================================
--- trunk/server/memcached/src/main/java/org/infinispan/server/memcached/AppendCommand.java (rev 0)
+++ trunk/server/memcached/src/main/java/org/infinispan/server/memcached/AppendCommand.java 2009-12-02 20:18:03 UTC (rev 1248)
@@ -0,0 +1,73 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2009, Red Hat, Inc. and/or its affiliates, and
+ * individual contributors as indicated by the @author tags. See the
+ * copyright.txt file in the distribution for a full listing of
+ * individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.infinispan.server.memcached;
+
+import org.infinispan.Cache;
+
+/**
+ * AppendCommand.
+ *
+ * @author Galder Zamarreño
+ * @since 4.0
+ */
+public class AppendCommand extends SetCommand {
+
+ AppendCommand(Cache cache, StorageParameters params, byte[] data) {
+ super(cache, CommandType.APPEND, params, data);
+ }
+
+ AppendCommand(Cache cache, CommandType type, StorageParameters params, byte[] data) {
+ super(cache, type, params, data);
+ }
+
+ @Override
+ protected StorageReply put(String key, Value append) {
+ Value current = (Value) cache.get(key);
+ if (current != null) {
+ byte[] data = concat(current.getData(), append.getData());
+ Value next = new Value(current.getFlags(), data);
+ boolean replaced = cache.replace(key, current, next);
+ if (replaced)
+ return StorageReply.STORED;
+ else
+ return StorageReply.NOT_STORED;
+ } else {
+ return StorageReply.NOT_STORED;
+ }
+ }
+
+ protected byte[] concat(byte[] current, byte[] append) {
+ return TextProtocolUtil.concat(current, append);
+ }
+
+ @Override
+ protected StorageReply putExpiry(String key, Value value, long expiry) {
+ return put(key, value); // ignore expiry
+ }
+
+ @Override
+ protected StorageReply putExpiryUnixTime(String key, Value value, long expiry) {
+ return put(key, value); // ignore expiry
+ }
+
+}
Added: trunk/server/memcached/src/main/java/org/infinispan/server/memcached/CasCommand.java
===================================================================
--- trunk/server/memcached/src/main/java/org/infinispan/server/memcached/CasCommand.java (rev 0)
+++ trunk/server/memcached/src/main/java/org/infinispan/server/memcached/CasCommand.java 2009-12-02 20:18:03 UTC (rev 1248)
@@ -0,0 +1,45 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2009, Red Hat, Inc. and/or its affiliates, and
+ * individual contributors as indicated by the @author tags. See the
+ * copyright.txt file in the distribution for a full listing of
+ * individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.infinispan.server.memcached;
+
+/**
+ * CasCommand.
+ *
+ * @author Galder Zamarreño
+ * @since 4.0
+ */
+public class CasCommand /* extends StorageCommand */ {
+// final long unique;
+//
+// CasCommand(String key, int flags, long expiry, int bytes, long unique) {
+// super(CommandType.CAS, key, flags, expiry, bytes);
+// this.unique = unique;
+// }
+//
+// @Override
+// public Object perform() throws Throwable {
+// throw new org.jboss.util.NotImplementedException("FIXME NYI perform");
+// return null;
+// }
+
+}
Added: trunk/server/memcached/src/main/java/org/infinispan/server/memcached/CasValue.java
===================================================================
--- trunk/server/memcached/src/main/java/org/infinispan/server/memcached/CasValue.java (rev 0)
+++ trunk/server/memcached/src/main/java/org/infinispan/server/memcached/CasValue.java 2009-12-02 20:18:03 UTC (rev 1248)
@@ -0,0 +1,39 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2009, Red Hat, Inc. and/or its affiliates, and
+ * individual contributors as indicated by the @author tags. See the
+ * copyright.txt file in the distribution for a full listing of
+ * individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.infinispan.server.memcached;
+
+/**
+ * CasValue.
+ *
+ * @author Galder Zamarreño
+ * @since 4.0
+ */
+public class CasValue {
+ final Value value;
+ final long unique;
+
+ CasValue(Value value, long unique) {
+ this.value = value;
+ this.unique = unique;
+ }
+}
Added: trunk/server/memcached/src/main/java/org/infinispan/server/memcached/Command.java
===================================================================
--- trunk/server/memcached/src/main/java/org/infinispan/server/memcached/Command.java (rev 0)
+++ trunk/server/memcached/src/main/java/org/infinispan/server/memcached/Command.java 2009-12-02 20:18:03 UTC (rev 1248)
@@ -0,0 +1,38 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2009, Red Hat, Inc. and/or its affiliates, and
+ * individual contributors as indicated by the @author tags. See the
+ * copyright.txt file in the distribution for a full listing of
+ * individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.infinispan.server.memcached;
+
+import org.jboss.netty.channel.Channel;
+
+/**
+ * Command.
+ *
+ * @author Galder Zamarreño
+ * @since 4.0
+ */
+public interface Command {
+
+ Object perform(Channel ch) throws Exception;
+
+ CommandType getType();
+}
Added: trunk/server/memcached/src/main/java/org/infinispan/server/memcached/CommandFactory.java
===================================================================
--- trunk/server/memcached/src/main/java/org/infinispan/server/memcached/CommandFactory.java (rev 0)
+++ trunk/server/memcached/src/main/java/org/infinispan/server/memcached/CommandFactory.java 2009-12-02 20:18:03 UTC (rev 1248)
@@ -0,0 +1,101 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2009, Red Hat, Inc. and/or its affiliates, and
+ * individual contributors as indicated by the @author tags. See the
+ * copyright.txt file in the distribution for a full listing of
+ * individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.infinispan.server.memcached;
+
+import java.io.EOFException;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.concurrent.TimeUnit;
+
+import org.infinispan.Cache;
+import org.infinispan.util.logging.Log;
+import org.infinispan.util.logging.LogFactory;
+
+/**
+ * CommandFactory.
+ *
+ * @author Galder Zamarreño
+ * @since 4.0
+ */
+public class CommandFactory {
+ private static final Log log = LogFactory.getLog(CommandFactory.class);
+
+ private final Cache cache;
+
+ public CommandFactory(Cache cache) {
+ this.cache = cache;
+ }
+
+ public Command createCommand(String line) throws IOException {
+ if (log.isTraceEnabled()) log.trace("Command line: " + line);
+ String[] args = line.trim().split(" +");
+
+ CommandType type = null;
+ String tmp = args[0];
+ if(tmp == null)
+ throw new EOFException();
+ else
+ type = CommandType.parseType(tmp);
+
+ switch(type) {
+ case SET:
+ case ADD:
+ case REPLACE:
+ case APPEND:
+ case PREPEND:
+ case CAS:
+ String key = args[1]; // key
+ if(key == null) throw new EOFException();
+
+ tmp = args[2]; // flags
+ if(tmp == null) throw new EOFException();
+ int flags = Integer.parseInt(tmp);
+
+ tmp = args[3]; // expiry time
+ if(tmp == null) throw new EOFException();
+ long expiry = Long.parseLong(tmp); // seconds
+
+ tmp = args[4]; // number of bytes
+ if(tmp == null) throw new EOFException();
+ int bytes = Integer.parseInt(tmp);
+
+// if (type == CommandType.CAS) {
+// tmp = args[5]; // cas unique, 64-bit integer
+// long unique = Long.parseLong(tmp);
+// return type.buildCasCommand(key, flags, expiry, bytes, unique);
+// }
+
+ return StorageCommand.newStorageCommand(cache, type, new StorageParameters(key, flags, expiry, bytes), null);
+ case GET:
+ case GETS:
+ List<String> keys = new ArrayList<String>(5);
+ keys.addAll(Arrays.asList(args).subList(1, args.length));
+ return RetrievalCommand.newRetrievalCommand(cache, type, new RetrievalParameters(keys));
+ default:
+ return null;
+ }
+ }
+
+}
Added: trunk/server/memcached/src/main/java/org/infinispan/server/memcached/CommandType.java
===================================================================
--- trunk/server/memcached/src/main/java/org/infinispan/server/memcached/CommandType.java (rev 0)
+++ trunk/server/memcached/src/main/java/org/infinispan/server/memcached/CommandType.java 2009-12-02 20:18:03 UTC (rev 1248)
@@ -0,0 +1,83 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2009, Red Hat, Inc. and/or its affiliates, and
+ * individual contributors as indicated by the @author tags. See the
+ * copyright.txt file in the distribution for a full listing of
+ * individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.infinispan.server.memcached;
+
+import java.io.IOException;
+import java.io.StreamCorruptedException;
+
+/**
+ * Command.
+ *
+ * @author Galder Zamarreño
+ * @since 4.0
+ */
+enum CommandType {
+ SET, ADD, REPLACE, APPEND, PREPEND, CAS,
+ GET, GETS,
+ DELETE,
+ INCR, DECR,
+ STATS,
+ FLUSH_ALL,
+ VERSION,
+ QUIT
+ ;
+
+ boolean isStorage() {
+ switch(this) {
+ case SET:
+ case ADD:
+ case REPLACE:
+ case APPEND:
+ case PREPEND:
+ return true;
+ default:
+ return false;
+ }
+ }
+
+ @Override
+ public String toString() {
+ return super.toString().toLowerCase();
+ }
+
+ static CommandType parseType(String type) throws IOException {
+ if(type.equals(CommandType.SET.toString())) return SET;
+ else if(type.equals(CommandType.ADD.toString())) return ADD;
+ else if(type.equals(CommandType.REPLACE.toString())) return REPLACE;
+ else if(type.equals(CommandType.APPEND.toString())) return APPEND;
+ else if(type.equals(CommandType.PREPEND.toString())) return PREPEND;
+ else if(type.equals(CommandType.CAS.toString())) return CAS;
+ else if(type.equals(CommandType.GET.toString())) return GET;
+ else if(type.equals(CommandType.GETS.toString())) return GETS;
+ else if(type.equals(CommandType.DELETE.toString())) return DELETE;
+ else if(type.equals(CommandType.INCR.toString())) return INCR;
+ else if(type.equals(CommandType.DECR.toString())) return DECR;
+ else if(type.equals(CommandType.STATS.toString())) return STATS;
+ else if(type.equals(CommandType.FLUSH_ALL.toString())) return FLUSH_ALL;
+ else if(type.equals(CommandType.VERSION.toString())) return VERSION;
+ else if(type.equals(CommandType.QUIT.toString())) return QUIT;
+ else throw new StreamCorruptedException("request \"" + type + "\" not known");
+ }
+
+
+}
Added: trunk/server/memcached/src/main/java/org/infinispan/server/memcached/GetCommand.java
===================================================================
--- trunk/server/memcached/src/main/java/org/infinispan/server/memcached/GetCommand.java (rev 0)
+++ trunk/server/memcached/src/main/java/org/infinispan/server/memcached/GetCommand.java 2009-12-02 20:18:03 UTC (rev 1248)
@@ -0,0 +1,67 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2009, Red Hat, Inc. and/or its affiliates, and
+ * individual contributors as indicated by the @author tags. See the
+ * copyright.txt file in the distribution for a full listing of
+ * individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.infinispan.server.memcached;
+
+import org.infinispan.Cache;
+import org.jboss.netty.buffer.ChannelBuffer;
+import org.jboss.netty.channel.Channel;
+
+import static org.infinispan.server.memcached.TextProtocolUtil.CRLF;
+import static org.jboss.netty.buffer.ChannelBuffers.*;
+import static org.infinispan.server.memcached.RetrievalReply.VALUE;
+import static org.infinispan.server.memcached.RetrievalReply.END;
+
+/**
+ * GetCommand.
+ *
+ * @author Galder Zamarreño
+ * @since 4.0
+ */
+public class GetCommand extends RetrievalCommand {
+
+ GetCommand(Cache cache, CommandType type, RetrievalParameters params) {
+ super(cache, type, params);
+ }
+
+ @Override
+ public Object perform(Channel ch) throws Exception {
+ ChannelBuffer buffer;
+ for (String key : params.keys) {
+ Value value = (Value) cache.get(key);
+ if (value != null) {
+ StringBuilder sb = new StringBuilder();
+ sb.append(VALUE).append(" ")
+ .append(key).append(" ")
+ .append(value.getFlags()).append(" ")
+ .append(value.getData().length).append(" ");
+ buffer = wrappedBuffer(wrappedBuffer(sb.toString().getBytes()), wrappedBuffer(CRLF),
+ wrappedBuffer(value.getData()), wrappedBuffer(CRLF));
+ ch.write(buffer);
+ }
+ }
+
+ ch.write(wrappedBuffer(wrappedBuffer(END.toString().getBytes()), wrappedBuffer(CRLF)));
+ return null;
+ }
+
+}
Added: trunk/server/memcached/src/main/java/org/infinispan/server/memcached/MemcachedTextServer.java
===================================================================
--- trunk/server/memcached/src/main/java/org/infinispan/server/memcached/MemcachedTextServer.java (rev 0)
+++ trunk/server/memcached/src/main/java/org/infinispan/server/memcached/MemcachedTextServer.java 2009-12-02 20:18:03 UTC (rev 1248)
@@ -0,0 +1,58 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2009, Red Hat, Inc. and/or its affiliates, and
+ * individual contributors as indicated by the @author tags. See the
+ * copyright.txt file in the distribution for a full listing of
+ * individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.infinispan.server.memcached;
+
+import java.net.InetSocketAddress;
+import java.util.concurrent.Executors;
+
+import org.infinispan.Cache;
+import org.infinispan.manager.CacheManager;
+import org.infinispan.manager.DefaultCacheManager;
+import org.jboss.netty.bootstrap.ServerBootstrap;
+import org.jboss.netty.channel.ChannelFactory;
+import org.jboss.netty.channel.socket.nio.NioServerSocketChannelFactory;
+
+/**
+ * TextServer.
+ *
+ * @author Galder Zamarreño
+ * @since 4.0
+ */
+class MemcachedTextServer {
+ final CacheManager manager;
+
+ MemcachedTextServer(CacheManager manager) {
+ this.manager = manager;
+ }
+
+ public void start() {
+ // Configure Infinispan Cache instance
+ Cache cache = manager.getCache();
+
+ // Configure the server.
+ ChannelFactory factory = new NioServerSocketChannelFactory(Executors.newCachedThreadPool(), Executors.newCachedThreadPool());
+ ServerBootstrap bootstrap = new ServerBootstrap(factory);
+ bootstrap.setPipelineFactory(new TextProtocolPipelineFactory(cache));
+ bootstrap.bind(new InetSocketAddress(11211));
+ }
+}
Added: trunk/server/memcached/src/main/java/org/infinispan/server/memcached/PrependCommand.java
===================================================================
--- trunk/server/memcached/src/main/java/org/infinispan/server/memcached/PrependCommand.java (rev 0)
+++ trunk/server/memcached/src/main/java/org/infinispan/server/memcached/PrependCommand.java 2009-12-02 20:18:03 UTC (rev 1248)
@@ -0,0 +1,44 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2009, Red Hat, Inc. and/or its affiliates, and
+ * individual contributors as indicated by the @author tags. See the
+ * copyright.txt file in the distribution for a full listing of
+ * individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.infinispan.server.memcached;
+
+import org.infinispan.Cache;
+
+/**
+ * PrependCommand.
+ *
+ * @author Galder Zamarreño
+ * @since 4.0
+ */
+public class PrependCommand extends AppendCommand {
+
+ PrependCommand(Cache cache, StorageParameters params, byte[] data) {
+ super(cache, CommandType.PREPEND, params, data);
+ }
+
+ @Override
+ protected byte[] concat(byte[] current, byte[] prepend) {
+ return TextProtocolUtil.concat(prepend, current);
+ }
+
+}
Added: trunk/server/memcached/src/main/java/org/infinispan/server/memcached/ReplaceCommand.java
===================================================================
--- trunk/server/memcached/src/main/java/org/infinispan/server/memcached/ReplaceCommand.java (rev 0)
+++ trunk/server/memcached/src/main/java/org/infinispan/server/memcached/ReplaceCommand.java 2009-12-02 20:18:03 UTC (rev 1248)
@@ -0,0 +1,66 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2009, Red Hat, Inc. and/or its affiliates, and
+ * individual contributors as indicated by the @author tags. See the
+ * copyright.txt file in the distribution for a full listing of
+ * individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.infinispan.server.memcached;
+
+import java.util.concurrent.TimeUnit;
+
+import org.infinispan.Cache;
+
+/**
+ * ReplaceCommand.
+ *
+ * @author Galder Zamarreño
+ * @since 4.0
+ */
+public class ReplaceCommand extends SetCommand {
+
+ ReplaceCommand(Cache cache, StorageParameters params, byte[] data) {
+ super(cache, CommandType.REPLACE, params, data);
+ }
+
+ @Override
+ protected StorageReply put(String key, Value value) {
+ Object prev = cache.replace(params.key, value);
+ return reply(prev);
+ }
+
+ @Override
+ protected StorageReply putExpiry(String key, Value value, long expiry) {
+ Object prev = cache.replace(params.key, value, expiry, TimeUnit.SECONDS);
+ return reply(prev);
+ }
+
+ @Override
+ protected StorageReply putExpiryUnixTime(String key, Value value, long expiry) {
+ Object prev = cache.replace(params.key, value, expiry, TimeUnit.MILLISECONDS);
+ return reply(prev);
+ }
+
+ private StorageReply reply(Object prev) {
+ if (prev == null)
+ return StorageReply.NOT_STORED;
+ else
+ return StorageReply.STORED;
+ }
+
+}
Added: trunk/server/memcached/src/main/java/org/infinispan/server/memcached/RetrievalCommand.java
===================================================================
--- trunk/server/memcached/src/main/java/org/infinispan/server/memcached/RetrievalCommand.java (rev 0)
+++ trunk/server/memcached/src/main/java/org/infinispan/server/memcached/RetrievalCommand.java 2009-12-02 20:18:03 UTC (rev 1248)
@@ -0,0 +1,58 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2009, Red Hat, Inc. and/or its affiliates, and
+ * individual contributors as indicated by the @author tags. See the
+ * copyright.txt file in the distribution for a full listing of
+ * individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.infinispan.server.memcached;
+
+import org.infinispan.Cache;
+
+/**
+ * RetrievalCommand.
+ *
+ * @author Galder Zamarreño
+ * @since 4.0
+ */
+public abstract class RetrievalCommand implements Command {
+ final Cache cache;
+ private final CommandType type;
+ final RetrievalParameters params;
+
+ RetrievalCommand(Cache cache, CommandType type, RetrievalParameters params) {
+ this.cache = cache;
+ this.type = type;
+ this.params = params;
+ }
+
+ @Override
+ public CommandType getType() {
+ return type;
+ }
+
+ public static Command newRetrievalCommand(Cache cache, CommandType type, RetrievalParameters params) {
+ switch(type) {
+ case GET: return new GetCommand(cache, type, params);
+// case GETS: ...
+ default: throw new IllegalStateException("Unable to build storage command for type: " + type);
+ }
+
+
+ }
+}
Added: trunk/server/memcached/src/main/java/org/infinispan/server/memcached/RetrievalParameters.java
===================================================================
--- trunk/server/memcached/src/main/java/org/infinispan/server/memcached/RetrievalParameters.java (rev 0)
+++ trunk/server/memcached/src/main/java/org/infinispan/server/memcached/RetrievalParameters.java 2009-12-02 20:18:03 UTC (rev 1248)
@@ -0,0 +1,39 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2009, Red Hat, Inc. and/or its affiliates, and
+ * individual contributors as indicated by the @author tags. See the
+ * copyright.txt file in the distribution for a full listing of
+ * individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.infinispan.server.memcached;
+
+import java.util.List;
+
+/**
+ * RetrievalParameters.
+ *
+ * @author Galder Zamarreño
+ * @since 4.0
+ */
+public class RetrievalParameters {
+ final List<String> keys;
+
+ RetrievalParameters(List<String> keys) {
+ this.keys = keys;
+ }
+}
Added: trunk/server/memcached/src/main/java/org/infinispan/server/memcached/RetrievalReply.java
===================================================================
--- trunk/server/memcached/src/main/java/org/infinispan/server/memcached/RetrievalReply.java (rev 0)
+++ trunk/server/memcached/src/main/java/org/infinispan/server/memcached/RetrievalReply.java 2009-12-02 20:18:03 UTC (rev 1248)
@@ -0,0 +1,33 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2009, Red Hat, Inc. and/or its affiliates, and
+ * individual contributors as indicated by the @author tags. See the
+ * copyright.txt file in the distribution for a full listing of
+ * individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.infinispan.server.memcached;
+
+/**
+ * RetrievalReply.
+ *
+ * @author Galder Zamarreño
+ * @since 4.0
+ */
+public enum RetrievalReply {
+ VALUE, END;
+}
Added: trunk/server/memcached/src/main/java/org/infinispan/server/memcached/SetCommand.java
===================================================================
--- trunk/server/memcached/src/main/java/org/infinispan/server/memcached/SetCommand.java (rev 0)
+++ trunk/server/memcached/src/main/java/org/infinispan/server/memcached/SetCommand.java 2009-12-02 20:18:03 UTC (rev 1248)
@@ -0,0 +1,107 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2009, Red Hat, Inc. and/or its affiliates, and
+ * individual contributors as indicated by the @author tags. See the
+ * copyright.txt file in the distribution for a full listing of
+ * individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.infinispan.server.memcached;
+
+import java.util.Date;
+import java.util.concurrent.TimeUnit;
+
+import org.infinispan.Cache;
+import org.infinispan.CacheException;
+import org.infinispan.util.logging.Log;
+import org.infinispan.util.logging.LogFactory;
+
+import static org.infinispan.server.memcached.TextProtocolUtil.CRLF;
+import static org.jboss.netty.buffer.ChannelBuffers.*;
+import org.jboss.netty.channel.Channel;
+
+/**
+ * SetCommand.
+ *
+ * @author Galder Zamarreño
+ * @since 4.0
+ */
+public class SetCommand extends StorageCommand {
+
+ private static final Log log = LogFactory.getLog(SetCommand.class);
+
+ SetCommand(Cache cache, StorageParameters params, byte[] data) {
+ super(cache, CommandType.SET, params, data);
+ }
+
+ SetCommand(Cache cache, CommandType type, StorageParameters params, byte[] data) {
+ super(cache, type, params, data);
+ }
+
+ @Override
+ public Object perform(Channel ch) throws Exception {
+ StorageReply reply;
+ try {
+ Value value = new Value(params.flags, data);
+ if (params.expiry == 0) {
+ reply = put(params.key, value);
+ } else {
+ if (params.expiry > 60*60*24*30) {
+ // If expiry bigger number of seconds in 30 days, then it's considered unix time
+ long future = TimeUnit.SECONDS.toMillis(params.expiry);
+ long expiry = future - System.currentTimeMillis();
+ if (expiry > 0) {
+ reply = putExpiryUnixTime(params.key, value, expiry);
+ } else {
+ StringBuilder sb = new StringBuilder();
+ sb.append("Given expiry is bigger than 30 days, hence is treated as Unix time, ")
+ .append("but this time is in the past: ").append(future)
+ .append(", date: ").append(new Date(future));
+ throw new CacheException(sb.toString());
+ }
+ } else {
+ reply = putExpiry(params.key, value, params.expiry);
+ }
+ }
+
+ } catch (Exception e) {
+ log.error("Unexpected exception performing command", e);
+ reply = StorageReply.NOT_STORED;
+ }
+ ch.write(wrappedBuffer(wrappedBuffer(reply.toString().getBytes()), wrappedBuffer(CRLF)));
+ return null;
+ }
+
+ protected StorageReply put(String key, Value value) {
+ cache.put(params.key, value);
+ return reply();
+ }
+
+ protected StorageReply putExpiry(String key, Value value, long expiry) {
+ cache.put(params.key, value, params.expiry, TimeUnit.SECONDS);
+ return reply();
+ }
+
+ protected StorageReply putExpiryUnixTime(String key, Value value, long expiry) {
+ cache.put(params.key, value, expiry, TimeUnit.MILLISECONDS);
+ return reply();
+ }
+
+ private StorageReply reply() {
+ return StorageReply.STORED;
+ }
+}
Added: trunk/server/memcached/src/main/java/org/infinispan/server/memcached/StorageCommand.java
===================================================================
--- trunk/server/memcached/src/main/java/org/infinispan/server/memcached/StorageCommand.java (rev 0)
+++ trunk/server/memcached/src/main/java/org/infinispan/server/memcached/StorageCommand.java 2009-12-02 20:18:03 UTC (rev 1248)
@@ -0,0 +1,79 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2009, Red Hat, Inc. and/or its affiliates, and
+ * individual contributors as indicated by the @author tags. See the
+ * copyright.txt file in the distribution for a full listing of
+ * individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.infinispan.server.memcached;
+
+import java.io.IOException;
+import java.io.StreamCorruptedException;
+
+import org.infinispan.Cache;
+
+/**
+ * StorageCommand.
+ *
+ * @author Galder Zamarreño
+ * @since 4.0
+ */
+public abstract class StorageCommand implements Command {
+ final Cache cache;
+ private final CommandType type;
+ final StorageParameters params;
+// final String key;
+// final int flags;
+// final long expiry;
+// final int bytes;
+ final byte[] data;
+
+ StorageCommand(Cache cache, CommandType type, StorageParameters params, byte[] data) {
+ this.type = type;
+ this.params = params;
+ this.cache = cache;
+// this.key = key;
+// this.flags = flags;
+// this.expiry = expiry;
+// this.bytes = bytes;
+ this.data = data;
+ }
+
+ public CommandType getType() {
+ return type;
+ }
+
+ public Command setData(byte[] data) throws IOException {
+ return newStorageCommand(cache, type, params, data);
+ }
+
+ public static Command newStorageCommand(Cache cache, CommandType type, StorageParameters params, byte[] data) throws IOException {
+ switch(type) {
+ case SET: return new SetCommand(cache, params, data);
+ case ADD: return new AddCommand(cache, params, data);
+ case REPLACE: return new ReplaceCommand(cache, params, data);
+ case APPEND: return new AppendCommand(cache, params, data);
+ case PREPEND: return new PrependCommand(cache, params, data);
+ default: throw new StreamCorruptedException("Unable to build storage command for type: " + type);
+ }
+ }
+
+// public static Command buildCasCommand(String key, int flags, long expiry, int bytes, long unique) {
+// return new CasCommand(key, flags, expiry, bytes, unique);
+// }
+}
Added: trunk/server/memcached/src/main/java/org/infinispan/server/memcached/StorageParameters.java
===================================================================
--- trunk/server/memcached/src/main/java/org/infinispan/server/memcached/StorageParameters.java (rev 0)
+++ trunk/server/memcached/src/main/java/org/infinispan/server/memcached/StorageParameters.java 2009-12-02 20:18:03 UTC (rev 1248)
@@ -0,0 +1,44 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2009, Red Hat, Inc. and/or its affiliates, and
+ * individual contributors as indicated by the @author tags. See the
+ * copyright.txt file in the distribution for a full listing of
+ * individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.infinispan.server.memcached;
+
+/**
+ * StorageParameters.
+ *
+ * @author Galder Zamarreño
+ * @since 4.0
+ */
+public class StorageParameters {
+ final String key;
+ final int flags;
+ final long expiry;
+ final int bytes;
+ boolean noreply;
+
+ StorageParameters(String key, int flags, long expiry, int bytes) {
+ this.key = key;
+ this.flags = flags;
+ this.expiry = expiry;
+ this.bytes = bytes;
+ }
+}
Added: trunk/server/memcached/src/main/java/org/infinispan/server/memcached/StorageReply.java
===================================================================
--- trunk/server/memcached/src/main/java/org/infinispan/server/memcached/StorageReply.java (rev 0)
+++ trunk/server/memcached/src/main/java/org/infinispan/server/memcached/StorageReply.java 2009-12-02 20:18:03 UTC (rev 1248)
@@ -0,0 +1,38 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2009, Red Hat, Inc. and/or its affiliates, and
+ * individual contributors as indicated by the @author tags. See the
+ * copyright.txt file in the distribution for a full listing of
+ * individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.infinispan.server.memcached;
+
+/**
+ * StorageReply.
+ *
+ * @author Galder Zamarreño
+ * @since 4.0
+ */
+public enum StorageReply {
+ STORED, NOT_STORED, EXISTS, NOT_FOUND;
+
+// @Override
+// public String toString() {
+// return super.toString() + "\r\n";
+// }
+}
Added: trunk/server/memcached/src/main/java/org/infinispan/server/memcached/TextCommandDecoder.java
===================================================================
--- trunk/server/memcached/src/main/java/org/infinispan/server/memcached/TextCommandDecoder.java (rev 0)
+++ trunk/server/memcached/src/main/java/org/infinispan/server/memcached/TextCommandDecoder.java 2009-12-02 20:18:03 UTC (rev 1248)
@@ -0,0 +1,184 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2009, Red Hat, Inc. and/or its affiliates, and
+ * individual contributors as indicated by the @author tags. See the
+ * copyright.txt file in the distribution for a full listing of
+ * individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.infinispan.server.memcached;
+
+import java.io.IOException;
+import java.io.StreamCorruptedException;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+import org.infinispan.Cache;
+import org.infinispan.util.logging.Log;
+import org.infinispan.util.logging.LogFactory;
+import org.jboss.netty.buffer.ChannelBuffer;
+import org.jboss.netty.channel.Channel;
+import org.jboss.netty.channel.ChannelHandlerContext;
+import org.jboss.netty.channel.ExceptionEvent;
+import org.jboss.netty.handler.codec.replay.ReplayingDecoder;
+import static org.infinispan.server.memcached.TextProtocolUtil.*;
+
+/**
+ * TextCommandDecoder.
+ *
+ * @author Galder Zamarreño
+ * @since 4.0
+ */
+public class TextCommandDecoder extends ReplayingDecoder<TextCommandDecoder.State> {
+ private static final Log log = LogFactory.getLog(TextCommandDecoder.class);
+
+ private final CommandFactory factory;
+ private volatile Command command;
+ private final AtomicBoolean corrupted = new AtomicBoolean();
+
+ protected enum State {
+ READ_COMMAND, READ_UNSTRUCTURED_DATA;
+ }
+
+ TextCommandDecoder(Cache cache) {
+ super(State.READ_COMMAND, true);
+ factory = new CommandFactory(cache);
+ }
+
+ @Override
+ protected Object decode(ChannelHandlerContext ctx, Channel channel, ChannelBuffer buffer, State state) throws Exception {
+ switch (state) {
+ case READ_COMMAND:
+ String line = readLine(buffer);
+ try {
+ command = factory.createCommand(line);
+ corrupted.set(false);
+ } catch (IOException ioe) {
+ if (corrupted.get())
+ log.debug("Channel is corrupted and we're reading garbage, ignore read until we find a good command again");
+ else
+ throw ioe;
+ }
+
+ if (command.getType().isStorage())
+ checkpoint(State.READ_UNSTRUCTURED_DATA);
+ else
+ return command;
+ break;
+ case READ_UNSTRUCTURED_DATA:
+ StorageCommand storageCmd = (StorageCommand) command;
+ byte[] data= new byte[storageCmd.params.bytes];
+ buffer.readBytes(data, 0, data.length);
+ byte next = buffer.readByte();
+ if (next == CR) {
+ next = buffer.readByte();
+ if (next == LF) {
+ try {
+ return reset(storageCmd.setData(data));
+ } catch (IOException ioe) {
+ checkpoint(State.READ_COMMAND);
+ throw ioe;
+ }
+ } else {
+ throw new StreamCorruptedException("Expecting \r\n after data block");
+ }
+ } else {
+ throw new StreamCorruptedException("Expecting \r\n after data block");
+ }
+ }
+ return null;
+ }
+
+ @Override
+ public void exceptionCaught(ChannelHandlerContext ctx, ExceptionEvent e) throws Exception {
+ corrupted.compareAndSet(false, true);
+ log.error("Unexpected exception", e.getCause());
+ }
+
+ private Object reset(Command c) {
+ this.command = null;
+ checkpoint(State.READ_COMMAND);
+ return c;
+ }
+
+ private String readLine(ChannelBuffer buffer) {
+ StringBuilder sb = new StringBuilder(64);
+ int lineLength = 0;
+ while (true) {
+ byte next = buffer.readByte();
+ if (next == CR) {
+ next = buffer.readByte();
+ if (next == LF) {
+ return sb.toString();
+ }
+ } else if (next == LF) {
+ return sb.toString();
+ } else {
+ lineLength++;
+ sb.append((char) next);
+ }
+ }
+ }
+
+ // private String readLine(ChannelBuffer buffer) {
+ // int minFrameLength = Integer.MAX_VALUE;
+ //
+ // ChannelBuffer minDelim = null;
+ // int frameLength = indexOf(buffer, CR);
+ // if (frameLength >= 0 && frameLength < minFrameLength) {
+ // minFrameLength = frameLength;
+ // minDelim = CR;
+ // }
+ //
+ // if (minDelim != null) {
+ // int minDelimLength = minDelim.capacity();
+ // ChannelBuffer frame = buffer.readBytes(minFrameLength);
+ // buffer.skipBytes(minDelimLength);
+ // return frame.toString(Charset.defaultCharset().name());
+ // } else {
+ // return null;
+ // }
+ // }
+ //
+ // /**
+ // * Returns the number of bytes between the readerIndex of the haystack and
+ // * the first needle found in the haystack. -1 is returned if no needle is
+ // * found in the haystack.
+ // */
+ // private static int indexOf(ChannelBuffer haystack, ChannelBuffer needle) {
+ // for (int i = haystack.readerIndex(); i < haystack.writerIndex(); i ++) {
+ // int haystackIndex = i;
+ // int needleIndex;
+ // for (needleIndex = 0; needleIndex < needle.capacity(); needleIndex ++) {
+ // if (haystack.getByte(haystackIndex) != needle.getByte(needleIndex)) {
+ // break;
+ // } else {
+ // haystackIndex ++;
+ // if (haystackIndex == haystack.writerIndex() &&
+ // needleIndex != needle.capacity() - 1) {
+ // return -1;
+ // }
+ // }
+ // }
+ //
+ // if (needleIndex == needle.capacity()) {
+ // // Found the needle from the haystack!
+ // return i - haystack.readerIndex();
+ // }
+ // }
+ // return -1;
+ // }
+}
Added: trunk/server/memcached/src/main/java/org/infinispan/server/memcached/TextCommandHandler.java
===================================================================
--- trunk/server/memcached/src/main/java/org/infinispan/server/memcached/TextCommandHandler.java (rev 0)
+++ trunk/server/memcached/src/main/java/org/infinispan/server/memcached/TextCommandHandler.java 2009-12-02 20:18:03 UTC (rev 1248)
@@ -0,0 +1,56 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2009, Red Hat, Inc. and/or its affiliates, and
+ * individual contributors as indicated by the @author tags. See the
+ * copyright.txt file in the distribution for a full listing of
+ * individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.infinispan.server.memcached;
+
+import org.jboss.netty.buffer.ChannelBuffer;
+import org.jboss.netty.buffer.ChannelBuffers;
+import org.jboss.netty.channel.Channel;
+import org.jboss.netty.channel.ChannelHandlerContext;
+import org.jboss.netty.channel.ChannelPipelineCoverage;
+import org.jboss.netty.channel.MessageEvent;
+import org.jboss.netty.channel.SimpleChannelUpstreamHandler;
+
+/**
+ * TextProtocolServerHandler.
+ *
+ * @author Galder Zamarreño
+ * @since 4.0
+ */
+ at ChannelPipelineCoverage("one")
+class TextCommandHandler extends SimpleChannelUpstreamHandler {
+
+ @Override
+ public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception {
+ Command c = (Command) e.getMessage();
+ c.perform(ctx.getChannel());
+// Channel ch = ctx.getChannel();
+//
+// byte[] bytes = ret.toString().getBytes();
+// ChannelBuffer buffer = ChannelBuffers.buffer(bytes.length);
+// buffer.writeBytes(bytes);
+//
+// ch.write(buffer);
+ }
+
+
+}
Added: trunk/server/memcached/src/main/java/org/infinispan/server/memcached/TextProtocolPipelineFactory.java
===================================================================
--- trunk/server/memcached/src/main/java/org/infinispan/server/memcached/TextProtocolPipelineFactory.java (rev 0)
+++ trunk/server/memcached/src/main/java/org/infinispan/server/memcached/TextProtocolPipelineFactory.java 2009-12-02 20:18:03 UTC (rev 1248)
@@ -0,0 +1,63 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2009, Red Hat, Inc. and/or its affiliates, and
+ * individual contributors as indicated by the @author tags. See the
+ * copyright.txt file in the distribution for a full listing of
+ * individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.infinispan.server.memcached;
+
+import static org.jboss.netty.channel.Channels.*;
+
+import org.infinispan.Cache;
+import org.jboss.netty.channel.ChannelHandler;
+import org.jboss.netty.channel.ChannelPipeline;
+import org.jboss.netty.channel.ChannelPipelineFactory;
+
+/**
+ * TextProtocolPipelineFactory.
+ *
+ * @author Galder Zamarreño
+ * @since 4.0
+ */
+class TextProtocolPipelineFactory implements ChannelPipelineFactory {
+
+// private final ChannelHandler handler;
+//
+// public TextProtocolPipelineFactory(TextCommandHandler handler) {
+// this.handler = handler;
+// }
+
+ private final Cache cache;
+
+ public TextProtocolPipelineFactory(Cache cache) {
+ this.cache = cache;
+ }
+
+ @Override
+ public ChannelPipeline getPipeline() throws Exception {
+ // Create a default pipeline implementation.
+ ChannelPipeline pipeline = pipeline();
+ pipeline.addLast("decoder", new TextCommandDecoder(cache));
+ pipeline.addLast("handler", new TextCommandHandler());
+// pipeline.addLast("encoder", new TextResponseEncoder());
+
+ return pipeline;
+ }
+
+}
Added: trunk/server/memcached/src/main/java/org/infinispan/server/memcached/TextProtocolUtil.java
===================================================================
--- trunk/server/memcached/src/main/java/org/infinispan/server/memcached/TextProtocolUtil.java (rev 0)
+++ trunk/server/memcached/src/main/java/org/infinispan/server/memcached/TextProtocolUtil.java 2009-12-02 20:18:03 UTC (rev 1248)
@@ -0,0 +1,42 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2009, Red Hat, Inc. and/or its affiliates, and
+ * individual contributors as indicated by the @author tags. See the
+ * copyright.txt file in the distribution for a full listing of
+ * individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.infinispan.server.memcached;
+
+/**
+ * TextProtocolUtil.
+ *
+ * @author Galder Zamarreño
+ * @since 4.0
+ */
+public class TextProtocolUtil {
+ static final byte CR = 13;
+ static final byte LF = 10;
+ static final byte[] CRLF = new byte[] { CR, LF };
+
+ public static byte[] concat(byte[] a, byte[] b) {
+ byte[] data = new byte[a.length + b.length];
+ System.arraycopy(a, 0, data, 0, a.length);
+ System.arraycopy(b, 0, data, a.length , b.length);
+ return data;
+ }
+}
Added: trunk/server/memcached/src/main/java/org/infinispan/server/memcached/Value.java
===================================================================
--- trunk/server/memcached/src/main/java/org/infinispan/server/memcached/Value.java (rev 0)
+++ trunk/server/memcached/src/main/java/org/infinispan/server/memcached/Value.java 2009-12-02 20:18:03 UTC (rev 1248)
@@ -0,0 +1,85 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2009, Red Hat, Inc. and/or its affiliates, and
+ * individual contributors as indicated by the @author tags. See the
+ * copyright.txt file in the distribution for a full listing of
+ * individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.infinispan.server.memcached;
+
+import java.io.Externalizable;
+import java.io.IOException;
+import java.io.ObjectInput;
+import java.io.ObjectOutput;
+import java.util.Arrays;
+
+/**
+ * Value.
+ *
+ * @author Galder Zamarreño
+ * @since 4.0
+ */
+class Value implements Externalizable {
+ private int flags;
+ private byte[] data;
+
+ Value(int flags, byte[] data) {
+ this.flags = flags;
+ this.data = data;
+ }
+
+ public int getFlags() {
+ return flags;
+ }
+
+ public byte[] getData() {
+ return data;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (obj == this)
+ return true;
+ if (!(obj instanceof Value))
+ return false;
+ Value other = (Value) obj;
+ return Arrays.equals(data, other.data) && flags == other.flags;
+ }
+
+ @Override
+ public int hashCode() {
+ int result = 17;
+ result = 31 * result + flags;
+ result = 31 * result + data.hashCode();
+ return result;
+ }
+
+ @Override
+ public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
+ flags = in.read();
+ data = new byte[in.read()];
+ in.read(data);
+ }
+
+ @Override
+ public void writeExternal(ObjectOutput out) throws IOException {
+ out.write(flags);
+ out.write(data.length);
+ out.write(data);
+ }
+}
Added: trunk/server/memcached/src/test/java/org/infinispan/server/memcached/FunctionalTest.java
===================================================================
--- trunk/server/memcached/src/test/java/org/infinispan/server/memcached/FunctionalTest.java (rev 0)
+++ trunk/server/memcached/src/test/java/org/infinispan/server/memcached/FunctionalTest.java 2009-12-02 20:18:03 UTC (rev 1248)
@@ -0,0 +1,220 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2009, Red Hat, Inc. and/or its affiliates, and
+ * individual contributors as indicated by the @author tags. See the
+ * copyright.txt file in the distribution for a full listing of
+ * individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.infinispan.server.memcached;
+
+import java.lang.reflect.Method;
+import java.net.InetSocketAddress;
+import java.util.Arrays;
+import java.util.Map;
+import java.util.concurrent.Future;
+import java.util.concurrent.TimeUnit;
+
+import net.spy.memcached.DefaultConnectionFactory;
+import net.spy.memcached.MemcachedClient;
+
+import org.infinispan.manager.CacheManager;
+import org.infinispan.test.SingleCacheManagerTest;
+import org.infinispan.test.fwk.TestCacheManagerFactory;
+import org.testng.annotations.Test;
+
+/**
+ * FunctionalTest.
+ *
+ * @author Galder Zamarreño
+ * @since 4.0
+ */
+ at Test(groups = "functional", testName = "server.memcached.FunctionalTest")
+public class FunctionalTest extends SingleCacheManagerTest {
+ private MemcachedClient client;
+ private MemcachedTextServer server;
+
+ @Override
+ protected CacheManager createCacheManager() throws Exception {
+ cacheManager = TestCacheManagerFactory.createLocalCacheManager();
+ server = new MemcachedTextServer(cacheManager);
+ server.start();
+ DefaultConnectionFactory d = new DefaultConnectionFactory() {
+ @Override
+ public long getOperationTimeout() {
+ return 5000;
+ }
+ };
+
+ client = new MemcachedClient(d, Arrays.asList(new InetSocketAddress[]{new InetSocketAddress(11211)}));
+ return cacheManager;
+ }
+
+ public void testBasicSet(Method m) throws Exception {
+ Future<Boolean> f = client.set(k(m), 0, v(m));
+ assert f.get(5, TimeUnit.SECONDS);
+ assert client.get(k(m)).equals(v(m));
+ }
+
+ public void testSetWithExpirySeconds(Method m) throws Exception {
+ Future<Boolean> f = client.set(k(m), 1, v(m));
+ assert f.get(5, TimeUnit.SECONDS);
+ Thread.sleep(1100);
+ assert null == client.get(k(m));
+ }
+
+ public void testSetWithExpiryUnixTime(Method m) throws Exception {
+ int future = (int) TimeUnit.MILLISECONDS.toSeconds(System.currentTimeMillis() + 1000);
+ Future<Boolean> f = client.set(k(m), future, v(m));
+ assert f.get(5, TimeUnit.SECONDS);
+ Thread.sleep(1100);
+ assert null == client.get(k(m));
+ }
+
+ public void testGetMultipleKeys(Method m) throws Exception {
+ Future<Boolean> f1 = client.set(k(m, "k1-"), 0, v(m, "v1-"));
+ Future<Boolean> f2 = client.set(k(m, "k2-"), 0, v(m, "v2-"));
+ Future<Boolean> f3 = client.set(k(m, "k3-"), 0, v(m, "v3-"));
+ assert f1.get(5, TimeUnit.SECONDS);
+ assert f2.get(5, TimeUnit.SECONDS);
+ assert f3.get(5, TimeUnit.SECONDS);
+
+ Map<String, Object> ret = client.getBulk(Arrays.asList(new String[]{k(m, "k1-"), k(m, "k2-"), k(m, "k3-")}));
+ assert ret.get(k(m, "k1-")).equals(v(m, "v1-"));
+ assert ret.get(k(m, "k2-")).equals(v(m, "v2-"));
+ assert ret.get(k(m, "k3-")).equals(v(m, "v3-"));
+ }
+
+ public void testBasicAdd(Method m) throws Exception {
+ Future<Boolean> f = client.add(k(m), 0, v(m));
+ assert f.get(5, TimeUnit.SECONDS);
+ assert v(m).equals(client.get(k(m)));
+ }
+
+ public void testAddWithExpirySeconds(Method m) throws Exception {
+ Future<Boolean> f = client.add(k(m), 1, v(m));
+ assert f.get(5, TimeUnit.SECONDS);
+ Thread.sleep(1100);
+ assert null == client.get(k(m));
+
+ f = client.add(k(m), 0, v(m, "k1-"));
+ assert f.get(5, TimeUnit.SECONDS);
+ assert v(m, "k1-").equals(client.get(k(m)));
+ }
+
+ public void testAddWithExpiryUnixTime(Method m) throws Exception {
+ int future = (int) TimeUnit.MILLISECONDS.toSeconds(System.currentTimeMillis() + 1000);
+ Future<Boolean> f = client.add(k(m), future, v(m));
+ assert f.get(5, TimeUnit.SECONDS);
+ Thread.sleep(1100);
+ assert null == client.get(k(m));
+
+ f = client.add(k(m), 0, v(m, "k1-"));
+ assert f.get(5, TimeUnit.SECONDS);
+ assert v(m, "k1-").equals(client.get(k(m)));
+ }
+
+ public void testNotAddIsPresent(Method m) throws Exception {
+ Future<Boolean> f = client.add(k(m), 0, v(m));
+ assert(f.get(5, TimeUnit.SECONDS));
+ assert v(m).equals(client.get(k(m)));
+
+ f = client.add(k(m), 0, v(m, "k1-"));
+ assert false == f.get(5, TimeUnit.SECONDS);
+ assert client.get(k(m)).equals(v(m));
+ }
+
+ public void testBasicReplace(Method m) throws Exception {
+ Future<Boolean> f = client.add(k(m), 0, v(m));
+ assert(f.get(5, TimeUnit.SECONDS));
+ assert v(m).equals(client.get(k(m)));
+
+ f = client.replace(k(m), 0, v(m, "k1-"));
+ assert f.get(5, TimeUnit.SECONDS);
+ assert v(m, "k1-").equals(client.get(k(m)));
+ }
+
+ public void testNotReplaceIsNotPresent(Method m) throws Exception {
+ Future<Boolean> f = client.replace(k(m), 0, v(m));
+ assert false == f.get(5, TimeUnit.SECONDS);
+ assert null == client.get(k(m));
+ }
+
+ public void testReplaceWithExpirySeconds(Method m) throws Exception {
+ Future<Boolean> f = client.add(k(m), 0, v(m));
+ assert(f.get(5, TimeUnit.SECONDS));
+ assert v(m).equals(client.get(k(m)));
+
+ f = client.replace(k(m), 1, v(m, "k1-"));
+ assert f.get(5, TimeUnit.SECONDS);
+ assert client.get(k(m)).equals(v(m, "k1-"));
+ Thread.sleep(1100);
+ assert null == client.get(k(m));
+ }
+
+ public void testReplaceWithExpiryUnixTime(Method m) throws Exception {
+ Future<Boolean> f = client.add(k(m), 0, v(m));
+ assert f.get(5, TimeUnit.SECONDS);
+ assert v(m).equals(client.get(k(m)));
+
+ int future = (int) TimeUnit.MILLISECONDS.toSeconds(System.currentTimeMillis() + 1000);
+ f = client.replace(k(m), future, v(m, "k1-"));
+ assert f.get(5, TimeUnit.SECONDS);
+ assert client.get(k(m)).equals(v(m, "k1-"));
+ Thread.sleep(1100);
+ assert null == client.get(k(m));
+ }
+
+ public void testBasicAppend(Method m) throws Exception {
+ Future<Boolean> f = client.add(k(m), 0, v(m));
+ assert f.get(5, TimeUnit.SECONDS);
+ assert v(m).equals(client.get(k(m)));
+
+ f = client.append(0, k(m), v(m, "v1-"));
+ assert f.get(5, TimeUnit.SECONDS);
+ String expected = v(m).toString() + v(m, "v1-").toString();
+ assert expected.equals(client.get(k(m)));
+ }
+
+ public void testBasicPrepend(Method m) throws Exception {
+ Future<Boolean> f = client.add(k(m), 0, v(m));
+ assert f.get(5, TimeUnit.SECONDS);
+ assert v(m).equals(client.get(k(m)));
+
+ f = client.prepend(0, k(m), v(m, "v1-"));
+ assert f.get(5, TimeUnit.SECONDS);
+ String expected = v(m, "v1-").toString() + v(m).toString();
+ assert expected.equals(client.get(k(m)));
+ }
+
+ private String k(Method method, String prefix) {
+ return prefix + method.getName();
+ }
+
+ private Object v(Method method, String prefix) {
+ return prefix + method.getName();
+ }
+
+ private String k(Method method) {
+ return k(method, "k-");
+ }
+
+ private Object v(Method method) {
+ return v(method, "v-");
+ }
+
+}
More information about the infinispan-commits
mailing list