hadoop-zookeeper-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From maha...@apache.org
Subject svn commit: r772843 [5/5] - in /hadoop/zookeeper/trunk: ./ src/contrib/rest/ src/contrib/rest/conf/ src/contrib/rest/lib/ src/contrib/rest/src/ src/contrib/rest/src/java/ src/contrib/rest/src/java/org/ src/contrib/rest/src/java/org/apache/ src/contrib/...
Date Fri, 08 May 2009 05:27:03 GMT
Added: hadoop/zookeeper/trunk/src/contrib/rest/src/java/org/apache/zookeeper/server/jersey/jaxb/ZError.java
URL: http://svn.apache.org/viewvc/hadoop/zookeeper/trunk/src/contrib/rest/src/java/org/apache/zookeeper/server/jersey/jaxb/ZError.java?rev=772843&view=auto
==============================================================================
--- hadoop/zookeeper/trunk/src/contrib/rest/src/java/org/apache/zookeeper/server/jersey/jaxb/ZError.java (added)
+++ hadoop/zookeeper/trunk/src/contrib/rest/src/java/org/apache/zookeeper/server/jersey/jaxb/ZError.java Fri May  8 05:27:00 2009
@@ -0,0 +1,41 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.zookeeper.server.jersey.jaxb;
+
+import javax.xml.bind.annotation.XmlRootElement;
+
+
+/**
+ * Represents an ERROR using JAXB.
+ */
+@XmlRootElement(name="error")
+public class ZError {
+    public String request;
+    public String message;
+
+    public ZError(){
+        // needed by jersey
+    }
+
+    public ZError(String request, String message) {
+        this.request = request;
+        this.message = message;
+    }
+
+}

Added: hadoop/zookeeper/trunk/src/contrib/rest/src/java/org/apache/zookeeper/server/jersey/jaxb/ZPath.java
URL: http://svn.apache.org/viewvc/hadoop/zookeeper/trunk/src/contrib/rest/src/java/org/apache/zookeeper/server/jersey/jaxb/ZPath.java?rev=772843&view=auto
==============================================================================
--- hadoop/zookeeper/trunk/src/contrib/rest/src/java/org/apache/zookeeper/server/jersey/jaxb/ZPath.java (added)
+++ hadoop/zookeeper/trunk/src/contrib/rest/src/java/org/apache/zookeeper/server/jersey/jaxb/ZPath.java Fri May  8 05:27:00 2009
@@ -0,0 +1,63 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.zookeeper.server.jersey.jaxb;
+
+import javax.xml.bind.annotation.XmlRootElement;
+
+
+/**
+ * Represents a PATH using JAXB.
+ */
+@XmlRootElement(name="path")
+public class ZPath {
+    public String path;
+    public String uri;
+
+    public ZPath(){
+        // needed by jersey
+    }
+
+    public ZPath(String path) {
+        this(path, null);
+    }
+
+    public ZPath(String path, String uri) {
+        this.path = path;
+        this.uri = uri;
+    }
+
+    @Override
+    public int hashCode() {
+        return path.hashCode();
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (!(obj instanceof ZPath)) {
+            return false;
+        }
+        ZPath o = (ZPath) obj;
+        return path.equals(o.path);
+    }
+
+    @Override
+    public String toString() {
+        return "ZPath(" + path + ")";
+    }
+}

Added: hadoop/zookeeper/trunk/src/contrib/rest/src/java/org/apache/zookeeper/server/jersey/jaxb/ZStat.java
URL: http://svn.apache.org/viewvc/hadoop/zookeeper/trunk/src/contrib/rest/src/java/org/apache/zookeeper/server/jersey/jaxb/ZStat.java?rev=772843&view=auto
==============================================================================
--- hadoop/zookeeper/trunk/src/contrib/rest/src/java/org/apache/zookeeper/server/jersey/jaxb/ZStat.java (added)
+++ hadoop/zookeeper/trunk/src/contrib/rest/src/java/org/apache/zookeeper/server/jersey/jaxb/ZStat.java Fri May  8 05:27:00 2009
@@ -0,0 +1,106 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.zookeeper.server.jersey.jaxb;
+
+import javax.xml.bind.annotation.XmlRootElement;
+
+
+/**
+ * Represents a STAT using JAXB.
+ */
+@XmlRootElement(name="stat")
+public class ZStat {
+    public String path;
+    public String uri;
+    public byte[] data64;
+    public String dataUtf8;
+
+    public long czxid;
+    public long mzxid;
+    public long ctime;
+    public long mtime;
+    public int version;
+    public int cversion;
+    public int aversion;
+    public long ephemeralOwner;
+    public int dataLength;
+    public int numChildren;
+    public long pzxid;
+
+
+    public ZStat(){
+        // needed by jersey
+    }
+
+    public ZStat(String path, byte[] data64, String dataUtf8)
+    {
+        this.path = path;
+        this.data64 = data64;
+        this.dataUtf8 = dataUtf8;
+    }
+
+    public ZStat(String path, String uri, byte[] data64, String dataUtf8,
+            long czxid, long mzxid, long ctime, long mtime, int version,
+            int cversion, int aversion, long ephemeralOwner, int dataLength,
+            int numChildren, long pzxid)
+    {
+        this.path = path;
+        this.uri = uri;
+        this.data64 = data64;
+        this.dataUtf8 = dataUtf8;
+
+        this.czxid = czxid;
+        this.mzxid = mzxid;
+        this.ctime = ctime;
+        this.mtime = mtime;
+        this.version = version;
+        this.cversion = cversion;
+        this.aversion = aversion;
+        this.ephemeralOwner = ephemeralOwner;
+        this.dataLength = dataLength;
+        this.numChildren = numChildren;
+        this.pzxid = pzxid;
+    }
+
+    @Override
+    public int hashCode() {
+        return path.hashCode();
+    }
+
+    /**
+     * This method considers two ZStats equal if their path, encoding, and
+     * data match. It does not compare the ZooKeeper
+     * org.apache.zookeeper.data.Stat class fields.
+     */
+    @Override
+    public boolean equals(Object obj) {
+        if (!(obj instanceof ZStat)) {
+            return false;
+        }
+        ZStat o = (ZStat) obj;
+        return toString().equals(o.toString());
+    }
+
+    @Override
+    public String toString() {
+        return "ZStat(" + path + "," + "b64["
+            + (data64 == null ? null : new String(data64)) + "],"
+            + dataUtf8 + ")";
+    }
+}

Added: hadoop/zookeeper/trunk/src/contrib/rest/src/java/org/apache/zookeeper/server/jersey/resources/JAXBContextResolver.java
URL: http://svn.apache.org/viewvc/hadoop/zookeeper/trunk/src/contrib/rest/src/java/org/apache/zookeeper/server/jersey/resources/JAXBContextResolver.java?rev=772843&view=auto
==============================================================================
--- hadoop/zookeeper/trunk/src/contrib/rest/src/java/org/apache/zookeeper/server/jersey/resources/JAXBContextResolver.java (added)
+++ hadoop/zookeeper/trunk/src/contrib/rest/src/java/org/apache/zookeeper/server/jersey/resources/JAXBContextResolver.java Fri May  8 05:27:00 2009
@@ -0,0 +1,72 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.zookeeper.server.jersey.resources;
+
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Set;
+
+import javax.ws.rs.ext.ContextResolver;
+import javax.ws.rs.ext.Provider;
+import javax.xml.bind.JAXBContext;
+
+import org.apache.zookeeper.server.jersey.jaxb.ZChildrenJSON;
+import org.apache.zookeeper.server.jersey.jaxb.ZPath;
+import org.apache.zookeeper.server.jersey.jaxb.ZStat;
+
+import com.sun.jersey.api.json.JSONConfiguration;
+import com.sun.jersey.api.json.JSONJAXBContext;
+
+/**
+ * Tell Jersey how to resolve JSON formatting. Specifically detail the
+ * fields which are arrays and which are numbers (not strings).
+ */
+@Provider
+@SuppressWarnings("unchecked")
+public final class JAXBContextResolver implements ContextResolver<JAXBContext> {
+    private final JAXBContext context;
+
+    private final Set<Class> typesSet;
+
+    public JAXBContextResolver() throws Exception {
+        Class[] typesArr =
+            new Class[]{ZPath.class, ZStat.class, ZChildrenJSON.class};
+        typesSet = new HashSet<Class>(Arrays.asList(typesArr));
+        context = new JSONJAXBContext(
+                JSONConfiguration.mapped()
+                    .arrays("children")
+                    .nonStrings("czxid")
+                    .nonStrings("mzxid")
+                    .nonStrings("ctime")
+                    .nonStrings("mtime")
+                    .nonStrings("version")
+                    .nonStrings("cversion")
+                    .nonStrings("aversion")
+                    .nonStrings("ephemeralOwner")
+                    .nonStrings("dataLength")
+                    .nonStrings("numChildren")
+                    .nonStrings("pzxid")
+                    .build(),
+                typesArr);
+    }
+
+    public JAXBContext getContext(Class<?> objectType) {
+        return (typesSet.contains(objectType)) ? context : null;
+    }
+}

Added: hadoop/zookeeper/trunk/src/contrib/rest/src/java/org/apache/zookeeper/server/jersey/resources/KeeperExceptionMapper.java
URL: http://svn.apache.org/viewvc/hadoop/zookeeper/trunk/src/contrib/rest/src/java/org/apache/zookeeper/server/jersey/resources/KeeperExceptionMapper.java?rev=772843&view=auto
==============================================================================
--- hadoop/zookeeper/trunk/src/contrib/rest/src/java/org/apache/zookeeper/server/jersey/resources/KeeperExceptionMapper.java (added)
+++ hadoop/zookeeper/trunk/src/contrib/rest/src/java/org/apache/zookeeper/server/jersey/resources/KeeperExceptionMapper.java Fri May  8 05:27:00 2009
@@ -0,0 +1,86 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.zookeeper.server.jersey.resources;
+
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.UriInfo;
+import javax.ws.rs.ext.ExceptionMapper;
+import javax.ws.rs.ext.Provider;
+
+import org.apache.zookeeper.KeeperException;
+import org.apache.zookeeper.server.jersey.jaxb.ZError;
+
+
+/**
+ * Map KeeperException to HTTP status codes
+ */
+@Provider
+public class KeeperExceptionMapper implements ExceptionMapper<KeeperException> {
+    private UriInfo ui;
+
+    public KeeperExceptionMapper(@Context UriInfo ui) {
+        this.ui = ui;
+    }
+
+    public Response toResponse(KeeperException e) {
+        Response.Status status;
+        String message;
+
+        String path = e.getPath();
+
+        switch(e.code()) {
+        case AUTHFAILED:
+            status = Response.Status.UNAUTHORIZED;
+            message = path + " not authorized";
+            break;
+        case BADARGUMENTS:
+            status = Response.Status.BAD_REQUEST;
+            message = path + " bad arguments";
+            break;
+        case BADVERSION:
+            status = Response.Status.PRECONDITION_FAILED;
+            message = path + " bad version";
+            break;
+        case INVALIDACL:
+            status = Response.Status.BAD_REQUEST;
+            message = path + " invalid acl";
+            break;
+        case NODEEXISTS:
+            status = Response.Status.CONFLICT;
+            message = path + " already exists";
+            break;
+        case NONODE:
+            status = Response.Status.NOT_FOUND;
+            message = path + " not found";
+            break;
+        case NOTEMPTY:
+            status = Response.Status.CONFLICT;
+            message = path + " not empty";
+            break;
+        default:
+            status = Response.Status.fromStatusCode(502); // bad gateway
+            message = "Error processing request for " + path
+                + " : " + e.getMessage();
+        }
+
+        return Response.status(status).entity(
+                new ZError(ui.getRequestUri().toString(), message)).build();
+    }
+}

Added: hadoop/zookeeper/trunk/src/contrib/rest/src/java/org/apache/zookeeper/server/jersey/resources/RuntimeExceptionMapper.java
URL: http://svn.apache.org/viewvc/hadoop/zookeeper/trunk/src/contrib/rest/src/java/org/apache/zookeeper/server/jersey/resources/RuntimeExceptionMapper.java?rev=772843&view=auto
==============================================================================
--- hadoop/zookeeper/trunk/src/contrib/rest/src/java/org/apache/zookeeper/server/jersey/resources/RuntimeExceptionMapper.java (added)
+++ hadoop/zookeeper/trunk/src/contrib/rest/src/java/org/apache/zookeeper/server/jersey/resources/RuntimeExceptionMapper.java Fri May  8 05:27:00 2009
@@ -0,0 +1,48 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.zookeeper.server.jersey.resources;
+
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.UriInfo;
+import javax.ws.rs.ext.ExceptionMapper;
+import javax.ws.rs.ext.Provider;
+
+import org.apache.zookeeper.server.jersey.jaxb.ZError;
+
+/**
+ * Map RuntimeException to HTTP status codes
+ */
+@Provider
+public class RuntimeExceptionMapper
+    implements ExceptionMapper<RuntimeException>
+{
+    private UriInfo ui;
+
+    public RuntimeExceptionMapper(@Context UriInfo ui) {
+        this.ui = ui;
+    }
+
+    public Response toResponse(RuntimeException e) {
+        return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(
+                new ZError(ui.getRequestUri().toString(),
+                        "Error processing request due to " + e.getMessage()
+                        )).build();
+    }
+}

Added: hadoop/zookeeper/trunk/src/contrib/rest/src/java/org/apache/zookeeper/server/jersey/resources/ZErrorWriter.java
URL: http://svn.apache.org/viewvc/hadoop/zookeeper/trunk/src/contrib/rest/src/java/org/apache/zookeeper/server/jersey/resources/ZErrorWriter.java?rev=772843&view=auto
==============================================================================
--- hadoop/zookeeper/trunk/src/contrib/rest/src/java/org/apache/zookeeper/server/jersey/resources/ZErrorWriter.java (added)
+++ hadoop/zookeeper/trunk/src/contrib/rest/src/java/org/apache/zookeeper/server/jersey/resources/ZErrorWriter.java Fri May  8 05:27:00 2009
@@ -0,0 +1,63 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.zookeeper.server.jersey.resources;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.PrintStream;
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Type;
+
+import javax.ws.rs.Produces;
+import javax.ws.rs.WebApplicationException;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.MultivaluedMap;
+import javax.ws.rs.ext.MessageBodyWriter;
+import javax.ws.rs.ext.Provider;
+
+import org.apache.zookeeper.server.jersey.jaxb.ZError;
+
+/**
+ * Tell Jersey how to format an octet response error message.
+ */
+@Produces(MediaType.APPLICATION_OCTET_STREAM)
+@Provider
+public class ZErrorWriter implements MessageBodyWriter<ZError> {
+
+    public long getSize(ZError t, Class<?> type, Type genericType,
+            Annotation[] annotations, MediaType mediaType)  {
+        return -1;
+    }
+
+    public boolean isWriteable(Class<?> type, Type genericType,
+            Annotation[] annotations, MediaType mediaType) {
+        return ZError.class.isAssignableFrom(type);
+    }
+
+    public void writeTo(ZError t, Class<?> type, Type genericType,
+            Annotation[] annotations, MediaType mediaType,
+            MultivaluedMap<String, Object> httpHeaders,
+            OutputStream os)
+        throws IOException, WebApplicationException
+    {
+        PrintStream p = new PrintStream(os);
+        p.print("Request " + t.request + " failed due to " + t.message);
+        p.flush();
+    }
+}

Added: hadoop/zookeeper/trunk/src/contrib/rest/src/java/org/apache/zookeeper/server/jersey/resources/ZNodeResource.java
URL: http://svn.apache.org/viewvc/hadoop/zookeeper/trunk/src/contrib/rest/src/java/org/apache/zookeeper/server/jersey/resources/ZNodeResource.java?rev=772843&view=auto
==============================================================================
--- hadoop/zookeeper/trunk/src/contrib/rest/src/java/org/apache/zookeeper/server/jersey/resources/ZNodeResource.java (added)
+++ hadoop/zookeeper/trunk/src/contrib/rest/src/java/org/apache/zookeeper/server/jersey/resources/ZNodeResource.java Fri May  8 05:27:00 2009
@@ -0,0 +1,375 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.zookeeper.server.jersey.resources;
+
+import java.io.IOException;
+import java.net.URI;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.ws.rs.Consumes;
+import javax.ws.rs.DELETE;
+import javax.ws.rs.DefaultValue;
+import javax.ws.rs.GET;
+import javax.ws.rs.HEAD;
+import javax.ws.rs.POST;
+import javax.ws.rs.PUT;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.QueryParam;
+import javax.ws.rs.WebApplicationException;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.UriInfo;
+
+import org.apache.zookeeper.CreateMode;
+import org.apache.zookeeper.KeeperException;
+import org.apache.zookeeper.ZooKeeper;
+import org.apache.zookeeper.ZooDefs.Ids;
+import org.apache.zookeeper.data.Stat;
+import org.apache.zookeeper.server.jersey.ZooKeeperService;
+import org.apache.zookeeper.server.jersey.jaxb.ZChildren;
+import org.apache.zookeeper.server.jersey.jaxb.ZChildrenJSON;
+import org.apache.zookeeper.server.jersey.jaxb.ZError;
+import org.apache.zookeeper.server.jersey.jaxb.ZPath;
+import org.apache.zookeeper.server.jersey.jaxb.ZStat;
+
+import com.sun.jersey.api.json.JSONWithPadding;
+
+/**
+ * Version 1 implementation of the ZooKeeper REST specification.
+ */
+// TODO test octet fully
+@Path("znodes/v1/{path: .*}")
+public class ZNodeResource {
+    private final ZooKeeper zk;
+
+    public ZNodeResource(@Context UriInfo ui) throws IOException {
+        zk = ZooKeeperService.getClient(ui.getBaseUri().toString());
+    }
+
+    @HEAD
+    @Produces({MediaType.APPLICATION_JSON, "application/javascript",
+        MediaType.APPLICATION_XML, MediaType.APPLICATION_OCTET_STREAM})
+    public void existsZNode(@PathParam("path") String path, @Context UriInfo ui)
+        throws InterruptedException, KeeperException
+    {
+        path = "/" + path;
+        Stat stat = zk.exists(path, false);
+        if (stat == null) {
+            throwNotFound(path, ui);
+        }
+    }
+
+    /*
+     * getZNodeList and getZNodeListJSON are bogus - but necessary.
+     * Unfortunately Jersey 1.0.3 is unable to render both xml and json
+     * properly in the case where a object contains a list/array. It's
+     * impossible to get it to render properly for both. As a result we
+     * need to split into two jaxb classes.
+     */
+
+    @GET
+    @Produces({MediaType.APPLICATION_JSON, "application/javascript"})
+    public Response getZNodeListJSON(@PathParam("path") String path,
+            @QueryParam("callback") String callback,
+            @DefaultValue("data") @QueryParam("view") String view,
+            @DefaultValue("base64") @QueryParam("dataformat") String dataformat,
+            @Context UriInfo ui)
+        throws InterruptedException, KeeperException
+    {
+            return getZNodeList(true, path, callback, view, dataformat, ui);
+    }
+
+    @GET
+    @Produces(MediaType.APPLICATION_XML)
+    public Response getZNodeList(@PathParam("path") String path,
+            @QueryParam("callback") String callback,
+            @DefaultValue("data") @QueryParam("view") String view,
+            @DefaultValue("base64") @QueryParam("dataformat") String dataformat,
+            @Context UriInfo ui)
+        throws InterruptedException, KeeperException
+    {
+        return getZNodeList(false, path, callback, view, dataformat, ui);
+    }
+
+    private Response getZNodeList(boolean json, String path, String callback,
+            String view, String dataformat, UriInfo ui)
+        throws InterruptedException, KeeperException
+    {
+        path = "/" + path;
+        if (view.equals("children")) {
+            List<String> children = new ArrayList<String>();
+            for (String child : zk.getChildren(path, false)) {
+                children.add(child);
+            }
+
+            Object child;
+            String childTemplate = ui.getAbsolutePath().toString();
+            if (!childTemplate.endsWith("/")) {
+                childTemplate += "/";
+            }
+            childTemplate += "{child}";
+            if (json) {
+                child = new ZChildrenJSON(path, ui.getAbsolutePath().toString(),
+                        childTemplate, children);
+            } else {
+                child = new ZChildren(path, ui.getAbsolutePath().toString(),
+                        childTemplate, children);
+            }
+            return Response.status(Response.Status.OK).entity(
+                    new JSONWithPadding(child, callback)).build();
+        } else {
+            Stat stat = new Stat();
+            byte[] data = zk.getData(path, false, stat);
+
+            byte[] data64;
+            String dataUtf8;
+            if (data == null) {
+                data64 = null;
+                dataUtf8 = null;
+            } else if (!dataformat.equals("utf8")){
+                data64 = data;
+                dataUtf8 = null;
+            } else {
+                data64 = null;
+                dataUtf8 = new String(data);
+            }
+            ZStat zstat = new ZStat(path, ui.getAbsolutePath().toString(),
+                    data64, dataUtf8, stat.getCzxid(),
+                    stat.getMzxid(), stat.getCtime(), stat.getMtime(),
+                    stat.getVersion(), stat.getCversion(),
+                    stat.getAversion(), stat.getEphemeralOwner(),
+                    stat.getDataLength(), stat.getNumChildren(),
+                    stat.getPzxid());
+
+            return Response.status(Response.Status.OK).entity(
+                    new JSONWithPadding(zstat, callback)).build();
+        }
+    }
+
+    @GET
+    @Produces(MediaType.APPLICATION_OCTET_STREAM)
+    public Response getZNodeListAsOctet(@PathParam("path") String path)
+        throws InterruptedException, KeeperException
+    {
+        path = "/" + path;
+        Stat stat = new Stat();
+        byte[] data = zk.getData(path, false, stat);
+
+        if (data == null) {
+            return Response.status(Response.Status.NO_CONTENT).build();
+        } else {
+            return Response.status(Response.Status.OK).entity(data).build();
+        }
+    }
+
+    @PUT
+    @Produces({MediaType.APPLICATION_JSON, "application/javascript",
+        MediaType.APPLICATION_XML})
+    @Consumes(MediaType.APPLICATION_OCTET_STREAM)
+    public Response setZNode(@PathParam("path") String path,
+            @QueryParam("callback") String callback,
+            @DefaultValue("-1") @QueryParam("version") String versionParam,
+            @DefaultValue("base64") @QueryParam("dataformat") String dataformat,
+            @DefaultValue("false") @QueryParam("null") String setNull,
+            @Context UriInfo ui,
+            byte[] data)
+        throws InterruptedException, KeeperException
+    {
+        path = "/" + path;
+
+        int version;
+        try {
+            version = Integer.parseInt(versionParam);
+        } catch (NumberFormatException e) {
+            throw new WebApplicationException(Response.status(
+                    Response.Status.BAD_REQUEST).entity(
+                    new ZError(ui.getRequestUri().toString(),
+                            path + " bad version " + versionParam)).build());
+        }
+
+        if (setNull.equals("true")) {
+            data = null;
+        }
+
+        Stat stat = zk.setData(path, data, version);
+
+        ZStat zstat = new ZStat(path, ui.getAbsolutePath().toString(),
+                null, null, stat.getCzxid(),
+                stat.getMzxid(), stat.getCtime(), stat.getMtime(),
+                stat.getVersion(), stat.getCversion(),
+                stat.getAversion(), stat.getEphemeralOwner(),
+                stat.getDataLength(), stat.getNumChildren(),
+                stat.getPzxid());
+
+        return Response.status(Response.Status.OK).entity(
+                new JSONWithPadding(zstat, callback)).build();
+    }
+
+    @PUT
+    @Produces(MediaType.APPLICATION_OCTET_STREAM)
+    @Consumes(MediaType.APPLICATION_OCTET_STREAM)
+    public void setZNodeAsOctet(@PathParam("path") String path,
+            @DefaultValue("-1") @QueryParam("version") String versionParam,
+            @DefaultValue("false") @QueryParam("null") String setNull,
+            @Context UriInfo ui,
+            byte[] data)
+        throws InterruptedException, KeeperException
+    {
+        path = "/" + path;
+
+        int version;
+        try {
+            version = Integer.parseInt(versionParam);
+        } catch (NumberFormatException e) {
+            throw new WebApplicationException(Response.status(
+                    Response.Status.BAD_REQUEST).entity(
+                    new ZError(ui.getRequestUri().toString(),
+                            path + " bad version " + versionParam)).build());
+        }
+
+        if (setNull.equals("true")) {
+            data = null;
+        }
+
+        zk.setData(path, data, version);
+    }
+
+    @POST
+    @Produces({MediaType.APPLICATION_JSON, "application/javascript",
+        MediaType.APPLICATION_XML})
+    @Consumes(MediaType.APPLICATION_OCTET_STREAM)
+    public Response createZNode(@PathParam("path") String path,
+            @QueryParam("callback") String callback,
+            @DefaultValue("create") @QueryParam("op") String op,
+            @QueryParam("name") String name,
+            @DefaultValue("base64") @QueryParam("dataformat") String dataformat,
+            @DefaultValue("false") @QueryParam("null") String setNull,
+            @DefaultValue("false") @QueryParam("sequence") String sequence,
+            @Context UriInfo ui,
+            byte[] data)
+        throws InterruptedException, KeeperException
+    {
+        path = "/" + path + "/" + name;
+
+        if (!op.equals("create")) {
+            throw new WebApplicationException(Response.status(
+                    Response.Status.BAD_REQUEST).entity(
+                    new ZError(ui.getRequestUri().toString(),
+                            path + " bad operaton " + op)).build());
+        }
+
+        if (setNull.equals("true")) {
+            data = null;
+        }
+
+        CreateMode createMode;
+        if (sequence.equals("true")) {
+            createMode = CreateMode.PERSISTENT_SEQUENTIAL;
+        } else {
+            createMode = CreateMode.PERSISTENT;
+        }
+
+        String newPath = zk.create(path, data, Ids.OPEN_ACL_UNSAFE,
+                createMode);
+
+        URI uri = ui.getAbsolutePathBuilder().path(newPath).build();
+
+        return Response.created(uri).entity(
+                new JSONWithPadding(new ZPath(newPath,
+                        ui.getAbsolutePath().toString()))).build();
+    }
+
+    @POST
+    @Produces(MediaType.APPLICATION_OCTET_STREAM)
+    @Consumes(MediaType.APPLICATION_OCTET_STREAM)
+    public Response createZNodeAsOctet(@PathParam("path") String path,
+            @DefaultValue("create") @QueryParam("op") String op,
+            @QueryParam("name") String name,
+            @DefaultValue("false") @QueryParam("null") String setNull,
+            @DefaultValue("false") @QueryParam("sequence") String sequence,
+            @Context UriInfo ui,
+            byte[] data)
+        throws InterruptedException, KeeperException
+    {
+        path = "/" + path + "/" + name;
+
+        if (!op.equals("create")) {
+            throw new WebApplicationException(Response.status(
+                    Response.Status.BAD_REQUEST).entity(
+                    new ZError(ui.getRequestUri().toString(),
+                            path + " bad operaton " + op)).build());
+        }
+
+        if (setNull.equals("true")) {
+            data = null;
+        }
+
+        CreateMode createMode;
+        if (sequence.equals("true")) {
+            createMode = CreateMode.PERSISTENT_SEQUENTIAL;
+        } else {
+            createMode = CreateMode.PERSISTENT;
+        }
+
+        String newPath = zk.create(path, data, Ids.OPEN_ACL_UNSAFE,
+                createMode);
+
+        URI uri = ui.getAbsolutePathBuilder().path(newPath).build();
+
+        return Response.created(uri).entity(new ZPath(newPath,
+                ui.getAbsolutePath().toString())).build();
+    }
+
+    @DELETE
+    @Produces({MediaType.APPLICATION_JSON, "application/javascript",
+        MediaType.APPLICATION_XML, MediaType.APPLICATION_OCTET_STREAM})
+    public void deleteZNode(@PathParam("path") String path,
+            @DefaultValue("-1") @QueryParam("version") String versionParam,
+            @Context UriInfo ui)
+        throws InterruptedException, KeeperException
+    {
+        path = "/" + path;
+
+        int version;
+        try {
+            version = Integer.parseInt(versionParam);
+        } catch (NumberFormatException e) {
+            throw new WebApplicationException(Response.status(
+                    Response.Status.BAD_REQUEST).entity(
+                    new ZError(ui.getRequestUri().toString(),
+                            path + " bad version " + versionParam)).build());
+        }
+
+        zk.delete(path, version);
+    }
+
+    private static void throwNotFound(String path, UriInfo ui)
+        throws WebApplicationException
+    {
+        throw new WebApplicationException(Response.status(
+                Response.Status.NOT_FOUND).entity(
+                new ZError(ui.getRequestUri().toString(),
+                        path + " not found")).build());
+    }
+
+}

Added: hadoop/zookeeper/trunk/src/contrib/rest/src/python/README.txt
URL: http://svn.apache.org/viewvc/hadoop/zookeeper/trunk/src/contrib/rest/src/python/README.txt?rev=772843&view=auto
==============================================================================
--- hadoop/zookeeper/trunk/src/contrib/rest/src/python/README.txt (added)
+++ hadoop/zookeeper/trunk/src/contrib/rest/src/python/README.txt Fri May  8 05:27:00 2009
@@ -0,0 +1,6 @@
+Some basic python scripts which use the REST interface:
+
+zk_dump_tree.py -- dumps the nodes & data of a znode hierarchy
+
+Generally these scripts require:
+  * simplejson

Added: hadoop/zookeeper/trunk/src/contrib/rest/src/python/zk_dump_tree.py
URL: http://svn.apache.org/viewvc/hadoop/zookeeper/trunk/src/contrib/rest/src/python/zk_dump_tree.py?rev=772843&view=auto
==============================================================================
--- hadoop/zookeeper/trunk/src/contrib/rest/src/python/zk_dump_tree.py (added)
+++ hadoop/zookeeper/trunk/src/contrib/rest/src/python/zk_dump_tree.py Fri May  8 05:27:00 2009
@@ -0,0 +1,108 @@
+#!/usr/bin/python
+
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import getopt
+import sys
+import simplejson
+import urllib2
+from base64 import b64decode
+
+printdata = False
+fullpath = False
+
+def dump_node(url, depth):
+    """Dump the node, then dump children recursively
+    
+    Arguments:
+    - `url`:
+    - `depth`:
+    """
+    req = urllib2.urlopen(url)
+    resp = simplejson.load(req)
+    if 'Error' in resp:
+      raise resp['Error']
+
+    if fullpath:
+      name = resp['path']
+    else:
+      name = '/' + resp['path'].split('/')[-1]
+
+    data64 = resp.get('data64')
+    dataUtf8 = resp.get('dataUtf8')
+    if data64 and printdata:
+      data = b64decode(data64)
+      print '%(indent)s%(name)s = b64(%(data64)s) str(%(data)s)' % \
+          {'indent':' '*2*depth, 'name':name, 'data64':data64, 'data':data}
+    elif dataUtf8 and printdata:
+      print '%(indent)s%(name)s = %(data)s' % \
+          {'indent':' '*2*depth, 'name':name, 'data':dataUtf8}
+    else:
+      print '%(indent)s%(name)s' % {'indent':' '*2*depth, 'name':name}
+
+    req = urllib2.urlopen(resp['uri'] + '?view=children')
+    resp = simplejson.load(req)
+
+    for child in resp.get('children', []):
+        dump_node(resp['child_uri_template']
+                  .replace("{child}", urllib2.quote(child)),
+                  depth + 1)
+
+def zk_dump_tree(url, root):
+    """Dump the tree starting at the roota
+    
+    Arguments:
+    - `root`:
+    """
+    dump_node(url + '/znodes/v1' + root, 0)
+
+def usage():
+    """Usage
+    """
+    print 'Usage: zk_dump_tree.py [-h|--help -u|--url=url -d|--data -f|--fullpath -r|--root=root]'
+    print '  where url is the url of the rest server, data is whether to'
+    print '  to include node data on output, root is the znode root'
+    print '  fullpath prints the full node path (useful for copy/paste)'
+
+if __name__ == '__main__':
+    try:
+        opts, args = getopt.getopt(sys.argv[1:],
+            "hu:dfr:", ["help", "url=", "data", "fullpath", "root="])
+    except getopt.GetoptError, err:
+        # print help information and exit:
+        print str(err) # will print something like "option -a not recognized"
+        usage()
+        sys.exit(2)
+    url ='http://localhost:9998'
+    root = '/'
+    for o, a in opts:
+        if o in ("-d", "--data"):
+            printdata = True
+        elif o in ("-h", "--help"):
+            usage()
+            sys.exit()
+        elif o in ("-u", "--url"):
+            url = a
+        elif o in ("-r", "--root"):
+            root = a
+        elif o in ("-f", "--fullpath"):
+            fullpath = True
+        else:
+            assert False, "unhandled option"
+    
+    print 'Accessing REST server at ' + url
+    zk_dump_tree(url, root)

Propchange: hadoop/zookeeper/trunk/src/contrib/rest/src/python/zk_dump_tree.py
------------------------------------------------------------------------------
    svn:executable = *

Added: hadoop/zookeeper/trunk/src/contrib/rest/src/test/org/apache/zookeeper/server/jersey/Base.java
URL: http://svn.apache.org/viewvc/hadoop/zookeeper/trunk/src/contrib/rest/src/test/org/apache/zookeeper/server/jersey/Base.java?rev=772843&view=auto
==============================================================================
--- hadoop/zookeeper/trunk/src/contrib/rest/src/test/org/apache/zookeeper/server/jersey/Base.java (added)
+++ hadoop/zookeeper/trunk/src/contrib/rest/src/test/org/apache/zookeeper/server/jersey/Base.java Fri May  8 05:27:00 2009
@@ -0,0 +1,89 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.zookeeper.server.jersey;
+
+import junit.framework.TestCase;
+
+import org.apache.log4j.Logger;
+import org.apache.zookeeper.CreateMode;
+import org.apache.zookeeper.ZooKeeper;
+import org.apache.zookeeper.ZooDefs.Ids;
+import org.apache.zookeeper.server.jersey.SetTest.MyWatcher;
+import org.junit.After;
+import org.junit.Before;
+
+import com.sun.grizzly.http.SelectorThread;
+import com.sun.jersey.api.client.Client;
+import com.sun.jersey.api.client.WebResource;
+
+
+/**
+ * Test stand-alone server.
+ *
+ */
+public class Base extends TestCase {
+    protected static final Logger LOG = Logger.getLogger(Base.class);
+
+    protected static final String BASEURI = "http://localhost:10104/";
+    protected static final String ZKHOSTPORT = "localhost:22182";
+    protected Client c;
+    protected WebResource r;
+
+    protected ZooKeeper zk;
+
+    private SelectorThread threadSelector;
+
+    @Before
+    public void setUp() throws Exception {
+        super.setUp();
+
+        ZooKeeperService.mapUriBase(BASEURI, ZKHOSTPORT);
+
+        RestMain main = new RestMain(BASEURI);
+        threadSelector = main.execute();
+
+        zk = new ZooKeeper(ZKHOSTPORT, 30000, new MyWatcher());
+
+        c = Client.create();
+        r = c.resource(BASEURI);
+        r = r.path("znodes/v1");
+    }
+
+    @After
+    public void tearDown() throws Exception {
+        super.tearDown();
+
+        c.destroy();
+
+        zk.close();
+        ZooKeeperService.close(BASEURI);
+
+        threadSelector.stopEndpoint();
+    }
+
+    protected static String createBaseZNode() throws Exception {
+        ZooKeeper zk = new ZooKeeper(ZKHOSTPORT, 30000, new MyWatcher());
+
+        String baseZnode = zk.create("/test-", null, Ids.OPEN_ACL_UNSAFE,
+                CreateMode.PERSISTENT_SEQUENTIAL);
+        zk.close();
+
+        return baseZnode;
+    }
+}

Added: hadoop/zookeeper/trunk/src/contrib/rest/src/test/org/apache/zookeeper/server/jersey/CreateTest.java
URL: http://svn.apache.org/viewvc/hadoop/zookeeper/trunk/src/contrib/rest/src/test/org/apache/zookeeper/server/jersey/CreateTest.java?rev=772843&view=auto
==============================================================================
--- hadoop/zookeeper/trunk/src/contrib/rest/src/test/org/apache/zookeeper/server/jersey/CreateTest.java (added)
+++ hadoop/zookeeper/trunk/src/contrib/rest/src/test/org/apache/zookeeper/server/jersey/CreateTest.java Fri May  8 05:27:00 2009
@@ -0,0 +1,163 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.zookeeper.server.jersey;
+
+import java.util.Arrays;
+import java.util.Collection;
+
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+
+import org.apache.log4j.Logger;
+import org.apache.zookeeper.WatchedEvent;
+import org.apache.zookeeper.Watcher;
+import org.apache.zookeeper.data.Stat;
+import org.apache.zookeeper.server.jersey.jaxb.ZPath;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameters;
+
+import com.sun.jersey.api.client.ClientResponse;
+import com.sun.jersey.api.client.WebResource;
+import com.sun.jersey.api.client.WebResource.Builder;
+
+
+/**
+ * Test stand-alone server.
+ *
+ */
+@RunWith(Parameterized.class)
+public class CreateTest extends Base {
+    protected static final Logger LOG = Logger.getLogger(CreateTest.class);
+
+    private String accept;
+    private String path;
+    private String name;
+    private String encoding;
+    private Response.Status expectedStatus;
+    private ZPath expectedPath;
+    private byte[] data;
+    private boolean sequence;
+
+    public static class MyWatcher implements Watcher {
+        public void process(WatchedEvent event) {
+            // FIXME ignore for now
+        }
+    }
+
+    @Parameters
+    public static Collection<Object[]> data() throws Exception {
+        String baseZnode = Base.createBaseZNode();
+
+        return Arrays.asList(new Object[][] {
+          {MediaType.APPLICATION_JSON,
+              baseZnode, "foo bar", "utf8",
+              Response.Status.CREATED,
+              new ZPath(baseZnode + "/foo bar"), null,
+              false },
+          {MediaType.APPLICATION_JSON, baseZnode, "c-t1", "utf8",
+              Response.Status.CREATED, new ZPath(baseZnode + "/c-t1"), null,
+              false },
+          {MediaType.APPLICATION_JSON, baseZnode, "c-t1", "utf8",
+              Response.Status.CONFLICT, null, null, false },
+          {MediaType.APPLICATION_JSON, baseZnode, "c-t2", "utf8",
+              Response.Status.CREATED, new ZPath(baseZnode + "/c-t2"),
+              "".getBytes(), false },
+          {MediaType.APPLICATION_JSON, baseZnode, "c-t2", "utf8",
+              Response.Status.CONFLICT, null, null, false },
+          {MediaType.APPLICATION_JSON, baseZnode, "c-t3", "utf8",
+              Response.Status.CREATED, new ZPath(baseZnode + "/c-t3"),
+              "foo".getBytes(), false },
+          {MediaType.APPLICATION_JSON, baseZnode, "c-t3", "utf8",
+              Response.Status.CONFLICT, null, null, false },
+          {MediaType.APPLICATION_JSON, baseZnode, "c-t4", "base64",
+              Response.Status.CREATED, new ZPath(baseZnode + "/c-t4"),
+              "foo".getBytes(), false },
+          {MediaType.APPLICATION_JSON, baseZnode, "c-", "utf8",
+              Response.Status.CREATED, new ZPath(baseZnode + "/c-"), null,
+              true },
+          {MediaType.APPLICATION_JSON, baseZnode, "c-", "utf8",
+              Response.Status.CREATED, new ZPath(baseZnode + "/c-"), null,
+              true }
+          });
+    }
+
+    public CreateTest(String accept, String path, String name, String encoding,
+            Response.Status status, ZPath expectedPath, byte[] data,
+            boolean sequence)
+    {
+        this.accept = accept;
+        this.path = path;
+        this.name = name;
+        this.encoding = encoding;
+        this.expectedStatus = status;
+        this.expectedPath = expectedPath;
+        this.data = data;
+        this.sequence = sequence;
+    }
+
+    @Test
+    public void testCreate() throws Exception {
+        LOG.info("STARTING " + getName());
+
+        WebResource wr = r.path(path).queryParam("dataformat", encoding)
+            .queryParam("name", name);
+        if (data == null) {
+            wr = wr.queryParam("null", "true");
+        }
+        if (sequence) {
+            wr = wr.queryParam("sequence", "true");
+        }
+
+        Builder builder = wr.accept(accept);
+
+        ClientResponse cr;
+        if (data == null) {
+            cr = builder.post(ClientResponse.class);
+        } else {
+            cr = builder.post(ClientResponse.class, data);
+        }
+        assertEquals(expectedStatus, cr.getResponseStatus());
+
+        if (expectedPath == null) {
+            return;
+        }
+
+        ZPath zpath = cr.getEntity(ZPath.class);
+        if (sequence) {
+            assertTrue(zpath.path.startsWith(expectedPath.path));
+            assertTrue(zpath.uri.startsWith(r.path(path).toString()));
+        } else {
+            assertEquals(expectedPath, zpath);
+            assertEquals(r.path(path).toString(), zpath.uri);
+        }
+
+        // use out-of-band method to verify
+        byte[] data = zk.getData(zpath.path, false, new Stat());
+        if (data == null && this.data == null) {
+            return;
+        } else if (data == null || this.data == null) {
+            assertEquals(data, this.data);
+        } else {
+            assertTrue(new String(data) + " == " + new String(this.data),
+                    Arrays.equals(data, this.data));
+        }
+    }
+}

Added: hadoop/zookeeper/trunk/src/contrib/rest/src/test/org/apache/zookeeper/server/jersey/DeleteTest.java
URL: http://svn.apache.org/viewvc/hadoop/zookeeper/trunk/src/contrib/rest/src/test/org/apache/zookeeper/server/jersey/DeleteTest.java?rev=772843&view=auto
==============================================================================
--- hadoop/zookeeper/trunk/src/contrib/rest/src/test/org/apache/zookeeper/server/jersey/DeleteTest.java (added)
+++ hadoop/zookeeper/trunk/src/contrib/rest/src/test/org/apache/zookeeper/server/jersey/DeleteTest.java Fri May  8 05:27:00 2009
@@ -0,0 +1,95 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.zookeeper.server.jersey;
+
+import java.util.Arrays;
+import java.util.Collection;
+
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+
+import org.apache.log4j.Logger;
+import org.apache.zookeeper.CreateMode;
+import org.apache.zookeeper.WatchedEvent;
+import org.apache.zookeeper.Watcher;
+import org.apache.zookeeper.ZooDefs.Ids;
+import org.apache.zookeeper.data.Stat;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameters;
+
+import com.sun.jersey.api.client.ClientResponse;
+
+
+/**
+ * Test stand-alone server.
+ *
+ */
+@RunWith(Parameterized.class)
+public class DeleteTest extends Base {
+    protected static final Logger LOG = Logger.getLogger(DeleteTest.class);
+
+    private String zpath;
+    private Response.Status expectedStatus;
+
+    public static class MyWatcher implements Watcher {
+        public void process(WatchedEvent event) {
+            // FIXME ignore for now
+        }
+    }
+
+    @Parameters
+    public static Collection<Object[]> data() throws Exception {
+        String baseZnode = Base.createBaseZNode();
+
+        return Arrays.asList(new Object[][] {
+          {baseZnode, baseZnode, Response.Status.NO_CONTENT },
+          {baseZnode, baseZnode, Response.Status.NO_CONTENT }
+        });
+    }
+
+    public DeleteTest(String path, String zpath, Response.Status status) {
+        this.zpath = zpath;
+        this.expectedStatus = status;
+    }
+
+    public void verify(String type) throws Exception {
+        if (expectedStatus != Response.Status.NOT_FOUND) {
+            zpath = zk.create(zpath, null, Ids.OPEN_ACL_UNSAFE,
+                    CreateMode.PERSISTENT_SEQUENTIAL);
+        }
+
+        ClientResponse cr = r.path(zpath).accept(type).type(type)
+            .delete(ClientResponse.class);
+        assertEquals(expectedStatus, cr.getResponseStatus());
+
+        // use out-of-band method to verify
+        Stat stat = zk.exists(zpath, false);
+        assertNull(stat);
+    }
+
+    @Test
+    public void testDelete() throws Exception {
+        LOG.info("STARTING " + getName());
+        verify(MediaType.APPLICATION_OCTET_STREAM);
+        verify(MediaType.APPLICATION_JSON);
+        verify(MediaType.APPLICATION_XML);
+    }
+}

Added: hadoop/zookeeper/trunk/src/contrib/rest/src/test/org/apache/zookeeper/server/jersey/ExistsTest.java
URL: http://svn.apache.org/viewvc/hadoop/zookeeper/trunk/src/contrib/rest/src/test/org/apache/zookeeper/server/jersey/ExistsTest.java?rev=772843&view=auto
==============================================================================
--- hadoop/zookeeper/trunk/src/contrib/rest/src/test/org/apache/zookeeper/server/jersey/ExistsTest.java (added)
+++ hadoop/zookeeper/trunk/src/contrib/rest/src/test/org/apache/zookeeper/server/jersey/ExistsTest.java Fri May  8 05:27:00 2009
@@ -0,0 +1,79 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.zookeeper.server.jersey;
+
+import java.util.Arrays;
+import java.util.Collection;
+
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+
+import org.apache.log4j.Logger;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameters;
+
+import com.sun.jersey.api.client.ClientResponse;
+
+
+/**
+ * Test stand-alone server.
+ *
+ */
+@RunWith(Parameterized.class)
+public class ExistsTest extends Base {
+    protected static final Logger LOG = Logger.getLogger(ExistsTest.class);
+
+    private String path;
+    private Response.Status expectedStatus;
+
+    @Parameters
+    public static Collection<Object[]> data() throws Exception {
+        String baseZnode = Base.createBaseZNode();
+
+     return Arrays.asList(new Object[][] {
+      {baseZnode, Response.Status.OK },
+      {baseZnode + "dkdk38383", Response.Status.NOT_FOUND }
+     });
+    }
+
+    public ExistsTest(String path, Response.Status status) {
+        this.path = path;
+        this.expectedStatus = status;
+    }
+
+    private void verify(String type) {
+        ClientResponse cr = r.path(path).accept(type).type(type).head();
+        if (type.equals(MediaType.APPLICATION_OCTET_STREAM)
+                && expectedStatus == Response.Status.OK) {
+            assertEquals(Response.Status.NO_CONTENT, cr.getResponseStatus());
+        } else {
+            assertEquals(expectedStatus, cr.getResponseStatus());
+        }
+    }
+
+    @Test
+    public void testExists() throws Exception {
+        LOG.info("STARTING " + getName());
+        verify(MediaType.APPLICATION_OCTET_STREAM);
+        verify(MediaType.APPLICATION_JSON);
+        verify(MediaType.APPLICATION_XML);
+    }
+}

Added: hadoop/zookeeper/trunk/src/contrib/rest/src/test/org/apache/zookeeper/server/jersey/GetChildrenTest.java
URL: http://svn.apache.org/viewvc/hadoop/zookeeper/trunk/src/contrib/rest/src/test/org/apache/zookeeper/server/jersey/GetChildrenTest.java?rev=772843&view=auto
==============================================================================
--- hadoop/zookeeper/trunk/src/contrib/rest/src/test/org/apache/zookeeper/server/jersey/GetChildrenTest.java (added)
+++ hadoop/zookeeper/trunk/src/contrib/rest/src/test/org/apache/zookeeper/server/jersey/GetChildrenTest.java Fri May  8 05:27:00 2009
@@ -0,0 +1,139 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.zookeeper.server.jersey;
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+
+import org.apache.log4j.Logger;
+import org.apache.zookeeper.CreateMode;
+import org.apache.zookeeper.ZooDefs.Ids;
+import org.apache.zookeeper.server.jersey.jaxb.ZChildren;
+import org.apache.zookeeper.server.jersey.jaxb.ZChildrenJSON;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameters;
+
+import com.sun.jersey.api.client.ClientResponse;
+
+
+/**
+ * Test stand-alone server.
+ *
+ */
+@RunWith(Parameterized.class)
+public class GetChildrenTest extends Base {
+    protected static final Logger LOG = Logger.getLogger(GetChildrenTest.class);
+
+    private String accept;
+    private String path;
+    private Response.Status expectedStatus;
+    private String expectedPath;
+    private List<String> expectedChildren;
+
+    @Parameters
+    public static Collection<Object[]> data() throws Exception {
+        String baseZnode = Base.createBaseZNode();
+        String baseZnode2 = Base.createBaseZNode();
+        String baseZnode3 = Base.createBaseZNode();
+        String baseZnode4 = Base.createBaseZNode();
+        String baseZnode5 = Base.createBaseZNode();
+        String baseZnode6 = Base.createBaseZNode();
+
+        return Arrays.asList(new Object[][] {
+          {MediaType.APPLICATION_JSON, baseZnode + "abddkdkd",
+              Response.Status.NOT_FOUND, null, null },
+          {MediaType.APPLICATION_XML, baseZnode + "abddkdkd",
+              Response.Status.NOT_FOUND, null, null },
+          {MediaType.APPLICATION_JSON, baseZnode, Response.Status.OK,
+              baseZnode, Arrays.asList(new String[] {}) },
+          {MediaType.APPLICATION_XML, baseZnode, Response.Status.OK,
+              baseZnode, Arrays.asList(new String[] {}) },
+          {MediaType.APPLICATION_JSON, baseZnode, Response.Status.OK,
+              baseZnode, Arrays.asList(new String[] {"c1"}) },
+          {MediaType.APPLICATION_XML, baseZnode4, Response.Status.OK,
+              baseZnode4, Arrays.asList(new String[] {"c1"}) },
+          {MediaType.APPLICATION_JSON, baseZnode2, Response.Status.OK,
+              baseZnode2, Arrays.asList(new String[] {"c1", "c2"}) },
+          {MediaType.APPLICATION_XML, baseZnode5, Response.Status.OK,
+              baseZnode5, Arrays.asList(new String[] {"c1", "c2"}) },
+          {MediaType.APPLICATION_JSON, baseZnode3, Response.Status.OK,
+              baseZnode3, Arrays.asList(new String[] {"c1", "c2", "c3", "c4"}) },
+          {MediaType.APPLICATION_XML, baseZnode6, Response.Status.OK,
+              baseZnode6, Arrays.asList(new String[] {"c1", "c2", "c3", "c4"}) }
+
+          });
+    }
+
+    public GetChildrenTest(String accept, String path, Response.Status status,
+            String expectedPath, List<String> expectedChildren)
+    {
+        this.accept = accept;
+        this.path = path;
+        this.expectedStatus = status;
+        this.expectedPath = expectedPath;
+        this.expectedChildren = expectedChildren;
+    }
+
+    @Test
+    public void testGetChildren() throws Exception {
+        LOG.info("STARTING " + getName());
+
+        if (expectedChildren != null) {
+            for(String child : expectedChildren) {
+                zk.create(expectedPath + "/" + child, null,
+                        Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
+            }
+        }
+
+        ClientResponse cr = r.path(path).queryParam("view", "children")
+            .accept(accept).get(ClientResponse.class);
+        assertEquals(expectedStatus, cr.getResponseStatus());
+
+        if (expectedChildren == null) {
+            return;
+        }
+
+        if (accept.equals(MediaType.APPLICATION_JSON)) {
+            ZChildrenJSON zchildren = cr.getEntity(ZChildrenJSON.class);
+            Collections.sort(expectedChildren);
+            Collections.sort(zchildren.children);
+            assertEquals(expectedChildren, zchildren.children);
+            assertEquals(r.path(path).toString(), zchildren.uri);
+            assertEquals(r.path(path).toString() + "/{child}",
+                    zchildren.child_uri_template);
+        } else if (accept.equals(MediaType.APPLICATION_XML)) {
+            ZChildren zchildren = cr.getEntity(ZChildren.class);
+            Collections.sort(expectedChildren);
+            Collections.sort(zchildren.children);
+            assertEquals(expectedChildren, zchildren.children);
+            assertEquals(r.path(path).toString(), zchildren.uri);
+            assertEquals(r.path(path).toString() + "/{child}",
+                    zchildren.child_uri_template);
+        } else {
+            fail("unknown accept type");
+        }
+    }
+}

Added: hadoop/zookeeper/trunk/src/contrib/rest/src/test/org/apache/zookeeper/server/jersey/GetTest.java
URL: http://svn.apache.org/viewvc/hadoop/zookeeper/trunk/src/contrib/rest/src/test/org/apache/zookeeper/server/jersey/GetTest.java?rev=772843&view=auto
==============================================================================
--- hadoop/zookeeper/trunk/src/contrib/rest/src/test/org/apache/zookeeper/server/jersey/GetTest.java (added)
+++ hadoop/zookeeper/trunk/src/contrib/rest/src/test/org/apache/zookeeper/server/jersey/GetTest.java Fri May  8 05:27:00 2009
@@ -0,0 +1,123 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.zookeeper.server.jersey;
+
+import java.util.Arrays;
+import java.util.Collection;
+
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+
+import org.apache.log4j.Logger;
+import org.apache.zookeeper.server.jersey.jaxb.ZStat;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameters;
+
+import com.sun.jersey.api.client.ClientResponse;
+
+
+/**
+ * Test stand-alone server.
+ *
+ */
+@RunWith(Parameterized.class)
+public class GetTest extends Base {
+    protected static final Logger LOG = Logger.getLogger(GetTest.class);
+
+    private String accept;
+    private String path;
+    private String encoding;
+    private Response.Status expectedStatus;
+    private ZStat expectedStat;
+
+    @Parameters
+    public static Collection<Object[]> data() throws Exception {
+        String baseZnode = Base.createBaseZNode();
+
+     return Arrays.asList(new Object[][] {
+      {MediaType.APPLICATION_JSON, baseZnode, "utf8",
+          Response.Status.OK, new ZStat(baseZnode, null, null) },
+      {MediaType.APPLICATION_JSON, baseZnode, "utf8",
+          Response.Status.OK, new ZStat(baseZnode, null, "") },
+      {MediaType.APPLICATION_JSON, baseZnode, "utf8",
+          Response.Status.OK, new ZStat(baseZnode, null, "foo") },
+      {MediaType.APPLICATION_JSON, baseZnode, "base64",
+          Response.Status.OK, new ZStat(baseZnode, null, null) },
+      {MediaType.APPLICATION_JSON, baseZnode, "base64",
+          Response.Status.OK, new ZStat(baseZnode, "".getBytes(), null) },
+      {MediaType.APPLICATION_JSON, baseZnode, "base64",
+          Response.Status.OK, new ZStat(baseZnode, "".getBytes(), null) },
+      {MediaType.APPLICATION_JSON, baseZnode, "base64",
+              Response.Status.OK, new ZStat(baseZnode, "foo".getBytes(), null) },
+      {MediaType.APPLICATION_JSON, baseZnode + "abaddkdk", "utf8",
+                      Response.Status.NOT_FOUND, null },
+      {MediaType.APPLICATION_JSON, baseZnode + "abaddkdk", "base64",
+              Response.Status.NOT_FOUND, null },
+
+      {MediaType.APPLICATION_XML, baseZnode, "utf8",
+                  Response.Status.OK, new ZStat(baseZnode, null, "foo") },
+      {MediaType.APPLICATION_XML, baseZnode, "base64",
+                      Response.Status.OK,
+                      new ZStat(baseZnode, "foo".getBytes(), null) },
+      {MediaType.APPLICATION_XML, baseZnode + "abaddkdk", "utf8",
+                      Response.Status.NOT_FOUND, null },
+      {MediaType.APPLICATION_XML, baseZnode + "abaddkdk", "base64",
+              Response.Status.NOT_FOUND, null }
+
+     });
+    }
+
+    public GetTest(String accept, String path, String encoding,
+            Response.Status status, ZStat stat)
+    {
+        this.accept = accept;
+        this.path = path;
+        this.encoding = encoding;
+        this.expectedStatus = status;
+        this.expectedStat = stat;
+    }
+
+    @Test
+    public void testGet() throws Exception {
+        LOG.info("STARTING " + getName());
+
+        if (expectedStat != null) {
+            if (expectedStat.data64 != null || expectedStat.dataUtf8 == null) {
+                zk.setData(expectedStat.path, expectedStat.data64, -1);
+            } else {
+                zk.setData(expectedStat.path,
+                        expectedStat.dataUtf8.getBytes(), -1);
+            }
+        }
+
+        ClientResponse cr = r.path(path).queryParam("dataformat", encoding)
+            .accept(accept).get(ClientResponse.class);
+        assertEquals(expectedStatus, cr.getResponseStatus());
+
+        if (expectedStat == null) {
+            return;
+        }
+
+        ZStat zstat = cr.getEntity(ZStat.class);
+        assertEquals(expectedStat, zstat);
+        assertEquals(r.path(path).toString(), zstat.uri);
+    }
+}

Added: hadoop/zookeeper/trunk/src/contrib/rest/src/test/org/apache/zookeeper/server/jersey/RestTestSuite.java
URL: http://svn.apache.org/viewvc/hadoop/zookeeper/trunk/src/contrib/rest/src/test/org/apache/zookeeper/server/jersey/RestTestSuite.java?rev=772843&view=auto
==============================================================================
--- hadoop/zookeeper/trunk/src/contrib/rest/src/test/org/apache/zookeeper/server/jersey/RestTestSuite.java (added)
+++ hadoop/zookeeper/trunk/src/contrib/rest/src/test/org/apache/zookeeper/server/jersey/RestTestSuite.java Fri May  8 05:27:00 2009
@@ -0,0 +1,42 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.zookeeper.server.jersey;
+
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.runner.RunWith;
+import org.junit.runners.Suite;
+import org.junit.runners.Suite.SuiteClasses;
+
+@RunWith(Suite.class)
+@SuiteClasses({WadlTest.class, GetTest.class, GetChildrenTest.class,
+    CreateTest.class, SetTest.class, ExistsTest.class, DeleteTest.class })
+public class RestTestSuite {
+
+    @BeforeClass
+    public static void setUp() {
+        // suite setup
+    }
+
+    @AfterClass
+    public static void tearDown() {
+        // suite setup
+    }
+
+}

Added: hadoop/zookeeper/trunk/src/contrib/rest/src/test/org/apache/zookeeper/server/jersey/SetTest.java
URL: http://svn.apache.org/viewvc/hadoop/zookeeper/trunk/src/contrib/rest/src/test/org/apache/zookeeper/server/jersey/SetTest.java?rev=772843&view=auto
==============================================================================
--- hadoop/zookeeper/trunk/src/contrib/rest/src/test/org/apache/zookeeper/server/jersey/SetTest.java (added)
+++ hadoop/zookeeper/trunk/src/contrib/rest/src/test/org/apache/zookeeper/server/jersey/SetTest.java Fri May  8 05:27:00 2009
@@ -0,0 +1,155 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.zookeeper.server.jersey;
+
+import java.util.Arrays;
+import java.util.Collection;
+
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+
+import org.apache.log4j.Logger;
+import org.apache.zookeeper.CreateMode;
+import org.apache.zookeeper.WatchedEvent;
+import org.apache.zookeeper.Watcher;
+import org.apache.zookeeper.ZooDefs.Ids;
+import org.apache.zookeeper.data.Stat;
+import org.apache.zookeeper.server.jersey.jaxb.ZStat;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameters;
+
+import com.sun.jersey.api.client.ClientResponse;
+import com.sun.jersey.api.client.WebResource;
+import com.sun.jersey.api.client.WebResource.Builder;
+
+
+/**
+ * Test stand-alone server.
+ *
+ */
+@RunWith(Parameterized.class)
+public class SetTest extends Base {
+    protected static final Logger LOG = Logger.getLogger(SetTest.class);
+
+    private String accept;
+    private String path;
+    private String encoding;
+    private Response.Status expectedStatus;
+    private ZStat expectedStat;
+    private byte[] data;
+
+    public static class MyWatcher implements Watcher {
+        public void process(WatchedEvent event) {
+            // FIXME ignore for now
+        }
+    }
+
+    @Parameters
+    public static Collection<Object[]> data() throws Exception {
+        String baseZnode = Base.createBaseZNode();
+
+        return Arrays.asList(new Object[][] {
+          {MediaType.APPLICATION_JSON, baseZnode + "/s-t1", "utf8",
+              Response.Status.OK,
+              new ZStat(baseZnode + "/s-t1", null, null), null },
+          {MediaType.APPLICATION_JSON, baseZnode + "/s-t2", "utf8",
+              Response.Status.OK,
+              new ZStat(baseZnode + "/s-t2", null, null), new byte[0] },
+          {MediaType.APPLICATION_JSON, baseZnode + "/s-t3", "utf8",
+              Response.Status.OK,
+              new ZStat(baseZnode + "/s-t3", null, null), "foobar".getBytes() },
+          {MediaType.APPLICATION_JSON, baseZnode + "/s-t4", "base64",
+              Response.Status.OK,
+              new ZStat(baseZnode + "/s-t4", null, null), null },
+          {MediaType.APPLICATION_JSON, baseZnode + "/s-t5", "base64",
+              Response.Status.OK,
+              new ZStat(baseZnode + "/s-t5", null, null), new byte[0] },
+          {MediaType.APPLICATION_JSON, baseZnode + "/s-t6", "base64",
+              Response.Status.OK,
+              new ZStat(baseZnode + "/s-t6", null, null),
+              "foobar".getBytes() },
+          {MediaType.APPLICATION_JSON, baseZnode + "/dkdkdkd", "utf8",
+              Response.Status.NOT_FOUND, null, null },
+          {MediaType.APPLICATION_JSON, baseZnode + "/dkdkdkd", "base64",
+              Response.Status.NOT_FOUND, null, null },
+          });
+    }
+
+    public SetTest(String accept, String path, String encoding,
+            Response.Status status, ZStat expectedStat, byte[] data)
+    {
+        this.accept = accept;
+        this.path = path;
+        this.encoding = encoding;
+        this.expectedStatus = status;
+        this.expectedStat = expectedStat;
+        this.data = data;
+    }
+
+    @Test
+    public void testSet() throws Exception {
+        LOG.info("STARTING " + getName());
+
+        if (expectedStat != null) {
+            zk.create(expectedStat.path, "initial".getBytes(), Ids.OPEN_ACL_UNSAFE,
+                    CreateMode.PERSISTENT);
+        }
+
+        WebResource wr = r.path(path).queryParam("dataformat", encoding);
+        if (data == null) {
+            wr = wr.queryParam("null", "true");
+        }
+
+        Builder builder = wr.accept(accept)
+            .type(MediaType.APPLICATION_OCTET_STREAM);
+
+        ClientResponse cr;
+        if (data == null) {
+            cr = builder.put(ClientResponse.class);
+        } else {
+            // this shouldn't be necessary (wrapping data with string)
+            // but without it there are problems on the server - ie it
+            // hangs for 30 seconds and doesn't get the data.
+            // TODO investigate
+            cr = builder.put(ClientResponse.class, new String(data));
+        }
+        assertEquals(expectedStatus, cr.getResponseStatus());
+
+        if (expectedStat == null) {
+            return;
+        }
+
+        ZStat zstat = cr.getEntity(ZStat.class);
+        assertEquals(expectedStat, zstat);
+
+        // use out-of-band method to verify
+        byte[] data = zk.getData(zstat.path, false, new Stat());
+        if (data == null && this.data == null) {
+            return;
+        } else if (data == null || this.data == null) {
+            fail((data == null ? null : new String(data)) + " == "
+                    + (this.data == null ? null : new String(this.data)));
+        } else {
+            assertTrue(new String(data) + " == " + new String(this.data),
+                    Arrays.equals(data, this.data));
+        }
+    }
+}

Added: hadoop/zookeeper/trunk/src/contrib/rest/src/test/org/apache/zookeeper/server/jersey/WadlTest.java
URL: http://svn.apache.org/viewvc/hadoop/zookeeper/trunk/src/contrib/rest/src/test/org/apache/zookeeper/server/jersey/WadlTest.java?rev=772843&view=auto
==============================================================================
--- hadoop/zookeeper/trunk/src/contrib/rest/src/test/org/apache/zookeeper/server/jersey/WadlTest.java (added)
+++ hadoop/zookeeper/trunk/src/contrib/rest/src/test/org/apache/zookeeper/server/jersey/WadlTest.java Fri May  8 05:27:00 2009
@@ -0,0 +1,43 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.zookeeper.server.jersey;
+
+import org.apache.log4j.Logger;
+import org.junit.Test;
+
+import com.sun.jersey.api.client.WebResource;
+import com.sun.jersey.core.header.MediaTypes;
+
+
+/**
+ * Test stand-alone server.
+ *
+ */
+public class WadlTest extends Base {
+    protected static final Logger LOG = Logger.getLogger(WadlTest.class);
+
+    @Test
+    public void testApplicationWadl() {
+        WebResource r = c.resource(BASEURI);
+        String serviceWadl = r.path("application.wadl").
+                accept(MediaTypes.WADL).get(String.class);
+        assertTrue("Something wrong. Returned wadl length not > 0.",
+                serviceWadl.length() > 0);
+    }
+}

Added: hadoop/zookeeper/trunk/src/contrib/rest/src/test/zkServer.sh
URL: http://svn.apache.org/viewvc/hadoop/zookeeper/trunk/src/contrib/rest/src/test/zkServer.sh?rev=772843&view=auto
==============================================================================
--- hadoop/zookeeper/trunk/src/contrib/rest/src/test/zkServer.sh (added)
+++ hadoop/zookeeper/trunk/src/contrib/rest/src/test/zkServer.sh Fri May  8 05:27:00 2009
@@ -0,0 +1,57 @@
+#!/bin/bash
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+if [ "x$1" == "x" ]
+then
+    echo "USAGE: $0 startClean|start|stop hostPorts"
+    exit 2
+fi
+
+if [ "x$1" == "xstartClean" ]
+then
+    if [ "x${base_dir}" == "x" ]
+    then
+    rm -rf /tmp/zkdata
+    else
+    rm -rf ${base_dir}/build/tmp
+    fi
+fi
+
+# Make sure nothing is left over from before
+fuser -skn tcp 22182/tcp
+
+case $1 in
+start|startClean)
+    if [ "x${base_dir}" == "x" ]
+        then
+        mkdir -p /tmp/zkdata
+        java -cp ../../../zookeeper-dev.jar:../../../src/java/lib/log4j-1.2.15.jar:../../../conf org.apache.zookeeper.server.ZooKeeperServerMain 22182 /tmp/zkdata &> /tmp/zk.log &
+        else
+        mkdir -p ${base_dir}/build/tmp/zkdata
+        java -cp ${base_dir}/zookeeper-dev.jar:${base_dir}/src/java/lib/log4j-1.2.15.jar:${base_dir}/conf org.apache.zookeeper.server.ZooKeeperServerMain 22182 ${base_dir}/build/tmp/zkdata &> ${base_dir}/build/tmp/zk.log &
+    fi
+        sleep 5
+    ;;
+stop)
+    # Already killed above
+    ;;
+*)
+    echo "Unknown command " + $1
+    exit 2
+esac
+

Propchange: hadoop/zookeeper/trunk/src/contrib/rest/src/test/zkServer.sh
------------------------------------------------------------------------------
    svn:executable = *



Mime
View raw message