[ARVADOS] updated: 2e5fef753892523984f18c26fc16cfd599115f34

git at public.curoverse.com git at public.curoverse.com
Tue Apr 29 00:47:33 EDT 2014


Summary of changes:
 sdk/java/pom.xml                                   |   92 +++++
 .../main/java/org/arvados/sdk/java/Arvados.java    |  388 ++++++++++++++++++++
 .../java/org/arvados/sdk/java/MethodDetails.java   |   22 ++
 .../java/org/arvados/sdk/java/ArvadosTest.java     |  173 +++++++++
 .../controllers/arvados/v1/schema_controller.rb    |   11 +-
 5 files changed, 682 insertions(+), 4 deletions(-)
 create mode 100644 sdk/java/pom.xml
 create mode 100644 sdk/java/src/main/java/org/arvados/sdk/java/Arvados.java
 create mode 100644 sdk/java/src/main/java/org/arvados/sdk/java/MethodDetails.java
 create mode 100644 sdk/java/src/test/java/org/arvados/sdk/java/ArvadosTest.java

       via  2e5fef753892523984f18c26fc16cfd599115f34 (commit)
      from  03e570095885982d23e234bce8e1c068314b63af (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.


commit 2e5fef753892523984f18c26fc16cfd599115f34
Author: radhika <radhika at radhika>
Date:   Tue Apr 29 00:46:14 2014 -0400

    2525 - Arvados Java SDK. API discovery and call methods working. Need logging, further cleanup, and more testing.

diff --git a/sdk/java/pom.xml b/sdk/java/pom.xml
new file mode 100644
index 0000000..b174154
--- /dev/null
+++ b/sdk/java/pom.xml
@@ -0,0 +1,92 @@
+<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/maven-v4_0_0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+  <groupId>org.arvados.sdk.java</groupId>
+  <artifactId>java</artifactId>
+  <packaging>jar</packaging>
+  <version>1.0-SNAPSHOT</version>
+  <name>java</name>
+  <url>http://maven.apache.org</url>
+  
+  <dependencies>
+    <dependency>
+    	<groupId>com.google.apis</groupId>
+    	<artifactId>google-api-services-discovery</artifactId>
+    	<version>v1-rev42-1.18.0-rc</version>
+    </dependency>
+    <dependency>
+      <groupId>com.google.api-client</groupId>
+      <artifactId>google-api-client</artifactId>
+      <version>1.18.0-rc</version>
+    </dependency>
+    <dependency>
+    	<groupId>com.google.http-client</groupId>
+    	<artifactId>google-http-client-jackson2</artifactId>
+    	<version>1.18.0-rc</version>
+    </dependency>
+    <dependency>
+      <groupId>com.google.oauth-client</groupId>
+      <artifactId>google-oauth-client-jetty</artifactId>
+      <version>1.18.0-rc</version>
+    </dependency>
+    <dependency>
+    	<groupId>com.google.guava</groupId>
+    	<artifactId>guava</artifactId>
+    	<version>r05</version>
+    </dependency>
+    
+    <dependency>
+      <groupId>junit</groupId>
+      <artifactId>junit</artifactId>
+      <version>3.8.1</version>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+        <groupId>com.googlecode.json-simple</groupId>
+        <artifactId>json-simple</artifactId>
+        <version>1.1.1</version>
+	</dependency>
+  </dependencies>
+
+  <build>
+    <plugins>
+       <plugin>
+          <groupId>org.apache.maven.plugins</groupId>
+          <artifactId>maven-compiler-plugin</artifactId>
+          <version>3.1</version>
+          <configuration>
+            <source>1.6</source>
+            <target>1.6</target>
+          </configuration>
+       </plugin>
+        <plugin>
+          <groupId>org.apache.maven.plugins</groupId>
+          <artifactId>maven-assembly-plugin</artifactId>
+          <executions>
+            <execution>
+              <goals>
+                <goal>attached</goal>
+              </goals>
+              <phase>package</phase>
+              <configuration>
+                <descriptorRefs>
+                  <descriptorRef>jar-with-dependencies</descriptorRef>
+                </descriptorRefs>
+                <archive>
+                  <manifest>
+                    <mainClass>org.arvados.sdk.Arvados</mainClass>
+                  </manifest>
+                  <manifestEntries>
+                    <!--<Premain-Class>Your.agent.class</Premain-Class>
+                    <Agent-Class>Your.agent.class</Agent-Class>-->
+                    <Can-Redefine-Classes>true</Can-Redefine-Classes>
+                    <Can-Retransform-Classes>true</Can-Retransform-Classes>
+                  </manifestEntries>
+                </archive>
+              </configuration>
+            </execution>
+          </executions>
+        </plugin>
+      </plugins>
+    </build>
+</project>
diff --git a/sdk/java/src/main/java/org/arvados/sdk/java/Arvados.java b/sdk/java/src/main/java/org/arvados/sdk/java/Arvados.java
new file mode 100644
index 0000000..cc8a198
--- /dev/null
+++ b/sdk/java/src/main/java/org/arvados/sdk/java/Arvados.java
@@ -0,0 +1,388 @@
+package org.arvados.sdk.java;
+
+import com.google.api.client.http.javanet.*;
+import com.google.api.client.http.FileContent;
+import com.google.api.client.http.GenericUrl;
+import com.google.api.client.http.HttpContent;
+import com.google.api.client.http.HttpRequest;
+import com.google.api.client.http.HttpRequestFactory;
+import com.google.api.client.http.HttpTransport;
+import com.google.api.client.http.UriTemplate;
+import com.google.api.client.json.JsonFactory;
+import com.google.api.client.json.jackson2.JacksonFactory;
+import com.google.api.client.util.Lists;
+import com.google.api.client.util.Maps;
+import com.google.api.services.discovery.Discovery;
+import com.google.api.services.discovery.model.JsonSchema;
+import com.google.api.services.discovery.model.RestDescription;
+import com.google.api.services.discovery.model.RestMethod;
+import com.google.api.services.discovery.model.RestResource;
+
+import java.io.File;
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+public class Arvados {
+  private static HttpTransport HTTP_TRANSPORT;
+  private static final JsonFactory JSON_FACTORY = JacksonFactory.getDefaultInstance();
+  private static Discovery DISCOVERY_CLIENT;
+
+  private static final Pattern METHOD_PATTERN = Pattern.compile("((\\w+)\\.)*(\\w+)");
+
+  private static final String APP_NAME = "arvados";
+
+  private static String ARVADOS_API_TOKEN;
+  private static String ARVADOS_API_HOST;
+  private static String ARVADOS_API_HOST_INSECURE;
+
+  private static String ARVADOS_ROOT_URL;
+
+  static {
+    try {
+      // Read needed environmental variables
+      ARVADOS_API_TOKEN = System.getenv().get("ARVADOS_API_TOKEN");
+      if (ARVADOS_API_TOKEN == null) {
+        throw new Exception("Missing environment variable: ARVADOS_API_TOKEN");
+      }
+
+      ARVADOS_API_HOST = System.getenv().get("ARVADOS_API_HOST");      
+      if (ARVADOS_API_HOST == null) {
+        throw new Exception("Missing environment variable: ARVADOS_API_HOST");
+      }
+
+      ARVADOS_ROOT_URL = "https://" + ARVADOS_API_HOST;
+      ARVADOS_ROOT_URL += (ARVADOS_API_HOST.endsWith("/")) ? "" : "/";
+
+      ARVADOS_API_HOST_INSECURE = System.getenv().get("ARVADOS_API_HOST_INSECURE");
+      if (ARVADOS_API_HOST_INSECURE == null) {
+        throw new Exception("Missing environment variable: ARVADOS_API_HOST_INSECURE");
+      }
+
+      // Create HTTP_TRANSPORT object
+      NetHttpTransport.Builder builder = new NetHttpTransport.Builder();
+      builder.doNotValidateCertificate();
+      HTTP_TRANSPORT = builder.build();
+
+      // Create DISCOVERY_CLIENT object
+      Discovery.Builder discoveryBuilder = new Discovery.Builder(HTTP_TRANSPORT, JSON_FACTORY, null);
+
+      discoveryBuilder.setRootUrl(ARVADOS_ROOT_URL);
+      discoveryBuilder.setApplicationName(APP_NAME);
+      DISCOVERY_CLIENT = discoveryBuilder.build();
+    } catch (Throwable t) {
+      t.printStackTrace();
+      System.exit(1);
+    }
+  }
+
+  public static void main(String[] args) throws Exception {
+    // parse command argument
+    if (args.length == 0) {
+      showMainHelp();
+    } else {
+      String command = args[0];
+      if (command.equals("help")) {
+        help(args);
+      } else if (command.equals("call")) {
+        List<String> callParams = Arrays.asList(args);
+        String response = (new Arvados()).call(callParams);
+        System.out.println (response);
+      } else if (command.equals("discover")) {
+        List<String> callParams = Arrays.asList(args);
+        (new Arvados()).discover(callParams);
+      } else {
+        error(null, "unknown command: " + command);
+      }
+    }
+  }
+
+  protected static void help(String[] args) {
+    if (args.length == 1) {
+      showMainHelp();
+    } else {
+      String helpCommand = args[1];
+      if (helpCommand.equals("call")) {
+        System.out.println("Usage: Arvados call methodName [parameters]");
+        System.out.println();
+        System.out.println("Examples:");
+        System.out.println("  Arvados call arvados v1 users.list");
+        System.out.println("  Arvados call arvados v1 users.get <uuid>");
+        System.out.println("  Arvados call arvados v1 pipeline_instances.list");
+      } else if (helpCommand.equals("discover")) {
+        System.out.println("Usage");
+        System.out.println("Examples:");
+        System.out.println("  Arvados discover arvados v1");
+      } else {
+        error(null, "unknown command: " + helpCommand);
+      }
+    }
+  }
+
+  protected static void showMainHelp() {
+    System.out.println(APP_NAME);
+    System.out.println();
+    System.out.println("For more help on a specific command, type one of:");
+    System.out.println();
+    System.out.println("  Arvados help call");
+    System.out.println("  Arvados help discover");
+  }
+
+  private static void error(String command, String detail) {
+    System.err.println("ERROR: " + detail);
+    System.err.println("For help, type: Arvados" + (command == null ? "" : " help " + command));
+    System.exit(1);
+  }
+
+  public String call(List<String> callParams) throws Exception {
+    if (callParams.size() == 1) {
+      error("call", "missing api name");
+    } else if (callParams.size() == 2) {
+      error("call", "missing api version");
+    } else if (callParams.size() == 3) {
+      error("call", "missing method name");
+    }
+
+    String fullMethodName = callParams.get(3);
+    Matcher m = METHOD_PATTERN.matcher(fullMethodName);
+    if (!m.matches()) {
+      error("call", "invalid method name: " + fullMethodName);
+    }
+
+    RestDescription restDescription = loadArvadosApi(callParams.get(1), callParams.get(2));
+    Map<String, RestMethod> methodMap = null;
+    int curIndex = 0;
+    int nextIndex = fullMethodName.indexOf('.');
+    if (nextIndex == -1) {
+      methodMap = restDescription.getMethods();
+    } else {
+      Map<String, RestResource> resources = restDescription.getResources();
+      while (true) {
+        RestResource resource = resources.get(fullMethodName.substring(curIndex, nextIndex));
+        if (resource == null) {
+          break;
+        }
+        curIndex = nextIndex + 1;
+        nextIndex = fullMethodName.indexOf(curIndex + 1, '.');
+        if (nextIndex == -1) {
+          methodMap = resource.getMethods();
+          break;
+        }
+        resources = resource.getResources();
+      }
+    }
+
+    RestMethod method =
+        methodMap == null ? null : methodMap.get(fullMethodName.substring(curIndex));
+    if (method == null) {
+      error("call", "method not found: " + fullMethodName);
+    }
+
+    HashMap<String, Object> parameters = Maps.newHashMap();
+    File requestBodyFile = null;
+    String contentType = "application/json";
+
+    // Start looking for params at index 4. The first 4 were: call arvados v1 <method_name>
+    int i = 4;
+    // required parameters
+    if (method.getParameterOrder() != null) {
+      for (String parameterName : method.getParameterOrder()) {
+        JsonSchema parameter = method.getParameters().get(parameterName);
+        if (Boolean.TRUE.equals(parameter.getRequired())) {
+          if (i == callParams.size()) {
+            error("call", "missing required parameter: " + parameter);
+          } else {
+            putParameter(null, parameters, parameterName, parameter, callParams.get(i++));
+          }
+        }
+      }
+    }
+
+    // possibly required content
+    if (!method.getHttpMethod().equals("GET") && !method.getHttpMethod().equals("DELETE")) {
+      String fileName = callParams.get(i++);
+      requestBodyFile = new File(fileName);
+      if (!requestBodyFile.canRead()) {
+        error("call", "POST method requires input file. Unable to read file: " + fileName);
+      }
+    }
+
+    while (i < callParams.size()) {
+      String argName = callParams.get(i++);
+      if (!argName.startsWith("--")) {
+        error("call", "optional parameters must start with \"--\": " + argName);
+      }
+      String parameterName = argName.substring(2);
+      if (i == callParams.size()) {
+        error("call", "missing parameter value for: " + argName);
+      }
+      String parameterValue = callParams.get(i++);
+      if (parameterName.equals("contentType")) {
+        contentType = parameterValue;
+        if (method.getHttpMethod().equals("GET") || method.getHttpMethod().equals("DELETE")) {
+          error("call", "HTTP content type cannot be specified for this method: " + argName);
+        }
+      } else {
+        JsonSchema parameter = null;
+        if (restDescription.getParameters() != null) {
+          parameter = restDescription.getParameters().get(parameterName);
+        }
+        if (parameter == null && method.getParameters() == null) {
+          parameter = method.getParameters().get(parameterName);
+        }
+        putParameter(argName, parameters, parameterName, parameter, parameterValue);
+      }
+    }
+
+    GenericUrl url = new GenericUrl(UriTemplate.expand(
+        ARVADOS_ROOT_URL + restDescription.getBasePath() + method.getPath(), parameters,
+        true));
+
+    HttpContent content = null;
+    if (requestBodyFile != null) {
+      content = new FileContent(contentType, requestBodyFile);
+    }
+
+    try {
+      HttpRequestFactory requestFactory;
+      requestFactory = HTTP_TRANSPORT.createRequestFactory();
+
+      HttpRequest request = requestFactory.buildRequest(method.getHttpMethod(), url, content);
+      //request.getp
+      List<String> authHeader = new ArrayList<String>();
+      authHeader.add("OAuth2 " + ARVADOS_API_TOKEN);
+      request.getHeaders().put("Authorization", authHeader);
+      String response = request.execute().parseAsString();
+
+      return response;
+    } catch (Exception e) {
+      e.printStackTrace();
+      throw e;
+    }
+  }
+
+  public RestDescription discover(List<String> params) throws Exception {
+    if (params.size() == 1) {
+      error("call", "missing api name");
+    } else if (params.size() == 2) {
+      error("call", "missing api version");
+    } 
+
+    RestDescription restDescription = loadArvadosApi(params.get(1), params.get(2));
+
+    // compute method details
+    ArrayList<MethodDetails> result = Lists.newArrayList();
+    String resourceName = "";
+    processResources(result, resourceName, restDescription.getResources());
+
+
+    // display method details
+    Collections.sort(result);
+    for (MethodDetails methodDetail : result) {
+      System.out.println();
+      System.out.print("Arvados call " + params.get(1) + " " + params.get(2) + " " + methodDetail.name);
+      for (String param : methodDetail.requiredParameters) {
+        System.out.print(" <" + param + ">");
+      }
+      if (methodDetail.hasContent) {
+        System.out.print(" contentFile");
+      }
+      if (methodDetail.optionalParameters.isEmpty() && !methodDetail.hasContent) {
+        System.out.println();
+      } else {
+        System.out.println(" [optional parameters...]");
+        System.out.println("  --contentType <value> (default is \"application/json\")");
+        for (String param : methodDetail.optionalParameters) {
+          System.out.println("  --" + param + " <value>");
+        }
+      }
+    }
+
+    return (restDescription);
+  }
+
+  private RestDescription loadArvadosApi(String appName, String appVersion)
+      throws Exception {
+    try {
+      return DISCOVERY_CLIENT.apis().getRest(appName, appVersion).execute();
+    } catch (Exception e) {
+      e.printStackTrace();
+      throw e;
+    }
+  }
+
+  private static void processMethods(
+      ArrayList<MethodDetails> result, String resourceName, Map<String, RestMethod> methodMap) {
+    if (methodMap == null) {
+      return;
+    }
+    for (Map.Entry<String, RestMethod> methodEntry : methodMap.entrySet()) {
+      MethodDetails details = new MethodDetails();
+      String methodName = methodEntry.getKey();
+      RestMethod method = methodEntry.getValue();
+      details.name = (resourceName.isEmpty() ? "" : resourceName + ".") + methodName;
+      details.hasContent =
+          !method.getHttpMethod().equals("GET") && !method.getHttpMethod().equals("DELETE");
+      // required parameters
+      if (method.getParameterOrder() != null) {
+        for (String parameterName : method.getParameterOrder()) {
+          JsonSchema parameter = method.getParameters().get(parameterName);
+          if (Boolean.TRUE.equals(parameter.getRequired())) {
+            details.requiredParameters.add(parameterName);
+          }
+        }
+      }
+      // optional parameters
+      Map<String, JsonSchema> parameters = method.getParameters();
+      if (parameters != null) {
+        for (Map.Entry<String, JsonSchema> parameterEntry : parameters.entrySet()) {
+          String parameterName = parameterEntry.getKey();
+          JsonSchema parameter = parameterEntry.getValue();
+          if (!Boolean.TRUE.equals(parameter.getRequired())) {
+            details.optionalParameters.add(parameterName);
+          }
+        }
+      }
+      result.add(details);
+    }
+  }
+
+  private static void processResources(
+      ArrayList<MethodDetails> result, String resourceName, Map<String, RestResource> resourceMap) {
+    if (resourceMap == null) {
+      return;
+    }
+    for (Map.Entry<String, RestResource> entry : resourceMap.entrySet()) {
+      RestResource resource = entry.getValue();
+      String curResourceName = (resourceName.isEmpty() ? "" : resourceName + ".") + entry.getKey();
+      processMethods(result, curResourceName, resource.getMethods());
+      processResources(result, curResourceName, resource.getResources());
+    }
+  }
+
+  private static void putParameter(String argName, Map<String, Object> parameters,
+      String parameterName, JsonSchema parameter, String parameterValue) {
+    Object value = parameterValue;
+    if (parameter != null) {
+      if ("boolean".equals(parameter.getType())) {
+        value = Boolean.valueOf(parameterValue);
+      } else if ("number".equals(parameter.getType())) {
+        value = new BigDecimal(parameterValue);
+      } else if ("integer".equals(parameter.getType())) {
+        value = new BigInteger(parameterValue);
+      }
+    }
+    Object oldValue = parameters.put(parameterName, value);
+    if (oldValue != null) {
+      error("call", "duplicate parameter: " + argName);
+    }
+  }
+
+}
diff --git a/sdk/java/src/main/java/org/arvados/sdk/java/MethodDetails.java b/sdk/java/src/main/java/org/arvados/sdk/java/MethodDetails.java
new file mode 100644
index 0000000..cff3dc7
--- /dev/null
+++ b/sdk/java/src/main/java/org/arvados/sdk/java/MethodDetails.java
@@ -0,0 +1,22 @@
+package org.arvados.sdk.java;
+
+import com.google.api.client.util.Lists;
+import com.google.api.client.util.Sets;
+
+import java.util.ArrayList;
+import java.util.SortedSet;
+
+public class MethodDetails implements Comparable<MethodDetails> {
+    String name;
+    ArrayList<String> requiredParameters = Lists.newArrayList();
+    SortedSet<String> optionalParameters = Sets.newTreeSet();
+    boolean hasContent;
+
+    @Override
+    public int compareTo(MethodDetails o) {
+      if (o == this) {
+        return 0;
+      }
+      return name.compareTo(o.name);
+    }
+}
diff --git a/sdk/java/src/test/java/org/arvados/sdk/java/ArvadosTest.java b/sdk/java/src/test/java/org/arvados/sdk/java/ArvadosTest.java
new file mode 100644
index 0000000..e4c53bc
--- /dev/null
+++ b/sdk/java/src/test/java/org/arvados/sdk/java/ArvadosTest.java
@@ -0,0 +1,173 @@
+package org.arvados.sdk.java;
+
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileWriter;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+
+import com.google.api.services.discovery.model.RestDescription;
+import com.google.api.services.discovery.model.RestResource;
+
+import org.json.simple.JSONObject;
+import org.json.simple.parser.JSONParser;
+
+/**
+ * Unit test for Arvados.
+ */
+public class ArvadosTest extends TestCase {
+  /**
+   * Create the test case
+   *
+   * @param testName name of the test case
+   */
+  public ArvadosTest(String testName) {
+    super( testName );
+  }
+
+  public static Test suite() {
+    return new TestSuite(ArvadosTest.class);
+  }
+
+  public void testShowMainHelp() {
+    Arvados.showMainHelp();
+  }
+
+  /**
+   * test discover method
+   * @throws Exception
+   */
+  public void testDiscover() throws Exception {
+    Arvados arv = new Arvados();
+
+    List<String> params = new ArrayList<String>();
+    params.add("discover");
+    params.add("arvados");
+    params.add("v1");
+
+    RestDescription restDescription = arv.discover(params);
+
+    // The discover method returns the supported methods
+    Map<String, RestResource> resources = restDescription.getResources();
+    assertNotNull("Expected resources", resources);
+    //assertNotNull("Expected methods", restDescription.getMethods());
+
+    Object users = resources.get("users");
+    assertNotNull ("Expected users.list method", users);
+    assertEquals("Exepcted users.list to be a RestResource type", RestResource.class, users.getClass());
+
+    assertTrue("Root URL expected to match ARVADOS_API_HOST env paramdeter", 
+        restDescription.getRootUrl().contains(System.getenv().get("ARVADOS_API_HOST")));
+  }
+
+  /**
+   * Test users.list api
+   * @throws Exception
+   */
+  public void testCallUsersList() throws Exception {
+    Arvados arv = new Arvados();
+
+    List<String> callParams = new ArrayList<String>();
+    callParams.add("call");
+    callParams.add("arvados");
+    callParams.add("v1");
+    callParams.add("users.list");
+
+    String callResponse = arv.call(callParams);
+    assertTrue("Expected users.list in response", callResponse.contains("arvados#userList"));
+    assertTrue("Expected users.list in response", callResponse.contains("uuid"));
+
+    JSONParser parser = new JSONParser();
+    Object obj = parser.parse(callResponse);
+    JSONObject jsonObject = (JSONObject) obj;
+
+    assertEquals("Expected kind to be users.list", "arvados#userList", jsonObject.get("kind"));
+
+    List items = (List)jsonObject.get("items");
+    assertNotNull("expected users list items", items);
+    assertTrue("expected at least one item in users list", items.size()>0);
+
+    JSONObject firstUser = (JSONObject)items.get(0);
+    assertNotNull ("Expcted at least one user", firstUser);
+
+    assertEquals("Expected kind to be user", "arvados#user", firstUser.get("kind"));
+    assertNotNull("Expected uuid for first user", firstUser.get("uuid"));
+  }
+
+  /**
+   * Test users.get <uuid> api
+   * @throws Exception
+   */
+  public void testCallUsersGet() throws Exception {
+    Arvados arv = new Arvados();
+
+    // call user.system and get uuid of this user
+    List<String> callParams = new ArrayList<String>();
+    callParams.add("call");
+    callParams.add("arvados");
+    callParams.add("v1");
+    callParams.add("users.list");
+
+    String callResponse = arv.call(callParams);
+    JSONParser parser = new JSONParser();
+    Object obj = parser.parse(callResponse);
+    JSONObject jsonObject = (JSONObject) obj;
+    assertNotNull("expected users list", jsonObject);
+    List items = (List)jsonObject.get("items");
+    assertNotNull("expected users list items", items);
+
+    JSONObject firstUser = (JSONObject)items.get(0);
+    String userUuid = (String)firstUser.get("uuid");
+
+    // invoke users.get with the system user uuid
+    callParams = new ArrayList<String>();
+    callParams.add("call");
+    callParams.add("arvados");
+    callParams.add("v1");
+    callParams.add("users.get");
+    callParams.add(userUuid);
+
+    callResponse = arv.call(callParams);
+
+    //JSONParser parser = new JSONParser();
+    jsonObject = (JSONObject) parser.parse(callResponse);;
+    assertNotNull("Expected uuid for first user", jsonObject.get("uuid"));
+    assertEquals("Expected system user uuid", userUuid, jsonObject.get("uuid"));
+  }
+
+  /**
+   * Test users.create api
+   * @throws Exception
+   */
+  //@Ignore
+  public void testCreateUser() throws Exception {
+    Arvados arv = new Arvados();
+
+    // POST request needs an input file
+    File file = new File("/tmp/arvados_test.json");
+    BufferedWriter output = new BufferedWriter(new FileWriter(file));
+    output.write("{}");
+    output.close();
+
+    List<String> callParams = new ArrayList<String>();
+    callParams.add("call");
+    callParams.add("arvados");
+    callParams.add("v1");
+    callParams.add("users.create");
+    callParams.add("/tmp/arvados_test.json");
+    String callResponse = arv.call(callParams);
+
+    JSONParser parser = new JSONParser();
+    JSONObject jsonObject = (JSONObject) parser.parse(callResponse);
+    assertEquals("Expected kind to be user", "arvados#user", jsonObject.get("kind"));
+    assertNotNull("Expected uuid for first user", jsonObject.get("uuid"));
+    
+    file.delete();
+  }
+}
+
diff --git a/services/api/app/controllers/arvados/v1/schema_controller.rb b/services/api/app/controllers/arvados/v1/schema_controller.rb
index 625519e..39aa024 100644
--- a/services/api/app/controllers/arvados/v1/schema_controller.rb
+++ b/services/api/app/controllers/arvados/v1/schema_controller.rb
@@ -198,17 +198,17 @@ class Arvados::V1::SchemaController < ApplicationController
                 limit: {
                   type: "integer",
                   description: "Maximum number of #{k.to_s.underscore.pluralize} to return.",
-                  default: 100,
+                  default: "100",
                   format: "int32",
-                  minimum: 0,
+                  minimum: "0",
                   location: "query",
                 },
                 offset: {
                   type: "integer",
                   description: "Number of #{k.to_s.underscore.pluralize} to skip before first returned record.",
-                  default: 0,
+                  default: "0",
                   format: "int32",
-                  minimum: 0,
+                  minimum: "0",
                   location: "query",
                   },
                 filters: {
@@ -350,6 +350,9 @@ class Arvados::V1::SchemaController < ApplicationController
                 else
                   method[:parameters][k] = {}
                 end
+                if !method[:parameters][k][:default].nil?
+                  method[:parameters][k][:default] = 'string'
+                end
                 method[:parameters][k][:type] ||= 'string'
                 method[:parameters][k][:description] ||= ''
                 method[:parameters][k][:location] = (route.segment_keys.include?(k) ? 'path' : 'query')

-----------------------------------------------------------------------


hooks/post-receive
-- 




More information about the arvados-commits mailing list