Wie baue ich einen eigenen Knoten für jadice server?

In diesem Artikel soll anhand eines einfachen Beispiels gezeigt werden, wie der jadice server um eigene Nodes bzw. Worker erweitert werden kann, um damit neue Verarbeitungsschritte realisieren zu können.

 

Node-Klasse
Die neu zu erstellende Nodeklasse muss von der abstrakten Superklasse com.levigo.jadice.server.Node erben. Dabei ist zunächst nur die abstrakte Methode getNodeClassName() zu implementieren. Als Rückgabewert hat diese den voll qualifizierten Klassennamen der korrespondierenden Workerklasse zu liefern:

package com.myCompany.jadice.client;
import com.levigo.jadice.server.Node;

public class DemoNode extends Node {
public String getNodeClassName() {
// Klassenname der Workerklasse aus Bsp unten
return "com.myCompany.jadice.worker.DemoWorker";
}
}

Soll es möglich sein, dass dem Worker zur Laufzeit Parameter übermittelt werden, so kann dies durch weitere Methoden in der Node-Implementierung erfolgen. Dabei ist zu beachten, dass alle Objekt- und statischen Attribute das Interface Serializable implementieren müssen, da diese über JMS serialisiert und transportiert werden.

public String getMyParameter() {
// Sollte z.B. über Setter-Methode gesetzt werden
return "a Parameter";
}

Der selbst implementierte Node muss sowohl client- als auch serverseitig im Klassenpfad eingebunden werden und kann später in eigene Workflows eingebettet werden.

 

Worker-Klasse
Die Workerklasse, in der die Konvertierung durchgeführt wird, erbt von der abstrakten, generischen Superklasse com.levigo.jadice.server.core.NodeWorker<N>, wobei der Typ-Parameter <N> für die zugehörige Node-Klasse steht.
Hier ist die abstrakte Methode work() zu implementieren, in der die serverseitige Konvertierung durchführt wird.

package com.myCompany.jadice.server;

// Hier nur die wichtigen Imports
import com.levigo.jadice.server.core.NodeWorker;
import com.myCompany.jadice.client.DemoNode;

public class DemoWorker extends NodeWorker<DemoNode> {

protected void work() throws Throwable {
// Im Bsp oben definierter Parameter
String myParam = getNode().getMyParameter();

// Abholen der Eingabedaten
for (Stream stream : getInputBundle()) {
InputStream unprocessedIS = stream.getInputStream();
// Metadaten des empfangenen Datenstrom
StreamDescriptor unprocessedSD = stream.getDescriptor();

// Methode, die den Datenstrom verarbeitet
// (nicht im Listing gezeigt)
InputStream processedIS = process(unprocessedIS, myParam);

// Metadaten des verarbeiten Datenstroms
// unprocessedSD wird als „Parent" gesetzt
StreamDescriptor processedSD = new StreamDescriptor(unprocessedSD);
processedSD.setDescription("<Beschreibung>");
processedSD.setMimeType("<MIME Type>");
processedSD.setFileName("<Dateiname>");

// Verknüpfen von Ergebnis und Metadaten
Stream result = new BundledStream(processedIS, processedSD);
// Weitergabe des Ergebnisses
getOutputBundle().addStream(result);
}
}

Der auf diese Weise implementierte Worker muss nur im Klassenpfad des jadice servers eingebunden werden und wird bei Verwendung des zugehörigen Nodes aus dem vorherigen Abschnitt automatisch aufgerufen.