Newer Version Available

This content describes an older version of this product. View Latest

retrieve()

This call retrieves XML file representations of components in an organization.

Syntax

1AsyncResult = metadatabinding.retrieve(RetrieveRequest retrieveRequest)

Usage

Use this call to retrieve file representations of components in an organization.

Metadata API can deploy and retrieve up to 5,000 files at one time. While a specific file size limit is not enforced, you might encounter out-of-memory errors for very large files.

Note

To retrieve packaged or unpackaged components:

  1. Issue a retrieve() call to start the asynchronous retrieval. An AsyncResult object is returned. If the call is completed, the done field contains true. Most often, the call is not completed quickly enough to be noted in the result. If it is completed, note the value in the id field returned and skip the next step.
  2. If the call is not complete, issue a checkStatus() call in a loop using the value in the id field of the AsyncResult object, returned by the retrieve() call in the previous step. Check the AsyncResult object returned until the done field contains true. The time taken to complete a retrieve() call depends on the size of the zip file being deployed, so use a longer wait time between iterations as the size of the zip file increases.
  3. Issue a checkRetrieveStatus() call to obtain the results of the retrieve() call, using the id value returned in the first step.

Permissions

Your client application must be logged in with the “Modify All Data” permission.

Arguments

Name Type Description
retrieveRequest RetrieveRequest Encapsulates options for determining which packages or files are retrieved.

Response

AsyncResult

Sample Code—Java

This sample shows how to retrieve components into a zip file. See the deploy() sample code for details on how to deploy a zip file.

This sample was created using Apache Axis. The WSDL2Java utility generates a _package class, even though the metadata type is defined as Package in the Metadata WSDL. Other SOAP clients might generate a different name for the _package class.

Note

1swfobject.registerObject("clippy.codeblock-1", "9");package com.doc.samples;
2
3import java.io.*;
4import java.util.*;
5import java.nio.ByteBuffer;
6import java.nio.channels.Channels;
7import java.nio.channels.FileChannel;
8import java.nio.channels.ReadableByteChannel;
9import java.nio.channels.WritableByteChannel;
10
11import java.rmi.RemoteException;
12import javax.xml.rpc.ServiceException;
13
14import javax.xml.parsers.DocumentBuilder;
15import javax.xml.parsers.DocumentBuilderFactory;
16import javax.xml.parsers.ParserConfigurationException;
17
18import org.w3c.dom.Element;
19import org.w3c.dom.Node;
20import org.w3c.dom.NodeList;
21import org.xml.sax.SAXException;
22
23import com.sforce.soap.enterprise.LoginResult;
24import com.sforce.soap.enterprise.SessionHeader;
25import com.sforce.soap.enterprise.SforceServiceLocator;
26import com.sforce.soap.enterprise.SoapBindingStub;
27import com.sforce.soap.enterprise.fault.ExceptionCode;
28import com.sforce.soap.enterprise.fault.LoginFault;
29
30import com.sforce.soap._2006._04.metadata.MetadataBindingStub;
31import com.sforce.soap._2006._04.metadata.MetadataServiceLocator;
32import com.sforce.soap._2006._04.metadata.AsyncResult;
33import com.sforce.soap._2006._04.metadata.RetrieveRequest;
34import com.sforce.soap._2006._04.metadata.AsyncRequestState;
35import com.sforce.soap._2006._04.metadata.RetrieveResult;
36import com.sforce.soap._2006._04.metadata.RetrieveMessage;
37// Note that Axis generates a _package class, even though it is defined as Package
38// in the WSDL. Other SOAP clients may generate a different name for the _package class.
39import com.sforce.soap._2006._04.metadata._package;
40import com.sforce.soap._2006._04.metadata.PackageTypeMembers;
41
42
43public class RetrieveSample {
44    // binding for the Enterprise WSDL used for login() call
45	private SoapBindingStub binding;
46    // binding for the metadata WSDL used for create() and checkStatus() calls
47	private MetadataBindingStub metadatabinding;
48
49	static BufferedReader rdr = new BufferedReader(new InputStreamReader(System.in));
50
51    // one second in milliseconds
52    private static final long ONE_SECOND = 1000;
53    // maximum number of attempts to retrieve the results
54    private static final int MAX_NUM_POLL_REQUESTS = 50; 
55
56    // manifest file that controls which components get retrieved
57    private static final String MANIFEST_FILE = "package.xml"; 
58
59    private static final double API_VERSION = 15.0; 
60
61    public static void main(String[] args) throws ServiceException, Exception {
62        RetrieveSample sample = new RetrieveSample();
63        sample.run();
64    }
65
66    private void run() throws ServiceException, Exception {
67        if (login()) {
68            getUserInput("SUCCESSFUL LOGIN! Hit the enter key to continue.");
69            retrieveZip();
70        }
71    }
72
73    
74    private void retrieveZip() throws RemoteException, Exception
75    {
76        RetrieveRequest retrieveRequest = new RetrieveRequest();
77        retrieveRequest.setApiVersion(API_VERSION);
78        setUnpackaged(retrieveRequest);
79
80        AsyncResult asyncResult = metadatabinding.retrieve(retrieveRequest);
81        // Wait for the retrieve to complete
82        int poll = 0;
83        long waitTimeMilliSecs = ONE_SECOND;
84        while (!asyncResult.isDone()) {
85            Thread.sleep(waitTimeMilliSecs);
86            // double the wait time for the next iteration
87            waitTimeMilliSecs *= 2;
88            if (poll++ > MAX_NUM_POLL_REQUESTS) {
89                throw new Exception("Request timed out.  If this is a large set " +
90                		"of metadata components, check that the time allowed " +
91                		"by MAX_NUM_POLL_REQUESTS is sufficient.");
92            }
93            asyncResult = metadatabinding.checkStatus(
94            		new String[] {asyncResult.getId()})[0];
95            System.out.println("Status is: " + asyncResult.getState());
96        }
97
98        if (asyncResult.getState() != AsyncRequestState.Completed) {
99            throw new Exception(asyncResult.getStatusCode() + " msg: " +
100                    asyncResult.getMessage());
101        }
102
103        RetrieveResult result = metadatabinding.checkRetrieveStatus(asyncResult.getId());
104        
105        // Print out any warning messages
106        StringBuilder buf = new StringBuilder();
107        if (result.getMessages() != null) {
108            for (RetrieveMessage rm : result.getMessages()) {
109                buf.append(rm.getFileName() + " - " + rm.getProblem());
110            }
111        }
112        if (buf.length() > 0) {
113            System.out.println("Retrieve warnings:\n" + buf);
114        }
115
116        // Write the zip to the file system
117        System.out.println("Writing results to zip file");
118        ByteArrayInputStream bais = new ByteArrayInputStream(result.getZipFile());
119        File resultsFile = new File("retrieveResults.zip");
120        FileOutputStream os = new FileOutputStream(resultsFile);
121        try {
122            ReadableByteChannel src = Channels.newChannel(bais);
123            FileChannel dest = os.getChannel();
124            copy(src, dest);
125            
126            System.out.println("Results written to " + resultsFile.getAbsolutePath());
127        }
128        finally {
129            os.close();
130        }
131
132    }
133    
134    /**
135     * Helper method to copy from a readable channel to a writable channel,
136     * using an in-memory buffer.
137     */
138    private void copy(ReadableByteChannel src, WritableByteChannel dest)
139        throws IOException
140    {
141        // use an in-memory byte buffer
142        ByteBuffer buffer = ByteBuffer.allocate(8092);
143        while (src.read(buffer) != -1) {
144            buffer.flip();
145            while(buffer.hasRemaining()) {
146                dest.write(buffer);
147            }
148            buffer.clear();
149        }
150    }
151    
152    private void setUnpackaged(RetrieveRequest request) throws Exception
153    {
154        // Edit the path, if necessary, if your package.xml file is located elsewhere
155        File unpackedManifest = new File(MANIFEST_FILE);
156        System.out.println("Manifest file: " + unpackedManifest.getAbsolutePath());
157        
158        if (!unpackedManifest.exists() || !unpackedManifest.isFile())
159            throw new Exception("Should provide a valid retrieve manifest " +
160                    "for unpackaged content. " +
161                    "Looking for " + unpackedManifest.getAbsolutePath());
162
163        // Note that we populate the _package object by parsing a manifest file here.
164        // You could populate the _package based on any source for your
165        // particular application.
166        _package p = parsePackage(unpackedManifest);
167        request.setUnpackaged(p);
168    }
169 
170    private _package parsePackage(File file) throws Exception {
171        try {
172            InputStream is = new FileInputStream(file);
173            List<PackageTypeMembers> pd = new ArrayList<PackageTypeMembers>();
174            DocumentBuilder db =
175                DocumentBuilderFactory.newInstance().newDocumentBuilder();
176            Element d = db.parse(is).getDocumentElement();
177            for (Node c = d.getFirstChild(); c != null; c = c.getNextSibling()) {
178                if (c instanceof Element) {
179                    Element ce = (Element)c;
180                    //
181                    NodeList namee = ce.getElementsByTagName("name");
182                    if (namee.getLength() == 0) {
183                        // not
184                        continue;
185                    }
186                    String name = namee.item(0).getTextContent();
187                    NodeList m = ce.getElementsByTagName("members");
188                    List<String> members = new ArrayList<String>();
189                    for (int i = 0; i < m.getLength(); i++) {
190                        Node mm = m.item(i);
191                        members.add(mm.getTextContent());
192                    }
193                    PackageTypeMembers pdi = new PackageTypeMembers();
194                    pdi.setName(name);
195                    pdi.setMembers(members.toArray(new String[members.size()]));
196                    pd.add(pdi);
197                }
198            }
199            _package r = new _package();
200            r.setTypes(pd.toArray(new PackageTypeMembers[pd.size()]));
201            r.setVersion(API_VERSION + "");
202            return r;
203        } catch (ParserConfigurationException pce) {
204            throw new Exception("Cannot create XML parser", pce);
205        } catch (IOException ioe) {
206            throw new Exception(ioe);
207        } catch (SAXException se) {
208            throw new Exception(se);
209        }
210    }
211    
212    /**
213     * The login call is used to obtain a token from Salesforce.
214     * This token must be passed to all other calls to provide
215     * authentication.
216     */
217    private boolean login() throws ServiceException {
218        String userName = getUserInput("Enter username: ");
219        String password = getUserInput("Enter password: ");
220        /** Next, the sample client application initializes the binding stub.
221         * 
222         * This is our main interface to the API for the Enterprise WSDL.
223         * The getSoap method takes an optional parameter,
224         * (a java.net.URL) which is the endpoint.
225         * For the login call, the parameter always starts with 
226         * http(s)://login.salesforce.com. After logging in, the sample 
227         * client application changes the endpoint to the one specified 
228         * in the returned loginResult object.
229         */
230        binding = (SoapBindingStub) new SforceServiceLocator().getSoap();
231        
232        // Time out after a minute
233        binding.setTimeout(60000);
234        // Log in using the Enterprise WSDL binding
235        LoginResult loginResult;
236        try {
237            System.out.println("LOGGING IN NOW....");
238            loginResult = binding.login(userName, password);
239        }
240        catch (LoginFault ex) {
241  
242            // The LoginFault derives from AxisFault
243            ExceptionCode exCode = ex.getExceptionCode();
244            if (exCode == ExceptionCode.FUNCTIONALITY_NOT_ENABLED ||
245                exCode == ExceptionCode.INVALID_CLIENT ||
246                exCode == ExceptionCode.INVALID_LOGIN ||
247                exCode == ExceptionCode.LOGIN_DURING_RESTRICTED_DOMAIN ||
248                exCode == ExceptionCode.LOGIN_DURING_RESTRICTED_TIME ||
249                exCode == ExceptionCode.ORG_LOCKED ||
250                exCode == ExceptionCode.PASSWORD_LOCKOUT ||
251                exCode == ExceptionCode.SERVER_UNAVAILABLE ||
252                exCode == ExceptionCode.TRIAL_EXPIRED ||
253                exCode == ExceptionCode.UNSUPPORTED_CLIENT) {
254                System.out.println("Please be sure that you have a valid username " +
255                        "and password.");
256            } else {
257                // Write the fault code to the console
258                System.out.println(ex.getExceptionCode());
259                // Write the fault message to the console
260                System.out.println("An unexpected error has occurred." + ex.getMessage());
261            }
262            return false;
263        } catch (Exception ex) {
264            System.out.println("An unexpected error has occurred: " + ex.getMessage());
265            ex.printStackTrace();
266            return false;
267        }
268        // Check if the password has expired
269        if (loginResult.isPasswordExpired()) {
270            System.out.println("An error has occurred. Your password has expired.");
271            return false;
272        }
273        
274        /** Once the client application has logged in successfully, we use 
275         *  the results of the login call to reset the endpoint of the service  
276         *  to the virtual server instance that is servicing your organization.  
277         *  To do this, the client application sets the ENDPOINT_ADDRESS_PROPERTY 
278         *  of the binding object using the URL returned from the LoginResult. We
279         *  use the metadata binding from this point forward as we are invoking
280         *  calls in the metadata WSDL.
281         */
282        metadatabinding = (MetadataBindingStub)
283                new MetadataServiceLocator().getMetadata();
284        metadatabinding._setProperty(MetadataBindingStub.ENDPOINT_ADDRESS_PROPERTY,
285                loginResult.getMetadataServerUrl());
286
287        /** The sample client application now has an instance of the MetadataBindingStub 
288         *  that is pointing to the correct endpoint. Next, the sample client application 
289         *  sets a persistent SOAP header (to be included on all subsequent calls that 
290         *  are made with the SoapBindingStub) that contains the valid sessionId
291         *  for our login credentials. To do this, the sample client application 
292         *  creates a new SessionHeader object and set its sessionId property to the 
293         *  sessionId property from the LoginResult object.
294         */
295        // Create a new session header object and add the session id
296        // from the login return object
297        SessionHeader sh = new SessionHeader();
298        sh.setSessionId(loginResult.getSessionId());
299        /** Next, the sample client application calls the setHeader method of the 
300         *  SoapBindingStub to add the header to all subsequent method calls. This  
301         *  header will persist until the binding is destroyed or until the header 
302         *  is explicitly removed. The "SessionHeader" parameter is the name of the 
303         *  header to be added.
304         */
305        // set the session header for subsequent call authentication
306        metadatabinding.setHeader(
307            new MetadataServiceLocator().getServiceName().getNamespaceURI(),
308                "SessionHeader", sh);
309        
310        // return true to indicate that we are logged in, pointed
311        // at the right url and have our security token in place.
312        return true;
313    }
314    
315    //The sample client application retrieves the user's login credentials.
316    // Helper function for retrieving user input from the console
317    String getUserInput(String prompt) {
318        System.out.print(prompt);
319        try {
320            return rdr.readLine();
321        }
322        catch (IOException ex) {
323            return null;
324        }
325    }
326
327}
328