Hi,
When we create a class to insert metadata using Metadata class then we write callback class to send notifications or another process about the status of deployment or insert of metadata.
Callback class:
public class PostInstallCallback implements Metadata.DeployCallback{
public void handleResult(Metadata.DeployResult result,
Metadata.DeployCallbackContext context) {
if (result.status == Metadata.DeployStatus.Succeeded) {
// Deployment was successful, take appropriate action.
Messaging.SingleEmailMessage msgObj = new Messaging.SingleEmailMessage ();
msgObj.setSubject('MetaData insertion succeeded');
List<String> emailAddresses = new List<String>{UserInfo.getUserEmail()};
Metadata.DeployDetails deployDetailsList = result.details;
List<Metadata.DeployMessage> deploymentMessagesList = deployDetailsList.componentSuccesses;
String errorMessageBody = '';
for(Metadata.DeployMessage messageObj:deploymentMessagesList){
if(messageObj.success==true && !String.valueOf(messageObj.fullName).split('\\.')[1].containsIgnoreCase('xml')){
errorMessageBody+=String.valueOf(messageObj.fullName).split('\\.')[1]+'\n';
}
}
errorMessageBody +=' records created';
msgObj.setPlainTextBody(errorMessageBody);
msgObj.setToAddresses(emailAddresses);
Messaging.sendEmail(new List<Messaging.Email>{msgObj});
} else {
// Deployment wasn’t successful, take appropriate action.
Messaging.SingleEmailMessage msgObj = new Messaging.SingleEmailMessage ();
msgObj.setSubject('MetaData insertion failed');
msgObj.setPlainTextBody(result.details+'='+result.errorMessage);
List<String> emailAddresses = new List<String>{UserInfo.getUserEmail()};
Metadata.DeployDetails deployDetailsList = result.details;
List<Metadata.DeployMessage> deploymentMessagesList = deployDetailsList.componentFailures;
String errorMessageBody = '';
for(Metadata.DeployMessage messageObj:deploymentMessagesList){
if(messageObj.success==false){
errorMessageBody+=messageObj.problem+'\n';
}
}
msgObj.setPlainTextBody(errorMessageBody);
msgObj.setToAddresses(emailAddresses);
Messaging.sendEmail(new List<Messaging.Email>{msgObj});
}
}
}
Test Class:
@isTest
private class PostInstallCallbackTest {
@IsTest
static void testMyCallback() {
// Instantiate the callback.
Metadata.DeployCallback callback = new PostInstallCallback();
// Create test result and context objects.
Metadata.DeployResult result = new Metadata.DeployResult();
result.status = Metadata.DeployStatus.Succeeded;
Metadata.DeployMessage messageObj = new Metadata.DeployMessage();
messageObj.changed = true;
messageObj.success = true;
messageObj.fullName='';
messageObj.componentType ='CustomMetadata';
messageObj.fullName = 'VAT_Rate.SreeVardhan3';
Metadata.DeployDetails deployDetailsObj = new Metadata.DeployDetails();
deployDetailsObj.componentSuccesses.add(messageObj);
result.details = deployDetailsObj;
Metadata.DeployCallbackContext context = new Metadata.DeployCallbackContext();
// Invoke the callback's handleResult method.
callback.handleResult(result, context);
}
@IsTest
static void testMyCallbackErrorMessage() {
// Instantiate the callback.
Metadata.DeployCallback callback = new PostInstallCallback();
// Create test result and context objects.
Metadata.DeployResult result = new Metadata.DeployResult();
result.status = Metadata.DeployStatus.Failed;
Metadata.DeployMessage messageObj = new Metadata.DeployMessage();
messageObj.changed = false;
messageObj.success = false;
messageObj.componentType ='CustomMetadata';
messageObj.fullName = 'VAT_Rate.SreeVardhan3';
messageOBj.problem = 'Default: value not of required type: 1';
messageObj.problemType = Metadata.DeployProblemType.Error;
Metadata.DeployDetails deployDetailsObj = new Metadata.DeployDetails();
deployDetailsObj.componentFailures.add(messageObj);
result.details = deployDetailsObj;
Metadata.DeployCallbackContext context = new Metadata.DeployCallbackContext();
// Invoke the callback's handleResult method.
callback.handleResult(result, context);
}
}
References:
https://trailhead.salesforce.com/en/content/learn/modules/apex_metadata_api/apex_metadata_api_testing
When we create a class to insert metadata using Metadata class then we write callback class to send notifications or another process about the status of deployment or insert of metadata.
Callback class:
public class PostInstallCallback implements Metadata.DeployCallback{
public void handleResult(Metadata.DeployResult result,
Metadata.DeployCallbackContext context) {
if (result.status == Metadata.DeployStatus.Succeeded) {
// Deployment was successful, take appropriate action.
Messaging.SingleEmailMessage msgObj = new Messaging.SingleEmailMessage ();
msgObj.setSubject('MetaData insertion succeeded');
List<String> emailAddresses = new List<String>{UserInfo.getUserEmail()};
Metadata.DeployDetails deployDetailsList = result.details;
List<Metadata.DeployMessage> deploymentMessagesList = deployDetailsList.componentSuccesses;
String errorMessageBody = '';
for(Metadata.DeployMessage messageObj:deploymentMessagesList){
if(messageObj.success==true && !String.valueOf(messageObj.fullName).split('\\.')[1].containsIgnoreCase('xml')){
errorMessageBody+=String.valueOf(messageObj.fullName).split('\\.')[1]+'\n';
}
}
errorMessageBody +=' records created';
msgObj.setPlainTextBody(errorMessageBody);
msgObj.setToAddresses(emailAddresses);
Messaging.sendEmail(new List<Messaging.Email>{msgObj});
} else {
// Deployment wasn’t successful, take appropriate action.
Messaging.SingleEmailMessage msgObj = new Messaging.SingleEmailMessage ();
msgObj.setSubject('MetaData insertion failed');
msgObj.setPlainTextBody(result.details+'='+result.errorMessage);
List<String> emailAddresses = new List<String>{UserInfo.getUserEmail()};
Metadata.DeployDetails deployDetailsList = result.details;
List<Metadata.DeployMessage> deploymentMessagesList = deployDetailsList.componentFailures;
String errorMessageBody = '';
for(Metadata.DeployMessage messageObj:deploymentMessagesList){
if(messageObj.success==false){
errorMessageBody+=messageObj.problem+'\n';
}
}
msgObj.setPlainTextBody(errorMessageBody);
msgObj.setToAddresses(emailAddresses);
Messaging.sendEmail(new List<Messaging.Email>{msgObj});
}
}
}
Test Class:
@isTest
private class PostInstallCallbackTest {
@IsTest
static void testMyCallback() {
// Instantiate the callback.
Metadata.DeployCallback callback = new PostInstallCallback();
// Create test result and context objects.
Metadata.DeployResult result = new Metadata.DeployResult();
result.status = Metadata.DeployStatus.Succeeded;
Metadata.DeployMessage messageObj = new Metadata.DeployMessage();
messageObj.changed = true;
messageObj.success = true;
messageObj.fullName='';
messageObj.componentType ='CustomMetadata';
messageObj.fullName = 'VAT_Rate.SreeVardhan3';
Metadata.DeployDetails deployDetailsObj = new Metadata.DeployDetails();
deployDetailsObj.componentSuccesses.add(messageObj);
result.details = deployDetailsObj;
Metadata.DeployCallbackContext context = new Metadata.DeployCallbackContext();
// Invoke the callback's handleResult method.
callback.handleResult(result, context);
}
@IsTest
static void testMyCallbackErrorMessage() {
// Instantiate the callback.
Metadata.DeployCallback callback = new PostInstallCallback();
// Create test result and context objects.
Metadata.DeployResult result = new Metadata.DeployResult();
result.status = Metadata.DeployStatus.Failed;
Metadata.DeployMessage messageObj = new Metadata.DeployMessage();
messageObj.changed = false;
messageObj.success = false;
messageObj.componentType ='CustomMetadata';
messageObj.fullName = 'VAT_Rate.SreeVardhan3';
messageOBj.problem = 'Default: value not of required type: 1';
messageObj.problemType = Metadata.DeployProblemType.Error;
Metadata.DeployDetails deployDetailsObj = new Metadata.DeployDetails();
deployDetailsObj.componentFailures.add(messageObj);
result.details = deployDetailsObj;
Metadata.DeployCallbackContext context = new Metadata.DeployCallbackContext();
// Invoke the callback's handleResult method.
callback.handleResult(result, context);
}
}
References:
https://trailhead.salesforce.com/en/content/learn/modules/apex_metadata_api/apex_metadata_api_testing