Skip to content
Merged
Original file line number Diff line number Diff line change
Expand Up @@ -27,29 +27,19 @@
import io.micronaut.security.rules.SecurityRule;
import lombok.extern.slf4j.Slf4j;
import okhttp3.*;
import org.brapi.client.v2.model.exceptions.ApiException;
import org.brapi.v2.model.core.BrAPIListSummary;
import org.brapi.v2.model.core.BrAPIServerInfo;
import org.brapi.v2.model.core.response.BrAPIServerInfoResponse;
import org.breedinginsight.api.auth.AuthenticatedUser;
import org.breedinginsight.api.auth.ProgramSecured;
import org.breedinginsight.api.auth.ProgramSecuredRoleGroup;
import org.breedinginsight.api.auth.SecurityService;
import org.breedinginsight.api.model.v1.request.query.SearchRequest;
import org.breedinginsight.api.model.v1.validators.QueryValid;
import org.breedinginsight.brapi.v1.controller.BrapiVersion;
import org.breedinginsight.brapi.v2.model.request.query.ListQuery;
import org.breedinginsight.utilities.response.mappers.ListQueryMapper;
import org.breedinginsight.brapi.v2.services.BrAPIGermplasmService;
import org.breedinginsight.model.ProgramBrAPIEndpoints;
import org.breedinginsight.services.ProgramService;
import org.breedinginsight.services.exceptions.DoesNotExistException;
import org.breedinginsight.utilities.response.ResponseUtils;

import javax.inject.Inject;
import javax.validation.Valid;
import java.io.IOException;
import java.util.List;
import java.util.UUID;
import java.util.stream.Collectors;

Expand All @@ -60,16 +50,11 @@ public class BrAPIV2Controller {

private final SecurityService securityService;
private final ProgramService programService;
private final BrAPIGermplasmService germplasmService;
private ListQueryMapper listQueryMapper;

@Inject
public BrAPIV2Controller(SecurityService securityService, ProgramService programService, BrAPIGermplasmService germplasmService,
ListQueryMapper listQueryMapper) {
public BrAPIV2Controller(SecurityService securityService, ProgramService programService) {
this.securityService = securityService;
this.programService = programService;
this.germplasmService = germplasmService;
this.listQueryMapper = listQueryMapper;
}


Expand All @@ -86,43 +71,6 @@ public BrAPIServerInfoResponse serverinfo() {
return new BrAPIServerInfoResponse().result(serverInfo);
}

//@Get(BrapiVersion.BRAPI_V2 + "/lists")
@Get("/${micronaut.bi.api.version}/programs/{programId}" + BrapiVersion.BRAPI_V2 + "/lists{?queryParams*}")
@Produces(MediaType.APPLICATION_JSON)
@ProgramSecured(roleGroups = {ProgramSecuredRoleGroup.ALL})
public HttpResponse getLists(@PathVariable("programId") UUID programId, HttpRequest<String> request,
@QueryValue @QueryValid(using = ListQueryMapper.class) @Valid ListQuery queryParams
) throws DoesNotExistException, ApiException {
try {
List<BrAPIListSummary> brapiLists;

// If the date display format was sent as a query param, then update the query mapper.
String dateFormatParam = queryParams.getDateDisplayFormat();
if (dateFormatParam != null) {
listQueryMapper.setDateDisplayFormat(dateFormatParam);
}

if (queryParams.getListType() == null) {
// TODO: in future return all list types but for now just return germplasm
brapiLists = germplasmService.getGermplasmListsByProgramId(programId, request);
} else {
// TODO: return appropriate lists by type, only germplasm currently
switch (queryParams.getListType()) {
case "germplasm":
default:
brapiLists = germplasmService.getGermplasmListsByProgramId(programId, request);
}
}

SearchRequest searchRequest = queryParams.constructSearchRequest();
return ResponseUtils.getBrapiQueryResponse(brapiLists, listQueryMapper, queryParams, searchRequest);

} catch (IllegalArgumentException e) {
log.info(e.getMessage(), e);
return HttpResponse.status(HttpStatus.UNPROCESSABLE_ENTITY, "Error parsing requested date format");
}
}

@Get("/${micronaut.bi.api.version}/programs/{programId}" + BrapiVersion.BRAPI_V2 + "/{+path}")
@Produces(MediaType.APPLICATION_JSON)
@ProgramSecured(roleGroups = {ProgramSecuredRoleGroup.ALL})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import org.breedinginsight.brapi.v2.model.request.query.ExperimentExportQuery;
import org.breedinginsight.brapi.v2.model.request.query.ExperimentQuery;
import org.breedinginsight.brapi.v2.services.BrAPITrialService;
import org.breedinginsight.model.Dataset;
import org.breedinginsight.model.DownloadFile;
import org.breedinginsight.model.Program;
import org.breedinginsight.services.ProgramService;
Expand Down Expand Up @@ -108,9 +109,26 @@ public HttpResponse<StreamedFile> datasetExport(
HttpResponse response = HttpResponse.status(HttpStatus.INTERNAL_SERVER_ERROR, downloadErrorMessage).contentType(MediaType.TEXT_PLAIN).body(downloadErrorMessage);
return response;
}


}

@Get("/${micronaut.bi.api.version}/programs/{programId}/experiments/{experimentId}/dataset/{datasetId}{?stats}")
@ProgramSecured(roleGroups = {ProgramSecuredRoleGroup.ALL})
@Produces(MediaType.APPLICATION_JSON)
public HttpResponse<Response<Dataset>> getDatasetData(
@PathVariable("programId") UUID programId,
@PathVariable("experimentId") UUID experimentId,
@PathVariable("datasetId") UUID datasetId,
@QueryValue(defaultValue = "false") Boolean stats) {
String downloadErrorMessage = "An error occurred while fetching the dataset. Contact the development team at bidevteam@cornell.edu.";
try {
Program program = programService.getById(programId).orElseThrow(() -> new DoesNotExistException("Program does not exist"));
Response<Dataset> response = new Response(experimentService.getDatasetData(program, experimentId, datasetId, stats));
return HttpResponse.ok(response);
} catch (Exception e) {
log.info(e.getMessage(), e);
HttpResponse response = HttpResponse.status(HttpStatus.INTERNAL_SERVER_ERROR, downloadErrorMessage).contentType(MediaType.TEXT_PLAIN).body(downloadErrorMessage);
return response;
}
}

}
111 changes: 111 additions & 0 deletions src/main/java/org/breedinginsight/brapi/v2/ListController.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
/*
* See the NOTICE file distributed with this work for additional information
* regarding copyright ownership.
*
* Licensed 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.breedinginsight.brapi.v2;

import io.micronaut.http.HttpResponse;
import io.micronaut.http.HttpStatus;
import io.micronaut.http.MediaType;
import io.micronaut.http.annotation.*;
import io.micronaut.security.annotation.Secured;
import io.micronaut.security.rules.SecurityRule;
import lombok.extern.slf4j.Slf4j;
import org.brapi.client.v2.model.exceptions.ApiException;
import org.brapi.v2.model.core.BrAPIListSummary;
import org.brapi.v2.model.core.BrAPIListTypes;
import org.breedinginsight.api.auth.ProgramSecured;
import org.breedinginsight.api.auth.ProgramSecuredRoleGroup;
import org.breedinginsight.api.model.v1.request.query.SearchRequest;
import org.breedinginsight.api.model.v1.response.DataResponse;
import org.breedinginsight.api.model.v1.response.Response;
import org.breedinginsight.api.model.v1.validators.QueryValid;
import org.breedinginsight.brapi.v1.controller.BrapiVersion;
import org.breedinginsight.brapi.v2.model.request.query.ListQuery;
import org.breedinginsight.brapi.v2.services.BrAPIListService;
import org.breedinginsight.model.Program;
import org.breedinginsight.services.ProgramService;
import org.breedinginsight.services.exceptions.DoesNotExistException;
import org.breedinginsight.utilities.response.ResponseUtils;
import org.breedinginsight.utilities.response.mappers.ListQueryMapper;

import javax.inject.Inject;
import javax.validation.Valid;
import java.util.List;
import java.util.UUID;

@Slf4j
@Controller
@Secured(SecurityRule.IS_AUTHENTICATED)
public class ListController {

private final ProgramService programService;
private final BrAPIListService listService;
private final ListQueryMapper listQueryMapper;

@Inject
public ListController(ProgramService programService, BrAPIListService listService,
ListQueryMapper listQueryMapper) {
this.programService = programService;
this.listService = listService;
this.listQueryMapper = listQueryMapper;
}

//@Get(BrapiVersion.BRAPI_V2 + "/lists")
@Get("/${micronaut.bi.api.version}/programs/{programId}" + BrapiVersion.BRAPI_V2 + "/lists{?queryParams*}")
@Produces(MediaType.APPLICATION_JSON)
@ProgramSecured(roleGroups = {ProgramSecuredRoleGroup.ALL})
public HttpResponse<Response<DataResponse<Object>>> getLists(
@PathVariable("programId") UUID programId,
@QueryValue @QueryValid(using = ListQueryMapper.class) @Valid ListQuery queryParams
) throws DoesNotExistException, ApiException {
try {
Program program = programService
.getById(programId)
.orElseThrow(() -> new DoesNotExistException("Program does not exist"));

// get germplasm lists by default
BrAPIListTypes type = BrAPIListTypes.fromValue(queryParams.getListType());
if (type == null) {
type = BrAPIListTypes.GERMPLASM;
}
String source = null;
String id = null;
if (queryParams.getExternalReferenceSource() != null && !queryParams.getExternalReferenceSource().isEmpty()) {
source = queryParams.getExternalReferenceSource();
}
if (queryParams.getExternalReferenceId() != null && !queryParams.getExternalReferenceId().isEmpty()) {
id = queryParams.getExternalReferenceId();
}

// If the date display format was sent as a query param, then update the query mapper.
String dateFormatParam = queryParams.getDateDisplayFormat();
if (dateFormatParam != null) {
listQueryMapper.setDateDisplayFormat(dateFormatParam);
}
List<BrAPIListSummary> brapiLists = listService.getListSummariesByTypeAndXref(type, source, id, program);
SearchRequest searchRequest = queryParams.constructSearchRequest();

return ResponseUtils.getBrapiQueryResponse(brapiLists, listQueryMapper, queryParams, searchRequest);

} catch (IllegalArgumentException e) {
log.info(e.getMessage(), e);
return HttpResponse.status(HttpStatus.UNPROCESSABLE_ENTITY, "Error parsing requested date format");
} catch (ClassNotFoundException e) {
throw new RuntimeException(e);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import org.breedinginsight.api.model.v1.request.query.FilterRequest;
import org.breedinginsight.api.model.v1.request.query.SearchRequest;
import org.breedinginsight.brapi.v1.model.request.query.BrapiQuery;
import org.breedinginsight.brapps.importer.services.ExternalReferenceSource;
import org.jooq.tools.StringUtils;

import java.util.ArrayList;
Expand All @@ -17,14 +18,16 @@ public class ListQuery extends BrapiQuery {
private String name;
private String description;
private String size;
private String externalReferenceSource;
private String externalReferenceId;
private String dateCreated;
private String ownerName;
// This is a meta-parameter, it describes the display format of any date fields.
private String dateDisplayFormat;

public SearchRequest constructSearchRequest() {
List<FilterRequest> filters = new ArrayList<>();
if (!StringUtils.isBlank(getListType())) {
if (getListType() != null) {
filters.add(constructFilterRequest("type", getListType()));
}
if (!StringUtils.isBlank(getName())) {
Expand All @@ -36,6 +39,12 @@ public SearchRequest constructSearchRequest() {
if (!StringUtils.isBlank(getSize())) {
filters.add(constructFilterRequest("size", getSize()));
}
if (getExternalReferenceSource() != null) {
filters.add(constructFilterRequest("externalReferenceSource", getExternalReferenceSource()));
}
if (!StringUtils.isBlank(getExternalReferenceId())) {
filters.add(constructFilterRequest("externalReferenceId", getExternalReferenceId()));
}
if (!StringUtils.isBlank(getDateCreated())) {
filters.add(constructFilterRequest("dateCreated", getDateCreated()));
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
package org.breedinginsight.brapi.v2.services;

import io.micronaut.context.annotation.Property;
import lombok.extern.slf4j.Slf4j;
import org.brapi.client.v2.model.exceptions.ApiException;
import org.brapi.v2.model.BrAPIExternalReference;
import org.brapi.v2.model.core.BrAPIListSummary;
import org.brapi.v2.model.core.BrAPIListTypes;
import org.brapi.v2.model.core.request.BrAPIListSearchRequest;
import org.brapi.v2.model.core.response.BrAPIListsSingleResponse;
import org.breedinginsight.brapi.v2.dao.BrAPIGermplasmDAO;
import org.breedinginsight.brapps.importer.daos.*;
import org.breedinginsight.brapps.importer.services.ExternalReferenceSource;
import org.breedinginsight.model.Program;
import org.breedinginsight.services.exceptions.DoesNotExistException;
import org.breedinginsight.utilities.Utilities;

import javax.inject.Inject;
import javax.inject.Singleton;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.UUID;
import java.util.stream.Collectors;

@Slf4j
@Singleton
public class BrAPIListService {
private final String referenceSource;
private final BrAPIListDAO listDAO;
private final BrAPIGermplasmDAO germplasmDAO;

@Inject
public BrAPIListService(@Property(name = "brapi.server.reference-source") String referenceSource,
BrAPIListDAO listDAO,
BrAPIGermplasmDAO germplasmDAO) {

this.referenceSource = referenceSource;
this.listDAO = listDAO;
this.germplasmDAO = germplasmDAO;
}

public List<BrAPIListSummary> getListSummariesByTypeAndXref(
BrAPIListTypes type,
String xrefSource,
String xrefId,
Program program) throws ApiException, DoesNotExistException, ClassNotFoundException {
BrAPIListSearchRequest searchRequest = new BrAPIListSearchRequest();
if (type != null) {
searchRequest.listType(type);
}
if (xrefSource != null && !xrefSource.isEmpty()) {
searchRequest.externalReferenceSources(List.of(xrefSource));
}
if (xrefId != null && !xrefId.isEmpty()) {
searchRequest.externalReferenceIDs(List.of(xrefId));
}
List<BrAPIListSummary> lists = listDAO.getListBySearch(searchRequest, program.getId());
if (lists == null) {
throw new DoesNotExistException("list not returned from BrAPI service");
}

List<BrAPIListSummary> programLists = lists.stream().filter(list -> {
Optional<BrAPIExternalReference> programXrefOptional = Utilities.getExternalReference(list.getExternalReferences(),Utilities.generateReferenceSource(referenceSource, ExternalReferenceSource.PROGRAMS));
return programXrefOptional.isPresent() && programXrefOptional.get().getReferenceID().equals(program.getId().toString());
}).collect(Collectors.toList());
for (BrAPIListSummary list: programLists) {

// remove the program key from the list name
list.setListName(Utilities.removeProgramKeyAndUnknownAdditionalData(list.getListName(), program.getKey()));

// set the owner of the list items as the list owner
BrAPIListsSingleResponse listDetails = listDAO.getListById(list.getListDbId(), program.getId());
List<String> listItemNames = listDetails.getResult().getData();
switch (type) {
case OBSERVATIONVARIABLES:
break;
case GERMPLASM:
default:
String createdBy = germplasmDAO.getGermplasmByRawName(listItemNames, program.getId()).get(0)
.getAdditionalInfo()
.getAsJsonObject("createdBy")
.get("userName")
.getAsString();
list.setListOwnerName(createdBy);
}

}

return programLists;
}
}
Loading