Server Revolutions
     Der Spring Source DM Server




Sandro Sonntag - Adorsys GmbH & Co KG
                  1
Was erwartet Sie?

• Einführung in OSGi
• Was bedeutet „Enterprise“ für OSGi?
• Spring Dynamic Modules Architektur
• Eine Spring OSGi App from Scratch
• Einführung in die Konzepte des DM Servers
                    2
Warum noch ein
 Appserver?


      3
Wie funktioniert
  Wiederverwendung
       Heute?
• Auf Service Ebene?
• Auf Library Ebene?
• In unterschiedlichen Versionen?
• Und die Kommunikation zwischen Modulen?
• Und wie geht es Ihrem Permgen Space
  dabei?           4
Klassische Java Systeme
•   Java Standard Edition
    •   System Classloader
    •   eine Version pro Library
    •   Keinerlei Modul oder Komponenten Model auf
        Klassenebene
•   Java Enterprise Edition
    •   Eingeschränkt auf Deployment Typen (EJB, WAR, EAR)
    •   Grobgranular!
    •   Library Wiederverwendung nicht vorgesehen!


                                   5
Potential von OSGi
•   Modularisierung
    •   Auf Library und Service Ebene
•   Deklaration von Abhängigkeiten (zur Laufzeit!)
•   Förderung der Unabhängigkeit von
    Komponenten (Sichtbarkeit/Isolation)
• Sehr Leichtgewichtiger Container
• Kein „One size fits all“ Server mehr
• Bedeutet: riesen Schritt nach vorne!
                         6
Das Geheimnis
        heutiger Appserver
•   Fast alle JEE Application Server basieren heute auf
    OSGi
    •   ...und im Embedded Bereich und in der IDE läuft
        es schon seit Jahren!
•   Aber: keiner lässt die Applikationen von OSGi
    profitieren
•   Warum können Business-Apps nicht die Vorteile
    der OSGi Architektur nutzen?
•   Spring DM macht dies möglich

                            7
Software auf OSGi
•   Websphere
•   JBoss
•   Weblogic
•   OpenEJB
•   Eclipse
•   JOnAS 5
•   GlassFish (v3)
•   ServiceMix

                     8
OSGi?
•   Ist ein Modul Container
•   Partitioniert Systeme in Bundles
•   Build Zeit Abhängigkeiten gelten nun auch zur Runtime
•   Verwaltet Abhängigkeiten zwischen Modulen
•   Isoliert Module (strenge Sichbarkeitsregeln)
•   Vermittelt Services zwischen Bundles
•   kennt Versionierung
•   Sorgt für Disziplin!

                              9
Was ist ein
              Bundle?
• Jedes Bundle hat einen
  eigenen Classloader
• Dadurch können Bundles
  installiert, gestartet, gestopt, neugeladen
  werden
• Bundles legen Ihre Beziehungen zu
  anderen Bundles durch import/export
  fest
• Bundles unterliegen einem Lifecycle
                        10
Service Platform

• Bundles können Services dynamisch
  veröffentlichen
• ServiceRegistry erlaubt es diese Services zu
  nutzen



                     11
Bundle Activator
• Deployment von Services ist nicht
   Deklarativ!
• Vorteil: Flexibilität
• Nachteil: Komplexität, Fehleranfälligkeit
  Manifest-Version: 1.0

  Bundle-Activator: com.javaworld.sample.helloworld.Activator



  public class Activator implements BundleActivator {
      public void start(BundleContext context) throws Exception {
          System.out.println("Hello world");
      }
      public void stop(BundleContext context) throws Exception {
          System.out.println("Goodbye World");
      }
  }
                                          12
Service Registrierung in
             OSGI
public class HelloServiceActivator implements BundleActivator   {
    ServiceRegistration helloServiceRegistration;

    public void start(BundleContext context) throws Exception {
       HelloService helloService = new HelloServiceImpl();
       helloServiceRegistration =
       context.registerService(HelloService.class.getName(),
                                helloService, null);
    }
    public void stop(BundleContext context) throws Exception {
        helloServiceRegistration.unregister();
    }
}




                                      13
Verwendung eines
                 Services in OSGi
public class Activator implements BundleActivator {

    ServiceReference helloServiceReference;

    public void start(BundleContext context) throws Exception {
        System.out.println("Hello World!!");

        helloServiceReference= context.getServiceReference(HelloService.class.getName());
        HelloService helloService =(HelloService)context.getService(helloServiceReference);

        System.out.println(helloService.sayHello());

    }
    public void stop(BundleContext context) throws Exception {
        System.out.println("Goodbye World!!");

        context.ungetService(helloServiceReference);
    }
}



                                              14
Angst?
•   Neuer Infrastrukturcode
    •   Komplex!

    •   Fehleranfällig!

•   Achtung: lookup eines Objekts führt zu einer direkten Referenz des
    Objektes!
    •   Bei undeploy des Impl Bundles muss die Referenz freigegeben werden!

    •   Resourceleaks!

•   Was wenn sich Abhängigkeiten ändern?
    •   Services sollten nicht manuell referenziert werden
    •   Service Tracker wird empfohlen - noch komplexer!

•   Und sieht so die Zukunft aus?


                                      15
OSGi Enterprise

• Webapps
• Business Components
• Transaction manager
• Datasources
• Configurations
                  16
Business
Web Application
                             Services



        Enterprice Infrastructure


 Web Container                ORM


  Transaction MGR         Datasource MGR




             OSGi Platform




                    17
Spring DM Architektur




          18
Bundle Application
         Context
•   Bundle META-INF/spring enthält Konfiguration
•   oder Manifest enthält „Spring-Context: xyz.xml“
    declaration
•   Es werden alle XML Dateien gelesen
•   Ein OSGi Application Context wird erstellt
•   Durch Spring DM Extender ist kein
    BundleActivator notwendig
•   ApplicationContexte sind über die OSGi
    ServiceRegistry zugreifbar
                         19
OSGi Services ala
       Spring
• Import:
 <osgi:reference id="messageService"
 interface="com.xyz.MessageService"/>


• Export:
 <osgi:service ref="beanToBeExported"
 interface="com.xyz.MessageService"/>




                       20
OSGi Registry
           lauschen!
• Es existieren Listener Provider und
  Consumer Seite
• Damit lassen sich sehr elegant Services
  überwachen
   <reference id="someService" interface="com.xyz.MessageService">
     <listener bind-method="onBind" unbind-method="onUnbind">
        <beans:bean class="MyCustomListener"/>
     </listener>
   </reference>

   <service ref="beanToBeExported" interface="SomeInterface">
     <registration-listener ref="myListener"
       registration-method="serviceRegistered"
       unregistration-method="serviceUnregistered"/>
   </service>

                               21
Applikation in OSGi
                                                               Service
•   Ausschließlich                            Web              Registry
    Abhängigkeiten auf API

•   Änderung der
                                            Model/API
    Implementierung
    Möglich

•   zur Laufzeit!                     Service Implementation


•   Infrastruktur ist nur eine
    andere Art von Service
                                          Infrastructure

                                 22
OSGi Applikationen mit
       Spring
•   Es sind immer noch POJOs!
•   Keine Platform- und Codeabhängigkeit zu OSGi
•   Keine Codeänderung notwendig
•   Apps sind auch noch in JEE lauffähig
•   Best Pactice: 2 Spring Konfigurationen
    •   Applikations Konfiguration
    •   OSGi Konfiguration (Service Import/Export)

                         23
Webapp Unterstützung
•   Servlet Container weden selbst als Bundle
    deployed
•   Wie werden WAR Bundles im Webcontainer
    deployed?
    •   OSGi sieht hier nichts vor!
    •   Spring hält Web OSGi Bundles bereit
    •   Deployment via Spring OSGi Web Extender
•   Tomcat und Jetty werden unterstützt

                           24
Schlechte
          Gewohnheiten?
•   Class.forName
•   Thread ContextClassloader
    •   Das Verhalten ist in OSGi undefiniert!
    •   Spring DM kann den TCC managen!
•   Probleme mit statischen Variablen
•   Suche in Jars
    •   TLD´s, Facelet Tags
•   OSGi Service als Observable

                              25
Kompatibilität zu
      Enterprise Libs
• Viele der Bibliotheken sind nicht für OSGi
  entwickelt
• OSGi import und export fehlen im Manifest!
• Classloading Probleme
  • Verwendung von ContextClassloader
  • META-INF resources
  • Sichtbarkeit von Klassen
  • Packaging Fehler 26
Beliebte Frameworks
•   Spring 2.5 +
•   Jetty +
•   Tomcat 5 +
•   Tomcat 6 (kein JSP)
•   Hibernate/JPA (+)
•   JSP (+)
•   JSF Myfaces (+)
•   Apache Commons +
•   Log4J


                          27
Spring Enterprise
        Repository
• Enthält viele migrierte Bundles aus dem
  Maven Central Repository
• Leider sind es nicht immer die aktuellsten
• Es ist nicht garantiert dass die Libs auch
  funktionieren
• http://www.springsource.com/repository/
  app/

                     28
Was fehlt noch zu JEE?
                                 EJB/Web Container       Spring DM

           Webapps                         +                   +

         Services/EJBs                     +                   +

         Modulsystem                       /                   +

Kommunikation zwischen Modulen      / (Serialisiert)           +

          Remoting                         +            / (WebServices)

     Reife der Technologie                 +                   -

           Security                        +           / (Spring Security)




                                          29
SpringSource DM
     Server


       30
Etwas Praxis...
Begriffswirrwarr
•   Spring Dynamic Modules = Spring für OSGI

    •   Application Context per Bundle

    •   Webapp Unterstützung

    •   License: Apache

•   SpringSource DM Server

    •   neuer Typ: „Applikation“ (OSGi kennt nur Bundles)

    •   Distribution von OSGi Bundles und Scripten

    •   Diagnose & Monitoring (Kommerziell)

    •   Lizenz: GPL und Kommerziell
                              32
Features

• Vorinstallierte OSGi Standard Bundles
• PAR Package - Application Deployment
 • Isolation
• Deployment Plan als XML
• Diagnose & Monitoring (Kommerziell)
                    33
Technologien

• Spring Framework
• Tomcat
• OSGi R4.1
• Equinox als OSGi Implementierung
• Spring Dynamic Modules
                   34
Architektur




     35
WAR Deployment
       Types

• Standard WAR mit Libraries
• Shared Libraries WAR
• Shared Services WAR

                    36
PAR
• OSGi kenn keine Applikation
• dadurch schwammige Grenzen
• Versionierung über Bundles hinweg
• (re)deploy als Einheit
• Verbergen von internas
 • Services
 • Bundles
                    37
PAR


  Web                                 Business
                   Model
Application                           Services



          Enterprice Infrastructure


   Web Container                ORM


   Transaction MGR          Datasource MGR




               OSGi Platform




                     38
Plans
• Beschreibt die zu deployenden Bundles
• Wie ein PAR jedoch werden die Bundles
     referenziert
• Effizenter da weniger IO
<plan name="com.springsource.server.admin.plan" version="2.0.0" scoped="true" atomic="true"
      xmlns="http://www.springsource.org/schema/dm-server/plan"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:schemaLocation="http://www.springsource.org/schema/dm-server/plan
                   http://www.springsource.org/schema/dm-server/plan/springsource-dm-server-
plan.xsd">


     <artifact type="bundle" name="com.springsource.server.admin.state" version="[2.0,2.5)"/>

     <artifact type="bundle" name="com.springsource.server.admin.content" version="[2.0,2.5)"/>
      <artifact type="bundle" name="com.springsource.server.admin.web" version="[2.0,2.5)"/>
</plan>
                                                39
Import Hölle

• Import Library
 • Hibernate
 • Spring
 • JSF
• Import Bundle
                   40
Hibernate CNF
             Probleme
•   Problem Lazy Loding
•   Domain Model Bytecode Enhancement
•   Unsichtbare Abhängigkeit Model -> Hibernate
    entsteht
•   Lösung 1: Import-Package
    •   Ungewollte Abhängigkeit
•   Lösung 2: import-scope:=application
    •   Angabe den direkten Hibernate
        Abhängigkeiten    41
Licht und Schatten
•   OSGi ist zweifelsohne ein Fortschritt und in vielen Dingen
    bestehenden Komponenten Technologien wie EJB überlegen
•   Spring integriert sich hervorragend in die OSGi Platform
    und ist eine Bereicherung das bereits viele Enterprise
    Probleme gelöst sind
•   Leider verderben nicht OSGi konforme Libraries immer
    wieder den Spaß durch Classloading Probleme
•   Im Enterprise Bereich kann man leider noch nicht von
    „straight forward“ Entwicklung sprechen, hier gibt es noch
    viele Detail Probleme


                              42
Resourcen
• www.spring-buch.de/Beispiele/readme.html
• http://www.javaworld.com/javaworld/
  jw-04-2008/jw-04-osgi2.html
• http://www.javaworld.com/javaworld/
  jw-03-2008/jw-03-osgi1.html
• http://springosgi.googlepages.com/
                     43
Noch Fragen?

Server Revolutions- Der Spring Source DM Server

  • 1.
    Server Revolutions Der Spring Source DM Server Sandro Sonntag - Adorsys GmbH & Co KG 1
  • 2.
    Was erwartet Sie? •Einführung in OSGi • Was bedeutet „Enterprise“ für OSGi? • Spring Dynamic Modules Architektur • Eine Spring OSGi App from Scratch • Einführung in die Konzepte des DM Servers 2
  • 3.
    Warum noch ein Appserver? 3
  • 4.
    Wie funktioniert Wiederverwendung Heute? • Auf Service Ebene? • Auf Library Ebene? • In unterschiedlichen Versionen? • Und die Kommunikation zwischen Modulen? • Und wie geht es Ihrem Permgen Space dabei? 4
  • 5.
    Klassische Java Systeme • Java Standard Edition • System Classloader • eine Version pro Library • Keinerlei Modul oder Komponenten Model auf Klassenebene • Java Enterprise Edition • Eingeschränkt auf Deployment Typen (EJB, WAR, EAR) • Grobgranular! • Library Wiederverwendung nicht vorgesehen! 5
  • 6.
    Potential von OSGi • Modularisierung • Auf Library und Service Ebene • Deklaration von Abhängigkeiten (zur Laufzeit!) • Förderung der Unabhängigkeit von Komponenten (Sichtbarkeit/Isolation) • Sehr Leichtgewichtiger Container • Kein „One size fits all“ Server mehr • Bedeutet: riesen Schritt nach vorne! 6
  • 7.
    Das Geheimnis heutiger Appserver • Fast alle JEE Application Server basieren heute auf OSGi • ...und im Embedded Bereich und in der IDE läuft es schon seit Jahren! • Aber: keiner lässt die Applikationen von OSGi profitieren • Warum können Business-Apps nicht die Vorteile der OSGi Architektur nutzen? • Spring DM macht dies möglich 7
  • 8.
    Software auf OSGi • Websphere • JBoss • Weblogic • OpenEJB • Eclipse • JOnAS 5 • GlassFish (v3) • ServiceMix 8
  • 9.
    OSGi? • Ist ein Modul Container • Partitioniert Systeme in Bundles • Build Zeit Abhängigkeiten gelten nun auch zur Runtime • Verwaltet Abhängigkeiten zwischen Modulen • Isoliert Module (strenge Sichbarkeitsregeln) • Vermittelt Services zwischen Bundles • kennt Versionierung • Sorgt für Disziplin! 9
  • 10.
    Was ist ein Bundle? • Jedes Bundle hat einen eigenen Classloader • Dadurch können Bundles installiert, gestartet, gestopt, neugeladen werden • Bundles legen Ihre Beziehungen zu anderen Bundles durch import/export fest • Bundles unterliegen einem Lifecycle 10
  • 11.
    Service Platform • Bundleskönnen Services dynamisch veröffentlichen • ServiceRegistry erlaubt es diese Services zu nutzen 11
  • 12.
    Bundle Activator • Deploymentvon Services ist nicht Deklarativ! • Vorteil: Flexibilität • Nachteil: Komplexität, Fehleranfälligkeit Manifest-Version: 1.0 Bundle-Activator: com.javaworld.sample.helloworld.Activator public class Activator implements BundleActivator { public void start(BundleContext context) throws Exception { System.out.println("Hello world"); } public void stop(BundleContext context) throws Exception { System.out.println("Goodbye World"); } } 12
  • 13.
    Service Registrierung in OSGI public class HelloServiceActivator implements BundleActivator { ServiceRegistration helloServiceRegistration; public void start(BundleContext context) throws Exception { HelloService helloService = new HelloServiceImpl(); helloServiceRegistration = context.registerService(HelloService.class.getName(), helloService, null); } public void stop(BundleContext context) throws Exception { helloServiceRegistration.unregister(); } } 13
  • 14.
    Verwendung eines Services in OSGi public class Activator implements BundleActivator { ServiceReference helloServiceReference; public void start(BundleContext context) throws Exception { System.out.println("Hello World!!"); helloServiceReference= context.getServiceReference(HelloService.class.getName()); HelloService helloService =(HelloService)context.getService(helloServiceReference); System.out.println(helloService.sayHello()); } public void stop(BundleContext context) throws Exception { System.out.println("Goodbye World!!"); context.ungetService(helloServiceReference); } } 14
  • 15.
    Angst? • Neuer Infrastrukturcode • Komplex! • Fehleranfällig! • Achtung: lookup eines Objekts führt zu einer direkten Referenz des Objektes! • Bei undeploy des Impl Bundles muss die Referenz freigegeben werden! • Resourceleaks! • Was wenn sich Abhängigkeiten ändern? • Services sollten nicht manuell referenziert werden • Service Tracker wird empfohlen - noch komplexer! • Und sieht so die Zukunft aus? 15
  • 16.
    OSGi Enterprise • Webapps •Business Components • Transaction manager • Datasources • Configurations 16
  • 17.
    Business Web Application Services Enterprice Infrastructure Web Container ORM Transaction MGR Datasource MGR OSGi Platform 17
  • 18.
  • 19.
    Bundle Application Context • Bundle META-INF/spring enthält Konfiguration • oder Manifest enthält „Spring-Context: xyz.xml“ declaration • Es werden alle XML Dateien gelesen • Ein OSGi Application Context wird erstellt • Durch Spring DM Extender ist kein BundleActivator notwendig • ApplicationContexte sind über die OSGi ServiceRegistry zugreifbar 19
  • 20.
    OSGi Services ala Spring • Import: <osgi:reference id="messageService" interface="com.xyz.MessageService"/> • Export: <osgi:service ref="beanToBeExported" interface="com.xyz.MessageService"/> 20
  • 21.
    OSGi Registry lauschen! • Es existieren Listener Provider und Consumer Seite • Damit lassen sich sehr elegant Services überwachen <reference id="someService" interface="com.xyz.MessageService"> <listener bind-method="onBind" unbind-method="onUnbind"> <beans:bean class="MyCustomListener"/> </listener> </reference> <service ref="beanToBeExported" interface="SomeInterface"> <registration-listener ref="myListener" registration-method="serviceRegistered" unregistration-method="serviceUnregistered"/> </service> 21
  • 22.
    Applikation in OSGi Service • Ausschließlich Web Registry Abhängigkeiten auf API • Änderung der Model/API Implementierung Möglich • zur Laufzeit! Service Implementation • Infrastruktur ist nur eine andere Art von Service Infrastructure 22
  • 23.
    OSGi Applikationen mit Spring • Es sind immer noch POJOs! • Keine Platform- und Codeabhängigkeit zu OSGi • Keine Codeänderung notwendig • Apps sind auch noch in JEE lauffähig • Best Pactice: 2 Spring Konfigurationen • Applikations Konfiguration • OSGi Konfiguration (Service Import/Export) 23
  • 24.
    Webapp Unterstützung • Servlet Container weden selbst als Bundle deployed • Wie werden WAR Bundles im Webcontainer deployed? • OSGi sieht hier nichts vor! • Spring hält Web OSGi Bundles bereit • Deployment via Spring OSGi Web Extender • Tomcat und Jetty werden unterstützt 24
  • 25.
    Schlechte Gewohnheiten? • Class.forName • Thread ContextClassloader • Das Verhalten ist in OSGi undefiniert! • Spring DM kann den TCC managen! • Probleme mit statischen Variablen • Suche in Jars • TLD´s, Facelet Tags • OSGi Service als Observable 25
  • 26.
    Kompatibilität zu Enterprise Libs • Viele der Bibliotheken sind nicht für OSGi entwickelt • OSGi import und export fehlen im Manifest! • Classloading Probleme • Verwendung von ContextClassloader • META-INF resources • Sichtbarkeit von Klassen • Packaging Fehler 26
  • 27.
    Beliebte Frameworks • Spring 2.5 + • Jetty + • Tomcat 5 + • Tomcat 6 (kein JSP) • Hibernate/JPA (+) • JSP (+) • JSF Myfaces (+) • Apache Commons + • Log4J 27
  • 28.
    Spring Enterprise Repository • Enthält viele migrierte Bundles aus dem Maven Central Repository • Leider sind es nicht immer die aktuellsten • Es ist nicht garantiert dass die Libs auch funktionieren • http://www.springsource.com/repository/ app/ 28
  • 29.
    Was fehlt nochzu JEE? EJB/Web Container Spring DM Webapps + + Services/EJBs + + Modulsystem / + Kommunikation zwischen Modulen / (Serialisiert) + Remoting + / (WebServices) Reife der Technologie + - Security + / (Spring Security) 29
  • 30.
  • 31.
  • 32.
    Begriffswirrwarr • Spring Dynamic Modules = Spring für OSGI • Application Context per Bundle • Webapp Unterstützung • License: Apache • SpringSource DM Server • neuer Typ: „Applikation“ (OSGi kennt nur Bundles) • Distribution von OSGi Bundles und Scripten • Diagnose & Monitoring (Kommerziell) • Lizenz: GPL und Kommerziell 32
  • 33.
    Features • Vorinstallierte OSGiStandard Bundles • PAR Package - Application Deployment • Isolation • Deployment Plan als XML • Diagnose & Monitoring (Kommerziell) 33
  • 34.
    Technologien • Spring Framework •Tomcat • OSGi R4.1 • Equinox als OSGi Implementierung • Spring Dynamic Modules 34
  • 35.
  • 36.
    WAR Deployment Types • Standard WAR mit Libraries • Shared Libraries WAR • Shared Services WAR 36
  • 37.
    PAR • OSGi kennkeine Applikation • dadurch schwammige Grenzen • Versionierung über Bundles hinweg • (re)deploy als Einheit • Verbergen von internas • Services • Bundles 37
  • 38.
    PAR Web Business Model Application Services Enterprice Infrastructure Web Container ORM Transaction MGR Datasource MGR OSGi Platform 38
  • 39.
    Plans • Beschreibt diezu deployenden Bundles • Wie ein PAR jedoch werden die Bundles referenziert • Effizenter da weniger IO <plan name="com.springsource.server.admin.plan" version="2.0.0" scoped="true" atomic="true" xmlns="http://www.springsource.org/schema/dm-server/plan" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springsource.org/schema/dm-server/plan http://www.springsource.org/schema/dm-server/plan/springsource-dm-server- plan.xsd"> <artifact type="bundle" name="com.springsource.server.admin.state" version="[2.0,2.5)"/> <artifact type="bundle" name="com.springsource.server.admin.content" version="[2.0,2.5)"/> <artifact type="bundle" name="com.springsource.server.admin.web" version="[2.0,2.5)"/> </plan> 39
  • 40.
    Import Hölle • ImportLibrary • Hibernate • Spring • JSF • Import Bundle 40
  • 41.
    Hibernate CNF Probleme • Problem Lazy Loding • Domain Model Bytecode Enhancement • Unsichtbare Abhängigkeit Model -> Hibernate entsteht • Lösung 1: Import-Package • Ungewollte Abhängigkeit • Lösung 2: import-scope:=application • Angabe den direkten Hibernate Abhängigkeiten 41
  • 42.
    Licht und Schatten • OSGi ist zweifelsohne ein Fortschritt und in vielen Dingen bestehenden Komponenten Technologien wie EJB überlegen • Spring integriert sich hervorragend in die OSGi Platform und ist eine Bereicherung das bereits viele Enterprise Probleme gelöst sind • Leider verderben nicht OSGi konforme Libraries immer wieder den Spaß durch Classloading Probleme • Im Enterprise Bereich kann man leider noch nicht von „straight forward“ Entwicklung sprechen, hier gibt es noch viele Detail Probleme 42
  • 43.
    Resourcen • www.spring-buch.de/Beispiele/readme.html • http://www.javaworld.com/javaworld/ jw-04-2008/jw-04-osgi2.html • http://www.javaworld.com/javaworld/ jw-03-2008/jw-03-osgi1.html • http://springosgi.googlepages.com/ 43
  • 44.

Hinweis der Redaktion