From 21e79c833fcbd2d7c43380a2f74b5c0173c6c1a0 Mon Sep 17 00:00:00 2001 From: Manuel Traut Date: Tue, 18 Feb 2014 23:24:52 +0100 Subject: corba example: switch to autotools ace/tao is now packaged in debian/experimental. it's definitely easier to use the packaged stuff instead of building ace/tao by your own. the mwc packaging of debian is currently a pain. it is shipped without config files for tao.., but the tao debian packages provide pkg-config support so this patch converts the project into a autotools project :) Signed-off-by: Manuel Traut --- frameworks/middleware/examples/corba/AUTHORS | 0 frameworks/middleware/examples/corba/ChangeLog | 0 frameworks/middleware/examples/corba/Makefile.am | 29 +++++++++++++++++++++++ frameworks/middleware/examples/corba/NEWS | 0 frameworks/middleware/examples/corba/README | 12 ++++++++++ frameworks/middleware/examples/corba/autogen.sh | 3 +++ frameworks/middleware/examples/corba/configure.ac | 28 ++++++++++++++++++++++ frameworks/middleware/examples/corba/ping_I.cpp | 1 - 8 files changed, 72 insertions(+), 1 deletion(-) create mode 100644 frameworks/middleware/examples/corba/AUTHORS create mode 100644 frameworks/middleware/examples/corba/ChangeLog create mode 100644 frameworks/middleware/examples/corba/Makefile.am create mode 100644 frameworks/middleware/examples/corba/NEWS create mode 100644 frameworks/middleware/examples/corba/README create mode 100755 frameworks/middleware/examples/corba/autogen.sh create mode 100644 frameworks/middleware/examples/corba/configure.ac (limited to 'frameworks') diff --git a/frameworks/middleware/examples/corba/AUTHORS b/frameworks/middleware/examples/corba/AUTHORS new file mode 100644 index 0000000..e69de29 diff --git a/frameworks/middleware/examples/corba/ChangeLog b/frameworks/middleware/examples/corba/ChangeLog new file mode 100644 index 0000000..e69de29 diff --git a/frameworks/middleware/examples/corba/Makefile.am b/frameworks/middleware/examples/corba/Makefile.am new file mode 100644 index 0000000..72a6a67 --- /dev/null +++ b/frameworks/middleware/examples/corba/Makefile.am @@ -0,0 +1,29 @@ +IDL_COMPILER=tao_idl +IDL_COMPILER_OPT=-GI + +IDL_GEN_H_SRV = pingI.h pingS.h +IDL_GEN_S_SRV = pingS.cpp +IDL_GEN_H_CLT = pingC.h pingC.inl +IDL_GEN_S_CLT = pingC.cpp + +pingI.h: ping.idl + $(IDL_COMPILER) $(IDL_COMPILER_OPT) ping.idl + +noinst_HEADERS = $(IDL_GEN_H_SRV) $(IDL_GEN_H_CLT) + +CLEANFILES = $(IDL_GEN_H_SRV) $(IDL_GEN_S_SRV) \ + $(IDL_GEN_H_CLT) $(IDL_GEN_S_CLT) pingI.cpp + +CORBA_CFLAGS = $(TAO_CFLAGS) $(TAO_CosNaming_CFLAGS) \ + $(TAO_PortableServer_CFLAGS) $(TAO_RTCORBA_CFLAGS) +CORBA_LIBS = $(TAO_LIBS) $(TAO_CosNaming_LIBS) $(TAO_PortableServer_LIBS) \ + $(TAO_RTCORBA_LIBS) + +bin_PROGRAMS = receiver supplier +receiver_SOURCES = ping_I.cpp $(IDL_GEN_S_SRV) $(IDL_GEN_S_CLT) Receiver.cpp +receiver_CFLAGS = $(CORBA_CFLAGS) +receiver_LDADD = $(CORBA_LIBS) + +supplier_SOURCES = Supplier.cpp $(IDL_GEN_S_CLT) +supplier_CFLAGS = $(CORBA_CFLAGS) +supplier_LDADD = $(CORBA_LIBS) diff --git a/frameworks/middleware/examples/corba/NEWS b/frameworks/middleware/examples/corba/NEWS new file mode 100644 index 0000000..e69de29 diff --git a/frameworks/middleware/examples/corba/README b/frameworks/middleware/examples/corba/README new file mode 100644 index 0000000..74ca9bb --- /dev/null +++ b/frameworks/middleware/examples/corba/README @@ -0,0 +1,12 @@ +apt-get install -t experimental libtao-dev mpc-ace libtao-orbsvcs-dev \ +tao-cosnaming tao-idl tao-utils + +./autogen.sh +./configure +make + +Naming_Service -ORBEndpoint iiop://localhost:55555 + + +./receiver -ORBInitRef NameService=corbaloc:iiop:localhost:55555/NameService +./supplier -ORBInitRef NameService=corbaloc:iiop:localhost:55555/NameService diff --git a/frameworks/middleware/examples/corba/autogen.sh b/frameworks/middleware/examples/corba/autogen.sh new file mode 100755 index 0000000..58c0175 --- /dev/null +++ b/frameworks/middleware/examples/corba/autogen.sh @@ -0,0 +1,3 @@ +#!/bin/bash +automake --add-missing +autoreconf -sif diff --git a/frameworks/middleware/examples/corba/configure.ac b/frameworks/middleware/examples/corba/configure.ac new file mode 100644 index 0000000..6127c33 --- /dev/null +++ b/frameworks/middleware/examples/corba/configure.ac @@ -0,0 +1,28 @@ +# -*- Autoconf -*- +# Process this file with autoconf to produce a configure script. + +AC_PREREQ([2.69]) +AC_INIT([corba-example], [1.0], [manut@linutronix.de]) +AC_CONFIG_SRCDIR([Receiver.cpp]) +AM_INIT_AUTOMAKE([dist-bzip2]) +AC_CONFIG_HEADERS([config.h]) + +# Checks for programs. +AC_PROG_CXX + +# Checks for libraries. +PKG_CHECK_MODULES([TAO], [TAO]) +PKG_CHECK_MODULES([TAO_CosNaming], [TAO_CosNaming]) +PKG_CHECK_MODULES([TAO_PortableServer], [TAO_PortableServer]) +PKG_CHECK_MODULES([TAO_RTCORBA], [TAO_RTCORBA]) + +# Checks for header files. + +# Checks for typedefs, structures, and compiler characteristics. + +# Checks for library functions. +AC_CHECK_FUNCS([clock_gettime]) + +AC_CONFIG_FILES([Makefile]) + +AC_OUTPUT diff --git a/frameworks/middleware/examples/corba/ping_I.cpp b/frameworks/middleware/examples/corba/ping_I.cpp index 309d1e8..e02924f 100644 --- a/frameworks/middleware/examples/corba/ping_I.cpp +++ b/frameworks/middleware/examples/corba/ping_I.cpp @@ -21,4 +21,3 @@ void Linutronix_Ping_i::send ( clock_gettime(CLOCK_MONOTONIC, &time_rx); std::cout< Date: Tue, 18 Feb 2014 23:27:47 +0100 Subject: dbus example: remove compile.sh and make a autotools project compile.sh was a pain. didn't work with current debian. so this patch removes it and converts the example to an autools project. Signed-off-by: Manuel Traut --- frameworks/middleware/examples/dbus/AUTHORS | 0 frameworks/middleware/examples/dbus/ChangeLog | 0 frameworks/middleware/examples/dbus/Makefile.am | 8 ++++++++ frameworks/middleware/examples/dbus/NEWS | 0 frameworks/middleware/examples/dbus/README | 0 frameworks/middleware/examples/dbus/autogen.sh | 3 +++ frameworks/middleware/examples/dbus/compile.sh | 3 --- frameworks/middleware/examples/dbus/configure.ac | 24 +++++++++++++++++++++++ frameworks/middleware/examples/dbus/ping-client.c | 24 +++++++++++++---------- frameworks/middleware/examples/dbus/ping-server.c | 2 -- 10 files changed, 49 insertions(+), 15 deletions(-) create mode 100644 frameworks/middleware/examples/dbus/AUTHORS create mode 100644 frameworks/middleware/examples/dbus/ChangeLog create mode 100644 frameworks/middleware/examples/dbus/Makefile.am create mode 100644 frameworks/middleware/examples/dbus/NEWS create mode 100644 frameworks/middleware/examples/dbus/README create mode 100755 frameworks/middleware/examples/dbus/autogen.sh delete mode 100755 frameworks/middleware/examples/dbus/compile.sh create mode 100644 frameworks/middleware/examples/dbus/configure.ac (limited to 'frameworks') diff --git a/frameworks/middleware/examples/dbus/AUTHORS b/frameworks/middleware/examples/dbus/AUTHORS new file mode 100644 index 0000000..e69de29 diff --git a/frameworks/middleware/examples/dbus/ChangeLog b/frameworks/middleware/examples/dbus/ChangeLog new file mode 100644 index 0000000..e69de29 diff --git a/frameworks/middleware/examples/dbus/Makefile.am b/frameworks/middleware/examples/dbus/Makefile.am new file mode 100644 index 0000000..830a98e --- /dev/null +++ b/frameworks/middleware/examples/dbus/Makefile.am @@ -0,0 +1,8 @@ +bin_PROGRAMS = pingserver pingclient +pingserver_SOURCES = ping-server.c +pingserver_CFLAGS = $(DBUS_CFLAGS) +pingserver_LDADD = $(DBUS_LIBS) + +pingclient_SOURCES = ping-client.c +pingclient_CFLAGS = $(DBUS_CFLAGS) +pingclient_LDADD = $(DBUS_LIBS) diff --git a/frameworks/middleware/examples/dbus/NEWS b/frameworks/middleware/examples/dbus/NEWS new file mode 100644 index 0000000..e69de29 diff --git a/frameworks/middleware/examples/dbus/README b/frameworks/middleware/examples/dbus/README new file mode 100644 index 0000000..e69de29 diff --git a/frameworks/middleware/examples/dbus/autogen.sh b/frameworks/middleware/examples/dbus/autogen.sh new file mode 100755 index 0000000..58c0175 --- /dev/null +++ b/frameworks/middleware/examples/dbus/autogen.sh @@ -0,0 +1,3 @@ +#!/bin/bash +automake --add-missing +autoreconf -sif diff --git a/frameworks/middleware/examples/dbus/compile.sh b/frameworks/middleware/examples/dbus/compile.sh deleted file mode 100755 index d2b2822..0000000 --- a/frameworks/middleware/examples/dbus/compile.sh +++ /dev/null @@ -1,3 +0,0 @@ -#!/bin/bash -gcc -o server -lrt -I/usr/include/dbus-1.0 -I/usr/lib/dbus-1.0/include -I/usr/include/glib-2.0 -I/usr/lib/glib-2.0/include -ldbus-glib-1 -ldbus-1 -lgobject-2.0 -lglib-2.0 ping-server.c -gcc -o client -lrt -I/usr/include/dbus-1.0 -I/usr/lib/dbus-1.0/include -I/usr/include/glib-2.0 -I/usr/lib/glib-2.0/include -ldbus-glib-1 -ldbus-1 -lgobject-2.0 -lglib-2.0 ping-client.c diff --git a/frameworks/middleware/examples/dbus/configure.ac b/frameworks/middleware/examples/dbus/configure.ac new file mode 100644 index 0000000..bf99b42 --- /dev/null +++ b/frameworks/middleware/examples/dbus/configure.ac @@ -0,0 +1,24 @@ +# -*- Autoconf -*- +# Process this file with autoconf to produce a configure script. + +AC_PREREQ([2.69]) +AC_INIT([dbus-example], [1.0], [manut@linutronix.de]) +AC_CONFIG_SRCDIR([ping-server.c]) +AM_INIT_AUTOMAKE([dist-bzip2]) +AC_CONFIG_HEADERS([config.h]) + +# Checks for programs. +AC_PROG_CC + +# Checks for libraries. +PKG_CHECK_MODULES([DBUS], [dbus-glib-1]) +# Checks for header files. + +# Checks for typedefs, structures, and compiler characteristics. + +# Checks for library functions. +AC_CHECK_FUNCS([clock_gettime]) + +AC_CONFIG_FILES([Makefile]) + +AC_OUTPUT diff --git a/frameworks/middleware/examples/dbus/ping-client.c b/frameworks/middleware/examples/dbus/ping-client.c index e3035e4..ceb3205 100644 --- a/frameworks/middleware/examples/dbus/ping-client.c +++ b/frameworks/middleware/examples/dbus/ping-client.c @@ -12,10 +12,10 @@ int main (int argc, char **argv) DBusConnection *bus; DBusError error; - if (argc > 1) - v_STRING = argv[1]; - else - v_STRING = "no arg given"; + if (argc > 1) + v_STRING = argv[1]; + else + v_STRING = "no arg given"; /* Create a new event loop to run in */ loop = g_main_loop_new (NULL, FALSE); @@ -42,8 +42,8 @@ int main (int argc, char **argv) static gboolean send_ping (DBusConnection *bus) { DBusMessage *message; - struct timespec tx_time; - struct timespec done_time; + struct timespec tx_time; + struct timespec done_time; message = dbus_message_new_signal ("/de/linutronix/Ping", "de.linutronix.Ping", "Ping"); @@ -51,12 +51,16 @@ static gboolean send_ping (DBusConnection *bus) dbus_message_append_args (message, DBUS_TYPE_STRING, &v_STRING, DBUS_TYPE_INVALID); - clock_gettime(CLOCK_MONOTONIC, &tx_time); + + clock_gettime(CLOCK_MONOTONIC, &tx_time); + /* Send the signal */ dbus_connection_send (bus, message, NULL); - clock_gettime(CLOCK_MONOTONIC, &done_time); - g_print("%d:%d\n%d:%d\n\n", tx_time.tv_sec, tx_time.tv_nsec/1000, - done_time.tv_sec, done_time.tv_nsec/1000); + clock_gettime(CLOCK_MONOTONIC, &done_time); + + g_print("%d:%d\n%d:%d\n\n", tx_time.tv_sec, tx_time.tv_nsec/1000, + done_time.tv_sec, done_time.tv_nsec/1000); + /* Free the signal now we have finished with it */ dbus_message_unref (message); /* Return TRUE to tell the event loop we want to be called again */ diff --git a/frameworks/middleware/examples/dbus/ping-server.c b/frameworks/middleware/examples/dbus/ping-server.c index 36dd122..96b2397 100644 --- a/frameworks/middleware/examples/dbus/ping-server.c +++ b/frameworks/middleware/examples/dbus/ping-server.c @@ -60,7 +60,6 @@ static DBusHandlerResult signal_filter clock_gettime(CLOCK_MONOTONIC, &rx_time); g_print("ping received: %s - %d:%d\n", s, rx_time.tv_sec, rx_time.tv_nsec/1000); - // dbus_free (s); } else { g_print("ping received, but error getting message: %s\n", error.message); dbus_error_free (&error); @@ -69,4 +68,3 @@ static DBusHandlerResult signal_filter } return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; } - -- cgit v1.2.3 From 6200bc8389548831e6fc345ceb9867b0d0c1b1ab Mon Sep 17 00:00:00 2001 From: Manuel Traut Date: Tue, 18 Feb 2014 23:29:58 +0100 Subject: update middleware presentation - give an introduction to the topic, what is a middleware, why do we need it - mention some xml based middlewares - update the dbus section, no we don't have HAL anymore :)) - mention the idl workflow in the corba section Signed-off-by: Manuel Traut --- frameworks/middleware/pres_middleware.tex | 571 ++++++++++++++++++++++++++++-- 1 file changed, 546 insertions(+), 25 deletions(-) (limited to 'frameworks') diff --git a/frameworks/middleware/pres_middleware.tex b/frameworks/middleware/pres_middleware.tex index 2f4c462..d147ceb 100644 --- a/frameworks/middleware/pres_middleware.tex +++ b/frameworks/middleware/pres_middleware.tex @@ -3,23 +3,473 @@ \title{\lq Middleware\rq} \maketitle -\subsection{DBUS} \begin{frame} -\frametitle{DBUS Communication Framework} +\frametitle{Agenda} +\begin{itemize} +\item Overview +\item XML based Middleware +\item Celery +\item DDS +\item D-Bus +\item CORBA +\end{itemize} +GOAL: get an idea about: + +the amount of available middleware solutions + +and for what they can be used. +\end{frame} + +\subsection{Overview} + +\begin{frame} +\frametitle{Use-case} +\begin{center} +\includegraphics[width=0.8\textheight]{images/714px-Middleware_Schema.png} +\end{center} +\tiny Source: http://commons.wikimedia.org/wiki/File:Middleware\_Schema.svg +\end{frame} + +\begin{frame} +\frametitle{Why should we use a middleware?} +\begin{itemize} +\item IPC +\item scalability +\item os abstraction +\item reusability of sw components +\end{itemize} +\end{frame} + +\begin{frame} +\frametitle{Kinds of Middleware} +\begin{itemize} +\item Message Oriented Middleware (MOM) +\item Remote Procedure Calls (RPC) +\item Webapplications? +\end{itemize} +\end{frame} + +\begin{frame} +\frametitle{Requirements} +\begin{block}{Abstraction Layers} +\begin{itemize} +\item operating system +\item programing language +\item localization +\item transport +\item concurrent access +\end{itemize} +\end{block} +\end{frame} + +\begin{frame} +\frametitle{Requirements} +\begin{block}{Technical, product specific} +\begin{itemize} +\item os / language support +\item performance +\item requirement coverage +\item commerical, open-source, (long-time) support +\end{itemize} +\end{block} +\end{frame} + +\begin{frame} +\frametitle{Standards, Protocols} +\begin{itemize} +\item XML based Middleware +\item Celery - Job Queue Protocol +\item DDS - Data Distribution Service +\item D-Bus - MOM +\item CORBA - Common Object Request Broker +\end{itemize} +\end{frame} + +\subsection{XML based Middleware} +\begin{frame} +\frametitle{popular protocols} +\begin{description} +\item[XML-RPC] Extensible Markup Language Remote Procedure Call +\item[SOAP/WSDL] many webservices are based on SOAP +\item[XMPP] Extensible Messaging and Presence Protocol +\end{description} +\end{frame} + +\begin{frame} +\frametitle{XML-RPC} +\begin{itemize} +\item native supported by Python (see example) +\item C/C++ Implementation: http://xmlrpc-c.sourceforge.net/ +\item Client- / Serverarchitecture +\item uses http as transport +\end{itemize} +\end{frame} + +\begin{frame}[fragile] +\frametitle{XML-RPC example in Python} +server.py\#p1 +\begin{lstlisting}[language=python] +from datetime import datetime +from SimpleXMLRPCServer import SimpleXMLRPCServer +import xmlrpclib + +def today (): + today = datetime.today () + return xmlrpclib.DateTime (today) + +def load (): + fd = open ("/proc/loadavg", "r") + loadavg = fd.read () + sysload = loadavg.split () + return xmlrpclib.FloatType (sysload[0]) +\end{lstlisting} +\end{frame} + +\begin{frame}[fragile] +\frametitle{XML-RPC example in Python} +server.py\#p2 +\begin{lstlisting}[language=python] +server = SimpleXMLRPCServer (("localhost", + 8000)) + +server.register_function (today, "today") +server.register_function (load, "load") + +print "Listening on port 8000..." +server.serve_forever () +\end{lstlisting} +\end{frame} + + +\begin{frame}[fragile] +\frametitle{XML-RPC example in Python} +client.py\#p1 +\begin{lstlisting}[language=python] +import xmlrpclib +from datetime import datetime + +proxy = xmlrpclib.ServerProxy ( + "http://localhost:8000/") +\end{lstlisting} +\end{frame} + +\begin{frame}[fragile] +\frametitle{XML-RPC example in Python} +client.py\#p2 +\begin{lstlisting}[language=python] +today = proxy.today () +# today = 20140218T14:23:45 + +conv = datetime.strptime (today.value, + "%Y%m%dT%H:%M:%S") + +print "Today:", conv.strftime ( + "%d.%m.%Y, %H:%M") + +load = proxy.load () +print "system load:", load +\end{lstlisting} +\end{frame} + +\begin{frame}[fragile] +\frametitle{XML-RPC example in Python} +output: +\begin{lstlisting}[language=bash] + % python client.py +Today: 18.02.2014, 14:26 +system load: 0.45 +\end{lstlisting} +\end{frame} + +\begin{frame}[fragile] +\frametitle{XML-RPC example in Python} +http payload of today rpc call seen in wireshark: +\begin{lstlisting}[language=XML] + + + today + + +\end{lstlisting} +\end{frame} + +\begin{frame}[fragile] +\frametitle{XML-RPC example in Python} +http payload of today rpc response seen in wireshark: +\begin{lstlisting}[language=XML] + + + + + + + 20140218T14:26:25 + + + + + +\end{lstlisting} +\end{frame} + +\begin{frame} +\frametitle{SOAP/WSDL} +\begin{block}{Overview} +\begin{itemize} +\item WSDL (Web Services Description Language) + +describes the interface and spcecial datatypes +\item the SOAP protocol is used for communication +\item SOAP can be used with various transports: + +FTP, SMTP, HTTP(S), JMS +\item hopping is supported, with different transports +\item Client- / Serverarchitecture +\end{itemize} +\end{block} +\end{frame} + +\begin{frame} +\frametitle{SOAP/WSDL} +\begin{block}{Implementations} +\begin{itemize} +\item ZSI: Python +\item KDSOAP: Qt4/5 native Library (commercial) +\item gSOAP: C/C++ +\item Apache Axis2: C++, JAVA +\item Apache CXF: JAVA (+ other middleware protocols) +\item SOAP::WSDL: Perl +\item SOAP4R: Ruby +\item wsdl2objc: Objective C +\item .NET, mono +\end{itemize} +\end{block} +\end{frame} + +\begin{frame}[fragile] +\frametitle{SOAP example in Python/ZSI} +server.py +\begin{lstlisting}[language=python] +from datetime import datetime +from ZSI import dispatch + +def today (arg): + print "today arg:", arg + today = datetime.today () + return str (today) +def load (arg): + print "load arg:", arg + fd = open ("/proc/loadavg", "r") + loadavg = fd.read () + sysload = loadavg.split () + return sysload[0] + +dispatch.AsServer (port=8000, rpc=True) +\end{lstlisting} +\end{frame} + +\begin{frame}[fragile] +\frametitle{SOAP example in Python/ZSI} +client.py +\begin{lstlisting}[language=python] +from datetime import datetime +from ZSI.client import Binding + +b = Binding (url='http://localhost:8000/') +t = b.today (5) +# t = 2014-02-18 15:59:50.571927 +c = datetime.strptime (t, + "%Y-%m-%d %H:%M:%S.%f") +print "Today:", c.strftime ("%d.%m.%Y, %H:%M") +print b.load ("string") +\end{lstlisting} +\end{frame} + + +\begin{frame} +\frametitle{XMPP - Extensible Messaging and Presence Protocol} +\begin{block}{Overview} +\begin{itemize} +\item protocol for MOM based on XML +\item originally named Jabber +\item used for +\begin{itemize} + \item real-time Instant Messaging + \item publishing Presence Informations + \item Contactlist maintenance +\end{itemize} +\end{itemize} +\end{block} +\end{frame} + + +\begin{frame} +\frametitle{Extensible Messaging and Presence Protocol} +\begin{block}{IM for Industry??} +\begin{itemize} +\item free and open standard (IETF RFC 6120, 6121) +\item XMPP servers can be isolated, security is implemented (SASL, TLS) +\item TCP and HTTP(S) transports are supported +\item Priority support: multiple logins from same account, + +login with highest pority gets message +\item not just used for IM: +\begin{itemize} + \item smart grid + \item publish-subscribe systems + \item games + \item signalling for VoIP +\end{itemize} +\end{itemize} +\end{block} +\end{frame} + +\begin{frame} +\frametitle{Extensible Messaging and Presence Protocol} +\begin{block}{Extensible\dots} +\begin{itemize} +\item network management +\item collaboration tools +\item file sharing, gaming +\item remote systems control and monitoring +\item geolocation +\end{itemize} +\end{block} +\end{frame} + +\begin{frame} +\frametitle{Extensible Messaging and Presence Protocol} +\begin{block}{Implemmentations} +\dots too many to mention, have a look at + +http://xmpp.org/xmpp-software/ + +for libraries, clients and servers +\end{block} +\end{frame} + + +\begin{frame}[fragile] +\frametitle{XMPP Client Example} +xmpp\_client.cpp +\begin{lstlisting}[language=C++] +#include +#include "myclient.h" + +int main(int argc, char *argv[]) +{ + QCoreApplication app(argc, argv); + + MyClient client; + client.connectToServer("qtapp@localhost", + "test"); + + return app.exec(); +} +\end{lstlisting} +\end{frame} + +\begin{frame}[fragile] +\frametitle{XMPP Client Example} +myclient.h +\begin{lstlisting}[language=C++] +#include + +class MyClient : public QXmppClient +{ + Q_OBJECT + + public: + MyClient(); + ~MyClient(); + + public slots: + void message_rx(const QXmppMessage&); +}; +\end{lstlisting} +\end{frame} + +\begin{frame}[fragile] +\frametitle{XMPP Client Example} +myclient.cpp\#p1 +\begin{lstlisting}[language=C++] +#include +#include + +#include "myclient.h" + +MyClient::MyClient() : QXmppClient() +{ + bool check = connect(this, + SIGNAL(messageReceived(QXmppMessage)), + SLOT(message_rx(QXmppMessage))); + + Q_ASSERT(check); + Q_UNUSED(check); +} +\end{lstlisting} +\end{frame} + +\begin{frame}[fragile] +\frametitle{XMPP Client Example} +myclient.cpp\#p2 +\begin{lstlisting}[language=C++] +MyClient::~MyClient() { ; } + +void +MyClient::message_rx(const QXmppMessage& msg) +{ + QString from = msg.from(); + QString body = msg.body(); + + std::cout< org.enlightenment.FileManager \ + /org/enlightenment/FileManager \ + org.enlightenment.FileManager.OpenDirectory \ + /home/local +\end{verbatim} \end{frame} -\begin{frame} -\frametitle{Desktop Integration} -\begin{center} -\includegraphics[height=0.8\textheight]{images/dbus-hal.png} -\end{center} -Source: http://www.redhat.com +\begin{frame}[fragile] +\frametitle{System Integration} +e.g. hotplug events +\begin{verbatim} +% mdbus2 -s -l +[SIGNAL] +org.freedesktop.UDisks.DeviceAdded +/org/freedesktop/UDisks :1.25 +('/org/freedesktop/UDisks/devices/sdb',) +\end{verbatim} +\end{frame} + +\begin{frame}[fragile] +\begin{verbatim} +[SIGNAL] +org.freedesktop.DBus.ObjectManager.InterfacesAdded +/org/freedesktop/UDisks2 :1.40 +('/org/freedesktop/UDisks2/drives/WD_My_Passport_0748_57584D314335325839363238', +{'org.freedesktop.UDisks2.Drive': + {'Vendor': <'WD'>, 'Model': <'My Passport0748'>, + 'Revision': <'1015'>, 'Serial': <'57584D314335325839363238'>, + 'WWN': <''>, 'Id': <'WD-My-Passport-0748-57584D314335325839363238'>, + 'Configuration': <@a{sv} {}>, 'Media': <''>, + 'MediaCompatibility': <@as []>, 'MediaRemovable':, + 'MediaAvailable': , 'MediaChangeDetected': , + 'Size':, + 'TimeDetected': , + 'TimeMediaDetected': , + 'Optical': , OpticalBlank': , + 'OpticalNumTracks': , + 'OpticalNumAudioTracks': , + 'OpticalNumDataTracks': , + 'OpticalNumSessions': , + 'RotationRate': <-1>, 'ConnectionBus':<'usb'>, + 'Seat': <'seat0'>, 'Removable': , 'Ejectable': , + 'SortKey': <'01hotplug/1392720111627238'>, + 'CanPowerOff': , + 'SiblingId':<'/sys/devices/pci0000:00/0000:00:14.0/usb2/2-1/2-1:1.0'>}}) +\end{verbatim} +\end{frame} + +\begin{frame}[fragile] +\frametitle{Example: Session Bus Signals} +\begin{itemize} +\item have a look at the code +\item start pingserver and pingclient +\item monitor signals with 'mdbus2 -l' +\end{itemize} \end{frame} \subsection{CORBA} @@ -73,13 +567,40 @@ Source: http://www.redhat.com \end{block} \end{frame} +\begin{frame} +\frametitle{well-known implementations} +\begin{itemize} +\item omniORB: C++ / Python +\item ACE/TAO: C++ including RTCORBA support +\item MICO: C++ focus on security +\item JacORB: JAVA +\item IIOP.NET: .NET Remoting integration +\item ORBit2: C with C++ and Python bindings +\end{itemize} +\end{frame} + + \begin{frame} \frametitle{Functional Principle} \begin{center} -\includegraphics[height=0.8\textheight]{images/orb.jpg} +\includegraphics[width=1.0\textwidth]{images/orb.jpg} \end{center} \end{frame} + +\begin{frame} +\frametitle{Functional Principle} +\begin{block}{IDL Interface Description Language} +\begin{itemize} +\item write Interface Description +\item use IDL compiler to produce stubs and skeleton code +\item implement interfaces and use interfaces in native language +\item compile applications +\end{itemize} +\end{block} +\end{frame} + + \begin{frame} \frametitle{Functional Principle} \begin{block}{CORBA Services} -- cgit v1.2.3 From de1b78ee51ee99165c7ad1030cc13a24fd05e394 Mon Sep 17 00:00:00 2001 From: Manuel Traut Date: Tue, 18 Feb 2014 23:34:04 +0100 Subject: middleware: add a python xmlrpc example xmlrpc is supported by the python stdlib so let's play around with it! Signed-off-by: Manuel Traut --- frameworks/middleware/examples/xmlrpc/client.py | 14 ++++++++++++++ frameworks/middleware/examples/xmlrpc/server.py | 21 +++++++++++++++++++++ 2 files changed, 35 insertions(+) create mode 100755 frameworks/middleware/examples/xmlrpc/client.py create mode 100755 frameworks/middleware/examples/xmlrpc/server.py (limited to 'frameworks') diff --git a/frameworks/middleware/examples/xmlrpc/client.py b/frameworks/middleware/examples/xmlrpc/client.py new file mode 100755 index 0000000..2b466b7 --- /dev/null +++ b/frameworks/middleware/examples/xmlrpc/client.py @@ -0,0 +1,14 @@ +#!/usr/bin/python + +import xmlrpclib +from datetime import datetime + +proxy = xmlrpclib.ServerProxy ("http://localhost:8000/") + +today = proxy.today () +# today = 20140218T14:23:45 +converted = datetime.strptime (today.value, "%Y%m%dT%H:%M:%S") +print "Today: %s" % converted.strftime ("%d.%m.%Y, %H:%M") + +load = proxy.load () +print "system load:", load diff --git a/frameworks/middleware/examples/xmlrpc/server.py b/frameworks/middleware/examples/xmlrpc/server.py new file mode 100755 index 0000000..ebde5ee --- /dev/null +++ b/frameworks/middleware/examples/xmlrpc/server.py @@ -0,0 +1,21 @@ +#!/usr/bin/python + +from datetime import datetime +from SimpleXMLRPCServer import SimpleXMLRPCServer +import xmlrpclib + +def today (): + today = datetime.today () + return xmlrpclib.DateTime (today) + +def load (): + fd = open ("/proc/loadavg", "r") + loadavg = fd.read () + sysload = loadavg.split () + return xmlrpclib.FloatType (sysload[0]) + +server = SimpleXMLRPCServer (("localhost", 8000)) +server.register_function (today, "today") +server.register_function (load, "load") +print "Listening on port 8000..." +server.serve_forever () -- cgit v1.2.3 From a9f5c60272e630c3de528dc773eb5af491a01e0a Mon Sep 17 00:00:00 2001 From: Manuel Traut Date: Tue, 18 Feb 2014 23:34:33 +0100 Subject: middleware: add a python soap example it's a quite small one. Maybe we can add an interface description sometimes. Signed-off-by: Manuel Traut --- frameworks/middleware/examples/soap/client.py | 11 +++++++++++ frameworks/middleware/examples/soap/server.py | 18 ++++++++++++++++++ 2 files changed, 29 insertions(+) create mode 100755 frameworks/middleware/examples/soap/client.py create mode 100755 frameworks/middleware/examples/soap/server.py (limited to 'frameworks') diff --git a/frameworks/middleware/examples/soap/client.py b/frameworks/middleware/examples/soap/client.py new file mode 100755 index 0000000..9cd35f2 --- /dev/null +++ b/frameworks/middleware/examples/soap/client.py @@ -0,0 +1,11 @@ +#!/usr/bin/python + +from datetime import datetime +from ZSI.client import Binding + +b = Binding(url='http://localhost:8000/') +t = b.today (5) +# t = 2014-02-18 15:59:50.571927 +conv = datetime.strptime (t, "%Y-%m-%d %H:%M:%S.%f") +print "Today: %s" % conv.strftime ("%d.%m.%Y, %H:%M") +print b.load ("string") diff --git a/frameworks/middleware/examples/soap/server.py b/frameworks/middleware/examples/soap/server.py new file mode 100755 index 0000000..32a550a --- /dev/null +++ b/frameworks/middleware/examples/soap/server.py @@ -0,0 +1,18 @@ +#!/usr/bin/python + +from datetime import datetime +from ZSI import dispatch + +def today (arg): + print "today arg:", arg + today = datetime.today () + return str (today) + +def load (arg): + print "load arg:", arg + fd = open ("/proc/loadavg", "r") + loadavg = fd.read () + sysload = loadavg.split () + return sysload[0] + +dispatch.AsServer (port=8000, rpc=True) -- cgit v1.2.3 From 07761742a5a104020c975f649bd188a950a4891c Mon Sep 17 00:00:00 2001 From: Manuel Traut Date: Tue, 18 Feb 2014 23:36:45 +0100 Subject: middleware/xmpp: add an example - this is a minimal qt client that can be used with a jabber/xmpp server - have a look at the README file for the test setup Signed-off-by: Manuel Traut --- frameworks/middleware/examples/xmpp/README | 28 +++++++++++++++++++++ frameworks/middleware/examples/xmpp/client.cpp | 24 ++++++++++++++++++ frameworks/middleware/examples/xmpp/myclient.cpp | 32 ++++++++++++++++++++++++ frameworks/middleware/examples/xmpp/myclient.h | 17 +++++++++++++ frameworks/middleware/examples/xmpp/xmpp.pro | 15 +++++++++++ 5 files changed, 116 insertions(+) create mode 100644 frameworks/middleware/examples/xmpp/README create mode 100644 frameworks/middleware/examples/xmpp/client.cpp create mode 100644 frameworks/middleware/examples/xmpp/myclient.cpp create mode 100644 frameworks/middleware/examples/xmpp/myclient.h create mode 100644 frameworks/middleware/examples/xmpp/xmpp.pro (limited to 'frameworks') diff --git a/frameworks/middleware/examples/xmpp/README b/frameworks/middleware/examples/xmpp/README new file mode 100644 index 0000000..ef147ce --- /dev/null +++ b/frameworks/middleware/examples/xmpp/README @@ -0,0 +1,28 @@ +a) apt-get install libqxmpp-dev psi ejabberd + +b) edit /etc/ejabberd/ejabberd.cfg to allow inband registration: + + --8<--- + %% No username can be registered via in-band registration: + %% To enable in-band registration, replace 'deny' with 'allow' + % (note that if you remove mod_register from modules list then users will not + % be able to change their password as well as register). + % This setting is default because it's more safe. + {access, register, [{allow, all}]}. + --8<--- + +c) start psi and configure it to use 'localhost' as server and create two + accounts: : + qtapp:test + +d) login with and qtapp, add both accounts to their contact list, + and try to send messages. logoff the qtapp account. + +e) build the qt client application and start it: + +qmake +make +./client + +f) the qtapp account needs now to be online in psi, write a messagte to qtapp + the message should be displayed in the commandline diff --git a/frameworks/middleware/examples/xmpp/client.cpp b/frameworks/middleware/examples/xmpp/client.cpp new file mode 100644 index 0000000..9390438 --- /dev/null +++ b/frameworks/middleware/examples/xmpp/client.cpp @@ -0,0 +1,24 @@ +/* +* Copyright (C) 2008-2010 Manjeet Dahiya +* +* Author: +* Manjeet Dahiya +* modified 2014 by Manuel Traut +*/ + +#include + +//#include + +#include "myclient.h" + +int main(int argc, char *argv[]) +{ + QCoreApplication a(argc, argv); + // QXmppLogger::getLogger()->setLoggingType(QXmppLogger::StdoutLogging); + + MyClient client; + client.connectToServer("qtapp@localhost", "test"); + + return a.exec(); +} diff --git a/frameworks/middleware/examples/xmpp/myclient.cpp b/frameworks/middleware/examples/xmpp/myclient.cpp new file mode 100644 index 0000000..fa28603 --- /dev/null +++ b/frameworks/middleware/examples/xmpp/myclient.cpp @@ -0,0 +1,32 @@ +/* +* Copyright (C) 2008-2010 Manjeet Dahiya +* +* Author: +* Manjeet Dahiya +* +* modified 2014 by Manuel Traut +*/ + +#include +#include + +#include "myclient.h" + +MyClient::MyClient() : QXmppClient() +{ + bool check = connect(this, + SIGNAL(messageReceived(QXmppMessage)), + SLOT(message_rx(QXmppMessage))); + Q_ASSERT(check); + Q_UNUSED(check); +} + +MyClient::~MyClient() { ; } + +void MyClient::message_rx(const QXmppMessage& message) +{ + QString from = message.from(); + QString msg = message.body(); + std::cout< + +class MyClient : public QXmppClient +{ + Q_OBJECT +public: + MyClient(); + ~MyClient(); + +public slots: + void message_rx(const QXmppMessage&); +}; + +#endif diff --git a/frameworks/middleware/examples/xmpp/xmpp.pro b/frameworks/middleware/examples/xmpp/xmpp.pro new file mode 100644 index 0000000..7f0be00 --- /dev/null +++ b/frameworks/middleware/examples/xmpp/xmpp.pro @@ -0,0 +1,15 @@ +###################################################################### +# Automatically generated by qmake (2.01a) Tue Feb 18 19:47:09 2014 +###################################################################### + +TEMPLATE = app +TARGET = client +DEPENDPATH += . +INCLUDEPATH += . + +# Input +SOURCES += client.cpp myclient.cpp +HEADERS += myclient.h + +QT += network +LIBS += -lqxmpp -- cgit v1.2.3 From fd369b1d74b95904b91bfd0fc6c7c52aacd31872 Mon Sep 17 00:00:00 2001 From: Manuel Traut Date: Tue, 18 Feb 2014 23:50:21 +0100 Subject: middleware/example/corba/README document option of supplier that is send to the receiver Signed-off-by: Manuel Traut --- frameworks/middleware/examples/corba/README | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'frameworks') diff --git a/frameworks/middleware/examples/corba/README b/frameworks/middleware/examples/corba/README index 74ca9bb..5d71b99 100644 --- a/frameworks/middleware/examples/corba/README +++ b/frameworks/middleware/examples/corba/README @@ -9,4 +9,4 @@ Naming_Service -ORBEndpoint iiop://localhost:55555 ./receiver -ORBInitRef NameService=corbaloc:iiop:localhost:55555/NameService -./supplier -ORBInitRef NameService=corbaloc:iiop:localhost:55555/NameService +./supplier test -ORBInitRef NameService=corbaloc:iiop:localhost:55555/NameService -- cgit v1.2.3 From 276f95e75e21e16fb132ea682e6dbf8dec520738 Mon Sep 17 00:00:00 2001 From: Manuel Traut Date: Wed, 19 Feb 2014 08:10:15 +0100 Subject: middleware: update CORBA section - mention policies - added more details about abstractions (os, language, transports) Signed-off-by: Manuel Traut --- frameworks/middleware/pres_middleware.tex | 55 ++++++++++++++++++++++++++++--- 1 file changed, 50 insertions(+), 5 deletions(-) (limited to 'frameworks') diff --git a/frameworks/middleware/pres_middleware.tex b/frameworks/middleware/pres_middleware.tex index d147ceb..c2933ba 100644 --- a/frameworks/middleware/pres_middleware.tex +++ b/frameworks/middleware/pres_middleware.tex @@ -556,17 +556,17 @@ org.freedesktop.DBus.ObjectManager.InterfacesAdded \end{frame} \subsection{CORBA} + \begin{frame} \frametitle{Common Object Request Broker Architecture} -\begin{block}{abstracts} \begin{itemize} -\item operating systems -\item programming language -\item transport protocol +\item hosting of objects / RPC +\item typically a Client- / Serverarchitecture +\item one application can be Client and Server at the same time \end{itemize} -\end{block} \end{frame} + \begin{frame} \frametitle{well-known implementations} \begin{itemize} @@ -580,6 +580,35 @@ org.freedesktop.DBus.ObjectManager.InterfacesAdded \end{frame} +\begin{frame} +\frametitle{communication between different operating systems} +\begin{itemize} +\item hosting of objects is abstracted, e.g. ThreadPool +\item use of OS services, e.g. sockets is abstracted +\end{itemize} +\end{frame} + + +\begin{frame} +\frametitle{communication between programming languages} +\begin{itemize} +\item CORBA uses its own datatypes +\item datatype mapping needs to be implement for each language +\end{itemize} +\end{frame} + + +\begin{frame} +\frametitle{common transports} +\begin{itemize} +\item IIOP +\item socket +\item shared-memory +\item implementing own transports is possible +\end{itemize} +\end{frame} + + \begin{frame} \frametitle{Functional Principle} \begin{center} @@ -600,6 +629,22 @@ org.freedesktop.DBus.ObjectManager.InterfacesAdded \end{block} \end{frame} +\begin{frame} +\frametitle{Functional Principle} +\begin{block}{Policies} +\begin{itemize} +\item Server- or Clientsiede Policies +\item Run-time and compile-time Policies +\item e.g. for +\begin{itemize} +\item Lifetime of objects +\item Activation of objects +\item Thread Policies +\item Connection Polies +\end{itemize} +\end{itemize} +\end{block} +\end{frame} \begin{frame} \frametitle{Functional Principle} -- cgit v1.2.3 From 5ec6915a8f955c8ef72165e7392718a0b1f75bfa Mon Sep 17 00:00:00 2001 From: Manuel Traut Date: Wed, 19 Feb 2014 09:36:54 +0100 Subject: middleware: add celery section and example celery is a python framework for job execution Signed-off-by: Manuel Traut --- frameworks/middleware/examples/celery/README | 3 + frameworks/middleware/examples/celery/exec_task.py | 15 +++++ frameworks/middleware/examples/celery/test.py | 36 ++++++++++ frameworks/middleware/examples/celery/worker.sh | 2 + frameworks/middleware/pres_middleware.tex | 77 ++++++++++++++++++++++ 5 files changed, 133 insertions(+) create mode 100644 frameworks/middleware/examples/celery/README create mode 100644 frameworks/middleware/examples/celery/exec_task.py create mode 100755 frameworks/middleware/examples/celery/test.py create mode 100755 frameworks/middleware/examples/celery/worker.sh (limited to 'frameworks') diff --git a/frameworks/middleware/examples/celery/README b/frameworks/middleware/examples/celery/README new file mode 100644 index 0000000..9045901 --- /dev/null +++ b/frameworks/middleware/examples/celery/README @@ -0,0 +1,3 @@ +apt-get install python-celery +./worker.sh +./test.py diff --git a/frameworks/middleware/examples/celery/exec_task.py b/frameworks/middleware/examples/celery/exec_task.py new file mode 100644 index 0000000..9169250 --- /dev/null +++ b/frameworks/middleware/examples/celery/exec_task.py @@ -0,0 +1,15 @@ +import os + +from celery import Celery + +app = Celery ('tasks', broker='sqla+sqlite:///celerydb.sqlite', + backend='db+sqlite:///results.sqlite') + +@app.task +def execute (command): + return os.system (command) + +@app.task +def execute2 (command): + if os.system (command): + raise Exception ("command not found") diff --git a/frameworks/middleware/examples/celery/test.py b/frameworks/middleware/examples/celery/test.py new file mode 100755 index 0000000..7d79c8e --- /dev/null +++ b/frameworks/middleware/examples/celery/test.py @@ -0,0 +1,36 @@ +#!/usr/bin/python + +import sys +import traceback + +from exec_task import execute, execute2 + +execute.delay ("echo hello world") + +print "\n\n" + +result = execute.delay ("sleep 2") +print "result ready?", result.ready () +print "wait for result..." +ret = result.get (timeout=10) +print "task done", ret + +print "\n\n" + +result = execute.delay ("/bin/false") +print "/bin/false:", result.get (timeout=10) + +print "\n\n" + +result = execute2.delay ("/bin/treu") +try: + print "/bin/treu:", result.get (timeout=10) +except: + print "exception occured; backtrace:" + print result.traceback + +print "\n\n" + +result = execute2.delay ("/bin/true") +print "/bin/true:", result.get (timeout=10) + diff --git a/frameworks/middleware/examples/celery/worker.sh b/frameworks/middleware/examples/celery/worker.sh new file mode 100755 index 0000000..1705198 --- /dev/null +++ b/frameworks/middleware/examples/celery/worker.sh @@ -0,0 +1,2 @@ +#!/bin/sh +celery -A exec_task worker --loglevel=info diff --git a/frameworks/middleware/pres_middleware.tex b/frameworks/middleware/pres_middleware.tex index c2933ba..c2eacc7 100644 --- a/frameworks/middleware/pres_middleware.tex +++ b/frameworks/middleware/pres_middleware.tex @@ -445,6 +445,83 @@ MyClient::message_rx(const QXmppMessage& msg) \subsection{Celery} +\begin{frame} +\frametitle{Overview} +\begin{itemize} +\item Distributed Task Queue +\item based on message passing +\item real-time operation and scheduling +\item Tasks can be hosted on a single or on mulitple workers +\item synchronous and asynchronous execution +\item rate limit support +\end{itemize} +\end{frame} + +\begin{frame} +\frametitle{implementations} +\begin{itemize} +\item celery-project: Python +\item celery-php: PHP +\end{itemize} +\end{frame} + +\begin{frame} +\frametitle{celeryproject} +\begin{block}{supports multiple message broker} +\begin{itemize} +\item database: Django, or any supported by SQLAlchemy +\item RabbitMQ +\item Redis +\item Amazon SQS (experimental) +\end{itemize} +\end{block} +\end{frame} + +\begin{frame} +\frametitle{celeryproject} +\begin{block}{supports multiple result storage} +\begin{itemize} +\item database: any supported by SQLAlchemy +\item memcached +\item Redis +\item AMQP +\item Cassandra +\item IronCache +\end{itemize} +\end{block} +\end{frame} + +\begin{frame}[fragile] +\frametitle{celeryproject, example} +exec\_task.py +\begin{lstlisting}{language=python} +import os +from celery import Celery + +app = Celery ('tasks', broker='sqla+sqlite:///celerydb.sqlite) + +@app.task +def execute (command): + os.system (command) +\end{lstlisting} +\end{frame} + +\begin{frame}[fragile] +\frametitle{celeryproject, example} +test.py +\begin{lstlisting}{language=python} +from exec_task import execute + +execute.delay ("echo hello world") +\end{lstlisting} + +start the example: +\begin{lstlisting}{language=bash} +term1% celery -A exec_task worker +term2% ./test.py +\end{lstlisting} +\dots an example using return values and exceptions is in the example dir +\end{frame} \subsection{DDS} -- cgit v1.2.3 From 445b026710cd33745e13e952f25288b4fd87cd1e Mon Sep 17 00:00:00 2001 From: Manuel Traut Date: Wed, 19 Feb 2014 09:52:10 +0100 Subject: middleware: don't mention DDS there is only one open-source implementation and the topic is quiet to complex for a short overview! Signed-off-by: Manuel Traut --- frameworks/middleware/pres_middleware.tex | 6 ------ 1 file changed, 6 deletions(-) (limited to 'frameworks') diff --git a/frameworks/middleware/pres_middleware.tex b/frameworks/middleware/pres_middleware.tex index c2eacc7..b8ccce1 100644 --- a/frameworks/middleware/pres_middleware.tex +++ b/frameworks/middleware/pres_middleware.tex @@ -9,7 +9,6 @@ \item Overview \item XML based Middleware \item Celery -\item DDS \item D-Bus \item CORBA \end{itemize} @@ -79,7 +78,6 @@ and for what they can be used. \begin{itemize} \item XML based Middleware \item Celery - Job Queue Protocol -\item DDS - Data Distribution Service \item D-Bus - MOM \item CORBA - Common Object Request Broker \end{itemize} @@ -524,10 +522,6 @@ term2% ./test.py \end{frame} -\subsection{DDS} - - - \subsection{D-Bus} \begin{frame} -- cgit v1.2.3 From 2f46ad6a6f7393dc7898672a7ea3337395bafae9 Mon Sep 17 00:00:00 2001 From: Manuel Traut Date: Wed, 19 Feb 2014 10:00:49 +0100 Subject: middleware: add conclusion Signed-off-by: Manuel Traut --- frameworks/middleware/pres_middleware.tex | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'frameworks') diff --git a/frameworks/middleware/pres_middleware.tex b/frameworks/middleware/pres_middleware.tex index b8ccce1..a658f83 100644 --- a/frameworks/middleware/pres_middleware.tex +++ b/frameworks/middleware/pres_middleware.tex @@ -771,4 +771,16 @@ org.freedesktop.DBus.ObjectManager.InterfacesAdded \end{block} \end{frame} +\subsection{Conclusion} +\begin{frame} +\frametitle{Conclusion} +\begin{itemize} +\item many frameworks available +\item different kind of abstraction +\item special frameworks for special problems +\item which framework is best for my problem? +\item is it helpful to use multiple frameworks? +\end{itemize} +\end{frame} + \input{tailpres} -- cgit v1.2.3