SlideShare a Scribd company logo
1 of 29
Using the Tooling API to Generate 
Apex SOAP Web Service Clients 
Daniel Ballinger 
Senior Developer 
@FishOfPrey
Daniel Ballinger 
Senior Developer 
@FishOfPrey
Have you ever seen… 
Feature Limits 
Apex and 
Deployment 
No file chosen 
Choose File 
Error: Failed to parse wsdl: Unknown element: import 
No file chosen 
Choose File 
Error: Failed to parse wsdl: Found more than one wsdl:binding. WSDL with multiple binding not supported 
Apex Generation Failed 
Unsupported WSDL. Found more than one part for message XAVRequestMessage 
Apex Generation Failed 
Unsupported schema type: {http://www.w3.org/2001/XMLSchema}anyType 
Apex Generation Failed 
The total size of apex code in this application after removing comments exceeds the maximum character size of 
3000000 
Apex Generation Failed 
Class name 'toolingSoapSforceCom' already in use. Please delete this class or specify a new class name 
Supported WSDL Features 
http://www.salesforce.com/us/developer/docs/apexcode/Content/apex_callouts_wsdl2apex.htm#supported_wsdls_topic-title
In This Session 
•The FuseIT SFDC Explorer tool 
• Existing Salesforce WSDL functionality 
•Demo custom WSDL to Apex tooling 
•How it was made
The FuseIT SFDC Explorer Tool – FusesFriend 
• Features 
• Windows only for the full tool 
• Basic web version of WSDL tooling 
– Session management 
– Schema Explorer + Tooling API 
– SOQL queries 
– Running Test Cases 
– Debug Log Monitoring 
– Data Export Retrieval 
– Anonymous Apex 
– Code Coverage 
– WSDL import to Apex 
http://www.fuseit.com/explorer
Unsupported 
feature 
Existing WSDL2Apex Experience 
WSDL 
> 1 MB 
<xsd:import> 
<xsd:include> 
Existing Class 
Name 
Manually 
Edit WSDL 
Superfluous 
bindings 
Download 
single WSDL 
Generate 
from WSDL 
Upload 
single WSDL 
Namespaces 
to Classes 
Generate 
Apex Code 
Call 
Generated 
Code
Shaving the [WSDL] Yak 
“Yak shaving is what you are doing when you're doing 
some stupid, fiddly little task that bears no obvious 
relationship to what you're supposed to be working 
on, but yet a chain of twelve causal relations links 
what you're doing to the original meta-task.” 
Scott Hanselman 
Photo by Dennis Jarvis CC BY-SA 3.0
Demo 
SFDC Explorer Basic
The IT Crowd – Series 1 Episode 2: Fire!
Code Coverage Testing for Generated Code 
•Need to implement WebServiceMock Interface 
• Invoke each web service method 
•Handle Request and Response types 
•Supporting Types (Headers)
Demo 
SFDC Explorer Web Service Mock
The Metadata API – Handling larger WSDLs 
Class name 'Metadata' already in use. 
Please edit WSDL to remove repeated 
names 
• CustomObject et al. extend Metadata and 
need elements from it to work correctly. 
<xs:extension base="Metadata"> 
• 330 KB WSDL 
Apex Character Limit 
Metadata 
590,915 
Remaining 
• 590,915 characters / 6740 lines 
without comments 
• Approximately 20% of 3,000,000 
character Apex limit
Method filtering functionality 
•Reduces amount of generated code 
•Reduces testing requirements for dead code 
• Potentially skips unsupported features 
• Optionally remove supporting Apex classes
Demo 
SFDC Explorer Method filtering
How it works 
Deploy to 
Salesforce 
• Tooling API to 
deploy all 
associated Apex 
classes at once 
Transform 
to Apex 
• T4 (Text Template 
Transformation 
Toolkit)Templates to 
convert the object 
model into Apex 
Build Apex 
Model 
• C# Object Model of 
Apex Classes, 
Members and 
Methods 
Parse 
WSDL 
• Import all WSDL 
data and extract 
required elements
.NET Representation of Apex Class model 
ApexClass 
1 InnerApexClasses * Members * Methods 
ApexClassCollection ApexMember 
StringArrayApexMember 
ApexMethod 
ApexMethodParameter 
ApexMethodHttp 
ReturnType 
ReturnVoid ReturnPrimitive ReturnClassType 
Type Infos 
Inner Classes 
Namespace Collection 
Parameters 
* 
ReturnType 
1 
ApexClasses 
0..* 
Outer class for each Namespace 
Created for the Port/Service 
Each Request/Response
Tooling API deployment 
Existing ID 
• Create a MetadataContainer with a 
unique name 
• Create a collection of 
ApexClassMember referencing the 
MetadataContainerId 
• Create a ContainerAsyncRequest 
– Option to Validate Only (IsCheckOnly) 
• Keep retrieving until the State is no 
longer Queued. 
• Delete MetadataContainer 
New – no existing ID 
• Call create and collect the SaveResults 
• Or create an empty stub class to get an 
ID and use the MetadataContainer
Tooling API deployment 
Existing ID 
• Create a MetadataContainer with a 
unique name 
• Create a collection of 
ApexClassMember referencing the 
MetadataContainerId 
• Create a ContainerAsyncRequest 
New – no existing ID 
• Call create and collect the SaveResults 
• Or create an empty stub class to get an 
ID and use the MetadataContainer 
List<ApexClass> apexClassesToInsert = new List<ApexClass>(); 
// Add ApexClass records with T4 generated Body 
ApexClass classToInsert = new ApexClass() { Name = "HelloDF" }; 
classToInsert.Body = "public class " + classToInsert.Name + " { public class Add{ }}"; 
apexClasses.Add(classToInsert); 
– Option to Validate Only (IsCheckOnly) 
• Keep retrieving until the State is no 
longer Queued. 
• Delete MetadataContainer 
SaveResult[] saveResults = toolingService.create(apexClassesToInsert.ToArray()); 
if (saveResults != null) { 
foreach (SaveResult sr in saveResults) { 
if (!sr.success) { 
throw new ToolingCreateException(apexClassesToInsert.ToArray(), saveResults); 
} 
} 
}
Tooling API deployment 
Existing ID 
• Create a MetadataContainer with a 
unique name 
• Create a collection of 
ApexClassMember referencing the 
MetadataContainerId 
• Create a ContainerAsyncRequest 
New – no existing ID 
• Call create and collect the SaveResults 
• Or create an empty stub class to get an 
MIeDta adantda Cuosntea ithneer McoenttaadianetarC=onnetwaiMneetradataContainer(); 
– Option to Validate Only (IsCheckOnly) 
• Keep retrieving until the State is no 
longer Queued. 
• Delete MetadataContainer 
// max length 32 characters! 
container.Name = "UAC " + DateTime.Now.Ticks; 
SaveResult[] containerResults = toolingService.create(new sObject[] { container }); 
if (!containerResults[0].success) { 
throw new ToolingCreateException(container, containerResults[0]); 
} 
Id metadataContainerId = new Id(containerResults[0].id);
Tooling API deployment 
Existing ID 
• Create a MetadataContainer with a 
unique name 
• Create a collection of 
ApexClassMember referencing the 
MetadataContainerId 
• Create a ContainerAsyncRequest 
– Option to Validate Only (IsCheckOnly) 
• Keep retrieving until the State is no 
longer Queued. 
• Delete MetadataContainer 
New – no existing ID 
• Call create and collect the SaveResults 
• Or create an empty stub class to get an 
ID and use the MetadataContainer 
var toUpdate = new List<ApexClassMember>(); 
foreach(ApexClass ac in classesToUpsert) { 
var acm = new ApexClassMember(); 
acm.ContentEntityId = ac.Id; // 01p… 
acm.Body = ac.Body; // T4 Template output 
acm.FullName = ac.Name; // class name 
acm.MetadataContainerId = 
metadataContainerId.CaseSafeID; 
toUpdate.Add(acm); 
} 
sObject[] toCreate = toUpdate.ToArray(); 
SaveResult[] cResult = 
toolingService.create(apexClassMembersToCreate); 
foreach (SaveResult sr in cResult) { 
if (!sr.success) { 
throw new ToolingCreateException(toCreate, 
cResult); 
} 
}
Tooling API deployment 
Existing ID 
• Create a MetadataContainer with a 
unique name 
• Create a collection of 
ApexClassMember referencing the 
MetadataContainerId 
• Create a ContainerAsyncRequest 
– Option to Validate Only (IsCheckOnly) 
• Keep retrieving until the State is no 
longer Queued. 
• Delete MetadataContainer 
var cr = new ContainerAsyncRequest(); 
cr.MetadataContainerId = 
metadataContainerId.CaseSafeID; 
cr.IsCheckOnly = false; 
SaveResult[] cars = this.create(new sObject[]{cr}); 
if (! cars[0].success) { 
throw new ToolingCreateException(cr,cars[0]); 
} 
ContainerAsyncRequest retrieve = 
WaitForClassToUpdate(containerAsyncResults); 
if (retrieve.State == "Failed") { 
throw ApexUpdateException.FromDeployDetails 
(retrieve.DeployDetails); 
} 
DeleteResult[] dr = this.delete(new string[] 
{ metadataContainerId.CaseSafeID });
WSDL Variation 
http://www.superbwallpapers.com/photography/snowflakes-10358/ 
If you have a unique WSDL: 
• http://www.fuseit.com/wsdlhelp 
• Please provide the WSDL details 
Use HTTP Requests for 
WebServiceCallout.invoke 
limits
Summary 
•Manually dealing with WSDL import errors is time consuming 
and error prone 
• Extended SOAP support for several common WSDL issues: 
– Increased support – <xsd:import> <xsd:include> <xsd:extension> 
– Generate basic code coverage 
– Method filtering to reduce Apex
Q&A 
+ What Next 
• Download: the free FuseIT SFDC Explorer Tool (or get the web version) 
http://www.fuseit.com/explorer 
• Idea: Run anonymous apex as if it were a test case 
http://goo.gl/Aci1ys 
• Salesforce: The now open source WSDL2Apex generator 
http://goo.gl/tUcnVj 
• Session: Building Callouts Without WSDL2Apex and Apex Parsers 
Tuesday, 4:00 PM - 4:30 PM | Moscone Center West | Mobile Theater 
www.fuseit.com 
@FishOfPrey 
www.fishofprey.com 
@GirishaArora 
Girisha Arora
Bonus Slides
Handling Extensions 
• <xsd:extension base=“”/> 
• Copy fields from base type to the 
sub class. 
• Use extends in the future 
• Metadata API 
• AccountOwnerSharingRule extends 
• OwnerSharingRule extends 
• BaseSharingRule extends 
• Metadata
HTTP Requests 
• When WebServiceCallout.invoke() fails 
• A template for supporting more complex callouts 
• Access full fault messages 
SOAPFault Information for Apex 
https://success.salesforce.com/ideaView?id=08730000000BqG9AAK
Apex Class Drifting with WSDL changes

More Related Content

What's hot

Building Web Interface On Rails
Building Web Interface On RailsBuilding Web Interface On Rails
Building Web Interface On RailsWen-Tien Chang
 
Lecture 3: Servlets - Session Management
Lecture 3:  Servlets - Session ManagementLecture 3:  Servlets - Session Management
Lecture 3: Servlets - Session ManagementFahad Golra
 
Comment utiliser Visual Studio Code pour travailler avec une scratch Org
Comment utiliser Visual Studio Code pour travailler avec une scratch OrgComment utiliser Visual Studio Code pour travailler avec une scratch Org
Comment utiliser Visual Studio Code pour travailler avec une scratch OrgThierry TROUIN ☁
 
In memory OLAP engine
In memory OLAP engineIn memory OLAP engine
In memory OLAP engineWO Community
 
Spray - Build RESTfull services in scala
Spray - Build RESTfull services in scalaSpray - Build RESTfull services in scala
Spray - Build RESTfull services in scalaSandeep Purohit
 
SDPHP Lightning Talk - Let's Talk Laravel
SDPHP Lightning Talk - Let's Talk LaravelSDPHP Lightning Talk - Let's Talk Laravel
SDPHP Lightning Talk - Let's Talk Laravelmarcusamoore
 
Créer et gérer une scratch org avec Visual Studio Code
Créer et gérer une scratch org avec Visual Studio CodeCréer et gérer une scratch org avec Visual Studio Code
Créer et gérer une scratch org avec Visual Studio CodeThierry TROUIN ☁
 
Remote code-with-expression-language-injection
Remote code-with-expression-language-injectionRemote code-with-expression-language-injection
Remote code-with-expression-language-injectionMickey Jack
 
Barcamp Auckland Rails3 presentation
Barcamp Auckland Rails3 presentationBarcamp Auckland Rails3 presentation
Barcamp Auckland Rails3 presentationSociable
 
Activator and Reactive at Play NYC meetup
Activator and Reactive at Play NYC meetupActivator and Reactive at Play NYC meetup
Activator and Reactive at Play NYC meetupHenrik Engström
 
Spring 3: What's New
Spring 3: What's NewSpring 3: What's New
Spring 3: What's NewTed Pennings
 
ERRest - The Next Steps
ERRest - The Next StepsERRest - The Next Steps
ERRest - The Next StepsWO Community
 

What's hot (20)

Building Web Interface On Rails
Building Web Interface On RailsBuilding Web Interface On Rails
Building Web Interface On Rails
 
Lecture 3: Servlets - Session Management
Lecture 3:  Servlets - Session ManagementLecture 3:  Servlets - Session Management
Lecture 3: Servlets - Session Management
 
Comment utiliser Visual Studio Code pour travailler avec une scratch Org
Comment utiliser Visual Studio Code pour travailler avec une scratch OrgComment utiliser Visual Studio Code pour travailler avec une scratch Org
Comment utiliser Visual Studio Code pour travailler avec une scratch Org
 
ERRest
ERRestERRest
ERRest
 
Backbone js
Backbone jsBackbone js
Backbone js
 
In memory OLAP engine
In memory OLAP engineIn memory OLAP engine
In memory OLAP engine
 
Spray - Build RESTfull services in scala
Spray - Build RESTfull services in scalaSpray - Build RESTfull services in scala
Spray - Build RESTfull services in scala
 
SDPHP Lightning Talk - Let's Talk Laravel
SDPHP Lightning Talk - Let's Talk LaravelSDPHP Lightning Talk - Let's Talk Laravel
SDPHP Lightning Talk - Let's Talk Laravel
 
70562 (1)
70562 (1)70562 (1)
70562 (1)
 
Créer et gérer une scratch org avec Visual Studio Code
Créer et gérer une scratch org avec Visual Studio CodeCréer et gérer une scratch org avec Visual Studio Code
Créer et gérer une scratch org avec Visual Studio Code
 
ERRest in Depth
ERRest in DepthERRest in Depth
ERRest in Depth
 
Remote code-with-expression-language-injection
Remote code-with-expression-language-injectionRemote code-with-expression-language-injection
Remote code-with-expression-language-injection
 
Barcamp Auckland Rails3 presentation
Barcamp Auckland Rails3 presentationBarcamp Auckland Rails3 presentation
Barcamp Auckland Rails3 presentation
 
KAAccessControl
KAAccessControlKAAccessControl
KAAccessControl
 
IoC with PHP
IoC with PHPIoC with PHP
IoC with PHP
 
Activator and Reactive at Play NYC meetup
Activator and Reactive at Play NYC meetupActivator and Reactive at Play NYC meetup
Activator and Reactive at Play NYC meetup
 
Ruby On Rails
Ruby On RailsRuby On Rails
Ruby On Rails
 
Spring 3: What's New
Spring 3: What's NewSpring 3: What's New
Spring 3: What's New
 
ERRest - The Next Steps
ERRest - The Next StepsERRest - The Next Steps
ERRest - The Next Steps
 
Cloudformation101
Cloudformation101Cloudformation101
Cloudformation101
 

Viewers also liked

Using Node.js for Mocking Apex Web Services
Using Node.js for Mocking Apex Web ServicesUsing Node.js for Mocking Apex Web Services
Using Node.js for Mocking Apex Web ServicesJeff Douglas
 
Parsing XML & JSON in Apex
Parsing XML & JSON in ApexParsing XML & JSON in Apex
Parsing XML & JSON in ApexAbhinav Gupta
 
Salesforce Apex Language Reference
Salesforce Apex Language ReferenceSalesforce Apex Language Reference
Salesforce Apex Language Referencesalesforcer
 
APEX & MTdoxx
APEX & MTdoxxAPEX & MTdoxx
APEX & MTdoxxMT AG
 
Getting Started With Apex REST Services
Getting Started With Apex REST ServicesGetting Started With Apex REST Services
Getting Started With Apex REST ServicesSalesforce Developers
 
Integrations with the Force.com Platform Using Custom Apex REST Services
Integrations with the Force.com Platform Using Custom Apex REST ServicesIntegrations with the Force.com Platform Using Custom Apex REST Services
Integrations with the Force.com Platform Using Custom Apex REST ServicesSalesforce Developers
 
Best practices in using Salesforce Metadata API
Best practices in using Salesforce Metadata APIBest practices in using Salesforce Metadata API
Best practices in using Salesforce Metadata APISanchit Dua
 
Integrate with External Systems using Apex Callouts
Integrate with External Systems using Apex CalloutsIntegrate with External Systems using Apex Callouts
Integrate with External Systems using Apex CalloutsSalesforce Developers
 
Batchable vs @future vs Queueable
Batchable vs @future vs QueueableBatchable vs @future vs Queueable
Batchable vs @future vs QueueableBoris Bachovski
 
Secure Salesforce: External App Integrations
Secure Salesforce: External App IntegrationsSecure Salesforce: External App Integrations
Secure Salesforce: External App IntegrationsSalesforce Developers
 
Advanced Platform Series - OAuth and Social Authentication
Advanced Platform Series - OAuth and Social AuthenticationAdvanced Platform Series - OAuth and Social Authentication
Advanced Platform Series - OAuth and Social AuthenticationSalesforce Developers
 
Make Your App Lightning Ready with Winter '17 (December 8, 2016)
Make Your App Lightning Ready with Winter '17 (December 8, 2016)Make Your App Lightning Ready with Winter '17 (December 8, 2016)
Make Your App Lightning Ready with Winter '17 (December 8, 2016)Salesforce Partners
 
Introduction to apex code
Introduction to apex codeIntroduction to apex code
Introduction to apex codeEdwinOstos
 

Viewers also liked (19)

Using Node.js for Mocking Apex Web Services
Using Node.js for Mocking Apex Web ServicesUsing Node.js for Mocking Apex Web Services
Using Node.js for Mocking Apex Web Services
 
Parsing XML & JSON in Apex
Parsing XML & JSON in ApexParsing XML & JSON in Apex
Parsing XML & JSON in Apex
 
Salesforce Apex Language Reference
Salesforce Apex Language ReferenceSalesforce Apex Language Reference
Salesforce Apex Language Reference
 
APEX & MTdoxx
APEX & MTdoxxAPEX & MTdoxx
APEX & MTdoxx
 
Getting Started With Apex REST Services
Getting Started With Apex REST ServicesGetting Started With Apex REST Services
Getting Started With Apex REST Services
 
Integrations with the Force.com Platform Using Custom Apex REST Services
Integrations with the Force.com Platform Using Custom Apex REST ServicesIntegrations with the Force.com Platform Using Custom Apex REST Services
Integrations with the Force.com Platform Using Custom Apex REST Services
 
Forcelandia 2015
Forcelandia 2015Forcelandia 2015
Forcelandia 2015
 
Best practices in using Salesforce Metadata API
Best practices in using Salesforce Metadata APIBest practices in using Salesforce Metadata API
Best practices in using Salesforce Metadata API
 
Salesforce asynchronous apex
Salesforce asynchronous apexSalesforce asynchronous apex
Salesforce asynchronous apex
 
Integrate with External Systems using Apex Callouts
Integrate with External Systems using Apex CalloutsIntegrate with External Systems using Apex Callouts
Integrate with External Systems using Apex Callouts
 
Using the Google SOAP API
Using the Google SOAP APIUsing the Google SOAP API
Using the Google SOAP API
 
Batchable vs @future vs Queueable
Batchable vs @future vs QueueableBatchable vs @future vs Queueable
Batchable vs @future vs Queueable
 
Using Apex for REST Integration
Using Apex for REST IntegrationUsing Apex for REST Integration
Using Apex for REST Integration
 
SalesForce WebServices part 2
SalesForce WebServices part 2SalesForce WebServices part 2
SalesForce WebServices part 2
 
Secure Salesforce: External App Integrations
Secure Salesforce: External App IntegrationsSecure Salesforce: External App Integrations
Secure Salesforce: External App Integrations
 
Exploring the Salesforce REST API
Exploring the Salesforce REST APIExploring the Salesforce REST API
Exploring the Salesforce REST API
 
Advanced Platform Series - OAuth and Social Authentication
Advanced Platform Series - OAuth and Social AuthenticationAdvanced Platform Series - OAuth and Social Authentication
Advanced Platform Series - OAuth and Social Authentication
 
Make Your App Lightning Ready with Winter '17 (December 8, 2016)
Make Your App Lightning Ready with Winter '17 (December 8, 2016)Make Your App Lightning Ready with Winter '17 (December 8, 2016)
Make Your App Lightning Ready with Winter '17 (December 8, 2016)
 
Introduction to apex code
Introduction to apex codeIntroduction to apex code
Introduction to apex code
 

Similar to Using the Tooling API to Generate Apex SOAP Web Service Clients

Local data storage for mobile apps
Local data storage for mobile appsLocal data storage for mobile apps
Local data storage for mobile appsIvano Malavolta
 
Local storage in Web apps
Local storage in Web appsLocal storage in Web apps
Local storage in Web appsIvano Malavolta
 
Swift Micro-services and AWS Technologies
Swift Micro-services and AWS TechnologiesSwift Micro-services and AWS Technologies
Swift Micro-services and AWS TechnologiesSimonPilkington8
 
DDD, CQRS and testing with ASP.Net MVC
DDD, CQRS and testing with ASP.Net MVCDDD, CQRS and testing with ASP.Net MVC
DDD, CQRS and testing with ASP.Net MVCAndy Butland
 
Asp.Net Ajax Component Development
Asp.Net Ajax Component DevelopmentAsp.Net Ajax Component Development
Asp.Net Ajax Component DevelopmentChui-Wen Chiu
 
Using Java to implement SOAP Web Services: JAX-WS
Using Java to implement SOAP Web Services: JAX-WS�Using Java to implement SOAP Web Services: JAX-WS�
Using Java to implement SOAP Web Services: JAX-WSKatrien Verbert
 
JAVA EE DEVELOPMENT (JSP and Servlets)
JAVA EE DEVELOPMENT (JSP and Servlets)JAVA EE DEVELOPMENT (JSP and Servlets)
JAVA EE DEVELOPMENT (JSP and Servlets)Talha Ocakçı
 
Cassandra Day Chicago 2015: Building Java Applications with Apache Cassandra
Cassandra Day Chicago 2015: Building Java Applications with Apache CassandraCassandra Day Chicago 2015: Building Java Applications with Apache Cassandra
Cassandra Day Chicago 2015: Building Java Applications with Apache CassandraDataStax Academy
 
Query service in vCloud Director
Query service in vCloud DirectorQuery service in vCloud Director
Query service in vCloud DirectorMayank Goyal
 
Scaling asp.net websites to millions of users
Scaling asp.net websites to millions of usersScaling asp.net websites to millions of users
Scaling asp.net websites to millions of usersoazabir
 
Google apps script database abstraction exposed version
Google apps script database abstraction   exposed versionGoogle apps script database abstraction   exposed version
Google apps script database abstraction exposed versionBruce McPherson
 
(DEV204) Building High-Performance Native Cloud Apps In C++
(DEV204) Building High-Performance Native Cloud Apps In C++(DEV204) Building High-Performance Native Cloud Apps In C++
(DEV204) Building High-Performance Native Cloud Apps In C++Amazon Web Services
 
Soa development using javascript
Soa development using javascriptSoa development using javascript
Soa development using javascriptDsixE Inc
 
WinAppDriver Development
WinAppDriver DevelopmentWinAppDriver Development
WinAppDriver DevelopmentJeremy Kao
 
Painless Persistence in a Disconnected World
Painless Persistence in a Disconnected WorldPainless Persistence in a Disconnected World
Painless Persistence in a Disconnected WorldChristian Melchior
 
Intro to Core Data
Intro to Core DataIntro to Core Data
Intro to Core DataMake School
 
Developing your first application using FIWARE
Developing your first application using FIWAREDeveloping your first application using FIWARE
Developing your first application using FIWAREFIWARE
 

Similar to Using the Tooling API to Generate Apex SOAP Web Service Clients (20)

Local data storage for mobile apps
Local data storage for mobile appsLocal data storage for mobile apps
Local data storage for mobile apps
 
AWS Java SDK @ scale
AWS Java SDK @ scaleAWS Java SDK @ scale
AWS Java SDK @ scale
 
Local storage in Web apps
Local storage in Web appsLocal storage in Web apps
Local storage in Web apps
 
Swift Micro-services and AWS Technologies
Swift Micro-services and AWS TechnologiesSwift Micro-services and AWS Technologies
Swift Micro-services and AWS Technologies
 
DDD, CQRS and testing with ASP.Net MVC
DDD, CQRS and testing with ASP.Net MVCDDD, CQRS and testing with ASP.Net MVC
DDD, CQRS and testing with ASP.Net MVC
 
Asp.Net Ajax Component Development
Asp.Net Ajax Component DevelopmentAsp.Net Ajax Component Development
Asp.Net Ajax Component Development
 
Using Java to implement SOAP Web Services: JAX-WS
Using Java to implement SOAP Web Services: JAX-WS�Using Java to implement SOAP Web Services: JAX-WS�
Using Java to implement SOAP Web Services: JAX-WS
 
JAVA EE DEVELOPMENT (JSP and Servlets)
JAVA EE DEVELOPMENT (JSP and Servlets)JAVA EE DEVELOPMENT (JSP and Servlets)
JAVA EE DEVELOPMENT (JSP and Servlets)
 
Cassandra Day Chicago 2015: Building Java Applications with Apache Cassandra
Cassandra Day Chicago 2015: Building Java Applications with Apache CassandraCassandra Day Chicago 2015: Building Java Applications with Apache Cassandra
Cassandra Day Chicago 2015: Building Java Applications with Apache Cassandra
 
Practical OData
Practical ODataPractical OData
Practical OData
 
Query service in vCloud Director
Query service in vCloud DirectorQuery service in vCloud Director
Query service in vCloud Director
 
Scaling asp.net websites to millions of users
Scaling asp.net websites to millions of usersScaling asp.net websites to millions of users
Scaling asp.net websites to millions of users
 
S313431 JPA 2.0 Overview
S313431 JPA 2.0 OverviewS313431 JPA 2.0 Overview
S313431 JPA 2.0 Overview
 
Google apps script database abstraction exposed version
Google apps script database abstraction   exposed versionGoogle apps script database abstraction   exposed version
Google apps script database abstraction exposed version
 
(DEV204) Building High-Performance Native Cloud Apps In C++
(DEV204) Building High-Performance Native Cloud Apps In C++(DEV204) Building High-Performance Native Cloud Apps In C++
(DEV204) Building High-Performance Native Cloud Apps In C++
 
Soa development using javascript
Soa development using javascriptSoa development using javascript
Soa development using javascript
 
WinAppDriver Development
WinAppDriver DevelopmentWinAppDriver Development
WinAppDriver Development
 
Painless Persistence in a Disconnected World
Painless Persistence in a Disconnected WorldPainless Persistence in a Disconnected World
Painless Persistence in a Disconnected World
 
Intro to Core Data
Intro to Core DataIntro to Core Data
Intro to Core Data
 
Developing your first application using FIWARE
Developing your first application using FIWAREDeveloping your first application using FIWARE
Developing your first application using FIWARE
 

Recently uploaded

Modernizing Legacy Systems Using Ballerina
Modernizing Legacy Systems Using BallerinaModernizing Legacy Systems Using Ballerina
Modernizing Legacy Systems Using BallerinaWSO2
 
Less Is More: Utilizing Ballerina to Architect a Cloud Data Platform
Less Is More: Utilizing Ballerina to Architect a Cloud Data PlatformLess Is More: Utilizing Ballerina to Architect a Cloud Data Platform
Less Is More: Utilizing Ballerina to Architect a Cloud Data PlatformWSO2
 
Polkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin WoodPolkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin WoodJuan lago vázquez
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FMESafe Software
 
Exploring Multimodal Embeddings with Milvus
Exploring Multimodal Embeddings with MilvusExploring Multimodal Embeddings with Milvus
Exploring Multimodal Embeddings with MilvusZilliz
 
MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024MIND CTI
 
JohnPollard-hybrid-app-RailsConf2024.pptx
JohnPollard-hybrid-app-RailsConf2024.pptxJohnPollard-hybrid-app-RailsConf2024.pptx
JohnPollard-hybrid-app-RailsConf2024.pptxJohnPollard37
 
JavaScript Usage Statistics 2024 - The Ultimate Guide
JavaScript Usage Statistics 2024 - The Ultimate GuideJavaScript Usage Statistics 2024 - The Ultimate Guide
JavaScript Usage Statistics 2024 - The Ultimate GuidePixlogix Infotech
 
WSO2 Micro Integrator for Enterprise Integration in a Decentralized, Microser...
WSO2 Micro Integrator for Enterprise Integration in a Decentralized, Microser...WSO2 Micro Integrator for Enterprise Integration in a Decentralized, Microser...
WSO2 Micro Integrator for Enterprise Integration in a Decentralized, Microser...WSO2
 
[BuildWithAI] Introduction to Gemini.pdf
[BuildWithAI] Introduction to Gemini.pdf[BuildWithAI] Introduction to Gemini.pdf
[BuildWithAI] Introduction to Gemini.pdfSandro Moreira
 
API Governance and Monetization - The evolution of API governance
API Governance and Monetization -  The evolution of API governanceAPI Governance and Monetization -  The evolution of API governance
API Governance and Monetization - The evolution of API governanceWSO2
 
AI+A11Y 11MAY2024 HYDERBAD GAAD 2024 - HelloA11Y (11 May 2024)
AI+A11Y 11MAY2024 HYDERBAD GAAD 2024 - HelloA11Y (11 May 2024)AI+A11Y 11MAY2024 HYDERBAD GAAD 2024 - HelloA11Y (11 May 2024)
AI+A11Y 11MAY2024 HYDERBAD GAAD 2024 - HelloA11Y (11 May 2024)Samir Dash
 
DEV meet-up UiPath Document Understanding May 7 2024 Amsterdam
DEV meet-up UiPath Document Understanding May 7 2024 AmsterdamDEV meet-up UiPath Document Understanding May 7 2024 Amsterdam
DEV meet-up UiPath Document Understanding May 7 2024 AmsterdamUiPathCommunity
 
Vector Search -An Introduction in Oracle Database 23ai.pptx
Vector Search -An Introduction in Oracle Database 23ai.pptxVector Search -An Introduction in Oracle Database 23ai.pptx
Vector Search -An Introduction in Oracle Database 23ai.pptxRemote DBA Services
 
Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...
Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...
Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...Orbitshub
 
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost SavingRepurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost SavingEdi Saputra
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FMESafe Software
 
How to Check CNIC Information Online with Pakdata cf
How to Check CNIC Information Online with Pakdata cfHow to Check CNIC Information Online with Pakdata cf
How to Check CNIC Information Online with Pakdata cfdanishmna97
 
AWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of TerraformAWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of TerraformAndrey Devyatkin
 
Simplifying Mobile A11y Presentation.pptx
Simplifying Mobile A11y Presentation.pptxSimplifying Mobile A11y Presentation.pptx
Simplifying Mobile A11y Presentation.pptxMarkSteadman7
 

Recently uploaded (20)

Modernizing Legacy Systems Using Ballerina
Modernizing Legacy Systems Using BallerinaModernizing Legacy Systems Using Ballerina
Modernizing Legacy Systems Using Ballerina
 
Less Is More: Utilizing Ballerina to Architect a Cloud Data Platform
Less Is More: Utilizing Ballerina to Architect a Cloud Data PlatformLess Is More: Utilizing Ballerina to Architect a Cloud Data Platform
Less Is More: Utilizing Ballerina to Architect a Cloud Data Platform
 
Polkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin WoodPolkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin Wood
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
 
Exploring Multimodal Embeddings with Milvus
Exploring Multimodal Embeddings with MilvusExploring Multimodal Embeddings with Milvus
Exploring Multimodal Embeddings with Milvus
 
MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024
 
JohnPollard-hybrid-app-RailsConf2024.pptx
JohnPollard-hybrid-app-RailsConf2024.pptxJohnPollard-hybrid-app-RailsConf2024.pptx
JohnPollard-hybrid-app-RailsConf2024.pptx
 
JavaScript Usage Statistics 2024 - The Ultimate Guide
JavaScript Usage Statistics 2024 - The Ultimate GuideJavaScript Usage Statistics 2024 - The Ultimate Guide
JavaScript Usage Statistics 2024 - The Ultimate Guide
 
WSO2 Micro Integrator for Enterprise Integration in a Decentralized, Microser...
WSO2 Micro Integrator for Enterprise Integration in a Decentralized, Microser...WSO2 Micro Integrator for Enterprise Integration in a Decentralized, Microser...
WSO2 Micro Integrator for Enterprise Integration in a Decentralized, Microser...
 
[BuildWithAI] Introduction to Gemini.pdf
[BuildWithAI] Introduction to Gemini.pdf[BuildWithAI] Introduction to Gemini.pdf
[BuildWithAI] Introduction to Gemini.pdf
 
API Governance and Monetization - The evolution of API governance
API Governance and Monetization -  The evolution of API governanceAPI Governance and Monetization -  The evolution of API governance
API Governance and Monetization - The evolution of API governance
 
AI+A11Y 11MAY2024 HYDERBAD GAAD 2024 - HelloA11Y (11 May 2024)
AI+A11Y 11MAY2024 HYDERBAD GAAD 2024 - HelloA11Y (11 May 2024)AI+A11Y 11MAY2024 HYDERBAD GAAD 2024 - HelloA11Y (11 May 2024)
AI+A11Y 11MAY2024 HYDERBAD GAAD 2024 - HelloA11Y (11 May 2024)
 
DEV meet-up UiPath Document Understanding May 7 2024 Amsterdam
DEV meet-up UiPath Document Understanding May 7 2024 AmsterdamDEV meet-up UiPath Document Understanding May 7 2024 Amsterdam
DEV meet-up UiPath Document Understanding May 7 2024 Amsterdam
 
Vector Search -An Introduction in Oracle Database 23ai.pptx
Vector Search -An Introduction in Oracle Database 23ai.pptxVector Search -An Introduction in Oracle Database 23ai.pptx
Vector Search -An Introduction in Oracle Database 23ai.pptx
 
Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...
Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...
Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...
 
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost SavingRepurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
 
How to Check CNIC Information Online with Pakdata cf
How to Check CNIC Information Online with Pakdata cfHow to Check CNIC Information Online with Pakdata cf
How to Check CNIC Information Online with Pakdata cf
 
AWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of TerraformAWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of Terraform
 
Simplifying Mobile A11y Presentation.pptx
Simplifying Mobile A11y Presentation.pptxSimplifying Mobile A11y Presentation.pptx
Simplifying Mobile A11y Presentation.pptx
 

Using the Tooling API to Generate Apex SOAP Web Service Clients

  • 1. Using the Tooling API to Generate Apex SOAP Web Service Clients Daniel Ballinger Senior Developer @FishOfPrey
  • 2. Daniel Ballinger Senior Developer @FishOfPrey
  • 3. Have you ever seen… Feature Limits Apex and Deployment No file chosen Choose File Error: Failed to parse wsdl: Unknown element: import No file chosen Choose File Error: Failed to parse wsdl: Found more than one wsdl:binding. WSDL with multiple binding not supported Apex Generation Failed Unsupported WSDL. Found more than one part for message XAVRequestMessage Apex Generation Failed Unsupported schema type: {http://www.w3.org/2001/XMLSchema}anyType Apex Generation Failed The total size of apex code in this application after removing comments exceeds the maximum character size of 3000000 Apex Generation Failed Class name 'toolingSoapSforceCom' already in use. Please delete this class or specify a new class name Supported WSDL Features http://www.salesforce.com/us/developer/docs/apexcode/Content/apex_callouts_wsdl2apex.htm#supported_wsdls_topic-title
  • 4. In This Session •The FuseIT SFDC Explorer tool • Existing Salesforce WSDL functionality •Demo custom WSDL to Apex tooling •How it was made
  • 5. The FuseIT SFDC Explorer Tool – FusesFriend • Features • Windows only for the full tool • Basic web version of WSDL tooling – Session management – Schema Explorer + Tooling API – SOQL queries – Running Test Cases – Debug Log Monitoring – Data Export Retrieval – Anonymous Apex – Code Coverage – WSDL import to Apex http://www.fuseit.com/explorer
  • 6. Unsupported feature Existing WSDL2Apex Experience WSDL > 1 MB <xsd:import> <xsd:include> Existing Class Name Manually Edit WSDL Superfluous bindings Download single WSDL Generate from WSDL Upload single WSDL Namespaces to Classes Generate Apex Code Call Generated Code
  • 7. Shaving the [WSDL] Yak “Yak shaving is what you are doing when you're doing some stupid, fiddly little task that bears no obvious relationship to what you're supposed to be working on, but yet a chain of twelve causal relations links what you're doing to the original meta-task.” Scott Hanselman Photo by Dennis Jarvis CC BY-SA 3.0
  • 9. The IT Crowd – Series 1 Episode 2: Fire!
  • 10. Code Coverage Testing for Generated Code •Need to implement WebServiceMock Interface • Invoke each web service method •Handle Request and Response types •Supporting Types (Headers)
  • 11. Demo SFDC Explorer Web Service Mock
  • 12. The Metadata API – Handling larger WSDLs Class name 'Metadata' already in use. Please edit WSDL to remove repeated names • CustomObject et al. extend Metadata and need elements from it to work correctly. <xs:extension base="Metadata"> • 330 KB WSDL Apex Character Limit Metadata 590,915 Remaining • 590,915 characters / 6740 lines without comments • Approximately 20% of 3,000,000 character Apex limit
  • 13. Method filtering functionality •Reduces amount of generated code •Reduces testing requirements for dead code • Potentially skips unsupported features • Optionally remove supporting Apex classes
  • 14. Demo SFDC Explorer Method filtering
  • 15. How it works Deploy to Salesforce • Tooling API to deploy all associated Apex classes at once Transform to Apex • T4 (Text Template Transformation Toolkit)Templates to convert the object model into Apex Build Apex Model • C# Object Model of Apex Classes, Members and Methods Parse WSDL • Import all WSDL data and extract required elements
  • 16. .NET Representation of Apex Class model ApexClass 1 InnerApexClasses * Members * Methods ApexClassCollection ApexMember StringArrayApexMember ApexMethod ApexMethodParameter ApexMethodHttp ReturnType ReturnVoid ReturnPrimitive ReturnClassType Type Infos Inner Classes Namespace Collection Parameters * ReturnType 1 ApexClasses 0..* Outer class for each Namespace Created for the Port/Service Each Request/Response
  • 17. Tooling API deployment Existing ID • Create a MetadataContainer with a unique name • Create a collection of ApexClassMember referencing the MetadataContainerId • Create a ContainerAsyncRequest – Option to Validate Only (IsCheckOnly) • Keep retrieving until the State is no longer Queued. • Delete MetadataContainer New – no existing ID • Call create and collect the SaveResults • Or create an empty stub class to get an ID and use the MetadataContainer
  • 18. Tooling API deployment Existing ID • Create a MetadataContainer with a unique name • Create a collection of ApexClassMember referencing the MetadataContainerId • Create a ContainerAsyncRequest New – no existing ID • Call create and collect the SaveResults • Or create an empty stub class to get an ID and use the MetadataContainer List<ApexClass> apexClassesToInsert = new List<ApexClass>(); // Add ApexClass records with T4 generated Body ApexClass classToInsert = new ApexClass() { Name = "HelloDF" }; classToInsert.Body = "public class " + classToInsert.Name + " { public class Add{ }}"; apexClasses.Add(classToInsert); – Option to Validate Only (IsCheckOnly) • Keep retrieving until the State is no longer Queued. • Delete MetadataContainer SaveResult[] saveResults = toolingService.create(apexClassesToInsert.ToArray()); if (saveResults != null) { foreach (SaveResult sr in saveResults) { if (!sr.success) { throw new ToolingCreateException(apexClassesToInsert.ToArray(), saveResults); } } }
  • 19. Tooling API deployment Existing ID • Create a MetadataContainer with a unique name • Create a collection of ApexClassMember referencing the MetadataContainerId • Create a ContainerAsyncRequest New – no existing ID • Call create and collect the SaveResults • Or create an empty stub class to get an MIeDta adantda Cuosntea ithneer McoenttaadianetarC=onnetwaiMneetradataContainer(); – Option to Validate Only (IsCheckOnly) • Keep retrieving until the State is no longer Queued. • Delete MetadataContainer // max length 32 characters! container.Name = "UAC " + DateTime.Now.Ticks; SaveResult[] containerResults = toolingService.create(new sObject[] { container }); if (!containerResults[0].success) { throw new ToolingCreateException(container, containerResults[0]); } Id metadataContainerId = new Id(containerResults[0].id);
  • 20. Tooling API deployment Existing ID • Create a MetadataContainer with a unique name • Create a collection of ApexClassMember referencing the MetadataContainerId • Create a ContainerAsyncRequest – Option to Validate Only (IsCheckOnly) • Keep retrieving until the State is no longer Queued. • Delete MetadataContainer New – no existing ID • Call create and collect the SaveResults • Or create an empty stub class to get an ID and use the MetadataContainer var toUpdate = new List<ApexClassMember>(); foreach(ApexClass ac in classesToUpsert) { var acm = new ApexClassMember(); acm.ContentEntityId = ac.Id; // 01p… acm.Body = ac.Body; // T4 Template output acm.FullName = ac.Name; // class name acm.MetadataContainerId = metadataContainerId.CaseSafeID; toUpdate.Add(acm); } sObject[] toCreate = toUpdate.ToArray(); SaveResult[] cResult = toolingService.create(apexClassMembersToCreate); foreach (SaveResult sr in cResult) { if (!sr.success) { throw new ToolingCreateException(toCreate, cResult); } }
  • 21. Tooling API deployment Existing ID • Create a MetadataContainer with a unique name • Create a collection of ApexClassMember referencing the MetadataContainerId • Create a ContainerAsyncRequest – Option to Validate Only (IsCheckOnly) • Keep retrieving until the State is no longer Queued. • Delete MetadataContainer var cr = new ContainerAsyncRequest(); cr.MetadataContainerId = metadataContainerId.CaseSafeID; cr.IsCheckOnly = false; SaveResult[] cars = this.create(new sObject[]{cr}); if (! cars[0].success) { throw new ToolingCreateException(cr,cars[0]); } ContainerAsyncRequest retrieve = WaitForClassToUpdate(containerAsyncResults); if (retrieve.State == "Failed") { throw ApexUpdateException.FromDeployDetails (retrieve.DeployDetails); } DeleteResult[] dr = this.delete(new string[] { metadataContainerId.CaseSafeID });
  • 22. WSDL Variation http://www.superbwallpapers.com/photography/snowflakes-10358/ If you have a unique WSDL: • http://www.fuseit.com/wsdlhelp • Please provide the WSDL details Use HTTP Requests for WebServiceCallout.invoke limits
  • 23. Summary •Manually dealing with WSDL import errors is time consuming and error prone • Extended SOAP support for several common WSDL issues: – Increased support – <xsd:import> <xsd:include> <xsd:extension> – Generate basic code coverage – Method filtering to reduce Apex
  • 24. Q&A + What Next • Download: the free FuseIT SFDC Explorer Tool (or get the web version) http://www.fuseit.com/explorer • Idea: Run anonymous apex as if it were a test case http://goo.gl/Aci1ys • Salesforce: The now open source WSDL2Apex generator http://goo.gl/tUcnVj • Session: Building Callouts Without WSDL2Apex and Apex Parsers Tuesday, 4:00 PM - 4:30 PM | Moscone Center West | Mobile Theater www.fuseit.com @FishOfPrey www.fishofprey.com @GirishaArora Girisha Arora
  • 25.
  • 27. Handling Extensions • <xsd:extension base=“”/> • Copy fields from base type to the sub class. • Use extends in the future • Metadata API • AccountOwnerSharingRule extends • OwnerSharingRule extends • BaseSharingRule extends • Metadata
  • 28. HTTP Requests • When WebServiceCallout.invoke() fails • A template for supporting more complex callouts • Access full fault messages SOAPFault Information for Apex https://success.salesforce.com/ideaView?id=08730000000BqG9AAK
  • 29. Apex Class Drifting with WSDL changes