Benutzerdefinierte Skripte für Datenbankanwendungstabellen entwickeln (MySQL) mit Groovy
Benutzerdefiniertes Skripting für Datenbankanwendungstabellen (MySQL) - Überblick
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.
Jedes benutzerdefinierte Skript muss im Groovy-Format implementiert werden. Andere Scripting-Formate werden nicht unterstützt.
- Erstellen
- Aktualisieren
- Löschen
- Dataload
- Beziehungsdaten hinzufügen
- Beziehungsdaten entfernen
/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.- Benutzerdefinierte Tabellenaktualisierungen ausführen
- Benutzerdefiniertes Auditing
- Benutzerdefinierte Benachrichtigungen senden
- Standardlogik verwenden, die mit dem Connector {\b Database Application Tables} bereitgestellt wird
- In Skripten implementierte benutzerdefinierte Logik verwenden
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 NOT NULL AUTO_INCREMENT PRIMARY KEY,
USERNAME VARCHAR(50) NOT NULL,
FIRSTNAME VARCHAR(50),
LASTNAME VARCHAR(50),
EMAIL VARCHAR(50) NOT NULL,
COUNTRYCODE VARCHAR(20),
DESCRIPTION VARCHAR(50),
SALARY DECIMAL(10, 2),
JOININGDATE DATE,
STATUS VARCHAR(50),
LASTUPDATED TIMESTAMP(6),
PASSWORD VARCHAR(50));
MYDBAT_GROUPS
USE {dataBase};
CREATE TABLE MYDBAT_GROUPS (
GROUPID VARCHAR(20) NOT NULL,
GROUPNAME VARCHAR(20) NOT NULL,
PRIMARY KEY (GROUPID));
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(20) NOT NULL,
PRIMARY KEY (USERID,GROUPID));
ALTER TABLE DBAT_PERSON_GROUP
ADD CONSTRAINT FK_USERID
FOREIGN KEY (USERID) REFERENCES DBAT_PERSON(USERID);
MYDBAT_PERSON_ROLE
USE {dataBase};
CREATE TABLE MYDBAT_PERSON_ROLE(
USERID INT NOT NULL,
ROLEID VARCHAR(20) NOT NULL,
PRIMARY KEY (USERID,ROLEID));
ALTER TABLE MYDBAT_PERSON_ROLE
ADD CONSTRAINT FK_USERIDROLE
FOREIGN KEY (USERID) REFERENCES DBAT_PERSON(USERID);
MYDBAT_COUNTRY
USE {dataBase};
CREATE TABLE MYDBAT_COUNTRY(
COUNTRYCODE VARCHAR(20) NOT NULL,
COUNTRYNAME VARCHAR(20) NOT NULL,
PRIMARY KEY (COUNTRYCODE)
);
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:
| 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:
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:
|
| 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.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import org.identityconnectors.framework.common.objects.*;
import org.identityconnectors.common.security.GuardedString;
ResultSet rs = null;
CallableStatement st = null;
try {
String ocName = "";
if (timing != "") {
trace.info("[Execute Query] timing attribute value: " + timing);
ocName = timing.split(":")[1];
}
trace.info("[Execute Query] for objectClass: " + ocName);
if (ocName.equals("ACCOUNT") || ocName.equals("TARGETACCOUNT")) {
if (filterString != "") {
trace.info("[Execute Query] Performing Recon with Filter. Filter is: " + filterString + " And Filter Params are: " + filterParams);
// Example: Filter is MYDBAT_PERSON.USERID = ? And Filter Params are [MYDBAT_PERSON.USERID:21]
String[] filter = filterParams.get(0).split(":");
st = conn.prepareCall("{call EXECUTE_QUERY_WITH_FILTER(?, ?)}");
st.setString(1, filter[0]); // Column name (e.g., MYDBAT_PERSON.USERID)
st.setInt(2, Integer.parseInt(filter[1])); // Value to filter (e.g., 21)
} else {
trace.info("[Execute Query] Performing Full Recon.");
st = conn.prepareCall("{call EXECUTE_QUERY_PERSON()}");
}
// Execute the procedure and get the ResultSet
rs = st.executeQuery(); // No need to register OUT parameter
SimpleDateFormat targetFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss z");
DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
while (rs.next()) {
ConnectorObjectBuilder cob = new ConnectorObjectBuilder();
cob.setObjectClass(ObjectClass.ACCOUNT);
Attribute fname = AttributeBuilder.build("FIRSTNAME", rs.getString("FIRSTNAME"));
Attribute lname = AttributeBuilder.build("LASTNAME", rs.getString("LASTNAME"));
Attribute uid = AttributeBuilder.build("__UID__", rs.getString("USERID"));
Attribute name = AttributeBuilder.build("__NAME__", rs.getString("USERNAME"));
Attribute email = AttributeBuilder.build("EMAIL", rs.getString("EMAIL"));
Attribute description = AttributeBuilder.build("DESCRIPTION", rs.getString("DESCRIPTION"));
Date dbDate = rs.getDate("JOININGDATE");
String joinDateStr = null;
Long joinDate = null;
if (dbDate != null) {
java.util.Date date = df.parse(dbDate.toString());
joinDateStr = targetFormat.format(date);
joinDate = date.getTime();
trace.info("date: " + date + " ---- joinDate: " + joinDate);
}
if (joinDate != null) {
trace.info("Setting joinDate: " + joinDate);
Attribute joindate = AttributeBuilder.build("JOININGDATE", joinDate);
cob.addAttribute(joindate);
}
Attribute status = AttributeBuilder.build("STATUS", rs.getString("STATUS"));
Attribute countryCode = AttributeBuilder.build("COUNTRYCODE", rs.getString("COUNTRYCODE"));
cob.addAttribute(fname);
cob.addAttribute(lname);
cob.addAttribute(uid);
cob.addAttribute(name);
cob.addAttribute(email);
cob.addAttribute(description);
cob.addAttribute(status);
cob.addAttribute(countryCode);
if (!handler.handle(cob.build())) return;
}
} else if (ocName.equals("DBAT_COUNTRY")) {
trace.info("[Execute Query] for Lookup: " + ocName);
CallableStatement countryStmt = conn.prepareCall("{call GET_COUNTRIES()}");
rs = countryStmt.executeQuery();
while (rs.next()) {
ConnectorObjectBuilder cob = new ConnectorObjectBuilder();
cob.setObjectClass(new ObjectClass("DBAT_COUNTRY"));
Attribute groupId = AttributeBuilder.build("__UID__", rs.getString(1));
Attribute groupName = AttributeBuilder.build("__NAME__", rs.getString(2));
cob.addAttribute(groupId);
cob.addAttribute(groupName);
if (!handler.handle(cob.build())) return;
}
rs.close();
countryStmt.close();
} else if (ocName.equals("DBAT_GROUPS")) {
trace.info("[Execute Query] for Entitlement: " + ocName);
CallableStatement groupStmt = conn.prepareCall("{call GET_GROUPS()}");
rs = groupStmt.executeQuery();
while (rs.next()) {
ConnectorObjectBuilder cob = new ConnectorObjectBuilder();
cob.setObjectClass(new ObjectClass("DBAT_GROUPS"));
Attribute groupId = AttributeBuilder.build("__UID__", rs.getString(1));
Attribute groupName = AttributeBuilder.build("__NAME__", rs.getString(2));
cob.addAttribute(groupId);
cob.addAttribute(groupName);
if (!handler.handle(cob.build())) return;
}
rs.close();
groupStmt.close();
}else if (ocName.equals("DBAT_ROLES")) {
trace.info("[Execute Query] for Entitlement: " + ocName);
CallableStatement groupStmt = conn.prepareCall("{call GET_ROLES()}");
rs = groupStmt.executeQuery();
while (rs.next()) {
ConnectorObjectBuilder cob = new ConnectorObjectBuilder();
cob.setObjectClass(new ObjectClass("DBAT_ROLESS"));
Attribute groupId = AttributeBuilder.build("__UID__", rs.getString(1));
Attribute groupName = AttributeBuilder.build("__NAME__", rs.getString(2));
cob.addAttribute(groupId);
cob.addAttribute(groupName);
if (!handler.handle(cob.build())) return;
}
rs.close();
groupStmt.close();
}
} finally {
if (rs != null) rs.close();
if (st != null) st.close();
}
Gespeicherte Prozedur: Benutzer laden
USE {dataBase};
DELIMITER //
CREATE PROCEDURE EXECUTE_QUERY_PERSON()
BEGIN
SELECT USERID,
FIRSTNAME,
LASTNAME,
EMAIL,
DESCRIPTION,
SALARY,
JOININGDATE,
STATUS,
COUNTRYCODE,
USERNAME
FROM MYDBAT_PERSON;
END //
DELIMITER ;
Gespeicherte Prozedur: Gefilterte Benutzersuche
USE {dataBase};
DELIMITER //
CREATE PROCEDURE EXECUTE_QUERY_WITH_FILTER(
IN filter VARCHAR(255),
IN filterValue int
)
BEGIN
SET @sql_query = CONCAT(
'SELECT USERID,
FIRSTNAME,
LASTNAME,
EMAIL,
DESCRIPTION,
SALARY,
JOININGDATE,
STATUS,
COUNTRYCODE,
USERNAME ',
'FROM MYDBAT_PERSON WHERE ', filter, ' = ?'
);
PREPARE stmt FROM @sql_query;
SET @filter_value = filterValue;
EXECUTE stmt USING @filter_value;
DEALLOCATE PREPARE stmt;
END //
DELIMITER ;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 verwendetGespeicherte Prozedur: Rollen abrufen
USE {dataBase};
DELIMITER //
CREATE PROCEDURE GET_ROLES()
BEGIN
SELECT ROLEID,
ROLENAME
FROM MYDBAT_ROLES;
END //
DELIMITER ;
Gespeicherte Prozedur: Benutzerrollen abrufen
USE {dataBase};
DELIMITER //
CREATE PROCEDURE GET_USERROLE(
IN userin int
)
BEGIN
SELECT USERID,
ROLEID,
FROMDATE,
TODATE
FROM MYDBAT_PERSON_ROLE
WHERE USERID = userin;
END //
DELIMITER ;
Gespeicherte Prozedur: Gruppen abrufen
USE {dataBase};
DELIMITER //
CREATE PROCEDURE GET_GROUPS()
BEGIN
SELECT GROUPID,
GROUPNAME
FROM MYDBAT_GROUPS;
END //
DELIMITER ;
Gespeicherte Prozedur: Benutzergruppen abrufen
USE {dataBase};
DELIMITER //
CREATE PROCEDURE GET_USERGROUP(
IN userin int
)
BEGIN
SELECT USERID,
GROUPID
FROM MYDBAT_PERSON_GROUP
WHERE USERID = userin;
END //
DELIMITER ;
Gespeicherte Prozedur: Lookups abrufen (Land)
USE {dataBase};
DELIMITER //
CREATE PROCEDURE GET_COUNTRIES()
BEGIN
SELECT COUNTRYCODE,
COUNTRYNAME
FROM MYDBAT_COUNTRY;
END //
DELIMITER ;
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.PreparedStatement;
import java.sql.ResultSet;
import java.sql.CallableStatement;
import java.text.SimpleDateFormat;
import java.util.Date;
import org.identityconnectors.common.security.GuardedString;
import org.identityconnectors.framework.common.objects.*;
trace.info("[Create-Groovy] Attributes::" + attributes);
// Get all the attributes from script argument
GuardedString pass = attributes.get("__PASSWORD__") != null ? attributes.get("__PASSWORD__").getValue().get(0) : null;
String uname = attributes.get("__NAME__") != null ? attributes.get("__NAME__").getValue().get(0) : null;
boolean enableValue = attributes.get("__ENABLE__") != null ? attributes.get("__ENABLE__").getValue().get(0) : true;
String email = attributes.get("EMAIL") != null ? attributes.get("EMAIL").getValue().get(0) : null;
String first = attributes.get("FIRSTNAME") != null ? attributes.get("FIRSTNAME").getValue().get(0) : null;
String last = attributes.get("LASTNAME") != null ? attributes.get("LASTNAME").getValue().get(0) : null;
String desc = attributes.get("DESCRIPTION") != null ? attributes.get("DESCRIPTION").getValue().get(0) : null;
Object salary = attributes.get("SALARY") != null ? attributes.get("SALARY").getValue().get(0) : null; // Changed to Object
String countryCode = attributes.get("COUNTRYCODE") != null ? attributes.get("COUNTRYCODE").getValue().get(0) : null;
Object joiningdate = attributes.get("JOININGDATE") != null ? attributes.get("JOININGDATE").getValue().get(0) : null; // Changed to Object
// Prepare callable statement for the stored procedure
CallableStatement createStmt = null;
try {
// Prepare the SQL statement to call the stored procedure
createStmt = conn.prepareCall("{CALL ADD_PERSON(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)}");
// Set the input parameters for the stored procedure
createStmt.setString(1, uname); // USERNAME
createStmt.setString(2, first); // FIRSTNAME
createStmt.setString(3, last); // LASTNAME
createStmt.setString(4, email); // EMAIL
createStmt.setString(5, countryCode); // COUNTRYCODE
createStmt.setString(6, desc); // DESCRIPTION
// Handling SALARY: Ensure it's numeric or set as NULL
if (salary != null && salary instanceof String) {
try {
createStmt.setBigDecimal(9, new BigDecimal((String) salary)); // Parse to BigDecimal
} catch (NumberFormatException e) {
trace.error("[Create-Groovy] Invalid SALARY format: " + salary);
createStmt.setNull(9, java.sql.Types.DECIMAL); // Set NULL if invalid
}
} else {
createStmt.setNull(9, java.sql.Types.DECIMAL); // NULL for SALARY if not provided
}
// Handling JOININGDATE: Convert from long to MySQL DATE format
if (joiningdate != null) {
if (joiningdate instanceof Long) {
// Convert long to java.util.Date
Date dateObj = new Date((Long) joiningdate);
// Format the date to 'yyyy-MM-dd'
SimpleDateFormat dateFormatter = new SimpleDateFormat("yyyy-MM-dd");
String formattedDate = dateFormatter.format(dateObj);
createStmt.setString(8, formattedDate); // Set the formatted date
} else {
trace.error("[Create-Groovy] Invalid JOININGDATE format: Expected Long but got " + joiningdate.getClass());
createStmt.setNull(8, java.sql.Types.DATE); // Set NULL if the format is invalid
}
} else {
createStmt.setNull(8, java.sql.Types.DATE); // NULL for JOININGDATE if not provided
}
// STATUS: ACTIVE or INACTIVE
if (enableValue) {
createStmt.setString(7, "ACTIVE"); // STATUS
} else {
createStmt.setString(7, "INACTIVE"); // STATUS
}
// PASSWORD Handling
if (pass != null) {
pass.access(new GuardedString.Accessor() {
public void access(char[] clearChars) {
createStmt.setString(10, new String(clearChars)); // PASSWORD
}
});
} else {
createStmt.setString(10, null); // NULL for PASSWORD if not provided
}
// The output parameter for USERID (generated by the stored procedure)
createStmt.registerOutParameter(11, java.sql.Types.VARCHAR);
// Execute the stored procedure
createStmt.executeUpdate();
// Retrieve the generated USERID (either auto-increment or UUID)
String generatedUserId = createStmt.getString(11); // Get the output parameter (USERID)
trace.info("[Create] Created User with USERID::" + generatedUserId);
// Return the generated USERID as Uid
return new Uid(generatedUserId);
} catch (Exception e) {
trace.error("[Create-Groovy] Error during user creation: " + e.getMessage());
throw e; // Re-throw exception to signal failure
} finally {
// Clean up resources
if (createStmt != null) {
createStmt.close();
}
}
Gespeicherten Account erstellen - Vorgehensweise
DELIMITER $$
CREATE PROCEDURE ADD_PERSON (
IN USERNAME VARCHAR(50),
IN FIRSTNAME VARCHAR(50),
IN LASTNAME VARCHAR(50),
IN EMAIL VARCHAR(50),
IN COUNTRYCODE VARCHAR(20),
IN DESCRIPTION VARCHAR(50),
IN STATUS VARCHAR(50),
IN JOININGDATE DATE,
IN SALARY DECIMAL(10,2),
IN PASSWORD VARCHAR(50),
OUT USERID VARCHAR(50)
)
BEGIN
DECLARE generated_user_id VARCHAR(50);
DECLARE is_auto_increment VARCHAR(50); -- Change to VARCHAR to hold string values like 'auto_increment'
-- Check if USERID column has the 'auto_increment' flag in the EXTRA column
SELECT EXTRA
INTO is_auto_increment
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = 'MYDBAT_PERSON'
AND COLUMN_NAME = 'USERID'
AND TABLE_SCHEMA = DATABASE();
-- Check if 'auto_increment' is present in the EXTRA column
IF is_auto_increment LIKE '%auto_increment%' THEN
-- If USERID is auto-increment
INSERT INTO MYDBAT_PERSON (
USERNAME, FIRSTNAME, LASTNAME, EMAIL, COUNTRYCODE, DESCRIPTION, STATUS, JOININGDATE, SALARY, PASSWORD
)
VALUES (
USERNAME, FIRSTNAME, LASTNAME, EMAIL, COUNTRYCODE, DESCRIPTION, STATUS, JOININGDATE, SALARY, PASSWORD
);
-- Retrieve the auto-generated USERID and cast it to VARCHAR
SET USERID = CAST(LAST_INSERT_ID() AS CHAR);
ELSE
-- If USERID is NOT auto-increment, generate a UUID for USERID
SET generated_user_id = UUID();
-- Insert the record with the generated UUID
INSERT INTO MYDBAT_PERSON (
USERID, USERNAME, FIRSTNAME, LASTNAME, EMAIL, COUNTRYCODE, DESCRIPTION, STATUS, JOININGDATE, SALARY, PASSWORD
)
VALUES (
generated_user_id, USERNAME, FIRSTNAME, LASTNAME, EMAIL, COUNTRYCODE, DESCRIPTION, STATUS, JOININGDATE, SALARY, PASSWORD
);
-- Set the generated UUID in the output, as a VARCHAR
SET USERID = generated_user_id;
END IF;
END$$
DELIMITER ;
Diese Stored Procedure ist eine Beispielimplementierung zum Erstellen eines Benutzers in der Datenbank. Das Skript prüft, ob für die Spalte USERID der Tabelle MYDBAT_PERSON eine automatische Inkrementierung festgelegt ist. Das bedeutet, dass die Benutzer-ID automatisch aufgefüllt wird. Wenn die automatische Erhöhung festgelegt ist, wird der Benutzer mit einer SQL-Anweisung ohne die Benutzer-ID erstellt, da diese von der Datenbank automatisch festgelegt wird. Wenn die automatische Erhöhung nicht festgelegt ist, wird der Benutzer mit einer SQL-Anweisung erstellt, die die Benutzer-ID generiert und in die Tabelle MYDBAT_PERSON einfügt. Da die Implementierung der USERID in verschiedenen Implementierungen variieren kann, sollte diese gespeicherte Prozedur Ihren spezifischen Anforderungen entsprechen.
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 org.identityconnectors.framework.common.objects.*
import java.text.*
trace.info("[addMultiValuedAttributeScript-Groovy] Adding Child data::" + attributes)
childst = null
try {
// Adding Group data
childDataEOSet = null
// Logic for handling simple multi-valued attributes
if (attributes.get("MYDBAT_PERSON_GROUP") != null) {
childDataEOSet = attributes.get("MYDBAT_PERSON_GROUP").getValue()
childst = conn.prepareStatement("INSERT INTO dbat.MYDBAT_PERSON_GROUP (USERID, GROUPID) VALUES (?, ?)")
int id = attributes.get("__UID__").getValue().get(0).toInteger()
if (childDataEOSet != null) {
trace.info("[addMultiValuedAttributeScript] Adding Group data.")
// Iterate through child data and insert into table
for (iterator = childDataEOSet.iterator(); iterator.hasNext(); ) {
eo = iterator.next()
attrsSet = eo.getAttributes()
grpattr = AttributeUtil.find("GROUPID", attrsSet)
if (grpattr != null) {
// Extract group ID and insert record
groupid = grpattr.getValue().get(0)
childst.setInt(1, id)
childst.setString(2, groupid)
childst.executeUpdate()
childst.clearParameters()
}
}
}
}
} finally {
if (childst != null)
childst.close()
}
try {
childDataEOSet = null
// Logic for handling complex multi-valued attributes
if (attributes.get("MYDBAT_PERSON_ROLE") != null) {
childDataEOSet = attributes.get("MYDBAT_PERSON_ROLE").getValue()
childst = conn.prepareStatement("INSERT INTO dbat.MYDBAT_PERSON_ROLE (USERID, ROLEID) VALUES (?, ?)")
int id = attributes.get("__UID__").getValue().get(0).toInteger()
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) {
// Extract role ID and insert record
roleid = roleattr.getValue().get(0)
childst.setInt(1, id)
childst.setString(2, roleid)
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 org.identityconnectors.framework.common.objects.*
trace.info("[removeMultiValuedAttributeScript] Removing Child data::" + attributes)
try {
childDataEOSet = null
delSt = null
// Get UID and convert to int
int id = Integer.parseInt(attributes.get("__UID__").getValue().get(0))
// Handle removal of person group data
if (attributes.get("MYDBAT_PERSON_GROUP") != null) {
childDataEOSet = attributes.get("MYDBAT_PERSON_GROUP").getValue()
// Call the MySQL stored procedure
delSt = conn.prepareCall("{CALL DELETE_USERGROUP(?, ?)}")
if (childDataEOSet != null) {
trace.info("[removeMultiValuedAttributeScript] Removing Group data.")
// Iterate through child data and delete
for (iterator = childDataEOSet.iterator(); iterator.hasNext(); ) {
eo = iterator.next()
attrsSet = eo.getAttributes()
grpattr = AttributeUtil.find("GROUPID", attrsSet)
if (grpattr != null) {
groupid = grpattr.getValue().get(0)
delSt.setInt(1, id) // Use setInt for integer ID
delSt.setString(2, groupid)
delSt.executeUpdate()
trace.info("[removeMultiValuedAttributeScript] Deleted Group::" + groupid)
}
}
}
}
} finally {
if (delSt != null)
delSt.close()
}
try {
childDataEOSet = null
delSt = null
// Get UID and convert to int
int id = Integer.parseInt(attributes.get("__UID__").getValue().get(0))
// Handle removal of person role data
if (attributes.get("MYDBAT_PERSON_ROLE") != null) {
childDataEOSet = attributes.get("MYDBAT_PERSON_ROLE").getValue()
// Call the MySQL stored procedure
delSt = conn.prepareCall("{CALL DELETE_USERROLE(?, ?)}")
if (childDataEOSet != null) {
trace.info("[removeMultiValuedAttributeScript] Removing Role data.")
for (iterator = childDataEOSet.iterator(); iterator.hasNext(); ) {
eo = iterator.next()
attrsSet = eo.getAttributes()
roleattr = AttributeUtil.find("ROLEID", attrsSet)
if (roleattr != null) {
rolename = roleattr.getValue().get(0)
delSt.setInt(1, id) // Use setInt for integer ID
delSt.setString(2, rolename)
delSt.executeUpdate()
trace.info("[removeMultiValuedAttributeScript] Deleted Role::" + rolename)
}
}
}
}
} finally {
if (delSt != null)
delSt.close()
}
Gespeicherte Prozedur: Untergeordnetes Element entfernen
DELIMITER $$
CREATE PROCEDURE DELETE_USERROLE (
IN input_userid INT,
IN input_roleid VARCHAR(20)
)
BEGIN
-- Check if the record exists before attempting deletion
IF EXISTS (
SELECT 1
FROM MYDBAT_PERSON_ROLE
WHERE USERID = input_userid AND ROLEID = input_roleid
) THEN
-- Perform the deletion
DELETE FROM MYDBAT_PERSON_ROLE
WHERE USERID = input_userid AND ROLEID = input_roleid;
ELSE
-- If no record exists, signal an error or do nothing
SIGNAL SQLSTATE '45000'
SET MESSAGE_TEXT = 'The specified USERID and ROLEID combination does not exist in MYDBAT_PERSON_ROLE.';
END IF;
END$$
DELIMITER ;
DELIMITER $$
CREATE PROCEDURE DELETE_USERGROUP (
IN input_userid INT,
IN input_groupid VARCHAR(20)
)
BEGIN
-- Check if the record exists before attempting deletion
IF EXISTS (
SELECT 1
FROM MYDBAT_PERSON_GROUP
WHERE USERID = input_userid AND GROUPID = input_groupid
) THEN
-- Perform the deletion
DELETE FROM MYDBAT_PERSON_GROUP
WHERE USERID = input_userid AND GROUPID = input_groupid;
ELSE
-- If no record exists, signal an error or do nothing
SIGNAL SQLSTATE '45000'
SET MESSAGE_TEXT = 'The specified USERID and GROUPID combination does not exist in MYDBAT_PERSON_GROUP.';
END IF;
END$$
DELIMITER ;
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.PreparedStatement;
import org.identityconnectors.framework.common.objects.*;
// Get the UID from the input map 'attributes'
String uid = attributes.get("__UID__").getValue().get(0);
trace.info("[Delete-Groovy] Deleting user:: " + uid);
try {
// Delete data from child tables and then, main table
// Delete user roles
st = conn.prepareStatement("DELETE FROM dbat.MYDBAT_PERSON_ROLE WHERE userid=?");
st.setString(1, uid);
st.executeUpdate();
st.close();
// Delete user groups
st = conn.prepareStatement("DELETE FROM dbat.MYDBAT_PERSON_GROUP WHERE userid=?");
st.setString(1, uid);
st.executeUpdate();
st.close();
// Delete user account
st = conn.prepareStatement("DELETE FROM dbat.MYDBAT_PERSON WHERE userid=?");
st.setString(1, uid);
st.executeUpdate();
} finally {
if (st != null)
st.close();
};
trace.info("Deleted user:: " + uid);
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 org.identityconnectors.framework.common.objects.*;
import java.text.*;
import org.identityconnectors.framework.common.exceptions.*;
import java.sql.*;
trace.info("[Update-Groovy] Attributes::" + attributes);
/** During an Update operation, AGCS sends the UID attribute along with updated attributes. Get all the values of attributes **/
String id = attributes.get("__UID__") != null ? attributes.get("__UID__").getValue().get(0) : null;
String firstName = attributes.get("FIRSTNAME") != null ? attributes.get("FIRSTNAME").getValue().get(0) : null;
String lastName = attributes.get("LASTNAME") != null ? attributes.get("LASTNAME").getValue().get(0) : null;
String email = attributes.get("EMAIL") != null ? attributes.get("EMAIL").getValue().get(0) : null;
String description = attributes.get("DESCRIPTION") != null ? attributes.get("DESCRIPTION").getValue().get(0) : null;
String salary = attributes.get("SALARY") != null ? attributes.get("SALARY").getValue().get(0) : null;
String joindate = attributes.get("JOININGDATE") != null ? attributes.get("JOININGDATE").getValue().get(0) : null;
Boolean enableValue = attributes.get("__ENABLE__") != null ? attributes.get("__ENABLE__").getValue().get(0) : true;
// Throw exception if uid is null
if (id == null) throw new ConnectorException("UID Cannot be Null");
PreparedStatement stmt = null;
try {
// Create prepared statement to update the MYDBAT_PERSON table
stmt = conn.prepareStatement("UPDATE dbat.MYDBAT_PERSON SET FIRSTNAME=IFNULL(?, FIRSTNAME), LASTNAME=IFNULL(?, LASTNAME), EMAIL=IFNULL(?, EMAIL), SALARY=IFNULL(?, SALARY), JOININGDATE=IFNULL(?, JOININGDATE), STATUS=IFNULL(?, STATUS) WHERE USERID =?");
// Set SQL input parameters
stmt.setString(1, firstName); // First name
stmt.setString(2, lastName); // Last name
stmt.setString(3, email); // Email
// Handle salary: Convert to BigDecimal if not null, otherwise set SQL NULL
if (salary != null) {
stmt.setBigDecimal(4, new BigDecimal(salary));
} else {
stmt.setNull(4, java.sql.Types.DECIMAL); // Set SQL NULL for salary
}
// Handle joindate: Convert to MySQL date format if not null
String dateStr = null;
if (joindate != null) {
Date date = new Date(joindate);
DateFormat targetFormat = new SimpleDateFormat("yyyy-MM-dd"); // MySQL date format
dateStr = targetFormat.format(date);
}
stmt.setString(5, dateStr); // Joining date
// Handle enable/disable status
if (enableValue) {
stmt.setString(6, "Enabled");
} else {
stmt.setString(6, "Disabled");
}
// Set UID for the WHERE condition
stmt.setString(7, id);
// Execute the update
stmt.executeUpdate();
} finally {
// Ensure the statement is closed to release resources
if (stmt != null) stmt.close();
}
trace.info("[Update] Updated user::" + id);
return new Uid(id);