package ca.intelliware.ihtsdo.mlds.web.rest;
import java.io.IOException;
import javax.annotation.Resource;
import javax.annotation.security.RolesAllowed;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.transaction.Transactional;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import ca.intelliware.ihtsdo.mlds.domain.ReleaseFile;
import ca.intelliware.ihtsdo.mlds.domain.ReleaseVersion;
import ca.intelliware.ihtsdo.mlds.repository.ReleaseFileRepository;
import ca.intelliware.ihtsdo.mlds.repository.ReleaseVersionRepository;
import ca.intelliware.ihtsdo.mlds.security.AuthoritiesConstants;
import ca.intelliware.ihtsdo.mlds.service.UserMembershipAccessor;
import com.codahale.metrics.annotation.Timed;
@RestController
public class ReleaseFilesResource {
@Resource
ReleaseVersionRepository releaseVersionRepository;
@Resource
ReleaseFileRepository releaseFileRepository;
@Resource
ReleasePackageAuditEvents releasePackageAuditEvents;
@Resource
ReleasePackageAuthorizationChecker authorizationChecker;
@Resource
UriDownloader uriDownloader;
@Resource
UserMembershipAccessor userMembershipAccessor;
////////////////////////////////////////////////////////////////////////////////////////////////////////
// Release Files
@RequestMapping(value = Routes.RELEASE_FILE,
method = RequestMethod.GET,
produces = MediaType.APPLICATION_JSON_VALUE)
@RolesAllowed({ AuthoritiesConstants.USER, AuthoritiesConstants.MEMBER, AuthoritiesConstants.STAFF, AuthoritiesConstants.ADMIN })
@Timed
public @ResponseBody ResponseEntity<ReleaseFile> getReleaseFile(@PathVariable long releasePackageId, @PathVariable long releaseVersionId, @PathVariable long releaseFileId) {
ReleaseFile releaseFile = releaseFileRepository.findOne(releaseFileId);
if (releaseFile == null) {
return new ResponseEntity<>(HttpStatus.NOT_FOUND);
}
//FIXME should we check children being consistent?
authorizationChecker.checkCanEditReleasePackage(releaseFile.getReleaseVersion().getReleasePackage());
return new ResponseEntity<ReleaseFile>(releaseFile, HttpStatus.OK);
}
@RequestMapping(value = Routes.RELEASE_FILES,
method = RequestMethod.POST,
produces = MediaType.APPLICATION_JSON_VALUE)
@Transactional
@RolesAllowed({ AuthoritiesConstants.STAFF, AuthoritiesConstants.ADMIN })
@Timed
public @ResponseBody ResponseEntity<ReleaseFile> createReleaseFile(@PathVariable long releasePackageId, @PathVariable long releaseVersionId, @RequestBody ReleaseFile body) {
ReleaseVersion releaseVersion = releaseVersionRepository.findOne(releaseVersionId);
if (releaseVersion == null) {
return new ResponseEntity<>(HttpStatus.NOT_FOUND);
}
authorizationChecker.checkCanEditReleasePackage(releaseVersion.getReleasePackage());
releaseFileRepository.save(body);
releaseVersion.addReleaseFile(body);
releasePackageAuditEvents.logCreationOf(body);
return new ResponseEntity<ReleaseFile>(body, HttpStatus.OK);
}
@RolesAllowed({AuthoritiesConstants.STAFF, AuthoritiesConstants.ADMIN})
@RequestMapping(value = Routes.RELEASE_FILE,
method = RequestMethod.DELETE,
produces = MediaType.APPLICATION_JSON_VALUE)
@Transactional
@Timed
public @ResponseBody ResponseEntity<ReleaseFile> deleteReleaseFile(@PathVariable long releasePackageId, @PathVariable long releaseVersionId, @PathVariable long releaseFileId) {
ReleaseFile releaseFile = releaseFileRepository.findOne(releaseFileId);
if (releaseFile == null) {
return new ResponseEntity<>(HttpStatus.NOT_FOUND);
}
authorizationChecker.checkCanEditReleasePackage(releaseFile.getReleaseVersion().getReleasePackage());
releaseFileRepository.delete(releaseFile);
releasePackageAuditEvents.logDeletionOf(releaseFile);
return new ResponseEntity<ReleaseFile>(HttpStatus.OK);
}
@RequestMapping(value = Routes.RELEASE_FILE_DOWNLOAD,
method = RequestMethod.GET)
@RolesAllowed({ AuthoritiesConstants.USER, AuthoritiesConstants.MEMBER, AuthoritiesConstants.STAFF, AuthoritiesConstants.ADMIN })
@Timed
public @ResponseBody
void downloadReleaseFile(@PathVariable long releasePackageId, @PathVariable long releaseVersionId, @PathVariable long releaseFileId,
HttpServletRequest request, HttpServletResponse response) throws IOException {
ReleaseFile releaseFile = releaseFileRepository.findOne(releaseFileId);
if (releaseFile == null) {
//TODO better 404 handling
throw new RuntimeException("no such file found");
}
//FIXME should we check children being consistent?
authorizationChecker.checkCanDownloadReleaseVersion(releaseFile.getReleaseVersion());
int statusCode = HttpStatus.INTERNAL_SERVER_ERROR.value();
try {
String downloadUrl = releaseFile.getDownloadUrl();
statusCode = uriDownloader.download(downloadUrl, request, response);
} finally {
releasePackageAuditEvents.logDownload(releaseFile, statusCode, userMembershipAccessor.getAffiliate());
}
}
}