Erweitern Sie RDi: Tool zur Anzeige von Nachrichtenwarteschlangen entwickeln, Teil 7
Als Einführungsbeispiel für die Arbeit mit RDi erstellen wir ein Tool zum Überwachen von Nachrichtenwarteschlangen
VON WIM JONGMAN
Fertigstellen des Tools Als nächstes passen wir die Methode selection Changed so an, dass sie auf die ausgewählten System i Objekte reagiert (Abbildung 6). Bei Markierung A wird der Teil, der an diese Methode übergeben wird, ebenso wie das ausgewählte Objekt, gespeichert. Diesen Teil benötigen wir später, wenn wir die Attribute unserer Nachrichtenüberwachung ändern wollen.
Zum Thema RDi sind erschienen: RDi als maßgeschneiderte Software-Entwicklungsumgebung
- Oktober 2009
Fügen Sie einer Anwendung eine Sicht hinzu
- Februar/März 2010
- April/Mai 2010
- Juni/Juli 2010
Tool zur Anzeige von Nachrichtenwarteschlangen
- entwickeln
- Oktober 2010
- Januar 2011
Bei Markierung B wird eine zusätzliche Prüfung durchgeführt, mit der sichergestellt werden soll, dass der übergebene Teil nicht Null ist. Bei Markierung C wird geprüft, ob die Auswahl aus einer Baumstruktur stammt. Falls das zutrifft, erhalten wir das erste Segment des Verzeichnisbaums und prüfen, ob es sich um Vorkommen von Host handelt (Markierung D). Wenn die Variable fi rstSegment unsere Kriterien erfüllt und nicht dem aktuellen Host entspricht, dann hat der Anwender einen neuen Host ausgewählt. Das bedeutet, dass wir die Überwachung mit Hilfe der bereits früher beschriebenen Methode stopMonitor beenden müssen (Markierung E).
Der Code bei Markierung F ist interessant, weil er zeigt, wie man auf das Objekt JTOpenAS400 zugreift, eine wichtige Klasse, wenn man mit Java auf das System i zugreifen will. Dieses AS400-Objekt können wir jetzt an die Methode loadMessageQueue() übergeben (Markierung G). Diese Methode ruft die letzten 50 (oder weniger) Nachrichten aus der angegebenen Warteschlange ab und stellt sie in unser Textfeld. Danach starten wir bei Markierung H einen Job, der die Nachrichtenwarteschlange auf neu ankommende Nachrichten überwacht.
Für diese Aufgabe verwenden wir einen Java-Thread, aber zuerst wollen wir die Methode erstellen, die die Nachrichten aus der Warteschlange liest und in das Textfeld überträgt (Abbildung 7). An dieser Methode können Sie lernen, wie man Nachrichten aus einer Nachrichtenwarteschlange abruft. Bei Markierung A prüfen wir, was ausgewählt wurde, und erstellen ein entsprechendes MessageQueue- Objekt. Dann weisen wir die Warteschlange an, uns die neueste Nachricht zu übergeben, indem wir ihre Methode setListDirection aufrufen. Bei Markierung B prüfen wir, ob sich Nachrichten in der Warteschlange befi nden. Falls nicht, geben wir einen entsprechenden Text aus und beenden den Aufruf. Bei Markierung C erhalten wir zuerst die Nachrichten, die die Methode load() anweisen, zuerst einmal die Nachrichten einzulesen, bevor wir das Ergebnis in ein Array laden. Bei Markierung D werden alle abgerufenen Nachrichten zu einer temporären Variable zusammengehängt. Die erste Nachricht, die eigentlich die letzte ist, wenn Sie sich an die Funktionsweise der Methode setListDirection() erinnern, wird bei Markierung E gespeichert, um später prüfen zu können, ob neue Nachrichten in der Warteschlange stehen. Bei Markierung F wird das Textfeld gefüllt, um uns die Ergebnisse anzuzeigen. Falls ein Fehler auftritt, wird er bei Markierung G abgefangen und anstelle der Nachrichtenim Textfeld angezeigt.
Können Sie uns noch folgen? Wir kommen zu unserer letzten Methode, waitForMessages() (Abbildung 8). Diese Methode überwacht die Nachrichtenwarteschlange auf neue Einträge. Wir verwenden dazu einen Java-Thread, was man in etwa mit dem Befehl SBMJOB vergleichen kann (der auszuführende Code wird in ein Runnable-Objekt gepackt).
Bei Markierung A wird eine innere Klasse erstellt, die die erforderlichen Methoden des Runnable Interface (der Methode run()) implementiert. Zum Warten auf neue Nachrichten können wir zwei Methoden verwenden. Methode A benutzt eine der receive() Methoden der Klasse MessageQueue. Diese Methode kann zwar auf neue Nachrichten warten, sie hat aber den Nachteil, dass sie nur dann eingesetzt werden kann, wenn die Nachrichtenwarteschlange nicht durch einen interaktiven Job gesperrt ist. Wir werden also Methode B einsetzen, die die bereits zuvor verwendete Methode getMessages() nutzt. Um das System nicht unnötig zu belasten, legen wir bei Markierung B 10 Sekunden Pause ein, bevor wir beim nächsten Mal versuchen, Nachrichten aus der Warteschlange zu lesen. Sie können die Verzögerung auch auf einen höheren Wert einstellen, wenn Sie möchten, aber Ihr Überwachungsprogramm ist dann nicht mehr besonders reaktionsschnell. Falls Nachrichten in der Warteschlange gefunden werden (Markierung C), rufen wir die jüngste ab. Hat diese Nachricht einen anderen Zeitstempel als die zuletzt gelesene, rufen wir den Nachrichtentext der ersten Ebene für diese neue Nachricht ab (Markierung D).
Abbildung 6: Endgültiger Code der Methode selectionChanged()
public void selectionChanged(IWorkbenchPart part, ISelection selection) {
this.oldPart = part;
this.oldSelection = selection;
// Return if we provided this selection
if (part == this || part == null)
return;
// Is this a tree selection?
if (selection instanceof ITreeSelection) {
Object firstSegment = ((ITreeSelection) selection).getPaths()[0]
.getFirstSegment();
if (firstSegment instanceof Host && firstSegment != currentHost) {
// Stop the monitor thread
stopMonitor();
AS400 theAS400 = null;
Host host = (Host) firstSegment;
currentHost = host;
theAS400 = ((ToolboxConnectorService) host
.getConnectorServices()[0]).getAS400(true);
loadMessageQueue(theAS400);
waitForMessage();
}
}
}
Abbildung 7: Endgültiger Code der Methode loadMessageQueue()
private void loadMessageQueue(AS400 theAS400) {
// Setup the correct message queue
1 if (user.equals(“QSYSOPR”))
queue = new MessageQueue(theAS400, “/qsys.lib/qsysopr.msgq”);
else
queue = new MessageQueue(theAS400);
queue.setListDirection(false);
// Get the messages from the queue
try {
2 int queueLength = queue.getLength();
if (queueLength == 0) {
setText(“No messages in queue”);
return;
}
3 queue.getMessages(0, queueLength > 50 ? 50 : queueLength);
queue.load();
QueuedMessage[] result =
queue.getMessages(0, queueLength > 50 ? 50 : queueLength);
StringBuffer messageText = new StringBuffer();
lastMessage = null;
for (QueuedMessage msg : result) {
4 messageText.append(msg.getText() + “\n\r”);
5 if (lastMessage == null)
lastMessage = msg;
}
6 setText(messageText.toString());
} catch (Exception e) {
7 setText(e.getMessage());
}
}
Abbildung 8: Endgültiger Code der Methode waitForMessage()
public void waitForMessage() {
final MessageQueue queue = this.queue;
Runnable runner = new Runnable() {
public void run() {
String txt = “”;
QueuedMessage msg = null;
try {
Thread.sleep(10000);
queue.load();
if (queue.getLength() > 0)
msg = queue.getMessages(0, 1)[0];
if (msg != null && !msg.getDate().equals(lastMessage.getDate()))
txt = msg.getText();
if (txt.length() > 0) {
loadMessageQueue(queue.getSystem());
if (alert && msg.getSeverity() >= severityInt) {
final String text2 = txt;
Display.getDefault().syncExec(new Runnable() {
public void run() {
MessageDialog.openInformation(Display.getDefault().getActiveShell(),
“New Message”, text2);
}});}}
waitForMessage();
} catch (Exception e) {
txt = “Error “ + e.getMessage();
setText(txt);
return;
}}};
monitorThread = new Thread(runner);
monitorThread.setName(“Message Monitor”);
monitorThread.start();
}
Falls es bei Markierung E Nachrichtentext der ersten Ebene gibt, laden wir zunächst unsere View neu (Markierung F). Falls wir alarmiert werden wollen, prüfen wir, ob die Schwere der Nachricht über dem festgelegten Schwellenwert liegt (Markierung G). Trifft beides zu, öffnen wir eine Message Box, die auf die neue Nachricht hinweist. Nachdem die Arbeit getan ist, können wir bei Markierung H unseren Job beenden. Aber zuvor setzen wir noch einen neuen ab, indem wir rekursiv die Methode aufrufen, die diese Runnable umgibt. Falls irgendwelche Fehler auftreten, wird ein Catcher aktiv, der uns darüber informiert (Markierung I). Diese Defi nition der Runnable bewirkt zunächst einmal noch nichts, weil sie erst zur Ausführung übertragen werden muss (Markierung J). Zum Testen unserer Anwendung starten Sie vom Manifest- Editor aus eine Eclipse-Sitzung und öffnen die RSE-Perspektive). Dann öffnen Sie die Sicht (Window/ Show View/Other) und die Baumstruktur. Unsere Sicht muss sich darin befi nden. Öffnen Sie die Sicht und – das ist sehr wichtig – einen Ihrer System i Nodes aus der RSE-Sicht. Unsere Sicht reagiert auf eine Auswahl in der RSE-Sicht.
Das Tool zum Einsatz bringen
Der letzte Schritt (versprochen!) ist das Erzeugen einer einsetzbaren Komponente, die in jeder Installation von RDi 7.5 lauffähig ist. Wechseln Sie dazu in die Package Explorer Sicht, klicken Sie mit der rechten Maustaste auf den Projektnamen, und wählen Sie Export, wie in Abbildung 9 dargestellt. In dem Wizard, der daraufhin erscheint, wählen Sie „Plug-in Development, Deployabel Plugins and Fragments“, und klicken Sie auf „Next“. Geben Sie ein Verzeichnis in das entsprechende Feld ein, und klicken Sie auf „Finish“ (Abbildung 10). Dadurch wird ein Verzeichnis namens „Plugins“ erstellt, das eine jar-Datei mit unserem kleinen Produkt enthält. Zum Installieren der Anwendung wechseln Sie in das Verzeichnis, in dem RDi installiert ist, und in dem sich auch die Datei eclipse.exe befi ndet. Erstellen Sie in diesem Verzeichnis ein Unterverzeichnis „Dropins“, falls es noch nicht existiert, und speichern Sie die jar-Datei in diesem Verzeichnis.
Starten Sie jetzt RDi neu, öffnen Sie den RSE, unsere Nachrichten-Sicht, und wählen Sie Ihr System i in der RSE-Sicht aus. Geben Sie der Sicht eine Sekunde, um sich einzurichten, und wechseln Sie dann zu Ihrem Green Screen, um sich selbst eine Nachricht zu senden (Abbildung 11).
Warum es wichtig ist, RDi zu erweitern
In unserer Artikelserie haben Sie gelernt, wie man RDi erweitern kann, RDi ist bedeutsam, weil es das Entwicklungs-Tool moderner System i Shops ist. Und obwohl RDi bereits einige kleine Kostbarkeiten enthält, kann es kaum alles bieten, was Sie sich zur Erleichterung Ihrer Arbeit eingerichtet haben. Es ist viel wert, wenn man seine eigenen Tools in RDi integrieren kann. Das Erweitern von Eclipse und somit RDi ist nicht einfach. Viele Unternehmen bieten Eclipse RCP-Schulungen an, die die Grundkenntnisse in vier Tagen vermitteln. Etwas Erfahrung in der Java-Programmierung und im Umgang mit Eclipse/RDi sind erforderlich. Industrial-TSI und die Eclipse Foundation bieten eine Reihe von Schulungen zu diesem Thema an. Näheres dazu finden Sie auf www.eclipse.org.
Wim Jongman
(wim.jongman(ät)remainsoftware.com) ist Mitbesitzer von Remain Software und Industrial-TSI. Wim Jongman und sein Team von Remain Software sind die Autoren eines Eclipse/RDi-basierten Software Change Management Systems für das System i mit dem Namen TD/OMS. Wim Jongman ist Mitglied der Eclipse Training Alliance und hat schon viele Programmierer in die Verwendung und Erweiterung von Eclipse und Eclipse-basierten Produkten wie RDi eingewiesen.Übersetzt und für den deutschsprachigen Markt überarbeitet von Mathias Spateneder.


