Introduction
So I thought that would be a nice use case to start, here is what I envisioned based on certain requirements from an actual customer I am helping at the present time.
As members of the Fusion Middleware Architecture Group (a.k.a the A-Team), we get exposed to a wide range of challenging technical issues around security and Oracle Fusion Middleware. We're using this blog to answer common questions and provide interesting solutions to the real-world scenarios that our customers encounter every day. NOTICE: All our post and much more can now be found at http://www.ateam-oracle.com/category/identity-management/
I pointed a couple of people at those posts and they told me they wanted more. More explanation, more clarity, and more about how to use Upstart to boot the entire environment.
So in this post I'm going to show how to use Upstart to start the Oracle database, then (once the database is started) start OID and OVD, and only then start OAM and the other WebLogic services.
The first thing I did was convert my Oracle database startup from a SysV-style init script to Upstart. Colm Divilly did the heavy lifting for me and blogged his config file for Ubuntu. I took that and tweaked it for OEL.
This goes in /etc/init/oracledb.conf:
description "Oracle Database" # Based on blog post at # https://cdivilly.wordpress.com/2010/10/28/ubuntu-upstart-script-for-oracle-database/ # The location of the Oracle install env ORACLE_HOME=/home/oracle/database/product/11.2.0/dbhome_1 # The user to execute Oracle as env ORACLE=oracle start on runlevel [2345] stop on runlevel [016] expect fork pre-start script logger "Starting Oracle DB" su - $ORACLE -c "$ORACLE_HOME/bin/dbstart $ORACLE_HOME" end script post-stop script logger "Stopping Oracle DB" su - $ORACLE -c "$ORACLE_HOME/bin/dbshut $ORACLE_HOME" end script
Then /etc/init/oid.conf for OID, OVD and the WebLogic server where I run ODSM:
start on started oracledb stop on stopping oracledb # This is good for debugging purposes but it's a bad idea to leave # this on long term. #console output # this starts OPMN, OID and OVD pre-start script logger "pre-start for OID/OVD" /bin/su - oracle -c "/home/oracle/middleware/asinst_1/bin/opmnctl startall" logger "pre-start for OID/OVD complete" end script # and this stops them post-stop script logger "pre-stop for OID/OVD complete" /bin/su - oracle -c "/home/oracle/middleware/asinst_1/bin/opmnctl stopall" logger "pre-stop for OID/OVD complete" end script # this is the AdminServer only: exec /bin/su - oracle -- /home/oracle/middleware/user_projects/domains/IDMDomain/bin/startWebLogic.sh
The important thing there is the "start on started oracledb" stanza. What that says in English is much as you would expect - "start this once the 'oracledb' service is started". The "stop on" does the same for when the database is being stopped; which will cause Upstart to stop OID and OVD before it tries to stop the database.
Upstart works out the dependencies automatically so no need to worry about numbers or pinging the database via sqlplus or tnsping.
The Upstart config for the OAM Server looks the much the same:
/etc/init/oamadminserver.conf
start on started oracledb stop on stopping oracledb exec /bin/su - oracle -- /home/oracle/middleware/user_projects/domains/IAMDomain/bin/startWebLogic.shEnjoy.
2012-12-05 19:06:38.038 PiggyBank[24799:1303] -[__NSCFString OMJSONValue]: unrecognized selector sent to instance 0xb2be000This error appeared after the Application Profile was downloaded and I couldn't figure out what I had done wrong.
Turns out I'd forgotten one step after adding the SDK bits to the XCode project - I had forgot to add the linker flags "-ObjC -all_load" under Build Settings.
To fix this click on the Project, then click the Target, then click the "Build Settings" tab and find the "Other Linker Flags" row. Edit it and add -ObjC -all_load to whatever's already there. Here's a screen shot:
Those flags are needed whenever a new message (function) will be passed to existing class without extending it. Inside the bits of the M&S SDK NSString doesn't have OMJSONValue but the SDK will pass OMJSONValue to NSString, so those flags are needed to make it work.
Of course this is documented in a block marked "Important:" but I missed it and I'm guessing if you found this blog post via Google you did too!
But I hadn't sat down to redo my old (and crummy) OID/OVD start scripts to use Upstart until this week partly because "if it ain't broke don't fix it" but partly because who the heck has time?!
This week I needed to create a new environment to put together a demo of the Mobile side of OAM Mobile and Social and thought I'd take a few minutes to fix that. It didn't take all that long.
Here's my /etc/init/oid.conf
start on runlevel [345] # This is good for debugging purposes but it's a bad idea to leave # this on long term. #console output # this starts OPMN, OID and OVD pre-start script /bin/su - oracle -c "/home/oracle/middleware/asinst_1/bin/opmnctl startall" end script # and this stops them post-stop script /bin/su - oracle -c "/home/oracle/middleware/asinst_1/bin/opmnctl stopall" end script # note that I'm only starting the AdminServer here exec /bin/su - oracle -- /home/oracle/middleware/user_projects/domains/IDMDomain/bin/startWebLogic.shNote: Because this is a little test environment and I want to keep the memory down and don't need DIP or a bunch of other stuff I simply moved ODSM from wls_ods1 to the Admin Server. That lets me run OID and ODSM without needing to start the wls_ods1 managed server.
For those of you going a couple of items of interest:
There's a Meet and Greet with the Identity Management Team on Wednesday afternoon so if you're around please stop by.
My Hands On Lab (HOL10478) on Monday afternoon at the Marriott is currently fully booked but the weather looks like it's going to be amazing. If you haven't been able to get in you might want to try just showing up and see if anyone blows it off. If you're desperate to get in for some crazy reason send me an email or leave a comment here and I'll see if I can convince the room monitor to let a few extra people in.
There are a bunch of interesting sessions on the IdM track this year and unless I have booth duty or a meeting you'll probably find me sitting in the back of most those sessions. If you see me please say hi.
See you at OpenWorld!
####<Sep 13, 2012 6:19:42 PM EDT> <Error> <oracle.oam.engine.policy> <iamr2.oracleateam.com> <AdminServer> <[ACTIVE] ExecuteThread: '7' for queue: 'weblogic.kernel.Default (self-tuning)'> <weblogic> <> <e3b75e49ebb52881:-4d179e40:139c1939ab6:-8000-00000000000005a3> <1347574782661> <BEA-000000> <The policy store is not available; please see the log file for more details. oracle.security.am.common.policy.admin.store.PolicyStoreException: OAMSSA-06252: The policy store is not available; please see the log file for more details. at oracle.security.am.common.policy.util.OESUtils.checkAndThrowException(OESUtils.java:630) at oracle.security.am.common.policy.util.ResourceTypeHelper.setupHostIdentifierResourceType(ResourceTypeHelper.java:438) at oracle.security.am.common.policy.admin.provider.oes.DefaultApplicationDomain.createHostIdentifierPolicy(DefaultApplicationDomain.java:118) at oracle.security.am.common.policy.admin.provider.oes.DefaultApplicationDomain.<init>(DefaultApplicationDomain.java:93) at oracle.security.am.common.policy.admin.provider.oes.DefaultApplicationDomain.getGlobalDefault(DefaultApplicationDomain.java:461) at oracle.security.am.common.policy.admin.provider.oes.ApplicationManager.setupGlobalDefaultAppDomain(ApplicationManager.java:112) at oracle.security.am.common.policy.admin.provider.oes.ApplicationManager.<init>(ApplicationManager.java:61) at oracle.security.am.common.policy.admin.provider.oes.ApplicationManager.getApplicationManager(ApplicationManager.java:125) at oracle.security.am.common.policy.util.OESSetupHelper.loadOAMApplicationManager(OESSetupHelper.java:340) at oracle.security.am.common.policy.util.OESSetupHelper.loadOAMApplicationPolicies(OESSetupHelper.java:166) at oracle.security.am.common.policy.util.OESSetupHelper.loadApplicationPolicies(OESSetupHelper.java:154) at oracle.security.am.common.policy.admin.provider.oes.proxy.OESAdminProxy.init(OESAdminProxy.java:84) at oracle.security.am.common.policy.admin.provider.oes.OESPolicyAdminProvider.init(OESPolicyAdminProvider.java:130) at oracle.security.am.common.policy.admin.PolicyAdminFactory.getProvider(PolicyAdminFactory.java:241) at oracle.security.am.common.policy.admin.PolicyAdminFactory.init(PolicyAdminFactory.java:166) at oracle.security.am.common.policy.admin.PolicyAdminFactory.getPolicyAdmin(PolicyAdminFactory.java:334) ...And in the -diagnostic log:
[2012-09-13T18:19:42.364-04:00] [AdminServer] [NOTIFICATION] [] [oracle.adfdt.model.mds.MDSApplicationService] [tid: [ACTIVE].ExecuteThread: '7' for queue: 'weblogic.kernel.Default (self-tuning)'] [userId: weblogic] [ecid: e3b75e49ebb52881:-4d179e40:139c1939ab6:-8000-00000000000005a3,0] [APP: oam_admin#11.1.2.0.0] [[ oracle.mds.exception.ReadOnlyStoreException: MDS-01273: The operation on the resource /oracle/oam/ui/adfm/DataBindings.cpx failed because source metadata store mapped to the namespace / DEFAULT is read only. at oracle.mds.core.MDSSession.checkAndSetWriteStoreInUse(MDSSession.java:2495) at oracle.mds.core.MDSSession.checkAndSetWriteStoreInUse(MDSSession.java:2548) at oracle.mds.core.MDSSession.getMutableMO(MDSSession.java:3493) at oracle.mds.core.MDSSession.getMutableMO(MDSSession.java:1660) at oracle.mds.core.MDSSession.getMutableMO(MDSSession.java:1546) at oracle.adfdt.model.mds.MDSApplicationService.findApplication(MDSApplicationService.java:57) at oracle.adfdt.model.mds.MDSModelDesignTimeContext.initServices(MDSModelDesignTimeContext.java:232) at oracle.adfdt.model.mds.MDSModelDesignTimeContext.<init>(MDSModelDesignTimeContext.java:82) at oracle.adfdt.mds.MDSDesignTimeContext.<init>(MDSDesignTimeContext.java:66) at oracle.adfinternal.view.page.editor.Page.getDesignTimeBindingContainer(Page.java:596) at oracle.adfinternal.view.page.editor.contextual.event.ContextualModelManager.getBindingContainerForView(ContextualModelManager.java:209) at oracle.adfinternal.view.page.editor.contextual.event.ContextualModelManager.getCurrentContextualResolver(ContextualModelManager.java:131) at oracle.adfinternal.view.page.editor.bean.ContextualWiringBean.getResolver(ContextualWiringBean.java:625) at oracle.adfinternal.view.page.editor.bean.ContextualWiringBean.clearSelection(ContextualWiringBean.java:594) at oracle.adfinternal.view.page.editor.bean.ContextualWiringBean.handlePageNavigation(ContextualWiringBean.java:130) at oracle.adfinternal.view.page.editor.contextual.event.EventHandler.processNavigation(EventHandler.java:92) ...
In the olden days when you wanted to start a program when the machine booted there were a bunch of options. You could put it in /etc/inittab and let init handle it for you; but there were a bunch of problems with that. In recent vintages of Linux we have Sys-V (pronounced System Five) style init scripts where you'd write a shell script that took a command line option "start" or "stop" and started or stopped the service, then put that script in /etc/rc3.d with a name like S99myservice. Or better yet you'd tuck it into /etc/init.d and then symlink it to the right name in /etc/rc3.d (for example). If you were reasonably smart you'd put a "chkconfig" stanza at the top and let chkconfig do the symlinking for you. You still needed to write that script which basically meant a bunch of copy/pasting the same thing over and over. And you needed to make sure the process ran "in the background" which lead to lots of people using the "&" in really awful ways that made me feel dirty to see.
But I'm here to tell you that while that's all well and good, and you can still do that if you want under Oracle or RedHat Linux 6 you no longer have to.
In Ubuntu, RedHat and Oracle Linux there's a new flavor of init called Upstart that all the kids are using and it's the new hotness when it comes to making programs into daemons and wiring them to start and stop at appropriate times.
After using it for a little bit I think I might be in love. It is a pleasure to use compared to the (now) old way.
Say you want to start Node Manager every time the machine boots. To do that you just create a file named /etc/init/nodemanager.conf and put this in it the /etc/init directory.
start on runlevel [345] exec /bin/su - oracle -- /home/oracle/Oracle/Middleware/wlserver_10.3/server/bin/startNodeManager.shSubstitute oracle for whichever user you run the stuff as and adjust the path as needed for your particular environment.
Want to start the OAM Admin and Managed servers on boot?
Create a file named /etc/init/oamadminserver.conf:
start on runlevel [345] exec /bin/su - oracle -- /home/oracle/Oracle/Middleware/user_projects/domains/OAMDomain/bin/startWebLogic.shAnd /etc/init/oamserver1.conf:
start on runlevel [345] exec /bin/su - oracle -- /home/oracle/Oracle/Middleware/user_projects/domains/OAMDomain/bin/startManagedWebLogic.sh oam_server1
Reboot the machine and the OAM AdminServer and the Managed Server will come up automatically.
If you want to start, check the status of, or stop the service? It's super simple:
[root@r2d2 init]# start oamserver1 oamserver1 start/running, process 5573 [root@r2d2 init]# status oamserver1 oamserver1 start/running, process 5573 [root@r2d2 init]# stop oamserver1 oamserver1 stop/waitingAnd this is just scratching the surface of what you can do with Upstart.
You've got to try it out!
To get your very own copy from eDelivery:
Click that and scroll down to the bottom and you'll see the doc set:
One of the great things about the new doc set is the inclusion of ePub files. This means that if you have an iPad you can load up the doc library onto that and read the docs on the couch. On on a plane.
Or on the throne!
(just don't lend me your iPad afterwards please!)
You can pull the ePubs out of the zip directly or you can get them by opening the library's index, picking one of the docs inside and then looking in the upper right hand corner:
ENJOY!
Name
|
Type – Length
|
Description
|
USR_LOGIN
|
VARCHAR(20)
|
This field contains the login id of the
user whose profile contains the multi-value attribute.
|
USR_LINK_KEY
|
VARCHAR (6)
|
This field links the values of an attribute to the
specific user profile.
|
USR_LINK_FLD_NAME
|
VARCHAR(30)
|
The name of the Field. This is the same
value as the FIELD_ID column of table OIM_EXT_CUSTOM_FORMS_DEF described
later.
|
USR_LINK_VALUE_ID
|
INT
|
This field contains the index of the values. This is
also part of the primary key.
|
USR_LINK_FLD_VALUE
|
CLOB
|
Stores individual values in a sequence of
values for the multi-value attribute.
|
USR_LINK_FLD_SIZE
|
INT
|
The amount of characters allowed in the field values.
|
USR_RO_NAME
|
VARCHAR(30)
|
The name of the Resource Object whose
process form contains a child table that holds the values for this
multi-value attribute. This field may be NULL if the multi-value attribute is
not associated to any Resource Object.
|
USR_RO_CHD_TABLE
|
VARCHAR(30)
|
The name of the Child Table where the attribute
values will be contained.
|
Name
|
Type – Length
|
Description
|
PROCESS_KEY
|
VARCHAR (6)
|
This is a unique ID for the process.
|
PATH_ID
|
INT
|
This field stores the sequence number of approval
routes in an approval flow.
|
APPROVAL_SLIP
|
VARCHAR(500)
|
The field contains either a single Login ID
or a comma separated list of login IDs which represents the list of approvers
that will receive the request in the way determined by the ROUTING_TYPE.
|
ROUTING_TYPE
|
VARCHAR(20)
|
The type of Routing for the request. Valid values
are: SEQUENTIAL or PARALLEL.
|
ESCALATION_TIME
|
VARCHAR(20)
|
This is the time it will take for the
approver to process the request before it gets escalated. The value is
formatted according to the W3C notation for durations. Example: P1D (means
after one day or no response for the task). If NO-LIMIT is specified then the
escalation policy will be set P365D (1 year).
|
ESCALATION_USER
|
VARCHAR(20)
|
The Login ID of the user this will be escalated to.
|
TERMINAL_APPROVER
|
VARCHAR(3)
|
This value indicates if this approver’s
response terminates the approval flow immediately. Legal values are ‘Yes’ and
‘No’.
|
Name
|
Type – Length
|
Description
|
FORM_ID
|
VARCHAR (30)
|
This is a unique ID for the FORM.
|
FIELD_ID
|
VARCHAR(30)
|
This is a unique ID for a FORM Field.
|
FIELD_TYPE
|
VARCHAR(30)
|
The value of this field represents the HTML
control that will be used to input the value of the field.
|
FIELD_IS_MV
|
VARCHAR(3)
|
Flag that indicates whether the field is Multi-Valued
or Single Valued. Allowed values for this field are ‘Yes’ and ‘No’.
|