Andy in the Cloud

From BBC Basic to Force.com and beyond…

37 thoughts on “Apex Metadata API Streamlined and Simplified for Summer’14

  1. Pingback: Introduction to calling the Metadata API from Apex | Andy in the Cloud

  2. Eric Kintzer (@cropredy)'s avatar

    Andy — using the sandbox deploy from git URL for the Apex metadata API financialforcedev/apex-mdapi , I get this error

    ….
    Deployment Complete
    Failures:
    package.xml(MetadataServicePatcher/MetadataServicePatchedCopy):An object ‘MetadataServicePatcher/MetadataServicePatchedCopy’ of type Document was named in package.xml, but was not found in zipped directory

  3. Yasa Kusuma's avatar

    Sorry about all the noob questions…I am attempting to create a new layout, not sure what I am missing. I looked in your MetaDataServiceExamples class and did not find one on creating a new layout. This code executes fine but it’s not creating the layout.
    I looked here too https://developer.salesforce.com/docs/atlas.en-us.api_meta.meta/api_meta/meta_layouts.htm, still not getting the layout. Can you point me in the right direction?

    //Create new layout
    MetadataService.MetadataPort service = new MetadataService.MetadataPort();
    service.SessionHeader = new MetadataService.SessionHeader_element();
    service.SessionHeader.sessionId = UserInfo.getSessionId();

    MetadataService.Layout testLayout = new MetadataService.Layout();
    testLayout.fullName = ‘test__MyObject__c-Test Layout’;
    //
    //What else do I need?
    //
    List results = service.createMetadata(new MetadataService.Metadata[] { testLayout });

  4. vaibhav100ni's avatar

    Hi Andy Amazing blog with Awasome Knowladge.
    I have query can you halp me
    I just want to create and Update Profile object permission and profile Field permission related to an object
    actually i am a beginner and want to do this task

    • Andrew Fawcett's avatar

      Recommend you first study the apex developers guide, bits on classes and inner classes, also consuming web services. Then review the sample code in metadadaserviceexamples.cls I can help with specific questions, but I don’t have the bandwidth to train you. Hope that’s ok and good luck!

  5. vaibhav100ni's avatar

    oh sorry by mistake i have write profile field lavel permission ,i have find out in metadata service api example but not profile object lavel permission, want to ask is it updatable because i have try to update it but get failled .

  6. vaibhav100ni's avatar

    i will try more in this direction , thanks for your help

  7. vaibhav100ni's avatar

    This is my code but not working even not giving any error , can you help me

    MetadataService.MetadataPort service = createService();
    MetadataService.Profile admin = new MetadataService.Profile();
    admin.fullName = ‘Admin’;
    admin.custom = false;
    MetadataService.ProfileObjectPermissions objPerm = new MetadataService.ProfileObjectPermissions();
    objPerm.object_x=’Account’;
    objPerm.modifyAllRecords = false;
    objPerm.allowDelete = false;
    //fieldSec.editable=true;
    admin.objectPermissions = new MetadataService.ProfileObjectPermissions[] {objPerm} ;
    List results =
    service.updateMetadata(
    new MetadataService.Metadata[] { admin });
    MetadataService.handleSaveResults(results[0]);

    • Andrew Fawcett's avatar

      Have you compared it with the example?

      • vaibhav100ni's avatar

        There is not any update example on ObjectPermission but there was example for FieldPermission And i have write these code according to that .

      • Andrew Fawcett's avatar

        Ok please raise a GitHub issue, it’s easier to discuss in that site. Also have you considered simply creating a permission set and assigning it to the users? This can all be done in native apex code.

  8. vaibhav100ni's avatar

    yupp I also have create native code to get a permission set of required profile ,till my code working properly and when i try to update its permission, it gives error.

    • Andrew Fawcett's avatar

      Profile permission sets are readonly. You need to create a brand new permission set on apex using dml then you can write to it and assign it, again all on apex.

  9. AlanC's avatar

    are you able to retrieve an ApexClass using renameMetadata() ?
    I’ve tried and get this error System.CalloutException: Web service callout failed: WebService returned a SOAP Fault: INVALID_TYPE: This type of metadata is not available for this organization faultcode=sf:INVALID_TYPE faultactor=

  10. Jigar Naik's avatar

    Hi Andy,
    Is there any way to read content of apex class through API? I’ve been able to read content of the page but not of the class.

  11. savio jose's avatar

    Hi Andy,

    Firstly, thanks for putting in effort for creating such an awesome wrapper. Before i deep dive, need some quick advice.
    I am working with goal metrics and have a requirement to clone an existing metric and also link it to a new report which basically the clone of existing report linked to the metric but with just the date parameters changed.

    Is it possible to clone an existing report to create a new one using a combination of Report API and the metadata API wrapper?

    • Andrew Fawcett's avatar

      I am not familiar with goal metrics feature. You can for sure though retrieve a report definition with metadada Api, modify it and create a new one. The Analytics API is read only and the information structures it returns is not compatible with the inputs of the Metadata API. So I would stick with Metadata API for what you need here. Thanks for your kind comments!

      • savio jose's avatar

        Thanks Andy. I could achieve what was required using the metadata API & it works perfectly but the issue is that it requires ‘Modify All Data’ permission.
        Is there any workaround to this? The end user would be using this feature to clone theirs Goals, associated metrics and linked reports & I definitely can’t give them ‘Modify All Data’ permission 😦

      • Andrew Fawcett's avatar

        You can use an oauth token from another user, to do the work on their behalf. It’s been discussed in the GitHub issues on the repo if you search the repo for oAuth. It requires basically performing an oAuth web ui authorisation flow with a user as part of the setup of your solution, then storing the oauth code in some ideally secure place for later use. Use of oAuth with the Metadata API is something that keeps coming up so might be something I should dig into further for a future blog. It’s worth noting that you could also just login with another users credentials and use that session id, obviously for that type of solution your less secure as you need to store this user and password some place. Hope this helps for now.

      • Andrew Fawcett's avatar

        By the way would like to share your use case with Salesforce? They are looking for funding (justify internal resource allocation) to build this properly into the platform. Your clone use case is a good one, if you check my Twitter feed you will find a link to a Salesforce Community Group they have setup.

  12. savio jose's avatar

    Thanks Andy … i have already started work on using some integration account for login, will give you the updates once done..And yes i definitely don’t mind sharing the use case, will do it as soon i fix this one…

  13. savio jose's avatar

    Hi Andy..I did it using ‘Named Credentials’ & it works with both Password Authentication or OAuth 2.0 protocol.

  14. Shrivaths Kulkarni's avatar

    Hello Andy, Thank you for the post. I have query regarding ApexClass, Can we create ApexClass using CreateMetadata api? I tried to do so in my Developer addition and getting error as mentioned. Please suggest.
    System.CalloutException: Web service callout failed: WebService returned a SOAP Fault: INVALID_TYPE: This type of object is not available for this organization faultcode=sf:INVALID_TYPE faultactor=

    • Andrew Fawcett's avatar

      Sorry Salesforce does not support this, only via deploy operation. See the deploy example on the repo.

  15. mandarkulkarni's avatar

    Hi Andy,

    I am big fan of MetadataAPI and built some small utility tools to leverage the api. Thanks for the blog and work that you did on MetadataService class to make it available in Apex.

    Quick question – I want to re-name some of the Test Classes in Production and thinking of using renameMetadata() call. Do you know if renameMetadata() runs the test classes when used in Prod? I am going to give it a try, but just in case if you know.

    • Andrew Fawcett's avatar

      Thanks for the kind comments. Sadly ApexClass Metadada type is not supported for the CRUD methods. Only deploy and retrieve method. Even then it’s not really a rename, you upload a destructive package xml to delete the class and a new one in its place. This operation can be further complicated by references to the class. In short, rename of apex class is not really supported.

  16. Engel Gefallen's avatar

    Hello, thanks about this information, I try to update the sharingModel but it does not work, it update the pluralLabel but nosharingModel.

    MetadataService.CustomObject customObject = new MetadataService.CustomObject();
    customObject.fullName = ‘CIC_Test__c’;
    customObject.label = ‘Test’;
    customObject.pluralLabel = ‘Tests Actualizado 1’;
    customObject.nameField = new MetadataService.CustomField();
    customObject.nameField.type_x = ‘Text’;
    customObject.nameField.label = ‘Test Record Upsert’;
    customObject.deploymentStatus = ‘Deployed’;
    customObject.sharingModel = ‘Private’ ;
    results =
    service.upsertMetadata(
    new MetadataService.Metadata[] { customObject });

    Greetings.

    • Andrew Fawcett's avatar

      Have you inspected the results variable to see if there is any error message? If you look at the MetadataServiceExamples.cls there is some samples and each show how to handle the results object to learn about errors.

  17. Engel Gefallen's avatar

    Thank you for you reply, i make a handler this is those are results, the operation was successful

    success: true
    fullName: CIC_Test__c
    created: false
    errors: null

    Full service return:
    results: [UpsertResult:[apex_schema_type_info=(http://soap.sforce.com/2006/04/metadata, true, false), created=false, created_type_info=(created, http://soap.sforce.com/2006/04/metadata, null, 1, 1, false), errors=null, errors_type_info=(errors, http://soap.sforce.com/2006/04/metadata, null, 0, -1, false), field_order_type_info=(created, errors, fullName, success), fullName=CIC_Test__c, fullName_type_info=(fullName, http://soap.sforce.com/2006/04/metadata, null, 1, 1, false), success=true, success_type_info=(success, http://soap.sforce.com/2006/04/metadata, null, 1, 1, false)]]

    Greetings.

Leave a reply to savio jose Cancel reply