package edu.washington.escience.myriad.api.encoding;

import java.util.List;

import org.codehaus.jackson.annotate.JsonSubTypes;
import org.codehaus.jackson.annotate.JsonSubTypes.Type;
import org.codehaus.jackson.annotate.JsonTypeInfo;

import com.google.common.collect.ImmutableList;

import edu.washington.escience.myriad.parallel.PartitionFunction;

@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "type")
@JsonSubTypes({
    @Type(value = MultiFieldPartitionFunctionEncoding.class, name = "MultiFieldHash"),
    @Type(value = SingleFieldPartitionFunctionEncoding.class, name = "SingleFieldHash") })
public abstract class PartitionFunctionEncoding<T extends PartitionFunction<?, ?>> extends MyriaApiEncoding {
  public String type;

  /**
   * @param numPartitions the number of ways to partition the data.
   * @return the instantiated partition function.
   */
  public abstract T construct(int numPartitions);

  /**
   * @return the list of required arguments for this PartitionFunctionEncodign.
   */
  protected abstract List<String> getRequiredArguments();

  @Override
  protected List<String> getRequiredFields() {
    return new ImmutableList.Builder<String>().add("type").addAll(getRequiredArguments()).build();
  }
}
package edu.washington.escience.myriad.api.encoding;

import java.util.List;

import org.codehaus.jackson.annotate.JsonSubTypes;
import org.codehaus.jackson.annotate.JsonSubTypes.Type;
import org.codehaus.jackson.annotate.JsonTypeInfo;

import com.google.common.collect.ImmutableList;

import edu.washington.escience.myriad.parallel.PartitionFunction;

@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "type")
@JsonSubTypes({
    @Type(value = MultiFieldPartitionFunctionEncoding.class, name = "MultiFieldHash"),
    @Type(value = SingleFieldPartitionFunctionEncoding.class, name = "SingleFieldHash") })
public abstract class PartitionFunctionEncoding<T extends PartitionFunction<?, ?>> extends MyriaApiEncoding {
  public String type;

  /**
   * @param numPartitions the number of ways to partition the data.
   * @return the instantiated partition function.
   */
  public abstract T construct(int numPartitions);

  /**
   * @return the list of required arguments for this PartitionFunctionEncoding.
   */
  protected abstract List<String> getRequiredArguments();

  @Override
  protected List<String> getRequiredFields() {
    return new ImmutableList.Builder<String>().addAll(getRequiredArguments()).build();
  }
}
remove the required field type. The fix is small, the story is long... When I submitted a query contains a SingleHashPartitionFunction (for example, jsonQueries/sample_queries/single_join.json, I got: the field "type" of SingleFieldPartitionFunctionEncoding is not set. I googled a lot and I believe the problem is because of this: http://fasterxml.github.io/jackson-annotations/javadoc/2.0.0/com/fasterxml/jackson/annotation/JsonTypeInfo.html. Basically, since "type" is used to distinguish subtypes, it's not passed and set in SingleFieldPartitionFunctionEncoding. However, this feature is only available for jackson >= 2.0.0. But restlet 2.1.2 explicitly requires jackson 1.9.8 (http://maven.restlet.org/org/restlet/jse/org.restlet.ext.jackson/2.1.2/org.restlet.ext.jackson-2.1.2.pom), and I guess we should just follow it. I'm not sure if we should upgrade restlet either, since there's no stable version available. So my final solution is simply removing this constraint... This (and the new-local-join-out-of-memory) thing actually reminds me one thing, besides junit tests, we also need to run json query tests each time when we change something. I'm not sure how to set up a procedure regarding this.