[SalesForce] Deploying components via Metadata API from Apex

I was trying to invoke metadata api from apex. Link provides an excellent way to do that.
I did generate the Apex Class and now as per the post's code when i run that code it should create an object on the fly, callout happened Succesfully ( when i ran in developer console logs showed success ). But its not reflected even after couple of hours.

Did i miss anything?

Best Answer

The Salesforce Metadata API is asynchronous. Meaning you do not get an immediate, yes/no, answer from it. You need to call the checkStatus operation to poll for the result, as described here.

Basic Steps for Creating Metadata Components

Use the following process to create metadata components:

Design an array and populate it with the components that you want to create.

Call create() with the component array passed in as an argument.

An AsyncResult object is returned for each component you tried to create. It is updated with status information as the operation moves from a queue to completed or error state.

Call checkStatus() in a loop until the status values in AsyncResult indicate that all the create operations are completed. Start with a wait time of one second between iterations of checkStatus() calls, and double the wait time each time you make a subsequent call.

If your using the API with Apex, you must poll for it rather than using a loop (as Apex does not have the concept of pausing the execution for duration). You can either use apex:actionPoller (Visualforce) or Batch Apex. The library you have linked to gives examples of each described in the read me file.

Here is an example from the Apex Metadata library submitting the Metadata creations via Batch Apex and having it poll those operations, submitting an email (action configurable) to the user with the results.

// Define Metadata item to create a Custom Object
MetadataService.CustomObject customObject = new MetadataService.CustomObject();
customObject.fullName = objectName + '__c';
customObject.label = objectName;
customObject.pluralLabel = objectName+'s';
customObject.nameField = new MetadataService.CustomField();
customObject.nameField.type_x = 'Text';
customObject.nameField.label = 'Test Record';
customObject.deploymentStatus = 'Deployed';
customObject.sharingModel = 'ReadWrite';

// Pass the Metadata items to the job for processing, indicating any dependencies
MetadataCreateJob.run(
    new List<MetadataCreateJob.Item> { 
            new MetadataCreateJob.Item(customObject) },
    new MetadataCreateJob.EmailNotificationMetadataAsyncCallback());