3. Agenda
● Introducción
● Breves definiciones
● WSDL to Apex
● Identificando estructuras
● Estrategia
● Caso de estudio I
● Caso de estudio II
● Caso de estudio III
● ¿Preguntas? ¿Reflexiones?
4. Motivaciones
En muchas ocasiones, precisamos realizar modificaciones de metadata
directamente desde nuestra aplicación. Lamentablemente, Apex aún no expone
funcionalidades directas para poder lograr este cometido en la mayoría de los
casos.
¿Ejemplos?
5. Algunos acuerdos previos
● Código con tinte académico.
● Simplificación de muchos conceptos (por razones de tiempo y para no dormir al auditorio).
6. Web Service Description Language
El WSDL es un lenguaje de descripción de interfaz basado en XML y se utiliza
para describir la funcionalidad ofrecida por un web service.
7. Metadata API
Definición de Salesforce:
Use Metadata API to retrieve, deploy, create, update, or delete customizations for your org. The most common use is to migrate changes from a sandbox or
testing org to your production environment. Metadata API is intended for managing customizations and for building tools that can manage the metadata
model, not the data itself.
The easiest way to access the functionality in Metadata API is to use the Salesforce Extensions for Visual Studio Code or the Ant Migration Tool. Both tools
are built on top of Metadata API and use the standard tools to simplify working with Metadata API.
● The Salesforce Extensions for Visual Studio Code includes tools for developing on the Salesforce platform in the lightweight, extensible VS
Code editor. These tools provide features for working with development orgs (scratch orgs, sandboxes, and DE orgs), Apex, Aura components,
and Visualforce.
● The Ant Migration Tool is ideal if you use a script or the command line for moving metadata between a local directory and a Salesforce org.
¿Y Apex?
8. WSDL to Apex Class
Si tengo un WSDL puedo convertirlo a una Apex Class.
9. WSDL to Apex Class
¿Qué WSDL preciso? Medata WSDL
¿Dónde lo obtengo? Setup -> API
10. WSDL to Apex Class
Point and Click. Al parecer simple (tan sólo cambiar el port Metadata de nombre)
¿Qué podría salir mal?
11. WSDL to Apex Class
Veamos este problema como una oportunidad de entender el funcionamiento y
poder configurar o armar la clase, con los requerimientos mínimos que nuestro
negocio nos pide.
● Clase innecesariamente grande (en muchos casos).
○ Problemas “estructurales”.
○ Problemas conceptuales (uso una clase que la instalo y no tengo mucha idea que hace).
■ Proyecto que dio soporte por muchos años a estos problemas.
■ https://github.com/financialforcedev/apex-mdapi
13. WSDL to Apex Class - Tunning
Estrategia de abordaje.
● ¿Qué precisa el negocio?
● ¿Qué metadata preciso para cumplir con los requisitos?
Con las respuestas a estas preguntas, diseño mi clase y la armo.
(Va algún tip o receta para que la clase compile)
14. Caso de estudio. Named Credentials.
● ¿Qué precisa el negocio?
○ Crear dinámicamente y por código una named credential.
● ¿Qué metadata preciso para cumplir con los requisitos?
Metadata específica.
● NamedCredential
Atributos.
● LogInfo
● SessionHeader_element
● DebuggingInfo_element
● DebuggingHeader_element
● CallOptions_element
● AllOrNoneHeader_element
● createMetadata_element
● createMetadataResponse_element
● SaveResult
● Error
● ExtendedErrorDetails
Funciones.
● createMetadata
¿Cómo obtengo estos atributos?
15. Caso de estudio. Named Credentials.
La clase que nunca se generó me va a
servir para obtener los componentes
que mencionamos previamente.
Voy a quedarme con el código que
preciso (y hasta puedo usar el mismo
nombre para evitar tener que hacer
algún replace).
public String endpoint_x = URL.getSalesforceBaseUrl().toExternalForm() + '/services/Soap/m/51.0';
Inner class virtual Metadata .
public virtual class Metadata {
public String fullName;
}
La metadata específica va a extender a Metadata. En nuestro ejemplo:
public class NamedCredential extends Metadata{
En la clase agregamos:
public String type = 'NamedCredential';
public String fullName;
private String[] fullName_type_info = new String[]{'fullName','http://soap.sforce.com/2006/04/metadata',null,'0','1','false'};
private String[] type_att_info = new String[]{'xsi:type'};
Y modificamos (le agregamos ‘fullName’ a la lista de strings):
private String[] field_order_type_info = new String[]{'fullName',
'allowMergeFieldsInBody','allowMergeFieldsInHeader','authProvider','authTokenEndpointUrl','awsAccessKey','awsAccessSecret','awsRegion','awsService','certificate','end
point','generateAuthorizationHeader','jwtAudience','jwtFormulaSubject','jwtIssuer','jwtSigningCertificate','jwtTextSubject','jwtValidityPeriodSeconds','label','oauthR
efreshToken','oauthScope','oauthToken','outboundNetworkConnection','password','principalType','protocol','username'};
Lista de pasos para que la clase
funcione.
16. Caso de estudio. Named Credentials.
Generó el código que va a utilizar esta clase recientemente creada.
DemoService.MetadataPort service = new DemoService.MetadataPort();
service.SessionHeader = new DemoService.SessionHeader_element();
service.SessionHeader.sessionId = UserInfo.getSessionId();
DemoService.NamedCredential credential = new DemoService.NamedCredential();
credential.fullName = 'TrailblazerDemoAPI';
credential.label = 'Trailblazer Demo';
credential.endpoint = 'https://aquivalabs.com';
credential.principalType = 'NamedUser';
credential.protocol = 'AwsSv4';
credential.awsAccessKey = 'AKIARU6LVKHX2ITYNXXX';
credential.awsAccessSecret = 'NqaXhfFyRfMXTyWuHqEU86DJCVbM3uWdX6BZZZZ';
credential.awsRegion = 'us-west-2';
credential.awsService = 'execute-api';
credential.generateAuthorizationHeader = true;
DemoService.SaveResult[] res = service.createMetadata(new DemoService.Metadata[] {credential});
17. Caso de estudio. Permission sets.
● ¿Qué precisa el negocio?
○ Crear al dinámicamente y por código un permission set
○ Configurar algún permiso para un objeto y un campo
● ¿Qué metadata preciso para cumplir con los requisitos?
Funciones.
● createMetadata
Metadata específica.
● PermissionSet
Atributos.
● LogInfo
● SessionHeader_element
● DebuggingInfo_element
● DebuggingHeader_element
● CallOptions_element
● AllOrNoneHeader_element
● createMetadata_element
● createMetadataResponse_element
● SaveResult
● Error
● ExtendedErrorDetails
● PermissionSetApplicationVisibility
● PermissionSetApexClassAccess
● …………………..
● ………………......
● ...........................
● PermissionSetUserPermission
18. Caso de estudio. Custom Object (usando clase completa)
● ¿Qué precisa el negocio?
○ Crear al dinámicamente y por código un objeto
● ¿Qué metadata preciso para cumplir con los requisitos?
Funciones.
● createMetadata
Metadata específica.
● CustomObject
Atributos.
● LogInfo
● SessionHeader_element
● DebuggingInfo_element
● DebuggingHeader_element
● CallOptions_element
● AllOrNoneHeader_element
● createMetadata_element
● createMetadataResponse_element
● SaveResult
● Error
● ExtendedErrorDetails
● ..................................
● ..................................
● Y muchos otros más...
https://github.com/financialforcedev/apex-mdapi/blob/master/apex-mdapi/src/classes/MetadataServiceExamples.cls
19. Caso de estudio. Remote Site Setting
● ¿Qué precisa el negocio?
○ Crear al dinámicamente y por código un remote site setting.
○ Verificar desde apex que existe ese Remote Site Setting
● ¿Qué metadata preciso para cumplir con los requisitos?
Funciones.
● createMetadata
● listMetadata
Metadata específica.
● RemoteSiteSetting
Atributos.
● LogInfo
● SessionHeader_element
● DebuggingInfo_element
● DebuggingHeader_element
● CallOptions_element
● AllOrNoneHeader_element
● createMetadata_element
● createMetadataResponse_element
● SaveResult
● Error
● ExtendedErrorDetails
● ..................................
● ..................................
● Y muchos otros más...