Benutzerdefinierte Skripte für Datenbankanwendungstabellen (MSSQL) mit Groovy entwickeln

Überblick über benutzerdefiniertes Skripting für Datenbankanwendungstabellen (MSSQL)

Wenn Sie Accounts in Oracle Access Governance mit der Integration "Datenbanktabellen" bereitstellen, werden Vorgänge wie Erstellen, Aktualisieren und Löschen mit dem standardmäßig bereitgestellten Code implementiert. In Fällen, in denen Sie die standardmäßig bereitgestellten Vorgänge ändern möchten, können Sie optional eigene benutzerdefinierte Skripte bereitstellen, die Ihre eigenen spezifischen Provisioning-Vorgangsanforderungen implementieren. Dieser Schritt ist völlig optional. Sie müssen keine benutzerdefinierten Skripte erstellen, wenn die Standardvorgänge Ihnen die erforderlichen Informationen liefern. Sie können benutzerdefinierte Skripte zu allen unterstützten Vorgängen hinzufügen. Wenn Sie benutzerdefinierte Skripte auswählen, müssen Sie sie nur dort hinzufügen, wo der Standardvorgang geändert werden muss. Sie können eine Kombination aus benutzerdefinierten und Standardskripten für die unterstützten Vorgänge verwenden, obwohl Sie für jeden bestimmten Vorgang nur eine oder die andere Option haben können. Beispiel: Der Vorgang create wird möglicherweise mit einem benutzerdefinierten Skript implementiert, das Ihrer Organisation bestimmte Funktionen hinzufügt, während der Vorgang delete unverändert bleibt und die Standardfunktionalität verwendet.

Nachdem Sie die Datenbankanwendungstabellen für die Verwendung eines benutzerdefinierten Skripts implementiert und konfiguriert haben, wird dieses Skript verwendet, wenn Sie das nächste Mal einen Provisioning- oder Dataload-Vorgang ausführen.
Hinweis

Jedes benutzerdefinierte Skript muss im Groovy-Format implementiert werden. Andere Scripting-Formate werden nicht unterstützt.
Wenn Sie ein orchestriertes System für Datenbankanwendungstabellen erstellen, können Sie Skripte identifizieren, die für eine Reihe von Provisioning-Vorgängen in der Datenbankanwendung ausgeführt werden sollen, die Accountdaten enthalten. Diese Vorgänge sind:
  • Erstellen
  • Aktualisieren
  • Löschen
  • Dataload
  • Beziehungsdaten hinzufügen
  • Beziehungsdaten entfernen
Diese Skripte müssen sich auf dem Agent-Host im Installationsverzeichnis des Agent befinden. Beispiel: /app/<custom script> . Sie konfigurieren den Agent mit dem Speicherort der Skripte in den Integrationseinstellungen für das orchestrierte System. Stellen Sie sicher, dass der Betriebssystembenutzer, auf dem der Agent ausgeführt wird, über Lese-/Schreibberechtigungen für benutzerdefinierte Skripte verfügt.
Wenn Sie eine Provisioning-Aufgabe ausführen, wird das Skript als Ersatz für die Standardverarbeitung ausgeführt, die mit der Aufgabe verknüpft ist. Das Skript muss die Standard-Provisioning-Aufgabe wie "Erstellen" oder "Aktualisieren" verarbeiten und kann auch benutzerdefinierte Aufgaben über den Standard-Provisioning-Prozess hinaus haben, wie z.B.:
  • Benutzerdefinierte Tabellenaktualisierungen ausführen
  • Benutzerdefiniertes Auditing
  • Benutzerdefinierte Benachrichtigungen senden
Das bedeutet, dass Sie zwei Optionen für das Provisioning der Verarbeitung mit der Integration von Datenbankanwendungstabellen haben:
  1. Standardlogik verwenden, die mit dem Connector {\b Database Application Tables} bereitgestellt wird
  2. In Skripten implementierte benutzerdefinierte Logik verwenden
Benutzerdefinierte Skripte werden nur verwendet, wenn sie in Ihrem orchestrierten System konfiguriert sind. Wenn Sie also beim Erstellen des orchestrierten Systems ein Erstellungsskript angegeben haben, aber kein Skript zum Aktualisieren vorhanden ist, wird das benutzerdefinierte Skript für die Aufgabe "Provisioning erstellen" verwendet, während die Aktualisierungsaufgabe mit der Standard-Connector-Verarbeitung implementiert wird.

Beachten Sie außerdem, dass alle benutzerdefinierten Skripttypen für ein orchestriertes System unterstützt werden, das für den Modus des verwalteten Systems konfiguriert ist. Der einzige Skripttyp, der für den zuverlässigen Quellmodus unterstützt wird, ist der Dataload-Typ, der für beide Modi unterstützt wird.

Beispieldatenbankschema

Die in den folgenden Abschnitten bereitgestellten Beispiele basieren auf den in diesem Abschnitt beschriebenen Datenbanktabellen.

MYDBAT_PERSON

USE {dataBase};
CREATE TABLE MYDBAT_PERSON
  (USERID INT IDENTITY(1, 1) NOT NULL PRIMARY KEY,
   USERNAME VARCHAR(50) NOT NULL,
   FIRSTNAME VARCHAR(50),
   LASTNAME VARCHAR(50),
   EMAIL VARCHAR(50) NOT NULL,
   COUNTRYCODE VARCHAR(20),
   DESCRIPTION VARCHAR(MAX),
   SALARY MONEY,
   JOININGDATE DATE,
   STATUS VARCHAR(20) NOT NULL,
   PASSWORD VARCHAR(MAX));

MYDBAT_GROUPS

USE {dataBase};
   CREATE TABLE MYDBAT_GROUPS
   (GROUPID VARCHAR(50) NOT NULL PRIMARY KEY,
   GROUPNAME VARCHAR(50) NOT NULL);

MYDBAT_ROLES

USE {dataBase};
   CREATE TABLE MYDBAT_ROLES
   (ROLEID varchar(50) NOT NULL PRIMARY KEY,
   ROLENAME varchar(50) NOT NULL);

MYDBAT_PERSON_GROUP

USE {dataBase};
   CREATE TABLE MYDBAT_PERSON_GROUP
   (USERID INT NOT NULL,
   GROUPID VARCHAR(50) NOT NULL,
   CONSTRAINT MYDBAT_PERSON_GROUP_PK PRIMARY KEY (USERID, GROUPID),
   CONSTRAINT MYDBAT_PERSON_FK1 FOREIGN KEY (USERID)
     REFERENCES MYDBAT_PERSON (USERID),
   CONSTRAINT MYDBAT_GROUPS_FK1 FOREIGN KEY (GROUPID)
     REFERENCES MYDBAT_GROUPS (GROUPID));

MYDBAT_PERSON_ROLE

USE {dataBase};
   CREATE TABLE MYDBAT_PERSON_ROLE  
   (USERID INT NOT NULL,
   ROLEID VARCHAR(50) NOT NULL,
   FROMDATE DATE,
   TODATE DATE,
   CONSTRAINT MYDBAT_PERSON_ROLE_PK PRIMARY KEY (USERID, ROLEID),
   CONSTRAINT MYDBAT_PERSON_FK2 FOREIGN KEY (USERID)
     REFERENCES MYDBAT_PERSON (USERID),
   CONSTRAINT MYDBAT_ROLES_FK1 FOREIGN KEY (ROLEID)
     REFERENCES MYDBAT_ROLES (ROLEID));

MYDBAT_COUNTRY

USE {dataBase};
   CREATE TABLE MYDBAT_COUNTRY
   (COUNTRYCODE VARCHAR(20) NOT NULL PRIMARY KEY,
   COUNTRYNAME VARCHAR(200) NOT NULL);
Hinweis

Für untergeordnete Tabellen wie mydbat_roles, mydbat_groups und mydbat_country muss ein Primärschlüssel-Constraint definiert sein. Wenn kein Primärschlüssel für untergeordnete Tabellen definiert ist, verläuft die Validierung nicht erfolgreich, und es wird ein Fehler angezeigt: Schlüssel für Tabelle <tablename> sind nicht definiert.

Groovy-Skriptargumente

Die folgenden Argumente können in Groovy-Skripten verwendet werden:

Skript-Argumente
Argument Beschreibung
Connector Das Connector-Objekt {\b Database Application Tables}.
Timing

Wenn das Groovy-Skript aufgerufen wird. Das timing-Attribut erläutert auch den Typ des ausgeführten Vorgangs. Beispiel: Wenn es sich um einen Suchvorgang handelt, wird auch die Objektklasse zurückgegeben, die durchsucht wird.

Das Format des Zeitarguments für die Lookup-Feldsynchronisierung lautet:
executeQuery:OBJECT_CLASS
In diesem Format wird OBJECT_CLASS durch den Typ des abzustimmenden Objekts ersetzt.
Beispiel: Bei einem geplanten Job für die Lookup-Feldsynchronisierung, der den Objekttyp Rolle enthält, lautet der Wert des Timingarguments wie folgt:
executeQuery:Role
Attribute Alle Attribute.
Trace Logger als Script Trace Bridge zur Anwendung
wobei Zeichenfolge mit Bedingung für "Abfrage ausführen" oder Null.
Handler resultSetHandler oder SyncResultsHandler für die Connector-Objekte, die von der Ausführungsabfrage, dem Synchronisierungsvorgang oder der Nullrückgabe erzeugt werden.
Angebotserstellung Der Typ des Tabellennamens, der in SQL verwendet wird. Der Standardwert ist eine leere Zeichenfolge. Der Wert dieses Arguments wird aus den Integrationseinstellungen abgerufen.
nativeTimestamps Gibt an, ob das Skript die Zeitstempeldaten der Spalten als Typ java.sql.Timestamp aus der Datenbanktabelle abruft. Diese Informationen werden aus den Integrationseinstellungen abgerufen.
allNative Gibt an, ob das Skript den Datentyp der Spalten in einem nativen Format aus der Datenbanktabelle abrufen muss. Der Wert dieses Arguments wird aus den Integrationseinstellungen abgerufen. Der Wert dieses Arguments gibt an, ob das Skript Ausnahmen auslösen muss, wenn ein Null-Fehlercode (0x00) aufgetreten ist.
enableEmptyString Gibt an, ob die Unterstützung für das Schreiben einer leeren Zeichenfolge anstelle eines NULL-Wertes aktiviert werden muss. Der Wert dieses Arguments wird aus den Integrationseinstellungen abgerufen.
filterString Zeichenfolgenfilterbedingung für "Abfrage ausführen" oder Null.
filterParams Liste der Filterparameter. Jeder Parameter ist im Format COLUMN_NAME:VALUE vorhanden. Beispiel: FIRSTNAME:test.
Synchronisierungsattribute Name der Datenbankspalte, die für die inkrementelle Abstimmung konfiguriert ist. Dieses Argument ist im Synchronisierungsskript verfügbar, das während einer inkrementellen Abstimmungsausführung aufgerufen wird.
Synctoken Wert des Synchronisierungsattributs. Dieses Argument ist im Synchronisierungsskript verfügbar.

Beispiel für Dataload-Skript

Das Dataload-Skript liest die Daten aus allen Tabellen für alle definierten Entitys. In diesem Szenario bezieht sich der Begriff Dataload auf den vollständigen Dataload und den Lookup-Dataload.

Dieses Beispielskript liest Benutzerdaten aus der Tabelle MYDBAT_PERSON und die Beziehungsdaten der Benutzer aus den Tabellen MYDABAT_PERSON_ROLE und MYDBAT_PERSON_GROUP. Berechtigungsdaten werden aus der Tabelle MYDBAT_GROUPS gelesen, und Lookup-Daten werden aus der Tabelle MYDBAT_COUNTRY gelesen. Außerdem wird eine einfache Filtersuche in der Tabelle MYDBAT_PERSON unterstützt. Alle diese Daten werden mit Stored Procedures gelesen.

Dataload-Skript

import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.ResultSet;
import java.math.*;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import org.identityconnectors.framework.common.objects.*;
import java.lang.reflect.*;
import org.identityconnectors.common.security.GuardedString;
import java.text.*;
 
String ocName ;
var df = new SimpleDateFormat("yyyy-MM-dd");
var targetFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss z");
if( timing != "") {
    trace.info("[Execute Query] timing attribute value: "+ timing);
    ocName = timing.split(":")[1]
}
     
trace.info("[Execute Query] for objectClass: "+ ocName);
switch (ocName) {
    //Lookup
    case "MYDBAT_COUNTRY":
        CallableStatement callableStatement = null;
        ResultSet resultSet = null;
        try {
            callableStatement = conn.prepareCall("{call GET_COUNTRIES}");
            resultSet = (ResultSet) callableStatement.executeQuery();
             
            while (resultSet.next()) {
                var cob = new ConnectorObjectBuilder();
                cob.setObjectClass(new ObjectClass("MYDBAT_COUNTRY"));
                cob.addAttribute(AttributeBuilder.build(Uid.NAME, resultSet.getString(1)));
                cob.addAttribute(AttributeBuilder.build(Name.NAME, resultSet.getString(2)));
                 
                if(!handler.handle(cob.build())) return;
            }
        } finally {
            if(resultSet != null)
                resultSet.close();
            if(callableStatement != null)
                callableStatement.close();
        }
        break;
     
    //Entitlement
    case "MYDBAT_GROUPS":
        CallableStatement callableStatement = null;
        ResultSet resultSet = null;
        try {
            callableStatement = conn.prepareCall("{call GET_GROUPS}");
            resultSet = (ResultSet) callableStatement.executeQuery();
             
            while (resultSet.next()) {
                var cob = new ConnectorObjectBuilder();
                cob.setObjectClass(new ObjectClass("MYDBAT_GROUPS"));
                cob.addAttribute(AttributeBuilder.build(Uid.NAME, resultSet.getString(1)));
                cob.addAttribute(AttributeBuilder.build(Name.NAME, resultSet.getString(2)));
                 
                if(!handler.handle(cob.build())) return;
            }
        } finally {
            if(resultSet != null)
                resultSet.close();
            if(callableStatement != null)
                callableStatement.close();
        }
        break;
     
    //Entitlement  
    case "DBAT_ROLES":
        CallableStatement callableStatement = null;
        ResultSet resultSet = null;
        try {
            callableStatement = conn.prepareCall("{call GET_ROLES}");
            resultSet = (ResultSet) callableStatement.executeQuery();
             
            while (resultSet.next()) {
                var cob = new ConnectorObjectBuilder();
                cob.setObjectClass(new ObjectClass("MYDBAT_ROLES"));
                cob.addAttribute(AttributeBuilder.build(Uid.NAME, resultSet.getString(1)));
                cob.addAttribute(AttributeBuilder.build(Name.NAME, resultSet.getString(2)));
                 
                if(!handler.handle(cob.build())) return;
            }
        } finally {
            if(resultSet != null)
                resultSet.close();
            if(callableStatement != null)
                callableStatement.close();
        }
        break;
         
    case "ACCOUNT":
    case "TARGETACCOUNT":
        CallableStatement parentCallableStatement = null;
        ResultSet parentResultSet = null;
        try {
            if (filterString != "") {
                trace.info("[Execute Query] Performing Recon with Filter. Filter is:: "+ filterString +" And Filer Params are:: "+ filterParams);
                //[Execute Query] Performing Recon with Filter. Filter is::MYDBAT_PERSON.USERID = ? And Filer Params are::Params are:: [MYDBAT_PERSON.USERID:31]
                parentCallableStatement = conn.prepareCall("{call GET_PERSON_BY_USERID(?)}");
                parentCallableStatement.setString(1, filterParams.get(0).split(":")[1]);
            } else {
                trace.info("[Execute Query] Performing Full Recon.");
                parentCallableStatement = conn.prepareCall("{call GET_PERSONS}");
            }
            parentResultSet = (ResultSet) parentCallableStatement.executeQuery();
            while (parentResultSet.next()) {
                var cob = new ConnectorObjectBuilder();
                cob.setObjectClass(ObjectClass.ACCOUNT);
                cob.addAttribute(AttributeBuilder.build(Uid.NAME, parentResultSet.getString(1)));
                cob.addAttribute(AttributeBuilder.build("FIRSTNAME", parentResultSet.getString(2)));
                cob.addAttribute(AttributeBuilder.build("LASTNAME", parentResultSet.getString(3)));
                cob.addAttribute(AttributeBuilder.build("EMAIL", parentResultSet.getString(4)));
                cob.addAttribute(AttributeBuilder.build("DESCRIPTION", parentResultSet.getString(5)));
                cob.addAttribute(AttributeBuilder.build("SALARY", parentResultSet.getDouble(6)));
                var joiningDbDate = parentResultSet.getDate(7);
                if( joiningDbDate != null ) {
                    var date = df.parse(joiningDbDate.toString());
                    var joinDateStr = targetFormat.format(date);
                    var joinDate = date.getTime();
                    trace.info("date : "+ date +" ---- joinDate : "+ joinDate);
                    trace.info("Setting joinDate: "+ joinDate);
                    cob.addAttribute(AttributeBuilder.build("JOININGDATE", joinDate));
                }
                cob.addAttribute(AttributeBuilder.build(OperationalAttributes.ENABLE_NAME, "ACTIVE".equalsIgnoreCase(parentResultSet.getString(8))));
                cob.addAttribute(AttributeBuilder.build("COUNTRYCODE", parentResultSet.getString(9)));
                cob.addAttribute(AttributeBuilder.build(Name.NAME, parentResultSet.getString(10)));
     
                if (ocName.equals("TARGETACCOUNT")) {
                    CallableStatement callableStatement = null;
                    ResultSet resultSet = null;
                    try {
                        //Person role
                        callableStatement = conn.prepareCall("{call GET_PERSON_ROLE(?)}");
                        callableStatement.setString(1, parentResultSet.getString(1));
                        resultSet = (ResultSet) callableStatement.executeQuery();
                                 
                        var eoList = new ArrayList<EmbeddedObject>();
                         
                        while (resultSet.next()) {
                            var roleEA = new EmbeddedObjectBuilder();
                            roleEA.setObjectClass(new ObjectClass("MYDBAT_ROLES"));
                            roleEA.addAttribute(AttributeBuilder.build("ROLEID", resultSet.getString(2)));
                             
                            var fromDbDate = resultSet.getDate(3);
                            if( fromDbDate != null ) {
                                var date = df.parse(fromDbDate.toString());
                                var fromDateStr = targetFormat.format(date);
                                var fromDate = date.getTime();
                                trace.info("Setting roles fromDate : "+ fromDate);
                                roleEA.addAttribute(AttributeBuilder.build("FROMDATE", fromDate));
                            }
                             
                            var toDbDate = resultSet.getDate(4);
                            if( toDbDate != null ) {
                                var date = df.parse(toDbDate.toString());
                                var toDateStr = targetFormat.format(date);
                                var toDate = date.getTime();
                                trace.info("Setting roles toDate: "+ toDate);
                                roleEA.addAttribute(AttributeBuilder.build("TODATE", toDate));
                            }
                            eoList.add(roleEA.build());
                        }
                         
                        var roleEm = eoList.toArray(new EmbeddedObject[eoList.size()]);
                        cob.addAttribute(AttributeBuilder.build("MYDBAT_PERSON_ROLE", (Object[]) roleEm));
                    } finally {
                        if(resultSet != null)
                            resultSet.close();
                        if(callableStatement != null)
                            callableStatement.close();
                    }
                     
                    try {
                        //Person group
                        callableStatement = conn.prepareCall("{call GET_PERSON_GROUP(?)}");
                        callableStatement.setString(1, parentResultSet.getString(1));
                        resultSet = (ResultSet) callableStatement.executeQuery();
                         
                        var geoList = new ArrayList<EmbeddedObject>();
                         
                        while (resultSet.next()) {
                            var groupEA = new EmbeddedObjectBuilder();
                            groupEA.setObjectClass(new ObjectClass("MYDBAT_GROUPS"));
                            groupEA.addAttribute(AttributeBuilder.build("GROUPID", resultSet.getString(2)));
                            geoList.add(groupEA.build());
                        }
                         
                        var groupEm = geoList.toArray(new EmbeddedObject[geoList.size()]);
                        cob.addAttribute(AttributeBuilder.build("DBAT_PERSON_GROUP", (Object[]) groupEm));
                    } finally {
                        if( resultSet != null )
                            resultSet.close();
                        if( callableStatement != null )
                            callableStatement.close();
                    }
                }
                 
                if(!handler.handle(cob.build())) return;
            }
        } finally {
            if( parentResultSet != null )
                parentResultSet.close();
            if( parentCallableStatement != null )
                parentCallableStatement.close();
        }
        break;
}

Gespeicherte Prozedur: Benutzer laden

USE {dataBase};
 
CREATE OR ALTER PROCEDURE GET_PERSONS
AS
BEGIN
    SELECT USERID,
           FIRSTNAME,
           LASTNAME,
           EMAIL,
           DESCRIPTION,
           SALARY,
           JOININGDATE,
           STATUS,
           COUNTRYCODE,
           USERNAME
    FROM MYDBAT_PERSON
END;

Gespeicherte Prozedur: Gefilterte Benutzersuche

USE {dataBase};
 
CREATE OR ALTER PROCEDURE GET_PERSON_BY_USERID
@user_id INT
AS
BEGIN
   SELECT USERID,
          FIRSTNAME,
          LASTNAME,
          EMAIL,
          DESCRIPTION,
          SALARY,
          JOININGDATE,
          STATUS,
          COUNTRYCODE,
          USERNAME
   FROM MYDBAT_PERSON 
   WHERE USERID = @user_id;
END;
Dies ist ein sehr einfaches Beispiel für die Filtersuche mit nur einer Filterbedingung. Beispiel: MYDBAT_PERSON.USERID:21. Wird speziell für die writeBack-Verarbeitung nach dem Erstellungsvorgang verwendet

Gespeicherte Prozedur: Rollen abrufen

USE {dataBase};
 
CREATE OR ALTER PROCEDURE GET_ROLES
AS
BEGIN
   SELECT ROLEID,
          ROLENAME 
   FROM MYDBAT_ROLES;
END;

Gespeicherte Prozedur: Benutzerrollen abrufen

USE {dataBase};
 
CREATE OR ALTER PROCEDURE GET_PERSON_ROLE
@user_id INT
AS
BEGIN
   SELECT USERID,
          ROLEID,
          FROMDATE,
          TODATE
   FROM MYDBAT_PERSON_ROLE WHERE USERID = @user_id
 END;

Gespeicherte Prozedur: Gruppen abrufen

USE {dataBase};
 
CREATE OR ALTER PROCEDURE GET_GROUPS
AS
BEGIN
   SELECT GROUPID,
          GROUPNAME
   FROM MYDBAT_GROUPS;
 END;

Gespeicherte Prozedur: Benutzergruppen abrufen

USE {dataBase};
 
CREATE OR ALTER PROCEDURE GET_PERSON_GROUP
@user_id INT
AS
BEGIN
   SELECT USERID,
          GROUPID
   FROM MYDBAT_PERSON_GROUP where USERID = @user_id;
END;

Gespeicherte Prozedur: Lookups abrufen (Land)

use {dataBase};
 
CREATE OR ALTER PROCEDURE GET_COUNTRIES
AS
BEGIN
   SELECT COUNTRYCODE,
          COUNTRYNAME
   FROM MYDBAT_COUNTRY;
 END;

Beispielerstellungsskript

Dieses Skript wird beim Provisioning eines neuen Accounts aus Oracle Access Governance aufgerufen. Hier werden Daten in die Tabelle MYDBAT_PERSON eingefügt.

Skript erstellen

import java.sql.CallableStatement;
import java.sql.Types;
import java.util.Date.*;
import org.identityconnectors.common.security.GuardedString;
import org.identityconnectors.framework.common.objects.*;
import java.text.*;
       
CallableStatement callableStatement = null;
String uid = null;
try {
    trace.info("[Create-Groovy] Attributes:: " + attributes);
     
    callableStatement = conn.prepareCall("{call ADD_PERSON(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)}");
    callableStatement.setString(1, attributes.get(Name.NAME) != null ? attributes.get(Name.NAME).getValue().get(0) : null);
    callableStatement.setString(2, attributes.get("FIRSTNAME") != null ? attributes.get("FIRSTNAME").getValue().get(0) : null);
    callableStatement.setString(3, attributes.get("LASTNAME") != null ? attributes.get("LASTNAME").getValue().get(0) : null);
    callableStatement.setString(4, attributes.get("EMAIL") != null ? attributes.get("EMAIL").getValue().get(0) : null);
    callableStatement.setString(5, attributes.get("COUNTRYCODE") != null ? attributes.get("COUNTRYCODE").getValue().get(0) : null);
    callableStatement.setString(6, attributes.get("DESCRIPTION") != null ? attributes.get("DESCRIPTION").getValue().get(0) : null);
    callableStatement.setString(7, (attributes.get(OperationalAttributes.ENABLE_NAME) != null ? attributes.get(OperationalAttributes.ENABLE_NAME).getValue().get(0) : true) ? "ACTIVE" : "INACTIVE");
     
    var joiningdate = attributes.get("JOININGDATE") != null ? attributes.get("JOININGDATE").getValue().get(0) : null;
    callableStatement.setString(8, (joiningdate != null && joiningdate != 0) ? new SimpleDateFormat("yyyy-MM-dd").format(new Date(joiningdate)) : null); 
     
    var salary = attributes.get("SALARY") != null ? attributes.get("SALARY").getValue().get(0) : null;
    if(salary != null)
        callableStatement.setDouble(9, salary);
    else
        callableStatement.setNull(9, Types.DOUBLE)
     
    var password = attributes.get(OperationalAttributes.PASSWORD_NAME) != null ? attributes.get(OperationalAttributes.PASSWORD_NAME).getValue().get(0) : null;
    if (password != null) {
        password.access(new GuardedString.Accessor() {
            public void access(char[] clearChars) { callableStatement.setString(10, new String(clearChars));}
        });
    } else
        callableStatement.setString(10, null);
     
    callableStatement.registerOutParameter(11, Types.NVARCHAR);
    callableStatement.execute();
     
    uid = callableStatement.getString(11);
} finally {
    if (callableStatement != null)
        callableStatement.close();
}
trace.info("[Create] Created User:: " +uid);
return new Uid(uid);

Beispiel für "Untergeordnetes Skript hinzufügen"

Dieses Skript wird beim Provisioning von Berechtigungen/Berechtigungen für Benutzer aus Oracle Access Governance aufgerufen. Hier werden Daten in die Tabellen MYDBAT_PERSON_GROUP und MYDBAT_PERSON_ROLE eingefügt.

Untergeordnetes Skript hinzufügen

import java.sql.PreparedStatement;
import org.identityconnectors.framework.common.objects.*;
import java.text.*;
  
trace.info("[addMultiValuedAttributeScript-Groovy] Adding Child data:: " + attributes);
String userId = attributes.get(Uid.NAME).getValue().get(0);
PreparedStatement childst = null;
Attribute dbatChild = null;
try {
    dbatChild = attributes.get("MYDBAT_PERSON_GROUP");
    if (dbatChild != null) {
        var childDataEOSet = dbatChild.getValue();
        childst = conn.prepareStatement("INSERT INTO MYDBAT_PERSON_GROUP VALUES (?, ?)");
         
        if (childDataEOSet != null) {
            trace.info("[addMultiValuedAttributeScript] Adding Group data.");
            for ( iterator = childDataEOSet.iterator(); iterator.hasNext(); ) {
                eo = iterator.next();
                attrsSet = eo.getAttributes();
                grpAttr = AttributeUtil.find("GROUPID", attrsSet);
                if (grpAttr != null) {
                    childst.setString(1, userId);
                    childst.setString(2, grpAttr.getValue().get(0));
                    childst.executeUpdate();
                    childst.clearParameters();
                }
            };
        }
    }
} finally {
    if (childst != null)
        childst.close();       
};
  
try {
    dbatChild = attributes.get("MYDBAT_PERSON_ROLE");
    if (dbatChild != null) {
        var childDataEOSet = dbatChild.getValue();
        childst = conn.prepareStatement("INSERT INTO MYDBAT_PERSON_ROLE VALUES (?, ?, ?, ?)");
         
        if (childDataEOSet != null) {
            trace.info("[addMultiValuedAttributeScript] Adding Role data.");
            for ( iterator = childDataEOSet.iterator(); iterator.hasNext(); ) {
                eo = iterator.next();
                attrsSet = eo.getAttributes();
                roleattr = AttributeUtil.find("ROLEID", attrsSet);
                 
                if (roleattr != null) {
                    childst.setString(1, userId);
                    childst.setString(2, roleattr.getValue().get(0));
                    childst.setString(3, AttributeUtil.find("FROMDATE", attrsSet) != null ? new SimpleDateFormat("yyyy-MM-dd").format(new Date(AttributeUtil.find("FROMDATE", attrsSet).getValue().get(0))) : null);
                    childst.setString(4, AttributeUtil.find("TODATE", attrsSet) != null ? new SimpleDateFormat("yyyy-MM-dd").format(new Date(AttributeUtil.find("TODATE", attrsSet).getValue().get(0))) : null);   
                     
                    childst.executeUpdate();
                    childst.clearParameters();
                }
            };
        }
    }
} finally {
    if (childst != null)
        childst.close();
};

Beispiel: Untergeordnetes Skript entfernen

Dieses Skript wird beim Deprovisioning von Berechtigungen/Berechtigungen von Benutzern aus Oracle Access Governance aufgerufen. Hier werden Daten mit Stored Procedures aus den Tabellen MYDBAT_PERSON_GROUP und MYDBAT_PERSON_ROLE entfernt.

Untergeordnetes Skript entfernen

import java.sql.CallableStatement;
import org.identityconnectors.framework.common.objects.*;
 
trace.info("[removeMultiValuedAttributeScript] Removing Child data:: "+ attributes);   
  
var uid = attributes.get(Uid.NAME).getValue().get(0);
CallableStatement callableStatement = null;
Attribute dbatChild = null;
try {
    dbatChild = attributes.get("MYDBAT_PERSON_GROUP");
    if (dbatChild != null) {
        var childDataEOSet = dbatChild.getValue();
        //Delete child data using stored procedure
        callableStatement = conn.prepareCall("{call DELETE_PERSON_GROUP(?, ?)}");
        if(childDataEOSet != null) {
            trace.info("[removeMultiValuedAttributeScript] Removing Group data.");
            //Iterate through child data and delete
            for( iterator = childDataEOSet.iterator(); iterator.hasNext(); ) {
                eo = iterator.next();
                grpattr = AttributeUtil.find("GROUPID", eo.getAttributes());
                if (grpattr != null) {
                    callableStatement.setString(1, uid);
                    callableStatement.setString(2, grpattr.getValue().get(0));
                    callableStatement.executeUpdate();
                    trace.info("[removeMultiValuedAttributeScript] Deleted Group:: "+ grpattr);
                }
            };
        }
    }
} finally {
    if (callableStatement != null)
        callableStatement.close();
};
 
try {
    dbatChild = attributes.get("MYDBAT_PERSON_ROLE");
    if (dbatChild != null) {
        var childDataEOSet = dbatChild.getValue();
        callableStatement = conn.prepareCall("{call DELETE_PERSON_ROLE(?, ?)}");
        if(childDataEOSet != null) {
            trace.info("[removeMultiValuedAttributeScript] Removing Role data.");
            for ( iterator = childDataEOSet.iterator(); iterator.hasNext(); ) {
                eo = iterator.next();
                roleattr = AttributeUtil.find("ROLEID", eo.getAttributes());
                if(roleattr != null) {
                    callableStatement.setString(1, uid);
                    callableStatement.setString(2, roleattr.getValue().get(0));
                    callableStatement.executeUpdate();
                    trace.info("[removeMultiValuedAttributeScript] Deleted Role:: "+ roleattr);
                }
            };
        }
    }
} finally {
    if (callableStatement != null)
        callableStatement.close();
};

Gespeicherte Prozedur: Untergeordnetes Element entfernen

USE {dataBase};
 
CREATE OR ALTER PROCEDURE DELETE_PERSON_GROUP
 @user_id INT, @group_id nvarchar(50)
 AS
 BEGIN
    DELETE from MYDBAT_PERSON_GROUP where USERID = @user_id AND GROUPID = @group_id
 END;

USE {dataBase};
 
CREATE OR ALTER PROCEDURE DELETE_PERSON_ROLE
 @user_id INT, @role_id nvarchar(50)
 AS
 BEGIN
   DELETE FROM MYDBAT_PERSON_ROLE where USERID = @user_id AND ROLEID = @role_id
 END;

Beispiel für Löschskript

Dieses Skript wird während des Widerrufs eines Accounts in Oracle Access Governance aufgerufen. Hier werden die Daten-Benutzerbeziehungstabellen MYDBAT_PERSON_ROLE und MYDBAT_PERSON_GROUP sowie Daten aus der Tabelle MYDBAT_PERSON gelöscht

Skript löschen

import java.sql.CallableStatement;
import org.identityconnectors.framework.common.objects.*;
    
var uid = attributes.get(Uid.NAME).getValue().get(0);
CallableStatement callableStatement = null;  
try {
    trace.info("[Delete-Groovy] Deleting user:: " + uid);
 
    callableStatement = conn.prepareCall("{call DELETE_PERSON(?)}");
    callableStatement.setString(1, uid);
    callableStatement.execute();
} finally {
    if (callableStatement != null)
        callableStatement.close();
};
trace.info("Deleted user:: " + uid);

Gespeicherte Prozedur: Löschen

USE {dataBase};
 
CREATE OR ALTER PROCEDURE DELETE_PERSON
 @user_id INT
 AS
 BEGIN
   DELETE FROM MYDBAT_PERSON_ROLE where USERID = @user_id;
   DELETE FROM MYDBAT_PERSON_GROUP where USERID = @user_id;
   DELETE FROM MYDBAT_PERSON WHERE USERID = @user_id;
 END;

Beispielaktualisierungsskript

Dieses Skript wird während Provisioning-Vorgängen aufgerufen, wenn der Account aus Oracle Access Governance aktualisiert wird. Hier aktualisieren wir die Daten in der Tabelle MYDBAT_PERSON

Skript aktualisieren

import java.sql.PreparedStatement;
import java.sql.Types;
import org.identityconnectors.framework.common.objects.*;
import java.text.*;
import org.identityconnectors.framework.common.exceptions.*;
import org.identityconnectors.common.security.GuardedString;
   
trace.info("[Update-Groovy] Atrributes:: " + attributes);
 
PreparedStatement stmt = null;
String userId = null;
try {
    userId = attributes.get(Uid.NAME) != null ? attributes.get(Uid.NAME).getValue().get(0) : null;
     
    if (userId == null)
        throw new ConnectorException("UID Cannot be Null");
 
    stmt = conn.prepareStatement("UPDATE MYDBAT_PERSON SET FIRSTNAME = COALESCE(?, FIRSTNAME), LASTNAME = COALESCE(?, LASTNAME), EMAIL = COALESCE(?, EMAIL), COUNTRYCODE = COALESCE(?, COUNTRYCODE), DESCRIPTION = COALESCE(?, DESCRIPTION), STATUS = COALESCE(?, STATUS), JOININGDATE = COALESCE(?, JOININGDATE), SALARY = COALESCE(?, SALARY), PASSWORD = COALESCE(?, PASSWORD) WHERE USERID = ?");
    stmt.setString(1, attributes.get("FIRSTNAME") != null ? attributes.get("FIRSTNAME").getValue().get(0) : null);
    stmt.setString(2, attributes.get("LASTNAME") != null ? attributes.get("LASTNAME").getValue().get(0) : null);
    stmt.setString(3, attributes.get("EMAIL") != null ? attributes.get("EMAIL").getValue().get(0) : null);
    stmt.setString(4, attributes.get("COUNTRYCODE") != null ? attributes.get("COUNTRYCODE").getValue().get(0) : null);
    stmt.setString(5, attributes.get("DESCRIPTION") != null ? attributes.get("DESCRIPTION").getValue().get(0) : null);
    stmt.setString(6, (attributes.get(OperationalAttributes.ENABLE_NAME) != null ? attributes.get(OperationalAttributes.ENABLE_NAME).getValue().get(0) : true) ? "ACTIVE" : "INACTIVE");
     
    var joiningdate = attributes.get("JOININGDATE") != null ? attributes.get("JOININGDATE").getValue().get(0) : null;
    stmt.setString(7, joiningdate != null ? new SimpleDateFormat("yyyy-MM-dd").format(new Date(joiningdate)) : null)
     
    var salary = attributes.get("SALARY") != null ? attributes.get("SALARY").getValue().get(0) : null;
    if(salary != null)
        stmt.setDouble(8, salary);
    else
        stmt.setNull(8, Types.DOUBLE)  
     
    var password = attributes.get(OperationalAttributes.PASSWORD_NAME) != null ? attributes.get(OperationalAttributes.PASSWORD_NAME).getValue().get(0) : null;
    if (password != null) {
        password.access(new GuardedString.Accessor() {
            public void access(char[] clearChars) { stmt.setString(9, new String(clearChars));}
        });
    } else
        stmt.setString(9, null);
    stmt.setString(10, userId);
     
    stmt.executeUpdate();
} finally {
    if (stmt != null)
        stmt.close();
};
trace.info("[Update] Updated user:: " + userId);
return new Uid(userId);