Saturday, August 31, 2013

Samples on how to use "CloudChoir - Salesforce integration-as-a-service"

Note: all credentials used in following DEMO videos are removed.

1. SF vs. Windows or Windows Azure or Linux - SSH (with password, without SSH cert)
Demo video:
http://youtu.be/KzCPjqHKnk4

Command:
SSH (old name "SSHBridge")

Sample Input XML:
<SSHBridge>
<host>cloudchoir2.cloudapp.net</host>
<port>22</port>
<user>azureuser</user>
<password>ThisIs1Password</password>
<timeout>20000</timeout>
<commandline>ls -l</
commandline>
</
SSHBridge>

Sample (Account) Trigger code:
(see below #2 as reference.) 


2. SF vs. Amazon EC2 VM or others - SSH (without password, with SSH cert in ".pem")
Demo videos:

Command:
SSH

Sample Input XML:

1st sample(XML - no base64. for easy demo.):
<SSHBridge>
    <host>ec2-54-213-54-199.us-west-2.compute.amazonaws.com</host>
    <port>22</port>
    <certfilename >CloudChoirEC2demo.pem</certfilename >
    <user>ubuntu</user>
    <password>-password-not-used</password>
    <timeout>20000</timeout>
    <commandline>ps -ef | grep tty</commandline>
</SSHBridge>
 


  1st sample, partial Trigger code:



            String s_Cred_SSH_Cert = 'CloudChoirEC2demo.pem';
                //Blob tempBlobCertNM = Blob.valueOf(s_Cred_SSH_Cert);
               // s_Cred_SSH_Cert = EncodingUtil.base64Encode(tempBlobCertNM);
            String s_Cred_Name = 'ubuntu';
                //Blob tempBlobCredNM = Blob.valueOf(s_Cred_Name);
                //s_Cred_Name = EncodingUtil.base64Encode(tempBlobCredNM);
            String s_Cred_Password = 'whatever, not used';
                //Blob tempBlobPWD = Blob.valueOf(s_Cred_Password);
                //s_Cred_Password = EncodingUtil.base64Encode(tempBlobPWD);
            String s_Cmd_Timeout = '8000';
            String s_Cmd_Input = 'ps -ef | grep tty';

            String sTemplate = '' +
                '<SSHBridge>' +
                    '<host>{0}</host>' +
                    '<port>{1}</port>'  +
                    '<certfilename>{2}</certfilename>' +
                    '<user>{3}</user>' +
                    '<password>{4}</password>' +
                    '<timeout>{5}</timeout>' +
                    '<commandline>{6}</commandline>' +
                '</SSHBridge>';     





2nd sample (XML - base64 version)
<SSHBridge>
    <host>ec2-54-213-54-199.us-west-2.compute.amazonaws.com</host>
    <port>22</port>
    <certfilename_base64>Q2xvdWRDaG9pckVDMmRlbW8ucGVt</certfilename_base64>
    <user_base64>dWJ1bnR1</user_base64>
    <password_base64>cGFzc3dvcmQtbm90LXVzZWQ=</password_base64>
    <timeout>20000</timeout>
    <commandline>ps -ef</commandline>
</SSHBridge>


2nd sample (Apex Trigger - base64 version)
2nd Sample (Account) full Trigger code:

  trigger AccountOutboundMessageTrigger on Account (after insert, after update) {     if (Trigger.isInsert)     {         for (Account acct : Trigger.new)         {             //following variables' values will be provided by either customer fields in Account or from some other related record in this Trigger,             //for DEMO purpose, I hard coded most of them             String s_AcctName = Trigger.new[0].Name;                        String sTableName = 'account';             String sColumnName = 'Description';              String sRecordID = Trigger.new[0].Id;             String sCommand = 'SSH';                          String s_Node_Address = 'ec2-54-213-54-199.us-west-2.compute.amazonaws.com';              String s_Node_Port = '22';             String s_Cred_SSH_Cert = 'CloudChoirEC2demo.pem';                                  Blob tempBlobCertNM = Blob.valueOf(s_Cred_SSH_Cert);                 s_Cred_SSH_Cert = EncodingUtil.base64Encode(tempBlobCertNM);                               String s_Cred_Name = 'ubuntu';                 Blob tempBlobCredNM = Blob.valueOf(s_Cred_Name);                 s_Cred_Name = EncodingUtil.base64Encode(tempBlobCredNM);                         String s_Cred_Password = 'whatever, not used';                 Blob tempBlobPWD = Blob.valueOf(s_Cred_Password);                 s_Cred_Password = EncodingUtil.base64Encode(tempBlobPWD);              String s_Cmd_Timeout = '8000';             String s_Cmd_Input = 'ps -ef | grep tty';                          String sTemplate = '' +                 '<SSHBridge>' +                     '<host>{0}</host>' +                         '<port>{1}</port>'  +                        '<certfilename_base64>{2}</certfilename_base64>' +                        '<user_base64>{3}</user_base64>' +                        '<password_base64>{4}</password_base64>' +                       '<timeout>{5}</timeout>' +                       '<commandline>{6}</commandline>' +                   '</SSHBridge>';                  String[] arguments = new String[] {s_Node_Address, s_Node_Port, s_Cred_SSH_Cert, s_Cred_Name, s_Cred_Password, s_Cmd_Timeout, s_Cmd_Input};             String sInputString = String.format(sTemplate, arguments);                          String sCreatedRecordID= '';             try             {                      cloudchoir__Integration__c aIntegration  = new cloudchoir__Integration__c();                    //name                   aIntegration.Name = s_AcctName;                    //callback                   aIntegration.cloudchoir__Callback_Table_Name__c = sTableName;                   aIntegration.cloudchoir__Callback_Column_Name__c = sColumnName;                    aIntegration.cloudchoir__Callback_Record_ID__c = sRecordID;                                    //input                   aIntegration.cloudchoir__Security__c = 'n/a';                   aIntegration.cloudchoir__Command__c = sCommand;                                     aIntegration.cloudchoir__Param__c = sInputString;                                  insert aIntegration;                   //keep relationship here                                   sCreatedRecordID = aIntegration.Id;             }catch (DmlException e) {                 sCreatedRecordID = 'N/A';             }                         break;         }     }     else if (Trigger.isUpdate)     {         if (Trigger.new[0].Description != Trigger.old[0].Description)  //thus no infinite loop         {             String sCurrentRecordID = Trigger.new[0].Id;             List<cloudchoir__Integration__c> l_child = [SELECT Id FROM cloudchoir__Integration__c WHERE cloudchoir__Callback_Record_ID__c =: sCurrentRecordID];             if (null != l_child && l_child.size()>0)             {                 delete l_child; //remove the 'temp' Integration record. (no need this delete, if you choose to keep it.)             }         }             } }



3. SF vs. Windows Batch
Demo video:
http://youtu.be/s3WO2-dXeqY

Command:
SSH

Sample Input XML:
<root>
<host>74.61.134.120</host>
<port>2222</port>
<user>DemoUser1</user>
<password>TempPa$$w0rd</password>
<timeout>20000</timeout>
<commandline>cmd /c c:\temp\list.bat</
commandline>
</root>


The content in "c:\temp\list.bat", it has only one line:
cmd /c dir c:\temp

Sample Trigger code:
(see above #2 as reference.) 

4. SF vs. Windows PowerShell
Demo video:
http://youtu.be/QhMhFvATPJI

Command:
POWERSHELL

Sample Input XML:
<root>
<host>74.61.134.120</host>
<port>2222</port>
<user>DemoUser1</user>
<password>TempPa$$w0rd</password>
<timeout>20000</timeout>
<powershell>Get-Service</powershell>
</root>


Sample Trigger code:
(see above #2 as reference.) 

5. SF vs. any external Java framework or library (Jar)
Anyone can test run this with his/hers existing Facebook token. (the sample input one is a valid one but expired.)

Demo video:
http://youtu.be/VItGaFwoEaE

Java framework for Facebook:
http://restfb.com/

Java/Groovy source code deployed:
import java.util.List;
import com.restfb.Connection;
import com.restfb.DefaultFacebookClient;
import com.restfb.FacebookClient;
import com.restfb.types.User;
import groovy.util.XmlSlurper
//Integration Pack - parent class
class RestFB {
    static String IntegrationCall(String jInput) throws Exception{
        return RestFBJava.ListFBFriends(jInput)
    }

}
class RestFBJava
{
    public static String ListFBFriends(String MY_ACCESS_TOKEN)
    {
        FacebookClient facebookClient = new DefaultFacebookClient(MY_ACCESS_TOKEN);
        Connection<User> myFriends = facebookClient.fetchConnection("me/friends", User.class);
        List<User> lUser = myFriends.getData();
        String sRet = "Friend count(" + myFriends.getData().size() + "):";
        for(int i=0; i< lUser.size(); i++)
        {
            sRet += lUser.get(i).getName() + ";";
        }
        return sRet;
    }
}


Command:  
RestFB

Sample Input: CAACSazocXasBAHW7fZA9tz7lVbhHmJIiPTN7SfQf5bCrxaspnRoAtJhqV57WoHFMLAfgMuJfLRze3QLKjF5CEZAckyeqzRm9UaYuKhgH2p4UZBxvMu8ZA5WLic1s5rl6ZBGliMkUEKtnXFOhcoDMPIleAIEL7T68A1oIbDfITgBKd14KIyZBSR5itiQ1ZAhs6ZADqCU83LiolwZDZD

Sample Trigger code:
trigger AccountCloudchoirRestFB on Account (after insert, after update) {
    if (Trigger.isInsert)
    {
        for (Account acct : Trigger.new)
        {
            String s_AcctName = Trigger.new[0].Name;          
            String sTableName = 'account';
            String sColumnName = 'Description';
            String sRecordID = Trigger.new[0].Id;
            String sCommand = 'RestFB';        
            String sInputString = Trigger.new[0].Description; 
           
            String sCreatedRecordID= '';
            try
            {  
                  cloudchoir__Integration__c aIntegration  = new cloudchoir__Integration__c();
                  //name
                  aIntegration.Name = s_AcctName;
                  //callback
                  aIntegration.cloudchoir__Callback_Table_Name__c = sTableName;
                  aIntegration.cloudchoir__Callback_Column_Name__c = sColumnName;
                  aIntegration.cloudchoir__Callback_Record_ID__c = sRecordID;                
                  //input
                  aIntegration.cloudchoir__Security__c = 'n/a';
                  aIntegration.cloudchoir__Command__c = sCommand;                 
                  aIntegration.cloudchoir__Param__c = sInputString;              
                  insert aIntegration;
                  //keep relationship here               
                  sCreatedRecordID = aIntegration.Id;
            }catch (DmlException e) {
                sCreatedRecordID = 'N/A';
            }           
            break;
        }
    }
    else if (Trigger.isUpdate)
    {
        if (Trigger.new[0].Description != Trigger.old[0].Description)  //thus no infinite loop
        {
            String sCurrentRecordID = Trigger.new[0].Id;
            List<cloudchoir__Integration__c> l_child = [SELECT Id FROM cloudchoir__Integration__c WHERE cloudchoir__Callback_Record_ID__c =: sCurrentRecordID];
            if (null != l_child && l_child.size()>0)
            {
                delete l_child; //remove the 'temp' Integration record. (no need this delete, if you choose to keep it.)
            }
        }       
    }
}



6. SF query Emails (demo)
Demo video:
http://youtu.be/QYL-g2I4Yuc

Command:

Sample Input XML:

Sample Trigger code:
(see above #1 and #2) 
7. SF query Linkedin (demo)
Demo video:
http://youtu.be/QYL-g2I4Yuc

Command:

Sample Input XML:

Sample Trigger code:
(see above #1 and #2) 
8. SF query Facebook (demo)
Demo video:
http://youtu.be/bafj6rof_BM

Command:

Sample Input XML:

Sample Trigger code:
(see above #1 and #2)

No comments: