Eine Referenzarchitektur stellt meiner Meinung nach eine konkrete Umsetzungsvorlage des definierten Idealbilds der zu erreichenden IT-Landschaft dar. Der Weg zur Umsetzung der Referenzarchitektur ist lang, und es werden projektbedingt in der Regel externe Einflüsse die Zielarchitektur beeinflussen. Damit der am Horizont positionierte Leuchtturm (Zielarchitektur und Strategie) trotz allem erreicht wird, muss der Architekt, darauf achten, dass der Pfad durch einstreuen von Frameworks, Werkzege oder Produkte durch die Entwickler, nicht zu weit verlassen wird und das Fernziel erreichbar bleibt. Ohne tiefgreifendes Know-How, einem Fundus von Best Practices innerhalb der Referenzarchitekturen und der stetigen Qualitätsprüfung bzw. deren Richtungsanpassung, wird die Architektur nicht stabil sein und sich langfristig in viele Richtungen ausbreiten. Konsequenterweise wird dies in einer unbeherrschbaren Architektur enden, wodurch die prognostizierten Vorteile wie Kostenreduzierung, Qualität und Agilität in unerreichbare Weite rücken. Dem Architekten kommt also eine zentrale Rolle zu, nicht nur bei der Definition, sondern insbesondere auch im gesamten Projektablauf von Strategie bis zur Realisierung.
ADFaces 11g Auth Redirect
•26. Juli 2009 • Kommentar schreibenMit folgendem Codefragment kann mit ADFFaces und ADFSecurity auf die registrierte JEE Loginseite verwiesen werden:
}if (!ADFContext.getCurrent().getSecurityContext().isAuthenticated()) { ExternalContext ctx = FacesContext.getCurrentInstance().getExternalContext(); HttpServletRequest request = (HttpServletRequest)ctx.getRequest(); String loginURL = request.getContextPath() + "/adfAuthentication?login=true&success_url=/faces/welcome"; ctx.redirect(loginURL); return null; }
Automatischer DB-Refresh der Daten auf dem Client
•18. Juni 2008 • Kommentar schreibenWie 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
•28. Mai 2008 • Kommentar schreibenOracle 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
•16. Mai 2008 • Kommentar schreiben
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
•16. Mai 2008 • Kommentar schreibenDer 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
•2. Mai 2008 • Kommentar schreibenMit 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)
•27. April 2008 • Kommentar schreibenUm 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
•17. April 2008 • Kommentar schreibenWas 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
•23. Februar 2008 • Kommentar schreibenBei 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
