-
Notifications
You must be signed in to change notification settings - Fork 11
Provide a better error for client-side shard filtering. #23
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -13,6 +13,12 @@ | |
*/ | ||
package com.google.cloud.genomics.utils; | ||
|
||
import java.io.IOException; | ||
import java.io.Serializable; | ||
import java.util.Collections; | ||
import java.util.Iterator; | ||
import java.util.Map; | ||
|
||
import com.google.api.services.genomics.Genomics; | ||
import com.google.api.services.genomics.GenomicsRequest; | ||
import com.google.api.services.genomics.model.Annotation; | ||
|
@@ -51,17 +57,16 @@ | |
import com.google.api.services.genomics.model.Variant; | ||
import com.google.api.services.genomics.model.VariantSet; | ||
import com.google.common.base.Function; | ||
import com.google.common.base.Joiner; | ||
import com.google.common.base.Optional; | ||
import com.google.common.base.Preconditions; | ||
import com.google.common.base.Predicate; | ||
import com.google.common.collect.AbstractSequentialIterator; | ||
import com.google.common.collect.FluentIterable; | ||
import com.google.common.collect.ImmutableMap; | ||
import com.google.common.collect.Iterables; | ||
import com.google.common.collect.Lists; | ||
|
||
import java.io.IOException; | ||
import java.io.Serializable; | ||
import java.util.Collections; | ||
import java.util.Iterator; | ||
import com.google.common.collect.Maps; | ||
|
||
/** | ||
* An abstraction that understands the {@code pageToken} / {@code nextPageToken} protocol for paging | ||
|
@@ -319,6 +324,13 @@ public static class Reads extends Paginator< | |
SearchReadsResponse, | ||
Read> { | ||
|
||
// TODO: When this is supported server-side, these additional fields are no longer required | ||
private static ImmutableMap<String,String> REQUIRED_STRICT_SHARD_FIELDS = | ||
ImmutableMap.<String, String>builder() | ||
.putAll(REQUIRED_FIELDS) | ||
.put("alignment", ".*\\p{Punct}alignment\\p{Punct}.*") | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. alignments, right? Also, is there some guarantee of leading/trailing punctuation? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nevermind about 'alignments', but the second comment stands. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nevermind the whole thread. These will always be wrapped in the repeated response field, i.e. alignments, annotations, variants There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Just requires time - it took me some time to wrap my brain around it too :) |
||
.put("position", ".*\\p{Punct}position\\p{Punct}.*") | ||
.build(); | ||
private final ShardBoundary shardBoundary; | ||
private Predicate<Read> shardPredicate = null; | ||
|
||
|
@@ -369,6 +381,14 @@ public boolean apply(Read read) { | |
.or(request)); | ||
} | ||
|
||
@Override | ||
public GenomicsRequestInitializer<GenomicsRequest<?>> setFieldsInitializer(final String fields) { | ||
if(shardBoundary == ShardBoundary.STRICT) { | ||
return new GenomicsSearchFieldRequestInitializer(fields, REQUIRED_STRICT_SHARD_FIELDS); | ||
} | ||
return new GenomicsSearchFieldRequestInitializer(fields, REQUIRED_FIELDS); | ||
} | ||
|
||
@Override Genomics.Reads getApi(Genomics genomics) { | ||
return genomics.reads(); | ||
} | ||
|
@@ -396,6 +416,13 @@ public static class Annotations extends Paginator< | |
SearchAnnotationsResponse, | ||
Annotation> { | ||
|
||
// TODO: When this is supported server-side, these additional fields are no longer required | ||
private static ImmutableMap<String,String> REQUIRED_STRICT_SHARD_FIELDS = | ||
ImmutableMap.<String, String>builder() | ||
.putAll(REQUIRED_FIELDS) | ||
.put("position", ".*\\p{Punct}position\\p{Punct}.*") | ||
.put("start", ".*\\p{Punct}start\\p{Punct}.*") | ||
.build(); | ||
private final ShardBoundary shardBoundary; | ||
private Predicate<Annotation> shardPredicate = null; | ||
|
||
|
@@ -445,6 +472,14 @@ public boolean apply(Annotation anno) { | |
.or(request)); | ||
} | ||
|
||
@Override | ||
public GenomicsRequestInitializer<GenomicsRequest<?>> setFieldsInitializer(final String fields) { | ||
if(shardBoundary == ShardBoundary.STRICT) { | ||
return new GenomicsSearchFieldRequestInitializer(fields, REQUIRED_STRICT_SHARD_FIELDS); | ||
} | ||
return new GenomicsSearchFieldRequestInitializer(fields, REQUIRED_FIELDS); | ||
} | ||
|
||
@Override Genomics.Annotations getApi(Genomics genomics) { | ||
return genomics.annotations(); | ||
} | ||
|
@@ -784,6 +819,12 @@ public static class Variants extends Paginator< | |
SearchVariantsResponse, | ||
Variant> { | ||
|
||
// TODO: When this is supported server-side, these additional fields are no longer required | ||
private static ImmutableMap<String,String> REQUIRED_STRICT_SHARD_FIELDS = | ||
ImmutableMap.<String, String>builder() | ||
.putAll(REQUIRED_FIELDS) | ||
.put("start", ".*\\p{Punct}start\\p{Punct}.*") | ||
.build(); | ||
private final ShardBoundary shardBoundary; | ||
private Predicate<Variant> shardPredicate = null; | ||
|
||
|
@@ -834,6 +875,14 @@ public boolean apply(Variant variant) { | |
.or(request)); | ||
} | ||
|
||
@Override | ||
public GenomicsRequestInitializer<GenomicsRequest<?>> setFieldsInitializer(final String fields) { | ||
if(shardBoundary == ShardBoundary.STRICT) { | ||
return new GenomicsSearchFieldRequestInitializer(fields, REQUIRED_STRICT_SHARD_FIELDS); | ||
} | ||
return new GenomicsSearchFieldRequestInitializer(fields, REQUIRED_FIELDS); | ||
} | ||
|
||
@Override Genomics.Variants getApi(Genomics genomics) { | ||
return genomics.variants(); | ||
} | ||
|
@@ -905,17 +954,46 @@ private Variantsets(Genomics genomics) { | |
@Override public void initialize(GenomicsRequest<?> search) {} | ||
}; | ||
|
||
public static GenomicsRequestInitializer<GenomicsRequest<?>> setFieldsInitializer( | ||
final String fields) { | ||
return new GenomicsRequestInitializer<GenomicsRequest<?>>() { | ||
@Override public void initialize(GenomicsRequest<?> search) { | ||
if (null != fields) { | ||
search.setFields(fields); | ||
} | ||
} | ||
}; | ||
protected static final ImmutableMap<String, String> REQUIRED_FIELDS = ImmutableMap | ||
.<String, String>builder() | ||
.put("nextPageToken", "(.+\\p{Punct})?nextPageToken(\\p{Punct}.+)?"). | ||
build(); | ||
|
||
public GenomicsRequestInitializer<GenomicsRequest<?>> setFieldsInitializer(final String fields) { | ||
return new GenomicsSearchFieldRequestInitializer(fields, REQUIRED_FIELDS); | ||
} | ||
|
||
public static class GenomicsSearchFieldRequestInitializer implements | ||
GenomicsRequestInitializer<GenomicsRequest<?>> { | ||
private final String fields; | ||
private final ImmutableMap<String, String> requiredFields; | ||
|
||
public GenomicsSearchFieldRequestInitializer(String fields, | ||
ImmutableMap<String, String> requiredFields) { | ||
this.fields = fields; | ||
this.requiredFields = requiredFields; | ||
} | ||
|
||
@Override | ||
public void initialize(GenomicsRequest<?> search) { | ||
if (null != fields) { | ||
Map<String, String> missingFields = | ||
Maps.filterValues(requiredFields, new Predicate<String>() { | ||
@Override | ||
public boolean apply(String input) { | ||
return !fields.matches(input); | ||
} | ||
}); | ||
Preconditions | ||
.checkArgument( | ||
missingFields.isEmpty(), | ||
"Required field(s) missing: '%s' Add this field to the list of fields to be returned in the partial response.", | ||
Joiner.on(",").join(missingFields.keySet())); | ||
search.setFields(fields); | ||
} | ||
} | ||
} | ||
|
||
private final Genomics genomics; | ||
|
||
public Paginator(Genomics genomics) { | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we assert nextPageToken somewhere?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added that too.