Commit 1a4e1ab4 authored by Christian Kniss's avatar Christian Kniss
Browse files

Initialisierung GitLab-Repo fuer Sourcecode der SWE de.bsvrz.kex.lmstic3-FREI_V1.1.1_D2017-07-04

parents
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
Manifest-Version: 1.0
Archiver-Version: Plexus Archiver
Built-By: gysi
Created-By: Apache Maven
Build-Jdk: 1.8.0_121
+365 −0
Original line number Diff line number Diff line
/*
 * Segment 2 (KEx), SWE LMS-TIC3
 * Copyright (C) 2016 BitCtrl Systems GmbH 
 * 
 * This library is free software; you can redistribute it and/or modify it under
 * the terms of the GNU Lesser General Public License as published by the Free
 * Software Foundation; either version 2.1 of the License, or (at your option)
 * any later version.
 *
 * This library is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
 * details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this library; if not, write to the Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA.
 *
 * Contact Information:
 * BitCtrl Systems GmbH
 * Weißenfelser Straße 67
 * 04229 Leipzig
 * Phone: +49 341-490670
 * mailto: info@bitctrl.de
 */

package de.bsvrz.kex.lmstic3.empfang.dekoder;

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.nio.file.attribute.FileTime;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import com.bitctrl.Constants;

import de.bsvrz.kex.lmstic3.empfang.ftpempfang.FTPEmpfang;
import de.bsvrz.kex.lmstic3.vew.LMSFTPListener;
import de.bsvrz.kex.lmstic3.vew.LMSKommunikationsstatus;
import de.bsvrz.kex.lmstic3.vew.LMSMeldungenListener;
import de.bsvrz.kex.lmstic3.vew.LMSParameter;
import de.bsvrz.kex.lmstic3.vew.LMSTIC3LogTools;
import de.bsvrz.kex.lmstic3.vew.LMTIC3Betriebsmeldungen;
import de.bsvrz.kex.lmstic3.vew.LMTIC3Betriebsmeldungen.LMTIC3Betriebsmeldung;
import de.bsvrz.kex.lmstic3.vew.LmsMsg;
import de.bsvrz.kex.lmstic3.vew.daten.ExterneMeldung;
import de.bsvrz.kex.lmstic3.vew.daten.tic.TIC3Meldung;
import de.bsvrz.kex.lmstic3.vew.daten.tic.TIC3MeldungsDaten;
import de.bsvrz.sys.funclib.debug.Debug;

/**
 * Modul Meldungsdekodierer.
 *
 * @author BitCtrl Systems GmbH, Gieseler
 * @version $Id: Meldungsdekodierer.java 66499 2017-06-21 12:23:02Z gieseler $
 */

public class Meldungsdekodierer extends Thread implements LMSFTPListener {

	/**
	 * Logger für Debug-Ausgaben.
	 */
	private final Debug debug = Debug.getLogger();

	/**
	 * Name der Landesmeldestelle.
	 */
	private String lmsName;

	/**
	 * Die aktuellen Parameter.
	 */
	private LMSParameter lmsParameter = new LMSParameter();

	/** Kommunikationsstatus. */
	private LMSKommunikationsstatus kommunikationsStatus;

	/** die Liste neu empfangener Dateien. */
	private final ArrayList<File> neueDateien = new ArrayList<>();

	/** FTP-Serverthread. */
	private FTPEmpfang ftpserver;

	/**
	 * Liste der angemeldeten Listener.
	 */
	private final List<LMSMeldungenListener> listenerList = new ArrayList<>();

	/**
	 * Run-Flag.
	 */
	private boolean run = true;

	/** Waitlock. */
	private final Object waitLock = new Object();

	private boolean mitValidierung = true;

	/**
	 * Konstruktor.
	 *
	 * @param lms
	 *            Landesmeldestelle
	 * @param lmsParameter
	 *            Parameter
	 * @param mitValidierung
	 *            legt fest, ob die empfangenen Dateien gegen das Schema
	 *            validiert werden sollen
	 */
	public Meldungsdekodierer(final String lms, final LMSParameter lmsParameter, final boolean mitValidierung) {
		super();
		this.mitValidierung = mitValidierung;
		this.setName(this.getClass().getSimpleName());
		this.lmsName = lms;
		this.lmsParameter = lmsParameter;

		// selbst starten
		start();
	}

	@Override
	public void empfangen(final List<File> dateien) {
		synchronized (neueDateien) {
			neueDateien.addAll(dateien);
			Collections.sort(neueDateien);
		}

		synchronized (waitLock) {
			waitLock.notify();
		}
	}

	@Override
	public void kommunikationsStatus(final LMSKommunikationsstatus status) {
		kommunikationsStatus = status;
		if (kommunikationsStatus == LMSKommunikationsstatus.GESTOERT) {
			LMSTIC3LogTools.log(debug, LmsMsg.WarningStoerungEingehend, lmsName);
			LMTIC3Betriebsmeldungen.sendeMeldung(LMTIC3Betriebsmeldung.KOMMUNIKATION_EINGEHEND_GESTOERT);
		}

		if (kommunikationsStatus == LMSKommunikationsstatus.NICHT_GESTOERT) {
			LMSTIC3LogTools.log(debug, LmsMsg.InfoStatusEingehendOK, lmsName);
			LMTIC3Betriebsmeldungen.sendeMeldung(LMTIC3Betriebsmeldung.KOMMUNIKATION_EINGEHEND_OK);
		}
	}

	/**
	 * Kopiert eine Datei.
	 *
	 * @param quelldatei
	 *            Quelldatei
	 * @param zieldatei
	 *            Zieldatei
	 * @throws IOException
	 *             bei Ausnahmen
	 */
	void kopiereDatei(final String quelldatei, final String zieldatei) throws IOException {
		Files.copy(Paths.get(quelldatei), Paths.get(zieldatei));

		// Setze LastModifiedTime für Kopie, da dieses Attribut (unter Windows)
		// beim Kopieren von Dateien nicht geändert wird. Für die Tests der SWE
		// sind die beigestellten Testdateien damit alt und werden bei
		// 'ueberpruefeSicherungsverzeichnis' gleich wieder gelöscht.
		Files.setLastModifiedTime(Paths.get(zieldatei), FileTime.fromMillis(System.currentTimeMillis()));
	}

	@Override
	public void run() {
		Thread.setDefaultUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
			@Override
			public void uncaughtException(final Thread t, final Throwable e) {
				LMSTIC3LogTools.log(debug, LmsMsg.ErrorThreadBeendet, "Meldungsdekodierer (" + e + ")"); //$NON-NLS-1$
				run = false;
				if ((ftpserver != null) && ftpserver.isAlive()) {
					ftpserver.stopp();
					try {
						ftpserver.join();
					} catch (final InterruptedException e1) {
						// e1.printStackTrace();
					}
				}
				interrupt();
			}
		});

		try {
			ftpserver = new FTPEmpfang(lmsParameter);
			ftpserver.addListener(this);
			while (run) {
				try {
					ueberpruefeSicherungsverzeichnis();
					verarbeiteNeueDateien();

					synchronized (waitLock) {
						waitLock.wait(10000);
					}

					if (!ftpserver.isAlive()) {
						LMSTIC3LogTools.log(debug, LmsMsg.ErrorThreadBeendet, "FTPEmpfang");
						break;
					}
				} catch (final InterruptedException e) {
				}
			}
		} catch (final Exception e) {
			LMSTIC3LogTools.log(debug, LmsMsg.ErrorAppException, e.getMessage());
			e.printStackTrace();
		}

		if (ftpserver != null) {
			ftpserver.stopp();
		}
	}

	/**
	 * Kopiert eine Datei in das Sicherungsverzeichnis.
	 *
	 * @param datei
	 *            die zusichernde Datei
	 */
	private void sichereDatei(final File datei) {
		if (lmsParameter.getSicherungsVerzeichnis() == null || lmsParameter.getSicherungsVerzeichnis().length() == 0) {
			debug.warning(
					"Die Datei '" + datei + "' wird nicht gesichert, da kein Sicherungsverzeichnis parametriert ist");
			return;
		}

		final File sicherungsverzeichnis = new File(lmsParameter.getSicherungsVerzeichnis());

		try {
			if (!sicherungsverzeichnis.exists()) {
				sicherungsverzeichnis.mkdirs();
			}
			final File backupfile = new File(sicherungsverzeichnis, datei.getName());

			debug.info("Die Datei " + datei + " wird nach " + backupfile.getAbsolutePath() + " kopiert");
			// es wird kopiert und nicht verschoben, da die Dateien in
			// verschiedenen Dateisystemen liegen können
			kopiereDatei(datei.getAbsolutePath(), backupfile.getAbsolutePath());
		} catch (final Exception e) {
			LMSTIC3LogTools.log(debug, LmsMsg.ErrorAppException, e.getMessage());
			debug.error("Fehler beim Kopieren der Datei " + datei + e.getMessage());
		}
	}

	/**
	 * Stoppt den Thread.
	 */
	public void stopp() {
		this.run = false;
		this.interrupt();
	}

	/**
	 * &Uuml;berp&uuml;ft das Sicherungsverzeichnis und l&ouml;scht alle
	 * Dateien, die l&auml;nger als die parametrierte Sicherungszeit nicht
	 * ge&auml;ndert wurden.
	 */
	private void ueberpruefeSicherungsverzeichnis() {
		final File sicherungsverzeichnis = new File(lmsParameter.getSicherungsVerzeichnis());

		if (sicherungsverzeichnis.length() == 0) {
			// keine Sicherung
			return;
		}

		// Sicherungszeit ist in Tagen
		final long sicherungszeit = lmsParameter.getSicherungsZeitTage() * Constants.MILLIS_PER_DAY;

		try {
			if (sicherungsverzeichnis.exists()) {
				final File[] dateien = sicherungsverzeichnis.listFiles();

				if (dateien != null) {
					for (final File datei : dateien) {
						if ((System.currentTimeMillis() - datei.lastModified()) > sicherungszeit) {
							datei.delete();
						}
					}
				}
			}
		} catch (final Exception e) {
			LMSTIC3LogTools.log(debug, LmsMsg.ErrorAppException, e.getMessage());
		}
	}

	/**
	 * Verarbeitet neu empfangene Dateien.
	 */
	private void verarbeiteNeueDateien() {

		ArrayList<File> dateien = null;

		synchronized (neueDateien) {
			if (!neueDateien.isEmpty()) {
				dateien = new ArrayList<>(neueDateien);
				neueDateien.clear();
			}
		}

		final List<ExterneMeldung> dateimeldungen = new ArrayList<>();

		if ((dateien != null) && (dateien.size() > 0)) {
			for (final File datei : dateien) {
				LMSTIC3LogTools.log(debug, LmsMsg.InfoDateiVerarbeitet, datei);

				final TIC3InfoDatei tid = new TIC3InfoDatei(datei);

				final TIC3InfoDateiDaten bildeMeldungen = tid.bildeMeldungen(mitValidierung);

				for (TIC3MeldungsDaten daten : bildeMeldungen.getMeldungen()) {
					dateimeldungen.add(new TIC3Meldung(daten));
				}

				if (bildeMeldungen.getExeption() != null) {
					LMSTIC3LogTools.log(debug, LmsMsg.ErrorTICDatei, datei, bildeMeldungen.getExeption().getMessage());
					LMTIC3Betriebsmeldungen.sendeDateifehler(System.currentTimeMillis(),
							bildeMeldungen.getMeldungen().size() > 0);
					sichereDatei(datei);
				}
				LMSTIC3LogTools.log(debug, LmsMsg.FineDateiGeloescht, datei);

				final boolean delete = datei.delete();
				if (!delete) {
					debug.warning("Die Datei '" + datei.getAbsolutePath() + "' konnte nicht gelöscht werden!");
				}
			}

			// if (!dateimeldungen.isEmpty()) {
			informiereListenerDateien(dateimeldungen);
			// }
		}

	}

	@Override
	public void versendet(final List<File> dateien, final LMSKommunikationsstatus status) {
		/** im Dekodierer nichts zu tun */
	}

	/**
	 * F&uuml;gt einen Listener hinzu.
	 *
	 * @param listener
	 *            neuer Listener
	 */
	public void addListener(final LMSMeldungenListener listener) {
		listenerList.add(listener);
	}

	/**
	 * Informiert die Listener &uuml;ber neue Daten.
	 *
	 * @param meldungen
	 *            Liste der neuen Dateien
	 */
	void informiereListenerDateien(final List<ExterneMeldung> meldungen) {
		for (final LMSMeldungenListener listener : listenerList) {
			listener.empfangen(new ArrayList<>(meldungen));
		}
	}
}
+164 −0
Original line number Diff line number Diff line
/*
 * Segment 2 (KEx), SWE LMS-TIC3
 * Copyright (C) 2016 BitCtrl Systems GmbH 
 * 
 * This library is free software; you can redistribute it and/or modify it under
 * the terms of the GNU Lesser General Public License as published by the Free
 * Software Foundation; either version 2.1 of the License, or (at your option)
 * any later version.
 *
 * This library is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
 * details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this library; if not, write to the Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA.
 *
 * Contact Information:
 * BitCtrl Systems GmbH
 * Weißenfelser Straße 67
 * 04229 Leipzig
 * Phone: +49 341-490670
 * mailto: info@bitctrl.de
 */

package de.bsvrz.kex.lmstic3.empfang.dekoder;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;

import javax.xml.XMLConstants;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.validation.Schema;
import javax.xml.validation.SchemaFactory;

import org.w3c.dom.Document;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

import de.bsvrz.kex.lmstic3.vew.daten.tic.TIC3Exception;
import de.bsvrz.kex.lmstic3.vew.daten.tic.TIC3Meldung;
import de.bsvrz.kex.lmstic3.vew.daten.tic.TIC3MeldungsDaten;

/**
 * Klasse zum Zugriff auf Dateien nach TIC3-Info Spezifikation.
 *
 * @author BitCtrl Systems GmbH, Gieseler
 * @version $Id: TIC3InfoDatei.java 64239 2016-11-09 12:34:02Z gieseler $
 */
public class TIC3InfoDatei {

	/** TIC-Info Schema Location. */
	private final String ticSchemaDatei = "de/bsvrz/kex/lms/vew/TIC Info XML.xsd";

	/** die Datei. */
	private final File ticDatei;

	/**
	 * Konstruktor aus Datei.
	 *
	 * @param datei
	 *            Datei
	 */
	public TIC3InfoDatei(final File datei) {
		ticDatei = datei;
	}

	/**
	 * Erzeugt aus der Datei eine Liste von enthaltenen TIC3-Meldungen.
	 *
	 * @param mitVerifikation
	 *            legt fest, ob die empfangenen Dateien gegen das Schema
	 *            validiert werden sollen
	 * @return {@link TIC3InfoDateiDaten}
	 */
	public TIC3InfoDateiDaten bildeMeldungen(final boolean mitVerifikation) {
		final TIC3InfoDateiDaten daten = new TIC3InfoDateiDaten();

		final Document doc;
		try {
			doc = getDocument(mitVerifikation);
		} catch (final TIC3InfoDateiException e) {
			daten.setExeption(new TIC3InfoDateiException(e.getMessage()));
			return daten;
		}

		final NodeList nl = doc.getElementsByTagName(TIC3Meldung.XML_ELEMENT_MELDUNG);

		for (int i = 0; i < nl.getLength(); i++) {
			try {
				final TIC3MeldungsDaten meldung = new TIC3MeldungsDaten(nl.item(i));
				daten.addMeldung(meldung);
			} catch (final TIC3Exception | NumberFormatException e) {
				// speichere die erste Exception
				if (daten.getExeption() == null) {
					daten.setExeption(new TIC3InfoDateiException(e.getMessage()));
				}
			}
		}

		return daten;
	}

	/**
	 * Erzeugt das Document zur Datei. (Falls eine Verifikation der Datei gegen
	 * das Schema einmal m&ouml;glich ist, sollte dies hier erfolgen)
	 *
	 * @param mitVerifikation
	 *            legt fest, ob die empfangenen Dateien gegen das Schema
	 *            validiert werden sollen
	 * @return Document
	 * @throws TIC3InfoDateiException
	 *             bei Fehlern
	 */
	private Document getDocument(final boolean mitVerifikation) throws TIC3InfoDateiException {
		Document doc = null;

		final DocumentBuilderFactory docfactory = DocumentBuilderFactory.newInstance();

		if (mitVerifikation) {
			final SchemaFactory schemafactory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
			final URL schemaurl;
			try {
				schemaurl = new URL("file://" + ticSchemaDatei);

				// final URL schemaurl =
				// ClassLoader.getSystemResource(_ticSchemaDatei);
				// Validierung gegen Schema nicht möglich
				// Aussage Herr Kuske, Fa. GEWI
				final Schema ticschema = schemafactory.newSchema(schemaurl);
				docfactory.setSchema(ticschema);
				docfactory.setValidating(true);
			} catch (final MalformedURLException e) {
				throw new TIC3InfoDateiException(e.getMessage());
			} catch (final SAXException e) {
				throw new TIC3InfoDateiException(e.getMessage());
			}
		}

		InputStream is = null;
		try {
			final DocumentBuilder parser = docfactory.newDocumentBuilder();
			is = new FileInputStream(ticDatei);
			doc = parser.parse(is);
		} catch (final Exception e) {
			throw new TIC3InfoDateiException(e.getMessage());
		} finally {
			if (is != null) {
				try {
					is.close();
				} catch (IOException e) {
				}
			}
		}

		return doc;
	}
}
+84 −0
Original line number Diff line number Diff line
/*
 * Segment 2 (KEx), SWE LMS-TIC3
 * Copyright (C) 2016 BitCtrl Systems GmbH 
 * 
 * This library is free software; you can redistribute it and/or modify it under
 * the terms of the GNU Lesser General Public License as published by the Free
 * Software Foundation; either version 2.1 of the License, or (at your option)
 * any later version.
 *
 * This library is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
 * details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this library; if not, write to the Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA.
 *
 * Contact Information:
 * BitCtrl Systems GmbH
 * Weißenfelser Straße 67
 * 04229 Leipzig
 * Phone: +49 341-490670
 * mailto: info@bitctrl.de
 */

package de.bsvrz.kex.lmstic3.empfang.dekoder;

import java.util.ArrayList;
import java.util.Collection;

import de.bsvrz.kex.lmstic3.vew.daten.tic.TIC3MeldungsDaten;

/**
 * Ergebnis Einlesen der TIC3-Datei.
 *
 * @author BitCtrl Systems GmbH, Gieseler
 * @version $Id: $
 */
public class TIC3InfoDateiDaten {

	private Collection<TIC3MeldungsDaten> meldungen = new ArrayList<>();

	private TIC3InfoDateiException exeption;

	/**
	 * Gibt die in der Datei enthaltenen Meldungen zur&uuml;ck.
	 * 
	 * @return {@link TIC3MeldungsDaten}
	 */
	public Collection<TIC3MeldungsDaten> getMeldungen() {
		return meldungen;
	}

	/**
	 * F&uuml;gt Meldungsdaten hinzu.
	 * 
	 * @param meldung
	 *            {@link TIC3MeldungsDaten}
	 */
	public void addMeldung(final TIC3MeldungsDaten meldung) {
		meldungen.add(meldung);
	}

	/**
	 * Gibt die erste aufgetretene Ausnahme zur&uuml;ck.
	 * 
	 * @return {@link TIC3InfoDateiException}
	 */
	public TIC3InfoDateiException getExeption() {
		return exeption;
	}

	/**
	 * Setzt aufgetretene Ausnahme.
	 * 
	 * @param exeption
	 *            {@link TIC3InfoDateiException}
	 */
	public void setExeption(final TIC3InfoDateiException exeption) {
		this.exeption = exeption;
	}

}
+50 −0
Original line number Diff line number Diff line
/*
 * Segment 2 (KEx), SWE LMS-TIC3
 * Copyright (C) 2016 BitCtrl Systems GmbH 
 * 
 * This library is free software; you can redistribute it and/or modify it under
 * the terms of the GNU Lesser General Public License as published by the Free
 * Software Foundation; either version 2.1 of the License, or (at your option)
 * any later version.
 *
 * This library is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
 * details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this library; if not, write to the Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA.
 *
 * Contact Information:
 * BitCtrl Systems GmbH
 * Weißenfelser Straße 67
 * 04229 Leipzig
 * Phone: +49 341-490670
 * mailto: info@bitctrl.de
 */

package de.bsvrz.kex.lmstic3.empfang.dekoder;

/**
 * Ausnahmeklasse f&uuml;r Ausnahmen beim Einlesen von TIC3-Info Dateien.
 *
 * @author BitCtrl Systems GmbH, Gieseler
 */
public class TIC3InfoDateiException extends Exception {

	/**
	 * VersionUID .
	 */
	private static final long serialVersionUID = 5674973184064158638L;

	/**
	 * Konstruktor mit Message-Argument.
	 *
	 * @param message
	 *            Grund der Ausnahme
	 */
	public TIC3InfoDateiException(final String message) {
		super(message);
	}
}