package io.cattle.platform.configitem.server.model.impl;
import io.cattle.platform.configitem.model.ItemVersion;
import io.cattle.platform.configitem.server.model.Request;
import io.cattle.platform.configitem.version.ConfigItemStatusManager;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.security.DigestOutputStream;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.zip.GZIPOutputStream;
import org.apache.commons.codec.binary.Hex;
import org.apache.commons.compress.archivers.tar.TarArchiveOutputStream;
import org.apache.commons.io.IOUtils;
import org.apache.commons.io.output.NullOutputStream;
public class LocalArchiveConfigItem extends AbstractConfigItem {
File file;
String revision;
public LocalArchiveConfigItem(File file, String name, ConfigItemStatusManager versionManager) throws IOException {
super(name, versionManager);
this.file = file;
this.hash();
}
public void hash() throws IOException {
DigestOutputStream os = null;
try {
os = new DigestOutputStream(new NullOutputStream(), MessageDigest.getInstance("SHA-256"));
copyFile(os);
os.close();
revision = Hex.encodeHexString(os.getMessageDigest().digest());
os = null;
} catch (NoSuchAlgorithmException e) {
throw new IOException(e);
} finally {
IOUtils.closeQuietly(os);
}
}
@Override
public void handleRequest(Request req) throws IOException {
req.setContentType("application/octet-stream");
if (!upToDate(req)) {
OutputStream os = req.getOutputStream();
os.write(String.format("version:%s\n", getVersion(req)).getBytes("UTF-8"));
copyFile(os);
}
}
protected boolean upToDate(Request req) throws IOException {
ItemVersion current = req.getCurrentVersion();
String version = getVersion(req);
if (current != null && current.toExternalForm().equals(version)) {
OutputStream os = req.getOutputStream();
GZIPOutputStream gzos = new GZIPOutputStream(os);
TarArchiveOutputStream taos = null;
try {
taos = new TarArchiveOutputStream(gzos);
taos.setLongFileMode(TarArchiveOutputStream.LONGFILE_GNU);
ArchiveContext context = new ArchiveContext(req, taos, version);
AbstractArchiveBasedConfigItem.writeUpToDate(context);
AbstractArchiveBasedConfigItem.writeVersion(context);
AbstractArchiveBasedConfigItem.writeHashes(context);
} finally {
IOUtils.closeQuietly(taos);
}
return true;
}
return false;
}
protected void copyFile(OutputStream os) throws IOException {
try (FileInputStream fis = new FileInputStream(file)) {
IOUtils.copyLarge(fis, os, new byte[1024 * 128]);
}
}
@Override
public String getSourceRevision() {
return revision;
}
}