All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.lockss.laaws.rs.impl.ArchivesApiServiceImpl Maven / Gradle / Ivy

The newest version!
package org.lockss.laaws.rs.impl;

import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.ObjectWriter;
import org.apache.commons.io.FileUtils;
import org.archive.format.warc.WARCConstants;
import org.lockss.laaws.rs.api.ArchivesApiDelegate;
import org.lockss.log.L4JLogger;
import org.lockss.spring.base.BaseSpringApiServiceImpl;
import org.lockss.spring.error.LockssRestServiceException;
import org.lockss.util.StringUtil;
import org.lockss.util.io.DeferredTempFileOutputStream;
import org.lockss.util.rest.exception.LockssRestHttpException;
import org.lockss.util.rest.repo.LockssRepository;
import org.lockss.util.rest.repo.RestLockssRepository;
import org.lockss.util.rest.repo.model.ImportStatus;
import org.lockss.util.rest.repo.util.ArtifactCache;
import org.lockss.util.rest.repo.util.ImportStatusIterable;
import org.lockss.util.rest.repo.util.NamedInputStreamResource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.Resource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.util.MimeType;
import org.springframework.web.multipart.MultipartFile;

import javax.jms.JMSException;
import javax.jms.Message;
import jakarta.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.io.InputStream;
import java.util.*;

@Service
public class ArchivesApiServiceImpl extends BaseSpringApiServiceImpl implements ArchivesApiDelegate {
  private static L4JLogger log = L4JLogger.getLogger();
  private final MediaType APPLICATION_WARC = MediaType.valueOf("application/warc");

  @Autowired
  LockssRepository repo;

  private final HttpServletRequest request;

  @Autowired
  public ArchivesApiServiceImpl(HttpServletRequest request) {
    this.request = request;
  }

  /**
   * Controller for {@code POST /archives}.
   * 

* Imports the artifacts from an archive into this LOCKSS Repository Service. * * @param auId A {@link String} containing the AUID of the artifacts. * @param archive A {@link MultipartFile} containing the archive. * @param namespace A {@link String} containing the namespace of the artifacts. * @param storeDuplicate A {@link Boolean} indicating whether artifacts whose content is identical to the previous version should be stored * @param excludeStatusPattern A {@link String} containing a regexp. WARC records whose HTTP response status code matches will not be added to the repository * @return */ @Override public ResponseEntity addArtifacts(String auId, MultipartFile archive, String namespace, Boolean storeDuplicate, String excludeStatusPattern) { log.debug("archive.name = {}", archive.getName()); log.debug("archive.origFileName = {}", archive.getOriginalFilename()); log.debug("archive.type = {}", archive.getContentType()); if (!StringUtil.isNullString(excludeStatusPattern)) log.debug("excludeStatusPattern = {}", excludeStatusPattern); String parsedRequest = String.format("namespace: %s, auId: %s, requestUrl: %s", namespace, auId, ServiceImplUtil.getFullRequestUrl(request)); log.debug2("Parsed request: {}", parsedRequest); MimeType archiveType = MimeType.valueOf(archive.getContentType()); if (archiveType.equals(APPLICATION_WARC)) { try { boolean needCacheInvalidate = false; try (InputStream input = archive.getInputStream(); ImportStatusIterable result = repo.addArtifacts(namespace, auId, input, LockssRepository.ArchiveType.WARC, storeDuplicate, excludeStatusPattern)) { try (DeferredTempFileOutputStream out = new DeferredTempFileOutputStream((int) (16 * FileUtils.ONE_MB), (String) null)) { ObjectMapper objMapper = new ObjectMapper(); objMapper.disable(JsonGenerator.Feature.AUTO_CLOSE_TARGET); ObjectWriter objWriter = objMapper.writerFor(ImportStatus.class); // Write result to temporary file for (ImportStatus status : result) { if (ImportStatus.StatusEnum.OK == status.getStatus()) { needCacheInvalidate = true; } objWriter.writeValue(out, status); } out.flush(); if (needCacheInvalidate) { sendCacheInvalidateAu(ArtifactCache.InvalidateOp.Commit, auId); } // Set Content-Length of file HttpHeaders headers = new HttpHeaders(); headers.setContentLength(out.getByteCount()); // Return result as a Resource Resource jsonResult = new NamedInputStreamResource("result", out.getDeleteOnCloseInputStream()); return new ResponseEntity<>(jsonResult, headers, HttpStatus.OK); } } } catch (IOException e) { String errorMessage = "Error adding artifacts from archive"; throw new LockssRestServiceException(LockssRestHttpException.ServerErrorType.APPLICATION_ERROR, HttpStatus.INTERNAL_SERVER_ERROR, errorMessage, parsedRequest); } } else { String errorMessage = "Archive not supported"; throw new LockssRestServiceException(LockssRestHttpException.ServerErrorType.NONE, HttpStatus.BAD_REQUEST, errorMessage, parsedRequest); } } @jakarta.annotation.PostConstruct private void init() { setUpJms(JMS_SEND, RestLockssRepository.REST_ARTIFACT_CACHE_ID, RestLockssRepository.REST_ARTIFACT_CACHE_TOPIC); } protected void sendCacheInvalidateAu(ArtifactCache.InvalidateOp op, String auid) { if (jmsProducer != null && auid != null) { Map map = new HashMap<>(); map.put(RestLockssRepository.REST_ARTIFACT_CACHE_MSG_ACTION, RestLockssRepository.REST_ARTIFACT_CACHE_MSG_ACTION_INVALIDATE_AU); map.put(RestLockssRepository.REST_ARTIFACT_CACHE_MSG_OP, op.toString()); map.put(RestLockssRepository.REST_ARTIFACT_CACHE_MSG_KEY, auid); try { jmsProducer.sendMap(map); } catch (JMSException e) { log.error("Couldn't send cache invalidate notification", e); } } } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy