Commit aef8c50f authored by cnguyen2's avatar cnguyen2
Browse files

Respond with all data if no query param is provided

parent c65d5a03
Pipeline #203316 passed with stages
......@@ -10,6 +10,7 @@ import java.lang.reflect.InvocationTargetException;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.stream.IntStream;
import org.jboss.logging.Logger;
......@@ -31,8 +32,8 @@ public abstract class InMemoryRepo<T> implements Repo<T> {
public abstract List<T> genItems();
@Override
public T get(String id) {
return idMap.get(id);
public Optional<T> get(String id) {
return Optional.ofNullable(idMap.get(id));
}
@Override
......
package ibb.api.geneinfo.repo;
import java.util.List;
import java.util.Optional;
public interface Repo<T> {
T get(String id);
Optional<T> get(String id);
List<T> getAll();
List<T> getByField(String field, Object value);
}
\ No newline at end of file
package ibb.api.geneinfo.resource;
import static java.util.stream.Collectors.toList;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Stream;
import javax.inject.Inject;
import javax.ws.rs.BadRequestException;
import javax.ws.rs.DefaultValue;
import javax.ws.rs.GET;
import javax.ws.rs.NotFoundException;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.MediaType;
import org.eclipse.microprofile.openapi.annotations.Operation;
import org.eclipse.microprofile.openapi.annotations.parameters.Parameter;
import org.eclipse.microprofile.openapi.annotations.parameters.Parameters;
import org.eclipse.microprofile.openapi.annotations.responses.APIResponse;
import org.eclipse.microprofile.openapi.annotations.responses.APIResponses;
import ibb.api.geneinfo.model.DrosophilaGene;
import ibb.api.geneinfo.repo.Repo;
import ibb.api.geneinfo.util.Util;
@Path("/drosophila/genes")
@Produces(MediaType.APPLICATION_JSON)
public class DrosophilaGeneResource {
@Inject
Repo<DrosophilaGene> repo;
@GET
@Path("/{id: FBgn[0-9]{7}}")
@Operation(summary = "Get information of a drosophila gene")
@Parameters({
@Parameter(name = "id", description = "Flybase gene identifier in format FBgn[0-9]{7}", example = "FBgn0000015")
})
@APIResponses({
@APIResponse(responseCode = "200", description = "Success"),
@APIResponse(responseCode = "404", description = "Not found")
})
public DrosophilaGene getOne(@PathParam("id") String id) {
return repo.get(id).orElseThrow(NotFoundException::new);
}
@GET
@Path("/")
@Operation(summary = "Get information of a list of drosophila genes")
@Parameters({
@Parameter(name = "ids", description = "Comma-separated list of Drosophila gene identifiers in format FBgn[0-9]{7}", example = "FBgn0000015,FBgn0012142"),
@Parameter(name = "symbol"),
@Parameter(name = "fullname"),
@Parameter(name = "annotationId")
})
@APIResponses({
@APIResponse(responseCode = "200", description = "Success"),
@APIResponse(responseCode = "400", description = "Bad request. More than one query parameter were supplied")
})
public List<DrosophilaGene> getAll(
@DefaultValue("") @QueryParam("ids") String ids,
@QueryParam("symbol") String symbol,
@QueryParam("fullname") String fullname,
@QueryParam("annotationId") String annotationId) {
Set<String> idSet = Util.trimAndSplit(ids);
long paramCnt = Stream.of(symbol, fullname, annotationId).filter(Objects::nonNull).count();
if (paramCnt > 0 && idSet.size() > 0 || idSet.size() == 0 && paramCnt > 1) {
throw new BadRequestException("Only one query param is allowed");
}
Stream<DrosophilaGene> genes;
if (!idSet.isEmpty()) {
genes = idSet.stream()
.map(repo::get)
.filter(Optional::isPresent)
.map(Optional::get);
} else if (symbol != null) {
genes = repo.getByField("symbol", symbol).stream();
} else if (fullname != null) {
genes = repo.getByField("fullname", fullname).stream();
} else if (annotationId != null) {
genes = repo.getByField("annotationId", annotationId).stream();
} else {
genes = repo.getAll().stream();
}
return genes.collect(toList());
}
}
package ibb.api.geneinfo.resource;
import static java.util.stream.Collectors.toList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import javax.inject.Inject;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.Status;
import org.eclipse.microprofile.openapi.annotations.Operation;
import org.eclipse.microprofile.openapi.annotations.enums.ParameterIn;
import org.eclipse.microprofile.openapi.annotations.enums.SchemaType;
import org.eclipse.microprofile.openapi.annotations.media.Content;
import org.eclipse.microprofile.openapi.annotations.media.Schema;
import org.eclipse.microprofile.openapi.annotations.parameters.Parameter;
import org.eclipse.microprofile.openapi.annotations.responses.APIResponse;
import ibb.api.geneinfo.model.DrosophilaGene;
import ibb.api.geneinfo.model.TriboliumGene;
import ibb.api.geneinfo.repo.Repo;
@Path("/")
@Produces(MediaType.APPLICATION_JSON)
public class GeneResource {
@Inject
Repo<DrosophilaGene> dGeneRepo;
@Inject
Repo<TriboliumGene> tGeneRepo;
@GET
@Path("/drosophila/genes/{id: FBgn[0-9]{7}}")
@Operation(summary = "Get information for a drosophila gene.")
public DrosophilaGene getFlybaseGene(
@Parameter(
description = "Flybase gene identifier in format FBgn[0-9]{7}.",
example = "FBgn0000015")
@PathParam("id") String id) {
return dGeneRepo.get(id);
}
@GET
@Path("/drosophila/genes")
@Operation(summary = "Get information for a list of drosophila genes")
@APIResponse(
responseCode = "200",
description = "A list of found genes.",
content = @Content(
mediaType = "application/json",
schema = @Schema(type = SchemaType.ARRAY, implementation = DrosophilaGene.class)))
@APIResponse(
responseCode = "400",
description = "Zero or more than one query params are provided.")
public Response getFlybaseGenes(
@Parameter(
in = ParameterIn.QUERY,
description = "Comma-separated list of Drosophila gene identifiers in format FBgn[0-9]{7}")
@QueryParam("ids") String idsStr,
@QueryParam("symbol") String symbol,
@Parameter(
in = ParameterIn.QUERY,
example = "knirps")
@QueryParam("fullname") String fullname,
@QueryParam("annotationId") String annotationId) {
Set<String> ids = idsStr == null ? Set.of() : Set.of(idsStr.split(","));
long paramCnt = Stream.of(symbol, fullname, annotationId).filter(p -> p != null).count();
if (paramCnt > 0 && ids.size() > 0 || ids.size() == 0 && paramCnt != 1) {
return Response.status(Status.BAD_REQUEST).build();
}
Collection<DrosophilaGene> dGenes;
if (!ids.isEmpty()) {
dGenes = ids.stream()
.filter(id -> checkFBgnID(id))
.map(id -> dGeneRepo.get(id))
.filter(gene -> gene != null)
.collect(Collectors.toList());
} else if (symbol != null) {
dGenes = dGeneRepo.getByField("symbol", symbol);
} else if (fullname != null) {
dGenes = dGeneRepo.getByField("fullname", fullname);
} else if (annotationId != null) {
dGenes = dGeneRepo.getByField("annotationId", annotationId);
} else {
dGenes = Collections.emptyList();
}
return Response.ok(dGenes.stream().collect(toList())).build();
}
@GET
@Path("/tribolium/genes/{id: TC[0-9]{6}}")
@Operation(summary = "Get information for a tribolium gene.")
public TriboliumGene getTriboliumGene(
@Parameter(
description = "Tribolium gene identifier in format TC[0-9]{6}}.",
example = "TC001906")
@PathParam("id") String id) {
return tGeneRepo.get(id);
}
@GET
@Path("/tribolium/genes")
@Operation(summary = "Get information for a list of tribolium genes")
public List<TriboliumGene> getTriboliumGenes(
@Parameter(
in = ParameterIn.QUERY,
description = "Comma-separated list of Tribolium gene identifiers in format TC[0-9]{6}",
example = "TC001906")
@QueryParam("ids") String idsStr) {
Set<String> ids = idsStr == null ? Set.of() : Set.of(idsStr.split(","));
return ids.stream()
.filter(id -> checkTCID(id))
.map(id -> tGeneRepo.get(id))
.filter(gene -> gene != null)
.collect(Collectors.toList());
}
/**
* Checks if a FlyBase gene identifier (FBgn) is in the right format
* @param fbgn The Flybase gene identifier to be checked
* @return True if the identifier is correctly formatted, False otherwise
*/
private boolean checkFBgnID(final String fbgn) {
return fbgn.matches("FBgn[0-9]{7}");
}
/**
* Checks if a tribolium gene identifier (TC) is in the right format
* @param tc The TC gene identifier to be checked
* @return True if the identifier is correctly formatted, False otherwise
*/
private boolean checkTCID(final String tc) {
return tc.matches("TC[0-9]{6}");
}
}
\ No newline at end of file
package ibb.api.geneinfo.resource;
import static java.util.stream.Collectors.toList;
import java.util.List;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Stream;
import javax.inject.Inject;
import javax.ws.rs.DefaultValue;
import javax.ws.rs.GET;
import javax.ws.rs.NotFoundException;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.MediaType;
import org.eclipse.microprofile.openapi.annotations.Operation;
import org.eclipse.microprofile.openapi.annotations.parameters.Parameter;
import org.eclipse.microprofile.openapi.annotations.parameters.Parameters;
import org.eclipse.microprofile.openapi.annotations.responses.APIResponse;
import org.eclipse.microprofile.openapi.annotations.responses.APIResponses;
import ibb.api.geneinfo.model.TriboliumGene;
import ibb.api.geneinfo.repo.Repo;
import ibb.api.geneinfo.util.Util;
@Path("/tribolium/genes")
@Produces(MediaType.APPLICATION_JSON)
public class TriboliumGeneResource {
@Inject
Repo<TriboliumGene> repo;
@GET
@Path("/{id: TC[0-9]{6}}")
@Operation(summary = "Get information for a tribolium gene.")
@Parameters({
@Parameter(name = "id", description = "Tribolium gene identifier in format TC[0-9]{6}}", example = "TC016177")
})
@APIResponses({
@APIResponse(responseCode = "200", description = "Success"),
@APIResponse(responseCode = "404", description = "Not found")
})
public TriboliumGene getOne(@PathParam("id") String id) {
return repo.get(id).orElseThrow(NotFoundException::new);
}
@GET
@Operation(summary = "Get information of a list of tribolium genes")
@Parameters({
@Parameter(name = "ids", description = "Comma-separated list of Tribolium gene identifiers in format TC[0-9]{6}}", example = "TC016177,TC001906")
})
@APIResponses({
@APIResponse(responseCode = "200", description = "Success")
})
public List<TriboliumGene> getAll(@DefaultValue("") @QueryParam("ids") String ids) {
Set<String> idSet = Util.trimAndSplit(ids);
Stream<TriboliumGene> genes;
if (!idSet.isEmpty()) {
genes = idSet.stream()
.map(repo::get)
.filter(Optional::isPresent)
.map(Optional::get);
} else {
genes = repo.getAll().stream();
}
return genes.collect(toList());
}
}
package ibb.api.geneinfo.util;
import static java.util.stream.Collectors.toCollection;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet;
import java.util.Set;
import java.util.function.Predicate;
import java.util.function.Supplier;
public class Util {
public static <C extends Collection<String>> C trimAndSplit(String str, Supplier<C> collectionFactory) {
return Arrays.stream(str.trim().split(","))
.map(String::trim)
.filter(Predicate.not(""::equals))
.collect(toCollection(collectionFactory));
}
public static <C extends Collection<String>> Set<String> trimAndSplit(String str) {
return trimAndSplit(str, HashSet::new);
}
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment