Wednesday, December 19, 2012

Steps to create a custom notification event in OIM 11g R2 and triggering it using OIMClient API


First step is to create a custom notification Event metadata. To achieve this create a custom event xml metadata file. For example if we want to define a custom notification when a user modifies his/her Challenge Questions the custom event xml file would look like:

<?xml version='1.0' encoding='UTF-8'?>
<Events xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../notification/metadata/NotificationEvent.xsd" xmlns="http://xmlns.oracle.com/oim/notificationevent">
<EventType name="SetChallengeQuestions">
<Resolver class="custom.oim.notification.setchallengequestions.SetChallengeQuestionsResolver">
<Param Name="SetChallengeQuestions" DataType="X2-Entity" EntityName="SetChallengeQuestions"/>
</Resolver>
</EventType>
</Events>

Note: you can save the xml file with any name but to avoid confusion we have named it SetChallengeQuestions.xml file
Now import this xml file using weblogicImportMetadata.sh file located at $OIM_ORACLE_HOME /server/bin
Note: Before executing weblogicImportMetadata.sh you need to modify the weblogic.properties located at $OIM_ORACLE_HOME/server/bin directory. The property file must have the below properties:

wls_servername=oim_server1
application_name = OIMMetadata
metadata_from_loc=/home/oracle/notification
metadata_to_loc=/home/oracle/notification
metadata_files=/metadata/iam-features-selfservice/notification/SetChallengeQuestions.xml

Run weblogicImportMetadata.sh script to import the metadata files.
Note: OIM_ORACLE_HOME environment variable must be set before running this command.

Now create a SetChallengeQuestionsResolver.java class compile it and create a jar file with this class file



 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
import java.util.Collections;
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.usermgmt.vo.User;
import oracle.iam.identity.utils.Utils;
import oracle.iam.notification.impl.NotificationEventResolver;
import oracle.iam.notification.vo.NotificationAttribute;
import oracle.iam.passwordmgmt.vo.Constants;
import oracle.iam.platform.Platform;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;


public class SetChallengeQuestionsResolver implements NotificationEventResolver{
    protected static final Logger logger= LoggerFactory.getLogger( SetChallengeQuestionsResolver.class);
    
    public List<NotificationAttribute> getAvailableData(String string,
                                                        Map<String, Object> map) {
        return Collections.emptyList();
    }

    public HashMap<String, Object> getReplacedData(String string, Map<String, Object> map) throws Exception{
        HashMap<String, Object> resolvedData = new HashMap();
        String userLoginId=null;
        Set<String> userRetAttrs = new HashSet<String>(); 
        if (!Utils.isMTFriendly()) {
            resolvedData.put("userLoginId", map.get("userLoginId"));         
        }
        else {
            resolvedData.put("userLoginId", map.get("Non MT User Login"));
            resolvedData.put("tenantName", map.get(Constants.TENANT_NAME));
        }
        
        userLoginId = String.valueOf(resolvedData.get("userLoginId"));           
        userRetAttrs.add("First Name");
        userRetAttrs.add("Last Name");
        UserManager userMgr = Platform.getService(UserManager.class); 
        User user;        
        user = userMgr.getDetails(userLoginId, userRetAttrs, true);
        
        logger.debug("First Name inside SetChallengeQuestionsResolver:   "+user.getFirstName());
        logger.debug("Last Name:   "+user.getLastName());    
        resolvedData.put("firstName", user.getFirstName());
        resolvedData.put("lastName", user.getLastName());       
         
        return resolvedData;
    }
}


Define a plugin.xml
<?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= "custom.oim.notification.setchallengequestions.SetChallengeQuestionsResolver" version="1.0" name="CustomSetChallengeQuestionsResolver"/>    
    </plugins>
</oimplugins>

Create a Zip file named setchallengequestionsresolver.zip file that contains the lib folder (which the jar file you have created earlier) Resources folder (empty) and the plugin.xml file
Copy the setchallengequestionsresolver.zip file to the $OIM_ORACLE_HOME/server/plugins directory.
Create a new email template for this event.
Login to OIM System Administration Console using the following URL. http://<OIM Server Hostname>:<OIM server Port>/sysadmin and the following connections page will appear as shown in the below screen shot.
Note 1: The OIM Server Hostname and OIM server Port values have to be replaced with actual values depending on the environment you are carrying out these steps.
Note 2: The sample URL for accessing OIM System Administration screen looks like this http://idmlab.com:14000/sysadmin.

Click on Notification under System Management and new window will open.
Click on Add Notification button and “Create Template” tab will appear.
Enter “Template Name” value as “SetChallengeQuestionsTemplate”, enter some description text, Select “SetChallengeQuestions” as the “Available Event”, Select “UTF-8” as the “Encoding”, “Message Subject” as “Information Updated”, “Type” as “HTML”, “Short Message” as “Information Updated”, and “Long message” as the below html text and then click Save.

<html><head></head>  <body>   
                    <p>
Dear $firstName $lastName,
</p> <p>
Your Challenge Questions and/or Answers were updated successfully. </p>
Thank you,<br/>

OIM

<p>
Please do not reply to this system generated E-mail.
</p>
</body></html>

A notification event can be triggered from different places in OIM. The logic behind the triggering must be coded and plugged into OIM. This sample triggers a notification event when the challenge questions are changed using OIMClient API. The sample code to change challenge questions and trigger notification is:



  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
    
 public boolean changeSecurityQuestions(String userLogin, String password, Map<String, Object> quesAns) throws Exception, UserAccountDisabledException, UserAccountInvalidException, NumberOfChallengesMismatchException, InvalidQuestionException {
 
  String oimURL = "t3://idmlab.com:14000";
  
     System.setProperty(JAVA_SECURITY_AUTH_LOGIN_CONFIG_KEY,"C:\\OIMClientTest\\config\\authwl.conf");
        System.setProperty("APPSERVER_TYPE", "wls");

        Hashtable<String, String> env = new Hashtable<String, String>();
        env.put(oracle.iam.platform.OIMClient.JAVA_NAMING_FACTORY_INITIAL, "weblogic.jndi.WLInitialContextFactory");
        env.put(oracle.iam.platform.OIMClient.JAVA_NAMING_PROVIDER_URL, oimURL);
        
        oracle.iam.platform.OIMClientoimClient = new oracle.iam.platform.OIMClient(env);
  
  
  UnauthenticatedSelfService unauthenticatedSelfService = OIMClientFactory.getUnauthenticatedSelfService(); 
  UserManager userManager = OIMClientFactory.getUserManager(); 
  NotificationService notificationService = oimClient.getService(NotificationService.class);  
  
        boolean flag = true;
  
        // changing the challenge questions for the user
        try {
            unauthenticatedSelfService.setChallengeValues(userLogin, password.toCharArray(), quesAns);
        } catch (UnauthenticatedSelfServiceException e) {
            logger.error(e.getMessage(),e);       
            Exception ex = new Exception(e.getMessage(), e);
            ex.setErrorMsgKey("ERROR_CHANGESECURITYQUESTIONS_UNAUTHENTICATEDSELFSERVICEEXCEPTION" ); 
            throw Exception ;
        } catch (UserAccountDisabledException e) {
            logger.error(e.getMessage(),e);       
            Exception ex=new Exception(e.getMessage(), e);
            ex.setErrorMsgKey("ERROR_CHANGESECURITYQUESTIONS_USERACCOUNTDISABLEDEXCEPTION" ); 
            throw Exception ;
        } catch (UserAccountInvalidException e) {
            logger.error(e.getMessage(),e);       
            Exception ex =new Exception(e.getMessage(), e);
            ex.setErrorMsgKey("ERROR_CHANGESECURITYQUESTIONS_USERACCOUNTINVALIDEXCEPTION" ); 
            throw Exception ;
        } catch (NumberOfChallengesMismatchException e) {
            logger.error(e.getMessage(),e);       
            Exception ex=new Exception(e.getMessage(), e);
            ex.setErrorMsgKey("ERROR_CHANGESECURITYQUESTIONS_NUMBEROFCHALLENGESMISMATCHEXCEPTION" ); 
            throw Exception ;
        } catch (InvalidQuestionException e) {
            logger.error(e.getMessage(),e);       
            Exception ex=new Exception(e.getMessage(), e);
            ex.setErrorMsgKey("ERROR_CHANGESECURITYQUESTIONS_INVALIDQUESTIONEXCEPTION" ); 
            throw Exception ;
        }        
         
        try {            
            logger.debug(" Successful login using admin account inside unauth.resetPassword() using  : "+userLogin); 
            userManager = oimClient.getService(UserManager.class);
            notificationService=oimClient.getService(NotificationService.class);  
        } catch (LoginException e) {
            logger.error(" Remote login failed  inside  UnAuthen.ResetPassword() !!!!!");
            logger.error(e.getMessage(),e);               
            Exception=new Exception(e.getMessage(), e);
            Exception.setErrorMsgKey("ERROR_RESETPASSWORD_LOGINEXCEPTION");  
            throw Exception;
        }
        
  
  // Triggering a notification Event
  
  NotificationEvent eventToSend;

        try {            
            eventToSend = createNotificationEvent(userManager,"SetChallengeQuestionsTemplate",userLogin);
            logger.debug("successfully created  notification event ");
        } catch (Exception e) {
            logger.error(e.getMessage(),e);               
            Exception ex=new Exception(e.getMessage(), e);
            ex.setErrorMsgKey("Exception while invoking createNotificationEvent() !"); 
            throw ex ; 
        }
        try {
            notService.notify(eventToSend);
            logger.debug("successfully  sent notification  ");
        } catch (EventException e) {
            logger.error(e.getMessage(),e);               
            Exception ex=new Exception(e.getMessage(), e);
            ex.setErrorMsgKey("Exception while invoking   notify() !"); 
            throw ex ;
        } catch (UnresolvedNotificationDataException e) {
            logger.error(e.getMessage(),e);               
            Exception ex=new Exception(e.getMessage(), e);
            ex.setErrorMsgKey("Exception while invoking   notify() !"); 
            throw ex ;
        } catch (TemplateNotFoundException e) {
            logger.error(e.getMessage(),e);               
            Exception ex=new Exception(e.getMessage(), e);
            ex.setErrorMsgKey("Exception while invoking   notify() !"); 
            throw ex ;
        } catch (MultipleTemplateException e) {
            logger.error(e.getMessage(),e);               
            Exception ex=new Exception(e.getMessage(), e);
            ex.setErrorMsgKey("Exception while invoking   notify() !"); 
            throw ex ;
        } catch (NotificationResolverNotFoundException e) {
            logger.error(e.getMessage(),e);               
            Exception ex=new Exception(e.getMessage(), e);
            ex.setErrorMsgKey("Exception while invoking   notify() !"); 
            throw ex ;
        } catch (UserDetailsNotFoundException e) {
            logger.error(e.getMessage(),e);               
            Exception ex=new Exception(e.getMessage(), e);
            ex.setErrorMsgKey("Exception while invoking   notify() !"); 
            throw ex ;
        } catch (NotificationException e) {
            logger.error(e.getMessage(),e);               
            Exception ex=new Exception(e.getMessage(), e);
            ex.setErrorMsgKey("Exception while invoking   notify() !"); 
            throw ex ;
        }
  
        logger.debug(" Updated  the qns an ans   successfully  : "  + flag);
        return flag;
    }

4 comments:

Safdar Ali said...

This is great. I really appreciate this. Thanks for sharing.

mass notifications

Unknown said...

OIM has out of box templates to send email right? But after deploying this the out of box template that sends mail once an user is created has stopped working(even after unregistering this) can you help out pls....

Unknown said...

NotificationEventResolver is in which jar file.. we are not getting any jar for this

Unknown said...

Hi Siva Kumar,
You can OIMServer jar. Please find the location of the jar is D:\d01\FMW\Middlleware\Oracle_IDM1\server\apps\was\oim.ear\APP-INF\lib\OIMServer.jar(for me this
)