Andy in the Cloud

From BBC Basic to Force.com and beyond…

240 thoughts on “Introduction to calling the Metadata API from Apex

  1. Pingback: Failing to update picklist on task object via metadata API | DL-UAT

  2. Shrikant's avatar

    Hello Guys,

    I try to access read the PageLayout using the latest Metadata API i.e 33, I can read all other metadata excepting Layouts.

    Has any face the same problem.

    Thanks!

  3. Rajeev Shekhar's avatar

    Andy, that’s indeed brilliant. Awesome stuff. However, I do have one question. Actually, the requirement is to sync two Objects in Salesforce, not only the data but the Metadata too. Let’s say there are two Objects, A and B. If a field is added or deleted in A, the same should reflect in B. Could you please suggest in detail how can I use your metadata api to achieve such functionality???

    • Andrew Fawcett's avatar

      Thanks! There are a lot of examples for this in the metadataserviceexamples class you can use as a basis, then also look at my sobjectdataloader repo for the data side. I am afraid I just don’t have time to go into detail in this with you, sorry. Happy if you want to ask some hi level questions after having a look at the above.

  4. Bilal Nazir (@bilalnazir90)'s avatar

    Hi Andy,
    This is very great and helpful API and I’ve a query about retrieving layout metadata. Is there a way I can retrieve all the fields on a specific layout provided the recordType?


    Bilal

  5. Abhishek's avatar

    Hi Andy,

    I was stuck on a point I have a code which is working fine for retrieve the folder info of an org.

    MetadataService.MetadataPort service = new MetadataService.MetadataPort();
    List queries = new List();
    service.SessionHeader = new MetadataService.SessionHeader_element();
    service.SessionHeader.sessionId = UserInfo.getSessionId();
    MetadataService.ListMetadataQuery queryDocumentFolder = new MetadataService.ListMetadataQuery();
    queryDocumentFolder.type_x = ‘DocumentFolder’;
    queries.add(queryDocumentFolder);
    system.debug(‘========queries=====’+queries);
    MetadataService.FileProperties[] fileProperties = service.listMetadata(queries, 30);
    system.debug(‘========fileProperties=====’+fileProperties);
    List folderNames = new List();
    for(MetadataService.FileProperties fileProperty : fileProperties)
    folderNames.add(fileProperty.fileName.replace(‘documents/’, ”));
    system.debug(‘========queries=====’+queries);

    Now I want to make it generic so in the line “queryDocumentFolder.type_x = ‘DocumentFolder’;” instead of DocumentFolder if I pass “ApexClass” it should return all the Apex class of that org same for other component.
    Currently when I am trying to do this I am facing the exception can you please help me to come out of it?

    Thanks in Advance.

    Abhishek

    • Andrew Fawcett's avatar

      Sorry hard to help if you have to given me the exception your getting. However you may also like to know you can use Soql to query apex classes, just query the ApexClass object. Hope this help, if you want to proceed with Metadata API you will have to give me some more insight as to the exception message you have?

  6. Renato's avatar

    The “create” method does not exist in the MetadataService.cls. Could you please update your example, or provide another example on how to use the Metadata API to create objects such as Workflow Rules using async methods?

  7. sat su's avatar

    Thanks for posting this discussion. I would like to know How to get field Description from object metadata getDescription() ?? Thank you.

  8. Waclaw Smaga's avatar

    Hi guys
    I need to pull lastModifiedDate for RecordType.
    Is this not supported by MetadataService?

    Workbench shows this information for every record type, also official Metadata API listing all the record types shows this.

    Any suggestions or do I need to make official Metadata API call and pull huge amout of RTs?

    • Andrew Fawcett's avatar

      It should be a direct wrapper. Can you raise an issue on the GitHub site with a screenshot of what your seeing elsewhere in the docs and I will try to find it for you. Thanks.

      • Waclaw Smaga's avatar

        I may have not described the case at hand clearly enough 🙂

        So, I’m pulling Record Types using readMetadata(‘RecordType’, ), but there is no info on lastModifiedDate.
        LastModifiedDate is included in listMetada(, ), which I guess is used by workbench and is indeed available in MetadataService, but this pulls huge amount of data in my org (over 600 RTs).

        I was wondering if there is a way to pull lastModifiedDate for RTs without querying all of them.
        Probably not, as my understanding is that lastModifiedDate is a property of a file holding metadata, not of specific metadata as such.

        Background requirement is to get picklist values for different record types, but in a web service for mobile devices, so time is of the essence. My approach for this is to create some “cache” with the values (sObject), that would be refreshed only if anything changed, thus I need lastModifiedDate for included RTs 🙂

        So my final question is: is there a way to pull lastModifiedDate for RTs without querying all of them?

      • Andrew Fawcett's avatar

        Not via metadada API, have you looked at tooling API?

  9. Waclaw Smaga's avatar

    Nope, not yet. I will look into it, but I’m resistant to including yet another API 🙂

  10. Mohit's avatar

    Hi Andrew,

    Thank you for such a fantastic class.
    I just wanted to know like if there is a way to reduce the size of the MetadataService class as it itself consumes around 500000 characters and we all know Salesforce is picky about the character limit.
    Any suggestion would be helpful.

    Warm Regards

    • Andrew Fawcett's avatar

      This has been raised as an idea in the GitHub issues list for sure. And is a good one. Checkout some thoughts on there. Other than simply copy and pasting over what you need until it all compiles, I don’t yet have a tool or automated approach to cutting it down. Sorry.

  11. Rahul's avatar

    Hi Andrew,

    I tried to invoke the Metadata api from the Salesforce site but it is throwing an error like “Web service callout failed: WebService returned a SOAP Fault: UNKNOWN_EXCEPTION: Site under construction faultcode=UNKNOWN_EXCEPTION faultactor=” in the debug logs, Can you please help me to fix this

    • Andrew Fawcett's avatar

      Check the code that initialises the end point in the metadataservice class, it might need adjusting for this execution context. Also if your running as guest this will not work as that user does not have API or admin access. For that matter I suspect your general issue is site users won’t either. What you may have to consider is a more advanced approach of using a precaptured oauth token from an admin user in the org and having the code pass that as the session id. However you need to be very very careful with this kind of elevation of privileges. What is it your doing with the metadata API, there are some things now that can be done via soql….

  12. kuhinoor's avatar

    hii…..

    How to create tab using metadata API.

    • Andrew Fawcett's avatar

      Take a look at the examples class in the repo, if there is not one, you can probably figure it out from createObject example and by reviewing advice in my FAQ blog, linked from the readme file.

  13. Mahesh Gaikwad's avatar

    Hi Andrew,
    I am recently getting readtimeout exception while fetching metadata for profiles. It occurs sometime not always, Could you please help me to fix this?.

    • Andrew Fawcett's avatar

      There is a timeout property on the header where you set the session Id, try increasing this

      • Fahad Munawar Khan's avatar

        Couldn’t find that property, although i added a line service.timeout_x = 90000; but didn’t work out, am i missing somehting

      • Andrew Fawcett's avatar

        I think that’s the one, might be best to post your current issue on the GitHub repository as an issue, me and or others in FF or the community can view it more easily

      • Fahad Munawar Khan's avatar

        ahh never mind, it worked like a charm, you are a rockstar as always ^_^

      • Andrew Fawcett's avatar

        Ah wonderful!

  14. Mahesh Gaikwad's avatar

    I have updated timeout property. Thank you very much.

  15. dilip jha's avatar

    Hi all i am trying to automate post sandbox refresh activities and to achieve this i need to update email alerts, custom labels, outbound messages as at present we need to do manually one by one as these all are metadata so we can’t do by normal apex. so can you share any sugestions how it can be acheived. as in above examples i have seen creating fields and other stuffs.

  16. Salma's avatar

    Did you already try to create connected app through metadataapi?

  17. Salma's avatar

    Hello Andrew ,
    I tried with this MetadataService.AsyncResult[] results =
    service.create(new List { customField }); but gives me this errorMethod does not exist or incorrect signature: [MetadataService.MetadataPort].create(List). It seems that the create method doesn’t exist in MetadataService class that i just uploaded in my org. Big Thanks

  18. Anil's avatar

    Hi All,

    This was a great discussion.

    I’m looking to retrieve all the metadata components (Objects, Fields, Pagelayouts, Validation Rules, Workflow Rules, Approval Processes) based on Last Modified Date by using Query or any kind of script.

    If anyone have any workaround for this.

    Thanks,
    Anil

    • Andrew Fawcett's avatar

      You might want to look at the Tooling API where you can do soql over some of these metadata type objects, then come back to metadata API and build a package xml file driven by the results and passed to the retrieve API. Or you can stick with tooling API and retrieve what you need, though it only currently has a subset of Metadada types.

  19. kotagiri's avatar

    Hi Andrew Fawcett,
    how can we enable account teams and chatter and lightning design system through apex code can you help me please.

  20. kotagiri's avatar

    Thank You for Sharing Andrew Fawcett.
    But here i have to enable those things in other org so where can i provide user name and password,url?
    and also i created on package.xml file how can i deploy to org without using any tool like(eclipse,ant,migration,change set), is there any way to deploy through apex code or any back end process. here you provided MetadataServiceExamples class but am unable to find where you are passing username and password,here you are using MetadataDeployController how can you use ZipData prperty,getPackageXml method i tried to use same code in my org but it is not working.
    if you know anything can you provide that information.

    • Andrew Fawcett's avatar

      The samples work only in the org they are installed in. They use UserInfo.getSessionId. If you want to do the same from one org to anther, you have to obtain an oAuth token (recommended) or login as another user via the Logon API and use the resulting session is (not recommend as you would have to store the target orgs user and password).

      • LBS's avatar

        Hi Andrew,

        I tried replacing UserInfo.getSessionId from access token on another Org. But I’m getting multiple exceptions. But I’m getting INVALID_SESSION_ID exception. Then I tried updating the code as follows.

        MetadataService.MetadataPort service = new MetadataService.MetadataPort(); service.SessionHeader = new MetadataService.SessionHeader_element();

        //service.SessionHeader.sessionId = UserInfo.getSessionId();
        service.SessionHeader.sessionId = clientAccessToken;

        //I tried setting following as the endpoint_x. But was getting separate error
        //service.endpoint_x = ‘https://login.salesforce.com’;

        But then I was getting some other exception of “System.CalloutException: Web service callout failed: Unexpected element. Parser was expecting element ‘http://schemas.xmlsoap.org/soap/envelope/:Envelope’ but found ‘http://www.w3.org/1999/xhtml:html'”

        Appriciate if you can help to figure this out. API versions of my source and target orgs are different as well. Source has 38 while target has 39. Not sure whether this might be the reason.

        Thanks a lot for your support in advanced

      • Andrew Fawcett's avatar

        If looks like your trying to use the client access token? Just checking here, you are using an oAuth token from the user/password or web flow from oAuth? You cannot use the static client or secret id given when you setup the connected app. If you are using it. It looks like there is some unmarshalling issue. Run your code from dev console and review the debug log. You will be able to see the actual xml response returned this way. Hope this helps.

      • LBS's avatar

        Many Thanks for the response! I’m using username/password to get access token. The issue i had was with remote site settings. It was pointed to the current instance. So i have changed it to target instance and it worked fine. Moving forward I need to use your solution in my source org as well as the target org. So what’s your suggestion on that?

      • Andrew Fawcett's avatar

        For the source org you can use the running users session id so long as they have access to the API. If not you can have the admin go through the flow and store the oAuth token to be used by the code running on behalf of other users. Obviously use this approach with care

  21. Guy Gardner's avatar

    Andrew,

    Need some help. I am trying to get details on profiles in my org using the API.

    I am getting a time out on getting any profile back from the API using this code
    (MetadataService.Profile) service.readMetadata(‘Profile’,new String[] { profn }).getRecords()[0]

    This call always times out, even if I turn up the timeout_x to 90000 so that it exceeds 120 seconds max on call outs and then errors out.

    Note in the above call out the variable profn is equal to a Profle Name that I got back from a call to service.listMetadata(quer, vers) where the type=’Profile’.

  22. Bhavi's avatar

    Hi Andrew,

    Thanks for sharing such a great API.
    I am trying to deploy selected metadata to my destination org.
    My question is how can i create a zip out of the selected components to pass it as a parameter to deploy() call.

    Please suggest and thanks in advance.

  23. Ibad-Ur Rahman's avatar

    Hi, I am new to Sales Force so this might be a stupid question, but how can I import the .cls file into my org so that all those classes are available?

    • Andrew Fawcett's avatar

      No worries. You can use many tools, if your familiar with command line, Google search for Salesforce Migration Toolkit

    • Andrew Fawcett's avatar

      You can click the Deploy to Salesforce button on the readme file. This is not a Salesforce tool though. Others are Force.com IDE and also Developer Console

      • Ibad-Ur Rahman's avatar

        How would I import using the Developer Console? Again, many thanks, I am a bit new to this.

      • Andrew Fawcett's avatar

        It depends if you only want a few classes, the key ones are metadataservice.cls and metadataservicetest.cls, then copy and paste is best. If it’s the whole repo it’s the Deploy to Salesforce button, or if you prefer to download the repo try the Salesforce Migration Toolkit I mentioned.

      • Ibad-Ur Rahman's avatar

        Got it, that clarified everything! Thank you very much for your help and this awesome wrapper!

  24. Ibad-Ur Rahman's avatar

    Hi, this may be a dumb question, but I am quite new to Salesforce. Could you please tell me how to use the .cls file? Do I have to import it into my SF org somehow? How do I make the classes contained in it available to my apex code in my org?

  25. saranraj's avatar

    Hi i am new in Salesforce i am try to delete the apex class in visual force page .. i am getting error, Compile Error: DML not allowed on ApexClass at line . please give any idea to delete the apex class in production using VF page

    • Andrew Fawcett's avatar

      Sorry deleting apex code programmatically in apex directly via do is not supported by the platform.

      You could do this via the Metadada API, this is a WebService api so a http callout is needed. Also you need to use the deploy API operation. If you checkout my flow factory or declarative rollup summary tool in GitHub you can see examples. Also the apex Metadata API wrapper GitHub repo has a deploy example controller you can see.

  26. Anil's avatar

    Hi Andrew,

    I want to update description of bulk custom fields (500 fields) at a time across multiple objects. Do we have any approach to do this?. Could you please provide me sample code for this.

    I know how to fetch the metadata details of custom fields by using Tooling API. From that, I could not able to do an update operation.

    Please check and let us know best approach to do this.

    Thanks,
    Anil

    • Andrew Fawcett's avatar

      My best bet would be to use the Metadada API deploy operation, you can see an example in the deploy controller class and also by studying the deploy api documentation. You would need to include in the package sent to the deploy method .object files with only fields in and description, should should be enough, you can test this via a the ant tool perhaps before wasting time on coding. See the Salesforce migration toolkit for ant usage. Sorry I don’t have a ready made example for you.

  27. Ramana's avatar

    can we get all test classes and test methods from one particular project using tooling api then how ?

    • Andrew Fawcett's avatar

      There is no concept of a project in the tooling API only the idea of workspace you set up by making other API calls. I have not kept up with tooling API calls, but it is possible there is an API to get this information since many ide’s provide this ui to select them. If not you will have to parse the apex code classes yourself for this. I just spent a few moments looking at the tooling API docs and didn’t see anything. You might find an answer by looking at code from IDE like MavensMate perhaps, i believe it’s code is open source? Good luck!

  28. brcline's avatar

    Andrew,

    Really appreciate that you have taken the time to build this and are continuing to support it. I’m looking at using your wrapper in an isv package to dynamically add Salesforce’s url.

    Do you happen to know if this would pass the security review process?

    Thanks,
    Brian

    • Andrew Fawcett's avatar

      If you use the component to prompt the admin to approve the connection with the Metadada API they appear to be accepting it. I have seen in the chatter group for the security review team them reference my post outlining this approach to setting up the remote site which allows the comms to work. I assume this is what you mean by “add Salesforce’s url” ?

  29. Bryant Daniels's avatar

    Hi Andrew Fawcett,

    Are we able to modify the metadata for a custom permission set, for example I am able to create a permission set but I would also like to enable a few check boxes under the System Permission. Like ViewEncryptedData. I would like to do this all with apex code but I couldn’t find anything, I noticed that the metadata has access to it.

    ConfigSettings
    false

    EnabledChatter
    false

    Permission Set that allows the user to Manage Encryption Keys & View Encrypted Data
    Manage Encryption
    Salesforce

    true
    ManageEncryptionKeys

    true
    ViewEncryptedData

  30. Rudolf Niehaus's avatar

    Hi Andrew.

    I am battling to get a test mock class implemented for service.readMetadata on a page layout. The actual class is working fine, it is just the mock test that keeps failing with a System.NullPointerException: Attempt to de-reference a null object at the point where I do the readMetadata call. Any help would be greatly appreciated.

    Thanks
    Rudolf.

  31. shreya's avatar

    how to get list of sharing setting and sharing rules in salesforce using metadata api?

  32. Vamsi Katragadda's avatar

    Hi, below code is giving me an exception, any idea? i have the remote site settings and i am on Spring17 release.

    Exception:

    System.CalloutException: Web service callout failed: WebService returned a SOAP Fault: Must specify a {http://www.w3.org/2001/XMLSchema-instance}type attribute value for the {http://soap.sforce.com/2006/04/metadata}metadata element faultcode=soapenv:Client faultactor=

    Code:

    system.debug(‘printing ‘+URL.getSalesforceBaseUrl());
    MetadataService.MetadataPort service = new MetadataService.MetadataPort();
    service.SessionHeader = new MetadataService.SessionHeader_element();
    service.SessionHeader.sessionId = UserInfo.getSessionId();
    MetadataService.DuplicateRule customObject = new MetadataService.DuplicateRule();
    customObject.actionOnInsert=’allow’;
    customObject.actionOnUpdate=’allow’;
    customObject.isActive=true;
    customObject.masterLabel=’Main Label’;
    customObject.sortOrder=3;
    customObject.securityOption=’EnforceSharingRules’;
    string [] insertOperations = new string[]{‘Report’};
    string [] updateOperations = new string[]{‘Report’};

    MetadataService.SaveResult[] sr = service.createMetadata(new MetadataService.Metadata[]{customObject});

    • Andrew Fawcett's avatar

      This could be a bug witb the wrapper code not supporting the more complex sharing metadata types. Can you post an issue on the GitHub repo please

  33. Mudalige's avatar

    Hi Andrew,

    This is impressive. I’m trying to access metadata (Apex classes,VF pages,components,WF rules etc…) on Org B from Org A. I have the access token (retrieved via oAuth) to Org B. Can you use the same methodology to access them?

  34. John's avatar

    MetadataService.MetadataPort isn’t found in the MetadataService WSDL. I am actually using C# to set field permissions on a salesforce object.

  35. Sharan Desai's avatar

    Hi Andrew Fawcett,

    I am struggling to write an apex code to add new values to a standard picklist field, Can you please share some sample

  36. technologyconcept's avatar

    Hi People,

    Can anyone share apex code sample to add new values to a standard picklist field as a metadata service

  37. DevUser's avatar

    Could you please tell me if it is possible to install a managed package from app exchange also utilizing the metadata api?

  38. Shiva Nalla's avatar

    Hi Andrew,

    Thank you for sharing info on the Metadata api calls from Apex. I am trying to build a SandboxPostCopy script so that it can automate some of the post refresh activities. One of the setting I am trying to update is the remote site settings endpoints.

    After looking into some salesforce docs and online resources, I see that Metadata API is the only way to update RemoteSiteSettings. To access metadata api, I will need to configure the instance url as an endpoint which again requires accessing metadata api. Is there any other way to update the remote site settings through apex from the post copy script. Thanks in advance!

    • Andrew Fawcett's avatar

      This is a catch for sure. Do you find your sandbox is always spinning up on the same instance? If so add this to your production org remote sites. If not, you can deploy my domain to get a fixed URL.

  39. Ashish Keshari's avatar

    Hi Andrew,
    I have come up with some custom Apex coding to Read Report Folder and displaying users list within custom Report Folder using your MetadataService class and would like to post it as a blog in my website http://www.ashishkeshari.com. Is it fine with you and I will refer to your blog as source for MetadataService class and keep the header declaration as intact – is that fine with you ?

  40. Pingback: Custom Reports Folder Sharing List using Metadata API – It's getting cloudy here…

  41. Pingback: Salesforce MetaData API Usage – Create Custom Field | Sharon Maliakkal

  42. Bharath's avatar

    Hi Andrew, Iam able to fetch data from Metadata API by using both listmetadata and readmetadata method by passing the fullname of listmetadata to Read Metadata inorder to retrieve other labels.Now i created two webservice mocks for listmetadata and readmetadata .when i try to test the main class with the both the webservice classes,only one (either listmeta or readmeta)is able to cover and eventually test class is failing with a stacktrace error,
    Any help is appreciable ,Thanks in advance

  43. Bharath's avatar

    Hi Andy, Would you Explain Why readmetadata method in Metadataport is not invoked in MetaData Service Test Class ?

    • Andrew Fawcett's avatar

      It’s a complex API and mocking those responses didn’t seem valuable. Most of the code is system generated by salesforce as well. I appreciate this means not 100% coverage. If it’s an issue feel free to raise a GitHub request and we can look at it in the future. 👍🏻

  44. theauthor36's avatar

    Hi Andy, I’m using your Metadata API to get a list of RemoteSites but the results do not include the actual URL only the names of the metadata fields and the ID of the Remote Site. Because this object is not exposed I cannot retrieve the fields from this ID using a SOQL query. For example, I have the Remote Site name as Google below but I cannot get the Remote Site URL which is “http://www.google.com.” Any suggestions?

    These are the results

    fileName=remoteSiteSettings/GoogleHome.remoteSite, fileName_type_info=(fileName, http://soap.sforce.com/2006/04/metadata, null, 1, 1, false), fullName=GoogleHome,

    • theauthor36's avatar

      I’ve added these lines into the public class FileProperties but no joy…

      public String url;
      private String[] url_type_info = new String[]{‘url’,’http://soap.sforce.com/2006/04/metadata’,null,’1′,’1′,’false’};

      • Andrew Fawcett's avatar

        The listMetadata response only lists some details of the Metadata types. To get all details you need to use readMetadata method

    • Andrew Fawcett's avatar

      You need to use the readMetadata method once you know the full Metadata name of the remote site, which the listMetadata API returns. You can see examples of both in the MetadaraServiceExamples.cls class. Btw have you considered using Named Credentials? Assuming your wanting to avoid hard coding a URL is your motivation that is?

      • theauthor36's avatar

        I see several different readMetadata methods (readMetadata_element , readMetadataResponse_element) which one do I use and now that I have the Remote Site name how do I invoke it?

      • Andrew Fawcett's avatar

        There is only one readMetadata method, check out the examples in the metadataserviceexamples class

      • theauthor36's avatar

        Would this work?

        MetadataService.RemoteSiteSetting rss = (MetadataService.RemoteSiteSetting) service.readMetadata(‘Google’, new String[] { ‘URL’ }).getRecords()[0];

  45. theauthor36's avatar

    Andrew, I’m not sure I understand your response. I was referring to your Metadata Service class which has about three different variations of readMetaData methods. In any case, I did use the right readMetaData method and was unable to pull back the URL for the RemoteSite. It simply reads as “null.” This may be one of those fields that Salesforce doesn’t want to make accessible. Thanks for your blog, I find it very informative and interesting.

  46. shreya's avatar

    Hi Andrew,
    Is there any way to get list of standard objects fields. I have tried using Partner API, But I am getting callout exception. Can you suggest on this?

  47. Bharath Kumar Eilane's avatar

    Hi Andrew,
    I am facing an issue while in the xml response while solving a problem statement regarding security settings from metadata class stating that “Web service callout failed: Unable to parse callout response. Apex type not found for element referrerPolicy”, and before this i got a similar error with “Web service callout failed: Unable to parse callout response. Apex type not found for element hstsOnForcecomSites”,i solved this thing by adding this newly added metadata field in the class,but now i am unable to trace the error for the first error, is there any way to find that error?any help would be greatly appreciated and Thanks in advance

    • Andrew Fawcett's avatar

      Have you downloaded the latest file from GitHub? It seems these are fields that are not in the wsdl used to generate the class code. Sometimes this happens, your approach is one way to solve it. But if the missing info is complex it can be hard to guess. Please check the Apex Metadata api for your type and also check the wsdl. Did you by any chance change the version of Metadata api used by the class? If so this can also cause the issue, as the server will return xml not supported by the code since it was generated from an earlier version. If you need a new api version check for the latest in GitHub or follow the notes in the readme to generate a new one (though I think the latest was recently uploaded). Hope this helps. If not raise an issue on the GitHub sure and myself or another can try to help. Easier than chatting here. Andy

      • Bharath Kumar Eilane's avatar

        Thanks for the valuable suggestions Andy!! I Solved The issue by adding addditional required code in my metadata class by debugging the response,now its working fine

      • Andrew Fawcett's avatar

        Thanks! Would you mind sharing snippets of what you added on the GitHub repo please?

  48. Ibad Rahman's avatar

    Hi Andy, I was writing a test class for some code that calls your wrapper to retrieve and modify picklist values. I was wondering if it’s possible to interrogate the request object’s parameters in the doInvoke method in the mock class? The use-case is that I would like to differentiate between a request for one picklist and another. Ideally I would also like to be able to see the metadatatype being requested, though this is optional at this point as so far my code just asks for ‘CustomField’ metadatatype . The type of request I am dealing with it readMetadata().

    • Andrew Fawcett's avatar

      Yep you should be able to cast the ‘request’ parameter passed into the doInvoke method to the request type and then assert on the contents of it. Have a read through the readMetadata method code to figure out the request type or do System.debug(String.valueOf(request));

  49. Steven's avatar

    Hi Andy, thanks for this tool.
    I’ve written a SandboxPostCopy class and it was used yesterday for the first time when we refreshed our sandbox. I see this line in the debug logs so I don’t think it’s worked. It’s from WebServiceCallout.invoke() in MetadataService.listMetadata(); Is there something extra I have to do to use Metadata API with SandboxPostCopy?

    CALLOUT_REQUEST|[9218]|listMetadata_element:[apex_schema_type_info=(http://soap.sforce.com/2006/04/metadata, true, false), asOfVersion=43.0, asOfVersion_type_info=(asOfVersion, http://soap.sforce.com/2006/04/metadata, null, 1, 1, false), field_order_type_info=(queries, asOfVersion), queries=(ListMetadataQuery:[apex_schema_type_info=(http://soap.sforce.com/2006/04/metadata, true, false), field_order_type_info=(folder, type_x), folder=null, folder_type_info=(folder, http://soap.sforce.com/2006/04/metadata, null, 0, 1, false), type_x=WorkflowOutboundMessage, type_x_type_info=(type, http://soap.sforce.com/2006/04/metadata, null, 1, 1, false)]), queries_type_info=(queries, http://soap.sforce.com/2006/04/metadata, null, 0, -1, false)]::SOAPAction=”” Accept=text/xml User-Agent=SFDC-Callout/44.0 SFDC_STACK_DEPTH=1 Content-Type=text/xml; charset=UTF-8

    EXCEPTION_THROWN|[9218]|System.CalloutException: Web service callout failed: WebService returned a SOAP Fault: INVALID_SESSION_ID: Invalid Session ID found in SessionHeader: Illegal Session faultcode=sf:INVALID_SESSION_ID faultactor=

    Thanks!

    • Andrew Fawcett's avatar

      This is by design the user context for sandbox copy classes does not expose a session id. This is a platform restriction. There was a discussion on twitter about this recently with no clear workaround other than having a vf page host the logic, which of course is not as automated as one would like.

      • Steven's avatar

        Thanks for the quick response. Shame there’s no proper workaround but now I know I’ll manually work around it! Thanks!

  50. T Dandi's avatar

    Hi Andy, I am working on creating a script to create custom force.com site. Thanks to the examples in git, I can do that. However, I wanted to know if I can also create Force.com site subdomain via MetadataService to create a domain, if no domain exists. Thanks!

Leave a comment