SlideShare una empresa de Scribd logo
1 de 22
Process Orchestration using
           Streaming API and Heroku

Andrew Fawcett, FinancialForce.com, CTO
@andyinthecloud
Safe harbor
Safe harbor statement under the Private Securities Litigation Reform Act of 1995:

This presentation may contain forward-looking statements that involve risks, uncertainties, and assumptions. If any such uncertainties
materialize or if any of the assumptions proves incorrect, the results of salesforce.com, inc. could differ materially from the results expressed or
implied by the forward-looking statements we make. All statements other than statements of historical fact could be deemed forward-looking,
including any projections of product or service availability, subscriber growth, earnings, revenues, or other financial items and any statements
regarding strategies or plans of management for future operations, statements of belief, any statements concerning new, planned, or upgraded
services or technology developments and customer contracts or use of our services.

The risks and uncertainties referred to above include – but are not limited to – risks associated with developing and delivering new functionality
for our service, new products and services, our new business model, our past operating losses, possible fluctuations in our operating results
and rate of growth, interruptions or delays in our Web hosting, breach of our security measures, the outcome of intellectual property and other
litigation, risks associated with possible mergers and acquisitions, the immature market in which we operate, our relatively limited operating
history, our ability to expand, retain, and motivate our employees and manage our growth, new releases of our service and successful
customer deployment, our limited history reselling non-salesforce.com products, and utilization and selling to larger enterprise customers.
Further information on potential factors that could affect the financial results of salesforce.com, inc. is included in our annual report on Form 10-
Q for the most recent fiscal quarter ended July 31, 2012. This documents and others containing important disclosures are available on the SEC
Filings section of the Investor Information section of our Web site.

Any unreleased services or features referenced in this or other presentations, press releases or public statements are not currently available
and may not be delivered on time or at all. Customers who purchase our services should make the purchase decisions based upon features
that are currently available. Salesforce.com, inc. assumes no obligation and does not intend to update these forward-looking statements.
All about FinancialForce.com
                 Leading Native ISV on Force.com

                 • #1 Accounting App on Force.com
                 • #1 Professional Services Automation App on Force.com


                 Backed by Salesforce.com & UNIT4

                 • UNIT4 - $600 million, 33 years building business apps


                 Growing Rapidly

                 • San Francisco HQ – 595 Market St.
                 • 145 Employees
                 • Customers in 23 countries
Andrew Fawcett
CTO
@andyinthecloud
Building declarative applications
Building applications that support Force.com declarative features is critical.
Building applications that consume Force.com declarative features to support your
  app is smart!
     Encourage users admins to use what they have already
         • Building their solution consisting of part your app and part platform features can be a powerful combo!

     Make sure you understand how to be dynamic…
         • Metadata API, Apex Describe
         • Dynamic SOQL, Dynamic Visualforce, Fieldsets
         • Reference Formulas, Rollup Summaries, List Views etc..

     Make your applications metadata portable between orgs!
Consultants love our declarative applications! 
Our user story
As A: System Applications Administrator
I want: To be able to link a series of HTTP / REST based API’s to data changes
   occurring in my organization, based on criteria I provide. Without resorting
   to Apex coding.
So that: I can harness the power of many HTTP / REST based services to
  further automate my companies business processes. And leverage my skills
  as a System Administrator.
Our user case : eBay Integration
     Invoice Number: INV-000001

                                                                                      Process Manager


        eBay Item: 12345678



                                                                                        Streaming API via
                                                                                         Bayeux Protocol
                Overview Salesforce Streaming API via Bayeux Protocol

1.   Create a Push Topic in Force.com
      •     Using the SOQL statement you provide. Salesforce servers will send JSON
            messages to listeners. When changes occur to record data that meet the
            criteria expressed by the SOQL query.Item: 12345678
                                              eBay

2.   Install a Bayeux Client Library
      •     Clients are available from http://cometd.org (none for Apex)
3.   Connect and start Listening!
      •     This sample uses the Java Bayeux library
Live Demonstration
PushTopic (Streaming API)         Name                       Query Select From
      Name                               processchanges             Process__c
      Query
      NotifyForOperations                processlogslinescreated    ProcessLogLine__c
      NotifyForFields                    {Proccess__c.Id}           {SourceObject__c}

               Process__c          /topic/processchanges                                           Process__c Listener
      Name                                                                               On Insert
      SourceObject__c                       ProcessStep__c
                                                                                         1.   Generate PushTopic Query
      When__c                         Name
                                                                                         2.   Create new PushTopic record
      ListViewName__c                 HTMLEndpoint__c
                                                                                         3.   Subscribe via Streaming API
                                      HTMLHeader__c
                                                                                         4.   Start {SourceObject__c} Listener
                                      HTMLMethod__c                     Admin creates
                                                                                         5.   Log to ProcessLogLineItem__c
                                      HTMLBody__c                         Process
ProcessLogLine__c Listener                 ProcessLogLine__c
  Live Log Viewer                     Message__c                                                {SourceObject__c} Listener
      “1. xxxx
       2. xxxx”
                                   /topic/processlogslinescreated
                                                                                         On Update
                                                                                         1.  Read ProcessSteps__c
                    Invoice__c          /topic/{Process__c.Id}                           2.  Read {SourceObject__c}
      Name                                                                               3.  Call {HTMLEndpoint__c} …
      Account__c                                                                         4.  Log to ProcessLogLineItem__c
      Amount__c
      eBayItemNumber__c
      eBayCompleteSaleRequest__c
                                                                        Invoice Clerk
                                                                       updates Invoice   HTTP POST:
                                                                                         <CompleteSaleRequest>
                                                                                           <Item>{!eBayItemNumber}</Item>
                                                                                         </CompleteSaleRequest>
Java Code : Heroku Worker Process
/**
 * Heroku Work Processes are simply Java classes with a main method!
 */

01: public class WorkerProcess
02: {
03: // Salesforce API's
04: private static final String SALESFORCE_API = "25.0";
05: private static final String LOGIN_ENDPOINT = "https://login.salesforce.com/services/Soap/u/" + SALESFORCE_API;
06: private static final String REST_ENDPOINT_URI = "/services/data/v" + SALESFORCE_API + "/";
07: private static final String STREAMING_ENDPOINT_URI = "/cometd/" + SALESFORCE_API;
08:
09: /**
10:   * Main entry point for the Heroku Worker Process
11:   * @param args
12:   * @throws Exception
13:   */
14: public static void main(String[] args) throws Exception
15: {
16:           // Startup and assignment of listeners to Salesforce Streaming API topics…
17: }
Java Code : Process__c Listener
/**
 * Listener : Process__c
 * Comment : Bayeux Client used connect to Streaming API and implement MessageListener interface
 * @see          makeStreamingAPIConnection method
 * @see       JSON class from Jetty
 * @see       processInsert method
 */
01: // Connect to Salesforce Streaming API
02: final BayeuxClient client = makeStreamingAPIConnection(loginResult);
03:
04: // Subscribe to the Process__c topic to listen for new or updated Processes
05: client.getChannel("/topic/processchanges").subscribe(new MessageListener()
06: {
07:          public void onMessage(ClientSessionChannel channel, Message message)
08:          {
09:            HashMap<String, Object> data = (HashMap<String, Object>) JSON.parse(message.toString());
10:            HashMap<String, Object> record = (HashMap<String, Object>) data.get("data");
11:            HashMap<String, Object> sobject = (HashMap<String, Object>) record.get("sobject");
12:            HashMap<String, Object> event = (HashMap<String, Object>) record.get("event");
13:            // Event type, insert or update?
14:            String type = (String) event.get("type");
15:            if(type.equals("created"))
16:                       processInsert(loginResult, client, sobject);
17:          }
18: });
Java Code : Process__c Listener
  Java Code : Process__c                                                                                  Listener
  /**
   * Listener : Process__c
   * Step : Connect and Listen
   *       API connections and message data, used WSC manual login to obtain Metadata API base URL from
   *       LoginResult (not normally exposed by the standard connector classes)
   * @see      makeRestConnection method (Rest URL helper)
   */
  01: // Connection configuration
  02: ConnectorConfig metadataConfig = new ConnectorConfig();
  03: metadataConfig.setSessionId(loginResult.getSessionId());
  04: metadataConfig.setServiceEndpoint(loginResult.getMetadataServerUrl());
  05: MetadataConnection metadataConnection =
  06:          com.sforce.soap.metadata.Connector.newConnection(metadataConfig);
  07:
  08: // Make a REST connection
  09: RestConnection restConnection = makeRestConnection(loginResult);
  10:
  11: // Message data from Proccess__c
  12: String processId = (String) sObject.get("Id");
  13: String processName = (String) sObject.get("Name");
  14: String sourceObject = (String) sObject.get("SourceObject__c");
  15: String listViewName = (String) sObject.get("ListViewName__c");
Java Code : Process__c Listener
  Java Code : Process__c                                                                              Listener
   /**
    * Listener : Process__c
    * Step : Generate PushTopic Query
    * Comment : Retrieve via Metadata API custom object definition to get at the List View
    *       definition for generating PushTopic Query
   */
   01: // Retrieve Custom Object Meta data (and thus List View definition) for Source Object
   02: RetrieveRequest retrieveRequest = new RetrieveRequest();
   03: retrieveRequest.setSinglePackage(true);
   04: com.sforce.soap.metadata.Package packageManifest = new com.sforce.soap.metadata.Package();
   05: ArrayList<PackageTypeMembers> types = new ArrayList<PackageTypeMembers>();
   06: PackageTypeMembers packageTypeMember = new PackageTypeMembers();
   07: packageTypeMember.setName("CustomObject");
   08: packageTypeMember.setMembers(new String[] { sourceObject });
   09: types.add(packageTypeMember);
   10: packageManifest.setTypes((PackageTypeMembers[]) types.toArray(new PackageTypeMembers[] {}));
   11: retrieveRequest.setUnpackaged(packageManifest);
   12: AsyncResult response = metadataConnection.retrieve(retrieveRequest);
   13: while(!response.isDone())
   14: {
   15:          Thread.sleep(1000);
   16:          response = metadataConnection.checkStatus(new String[] { response.getId()} )[0];
   17: }
   18: RetrieveResult retrieveResult = metadataConnection.checkRetrieveStatus(response.getId());
Java Code : Process__c Listener
  Java Code : Process__c                                                                                   Listener
  /**
   * Listener : Process__c
   * Step : Generate PushTopic Query
   * Comment : Uses the WSC TypeMapper to deserialise the Custom Object definition from the
   *         package zip returned by „retrieve‟
   */
  01: // Parse Custom Object metadata for Process Source Object
  02: CustomObject customObject = new CustomObject();
  03: byte[] zipBytes = retrieveResult.getZipFile();
  04: ZipInputStream zipis = new ZipInputStream(new ByteArrayInputStream(zipBytes, 0, zipBytes.length));
  05: ZipEntry zipEntry = null;
  06: while((zipEntry = zipis.getNextEntry()) != null) {
  07:          if(zipEntry.getName().endsWith(sourceObject + ".object")) / Process Source Object?
  08:          {
  09:                       TypeMapper typeMapper = new TypeMapper();
  10:                       XmlInputStream xmlis = new XmlInputStream();
  11:                       xmlis.setInput(zipis, "UTF-8");
  12:                       customObject.load(xmlis, typeMapper);
  13:                       zipis.closeEntry();
  14:                       break;
  15:          }
  16: }
  17: // Find the List View indicated on the Process to define query for Streaming API Push Topic
  18: ListView processlistView = null;
  19: for(ListView listView : customObject.getListViews()) { ... }
Java Code : Process__c Listener
  Java Code : Process__c                                                                            Listener
   /**
    * Listener : Process__c
    * Step : Generate PushTopic Query
    * Comment : Parse List View definition to construct SOQL Query for Push Topic. Code shortened
    *       for this slide.
    */
  01: // Generate SOQL statement for PushTopic based on List View definition
  02: StringBuilder fieldList = new StringBuilder("Id");
  03: for(String field : processlistView.getColumns())
  04:          fieldList.append(", " + field);
  05: // Simple version assumes AND‟s, ignores processListView.getBooleanFilter()
  06: StringBuilder whereClause = new StringBuilder();
  07: for(ListViewFilter lvFilter : processlistView.getFilters())
  08: {
  09:          switch (lvFilter.getOperation())
  10:          {
  11:                       case equals:
  12:                       // ...
  13:          }
  14: }
  15: // Construct SOQL query statement
  16: StringBuilder soql = new StringBuilder()
  17:          .append("select ”) .append(fieldList.toString())
  18:          .append("from ”)          .append(sourceObject + " ")
  19:          .append("where ”)          .append(whereClause.toString());
Java Code : Process__c Listener
  Java Code : Process__c                                                                              Listener
  /**
   * Listener : Process__c
   * Step      : Create PushTopic and subscribe
   * Comment        : PushTopic Name has to be unique thus we used the Process__c.Id.
   *         It is possible to immediately subscribe once the Push Topic has been created!
   * @see         SourceObjectListener class implements MessageListener interface!
   */
  01: // Create PushTopic
  02: PushTopic pushTopic = new PushTopic();
  03: pushTopic.Name = processId;
  04: pushTopic.Query = soql.toString();
  05: pushTopic.ApiVersion = SALESFORCE_API;
  06: pushTopic.NotifyForOperations = "All"; // TODO: Interpret the 'When__c' field from Process__c
  07: pushTopic.NotifyForFields = "Referenced";
  08: restConnection.create(pushTopic);
  09:
  10: // Update Process with Push Topic Name (so that if the worker restarts it can reconnect)
  11: Process__c process = new Process__c();
  12: process.PushTopicName__c = pushTopic.Name;
  13: restConnection.update(process, processId);
  14:
  15: // Start listening on the new Push Topic immediately!
  16: client.getChannel("/topic/"+pushTopic.Name).subscribe(
  17:           new SourceObjectListener(loginResult, processId, sourceObject));
Java Code {SourceObject__c} Listener
 Java Code : : {SourceObject__c} Listener
 /**
  * Listener : {SourceObject__c}
  * Step 1    : Parse Source Object Id from message and read current process steps. Determine what HTTP call
  *         information will be provided by the source object record fields.
  */

 01: public static class SourceObjectListener implements MessageListener
 02: {
 03:         public void onMessage(ClientSessionChannel channel, Message message)
 04:         {
 05:                      // Source Object Message
 06:                      HashMap<String, Object> data = (HashMap<String, Object>) JSON.parse(message.toString());
 07:                      HashMap<String, Object> record = (HashMap<String, Object>) data.get("data");
 08:                      HashMap<String, Object> sobject = (HashMap<String, Object>) record.get("sobject");
 09:                      String sourceId = (String) sobject.get("Id")
 10:                      // Query Process Steps
 11:                QueryResult processStepsResult = m_partnerConnection.query(
 12:                      “select Id, Name, " +
 13:                                              "HTTPEndPoint__c, HTTPEndPointFrom__c, " +
 14:                                   "HTTPMethod__c, HTTPMethodFrom__c, " +
 15:                                   "HTTPHeader__c, HTTPHeaderFrom__c, " +
 16:                                   "HTTPBody__c, HTTPBodyFrom__c " +
 17:                      ”from ProcessStep__c " +
 18:                      "where Process__c = '" + m_processId + "'");
Java Code {SourceObject__c} Listener
 Java Code : : {SourceObject__c} Listener
 /**
  * Listener : {SourceObject__c}
  * Step 2    : Dynamically build query for source object to include fields required
  *         to make HTTP callout contextual
  */
  01: // Construct Source Object SOQL (query formula fields)
  02: StringBuilder fieldList = new StringBuilder();
  03: fieldList.append("Id, Name");
  04: for(String field : sourceFields)
  05:          fieldList.append(", " + field);
  06: StringBuilder soql = new StringBuilder()
  07:          .append("select ")
  08:          .append(fieldList.toString() + " ")
  09:          .append("from ")
  10:          .append(m_sourceObject + " ")
  11:          .append("where ")
  12:          .append("id = '%s'");
  13: String sourceObjectQuery = soql.toString();
  14:
  15: // Query Source Object record
  16: String query = String.format(sourceObjectQuery, sourceId);
  17: QueryResult sourceObjectResult = m_partnerConnection.query(query);
  18: SObject sourceRecord = sourceObjectResult.getRecords()[0];
Java Code {SourceObject__c} Listener
 Java Code : : {SourceObject__c} Listener
  /**
   * Listener : {SourceObject__c}
   * Step 3   : Use Jetty HTTP Client to make callout. HTTP call out details are taken from literals on the step
   *         or from formula fields on the source record
   */
  01: // Create the HTTP client
  02: HttpClient httpClient = new HttpClient();
  03: httpClient.setConnectorType(HttpClient.CONNECTOR_SELECT_CHANNEL);
  04: httpClient.start();
  05: // HTTP parameters
  06: String httpEndpoint = ...
  07: String httpHeader = ...
  08: String httpMethod = ...
  09: String httpBody = ...
  10:         processStep.HTTPBodyFrom__c.equals("Literal") ?
  11:         processStep.HTTPBody__c : (String) sourceRecord.getField(processStep.HTTPBody__c);
  12: // Construct HTTP request
  13: ContentExchange contentExchange = new ContentExchange(true);
  14: contentExchange.setMethod(httpMethod);
  15: contentExchange.setURL(httpEndpoint);
  16: contentExchange.setRequestHeader(...);
  17: contentExchange.setRequestContent(new ByteArrayBuffer(httpBody));
  18: httpClient.send(contentExchange);
  19: contentExchange.waitForDone();
Resources
Java Code : {SourceObject__c} Listener
    • Other // TODO:’s and Ideas?! 
      – Record Types for Process Steps?
      – State / Variables between Steps?
    • Source Code and Contact Details
      GitHub:
      https://github.com/financialforcedev
      Heroku App (Clone):
      https://api.heroku.com/myapps/df12-processmanager/clone
      Twitter: andyinthecloud
DF12 - Process Orchestration using Streaming API and Heroku
DF12 - Process Orchestration using Streaming API and Heroku

Más contenido relacionado

La actualidad más candente

Adapters db-104-informixstoredprocedure
Adapters db-104-informixstoredprocedureAdapters db-104-informixstoredprocedure
Adapters db-104-informixstoredprocedureprathap kumar
 
Java Web Programming [9/9] : Web Application Security
Java Web Programming [9/9] : Web Application SecurityJava Web Programming [9/9] : Web Application Security
Java Web Programming [9/9] : Web Application SecurityIMC Institute
 
Integrating dialog flow (api.ai) into qiscus sdk chat application
Integrating dialog flow (api.ai) into qiscus sdk chat applicationIntegrating dialog flow (api.ai) into qiscus sdk chat application
Integrating dialog flow (api.ai) into qiscus sdk chat applicationErick Ranes Akbar Mawuntu
 
Harmony API developers documentation (version 2.2)
Harmony API developers documentation (version 2.2)Harmony API developers documentation (version 2.2)
Harmony API developers documentation (version 2.2)112Motion
 
Apache Aries Blog Sample
Apache Aries Blog SampleApache Aries Blog Sample
Apache Aries Blog SampleSkills Matter
 
Orchard Dynamic Class Extensions
Orchard Dynamic Class ExtensionsOrchard Dynamic Class Extensions
Orchard Dynamic Class Extensionsmarkdolar
 
Java Web Programming [8/9] : JSF and AJAX
Java Web Programming [8/9] : JSF and AJAXJava Web Programming [8/9] : JSF and AJAX
Java Web Programming [8/9] : JSF and AJAXIMC Institute
 
OrchardCMS module development
OrchardCMS module developmentOrchardCMS module development
OrchardCMS module developmentJay Harris
 

La actualidad más candente (10)

JSP Error handling
JSP Error handlingJSP Error handling
JSP Error handling
 
Adapters db-104-informixstoredprocedure
Adapters db-104-informixstoredprocedureAdapters db-104-informixstoredprocedure
Adapters db-104-informixstoredprocedure
 
Java Web Programming [9/9] : Web Application Security
Java Web Programming [9/9] : Web Application SecurityJava Web Programming [9/9] : Web Application Security
Java Web Programming [9/9] : Web Application Security
 
Intro to flask2
Intro to flask2Intro to flask2
Intro to flask2
 
Integrating dialog flow (api.ai) into qiscus sdk chat application
Integrating dialog flow (api.ai) into qiscus sdk chat applicationIntegrating dialog flow (api.ai) into qiscus sdk chat application
Integrating dialog flow (api.ai) into qiscus sdk chat application
 
Harmony API developers documentation (version 2.2)
Harmony API developers documentation (version 2.2)Harmony API developers documentation (version 2.2)
Harmony API developers documentation (version 2.2)
 
Apache Aries Blog Sample
Apache Aries Blog SampleApache Aries Blog Sample
Apache Aries Blog Sample
 
Orchard Dynamic Class Extensions
Orchard Dynamic Class ExtensionsOrchard Dynamic Class Extensions
Orchard Dynamic Class Extensions
 
Java Web Programming [8/9] : JSF and AJAX
Java Web Programming [8/9] : JSF and AJAXJava Web Programming [8/9] : JSF and AJAX
Java Web Programming [8/9] : JSF and AJAX
 
OrchardCMS module development
OrchardCMS module developmentOrchardCMS module development
OrchardCMS module development
 

Similar a DF12 - Process Orchestration using Streaming API and Heroku

SoftLayer API 12032015
SoftLayer API  12032015SoftLayer API  12032015
SoftLayer API 12032015Nacho Daza
 
Best Practices for Architecting a Pragmatic Web API.
Best Practices for Architecting a Pragmatic Web API.Best Practices for Architecting a Pragmatic Web API.
Best Practices for Architecting a Pragmatic Web API.Mario Cardinal
 
Get things done with Yii - quickly build webapplications
Get things done with Yii - quickly build webapplicationsGet things done with Yii - quickly build webapplications
Get things done with Yii - quickly build webapplicationsGiuliano Iacobelli
 
Creating a World-Class RESTful Web Services API
Creating a World-Class RESTful Web Services APICreating a World-Class RESTful Web Services API
Creating a World-Class RESTful Web Services APIDavid Keener
 
Online Bank Hack
Online Bank HackOnline Bank Hack
Online Bank HackCaleb Sima
 
MuleSoft Certified Platform Architect Exam Dumps 2023.pdf
MuleSoft Certified Platform Architect Exam Dumps 2023.pdfMuleSoft Certified Platform Architect Exam Dumps 2023.pdf
MuleSoft Certified Platform Architect Exam Dumps 2023.pdfSkillCertProExams
 
WSO2Con EU 2015: Extending and Customizing WSO2 API Manager
WSO2Con EU 2015: Extending and Customizing WSO2 API ManagerWSO2Con EU 2015: Extending and Customizing WSO2 API Manager
WSO2Con EU 2015: Extending and Customizing WSO2 API ManagerWSO2
 
InterConnect 2016 Java EE 7 Overview (PEJ-5296)
InterConnect 2016 Java EE 7 Overview (PEJ-5296)InterConnect 2016 Java EE 7 Overview (PEJ-5296)
InterConnect 2016 Java EE 7 Overview (PEJ-5296)Kevin Sutter
 
AspMVC4 start101
AspMVC4 start101AspMVC4 start101
AspMVC4 start101Rich Helton
 
Php and web forms
Php and web formsPhp and web forms
Php and web formssana mateen
 
Yii Framework Security
Yii Framework SecurityYii Framework Security
Yii Framework SecurityIlko Kacharov
 
Repository Pattern in MVC3 Application with Entity Framework
Repository Pattern in MVC3 Application with Entity FrameworkRepository Pattern in MVC3 Application with Entity Framework
Repository Pattern in MVC3 Application with Entity FrameworkAkhil Mittal
 
Introduction to the Client OM in SharePoint 2010
Introduction to the Client OM in SharePoint 2010Introduction to the Client OM in SharePoint 2010
Introduction to the Client OM in SharePoint 2010Ben Robb
 
Simplify your professional web development with symfony
Simplify your professional web development with symfonySimplify your professional web development with symfony
Simplify your professional web development with symfonyFrancois Zaninotto
 

Similar a DF12 - Process Orchestration using Streaming API and Heroku (20)

SoftLayer API 12032015
SoftLayer API  12032015SoftLayer API  12032015
SoftLayer API 12032015
 
Best Practices for Architecting a Pragmatic Web API.
Best Practices for Architecting a Pragmatic Web API.Best Practices for Architecting a Pragmatic Web API.
Best Practices for Architecting a Pragmatic Web API.
 
contentDM
contentDMcontentDM
contentDM
 
1z0 591
1z0 5911z0 591
1z0 591
 
Get things done with Yii - quickly build webapplications
Get things done with Yii - quickly build webapplicationsGet things done with Yii - quickly build webapplications
Get things done with Yii - quickly build webapplications
 
Creating a World-Class RESTful Web Services API
Creating a World-Class RESTful Web Services APICreating a World-Class RESTful Web Services API
Creating a World-Class RESTful Web Services API
 
Development withforce
Development withforceDevelopment withforce
Development withforce
 
Online Bank Hack
Online Bank HackOnline Bank Hack
Online Bank Hack
 
MuleSoft Certified Platform Architect Exam Dumps 2023.pdf
MuleSoft Certified Platform Architect Exam Dumps 2023.pdfMuleSoft Certified Platform Architect Exam Dumps 2023.pdf
MuleSoft Certified Platform Architect Exam Dumps 2023.pdf
 
WSO2Con EU 2015: Extending and Customizing WSO2 API Manager
WSO2Con EU 2015: Extending and Customizing WSO2 API ManagerWSO2Con EU 2015: Extending and Customizing WSO2 API Manager
WSO2Con EU 2015: Extending and Customizing WSO2 API Manager
 
InterConnect 2016 Java EE 7 Overview (PEJ-5296)
InterConnect 2016 Java EE 7 Overview (PEJ-5296)InterConnect 2016 Java EE 7 Overview (PEJ-5296)
InterConnect 2016 Java EE 7 Overview (PEJ-5296)
 
AspMVC4 start101
AspMVC4 start101AspMVC4 start101
AspMVC4 start101
 
Fwdtechseminars
FwdtechseminarsFwdtechseminars
Fwdtechseminars
 
ELEVATE Paris
ELEVATE ParisELEVATE Paris
ELEVATE Paris
 
flask.pptx
flask.pptxflask.pptx
flask.pptx
 
Php and web forms
Php and web formsPhp and web forms
Php and web forms
 
Yii Framework Security
Yii Framework SecurityYii Framework Security
Yii Framework Security
 
Repository Pattern in MVC3 Application with Entity Framework
Repository Pattern in MVC3 Application with Entity FrameworkRepository Pattern in MVC3 Application with Entity Framework
Repository Pattern in MVC3 Application with Entity Framework
 
Introduction to the Client OM in SharePoint 2010
Introduction to the Client OM in SharePoint 2010Introduction to the Client OM in SharePoint 2010
Introduction to the Client OM in SharePoint 2010
 
Simplify your professional web development with symfony
Simplify your professional web development with symfonySimplify your professional web development with symfony
Simplify your professional web development with symfony
 

Último

A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxA Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxLoriGlavin3
 
What is DBT - The Ultimate Data Build Tool.pdf
What is DBT - The Ultimate Data Build Tool.pdfWhat is DBT - The Ultimate Data Build Tool.pdf
What is DBT - The Ultimate Data Build Tool.pdfMounikaPolabathina
 
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptxPasskey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptxLoriGlavin3
 
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24Mark Goldstein
 
Modern Roaming for Notes and Nomad – Cheaper Faster Better Stronger
Modern Roaming for Notes and Nomad – Cheaper Faster Better StrongerModern Roaming for Notes and Nomad – Cheaper Faster Better Stronger
Modern Roaming for Notes and Nomad – Cheaper Faster Better Strongerpanagenda
 
Rise of the Machines: Known As Drones...
Rise of the Machines: Known As Drones...Rise of the Machines: Known As Drones...
Rise of the Machines: Known As Drones...Rick Flair
 
Why device, WIFI, and ISP insights are crucial to supporting remote Microsoft...
Why device, WIFI, and ISP insights are crucial to supporting remote Microsoft...Why device, WIFI, and ISP insights are crucial to supporting remote Microsoft...
Why device, WIFI, and ISP insights are crucial to supporting remote Microsoft...panagenda
 
A Framework for Development in the AI Age
A Framework for Development in the AI AgeA Framework for Development in the AI Age
A Framework for Development in the AI AgeCprime
 
Assure Ecommerce and Retail Operations Uptime with ThousandEyes
Assure Ecommerce and Retail Operations Uptime with ThousandEyesAssure Ecommerce and Retail Operations Uptime with ThousandEyes
Assure Ecommerce and Retail Operations Uptime with ThousandEyesThousandEyes
 
Moving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdfMoving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdfLoriGlavin3
 
How to write a Business Continuity Plan
How to write a Business Continuity PlanHow to write a Business Continuity Plan
How to write a Business Continuity PlanDatabarracks
 
Emixa Mendix Meetup 11 April 2024 about Mendix Native development
Emixa Mendix Meetup 11 April 2024 about Mendix Native developmentEmixa Mendix Meetup 11 April 2024 about Mendix Native development
Emixa Mendix Meetup 11 April 2024 about Mendix Native developmentPim van der Noll
 
How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.Curtis Poe
 
Take control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test SuiteTake control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test SuiteDianaGray10
 
How to Effectively Monitor SD-WAN and SASE Environments with ThousandEyes
How to Effectively Monitor SD-WAN and SASE Environments with ThousandEyesHow to Effectively Monitor SD-WAN and SASE Environments with ThousandEyes
How to Effectively Monitor SD-WAN and SASE Environments with ThousandEyesThousandEyes
 
Potential of AI (Generative AI) in Business: Learnings and Insights
Potential of AI (Generative AI) in Business: Learnings and InsightsPotential of AI (Generative AI) in Business: Learnings and Insights
Potential of AI (Generative AI) in Business: Learnings and InsightsRavi Sanghani
 
DevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsDevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsSergiu Bodiu
 
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024BookNet Canada
 
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...Alkin Tezuysal
 
Connecting the Dots for Information Discovery.pdf
Connecting the Dots for Information Discovery.pdfConnecting the Dots for Information Discovery.pdf
Connecting the Dots for Information Discovery.pdfNeo4j
 

Último (20)

A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxA Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
 
What is DBT - The Ultimate Data Build Tool.pdf
What is DBT - The Ultimate Data Build Tool.pdfWhat is DBT - The Ultimate Data Build Tool.pdf
What is DBT - The Ultimate Data Build Tool.pdf
 
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptxPasskey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptx
 
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24
 
Modern Roaming for Notes and Nomad – Cheaper Faster Better Stronger
Modern Roaming for Notes and Nomad – Cheaper Faster Better StrongerModern Roaming for Notes and Nomad – Cheaper Faster Better Stronger
Modern Roaming for Notes and Nomad – Cheaper Faster Better Stronger
 
Rise of the Machines: Known As Drones...
Rise of the Machines: Known As Drones...Rise of the Machines: Known As Drones...
Rise of the Machines: Known As Drones...
 
Why device, WIFI, and ISP insights are crucial to supporting remote Microsoft...
Why device, WIFI, and ISP insights are crucial to supporting remote Microsoft...Why device, WIFI, and ISP insights are crucial to supporting remote Microsoft...
Why device, WIFI, and ISP insights are crucial to supporting remote Microsoft...
 
A Framework for Development in the AI Age
A Framework for Development in the AI AgeA Framework for Development in the AI Age
A Framework for Development in the AI Age
 
Assure Ecommerce and Retail Operations Uptime with ThousandEyes
Assure Ecommerce and Retail Operations Uptime with ThousandEyesAssure Ecommerce and Retail Operations Uptime with ThousandEyes
Assure Ecommerce and Retail Operations Uptime with ThousandEyes
 
Moving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdfMoving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdf
 
How to write a Business Continuity Plan
How to write a Business Continuity PlanHow to write a Business Continuity Plan
How to write a Business Continuity Plan
 
Emixa Mendix Meetup 11 April 2024 about Mendix Native development
Emixa Mendix Meetup 11 April 2024 about Mendix Native developmentEmixa Mendix Meetup 11 April 2024 about Mendix Native development
Emixa Mendix Meetup 11 April 2024 about Mendix Native development
 
How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.
 
Take control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test SuiteTake control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test Suite
 
How to Effectively Monitor SD-WAN and SASE Environments with ThousandEyes
How to Effectively Monitor SD-WAN and SASE Environments with ThousandEyesHow to Effectively Monitor SD-WAN and SASE Environments with ThousandEyes
How to Effectively Monitor SD-WAN and SASE Environments with ThousandEyes
 
Potential of AI (Generative AI) in Business: Learnings and Insights
Potential of AI (Generative AI) in Business: Learnings and InsightsPotential of AI (Generative AI) in Business: Learnings and Insights
Potential of AI (Generative AI) in Business: Learnings and Insights
 
DevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsDevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platforms
 
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
 
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...
 
Connecting the Dots for Information Discovery.pdf
Connecting the Dots for Information Discovery.pdfConnecting the Dots for Information Discovery.pdf
Connecting the Dots for Information Discovery.pdf
 

DF12 - Process Orchestration using Streaming API and Heroku

  • 1. Process Orchestration using Streaming API and Heroku Andrew Fawcett, FinancialForce.com, CTO @andyinthecloud
  • 2. Safe harbor Safe harbor statement under the Private Securities Litigation Reform Act of 1995: This presentation may contain forward-looking statements that involve risks, uncertainties, and assumptions. If any such uncertainties materialize or if any of the assumptions proves incorrect, the results of salesforce.com, inc. could differ materially from the results expressed or implied by the forward-looking statements we make. All statements other than statements of historical fact could be deemed forward-looking, including any projections of product or service availability, subscriber growth, earnings, revenues, or other financial items and any statements regarding strategies or plans of management for future operations, statements of belief, any statements concerning new, planned, or upgraded services or technology developments and customer contracts or use of our services. The risks and uncertainties referred to above include – but are not limited to – risks associated with developing and delivering new functionality for our service, new products and services, our new business model, our past operating losses, possible fluctuations in our operating results and rate of growth, interruptions or delays in our Web hosting, breach of our security measures, the outcome of intellectual property and other litigation, risks associated with possible mergers and acquisitions, the immature market in which we operate, our relatively limited operating history, our ability to expand, retain, and motivate our employees and manage our growth, new releases of our service and successful customer deployment, our limited history reselling non-salesforce.com products, and utilization and selling to larger enterprise customers. Further information on potential factors that could affect the financial results of salesforce.com, inc. is included in our annual report on Form 10- Q for the most recent fiscal quarter ended July 31, 2012. This documents and others containing important disclosures are available on the SEC Filings section of the Investor Information section of our Web site. Any unreleased services or features referenced in this or other presentations, press releases or public statements are not currently available and may not be delivered on time or at all. Customers who purchase our services should make the purchase decisions based upon features that are currently available. Salesforce.com, inc. assumes no obligation and does not intend to update these forward-looking statements.
  • 3. All about FinancialForce.com Leading Native ISV on Force.com • #1 Accounting App on Force.com • #1 Professional Services Automation App on Force.com Backed by Salesforce.com & UNIT4 • UNIT4 - $600 million, 33 years building business apps Growing Rapidly • San Francisco HQ – 595 Market St. • 145 Employees • Customers in 23 countries
  • 5. Building declarative applications Building applications that support Force.com declarative features is critical. Building applications that consume Force.com declarative features to support your app is smart!  Encourage users admins to use what they have already • Building their solution consisting of part your app and part platform features can be a powerful combo!  Make sure you understand how to be dynamic… • Metadata API, Apex Describe • Dynamic SOQL, Dynamic Visualforce, Fieldsets • Reference Formulas, Rollup Summaries, List Views etc..  Make your applications metadata portable between orgs! Consultants love our declarative applications! 
  • 6. Our user story As A: System Applications Administrator I want: To be able to link a series of HTTP / REST based API’s to data changes occurring in my organization, based on criteria I provide. Without resorting to Apex coding. So that: I can harness the power of many HTTP / REST based services to further automate my companies business processes. And leverage my skills as a System Administrator.
  • 7. Our user case : eBay Integration Invoice Number: INV-000001 Process Manager eBay Item: 12345678 Streaming API via Bayeux Protocol Overview Salesforce Streaming API via Bayeux Protocol 1. Create a Push Topic in Force.com • Using the SOQL statement you provide. Salesforce servers will send JSON messages to listeners. When changes occur to record data that meet the criteria expressed by the SOQL query.Item: 12345678 eBay 2. Install a Bayeux Client Library • Clients are available from http://cometd.org (none for Apex) 3. Connect and start Listening! • This sample uses the Java Bayeux library
  • 9. PushTopic (Streaming API) Name Query Select From Name processchanges Process__c Query NotifyForOperations processlogslinescreated ProcessLogLine__c NotifyForFields {Proccess__c.Id} {SourceObject__c} Process__c /topic/processchanges Process__c Listener Name On Insert SourceObject__c ProcessStep__c 1. Generate PushTopic Query When__c Name 2. Create new PushTopic record ListViewName__c HTMLEndpoint__c 3. Subscribe via Streaming API HTMLHeader__c 4. Start {SourceObject__c} Listener HTMLMethod__c Admin creates 5. Log to ProcessLogLineItem__c HTMLBody__c Process ProcessLogLine__c Listener ProcessLogLine__c Live Log Viewer Message__c {SourceObject__c} Listener “1. xxxx 2. xxxx” /topic/processlogslinescreated On Update 1. Read ProcessSteps__c Invoice__c /topic/{Process__c.Id} 2. Read {SourceObject__c} Name 3. Call {HTMLEndpoint__c} … Account__c 4. Log to ProcessLogLineItem__c Amount__c eBayItemNumber__c eBayCompleteSaleRequest__c Invoice Clerk updates Invoice HTTP POST: <CompleteSaleRequest> <Item>{!eBayItemNumber}</Item> </CompleteSaleRequest>
  • 10. Java Code : Heroku Worker Process /** * Heroku Work Processes are simply Java classes with a main method! */ 01: public class WorkerProcess 02: { 03: // Salesforce API's 04: private static final String SALESFORCE_API = "25.0"; 05: private static final String LOGIN_ENDPOINT = "https://login.salesforce.com/services/Soap/u/" + SALESFORCE_API; 06: private static final String REST_ENDPOINT_URI = "/services/data/v" + SALESFORCE_API + "/"; 07: private static final String STREAMING_ENDPOINT_URI = "/cometd/" + SALESFORCE_API; 08: 09: /** 10: * Main entry point for the Heroku Worker Process 11: * @param args 12: * @throws Exception 13: */ 14: public static void main(String[] args) throws Exception 15: { 16: // Startup and assignment of listeners to Salesforce Streaming API topics… 17: }
  • 11. Java Code : Process__c Listener /** * Listener : Process__c * Comment : Bayeux Client used connect to Streaming API and implement MessageListener interface * @see makeStreamingAPIConnection method * @see JSON class from Jetty * @see processInsert method */ 01: // Connect to Salesforce Streaming API 02: final BayeuxClient client = makeStreamingAPIConnection(loginResult); 03: 04: // Subscribe to the Process__c topic to listen for new or updated Processes 05: client.getChannel("/topic/processchanges").subscribe(new MessageListener() 06: { 07: public void onMessage(ClientSessionChannel channel, Message message) 08: { 09: HashMap<String, Object> data = (HashMap<String, Object>) JSON.parse(message.toString()); 10: HashMap<String, Object> record = (HashMap<String, Object>) data.get("data"); 11: HashMap<String, Object> sobject = (HashMap<String, Object>) record.get("sobject"); 12: HashMap<String, Object> event = (HashMap<String, Object>) record.get("event"); 13: // Event type, insert or update? 14: String type = (String) event.get("type"); 15: if(type.equals("created")) 16: processInsert(loginResult, client, sobject); 17: } 18: });
  • 12. Java Code : Process__c Listener Java Code : Process__c Listener /** * Listener : Process__c * Step : Connect and Listen * API connections and message data, used WSC manual login to obtain Metadata API base URL from * LoginResult (not normally exposed by the standard connector classes) * @see makeRestConnection method (Rest URL helper) */ 01: // Connection configuration 02: ConnectorConfig metadataConfig = new ConnectorConfig(); 03: metadataConfig.setSessionId(loginResult.getSessionId()); 04: metadataConfig.setServiceEndpoint(loginResult.getMetadataServerUrl()); 05: MetadataConnection metadataConnection = 06: com.sforce.soap.metadata.Connector.newConnection(metadataConfig); 07: 08: // Make a REST connection 09: RestConnection restConnection = makeRestConnection(loginResult); 10: 11: // Message data from Proccess__c 12: String processId = (String) sObject.get("Id"); 13: String processName = (String) sObject.get("Name"); 14: String sourceObject = (String) sObject.get("SourceObject__c"); 15: String listViewName = (String) sObject.get("ListViewName__c");
  • 13. Java Code : Process__c Listener Java Code : Process__c Listener /** * Listener : Process__c * Step : Generate PushTopic Query * Comment : Retrieve via Metadata API custom object definition to get at the List View * definition for generating PushTopic Query */ 01: // Retrieve Custom Object Meta data (and thus List View definition) for Source Object 02: RetrieveRequest retrieveRequest = new RetrieveRequest(); 03: retrieveRequest.setSinglePackage(true); 04: com.sforce.soap.metadata.Package packageManifest = new com.sforce.soap.metadata.Package(); 05: ArrayList<PackageTypeMembers> types = new ArrayList<PackageTypeMembers>(); 06: PackageTypeMembers packageTypeMember = new PackageTypeMembers(); 07: packageTypeMember.setName("CustomObject"); 08: packageTypeMember.setMembers(new String[] { sourceObject }); 09: types.add(packageTypeMember); 10: packageManifest.setTypes((PackageTypeMembers[]) types.toArray(new PackageTypeMembers[] {})); 11: retrieveRequest.setUnpackaged(packageManifest); 12: AsyncResult response = metadataConnection.retrieve(retrieveRequest); 13: while(!response.isDone()) 14: { 15: Thread.sleep(1000); 16: response = metadataConnection.checkStatus(new String[] { response.getId()} )[0]; 17: } 18: RetrieveResult retrieveResult = metadataConnection.checkRetrieveStatus(response.getId());
  • 14. Java Code : Process__c Listener Java Code : Process__c Listener /** * Listener : Process__c * Step : Generate PushTopic Query * Comment : Uses the WSC TypeMapper to deserialise the Custom Object definition from the * package zip returned by „retrieve‟ */ 01: // Parse Custom Object metadata for Process Source Object 02: CustomObject customObject = new CustomObject(); 03: byte[] zipBytes = retrieveResult.getZipFile(); 04: ZipInputStream zipis = new ZipInputStream(new ByteArrayInputStream(zipBytes, 0, zipBytes.length)); 05: ZipEntry zipEntry = null; 06: while((zipEntry = zipis.getNextEntry()) != null) { 07: if(zipEntry.getName().endsWith(sourceObject + ".object")) / Process Source Object? 08: { 09: TypeMapper typeMapper = new TypeMapper(); 10: XmlInputStream xmlis = new XmlInputStream(); 11: xmlis.setInput(zipis, "UTF-8"); 12: customObject.load(xmlis, typeMapper); 13: zipis.closeEntry(); 14: break; 15: } 16: } 17: // Find the List View indicated on the Process to define query for Streaming API Push Topic 18: ListView processlistView = null; 19: for(ListView listView : customObject.getListViews()) { ... }
  • 15. Java Code : Process__c Listener Java Code : Process__c Listener /** * Listener : Process__c * Step : Generate PushTopic Query * Comment : Parse List View definition to construct SOQL Query for Push Topic. Code shortened * for this slide. */ 01: // Generate SOQL statement for PushTopic based on List View definition 02: StringBuilder fieldList = new StringBuilder("Id"); 03: for(String field : processlistView.getColumns()) 04: fieldList.append(", " + field); 05: // Simple version assumes AND‟s, ignores processListView.getBooleanFilter() 06: StringBuilder whereClause = new StringBuilder(); 07: for(ListViewFilter lvFilter : processlistView.getFilters()) 08: { 09: switch (lvFilter.getOperation()) 10: { 11: case equals: 12: // ... 13: } 14: } 15: // Construct SOQL query statement 16: StringBuilder soql = new StringBuilder() 17: .append("select ”) .append(fieldList.toString()) 18: .append("from ”) .append(sourceObject + " ") 19: .append("where ”) .append(whereClause.toString());
  • 16. Java Code : Process__c Listener Java Code : Process__c Listener /** * Listener : Process__c * Step : Create PushTopic and subscribe * Comment : PushTopic Name has to be unique thus we used the Process__c.Id. * It is possible to immediately subscribe once the Push Topic has been created! * @see SourceObjectListener class implements MessageListener interface! */ 01: // Create PushTopic 02: PushTopic pushTopic = new PushTopic(); 03: pushTopic.Name = processId; 04: pushTopic.Query = soql.toString(); 05: pushTopic.ApiVersion = SALESFORCE_API; 06: pushTopic.NotifyForOperations = "All"; // TODO: Interpret the 'When__c' field from Process__c 07: pushTopic.NotifyForFields = "Referenced"; 08: restConnection.create(pushTopic); 09: 10: // Update Process with Push Topic Name (so that if the worker restarts it can reconnect) 11: Process__c process = new Process__c(); 12: process.PushTopicName__c = pushTopic.Name; 13: restConnection.update(process, processId); 14: 15: // Start listening on the new Push Topic immediately! 16: client.getChannel("/topic/"+pushTopic.Name).subscribe( 17: new SourceObjectListener(loginResult, processId, sourceObject));
  • 17. Java Code {SourceObject__c} Listener Java Code : : {SourceObject__c} Listener /** * Listener : {SourceObject__c} * Step 1 : Parse Source Object Id from message and read current process steps. Determine what HTTP call * information will be provided by the source object record fields. */ 01: public static class SourceObjectListener implements MessageListener 02: { 03: public void onMessage(ClientSessionChannel channel, Message message) 04: { 05: // Source Object Message 06: HashMap<String, Object> data = (HashMap<String, Object>) JSON.parse(message.toString()); 07: HashMap<String, Object> record = (HashMap<String, Object>) data.get("data"); 08: HashMap<String, Object> sobject = (HashMap<String, Object>) record.get("sobject"); 09: String sourceId = (String) sobject.get("Id") 10: // Query Process Steps 11: QueryResult processStepsResult = m_partnerConnection.query( 12: “select Id, Name, " + 13: "HTTPEndPoint__c, HTTPEndPointFrom__c, " + 14: "HTTPMethod__c, HTTPMethodFrom__c, " + 15: "HTTPHeader__c, HTTPHeaderFrom__c, " + 16: "HTTPBody__c, HTTPBodyFrom__c " + 17: ”from ProcessStep__c " + 18: "where Process__c = '" + m_processId + "'");
  • 18. Java Code {SourceObject__c} Listener Java Code : : {SourceObject__c} Listener /** * Listener : {SourceObject__c} * Step 2 : Dynamically build query for source object to include fields required * to make HTTP callout contextual */ 01: // Construct Source Object SOQL (query formula fields) 02: StringBuilder fieldList = new StringBuilder(); 03: fieldList.append("Id, Name"); 04: for(String field : sourceFields) 05: fieldList.append(", " + field); 06: StringBuilder soql = new StringBuilder() 07: .append("select ") 08: .append(fieldList.toString() + " ") 09: .append("from ") 10: .append(m_sourceObject + " ") 11: .append("where ") 12: .append("id = '%s'"); 13: String sourceObjectQuery = soql.toString(); 14: 15: // Query Source Object record 16: String query = String.format(sourceObjectQuery, sourceId); 17: QueryResult sourceObjectResult = m_partnerConnection.query(query); 18: SObject sourceRecord = sourceObjectResult.getRecords()[0];
  • 19. Java Code {SourceObject__c} Listener Java Code : : {SourceObject__c} Listener /** * Listener : {SourceObject__c} * Step 3 : Use Jetty HTTP Client to make callout. HTTP call out details are taken from literals on the step * or from formula fields on the source record */ 01: // Create the HTTP client 02: HttpClient httpClient = new HttpClient(); 03: httpClient.setConnectorType(HttpClient.CONNECTOR_SELECT_CHANNEL); 04: httpClient.start(); 05: // HTTP parameters 06: String httpEndpoint = ... 07: String httpHeader = ... 08: String httpMethod = ... 09: String httpBody = ... 10: processStep.HTTPBodyFrom__c.equals("Literal") ? 11: processStep.HTTPBody__c : (String) sourceRecord.getField(processStep.HTTPBody__c); 12: // Construct HTTP request 13: ContentExchange contentExchange = new ContentExchange(true); 14: contentExchange.setMethod(httpMethod); 15: contentExchange.setURL(httpEndpoint); 16: contentExchange.setRequestHeader(...); 17: contentExchange.setRequestContent(new ByteArrayBuffer(httpBody)); 18: httpClient.send(contentExchange); 19: contentExchange.waitForDone();
  • 20. Resources Java Code : {SourceObject__c} Listener • Other // TODO:’s and Ideas?!  – Record Types for Process Steps? – State / Variables between Steps? • Source Code and Contact Details GitHub: https://github.com/financialforcedev Heroku App (Clone): https://api.heroku.com/myapps/df12-processmanager/clone Twitter: andyinthecloud

Notas del editor

  1. Rehab Breakfast on Friday, talking to people in the area for roles we have open, come along even if your tired! ;-)Expanding Development Group, adding Development Team in SFIndustrial Strength Applications
  2. - Mention platform Flow and Workflow differences and capabilities vs this solution.
  3. Timing: 6 minutes
  4. Timing: 2 minutes
  5. Timing: Code Walkthrough 8 minutes
  6. Timing: Code Walkthrough 8 minutes
  7. Timing: Code Walkthrough 8 minutes
  8. Timing: Code Walkthrough 8 minutes
  9. Timing: Code Walkthrough 8 minutes
  10. Timing: Code Walkthrough 8 minutes
  11. Timing: Code Walkthrough 8 minutes
  12. Timing: Code Walkthrough 8 minutes
  13. Timing: Code Walkthrough 8 minutes
  14. Timing: Code Walkthrough 8 minutes
  15. Timing: Code Walkthrough 8 minutes