package de.is24.infrastructure.gridfs.http.metadata.generation; import de.is24.infrastructure.gridfs.http.jaxb.Data; import de.is24.infrastructure.gridfs.http.jaxb.RepoMd; import de.is24.infrastructure.gridfs.http.security.PGPSigner; import de.is24.infrastructure.gridfs.http.storage.FileDescriptor; import de.is24.infrastructure.gridfs.http.storage.FileStorageService; import de.is24.util.monitoring.spring.TimeMeasurement; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import javax.xml.bind.JAXBContext; import javax.xml.bind.JAXBException; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.util.List; @Service @TimeMeasurement public class RepoMdGenerator { public static final int INITIAL_BUFFER_SIZE = 4 * 1024; private final FileStorageService fileStorageService; private final JAXBContext jaxbContext; private final PGPSigner pgpSigner; /* for cglib */ protected RepoMdGenerator() { jaxbContext = null; fileStorageService = null; pgpSigner = null; } @Autowired public RepoMdGenerator(FileStorageService fileStorageService, PGPSigner pgpSigner) { this.fileStorageService = fileStorageService; this.pgpSigner = pgpSigner; try { this.jaxbContext = JAXBContext.newInstance(RepoMd.class); } catch (JAXBException e) { throw new IllegalStateException("Could not initialize JAXBContext.", e); } } public void generateRepoMdXml(final String reponame, final List<Data> data) { byte[] content = createXml(createRepoMd(createRevision(), data)); fileStorageService.storeFile(new ByteArrayInputStream(content), new FileDescriptor(filename(reponame)), true); if (pgpSigner.isActive()) { byte[] signature = pgpSigner.sign(content); fileStorageService.storeFile(new ByteArrayInputStream(signature), new FileDescriptor(signatureFilename(reponame)), true); } } private byte[] createXml(RepoMd repoMd) { ByteArrayOutputStream tempOutputStream = new ByteArrayOutputStream(INITIAL_BUFFER_SIZE); try { jaxbContext.createMarshaller().marshal(repoMd, tempOutputStream); } catch (JAXBException e) { throw new IllegalStateException("Unable to marshall RepoMd object.", e); } return tempOutputStream.toByteArray(); } private String filename(String reponame) { return reponame + "/repodata/repomd.xml"; } private String signatureFilename(String reponame) { return filename(reponame) + ".asc"; } private RepoMd createRepoMd(long revision, List<Data> data) { RepoMd repoMd = new RepoMd(); repoMd.setRevision(revision); repoMd.setData(data); return repoMd; } private long createRevision() { return System.currentTimeMillis(); } }