1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package br.com.ingenieux.mojo.beanstalk.version;
18
19 import com.amazonaws.services.elasticbeanstalk.model.ApplicationVersionDescription;
20 import com.amazonaws.services.elasticbeanstalk.model.DeleteApplicationVersionRequest;
21 import com.amazonaws.services.elasticbeanstalk.model.DescribeApplicationVersionsRequest;
22 import com.amazonaws.services.elasticbeanstalk.model.DescribeApplicationVersionsResult;
23 import com.amazonaws.services.elasticbeanstalk.model.DescribeEnvironmentsRequest;
24 import com.amazonaws.services.elasticbeanstalk.model.DescribeEnvironmentsResult;
25 import com.amazonaws.services.elasticbeanstalk.model.EnvironmentDescription;
26
27 import org.apache.commons.lang.builder.CompareToBuilder;
28 import org.apache.maven.plugin.MojoExecutionException;
29 import org.apache.maven.plugin.MojoFailureException;
30 import org.apache.maven.plugins.annotations.Mojo;
31 import org.apache.maven.plugins.annotations.Parameter;
32
33 import java.util.ArrayList;
34 import java.util.Collections;
35 import java.util.Comparator;
36 import java.util.Date;
37 import java.util.List;
38 import java.util.ListIterator;
39 import java.util.regex.Pattern;
40
41 import br.com.ingenieux.mojo.beanstalk.AbstractBeanstalkMojo;
42
43
44
45
46
47
48 @Mojo(name = "clean-previous-versions")
49 public class CleanPreviousVersionsMojo extends AbstractBeanstalkMojo {
50
51
52
53
54 @Parameter(property = "beanstalk.applicationName", defaultValue = "${project.artifactId}", required = true)
55 String applicationName;
56
57
58
59
60 @Parameter(property = "beanstalk.deleteSourceBundle", defaultValue = "false")
61 boolean deleteSourceBundle;
62
63
64
65
66 @Parameter(property = "beanstalk.versionsToKeep")
67 Integer versionsToKeep;
68
69
70
71
72 @Parameter(property = "beanstalk.daysToKeep")
73 Integer daysToKeep;
74
75
76
77
78
79 @Parameter(property = "beanstalk.cleanFilter")
80 String cleanFilter;
81
82
83
84
85 @Parameter(property = "beanstalk.dryRun", defaultValue = "true")
86 boolean dryRun;
87
88 private int deletedVersionsCount;
89
90 @Override
91 protected Object executeInternal() throws MojoExecutionException, MojoFailureException {
92 boolean bVersionsToKeepDefined = (null != versionsToKeep);
93 boolean bDaysToKeepDefined = (null != daysToKeep);
94
95 if (!(bVersionsToKeepDefined ^ bDaysToKeepDefined)) {
96 throw new MojoFailureException("Declare either versionsToKeep or daysToKeep, but not both nor none!");
97 }
98
99 DescribeApplicationVersionsRequest describeApplicationVersionsRequest = new DescribeApplicationVersionsRequest().withApplicationName(applicationName);
100
101 DescribeApplicationVersionsResult appVersions = getService().describeApplicationVersions(describeApplicationVersionsRequest);
102
103 DescribeEnvironmentsResult environments = getService().describeEnvironments(new DescribeEnvironmentsRequest().withApplicationName(applicationName));
104
105 List<ApplicationVersionDescription> appVersionList = new ArrayList<ApplicationVersionDescription>(appVersions.getApplicationVersions());
106
107 deletedVersionsCount = 0;
108
109 for (EnvironmentDescription d : environments.getEnvironments()) {
110 boolean bActiveEnvironment = (d.getStatus().equals("Running") || d.getStatus().equals("Launching") || d.getStatus().equals("Ready"));
111
112 for (ListIterator<ApplicationVersionDescription> appVersionIterator = appVersionList.listIterator(); appVersionIterator.hasNext(); ) {
113 ApplicationVersionDescription appVersion = appVersionIterator.next();
114
115 boolean bMatchesVersion = appVersion.getVersionLabel().equals(d.getVersionLabel());
116
117 if (bActiveEnvironment && bMatchesVersion) {
118 getLog().info("VersionLabel " + appVersion.getVersionLabel() + " is bound to environment " + d.getEnvironmentName() + " - Skipping it");
119
120 appVersionIterator.remove();
121 }
122 }
123 }
124
125 filterAppVersionListByVersionLabelPattern(appVersionList, cleanFilter);
126
127 Collections.sort(
128 appVersionList,
129 new Comparator<ApplicationVersionDescription>() {
130 @Override
131 public int compare(ApplicationVersionDescription o1, ApplicationVersionDescription o2) {
132 return new CompareToBuilder().append(o1.getDateUpdated(), o2.getDateUpdated()).toComparison();
133 }
134 });
135
136 if (bDaysToKeepDefined) {
137 Date now = new Date();
138
139 for (ApplicationVersionDescription d : appVersionList) {
140 long delta = now.getTime() - d.getDateUpdated().getTime();
141
142 delta /= 1000;
143 delta /= 86400;
144
145 boolean shouldDeleteP = (delta > daysToKeep);
146
147 if (getLog().isDebugEnabled()) {
148 getLog().debug("Version " + d.getVersionLabel() + " was from " + delta + " days ago. Should we delete? " + shouldDeleteP);
149 }
150
151 if (shouldDeleteP) {
152 deleteVersion(d);
153 }
154 }
155 } else {
156 while (appVersionList.size() > versionsToKeep) {
157 deleteVersion(appVersionList.remove(0));
158 }
159 }
160
161 getLog().info("Deleted " + deletedVersionsCount + " versions.");
162
163 return null;
164 }
165
166 void deleteVersion(ApplicationVersionDescription versionToRemove) {
167 getLog().info("Must delete version: " + versionToRemove.getVersionLabel());
168
169 DeleteApplicationVersionRequest req =
170 new DeleteApplicationVersionRequest()
171 .withApplicationName(versionToRemove.getApplicationName())
172 .withDeleteSourceBundle(deleteSourceBundle)
173 .withVersionLabel(versionToRemove.getVersionLabel());
174
175 if (!dryRun) {
176 getService().deleteApplicationVersion(req);
177 deletedVersionsCount++;
178 }
179 }
180
181 void filterAppVersionListByVersionLabelPattern(List<ApplicationVersionDescription> appVersionList, String patternString) {
182 if (patternString == null) {
183 return;
184 }
185
186 getLog().info("Filtering versions with pattern : " + patternString);
187
188 Pattern p = Pattern.compile(patternString);
189 for (ListIterator<ApplicationVersionDescription> appVersionIterator = appVersionList.listIterator(); appVersionIterator.hasNext(); ) {
190
191 if (!p.matcher(appVersionIterator.next().getVersionLabel()).matches()) {
192 appVersionIterator.remove();
193 }
194 }
195 }
196 }