-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathFileBasedDeployAndRetrieve.java
More file actions
317 lines (278 loc) · 12.7 KB
/
Copy pathFileBasedDeployAndRetrieve.java
File metadata and controls
317 lines (278 loc) · 12.7 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
import java.io.*;
import java.nio.channels.Channels;
import java.nio.channels.FileChannel;
import java.nio.channels.ReadableByteChannel;
import java.rmi.RemoteException;
import java.util.*;
import javax.xml.parsers.*;
import org.w3c.dom.*;
import org.xml.sax.SAXException;
import com.sforce.soap.metadata.*;
/**
* Sample that logs in and shows a menu of retrieve and deploy metadata options.
*/
public class FileBasedDeployAndRetrieve {
private MetadataConnection metadataConnection;
private static final String ZIP_FILE = "components.zip";
// manifest file that controls which components get retrieved
private static final String MANIFEST_FILE = "package.xml";
private static final double API_VERSION = 29.0;
// one second in milliseconds
private static final long ONE_SECOND = 1000;
// maximum number of attempts to deploy the zip file
private static final int MAX_NUM_POLL_REQUESTS = 50;
private BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
public static void main(String[] args) throws Exception {
FileBasedDeployAndRetrieve sample = new FileBasedDeployAndRetrieve();
sample.run();
}
public FileBasedDeployAndRetrieve() {
}
private void run() throws Exception {
this.metadataConnection = MetadataLoginUtil.login();
// Show the options to retrieve or deploy until user exits
String choice = getUsersChoice();
while (choice != null && !choice.equals("99")) {
if (choice.equals("1")) {
retrieveZip();
} else if (choice.equals("2")) {
deployZip();
} else {
break;
}
// show the options again
choice = getUsersChoice();
}
}
/*
* Utility method to present options to retrieve or deploy.
*/
private String getUsersChoice() throws IOException {
System.out.println(" 1: Retrieve");
System.out.println(" 2: Deploy");
System.out.println("99: Exit");
System.out.println();
System.out.print("Enter 1 to retrieve, 2 to deploy, or 99 to exit: ");
// wait for the user input.
String choice = reader.readLine();
return choice != null ? choice.trim() : "";
}
private void deployZip() throws Exception {
byte zipBytes[] = readZipFile();
DeployOptions deployOptions = new DeployOptions();
deployOptions.setPerformRetrieve(false);
deployOptions.setRollbackOnError(true);
AsyncResult asyncResult = metadataConnection.deploy(zipBytes, deployOptions);
DeployResult result = waitForDeployCompletion(asyncResult.getId());
if (!result.isSuccess()) {
printErrors(result, "Final list of failures:\n");
throw new Exception("The files were not successfully deployed");
}
System.out.println("The file " + ZIP_FILE + " was successfully deployed\n");
}
/*
* Read the zip file contents into a byte array.
*/
private byte[] readZipFile() throws Exception {
byte[] result = null;
// We assume here that you have a deploy.zip file.
// See the retrieve sample for how to retrieve a zip file.
File zipFile = new File(ZIP_FILE);
if (!zipFile.exists() || !zipFile.isFile()) {
throw new Exception("Cannot find the zip file for deploy() on path:"
+ zipFile.getAbsolutePath());
}
FileInputStream fileInputStream = new FileInputStream(zipFile);
try {
ByteArrayOutputStream bos = new ByteArrayOutputStream();
byte[] buffer = new byte[4096];
int bytesRead = 0;
while (-1 != (bytesRead = fileInputStream.read(buffer))) {
bos.write(buffer, 0, bytesRead);
}
result = bos.toByteArray();
} finally {
fileInputStream.close();
}
return result;
}
/*
* Print out any errors, if any, related to the deploy.
* @param result - DeployResult
*/
private void printErrors(DeployResult result, String messageHeader) {
DeployDetails details = result.getDetails();
StringBuilder stringBuilder = new StringBuilder();
if (details != null) {
DeployMessage[] componentFailures = details.getComponentFailures();
for (DeployMessage failure : componentFailures) {
String loc = "(" + failure.getLineNumber() + ", " + failure.getColumnNumber();
if (loc.length() == 0 && !failure.getFileName().equals(failure.getFullName()))
{
loc = "(" + failure.getFullName() + ")";
}
stringBuilder.append(failure.getFileName() + loc + ":"
+ failure.getProblem()).append('\n');
}
RunTestsResult rtr = details.getRunTestResult();
if (rtr.getFailures() != null) {
for (RunTestFailure failure : rtr.getFailures()) {
String n = (failure.getNamespace() == null ? "" :
(failure.getNamespace() + ".")) + failure.getName();
stringBuilder.append("Test failure, method: " + n + "." +
failure.getMethodName() + " -- " + failure.getMessage() +
" stack " + failure.getStackTrace() + "\n\n");
}
}
if (rtr.getCodeCoverageWarnings() != null) {
for (CodeCoverageWarning ccw : rtr.getCodeCoverageWarnings()) {
stringBuilder.append("Code coverage issue");
if (ccw.getName() != null) {
String n = (ccw.getNamespace() == null ? "" :
(ccw.getNamespace() + ".")) + ccw.getName();
stringBuilder.append(", class: " + n);
}
stringBuilder.append(" -- " + ccw.getMessage() + "\n");
}
}
}
if (stringBuilder.length() > 0) {
stringBuilder.insert(0, messageHeader);
System.out.println(stringBuilder.toString());
}
}
private void retrieveZip() throws Exception {
RetrieveRequest retrieveRequest = new RetrieveRequest();
// The version in package.xml overrides the version in RetrieveRequest
retrieveRequest.setApiVersion(API_VERSION);
setUnpackaged(retrieveRequest);
AsyncResult asyncResult = metadataConnection.retrieve(retrieveRequest);
RetrieveResult result = waitForRetrieveCompletion(asyncResult);
if (result.getStatus() == RetrieveStatus.Failed) {
throw new Exception(result.getErrorStatusCode() + " msg: " +
result.getErrorMessage());
} else if (result.getStatus() == RetrieveStatus.Succeeded) {
// Print out any warning messages
StringBuilder stringBuilder = new StringBuilder();
if (result.getMessages() != null) {
for (RetrieveMessage rm : result.getMessages()) {
stringBuilder.append(rm.getFileName() + " - " + rm.getProblem() + "\n");
}
}
if (stringBuilder.length() > 0) {
System.out.println("Retrieve warnings:\n" + stringBuilder);
}
System.out.println("Writing results to zip file");
File resultsFile = new File(ZIP_FILE);
FileOutputStream os = new FileOutputStream(resultsFile);
try {
os.write(result.getZipFile());
} finally {
os.close();
}
}
}
private DeployResult waitForDeployCompletion(String asyncResultId) throws Exception {
int poll = 0;
long waitTimeMilliSecs = ONE_SECOND;
DeployResult deployResult;
boolean fetchDetails;
do {
Thread.sleep(waitTimeMilliSecs);
// double the wait time for the next iteration
waitTimeMilliSecs *= 2;
if (poll++ > MAX_NUM_POLL_REQUESTS) {
throw new Exception(
"Request timed out. If this is a large set of metadata components, " +
"ensure that MAX_NUM_POLL_REQUESTS is sufficient.");
}
// Fetch in-progress details once for every 3 polls
fetchDetails = (poll % 3 == 0);
deployResult = metadataConnection.checkDeployStatus(asyncResultId, fetchDetails);
System.out.println("Status is: " + deployResult.getStatus());
if (!deployResult.isDone() && fetchDetails) {
printErrors(deployResult, "Failures for deployment in progress:\n");
}
}
while (!deployResult.isDone());
if (!deployResult.isSuccess() && deployResult.getErrorStatusCode() != null) {
throw new Exception(deployResult.getErrorStatusCode() + " msg: " +
deployResult.getErrorMessage());
}
if (!fetchDetails) {
// Get the final result with details if we didn't do it in the last attempt.
deployResult = metadataConnection.checkDeployStatus(asyncResultId, true);
}
return deployResult;
}
private RetrieveResult waitForRetrieveCompletion(AsyncResult asyncResult) throws Exception {
// Wait for the retrieve to complete
int poll = 0;
long waitTimeMilliSecs = ONE_SECOND;
String asyncResultId = asyncResult.getId();
RetrieveResult result = null;
do {
Thread.sleep(waitTimeMilliSecs);
// Double the wait time for the next iteration
waitTimeMilliSecs *= 2;
if (poll++ > MAX_NUM_POLL_REQUESTS) {
throw new Exception("Request timed out. If this is a large set " +
"of metadata components, check that the time allowed " +
"by MAX_NUM_POLL_REQUESTS is sufficient.");
}
result = metadataConnection.checkRetrieveStatus(
asyncResultId, true);
System.out.println("Retrieve Status: " + result.getStatus());
} while (!result.isDone());
return result;
}
private void setUnpackaged(RetrieveRequest request) throws Exception {
// Edit the path, if necessary, if your package.xml file is located elsewhere
File unpackedManifest = new File(MANIFEST_FILE);
System.out.println("Manifest file: " + unpackedManifest.getAbsolutePath());
if (!unpackedManifest.exists() || !unpackedManifest.isFile()) {
throw new Exception("Should provide a valid retrieve manifest " +
"for unpackaged content. Looking for " +
unpackedManifest.getAbsolutePath());
}
// Note that we use the fully quualified class name because
// of a collision with the java.lang.Package class
com.sforce.soap.metadata.Package p = parsePackageManifest(unpackedManifest);
request.setUnpackaged(p);
}
private com.sforce.soap.metadata.Package parsePackageManifest(File file)
throws ParserConfigurationException, IOException, SAXException {
com.sforce.soap.metadata.Package packageManifest = null;
List<PackageTypeMembers> listPackageTypes = new ArrayList<PackageTypeMembers>();
DocumentBuilder db =
DocumentBuilderFactory.newInstance().newDocumentBuilder();
InputStream inputStream = new FileInputStream(file);
Element d = db.parse(inputStream).getDocumentElement();
for (Node c = d.getFirstChild(); c != null; c = c.getNextSibling()) {
if (c instanceof Element) {
Element ce = (Element) c;
NodeList nodeList = ce.getElementsByTagName("name");
if (nodeList.getLength() == 0) {
continue;
}
String name = nodeList.item(0).getTextContent();
NodeList m = ce.getElementsByTagName("members");
List<String> members = new ArrayList<String>();
for (int i = 0; i < m.getLength(); i++) {
Node mm = m.item(i);
members.add(mm.getTextContent());
}
PackageTypeMembers packageTypes = new PackageTypeMembers();
packageTypes.setName(name);
packageTypes.setMembers(members.toArray(new String[members.size()]));
listPackageTypes.add(packageTypes);
}
}
packageManifest = new com.sforce.soap.metadata.Package();
PackageTypeMembers[] packageTypesArray =
new PackageTypeMembers[listPackageTypes.size()];
packageManifest.setTypes(listPackageTypes.toArray(packageTypesArray));
packageManifest.setVersion(API_VERSION + "");
return packageManifest;
}
}