diff --git a/Bachelorarbeit.tex b/Bachelorarbeit.tex index 3ae2963..1d6c8c7 100644 --- a/Bachelorarbeit.tex +++ b/Bachelorarbeit.tex @@ -874,12 +874,12 @@ Ein wichtiges Werkzeug bei der Verarbeitung von Ereignisdatenströmen ist das Au \paragraph{Auslösen von Ereignissen} Das Auslösen von Ereignissen innerhalb der Ereignisverarbeitung kann genutzt werden, um eine mehrstufige Auswertung mit CEP-Regeln zu erhalten. Hierbei werden die Ergebnisse aus der Verarbeitung durch CEP-Regel genutzt, um den Typen und die Attributwerte des neuen Ereignisses zu bestimmen. -In C-SPARQL können bestimmte Abfragen, wie etwa \texttt{CONSTRUCT}-Queries als Datenströme registriert werden, um somit ihre Ergebnisse in weiteren CEP-Regeln verarbeiten zu können. Hierzu wird nach dem Schlüsselwort \texttt{REGISTER}, wie die Grammatik aus Listing~\ref{lst:register_query_csparql} beschreibt, das Schlüsselwort \texttt{STREAM} angegeben\footnote{Zusätzlich ist es notwendig, den Query nach der Registrierung von einem \texttt{RDFStreamFormatter} beobachten zu lassen, den man separat an der Engine registrieren muss. Mehr dazu in Kapitel~\ref{cpt:csparql_in_practice}}. +In C-SPARQL können bestimmte Abfragen, wie etwa \texttt{CONSTRUCT}-Queries als Datenströme registriert werden, um somit ihre Ergebnisse in weiteren CEP-Regeln verarbeiten zu können. Hierzu wird nach dem Schlüsselwort \texttt{REGISTER}, wie die Grammatik aus Listing~\ref{lst:register_query_csparql} beschreibt, das Schlüsselwort \texttt{STREAM} angegeben\footnote{Zusätzlich ist es notwendig, den Query nach der Registrierung von einem \texttt{RDFStreamFormatter} beobachten zu lassen, den man separat als Stream an der Engine registrieren muss. Mehr dazu in Kapitel~\ref{cpt:csparql_in_practice}}. Um dies zu zeigen, sei in Listing~\ref{lst:abstract_cep_rule_five} eine abstrakte CEP-Regel gegeben, die Ereignisse vom Typ \texttt{CarStatusEvent} nach den im Attribut \texttt{relatedCar} angegebenen PKW gruppiert, für jeden PKW dessen durchschnittliche Geschwindigkeit ermittelt und für jedes Ergebnis ein neues Ereignis vom Typ \texttt{AverageSpeedEvent} erzeugt, welches die Durchschnittsgeschwindigkeit enthalten soll. \begin{lstlisting}[mathescape=true,label={lst:abstract_cep_rule_five},caption={CEP-Regel erzeugt neue Ereignisse}] CONDITION ($(CarStatusEvent\ AS\ statusEvent)$)[WindowSize:15min,StepSize:5m] - $\wedge$ AGGREGATE(statusEvent, "motorRPM", {statusEvent.relatedCar}, AVG) AS avgSpeed + $\wedge$ AGGREGATE(statusEvent, "speed", {statusEvent.relatedCar}, AVG) AS avgSpeed ACTION new AverageSpeedEvent(relatedCar=statusEvent.relatedCar, averageSpeed=avgSpeed) \end{lstlisting} @@ -904,11 +904,19 @@ WHERE { } } \end{lstlisting} -Da C-SPARQL die gleichzeitige Nutzung von \texttt{GROUP BY} mit \texttt{CONSTRUCT} erlaubt, nutzt die Abfrage aus Listing~\ref{lst:csparql_construct_query} einen in geschweiften Klammern eingefassten Subquery, um die Aggregation vornehmen zu können. Um für die innerhalb von \texttt{CONSTRUCT} neu zu erzeugten Ereignisinstanzen ein Subjekt zu erhalten, wird mit \texttt{[]} ein sogenannter \emph{Blank Node} verwendet. Innerhalb der \texttt{CONSTRUCT}-Anweisung wird nur das letzte Tripel mit einem Punkt beendet; die letzten beiden Tripel zeigen durch die Verwendung eines Semikolons an, dass sie das selbe Subjekt wie das erste Tripel für ihre Aussage verwenden. Somit haben alle drei der konstruierten Tripel das selbe Blank Node als Subjekt. Nach Auswertung des Queries erhält jeder Blank Node von der Engine eine Kennung, anhand der er identifiziert werden kann. +Da C-SPARQL die gleichzeitige Nutzung von \texttt{GROUP BY} mit \texttt{CONSTRUCT} erlaubt, nutzt die Abfrage aus Listing~\ref{lst:csparql_construct_query} einen in geschweiften Klammern eingefassten Subquery, um die Aggregation vornehmen zu können. Um für die innerhalb von \texttt{CONSTRUCT} neu zu erzeugten Ereignisinstanzen ein Subjekt zu erhalten, wird mit \texttt{[]} ein sogenannter \emph{Blank Node} verwendet. Innerhalb der \texttt{CONSTRUCT}-Anweisung wird nur das letzte Tripel mit einem Punkt beendet; die letzten beiden Tripel zeigen durch die Verwendung eines Semikolons an, dass sie das selbe Subjekt wie das erste Tripel für ihre Aussage verwenden. Somit haben alle drei der konstruierten Tripel das selbe Blank Node als Subjekt. Nach Auswertung des Queries erhält jeder Blank Node von der Engine eine Kennung, anhand welcher er identifiziert werden kann. \paragraph{Ausführen von Code und Anstoßen externer Dienste} -\dots Hierfür muss man sich am CsparqlQueryResultProxy als Observer einklemmen, dann geht das. Man bekommt dann neben dem Proxy noch eine RDFTable mit den Ergebnissen reingeschossen. Im Java-Code kann man dann tun, was man will. +Natürlich bietet die C-SPARQL-Engine auch Möglichkeiten zum Ausführen von eigenem Code und somit auch zum Anstoßen von externen Diensten. Allerdings bietet sie dafür keine Möglichkeiten innerhalb der C-SPARQL-Sprache selbst, sondern erfordert das Anbringen von einem \texttt{Observer} an den durch die Registrierung eines Queries an der Engine entstandenen \texttt{CsparqlQueryResultProxy}. Dieser wird jedes Mal benachrichtigt, wenn für den registrierten Query ein Ergebnis vorliegt. Dabei wird die durch das \texttt{Observer}-Interface implementierte Methode \texttt{update()} aufgerufen, welcher der \texttt{CsparqlQueryResultProxy} des Queries sowie die \texttt{RDFTable} mit den Ergebnissen übergeben wird. Innerhalb der Methode \texttt{update()} kann dann beliebiger Java-Code hinterlegt werden, der mit den Ergebnisdaten arbeitet oder einen externen Dienst anstößt. +Somit kann von der CEP-Regel in Listing~\ref{lst:abstract_cep_rule_six} nur der \texttt{CONDITION}-Teil in C-SPARQL umgesetzt werden, da für den \texttt{ACTION}-Teil zusätzlicher Java-Code benötigt wird: +\begin{lstlisting}[mathescape=true,label={lst:abstract_cep_rule_six},caption={CEP-Regel stößt externen Dienst an}] +CONDITION ($(CarStatusEvent\ AS\ statusEvent)$)[WindowSize:15min,StepSize:5m] + $\wedge$ AGGREGATE(statusEvent, "speed", {statusEvent.relatedCar}, AVG) AS avgSpeed + $\wedge$ avgSpeed > 140 +ACTION + callNotifyCustomerIsSpeedingService(relatedCar=statusEvent.relatedCar, averageSpeed=avgSpeed) +\end{lstlisting} \section{Einbindung von Domänenwissen} Integration von Hintergrundwissen findet live im Query statt ohne extra Klimmzüge, da alles innerhalb der C-SPARQL-Queries abzufragen ist. Lediglich der lokale Graph muss gegebenenfalls genannt werden.