Beiträge

Blogpost ODI.jpg

ODI // Getting an OdiInstance

Bisher musste man, wenn man bei der Ausführung einer ODI-Procedure der Technologie „Groovy“ am Agent die SDK ansprechen wollte, manuell im Sourcecode eine Connection zum Master- und Workrepository herstellen. Das macht es notwendig, dass die Connect-Info in einer Konfiguration hinterlegt werden musste.
Seit dem ODI der Version 12.2 gibt es aber eine odiRef-Funktion, die all diesen Aufwand obsolet macht und eine Instanz der Klasse OdiInstance direkt verfügbar macht.
Im Sourcecode schaut der Unterschied folgendermaßen aus:

pre ODI 12.2:

// Master Respository
String masterRepositoryJdbcDriver = "oracle.jdbc.OracleDriver";
masterRepositoryJndiName = null; // if agent is running on WLS you could use a JDNI data source for repo connection
MasterRepositoryDbInfo mRepDbInfo = null 
if (masterRepositoryJndiName)
  mRepDbInfo = new MasterRepositoryDbInfo(masterRepositoryJndiName, new PoolingAttributes()); 
else {
  masterRepositoryJdbcUrl      = "jdbc:oracle:thin:@host:port/service";
  masterRepositoryJdbcUser     = "ODI_REPO_SCHEMA";
  masterRepositoryJdbcPassword = "*****";
  mRepDbInfo = new MasterRepositoryDbInfo(masterRepositoryJdbcUrl, masterRepositoryJdbcDriver, masterRepositoryJdbcUser, masterRepositoryJdbcPassword.toCharArray(), new PoolingAttributes());
}

// Work Repository
workRepositoryName = "WORKREP";
WorkRepositoryDbInfo wRepDbInfo= new WorkRepositoryDbInfo(workRepositoryName, new PoolingAttributes());

// ODI Instance
OdiInstance odiInstance = OdiInstance.createInstance(new OdiInstanceConfig(mRepDbInfo, wRepDbInfo));

// Authentication
odiUser = "SUPERVISOR";
odiPassword = "*****";
Authentication auth = odiInstance.getSecurityManager().createAuthentication(odiSupervisorUser, odiSupervisorPassword.toCharArray());
odiInstance.getSecurityManager().setCurrentThreadAuthentication(auth);

// Transaction
ITransactionDefinition txnDef = new DefaultTransactionDefinition();
ITransactionManager tm = odiInstance.getTransactionManager();
tme = odiInstance.getTransactionalEntityManager();
ITransactionStatus txnStatus = tm.getTransaction(txnDef);

//
// ... place your SDK code here ...
//

tm.commit(txnStatus); // or tm.rollback(txnStatus);
auth.close();
odiInstance.close();

ab ODI 12.2:

OdiInstance odiInstance = odiRef.getOdiInstance();

// Transaction
ITransactionDefinition txnDef = new DefaultTransactionDefinition();
ITransactionManager tm = odiInstance.getTransactionManager();
tme = odiInstance.getTransactionalEntityManager();
ITransactionStatus txnStatus = tm.getTransaction(txnDef);

//
// ... place your SDK code here ...
//

tm.commit(txnStatus); // or tm.rollback(txnStatus);
odiInstance.close();

 

Programmgesteuertes Verschieben des ODI Load Plan in einen bestimmten Ordner

Haben Sie schon einmal erlebt, dass Ihr Load Plan nicht dort ist wo Sie ihn hinterlegt haben?

Aufgrund der manchmal schlechten Implementierung der ODI-Studio Benutzeroberfläche kommt es sehr oft vor, dass jemand anderes (oder sogar Sie selbst) einen Load Plan an einen Ort verschoben hat, an dem er nicht sein sollte.

Wenn die entsprechende Warnung in den ODI Studio Einstellungen deaktiviert ist, erkennt der Entwickler nicht einmal, dass er verschoben wurde.

Sobald Sie dann das Chaos entdeckt haben könnte es auch noch schwierig sein den Load Plan wegen Tonnen von Szenarien in der ODI-Studio Ansicht „Ladepläne und Szenarien“ zurückzusetzen.

Aus diesem Grund habe ich ein nützliches Skript geschrieben, um einen Load Plan wieder an seinen richtigen Platz zu bringen.

Viel Spaß!

import oracle.odi.core.persistence.transaction.ITransactionStatus;
import oracle.odi.core.persistence.transaction.support.DefaultTransactionDefinition;
import oracle.odi.domain.runtime.scenario.finder.IOdiScenarioFolderFinder;
import oracle.odi.domain.runtime.scenario.OdiScenarioFolder;
import oracle.odi.domain.runtime.loadplan.OdiLoadPlan;
import oracle.odi.domain.runtime.loadplan.finder.IOdiLoadPlanFinder;

//
// Find a subfolder with given folderName in parentFolder. 
// When no folder exists and creationFlag = true then the folder will be created.
//
def getScenFolder(parentFolder,folderName,creationFlag,tme) {
  def ff = (IOdiScenarioFolderFinder)tme.getFinder(OdiScenarioFolder.class);
  // There would be a findName() method in the finder class, 
  // but it delivers the first folder having the given name even if more than one exists. 
  // So here all folders have to be checked.
  def fs = ff.findAll(); 
  def folder = null;
  for (f in fs) {
    // If the folder has the same name and the parent folder is the given parentFolder then correct folder was found. 
    // The last part of the expression also checks the top level folder.
    if (f.getName()==folderName&&((f.getParentScenFolder()==parentFolder)||(!f.getParentScenFolder()&&!parentFolder))) {
      folder = f;
    }
  }
  // If the folder doesn't exist and creation is requested then it will be created´.
  if ((!folder)&&creationFlag) {
    if (parentFolder) {
      folder = new OdiScenarioFolder(parentFolder, folderName);
    }
    else {
      folder = new OdiScenarioFolder(folderName);
    }
    tme.persist(folder);
  }
  return folder;
}

//
// Find the folder represented by the full folderPath. 
// The creationFlag indicated if the path should be created if is not exists.
//
def getScenFolder(folderPath,creationFlag,tme){  
  // Split the folder path into parts based on slashes
  parts = folderPath.split("/");
  def parentFolder = null;
  // Loop through the parts to find the correct folder beginning with the root to the leaves.
  for (part in parts) {
    if (part) {
      folder = getScenFolder(parentFolder,part,creationFlag,tme);
      if (!folder) return null; // Stop when either no folder was found or no folder was created.
      parentFolder = folder; // Save found folder as parentfolder for the next level loop.
    }
  }
  return folder;
}

//
// Find the loadplan
//
def getLoadPlan(lpName,tme){
  lpf = (IOdiLoadPlanFinder)tme.getFinder(OdiLoadPlan.class);
  lp = lpf.findByName(lpName);
  return lp;
}

//
// Move the loadplan named with lpName to the folder given by the full folder path in folderPath. 
//
def fixLP(folderPath,lpName,creationFlag){
  txnDef = new DefaultTransactionDefinition();
  tm = odiInstance.getTransactionManager();
  tme = odiInstance.getTransactionalEntityManager();
  txnStatus = tm.getTransaction(txnDef);
  
  try{
    lp = getLoadPlan(lpName,tme);
    // Get the scenario folder given by the full path (creationFlag could force the creation of this path)
    scenf = getScenFolder(folderPath,creationFlag,tme);
    lp.setScenarioFolder(scenf); // Move the load plan to the scenario folder
    tme.persist(lp); // Persist the changes
    tm.commit(txnStatus); // Commit everything
  } catch (Throwable all) {
    println(all)
    tm.rollback(txnStatus); // Rollback if something went wrong
    println(all.getStackTrace());
  }
}

//
// Call the main function to move the loadplan where it should be.
//
fixLP('/ALL_LOADPLANS/MY_LOADPLANS','MY_LOADPLAN',true);

Ablöse Oracle Warehouse Builder OWB durch Oracle Data Integrator ODI

Ab der Oracle 12c R2 ist der Betrieb vom Oracle Warehouse Builder (OWB) nicht mehr lizenziert.

Das von Oracle verlautbarte Statement of Direction lautet: Future database releases beyond Oracle Database 12c Release 1 will not be certified with OWB 11.2. Oracle Warehouse Builder“

Für die Oracle 12c R1 EE Datenbank endet der Premier Support mit Juli 2018, sodass der zertifizierte Betrieb des OWB noch bis Mitte 2018 gesichert ist.

Aus strategischen Überlegungen ist jetzt der richtige Zeitpunkt um den Umstieg ohne Zeitdruck zu planen und Migrationsprojekte rechtzeitig auf Schiene zu bringen.

Oracle Warehouse Builder OWB

Ansicht Oracle Warehouse Builder OWB

Für die Migration sind folgende Szenarien möglich:

  • Oracle Data Integrator
  • Custom PL/SQL
  • Open Source ETL Tools
  • 3rd Party ETL Tools

Die Vorteile und Nachteile der einzelen Szenarien im Detail:

Migration via Oracle Data Integrator ODI

Vorteile:

  • Ein Migrationstool ist im OWB im letzten Patchset für 11.2.0.3 und 11.2.0.4 enthalten und migriert einen Großteil der Mappings vom OWB zu ODI
  • Seit Version 12c ist der flowbasierte Ansatz der Modellierungsweise dem OWB sehr ähnlich
  • Durch das Knowledge Module System (ähnlich einem Plug-in) ist der ODI sehr erweiterbar
  • Eine große Menge an vorgefertigten Knowledge Modules ist bereits vorhanden (uA. auch ein Knowledge Modul für Big Data )
  • Set Based Ansatz mit Nutzung aller Features von Oracle Datenbanken
  • Metamodellbasierender Ansatz
  • Standard Datenqualitätsprüfung integriert

Nachteile:

  • Für den Oracle Data Ingegrator fallen Lizenzkosten kann
  • Eine 100% Migration ohne manuellen Zusatzaufwand ist nicht möglich
  • Der ODI ist ein neues Tool mit entsprechendem Lernaufwand

 Ansicht des Oracle Data Integrator ODI

Ansicht Oracle Data Integrator ODI

Migration via Custom PL/SQL

Vorteile:

  • Alle notwendigen SQL Statements sind aus dem OWB Mappings extrahierbar
  • Set Based Ansatz mit Nutzung aller Features von Oracle Datenbanken möglich
  • Vorhandenes Knowhow der Mitarbeiter nutzbar
  • Unabhängigkeit von ETL Tools

Nachteile:

  • Kein metamodellbasierender Ansatz
  • ETL Gerüst muss selbst entwickelt werden
  • Erweiterbarkeit ist sehr aufwendig (z.B. Richtung Big Data oder anderen Quellen)
  • Große Abhängigkeit von Oracle Datenbank

 

Migration via Open Source ETL Tools

Vorteile:

  • Keine Lizenzkosten (Achtung: viele Open Source Tools sind in der Community Version in der Funktion sehr stark eingeschränkt)
  • Unabhängigkeit von Oracle
  • Metamodellbasierender Ansatz

Nachteile:

  • Set Based Verarbeitung oft nur mit Tricks anwendbar und viele Features  wie zB. Lineage sind nicht verwendbar
  • Eventuell ist ein starker Middleware Server zusätzlich zu den Datenbankservern notwendig
  • Neues Tool mit entsprechendem Lernaufwand
  • Enterprise Version von Open Source ETL Tools sind meistens mit Lizenzkosten verbunden

Migration mit 3rd Party ETL Tools

Vorteile:

  • Unabhängigkeit von Oracle
  • Metamodellbasierender Ansatz

Nachteile:

  • In der Regel hohe Lizenzkosten
  • Oft starke Middleware Server zusätzlich zu den Datenbankservern notwendig
  • Neues Tool mit entsprechendem Lernaufwand

Lizenzierung des Oracle Data Integrator ODI

  • Lizenzprozessor: Corefaktor (=0,5 bei Intel) * Anzahl der Cores des Servers der Datenbank, auf der Transformationsprozesse laufen.
  • CPU-Lizenzierung: es müssen nur die Lizenzprozessoren der Datenbank lizenziert werden, auf der die Transformationsprozesse laufen.
    D.h. wenn die Extraktionsprozesse die Daten 1:1 von der Quelle ins Ziel verschieben, muss die Quelle nicht lizenziert werden und es muss nur der Server der DWH-Datenbank betrachtet werden.
  • NUP-Lizenzierung: mindestens 25 User pro Lizenzprozessor; als Benutzer zählen diejenigen, die Transaktionsprozesse starten oder darauf zugreifen (d.h. sicher weit unter 25).

Gegenüberstellung der Migrations Varianten

  3rd Party Open Source ODI Custom PL/SQL
Metadatengetrieben Ja Ja Ja  
Erweiterbarkeit ? ? Ja  
Datenqualitätsprüfung ? ? Ja  
Skalierbarkeit ? ? Ja  
Investitionssicherheit Ja ? Ja  
Big Data Ready ? ? Ja  
Lizenzkostenfrei   Ja   Ja