Oracle https://www.avioconsulting.com/taxonomy/term/365 en How to Update Oracle SOA 11g Timeouts https://www.avioconsulting.com/blog/how-update-oracle-soa-11g-timeouts <div class="avio-content"> <div class="page-title"> <div class="lead-image"> <div> <div>Blog Lead Image</div> <div> <img src="/sites/default/files/2019-05/pexels-photo-1661004.jpeg" width="1880" height="1030" alt="Team" typeof="foaf:Image" /> </div> </div> <div class="dark-overlay"></div> </div> <div class="text-overlay"> <div class="container"> <div class="row"> <div class="col-sm-12"> <div><h2> <a href="/blog/how-update-oracle-soa-11g-timeouts" hreflang="en">How to Update Oracle SOA 11g Timeouts</a> </h2> </div> </div> </div> </div> </div> </div> <div class="main-content"> <div class="container"> <div class="row"> <div class="col-sm-12 node-body"> <div> <div><p dir="ltr">Imagine your SOA/BPM application is consuming a service (internal or third party) that takes more than 5 minutes to reply, which is more than the default JTA timeout. What would happen in this situation? The result is a faulted instance.<br />  </p> <p dir="ltr">Last month at a <a href="http://www.oracle.com/us/technologies/bpm/suite/overview/index.html">Oracle BPM</a> project, we faced a similar situation. After doing some research, we realized that not only do you have to update the EJBs or JTA timeouts, but there are also several other timeouts to tweak. In fact, six different timeouts need to be updated. Five of them related to the <a href="https://www.oracle.com/middleware/technologies/soasuite.html">Oracle SOA Suite</a>, plus the DB timeout. Here’s an overview of the 6 timeouts that we had to update and how to do so!<br />  </p> <h2>Web Service binding timeout</h2> <p dir="ltr">First, you need to identify all composites involved with the long-running service. This will include the composites where the service is called, and the composites calling these composites. Then, in each composite go to the source view and add the following properties to the web service binding (tag &lt;binding.ws/&gt;):<br />  </p> <ul><li>oracle.webservices.httpConnTimeout (milliseconds)</li> <li>oracle.webservices.httpReadTimeout (milliseconds)</li> <li>oracle.webservices.local.optimization (false)</li> </ul><p dir="ltr"> </p> <p class="text-align-center"><b id="docs-internal-guid-d822e284-7fff-586f-e223-99d2693b8acd"><img height="203" src="https://lh3.googleusercontent.com/-sLb4LCfehuS86Im8xOfQlI39MnxOA2TDXCB3hqNOCekZlYjXO5SBaj42OMDq0BN12wooR4ug93ki_CzWlo6P7ys76b_58Wm8Vb0j78Tu4EjhK4MBQVg89zMbIHj-4FpJNUpWeK3" width="876" /></b></p> <p dir="ltr">Local optimization is enabled by default in SOA Suite to optimize synchronous calls between BPEL processes deployed on the same container. We need to disable the local optimization, otherwise, the HTTP timeouts won't be considered.<br />  </p> <h2 class="text-align-justify">BPEL timeout </h2> <p dir="ltr">Set the property "SyncMaxWaitTime" (value is in seconds). Go to the Enterprise Manager, then in the navigation menu on the left, expand the "SOA" folder and click on the "soa-infra (&lt;SOA server name&gt;)" item.<br />  </p> <p class="text-align-center"><b id="docs-internal-guid-9a9e4fea-7fff-ebd9-0623-203615ac896b"><img height="202" src="https://lh4.googleusercontent.com/vWI6pew8GrYvA2Dfq10tCmIANi72_Sl8aiQu9fCXx7TQct8pAnZul7mFA4MF8ywJvxZcReVIlr2lgdibuDPx8jzgilIY_pnBxpD0fIkwApO1I0fpXZnS8F4-sw1L_RBqdPGHn4ZF" width="295" /></b></p> <p dir="ltr"> </p> <p dir="ltr">In the details page, expand the "SOA Infrastructure" dropdown. Then go to "SOA Administration" and finally, click on "BPEL Properties" option.</p> <p dir="ltr"> </p> <p class="text-align-center"><b id="docs-internal-guid-e26fafac-7fff-e138-b9a3-738cb2a3572b"><img height="435" src="https://lh4.googleusercontent.com/tiHNvixUgG9imov5ENzv10LvO8dFveZnDRs0k-k5YOx1_bIdxq4yDnrSbHoAU7062cI209U7lWumQta1vilvi5v41gGSesd1UFJiS7Vwyyod4zpGPIe-27Og5P_XOTM0eRVVjpG9" width="349" /></b></p> <p dir="ltr"> </p> <p dir="ltr">The "BPEL Service Engine Properties" page is shown. From there, click on the link "More BPEL Configuration Properties..."</p> <p dir="ltr"> </p> <p class="text-align-center"><b id="docs-internal-guid-8ee2c1e6-7fff-509d-975b-90a749b20219"><img height="289" src="https://lh4.googleusercontent.com/rnXbo7bVmUrwPBpJghIcQ_HW7doPgDEd4n2n-bP0bA5QCSS13I5tDxhmK42sH3iwYb4gXBoyOmO0yH4NepNSI_By6OzC7sgoxQedRUiqSiNxcbD7SiWPTXwRr0NdueBGOcIJOfhW" width="378" /></b></p> <p dir="ltr"> </p> <p dir="ltr">In the "Application Defined MBeans" page, you can update the value of "SyncMaxWaitTime" property<b id="docs-internal-guid-430238a2-7fff-d535-0243-ddc95f5b345d">– </b>keep in mind this value is in seconds.</p> <p dir="ltr"> </p> <p class="text-align-center"><b id="docs-internal-guid-92593fe7-7fff-4b4e-1745-8a3972017a1b"><img height="233" src="https://lh4.googleusercontent.com/WvaTqupGfHOsfI-uTOCnN7d_36RXS9hZS-VFZqaNuRZsXvAey789btmyVVbZlMftKZ2rTvDD1c-VHwBGzCZWB5CPKB20xh7tTr5JNstRANLgzpkvWH7yP0Qh69tP9z0vpy2-AW8P" width="802" /></b></p> <p dir="ltr"> </p> <h2>EJB's timeouts</h2> <p dir="ltr">Open the WebLogic console, then go to Deployments, find "soa-infra" and expand it by clicking on the plus sign. <br />  </p> <p dir="ltr">You have to update the timeout of the following EJB's:</p> <ul><li class="text-align-justify">BPELEngineBean</li> <li class="text-align-justify">BPELDeliveryBean</li> <li class="text-align-justify">BPELActivityManagerBean</li> <li class="text-align-justify">BPELServerManagerBean</li> <li class="text-align-justify">BPELProcessManagerBean</li> <li class="text-align-justify">BPELInstanceManagerBean</li> <li class="text-align-justify">BPELFinderBean</li> </ul><p class="text-align-justify"> </p> <p dir="ltr">Typically, the way to update the timeout of these EJB's would be clicking on the name, then in the Configuration tab, increasing the value of "Transaction Timeout" and finally, activating the changes. But first, make sure to stop all SOA Servers before doing that. According to <a href="https://support.oracle.com/epmos/faces/DocumentDisplay?_afrLoop=420555745794054&amp;parent=EXTERNAL_SEARCH&amp;sourceId=PROBLEM&amp;id=1271369.1&amp;_afrWindowMode=0&amp;_adf.ctrl-state=gux9xo6w_4">Oracle Support Doc ID 1271369.1</a>, if you update these BPEL EJB's while the SOA servers are running, your SOA Infra won't start up anymore and you'll experience the pain.</p> <p dir="ltr">If you did update the transaction timeouts with the SOA Servers running and now your SOA environment is broken, don’t fret. Try the following steps to resolve the issue:</p> <ul><li>Shutdown the entire domain.</li> <li>In a console, go to the &lt;your domain folder&gt;/servers/AminServer and rename the "tmp" folder to "tmp_OLD".</li> <li>Start the Admin Server and then the SOA Servers.</li> </ul><p dir="ltr">This should bring your SOA environment back to life. <br />  </p> <h2>JTA Timeout</h2> <p dir="ltr">In the WebLogic console, go to the Domain Structure panel and click on the domain name. Then in the domain settings page, go to "Configuration" and then "JTA" tab. From there, you can update the value of "Timeout Seconds" property.<br />  </p> <p class="text-align-center"><b id="docs-internal-guid-04cef1cf-7fff-209d-0b18-f4933c5b83a7"><img height="259" src="https://lh6.googleusercontent.com/IeMzCCplRJunrh4f3oCc9j7t9E9yWDw73T7MEnF-jCljMgIP0Q1NBrwr7WjkUP_jzTRdBAgl1KH5gb4DJk4pGiVAjyuWvXKY9rzK89pY1ykbfdaEEq7jI9Ful4Fjnunig0LDtSbz" width="624" /></b></p> <p class="text-align-center"> </p> <h2 class="text-align-justify">SOADataSource XA Transaction Timeout</h2> <p class="text-align-justify">In the WebLogic console, go to the Domain Structure panel, then "Services" and then "Data Sources". Find "SOADataSource" on the list and click it. Select the "Configuration" tab and then "Transaction" tab. From there, make sure that "Use XA Data Source Interface" is checked and "XA Transaction Timeout" is set to zero (which means the WebLogic Server Transaction Manager passes the global WebLogic Server transaction timeout in seconds).</p> <p dir="ltr"> </p> <p class="text-align-center"><b id="docs-internal-guid-a871cb7a-7fff-d747-2330-f92945db2a28"><img height="319" src="https://lh5.googleusercontent.com/qCMR1jrhLjXX_RC6iGbznnjBQ2r46oWZz3cGpFrNeXXafSx0-vrkDXj8ojBaugE7LUEn809goKxuTv5JXS2O3bcit7ACrEdGT7Ns31n-c460vBaoB_jvDF2nfLJzjVi5T-Gyklya" width="504" /></b></p> <p dir="ltr"> </p> <h2 class="text-align-justify">Database distributed transaction timeout</h2> <p class="text-align-justify">Last but not least, update the DB transaction timeout. For that, ask the DBA to help you to update the DISTRIBUTED_LOCK_TIMEOUT value of your Oracle Database.</p> <p dir="ltr"> </p> <p dir="ltr">Having faulted instances can be extremely frustrating and time-consuming if you don't know how to update them efficiently. So, next time when your <a href="http://www.oracle.com/us/technologies/bpm/suite/overview/index.html">Oracle BPM</a> project faces the same situation, I hope that this how-to guide will help you identify what is causing the issue and you'll be able to quickly update the timeouts and resolve the issue!</p> </div> </div> </div> </div> </div><div class="container comment-container"> <div class="text-align-center"><h2>Join the Conversation</h2> </div> <div class="row"> <div class="col-sm-12"> <drupal-render-placeholder callback="comment.lazy_builders:renderForm" arguments="0=node&amp;1=744&amp;2=comment_node_blog&amp;3=comment_node_blog" token="Zrpzy5EK5SRj9Kk1dGdUmyiZS3Q8mJjgOMFmAXfSVo0"></drupal-render-placeholder> </div> </div> </div> <div class="container"> <div class="row"> <div class="col-sm-12 blog-tags"> <div> <div><a href="/taxonomy/term/365" hreflang="en">Oracle</a></div> <div><a href="/blog/categories/bpm" hreflang="en">BPM</a></div> <div><a href="/blog/categories/soa" hreflang="en">SOA</a></div> </div> </div> </div> </div> <div><drupal-render-placeholder callback="Drupal\block\BlockViewBuilder::lazyBuilder" arguments="0=views_block__blogs_block_4&amp;1=default&amp;2=en" token="jBjf0n8iki9sjPwElNYA4B92vVETYVFMv7O9pm9FdHQ"></drupal-render-placeholder></div> <div> <div>About the Author</div> <div></div> </div> </div> </div> Wed, 01 May 2019 22:47:50 +0000 Sebastian Marucci 744 at https://www.avioconsulting.com https://www.avioconsulting.com/blog/how-update-oracle-soa-11g-timeouts#comments Documentation - You'll Thank Yourself Later https://www.avioconsulting.com/blog/documentation-youll-thank-yourself-later <div class="avio-content"> <div class="page-title"> <div class="lead-image"> <div> <div>Blog Lead Image</div> <div> <img src="/sites/default/files/default_images/network-pen-blog-3_0.jpg" width="2000" height="1333" alt="Avio Consulting" typeof="foaf:Image" /> </div> </div> <div class="dark-overlay"></div> </div> <div class="text-overlay"> <div class="container"> <div class="row"> <div class="col-sm-12"> <div><h2> <a href="/blog/documentation-youll-thank-yourself-later" hreflang="en">Documentation - You&#039;ll Thank Yourself Later</a> </h2> </div> </div> </div> </div> </div> </div> <div class="main-content"> <div class="container"> <div class="row"> <div class="col-sm-12 node-body"> <div> <div><p>Documentation. Hardly anybody wants to write it, but it is one of the most important deliverables in a software project. Without documentation, it becomes very difficult to understand why things were done the way they were and if the project is operating as expected. </p> <p>I have joined several projects where there was a lack of documentation. Sometimes you’ll be blessed with comments, but, in my experience, the only comments to be found are commented-out code. In Oracle SOA/BPM projects and Mulesoft projects, documentation is even rarer than in other projects. I’m not perfect - I’ve contributed to this problem as well. I’ve completed some code for a project and then, a month later, had to come back to the same code and figure out what the code is supposed to be doing in order to make modifications. Many developers will tell you the “code is self-documenting”, but the code doesn't show you the intent. In order to ascertain intent, one must consult documentation or requirements, and it isn’t always clear which code fulfills which requirements.</p> <p><img alt="Commented Code" data-entity-type="file" data-entity-uuid="43364b49-d141-484b-b9f0-16cc483e2808" height="131" src="/sites/default/files/inline-images/Screen%20Shot%202019-01-07%20at%201.20.40%20PM.png" width="655" class="align-left" /></p> <p> </p> <p> </p> <p> </p> <p> </p> <p> </p> <p>We are all better than this!</p> <p> </p> <p><img alt="Mulesoft Notes Field" data-entity-type="file" data-entity-uuid="c0233439-8a75-4080-9dba-1d4fc57a2f2e" height="330" src="/sites/default/files/inline-images/Screen%20Shot%202019-01-04%20at%203.47.00%20PM.png" width="652" /><img alt="Oracle Documentation" data-entity-type="file" data-entity-uuid="99c29f98-1b67-41ac-a57a-955eb78665b5" height="256" src="/sites/default/files/inline-images/Screen%20Shot%202019-01-04%20at%203.44.24%20PM.png" width="505" /></p> <p>Save your colleagues and yourself some unnecessary time and document your code. It is possible to figure out what a chunk of code is supposed to do, but it takes much less time to read a sentence that says what the code is meant to do. The comment doesn’t have to be extremely detailed, it just needs to express the general idea. Put a comment in your Java code, fill in the Description field in your BPMN or BPEL activities, or write something in that Notes attribute on your Mulesoft message processors. Don’t leave the comments blank - you will thank yourself later!</p> </div> </div> </div> </div> </div><div class="container comment-container"> <div class="text-align-center"><h2>Join the Conversation</h2> </div> <div class="row"> <div class="col-sm-12"> <drupal-render-placeholder callback="comment.lazy_builders:renderForm" arguments="0=node&amp;1=738&amp;2=comment_node_blog&amp;3=comment_node_blog" token="Xxgpqfan-pc6CC8yR5FIbxX217LJ64swBJCwEYY6THI"></drupal-render-placeholder> </div> </div> </div> <div class="container"> <div class="row"> <div class="col-sm-12 blog-tags"> <div> <div><a href="/blog/categories/adf" hreflang="en">ADF</a></div> <div><a href="/blog%3Fbid%3D332" hreflang="en">MuleSoft</a></div> <div><a href="/taxonomy/term/365" hreflang="en">Oracle</a></div> <div><a href="/blog/categories/bpm" hreflang="en">BPM</a></div> <div><a href="/blog/categories/soa" hreflang="en">SOA</a></div> <div><a href="/blog/categories/other" hreflang="en">Other</a></div> </div> </div> </div> </div> <div><drupal-render-placeholder callback="Drupal\block\BlockViewBuilder::lazyBuilder" arguments="0=views_block__blogs_block_4&amp;1=default&amp;2=en" token="jBjf0n8iki9sjPwElNYA4B92vVETYVFMv7O9pm9FdHQ"></drupal-render-placeholder></div> <div> <div>About the Author</div> <div></div> </div> </div> </div> Mon, 07 Jan 2019 19:38:32 +0000 Adam Mead 738 at https://www.avioconsulting.com https://www.avioconsulting.com/blog/documentation-youll-thank-yourself-later#comments Provisioning Oracle API Platform Gateway Nodes using Terraform and Ansible on AWS https://www.avioconsulting.com/blog/provisioning-oracle-api-platform-gateway-nodes-using-terraform-and-ansible-aws <div class="avio-content"> <div class="page-title"> <div class="lead-image"> <div> <div>Blog Lead Image</div> <div> <img src="/sites/default/files/default_images/network-pen-blog-3_0.jpg" width="2000" height="1333" alt="Avio Consulting" typeof="foaf:Image" /> </div> </div> <div class="dark-overlay"></div> </div> <div class="text-overlay"> <div class="container"> <div class="row"> <div class="col-sm-12"> <div><h2> <a href="/blog/provisioning-oracle-api-platform-gateway-nodes-using-terraform-and-ansible-aws" hreflang="en">Provisioning Oracle API Platform Gateway Nodes using Terraform and Ansible on AWS</a> </h2> </div> </div> </div> </div> </div> </div> <div class="main-content"> <div class="container"> <div class="row"> <div class="col-sm-12 node-body"> <div> <div><h1 style="margin:20pt 0pt 0pt"><span style="line-height:107%">Provisioning Oracle API Platform Gateway Nodes using Terraform and Ansible on AWS</span></h1> <p style="margin:10pt 0pt 0pt"><span style="line-height:200%">When using Oracle Autonomous API Platform, an API gets deployed to a logical gateway.  The logical gateway consists of one or more nodes which are instances of the runtime, installed on physical machines, virtual machines, or cloud infrastructure.  The gateway nodes handle the processing of the API requests, but a load balancer is still required to distribute traffic between the nodes.  When performance becomes an issue, more nodes can be added to increase throughput.  Providing an automated way to manage nodes ensures consistency of configurations and the ability to easily add and remove nodes.</span></p> <p style="margin:1pt 0pt 0pt"> </p> <p style="margin:1pt 0pt 0pt"><span style="line-height:200%">The gateway nodes can be installed on-premise or in the cloud, and are not restricted to the Oracle cloud.  This allows for customers who are already using AWS to host their micro-services, to use Oracle's API Platform platform to be able to monitor and expose their APIs on a central location.  The API Platform portal, provides a central location deploy, activate, deprecate, and secure APIs while having complete visibility of the usages and KPI monitoring.</span></p> <p><img alt="APICS Overview" data-entity-type="file" data-entity-uuid="fb5b58e1-2ae3-4c38-a579-9340cb1b6553" src="/sites/default/files/inline-images/APICS_Overview.png" /></p> <p style="margin:1pt 0pt 0pt"><span style="line-height:200%">In this blog, I'll describe how I've created an automated way to provision, configure, and register new API gateway nodes, running on Amazon EC2 into the API Platform using Terraform and Ansible.</span></p> <p style="margin:1pt 0pt 0pt"> </p> <p style="margin:1pt 0pt 0pt"><span style="line-height:200%">Technologies used (and links for more help):</span></p> <ul><li><a href="https://docs.oracle.com/en/cloud/paas/api-platform-cloud-um/apfad/">APICS</a>: This the Oracle API Platform Cloud Service</li> <li><a href="https://aws.amazon.com/">AWS</a>: Amazon Web Services - This will be used to host our EC2 instances and application load balancer</li> <li><a href="https://www.terraform.io/">Terraform</a>: A tool to write, plan, and create infrastructure as code. This is used to provision the network setup and create the AWS compute instances</li> <li><a href="https://www.ansible.com/">Ansible</a>: A tool to provide simple IT automation, including application deployment, configuration, and orchestration</li> </ul><h2>Manual Provisioning, Configuring and Registering a new node</h2> <p style="margin:10pt 0pt 0pt"><span style="line-height:200%">Likely the most time-consuming effort in adding new nodes to the gateway is in the provisioning of the server, whether it is virtual or physical.  The servers need to create, networking needs to be assigned, and a load balancer defined, pointing to each of the servers provisioned.  I'm not going to go into details on this (as it is automated later), but anyone that has had to do this, understands that it is very prone to user errors and can be a very tedious process.</span></p> <p style="margin:1pt 0pt 0pt"> </p> <p style="margin:1pt 0pt 0pt"><span style="line-height:200%">Once the server has been provisioned, and the networking configured, software must be installed.  With any new server instance, software packages must be installed or updated, including the latest Java JDK.  Once base packages have been configured, the actual API Gateway installation files must be downloaded, unpacked, installed, configured to join the gateway.  </span></p> <p style="margin:1pt 0pt 0pt"> </p> <p style="margin:1pt 0pt 0pt"><span style="line-height:200%">Although not overly complicated, the typical timeframe for all of this could be days or weeks for most organizations.  So why can't this be automated?  Well, of course, it can!</span></p> <h2>Automating it all</h2> <p style="margin:10pt 0pt 0pt"><span style="line-height:200%">In this blog we will be using AWS EC2 instances, however, OCI could also be used because Terraform has providers for many cloud platforms.  Terraform is being used to provision the infrastructure and Ansible used to configure the software.   The provided script assumes that the logical gateway (DEV-Gateway) has already been created, and is waiting for nodes to join.   This step could be automated with the management API, however, in this example, the logical gateway already exists.</span></p> <p style="margin:1pt 0pt 0pt"><span style="line-height:200%">This code is available on <a href="https://github.com/avioconsulting/apics-terraform-ansible">Github</a>.</span></p> <h3>Terraform</h3> <p style="margin:10pt 0pt 0pt"><span style="line-height:200%">Using Terraform and the <a href="https://www.terraform.io/docs/providers/aws/">AWS API</a> we will create the desired infrastructure, which includes 2 compute nodes, a load balancer, and the networking required, including private and public subnets, and security roles.</span></p> <p style="margin:1pt 0pt 0pt"> </p> <p style="margin:1pt 0pt 0pt"><span style="line-height:200%">If you've never used Terraform before, see the <a href="https://www.terraform.io/intro/getting-started/install.html">getting started guide</a>.  You can then take a look at the source code in Github to review the exact configuration and parameters that I've used.</span></p> <p><img alt="AWS Network Diagram" data-entity-type="file" data-entity-uuid="be38048d-5d5d-449d-8924-24caca9ebf0f" src="/sites/default/files/inline-images/AWSNetworkDiagram.png" width="500" /></p> <p style="margin:1pt 0pt 0pt"><span style="line-height:200%">Below is the description of the modules that Terraform created.</span></p> <pre> <code>Terraform will perform the following actions: + module.compute.aws_instance.apics-node + module.compute.aws_key_pair.dev-key + module.compute.aws_security_group.apics-node + module.compute.aws_security_group_rule.apics-node-http + module.compute.aws_security_group_rule.apics-node-http-outbound + module.compute.aws_security_group_rule.apics-node-ssh + module.network.aws_eip.nat_eip + module.network.aws_internet_gateway.public-ig + module.network.aws_nat_gateway.nat_gw + module.network.aws_network_acl.private + module.network.aws_network_acl.public + module.network.aws_network_acl_rule.private-acl-egress-tcp + module.network.aws_network_acl_rule.private-acl-ingress-vpc + module.network.aws_network_acl_rule.public-acl-egress-tcp + module.network.aws_network_acl_rule.public-acl-ingress-tcp + module.network.aws_route.private-route-nat + module.network.aws_route.public-route-igw + module.network.aws_route_table.private-rtb + module.network.aws_route_table.public-rtb + module.network.aws_route_table_association.private-a + module.network.aws_route_table_association.private-b + module.network.aws_route_table_association.public-a + module.network.aws_route_table_association.public-b + module.network.aws_subnet.private-a + module.network.aws_subnet.private-b + module.network.aws_subnet.public-a + module.network.aws_subnet.public-b + module.network.aws_vpc.vpc Plan: 28 to add, 0 to change, 0 to destroy. ------------------------------------------------------------------------</code></pre> <h3 style="margin:20pt 0pt 0pt"><span style="line-height:107%">Ansible</span></h3> <p style="margin:10pt 0pt 0pt"><span style="line-height:200%">Ansible provides 'playbooks' which define a set of instructions that install and configure software.  There are other configuration management tools, such as Puppet and Chef that can accomplish the same, but for this example, Ansible is being used.  Check out the Ansible <a href="https://docs.ansible.com/ansible/2.5/user_guide/quickstart.html">quick start guide</a> if you've never written a playbook, it provides an easy way to consistently and quickly ensure new systems have exactly the same setup.</span></p> <p style="margin:1pt 0pt 0pt"> </p> <p style="margin:1pt 0pt 0pt"><span style="line-height:200%">Ansible playbooks are being invoked from Terraform after the creation of the compute instance.  These are used to configure the software running on the instance. </span></p> <p style="margin:1pt 0pt 0pt"> </p> <p style="margin:1pt 0pt 0pt"><span style="line-height:200%">For the gateway node installation, a configuration JSON file is required that contains some installation properties (location, gateway name, gateway id, listen address, etc).  This is automatically built by Terraform (see screenshot) with the outputs from the network and node creation and transferred to the remote system just before executing the apicsgateway playbook.</span></p> <pre> <code> # build gateway-props.json file... provisioner "file" { content = &lt;&lt;EOD { "nodeInstallDir" : "/opt/oracle/gateway", "logicalGateway" : "${var.logical-gateway}", "logicalGatewayId" : "${var.logical-gateway-id}", "gatewayNodeName" : "${var.gateway-name}-1", "managementServiceUrl" : "${var.management-service-url}", "listenIpAddress" : "${aws_instance.apics-node-1.private_ip}", "publishAddress" : "${aws_lb.apics-lb.dns_name}", "gatewayExecutionMode" : "${var.gateway-execution-mode}", "idcsUrl" : "${var.idcs-url}", "requestScope" : "${var.request-scope}", "prevInstallCleanupAction" : "clean" } EOD destination = "/home/ec2-user/local-gateway-props.json" connection { type = "ssh" user = "ec2-user" } } # install apics gateway provisioner "local-exec" { command = "ansible-playbook -i configure/aws_hosts1 configure/playbook-install-configure-join-apicsgatewaynode.yml" } }</code></pre> <p>During the install of the gateway node and the execution of the API Gateway install-configure-start-join command, there are several prompts for user input.  These prompts are handled by a module called 'pexpect'.  The module automatically reads the prompts and responds with the supplied values.</p> <pre> <code> - name: Call install-configure-start-join (takes a while ~8 min) become: false expect: command: "./APIGateway -f ../../local-gateway-props.json -a install-configure-start-join" chdir: "/opt/oracle/binaries/gateway/" timeout: 600 responses: 'Please enter user name for weblogic*' : "{{gateway_user}}" 'Password*' : - "{{gateway_user_pass}}" - "{{gateway_manager_pass}}" - "{{gateway_manager_runtime_pass}}" - "{{gateway_manager_runtime_pass}}" 'This action will now cleanup existing gateway*' : "y" 'Please enter gateway manager user*' : "{{gateway_manager_user}}" 'Please enter gateway manager client id*' : "{{client_id}}" 'Please enter gateway manager client secret*' : "{{client_secret}}" 'Please enter gateway manager runtime user*' : "{{gateway_manager_runtime_user}}" 'Please enter gateway manager runtime client id*' : "{{client_id}}" 'Please enter gateway manager runtime client secret*' : "{{client_secret}}" 'Do you want to add the grant to gateway runtime user*' : "y" 'Please enter gateway runtime user*' : "{{gateway_manager_runtime_user}}" 'Would you like to create-join instead*' : "y" creates: "/opt/oracle/gateway/GATEWAY_HOME"</code></pre> <p>The first playbook (playbook-install-jdk8.yml) installs a newer version of Java, and the second playbook (playbook-install-configure-join-apicsgatewaynode.yml) executes the following tasks to set up the instance:</p> <ul><li>Initialize variable to validate if the gateway node has been previously installed (checks for the install directory)</li> <li>Download the APIGateway archive</li> <li>Create directory (to unpack archive into)</li> <li>Unpack archive</li> <li>Fix ownership of unpacked files</li> <li>Cleanup archive</li> <li>Install pexpect (will need to assist gateway installer)</li> <li>Move configuration file (generated by terraform, and transferred earlier)</li> <li>Call install-configure-start-join on APIGateway install</li> <li>Retrieve the gateway node IDs using the management API</li> <li>Update state to Active using the management API</li> </ul><h3 style="margin:20pt 0pt 0pt"><span style="line-height:107%">Execution</span></h3> <p style="margin:10pt 0pt 0pt"><span style="line-height:200%">The actual execution takes about 12 minutes.  Not a very exciting video, but this creates the entire infrastructure required for 2 nodes, with all of the software installed, and executes the registration of the new instance into the API Platform.</span></p> <p style="margin:1pt 0pt 0pt"> </p> <p><iframe allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen="" frameborder="0" height="315" src="https://www.youtube.com/embed/gWmvn0vtEy4" width="560"></iframe></p> <p style="margin:1pt 0pt 0pt"><span style="line-height:200%">Below shows the 2 nodes registered and active.</span></p> <p><br /><img alt="DEV-Gateway" data-entity-type="file" data-entity-uuid="8a6f40fb-0a99-413d-ac4c-cf2cecca9c65" src="/sites/default/files/inline-images/DEV-Gateway.png" width="800" /></p> <h4 id="BLOG-AutomatingtheCreationofAPICSGatewayNodesusingTerraformandAnsibleonAWS-Usingtheservice">Using the service</h4> <p style="margin:10pt 0pt 0pt"><span style="line-height:200%">I followed the Oracle tutorial <a href="http://www.oracle.com/webfolder/technetwork/tutorials/obe/cloud/apics/implementing/implementing_apis.html" rel="nofollow">Implementing APIs</a> to build and deploy an API using APICS.</span></p> <p><img alt="Deploy API" data-entity-type="file" data-entity-uuid="64add8e0-13c7-474a-9f0a-bb619f7b834d" src="/sites/default/files/inline-images/DeployAPI.png" /></p> <p style="margin:1pt 0pt 0pt"><span style="line-height:200%">Below is the execution of the REST service from Postman.</span></p> <p><img alt="Postman APICS Response" data-entity-type="file" data-entity-uuid="f52c9b78-3edf-41dc-8137-56171863c0d1" src="/sites/default/files/inline-images/APICSResponse.png" /></p> <p style="margin:1pt 0pt 0pt"><span style="line-height:200%">The APICS Reporting chart of requests.</span></p> <p><img alt="Analytics" data-entity-type="file" data-entity-uuid="22c5a889-6906-44d5-a416-04be96cdd1bd" src="/sites/default/files/inline-images/Analytics.png" /></p> <p> </p> </div> </div> </div> </div> </div><div class="container comment-container"> <div class="text-align-center"><h2>Join the Conversation</h2> </div> <div class="row"> <div class="col-sm-12"> <drupal-render-placeholder callback="comment.lazy_builders:renderForm" arguments="0=node&amp;1=735&amp;2=comment_node_blog&amp;3=comment_node_blog" token="nUWVuKAIMqvGM7YCEryuW00ZRgaflZNgRw91hFC9FkU"></drupal-render-placeholder> </div> </div> </div> <div class="container"> <div class="row"> <div class="col-sm-12 blog-tags"> <div> <div><a href="/taxonomy/term/365" hreflang="en">Oracle</a></div> </div> </div> </div> </div> <div><drupal-render-placeholder callback="Drupal\block\BlockViewBuilder::lazyBuilder" arguments="0=views_block__blogs_block_4&amp;1=default&amp;2=en" token="jBjf0n8iki9sjPwElNYA4B92vVETYVFMv7O9pm9FdHQ"></drupal-render-placeholder></div> <div> <div>About the Author</div> <div></div> </div> </div> </div> Thu, 15 Nov 2018 18:30:14 +0000 Kevin and Adam 735 at https://www.avioconsulting.com https://www.avioconsulting.com/blog/provisioning-oracle-api-platform-gateway-nodes-using-terraform-and-ansible-aws#comments Oracle OpenWorld 2018 - 5 Things I Learned https://www.avioconsulting.com/blog/oracle-openworld-2018-5-things-i-learned <div class="avio-content"> <div class="page-title"> <div class="lead-image"> <div> <div>Blog Lead Image</div> <div> <img src="/sites/default/files/2018-11/20181024_083157_0_1.jpg" width="2886" height="755" alt="Oracle Red Carpet" typeof="foaf:Image" /> </div> </div> <div class="dark-overlay"></div> </div> <div class="text-overlay"> <div class="container"> <div class="row"> <div class="col-sm-12"> <div><h2> <a href="/blog/oracle-openworld-2018-5-things-i-learned" hreflang="en">Oracle OpenWorld 2018 - 5 Things I Learned</a> </h2> </div> </div> </div> </div> </div> </div> <div class="main-content"> <div class="container"> <div class="row"> <div class="col-sm-12 node-body"> <div> <div><p style="margin:1pt 0pt 0pt"><span style="line-height:200%">This was my first time at Oracle OpenWorld, and WOW.... Oracle really goes overboard.  They had massive banners and signs calling out the 'Oracle Autonomous Database Cloud', 'Self-Repairing Database', 'Innovative', it goes on and on.  They laid out a literal red carpet, covering all of Howard Street between 3rd and 4th streets.  It's just impressive to see.</span></p> <p style="margin:10pt 0pt 0pt"><span style="line-height:200%"><img alt="Oracle Red Carpet" data-entity-type="file" data-entity-uuid="e79caf05-7ad5-4365-837e-9b4788c0065e" src="/sites/default/files/inline-images/20181024_083157_1.jpg" /></span></p> <p style="margin:10pt 0pt 0pt"><span style="line-height:200%">But, I was here to learn.  Being an architect in the Integration realm (SOA, ICS, OIC, etc), I tried to focus on sessions that would pertain to me and hopefully learn a few new tricks.  There were tons of sessions on everything Oracle, but only a handful interested me.</span></p> <p style="margin:10pt 0pt 0pt"><span style="line-height:200%">Along with learning about the Oracle (and non-oracle) products, I was able to meet up with many great colleagues from outside the US that I haven't seen in a while, or only had the opportunity to communicate with through email or conferences calls.</span></p> <p style="margin:10pt 0pt 0pt"><span style="line-height:200%">Here is a small (I went to many sessions) breakdown of the ones I enjoyed.</span></p> <h2 style="margin:20pt 0pt 0pt"><span style="line-height:107%">Citizen Developer Self-Service Integration</span></h2> <p style="margin:1pt 0pt 0pt"><span style="line-height:200%">The self-service integration cloud is intended to 'empower the business user' by providing pre-built templates for application integrations.  The idea is that a business user can connect the applications they use every day to share data or trigger other applications when an event occurs.  These are not company wide integrations, but for a single user.  The scenario that was discussed involved connecting Gmail with Google Sheets.  When a business user creates a new contact in Gmail, that contact is immediately exported and added to a Google sheet.  This didn't seem like a very useful scenario, but I could see the data being sent to other applications, like creating the same contact in a different system.  </span></p> <p style="margin:10pt 0pt 0pt"><span style="line-height:200%">The self-service integration cloud is currently licensed separately, but based heavily on the OIC platform.  It looks very similar to OIC when building integrations.  If you have any experience using OIC, the self-service integration will feel right at home.  I'm always wary of when products are designed for the 'citizen developer' or 'business user' because these products typically have limited functionality (due to 'ease-of-use') or are actually harder than originally intended.Eduardo Chiocconi, Tuck Chang and Srikant Tirumalai did a great job demonstrating the features that have been developed and showed off some of the advanced use cases.  I'm looking forward to exploring some more of the available options with this new(ish) product!</span></p> <h2 style="margin:20pt 0pt 0pt"><span style="line-height:107%">The Future of Serverless Is Now: CI/CD for the Oracle Fn Project</span></h2> <p style="margin:1pt 0pt 0pt"><span style="line-height:200%">I spent quite a bit of time working with Leo Gonzalez from <a href="https://www.spsolutions.com.mx/en/">S&amp;P Solutions</a> on a previous engagement and was thrilled to reconnect with him at Oracle OpenWorld.  He and his colleague Rolando Carrasco presented on the simplicity of deploying Oracle functions and provided a quick live demo starting and deploying a hello world function (Hola Mundo for them!) in a few different programming languages.  These code sets were all changed during the demo and were all automatically deployed using a continuous integration pipeline.  I have had limited exposure to the Oracle function, however, the presentation piqued my interest, with its simplicity.  I'll have to go back and check it out myself.</span></p> <h2 style="margin:20pt 0pt 0pt"><span style="line-height:107%">DevOps in the Cloud with Oracle Developer Cloud Service</span></h2> <p style="margin:1pt 0pt 0pt"><span style="line-height:200%">Having some basic experience with DCS, I was interested to find what type of Hands-On Lab the Oracle team would come up with.  The lab, meant to take under an hour, was surprisingly thorough.  It had participants create a new project inside of DCS, initialize a GIT repository, create and assign development tasks, start a newsprint including development tasks, make a code change, create build triggers and a build pipeline, merge a feature branch, and watch it all get deployed.  Abhinav Shroff and Murtaza Amiji did a great job preparing and presenting the lab.</span></p> <h2 style="margin:20pt 0pt 0pt"><span style="line-height:107%">Serverless, the Future of the Cloud?</span></h2> <p style="margin:1pt 0pt 0pt"><span style="line-height:200%">I went to see Bert Ertman's present on serverless integrations.  After seeing an earlier presentation on Oracle functions, I was interested in what Bert had to say.  He provided some interesting points calling out a variety of options for serverless... Amazon Lambda is one of the most prevalent.  His presentation included a demo of using an event-based process, where the lambda function monitored an S3 bucket for images, and when a new image was uploaded, it would crop the image down to 100 x 100 pixels, and move to a different bucket.  His use case was for adding employee images taken from a camera or phone, and cropping them down to be used as a thumbnail in a profile picture was perfect for a serverless integration.  The processing power would only be used when necessary, and not require a company to keep an integration active, and only Pay As You Go (PAYGO).</span></p> <h2 style="margin:20pt 0pt 0pt"><span style="line-height:107%">Oracle Integration Cloud Best Practices Panel: Transforming to Hybrid Cloud</span></h2> <p style="margin:1pt 0pt 0pt"><span style="line-height:200%">This presentation was based on actual implementations from 3 different companies.These companies included Minnkota Power Cooperative, ICU Medical, and GE.  There was a short presentation by each of the companies, followed by some Q&amp;A.  With product management on hand, some great insight into new features was discussed to make the integration lifecycle easier, including whole environment cloning (all integrations, connections, lookups, etc).  There were discussions about best-practices of how to promote integrations (shameless plug - <a href="https://www.avioconsulting.com/blog/avio-ics-maven-plugin">AVIO Maven ICS Plugin</a>) but also questions regarding the storing of integrations (and other artifacts) into a code repository for safe keeping.</span></p> <p style="margin:10pt 0pt 0pt"><span style="line-height:200%">When connecting OIC to on-prem applications, a connectivity agent is used.  There were some questions and concerns regarding the stability of this, but Product Management indicated that the new version added HA, a smaller footprint, auto-updating, and several bug fixes.  Be on the look for this if you are connecting on-prem applications to your cloud applications.</span></p> </div> </div> </div> </div> </div><div class="container comment-container"> <div class="text-align-center"><h2>Join the Conversation</h2> </div> <div class="row"> <div class="col-sm-12"> <drupal-render-placeholder callback="comment.lazy_builders:renderForm" arguments="0=node&amp;1=732&amp;2=comment_node_blog&amp;3=comment_node_blog" token="2Wsx9DKhokDpl41IZAv3FPO6eZrkXDr8eHGT2Yh6N0U"></drupal-render-placeholder> </div> </div> </div> <div class="container"> <div class="row"> <div class="col-sm-12 blog-tags"> <div> <div><a href="/taxonomy/term/365" hreflang="en">Oracle</a></div> </div> </div> </div> </div> <div><drupal-render-placeholder callback="Drupal\block\BlockViewBuilder::lazyBuilder" arguments="0=views_block__blogs_block_4&amp;1=default&amp;2=en" token="jBjf0n8iki9sjPwElNYA4B92vVETYVFMv7O9pm9FdHQ"></drupal-render-placeholder></div> <div> <div>About the Author</div> <div></div> </div> </div> </div> Thu, 01 Nov 2018 14:12:37 +0000 Kevin King 732 at https://www.avioconsulting.com https://www.avioconsulting.com/blog/oracle-openworld-2018-5-things-i-learned#comments Using Oracle BPEL Direct Bindings in Java https://www.avioconsulting.com/blog/using-oracle-bpel-direct-bindings-java <div class="avio-content"> <div class="page-title"> <div class="lead-image"> <div> <div>Blog Lead Image</div> <div> <img src="/sites/default/files/default_images/network-pen-blog-3_0.jpg" width="2000" height="1333" alt="Avio Consulting" typeof="foaf:Image" /> </div> </div> <div class="dark-overlay"></div> </div> <div class="text-overlay"> <div class="container"> <div class="row"> <div class="col-sm-12"> <div><h2> <a href="/blog/using-oracle-bpel-direct-bindings-java" hreflang="en">Using Oracle BPEL Direct Bindings in Java</a> </h2> </div> </div> </div> </div> </div> </div> <div class="main-content"> <div class="container"> <div class="row"> <div class="col-sm-12 node-body"> <div> <div><p>This blog contains best practices for interfacing Java to external systems through Oracle BPEL components. Java will often be used to integrated functionality within the SOA framework since the framework allows wiring of Java code in order to perform various operations during human task assignment, and execution, as an example. And since these Java classes are embedded in the framework, and these classes may need to pull data from databases, Active Directory, REST services, WSDLs, etc., what is the best way to do this? You guess it: Direct Bindings.</p> <p>Why use direct bindings? First of all, a direct binding creates a simple RMI interface between Java code and a BPEL process. Besides the speed and efficiency one gets from RMI, using direct bindings leverages the capabilities already available within the SOA framework. There’s no need to go outside the SOA framework to get assignment data (in this example) from a database or other data source. Using SOA libraries, BPEL and SOA adapters everything needed is already available.</p> <p>Note that our use case has to do with implementing a very specialized version of role or parameter-based team assignments. Another assignment strategy is give here for <a href="https://www.avioconsulting.com/blog/creating-parametric-roles-using-business-rules">creating parametric roles using business rules</a>. However there are many other use cases that can be applied that don't have to do with assignments at all. Dynamic Bindings can and should be used whenever you want to interact with BPEL code from within Java.</p> <h2>Design by Interface First</h2> <p>The first step is to create an interface that will be used between the BPEL process and Java code. In this blog we will implement an interface that will be used to return a list of assignments for a given work team. The work team will be determined from the project the team is working on and other project properties such as the work area and activity type. The work team will contain a list of BPM application roles or a particular individual in a role. </p> <h3>Input Requirements</h3> <ul><li>projectId - string</li> <li>workArea - string  </li> <li>activityType - string</li> </ul><h3>Output Requirements</h3> <p>The output will be a list of assignments. Since the task assignment may contain direct assignments or role-based assignments, this will support both.</p> <p>    List of Assignments</p> <ul><li>assignment - string</li> <li>type - string</li> </ul><h3>Example Interface Schema</h3> <p> </p> <p style="font-size: 15px;background-color: #EFEFEF">&lt;?xml version="1.0" encoding="UTF-8"?&gt;<br /> &lt;schema xmlns:tns="<a href="http://xmlns.oracle.com/default/DynamicTaskAssignment/GetProjectTaskAssignments">http://xmlns.oracle.com/default/DynamicTaskAssignment/GetProjectTaskAss…</a>"<br />         targetNamespace="<a href="http://xmlns.oracle.com/default/ynamicTaskAssignment/GetProjectTaskAssignments">http://xmlns.oracle.com/default/ynamicTaskAssignment/GetProjectTaskAssi…</a>"<br />         xmlns="<a href="http://www.w3.org/2001/XMLSchema">http://www.w3.org/2001/XMLSchema</a>"&gt;<br />  &lt;element name="process"&gt;<br />     &lt;complexType&gt;<br />        &lt;sequence&gt;<br />           &lt;element name="projectId" type="string"/&gt;<br />           &lt;element name="processActivityKey" type="string"/&gt;<br />           &lt;element name="workAread" type="string"/&gt;<br />      &lt;/sequence&gt;<br />     &lt;/complexType&gt;<br />  &lt;/element&gt;<br />  &lt;element name="processResponse"&gt;<br />      &lt;complexType&gt;<br />          &lt;sequence&gt;<br />               &lt;element name="dynamicRoleNamesList" type="tns:DynamicRoleNamesListType"/&gt;<br />          &lt;/sequence&gt;<br />       &lt;/complexType&gt;<br />  &lt;/element&gt;<br />  &lt;complexType name="DynamicRoleNamesListType"&gt;<br />        &lt;sequence&gt;<br />             &lt;element name="dynamicRoleName" type="tns:DynamicRoleNameType" minOccurs="0" maxOccurs="unbounded"/&gt;<br />         &lt;/sequence&gt;<br />  &lt;/complexType&gt;<br />  &lt;complexType name="DynamicRoleNameType"&gt;<br />      &lt;sequence&gt;<br />            &lt;element name="assignment" type="string"/&gt;<br />             &lt;element name="type" type="tns:AssignmentTypes"/&gt;<br />       &lt;/sequence&gt;<br />  &lt;/complexType&gt;<br />  &lt;simpleType name="AssignmentTypes"&gt;<br />         &lt;restriction base="string"&gt;<br />             &lt;enumeration value="USER"/&gt;<br />             &lt;enumeration value="APPLICATION_ROLE"/&gt;<br />         &lt;/restriction&gt;<br />     &lt;/simpleType&gt;<br /> &lt;/schema&gt;</p> <h3>The BPEL Process And Direct Binding</h3> <p> </p> <p>Now we create the BPEL process and edit the schema template created when the BPEL process is created. This screen shot shows the BPEL creation wizard. Here we are creating a BPEL process, called GetDynamicAssignment in a composite called DynamicAssignments. This has to be a synchronous process, and we will not be needing it to be exposed as a SOAP service, so the check-box can be cleared.</p> <p><img alt="BPEL Process Creation Wizard" data-entity-type="file" data-entity-uuid="5edadc3a-0a31-44c5-b8ef-d46e8fd403e7" height="442" src="/sites/default/files/inline-images/DirectBindings_create_bpel.png" width="552" /></p> <p>Although we will not be using it as a SOAP service, you may want to create it with a SOAP service for testing purposes. Below, we will create it without the SOAP Service, since the creation of the BPEL process will generate the WSDL and message schemas we need in either scenario. </p> <p><br /> Please note: Testing your BPEL process without a SOAP service may be an issue. You may want to wrap this code with another BPEL process and expose it as a web service, or don’t replace the SOAP service with a direct binding until you are finished testing it. When you are ready, you can delete the  SOAP service (or Direct Binding service) and replace it with one or the other as you test it or interact with it via Java. The following images shows how this can be done.</p> <p> </p> <p><img alt="Deleting SOAP Service or Direct Binding" data-entity-type="file" data-entity-uuid="61ef417f-7e0a-4880-a5ca-523706c13aea" height="502" src="/sites/default/files/inline-images/DirectBindings_del_wsdll.png" width="553" /></p> <p><br /> Next we create the direct binding (or web service interface) by dragging a new direct binding object over from the component pallet to the Exposed Service region of the composite editor. </p> <p><img alt="Creating Direct Binding From Component Pallet" data-entity-type="file" data-entity-uuid="eaabfecc-b0eb-4cbb-8d5d-541ecba4b4e7" height="234" src="/sites/default/files/inline-images/DirectBindings_createBinding.png" width="495" /></p> <p>The direct binding creation wizard will pop up, and you can enter the name of the direct binding service and reference the BPEL wsdl, GetDynamicAssigment.wsdl, created during the BPEL process creation step above.</p> <p><img alt="Direct Binding Creation Wizard" data-entity-type="file" data-entity-uuid="d90af6e8-4407-49e5-8a94-aa398ed8de03" height="495" src="/sites/default/files/inline-images/DirectBindings_create_bpel_0.png" width="619" /></p> <p>After you click ok, you will need to link the direct binding to the BPEL process using the partner link already generated during BPEL process creation.</p> <p><img alt="Linking to the BPEL Process" data-entity-type="file" data-entity-uuid="845589b1-4ffa-47cf-aa97-e42d46b972f6" height="387" src="/sites/default/files/inline-images/DirectBindings_attachBinding.png" width="546" /></p> <p>We now have a BPEL process that you can use within Java to leverage any service adapters available, such as for a database or web service. For our use case, the team assignments are stored in a database, so we will edit the template schema created for the BPEL process and use a database adapter to pull data from team assignments tables based on the project ID, work area and process-type inputs. This is basic SOA implementation, so details are not provided here.  </p> <p> </p> <p><img alt="BPEL Process Shell" data-entity-type="file" data-entity-uuid="58324474-8168-483d-ba27-e648d4a3e37d" height="385" src="/sites/default/files/inline-images/DirectBindings_bpel.png" width="543" /></p> <p><br /> The next thing we will describe is how to call invoke this service and marshal data into the request and back out of the response using JAXB classes and Oracle’s SOA Management API.</p> <h2>Java Code</h2> <p>This section describes the Java code that we will use to execute the BPEL process through the direct binding interface. Since we are using RMI, we will need to pass payload data between the BPEL process and our code using org.w3c.dom.Element classes. In this example, we will marshal and unmarshal data into org.w3c.dom classes using JAXB. You can use JDeveloper to create JAXB class or the following command line.</p> <p>xjc .\xsd\GetProjectTaskAssignments.xsd -p org.avio.assignments.domain -d .\src</p> <p>This will create the following Java classes in the org.avio.assignments.domain package:</p> <ul><li>AssigmentTypes.java</li> <li>DynamicRoleNamesListTypes.java</li> <li>DynamicRoleNameTypes.java</li> <li>ObjectFactory.java</li> <li>Package-info.java</li> <li>Process.java</li> <li>ProcessResponse.java</li> </ul><h3><br /> Oracle’s Direct Binding and RMI Java Libraries</h3> <p>Oracle’s documentation for using the Direct Bindings is documented here. <a href="https://docs.oracle.com/cd/E36909_01/dev.1111/e10224/invocapi.htm">https://docs.oracle.com/cd/E36909_01/dev.1111/e10224/invocapi.htm</a>. <br /> Implementing this, however, is rather complex. It requires the following:</p> <ul><li>An RMI connection</li> <li>The distinguishing name (DN) to the default composite version</li> <li>An org.w3c.dom Process request</li> <li>The BPEL process end-point</li> <li>An org.w3c.dom Process Response</li> </ul><p>To simplify the RMI interface (using Soa Management API or more specifically, the Locator class as documented here <a href="https://docs.oracle.com/cd/E28280_01/apirefs.1111/e10659/toc.htm">https://docs.oracle.com/cd/E28280_01/apirefs.1111/e10659/toc.htm</a>) we define this Java method, getCurrentLocator() that will be used in our code sample. It returns an RMI locator to the SOA system.</p> <p> </p> <p style="font-size: 15px;background-color: #EFEFEF"> private Locator getCurrentLocator(String providerUrl, String adminUserName, <br />                                            String adminPassword) throws Exception {<br />         Hashtable jndiProps = new Hashtable();<br />         jndiProps.put(Context.PROVIDER_URL, providerUrl);<br />         jndiProps.put(Context.INITIAL_CONTEXT_FACTORY,<br />                       "weblogic.jndi.WLInitialContextFactory");<br />         jndiProps.put(Context.SECURITY_PRINCIPAL, adminUserName);<br />         jndiProps.put(Context.SECURITY_CREDENTIALS, adminPassword);<br />        return LocatorFactory.createLocator(jndiProps);<br /> }</p> <p><br /> The two method addressed below,  getDefaultCompositeByNameabove() and executeCompositeServiceEndpoint(), use the getCurrentLocator method.</p> <h3>    <br /> Finding the Active Composite Version</h3> <p><br /> Since several versions of composite, DynamicAssignments may be deployed, we will need to get the composite DN of the default composite version. The composite DN takes the form of partition/compositename!version, or “default/DynamicAssignments!3.2.0. We have this method, getDefaultCompositeByName, to return the default Composite. </p> <p> </p> <p style="font-size: 15px;background-color: #EFEFEF">    public Composite getDefaultCompositeByName(String compositeNameStr,<br />                                                String providerUrl,<br />                                                String adminUserName,<br />                                                String adminPassword) throws Exception {<br />         CompositeFilter cFilter = new CompositeFilter();<br />         CompositeDN compositeDN = new CompositeDN(compositeNameStr);<br />         cFilter.setPartition(compositeDN.getDomainName());<br />         cFilter.setCompositeName(compositeDN.getCompositeName());<br />         List&lt;Composite&gt; composites =<br />             locatorFactory.getCurrentLocator(providerUrl, adminUserName,<br />                                              adminPassword).getComposites(cFilter);<br />         for (Composite composite : composites) {<br />             if (composite.isDefaultRevision())<br />                 return composite;<br />             }<br />         return null;<br />     }</p> <h3>Executing the BPEL Process From Java</h3> <p><br /> The execution of the BPEL process requires the default composite, obtained above, the WSDL port and operation, and the payload as a org.w3c.dom.Element. The RMI call requires us to wrap the payload in a Message class, and here again we use Oracle Java libraries, XMLMessageFactory, to create the payload we need. This is all wrapped by the Java method shown below that returns the response as a org.w3c.dom.Element class. </p> <p style="font-size: 15px;background-color: #EFEFEF"> public Element executeCompositeServiceEndpoint(Composite composite,<br />                                                    String port,<br />                                                    String operation,<br />                                                    String payloadName,<br />                                                    Element payloadElem,<br />                                                    String providerUrl,<br />                                                    String adminUserName,<br />                                                    String adminPassword) throws Exception {<br />        Map&lt;String, Element&gt; partData = new HashMap&lt;String, Element&gt;();<br />         partData.put(payloadName, payloadElem);        <br />         Message&lt;Element&gt; request = XMLMessageFactory.getInstance().createMessage();<br />         Payload&lt;Element&gt; payload = PayloadFactory.createXMLPayload(partData);<br />         request.setPayload(payload);<br />         DirectConnection connection =<br />             locatorFactory.getCurrentLocator(<br />                     providerUrl, adminUserName,<br />                     adminPassword).createDirectConnection(composite.getCompositeDN(),port);               <br />         Message&lt;Element&gt; response = connection.request(operation, request);<br />         ByteArrayOutputStream sw = new ByteArrayOutputStream();<br />         Node n = response.getPayload().getData().values().iterator().next();<br />         return (Element) n;<br /> }</p> <h3>Making the Call</h3> <p><br /> The last step ties this all together in the following Java method, getProjectTaskAssignments. This method takes as an argument the JAXB request class, Process.class, and connect properties. It then converts the request to a dom Element, gets the default composite, executes the BPEL process, and returns the response from the BPEL process in the JAXB ProcessResponse class.</p> <p style="font-size: 15px;background-color: #EFEFEF"> <br /> private ProcessResponse getProjectTaskAssignments(<br />           Process request,<br />           String providerUrl,<br />           String adminUserName,<br />           String adminPassword) {<br />                         <br />             // Create the Request Using the JAXB class, Process.class<br />             DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();<br />             dbf.setNamespaceAware(true);<br />             DocumentBuilder db = dbf.newDocumentBuilder();<br />             Document document = db.newDocument();<br />             JAXBContext jc = JAXBContext.newInstance(Process.class);              <br />              // Marshal the Process.class object into a W3C.Document object<br />              Marshaller marshaller = jc.createMarshaller();<br />              marshaller.marshal(request, document);<br />              Element requestRoot= document.getDocumentElement();<br />    <br />            // Get the default composite version<br />             Composite dbComposite =<br />                     soaAdminService.getDefaultCompositeByName("default/DynamicAssignment",<br />                                                                      providerUrl,<br />                                                                      adminUserName,<br />                                                                      adminPassword);<br />             <br />             response =<br />                     soaAdminService.executeCompositeServiceEndpoint(dbComposite,<br />                                                                            "GetProjectTaskAssignments_client_db",<br />                                                                            "process",<br />                                                                            "payload",<br />                                                                            requestRoot,<br />                                                                            providerUrl,<br />                                                                            adminUserName,<br />                                                                            adminPassword);<br />             <br />            jc = JAXBContext.newInstance(ObjectFactory.class); <br />            Unmarshaller u = jc.createUnmarshaller();<br />            ProcessResponse processResponse= (ProcessResponse)u.unmarshal(response);<br />             return processResponse;<br /> }</p> <h2>Conclusion</h2> <p>Notice that all this code uses components and libraries contained in Oracle SOA Fusion Middleware. If you are consuming these Java classes from within a BPM or BPEL composite, then you won’t need to include any external libraries. If you are using JDev to create other SOA composite, then all the libraries will be included during design time. During deployment and run-time, you’ll just need to include the Java classes and methods described above.</p> </div> </div> </div> </div> </div><div class="container comment-container"> <div class="text-align-center"><h2>Join the Conversation</h2> </div> <div class="row"> <div class="col-sm-12"> <drupal-render-placeholder callback="comment.lazy_builders:renderForm" arguments="0=node&amp;1=731&amp;2=comment_node_blog&amp;3=comment_node_blog" token="scCGswV1m4H7Z-OI5B5gva0gHu7lpRfI35OdNJTvPzE"></drupal-render-placeholder> </div> </div> </div> <div class="container"> <div class="row"> <div class="col-sm-12 blog-tags"> <div> <div><a href="/taxonomy/term/365" hreflang="en">Oracle</a></div> <div><a href="/blog/categories/bpm" hreflang="en">BPM</a></div> <div><a href="/blog/categories/soa" hreflang="en">SOA</a></div> </div> </div> </div> </div> <div><drupal-render-placeholder callback="Drupal\block\BlockViewBuilder::lazyBuilder" arguments="0=views_block__blogs_block_4&amp;1=default&amp;2=en" token="jBjf0n8iki9sjPwElNYA4B92vVETYVFMv7O9pm9FdHQ"></drupal-render-placeholder></div> <div> <div>About the Author</div> <div></div> </div> </div> </div> Fri, 19 Oct 2018 21:54:11 +0000 Mark Peterson 731 at https://www.avioconsulting.com https://www.avioconsulting.com/blog/using-oracle-bpel-direct-bindings-java#comments Writing PL/SQL Unit Tests in SQL https://www.avioconsulting.com/blog/writing-plsql-unit-tests-sql <div class="avio-content"> <div class="page-title"> <div class="lead-image"> <div> <div>Blog Lead Image</div> <div> <img src="/sites/default/files/default_images/network-pen-blog-3_0.jpg" width="2000" height="1333" alt="Avio Consulting" typeof="foaf:Image" /> </div> </div> <div class="dark-overlay"></div> </div> <div class="text-overlay"> <div class="container"> <div class="row"> <div class="col-sm-12"> <div><h2> <a href="/blog/writing-plsql-unit-tests-sql" hreflang="en">Writing PL/SQL Unit Tests in SQL</a> </h2> </div> </div> </div> </div> </div> </div> <div class="main-content"> <div class="container"> <div class="row"> <div class="col-sm-12 node-body"> <div> <div><h2 style="margin:20pt 0pt 0pt"><span style="line-height:107%">Overview</span></h2> <p style="margin:1pt 0pt 0pt"><span style="line-height:200%">PL/SQL Procedures more times than not implement complex business rules and logic.  DBMS output statements and the SQL Developer debugger are tools that can assist when initially testing the procedure but when a change is made to a procedure it must be thoroughly regression-tested to ensure the new or change feature hasn't broken something else.  While SQL Developer provides its own unit testing framework it's more than a little tedious to setup and it requires the unit tests be run in SQL Developer.  Alternatively, the approach described in this topic proposes the use of a SQL script to create the test data and to run the test and record the results in a custom unit testing table.</span></p> <p style="margin:10pt 0pt 0pt"><span style="line-height:200%">The setup described here is entirely based on Oracle SQL and can be run outside of SQL Developer</span></p> <h2 style="margin:20pt 0pt 0pt"><span style="line-height:107%">Unit Test Table</span></h2> <p style="margin:1pt 0pt 0pt"><span style="line-height:200%">The approach here requires creating one custom table to store the results of the unit tests.  Unit tests are organized in a folder of tests testing the same PL/SQL package.  Each of the unit testing scripts in the folder will record their tests results (sample DDL provided below) according to this group name (TEST_GROUP), whatever you want to call it.  In addition, there is a TEST_RESULT column that records PASSED or FAILED associated with the unit test name and description.</span></p> <pre> <code class="language-sql">DROP TABLE "UNIT_TESTING_TABLE" CASCADE CONSTRAINTS; CREATE TABLE "UNIT_TESTING_TABLE" ( "TEST_GROUP" NVARCHAR2(30), "TEST_NAME" NVARCHAR2(30), "TEST_DESCRIPTION" NVARCHAR2(1000), "TEST_RESULT" NVARCHAR2(20), "TEST_DETAILS" NVARCHAR2(1000), "CREATED_DATE" TIMESTAMP (6) DEFAULT ON NULL systimestamp ) SEGMENT CREATION IMMEDIATE LOGGING; ALTER TABLE "UNIT_TESTING_TABLE" MODIFY ("TEST_RESULT" NOT NULL ENABLE); ALTER TABLE "UNIT_TESTING_TABLE" MODIFY ("TEST_NAME" NOT NULL ENABLE); ALTER TABLE "UNIT_TESTING_TABLE" MODIFY ("TEST_GROUP" NOT NULL ENABLE);</code></pre> <h2 style="margin:20pt 0pt 0pt"><span style="line-height:107%">Running the Unit Tests</span></h2> <p style="margin:1pt 0pt 0pt"><span style="line-height:200%">A SQL script to run the unit tests will be written in the same unit testing directory (e.g. Run-Initiator-UnitTests.sql) which first will clean up the unit testing table (line <strong>1</strong>), invoke each of the unit test scripts (lines <strong>3-6</strong>) in the directory and then display the PASSED or FAILED results (lines <strong>8-16</strong>).</span></p> <p><img alt="Unit Tests" data-entity-type="file" data-entity-uuid="5c353f7b-deb3-41d3-bd54-7d5e8a4a1540" src="/sites/default/files/inline-images/unit-test-script.jpg" /></p> <h2 style="margin:20pt 0pt 0pt"><span style="line-height:107%">Writing a Unit Test</span></h2> <p style="margin:1pt 0pt 0pt"><span style="line-height:200%">Each of the unit tests will have <u>four sections</u>:</span></p> <ul><li style="margin:5pt 0pt 0pt"><span style="line-height:100%">Describe unit test</span></li> <li style="margin:5pt 0pt 0pt"><span style="line-height:100%">DELETE and INSERT test data</span></li> <li style="margin:5pt 0pt 0pt"><span style="line-height:100%">Initialize and call the PL/SQL Procedure</span></li> <li style="margin:5pt 0pt 0pt"><span style="line-height:100%">Assert test results and record the results</span></li> </ul><p style="margin:1pt 0pt 0pt"><span style="line-height:200%">A sample script will be provided below to document each of these four sections.  The first two are easy enough and are shown below.</span></p> <p><img alt="Sections 1 and 2" data-entity-type="file" data-entity-uuid="9702a141-8a27-48a1-9e94-7a2f6a3ab96c" src="/sites/default/files/inline-images/sections1-2.jpg" /></p> <p>The third section is easy to create, simply open the Test or Debug dialog of the PL/SQL Procedure. An EXCEPTION variable is declared on line <strong>22</strong> below.  Lines <strong>23-25</strong> were added to this to set various variables needed to record the results in the unit testing table.</p> <p><img alt="Section 3: Initialize and Invoke" data-entity-type="file" data-entity-uuid="4abbdc5c-8415-4ad0-9a69-6c8dd9ad77b8" src="/sites/default/files/inline-images/section3.jpg" /></p> <p><img alt="(info)" data-emoji-fallback="ℹ" data-emoji-id="2139" data-emoji-shortname=":information_source:" data-emoticon-name="information" src="https://avioconsulting.atlassian.net/wiki/s/1862299441/6452/431cf7880c37644f5d75c01eafff950eede0f382/_/images/icons/emoticons/information.png" /> Lines <strong>30-37</strong> invoke the PL/SQL Procedure under test.</p> <p style="margin:1pt 0pt 0pt"><span style="line-height:200%">Immediately after calling the PL/SQL Procedure add IF conditions to test the outcome.  If any of these "assertions" are true then invoke the EXCEPTION.   If the EXCEPTION is not raised then insert the PASSED status.  Note the implementation of the failed_the_test EXCEPTION on lines <strong>55-57</strong> that will insert the FAILED status.</span></p> <p><img alt="Section 4: Assertions" data-entity-type="file" data-entity-uuid="48e53c8e-18ba-433c-b390-d92bb02a5d15" src="/sites/default/files/inline-images/section4.jpg" /></p> <p><img alt="(info)" data-emoji-fallback="ℹ" data-emoji-id="2139" data-emoji-shortname=":information_source:" data-emoticon-name="information" src="https://avioconsulting.atlassian.net/wiki/s/1862299441/6452/431cf7880c37644f5d75c01eafff950eede0f382/_/images/icons/emoticons/information.png" /> Lines <strong>58-60</strong> provide an OTHERS exception to catch unexpected exceptions from the procedure under test.  If the procedure under test throws an exception that is expected, then define an EXCEPTION for it in the exception block and set the test status to PASSED.  </p> <h2 style="margin:20pt 0pt 0pt"><span style="line-height:107%">Best Practices</span></h2> <ul><li style="margin:5pt 0pt 0pt"><span style="line-height:100%">The unit tests are run in a <u>local or isolated</u> Oracle database instance.  The reason for this is that each of the tests delete and create their own test data, which may wreak havoc in your DEV and TEST environments.</span></li> <li style="margin:5pt 0pt 0pt"><span style="line-height:100%">The unit testing table contains a description and it should describe what the tests is about so anyone looking at either the results in the table or in the unit test will understand the breadth of what is being tested. </span></li> <li style="margin:5pt 0pt 0pt"><span style="line-height:100%">The unit test file name itself should match (tersely) so anyone looking at the unit tests folder can distinguish one from another. </span></li> <li style="margin:5pt 0pt 0pt"><span style="line-height:100%">The assertions can query any table in the database under test and need not reflect only what is returned from the procedure.</span></li> <li style="margin:5pt 0pt 0pt"><span style="line-height:100%">Execute the unit test scripts in the file name order seen in the folder which will ensure you aren't missing any tests.</span></li> </ul><h2 style="margin:20pt 0pt 0pt"><span style="line-height:100%"><span style="line-height:107%">Summary</span></span></h2> <p style="margin:1pt 0pt 0pt"><span style="line-height:100%"><span style="line-height:200%">Having the unit tests written in a pure Oracle syntax and execution mode is intuitive, learned easily and provides a robust means to regression test PL/SQL procedures.  The unit testing table will record each of the unit test group results so test failures can be easily located.</span></span></p> </div> </div> </div> </div> </div><div class="container comment-container"> <div class="text-align-center"><h2>Join the Conversation</h2> </div> <div class="row"> <div class="col-sm-12"> <drupal-render-placeholder callback="comment.lazy_builders:renderForm" arguments="0=node&amp;1=718&amp;2=comment_node_blog&amp;3=comment_node_blog" token="BvtUfcG_-mIDBV2n7C5KCxBC6_ik2DzS5NifweN-5Ws"></drupal-render-placeholder> </div> </div> </div> <div class="container"> <div class="row"> <div class="col-sm-12 blog-tags"> <div> <div><a href="/taxonomy/term/365" hreflang="en">Oracle</a></div> </div> </div> </div> </div> <div><drupal-render-placeholder callback="Drupal\block\BlockViewBuilder::lazyBuilder" arguments="0=views_block__blogs_block_4&amp;1=default&amp;2=en" token="jBjf0n8iki9sjPwElNYA4B92vVETYVFMv7O9pm9FdHQ"></drupal-render-placeholder></div> <div> <div>About the Author</div> <div></div> </div> </div> </div> Mon, 09 Jul 2018 17:54:35 +0000 Gregory Hughlett 718 at https://www.avioconsulting.com https://www.avioconsulting.com/blog/writing-plsql-unit-tests-sql#comments Oracle ICS - Advanced XSLT Mapping in JDeveloper https://www.avioconsulting.com/blog/oracle-ics-advanced-xslt-mapping-jdeveloper <div class="avio-content"> <div class="page-title"> <div class="lead-image"> <div> <div>Blog Lead Image</div> <div> <img src="/sites/default/files/default_images/network-pen-blog-3_0.jpg" width="2000" height="1333" alt="Avio Consulting" typeof="foaf:Image" /> </div> </div> <div class="dark-overlay"></div> </div> <div class="text-overlay"> <div class="container"> <div class="row"> <div class="col-sm-12"> <div><h2> <a href="/blog/oracle-ics-advanced-xslt-mapping-jdeveloper" hreflang="en">Oracle ICS - Advanced XSLT Mapping in JDeveloper</a> </h2> </div> </div> </div> </div> </div> </div> <div class="main-content"> <div class="container"> <div class="row"> <div class="col-sm-12 node-body"> <div> <div><p>While mastering the nuances of Oracle Integration Cloud Service (ICS), I was pushing along through a transformation mapping from a fairly complex source to an equally complex target.  Requirements slowly spiraled from 'simple' mappings to 'can-i-even-do-that' mappings.  ICS provides a decent graphical interface for creating transformations (once you get familiar with it).  It allows for an easy way to map from source to target, as long as you don't need to do anything complicated.</p> <p>If you aren't familiar with ICS, check out another blog on <a href="http://www.avioconsulting.com/blog/testing-my-integration-on-ICS">Getting Your Feet Wet in ICS</a>.</p> <p><img alt="Simple mapping" data-entity-type="file" data-entity-uuid="a7cb94c7-a24f-4501-9172-c7cc44daf2be" src="/sites/default/files/inline-images/SimpleMap.png" /></p> <p>Although possible, it takes nearly 15 clicks (assuming you do it in the correct order) to add an if conditional similar to:</p> <pre> <code class="language-xml">&lt;xsl:if test="string-length($returnCode) &gt; 0"&gt; &lt;tns:Keyword&gt; &lt;xsl:value-of select="$returnCode"/&gt; &lt;/tns:Keyword&gt; &lt;/xsl:if&gt;</code></pre> <p><img alt="Conditional If" data-entity-type="file" data-entity-uuid="9cf0fa42-062c-40b5-8b36-b9d7fae0309b" src="/sites/default/files/inline-images/conditionalIf.png" /></p> <p>It's the complex scenarios and advanced functions that make transformations so powerful, has Oracle actually removed this functionality?</p> <p><strong>Of course not!</strong>  The core libraries that execute a transformation are still there, and the transformations can be edited externally, e.g. in JDeveloper (or whatever xslt editing tool you wish), although it's not entirely intuitive how to make this work.</p> <p>Keep in mind, that although JDeveloper makes it easy to add in complex functionality, I do suggest, to try and keep transformations simple.  More about this later.</p> <h2 id="BLOG-ICSAdvancedXSLTMappinginJDeveloper-ButWhyisthisNecessary?">But why is this necessary?</h2> <p>On a recent engagement, I was tasked with merging the response data of two services, into a new enriched request.  Having done this many times in SOA, I didn't think much of it.  </p> <p>I quickly found that the graphical interface on ICS could be a bit jumpy (especially with a large number of payload elements), and not as intuitive as I expected. The graphical interface was functional, but it only intuitively worked for my 'basic' mapping instructions, a source to target.  A conditional 'if' statement requires ~15 clicks, and my requirement called for dozens of 'if' conditions, for most of my mapped attributes.  There has to be a better way, I would've had to spend all day just mapping 'if's!</p> <p>Doing some planning, on how to accomplish the rest of my mapping requirements, I realized I could take advantage of more advanced features in XSLT including the use of variables, selectors, and even templates, but these features don't exist in the graphical interface mapper in ICS (or maybe I couldn't find them).  Although included in the graphical mapper, the if-conditions and choose-when tend to take more effort than necessary.</p> <h2 id="BLOG-ICSAdvancedXSLTMappinginJDeveloper-SowhyshouldIeditatransformationoutsideofICS?">So why should I edit a transformation outside of ICS?</h2> <p>There are specific cases where you would want to edit the transformation externally.</p> <ul><li>Some mappings can be done significantly faster in source mode.  These include: <ul><li>'If' conditionals</li> <li>'choose-when-otherwise' conditionals</li> <li>Large sections of similar/repeating segments</li> </ul></li> <li>More advanced functions/transformations can also be implemented, including: <ul><li>Variables</li> <li>Advanced selectors</li> <li>Templates</li> </ul></li> <li>When a transformation has a large schema, the graphical mapper starts to require 'show more' clicks to reveal additional elements, this gets tedious rather quickly.</li> <li>JDeveloper has a decent testing harness to create sample files, and execute the transformation at design time</li> </ul><p><img alt="Mapping from JDeveloper" data-entity-type="file" data-entity-uuid="64eb0b68-e5bf-48b8-9ca7-b48a5ded9efa" src="/sites/default/files/inline-images/JdevMapping.png" /></p> <p> </p> <p><strong>Tip: </strong><em>Editing the transformation <strong>does not</strong> enforce some rules that the graphical mapper would.  These errors can be found after re-importing, or trying to activate an integration.</em></p> <h2 id="BLOG-ICSAdvancedXSLTMappinginJDeveloper-Andwhywouldn'tIexternallyedittransformations?">And why wouldn't I externally edit transformations?</h2> <p>While it is simple to edit a transformation outside of the ICS graphical mapper, there are reasons you shouldn't do it.</p> <p>If kept simple, to update a mapping, requires an export of the entire integration, make the changes to the mapping, then a re-import back into ICS.</p> <p>If you choose to use the 'import' function on the transformation (and not the entire integration), it locks that transformation.  Once a mapping is locked (more on this below), ICS enforces some constraints</p> <ul><li>The mapping is no longer able to be viewed or edited from the ICS portal.  This makes it a little more difficult to debug when issues go wrong.</li> <li>It is not easy to add additional sources.  It's easier to create a new mapping action that includes the required sources, then copy the transformation from the source of the original mapping document.  Also, unless the sources were mapped in the same order, the namespace prefixes may have changed.</li> <li>Exporting / Importing tends to wreak havoc on the XML formatting, making it a little more difficult to locate changes.</li> <li>The built-in transformation tester in the graphical UI was convenient, although it didn't allow me to save any source files.</li> </ul><h2 id="BLOG-ICSAdvancedXSLTMappinginJDeveloper-AGoldenRule">A Golden Rule</h2> <p>Ok, not golden, but the general rule, <strong>DO NOT</strong> edit mappings outside of ICS unless the mappings are complex and use features not available in the graphical mapper.</p> <p>It is <strong>OK</strong> to use JDeveloper to update a mapping file with large copy/paste sections to save time, and run some external tests, however, if the mapping isn't complicated and doesn't need advanced features, keep it simple.  There is extra overhead when debugging if the mapping file isn't accessible from the graphical ICS mapper.</p> <p>Now, there are some scenarios that do require XSLT features not available from the ICS mapper: variables, advanced selectors, and templates; this allows us to meet those needs as well.</p> <p> </p> <h2 id="BLOG-ICSAdvancedXSLTMappinginJDeveloper-Justafewsimplesteps">Just a few simple steps</h2> <p>Oracle has the <a href="https://docs.oracle.com/en/cloud/paas/integration-cloud-service/icsug/importing-map-file-oracle-jdeveloper.html" rel="nofollow">Import/Export documented</a>, but I'll cover what I did to make this work.</p> <p> </p> <h3 id="BLOG-ICSAdvancedXSLTMappinginJDeveloper-DesigntheIntegration">Design the integration</h3> <p>So now let's discuss a common flow of how, and when to update the mappings externally.  Follow normal procedure for designing and implementing an integration, but leave the complicated mapping for later.  Create the required connections and appropriate flow of the integration, laying out the different mapping elements.  For the complex transformations, add some basic mappings from any source variables you need (we can fix this transformation later).</p> <p><strong>Tip: </strong><em>It's important to include at least one mapping from each different source so that they are added as a source reference in the XSL.</em></p> <p>In some cases, the mappings start out simple and straightforward and slowly evolve into very complex mappings.</p> <h3 id="BLOG-ICSAdvancedXSLTMappinginJDeveloper-ExporttheIntegration">Export the integration</h3> <p>Now that the integration has been designed, we need to export it to get to the source files.  You can manually export an integration from the ICS portal, however, check out the <a href="http://www.avioconsulting.com/blog/avio-ics-maven-plugin" rel="nofollow">AVIO ICS Maven Plugin</a> for a scripted solution (and follow best practices to get the code into source control!).</p> <h4 id="BLOG-ICSAdvancedXSLTMappinginJDeveloper-Finding/AccessingtheXSL">Finding / Accessing the XSL</h4> <p>If using the <a href="http://www.avioconsulting.com/blog/avio-ics-maven-plugin" rel="nofollow">AVIO ICS Maven Plugin</a>, the mapping files are going to be exported into <strong>&lt;INTEGRATION&gt;</strong>/<strong>src/main/iar/resources</strong> directory, otherwise, they will be in the exported artifacts under <strong>&lt;INTEGRATION&gt;.iar/icspackage/project/&lt;INTEGRATION&gt;/resources</strong> directory.</p> <p>There isn't a great way to figure out which 'processor' folder the desired transformation is in, however, a search for *.xsl will get you pretty close.  Another trick is to use the "search in files" feature on the name of the request or response object, e.g. "getObjectResponses" where GetObject is the ICS action.  Keep in mind, they are numbered from first added to last, so some assumptions can be made on which folder they are in.  </p> <h4 id="BLOG-ICSAdvancedXSLTMappinginJDeveloper-ViewinJDeveloper">View in JDeveloper</h4> <p>Now that we know which transformations we want to edit, let's open them in our favorite IDE, JDeveloper (or other IDE of your choice).</p> <p>Sure, you could open the xslt directly from JDeveloper, however, it is more convenient if we add the source files to a JDeveloper project, then we can utilize more features of the IDE.</p> <p><strong>Tip: </strong><em>This also allows to create sample request xml files, and save them for future debugging!</em></p> <p> </p> <h5 id="BLOG-ICSAdvancedXSLTMappinginJDeveloper-CreateanewApplication/Project">Create a new Application / Project</h5> <p>For my latest engagement, I created a new JDeveloper application, that contained a project for each of my integrations.  Just use a plain java project when creating the integration projects. </p> <p>Using a symlink or mklink (windows), create a link from within the project src directory, to the exported integrations resource directory that contains all of the xsl files.  This allows us to keep JDeveloper project artifacts out of the integration source.</p> <p>The below sample assumes the integration export is in the same folder as JDeveloperApplication.</p> <p>Creating Symlink in Linux:</p> <pre> <code class="language-go">:~/exports$ cd JdeveloperApplication/AVIO_FTP_INTEGRATION/src :~/exports/JdeveloperApplication/AVIO_FTP_INTEGRATION/src$ ln -s ../../../AVIO_FTP_INTEGRATION/src/main/iar/resources resources</code></pre> <p>Creating MKLink in Windows:</p> <pre> <code class="language-go">cd JdeveloperApplication\AVIO_FTP_INTEGRATION\src mklink /D win-resources ..\..\..\AVIO_FTP_INTEGRATION\src\main\iar\resources &lt;&lt;===&gt;&gt; D:\exports\AVIO_FTP_INTEGRATION\src\main\iar\resources</code></pre> <p><strong>Tip: </strong><em>The symlink or mklink can be checked into source control.  A mklink is visible under both Linux and Windows.</em></p> <p>Now the resource files are visible in JDeveloper</p> <p><img alt="Project structure" data-entity-type="file" data-entity-uuid="8df3e21e-487a-47aa-b9fe-41721f1b56ca" src="/sites/default/files/inline-images/ProjectStructure_2.png" /></p> <h4 id="BLOG-ICSAdvancedXSLTMappinginJDeveloper-MaketheChangestotheXSL">Make the changes to the XSL</h4> <p>As you would a SOA project, open the xsl, and create your advanced transformation.</p> <p class="quote-bg-dark"><strong>Tip:</strong> <em>After exporting from ICS, the transformation is all on a single line.  Use the 'reformat' feature in source mode to organize the transformation.  Occasionally, after reformatting, JDeveloper will need to be restarted to view the transformation in 'design' mode.</em></p> <div class="quote-bg-dark"> </div> <h3 id="BLOG-ICSAdvancedXSLTMappinginJDeveloper-ImporttheIntegration">Import the integration</h3> <p>Follow the instructions with the Maven plugin to reimport the integration, or create an archive file manually and import.</p> <p> </p> <h2 id="BLOG-ICSAdvancedXSLTMappinginJDeveloper-Whattoknow,theTipsandTricks">What to know, the Tips and Tricks</h2> <ul><li>After adding functionality that is not available from the graphical mapper, the mapping might show as a 'warning' or 'error', use the Import feature of the mapper to select the correct xsl file and 'Lock' the mapping from editing in ICS.<br /><img alt="Import" data-entity-type="file" data-entity-uuid="be983f6c-88da-4b80-b24d-aa093f1d7825" src="/sites/default/files/inline-images/ImportTransformation.png" /><img alt="Imported Map" data-entity-type="file" data-entity-uuid="cc6dc024-5a29-4f11-9ed5-8ae793825d00" src="/sites/default/files/inline-images/ImportedMap.png" /></li> <li>If possible, try to keep the mappings simple, so that they don't have to be locked.  This allows for a shorter debugging cycle if the mapping can be viewed in the ICS portal.</li> <li>If a map shows 'Warning', it could still work.  Warnings are typically the result of using a variable in the transformation, and ICS isn't sure if it works.  Either ignore these (not ideal), remove the variable, or use the import feature to lock the transformation.</li> <li>The first time you open a xslt in JDeveloper, it will likely be a really long single line.  Use the 'Reformat' feature to make it readable.  In some cases, JDeveloper still won't let you see the 'Design' view, just close and reopen JDeveloper to enable this view.</li> </ul><p> </p> <p> </p> <p> </p> <p> </p> </div> </div> </div> </div> </div><div class="container comment-container"> <div class="text-align-center"><h2>Join the Conversation</h2> </div> <div class="row"> <div class="col-sm-12"> <drupal-render-placeholder callback="comment.lazy_builders:renderForm" arguments="0=node&amp;1=705&amp;2=comment_node_blog&amp;3=comment_node_blog" token="NaDqoUI0apQ7wfXYJxgwE_7DpDG1GRoSso90cKZuGY4"></drupal-render-placeholder> </div> </div> </div> <div class="container"> <div class="row"> <div class="col-sm-12 blog-tags"> <div> <div><a href="/taxonomy/term/365" hreflang="en">Oracle</a></div> </div> </div> </div> </div> <div><drupal-render-placeholder callback="Drupal\block\BlockViewBuilder::lazyBuilder" arguments="0=views_block__blogs_block_4&amp;1=default&amp;2=en" token="jBjf0n8iki9sjPwElNYA4B92vVETYVFMv7O9pm9FdHQ"></drupal-render-placeholder></div> <div> <div>About the Author</div> <div></div> </div> </div> </div> Mon, 09 Apr 2018 13:41:51 +0000 Kevin King 705 at https://www.avioconsulting.com https://www.avioconsulting.com/blog/oracle-ics-advanced-xslt-mapping-jdeveloper#comments AVIO Releases an ICS Maven Plugin https://www.avioconsulting.com/blog/avio-releases-ics-maven-plugin <div class="avio-content"> <div class="page-title"> <div class="lead-image"> <div> <div>Blog Lead Image</div> <div> <img src="/sites/default/files/default_images/network-pen-blog-3_0.jpg" width="2000" height="1333" alt="Avio Consulting" typeof="foaf:Image" /> </div> </div> <div class="dark-overlay"></div> </div> <div class="text-overlay"> <div class="container"> <div class="row"> <div class="col-sm-12"> <div><h2> <a href="/blog/avio-releases-ics-maven-plugin" hreflang="en">AVIO Releases an ICS Maven Plugin</a> </h2> </div> </div> </div> </div> </div> </div> <div class="main-content"> <div class="container"> <div class="row"> <div class="col-sm-12 node-body"> <div> <div><h1>AVIO Releases an ICS Maven Plugin</h1> <p>Released today, the AVIO ICS Maven plugin has been released to <a href="https://repo.maven.apache.org/maven2/com/avioconsulting/maven/ics-maven-plugin/1.0/">Maven Central</a>.</p> <p><a href="https://docs.oracle.com/en/cloud/paas/integration-cloud-service/index.html">Oracle ICS</a> (Integration Cloud Service) is a cloud platform with a web-based interface used to quickly build integrations between cloud and on-premise applications.</p> <p>The ICS Maven plugin helps make the software development lifecycle simpler by scripting exports, imports, activation and more, allowing developers to easily store their code in source control, and automate the promotion to other cloud environments.</p> <p>Check out <a href="http://www.avioconsulting.com/blog/avio-ics-maven-plugin">http://www.avioconsulting.com/blog/avio-ics-maven-plugin</a> for more details.</p> <p>Source code in GitHub at: <a href="https://github.com/avioconsulting/ics-maven-plugin">https://github.com/avioconsulting/ics-maven-plugin</a></p> <p>To use in your pom, just add the packaging type, and plugin details (See <a href="https://github.com/avioconsulting/ics-maven-plugin">README</a>) :</p> <pre> <code class="language-xml"> &lt;packaging&gt;iar&lt;/packaging&gt; . . . &lt;plugin&gt; &lt;groupId&gt;com.avioconsulting.maven&lt;/groupId&gt; &lt;artifactId&gt;ics-maven-plugin&lt;/artifactId&gt; &lt;version&gt;1.0&lt;/version&gt; &lt;extensions&gt;true&lt;/extensions&gt; &lt;/plugin&gt;</code></pre> <p>Happy Cloud Developing!</p> </div> </div> </div> </div> </div><div class="container comment-container"> <div class="text-align-center"><h2>Join the Conversation</h2> </div> <div class="row"> <div class="col-sm-12"> <drupal-render-placeholder callback="comment.lazy_builders:renderForm" arguments="0=node&amp;1=704&amp;2=comment_node_blog&amp;3=comment_node_blog" token="Jq8jxAoHsiarU2qubMhd326HOe89xuA99TGAxBzRl2k"></drupal-render-placeholder> </div> </div> </div> <div class="container"> <div class="row"> <div class="col-sm-12 blog-tags"> <div> <div><a href="/taxonomy/term/365" hreflang="en">Oracle</a></div> </div> </div> </div> </div> <div><drupal-render-placeholder callback="Drupal\block\BlockViewBuilder::lazyBuilder" arguments="0=views_block__blogs_block_4&amp;1=default&amp;2=en" token="jBjf0n8iki9sjPwElNYA4B92vVETYVFMv7O9pm9FdHQ"></drupal-render-placeholder></div> <div> <div>About the Author</div> <div></div> </div> </div> </div> Tue, 27 Mar 2018 19:56:22 +0000 Kevin King 704 at https://www.avioconsulting.com https://www.avioconsulting.com/blog/avio-releases-ics-maven-plugin#comments AVIO ICS Maven Plugin https://www.avioconsulting.com/blog/avio-ics-maven-plugin <div class="avio-content"> <div class="page-title"> <div class="lead-image"> <div> <div>Blog Lead Image</div> <div> <img src="/sites/default/files/default_images/network-pen-blog-3_0.jpg" width="2000" height="1333" alt="Avio Consulting" typeof="foaf:Image" /> </div> </div> <div class="dark-overlay"></div> </div> <div class="text-overlay"> <div class="container"> <div class="row"> <div class="col-sm-12"> <div><h2> <a href="/blog/avio-ics-maven-plugin" hreflang="en">AVIO ICS Maven Plugin</a> </h2> </div> </div> </div> </div> </div> </div> <div class="main-content"> <div class="container"> <div class="row"> <div class="col-sm-12 node-body"> <div> <div><h1>AVIO ICS Maven Plugin</h1> <p>I began getting <a href="http://www.avioconsulting.com/blog/testing-my-integration-on-ICS" rel="nofollow">my feet wet</a> (shameless self-advertising) and took in the whole ICS experience.</p> <p>It has been a fun adventure working in ICS, mastering the art of deactivating, editing, fixing, saving, activating, and finally testing... only to curse at a simple forgotten step and repeat the process again.  Some tasks that used to be simple became harder, some tasks that were complicated and confusing became simpler.</p> <h2>What do you mean my changes are lost? (Heavy sigh)</h2> <p><img alt="AVIO Lock Is Lost" data-entity-type="file" data-entity-uuid="73cc7e8e-5a20-4906-87e3-9c42e34d7bfe" src="/sites/default/files/inline-images/AVIO_LockIsLost.png" /></p> <p>Sometimes when making changes to an integration or rearranging a layout, something becomes corrupt and ICS does not activate, or fails to edit properly, or loses my lock! I haven't dug into the root cause, and it easily could be my fault, but my first instinct is to make sure I protect myself in case it happens again.</p> <p>So I began manually exporting the integration after each development accomplishment. I would date these exports and keep them locally on my computer to re-import later if anything went wrong. Eventually, I started expanding them and putting them into source control, which allowed me to monitor changes to files. The process wasn't complicated, but it required too much time and way too many mouse clicks.</p> <h2>Why can't this be done programmatically?</h2> <p>Of course, it can! Oracle has exposed REST APIs to integrate with ICS. There are 2 versions available, <a href="https://docs.oracle.com/en/cloud/paas/integration-cloud-service/icsra/index.html" rel="nofollow">v1</a> and <a href="https://docs.oracle.com/en/cloud/paas/integration-cloud-service/icsrb/index.html" rel="nofollow">v2</a> (click for Oracle Documentation). As a general rule, use v2; however, some features aren't available in v2, and therefore v1 has to be used for some features (for example, activate and deactivate).</p> <p><img alt="REST APIs Version 2" data-entity-type="file" data-entity-uuid="6beeefbd-1cc3-49c8-9acb-19b47388cde8" src="/sites/default/files/inline-images/RESTAPIv2.png" /></p> <p>Soon, it became tedious for me to even use the REST APIs, and so I created a maven plugin to do the work for me.</p> <p> </p> <h2>Enter ics-maven-plugin.</h2> <p>AVIO Consulting has created a maven plugin, aptly named ics-maven-plugin, which is currently available through GitHub at <a href="https://github.com/avioconsulting/ics-maven-plugin" rel="nofollow">https://github.com/avioconsulting/ics-maven-plugin</a>. <s>The plugin will soon be available through Maven Central as well (I'll update when that happens).</s></p> <p>*Update (03-27-2018): This plugin is now available on Maven Central - <a href="https://repo.maven.apache.org/maven2/com/avioconsulting/maven/ics-maven-plugin/1.0/">https://repo.maven.apache.org/maven2/com/avioconsulting/maven/ics-maven-plugin/1.0/</a></p> <p>This new plugin has several features that make the development lifecycle much easier to bear!</p> <p>Keep in mind, none of these goals/phases makes development any simpler, you still have to develop the integrations and connections from the portal, but it does help significantly with the development lifecycle.</p> <p>Also, as a side note, sending messages to my colleagues saying that I had to write a <a href="https://maven.apache.org/developers/mojo-api-specification.html" rel="nofollow">Mojo</a> was mildly entertaining.</p> <h3>Phases</h3> <p>This plugin defines a new packaging type (iar) and hooks into the Maven lifecycle at the following phases:</p> <ul><li>generate-resources <ul><li>By default, this does nothing.</li> <li>If the 'export' property is set to true (-Dexport=true), it will run the 'export' goal and will export the integration defined in the POM file</li> <li>If the 'connection' property is set to the name of a connection (-Dconnection=EBS), a template JSON config file will be created</li> </ul></li> <li>package <ul><li>Runs the 'package' goal, which generates an iar file</li> </ul></li> </ul><h3>Additional individual goals</h3> <p>Additional goals are provided for supporting tasks but are not part of the standard maven lifecycle.</p> <ul><li>activate - Activates an integration</li> <li>deactivate - Deactivates an integration</li> <li>import <ul><li>Deactivates the integration if it is present and active</li> <li>Imports (or updates) the integration (iar file)</li> <li>Generates the connections / lookups / schedule components as necessary</li> <li>Updates the connection properties</li> <li>Activates the integration</li> </ul></li> <li>updateConnection - Updates the connection properties for a specific connection</li> </ul><p>See the <a href="https://github.com/avioconsulting/ics-maven-plugin" rel="nofollow">ics-maven-plugin</a> documentation for the latest functionality and detailed usage instructions.</p> <h3>Exported Project Structure</h3> <p>The exported IAR has a non-standard folder structure.  This plugin moves some folders around and puts them into a more common structure.  Additionally, the folder that contained the version number has been removed.  When the package phase is executed this structure is converted back to the ICS standard structure within the IAR file.</p> <p>Here are the basic folder mappings that occur:</p> <ul><li>icspackage/project/AVIO_FTP_INTEGRATIO_01.00.0000 → src/main/iar</li> <li>icspackage/appinstances → src/main/resources/connections</li> <li>icspackage/dvm → src/main/resources/lookups</li> <li>icspackage/schedule → src/main/resources/schedule</li> </ul><p>Below is an example of an exported integration that would get checked into source control.</p> <p><img alt="Export Folder Structure" data-entity-type="file" data-entity-uuid="f2a3d5a9-d535-4950-b1b6-1f18fee9aedd" src="/sites/default/files/inline-images/FolderStructure.png" /></p> <h2>ICS Development Lifecycle</h2> <p>First design and implement your integration within ICS, adding the invokes and actions as well as configuring your connections. Once you have something working, its time to back it up and save it in source control.</p> <h3>Export</h3> <p>Let's start with the basic function so that a copy of the integration can be stored in source control.</p> <p>The export goal will:</p> <ul><li>Use the API to download an export IAR file</li> <li>Expand the archive file locally</li> <li>Restructure the folders into the standard maven project structure (src/main directories)</li> </ul><p>The exported integration also includes details of dependent artifacts. So now an Integration project will be self-contained, with references to Connections, Lookups, and Schedules.</p> <pre> <code>kevin@kking-lt3:~/code/avio/demos/packages/avio-integration/AVIO_FTP_INTEGRATIO$ mvn generate-resources -Dexport=true -Denv=DEV [INFO] Scanning for projects... [INFO] [INFO] ------------------------------------------------------------------------ [INFO] Building AVIO_FTP_INTEGRATIO 01.00.0000 [INFO] ------------------------------------------------------------------------ [INFO] [INFO] --- maven-enforcer-plugin:1.4:enforce (enforce-property) @ AVIO_FTP_INTEGRATIO --- [INFO] [INFO] --- maven-resources-plugin:2.7:copy-resources (copy-project-properties) @ AVIO_FTP_INTEGRATIO --- [INFO] Using 'UTF-8' encoding to copy filtered resources. [INFO] Copying 2 resources [INFO] [INFO] --- properties-maven-plugin:1.0-alpha-2:read-project-properties (default) @ AVIO_FTP_INTEGRATIO --- [INFO] [INFO] --- ics-maven-plugin:1.0-SNAPSHOT:export (default-export) @ AVIO_FTP_INTEGRATIO --- [INFO] Exporting integration AVIO_FTP_INTEGRATIO_01.00.0000 from https://avioconsultingcloud.integration.us2.oraclecloud.com [INFO] Expanding ICS export, use -Dexpand=false to disable it. Optionally add -Dclean=true to remove existing files before expanding. [INFO] [Integration.exportIntegration] Starting [INFO] [RestUtilities.invokeService] Invoking REST Service [INFO] [RestUtilities.invokeService] Calling GET on https://avioconsultingcloud.integration.us2.oraclecloud.com/icsapis/v2/integrations/{id}/archive [INFO] [RestUtilities.invokeService] Using params: {id=AVIO_FTP_INTEGRATIO|01.00.0000} [INFO] [RestUtilities.invokeService] Service returned 200 in 1533 ms. [INFO] [Integration.expandIar] Decompression for target/AVIO_FTP_INTEGRATIO_01.00.0000.iar has commenced. [INFO] [Integration.expandIar] Decompression for target/AVIO_FTP_INTEGRATIO_01.00.0000.iar has completed. [INFO] [Integration.iarToProjectStructure] Starting, copying from target/iar [INFO] [Integration.iarToProjectStructure] Finished [INFO] [Integration.exportIntegration] Complete [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESS [INFO] ------------------------------------------------------------------------ [INFO] Total time: 3.042 s [INFO] Finished at: 2018-02-26T14:56:06-06:00 [INFO] Final Memory: 18M/253M [INFO] ------------------------------------------------------------------------</code></pre> <p>At this point, make sure you add the exported files to source control! Keep in mind the plugin also does not identify the differences from a previous version in source control, specifically any removed files.</p> <p>Once exported, this allows for advanced editing of XSLTs within JDeveloper as well.</p> <h3>Import into ICS</h3> <p>Now that the integration code is in source control, let's import it back into our environment or promote it to a new environment.</p> <p>The import goal will now:</p> <ul><li>Deactivate existing integrations</li> <li>Import (new) or update (existing) the integration</li> <li>Create connections and lookups (with configuration updates)</li> <li>Activate the integration</li> </ul><p>Now that saves time and a whole bunch of clicks! Yay!</p> <pre> <code>kevin@kking-lt3:~/code/avio/demos/packages/avio-integration/AVIO_FTP_INTEGRATIO$ mvn initialize ics:import -Denv=DEV [INFO] Scanning for projects... [INFO] [INFO] ------------------------------------------------------------------------ [INFO] Building AVIO_FTP_INTEGRATIO 01.00.0000 [INFO] ------------------------------------------------------------------------ [INFO] [INFO] --- maven-enforcer-plugin:1.4:enforce (enforce-property) @ AVIO_FTP_INTEGRATIO --- [INFO] [INFO] --- maven-resources-plugin:2.7:copy-resources (copy-project-properties) @ AVIO_FTP_INTEGRATIO --- [INFO] Using 'UTF-8' encoding to copy filtered resources. [INFO] Copying 2 resources [INFO] [INFO] --- properties-maven-plugin:1.0-alpha-2:read-project-properties (default) @ AVIO_FTP_INTEGRATIO --- [INFO] [INFO] --- ics-maven-plugin:1.0-SNAPSHOT:import (default-cli) @ AVIO_FTP_INTEGRATIO --- [INFO] Importing integration AVIO_FTP_INTEGRATIO_01.00.0000 to https://avioconsultingcloud.integration.us2.oraclecloud.com [INFO] [Integration.importIntegration] Starting [INFO] [Integration.retrieveIntegrationDetails] Starting [INFO] [RestUtilities.invokeService] Invoking REST Service [INFO] [RestUtilities.invokeService] Calling GET on https://avioconsultingcloud.integration.us2.oraclecloud.com/icsapis/v1/integrations/{integration}/{version} [INFO] [RestUtilities.invokeService] Using params: {integration=AVIO_FTP_INTEGRATIO, version=01.00.0000} [INFO] [RestUtilities.invokeService] Service returned 200 in 1212 ms. [INFO] [Integration.retrieveIntegrationDetails] Complete [INFO] [Integration.importIntegration] Current status: ACTIVATED [INFO] [Integration.deactivate] Starting [INFO] [RestUtilities.invokeService] Invoking REST Service [INFO] [RestUtilities.invokeService] Calling POST on https://avioconsultingcloud.integration.us2.oraclecloud.com/icsapis/v1/integrations/{integration}/{version}/deactivate [INFO] [RestUtilities.invokeService] Using params: {integration=AVIO_FTP_INTEGRATIO, version=01.00.0000} [INFO] [RestUtilities.invokeService] Service returned 200 in 3151 ms. [INFO] [Integration.deactivate] Complete [INFO] [RestUtilities.invokeService] Invoking REST Service [INFO] [RestUtilities.invokeService] Calling PUT on https://avioconsultingcloud.integration.us2.oraclecloud.com/icsapis/v2/integrations/archive [INFO] [RestUtilities.invokeService] Using params: {} [INFO] [RestUtilities.invokeService] Service returned 200 in 624 ms. [INFO] [Integration.importIntegration] Complete [INFO] [Integration.getConnections] Finding connections. [INFO] [Integration.retrieveIntegrationDetails] Starting [INFO] [RestUtilities.invokeService] Invoking REST Service [INFO] [RestUtilities.invokeService] Calling GET on https://avioconsultingcloud.integration.us2.oraclecloud.com/icsapis/v1/integrations/{integration}/{version} [INFO] [RestUtilities.invokeService] Using params: {integration=AVIO_FTP_INTEGRATIO, version=01.00.0000} [INFO] [RestUtilities.invokeService] Service returned 200 in 466 ms. [INFO] [Integration.retrieveIntegrationDetails] Complete [INFO] [Integration.getConnections] Integration AVIO_FTP_INTEGRATIO has 1 unique connections. [INFO] [RestUtilities.invokeService] Invoking REST Service [INFO] [RestUtilities.invokeService] Calling GET on https://avioconsultingcloud.integration.us2.oraclecloud.com/icsapis/v2/connections/{id} [INFO] [RestUtilities.invokeService] Using params: {id=AVIO_FTP} [INFO] [RestUtilities.invokeService] Service returned 200 in 238 ms. [INFO] [Connection.retrieveConnectionDetails] Complete [INFO] Connection AVIO_FTP has status CONFIGURED [INFO] Using 'UTF-8' encoding to copy filtered resources. [INFO] Copying 1 resource [INFO] [RestUtilities.invokeService] Invoking REST Service [INFO] [RestUtilities.invokeService] Calling POST on https://avioconsultingcloud.integration.us2.oraclecloud.com/icsapis/v2/connections/{id} [INFO] [RestUtilities.invokeService] Using params: {id=AVIO_FTP} [INFO] [RestUtilities.invokeService] Service returned 200 in 1166 ms. [INFO] [Connection.updateConnection] Complete [INFO] [Integration.activate] Starting [INFO] [RestUtilities.invokeService] Invoking REST Service [INFO] [RestUtilities.invokeService] Calling POST on https://avioconsultingcloud.integration.us2.oraclecloud.com/icsapis/v1/integrations/{integration}/{version}/activate?enablePayloadTracing={payloadTrace}&amp;enableTracing={enableTrace} [INFO] [RestUtilities.invokeService] Using params: {integration=AVIO_FTP_INTEGRATIO, payloadTrace=true, enableTrace=true, version=01.00.0000} [INFO] [RestUtilities.invokeService] Service returned 200 in 9943 ms. [INFO] [Integration.activate] Complete [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESS [INFO] ------------------------------------------------------------------------ [INFO] Total time: 18.261 s [INFO] Finished at: 2018-02-26T15:01:44-06:00 [INFO] Final Memory: 22M/255M [INFO] ------------------------------------------------------------------------</code></pre> <p> </p> <h2>Conclusion</h2> <p>This plugin now automates some tedious tasks and implements the release process into a CI/CD pipeline.</p> <p>I hope this helps others in their ICS projects!</p> <p> </p> </div> </div> </div> </div> </div><div class="container comment-container"> <div class="text-align-center"><h2>Join the Conversation</h2> </div> <div class="row"> <div class="col-sm-12"> <drupal-render-placeholder callback="comment.lazy_builders:renderForm" arguments="0=node&amp;1=701&amp;2=comment_node_blog&amp;3=comment_node_blog" token="yc1DkD8jVHcK4v8dTp0EchwD1q_r0Ri4Jt9DMogSoIw"></drupal-render-placeholder> </div> </div> </div> <div class="container"> <div class="row"> <div class="col-sm-12 blog-tags"> <div> <div><a href="/taxonomy/term/365" hreflang="en">Oracle</a></div> </div> </div> </div> </div> <div><drupal-render-placeholder callback="Drupal\block\BlockViewBuilder::lazyBuilder" arguments="0=views_block__blogs_block_4&amp;1=default&amp;2=en" token="jBjf0n8iki9sjPwElNYA4B92vVETYVFMv7O9pm9FdHQ"></drupal-render-placeholder></div> <div> <div>About the Author</div> <div></div> </div> </div> </div> Fri, 16 Mar 2018 12:53:46 +0000 Kevin King 701 at https://www.avioconsulting.com https://www.avioconsulting.com/blog/avio-ics-maven-plugin#comments Integration Cloud Service (ICS) - Lets POC and get our feet wet https://www.avioconsulting.com/blog/testing-my-integration-on-ICS <div class="avio-content"> <div class="page-title"> <div class="lead-image"> <div> <div>Blog Lead Image</div> <div> <img src="/sites/default/files/default_images/network-pen-blog-3_0.jpg" width="2000" height="1333" alt="Avio Consulting" typeof="foaf:Image" /> </div> </div> <div class="dark-overlay"></div> </div> <div class="text-overlay"> <div class="container"> <div class="row"> <div class="col-sm-12"> <div><h2> <a href="/blog/testing-my-integration-on-ICS" hreflang="en">Integration Cloud Service (ICS) - Lets POC and get our feet wet</a> </h2> </div> </div> </div> </div> </div> </div> <div class="main-content"> <div class="container"> <div class="row"> <div class="col-sm-12 node-body"> <div> <div><p>At a recent client, I had a "citizen integrator" ask me to show them some of the orchestrations that I've created in ICS, and how I went about creating them.  I began showing off some of the integrations, and some of the POCs that I created.  I didn't get very far until he stopped me and asked, how I was able to invoke the integrations to test them.  This is when I realized he had previously attempted to create some integrations, but didn't understand what he created, or how to trigger them and see them in action.</p> <p> </p> <h1>How do I test my integration on Oracle Integration Cloud Service (ICS)?</h1> <p>So, let's take a common scenario, where you are asked to verify that an integration works from ICS or as a developer you want to explore a new integration you are going to interact with. We are going to look at the most common type of integrations, 'Orchestration'.  Oracle has this all documented <a href="https://docs.oracle.com/en/cloud/paas/integration-cloud-service/icsug/creating-integrations.html#GUID-22FA3D3E-1E3A-4E2B-BC3B-C8CB9CA8C954" rel="nofollow">here</a>, so feel free to jump there for more thorough documentation! </p> <p>On creating a new Orchestration integration, the first decision is 'What triggers this integration?'.  There are two options,  'Schedule' and 'Application event or business object'... So what are these, and what should I choose.</p> <p> </p> <h2 id="BLOG-ICS-LetsPOCandgetourfeetwet-Scheduled">Trigger 1: Schedule</h2> <p>Let's start with Scheduled, as this is the quickest option to 'try out' an integration or mapping.</p> <p>Creating a 'Scheduled' orchestration is meant for exactly as it sounds, a schedule.  You can define it to run every minute, every hour, every Monday, whatever the requirement is...  The bonus feature about this option is the 'Submit Now' selection.  This makes it very easy to test!</p> <p>Now, let's create a new Orchestration, and select 'Scheduled' (make sure you follow best practices and add it to a package!)</p> <p><img alt="ICS - Scheduled Create" data-entity-type="file" data-entity-uuid="cf2d2742-74fa-4aa9-b1c7-851fbfcc2d46" height="396" src="/sites/default/files/inline-images/ScheduledCreate_0.png" width="504" /></p> <p> </p> <p>The integration comes up, and is empty except for a Schedule start and Stop elements.  Expand out Invokes, and drop in your connection.  Add in your mapping of values (hardcoded), or use the provided functions as necessary.</p> <p>Now, test it!</p> <p>Make sure you're integration has been activated (don't forget to Enable tracing and Include Payload!).  You should just 'Activate', and not 'Activate and Schedule', we don't need this to be reoccurring. </p> <p>From the integration drop down, select 'Submit Now'.</p> <p><img alt="ICS - Submit Now" data-entity-type="file" data-entity-uuid="14c12bea-aaec-4c41-9de1-0d3156fbaa13" height="226" src="/sites/default/files/inline-images/SubmitNow_0.png" width="635" /></p> <p> </p> <p>This will create an instance immediately! </p> <p>You will see a link appear at the top with a request id, you can click that to view details, or navigate to 'Monitoring → Tracking' and check investigate the instance.</p> <p><img alt="ICS - Activity Stream" data-entity-type="file" data-entity-uuid="95e6ca5b-3d43-45db-85e1-a430b97bef8d" height="360" src="/sites/default/files/inline-images/ActivityStream_0.png" width="639" /></p> <p> </p> <p>Although this is really great for creating a quick hard-coded integration, lets now discuss how to enhance this, by allowing for input variables!</p> <p> </p> <h2 id="BLOG-ICS-LetsPOCandgetourfeetwet-Applicationeventorbusinessobject">Trigger 2: Application event or business object</h2> <p>This choice allows you to expose a web service that can be used by other orchestrations, or invoked by other systems.  This is a more common scenario for creating a service orchestration between systems.  Some other common trigger scenarios include File Adapter and Database Adapter to poll for new files or records.</p> <p>This setup is a little different than the 'schedule' scenario above, in that, you will need to have a WSDL schema previously defined with your input and output elements.  Use JDeveloper, or your favorite IDE, to help you with designing a WSDL, but keep in mind that you cannot include separate xsd files, the schema needs to be self-contained in a single file.</p> <p><em>Tip: Design the WSDL as abstract, but before actually invoking the orchestration you'll need to make sure it has a concrete binding URL (see below).</em></p> <p>Create your connection with this WSDL, using a Trigger and Invoke (See documentation to limit the use), but this allows you to trigger or start an orchestration and allows you to invoke that orchestration from another orchestration.</p> <p>Create a new integration as above, but select the 'Application event or business object' option.</p> <p>The Orchestration should now be blank with an empty trigger to start.  Expand out Triggers, and add in your previously defined connection.  You can now continue development (I won't go into that here), but adding in your business scenarios with other invokes and routing.</p> <p>I'm not going to go into developing this integration, there's plenty of other documentation about how to do that, but let's discuss how to test our new ICS integration! Enter SOAP-UI.</p> <p> </p> <h3>SOAP-UI</h3> <p>If you haven't used SOAP-UI, stop reading now, and go check out their <a href="https://www.soapui.org/" rel="nofollow">website</a> and AVIO's <a href="http://www.avioconsulting.com/blog/6-tips-make-most-soapui-part-1">6 tips to make the most of SOAP-UI</a>.</p> <p>The difference between the 'Schedule' service and this one, is there is no way to manually invoke this from the ICS Console (Enterprise Manager used to allow a testing feature, but that is not included as of now).</p> <p>First, we'll go find the exposed WSDL address, and mention how to add credentials to be able to invoke your new service!</p> <p>The exposed WSDL, can be found on your Integrations page, click the 'i' for info.  You will see it under 'Endpoint URL'.</p> <p><img alt="ICS - URL Info" data-entity-type="file" data-entity-uuid="09325b78-5122-432e-902a-d16f1205727a" src="/sites/default/files/inline-images/Info_0.png" /></p> <p> </p> <p><img alt="ICS - WSDL URL Details" data-entity-type="file" data-entity-uuid="7735c58d-d786-484b-90a7-16e35c684ef3" src="/sites/default/files/inline-images/ics-getting-wsdl-integration-id-2_0.jpg" /></p> <p>This is also the URL that will need to be added to your WSDL binding.</p> <pre> <code class="language-xml">&lt;wsdl:service name="AgileIcsEbsPortType_TriggerEbsIntegration_REQUEST"&gt;     &lt;wsdl:port name="AgileIcsEbsPortType_TriggerEbsIntegration_REQUEST_pt" binding="tns:AgileIcsEbsPortType_TriggerEbsIntegration_REQUEST_binding"&gt;         &lt;soap:address location="https://icspodname-domain-id.integration.us2.oraclecloud.com:443/integration/flowsvc/soap/APLM_EBS_HNS/v01/"/&gt;     &lt;/wsdl:port&gt; &lt;/wsdl:service&gt;</code></pre> <p>Add this WSDL URL to a SOAP-UI project, and let it download the definition and exposed service operations.</p> <p>Create a new request, as you would with any new service, and populate your appropriate data elements.  If you try and execute this, you will get an error stating 'The request requires user authentication...'</p> <p>IMAGE_RequiresAuth</p> <p><img alt="ICS - Requires Authorization" data-entity-type="file" data-entity-uuid="d08b4eac-3db3-4339-83c9-18970220c4fd" src="/sites/default/files/inline-images/RequiresAuth_0.png" /></p> <p>So, lets add the authentication.  In the bottom left of that request, click 'Auth' to expand the authorization window.</p> <p><img alt="ICS - SOAP UI Authorization" data-entity-type="file" data-entity-uuid="a6f8cb54-608d-49ef-94e8-2085ba4967fa" src="/sites/default/files/inline-images/Auth_0.png" /></p> <p>In the drop-down, select 'Add new authorization', select 'Basic', and add your username and password that you use to log into ICS.</p> <p>Right-click in the request window, and select 'Add WSS Username Token'.  This will add a security header block to your request with your username and password.</p> <p><img alt="ICS - Add WSS Username" data-entity-type="file" data-entity-uuid="f22599b8-1903-4d83-83a4-3f77d46f5d7e" src="/sites/default/files/inline-images/AddWSSUsername_0.png" /></p> <p> </p> <p>Attempting to run the service now, still results in an error.  The key here is the text: "WSM-00122: Valid timestamp is not present in the message."</p> <p>Right click on the request window again, and select 'Add WS-Timestamp', and give it an interval (in seconds).  You should now see a timestamp with 'Created' and 'Expires' attributes.</p> <p><img alt="ICS - SOAP Request" data-entity-type="file" data-entity-uuid="7cfeb414-a887-412b-951d-190514196e91" src="/sites/default/files/inline-images/Request.png" /></p> <p> </p> <p>Keep in mind, that timestamp expires.  Just delete the 'Timestamp' elements, and recreate as above to generate a new timestamp.</p> <p>Now, jump back into ICS, (Monitoring → tracking) and look through the instance you just created!</p> <p>I hope this helps some people get started and playing around in ICS!</p> </div> </div> </div> </div> </div><div class="container comment-container"> <div class="text-align-center"><h2>Join the Conversation</h2> </div> <div class="row"> <div class="col-sm-12"> <div class="container blog-comments"> <div class="row"> <div class="col-sm-12"> <div class="pull-left author"> <div>Emily Brown</div> </div> <div class="comment-date"> <div>March 13, 2018</div> </div> </div> </div> <div class="row"> <div class="col-sm-12 comment-body"> <div><p>thanks</p></div> </div> </div> </div> <drupal-render-placeholder callback="comment.lazy_builders:renderForm" arguments="0=node&amp;1=699&amp;2=comment_node_blog&amp;3=comment_node_blog" token="YxluIYsIf50ak0nRFRbPstyXZk-LElqP8DbCDA2hVWI"></drupal-render-placeholder> </div> </div> </div> <div class="container"> <div class="row"> <div class="col-sm-12 blog-tags"> <div> <div><a href="/taxonomy/term/365" hreflang="en">Oracle</a></div> </div> </div> </div> </div> <div><drupal-render-placeholder callback="Drupal\block\BlockViewBuilder::lazyBuilder" arguments="0=views_block__blogs_block_4&amp;1=default&amp;2=en" token="jBjf0n8iki9sjPwElNYA4B92vVETYVFMv7O9pm9FdHQ"></drupal-render-placeholder></div> <div> <div>About the Author</div> <div></div> </div> </div> </div> Tue, 30 Jan 2018 22:04:22 +0000 Kevin King 699 at https://www.avioconsulting.com https://www.avioconsulting.com/blog/testing-my-integration-on-ICS#comments