/**
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.camel.itest.springboot.util;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.nio.file.Files;
import java.nio.file.attribute.BasicFileAttributes;
import java.nio.file.attribute.FileTime;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import org.apache.commons.io.FileUtils;
import org.apache.maven.repository.internal.MavenRepositorySystemUtils;
import org.eclipse.aether.DefaultRepositorySystemSession;
import org.eclipse.aether.RepositorySystem;
import org.eclipse.aether.artifact.Artifact;
import org.eclipse.aether.artifact.DefaultArtifact;
import org.eclipse.aether.connector.basic.BasicRepositoryConnectorFactory;
import org.eclipse.aether.deployment.DeployRequest;
import org.eclipse.aether.graph.Dependency;
import org.eclipse.aether.impl.DefaultServiceLocator;
import org.eclipse.aether.repository.LocalRepository;
import org.eclipse.aether.repository.RemoteRepository;
import org.eclipse.aether.resolution.ArtifactDescriptorRequest;
import org.eclipse.aether.resolution.ArtifactDescriptorResult;
import org.eclipse.aether.spi.connector.RepositoryConnectorFactory;
import org.eclipse.aether.spi.connector.transport.TransporterFactory;
import org.eclipse.aether.transport.file.FileTransporterFactory;
import org.eclipse.aether.transport.http.HttpTransporterFactory;
import static org.apache.camel.itest.springboot.util.LocationUtils.camelRoot;
public final class BOMResolver {
private static final String LOCAL_REPO = "target/maven-aether-repo";
private static final File CACHE_FILE = LocationUtils.camelRoot("tests/camel-itest-spring-boot/target/bom-versions-cache");
private static final BOMResolver INSTANCE = new BOMResolver();
private Map<String, String> versions;
@SuppressWarnings("unchecked")
private BOMResolver() {
try {
cleanupLocalRepo();
if (canUseCache()) {
try (ObjectInputStream in = new ObjectInputStream(new FileInputStream(CACHE_FILE))) {
this.versions = (Map<String, String>) in.readObject();
}
} else {
retrieveUpstreamBOMVersions();
CACHE_FILE.delete();
try (ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream(CACHE_FILE))) {
out.writeObject(versions);
}
}
} catch (Exception e) {
throw new IllegalStateException("Cannot initialize the version resolver", e);
}
}
private boolean canUseCache() throws IOException {
if (CACHE_FILE.exists()) {
BasicFileAttributes attr = Files.readAttributes(CACHE_FILE.toPath(), BasicFileAttributes.class);
FileTime fileTime = attr != null ? attr.creationTime() : null;
Long time = fileTime != null ? fileTime.toMillis() : null;
// Update the cache every day
return time != null && time.compareTo(System.currentTimeMillis() - 1000 * 60 * 60 * 24) > 0;
}
return false;
}
private void retrieveUpstreamBOMVersions() throws Exception {
RepositorySystem system = newRepositorySystem();
DefaultRepositorySystemSession session = MavenRepositorySystemUtils.newSession();
LocalRepository localRepo = new LocalRepository(LOCAL_REPO);
session.setLocalRepositoryManager(system.newLocalRepositoryManager(session, localRepo));
String camelVersion = DependencyResolver.resolveCamelParentProperty("${project.version}");
List<Artifact> neededArtifacts = new LinkedList<>();
neededArtifacts.add(new DefaultArtifact("org.apache.camel:camel:pom:" + camelVersion).setFile(camelRoot("pom.xml")));
neededArtifacts.add(new DefaultArtifact("org.apache.camel:camel-parent:pom:" + camelVersion).setFile(camelRoot("parent/pom.xml")));
neededArtifacts.add(new DefaultArtifact("org.apache.camel:spring-boot:pom:" + camelVersion).setFile(camelRoot("platforms/spring-boot/pom.xml")));
neededArtifacts.add(new DefaultArtifact("org.apache.camel:camel-spring-boot-dm:pom:" + camelVersion).setFile(camelRoot("platforms/spring-boot/spring-boot-dm/pom.xml")));
neededArtifacts.add(new DefaultArtifact("org.apache.camel:camel-spring-boot-dependencies:pom:" + camelVersion).setFile(camelRoot("platforms/spring-boot/spring-boot-dm/camel-spring-boot-dependencies/pom.xml")));
Artifact camelSpringBootParent = new DefaultArtifact("org.apache.camel:camel-starter-parent:pom:" + camelVersion).setFile(camelRoot("platforms/spring-boot/spring-boot-dm/camel-starter-parent/pom.xml"));
neededArtifacts.add(camelSpringBootParent);
RemoteRepository localRepoDist = new RemoteRepository.Builder("org.apache.camel.itest.springboot", "default", new File(LOCAL_REPO).toURI().toString()).build();
for (Artifact artifact : neededArtifacts) {
DeployRequest deployRequest = new DeployRequest();
deployRequest.addArtifact(artifact);
deployRequest.setRepository(localRepoDist);
system.deploy(session, deployRequest);
}
RemoteRepository mavenCentral = new RemoteRepository.Builder("central", "default", "http://repo1.maven.org/maven2/").build();
RemoteRepository apacheSnapshots = new RemoteRepository.Builder("apache-snapshots", "default", "http://repository.apache.org/snapshots/").build();
ArtifactDescriptorRequest dReq = new ArtifactDescriptorRequest(camelSpringBootParent, Arrays.asList(localRepoDist, mavenCentral, apacheSnapshots), null);
ArtifactDescriptorResult dRes = system.readArtifactDescriptor(session, dReq);
this.versions = new TreeMap<>();
for (Dependency dependency : dRes.getManagedDependencies()) {
Artifact a = dependency.getArtifact();
String key = a.getGroupId() + ":" + a.getArtifactId();
versions.put(key, dependency.getArtifact().getVersion());
}
}
public static BOMResolver getInstance() {
return INSTANCE;
}
public String getBOMVersion(String groupId, String artifactId) {
return versions.get(groupId + ":" + artifactId);
}
private void cleanupLocalRepo() throws IOException {
File f = new File(LOCAL_REPO);
if (f.exists()) {
FileUtils.deleteDirectory(f);
}
}
private RepositorySystem newRepositorySystem() {
DefaultServiceLocator locator = MavenRepositorySystemUtils.newServiceLocator();
locator.addService(RepositoryConnectorFactory.class, BasicRepositoryConnectorFactory.class);
locator.addService(TransporterFactory.class, FileTransporterFactory.class);
locator.addService(TransporterFactory.class, HttpTransporterFactory.class);
RepositorySystem system = locator.getService(RepositorySystem.class);
return system;
}
}