Thursday, April 30, 2015

ADF: JMX Data Control

Applicable to ADF 11.1.1.7.0 and Weblogic 10.3.6

Recently I had an requirement to display list of OID groups associated with user in OID(LDAP) in an ADF application. And I used JMX(Java Management Extensions) data control to perform query operations on OID configured in Weblogic server. Here is the steps I followed to develop it.

1. Create an ADF application and create JMX connection to weblogic server as shown below.
    URL Provider Path: /jndi/weblogic.management.mbeanservers.domainruntime


2. Create JMX Data Control as shown below.
   

Note: Select OID Provider under AdminServer. Don't select OID provider displaying directly under Security option.

3. Data Control will be displayed as shown below

    DataControl.dcx content:
    <?xml version="1.0" encoding="UTF-8" ?>
    <DataControlConfigs xmlns="http://xmlns.oracle.com/adfm/configuration"
                        version="11.1.1.64.93" id="DataControls"
                        Package="com.lkakarla.view">
    <AdapterDataControl id="UserAdminDC"
                        FactoryClass="oracle.adf.model.adapter.DataControlFactoryImpl"
                        ImplDef="oracle.adfinternal.model.adapter.jmx.JmxDataControlDef"
                        SupportsTransactions="true" SupportsSortCollection="false"
                        SupportsResetState="false" SupportsRangesize="true"
                        SupportsFindMode="true" SupportsUpdates="true"
                        Definition="JmxDataControl" BeanClass="JmxDataControl"
                        xmlns="http://xmlns.oracle.com/adfm/datacontrol">
      <Source>
        <JMXDCProperties xmlns="http://xmlns.oracle.com/adfm/adapter/jmx">
          <MBeanServerConnection connectionName="UserAdmin"/>
           <JMXBean displayName="myrealmOID"
                    objectName="Security:Name=myrealmOID,Location=AdminServer">
            <UpdatableOperations>
              <Operation name="listGroupMembers"/>
              <Operation name="listMemberGroups"/>
            </UpdatableOperations>
          </JMXBean>
        </JMXDCProperties>
      </Source>
     </AdapterDataControl>
   </DataControlConfigs>


4. Create a Page/Fragment and drag & drop method 'listMemberGroups' from Data Control to Page/Fragment. And Add following other methods as method bindings to Page definition. After adding the page definition will be dsipalyed as shown below.

   haveCurrent
   getCurrentName
   advance



5. Sample Page Code:

        <af:resource type="javascript">
          function onCb1EnterKey(event) {
              if (event.getKeyCode() == AdfKeyStroke.ENTER_KEY) {
                  var itField = event.getSource();
                  var btn1 = itField.findComponent('cb1');
                  var partialSubmit = true;
                  AdfActionEvent.queue(btn1, partialSubmit);
                  event.cancel();
              }
          }

        </af:resource>

      <af:showDetailItem text="Search User Roles" id="sdi546"
                       stretchChildren="first" styleClass="AFStretchWidth"
      <af:panelGroupLayout id="pgl2" styleClass="AFStretchWidth">
        <af:spacer width="10" height="10" id="s305"/>
        <af:panelBox text="Search User" id="pb1" styleClass="AFStretchWidth">
          <af:panelFormLayout id="pflu1" styleClass="AFStretchWidth">
            <af:panelLabelAndMessage label="Username" id="plam3" for="iuser1">
              <af:panelGroupLayout id="td1" layout="horizontal">
                <af:inputText id="iuser1"
                              binding="#{pageFlowScope.userBean.userName}"
                              placeholder="Enter User Email ID to Search"
                              autoSubmit="true">
                  <af:clientListener method="onCb1EnterKey" type="keyUp"/>
                </af:inputText>
                <af:spacer width="10" height="10" id="s10"/>
                <af:commandButton id="cb1"
                                  actionListener="#{pageFlowScope.userBean.searchGroups}"
                                  blocking="true" icon="/images/ico_search.png"
                                  text=" " partialSubmit="true"
                                  shortDesc="Click to Search Groups"/>
              </af:panelGroupLayout>
            </af:panelLabelAndMessage>
          </af:panelFormLayout>
        </af:panelBox>
        <af:spacer width="10" height="10" id="s1"/>
        <af:panelBox text="User Groups" id="pb14" styleClass="AFStretchWidth">
          <af:table value="#{pageFlowScope.userBean.userGrpList}" var="row"
                    rowBandingInterval="1" id="t2" partialTriggers="::cb1"
                    columnStretching="column:c1">
            <af:column sortable="false" headerText="Group Name" id="c1"
                       width="200">
              <af:outputText value="#{row.groupName}" id="ot7"/>
            </af:column>
          </af:table>
        </af:panelBox>
      </af:panelGroupLayout>
 
 
6. Sample Bean Code:

    import java.util.ArrayList;
    import java.util.List;
    import javax.faces.event.ActionEvent;
    import oracle.adf.model.BindingContext;
    import oracle.adf.view.rich.component.rich.input.RichInputText;
    import oracle.binding.BindingContainer;
    import oracle.binding.OperationBinding;

    private RichInputText userName;
    private String userGroup;
    private List<UserGroups> userGrpList;

    public void searchGroups(ActionEvent actionEvent) {

        Boolean haveCurrent = false;
        if (null != userGrpList) {
            userGrpList.clear();
        }
        userGrpList = new ArrayList();

        if (null == getUserName().getValue()) {
            System.out.println("User Name is NULL");
        } else {
            if (!getUserName().getValue().toString().isEmpty()) {
                System.out.println("User: " +
                                   getUserName().getValue().toString());
                setUserGroup(listMemberGroups(getUserName().getValue().toString().toLowerCase()));

                if (null != getUserGroup()) {
                    haveCurrent = haveCurrent(getUserGroup());
                    while (haveCurrent) {
                        String group = getCurrentName(getUserGroup());
                        userGrpList.add(new UserGroups(group));
                        advanceCur(getUserGroup());
                        haveCurrent = haveCurrent(getUserGroup());
                    }
                }
                System.out.println("User Group Size: " + userGrpList.size());
            }
        }
    }  
 
    public String listMemberGroups(String userName) {
        String cursor = null;
        BindingContext bctx = BindingContext.getCurrent();
        BindingContainer bindings = bctx.getCurrentBindingsEntry();

        OperationBinding listOp =
            bindings.getOperationBinding("listMemberGroups");

        listOp.getParamsMap().put("memberUserOrGroupName", userName);
        cursor = (String)listOp.execute();

        if (!listOp.getErrors().isEmpty()) {
            List errors = listOp.getErrors();
        }
        return cursor;
    }

    public Boolean haveCurrent(String cursor) {
        Boolean haveCurrent = false;
        BindingContext bctx = BindingContext.getCurrent();
        BindingContainer bindings = bctx.getCurrentBindingsEntry();

        OperationBinding haveCurrOp =
            bindings.getOperationBinding("haveCurrent");

        haveCurrOp.getParamsMap().put("cursor", cursor);
        haveCurrent = (Boolean)haveCurrOp.execute();

        if (!haveCurrOp.getErrors().isEmpty()) {
            List errors = haveCurrOp.getErrors();
        }
        return haveCurrent;
    }

    public String getCurrentName(String cursor) {
        String group = null;
        BindingContext bctx = BindingContext.getCurrent();
        BindingContainer bindings = bctx.getCurrentBindingsEntry();

        OperationBinding getNameOp =
            bindings.getOperationBinding("getCurrentName");

        getNameOp.getParamsMap().put("cursor", cursor);
        group = (String)getNameOp.execute();

        System.out.println("UserGroup: " + group);

        if (!getNameOp.getErrors().isEmpty()) {
            List errors = getNameOp.getErrors();
        }
        return group;
    }

    public void advanceCur(String cursor) {

        BindingContext bctx = BindingContext.getCurrent();
        BindingContainer bindings = bctx.getCurrentBindingsEntry();

        OperationBinding advanceOp = bindings.getOperationBinding("advance");
        advanceOp.getParamsMap().put("cursor", cursor);
        advanceOp.execute();
    }

    public void setUserName(RichInputText userName) {
        this.userName = userName;
    }

    public RichInputText getUserName() {
        return userName;
    }

    public void setUserGroup(String userGroup) {
        this.userGroup = userGroup;
    }

    public String getUserGroup() {
        return userGroup;
    }

    public void setUserGrpList(List<UserGroups> userGrpList) {
        this.userGrpList = userGrpList;
    }

    public List<UserGroups> getUserGrpList() {
        return userGrpList;
    }

   UserGroups Object:
   public class UserGroups {
       private String groupName;

       public UserGroups(String groupName) {
           this.setGroupName(groupName);
       }

       public void setGroupName(String groupName) {
           this.groupName = groupName;
       }

       public String getGroupName() {
           return groupName;
       }
   }