1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package io.wcm.tooling.commons.packmgr.download;
21
22 import static io.wcm.tooling.commons.packmgr.PackageManagerHelper.CRX_PACKAGE_EXISTS_ERROR_MESSAGE_PREFIX;
23
24 import java.io.Closeable;
25 import java.io.File;
26 import java.io.FileOutputStream;
27 import java.io.IOException;
28 import java.io.InputStream;
29
30 import org.apache.commons.io.IOUtils;
31 import org.apache.commons.lang3.StringUtils;
32 import org.apache.http.HttpStatus;
33 import org.apache.http.client.methods.CloseableHttpResponse;
34 import org.apache.http.client.methods.HttpGet;
35 import org.apache.http.client.methods.HttpPost;
36 import org.apache.http.client.protocol.HttpClientContext;
37 import org.apache.http.entity.mime.MultipartEntityBuilder;
38 import org.apache.http.impl.client.CloseableHttpClient;
39 import org.apache.http.util.EntityUtils;
40 import org.json.JSONObject;
41 import org.slf4j.Logger;
42 import org.slf4j.LoggerFactory;
43
44 import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
45 import io.wcm.tooling.commons.packmgr.PackageManagerException;
46 import io.wcm.tooling.commons.packmgr.PackageManagerHelper;
47 import io.wcm.tooling.commons.packmgr.PackageManagerProperties;
48 import io.wcm.tooling.commons.packmgr.install.VendorInstallerFactory;
49
50
51
52
53 public final class PackageDownloader implements Closeable {
54
55 private final PackageManagerProperties props;
56 private final PackageManagerHelper pkgmgr;
57 private final CloseableHttpClient httpClient;
58
59 private static final Logger log = LoggerFactory.getLogger(PackageDownloader.class);
60
61
62
63
64 public PackageDownloader(PackageManagerProperties props) {
65 this.props = props;
66 this.pkgmgr = new PackageManagerHelper(props);
67 this.httpClient = pkgmgr.getHttpClient();
68 }
69
70
71
72
73
74
75 public String uploadPackageDefinition(File file) {
76 HttpClientContext httpClientContext = pkgmgr.getPackageManagerHttpClientContext();
77
78 if (!file.exists()) {
79 throw new PackageManagerException("File not found: " + file.getAbsolutePath());
80 }
81
82
83 log.info("Upload package definition for {} to {} ...", file.getName(), props.getPackageManagerUrl());
84 HttpPost post = new HttpPost(props.getPackageManagerUrl() + "/.json?cmd=upload");
85 MultipartEntityBuilder entity = MultipartEntityBuilder.create()
86 .addBinaryBody("package", file)
87 .addTextBody("force", "true");
88 post.setEntity(entity.build());
89 JSONObject jsonResponse = pkgmgr.executePackageManagerMethodJson(httpClient, httpClientContext, post);
90 boolean success = jsonResponse.optBoolean("success", false);
91 String msg = jsonResponse.optString("msg", null);
92 String packagePath = jsonResponse.optString("path", null);
93
94 if (!success && StringUtils.startsWith(msg, CRX_PACKAGE_EXISTS_ERROR_MESSAGE_PREFIX) && StringUtils.isEmpty(packagePath)) {
95 packagePath = StringUtils.substringAfter(msg, CRX_PACKAGE_EXISTS_ERROR_MESSAGE_PREFIX);
96 success = true;
97 }
98 if (!success) {
99 throw new PackageManagerException("Package path detection failed: " + msg);
100 }
101
102 return packagePath;
103 }
104
105
106
107
108
109
110
111
112
113 @SuppressFBWarnings("RV_RETURN_VALUE_IGNORED_BAD_PRACTICE")
114 public File downloadContentPackage(String packagePath, String ouputFilePath, boolean rebuildPackage) {
115 try {
116 HttpClientContext httpClientContext = pkgmgr.getPackageManagerHttpClientContext();
117
118
119 if (rebuildPackage) {
120 log.info("Rebuilding package {} ...", packagePath);
121 HttpPost buildMethod = new HttpPost(props.getPackageManagerUrl() + "/console.html" + packagePath + "?cmd=build");
122 pkgmgr.executePackageManagerMethodHtmlOutputResponse(httpClient, httpClientContext, buildMethod);
123 }
124
125
126 log.info("Downloading package {} from {} ...", packagePath, props.getPackageManagerUrl());
127 String baseUrl = VendorInstallerFactory.getBaseUrl(props.getPackageManagerUrl());
128 HttpGet downloadMethod = new HttpGet(baseUrl + packagePath);
129
130
131 CloseableHttpResponse response = httpClient.execute(downloadMethod, httpClientContext);
132 try {
133 if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
134
135
136 InputStream responseStream = response.getEntity().getContent();
137
138
139 File outputFileObject = new File(ouputFilePath);
140 if (outputFileObject.exists()) {
141 outputFileObject.delete();
142 }
143
144
145 try (FileOutputStream fos = new FileOutputStream(outputFileObject)) {
146 IOUtils.copy(responseStream, fos);
147 fos.flush();
148 responseStream.close();
149 }
150
151 log.info("Package downloaded to {}", outputFileObject.getAbsolutePath());
152
153 return outputFileObject;
154 }
155 else {
156 throw new PackageManagerException("Package download failed:\n"
157 + EntityUtils.toString(response.getEntity()));
158 }
159 }
160 finally {
161 if (response != null) {
162 EntityUtils.consumeQuietly(response.getEntity());
163 try {
164 response.close();
165 }
166 catch (IOException ex) {
167
168 }
169 }
170 }
171 }
172 catch (IOException ex) {
173 throw new PackageManagerException("Download operation failed.", ex);
174 }
175 }
176
177 @Override
178 public void close() throws IOException {
179 httpClient.close();
180 }
181
182 }