Angelo Santagata

Subscribe to Angelo Santagata feed
Oracle Blogs
Updated: 2 hours 46 min ago

URL Encoding and other from Groovy

Wed, 2015-06-03 08: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 09:24
Hey all, Ive just reviesed the Getting Started with Oracle Sales Cloud Integrations blog entry with a few more links

Getting started with Sales Cloud (Updated)

Mon, 2015-05-04 09: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 09:48


From SalesCloud R9 onwards we now have Activities.. Activities can be tasks, appointments etc. 
Object NameActivityWSDLhttps://<hostname>:443/appCmmnCompActivitiesActivityManagement/ActivityService?wsdlVersion 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:Envelopexmlns: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 forPicard</act:Subject>
        </typ:activity>
     </typ:createActivity>
   </soapenv:Body>
</soapenv:Envelope>

SalesCloud Payload : How to create a Activity(Task)

Wed, 2015-04-29 09: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 07: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 18: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 11: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 09: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 17: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 09: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

What has Angelo been doing? Whats this marketplace all about?

Thu, 2015-02-19 04:39

About two years ago my role changed from focusing on Fusion Middleware enablement to SaaS Integration enablement. Simply put my team started looking at how to get partners integrated with our SaaS applications (SalesCloud - CRM, HCM, ERP ) using PaaS where needed and more recently also looking at the pure PaaS enablement model.

The market is growing and we now have an enterprise app store aimed at partners where they can host their apps and integrations. Checkout this video recently released featuring my VP, Sanjay Sinha, where he explains the ISV partner eco-system, how its changing the way we do business and the key benefits for ISV and OEM partners.

 



Snippet : How to query the Sales Cloud users username in groovy and in EL

Thu, 2015-02-19 04:16
Ive decided to create a new category called "Snippets" to capture small chunks of information which might be useful to other people

In Groovy
// Get the security context
def secCtx = adf.context.getSecurityContext()
// Check if user has a given role
if (secCtx.isUserInRole('MyAppRole')) {
  // get the current user's name
  def user = secCtx.getUserName()
  // Do something if user belongs to MyAppRole
}


In a EL Expression
#{securityContext.userName} 

UKOUG 2014 : Are you there?

Fri, 2014-12-05 09:55

Im going to be at UKOUG next week helping out with the AppsTech 2014 Apps "Just Do It Workshop"...

Are you going to be there?? if so come and find me on Monday in the Executive Rooms, Tuesday/Wednesday I'll a "participant" and attending the various presentations on Cloud, Integration technologies , Mobile and ADF.. Come and find me :-)

 https://blogs.oracle.com/fadevrel/entry/don_t_miss_us_at


Getting JDeveloper HttpAnalyzer to easily work against SalesCloud

Fri, 2014-12-05 09:48

Hey all

Little tip here. If your trying to debug some Java code working against SalesCloud one of the tools you might try and use is the http analyzer.. Alas I couldn’t get it to recognize the oracle sales cloud security certificate and the currently version of JDeveloper (11.1.1.7.1) doesnt give you an option to ignore the certificate..

However.. there is a workaround, simply start JDeveloper using a special flag which tells JDevelopers Http Analyzer to trust everybody!

jdev -J-Djavax.net.ssl.trusteverybody=true

Very useful…and obviously for testing and development its ok, but not for anyting else

For more information please see this  Doc reference

Getting Started with Oracle Fusion Cloud Integrations

Thu, 2014-12-04 12:32

Updated: 4-May-2015

Hey all,

If your getting started with integrating your application with Oracle Fusion Cloud then I wholeheartedly recommend you read the following resources before starting.. Most of the below is specific to Oracle Sales Cloud because it has App Composer, however much of the below is also applicable to HCM, ERP and other Fusion products.. 

Some of these are a MUST have read before you start integrating/coding/customizing :-) I've put them here in the order I think would work for most people... Kinda like a getting started check-list

I consider this blog entry an living blog entry, in that  I'll be updating it on a regular basis, so make sure you periodically check this location 


Top 5 Fusion Integrations Must Reads 

1. Familiarise yourself with the Sales Cloud Documentation. Specifically :
    • Go through the "User" section, documents like "Using Sales Cloud", "book. If your a techie like me you'll sit there and think, "Hey this is functional why do I need to read this?", well you do.. Even as a technical person, reading through the various user documents like the Using Sales Cloud" bits as an end user helps you understand what the different concepts/topics are.. You'll also understand things like the difference between a Prospect and a Sales Account, territories, assessments and much more.. Its worth a quick read, but do make sure you have a functional consultant to hand to make sure your not building something which can be done by configuration....
    • Read through all the books in the "Extensibility" section. The only anomaly here is the "Business Card Scanner mobile App" document. Its a walk-through of how to integrate Sales Cloud with a 3rd party Service to do business card scanning with MAF... Id leave that till last...
    • Peruse the Development section, this section contains a number of example use-cases, ie how to create a customer in R8, how to call an outbound service, its a good read....
2. Get an overview of the tasks you might do...
    • Once you've this then look at the "Tasks" section of the docs....Here the curriculum development folk have categorised some of the most common tasks and put short cuts to the documentation detailing how to do this.. e.g. like adding a field to Sales Cloud, calling a soap webservice etc
3. Are you going to be customizing the SalesCloud User Interface?
    • Many Sales Cloud integrations involve customizing the Sales Cloud User Interface. The customization could be as simple as adding a few fields to a standard object (like Opportunity), creating new objects (like MyOrder), validation or adding external content to one or many pages.
    • If your adding fields make sure you read the "Introduction to SalesCloud Customizations" section.
    • If you will be adding validation, triggers or calling webservices from Sales Cloud then make sure you read up on groovy scripting, and specifically the chapter on calling outbound SOAP webservices from groovy.
    • Make sure you understand the difference between calling a SOAP Service from groovy and creating an outbound webservice call using object workflows
      • In a nutshell , calling SOAP Services from groovy is a synchronous call, and calling a SOAP Service from a object workflow is a fire-and-forget asynchronous call
      • If you need to make sure an outbound webservice call is executed successfully then call the outbound webservice from a groovy script and surround it with an exception handler to catch any errors
    • On the subject of groovy be aware that in Sales Cloud you do not have access to the entire groovy language, thus make sure you understand that we only support a number of groovy functions (white-listing) and these are documented at the end of the book , Appendix A Supported Groovy Classes and Methods
4. Are you going to be accessing data from SalesCloud from the external app??
    • If you think you will be calling SOAP WebServices in Sales Cloud then the "Getting started with WebServices" is a MUST read...  This doc goes into details into how to look up the SOAP webservice in Fusion OER, how to create static proxies, querying data and how to perform CRUD operations...
    • Get to know Oracle Fusion OER,, its a gold mine of information.......
    • Read Arvinds ( A-Team Chronicles Blog ) excellent "Invoking Sales Cloud SOAP Services from external Applications (part 1)" blog entry. This blog entry describes the steps aronud looking up a SOAP service (ie Opportunities) and then how to create a SOAP JAX-WS static proxy using JDeveloper11g. I personally would the JAX-WS Proxy approach (vs the Data Control) and then building Java code around this to support your application.
5. Do you need your app to know who is calling it? 
    • Many integrations involve embedding a 3rd party web app into Oracle Sales Cloud as an iFrame or pressing a button in SalesCloud and calling the 3rd party app (either a UI or WebService call) . If your doing this then you'll almost certainly need to pass a "token" to the 3rd party application so it can use that it can call back to Sales Cloud with a key rather than a plain text username/password combo.. We call this key JWT TOKEN and its based on industry standards (http://jwt.io/) .  For a starters read my JWT Getting started blog  entry and then use the links to read the core documentation

That covers the top 5 areas of integration.. Now for a list of locations where you can get even MORE useful information :

More Information

  1. Oracle Learning Centres Quick Webinars on SalesCloud Integration
    • I worked with Development to get this mini tutorial series done, its excellent but Im obviously not biased eh  ;-) 
  2. R9 Simplified WebServices doc
    • This is a new document we recently completed based on how to use the new R9 Simplified SOAP TCA Services..  Although the document is targetted at R9 developers, it covers many of the standard topics like how to create a proxy, how to create a create operation etc.. It even has some sample CRUD payloads which are really really useful 
  3. Oracle Fusion Developer Relations
    1. Good friends of mine, they host a fantastic blog, youtube channel and whitepapers for Fusion Developers, another gold mine of information covering customization , extensions and integration code.
  4. Oracle Fusion Developer Relations
    1. Youtube channel : Not content with an awesome blog the Developer Relations folk even have a you tube channel where they host a collection of short "tutorials", showing all sorts such as "How to add a field to a page" , " How to call a webservice" etc..
    2. Oracle Fusion Developer Relations Whitepapers
  5. And finally there is my humble blog (which you are reading now) where I try and blog on things which aren't documented anywhere else.. If they are documented and are interesting I often link to it.. mainly because I want to find it myself :-)

Thats it folks!

If there are blog entries you'd like to see, or specific how to's, then feel free to contact me at angelo.santagata@oracle.com

Angelo 


How to use the Oracle Sales Cloud New Simplified WebServices API

Fri, 2014-11-14 04:05

Over the last two years my organisation has been working with multiple partners helping them create partner integrations and showing them how to use the variety of SOAP APIs available for Sales Cloud integrators. Based on this work Ive been working with development with the aim to simplify some of the API calls which require "multiple" calls to achieve a single objective.. For example to create a Customer Account you often need to create the Location first , and then the contacts and then the customer account.. In SalesCloud R9 you will have a new subset of APIs which will simplify this.

So you all have a head-start in learning the API I've worked with our documentation people and we've just released a new whitepaper/doc onto Oracle Support explaining the new API in lovely glorious detail. It also includes some sample code of each of the operations you might use and some hints and tips!

Enjoy and feel free to post feedback 

 You can download the documentation from Oracle Support, the document is called "Using Simplified SOAP WebServices" , its docId is 1938666.1 and this is a direct link to the document

Got problems with Nulls with ServiceCloud's objects in REST?

Wed, 2014-11-12 13:02
Using Oracle RightNow, Jersey 1.18, JAX-WS, JDeveloper 11.1.1.7.1

Whilst trying to creating a REST interface to our RightNow instance for a mobile application I was hitting an issue with null values being rendered by Jersey (Jackson)

The way I access RightNow is via JAX-WS  generated proxies which generates JAXB Objects. In the past I've been able to simply return the JAXB object to Jersey and it gets rendered all lovely jubbly.. However with the RightNow WSDL I'm getting lots of extra (null) fields rendered.. This doesn't occur with Sales Cloud so I'm assuming its something to do with the WSDL definition..

     
{ "incidents" : [
   {
       "Asset" : null, "AssignedTo" :  {
           "Account" : null, "StaffGroup" :  {
               "ID" :  {
                  "id" : 100885
              },"Name" : "B2CHousewares"
           },"ValidNullFields" : null
        },"BilledMinutes" : null, "Category" :  {
           "ID" :  {
               "id" : 124
           },"Parents" : [
           {
           .....
Look at all those "null" values, yuck...

Thankfully I found a workaround (yay!), I simply needed to create a custom Object Mapper and tell it *not* to render nulls. This worked for both the JAXB objects which were generated for me and other classes

Simply create a class which overrides the normal object Mapper factory and to make sure its used, ensure the @Provider tag is present

package myPackage;

import javax.ws.rs.ext.ContextResolver;
import javax.ws.rs.ext.Provider;

import org.codehaus.jackson.map.DeserializationConfig;
import org.codehaus.jackson.map.ObjectMapper;
import org.codehaus.jackson.map.SerializationConfig;
import org.codehaus.jackson.map.annotate.JsonSerialize;

@Provider
public class CustomJSONObjectMapper implements ContextResolver<ObjectMapper> {

    private ObjectMapper objectMapper;

   
    public CustomJSONObjectMapper() throws Exception {
        System.out.println("My object mapper init");
         objectMapper= new ObjectMapper();
         // Force all conversions to be NON_NULL for JSON
         objectMapper.setSerializationInclusion(JsonSerialize.Inclusion.NON_NULL);
    }

    public ObjectMapper getContext(Class<?> objectType) {
        System.out.println("My Object Mapper called");
        return objectMapper;
    }
}

And the result is lovely.. No null values and ready for my mobile app to consume .... 
{
    "organization" : [
    {
        "id" :  {
            "id" : 68
        },"lookupName" : "AngieSoft", "createdTime" : 1412166303000, "updatedTime" : 1412166303000, "name" : "AngieSoft", "salesSettings" :  {
            "salesAccount" :  {
                "id" :  {
                    "id" : 2
                }
            },"totalRevenue" :  {
                "currency" :  {
                    "id" :  {
                        "id" : 1
                    }
                }
            }
        },"source" :  {
            "id" :  {
                "id" : 1002
            },"parents" : [
            {
                "id" :  {
                    "id" : 32002
                }
            }
]
        },"crmmodules" :  {
            "marketing" : true, "sales" : true, "service" : true
        }
    }
]
}

Oh heads up Im using Jersey 1.18 because I want to deploy it to Oracle Java Cloud Service, if your using Jersey 2.x I believe the setSerializationInclusion method has changed..

Extending SaaS with PaaS free eLearning lectures

Mon, 2014-10-13 16:17

Hey all,

Over the last 4 months I've been working with some of my US friends to create a eLearning version of the PTS SaaS extending PaaS workshop I co-wrote....., Well the time has come and we've published the first 4 eLearning seminars, and I'm sure there will be more coming.

Check em out and let me know what you think and what other topics need to be covered.

https://apex.oracle.com/pls/apex/f?p=44785:24:0::::P24_CONTENT_ID,P24_PREV_PAGE:10390,24

Generating Sales Cloud Proxies using Axis? Getting errors?

Thu, 2014-10-09 11:40

If your generating SOAP proxies using Apache Axis/2 you may find yourself hitting strange errors.. Whats even stranger is that you can generate proxies using JDeveloper and it works fine in tooling like SOAPUI.. Well help is at hand..

The most common error is

IWAB0399E Error in generating Java from WSDL:  java.lang.RuntimeException: Unknown element _value

I'm not sure if this is a bug in Fusion Sales Clouds base tech (ADFBC SDOs) or a bug in Apache Axis but there is a workaround and engineering are looking into this.

For a workaround you have two options

  1. Use adb binding and set the flag –Eosv to turn off strict validation.
  2. Use JDK xjc command to generate the JAXB classes:
  3. e.g. xjs -wsdl http://<salescloudsoapendpoint/opptyMgmtOpportunities/OpportunityService?WSDL

Enjoy and let me know if this works for you :-) 

 

Angelo 

Pages