package nl.jpoint.vertx.deploy.agent; import io.vertx.core.json.JsonObject; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.net.URI; import java.nio.file.Path; import java.nio.file.Paths; public class DeployConfig { private static final Logger LOG = LoggerFactory.getLogger(AwsDeployApplication.class); private static final String MAVEN_CENTRAL = "https://repo1.maven.org/maven/"; private static final String DEFAULT_SERVICE_CONFIG_LOCATION = "/etc/default/"; private static final String VERTX_HOME = "vertx.home"; private static final String RUN_DIR = "vertx.run"; private static final String ARTIFACT_REPO = "artifact.storage"; private static final String AWS_ENABLED = "aws.enable"; private static final String AWS_REGION = "aws.region"; private static final String AWS_DEFAULT_REGION = "eu-west-1"; private static final String AWS_REGISTER_MAX_DURATION = "aws.as.register.maxduration"; private static final String CONFIG_LOCATION = "config.location"; private static final String SERVICE_CONFIG_LOCATION = "service.config.location"; private static final String HTTP_AUTH_USER = "http.authUser"; private static final String HTTP_PORT = "http.port"; private static final String HTTP_AUTH_PASS = "http.authPass"; private static final String MAVEN_REPO_URI = "maven.repo.uri"; private static final String MAVEN_SNAPSHOT_POLICY = "maven.repo.snapshot.policy"; private static final String CLUSTER = "vertx.clustering"; private static final String DEFAULT_JAVA_OPTS = "vertx.default.java.opts"; private static final String AWS_AS_AUTODISCOVER = "aws.as.autodiscover"; private static final String TYPED_DEPLOY = "typed.deploy"; private static final String POLL_INTERVAL = "aws.poll.interval"; private static final String AUTH_TOKEN = "auth.token"; private static final String AWS_INSTANCE_ID = "aws.elb.instanceid"; private static final String STAT_FILE = ".initial"; private final Path vertxHome; private final Path artifactRepo; private final URI nexusUrl; private String configLocation; private String awsRegion; private Integer httpPort; private String httpAuthUser; private String httpAuthPassword; private boolean awsEnabled = false; private boolean httpAuthentication = false; private boolean mavenRemote = true; private String awsLoadbalancerId; private int awsMaxRegistrationDuration; private String authToken; private boolean asCluster = true; private String remoteRepoPolicy; private String defaultJavaOpts; private String runDir; private String statFile; private boolean typedDeploy = false; private boolean awsAutoDiscover = false; private String serviceConfigLocation; private long pollInterval; private DeployConfig(String vertxHome, String artifactRepo, String nexusUrl) { this.vertxHome = Paths.get(vertxHome); this.artifactRepo = Paths.get(artifactRepo); if (nexusUrl == null || nexusUrl.isEmpty()) { this.mavenRemote = false; this.nexusUrl = null; } else { this.mavenRemote = true; this.nexusUrl = URI.create(nexusUrl); } } private static String validateRequiredField(String field, JsonObject config) { if (!config.containsKey(field) || config.getString(field).isEmpty()) { LOG.error("config missing config value for field {} ", field); throw new IllegalStateException("config missing config value for field " + field); } return (String) config.remove(field); } private static <T> T validateField(String field, JsonObject config) { return validateField(field, config, null); } private static <T> T validateField(String field, JsonObject config, T defaultValue) { if (config.containsKey(field) && config.getValue(field) != null) { return (T) config.remove(field); } return defaultValue; } static DeployConfig fromJsonObject(JsonObject config) { if (config == null) { LOG.error("Unable to read config file"); throw new IllegalStateException("Unable to read config file"); } String vertxHome = validateRequiredField(VERTX_HOME, config); String artifactRepo = validateRequiredField(ARTIFACT_REPO, config); String mavenRepo = validateField(MAVEN_REPO_URI, config, ""); if (mavenRepo.isEmpty()) { LOG.warn("'maven.repo.uri', using maven central"); mavenRepo = MAVEN_CENTRAL; } DeployConfig deployconfig = new DeployConfig(vertxHome, artifactRepo, mavenRepo) .withConfigLocation(config) .withServiceConfigLocation(config) .withHttpPort(config) .withAwsConfig(config) .withHttpAuth(config) .withAuthToken(config) .withCluster(config) .withRunDir(config) .withLoggerFactoryName(config) .withTypedDeploy(config) .withPollInterval(config) .withRemoteRepoUpdatePolicy(config); if (!config.isEmpty()) { config.fieldNames().forEach(s -> LOG.info("Unused variable in config '{}',", s)); } return deployconfig; } private DeployConfig withAuthToken(JsonObject config) { this.authToken = validateField(AUTH_TOKEN, config); return this; } private DeployConfig withTypedDeploy(JsonObject config) { this.typedDeploy = config.getBoolean(TYPED_DEPLOY, false); return this; } private DeployConfig withConfigLocation(JsonObject config) { this.configLocation = config.getString(CONFIG_LOCATION, ""); config.remove(CONFIG_LOCATION); return this; } private DeployConfig withPollInterval(JsonObject config) { this.pollInterval = config.getLong(POLL_INTERVAL, 3000L); config.remove(POLL_INTERVAL); return this; } private DeployConfig withServiceConfigLocation(JsonObject config) { this.serviceConfigLocation = config.getString(SERVICE_CONFIG_LOCATION, DEFAULT_SERVICE_CONFIG_LOCATION); config.remove(CONFIG_LOCATION); return this; } private DeployConfig withRunDir(JsonObject config) { this.runDir = config.getString(RUN_DIR, getVertxHome() + "/run/"); if (!runDir.endsWith("/")) { runDir = runDir + "/"; } this.statFile = runDir + STAT_FILE; config.remove(RUN_DIR); return this; } private DeployConfig withRemoteRepoUpdatePolicy(JsonObject config) { this.remoteRepoPolicy = config.getString(MAVEN_SNAPSHOT_POLICY, "always"); config.remove(MAVEN_SNAPSHOT_POLICY); return this; } private DeployConfig withCluster(JsonObject config) { this.asCluster = config.getBoolean(CLUSTER, true); config.remove(CLUSTER); return this; } private DeployConfig withLoggerFactoryName(JsonObject config) { this.defaultJavaOpts = config.getString(DEFAULT_JAVA_OPTS, ""); config.remove(DEFAULT_JAVA_OPTS); return this; } private DeployConfig withAwsConfig(JsonObject config) { this.awsRegion = validateField(AWS_REGION, config, AWS_DEFAULT_REGION); this.awsLoadbalancerId = validateField(AWS_INSTANCE_ID, config); this.awsEnabled = validateField(AWS_ENABLED, config, false); this.awsAutoDiscover = validateField(AWS_AS_AUTODISCOVER, config, false); this.awsMaxRegistrationDuration = config.getInteger(AWS_REGISTER_MAX_DURATION, 4); config.remove(AWS_REGISTER_MAX_DURATION); if (awsEnabled) { LOG.info("Enabled AWS support."); } else { LOG.info("Disabled AWS support."); } return this; } private DeployConfig withHttpAuth(JsonObject config) { this.httpAuthUser = validateField(HTTP_AUTH_USER, config, ""); this.httpAuthPassword = validateField(HTTP_AUTH_PASS, config, ""); if (!httpAuthUser.isEmpty() && !httpAuthPassword.isEmpty()) { LOG.info("Enabled http authentication."); this.httpAuthentication = true; } else { LOG.info("Disabled http authentication."); } return this; } private DeployConfig withHttpPort(JsonObject config) { this.httpPort = Integer.valueOf(validateField(HTTP_PORT, config, "6789")); return this; } public Path getVertxHome() { return vertxHome; } public Path getArtifactRepo() { return artifactRepo; } public URI getNexusUrl() { return nexusUrl; } public String getConfigLocation() { return configLocation; } public String getAwsRegion() { return awsRegion; } public String getAwsLoadbalancerId() { return awsLoadbalancerId; } public int getAwsMaxRegistrationDuration() { return awsMaxRegistrationDuration; } public String getHttpAuthUser() { return httpAuthUser; } public String getHttpAuthPassword() { return httpAuthPassword; } public boolean isAwsEnabled() { return awsEnabled; } public boolean isHttpAuthentication() { return httpAuthentication; } public boolean isMavenRemote() { return mavenRemote; } public String getAuthToken() { return authToken; } public boolean asCluster() { return asCluster; } public String getRemoteRepoPolicy() { return remoteRepoPolicy; } public String getDefaultJavaOpts() { return defaultJavaOpts; } public Integer getHttpPort() { return this.httpPort; } public String getRunDir() { return runDir; } public String getStatFile() { return statFile; } public boolean isAwsAutoDiscover() { return awsAutoDiscover; } public String getServiceConfigLocation() { return serviceConfigLocation; } public boolean isTypedDeploy() { return this.typedDeploy; } public long getPollIntervall() { return pollInterval; } }