Skip navigation.

Angelo Santagata

Syndicate content
Fusion Middleware / Cloud Integration Architect - If its middleware, or PaaS for SaaS, then I'm interested!
Updated: 4 hours 32 min ago

Streamline Oracle Development with Cloud Services

Thu, 2015-07-02 04:24
Streamline Java Development with Cloud Services
On-Demand Webinar Replay
Learn to deliver java applications to market faster. Reduce hardware and software costs for new development and testing environments. Improve DevOps efficiency. Build, test and run enterprise-grade applications in the Cloud and on premise.

Listen to this webinar replay with development expert James Governor, co-founder of RedMonk, and Daniel Pahng, President and CEO of mFrontiers, LLC, an ISV with hands-on experience developing enterprise mobility and Internet of Things (IOT) solutions, as they present this webcast on developing applications in the cloud. Listen today! For more information: July 2015                                                                                          Oracle Corporation - All rights reserved

Calling Fusion SOAP Services from Ruby

Wed, 2015-07-01 07:55
Just completed some integration work with a partner of ours using the Ruby language. Given that a lot of startups like Ruby I thought it would be useful to cut-n-paste the sample code here. This example creates a simple (minimal) opportunity using the SOAP API in Sales Cloud. That said the code would be almost identical if you were querying HCM Data, The approach we took here was to prototype the SOAP call using SOAPUI and then cut-n-paste the SOAP payload into the data variable. In a real industrialized solution I'd create the payloads in template form.

  def create_opportunity
  # Change yourhostname.com to your Fusion SOAP Endpoint Hostname     uri = URI.parse("https://yourhostname.com/opptyMgmtOpportunities/OpportunityService")
    http = Net::HTTP.new(uri.host, uri.port)     http.use_ssl = true     path = uri.request_uri     http.read_timeout = 5     http.open_timeout = 5

  # Change authorization header to contain Base64encoded string of username/password     headers = {     'Content-Type' => 'text/xml',     'soapAction' => 'http://xmlns.oracle.com/apps/sales/opptyMgmt/opportunities/opportunityService/createOpportunity',     'authorization' => 'Basic bBase64EncodedCredentialHere='     }
       # Data Contains the payload     data = '<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:typ="http://xmlns.oracle.com/apps/sales/opptyMgmt/opportunities/opportunityService/types/" xmlns:opp="http://xmlns.oracle.com/apps/sales/opptyMgmt/opportunities/opportunityService/" xmlns:rev="http://xmlns.oracle.com/apps/sales/opptyMgmt/revenues/revenueService/" xmlns:not="http://xmlns.oracle.com/apps/crmCommon/notes/noteService" xmlns:not1="http://xmlns.oracle.com/apps/crmCommon/notes/flex/noteDff/" xmlns:rev1="http://xmlns.oracle.com/oracle/apps/sales/opptyMgmt/revenues/revenueService/" xmlns:act="http://xmlns.oracle.com/apps/crmCommon/activities/activitiesService/">     <soapenv:Header/>     <soapenv:Body>     <typ:createOpportunity>     <typ:opportunity>     <opp:Name>Joel Test New1</opp:Name>     </typ:opportunity>     </typ:createOpportunity>     </soapenv:Body>     </soapenv:Envelope>'
    resp, data = http.post(path, data, headers)   end
!TIP!
A quick test in a SOAP testing tool like JDevelopers Http Analyzer or SOAPUI is a MUST before executing this!

URL Encoding and other from Groovy

Wed, 2015-06-03 07:44

There are times when you want to execute some code within Groovy which Oracle Sales Cloud's groovy doesn’t like. A very common example is URLEncode and Base64Encoding, however there are many others..


Native Groovy supports both base64 encoding/decoding and URL Encoding/Decoding


e.g.



String encoded = s.bytes.encodeBase64.toString()



Alas the groovy interpreter within Sales Cloud doesn’t support either the base64 encoding/decoding classes or the URLEncoding classes. Thankfully there is a an easy workaround, Sales Cloud does support the ability to call a SOAP Service from Sales Cloud and given that many SalesCloud installations will have a Java Cloud SX instance available to them its quite easy to create a Java SOAP Service, deploy it to JCSSX and then call this from Sales Cloud to do the stuff that Sales Cloud’s groovy wont allow you to do.



https://4.bp.blogspot.com/-W_PVvNpvJ_Y/VW7a8Ow9DpI/AAAAAAAAMq8/FOvtRAKulGM/s400/base64image.jpg


Steps to recreate this

  1. Create a new Project within your favourite IDE (I use JDeveloper11g for Sales Cloud Development, Netbeans for other stuff)

  2. Ensure your project has support for JAX-WS WebServices, within JDeveloper  create a JEE project.

  3. Within your project create a new Java class, I’ve called PTSEncoder

  4. Now cut and paste the following code into this class, obviously rename the Class name if you havent used the same name as I have

package oracle.pts.encoder;

import java.io.IOException;

import java.io.UnsupportedEncodingException;

import java.net.URLDecoder;

import java.net.URLEncoder;

import javax.jws.WebMethod;

import javax.jws.WebService;

import javax.xml.bind.DatatypeConverter;

@WebService

public class PTSEncoder {

   public PTSEncoder() {

       super();

   }


   /**

    *

    * @param s - String to be translated

    * @return

    */

@WebMethod(operationName = "encode")

   public String utf8encode(String s) {

       String result = "";

       try {


           result = URLEncoder.encode(s, "UTF-8");

           System.out.println("Encoded URL " + result);


       } catch (UnsupportedEncodingException e) {

           System.err.println(e);

       }

       return result;

   }


   /**

    *

    * @param s - String to be translated

    * @param enc - The name of a supported character encoding

    * @return

    */

   @WebMethod(operationName = "encodeWithEncType")

   public String ptsEncodeWithEncType(String s, String enc) {

       String result = "";

       try {

           if (enc == null || enc.length() <= 0) {

               enc = "UTF-8";

           }

           result = URLEncoder.encode(s, enc);

           System.out.println("Encoded URL " + result);


       } catch (UnsupportedEncodingException e) {

           System.err.println(e);


       }

       return result;

   }


   /**

    *

    * @param s - String to be translated

    * @return

    */

   @WebMethod(operationName = "decode")

   public String ptsDecode(String s) {

       String result = "";

       try {


           result = URLDecoder.decode(s, "UTF-8");

           System.out.println("Decoded URL " + result);


       } catch (UnsupportedEncodingException e) {

           System.err.println(e);

       }

       return result;

   }


   /**

    *

    * @param s - String to be translated

    * @param enc - The name of a supported character encoding

    * @return

    */

   @WebMethod(operationName = "decodeWithEncType")

   public String ptsDecodeWithEncType(String s, String enc) {

       String result = "";

       try {

           if (enc == null || enc.length() <= 0) {

               enc = "UTF-8";

           }

           result = URLDecoder.decode(s, enc);

           System.out.println("Decoded URL " + result);


           // String decodedUrl = URLDecoder.decode(encodedUrl, "UTF-8");

           //System.out.println("Dncoded URL " + decodedUrl);


       } catch (UnsupportedEncodingException e) {

           System.err.println(e);


       }

       return result;

   }


   /**

    * @param s

    * @return

    * @throws IOException

    */

@WebMethod(operationName = "encodebase64")

   public String ptsEncodeBase64(String s) throws IOException {        

       return DatatypeConverter.printBase64Binary(s.getBytes());

   }


   /**

    * @param s

    * @return

    * @throws IOException

    */

   @WebMethod(operationName = "decodebase64")

   public String ptsDecodeBase64(String s) throws IOException {    

       String result = new String(DatatypeConverter.parseBase64Binary(s));

       return result;

   }

// Simple tester

@WebMethod(exclude = true)

   public static void main(String[] args) {

       PTSEncoder pTSEncode = new PTSEncoder();

       pTSEncode.utf8encode("Angelo Woz here");

       pTSEncode.ptsEncodeWithEncType("Angelo Woz Here", "UTF-8");

       pTSEncode.utf8encode("------------");

       pTSEncode.ptsDecode("Jo was here");

       pTSEncode.ptsDecodeWithEncType("Jo Was here", "UTF-8");


       try {

           System.out.println("Encode Angelo = "+pTSEncode.ptsEncodeBase64("Encode Angelo"));

       } catch (IOException e) {

           e.printStackTrace();

       }

   }

}


For interest I created this class by first creating the methods and then using J Developers wizard to convert a class+methods into a SOAP WebService. This class uses Java annotations which tell at JEE server that most (not all) of these methods are WebService calls. This is done using server side injection at deployment time.

  1. If within JDeveloper you created your project as a web/jee project you can simply deploy it as is to your JCSSX, or local WLS Application Server

    1. Right Mouse Click on the Project, deploy to your deployment profile

    2. Deploy to Application Server

    3. Choose your application server and deploy

    4. Check the deployment

You can now test the SOAP Service using a SOAP testing tool like Http Analyzer or SOAP UI. The WSDL of the service would be the contextRoot+WebService Name. For JDeveloper this can be found if you right-click on the Webservice Class,Java WebServices Editor and look at the generation options



So in my instance the WSDL will be available at


https://<JCSSXServer>.java.us2.oraclecloudapps.com/PTSEncoder/PTSEncoderService?wsdl



  1. You can put this into SOAPUI or Http Analyzer and test away

  2. Now last you can register it in Sales Cloud as a web service and use it from Groovy

    1. Activate a Sandbox,  that way you can undo changes if oyu want

    2. Navigate to Application Composer

    3. Navigate to the application you will be using the SOAP WebService from (Common,Sales etc)

    4. Select WebServices

    5. Enter a name for the WebService, this name becomes the groovy package name

    6. Security None (for testing only)

    7. Then finally use the SoapService from any groovy script you desire, remember the Palette helps you find different services registered on you system



Sample Groovy Code

def base64result = adf.webServices.PTSBase64.encodebase64("Angelo Woz Here")


Final footnote

This example shows how to execute a base64 encoding externally using Java Cloud ServiceSaaS eXtensions (JCSSX), the example could easily have used Java Cloud Service, or some other Cloud service. More importantly you can code extensions using Java Cloud Service and call them from SalesCloud. Given that most JCSSX instances are going to be co-located within the same datacentre this makes the operation quick, efficient and very flexible!

Lastly, the service I deployed didn’t contain any security because it’s a stateless service and ok for anyone to call, that said in a production environment I would still add a medicum of security to the service just to make sure someone doesn’t try and abuse it.

Angelo
Enjoy!


Getting started with Sales Cloud (Updated)

Mon, 2015-05-04 08:24
Hey all, Ive just reviesed the Getting Started with Oracle Sales Cloud Integrations blog entry with a few more links

SalesCloud Payload : How to create a Activity(Task)

Wed, 2015-04-29 08:48


From SalesCloud R9 onwards we now have Activities.. Activities can be tasks, appointments etc.  Object Name Activity WSDLhttps://<hostname>:443/appCmmnCompActivitiesActivityManagement/ActivityService?wsdl Version Tested on R9  DescriptionThis payload demonstrates how to create an activity of type TASK, assign a primary lead owner  OperationcreateActivity  Parameters
*Required PriorityCode*,
StatusCode
ActivityContact
ActivityTypeCode*
ActivityFunctionCode*
Subject  Payload <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:typ="http://xmlns.oracle.com/apps/crmCommon/activities/activityManagementService/types/" xmlns:act="http://xmlns.oracle.com/apps/crmCommon/activities/activityManagementService/" xmlns:not="http://xmlns.oracle.com/apps/crmCommon/notes/noteService" xmlns:not1="http://xmlns.oracle.com/apps/crmCommon/notes/flex/noteDff/">    <soapenv:Header/>    <soapenv:Body>       <typ:createActivity>          <typ:activity> <!-- Priority = 1,2,3 , high, medium, low -->             <act:PriorityCode>1</act:PriorityCode>             <act:StatusCode>NOT_STARTED</act:StatusCode>             <act:ActivityContact> <!-- Primary contact ID-->                <act:ContactId>300000093409168</act:ContactId>             </act:ActivityContact>             <act:ActivityAssignee> <!-- Party ID of Assignnee -->                <act:AssigneeId>300000050989179</act:AssigneeId>             </act:ActivityAssignee>             <act:ActivityTypeCode>MEETING</act:ActivityTypeCode>             <act:ActivityFunctionCode>TASK</act:ActivityFunctionCode>                         <act:Subject>Test assign to Matt Hooper for Picard</act:Subject>          </typ:activity>       </typ:createActivity>    </soapenv:Body> </soapenv:Envelope>

Creating Sales Cloud Opportunity

Mon, 2015-04-20 06:02

Common Payload creating opportunities

  <createOpportunity>
    <opportunity>
      <ChildRevenue>
        <ProdGroupId>300000000537006</ProdGroupId>
        <RevnAmount>45000.0</RevnAmount>
        <ResourcePartyId>300000000519815</ResourcePartyId>
      </ChildRevenue>
      <SalesStageId>300000000157471</SalesStageId>
      <Comments>Provide training to 250 salespersons and support staff</Comments>
      <EffectiveDate>2012-09-30</EffectiveDate>
      <WinProb>5.0</WinProb>
      <Name>New Sales Training</Name>
      <OptyCreationDate>2012-08-27T00:00:00.000</OptyCreationDate>
      <TargetPartyId>300000001025130</TargetPartyId>
      <OwnerResourcePartyId>300000000519815</OwnerResourcePartyId>
      <OpportunityResource>
        <ResourceId>300000000519815</ResourceId>
        <OwnerFlag>true</OwnerFlag>
      </OpportunityResource>
    </opportunity>
  </createOpportunity>




Sample Java Code

1. Generate Proxy using Java Tooling (like JDeveloper)
2. Java Code Snippet

public static void main(String[] args) {

        // Default Values
        String username = "matt.hooper";
        String password = "somepassword";
        String SSLSecurityPolicy = "oracle/wss_username_token_over_ssl_client_policy";

        SecurityPolicyFeature[] securityFeature = new SecurityPolicyFeature[] { new   
SecurityPolicyFeature(SSLSecurityPolicy) };

        String url="https://<yourhost>/opptyMgmtOpportunities/OpportunityService?WSDL";
        // Setup the webservice interface
        OpportunityService_Service opportunityService_Service = new opportunityService_Service();
        OpportunityService opportunityService = opportunityService_Service.getopportunityServiceSoapHttpPort(securityFeature);
        // Get the request context to set the outgoing addressing properties
        WSBindingProvider wsbp = (WSBindingProvider)opportunityService;
        Map<String, Object> requestContext = wsbp.getRequestContext();
        requestContext.put(WSBindingProvider.USERNAME_PROPERTY, username);
        requestContext.put(WSBindingProvider.PASSWORD_PROPERTY, password);
        requestContext.put(WSBindingProvider.ENDPOINT_ADDRESS_PROPERTY, url);

        System.out.println("Example of creating an opportunity ");

        // Create Payload        
        ObjectFactory factory = new ObjectFactory();
        opportunity newopportunity=factory.createopportunity();
        newOpportunity.setName("Name of Opportunity");
        // Set other values
        //
        Opportunity result=opportunity.createOpportunity();
        // and so on




Scheduling Processes on Oracle JavaCloud Service SaaS Extensions (JCSSX)

Mon, 2015-04-13 17:38
In the past if we wanted to schedule some background processing in JCSSX we had to get help from the database's scheduler.. Using a clever feature of SchemaDB, that is the ability to call a REST Service from a PLSQL procedure, which in turn would execute our code on JCSSX we were able to effectively execute code on JCSSX at determined intervals/times etc. All this is now unnecessary! With the current version of JCSSX we now fully support a list of 3rd party frameworks (see link for a list) and Quartz is one of them. Jani, colleague from the Fusion Developer Relations team, has written up a really nice blog posting on the FADevrel blog summarising what you can do with Quartz and some code to get you started..You could say "Quartz in 10mins" blog! Check it out

Sample Payload : Creating a Lead

Wed, 2015-04-08 10:43

Very common operation

 Object Name
Lead Version Tested on
R9
 Description This payload demonstrates how to create a salesLead, assign a primary lead owner AND add additional resources to the lead
Operation createSalesLead  Parameters
*Required

Name*
StatusCode
CustomerId
ResourceId
PrimaryFlag

 Payload

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:typ="http://xmlns.oracle.com/apps/marketing/leadMgmt/leads/leadService/types/" xmlns:lead="http://xmlns.oracle.com/oracle/apps/marketing/leadMgmt/leads/leadService/" xmlns:lead1="http://xmlns.oracle.com/apps/marketing/leadMgmt/leads/leadService/">
   <soapenv:Header/>
   <soapenv:Body>
      <typ:createSalesLead>
         <typ:salesLead>
            <lead:Name>gold2 - cust</lead:Name>
            <lead:StatusCode>UNQUALIFIED</lead:StatusCode>
            <lead:CustomerId>100000000055319</lead:CustomerId>
            <!--PartyID of person you want to assign it to-->
            <lead:OwnerId>300000000629932</lead:OwnerId>
            <lead:MklLeadResources>
        <!-- ResourceID is PartyID of additional Resource -->
               <lead1:ResourceId>300000000623680</lead1:ResourceId>
               <lead1:PrimaryFlag>false</lead1:PrimaryFlag>
            </lead:MklLeadResources>
         </typ:salesLead>
      </typ:createSalesLead>
   </soapenv:Body>
</soapenv:Envelope>

 

 


Smart watches in the enterprise?

Wed, 2015-04-01 08:17

Although smart watches have been around for a couple of years (Sony had a v1 2+yrs ago, Pebble, Samsung gear, Google wear etc) now that Apple is poised to deliver its iWatch the worlds gone crazy about them.. or has it?? Personally I'm still struggling to identify the “killer” SmartWatch App where I would start to wear a watch again (I stopped wearing watches the day I discovered my Nokia mobile had a clock).. One area which I totally “get” is Healthcare.. In that the watch/wearable device can monitor my steps, heart-rate, stress levels (skin resistance) etc… but what about the enterprise???

Anyway, some friends of mine at Oracle HQ (Jeremy & Ultan) have done some awesome R&D in this area, gotten hold of some watches, prototyped some ideas and come up with some compelling ideas.. ..

Is “glancing” and “glance-able” apps the game changer?? You decide..

https://blogs.oracle.com/usableapps/entry/a_glance_at_smartwatches_in

Getting inaccessible URL when executing REST calls within JCSSX????

Mon, 2015-03-30 16:16

Recently I was coding up a REST client for use with Oracle Documents Cloud, using Jersey REST client, and it needed to be deployed to Oracle Java Cloud SX (aka JCSSX). The client code worked perfectly on a local Weblogic 11g but when deployed to the JCSSX instance it would give the following error :

Normal 0 false false false EN-GB X-NONE X-NONE MicrosoftInternetExplorer4

java.lang.RuntimeException: java.security.AccessControlException: access denied ("java.net.SocketPermission" "partners-pts.documents.us2.somecloud.com:443", "connect,resolve")

/* Style Definitions */ table.MsoNormalTable {mso-style-name:"Table Normal"; mso-tstyle-rowband-size:0; mso-tstyle-colband-size:0; mso-style-noshow:yes; mso-style-priority:99; mso-style-qformat:yes; mso-style-parent:""; mso-padding-alt:0cm 5.4pt 0cm 5.4pt; mso-para-margin:0cm; mso-para-margin-bottom:.0001pt; mso-pagination:widow-orphan; font-size:11.0pt; font-family:"Calibri","sans-serif"; mso-ascii-font-family:Calibri; mso-ascii-theme-font:minor-latin; mso-fareast-font-family:"Times New Roman"; mso-fareast-theme-font:minor-fareast; mso-hansi-font-family:Calibri; mso-hansi-theme-font:minor-latin; mso-bidi-font-family:"Times New Roman"; mso-bidi-theme-font:minor-bidi;}

Initially I was convinced that this was some sort of networking issue in JCSSX, I.e. it couldn't connect to the documents cloud server via the network.. I even tried manually setting the proxy in the Java Code all to no avail..

After quite a while looking I discovered the problem...

This is the detailed error message I got :

Normal 0 false false false EN-GB X-NONE X-NONE MicrosoftInternetExplorer4 Caused by: java.security.AccessControlException: access denied ("java.net.SocketPermission" "partners-pts.documents.us2.somecloud.com:443" "connect,resolve")
at java.security.AccessControlContext.checkPermission(AccessControlContext.java:372)
at java.security.AccessController.checkPermission(AccessController.java:559)
at java.lang.SecurityManager.checkPermission(SecurityManager.java:549)
at java.lang.SecurityManager.checkConnect(SecurityManager.java:1051)
at sun.net.www.http.HttpClient.openServer(HttpClient.java:510)
at sun.net.www.protocol.https.HttpsClient.<init>(HttpsClient.java:275)

at sun.net.www.protocol.https.HttpsClient.New(HttpsClient.java:371)
at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.getNewHttpClient(AbstractDelegateHttpsURLConnection.java:191)
at sun.net.www.protocol.http.HttpURLConnection.plainConnect(HttpURLConnection.java:932)
at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.java:177)
at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1300)
at java.net.HttpURLConnection.getResponseCode(HttpURLConnection.java:468)
... 81 more

/* Style Definitions */ table.MsoNormalTable {mso-style-name:"Table Normal"; mso-tstyle-rowband-size:0; mso-tstyle-colband-size:0; mso-style-noshow:yes; mso-style-priority:99; mso-style-qformat:yes; mso-style-parent:""; mso-padding-alt:0cm 5.4pt 0cm 5.4pt; mso-para-margin:0cm; mso-para-margin-bottom:.0001pt; mso-pagination:widow-orphan; font-size:11.0pt; font-family:"Calibri","sans-serif"; mso-ascii-font-family:Calibri; mso-ascii-theme-font:minor-latin; mso-fareast-font-family:"Times New Roman"; mso-fareast-theme-font:minor-fareast; mso-hansi-font-family:Calibri; mso-hansi-theme-font:minor-latin; mso-bidi-font-family:"Times New Roman"; mso-bidi-theme-font:minor-bidi;}


The bold bits hint at the issue.. For some reason my code was using the Sun HTTP Handler which isn't supported on the JCSSX stack but I hadnt configured it to use the Sun Http Handler...You can get your code to use the Sun Http Handler by either setting the system property "UseSunHttpHandler=true" in code or by using Oracle Cloud SDK to set it as a system property.

To check if you have the UseSunHttpHandler set, issue the following command (changing your JCSSX details)

 javacloud list-system-properties -user <username> -p <password> -id <identityDomain>-si  <serverInstance> -httpproxy <httpProxy:port> -datacenter <dataCenterName>

If you have the UseSunHttpHander set to true, or even present, then remove it! Someone had set it in my instance but none of my team members would admit to it.....

 javacloud delete-system-property -user <username> -p <password> -id <identityDomain>-si  <serverInstance> -httpproxy <httpProxy:port> -datacenter <dataCenterName> -name UseSunHttpHandler

Restart your instance and all should then be well.

We've logged an enhancement request to get JCSSX to ignore this specific system property but just incase you hit it before the ER hits the JCSSX servers.



PTS Sample code now available on GitHub

Mon, 2015-03-30 08:43

Not sure many people know about this, but sometime ago my team created a whole collection of sample code. This code is available on OTN at this location  but it is now also available in github here!

 We'll be updating this repository with some new code soon, when we do I'll make sure to update this blog entry