package gov.nysenate.openleg.controller.api.senatesite; import com.google.common.eventbus.EventBus; import gov.nysenate.openleg.client.response.base.BaseResponse; import gov.nysenate.openleg.client.response.base.SimpleResponse; import gov.nysenate.openleg.client.response.error.ErrorCode; import gov.nysenate.openleg.client.response.error.ErrorResponse; import gov.nysenate.openleg.client.response.error.ViewObjectErrorResponse; import gov.nysenate.openleg.controller.api.base.BaseCtrl; import gov.nysenate.openleg.dao.bill.reference.senatesite.SenateSiteDao; import gov.nysenate.openleg.model.spotcheck.SpotCheckRefType; import gov.nysenate.openleg.model.spotcheck.SpotCheckReferenceEvent; import gov.nysenate.openleg.model.spotcheck.senatesite.SenateSiteDumpFragment; import gov.nysenate.openleg.util.AsyncRunner; import gov.nysenate.openleg.util.SenateSiteDumpFragParser; import gov.nysenate.openleg.util.SenateSiteDumpFragParser.SenateSiteDumpFragParserException; import org.apache.shiro.authz.annotation.RequiresPermissions; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; import org.springframework.web.bind.annotation.*; import java.io.IOException; import static gov.nysenate.openleg.controller.api.base.BaseCtrl.BASE_API_PATH; @RestController @RequestMapping(BASE_API_PATH + "/senatesite") public class SenateSiteDumpCtrl extends BaseCtrl { private static final Logger logger = LoggerFactory.getLogger(SenateSiteDumpCtrl.class); @Autowired private SenateSiteDao senateSiteDao; @Autowired private AsyncRunner asyncRunner; @Autowired private EventBus eventBus; @Autowired private SenateSiteDumpFragParser parser; /** * nysenate.gov Bill Dump API * * Posts a fragment of a json bill data dump * * Usage: (POST) /api/3/senatesite/billdump */ @RequiresPermissions("senatesite:billdump:post") @RequestMapping(value = "/billdump", method = RequestMethod.POST, consumes = "application/json") public BaseResponse sendSenateSiteBillDumpFragment(@RequestBody String billFragmentJson) throws IOException { if(!saveDump(billFragmentJson,SpotCheckRefType.SENATE_SITE_BILLS)){ return new SimpleResponse(false, "could not save dump :(", "bill-dump-failed"); } return new SimpleResponse(true, "bill dump received. Thanks!", "bill-dump-received"); } /** * nysenate.gov Calendar Dump API * * Posts a fragment of a json calendar data dump * * Usage: (POST) /api/3/senatesite/caldump */ @RequiresPermissions("senatesite:caldump:post") @RequestMapping(value = "/caldump",method = RequestMethod.POST, consumes = "application/json") public BaseResponse sendSenateSiteCalDumpFragment(@RequestBody String calFragmentJson) throws IOException{ if(!saveDump(calFragmentJson,SpotCheckRefType.SENATE_SITE_CALENDAR)){ return new SimpleResponse(false, "could not save dump :(", "calendar-dump-failed"); } return new SimpleResponse(true, "calendar dump received. Thanks!", "calendar-dump-received"); } /** * nysenate.gov Agenda Dump API * * Posts a fragment of a json agenda data dump * * Usage: (POST) /api/3/senatesite/agendadump */ @RequiresPermissions("senatesite:agendadump:post") @RequestMapping(value = "/agendadump",method = RequestMethod.POST, consumes = "application/json") public BaseResponse sendSenateSiteAgendaDumpFragment(@RequestBody String calFragmentJson) throws IOException{ if(!saveDump(calFragmentJson,SpotCheckRefType.SENATE_SITE_AGENDA)){ return new SimpleResponse(false, "could not save dump :(", "agenda-dump-failed"); } return new SimpleResponse(true, "agenda dump received. Thanks!", "agenda-dump-received"); } /** * This method saves FragmentJson received with appropriate SpotchekRefType * @param fragmentJson: Bill or Calendar or Agenda Dump * @param refType: Bill or Calendar or Agenda SpotCheckRefType * @return true: if successful or false: otherwise * @throws IOException */ private boolean saveDump(String fragmentJson, SpotCheckRefType refType) throws IOException{ SenateSiteDumpFragment fragment = parser.parseFragment(fragmentJson, refType); try { senateSiteDao.saveDumpFragment(fragment, fragmentJson); } catch (IOException ex) { return false; } asyncRunner.run(() -> eventBus.post(new SpotCheckReferenceEvent(refType))); return true; } /** Exception Handling */ @ExceptionHandler(SenateSiteDumpFragParserException.class) @ResponseStatus(value = HttpStatus.BAD_REQUEST) protected ErrorResponse handleBadJsonData(SenateSiteDumpFragParserException ex) { logger.error("Senate site dump fragment json parsing error", ex); return new ViewObjectErrorResponse(ErrorCode.SENATE_SITE_JSON_DUMP_MISSING_FIELDS, ex.getMessage()); } }