You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: README.markdown
+50-53Lines changed: 50 additions & 53 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -3,6 +3,9 @@ Apex Wrapper Salesforce Metadata API
3
3
4
4
**[Deploy to Salesforce](https://githubsfdeploy.herokuapp.com/app/githubdeploy/financialforcedev/apex-mdapi)**
5
5
6
+
**Update: 24th April 2014:**
7
+
- Updated to **Spring'14 Metadata API (v30.0), significant new features, see blog.
8
+
6
9
**Update: 27th October 2013:**
7
10
- A new introduction to the API has been published [here](http://andyinthecloud.com/2013/10/27/introduction-to-calling-the-metadata-api-from-apex/)
8
11
- A new supporting Visualforce example has also been created to show how to use apex:actionPoller
@@ -35,10 +38,21 @@ Known Issues and Resolutions
35
38
36
39
- If you recieve the error message *'Insufficient access; cannot execute Metadata operation with PAC enabled session id'* within Apex code within a managed package utilising this library. Please ensure to changed the API access from Restricted to Unrestricted on your Package defintion. Many thanks to the great work from [vipulpahwa](https://github.com/vipulpahwa) and [Daniel Blackhall](https://github.com/seeflat) to getting to the bottom of this rather cryptic error message.
37
40
38
-
Introduction
39
-
------------
41
+
Documentation
42
+
-------------
43
+
44
+
In addition to the documetnation in this README, the following blogs also cover the library.
45
+
46
+
-[Introduction to calling the Metadata API from Apex](http://andyinthecloud.com/2013/10/27/introduction-to-calling-the-metadata-api-from-apex/).
47
+
-[Spring’14 Pre-Release : Updating Layouts in Apex](http://andyinthecloud.com/category/metadata-api/)
48
+
-[“Look ma, no hands!” : Automating Install and Uninstall of Packages!](http://andyinthecloud.com/2013/06/23/look-ma-no-hands-automating-install-and-uninstall-of-packages/)
49
+
-[Scripting the Apex Metadata API and Batch Apex Support](http://andyinthecloud.com/2013/05/06/scripting-the-apex-metadata-api-and-batch-apex-support/)
50
+
-[Apex Metadata API Spring’13 Update : Org Settings Access](http://andyinthecloud.com/2013/03/10/apex-metadata-api-spring13-update-org-settings-access/)
51
+
52
+
This API mirrors as much as possible the API types and operations described in the standard documentation. The behaviour and functionality provided is also as described in the Salesforce documentation, in terms of what metadata is available and accessable via the specific operations.
53
+
54
+
-[Salesforce Metadata API Developers Guide](http://www.salesforce.com/us/developer/docs/api_meta/index.htm)
40
55
41
-
There is a good blog entry providing an introduction to this library [here](http://andyinthecloud.com/2013/10/27/introduction-to-calling-the-metadata-api-from-apex/)
42
56
43
57
Background and Motivation
44
58
-------------------------
@@ -47,17 +61,17 @@ There seems to be a growing number of Apex developers wanting to develop solutio
47
61
48
62
As adminstrators leverage more and more of these solutions the topic of automation arrises. Can the developers of these solutions help the adminstrator by implementing wizards or self configuring solutions without asking the adminstrator to create these manually and then have to reference them back into the solution?
49
63
50
-
Strategies
51
-
----------
64
+
Strategies for calling from Apex
65
+
--------------------------------
52
66
53
67
Salesforce provides a great number of API's for developers to consume, both off and on platform (as Apex developers). If you happen to be off platform (say in Heroku) and developing code to help automate adminstration. Then you can utilise the Salesforce Metadata API (via the Salesforce WebService Connector) to help with this. It is a robust and readily available API for creating objects, fields, pages and many other component types.
54
68
55
69
While Salesforce offer on platform Apex developers a means to query some of this information (a subset of the Metadata API coverage) via Apex Describe. It does not as yet provide a means to manipulate this metadata from Apex natively. We are told this is in the pipeline though I am personally not aware of when this will arrive.
56
70
57
71
So what can we do in the meantime as Apex developers? Well it turns out that Apex is quite good at making outbound calls to Web Services and more recently REST base API's, all be it as always with a few governors to be aware. So why can Apex not call out to the Metadata Web Services API? After all, there is a WSDL for it and you have the ability as an Apex developer to import a WSDL into Apex and consume the code it generates to make the call, right? Well...
58
72
59
-
Problems and Solutions
60
-
----------------------
73
+
Challanges calling the Metadata API from Apex?
74
+
----------------------------------------------
61
75
62
76
Salesforce have been promoting recently the Metadata REST API. While this is still not a native API to Apex, it would be a lot easier to call than the Web Service one, though you would have develop your own wrapper classes. Unfortunatly this API is still in pilot and I have been told by Salesforce its appearance as a GA API is still someway out, sadly.
63
77
@@ -70,30 +84,28 @@ The main reasons are as follows...
70
84
* The WSDL2Apex tool does not support polymorphic XML and the Metadata WSDL contains types that extend each other, e.g. CustomObject extends Metadata
71
85
* The Apex XML serialiser does not support inheritance (see above point). More specifically it does not see base class members nor does it emit the 'xsi:type' attribute to support polymorphic XML data binding. So the generated Apex code requires a bit of tweaking to support this.
72
86
* The Apex language does not support the Zip file format, so the **retrieve** and the **deploy** operations so these are a no go from a pure Apex perspective. However this doesnt stop the of Javascript to handle zips! See sections below on how this has been done.
73
-
* Most operations return **AsyncResult** which gives you an Id to call back on to determine the fate of your request. While this can be called, you will need to do this via AJAX, Apex Future or Apex Job. The deploy and retrieve samples utilise apex:actionPoller.
87
+
* Some operations return **AsyncResult** which gives you an Id to call back on to determine the fate of your request. While this can be called, you will need to do this via AJAX, Apex Future or Apex Job. The deploy and retrieve samples utilise apex:actionPoller.
88
+
* Newer CRUD operations since Spring'14, are now realtime, meaning you don't have to poll for the result of the operation as was previously the case. The examples below show these operations in action.
74
89
75
-
So once these issues are resolved we can now get access to the Metadata API from Apex!
90
+
This library addresses all these issues for you, you can download the [MetadataService.cls](https://github.com/financialforcedev/apex-mdapi/blob/master/apex-mdapi/src/classes/MetadataService.cls) and [MetadataServiceTest.cls](https://github.com/financialforcedev/apex-mdapi/blob/master/apex-mdapi/src/classes/MetadataServiceTest.cls) and use them directly in your solutions. So you can now gain access to the Metadata API from Apex!
76
91
77
-
* The following so called CRUD operations are useable within Apex, **create**, **update** and **delete**.
92
+
* The following so called CRUD operations are useable within Apex, **create**, **read**, **update** and **delete**.
78
93
* As well as **listMetadata** and **describeMetadata**.
79
94
* You can also call **checkStatus** to check the status of your requests.
80
95
* With a bit of help from a Javascript library, the infamous **retrieve** and **deploy** also become workable.
81
96
82
97
**Note:** The CRUD operations do not support Apex Class or Apex Trigger components sadly, this is a API restriction and not an issue with calling from Apex as such.
83
98
84
-
So I've created this Github repo to capture a modified version of the generated Apex class around the Metadata API. Which addresses the problems above. So that you can download it and get started straight away. Be warned though I have only performed tweaks to some of the more popular component types. I am more than happy if others want to contribute tweaks to others!
99
+
So I've created this Github repo to capture a modified version of the generated Apex class around the Metadata API. Which addresses the problems above. So that you can download it and get started straight away.
-[Salesforce Metadata API Developers Guide](http://www.salesforce.com/us/developer/docs/api_meta/index.htm)
91
105
92
106
Examples
93
107
--------
94
108
95
-
**NOTE:** The following examples do not show how to call the checkStatus method. This will need to be done in your Visualforce controller via a timed refresh or via a scheduled job. See the following Retrieve and Deploy demos for how to use apex:actionPoller for this or the Batch Apex demo.
96
-
97
109
public static void createObject()
98
110
{
99
111
MetadataService.MetadataPort service = createService();
@@ -159,6 +171,8 @@ You can view more examples [here](https://github.com/financialforcedev/apex-mdap
159
171
Metadata Visualforce Demo
160
172
-------------------------
161
173
174
+
**NOTE:** Since Spring'14 (API 30.0) this only applies if your using the Async versions of the methods or you are finding that the realtime methods are timing out.
175
+
162
176
If you have an interactive tool your building, you can use Visualforce and use the **apex:actionPoller** to store the AsyncResult in your controller and write a controller method to call the checkStatus, which the action poller repeatedly calls until the AsyncResult indicates the request is completed by Salesforce. You can read more about this sample in this blog [here](http://andyinthecloud.com/2013/10/27/introduction-to-calling-the-metadata-api-from-apex/).
@@ -168,6 +182,8 @@ If you have an interactive tool your building, you can use Visualforce and use t
168
182
Metadata Batch Apex Demo
169
183
------------------------
170
184
185
+
**NOTE:** Since Spring'14 (API 30.0) this only applies if your using the Async versions of the methods or you are finding that the realtime methods are timing out.
186
+
171
187
As described above you can poll the checkStatus operation for completion via either apex:actionPoller or Batch Apex. This example code shows how to create a number of Metadata components (custom object, fields and a page) from Apex without requiring Visualforce. You can read more about it [here](http://andyinthecloud.com/2013/05/06/scripting-the-apex-metadata-api-and-batch-apex-support/)
172
188
173
189
// Define Metadata item to create a Custom Object
@@ -318,49 +334,30 @@ You can study the Visualforce page [here](https://github.com/financialforcedev/a
318
334
How to create your own MetadataService.cls
319
335
------------------------------------------
320
336
321
-
If you want to repeat what I did on new version of the Metadata WSDL or just want to tweak further component types beyond the ones used in the above examples. Here is how I did it...
337
+
**IMPORTANT NOTE:** This library contains a pre-build version of the Metadata API, you only need to follow these steps if the version of the Metadata API you want is not reflected in the repository currently or if you have modified the patcher script to customise it for your own needs.
322
338
323
339
- Generating a valid Apex MetadataService class
324
-
- Edit the WSDL
340
+
- Download and edit the WSDL
325
341
- Change the Port name from 'Metadata' to 'MetadataPort'
326
342
- As of Summer'13 (API 28) there was a small bug in the CustomField type definition, change the 'type' element definition to include a minOccurs="0" atttribute, as per the other elements in this type.
327
-
- Attempt to generate Apex from this WSDL
328
-
- Give it a better name if you want when prompted, e.g. MetadataService
329
-
- In earlier platform releases this would error, as update and delete are reserved words.
330
-
- It seems this has now been fixed and as of Summer'13 the Metadata API WSDL generates without errors!
331
-
- Open Eclipse (or your favourite editor)
332
-
- Open the class
333
-
- To be compatible with the samples here, edit the method name update_x to updateMetadata
334
-
- To be compatible with the samples here, edit the method name delete_x to deleteMetadata
335
-
- To be compatible with the samples here, edit the method name retrieve_x to retrieve
336
-
- Save the class
337
-
- Update the MetadataServiceText class
338
-
- Observe the uncovered items (new metadata operations, types added since last release)
339
-
- Add new code to cover operations and types
343
+
- Generate Apex from this WSDL
344
+
- When prompted give it a name of MetadataServiceImported
345
+
- Verify a MetadataServiceImported class has been created
346
+
- Run the Patch script to generate a new MetadataService class (as a Document)
347
+
- Ensure you have a Document Folder called MetadataServicePatcher (Developer Name)
348
+
- Run the following code from execute annoynmous in Developer Console
349
+
MetadataServicePatcher.patch();
350
+
- Verify this has created a MetadataServicePatched Document in the abov folder
351
+
- Update MetadataService.cls
352
+
- Open the MetadataServicePatched Document and copy the code
353
+
- Paste the code over the current or new MetadataService.cls class
354
+
(recommend MavensMate for this as the file is some 8000+ lines long)
355
+
- Update MetadataServiceTest.cls
340
356
- See this for guidelines http://andyinthecloud.com/2013/05/11/code-coverage-for-wsdl2apex-generated-classes
341
-
- Making further edits to the Apex code
342
-
- Modify the end point to be dynamic
343
-
- public String endpoint_x = URL.getSalesforceBaseUrl().toExternalForm() + '/services/Soap/m/28.0';
344
-
- Make 'Metadata' inner class 'virtual'
345
-
- Make 'MetadataWithContent' inner class 'virtual'
346
-
- Review WSDL for types that extend 'tns:Metadata' and update related Apex classes to also extend Metadata
347
-
- Review WSDL for types that extend 'tns:MetadataWithContent' and update related Apex classes to also extend MetadataWithContent
348
-
- Apply the following to each class that extends Metadata, e.g. for CustomObject
349
-
Add the following at the top of the class
350
-
public String type = 'CustomObject';
351
-
public String fullName;
352
-
Add the following at the top of the private static members
353
-
private String[] type_att_info = new String[]{'xsi:type'};
354
-
private String[] fullName_type_info = new String[]{'fullName','http://www.w3.org/2001/XMLSchema','string','0','1','false'};
355
-
Add 'fullName' as the first item in the field_order_type_info String array, e.g.
356
-
private String[] field_order_type_info = new String[]{'fullName', 'actionOverrides' …. 'webLinks'};
357
-
- Apply the following to each class that extends MetadataWithContent, e.g. for ApexPage
358
-
Add the following after 'fullName'
359
-
public String content;
360
-
Add the following after 'fullName_type_info'
361
-
private String[] content_type_info = new String[]{'content','http://www.w3.org/2001/XMLSchema','base64Binary','0','1','false'};
362
-
Add 'content' after 'fullName' in the field_order_type_info String array, e.g.
363
-
private String[] field_order_type_info = new String[]{'fullName', 'content', 'apiVersion','description','label','packageVersions'};
357
+
- Future releases of the patch script may also generate this class
358
+
359
+
**NOTE:** You can review the changes made to the standard Saleforce generated Web Service Apex class for the Metadata API, by reading the comments at the top of the [MetadataServicePatcher.cls](https://github.com/financialforcedev/apex-mdapi/blob/master/apex-mdapi/src/classes/MetadataServicePatcher.cls) class.
0 commit comments