Advertisements
RSS

Tag Archives: Oracle

How to setup SSH access to Oracle Compute Cloud Service Instances

After playing around with the CLI it’s time to run some instance on the Oracle Compute Cloud Service. Oracle offers a broad range of images divided in 3 categories namely: Oracle images, Private images and Marketplace. The marketplace holds almost 400 turn-key solutions (from PeopleSoft to WordPress) where the category Oracle images are mostly Oracle Enterprise Linux distributions.

For this blog I will start a Oracle Linux 7.2 machine on the Oracle Compute Cloud and connect through SSH from my own machine.

Setting up security (SSH)

First we need to create a private and public keypair to authenticate against the Linux instance. Where the private key is safely stored on my desktop, the public key will be uploaded to the Oracle Compute Cloud. Run the following command:

jvzoggel$ ssh-keygen -b 2048 -t rsa
Generating public/private rsa key pair.
Enter file in which to save the key (/Users/jvzoggel/.ssh/id_rsa): 
Enter passphrase (empty for no passphrase): verySecret1
Enter same passphrase again: verySecret1
Your identification has been saved in /Users/jvzoggel/.ssh/id_rsa.
Your public key has been saved in /Users/jvzoggel/.ssh/id_rsa.pub.

In the Oracle Compute Cloud Service console we select Network -> SSH Public Keys.
Select the generated .pub file (which holds your public key and is safe to share).

Now that the Oracle cloud knows our public key it can allow secure authentication to it’s instances. However we need to do some security configuration to make sure the SSH traffic will be able to passthrough. This can be done during the instance creation, but I think it’s better to do it upfront.

Creating a secure ip list (source)

Under Network -> Shared Network -> Security IP-Lists we add a new entry. Any entry can hold multiple IP ranges, but in our case we will just add 1 IP address which is our public IP address on the internet. If you don’t know what your IP is entering the WWW then google on “what is my IP address” and many sites will help you out. Enter your address as shown below and select create.

Creating a secure list (target)

The next step is to create a security list. A security list is a bundle of 1 to many instances that you can use as source or destination in security rules. Before we create our security rule and even instance, we create the list upfront that will hold that 1 instance for security rule destination.

Creating a secure rule (bring it all together)

You can use security rules to control network access between your instances and the Internet. In this case we will create a rule that allows only SSH traphic, from our own machine to the soon to be created instance in our (now empty) security list. Oracle Compute recognises a lot of default security applications among them SSH. Make sure to select the IP list as source and list as destination.

Security should be all set, let’s start our first instance.

Creating a secure Instance on Oracle Compute Cloud

Under Instances -> Instance we select Oracle Images and get a latest version of Oracle Enterprise Linux. Make sure not to select Review and Create but use the “>” button on the right of it. My opinion the UX is not really explanatory here, it would be better to label it “Configure and Create” or something.

Go through the wizard and during the Instance step make sure to add the public SSH key we uploaded earlier. This will allow access to our instance with SSH without the need of a password.

In the Network step of the wizard we add the new instance to our freshly created security list. With this, the instance will inherit all the security rule configurations we made earlier.

Finish the wizard and wait for the Compute Cloud Orchestration to complete. After that your instance should be running.

Proof of the pudding

Check the public IP of your Oracle Compute Cloud instance and use it in your shell to connect with the SSH command.

And voila…

jvzoggel$ ssh -i /Users/jvzoggel/.ssh/id_rsa opc@120.140.10.50 
[opc@bd8ee6 /]
[opc@bd8ee6 /]$ whoami
opc
[opc@bd8ee6 /]$
[opc@bd8ee6 /]$ cat /etc/oracle-release
Oracle Linux Server release 7.2

References

Advertisements
 
Leave a comment

Posted by on 26-04-2017 in Uncategorized

 

Tags: , , , ,

Using the Oracle Public Cloud Command Line Interface (CLI)

The Oracle Public Cloud Command-Line Interface is a utility to enable management of your cloud environment from the command line. The current release (1.1.0) only supports the Compute service, but Oracle states that additional service support coming in future releases

I like command line interfaces and being familiar with Oracle’s cloud competitors implementation I was curious. So I downloaded the CLI tool here and since I had already python installed on my OS X the startup time as a newcomer is relatively short.

The initial setup

We need 3 variables to connect to the Oracle Cloud:

  • The REST API endpoint
  • domain/username
  • password

You can get the REST endpoint by logging in to the Oracle Cloud and check the service details under Oracle Compute Cloud Service.

So we get the REST Endpoint here for our OPC_API and the OPC_USER is a combination of prefix “/Compute-“, your domain and your Cloud username. So run the next 2 commands in your shell (and use your own version off course):

export OPC_API="https://api-z00.compute.us1.oraclecloud.com"
export OPC_USER=/Compute-gse00000001/cloud.admin

We need to paste the password in a textfile, because the oracle-compute CLI otherwise will tell us:
ValidationError: Secure argument “password” can only be read from a file or terminal, but the argument “xxxxx” is not a regular file

So create a pwd.txt, store the password there and

chmod 600 /full/path/to/password/file

Authentication

Next step is getting authenticated against the Oracle Compute Cloud.

oracle-compute auth /Compute-gse00000001/cloud.admin pwd.txt

This command returns an authentication token and sets the OPC_COOKIE environment variable. The token expires after 30 minutes. As the CLI tool handles authentication by managing the cookies file, you don’t need to run the export command yourself.

The authentication token expires 30 minutes from the time you run the auth command. The refresh_token command extends the expiry of the current authentication token with another 30 minutes, but not beyond the session expiry time, which is 3 hours.

oracle-compute refresh_token

You can now use all the CLI commands like list, delete, add, create, discover, get and more. At least for 30 minutes :)

References

 
1 Comment

Posted by on 25-04-2017 in Uncategorized

 

Tags: , , ,

How to upload large files to Oracle Support calls

I usually update Oracle Support calls with screenshots, text snippets or infamous one-liners. However yesterday I needed to update a call with half our ACM/BPM environment SOAINFRA table dump. So poking around on the net I found a cool script from André Karlsson that did the trick.

Script

#!/bin/bash

HOST='transport.oracle.com'
USER='your.oracle.account@yourprovider.org'     #Add your Oracle Support iD
FILE=$1
SR=$2
FILEname=`basename $1`

transport () {
set -x
        curl -T ${FILE} -o ${FILEname} -u ${USER} "https://${HOST}/upload/issue/${SR}/"
}
if [[ -n $2 ]] ; then
        transport
else
cat << EOF
${0} [file] [SR]
EOF

fi

Runtime

jvzoggel$ ./upload.sh [FILENAME] 3-1234567890

References

All credits to André Karlsson and his blogpost here:
https://www.protractus.com/2014/05/upload-attachment-to-oracle-support-from-command-line/

 
Leave a comment

Posted by on 31-03-2017 in Uncategorized

 

Tags: ,

Using the Oracle Database to store and present XML data

Because we investigated the possibilities to store our (old) BPM Human Task data outside the SOAINFRA database (for archive, metrics and search queries on short history) we looked into a few possibilities in a spike / PoC. Because the Task data is actually structured XML data of which we do not know yet what future needs would require, the most safe solution was to store the complete XML document in a datastore.

Luckily the Oracle database has the option to store XML data and use views to represent the data “the old fashion way”. So this design in high-level looks like this.

xmldata

First we create a table:

CREATE TABLE TEST_TAAK
( "ID" NUMBER,
"TAAK_ID" VARCHAR2(36 BYTE),
"VERSIE" VARCHAR2(4 BYTE),
"PAYLOAD" "XMLTYPE"
)

Then insert a HumanTask (task) XML element into the table.
To make sure we don’t get any errors like:

  • “ORA-31011: XML parsing failed”
  • “SQL Error: ORA-01704: string literal too long; Cause: The string literal is longer than 4000 characters.”

we declare a variable to hold the XML string before we update/insert it.

Declare vXmlStr xmltype:=xmltype('&lt;task&gt;&lt;title&gt;My Task&lt;/title&gt;&lt;payload&gt;&lt;CaseNumber&gt;Case-1&lt;/CaseNumber&gt;&lt;DocumentUrl&gt;http://mydocument&lt;/DocumentUrl&gt;&lt;DocumentNaam&gt;myDocument&lt;/DocumentNaam&gt;&lt;/payload&gt;&lt;taskDefinitionURI&gt;default/Process_1.0!1600.93239/htMyTask&lt;/taskDefinitionURI&gt;&lt;ownerRole&gt;MyCasus_1.0.Users&lt;/ownerRole&gt;&lt;priority&gt;3&lt;/priority&gt;&lt;identityContext&gt;jazn.com&lt;/identityContext&gt;&lt;systemAttributes&gt;&lt;xmlstuff&gt;much stuff&lt;/xmlstuff&gt;&lt;taskDefinitionName&gt;htMyTask&lt;/taskDefinitionName&gt;&lt;xmlstuff&gt;more stuff&lt;/xmlstuff&gt;&lt;/systemAttributes&gt;&lt;systemMessageAttributes&gt;&lt;numberAttribute1&gt;0.0&lt;/numberAttribute1&gt;&lt;/systemMessageAttributes&gt;&lt;sca&gt;&lt;applicationName&gt;default&lt;/applicationName&gt;&lt;xmlstuff&gt;more stuff&lt;/xmlstuff&gt;&lt;/sca&gt;&lt;/task&gt;');
Begin
  Update TEST_TAAK set PAYLOAD = vXmlStr where ID=1;
End;

taskxml1

CREATE OR REPLACE FORCE VIEW TEST_TAAK_VW ("TAAK_ID", "VERSIE", "XML_TITLE", "XML_TASKDEFINITIONNAME", "XML_PAYLOAD")
AS
SELECT TT.TAAK_ID
, TT.VERSIE
, XMLRGL.TITLE
, XMLRGL.TASKDEFINITIONNAME
, XMLRGL.PAYLOAD
FROM
TEST_TAAK TT
, XMLTABLE( '/task' PASSING TT.PAYLOAD
COLUMNS TITLE VARCHAR2(40) PATH 'title'
, TASKDEFINITIONNAME VARCHAR2(40) PATH 'systemAttributes/taskDefinitionName'
, PAYLOAD XMLTYPE PATH 'payload'
) AS XMLRGL;

And the result, voila:

 

taskxml2

 

 
Leave a comment

Posted by on 22-09-2016 in Oracle

 

Tags: ,

How to implement permissions on your activities with Oracle Adaptive Case Management ?

When our Oracle Adaptive Case Management project started we initially used the default permissions on the case (Public, Restricted) to make sure our activities where available to the correct BPM application roles. A complex authorization model of roles, with LDAP groups, with users to allow access to the activities, but also custom UI and human tasks.

default_acm_permissions

An important concept of knowledge worker automation (on which off course our whole case is based) is that the users should not be locked into rigid BPM processes (and access constraints I would like to add) which the IT department came up with. So activities on one hand would be allowed access to by all internal knowledge workers anyway, because: “hey .. they are knowledge workers and know best, right ?”

The first exception

However for some exceptions we got the requirements to only allow a specific role to a specific activity. So what we did was adding a new permission for that role and made sure that the activity was only available for that role.

Screen Shot 2016-07-29 at 11.08.18

new permission for role Senior Employee

Screen Shot 2016-07-29 at 11.08.35

set the permission on the activity

And all was good, for a while …

Challenge accepted

This went pretty well for some time, until we ran into a new requirements which made us rethink our design:

  • We had the requirement that on a specific activity where currently only permRoleSeniorEmployee had access now, we had to add the role Medior Employee. Therefor the original design thought that all activities are available for all employees OR for just 1 specific role (senior) for quality assurance was no longer valid.

So we looked at our options :

  1. We allowed the application role Medior to the permRoleSenior permission for a quick win for now, but looking at our naming convention this would be a bit confusing in the long run. All other options below required a code change, build and deploy so we tried to be smart to prevent this from ever happening again.
  2. The activity sadly doesn’t have a multi-select (both 11g and 12.2.1) so it is not possible to select both permRoleSenior and permRoleMedior
  3. We could add a new permission like permRoleMediorAndSenior, but still limiting ourselves to the code base
  4. In future identical requirements we do not want to change the codebase of our ACM project and permissions should be able to change on runtime. So both option 2 and 3 are not smart in the long run.

Our “Best Practice”

We have long running cases (like, really long) and redeployment of a new version will not fix any new permissions requirements on running instances. However since we have 50+ activities in our case where most of them are (currently) allowed access to by all employee levels (the example here just uses 2, but in reality we have much more roles). So the idea of creating a separate permission for each activity was not appealing, we eventually decided that we just had to. So for each activity we created a unique permission and configured in on the activity.

Screen Shot 2016-07-29 at 11.41.15

new unique permission for the activity

Screen Shot 2016-07-29 at 11.41.20

set the permission on the activity

 

Scripted Configuration

Because know we have a LOT of permissions and roles we are gratefull for having a WLST script to make sure these are automatically configured through our environments. Scripts have some customization, but the main logic was found on the big WWW (sorry, not sure where and who to give credits).

So first we need a property file


permission.total=2

# permActMyProcess2
permission.1.appstripe=OracleBPMProcessRolesApp
permission.1.principalclass=oracle.security.jps.service.policystore.ApplicationRole
permission.1.principalname=RubixCasus_1.0.MediorEmployee
permission.1.permclass=oracle.bpm.casemgmt.permission.CasePermission
permission.1.permtarget=RubixCasus_1.0.PERMACTMYPROCESS2.ACTIVITY
permission.1.permactions=INVOKE
permission.2.appstripe=OracleBPMProcessRolesApp
permission.2.principalclass=oracle.security.jps.service.policystore.ApplicationRole
permission.2.principalname=RubixCasus_1.0.SeniorEmployee
permission.2.permclass=oracle.bpm.casemgmt.permission.CasePermission
permission.2.permtarget=RubixCasus_1.0.PERMACTMYPROCESS2.ACTIVITY
permission.2.permactions=INVOKE

And the WLST script


from java.util import Properties
from java.io import FileInputStream
from java.io import File
from oracle.security.jps.mas.mgmt.jmx.policy import PortablePrincipal
from oracle.security.jps.mas.mgmt.jmx.policy import PortablePermission
from oracle.security.jps.mas.mgmt.jmx.policy.PortablePrincipal import PrincipalType
import os, sys

PROPERTIES = sys.argv[1]

propInputStream = FileInputStream(PROPERTIES)
configProps = Properties()
configProps.load(propInputStream)
propInputStream.close()
pmTotal=configProps.get("permission.total")
print '... property permission.total:',pmTotal

connect('weblogic', 'welcome1', 't3://myserver:7001')

print '============================='
print 'Granting permissions...'
print '============================='
print '... property permission.total:',pmTotal
i=1
while (i <= int(pmTotal)) :

  pmAppStripe=configProps.get("permission."+str(i)+".appstripe")
  pmPrincipalClass=configProps.get("permission."+str(i)+".principalclass")
  pmPrincipalName=configProps.get("permission."+str(i)+".principalname")
  pmPermClass=configProps.get("permission."+str(i)+".permclass")
  pmPermTarget=configProps.get("permission."+str(i)+".permtarget")
  pmPermActions=configProps.get("permission."+str(i)+".permactions")

  domainRuntime()
  jpsBean = ObjectName('com.oracle.jps:type=JpsApplicationPolicyStore')

  print 'INFO - Index:',str(i),'| Name:',pmPrincipalName,'| Target:',pmPermTarget,' |Action:',pmPermActions

  principal = PortablePrincipal(pmPrincipalClass, pmPrincipalName,PrincipalType.CUSTOM)
  params = [pmAppStripe, principal.toCompositeData(None)]
  sign = ["java.lang.String", "javax.management.openmbean.CompositeData"]
  perms = mbs.invoke(jpsBean, "getPermissions", params, sign)

  permExists = false
  for perm in perms:
    p = PortablePermission.from(perm)
    if(p.target==pmPermTarget and p.permissionClassName==pmPermClass and pmPermActions in p.actions):
      permExists = true
      print 'INFO - Permission',pmPermTarget,'(',pmPermActions,') already set for ',pmPrincipalName
      break

    if(permExists==false):
    try:
      grantPermission(appStripe=''+pmAppStripe,principalClass=''+pmPrincipalClass,principalName=''+pmPrincipalName, permClass=''+pmPermClass, permTarget=''+pmPermTarget,permActions=''+pmPermActions)
      print 'INFO - Permission',pmPermTarget,'(',pmPermActions,') set for ',pmPrincipalName
    except:
      print 'ERROR - Failed adding permission ',pmPermTarget,'(',pmPermActions,') to',pmPrincipalName
      dumpStack()
      print sys.exc_info()
      os._exit(1)

  i = i + 1

Conclusion

The longer we thought about this the more we think the current permission solution lacks some maintainability. It would (for instance) be nice if the BPM WorkSpace would allow some graphical interface where all activities could be easily connected to the (already their) BPM Application Roles. So hopefully in the near future ?

 
Leave a comment

Posted by on 29-07-2016 in BPM, Oracle

 

Tags: , , , , ,

Using the Human Task identification key to set your own taskId with Oracle BPM (and BPEL)

Requirement

Our Oracle ACM/BPM system will create tasks which will not only be handled by users in a front-end but also through a B2B connection with our external partners. So we need to publish a message to our B2B partners when a task is available. The challenge here is that the taskId is externally generated in the Human Task component and for the BPM (and BPEL) process the taskId is unknown until the task is closed. So we need to generate our own taskId or a trick to capture and retrieve the taskId outside the process and send it back to the process.

Solution

We first looked at the option to use the Human Task onAssigned event which we could capture through EDN and handle accordingly. However one of the requirements was that we would not communicate an internal (task) ID to our B2B partners so needed to generate our own ID instead. So we thought about generate our own guid() and place it on one of the ProtectedTextAttributes so we could use this to query the correct task. But Laurens van der Starre pointed us out that Oracle actually has a solution for this and we could use the identification key on the Human Task.

So below is an example of a process where our own key (a guid) is generated in the script task and then placed on the human task.

process

Map the generated variable on the Identification Key

task

Runtime

In EM I can see that the generated key is 35373030303632323333383139353637. So we would normally communicate this to our B2B partner. Then on request from our B2B partner to send the details of the task service we can query the correct task using the Oracle TaskQueryService:


<soapenv:Envelope>
 <soapenv:Header/>
 <soapenv:Body>
 <tas:taskListRequest>
 <com:workflowContext>
 <com:credential>
 <com:login>${#Project#username}</com:login>
 <com:password>${#Project#password}</com:password>
 </com:credential>
 </com:workflowContext>
 <tas1:taskPredicateQuery>
 <tas1:displayColumnList>
 <tas1:displayColumn>IDENTIFICATIONKEY</tas1:displayColumn>
 </tas1:displayColumnList>
 <tas1:optionalInfoList>
 <!--tas1:taskOptionalInfo>Comments</tas1:taskOptionalInfo-->
 <!--tas1:taskOptionalInfo>Attachments</tas1:taskOptionalInfo-->
 <!--tas1:taskOptionalInfo>Payload</tas1:taskOptionalInfo-->
 </tas1:optionalInfoList>
 <tas1:predicate>
 <tas1:assignmentFilter>All</tas1:assignmentFilter>
 <tas1:clause>
 <tas1:column>IDENTIFICATIONKEY</tas1:column>
 <tas1:operator>EQ</tas1:operator>
 <tas1:value>35373030303632323333383139353637</tas1:value>
 </tas1:clause>
 </tas1:predicate>
 </tas1:taskPredicateQuery>
 </tas:taskListRequest>
 </soapenv:Body>
</soapenv:Envelope>

Result

 

<env:Envelope xmlns:env="http://schemas.xmlsoap.org/soap/envelope/">
 <env:Header/>
 <env:Body>
 <taskListResponse xmlns="http://xmlns.oracle.com/bpel/workflow/taskQueryService">
 <task xmlns="http://xmlns.oracle.com/bpel/workflow/task">
 <title>task-identification-key</title>
 <ownerRole>task-identification-key.ProcessOwner</ownerRole>
 <priority>3</priority>
 <processInfo/>
 <systemAttributes> ... </systemAttributes>
 <systemMessageAttributes/>
 <identificationKey>35373030303632323333383139353637</identificationKey>
 <percentageComplete>100.0</percentageComplete>
 <sca>
 <compositeDN>default/task-identification-key!1.0*soa_.....</compositeDN>
 </sca>
 <applicationContext>OracleBPMProcessRolesApp</applicationContext>
 <taskDefinitionId>default/task-identification-key!1.0/htMyTask</taskDefinitionId>
 <mdsLabel>soa_...</mdsLabel>
 <customAttributes/>
 </task>
 </taskListResponse>
 </env:Body>
</env:Envelope>

Example / Sources

 

 
1 Comment

Posted by on 29-04-2016 in BPM, Oracle

 

Tags: , ,

Limitation in Oracle Adaptive Case Management (ACM) revision ID length

All our Oracle BPM projects use a revision id during deployment of the SCA component which is something like [4 digits].[svn-revision] which might look like 1602.71234

The Oracle SCA version format convention

In the Oracle documentation it states that the Oracle SCA composite revision must apply this format:
n0[.n1[.n2[.n3[.n4]]]][-milestone-name[milestone-number] | _patch-number]
Where all but “milestone-name” and “comment” are numeric, composed of one or more digits (0-9) from 0 up to a maximum value of 99999999.

This is the same convention you see on the error when deploying a composite with an incorrect revision format.

foutmelding_jdev

So we are good due to the fact that our revision naming standard only use n0.n1 and both numbers will not reach the max value of 99999999 anywhere soon.

The problem

However when testing we discovered that when our revision passed 99999 we have a problem. Not due to the normal SOA or BPM components, they can easily handle the longer n1 digits. But due to the fact that our Oracle ACM projects will throw the following error when deploying a composite with a total(!) revision length of 10+

Logging:

: Case metadata deployment failed. 
Case metadata deployment failed for MyCase. 
Contact system administrator for assistance. 
{rootCauses=[]} 
at oracle.bpm.casemgmt.fabric.CaseManagementServiceEngine.deploy(CaseManagementServiceEngine.java:1941) 
at oracle.bpm.casemgmt.fabric.CaseManagementServiceEngine.deploy(CaseManagementServiceEngine.java:401) 
at oracle.bpm.casemgmt.fabric.CaseManagementServiceEngine.deploy(CaseManagementServiceEngine.java:182) 
... 
Caused By: BPM-72806 
..... 
at java.lang.Thread.run(Thread.java:662) 
Caused By: javax.persistence.PersistenceException: Exception [EclipseLink-4002] (Eclipse Persistence Services - 2.3.1.v20111018-r10243): org.eclipse.persistence.exceptions.DatabaseException 
Internal Exception: java.sql.SQLException: ORA-12899: value too large for column "SOA_SOAINFRA"."CM_CASE_DEFINITION"."COMPOSITE_VERSION" (actual: 12, maximum: 10)</pre>

So when checking the SOAINFRA database design we discovered that for ACM components the revision is also stored in a column with a definition of VARCHAR2(10)


DESC CM_CASE_DEFINITION
Name Null Type
----------------- -------- --------------
DEFINITION_ID NOT NULL VARCHAR2(400)
NAME NOT NULL VARCHAR2(255)
TITLE VARCHAR2(500)
DESCRIPTION VARCHAR2(1000)
CATEGORY VARCHAR2(400)
NAMESPACE VARCHAR2(2000)
COMPONENT_NAME VARCHAR2(200)
COMPOSITE_DN VARCHAR2(500)
COMPOSITE_NAME VARCHAR2(200)
COMPOSITE_VERSION VARCHAR2(10)
APPLICATION_NAME VARCHAR2(200)

table_soainfra

The solution

So we logged a service request (SR 3-12014738981) and together with Oracle Support we concluded that this is actually a bug in both 11g and 12c.
Bug 22564283 – Limitation in ACM revision ID due to CM_CASE_DEFINITION.COMPOSITE_VERSION

Yesterday we received confirmation from Oracle Support that the bug is fixed and we will receive a patch.
Meanwhile we can already use the workaround to update COMPOSITE_VERSION column in CM_ACTIVITY_DEFINITION and CM_CASE_DEFINITION to VARCHAR2(200).
So actually an easy fix on the SOAINFRA schema we assumed would work if we “hacked” it in our self, but we’re still very glad that it was quickly handled and solved through Oracle Support with an official supported patch.

alter table CM_ACTIVITY_DEFINITION modify (COMPOSITE_VERSION varchar2(200))
alter table CM_CASE_DEFINITION modify (COMPOSITE_VERSION varchar2(200))

So, if you run into the same problem you can refer with Oracle Support to the SR and BUG numbers mentioned above

 
Leave a comment

Posted by on 17-02-2016 in Uncategorized

 

Tags: , , , ,