header image
 

Automatischer DB-Refresh der Daten auf dem Client

Wie oft steht man vor dem Problem eine Architektur zu entwickeln, die Performant sein soll und gleichzeitig die Daten auf Client/Middletierseite aktuelle sein müssen. Übliche Lösungen setzden deshalb auf Client/MiddleTier-Seite Caches wie EHCache unter Hibernate oder JDBC oder ähnliches ein. Der Refresh erfolgt dann zyklisch per Poll oder Löschen ALLER Objekte im Cache.  

Mit Oracle Database Change Notification lässt sich dies jetzt eleganter lösen. DB-Änderungen werden nun satzgenau dem Client per Notification übermittelt. Im OTN existert dazu ein Beispiel für die 11g DB. Der Mechanismus funktioniert jedoch auch schon mit der Oracle XE DB Version 10.2 und dem ojdbc5 Treiber (dieser ist z.B. im 11g Jdeveloper enthalten).
Das im OTN veröffentliche Beispiel “Oracle Database Change Notification
muss dann jedoch die Methode “onDatabaseChangeNotification” wie folgt ersetzen:


public void onDatabaseChangeNotification(DatabaseChangeEvent e)
{
/* QueryChangeDescription [] changes = e.getQueryChangeDescription();
// Object ox = e.getTableChangeDescription();
// QueryChangeDescription change = changes[0];
*/
TableChangeDescription [] tableChanges = e.getTableChangeDescription();
TableChangeDescription tableChange = tableChanges[0];
RowChangeDescription[] rowChanges = tableChange.getRowChangeDescription();
RowChangeDescription rowChange = rowChanges[0];
oracle.sql.ROWID rowid = rowChange.getRowid();
demo.getUpdateForROWID( rowid );
}
}

MD5 Password-Check per PL/SQL und Java

Oracle bietet in der DB mehrere Möglichkeiten Werte in der DB zu verschlüsseln. Hat man jedoch den Anwendungsfall nur ein einzelnes Feld (z.B. Passwort) in der DB zu verschlüsseln und muss man sowohl per Java als auch per PL/SQL dazu eine LoginCheck-Funktion implementieren, kann dies mit folgender Routine einfach umgesetz werden.

Angepasste PL/SQL Funktion aus Oracle Metalink zur Verschlüsselung:


FUNCTION md5encode (CLEARTEXT IN VARCHAR2) RETURN VARCHAR2
IS
chk VARCHAR2(16);
hex VARCHAR2(32);
i INTEGER;
c INTEGER;
h INTEGER;
BEGIN
IF CLEARTEXT IS NULL THEN
RETURN ”;
ELSE
chk := dbms_obfuscation_toolkit.md5(input_string=>CLEARTEXT);
FOR i IN 1..16 LOOP
c := ASCII(SUBSTR(chk, i, 1));
h := TRUNC(c / 16);
IF h >= 10 THEN
hex := hex || CHR(h + 55);
ELSE
hex := hex || CHR(h + 48);
END IF;
h := MOD(c, 16);
IF h >= 10 THEN
hex := hex || CHR(h + 55);
ELSE
hex := hex || CHR(h + 48);
END IF;
END LOOP;
RETURN hex;
END IF;

END;

Dazu passende Java Verschlüsselung:

public String md5encode( String password ) throws Exception {
MessageDigest md5 = MessageDigest.getInstance( “MD5″ ) ;
byte[] rawBytes = md5.digest( password.getBytes() ) ;

String charIndex = “0123456789ABCDEF”;
StringBuffer sb = new StringBuffer(rawBytes.length * 2);

byte rawByte;
for (int i = 0; i> 4) & 0xF;
sb.append(charIndex.charAt(ix));
ix = rawByte & 0xF;
sb.append(charIndex.charAt(ix));
}
return sb.toString();
}

Die Checkroutine verschlüsselt nun das Klartextpassword per md5encode () und macht mit dem gespeicherten verschlüsselten Password einfachen einen String-Vergleich.

Java Psoudocode dazu:

String myCurrentPassword = “hallo123″
if(obfuscatedPasswordFromDBColumn.equals(md5encode(myCurrentPassword)) == true)
System.println(”Login OK”);
else
System.println(”Login Fehlgeschlagen”);

Loginmodule mit OC4J 11g und JSF

Mit Oracle 11g ist es nun möglich über seine eigen geschriebene Loginseite ein J2EE Security-Context aufbauen.

Es ist dabei nicht mehr notwendig ( aus Sicherheitsgründen jedoch empfohlen) den in der web.xml definierten Security-Context mit konfigurierter Loginseite zu verwenden.

Mit JSF kann beispielsweise innerhalb einer JSF-ManagedBean mit folgender Methode der J2EE SecurityContext des OC4J-Containers aufgebaut werden. 

 

LoginContext ctx = new LoginContext(”myContext”, subject, callback);

 

Die zur Ausführung kommende JAAS-LoginModule werden über die jps-config.xml Datei konfiguriert und über den Kontextname (hier im Beispiel “myContext”) referenziert.

 

<jpsContext name=”myContext”>

   <serviceInstanceRef ref=”myLoginmodule”/>

   <serviceInstanceRef ref=”xds.loginmodule”/>

   <serviceInstanceRef ref=”SAML.loginmodule”/>

   <serviceInstanceRef ref=”idstore.loginmodule”/>

</jpsContext>

 

Die hier referenzierten LoginModule (serviceInstanceRef) werden ebenfalls in der Datei jps-config.xml konfiguriert.

 Die Einbindung eines eigenen Loginmodules (JAAS-konform) und die gleichzeitige Ausführung der Standardmodule - beispielsweise das Setzen eines SAML-Tickets für WebService oder SSO - kann somit ebenfalls sehr einfach erfolgen.

 

<serviceInstance name=”de.bmaier.sample.security” provider=”jaas.login.provider”>

<description>My Sample LoginModule</description>

<property name=”loginModuleClassName” value=”<hier muss der Klassename mit Package-Angabe des eigenen LoginModules eingetragen werden “/>

<property name=”jaas.login.controlFlag” value=”REQUIRED”/>

</serviceInstance>

 

Ein Beispiel findet sich im Oracle-Forum   

 

 

 

 

 

 

 

Oracle BPEL Aufrauf aus BEA AquaLogic Service Bus

Der Versuch BPEL Prozesse aus BEA AquaLogic aufzurufen wird mit folgender Meldung fehlschalgen:

An unexpected error occured accessing information about the WSDL of the service:
com.bea.wli.config.component.NotFoundException: Can not compute effective WSDL for : BusinessService SecureInvocation/BizServices/ORCL MyTestBPELProzess standalone

Das Problem kann einfach durch Anpassung der  generierte AquaLogic  WSDL behoben werden:


<?xml version=”1.0″ encoding=”UTF-8″?>
<definitions name=”MyTestBPELProzess” targetNamespace=”http://xmlns.oracle.com/TestBPELProzess/TestBPELProzess/MyTestBPELProzess“> 

<plnk:partnerLinkType name=”MyTestBPELProzess”>
<plnk:role name=”MyTestBPELProzessProvider”>
<plnk:portType name=”client:MyTestBPELProzess”/>
</plnk:role>
</plnk:partnerLinkType>

Ändern zu:

<plnk:partnerLinkType name=”MyTestBPELProzess” xmlns:clientABC=”http://xmlns.oracle.com/TestBPELProzess/TestBPELProzess/MyTestBPELProzess“> 

 

<plnk:role name=”MyTestBPELProzessProvider”>
<plnk:portType name=”clientABC:MyTestBPELProzess”/>
</plnk:role>
</plnk:partnerLinkType>

 

 

 

Automatischer Web-Seiten Refresh mit ADFFaces 11g - Active Data Service

Mit Active Data Service stellt das ADFFaces Framework (11g) nun einen Mechanismus  bereit auf Datenänderungen im Backend zur reagieren und einen automaitschen Seiten-Refresh durchzuführen. Trotz dass die Funktion auf AJAX basiert, ist es dabei nicht notwendig JavaScript zu implementieren.

Einzig muss der JSF-Datenlieferant einer ADFFaces-Komponente - hier im Beispiel af:table - das Interface ActiveDataModel implementieren.

public class MyTableData extends CollectionModel implements ActiveDataModel {

….

Zu Beginn ruft der DataUpdateManager (ADF-Class)  die Methode  startActiveData() des ActiveDataModel und übergibt u.a. die ADF-Komponente, die auf Änderungs-Events horcht. 

    public synchronized void startActiveData(Collection<Object> rowKeys,
int startChangeCount,
ActiveDataListener listener) {

Zur Deregistrierung ruft ADF die Methode stopActiveData(...) auf. Im Normalfall wird man hier den Listener wieder aus seiner lokalen ListenerListe entferenen und bei Änderungen keinen Event mehr senden.

Informiert werden die ADFKomponenten über Events, wenn sich im Backend etwas geändert hat.
Dazu werden im Backend meist asynchrone Mechanismen wie Queues (MDB, JMS, AQ …), Threads, oder typische asynchrone Protokoll wie Mails/Chat verwendet.

Eine Benachrichtigung wird gewöhnlich in der Callback-Routine (z.B. onMessage  bei MDB) wie folgt aussehen:       

  List<ActiveDataEntry> myList = new ArrayList();
        myList.add(newEntry);
        ActiveDataUpdateEvent event =
            new MyActiveDataUpdateEvent(this, count, myList);
        for (ActiveDataListener listener : registeredActiveDataListeners) {
                registeredActiveDataListeners.dataChanged(event);
        }

 

Um ADF noch mittzuteilen welche Werte sich tatsächlich geändert haben und somit in dem UI refreshed werden sollen (AJAX), muss das Interface ActiveDataEntry für alle Rückgabewerte implementiert werden. Gewöhnlich wir man hier ein ActiveDataEntryWrapper implementieren und über Methoden  wie z.B. getChangeTyp() mitteilen, um welche Art von Änderungen es sich handelt. 

In der JSF-Seite ist an der Komponente lediglich die datenliefernde MannagedBean mit dem Interface ActiveDataModel einzutragen:


<af:table value=”#{MyTableDataBean}” var=”row”>
<af:column sortable=”false” headerText=”Message Body”
align=”start”>
<af:outputText value=”#{row.body}”/>
</af:column>
<af:column sortable=”false” headerText=”Message Form”
align=”start”>
<af:outputText value=”#{row.form}”/>
</af:column>
</af:table>

 

Ein gutes Beispiel (Download) dazu habe ich unter http://www.oracle.com/technology/pub/articles/jellema-googletalk.html gefunden.

 

 

 

Druckansicht einer JSF-Seite (ADFFaces 11g)

Um eine JSF-Seite in Druckansicht auszugeben - also ohne Links und sonstigen Elementen, die sich in HTML/AJAX  schlecht drucken lassen -, stellt das ADFFaces 11g Framework das Tag showPrintablePageBehavior bereit. Aufzurufen ist diese einfach durch Einbettung in das Command-Tag:

<af:commandButton immediate=”true text=”Druckansicht >
    <af:showPrintablePageBehavior />
</af:commandButton>

 

 

EMA - Enterprise Architecture Management

Was ist der Unterschied zwischen EAM und SOA, ist derzeit eine Häufig gestellte Frage:
EAM (Enterprise Architecture Management) wird verwendet um eine ganzheitliche Sicht auf die gesamte IT inkl. der Business-Architektur zu bekommen.  SOA stellt dagegen eine IT-Strategie innerhalb der EAM dar, welche zur Realisierung der definierten Ziele angewandt werden kann. EAM ist im Gegensatz zu SOA ein recht altes Konzept, das bereits Anfang der 80er von Zachmann definiert wurde.  

Durch den Einzug von SOA bekommt EAM eine immer bedeutendere Rolle in den Unternehmen und stellt zudem für strategisch operierende Managern ein unentberliches Hilfsmittel dar, die gesteckten Ziele durch effiziente Nutzung der IT zu errreichen.

 

SOA-Suite 11g - Out of Processes

Bei der Standardkonfiguration der Oracle SOA Suite 11g Beta - ist im Jdeveloper 11g enthalten -  und Verwendung der Oracle XE Datenbank als Repository werde die etwas komplexeren Beispiele wie Orderbooking den Fehler “Out of Processes” melden.

Die Anzahl der DB-Prozesse kann einfach mit folgendem Script dauerhaft erhöht werden:

sqlplus sys/system@XE as sysdba
SQL> show parameter session
SQL> show parameter processes
SQL> alter system set sessions=100 scope=spfile;
SQL> alter system set processes=150 scope=spfile;
SQL> shutdown immediate
SQL> startup
SQL> show parameter processes
SQL> show parameter session

Sicherheitsmatrix der Oracle DB

  Security Feature     8i     9i     9iR2     10g R1     10g R2     11g R1  
Adv. Security Option: TDE:
  Tablespace encryption
          X
Adv. Security Option: TDE:
  SecureFile LOB encryption
          X
Adv. Security Option: TDE:
  HSM support for master key
  mgmt
          X
Adv. Security Option:
  Kerberos: Long principal
  names
          X
Adv. Security Option:
  Kerberos: Credential cache
          X
Adv. Security Option:
  Strong Authentication for
  SYSDBA and SYSOPER
  connections
          X
Standards Based Password
  Verifier (SHA-1)
          X
Support for Multi-case &
  Special Characters in
  Passwords
          X
TDE, VPD, OLS, AppContext,
  EUS managed in Enterprise
  Manager (except OWM)
          X
SYSASM instead of SYSDBA
  for managing ASM
          X
Automatic Secure
  Configuration (Auditing,
  Password expiration etc.)
          X
 
Database Vault: Privileged
  User Controls
    X   X X
Database Vault:
  Multi-factor authorization
    X   X X
Database Vault: Custom
  access control policies
    X   X X
Database Vault: Command
  Rules
    X   X X
Database Vault: Separation
  of duty
    X   X X
VPD support for column
  policies
      X X X
VPD support for column
  masking
      X X X
Enhanced policy caching for
  VPD
      X X X
OLS - Store policies and
  user authorizations in
  Oracle Internet Directory
      X X X
OLS fully supports RAC and
  TAF
        X X
DBMS_CRYPTO replaces
  DBMS_OBFUSCATION_TOOLKIT
      X X X
Enterprise Manager
  introduces a basic policy
  for helping DBA’s harden an
  Oracle installation
      X X X
Enterprise Manager helps
  with patch management
      X X X
Proxy Authentication -
  supports thin-JDBC
      X X X
‘Connect’ role grants
  ‘create session’ only (use
  rstrconn.sql to revert to
  old behavior)
        X X
Remote Listener admin only
  possible when Listener
  password is set
        X X
Fine Grained auditing
  supports all DML
      X X X
Extended and Uniform Audit
  Trail
      X X X
Dynamic OS auditing
  location change
      X X X
SQL capture added to
  standard auditing
      X X X
Kerberos support for
  Enterprise Users
      X X X
All PKI dependencies
  removed for Enterprise User
  Security (except dblink)
      X X X
Multiple verifier support,
  case-sensitive password
  support in EUS
      X X X
Transparent Data
  Encryption: Compliance
  enablement
        X X
 
VPD support of partitioned
  fined-grained access control
  X X X X X
Global Application Context   X X X X X
OLS supported on all
  platforms
  X X X X X
Oracle Label Security:
  Releasabilities
    X X X X
VPD support for Static and
  Dynamic Policies
    X X X X
Secure Application Roles   X X X X X
Default accounts locked on
  install
  X X X X X
Proxy Authentication -
  supports thick-JDBC
  X X X X X
Proxy Auth. - credential
  proxy of X.509 certificates
  or Distinguished Names (DN)
  X X X X X
DBA GRANT/REVOKE of Object
  Privileges
    X X X X
Password for Users SYS and
  SYSTEM at Database Creation
    X X X X
Fine Grained Auditing   X X X X X
Audit SYS user     X X X X
Password authenticated
  Enterprise User Security
  X X X X X
Strong Authentication:
  Support for RADIUS
  Authorizations
  X X X X X
Support for PKCS#12
  certificates
  X X X X X
User Migration Utility for
  migrating DB users to LDAP
    X X X X
Network encryption support
  for AES
    X X X X
Public Key Infrastructure:
  SSL Hardware Acceleration
    X X X X
 
Virtual Private Database
  (VPD) allows transparent
  fine-grained access control
X X X X X X
Application context allows
  a secure and private
  application-defined cache
  (local)
X X X X X X
Database logon triggers
  allows preliminary security
  checks and setup capability
X X X X X X
Oracle Label Security - (on
  Sun Solaris only)
X (8.1.7) X X X X X
Policy Manager for GUI
  management of Fine Grained
  Access Control
X (8.1.7) (1) X X X X  
  Oracle Label Security receives Common Criteria EAL4
  evaluation (
    target=”_new”>Status
  )  
X (8.1.7.)   X X X  
VPD support for Parallel
  Query
X X X X X X
  Database receives Common Criteria EAL4 evaluation (
    target=”_new”>Status
  )  
X (8.1.7.)   X X X  
Password complexity
  routines ensuring password
  policies
X X X X X X
User profiles supports
  password management
X X X X X X
Account locking X X X X X X
Proxy Authentication for
  OCI programs
X (8.1.7) X X X X X
DBMS_OBFUSCATION_TOOLKIT
  for stored database
  encryption and hashing
X X X X X X
Enterprise Users for
  centralized user management
  and schema separation
X X X X X X
Network encryption receives
  FIPS evaluation
X (8.1.6) X X X X X
SSL for encryption and
  strong authentication
X X X X X X
Network encryption for
  ‘thin’ JDBC drivers
X (8.1.6) X X X X X
Unified User Model joins
  Web-based SSO with Database
  Enterprise Users
X X X X X X
  (1): OLS only  
 
 

* keine verbindliche Auflistung!

ADF-BC: ViewObject, Row, RowSet, RowSetIterator …

Das ADF-ViewObject hat in ADF-BC die Aufgabe SQL-Statements und Paramter zur Abfrage zu verwaten. Daten werden intern durch folgende Klassen verwaltet:
  • Row - Repräsentiert einen Tupel
  • RowSet - Repräsentiert eine SQL-Ergebnismenge mit Row Objekten          
Der Zugriff auf die Ergebnismenge erfolgt in der Regel über den  RowSetIterator
Bei einer Abfrage (vo.executeQuery() ) erstellt das ViewObjekt intern ein RowSet und ein RowSetIterator. Vereinfacht dargestellt würde jeder Zugriff wie folgt aussehen: vos.getRowSet().createRowSetIterator("sss").next();
                                                                                                                                    
Wer mit ADF-BC schon gearbeitet hat fragt sich nun warum können dann mit einer ViewObject Instanz die Operationen vo.next, vo. last, vo.first, usw. direkt aufgerufen werden?
Ganz einfach: die Klasse ViewObject implementiert zusätzlich das Interface RowSetIterator und stellt damit diese Mehtoden bereit. Intern erzeut das VO bei einer Abfrage einen RowSet und legt ihn intern in einr Liste mit dem Namen “_default” ab. Greift man nun z.B. mit der Mehthode vo.first() auf das VO zu, dann wird geprüft, ob ein Default-Rowset schon vorhanden ist und delegiert den Methodenaufruf einfach an den RowSet bzw. RowSetIterator weiter. Sollte kein RowSet vorhanden sein, dann wird zuvor automatisch die ExecuteQuery-Mehtode aufgerufen und ein RowSet angelegt.
Möchte man mehrere Iteratoren oder RowSets verwalten, dann sind diese benannt durch die Mehtode vo.createRowSet(Name) bzw. rowSet.createRowSetIterator(Name) anzulegen und per vo.findRowSet(name) wieder vom ViewObject abzuholen.
Siehe auch API Doc: