Monday, July 29, 2013

Using Spring Managed Beans in ADF application


In one of previous blogs I have written about “Custom ADF Web application to search users in OIM 11g r2”. In the same sample I have introduced Usage of Spring Managed Beans in the Backing Beans. This is how i have achieved it.

First I have created a bus context xml file in Model Project which defines all the service layer beans as shown below:



<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
  <bean id="propertyConfigurer"
        class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
    <property name="locations">
      <list>
        <value>classpath*:customoimapp-services.properties</value>
      </list>
    </property>
  </bean>
  <bean id="oimConnectionFactory"
        class="oracle.iam.ui.custom.model.connection.OIMConnectionFactory">
    <property name="namingProviderURL"
              value="${customoimapp.JAVA_NAMING_PROVIDER_URL}"/>
    <property name="securityAuthLoginConfigKey"
              value="${customoimapp.JAVA_SECURITY_AUTH_LOGIN_CONFIG_KEY}"/>
  </bean>
  <bean id="oimService"
        class="oracle.iam.ui.custom.model.service.impl.OIMServiceImpl">
    <property name="oimConnectionFactory" ref="oimConnectionFactory"/>
    <property name="adminUserid" value="${customoimapp.adminUserid}"/>
    <property name="adminPassword" value="${customoimapp.adminPassword}"/>
  </bean>
</beans>


the properties file looks that has all the values defined is as follows:


customoimapp.JAVA_NAMING_PROVIDER_URL=t3://oimhome.com:14000
customoimapp.JAVA_SECURITY_AUTH_LOGIN_CONFIG_KEY=C:\\Software\\OIM_DESIGNCONSOLE\\designconsole\\config\\authwl.conf
customoimapp.adminUserid=xelsysadm
customoimapp.adminPassword=Passw0rd


OIMConnectionFactory class and OIMServiceImpl class looks like this:


package oracle.iam.ui.custom.model.connection;

import java.util.Hashtable;

import oracle.iam.platform.OIMClient;

public class OIMConnectionFactory {
    public OIMConnectionFactory() {
        super();
    }

    protected static final String JAVA_SECURITY_AUTH_LOGIN_CONFIG_KEY = "java.security.auth.login.config";
    private String namingProviderURL;
    private String securityAuthLoginConfigKey;

    public OIMClient init() {
        OIMClient oimClient = null;
        Hashtable env = new Hashtable();
        env.put(OIMClient.JAVA_NAMING_PROVIDER_URL, namingProviderURL);
        env.put(OIMClient.JAVA_NAMING_FACTORY_INITIAL, OIMClient.WLS_CONTEXT_FACTORY);
        System.setProperty("OIM.AppServerType", "wls");
        System.setProperty("APPSERVER_TYPE", "wls");
        System.setProperty(JAVA_SECURITY_AUTH_LOGIN_CONFIG_KEY, securityAuthLoginConfigKey);
        oimClient = new OIMClient(env);
        return oimClient;
    }


    public void setNamingProviderURL(String namingProviderURL) {
        this.namingProviderURL = namingProviderURL;
    }

    public void setSecurityAuthLoginConfigKey(String securityAuthLoginConfigKey) {
        this.securityAuthLoginConfigKey = securityAuthLoginConfigKey;
    }
}



OimServiceImpl Class:


package oracle.iam.ui.custom.model.service.impl;

import com.bea.security.providers.xacml.entitlement.parser.Users;

import oracle.iam.ui.custom.model.connection.OIMConnectionFactory;
import oracle.iam.ui.custom.model.service.OIMService;

import oracle.iam.ui.custom.model.service.bean.OIMUserBean;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;

import javax.security.auth.login.LoginException;

import oracle.iam.identity.exception.UserSearchException;
import oracle.iam.identity.usermgmt.api.UserManager;
import oracle.iam.identity.usermgmt.vo.User;
import oracle.iam.platform.OIMClient;
import oracle.iam.platform.entitymgr.vo.SearchCriteria;

public class OIMServiceImpl implements OIMService {
    public OIMServiceImpl() {
        super();
    }

    public static final String FIRST_NAME = "First Name";
    public static final String LAST_NAME = "Last Name";
    public static final String USER_LOGIN = "User Login";
    public static final String EMAIL = "Email"; 
    public static final String STARTROW = "STARTROW";
    public static final String ENDROW = "ENDROW";
    private OIMConnectionFactory oimConnectionfactory;
    private String adminUserid;
    private String adminPassword;

    /**
     * @param firstName
     * @param lastName
     * @return
     */
    public List<OIMUserBean> searchUsersInOIM(String firstName, String lastName){
        
        List<OIMUserBean> usersList = new ArrayList<OIMUserBean>();
        HashMap<String, Object> configParam = new HashMap<String, Object>();
        
        OIMClient oimClient = oimConnectionfactory.init();
        try {
            oimClient.login(adminUserid, adminPassword.toCharArray());
            System.out.println("Login Successful");
        } catch (LoginException e) {
            e.printStackTrace();
        }
        configParam.put(STARTROW, 0);
        configParam.put(ENDROW, 1000);
        String userLogin = null;
        List<User> users =null;
        
        System.out.println("Search Criteria: First Name entered is: " + firstName);
        System.out.println("Search Criteria: Last Name entered is: " + lastName);
        
        
        SearchCriteria searchCriteria = new SearchCriteria(FIRST_NAME, firstName+"*", SearchCriteria.Operator.EQUAL);
        SearchCriteria searchCriteria1 = new SearchCriteria(LAST_NAME, lastName+"*", SearchCriteria.Operator.EQUAL); 
        SearchCriteria searchCriteria2 = new SearchCriteria(searchCriteria,searchCriteria1, SearchCriteria.Operator.AND); 
        
        UserManager userManager = oimClient.getService(UserManager.class);

        try {
            users = userManager.search(searchCriteria2, null, configParam);
            System.out.println("Search Results: Size is: " + users.size());
        } catch (UserSearchException e) {
            e.printStackTrace();
        }
        if (users != null && users.size() > 0 ){
            for(User user : users){
                OIMUserBean userFromOIM = new OIMUserBean();
                userFromOIM.setFirstName((String)user.getAttribute(FIRST_NAME));
                userFromOIM.setLastName((String)user.getAttribute(LAST_NAME));
                userFromOIM.setUserId((String)user.getAttribute(USER_LOGIN));
                userFromOIM.setEMail((String)user.getAttribute(EMAIL));
                usersList.add(userFromOIM);
            }
        }
        System.out.println("Return Results: Size is: " + usersList.size());
        return usersList;
    }

    public void setOimConnectionfactory(OIMConnectionFactory oimConnectionfactory) {
        this.oimConnectionfactory = oimConnectionfactory;
    }


    public void setAdminUserid(String adminUserid) {
        this.adminUserid = adminUserid;
    }

    public void setAdminPassword(String adminPassword) {
        this.adminPassword = adminPassword;
    }
}


That concludes changes to the Model Project. Now coming to the View Project:

Added a beanRefContext.xml in View src folder

beanRefContext.xml definition:


<?xml version="1.0" encoding="UTF-8"?>

<!--
  - Application context definition for servicelayer-context.
  - Contains context & bean references in other context files
  - Author: Venkata Nunna
  - Created Date:07/26/2013
  -->
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd 
       http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">

        <bean id="servicelayer-context" class="org.springframework.context.support.ClassPathXmlApplicationContext">
      <constructor-arg>
        <list>
                        <value>CustomOIMAPP-bus-context.xml</value>
        </list>
      </constructor-arg>
   </bean>
</beans>

Added customoimapp-servlet.xml with empty definition. We can add beans that are specific to Web Layer if required here.



<?xml version="1.0" encoding="UTF-8"?>
<beans 
 xmlns="http://www.springframework.org/schema/beans" 
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
 xmlns:context="http://www.springframework.org/schema/context"
 xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd">
 
  
</beans>

Modfiy web.xml to load the context files:


<?xml version = '1.0' encoding = 'UTF-8'?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
         version="2.5" xmlns="http://java.sun.com/xml/ns/javaee">
  <context-param>
    <param-name>javax.faces.STATE_SAVING_METHOD</param-name>
    <param-value>client</param-value>
  </context-param>
  <context-param>
    <description>If this parameter is true, there will be an automatic check of the modification date of your JSPs, and saved state will be discarded when JSP's change. It will also automatically check if your skinning css files have changed without you having to restart the server. This makes development easier, but adds overhead. For this reason this parameter should be set to false when your application is deployed.</description>
    <param-name>org.apache.myfaces.trinidad.CHECK_FILE_MODIFICATION</param-name>
    <param-value>false</param-value>
  </context-param>
  <context-param>
    <description>Whether the 'Generated by...' comment at the bottom of ADF Faces HTML pages should contain version number information.</description>
    <param-name>oracle.adf.view.rich.versionString.HIDDEN</param-name>
    <param-value>false</param-value>
  </context-param>
  <context-param>
    <param-name>oracle.adf.view.rich.dvt.DEFAULT_IMAGE_FORMAT</param-name>
    <param-value>HTML5</param-value>
  </context-param>
  <context-param>
    <param-name>org.apache.myfaces.trinidad.FACELETS_VIEW_MAPPINGS</param-name>
    <param-value>*.xhtml</param-value>
  </context-param>
  <context-param>
    <param-name>facelets.SKIP_XML_INSTRUCTIONS</param-name>
    <param-value>true</param-value>
  </context-param>
  <context-param>
    <param-name>org.apache.myfaces.trinidad.ALTERNATE_VIEW_HANDLER</param-name>
    <param-value>org.apache.myfaces.trinidadinternal.facelets.TrinidadFaceletViewHandler</param-value>
  </context-param>
  <context-param>
    <param-name>facelets.DEVELOPMENT</param-name>
    <param-value>true</param-value>
  </context-param>
  <context-param>
    <param-name>facelets.SKIP_COMMENTS</param-name>
    <param-value>true</param-value>
  </context-param>
  <context-param>
    <param-name>facelets.DECORATORS</param-name>
    <param-value>oracle.adfinternal.view.faces.facelets.rich.AdfTagDecorator</param-value>
  </context-param>
  <context-param>
    <param-name>facelets.RESOURCE_RESOLVER</param-name>
    <param-value>oracle.adfinternal.view.faces.facelets.rich.AdfFaceletsResourceResolver</param-value>
  </context-param>
<!-- Spring Related Context --> <context-param> <param-name>contextConfigLocation</param-name> <param-value>/WEB-INF/customoimapp-servlet.xml</param-value> </context-param> <context-param> <param-name>locatorFactorySelector</param-name> <param-value>classpath*:beanRefContext.xml</param-value> </context-param> <context-param> <param-name>parentContextKey</param-name> <param-value>servicelayer-context</param-value> </context-param> <!-- Spring Related Content -->
<filter> <filter-name>JpsFilter</filter-name> <filter-class>oracle.security.jps.ee.http.JpsFilter</filter-class> <init-param> <param-name>enable.anonymous</param-name> <param-value>true</param-value> </init-param> </filter> <filter> <filter-name>trinidad</filter-name> <filter-class>org.apache.myfaces.trinidad.webapp.TrinidadFilter</filter-class> </filter> <filter> <filter-name>ServletADFFilter</filter-name> <filter-class>oracle.adf.share.http.ServletADFFilter</filter-class> </filter> <filter-mapping> <filter-name>JpsFilter</filter-name> <url-pattern>/*</url-pattern> <dispatcher>FORWARD</dispatcher> <dispatcher>REQUEST</dispatcher> <dispatcher>INCLUDE</dispatcher> </filter-mapping> <filter-mapping> <filter-name>trinidad</filter-name> <servlet-name>Faces Servlet</servlet-name> <dispatcher>FORWARD</dispatcher> <dispatcher>REQUEST</dispatcher> </filter-mapping> <filter-mapping> <filter-name>ServletADFFilter</filter-name> <servlet-name>Faces Servlet</servlet-name> <dispatcher>FORWARD</dispatcher> <dispatcher>REQUEST</dispatcher> </filter-mapping> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <listener> <listener-class>org.springframework.web.context.request.RequestContextListener</listener-class> </listener> <servlet> <servlet-name>Faces Servlet</servlet-name> <servlet-class>javax.faces.webapp.FacesServlet</servlet-class> <load-on-startup>1</load-on-startup> </servlet> <servlet> <servlet-name>resources</servlet-name> <servlet-class>org.apache.myfaces.trinidad.webapp.ResourceServlet</servlet-class> </servlet> <servlet> <servlet-name>BIGRAPHSERVLET</servlet-name> <servlet-class>oracle.adfinternal.view.faces.bi.renderkit.graph.GraphServlet</servlet-class> </servlet> <servlet> <servlet-name>BIGAUGESERVLET</servlet-name> <servlet-class>oracle.adfinternal.view.faces.bi.renderkit.gauge.GaugeServlet</servlet-class> </servlet> <servlet> <servlet-name>MapProxyServlet</servlet-name> <servlet-class>oracle.adfinternal.view.faces.bi.renderkit.geoMap.servlet.MapProxyServlet</servlet-class> </servlet> <servlet> <servlet-name>GatewayServlet</servlet-name> <servlet-class>oracle.adfinternal.view.faces.bi.renderkit.graph.FlashBridgeServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>Faces Servlet</servlet-name> <url-pattern>/faces/*</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>resources</servlet-name> <url-pattern>/adf/*</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>resources</servlet-name> <url-pattern>/afr/*</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>BIGRAPHSERVLET</servlet-name> <url-pattern>/servlet/GraphServlet/*</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>BIGAUGESERVLET</servlet-name> <url-pattern>/servlet/GaugeServlet/*</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>MapProxyServlet</servlet-name> <url-pattern>/mapproxy/*</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>resources</servlet-name> <url-pattern>/bi/*</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>GatewayServlet</servlet-name> <url-pattern>/flashbridge/*</url-pattern> </servlet-mapping> <mime-mapping> <extension>swf</extension> <mime-type>application/x-shockwave-flash</mime-type> </mime-mapping> </web-app>

Now coming to using the Spring Managed Beans in your Backing bean, this is how you achieve it:

Declare the Service bean in your Backing Bean and in the getter method use WebApplicationContextUtils to get the Spring Managed bean.

Backing Bean code:



package oracle.iam.ui.custom.app.view.backing.bean;

import java.io.Serializable;

import java.util.ArrayList;

import javax.faces.context.FacesContext;

import javax.servlet.ServletContext;

import oracle.adf.view.rich.component.rich.RichDocument;
import oracle.adf.view.rich.component.rich.RichForm;
import oracle.adf.view.rich.component.rich.data.RichTable;
import oracle.adf.view.rich.component.rich.input.RichInputText;
import oracle.adf.view.rich.component.rich.layout.RichPanelBox;
import oracle.adf.view.rich.component.rich.nav.RichCommandButton;
import oracle.adf.view.rich.component.rich.output.RichPanelCollection;
import oracle.adf.view.rich.component.rich.output.RichSeparator;

import oracle.adf.view.rich.context.AdfFacesContext;

import oracle.iam.ui.custom.model.service.OIMService;
import oracle.iam.ui.custom.model.service.bean.OIMUserBean;
import oracle.iam.ui.custom.model.service.impl.OIMServiceImpl;


import org.springframework.beans.BeansException;
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
import org.springframework.context.ApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;

public class SearchUsersBackingBean implements Serializable {

    private static final long serialVersionUID = 1L;
    private ApplicationContext ctx;
    private RichForm f1;
    private RichDocument d1;
    private RichPanelBox pb1;
    private RichInputText it1;
    private RichInputText it2;
    private RichCommandButton cb1;
    private ArrayList<OIMUserBean> usersList = null;
    private boolean showResults = false;
    private RichSeparator s1;
    private RichPanelCollection pc1;
    private RichTable t1;

    private OIMService oimService;

    public void setF1(RichForm f1) {
        this.f1 = f1;
    }

    public RichForm getF1() {
        return f1;
    }

    public void setD1(RichDocument d1) {
        this.d1 = d1;
    }

    public RichDocument getD1() {
        return d1;
    }

    public void setPb1(RichPanelBox pb1) {
        this.pb1 = pb1;
    }

    public RichPanelBox getPb1() {
        return pb1;
    }

    public void setIt1(RichInputText it1) {
        this.it1 = it1;
    }

    public RichInputText getIt1() {
        return it1;
    }

    public void setIt2(RichInputText it2) {
        this.it2 = it2;
    }

    public RichInputText getIt2() {
        return it2;
    }

    public void setCb1(RichCommandButton cb1) {
        this.cb1 = cb1;
    }

    public RichCommandButton getCb1() {
        return cb1;
    }

    public String searchUsersInOIM() {
        //OIMServiceImpl oimService = new OIMServiceImpl();
        usersList =
                (ArrayList<OIMUserBean>)this.getOimService().searchUsersInOIM((String)getIt1().getValue(),
                                                                    (String)getIt2().getValue());
        System.out.println("FirstName from UI: " + getIt1().getValue());
        System.out.println("LastName from UI: " + getIt2().getValue());
        //setDummyResults();
        if (usersList.size() > 0) {
            showResults = true;
        }
        return "success";
    }

    public void setUsersList(ArrayList usersList) {
        this.usersList = usersList;
    }

    public ArrayList getUsersList() {
        return usersList;
    }

    private void setDummyResults() {
        usersList = new ArrayList<OIMUserBean>();
        usersList.add(new OIMUserBean("Test1f", "Test1l", "TestUL1",
                                      "test1@test.com"));
        usersList.add(new OIMUserBean("Test2f", "Test2l", "TestUL2",
                                      "test2@test.com"));
    }

    public void setS1(RichSeparator s1) {
        this.s1 = s1;
    }

    public RichSeparator getS1() {
        return s1;
    }

    public void setPc1(RichPanelCollection pc1) {
        this.pc1 = pc1;
    }

    public RichPanelCollection getPc1() {
        return pc1;
    }

    public void setT1(RichTable t1) {
        this.t1 = t1;
    }

    public RichTable getT1() {
        return t1;
    }

    public void setShowResults(boolean showResults) {
        this.showResults = showResults;
    }

    public boolean isShowResults() {
        return showResults;
    }

    public void setOimService(OIMService oimService) {
        this.oimService = oimService;
    }

    public OIMService getOimService() {
        if (this.oimService == null)
            this.oimService = (OIMService)getBean("oimService");

        return oimService;
    }

    /**
     * Get the Spring-managed bean by name from the WebApplicationContext .
     *
     * @param name
     * @return
     * @throws BeansException
     */
    protected Object getBean(String name){
        if (ctx == null) {
            try {
                return WebApplicationContextUtils.getWebApplicationContext((ServletContext)FacesContext.getCurrentInstance().getExternalContext().getContext()).getBean(name);
            } catch (BeansException e) {
                System.out.println("Beans Exception" + e);
            }
        }
        try {
            return ctx.getBean(name);
        } catch (BeansException e) {
            System.out.println("Beans Exception" + e);
        }
        return null;
    }


}



Thursday, May 23, 2013

Error in Approval Details / SOA Worklist App Pages after adding a Catalog Custom UDF in OIM 11g R2

We have recently added a Custom Catalog UDF in OIM 11g R2 after which we are seeing an error on page whenever we access Approval Details or SOA Worklist App as shown in the screen shot below.


The stack trace in the OIM diagnostic log is as shown below:


ADF: Adding the following JSF error message: Localized message not available.  Error returned is: null[[
java.lang.NullPointerException
        at oracle.iam.ui.catalog.model.am.CatalogAMImpl.isAllCartItemsReadyToSubmit(CatalogAMImpl.java:252)
        at sun.reflect.GeneratedMethodAccessor1655.invoke(Unknown Source)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
        at java.lang.reflect.Method.invoke(Method.java:597)
        at oracle.adf.model.binding.DCInvokeMethod.invokeMethod(DCInvokeMethod.java:657)
        at oracle.adf.model.binding.DCDataControl.invokeMethod(DCDataControl.java:2143)
        at oracle.adf.model.bc4j.DCJboDataControl.invokeMethod(DCJboDataControl.java:3114)
        at oracle.adf.model.binding.DCInvokeMethod.callMethod(DCInvokeMethod.java:261)
        at oracle.jbo.uicli.binding.JUCtrlActionBinding.doIt(JUCtrlActionBinding.java:1635)
        at oracle.adf.model.binding.DCDataControl.invokeOperation(DCDataControl.java:2150)


In order to fix this issue we had to add keys in the CommonModelBundle.properties and CommonModelBundle_en.propertie files in adflibCommonModel.jar (adflibCommonModel.jar\oracle\iam\ui\common\model directory) file inside oracle.iam.ui.view.war (oracle.iam.ui.view.war\WEB-INF\lib directory) file.

For example if the UDF you have added is CustomCatalogUDF then the entries in the property file should look like

oracle.iam.ui.common.model.catalog.entity.CatalogItemsEO.customCatalogUDF_LABEL=CustomCatalogUDF
oracle.iam.ui.common.model.catalog.entity.CartItemsEO.customCatalogUDF_LABEL=CustomCatalogUDF

Copy the updated war file $OIM_ORACLE_HOME/server/apps directory stop OIM managed server, remove tmp and cache folders under the manager server directory and then restart the managed server.

Access the Approval Details / SOA Worklist APP pages and you should not see this error anymore.

Note: We have also modified the adflibCommonModel.jar file inside oracle.iam.ui.model.ear (oracle.iam.ui.model.ear\APP-INF\lib directory) file to add these keys in keys in the CommonModelBundle.properties and CommonModelBundle_en.propertie files. But modifying the view war is the step that fixed the issue for us.


Friday, May 3, 2013

DBAT CONNECTOR INSTALLATION AND SETUP


Create a lookup for User Status:
1.    Login to Design Console. 
2.    Expand Administration and double click on Lookup Definition.
3.    Enter “Lookup.DBAT.User.Status” for Code and “DBAT” for Group and then Click Save.  
4.    Add two new Lookup Codes and click Save as highlighted.
Note: Creating a lookup is not a mandatory step. It is used only if you are provisioning user status to the target database table.

Installing DBAT Connector: 
1.    Copy the Database_App_Tables_9.1.0.5.0 directory into $ORACLE_OIM_HOME/server/ConnectorDefaultDirectory folder
Note: replace $ORACLE_OIM_HOME with the OIM HOME directory.
2.    Login to OIM System Administration Console.
3.    Click on Manage Connector link.
4.    Click on Install.
5.    Select DatabaseApplicationTables 9.1.0.5.0 from the Connector List and Click Load.
6.    Click Continue.
7.    Click Exit on the Confirmation of Successful Connector Installation Page.

Configure Generic Technology Connector:
1.    Login to OIM System Administration Console.
2.    Click on the Generic Connector link.
3.    Click on Create.
4.    Enter Name as “DBAT_USR_CONNECTOR” or any name you want unselect Reconciliation check box and select Provisioning check box. Select “Database Application Tables Provisioning” for both Transport Provider and Format Provider under Provisioning and then click Continue.
5.    Enter the details of the target database, target table, Unique column, Status Column and Status lookup as "Lookup.DBAT.User.Status" created earlier and click next.
6.    Map the OIM attributes and Click Close.
7.    Enter “DBATUSR” for OIM – Account and click Continue.
8.    Verify the Connector information and click Save.

Run catalog sync scheduler job.
You can create an Access Policy to provision this resource automatically. For testing this you can manually add the DBAT_USR_CONNECTOR_GTC resource manually.