View Javadoc
1   /*
2    * #%L
3    * wcm.io
4    * %%
5    * Copyright (C) 2017 wcm.io
6    * %%
7    * Licensed under the Apache License, Version 2.0 (the "License");
8    * you may not use this file except in compliance with the License.
9    * You may obtain a copy of the License at
10   *
11   *      http://www.apache.org/licenses/LICENSE-2.0
12   *
13   * Unless required by applicable law or agreed to in writing, software
14   * distributed under the License is distributed on an "AS IS" BASIS,
15   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16   * See the License for the specific language governing permissions and
17   * limitations under the License.
18   * #L%
19   */
20  package io.wcm.tooling.commons.packmgr.download;
21  
22  import java.io.Closeable;
23  import java.io.File;
24  import java.io.IOException;
25  import java.io.InputStream;
26  import java.io.OutputStream;
27  import java.nio.file.Files;
28  
29  import org.apache.commons.io.IOUtils;
30  import org.apache.http.HttpStatus;
31  import org.apache.http.client.methods.CloseableHttpResponse;
32  import org.apache.http.client.methods.HttpGet;
33  import org.apache.http.client.methods.HttpPost;
34  import org.apache.http.client.protocol.HttpClientContext;
35  import org.apache.http.impl.client.CloseableHttpClient;
36  import org.apache.http.util.EntityUtils;
37  import org.slf4j.Logger;
38  import org.slf4j.LoggerFactory;
39  
40  import io.wcm.tooling.commons.packmgr.PackageManagerException;
41  import io.wcm.tooling.commons.packmgr.PackageManagerHelper;
42  import io.wcm.tooling.commons.packmgr.PackageManagerProperties;
43  import io.wcm.tooling.commons.packmgr.install.VendorInstallerFactory;
44  
45  /**
46   * Downloads a single AEM content package.
47   */
48  public final class PackageDownloader implements Closeable {
49  
50    private final PackageManagerProperties props;
51    private final PackageManagerHelper pkgmgr;
52    private final CloseableHttpClient httpClient;
53  
54    private static final Logger log = LoggerFactory.getLogger(PackageDownloader.class);
55  
56    /**
57     * @param props Package manager configuration properties.
58     */
59    public PackageDownloader(PackageManagerProperties props) {
60      this.props = props;
61      this.pkgmgr = new PackageManagerHelper(props);
62      this.httpClient = pkgmgr.getHttpClient();
63    }
64  
65    /**
66     * Upload the given local package definition (without actually installing it).
67     * @param file Package definition file
68     * @return Package path
69     */
70    public String uploadPackageDefinition(File file) {
71  
72      if (!file.exists()) {
73        throw new PackageManagerException("File not found: " + file.getAbsolutePath());
74      }
75      String packageManagerUrl = props.getPackageManagerUrl();
76  
77      // try upload to get path of package - or otherwise make sure package def exists (no install!)
78      log.info("Upload package definition for {} to {} ...", file.getName(), packageManagerUrl);
79      VendorPackageDownloader downloader = VendorInstallerFactory.getPackageDownloader(packageManagerUrl);
80      return downloader.uploadPackageDefinition(packageManagerUrl, file, pkgmgr);
81    }
82  
83    /**
84     * Download content package from CRX package manager.
85     * @param packagePath Content Package path in AEM instance.
86     * @param ouputFilePath Path to download package from AEM instance to.
87     * @param rebuildPackage Whether to rebuild the package within the CRX package manager before downloading it to
88     *          include the latest content from repository.
89     * @return Downloaded content package file
90     */
91    public File downloadContentPackage(String packagePath, String ouputFilePath, boolean rebuildPackage) {
92      try {
93        HttpClientContext httpClientContext = pkgmgr.getPackageManagerHttpClientContext();
94        String packageManagerUrl = props.getPackageManagerUrl();
95        VendorPackageDownloader downloader = VendorInstallerFactory.getPackageDownloader(packageManagerUrl);
96  
97        // (Re-)build package
98        if (rebuildPackage) {
99          log.info("Rebuilding package {} ...", packagePath);
100         HttpPost buildMethod = downloader.createRebuildMethod(packagePath, packageManagerUrl);
101         pkgmgr.executePackageManagerMethodHtmlOutputResponse(httpClient, httpClientContext, buildMethod);
102       }
103 
104       // Download package
105       String baseUrl = downloader.createDownloadZipBaseUrl(packageManagerUrl);
106       log.info("Downloading package {} from {} ...", packagePath, baseUrl);
107 
108       HttpGet downloadMethod = new HttpGet(baseUrl + packagePath);
109 
110       // execute download
111       CloseableHttpResponse response = httpClient.execute(downloadMethod, httpClientContext);
112       try (response) {
113         if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
114 
115           // get response stream
116           InputStream responseStream = response.getEntity().getContent();
117 
118           // delete existing file
119           File outputFileObject = new File(ouputFilePath);
120           Files.deleteIfExists(outputFileObject.toPath());
121 
122           // write response file
123           try (OutputStream fos = Files.newOutputStream(outputFileObject.toPath())) {
124             IOUtils.copy(responseStream, fos);
125             fos.flush();
126             responseStream.close();
127           }
128 
129           log.info("Package downloaded to {}", outputFileObject.getAbsolutePath());
130 
131           return outputFileObject;
132         }
133         else {
134           throw new PackageManagerException("Package download failed:\n"
135               + EntityUtils.toString(response.getEntity()));
136         }
137       }
138       finally {
139         EntityUtils.consumeQuietly(response.getEntity());
140       }
141     }
142     catch (IOException ex) {
143       throw new PackageManagerException("Download operation failed.", ex);
144     }
145   }
146 
147   @Override
148   public void close() throws IOException {
149     httpClient.close();
150   }
151 
152 }