package io.airlift.airship.coordinator;
import com.google.common.collect.ImmutableList;
import com.google.common.io.Files;
import io.airlift.airship.coordinator.MavenMetadata.Snapshot;
import io.airlift.airship.coordinator.MavenMetadata.SnapshotVersion;
import io.airlift.airship.coordinator.MavenMetadata.Versioning;
import io.airlift.airship.shared.MavenCoordinates;
import io.airlift.airship.shared.Repository;
import java.io.File;
import java.io.FileOutputStream;
import java.net.URI;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
import static com.google.common.base.Charsets.UTF_8;
import static com.google.common.base.Objects.firstNonNull;
import static com.google.common.io.Files.asByteSink;
import static com.google.common.io.Resources.getResource;
import static com.google.common.io.Resources.asByteSource;
import static io.airlift.airship.shared.ArchiveHelper.createArchive;
import static io.airlift.airship.shared.FileUtils.createTempDir;
import static io.airlift.airship.shared.FileUtils.deleteRecursively;
import static io.airlift.airship.shared.FileUtils.newFile;
import static io.airlift.airship.shared.MavenCoordinates.toBinaryGAV;
import static io.airlift.airship.shared.MavenCoordinates.toConfigGAV;
public class TestingMavenRepository
extends MavenRepository
{
public static final Repository MOCK_REPO = new Repository()
{
@Override
public String configRelativize(String config)
{
return null;
}
@Override
public String configResolve(String config)
{
return config;
}
@Override
public String configShortName(String config)
{
return config;
}
@Override
public String configUpgrade(String config, String version)
{
MavenCoordinates coordinates = MavenCoordinates.fromConfigGAV(config);
if (coordinates == null) {
return null;
}
coordinates = new MavenCoordinates(coordinates.getGroupId(),
coordinates.getArtifactId(),
version,
coordinates.getPackaging(),
coordinates.getClassifier(),
null);
return toConfigGAV(coordinates);
}
@Override
public boolean configEqualsIgnoreVersion(String config1, String config2)
{
MavenCoordinates coordinates1 = MavenCoordinates.fromConfigGAV(config1);
MavenCoordinates coordinates2 = MavenCoordinates.fromConfigGAV(config2);
return coordinates1 != null &&
coordinates2 != null &&
coordinates1.equalsIgnoreVersion(coordinates2);
}
@Override
public URI configToHttpUri(String config)
{
return URI.create("fake://config/" + config);
}
@Override
public String binaryRelativize(String config)
{
return null;
}
@Override
public String binaryResolve(String binary)
{
return binary;
}
@Override
public String binaryUpgrade(String binary, String version)
{
MavenCoordinates coordinates = MavenCoordinates.fromBinaryGAV(binary);
if (coordinates == null) {
return null;
}
coordinates = new MavenCoordinates(coordinates.getGroupId(),
coordinates.getArtifactId(),
version,
coordinates.getPackaging(),
coordinates.getClassifier(),
null);
return toBinaryGAV(coordinates);
}
@Override
public boolean binaryEqualsIgnoreVersion(String binary1, String binary2)
{
MavenCoordinates coordinates1 = MavenCoordinates.fromBinaryGAV(binary1);
MavenCoordinates coordinates2 = MavenCoordinates.fromBinaryGAV(binary2);
return coordinates1 != null &&
coordinates2 != null &&
coordinates1.equalsIgnoreVersion(coordinates2);
}
@Override
public URI binaryToHttpUri(String binary)
{
return URI.create("fake://binary/" + binary);
}
};
private final File targetRepo;
public TestingMavenRepository()
throws Exception
{
this(createBinaryRepoDir());
}
public TestingMavenRepository(File targetRepo)
{
super(ImmutableList.<String>of("prod", "food.fruit"), targetRepo.toURI());
this.targetRepo = targetRepo;
}
public File getTargetRepo()
{
return targetRepo;
}
public void destroy()
{
deleteRecursively(targetRepo);
}
public static File createBinaryRepoDir()
throws Exception
{
File targetRepo = null;
try {
targetRepo = createTempDir("repo");
// copy maven-metadata.xml files
File appleMavenMetadata = new File(targetRepo, "food/fruit/apple/maven-metadata.xml");
appleMavenMetadata.getParentFile().mkdirs();
asByteSource(getResource(TestingMavenRepository.class, "apple-maven-metadata.xml")).copyTo(asByteSink(appleMavenMetadata));
File bananaMavenMetadata = new File(targetRepo, "food/fruit/banana/2.0-SNAPSHOT/maven-metadata.xml");
bananaMavenMetadata.getParentFile().mkdirs();
asByteSource(getResource(TestingMavenRepository.class, "banana-maven-metadata.xml")).copyTo(asByteSink(bananaMavenMetadata));
// tar up the archive and add them to the repository
File appleArchiveV1 = new File(targetRepo, "food/fruit/apple/1.0/apple-1.0.tar.gz");
File appleArchiveV2 = new File(targetRepo, "food/fruit/apple/2.0/apple-2.0.tar.gz");
File bananaArchive = new File(targetRepo, "food/fruit/banana/2.0-SNAPSHOT/banana-2.0-20110311.201909-1.tar.gz");
createArchive(appleArchiveV1);
appleArchiveV2.getParentFile().mkdirs();
Files.copy(appleArchiveV1, appleArchiveV2);
bananaArchive.getParentFile().mkdirs();
Files.copy(appleArchiveV1, bananaArchive);
// add prod configurations
initConfigRepo(targetRepo, "prod");
return targetRepo;
}
catch (Exception e) {
if (targetRepo != null) {
deleteRecursively(targetRepo);
}
throw e;
}
}
public static void initConfigRepo(File targetRepo, String groupId)
throws Exception
{
createConfig(targetRepo, groupId, "apple", "1.0", null);
createConfig(targetRepo, groupId, "apple", "2.0", null);
createConfig(targetRepo, groupId, "banana", "2.0-SNAPSHOT", "2.0-20110311.201909-1");
createMavenMetadata(targetRepo, groupId, "apple", ImmutableList.of(new VersionInfo("1.0"), new VersionInfo("2.0")));
createMavenMetadata(targetRepo, groupId, "banana", ImmutableList.of(new VersionInfo("2.0-SNAPSHOT", "20110311.201909", "1")));
}
public static void createConfig(File dir, String groupId, String artifactId, String version, String timestampVersion)
throws Exception
{
File configFile = newFile(dir,
groupId,
artifactId,
version,
artifactId + "-" + firstNonNull(timestampVersion, version) + ".config");
configFile.getParentFile().mkdirs();
ZipOutputStream out = new ZipOutputStream(new FileOutputStream(configFile));
// text file
out.putNextEntry(new ZipEntry(artifactId + ".txt"));
out.write(artifactId.getBytes(UTF_8));
// config.properties
out.putNextEntry(new ZipEntry("config.properties"));
String properties = "http-server.http.port=0\n" +
"config=" + artifactId;
out.write(properties.getBytes(UTF_8));
// jvm.config
out.putNextEntry(new ZipEntry("jvm.config"));
// config.properties
String resources;
if ("apple".equals(artifactId)) {
resources = "memory=512\n" +
"cpu=1";
}
else {
resources = "memory=1024\n" +
"cpu=2";
}
out.putNextEntry(new ZipEntry("airship-resources.properties"));
out.write(resources.getBytes(UTF_8));
out.close();
}
private static void createMavenMetadata(File dir, String groupId, String artifactId, Iterable<VersionInfo> versions)
throws Exception
{
MavenMetadata mavenMetadata = new MavenMetadata();
mavenMetadata.groupId = groupId;
mavenMetadata.artifactId = artifactId;
mavenMetadata.versioning = new Versioning();
for (VersionInfo version : versions) {
mavenMetadata.versioning.versions.add(version.version);
}
MavenMetadata.marshalMavenMetadata(newFile(dir, groupId, artifactId, "maven-metadata.xml"), mavenMetadata);
for (VersionInfo version : versions) {
if (version.version.contains("-SNAPSHOT")) {
MavenMetadata snapshotMetadata = new MavenMetadata();
snapshotMetadata.groupId = groupId;
snapshotMetadata.artifactId = artifactId;
snapshotMetadata.version = version.version;
snapshotMetadata.versioning = new Versioning();
snapshotMetadata.versioning.snapshot = new Snapshot();
snapshotMetadata.versioning.snapshot.timestamp = version.timestamp;
snapshotMetadata.versioning.snapshot.buildNumber = version.buildNumber;
SnapshotVersion snapshotVersion = new SnapshotVersion();
snapshotVersion.extension = "config";
snapshotVersion.value = String.format("%s-%s-%s",
version.version.replaceAll("-SNAPSHOT", ""),
version.timestamp,
version.buildNumber);
snapshotMetadata.versioning.snapshotVersions.add(snapshotVersion);
MavenMetadata.marshalMavenMetadata(newFile(dir, groupId, artifactId, version.version, "maven-metadata.xml"), snapshotMetadata);
}
}
}
private static class VersionInfo
{
public final String version;
public final String timestamp;
public final String buildNumber;
private VersionInfo(String version)
{
this(version, null, null);
}
private VersionInfo(String version, String timestamp, String buildNumber)
{
this.version = version;
this.timestamp = timestamp;
this.buildNumber = buildNumber;
}
}
}