№17. Работа с таймером

Тема: Работа с таймером

Время на выполнение: 30 минут

Задание

Разработать приложение, которое каждые 5 минут проверяет объем дискового пространства на сервере брокера и сохраняет данные в таблицу.

Выполнение

Создайте таблицу LAB_HDD_MONITOR в БД:

image002

CREATE TABLE "LAB_HDD_MONITOR"
   (  "DT" DATE,
      "FIESYSTEM" VARCHAR2(50),
      "BLOCKS" NUMBER,
      "USED" NUMBER,
      "AVAILABLE" NUMBER,
      "USE" NUMBER,
      "MOUNTEDON" VARCHAR2(50)
   ) ;

Создайте новое приложение LAB.17
image003

Подключите к приложение библиотеку Sys.Log.Lib
image004

Создайте модель сообщения:
image005

image006

image007

Схема сообщения:
image008

<?xml version="1.0" encoding="UTF-8"?><xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
 targetNamespace="http://sharavara.com/monitor" xmlns:Q1="http://sharavara.com/monitor">
   <xsd:element name="Disk" type="Q1:DiskType"></xsd:element>

   <xsd:complexType name="DiskType">
         <xsd:sequence>
                    <xsd:element name="LineDisk" type="Q1:LineDiskType" maxOccurs="unbounded" minOccurs="0"></xsd:element>
               </xsd:sequence>
   </xsd:complexType>

   <xsd:complexType name="LineDiskType">
            <xsd:sequence>
                <xsd:element name="Filesystem" type="xsd:string"></xsd:element>
                <xsd:element name="Blocks" type="xsd:string"></xsd:element>
                <xsd:element name="Used" type="xsd:string"></xsd:element>
                <xsd:element name="Available" type="xsd:string"></xsd:element>
                <xsd:element name="Use" type="xsd:string"></xsd:element>
                <xsd:element name="MountedOn" type="xsd:string"></xsd:element>
            </xsd:sequence>
   </xsd:complexType>
</xsd:schema>

Cоздайте поток Monitor:
image009

Добавьте к потоку ноду Timeout Notification
image010

Свойства ноды Timeout Notification
image011

Добавьте в рабочую область Java compute ноду. Переименуйте ее в Command и соедините с нодой таймера, как показано на рисунке
image012

Создайте класс для ноды Command
image013

image014

image015

image016

image017

Замените исходный од созданного класса на ниже следующий (можно скопировать из папки LAB):

package com.sharavara;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.StringTokenizer;

import com.ibm.broker.javacompute.MbJavaComputeNode;
import com.ibm.broker.plugin.MbElement;
import com.ibm.broker.plugin.MbException;
import com.ibm.broker.plugin.MbMessage;
import com.ibm.broker.plugin.MbMessageAssembly;
import com.ibm.broker.plugin.MbOutputTerminal;
import com.ibm.broker.plugin.MbXMLNSC;

public class Monitor_Command extends MbJavaComputeNode {

         public void evaluate(MbMessageAssembly inAssembly) throws MbException {
                   MbOutputTerminal out = getOutputTerminal("out");

                   MbMessage inMessage = inAssembly.getMessage();
                   MbMessage outMessage = new MbMessage();
                   copyMessageHeaders(inMessage, outMessage);

                   MbElement outRoot = outMessage.getRootElement();
                   MbElement xmlRoot = outRoot.createElementAsLastChild(MbXMLNSC.PARSER_NAME);

                   MbElement props = outRoot.getFirstChild();
                   MbElement enc = props.getFirstElementByPath("Encoding");
                   enc.setValue(273);
                   enc = props.getFirstElementByPath("CodedCharSetId");
                   enc.setValue(1208);

                   // Create MQMD
                   MbElement MQMD = props.createElementAfter("MQMD");
                   MQMD.createElementAsFirstChild(MbElement.TYPE_NAME_VALUE, "CodedCharSetId", 1208);

                   MbMessageAssembly outAssembly = new MbMessageAssembly(inAssembly, outMessage);

                   try {
                  //Create the XML declaration
                            MbElement xmlDecl = xmlRoot.createElementAsFirstChild(MbXMLNSC.XML_DECLARATION);
                            xmlDecl.setName("XmlDeclaration");
                            xmlDecl.createElementAsFirstChild(MbXMLNSC.ATTRIBUTE, "Version", "1.0");
                            xmlDecl.createElementAsFirstChild(MbXMLNSC.ATTRIBUTE, "Encoding", "utf-8");


                            MbElement disk = xmlRoot.createElementAsLastChild(MbElement.TYPE_NAME, "Disk", null);
                            disk.setNamespace("http://sharavara.com/monitor");     


                            /*
                            vs@broker:~/broker> df
                            Filesystem           1K-blocks     Used Available Use% Mounted on
                            rootfs               49534768 13386196 33632348 29% /
                            devtmpfs               1790968       164   1790804   1% /dev
                            tmpfs                 1796228   625940   1170288 35% /dev/shm
                            /dev/sda2             49534768 13386196 33632348 29% /
                            */

                            Process p;
                            try {
                                      p = Runtime.getRuntime().exec("df");
                                      p.waitFor();
                                      BufferedReader reader = new BufferedReader(new InputStreamReader(p.getInputStream()));
                                      String line = reader.readLine();
                                      line = reader.readLine();
                                      while (line != null) {
                                               MbElement elementLine = disk.createElementAsLastChild(MbElement.TYPE_NAME, "LineDisk", null);
                                               StringTokenizer st = new StringTokenizer(line);
                                               MbElement child = null;
                                               int i = 1;
                                               while (st.hasMoreTokens()) {
                                                        switch (i) {
                                                                  case 1 :
                                                                           child = elementLine.createElementAsLastChild(MbElement.TYPE_NAME, "Filesystem", null);
                                                                           child.setValue(st.nextToken());
                                                                           break;
                                                                  case 2 :
                                                                           child = elementLine.createElementAsLastChild(MbElement.TYPE_NAME, "Blocks", null);
                                                                           child.setValue(st.nextToken());
                                                                           break;
                                                                  case 3 :
                                                                           child = elementLine.createElementAsLastChild(MbElement.TYPE_NAME, "Used", null);
                                                                           child.setValue(st.nextToken());
                                                                           break;
                                                                  case 4 :
                                                                           child = elementLine.createElementAsLastChild(MbElement.TYPE_NAME, "Available", null);
                                                                           child.setValue(st.nextToken());
                                                                           break;
                                                                  case 5 :
                                                                           child = elementLine.createElementAsLastChild(MbElement.TYPE_NAME, "Use", null);
                                                                           child.setValue(st.nextToken());
                                                                           break;
                                                                  case 6 :
                                                                           child = elementLine.createElementAsLastChild(MbElement.TYPE_NAME, "MountedOn", null);
                                                                           child.setValue(st.nextToken());
                                                                           break;
                                                                  default :
                                                                           st.nextToken();
                                                                           break;
                                                        }
                                                       i++;
                                               }
                                               line = reader.readLine();
                                      }
                            } catch (Exception e) {
                                      e.printStackTrace();
                                      //TODO Procexx exceptions
                            }

                            // End of user code
                            // ----------------------------------------------------------

                            // The following should only be changed
                            // if not propagating message to the 'out' terminal
                            out.propagate(outAssembly);


                   } finally {

                            // clear the outMessage even if there's an exception
                            outMessage.clearMessage();
                   }
         }

         public void copyMessageHeaders(MbMessage inMessage, MbMessage outMessage) throws MbException {
                   MbElement outRoot = outMessage.getRootElement();

                   // iterate though the headers starting with the first child of the root
                   // element
                   MbElement header = inMessage.getRootElement().getFirstChild();
                   while (header != null /*&& header.getNextSibling() != null*/) // stop before
                   // the last
                   // child
                   // (body)
                   {
                            // copy the header and add it to the out message
                            outRoot.addAsLastChild(header.copy());
                            // move along to next header
                            header = header.getNextSibling();
                   }
         }
}

Сохраните приложение.

Добавьте к потоку подпоток обработки ошибок:
image018

Добавьте в рабочую область узел Database и переименуйте его в SaveToDatabase
image019

Свойства ноды Database
image020

Создайте ESQL модуль для ноды Database. Исходный код модуля:

BROKER SCHEMA com.sharavara
DECLARE ns NAMESPACE 'http://sharavara.com/monitor';

CREATE DATABASE MODULE Monitor_SaveToDatabase
                CREATE FUNCTION Main() RETURNS BOOLEAN
                BEGIN
                               DECLARE ref REFERENCE TO Body.ns:Disk;
                            MOVE ref FIRSTCHILD;
                               WHILE LASTMOVE(ref) DO
                                               INSERT INTO Database.VS.LAB_HDD_MONITOR (
                                               DT,
                                               FIESYSTEM,
                                               BLOCKS,
                                               USED,
                                               AVAILABLE,
                                               USE,
                                               MOUNTEDON
                                               )
                                               VALUES (
                                               CURRENT_TIMESTAMP,
                                               ref.Filesystem,
                                               CAST (ref.Blocks AS DECIMAL),
                                               CAST (ref.Used AS DECIMAL),
                                               CAST (ref.Available AS DECIMAL),
                                               CAST (REPLACE(ref.Use, '%', '') AS DECIMAL),
                                               ref.MountedOn
                                               );
                                               MOVE ref NEXTSIBLING;
                               END WHILE;
                               RETURN TRUE;
                END;
END MODULE;

Создайте BAR файл и установите приложение на сервере:
image021

После деплоя поток будет стартовать каждую минуту. Результат работы потока можно увидеть в таблице:
image022

Остановите приложение на сервере:
image023

Дополнительное задание:

Доработайте поток таким образом, что бы при превышении определенной квоты, уходило почтовое уведомление. Пример потока:
image024

image025