/* * Copyright (c) 2016 ingenieux Labs * * Licensed 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 br.com.ingenieux.mojo.beanstalk.env; import com.amazonaws.services.elasticbeanstalk.model.EnvironmentDescription; import org.apache.commons.lang.Validate; import org.apache.maven.plugin.AbstractMojoExecutionException; import org.apache.maven.plugins.annotations.Mojo; import org.apache.maven.plugins.annotations.Parameter; import java.util.Collection; import br.com.ingenieux.mojo.beanstalk.AbstractBeanstalkMojo; import br.com.ingenieux.mojo.beanstalk.cmd.env.swap.SwapCNamesCommand; import br.com.ingenieux.mojo.beanstalk.cmd.env.swap.SwapCNamesContext; import br.com.ingenieux.mojo.beanstalk.cmd.env.swap.SwapCNamesContextBuilder; import br.com.ingenieux.mojo.beanstalk.cmd.env.waitfor.WaitForEnvironmentCommand; import br.com.ingenieux.mojo.beanstalk.cmd.env.waitfor.WaitForEnvironmentContextBuilder; import br.com.ingenieux.mojo.beanstalk.util.EnvironmentHostnameUtil; import static java.lang.String.format; import static org.apache.commons.lang.StringUtils.defaultString; import static org.apache.commons.lang.StringUtils.isBlank; import static org.apache.commons.lang.StringUtils.isNotBlank; /** * Lists the available solution stacks * * See the docs for the <a href= "http://docs.amazonwebservices.com/elasticbeanstalk/latest/api/API_SwapEnvironmentCNAMEs.html" * >SwapEnvironmentCNAMEs API</a> call. * * @author Aldrin Leal * @since 0.2.3 */ @Mojo(name = "swap-environment-cnames") public class SwapEnvironmentCnamesMojo extends AbstractBeanstalkMojo { /** * Beanstalk Application Name */ @Parameter(property = "beanstalk.applicationName", defaultValue = "${project.artifactId}", required = true) String applicationName; /** * EnvironmentRef of source environment */ @Parameter(property = "beanstalk.sourceEnvironmentRef") String sourceEnvironmentRef; /** * EnvironmentRef of target environment */ @Parameter(property = "beanstalk.targetEnvironmentRef") String targetEnvironmentRef; /** * cname of source environment */ @Parameter(property = "beanstalk.sourceEnvironmentCNamePrefix") String sourceEnvironmentCNamePrefix; /** * cname of target environment */ @Parameter(property = "beanstalk.targetEnvironmentCNamePrefix") String targetEnvironmentCNamePrefix; boolean nonBlank(String... args) { for (String a : args) if (isBlank(a)) return false; return true; } @Override protected Object executeInternal() throws AbstractMojoExecutionException { SwapCNamesContext context; if (nonBlank(sourceEnvironmentRef, targetEnvironmentRef)) { EnvironmentDescription e0 = findOnly( new WaitForEnvironmentCommand(this) .lookupInternal( new WaitForEnvironmentContextBuilder().withApplicationName(applicationName).withEnvironmentRef(sourceEnvironmentRef).build())); EnvironmentDescription e1 = findOnly( new WaitForEnvironmentCommand(this) .lookupInternal( new WaitForEnvironmentContextBuilder().withApplicationName(applicationName).withEnvironmentRef(targetEnvironmentRef).build())); Validate.isTrue(isNotBlank(e0.getCNAME()), format("Environment '%s' must be non-worker (thus having a cname)", e1.getEnvironmentId())); Validate.isTrue(isNotBlank(e1.getCNAME()), format("Environment '%s' must be non-worker (thus having a cname)", e1.getEnvironmentId())); context = SwapCNamesContextBuilder.swapCNamesContext() // .withSourceEnvironmentId(e0.getEnvironmentId()) // .withDestinationEnvironmentId(e1.getEnvironmentId()) // .build(); } else if (nonBlank(sourceEnvironmentCNamePrefix, targetEnvironmentCNamePrefix)) { sourceEnvironmentCNamePrefix = defaultString(sourceEnvironmentCNamePrefix); targetEnvironmentCNamePrefix = defaultString(targetEnvironmentCNamePrefix); Validate.isTrue( sourceEnvironmentCNamePrefix.matches("[\\p{Alnum}\\-]{4,63}"), "Invalid Source Environment CName Prefix: " + sourceEnvironmentCNamePrefix); Validate.isTrue( targetEnvironmentCNamePrefix.matches("[\\p{Alnum}\\-]{4,63}"), "Invalid Target Environment CName Prefix: " + targetEnvironmentCNamePrefix); EnvironmentDescription sourceEnvironment = lookupEnvironment(applicationName, EnvironmentHostnameUtil.ensureSuffix(sourceEnvironmentCNamePrefix, getRegion())); EnvironmentDescription targetEnvironment = lookupEnvironment(applicationName, EnvironmentHostnameUtil.ensureSuffix(targetEnvironmentCNamePrefix, getRegion())); // TODO: Why 'destination' instead of 'target'? Make it consistent context = SwapCNamesContextBuilder.swapCNamesContext() // .withSourceEnvironmentId(sourceEnvironment.getEnvironmentId()) // .withDestinationEnvironmentId(targetEnvironment.getEnvironmentId()) // .build(); } else { throw new IllegalArgumentException("You must supply either {source,target}EnvironmentCNamePrefix or {source,target}EnvironmentRef"); } SwapCNamesCommand command = new SwapCNamesCommand(this); return command.execute(context); } private EnvironmentDescription findOnly(Collection<EnvironmentDescription> environmentDescriptions) { Validate.isTrue(1 == environmentDescriptions.size(), "More than one environment matches spec"); return environmentDescriptions.iterator().next(); } }