ヘッダーをスキップ
Oracle Identity Manager Audit Report開発者ガイド
リリース9.1.0
E05908-02
  目次
目次
索引
索引

戻る
戻る
 
次へ
次へ
 

A カスタム・ポストプロセッサのサンプル・コード

この付録のサンプルのポストプロセッサでは、Active Directory統合からグループ権限を取得します。Active Directory統合では、子表を使用してグループ・メンバーシップを格納します。

次のSQLスクリプトを使用して、必要な情報をレポート・データベースに格納するための表を作成します。


注意:

Microsoft SQL Serverは、Oracle Identity Managerリリース9.1.0ではサポートされていません。動作保証されているコンポーネントの詳細は、『Oracle Identity Managerリリース・ノート』の「動作保証されているコンポーネント」を参照してください。

CREATE SEQUENCE UPA_UD_ADUSRC_SEQ
INCREMENT BY 1
START WITH 1
CACHE 20

/*==============================================================*/
/* Table: UPA_UD_ADUSRC                                                                                      */
/*==============================================================*/
CREATE TABLE UPA_UD_ADUSRC (
  UPA_UD_ADUSRC_KEY                      NUMBER(19)       NOT NULL,
  UPA_RESOURCE_KEY                    NUMBER(19)       NOT NULL,
  OIU_KEY                          NUMBER(19)       NOT NULL,
  UD_ADUSRC_GROUPNAME         VARCHAR2(256)    NOT NULL,
  STATUS                                VARCHAR2(7),
  UPA_UD_ADUSRC_EFF_FROM_DATE  TIMESTAMP        NOT NULL,
  UPA_UD_ADUSRC_EFF_TO_DATE            TIMESTAMP,
  CREATE_DATE                              TIMESTAMP        NOT NULL,
  UPDATE_DATE                              TIMESTAMP        NOT NULL,
  CONSTRAINT PK_UPA_UD_ADUSRC PRIMARY KEY (UPA_UD_ADUSRC_KEY)
)

COMMENT ON TABLE UPA_UD_ADUSRC IS
'Stores AD group entitlements'

CREATE INDEX IDX_UPA_UD_ADUSRC_EFF_FROM_DT ON UPA_UD_ADUSRC (
   UPA_UD_ADUSRC_EFF_FROM_DATE ASC
)

カスタム・ポストプロセッサには次のコードを使用します。


package sample.audit.processor;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Statement;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.sql.Types;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import com.thortech.xl.audit.auditdataprocessors.CustomAuditDataProcessor;
import com.thortech.xl.audit.engine.AuditData;
import com.thortech.xl.audit.exceptions.AuditDataProcessingFailedException;
import com.thortech.xl.util.logging.LoggerMessages;

public class ADUserGroupMembershipProcessor extends CustomAuditDataProcessor {

    private static final String CHANGE_TAG = "Change";
    private static final String ATTRIBUTE_TAG = "Attribute";
    private static final String NAME_ATTRIBUTE = "name";
    private static final String CHANGE_LOCATION_ATTRIBUTE = "where";
    private static final String ACTION_ATTRIBUTE = "action";

    private static final String CHILD_DATA_PREFIX = "/Data";
    private static final String RESOURCE_DATA_PREFIX = "/ProcessData/Children/Child";
    private static final String RESOURCE_PROFILE_PREFIX = "/UserProfileSnapshot/ResourceProfile/ResourceInstance";

    private static final String AD_RESOURCE_NAME = "AD User";

    /*private static final String[] UPA_UD_ADUSRC_COLUMNS =
        {"UPA_UD_ADUSRC_KEY", "OIU_KEY", "UD_ADUSRC_KEY", "UD_ADUSRC_GROUPNAME",
         "UPA_UD_ADUSRC_EFF_FROM_DATE", "UPA_UD_ADUSRC_EFF_TO_DATE",
         "CREATE_DATE", "UPDATE_DATE"};*/

    public void processAuditData(Connection operationalDB,
            Connection reportingDB, List auditDataList, Timestamp auditEpoch)
            throws AuditDataProcessingFailedException {
        for (Iterator iter = auditDataList.iterator(); iter.hasNext();) {
            AuditData auditData = (AuditData) iter.next();
            // Retrieve data from AuditData value object
            //String auditeeID = auditData.getAuditeeID();
            List changeElements = getChangeElements(auditData.getChanges());
            // Retrieve AD User Group Membership related changes
            List ADUserGrpMembershipChangeElements =
                getADUserGroupMembershipChangeElements(changeElements);
            // Process change elements
            for (Iterator iterator = ADUserGrpMembershipChangeElements.iterator();iterator.hasNext();) {
                Element changeElement = (Element) iterator.next();
                // Retrieve the resource instance key (OIU_KEY) from the XPath expression
                long resourceInstanceKey = getResourceInstanceKey(changeElement);
                // Get the object name for this resource instance key
                String resName = getResourceName(auditData.getUpdatedSnapshot(), resourceInstanceKey);
                if(resName == null || !resName.equals(AD_RESOURCE_NAME))
                        continue;       // this is not the AD User resource so, skip it and check the next one...
                // Retrieve the child table key (UD_ADUSRC_KEY)
                long UDADUSRCKey = getUDADUSRCKey(changeElement);
                // Retrieve the current record, if present
                HashMap ADUserGroupMembershipProfile =
                    readADUserGroupMembershipData(reportingDB, resourceInstanceKey, UDADUSRCKey);
                // Reset the default columns
                ADUserGroupMembershipProfile.put("UPA_UD_ADUSRC_KEY",null);
                ADUserGroupMembershipProfile.put("OIU_KEY",null);
                ADUserGroupMembershipProfile.put("UD_ADUSRC_KEY",null);
                // Apply the changes
                String action = changeElement.getAttribute(ACTION_ATTRIBUTE);
                if (action.equalsIgnoreCase("Delete")) {
                    ADUserGroupMembershipProfile.put("STATUS","DELETE");
                } else {
                    ADUserGroupMembershipProfile.put("STATUS",action.toUpperCase());
                    Element groupNameElement =
                        getFirstChildElementByName(changeElement,ATTRIBUTE_TAG,NAME_ATTRIBUTE,"UD_ADUSRC_GROUPNAME");
                    Attribute attrDetails = getAttributeDetails(groupNameElement);
                    ADUserGroupMembershipProfile.put("UD_ADUSRC_GROUPNAME",attrDetails.getNewValue());
                }
                // Set values for the default columns
                ADUserGroupMembershipProfile.put("OIU_KEY",new Long(resourceInstanceKey));
                ADUserGroupMembershipProfile.put("UD_ADUSRC_KEY",new Long(UDADUSRCKey));
                ADUserGroupMembershipProfile.put("UPA_UD_ADUSRC_EFF_FROM_DATE", auditEpoch);
                ADUserGroupMembershipProfile.put("UPA_UD_ADUSRC_EFF_TO_DATE", null);
                ADUserGroupMembershipProfile.put("CREATE_DATE", new Timestamp(System.currentTimeMillis()));
                ADUserGroupMembershipProfile.put("UPDATE_DATE", new Timestamp(System.currentTimeMillis()));
                // Update existing active record if present
                updateActiveADUserGroupMembershipProfile(reportingDB, resourceInstanceKey, UDADUSRCKey, auditEpoch);
                // Insert new record
                insertNewADUserGroupMembershipProfile(reportingDB, ADUserGroupMembershipProfile);
            }
        }
    }

    private long insertNewADUserGroupMembershipProfile(Connection reportingDB,
            HashMap ADUserGroupMembershipProfile)
            throws AuditDataProcessingFailedException {
        long key = 0;
        try {
            String insertSQL =
                generateNewADUserGroupMembershipInsertSQL(reportingDB,ADUserGroupMembershipProfile);
            key = executeInsert(reportingDB, insertSQL, ADUserGroupMembershipProfile);
        } catch (SQLException e) {
            String errMsg = "Unable to insert new AD User Group Membership Profile";
            throw new AuditDataProcessingFailedException(errMsg,e);
        }
        return key;
    }

    private String generateNewADUserGroupMembershipInsertSQL(Connection reportingDB,
            HashMap ADUserGroupMembershipProfile) throws SQLException {
        String valuesPlaceHolder = "";
        String columnNames = "";
        String dbType = reportingDB.getMetaData().getDatabaseProductName();

        if (dbType.startsWith("Oracle")) {
            valuesPlaceHolder = "?, ";
            columnNames = "UPA_UD_ADUSRC_KEY, ";
        }

        for (Iterator iter = ADUserGroupMembershipProfile.keySet().iterator(); iter.hasNext();) {
            String columnName = (String) iter.next();
            Object columnValue = ADUserGroupMembershipProfile.get(columnName);
            if (!columnName.equals("UPA_UD_ADUSRC_KEY") && columnValue != null) {
                valuesPlaceHolder += "?, ";
                columnNames += columnName + ", ";
            }
        }

        // Trim the place holder variable and column names variable
        valuesPlaceHolder = (valuesPlaceHolder.trim()).substring(0,valuesPlaceHolder.length()-2);
        columnNames = (columnNames.trim()).substring(0,columnNames.length()-2);

        String insertSQL = "INSERT INTO UPA_UD_ADUSRC (" + columnNames + ") " +
                           "VALUES (" + valuesPlaceHolder + ")";

        return insertSQL;
    }

    private void updateActiveADUserGroupMembershipProfile(Connection reportingDB,
            long resourceInstanceKey, long UDADUSRCKey, Timestamp auditEpoch)
            throws AuditDataProcessingFailedException {
        String updateSQL = "UPDATE UPA_UD_ADUSRC " +
                              "SET UPA_UD_ADUSRC_EFF_TO_DATE=?" +
                            "WHERE OIU_KEY=?" +
                              "AND UD_ADUSRC_KEY=?" +
                              "AND UPA_UD_ADUSRC_EFF_TO_DATE is null";

        try {
            PreparedStatement pstmt = reportingDB.prepareStatement(updateSQL);
            pstmt.setTimestamp(1,auditEpoch);
            pstmt.setLong(2,resourceInstanceKey);
            pstmt.setLong(3,UDADUSRCKey);
            pstmt.executeUpdate();
        } catch (SQLException e) {
            String errMsg = "Failed to update active AD user group membership profile. " +
                            "Data in UPA_UD_ADUSRC could be inconsistent";
            if (dbLogger.isDebugEnabled())
                dbLogger.debug(errMsg,e);
            throw new AuditDataProcessingFailedException(errMsg, e);
        }

    }

    /**
     *
     * @param operationalDB
     * @param resourceInstanceKey
     * @param UDADUSRCKey
     * @return
     * @throws AuditDataProcessingFailedException
     */
    private HashMap readADUserGroupMembershipData(Connection reportingDB,
            long resourceInstanceKey, long UDADUSRCKey)
            throws AuditDataProcessingFailedException {
        String query = "SELECT * " +
                         "FROM UPA_UD_ADUSRC " +
                        "WHERE OIU_KEY=" + resourceInstanceKey + " " +
                          "AND UD_ADUSRC_KEY=" + UDADUSRCKey + " " +
                          "AND UPA_UD_ADUSRC_EFF_TO_DATE is null";
        try {
            return transformADUserGroupMembershipProfile(executeQuery(reportingDB, query));
        } catch (SQLException e) {
            throw new AuditDataProcessingFailedException("Unable to read data from " +
                    "JDBC resultset", e);
        } catch (Exception e) {
            String errMsg = "AD User Group Membership information stored in " +
                            "UPA_UD_ADUSRC is inconsistent";
            if (dbLogger.isDebugEnabled())
                dbLogger.debug(errMsg, e);
            throw new AuditDataProcessingFailedException(errMsg, e);
        }
    }

    /**
     *
     * @param result
     * @return
     * @throws Exception
     */
    private HashMap transformADUserGroupMembershipProfile(ResultSet result)
            throws Exception {
        HashMap ADUserGroupMembershipProfile = new HashMap();
        ResultSetMetaData metadata = result.getMetaData();

        // Move the cursor to the beginning of the resultset
        if (result.next()) {
            //
            for (int i = 0; i < metadata.getColumnCount(); i++) {
                Object columnValue = null;
                String columnName = metadata.getColumnName(i+1);
                int columnType = metadata.getColumnType(i+1);
                switch (columnType) {
                    case Types.INTEGER:
                        columnValue = new Long(result.getLong(i+1));
                        break;
                    case Types.VARCHAR:
                    case Types.CHAR:
                    case Types.LONGVARCHAR:
                        columnValue = result.getString(i+1);
                        break;
                    case Types.TIMESTAMP:
                        columnValue = result.getTimestamp(i+1);
                        break;
                    default:
                        columnValue = null;
                }
                if (result.wasNull()) {
                    columnValue = null;
                }
                ADUserGroupMembershipProfile.put(columnName, columnValue);
            }
            // Check if more than one record was returned. If so throw an exception
            if (result.next()) {
                String errMsg = "More than one active record found for AD group" +
                                result.getString("UD_ADUSRC_GROUPNAME");
                throw new Exception(errMsg);
            }
        }

        return ADUserGroupMembershipProfile;
    }

    /**
     *
     * @param changeElement
     * @return
     */
    private long getResourceInstanceKey(Element changeElement) {
        long resourceInstanceKey = 0;
        String changeLocation = changeElement.getAttribute(CHANGE_LOCATION_ATTRIBUTE);
        int keyStartPosition = changeLocation.indexOf(RESOURCE_PROFILE_PREFIX)+RESOURCE_PROFILE_PREFIX.length()+7;
        int keyEndPosition = keyStartPosition+changeLocation.substring(keyStartPosition).indexOf("'")-1;
        resourceInstanceKey = Long.parseLong(changeLocation.substring(keyStartPosition,keyEndPosition+1));
        return resourceInstanceKey;
    }

    /**
     *
     * @param changeElement
     * @return
     */
    private String getResourceName(Document snapshot, long resourceInstanceKey) {

        Element parentElement = snapshot.getDocumentElement();
        NodeList childNodes = parentElement.getChildNodes();

        for (int i = 0; i < childNodes.getLength(); i++) {
            Node childNode = childNodes.item(i);

            if ((childNode.getNodeType() == Node.ELEMENT_NODE) &&
                    childNode.getNodeName().equals("ResourceProfile")) {
                NodeList resourceProfileNodeList = childNode.getChildNodes();
                for (int j = 0; j < resourceProfileNodeList.getLength(); j++) {
                        Node resNode = childNodes.item(j);
                    if ((resNode.getNodeType() == Node.ELEMENT_NODE) &&
                                resNode.getNodeName().equals("ResourceInstance")) {
                        Element resourceInstanceElement = (Element)resNode;
                        String key = resourceInstanceElement.getAttribute("key");
                        if(key != null && Long.parseLong(key) == resourceInstanceKey)
                        {
                                Element name = getFirstChildElementByName(resourceInstanceElement, ATTRIBUTE_TAG, NAME_ATTRIBUTE, "Objects.Name");
                                return name.getFirstChild().getNodeValue();
                        }
                    }
                                }

            }
        }
        return null;
    }

    /**
     *
     * @param changeElement
     * @return
     */
    private long getUDADUSRCKey(Element changeElement) {
        long UDADUSRCKey = 0;
        String changeXPath = changeElement.getAttribute(CHANGE_LOCATION_ATTRIBUTE);
        String processDataXPath = changeXPath.substring(changeXPath.indexOf(RESOURCE_DATA_PREFIX));
        String childDataXPath = processDataXPath.substring(processDataXPath.indexOf(CHILD_DATA_PREFIX));
        int keyStartPosition = CHILD_DATA_PREFIX.length()+7;
        int keyEndPosition = keyStartPosition+childDataXPath.substring(keyStartPosition).indexOf("'")-1;
        UDADUSRCKey = Long.parseLong(childDataXPath.substring(keyStartPosition, keyEndPosition+1));
        return UDADUSRCKey;
    }

    /**
     *
     * @param changeElements
     * @return
     */
    private List getADUserGroupMembershipChangeElements(List changeElements) {
        List ADUserGrpMembershipChangeElements = new ArrayList();

        for (Iterator iter = changeElements.iterator(); iter.hasNext();) {
            Element change = (Element) iter.next();
            if (isChildrenData(change.getAttribute(CHANGE_LOCATION_ATTRIBUTE)))
                ADUserGrpMembershipChangeElements.add(change);
        }

        return ADUserGrpMembershipChangeElements;
    }

    /**
     *
     * @param attribute
     * @return
     */
    private boolean isChildrenData(String changeLocation) {
        if (changeLocation.startsWith(RESOURCE_PROFILE_PREFIX) &&
                changeLocation.indexOf(RESOURCE_DATA_PREFIX, RESOURCE_PROFILE_PREFIX.length()) > 0)
            return true;
        else
            return false;
    }

    /**
     *
     * @param connection
     * @param query
     * @return
     */
    protected ResultSet executeQuery(Connection connection, String query) {
        ResultSet result = null;
        try {
            Statement stmt = connection.createStatement();
            if (stmt.execute(query)) {
                result = stmt.getResultSet();
            }
        } catch (SQLException e) {
            if (dbLogger.isDebugEnabled()) {
                dbLogger.debug(LoggerMessages.getMessage("DBQueryExecutionError", query),e);
            }
        }
        return result;
    }

    /**
     *
     * @param connection
     * @param userGroupMembershipProfile
     * @param updateSQL
     */
    protected long executeInsert(Connection connection, String insertSQL,
            HashMap ADUserGroupMembershipProfile) throws SQLException {
        PreparedStatement insertStmt = connection.prepareStatement(insertSQL);
        String dbType = connection.getMetaData().getDatabaseProductName();

        long newKey = 0;
        int columnIndex = 1;
        //
        // Get new key for Oracle and set it into the prepared stmt
        if (dbType.startsWith("Oracle")) {
            ResultSet nextValRS = executeQuery(connection, "select UPA_UD_ADUSRC_SEQ.nextval from dual");
            long nextVal = nextValRS.getLong(1);
            insertStmt.setLong(columnIndex++,nextVal);
            newKey = nextVal;
        }

        // Set column names and values for other columns in UPA_UD_ADUSRC
        for (Iterator iter = ADUserGroupMembershipProfile.keySet().iterator(); iter.hasNext();) {
            String columnName = (String) iter.next();
            Object columnValue = ADUserGroupMembershipProfile.get(columnName);
            if (!columnName.equals("UPA_UD_ADUSRC_KEY") && columnValue != null) {
                if (columnValue.getClass().getName().endsWith("Long")) {
                    insertStmt.setLong(columnIndex++,((Long)columnValue).longValue());
                } else if (columnValue.getClass().getName().endsWith("String")) {
                    insertStmt.setString(columnIndex++,(String)columnValue);
                } else if (columnValue.getClass().getName().endsWith("Timestamp")) {
                    insertStmt.setTimestamp(columnIndex++,(Timestamp)columnValue);
                }
            }
        }

        insertStmt.executeUpdate();

        if (dbType.startsWith("Microsoft SQL Server")) {
            ResultSet nextValRS = executeQuery(connection, "select @@identity");
            long nextVal = nextValRS.getLong(1);
            newKey = nextVal;
        }
        return newKey;
    }
}