Thursday, July 21, 2011

OIM 11g Notifications

Notifications are one of the multiple features that were improved in OIM 11g release. The previous limitation of sending text based emails (out-of-the-box emails) only is gone.

Out-of-the-box templates for events like 'Reset Password', 'Create User Self Servic', 'User Deleted' are available and custom templates can be defined and used to send notifications out of OIM.

OIM provides a notification framework based on events, notification templates and template resolver. They are defined as follows:
  • Events are defined in a XML file and must be loaded into MDS database in order to be available for use.
  • Notification templates are defined through OIM advance administration console. The template contains the text and the substitution 'variables' that will be substituted by the data provided by the template resolver. Templates support HTML and text based emails and multiple languages.
  • Template resolver is a Java class that is responsible for providing the data to be used to parse the template, it must be deployed as an OIM plugin. The data provided by the resolver class will be used by OIM in the template substitution variables.
The main steps for defining custom notifications in OIM are:

  1. Define the Event that will be used for triggering the notification
  2. Define the Template to be formatted and sent
  3. Create the Template Resolver class
  4. Trigger the event from the relevant spot in OIM

This post explain each of the steps above and give some tips on how to create the notifications.



1. Defining the Event and its metadata

The Notification Event is defined through a XML file that must be loaded into MDS database. Also in MDS, there is a XSD that defines the tags and properties that the event XML may contain. The XSD is available at the following location in the MDS database:

/metadata/iam-features-notification/NotificationEvent.xsd

You can use the weblogicExportMetadata.sh script to export the XSD file.

Below an example of an event metadata definition:

<?xml version="1.0" encoding="UTF-8"?>
<Events xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../metadata/NotificationEvent.xsd">
  <EventType name="Demo Notification Event">
    <StaticData>
      <Attribute DataType="X2-Entity" EntityName="User" Name="User Login"/>
   <Attribute DataType="91-Entity" EntityName="User Group" Name="User Grp"/>
    </StaticData>
     <Resolver class="com.oracle.demo.oim.notification.DemoNotificationEventResolver">
      <Param DataType="X2-Entity" EntityName="User" Name="usr_login"/>
    </Resolver>
  </EventType>
</Events>

The property name in the tag EventType defines the event name, this is used in the OIM advanced administration UI. The StaticData session defines the entities (and their attributes) that can be used in the notification template, the entities attributes are used to define substitution tokens in the template. The resolver tag defines the Java class that OIM will invoke to provide the data to be used in the notification and the parameters that must be provided to the resolver class.

The XML must be loaded into the MDS database using the weblogicImportMetadata.sh script. You need to define resolver class name, but you don't need the class loaded in OIM just yet (it can be loaded later).

2. Defining the template

With the notification event defined in OIM, it is time to create the notification template based on that event. This action is done from the OIM advanced administration UI. The image below depicts the template created for this post:



Note that the template Demo Notification Event created in the previous step being used as the notification event.

Also note the Available Data dropdown and the Selected Data text field. The contents of the drop down are based on the event XML StaticData tag, the drop down basicly lists all the attributes of the entities defined in that tag. Once you select an element in the drop down, it will show up in the Selected Data text field and then you can just copy it and paste it into either the message subject or the message body fields. The picture below depicts this action:


It is important to mention that the Available Data and Selected Data are used in the substitution tokens definition only, they do not define the final data that will be sent in the notification. OIM will invoke the resolver class to get the data and make the substitutions.


3. Coding the notification resolver

The template resolver must implement the interface oracle.iam.notification.impl.NotificationEventResolver and provide actual implementation for the methods defined in the interface.

package com.oracle.demo.oim.notification;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import oracle.iam.identity.usermgmt.api.UserManager;
import oracle.iam.identity.vo.Identity;
import oracle.iam.notification.api.NotificationService;
import oracle.iam.notification.impl.NotificationEventResolver;
import oracle.iam.notification.vo.NotificationAttribute;
import oracle.iam.platform.Platform;

public class DemoNotificationEventResolver implements NotificationEventResolver{
    
    public DemoNotificationEventResolver() {}

   }
    public List<NotificationAttribute> getAvailableData(String eventType, Map<String, Object> map) {
        
        List<NotificationAttribute> list = 
new ArrayList<NotificationAttribute>();
        return list;
    }

    public HashMap<String, Object> getReplacedData(String eventType, Map<String, Object> eventParams) throws Exception {
        

        HashMap<String, Object> resolvedNotificationData = new HashMap<String, Object>();
        
        UserManager usrMgr = Platform.getService(UserManager.class);
        
        //getting the notfication parameter
        String userLogin = (String) eventParams.get("user_login");
        
        // Mapping token with their actual value for user attributes.
        if (userLogin != null) {
          
            NotificationService notificationService =  Platform.getService(NotificationService.class);
            //getting the list of all possible notification attributes
            List<NotificationAttribute> notificationAttributes =  notificationService.getStaticData(eventType);
            
            //seting the attributes for user search based on the notification attributes
            Set<String> userRetAttrs = new HashSet<String>();
            for (NotificationAttribute notificationAttribute :  notificationAttributes.get(0).getSubtree()) {
                userRetAttrs.add(notificationAttribute.getName());
            }
            
            //searching the user
            Identity user = usrMgr.getDetails(userLogin, userRetAttrs ,true);
            HashMap<String, Object> userAttributes = user.getAttributes();
            
            //setting the values in the resolved notification data Map
            String key = null;
            for (Map.Entry<String, Object>  entry : userAttributes.entrySet()) {
                
                key = entry.getKey();
                
                if (key != null) {
                    if ((entry.getValue() instanceof java.util.Map) && (key.equalsIgnoreCase(""))) {
                        key = key.replace(' ', '_');
                        resolvedNotificationData.put(key,  ((HashMap)entry.getValue()).get(""));
                    } 
                    else {
                        key = key.replace(' ', '_');
                        resolvedNotificationData.put(key, entry.getValue());
                    }
                }
           }
        }
        //returning the resolved data with all user information
        return resolvedNotificationData;
    }


This code must be deployed as an OIM plugin. The XML file defining the plugin is available below:

<?xml version="1.0" encoding="UTF-8"?>
<oimplugins xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <plugins pluginpoint="oracle.iam.notification.impl.NotificationEventResolver">
        <plugin pluginclass= "com.oracle.demo.oim.notification.DemoNotificationEventResolver" version="1.0" name="Demo Event Resolver"/>     
    </plugins>
</oimplugins>

4. Triggering the event

A notification event can be triggered from different spots in OIM. The logic behind the triggering must be coded and plugged into OIM. Some examples of spots for triggering notifications:
  • Event handlers: post process notifications for specific data updates in OIM users
  • Process tasks: to notify the users that a provisioning task was executed by OIM
  • Scheduled tasks: to notify something related to the task
In this post, a scheduled job was used to trigger the event. The scheduled job has two parameters:
  • Template Name: defines the notification template to be sent
  • User Login: defines the user record that will provide the data to be sent in the notification
 The scheduled job code:
package com.oracle.demo.oim.schedule;

import java.util.HashMap;

import oracle.iam.notification.api.NotificationService;
import oracle.iam.notification.vo.NotificationEvent;
import oracle.iam.platform.Platform;
import oracle.iam.scheduler.vo.TaskSupport;

public class NotificationDemoScheduledTask extends TaskSupport {
    
    public NotificationDemoScheduledTask() {
        super();
    }

    public void execute(HashMap taskParameters) {
  
        String templateName = (String)taskParameters.get("Template Name");
        String userId = (String)taskParameters.get("User Login");
        
        try {
            
            NotificationService notService = Platform.getService(NotificationService.class);
            NotificationEvent eventToSend = this.createNotificationEvent(templateName,userId);
            notService.notify(eventToSend);
            
        } catch (Exception e) {
            e.printStackTrace();
        }         
    }

    private NotificationEvent createNotificationEvent(String poTemplateName, String poUserId) {
        
        NotificationEvent event = new NotificationEvent();
        
        String[] receiverUserIds= {"xelsysadm"};       
        event.setUserIds(receiverUserIds);
        
        event.setTemplateName(poTemplateName);
        
        event.setSender(null);
        
        HashMap<String, Object> templateParams = new HashMap<String, Object>();
        templateParams.put("user_login",poUserId);

        event.setParams(templateParams);
        
        return event;
    }

    public HashMap getAttributes() {
        return null;
    }

    public void setAttributes() {}
}

The XML below that defines the scheduled task plugin:
<?xml version="1.0" encoding="UTF-8"?>
<oimplugins xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <plugins pluginpoint="oracle.iam.scheduler.vo.TaskSupport">
        <plugin pluginclass= "com.oracle.demo.oim.schedule.NotificationDemoScheduledTask" version="1.0" name="Notification Demo Task"/>     
    </plugins>
</oimplugins>

The XML below defines the scheduled task in OIM:
<?xml version='1.0' encoding='UTF-8'?>
<scheduledTasks xmlns="http://xmlns.oracle.com">
  <task>
    <name>Notification Task</name>
    <class>com.oracle.demo.oim.scheduled.NotificationDemoScheduledTask</class>
    <description>Notification Demo Task</description>
    <retry>5</retry>
    <parameters>
      <string-param required="true" helpText="Notification Template Name">Template Name</string-param>
    </parameters>
   </task>
</scheduledTasks>

5. Final comments
  • You should be able to easily deploy the samples above and get the custom OIM notification example working
  • Don't forget to configure the Email Server IT Resource instance in OIM. This configuration is required to send out  emails
  • If you develop from a Windows based laptop/desktop, you can install the Test Mail Server Tool. Then configure OIM Email Server IT Resource instance to point to it and it will show the notifications.
This post is part of the OIM 11g Academy. Check here for other OIM 11g posts.

43 comments:

  1. I don't understand, how did you create (define) new event?
    How did you import new xml event definition?
    Which paths did you use for importing?

    ReplyDelete
  2. It is all on step number #1

    You define the new event through the XML file. The XML will contain,among other things, the event name and the event resolver class.

    Then you use weblogicImportMetadata.sh script to load the XML into MDS database. The weblogicImportMetadata.sh script is available at $OIM_HOME/server/bin.

    ReplyDelete
  3. This comment has been removed by a blog administrator.

    ReplyDelete
    Replies
    1. There is a system property you can try:

      Request Notification Level

      Hope this helps

      Delete
    2. i am learning OIM . so would please let me what exactly the above program is doing..?
      i mean the workflow

      Thank you

      Delete
    3. The solution described above is an approach to send notifications out of OIM. There is a notification event definition, the notification resolver (which is the piece of code that provides the data to OIM put in the notification), and a scheduled task that actually triggers the notification.

      Delete
  4. This comment has been removed by the author.

    ReplyDelete
  5. Thanks for this post..it is very useful...

    I am trying to configure it, but while sending the notification, getting following error:

    [2012-03-26T15:33:38.575+05:30] [oim_server1] [ERROR] [] [HIG.LOGGER] [tid: [ACTIVE].ExecuteThread: '1' for queue: 'weblogic.kernel.Default (self-tuning)'] [userId: oiminternal] [ecid: 0000JPETW23Fg4WFLzrI8A1FS1BF00006Y,0] [APP: oim#11.1.1.3.0] [dcid: f0ed2a6d7fb07688:d3f276a:1364dcb5d26:-7ffd-00000000000001f0] oracle.iam.notification.exception.NotificationException: Cannot load the email service provider.[[
    at oracle.iam.notification.impl.NotificationServiceImpl.sendEmailNotification(NotificationServiceImpl.java:530)
    at oracle.iam.notification.impl.NotificationServiceImpl.notify(NotificationServiceImpl.java:319)
    at oracle.iam.notification.api.NotificationServiceEJB.notifyx(Unknown Source)


    Any idea about this error?

    ReplyDelete
    Replies
    1. I have not seen this error before. A few things to check:

      - Make sure that the Email Server IT resources is correctly configured
      - Make sure that OIM box can connect to SMTP server
      - Also, if you have OAM integration, make sure that OIM is capable of communicating with OAM

      Hope this helps

      Delete
  6. Hi,

    Looks like the above steps only applies to email notification. How can we configure OIM 11g to send an SMS notification?

    Does it supported?

    ReplyDelete
    Replies
    1. I do not think OIM natively supports SMS integration. But nothing prevents you from communicating with SMS gateways using Java APIs, and I do not think that would be a lot of work. Also I think some SMS providers accept incoming email messages and forward them as SMS messages, so I would check the specific SMS gateway you have to use for this feature.

      Delete
  7. Hi,

    I am using following product...

    IDM 11g (11.1.1.5.1), Backend Database Oracle 11gR2, Weblogic 1.3.5.

    I want to send the Email notification to the ResourceAuthorizers (my workflow is working fine, resource is getting approved and provisioned) i have enabled 'RequestNotificationLevel=1', and the Requester for 'Self-Request Resource' is getting all the notifications i.e 'Request Created' and 'Request Status Change' notifications.

    Its Only That the Approver is not getting any notification. What can be done to send the Notification to the Approver / Resource Authorizer in his mail box (just like requester) so that he knows that some request has been generated for his approval.

    Thanks and Regards.

    ReplyDelete
    Replies
    1. Zaffar,

      Such notifications are sent from SOA side. Check BPEL administration guide for the guidelines on how to configure them.

      Delete
    2. Hi Daniel,

      my Requirement is Similar to Zaffer. But I wanted to send notification in Multiple(Local Specific) Language. So cant we handle it in OIM.

      Thanks!!

      With Regards,

      Tushar.

      Delete
  8. Hi, I am trying to put large HTML content in the body of Email Template. But I am unable to save the content. When the content is small it get stored in body of Email Template.

    Question here is "Is there any Body Size restriction in the Email Template"?

    Suppose I want to put 2000 lines of Email Body..is it possible?
    Also, is there any character restriction while entering contents in the mail body? For Example: Assume like it does not support "#" etc

    ReplyDelete
    Replies
    1. I am not aware of any char restriction.

      But the size is limited to 4000 chars. That is the column size in the database.

      You can try to use custom notification resolvers and from there you can 'add' content to the email replacing the tokens for long texts.

      Delete
  9. I've installed Test Mail Server tool provided in the link. I am able to telnet Test Mail Server from my OIM machine. Then in OIM Admin UI I've changed Email Server parameters like "Server Name" to IP Address of Test Mail Server and "Authentication" to false. But I still don't see notifications to test mail server. I am testing default notification for Reset Password. In OIM logs I get error as "Sending Reset Password Notification is not successful". What other configurations do I need to perform?

    ReplyDelete
    Replies
    1. Yuva,

      Make sure that the system property is correctly configured. Also you either clean the cache or you restart the server after making the changes.

      Delete
  10. Hi, What is the advantage(s) of using this way of sending custom notifications over using tcEmailNotificationUtil API to send design console templates? There, template name is passed as a param and variables resolved to actual values. We will need to perform only steps 2 and 4 in that case.

    2. Define the Template to be formatted and sent
    4. Trigger the event from the relevant spot in OIM (scheduled task for instance)

    ReplyDelete
    Replies
    1. Hi Tarun,

      Some issues come mind: hhe old template format does not support HTML format. In the old format you do not have control over the data you want to add to the notification, you are restricted the the substitution variables that the Design Console offers. tcEmailNotificationUtil is not a published API.

      Thanks

      Delete
  11. I got the following exception:

    <Exit SendChallengeQuestionNotification sendNotificationToUser Exception:
    oracle.iam.notification.exception.NotificationResolverNotFoundException: Cannot find resolver for {0}.
    at oracle.iam.notification.impl.NotificationServiceImpl.processContentTags(NotificationServiceImpl.java:400)
    at oracle.iam.notification.impl.NotificationServiceImpl.getMessageContent(NotificationServiceImpl.java:363)

    ReplyDelete
    Replies
    1. Govind,

      It seems that there is some misconfiguration in your environment. But it is really hard to tell you exactly where.

      Delete
  12. Daniel Gralewski,

    I just want to have an email notification after a direct provisioning. When I add a resource to an end-user in the OIM Admin Console. How do I do it?

    ReplyDelete
    Replies
    1. Peter,

      You have a couple of different options here. But to leverage the 11g notification model you can trigger the notification from the 'Create User' task by extending the adapter associated to it. All you have to do is to add a piece of code to the adapter using the design console. In this code you can trigger the notification just like the example from this post.

      Delete
  13. Hi Daniel,

    I am at the Create User task for the Process Definition. Should I be updating the Notification tab and select Task Status Email Notification. I may need some steps here.

    Thanks,

    Peter..

    ReplyDelete
  14. Daniel Gralewski,

    I don't know if you got my last post or not. Anyway, I am at the Editing Task: Create User within a Process Definition. I see a notification tab. Should I Assign the Email Name: Task Status Email Notification and select User? I think I need some step..

    Thanks,

    Peter..

    ReplyDelete
    Replies
    1. Peter, that is one of the available options. But that option does not use the new HTML based notification engine. The documentation for this option is available at: http://docs.oracle.com/cd/E21764_01/doc.1111/e14309/promgt.htm#OMDEV2559

      Delete
  15. Hello Daniel Gralewski,

    This is a nice post and really helped me grasp the concept of oim11g notifications. I deployed the event and created the scheduler as said in your post. However, when I receive the email, the values are not getting substituted in the notification template. For example, the mail shows: First Name - $First_Name.

    Any help will be appreciated.

    Thanks,
    Maysun

    ReplyDelete
    Replies
    1. Maysun,

      I'm glad the post helps you to understand the concepts.

      Unfortunately is hard to say why the values are not being replaced. I would try to add some debug statements to the notification resolver. This will tell you whether or not it is being invoked and the data being set in the return Map.

      Hope this helps

      Daniel

      Delete
    2. Hello Daniel,

      Thanks for your reply.

      Yes, I did that and the problem seems to be that my userLogin variable in the Resolver class is null and hence is not entering the if loop that checks for the condition. It'd be really helpful if you could kindly summarize/recap the use of user login as there are more than one instance of it that is being used in both the java classes. The XML file uses usr_login, the Resolver class uses user_login while the Scheduled Job code uses USER_LOGIN.

      Thanks
      Maysun

      Delete
    3. Maysun,

      Thanks for pointing that. I fixed the code and the scheduled task is using 'user_login' now (in lowercase):


      HashMap templateParams = new HashMap();
      templateParams.put("user_login",poUserId);

      event.setParams(templateParams);

      Then the resolver is getting the data:

      //getting the notfication parameter
      String userLogin = (String) eventParams.get("user_login");

      Thanks again.

      Delete
  16. Daniel,

    Thanks for the useful post. I am new to 11gR2. I am building a NotificationEvent Schedule task. My requirement to send notification to new users and hence they can claim their account/identity. User will be allowed to select their customID while claim their account and the customID will translates in to their official email address (customID@domain.com).

    In custom field, I am recording users personal email address in OIM where I need to send the notification. But I coudln't find, how to set a custom field value(personal emailID field value) instead of OIM userIds!! Can you please guide me in right direction?

    String[] receiverUserIds= {"xelsysadm"};
    event.setUserIds(receiverUserIds);

    Regards
    Log

    ReplyDelete
    Replies
    1. Logu,

      Unfortunately I believe you hit some notification engine limitations. The APIs only take the 'user login' as 'receiver'. And the notification will be sent to whatever email is set in 'user email' attribute.

      But nothing prevents you from changing the 'user login' and 'user email' after the end user claims his/her account. So I would try to think in a solution along this line.

      Hope this helps

      Daniel

      Delete
  17. Thanks for the post Daniel. This has cleared a lot of things up for me.
    Ruth

    ReplyDelete
  18. Hey Daniel,
    Thanks for the great article.
    I want to send notification to the current logged in user, not xelsysadm.
    How can I achieve that?

    thanks

    ReplyDelete
    Replies
    1. Sjit,

      If you are running OIM 11g R2, you can use EL expressions to get the current logged in user and trigger the notification:

      Check section 30.4.1.1 at http://docs.oracle.com/cd/E27559_01/dev.1112/e27150/uicust.htm

      Hope this helps

      Daniel

      Delete
  19. Hi Daniel

    I have just owned a OIM 11.1.1.5.2 system.
    I think the system is setup with OOTB box reset password notification.

    When a password is reset for a used a notification is sent with random password but the random password is sent is not what gets set in OIM.

    Also when administrator fills in the password the notification is sent with the random password which is not same as the password administrator provided.

    Now i looked that the reset password template it is configured with $password and their is no avialble data or selected data showing.
    I tried to add another attribute $usr_password (eventhough template doesnot show available data drop down) in the template but email sent doesnot get it value and in the sent email.

    My question is does the OIM OOTB reset password notifiction require some changes to work. If yes,what changes do i need to make.Why is their no available data on change password notification.If you give me pointers on how to diagnose that would also help.
    Can oracle support help ??


    Regard
    Anuj

    ReplyDelete
  20. Hi Daniel
    Is their a way I can add email id in cc through notification api.
    Any way you can suggest where in I can have send the notification to another person as cc exmaple notifying user change in his role or org and ccing the mail to his manager or managers as well.
    otherwise I will have to create two notification one for user and one for manager which doesnot seem right

    ReplyDelete
    Replies
    1. Anuj,

      As far as I know, there is no option for cc.

      Delete
    2. Thanks Daniel for the quick response


      I would appreciate if you could please help me with OOTB reset password notification behavior. OIM sends out emaill's on reset paasword (OOTB)with wrong password.

      Problems:
      1) And the password in email is not the same as what has been set in DB in both administrator reset password and second option where in auto password generate is selected ???
      I decompiled souce code and found in oracle.iam.passwordmgmt.eventhandlers.ResetPasswordActionHandler i saw
      ----
      String generatedPassword = CryptoUtil.decrypt(encryptedPassword, "DBSecretKey");
      ----

      Is this a bug or Oracle expects all the users to rewrite the action handler for reset password notification to work.
      Also if i have to write this where can i find the DBSecret

      2) How is the sequence decided when administrator select the check box auto generate the password??

      Apologies again if I am asking basic question but I wanted to confirm if their is an easier option that you have found or used.

      Delete
    3. Anuj,

      If an administrator selects the 'auto generate' in the password reset, OIM will generate a random password, set it in the USR table and send it out in the email. Keep in mind that the password in the USR table is encrypted, so you will not be able to read the value; whereas the password in the email is sent in clear text.

      If the administrator does not select the 'auto generate', then he/she will have to enter the password value. Everything else is the same.

      If you are seeing a different behavior, either there is something wrong with your environment or you are hitting a bug. If that's the case, I recommend you to work with Oracle Support.

      Hope this helps



      Delete
  21. Can we use it to send notification to member of OIM group on completion of provisioning task?

    ReplyDelete
    Replies
    1. Pallavi,

      You can have a code within the task to trigger the notification.

      But you cannot directly associate the notification to the task completion.
      Hope this helps

      Delete

Note: Only a member of this blog may post a comment.