View Javadoc

1   package com.atlassian.amps.sdk.mpac;
2   
3   import java.io.IOException;
4   import java.net.PasswordAuthentication;
5   import java.net.URI;
6   import java.text.MessageFormat;
7   import java.util.ArrayList;
8   import java.util.List;
9   
10  import com.atlassian.amps.sdk.util.PropertiesReader;
11  import com.atlassian.jira.rest.client.api.JiraRestClient;
12  import com.atlassian.jira.rest.client.api.domain.Issue;
13  import com.atlassian.jira.rest.client.api.domain.SearchResult;
14  import com.atlassian.jira.rest.client.internal.async.AsynchronousJiraRestClientFactory;
15  import com.atlassian.marketplace.client.HttpConfiguration;
16  import com.atlassian.marketplace.client.MpacException;
17  import com.atlassian.marketplace.client.api.PluginDetailQuery;
18  import com.atlassian.marketplace.client.api.PluginVersionUpdate;
19  import com.atlassian.marketplace.client.impl.DefaultMarketplaceClient;
20  import com.atlassian.marketplace.client.model.LicenseIdentifier;
21  import com.atlassian.marketplace.client.model.Plugin;
22  import com.atlassian.marketplace.client.model.PluginVersion;
23  import com.atlassian.upm.api.util.Option;
24  
25  import org.apache.commons.lang.StringUtils;
26  import org.slf4j.Logger;
27  import org.slf4j.LoggerFactory;
28  
29  /**
30   * Created by Lucas Le on 5 Aug 2015.
31   */
32  public class MpacPublisher
33  {
34      final private static Logger LOG = LoggerFactory.getLogger(MpacPublisher.class);
35  
36      final public static String MPAC_STAGING_SERVER = "https://mpac-5.dev.internal.atlassian.com/";
37      final public static String MPAC_PRODUCTION_SERVER = "https://marketplace.atlassian.com/";
38      final public static String JIRA_SERVER_URL = "https://ecosystem.atlassian.net/";
39      final private String[] sdkPluginKeys = new String[] { "mac", "tgz", "windows", "rpm", "deb" };
40      final private static URI JIRA_SERVER_URI = URI.create(JIRA_SERVER_URL);
41      final private static URI MPAC_STAGING_SERVER_URI = URI.create(MPAC_STAGING_SERVER);
42      final private static URI MPAC_PRODUCTION_SERVER_URI = URI.create(MPAC_PRODUCTION_SERVER);
43      private DefaultMarketplaceClient mpacClient;
44      final private PropertiesReader releaseProperties;
45  
46      final private PasswordAuthentication mpacCredentials;
47      final private PasswordAuthentication ecoCredentials;
48      final private String version;
49      private String releaseNotes;
50  
51      private MpacPublisher(final PasswordAuthentication mpacCredentials, final PasswordAuthentication ecoCredentials, final String version)
52              throws IOException
53      {
54          this.mpacCredentials = mpacCredentials;
55          this.ecoCredentials = ecoCredentials;
56          this.version = version;
57          this.releaseProperties = PropertiesReader.getInstance();
58      }
59  
60      public void publish() throws IOException, MpacException
61      {
62              mpacClient = initializeMpacClient();
63              final List<SDKPlugin> sdkPlugins = processSdkPlugins();
64              for (SDKPlugin sdkPlugin : sdkPlugins)
65              {
66                  releaseNewPluginVersion(sdkPlugin);
67              }
68      }
69  
70      private List<SDKPlugin> processSdkPlugins()
71      {
72          final List<SDKPlugin> sdkPlugins = new ArrayList<SDKPlugin>(5);
73          for (int i = 0; i < sdkPluginKeys.length; i++)
74          {
75              final SDKPlugin sdkPlugin = SDKPlugin.SDKPluginBuilder
76                      .aSDKPlugin()
77                      .name("atlassian-plugin-sdk-" + sdkPluginKeys[i])
78                      .binaryURI(formatURI(releaseProperties.getBinaryURI(sdkPluginKeys[i])))
79                      .build();
80              sdkPlugins.add(sdkPlugin);
81          }
82          return sdkPlugins;
83      }
84  
85      private String formatURI(String uri)
86      {
87          LOG.debug(uri);
88          return MessageFormat.format(uri, version);
89      }
90  
91      private String initializeReleaseNotes(final String latestAmpsVersion, final String newAmpsVersion,
92              final String latestSdkVersion, final String newSdkVersion) throws IOException
93      {
94          final AsynchronousJiraRestClientFactory factory = new AsynchronousJiraRestClientFactory();
95          final JiraRestClient restClient = factory.createWithBasicHttpAuthentication(JIRA_SERVER_URI,
96                  ecoCredentials.getUserName(), ecoCredentials.getPassword().toString());
97          final String query = MessageFormat.format("(project IN (AMPS, AMPSDEV) and status = resolved and fixVersion > {0} and fixVersion <= {1}) "
98                          + "or (project IN (ATLASSDK ) and status = resolved and fixVersion > {2} and fixVersion <= {3})",
99                  latestAmpsVersion, newAmpsVersion,
100                 latestSdkVersion, newSdkVersion);
101         LOG.debug("initializeReleaseNotes query: " + query);
102         final StringBuilder releaseNotes = new StringBuilder();
103         final SearchResult searchResult = restClient.getSearchClient().searchJql(query).claim();
104         for (Issue issue : searchResult.getIssues())
105         {
106             releaseNotes.append("<p>");
107             releaseNotes.append(issue.getKey());
108             releaseNotes.append(": ");
109             releaseNotes.append(issue.getSummary());
110             releaseNotes.append("</p>");
111         }
112         restClient.close();
113         return releaseNotes.toString();
114     }
115 
116     private DefaultMarketplaceClient initializeMpacClient()
117     {
118         final HttpConfiguration myHttpConfiguration = HttpConfiguration.builder()
119                 .username(mpacCredentials.getUserName())
120                 .password(mpacCredentials.getPassword().toString())
121                 .connectTimeoutMillis(300000)
122                 .build();
123         final URI serverURI = releaseProperties.isReleaseProduction() ? MPAC_PRODUCTION_SERVER_URI : MPAC_STAGING_SERVER_URI;
124         final DefaultMarketplaceClient defaultMarketplaceClient = new DefaultMarketplaceClient(serverURI, myHttpConfiguration);
125         return defaultMarketplaceClient;
126     }
127 
128     private void releaseNewPluginVersion(final SDKPlugin sdkPlugin) throws MpacException, IOException
129     {
130         final Option<Plugin> sdkPlugins = mpacClient.plugins().get(PluginDetailQuery.builder(sdkPlugin.getName()).build());
131         final Plugin sdk = sdkPlugins.get();
132         final PluginVersion latestPluginVersion = sdk.getVersion();
133         if (!version.equals(latestPluginVersion.getVersion()))
134         {
135             if(StringUtils.isEmpty(releaseNotes))
136             {
137                 try
138                 {
139                     releaseNotes = initializeReleaseNotes(releaseProperties.getAMPSLatestVersion(),
140                             releaseProperties.getAMPSCurrentVersion(),
141                             latestPluginVersion.getVersion(),
142                             version);
143                 }catch(IOException io)
144                 {
145                     throw new IOException("Could not generate release notes, please check your Ecosystem again", io);
146                 }
147             }
148             LOG.debug("Create new version for plugin: " + sdkPlugin.getName() + " - binary URI: " + sdkPlugin.getBinaryURI());
149             LOG.debug("Release summary:\n " + releaseSummary());
150             LOG.debug("Release notes:\n " + releaseNotes);
151             PluginVersionUpdate newVersionData = PluginVersionUpdate.newVersion(
152                     sdkPlugin.getName(),
153                     latestPluginVersion.getBuildNumber() + 10,
154                     version,
155                     PluginVersionUpdate.Deployment
156                             .nonDeployable(URI.create(sdkPlugin.getBinaryURI())),
157                     LicenseIdentifier.ASL
158             ).summary(Option.some(releaseSummary()))
159                     .releaseNotes(Option.some(releaseNotes))
160                     .build();
161             mpacClient.plugins().putVersion(newVersionData);
162         }
163     }
164 
165     private String releaseSummary()
166     {
167         return MessageFormat.format(releaseProperties.getReleaseSummary(),
168                 version,
169                 releaseProperties.getAMPSCurrentVersion());
170     }
171 
172     public static class MpacPublisherBuilder
173     {
174         private PasswordAuthentication mpacCredentials;
175         private PasswordAuthentication ecoCredentials;
176         private String version;
177 
178         private MpacPublisherBuilder()
179         {
180         }
181 
182         public static MpacPublisherBuilder aMpacPublisher()
183         {
184             return new MpacPublisherBuilder();
185         }
186 
187         public MpacPublisherBuilder mpacCredentials(PasswordAuthentication mpacCredentials)
188         {
189             this.mpacCredentials = mpacCredentials;
190             return this;
191         }
192 
193         public MpacPublisherBuilder ecoCredentials(PasswordAuthentication ecoCredentials)
194         {
195             this.ecoCredentials = ecoCredentials;
196             return this;
197         }
198 
199         public MpacPublisherBuilder version(String version)
200         {
201             this.version = version;
202             return this;
203         }
204 
205         public MpacPublisherBuilder but()
206         {
207             return aMpacPublisher().mpacCredentials(mpacCredentials).ecoCredentials(ecoCredentials).version(version);
208         }
209 
210         public MpacPublisher build() throws IOException
211         {
212             MpacPublisher mpacPublisher = new MpacPublisher(mpacCredentials, ecoCredentials, version);
213             return mpacPublisher;
214         }
215     }
216 }