Apache ServiceMix – wprowadzenie
Apache ServiceMix – wprowadzenie
Apache ServiceMix to narzędzie które realizuje zadania korporacyjnej szyny danych czyli integracji różnorodnych systemów informatycznych w architekturze SOA (architektura zorientowana na usługi). Zastosowanie rozwiązania szyny ESB pozwala na wiązanie aplikacji za pomocą jednej centralnej magistrali dzięki czemu nie jest konieczne integrowanie aplikacji na zasadzie każdy z każdym.
Pobranie Apache ServiceMix:
http://servicemix.apache.org/downloads.html
Po pobraniu paczki *.zip i rozpakowaniu wydajemy polecenie uruchomienia Apache ServiceMix:
w katalogu .\bin wydajmy dla systemu Windows polecenie:
\apache-servicemix-7.1.0-SNAPSHOT\bin>servicemix.bat
Apache ServiceMix został uruchomiony!
Tworzymy plik XML o dowolnej nazwie i zapisujemy go w katalogu ./deploy. Katalog ten znajduje się w lokalizacji gdzie została rozpakowana paczka z oprogramowaniem:
<?xml version="1.0" encoding="UTF-8"?> <blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.osgi.org/xmlns/blueprint/v1.0.0 http://www.osgi.org/xmlns/blueprint/v1.0.0/blueprint.xsd"> <camelContext xmlns="http://camel.apache.org/schema/blueprint"> <route> <from uri="file:camel/input"/> <log message="Moving ${file:name} to the output directory"/> <to uri="file:camel/output"/> </route> </camelContext> </blueprint>
Teraz każde dodanie dowolnego pliku do katalogu ./camel/input spowoduje natychmiastowe przeniesienie go do katalogu ./camel/output:
Zobaczmy ostatnie logi:
jenkins@root>log:display | tail -n 10
wynik:
INFO | le://camel/input | route6 | 43 - org.apache.camel.camel-core - 2.16.5 | Moving 20190904_094420.jpg to the output directory
Dodajmy teraz wysłanie komunikatu do kolejki ActiveMQ w momencie dodania dowolnego pliku do katalogu activemq/input. Każdorazowe dodanie nowego pliku spowoduje natychmiastowe przeniesienie go do katalogu ./activemq/output.
<?xml version="1.0" encoding="UTF-8"?> <blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.osgi.org/xmlns/blueprint/v1.0.0 http://www.osgi.org/xmlns/blueprint/v1.0.0/blueprint.xsd"> <camelContext xmlns="http://camel.apache.org/schema/blueprint"> <route> <from uri="file:camel/input"/> <log message="Moving ${file:name} to the output directory"/> <to uri="file:camel/output"/> </route> <route> <from uri="file:activemq/input"/> <to uri="file:activemq/output"/> <setBody><simple>FileMovedEvent(file: ${file:name}, timestamp: ${date:now:hh:MM:ss.SSS}) </simple> </setBody> <to uri="activemq://events"/> </route> <route> <from uri="activemq://events"/><to uri="log:events"/> </route> </camelContext> </blueprint>
Zobaczmy ostatnie logi:
jenkins@root>log:display | tail -n 10
wynik:
INFO | Consumer[events] | events | 43 - org.apache.camel.camel-core - 2.16.5 | Exchange[ExchangePattern: InOnly, BodyType: String, Body: FileMovedEvent(file: 20190904_094420.jpg, timestamp: 11:12:38.772)]
Instalacja graficznej konsoli:
jenkins@root>feature:install webconsole jenkins@root>feature:list | grep webconsole webconsole | 4.0.9 | x | Started | standard-4.0.9 | Base support of the Karaf WebConsole
Konsola dostępna jest pod adresem:
http://localhost:8181/system/console
login: smx
haslo: smx
Wydajmy teraz polecenie które wyświetli id zainstalowanych paczek:
202 | Active | 50 | 0.6.4 | JAXB2 Basics - Runtime 215 | Active | 50 | 2.11.0.v20140415-163722-cac6383e66 | Scala Standard Library 223 | Active | 80 | 0.0.0 | test.xml jenkins@root>bundle:list
zatrzymanie działania paczki o id 223:
jenkins@root>bundle:stop 223 jenkins@root>
ponowne wznowienie działania paczki:
jenkins@root>bundle:start223 jenkins@root>
Moduły OSGi (bundle z ang. Open Services Gateway Initiative) to system dynamicznych modułów dla języka Java które uruchamiane są w kontenerach wpierających OSGi. Do kontenerów tych zaliczyć możemy np. Apache Felix czy Apache Karaf. Projektowanie aplikacji modularnych daje możliwość dynamicznego odłączania i przyłączania nowych modułów bez konieczności restartu całej aplikacji. Spring Dynamic Modules natomiast łączy technologię Spring z platformą OSGi. Przed Javą w wersji 9 nie było pojęcia modułu. Brakowało określenia tego czym jest moduł.
To co oferuje technologia OSGi to lekką platformę dla komponentowych, oraz zorientowanych na usługi aplikacji w ramach (JVM). OSGi zapewnia pełną izolację modułów, dzięki czemu mamy pewność, że nie będą one wpływały na siebie nawzajem (np. poprzez konflikty wersji zależnych bibliotek JAR).
Plik manifestu OSGi – OSGi bundles to zwykłe pliki *.jar, z dodatkowymi wpisami w manifeście:
Bundle-SymbolicName: osgi-example Bundle-Version: 1.0.0.SNAPSHOT Import-Package: pl.javaleader;version="1.0.0.SNAPSHOT",org.osgi.framework Export-Package: pl.javaleader;version="1.0.0.SNAPSHOT" Bundle-Activator: pl.javaleader.Activator
- Bundle-Version – wersja modułu,
- Bundle-SymbolicName – nazwa modułu, pod którą będzie widziany z innych modułów,
- Bundle-Activator – klasa aktywatora modułu, czyli z jakiej klasy należy skorzystać przy uruchamianiu i zatrzymywaniu modułu,
- Import-Package – pakiety które chcemy zaimportować do naszego bundle’a. Możliwe jest importowanie pakietów z innych modułów,
- Export-Package – jakie pakiety modułu chcemy wyeksportować. Tylko wyeksportowane pakiety mogą być importowane przez inne moduły.
Tworzymy nowy projekt z użyciem Apache Maven (bez archetypu) a następnie umieszczamy w odpowiednim katalogu plik ./resources/META-INF/MANIFEST.MF z zawartością opisaną powyżej.
Zawartość pliku pom.xml:
<dependencies> <dependency> <groupId>org.osgi</groupId> <artifactId>osgi_R4_core</artifactId> <version>1.0</version> <scope>provided</scope> <optional>true</optional> </dependency> <dependency> <groupId>org.osgi</groupId> <artifactId>osgi_R4_compendium</artifactId> <version>1.0</version> <scope>provided</scope> <optional>true</optional> </dependency> <dependency> <groupId>org.apache.cxf</groupId> <artifactId>cxf-rt-bindings-soap</artifactId> <version>3.1.0</version> </dependency> <dependency> <groupId>javax</groupId> <artifactId>javaee-api</artifactId> <version>7.0</version> </dependency> <dependency> <groupId>org.osgi</groupId> <artifactId>org.osgi.core</artifactId> <version>5.0.0</version> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-jar-plugin</artifactId> <configuration> <archive> <manifestFile>src/main/resources/META-INF/MANIFEST.MF</manifestFile> </archive> </configuration> </plugin> </plugins> </build>
tworzymy przykładowe klasy serwisowe które będą dostępne po protokole SOAP:
serwis:
import javax.jws.WebMethod; import javax.jws.WebService; @WebService public interface Calculator { @WebMethod() int add(int a, int b); @WebMethod() int sub(int a, int b); }
implementacja serwisu:
public class CalculatorImpl implements Calculator { public int add(int a, int b) { return a + b; } public int sub(int a, int b) { return a - b; } }
wystawiamy przykładowy endpoint – plik ./resources/META-INF/spring/beans.xml:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:jaxws="http://cxf.apache.org/jaxws" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd"> <jaxws:endpoint id = "calcService" implementor = "pl.javaleader.ws.CalculatorImpl" address = "/calcService"/> </beans>
instalujemy komponent w środowisku Apache ServiceMix:
install mvn:pl.javaleader/javaleader-calc-osgi/1.0.0-SNAPSHOT
startujemy aplikację:
start 297
wynik – aplikacja wystartowała – moduł prawidłowo zainstalowany!
jenkins@root>start 245 STARTING: JavaLeader.pl jenkins@root>
zobaczmy plik *.wsdl opisujący utworzony WebService!
http://localhost:8181/cxf/calcService?wsdl
Wykonajmy operację na bazie pliku *.wsdl opisującego nasze usługi. W tym celu należy zainstalować program SoapUI – https://www.soapui.org/.
Tworzymy nowy projekt SOAP:
Wykonujemy przykładowe zapytanie (z ang. request):
Leave a comment