package org.arquillian.cube.kubernetes.fabric8.impl.annotation;
import org.arquillian.cube.impl.util.IOUtil;
import org.arquillian.cube.impl.util.Strings;
import org.arquillian.cube.impl.util.SystemEnvironmentVariables;
import org.arquillian.cube.kubernetes.api.AnnotationProvider;
import org.arquillian.cube.kubernetes.api.Logger;
import org.jboss.arquillian.core.api.Instance;
import org.jboss.arquillian.core.api.annotation.ApplicationScoped;
import org.jboss.arquillian.core.api.annotation.Inject;
import org.jboss.arquillian.core.spi.Validate;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.StringReader;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
public class Fabric8AnnotationProvider implements AnnotationProvider {
public static final String GIT_COMMIT = "fabric8.io/git-commit";
public static final String GIT_URL = "fabric8.io/git-url";
public static final String GIT_BRANCH = "fabric8.io/git-branch";
public static final String PROJECT_PREFIX = "fabric8.io/project-";
@Inject
@ApplicationScoped
Instance<Logger> logger;
private AnnotationProvider delegate;
@Override
public AnnotationProvider toImmutable() {
if (delegate != null) {
return delegate;
}
synchronized (this) {
if (delegate == null) {
delegate = new ImmutableFabric8AnnotationProvider(logger.get());
}
}
return delegate;
}
@Override
public Map<String, String> create(String sessionId, String status) {
return toImmutable().create(sessionId, status);
}
public static class ImmutableFabric8AnnotationProvider implements AnnotationProvider {
private final Logger logger;
private ImmutableFabric8AnnotationProvider(Logger logger) {
Validate.notNull(logger, "A Logger instance is required.");
this.logger = logger;
}
@Override
public Map<String, String> create(String sessionId, String status) {
Map<String, String> annotations = new HashMap<>();
annotations.put(SESSION_ID, sessionId);
annotations.put(TEST_SESSION_STATUS, status);
File baseDir = getProjectBaseDir();
String gitUrl = getGitUrl(baseDir);
if (Strings.isNotNullOrEmpty(gitUrl)) {
annotations.put(GIT_URL, gitUrl);
}
annotations.putAll(getPomProperties(baseDir));
return annotations;
}
private Map<String, String> getPomProperties(File baseDir) {
Map<String, String> annotations = new HashMap<>();
// lets see if there's a maven generated set of pom properties
File pomProperties = new File(baseDir, "target/maven-archiver/pom.properties");
if (pomProperties.isFile()) {
try {
Properties properties = new Properties();
properties.load(new FileInputStream(pomProperties));
for (Object o : properties.keySet()) {
String key = String.valueOf(o);
String value = String.valueOf(properties.get(o));
if (Strings.isNotNullOrEmpty(key) && Strings.isNotNullOrEmpty(value)) {
annotations.put(PROJECT_PREFIX + key, value);
}
}
} catch (IOException e) {
logger.warn("Failed to load:[ " + pomProperties + "] file to annotate the namespace. Due to: " + e);
}
}
return annotations;
}
private String getGitUrl(File basedir) {
if (basedir.exists() && basedir.isDirectory()) {
File gitConfig = new File(basedir, ".git/config");
if (gitConfig.isFile() && gitConfig.exists()) {
try (InputStream is = new FileInputStream(gitConfig)) {
String text = IOUtil.asString(is);
if (text != null) {
return getGitUrl(text);
}
} catch (IOException e) {
logger.warn("Failed to read:[ " + gitConfig + "] file to annotate the namespace. Due to: " + e);
}
}
}
File parentFile = basedir.getParentFile();
if (parentFile != null) {
return getGitUrl(parentFile);
}
return null;
}
private static File getProjectBaseDir() {
String basedir = SystemEnvironmentVariables.getPropertyVariable("basedir", ".");
return new File(basedir);
}
private static String getGitUrl(String configText) {
String remote = null;
String lastUrl = null;
String firstUrl = null;
BufferedReader reader = new BufferedReader(new StringReader(configText));
Map<String, String> remoteUrls = new HashMap<>();
while (true) {
String line = null;
try {
line = reader.readLine();
} catch (IOException e) {
// ignore should never happen!
}
if (line == null) {
break;
}
if (line.startsWith("[remote ")) {
String[] parts = line.split("\"");
if (parts.length > 1) {
remote = parts[1];
}
} else if (line.startsWith("[")) {
remote = null;
} else if (remote != null && line.length() > 0 && Character.isWhitespace(line.charAt(0))) {
String trimmed = line.trim();
if (trimmed.startsWith("url ")) {
String[] parts = trimmed.split("=", 2);
if (parts.length > 1) {
lastUrl = parts[1].trim();
if (firstUrl == null) {
firstUrl = lastUrl;
}
remoteUrls.put(remote, lastUrl);
}
}
}
}
String answer = null;
if (remoteUrls.size() == 1) {
return lastUrl;
} else if (remoteUrls.size() > 1) {
answer = remoteUrls.get("origin");
if (answer == null) {
answer = firstUrl;
}
}
return answer;
}
@Override
public AnnotationProvider toImmutable() {
return this;
}
}
}