<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Splatch's devblog &#187; Apache</title>
	<atom:link href="http://blog.dywicki.pl/category/apache/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.dywicki.pl</link>
	<description>Pragmatyzm kontrolowany</description>
	<lastBuildDate>Fri, 05 Jun 2009 14:30:15 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=abc</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Jeśli coś nie jest komercyjne nie jest też profesjonalne</title>
		<link>http://blog.dywicki.pl/2008/11/19/jesli-cos-nie-jest-komercyjne-nie-jest-tez-profesjonalne/</link>
		<comments>http://blog.dywicki.pl/2008/11/19/jesli-cos-nie-jest-komercyjne-nie-jest-tez-profesjonalne/#comments</comments>
		<pubDate>Wed, 19 Nov 2008 09:22:43 +0000</pubDate>
		<dc:creator>Łukasz Dywicki</dc:creator>
				<category><![CDATA[Inne]]></category>
		<category><![CDATA[ServiceMix]]></category>
		<category><![CDATA[Śmieci]]></category>

		<guid isPermaLink="false">http://blog.dywicki.pl/?p=232</guid>
		<description><![CDATA[Ostatnimi czasy odbyłem kilka spotkań w większych i mniejszych firmach. To co mnie zastanowiło po jednej z ostatniej rozmów to zdanie:
Korzystamy z profesjonalnych narzędzi takich jak Tibco, WebMethods, czasami Bea.
Co łączy wymienione produkty? Otóż wszystkie są rozwiązaniami z klasy EAI i &#8230; są płatne. Zdanie to usłyszałem w odniesieniu do Apache Service Mix, którym się [...]]]></description>
			<content:encoded><![CDATA[<p>Ostatnimi czasy odbyłem kilka spotkań w większych i mniejszych firmach. To co mnie zastanowiło po jednej z ostatniej rozmów to zdanie:</p>
<blockquote><p>Korzystamy z profesjonalnych narzędzi takich jak <a href="http://www.tibco.com/">Tibco</a>, <a href="http://www.softwareag.com/Corporate/products/wm/default.asp">WebMethods</a>, czasami <a href="http://www.bea.com/framework.jsp?CNT=index.htm&#038;FP=/content/products/aqualogic/service_bus/">Bea</a>.</p></blockquote>
<p>Co łączy wymienione produkty? Otóż wszystkie są rozwiązaniami z klasy EAI i &#8230; są płatne. Zdanie to usłyszałem w odniesieniu do <a href="http://servicemix.apache.org">Apache Service Mix</a>, którym się interesuję. Wniosek z tej wypowiedzi jaki udało mi się wysnuć od razu stał się tematem tej noty, czyli jeśli coś nie jest komercyjne nie jest też profesjonalne. Tak jakby <acronym title="Open Source Software">OSS</acronym> był gorszym rozwiązaniem od kupienia licencji na pudełkowe rozwiązanie od jakiegoś producenta.</p>
<p>Trudno mi się z tym zgodzić ponieważ od początku swojej pracy obracam się w otwartym kodzie i niejeden raz korzystałem z wolnodostępnych narzędzi. Pamiętam jedną z sytuacji, gdzie w jednej z bardzo dużych międzynarodowych firm projekt przez pracowników był uważany za profesjonalny ponieważ był kupiony Oracle oraz licencja na jakiś przestarzały serwer. Kuriozalne, im więcej wydasz pieniędzy na licencję tym bardziej projekt jest profesjonalny. Klient dopiero wydając masę pieniędzy na licencję ma prawo powiedzieć, że kupił profesjonalny, będący na wysokim poziomie, produkt.</p>
<p>Zainspirowany tym wszystkim sięgnąłem do <a href="http://sjp.pwn.pl/">słownika języka polskiego PWN</a> w poszukiwania hasła <a href="http://sjp.pwn.pl/haslo.php?id=2508549">profesjonalny</a>:</p>
<blockquote><p>profesjonalny<br />
1. będący specjalistą w jakiejś dziedzinie<br />
2. uprawiany jako zawód<br />
3. będący na wysokim poziomie w danej dziedzinie<br />
4. spełniający wymagania profesjonalistów
</p></blockquote>
<p>Definicja słownikowa nie wspomina nic o pieniądzach, ale dodajmy ją w myśl pierwszego, zacytowanego zdania:<br />
1. Jeśli chcesz być specjalistą w jakiejś dziedzinie musisz korzystać z komercyjnych rozwiązań.<br />
3. Wysoki poziom w danej dziedzinie osiągniesz korzystając tylko z komercyjnych produktów.<br />
4. Produkt jest profesjonalny jeśli spełnia wymagania profesjonalistów, a jednym z kryteriów doboru tego narzędzia zgodnie z punktem 1 jest płatność.</p>
<p>Czy zgadzacie się z takimi założeniami? Ja &#8211; w ogóle. Nie jestem maniakiem Open Source ani fanatykiem wolnego oprogramowania. Nie jestem też nadmiernym zwolennikiem komercyjnych rozwiązań, ale to co powinno być kluczowe dla każdego programisty a tym bardziej firmy świadczącej usługi programistyczne to szukanie skutecznego rozwiązania problemu a nie wydania pieniędzy.</p>
<p>Reasumując, moje zdanie to:</p>
<ul>
<li>Nie wszędzie pasuje <acronym title="Open Source Software">OSS</acronym>.</li>
<li>Nie wszędzie konieczne są rozwiązania komercyjne.</li>
<li>Nie zawsze nabycie produktu rozwiązuje wszystkie problemy. Czasami rodzi też nowe.</li>
</ul>
<p>Warto zwrócić uwagę na to, że producenci oprogramowania czasami mamią i zarzucają nas całą masą marketingu, hasłami i wszelakimi buzzworld typu <acronym title="Service Oriented Architecture">SOA</acronym>, <acronym title="Asynchronous JavaScript and XML">AJAX</acronym> itp. podczas gdy rozwiązania oparte na <acronym title="Open Source Software">OSS</acronym> nie są reklamowane, a zdarza się sytuacje że mają funkcjonalność zbliżoną bądź nawet większą niż komercyjne.</p>
<p>Jakie jest, drodzy czytelnicy, wasze zdanie na temat &#8211; czy <acronym title="Open Source Software">OSS</acronym> może być profesjonalny? Co czyni produkt profesjonalnym?</p>]]></content:encoded>
			<wfw:commentRss>http://blog.dywicki.pl/2008/11/19/jesli-cos-nie-jest-komercyjne-nie-jest-tez-profesjonalne/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Log4j, przejrzyste komunikaty</title>
		<link>http://blog.dywicki.pl/2008/10/15/log4j-przejrzyste-komunikaty/</link>
		<comments>http://blog.dywicki.pl/2008/10/15/log4j-przejrzyste-komunikaty/#comments</comments>
		<pubDate>Wed, 15 Oct 2008 08:00:10 +0000</pubDate>
		<dc:creator>Łukasz Dywicki</dc:creator>
				<category><![CDATA[Framework]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[log4j]]></category>

		<guid isPermaLink="false">http://blog.dywicki.pl/?p=229</guid>
		<description><![CDATA[Log4j jest najpopularniejszą biblioteką do logowania dla Javy. Została ona wydana już jakiś czas temu i w chwili obecnej rozwija się znacznie wolniej niż kiedyś, warto jednak nadmienić że społeczność wciąż dostarcza nowych możliwości. Może najpierw o samej strukturze log4j.
Najważniejsze elementy
Log4j ma kilka składowych:

Appender
Layout
Category

Dzisiaj skupię się tylko na dwóch pierwszych. Appender jest odpowiedzialny za zapis [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://logging.apache.org/log4j/">Log4j</a> jest najpopularniejszą biblioteką do logowania dla Javy. Została ona wydana już jakiś czas temu i w chwili obecnej rozwija się znacznie wolniej niż kiedyś, warto jednak nadmienić że społeczność wciąż dostarcza nowych możliwości. Może najpierw o samej strukturze log4j.</p>
<h2>Najważniejsze elementy</h2>
<p>Log4j ma kilka składowych:</p>
<ul>
<li>Appender</li>
<li>Layout</li>
<li>Category</li>
</ul>
<p>Dzisiaj skupię się tylko na dwóch pierwszych. Appender jest odpowiedzialny za zapis bądź wysyłanie komunikatów do wybranego miejsca podczas gdy Layout konwertuje wpis do określonego formatu.</p>
<p>Z najciekawszych Appenderów wymienię</p>
<ul>
<li><a href="http://logging.apache.org/log4j/1.2/apidocs/org/apache/log4j/RollingFileAppender.html">RollingFileAppender</a> rotuje logi do określonego rozmiaru, po osiągnięciu np 10mb kopiuje stary plik zgodnie ze schematem i zaczyna zapisywać do nowego.</li>
<li><a href="http://logging.apache.org/log4j/1.2/apidocs/org/apache/log4j/DailyRollingFileAppender.html">DailyRollingFileAppender</a> zachowuje się podobnie jak wyżej wymieniony z tym, że umożliwia zapis z podziałem na lata, miesiące, dni czy nawet minuty.</li>
<li><a href="http://logging.apache.org/log4j/1.2/apidocs/org/apache/log4j/net/SyslogAppender.html">SyslogAppender</a>, który wysyła komunikaty do <a href="http://pl.wikipedia.org/wiki/Syslog">Sysloga</a></li>
<li><a href="http://logging.apache.org/log4j/1.2/apidocs/org/apache/log4j/lf5/LF5Appender.html">LF5Appender</a> wyświetlający logi w okienku tworzonym przy pomocy Swinga.
<li><a href="http://logging.apache.org/log4j/1.2/apidocs/org/apache/log4j/net/SMTPAppender.html">SMTPAppender</a> wysyłający maile z komunikatami. Jeśli się go źle skonfiguruje gwarantowane zapchanie skrzynki ;-)</li>
<li><a href="http://sourceforge.net/projects/nagiosappender/">NagiosAppender</a> przesyłający komunikaty do <a href="http://www.nagios.org/">Nagiosa</a>, narzędzia służącego do monitorowania.</li>
</ul>
<p>Mając już appender, który wie gdzie zapisywać wypada powiedzieć Log4j też <b>co powinien zapisywać</b>.</p>
<ul>
<li><a href="http://logging.apache.org/log4j/1.2/apidocs/org/apache/log4j/HTMLLayout.html">HTMLLayout</a> produkujący tabelę <acronym title="HyperText Markup Language">HTML</acronym></li>
<li><a href="http://logging.apache.org/log4j/1.2/apidocs/org/apache/log4j/PatternLayout.html">PatternLayout</a> posiadający możliwość określenia &#8220;szablonu&#8221; wpisu.</li>
</ul>
<p>Więcej Layoutów można znaleźć w <a href="http://logging.apache.org/log4j/1.2/apidocs/org/apache/log4j/Layout.html">Javadocu Log4j</a>.</p>
<p>Jako, że zdecydowanie najczęściej używa się PatternLayout dodam parę słów na temat tego co potrafi. We wzorze który będzie później użyty do stworzenia komunikatu możemy używać następujących wyrażeń:</p>
<ul>
<li><b>%c</b> kategoria zdarzenia</li>
<li><b>%C</b> nazwa klasy z której zostało wysłane zdarzenie</li>
<li><b>%d</b> data zdarzenia (przykład: %d{HH:mm:ss,SSS} )</li>
<li><b>%m</b> komunikat wysłany z aplikacji</li>
<li><b>%n</b> separator lini</li>
<li><b>%p</b> priorytet zdarzenia</li>
<li><b>%r</b> ilość milisekund, które zdążyły upłynąć od startu aplikacji</li>
<li><b>%t</b> nazwa wątku z którego zostało wysłane zdarzenie</li>
<li><b>%x</b> kontekst diagnostyczny powiązany z wątkiem (wie ktokolwiek co to znaczy?)</li>
<li><b>%%</b> pojedynczy znak %</li>
<li><b>%M</b> nazwa metody z której zostało wysłane zdarzenie (uwaga, bardzo wolne)</li>
<li><b>%L</b> numer linii z której zdarzenie pochodzi (uwaga, bardzo wolne)</li>
<li><b>%F</b> nazwa pliku z którego pochodzi zdarzenie (uwaga, bardzo wolne)</li>
<li><b>%l</b> informacja o wywołującym zdarzenie (uwaga, bardzo wolne, wskazuje na lokalizację z naszego kodu)</li>
</ul>
<p>Przykłady modyfikatorów:</p>
<ul>
<li><b>%20c</b> dodaje spacje z lewej strony jeśli nazwa kategorii jest krótsza niż 20 znaków</li>
<li><b>%-20c</b> dodaje spacje z prawej strony jeśli nazwa kategorii jest krótsza niż 20 znaków</li>
<li><b>%.30c</b> przycina kategorię pozostawiając ostatnie 30 znaków</li>
<li><b>%20.30c</b> wypełnia z lewej strony nazwę kategorię spacjami do 20 znaków oraz przycina początkowe znaki jeżeli jest dłuższa on 30 znaków</li>
<li><b>%-20.30c</b> analogicznie jak wyżej, z tym że znaki zostaną dodane z prawej strony. Ze swojej strony polecam używanie formatu np %-20.20, co zagwarantuje że element będzie miał zawsze 20 znaków. Jeśli pozostawimy <b>-20.30</b> to element będzie miał 20 znaków jeśli kategoria jest zbyt krótka a 30 gdy będzie za długa</li>
</ul>
<h2>Przykład konfiguracji</h2>
<p>Log4j można konfigurować na kilka sposobów. Programowo, przez plik properties oraz konfigurację <acronym title="eXtensible Markup Language">XML</acronym>. Zdecydowanie najpopularniejszy jest plik properties. Jego użycie jest banalnie proste. Włączamy log4j.jar do tak by był on dostępny w classpathu, a następnie tworzymy plik <em>log4j.properties</em>, który domyślnie jest poszukiwany przez bibliotekę jeśli nie została przekazana żadna konfiguracja. Aby jednak to się stało nasz kod musi spróbować wysłać jakąś wiadomość do Log4j.</p>
<p>log4j.rootLogger DEBUG, out</p>
<p># loggery<br />
log4j.logger.org.springframework INFO<br />
log4j.logger.org.apache.activemq INFO<br />
log4j.logger.org.apache.activemq.spring WARN<br />
log4j.logger.org.apache.servicemix DEBUG, stdout</p>
<p>#appendery<br />
log4j.appender.stdout org.apache.log4j.ConsoleAppender<br />
log4j.appender.stdout.layout org.apache.log4j.PatternLayout<br />
log4j.appender.stdout.layout.ConversionPattern %d{ABSOLUTE} | %-5p | %t | %c | %m%n</p>
<p>log4j.appender.out org.apache.log4j.DailyRollingFileAppender<br />
log4j.appender.out.DatePattern &#8216;-&#8217;yyyy-MM-dd&#8217;.log&#8217;&#8221;/><br />
log4j.appender.out.layout org.apache.log4j.PatternLayout<br />
log4j.appender.out.layout.ConversionPattern %d{ABSOLUTE} | %-5p | %t | %c | %m%n<br />
log4j.appender.out.file E:/fuse-esb/data/log/servicemix</p>
<p>Założenie powyższej konfiguracji jest następujące. Domyślny poziom logowania jest ustawiony na <em>DEBUG</em> a komunikaty są zapisywane do pliku (rootLogger). Zdefiniowane są dwa appendery <em>stdout</em> oraz <em>out</em>. Pierwszy jest użyty tylko dla paczki <em>org.apache.servicemix</em>. Pozostałe loggery mają określony tylko poziom logowania. Pliki z logami będą dzielone na dni, także w lokalizacji <em>E:/fuse-esb/data/log/</em> po 3 dniach działania od 13 do 15 października będziemy mieli 3 pliki:</p>
<ul>
<li>servicemix &#8211; logi z bierzącego dnia</li>
<li>servicemix-2008.10.14.log &#8211; logi z 14 października</li>
<li>servicemix-2008.10.13.log &#8211; logi z 13 października</li>
</ul>
<p>Mam nadzieję że od dzisiaj Log4j będzie Wam drodzy czytelnicy mówił więcej i prościej. Jeśli są jakieś kwestie które pozostają niewyjaśnione &#8211; proszę pytać.</p>]]></content:encoded>
			<wfw:commentRss>http://blog.dywicki.pl/2008/10/15/log4j-przejrzyste-komunikaty/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Budowanie klienta usługi sieciowej w oparciu o Apache CXF</title>
		<link>http://blog.dywicki.pl/2008/09/03/budowanie-klienta-uslugi-sieciowej-w-oparciu-o-apache-cxf/</link>
		<comments>http://blog.dywicki.pl/2008/09/03/budowanie-klienta-uslugi-sieciowej-w-oparciu-o-apache-cxf/#comments</comments>
		<pubDate>Wed, 03 Sep 2008 07:28:27 +0000</pubDate>
		<dc:creator>Łukasz Dywicki</dc:creator>
				<category><![CDATA[CXF]]></category>
		<category><![CDATA[Framework]]></category>
		<category><![CDATA[Java]]></category>

		<guid isPermaLink="false">http://blog.dywicki.pl/?p=223</guid>
		<description><![CDATA[W nawiązaniu do poprzedniej noty o CXFie, którą napisałem jakiś czas temu, gonię aby uzupełnić brak konfiguracji klienta. Sam proces jest bardzo zbliżony do tworzenia klienta w oparciu o XFire. Nie jest wymagana duża ilość kodu Javy, a w zasadzie tylko dwa pliki XML (client.xml, myservice.xml).
Pierwszy z nich odpowiada za wczytanie wymaganych rozszerzeń CXFa oraz [...]]]></description>
			<content:encoded><![CDATA[<p>W nawiązaniu do <a href="http://blog.dywicki.pl/2008/07/23/budowanie-uslugi-sieciowej-w-oparciu-o-apache-cxf/">poprzedniej noty o CXFie</a>, którą napisałem jakiś czas temu, gonię aby uzupełnić brak konfiguracji klienta. Sam proces jest bardzo zbliżony do tworzenia klienta w oparciu o XFire. Nie jest wymagana duża ilość kodu Javy, a w zasadzie tylko dwa pliki <acronym title="eXtensible Markup Language">XML</acronym> (client.xml, <em>myservice.xml</em>).</p>
<p>Pierwszy z nich odpowiada za wczytanie wymaganych rozszerzeń CXFa oraz definicję bazowej konfiguracji fabryki z interceptorami. W interceptorach możemy skonfigurować logowanie, obsługę załączników czy standardów WS-Security etc. Wszystkie te ustawienia będą dziedziczone, a fabryki docelowych usług będą dodawać tylko adres, do odpytywania. Na koniec bean klienta będzie miał określony <strong>autowire</strong> by nie przekazywać mu wszystkich własności.<br />
<span id="more-223"></span></p>
<p>Oto najważniejsze wstawki kodu oraz ich opis:</p>
<pre class="brush: xml;">&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
&lt;project xmlns=&quot;http://maven.apache.org/POM/4.0.0&quot; xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot;
    xsi:schemaLocation=&quot;http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd&quot;&gt;
    &lt;parent&gt;
        &lt;groupId&gt;org.code-house.cxf&lt;/groupId&gt;
        &lt;artifactId&gt;parent&lt;/artifactId&gt;
        &lt;version&gt;1.0-SNAPSHOT&lt;/version&gt;
    &lt;/parent&gt;

    &lt;modelVersion&gt;4.0.0&lt;/modelVersion&gt;
    &lt;groupId&gt;org.code-house.cxf&lt;/groupId&gt;
    &lt;artifactId&gt;client&lt;/artifactId&gt;
    &lt;version&gt;1.0-SNAPSHOT&lt;/version&gt;

    &lt;name&gt;Code House.Org - CXF - Client&lt;/name&gt;

    &lt;dependencies&gt;
        &lt;dependency&gt;
            &lt;groupId&gt;log4j&lt;/groupId&gt;
            &lt;artifactId&gt;log4j&lt;/artifactId&gt;
            &lt;version&gt;1.2.12&lt;/version&gt;
        &lt;/dependency&gt;
        &lt;dependency&gt;
            &lt;groupId&gt;org.code-house.cxf&lt;/groupId&gt;
            &lt;artifactId&gt;contract&lt;/artifactId&gt;
            &lt;version&gt;1.0-SNAPSHOT&lt;/version&gt;
        &lt;/dependency&gt;
        &lt;dependency&gt;
            &lt;groupId&gt;org.apache.cxf&lt;/groupId&gt;
            &lt;artifactId&gt;cxf-rt-frontend-jaxws&lt;/artifactId&gt;
        &lt;/dependency&gt;
        &lt;dependency&gt;
            &lt;groupId&gt;org.apache.cxf&lt;/groupId&gt;
            &lt;artifactId&gt;cxf-rt-transports-http&lt;/artifactId&gt;
        &lt;/dependency&gt;
        &lt;dependency&gt;
            &lt;groupId&gt;org.apache.cxf&lt;/groupId&gt;
            &lt;artifactId&gt;cxf-rt-transports-http-jetty&lt;/artifactId&gt;
            &lt;version&gt;${code-house.cxf.version}&lt;/version&gt;
        &lt;/dependency&gt;

        &lt;dependency&gt;
            &lt;groupId&gt;org.springframework&lt;/groupId&gt;
            &lt;artifactId&gt;spring-core&lt;/artifactId&gt;
            &lt;version&gt;${code-house.spring.version}&lt;/version&gt;
        &lt;/dependency&gt;
        &lt;dependency&gt;
            &lt;groupId&gt;org.springframework&lt;/groupId&gt;
            &lt;artifactId&gt;spring-test&lt;/artifactId&gt;
            &lt;version&gt;${code-house.spring.version}&lt;/version&gt;
            &lt;scope&gt;test&lt;/scope&gt;
        &lt;/dependency&gt;
    &lt;/dependencies&gt;

    &lt;dependencyManagement&gt;
        &lt;dependencies&gt;
            &lt;dependency&gt;
                &lt;groupId&gt;org.springframework&lt;/groupId&gt;
                &lt;artifactId&gt;spring-beans&lt;/artifactId&gt;
                &lt;version&gt;${code-house.spring.version}&lt;/version&gt;
            &lt;/dependency&gt;
            &lt;dependency&gt;
                &lt;groupId&gt;org.springframework&lt;/groupId&gt;
                &lt;artifactId&gt;spring-core&lt;/artifactId&gt;
                &lt;version&gt;${code-house.spring.version}&lt;/version&gt;
            &lt;/dependency&gt;
            &lt;dependency&gt;
                &lt;groupId&gt;org.springframework&lt;/groupId&gt;
                &lt;artifactId&gt;spring-context&lt;/artifactId&gt;
                &lt;version&gt;${code-house.spring.version}&lt;/version&gt;
            &lt;/dependency&gt;
        &lt;/dependencies&gt;
    &lt;/dependencyManagement&gt;

&lt;/project&gt;</pre>
<p>Deskryptor nie jest zbyt złożony, istotny jest tylko kawałek z kontraktem, który jak wskazuje nazwa jest definicją używanych typów:</p>
<pre class="brush: xml;">&lt;dependency&gt;
    &lt;groupId&gt;org.code-house.cxf&lt;/groupId&gt;
    &lt;artifactId&gt;contract&lt;/artifactId&gt;
    &lt;version&gt;1.0-SNAPSHOT&lt;/version&gt;
&lt;/dependency&gt;</pre>
<p>Teraz kolej na jedyną wstawkę Javy, która się pojawia w projekcie. Jest to zwykły bean, który będzie miał później wstrzykiwane obiekty pośredniczące w wywoływaniu usług.</p>
<pre class="brush: java;">package org.code_house.cxf.client;

import org.code_house.services.maven.MavenArtifactType;

/**
 * Klient usług Code-House.
 *
 * @author Łukasz Dywicki &lt;a href=&quot;splatch@code-house.org&quot;&gt;email&lt;/a&gt;
 *
 * $Id$
 */
public class Client {

    /**
     * Usługa do obsługi wyszukiwania artefaktów Mavena.
     */
    private MavenArtifactType maven;

    /**
     * Pobranie wartości pola maven.
     *
     * @return Wartość maven.
     */
    public MavenArtifactType getMaven() {
        return maven;
    }

    /**
     * Ustawienie wartości pola maven.
     *
     * @param maven Nowa wartość pola maven.
     */
    public void setMaven(MavenArtifactType maven) {
        this.maven = maven;
    }
}</pre>
<p>Resztę magii załatwia Spring:</p>
<pre class="brush: xml;">&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
&lt;beans xmlns=&quot;http://www.springframework.org/schema/beans&quot;
    xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot;
    xmlns:context=&quot;http://www.springframework.org/schema/context&quot;
    xsi:schemaLocation=&quot;
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context.xsd
        http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
    &quot;&gt;
    &lt;!--  Konfiguracja placeholderów (znaczy wstawek ${}) --&gt;
    &lt;context:property-placeholder location=&quot;classpath:client.properties&quot; /&gt;

    &lt;!-- Importy rzeczy koniecznych do pracy CXF --&gt;
    &lt;import resource=&quot;classpath:META-INF/cxf/cxf.xml&quot; /&gt;
    &lt;import resource=&quot;classpath:META-INF/cxf/cxf-extension-soap.xml&quot; /&gt;
    &lt;import resource=&quot;classpath:META-INF/cxf/cxf-extension-http-jetty.xml&quot; /&gt;

    &lt;!-- Konfiguracja poszczególnych usług wstrzykiwanych do klienta --&gt;
    &lt;import resource=&quot;classpath:services/*.xml&quot; /&gt;

    &lt;!-- Bean zawierający referencje do wygenerowanych klientów usług --&gt;
    &lt;bean id=&quot;client&quot; class=&quot;org.code_.housecxf.client.Client&quot; autowire=&quot;autodetect&quot; /&gt;

    &lt;!-- Bazowa konfiguracja fabryk - obiektów tworzących stuby klientów w runtime --&gt;
    &lt;bean id=&quot;baseClientFactory&quot; abstract=&quot;true&quot;
        class=&quot;org.apache.cxf.jaxws.JaxWsProxyFactoryBean&quot;&gt;
       &lt;property name=&quot;username&quot; value=&quot;${org.code_house.cxf.user}&quot; /&gt;
        &lt;property name=&quot;password&quot; value=&quot;${org.code_house.cxf.password}&quot; /&gt;
        &lt;property name=&quot;inInterceptors&quot;&gt;
            &lt;list&gt;
                &lt;ref bean=&quot;logIn&quot; /&gt;
            &lt;/list&gt;
        &lt;/property&gt;
        &lt;property name=&quot;outInterceptors&quot;&gt;
            &lt;list&gt;
                &lt;ref bean=&quot;logOut&quot; /&gt;
            &lt;/list&gt;
        &lt;/property&gt;
    &lt;/bean&gt;

    &lt;!-- Loggery dla CXF --&gt;
    &lt;bean id=&quot;logIn&quot; class=&quot;org.apache.cxf.interceptor.LoggingInInterceptor&quot; /&gt;
    &lt;bean id=&quot;logOut&quot; class=&quot;org.apache.cxf.interceptor.LoggingOutInterceptor&quot; /&gt;

&lt;/beans&gt;</pre>
<p>Zgodnie ze wstawką w linii 20 konieczna jest jeszcze konfiguracja usługi. Sztuczka polega na użyciu części konfiguracji zdefiniowanej wcześniej &#8211; baseClientFactory.</p>
<pre class="brush: xml;">&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
&lt;beans xmlns=&quot;http://www.springframework.org/schema/beans&quot;
    xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot;
    xsi:schemaLocation=&quot;
        http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
    &quot;&gt;

    &lt;!-- Konfiguracja stuba dla usługi wyszukiwania artefaktów --&gt;
    &lt;bean id=&quot;mavenService&quot; class=&quot;org.code_house.services.maven.MavenArtifactType&quot;
        factory-bean=&quot;mavenServiceFactory&quot; factory-method=&quot;create&quot; /&gt;

    &lt;!-- Fabryka usługi wyszukującej --&gt;
    &lt;bean id=&quot;mavenServiceFactory&quot; parent=&quot;baseClientFactory&quot;&gt;
        &lt;!-- jedyne parametry jakich potrzebujemy --&gt;
        &lt;property name=&quot;serviceClass&quot;
            value=&quot;org.code_house.services.maven.MavenArtifactType&quot; /&gt;
        &lt;property name=&quot;address&quot; value=&quot;${org.code_house.cxf.service.maven}&quot; /&gt;
    &lt;/bean&gt;

&lt;/beans&gt;</pre>
<p>Ustawienia, które mogą ulec zmianie, to znaczy użytkownik, hasło oraz adres usługi są wyodrębnione do pliku client.properties:</p>
<p># Placeholdery dla kontekstow springa<br />
# Adresy uslug<br />
server.port = 8080<br />
host = localhost<br />
org.code_house.cxf.service.maven http://${host}:${server.port}/webapp/services/maven</p>
<p># Autoryzacja<br />
org.code_house.cxf.user<br />
org.code_house.cxf.password</p>
<p>No i na koniec opcjonalny test, który odpytuje usługę:</p>
<pre class="brush: java;">
package org.code_house.cxf.client;
import org.code_house.services.maven.definition.ArtifactInfo;
import org.code_house.services.maven.types.FindArtifactRequest;
import org.code_house.services.maven.types.FindArtifactRespose;
import org.springframework.test.AbstractDependencyInjectionSpringContextTests;

/**
 * Proste wywołanie klasy klienta.
 *
 * @author Łukasz Dywicki &lt;a href=&quot;ldywicki@pocztowy.pl&quot;&gt;email&lt;/a&gt;
 *
 * $Id$
 */
public class MainTest extends AbstractDependencyInjectionSpringContextTests {

    /**
     * Wstrzyknięty klient.
     */
    private Client client;

    @Override
    protected String[] getConfigLocations() {
        return new String[] {&quot;classpath:client.xml&quot;};
    }

    public void testOne() {
        FindArtifactRequest request = new FindArtifactRequest();
        ArtifactInfo artifact = new ArtifactInfo();
        artifact.setGroupId(&quot;org.code_house.cxf&quot;);
        artifact.setArtifactId(&quot;contract&quot;);
        request.setQuery(artifact);

        FindArtifactRespose respose = client.getMaven().findArtifact(request);
        System.out.println(respose.getDownloadURL());
    }

    /**
     * Ustawienie wartości pola client.
     *
     * @param client Nowa wartość pola client.
     */
    public void setClient(Client client) {
        this.client = client;
    }

}</pre>
<p>To by było na tyle. Cały działający kod projektu jest już zamieszczony przy <a href="http://blog.dywicki.pl/2008/07/23/budowanie-uslugi-sieciowej-w-oparciu-o-apache-cxf/">poprzedniej nocie</a>, paczka ze wszystkimi listingami <a href="http://media.dywicki.pl/blog/cxf/cxf.zip">gotowa do pobrania</a>.</p>
<p>Teraz chyba pora zacząć opisywać mechanizmy Springa. :)</p>]]></content:encoded>
			<wfw:commentRss>http://blog.dywicki.pl/2008/09/03/budowanie-klienta-uslugi-sieciowej-w-oparciu-o-apache-cxf/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Budowanie usługi sieciowej w oparciu o Apache CXF</title>
		<link>http://blog.dywicki.pl/2008/07/23/budowanie-uslugi-sieciowej-w-oparciu-o-apache-cxf/</link>
		<comments>http://blog.dywicki.pl/2008/07/23/budowanie-uslugi-sieciowej-w-oparciu-o-apache-cxf/#comments</comments>
		<pubDate>Wed, 23 Jul 2008 06:27:55 +0000</pubDate>
		<dc:creator>Łukasz Dywicki</dc:creator>
				<category><![CDATA[CXF]]></category>
		<category><![CDATA[JAXB]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[XML]]></category>

		<guid isPermaLink="false">http://blog.dywicki.pl/?p=219</guid>
		<description><![CDATA[Od jakiegoś czasu w pracy do tworzenia usług sieciowych korzystam z Apache CXF. Jako że biblioteka jest stosunkowo nowa i nie najlepiej udokumentowana postanowiłem przedstawić na blogu jak wygląda proces tworzenia.
CXF jest połączeniem kilku bibliotek - YOKO, Celtixa oraz XFire. Każda z nich wcześniej realizowała pewien fragment obecnej funkcjonalności CXF - YOKO obsługuje Corbę a [...]]]></description>
			<content:encoded><![CDATA[<p>Od jakiegoś czasu w pracy do tworzenia usług sieciowych korzystam z <a href="http://cxf.apache.org">Apache CXF</a>. Jako że biblioteka jest stosunkowo nowa i nie najlepiej udokumentowana postanowiłem przedstawić na blogu jak wygląda proces tworzenia.</p>
<p>CXF jest połączeniem kilku bibliotek - <a href="http://cwiki.apache.org/YOKO/">YOKO</a>, <a href="http://celtix.objectweb.org/">Celtixa</a> oraz <a href="http://xfire.codehaus.org/">XFire</a>. Każda z nich wcześniej realizowała pewien fragment obecnej funkcjonalności CXF - YOKO obsługuje Corbę a XFire usługi sieciowe. Obecne CXF jest gotowy do używania "produkcyjnego", ponieważ niedawno wyszedł z fazy inkubacji. :)<br />
<span id="more-219"></span></p>
<h3>Architektura</h3>
<p>CXF ma dosyć elastyczną budowę. Zgodnie z <a href="http://cwiki.apache.org/CXF20DOC/cxf-architecture.html">dokumentacją</a> można wyróżnić najważniejsze składowe:</p>
<ul>
<li><b>Bus</b>, jest trzonem architektury CXF w którym definiuje i konfiguruje się rozszerzenia.</li>
<li><b>Messaging &#038; Interceptors</b>, zapewniają niskopoziomowy dostęp do komunikatów oraz warstwę na której jest oparta większość funkcjonalności.</li>
<li><b>Front ends</b>, frontendy są interfejsami programistycznymi do tworzenia usług (np. JAX-WS).</li>
<li><b>Services</b>, usługi zapewniają model wraz z opisem</li>
<li><b>Bidings</b>, element ten jest odpowiedzialny za obsługę konkretnego protokołu (<acronym title="Simple Object Access Protocol">SOAP</acronym>, REST, Corba etc).</li>
<li><b>Transports</b>, warstwa abstrakcji ułatwiająca zmianę sposobu transportu do/z usług.</li>
</ul>
<h3>Markieting :)</h3>
<p>CXF oferuje infrastrukturę konieczną do budowania usług, z najważniejszy zalet można wymienić:</p>
<ul>
<li>Wsparcie dla różnych protokołów.</li>
<li>Obsługa standardów WS-*, tj. WS-Addressing, WS-Security, WS-ReliableMessaging, oraz WS-Policy.</li>
<li>Obsługa wielu transportów.</li>
<li>Dołączane data-bindingi (np JAXB, Aegis).</li>
<li>Jasny podział front endów takich jak JAX-WS od najważniejszego kodu.</li>
<li>Wysoka wydajność.</li>
<li>Możliwość osadzania w różnych środowiskach.</li>
</ul>
<p>Z dodatkowych zalet, mogę dodać - bardzo łatwą integrację ze Springiem.</p>
<h2>Pierwsza usługa</h2>
<p>Do budowania projektów będziemy używać <a href="http://maven.apache.org">Mavena</a>. Implementowana usługa będzie oparta o frontend JAX-WS z ręcznie pisanym deskryptorem usługi (<acronym title="Web Services Description Language">WSDL</acronym> first). Jakkolwiek w bardzo prosty sposób można odwrócić kolejność i przy pomocy pluginu CXF do Mavena wygenerować deskryptor.</p>
<p>Struktura projektów będzie następująca:</p>
<ul>
<li>parent<br />
         Rodzic projektu ze zdefiniowanymi wersjami bibliotek i raportami.
    </li>
<ul>
<li>contract<br />
             Definicje używane zarówno przez klienta jak i serwer - <acronym title="Web Services Description Language">WSDL</acronym> oraz konfiguracja pluginu CXF.</li>
<li>client<br />
             Prosta biblioteka kliencka oparta o mechanizmy CXFa (JaxWSProxyFactoryBean).</li>
<li>server<br />
             Przykładowa implementacja usługi z bardzo prostym wykorzystaniem Springa.</li>
<li>webapp<br />
            Konfiguracja transporty CXF - w tym konkretnym przypadku servletu CXF.</li>
</ul>
</ul>
<h2>Parent</h2>
<p>Poniżej znajduje się deskryptor projektu, który jest używany do budowania całości.</p>
<pre class="brush: xml;">
&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
&lt;project xsi:schemaLocation=&quot;http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd&quot; xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot;&gt;

    &lt;!-- Informacja dla Mavena --&gt;
    &lt;modelVersion&gt;4.0.0&lt;/modelVersion&gt;

    &lt;!-- Identyfikacja projektu --&gt;
    &lt;groupId&gt;org.code-house.cxf&lt;/groupId&gt;
    &lt;artifactId&gt;parent&lt;/artifactId&gt;
    &lt;name&gt;Code House.Org - CXF&lt;/name&gt;
    &lt;version&gt;1.0-SNAPSHOT&lt;/version&gt;
    &lt;packaging&gt;pom&lt;/packaging&gt;

    &lt;description&gt;Rodzic projektu, zawiera wszystkie moduly.&lt;/description&gt;

    &lt;!-- Składowe projektu --&gt;
    &lt;modules&gt;
        &lt;module&gt;cxf-client&lt;/module&gt;
        &lt;module&gt;cxf-contract&lt;/module&gt;
        &lt;module&gt;cxf-server&lt;/module&gt;
        &lt;module&gt;cxf-webapp&lt;/module&gt;
    &lt;/modules&gt;

    &lt;!-- Definicje zmiennych dostępne również w modułach --&gt;
    &lt;properties&gt;
        &lt;code-house.cxf.version&gt;2.1.1&lt;/code-house.cxf.version&gt;
        &lt;code-house.jaxb.version&gt;2.1.3&lt;/code-house.jaxb.version&gt;
        &lt;code-house.spring.version&gt;2.5.4&lt;/code-house.spring.version&gt;
    &lt;/properties&gt;

    &lt;build&gt;
        &lt;plugins&gt;
            &lt;!-- Konfiguracja kompilatora --&gt;
            &lt;plugin&gt;
                &lt;artifactId&gt;maven-compiler-plugin&lt;/artifactId&gt;
                &lt;configuration&gt;
                    &lt;source&gt;1.5&lt;/source&gt;
                    &lt;target&gt;1.5&lt;/target&gt;
                &lt;/configuration&gt;
            &lt;/plugin&gt;
        &lt;/plugins&gt;
    &lt;/build&gt;

    &lt;reporting&gt;
    &lt;!--Wycięte :) --&gt;
    &lt;/reporting&gt;

    &lt;!-- Predefiniowane wersje bibliotek --&gt;
    &lt;dependencyManagement&gt;
        &lt;dependencies&gt;
            &lt;dependency&gt;
                &lt;groupId&gt;org.apache.cxf&lt;/groupId&gt;
                &lt;artifactId&gt;cxf-rt-frontend-jaxws&lt;/artifactId&gt;
                &lt;version&gt;${code-house.cxf.version}&lt;/version&gt;
            &lt;/dependency&gt;
            &lt;dependency&gt;
                &lt;groupId&gt;org.apache.cxf&lt;/groupId&gt;
                &lt;artifactId&gt;cxf-rt-transports-http&lt;/artifactId&gt;
                &lt;version&gt;${code-house.cxf.version}&lt;/version&gt;
            &lt;/dependency&gt;
            &lt;dependency&gt;
                &lt;groupId&gt;org.apache.cxf&lt;/groupId&gt;
                &lt;artifactId&gt;cxf-rt-transports-http-jetty&lt;/artifactId&gt;
                &lt;version&gt;${code-house.cxf.version}&lt;/version&gt;
            &lt;/dependency&gt;
            &lt;dependency&gt;
                &lt;groupId&gt;com.sun.xml.bind&lt;/groupId&gt;
                &lt;artifactId&gt;jaxb-impl&lt;/artifactId&gt;
                &lt;version&gt;${code-house.jaxb.version}&lt;/version&gt;
            &lt;/dependency&gt;
            &lt;dependency&gt;
                &lt;groupId&gt;javax.xml.bind&lt;/groupId&gt;
                &lt;artifactId&gt;jaxb-api&lt;/artifactId&gt;
                &lt;version&gt;2.1&lt;/version&gt;
            &lt;/dependency&gt;
        &lt;/dependencies&gt;
    &lt;/dependencyManagement&gt;

&lt;/project&gt;
</pre>
<h2>Contract</h2>
<p>Zgodnie z tym, co napisałem wcześniej - przyjąłem podejście, że <acronym title="Web Services Description Language">WSDL</acronym> jest pisany ręcznie, głównie dlatego że dla większych projektów można w prosty sposób narzucić jakąś organizację i podział plików, z których są następnie generowane źródła.<br />
Najistotniejsza wstawka, która powinna znaleźć się w pomie:</p>
<pre class="brush: xml;">
&lt;!-- Generowanie kodu z deskryptora <acronym title="Web Services Description Language">WSDL</acronym> --&gt;
&lt;plugin&gt;
    &lt;groupId&gt;org.apache.cxf&lt;/groupId&gt;
    &lt;artifactId&gt;cxf-codegen-plugin&lt;/artifactId&gt;
    &lt;executions&gt;
        &lt;execution&gt;
            &lt;phase&gt;generate-sources&lt;/phase&gt;
            &lt;configuration&gt;
                &lt;sourceRoot&gt;${basedir}/target/jaxws&lt;/sourceRoot&gt;
                &lt;wsdlOptions&gt;
                    &lt;wsdlOption&gt;
                        &lt;wsdl&gt;
                            ${basedir}/src/main/resources/maven.wsdl
                        &lt;/wsdl&gt;
                        &lt;extraargs&gt;
                            &lt;extraarg&gt;-quiet&lt;/extraarg&gt;
                        &lt;/extraargs&gt;
                    &lt;/wsdlOption&gt;
                &lt;/wsdlOptions&gt;
            &lt;/configuration&gt;
            &lt;goals&gt;
                &lt;goal&gt;wsdl2java&lt;/goal&gt;
            &lt;/goals&gt;
        &lt;/execution&gt;
    &lt;/executions&gt;
&lt;/plugin&gt;
</pre>
<p>Po dodaniu tej wstawki do sekcji <b>build/plugins</b> możemy przejść do tworzenia deskryptora usługi. W moim przypadku przyjąłem następujący podział:</p>
<ol>
<li>maven.wsdl - definicje metod oraz komunikatów w rozumieniu <acronym title="Web Services Description Language">WSDL</acronym> (messages). Można z powodzeniem wyłączyć z tego pliku same koperty i pozostawić metody a to co potrzebne włączyć dyrektywą <b>wsdl:import</b>.</li>
<li>types.xsd - typy używane do komunikacji - zazwyczaj pary request+response używane bezpośrednio w definiowaniu elementów <b>wsdl:part</b>.</li>
<li>definition.xsd - definicje typów złożonych, niezależnych od usług, tj. opis domain-modelu z którym usługa pracuje.</li>
</ol>
<p>Każdy z tych plików ma inną przestrzeń nazw.</p>
<h3>maven.wsdl</h3>
<pre class="brush: xml;">
&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
&lt;wsdl:definitions xmlns:soap=&quot;http://schemas.xmlsoap.org/wsdl/soap/&quot;
    xmlns:tns=&quot;http://code-house.org/services/maven&quot;
    xmlns:types=&quot;http://code-house.org/services/maven/types&quot;
    xmlns:wsdl=&quot;http://schemas.xmlsoap.org/wsdl/&quot;
    xmlns:xsd=&quot;http://www.w3.org/2001/XMLSchema&quot;
    targetNamespace=&quot;http://code-house.org/services/maven&quot;
    name=&quot;MavenServices&quot;
    &gt;

    &lt;wsdl:types&gt;
        &lt;xsd:schema targetNamespace=&quot;http://code-house.org/services/maven/types&quot;&gt;
            &lt;xsd:include schemaLocation=&quot;types.xsd&quot; /&gt;
        &lt;/xsd:schema&gt;
    &lt;/wsdl:types&gt;

    &lt;wsdl:message name=&quot;findArtifactRequest&quot;&gt;
        &lt;wsdl:part name=&quot;request&quot; type=&quot;types:FindArtifactRequest&quot; /&gt;
    &lt;/wsdl:message&gt;
    &lt;wsdl:message name=&quot;findArtifactResponse&quot;&gt;
        &lt;wsdl:part name=&quot;response&quot; type=&quot;types:FindArtifactRespose&quot; /&gt;
    &lt;/wsdl:message&gt;

    &lt;wsdl:portType name=&quot;MavenArtifactType&quot;&gt;
        &lt;wsdl:operation name=&quot;findArtifact&quot;&gt;
            &lt;wsdl:input message=&quot;tns:findArtifactRequest&quot; /&gt;
            &lt;wsdl:output message=&quot;tns:findArtifactResponse&quot; /&gt;
        &lt;/wsdl:operation&gt;
    &lt;/wsdl:portType&gt;

    &lt;wsdl:binding name=&quot;MavenArtifactSOAP&quot; type=&quot;tns:MavenArtifactType&quot;&gt;
        &lt;soap:binding style=&quot;document&quot; transport=&quot;http://schemas.xmlsoap.org/soap/http&quot; /&gt;
        &lt;wsdl:operation name=&quot;findArtifact&quot;&gt;
            &lt;wsdl:input&gt;
                &lt;soap:body use=&quot;literal&quot; /&gt;
            &lt;/wsdl:input&gt;
            &lt;wsdl:output&gt;
                &lt;soap:body use=&quot;literal&quot; /&gt;
            &lt;/wsdl:output&gt;
        &lt;/wsdl:operation&gt;
    &lt;/wsdl:binding&gt;

    &lt;wsdl:service name=&quot;MavenServices&quot;&gt;
        &lt;wsdl:port binding=&quot;tns:MavenArtifactSOAP&quot; name=&quot;Maven Services&quot;&gt;
            &lt;soap:address location=&quot;http://localhost:8080/webapp/services/maven&quot; /&gt;
        &lt;/wsdl:port&gt;
    &lt;/wsdl:service&gt;
&lt;/wsdl:definitions&gt;
</pre>
<h3>types.xsd</h3>
<pre class="brush: xml;">
&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
&lt;schema xmlns=&quot;http://www.w3.org/2001/XMLSchema&quot;
    targetNamespace=&quot;http://code-house.org/services/maven/types&quot;
    xmlns:tns=&quot;http://code-house.org/services/maven/types&quot;
    xmlns:def=&quot;http://code-house.org/services/maven/definition&quot;
    elementFormDefault=&quot;qualified&quot;&gt;

    &lt;import schemaLocation=&quot;definition.xsd&quot;
        namespace=&quot;http://code-house.org/services/maven/definition&quot; /&gt;

    &lt;complexType name=&quot;FindArtifactRequest&quot;&gt;
        &lt;sequence&gt;
            &lt;element name=&quot;query&quot; type=&quot;def:ArtifactInfo&quot; /&gt;
        &lt;/sequence&gt;
    &lt;/complexType&gt;

    &lt;complexType name=&quot;FindArtifactRespose&quot;&gt;
        &lt;sequence&gt;
            &lt;element name=&quot;downloadURL&quot; type=&quot;anyURI&quot; /&gt;
        &lt;/sequence&gt;
    &lt;/complexType&gt;

&lt;/schema&gt;
</pre>
<h3>definition.xsd</h3>
<pre class="brush: xml;">
&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
&lt;schema xmlns=&quot;http://www.w3.org/2001/XMLSchema&quot;
    targetNamespace=&quot;http://code-house.org/services/maven/definition&quot;
    xmlns:tns=&quot;http://code-house.org/services/maven/definition&quot;
    elementFormDefault=&quot;qualified&quot;&gt;

    &lt;complexType name=&quot;ArtifactInfo&quot;&gt;
        &lt;sequence&gt;
            &lt;element name=&quot;groupId&quot; type=&quot;string&quot; /&gt;
            &lt;element name=&quot;artifactId&quot; type=&quot;string&quot; /&gt;
            &lt;element name=&quot;version&quot; type=&quot;string&quot; minOccurs=&quot;0&quot; /&gt;
            &lt;element name=&quot;classifier&quot; type=&quot;tns:Classifier&quot; minOccurs=&quot;0&quot; /&gt;
            &lt;element name=&quot;packaging&quot; type=&quot;tns:Packaging&quot; minOccurs=&quot;0&quot; /&gt;
            &lt;element name=&quot;type&quot; type=&quot;tns:Type&quot; minOccurs=&quot;0&quot; /&gt;
        &lt;/sequence&gt;
    &lt;/complexType&gt;

    &lt;simpleType name=&quot;Type&quot;&gt;
        &lt;restriction base=&quot;string&quot;&gt;
            &lt;enumeration value=&quot;dll&quot; /&gt;
            &lt;enumeration value=&quot;so&quot; /&gt;
        &lt;/restriction&gt;
    &lt;/simpleType&gt;

    &lt;simpleType name=&quot;Classifier&quot;&gt;
        &lt;restriction base=&quot;string&quot;&gt;
            &lt;enumeration value=&quot;sources&quot; /&gt;
            &lt;enumeration value=&quot;javadoc&quot; /&gt;
            &lt;enumeration value=&quot;resources&quot; /&gt;
        &lt;/restriction&gt;
    &lt;/simpleType&gt;

    &lt;simpleType name=&quot;Packaging&quot;&gt;
        &lt;restriction base=&quot;string&quot;&gt;
            &lt;enumeration value=&quot;pom&quot; /&gt;
            &lt;enumeration value=&quot;jar&quot; /&gt;
            &lt;enumeration value=&quot;war&quot; /&gt;
            &lt;enumeration value=&quot;bundle&quot; /&gt;
        &lt;/restriction&gt;
    &lt;/simpleType&gt;

&lt;/schema&gt;
</pre>
<p>Po odpaleniu polecenia <b>mvn:install</b> powinniśmy otrzymać w konsoli fragment podobny do tego:</p>
<pre class="brush: plain;">
[INFO] [cxf-codegen:wsdl2java {execution: default}]
</pre>
<p>Jest to informacja, że plugin CXF został poprawnie skonfigurowany i uruchomiony.</p>
<h2>Serwer</h2>
<p>Sercem naszej usługi jest oczywiście jej implementacja dlatego też nie możemy obejść się bez niej. :) Projekt ten ma tylko dwie zależności - <b>contract</b> oraz artefakt <b>cxf-rt-frontend-jaxws</b>.</p>
<p>Konfiguracja serwera odbywa się w oparciu o springa:</p>
<pre class="brush: xml;">
&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
&lt;beans xmlns=&quot;http://www.springframework.org/schema/beans&quot;
    xmlns:jaxws=&quot;http://cxf.apache.org/jaxws&quot;
    xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot;
    xsi:schemaLocation=&quot;
        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
    &quot;&gt;

    &lt;!-- Dodatkowy bean zawierający właściwą implementację logiki związanej z wyszukiwaniem --&gt;
    &lt;bean id=&quot;service&quot; class=&quot;org.code_house.services.maven.DummyMavenSearchServiceImpl&quot; /&gt;

    &lt;!-- Bean będący implementacją usługi jako takiej - obsługujący wejście/wyjście --&gt;
    &lt;bean id=&quot;mavenService&quot; class=&quot;org.code_house.services.maven.MavenArtifactTypeImpl&quot;&gt;
        &lt;property name=&quot;service&quot; ref=&quot;service&quot; /&gt;
    &lt;/bean&gt;

    &lt;!-- Konfiguracja endpointu CXFa --&gt;
    &lt;jaxws:endpoint address=&quot;maven&quot; id=&quot;jaxwsMavenService&quot; implementor=&quot;#mavenService&quot; /&gt;

&lt;/beans&gt;
</pre>
<p>Serwer zawiera w zasadzie niewiele kodu, oto i on:</p>
<pre class="brush: java;">
package org.code_house.services.maven;

import java.net.URISyntaxException;

import javax.jws.WebService;

import org.code_house.services.maven.definition.ArtifactInfo;
import org.code_house.services.maven.types.FindArtifactRequest;
import org.code_house.services.maven.types.FindArtifactRespose;

/**
  * Implementacja usługi.
  */
@WebService(serviceName = &quot;MavenService&quot;,
    endpointInterface = &quot;org.code_house.services.maven.MavenArtifactType&quot;,
    targetNamespace = &quot;http://code-house.org/services/maven&quot;
)
public class MavenArtifactTypeImpl implements MavenArtifactType {

    /**
      * Bean zawierający implementację logiki biznesowej.
      */
    private MavenSearchService service;

    public FindArtifactRespose findArtifact(FindArtifactRequest request) {
        ArtifactInfo info = request.getQuery(); // pobranie struktury przekazanej od klienta

        // sformuowanie odpowiedzi
        FindArtifactRespose response = new FindArtifactRespose();
        try {
            response.setDownloadURL(service.find(info).toURI().toString());
        } catch (URISyntaxException e) {
            throw new RuntimeException(e);
        }
        return response;
    }

    /**
     * Ustawienie wartości pola service.
     *
     * @param service Nowa wartość pola service.
     */
    public void setService(MavenSearchService service) {
        this.service = service;
    }
}
</pre>
<p>Dodatkowy kod, który nie jest konieczny do implementacji usługi to definicja interfejsu <b>MavenSearchService</b>. Dzięki zastosowaniu takiego rozwiązania można w prostszy sposób testować działanie usługi poprzez przekazywanie jej mocka stworzonego np. przy pomocy <a href="http://easymock.org">easy mocka</a>. Kod takiego testu pominąłem ze względu na to, że notka i tak już jest za długa w tym momencie a jesteśmy ledwo w połowie drogi. :)</p>
<p>Przykładowa implementacja wcześniej wspomnianego intefejsu nie zawiera żadnej logiki i zawsze zwraca tą samą wartość.</p>
<pre class="brush: java;">
package org.code_house.services.maven;

import java.net.MalformedURLException;
import java.net.URL;

import org.code_house.services.maven.definition.ArtifactInfo;

// Najprostsza implementacja tylko po to żeby sprawdzić działanie usługi
public class DummyMavenSearchServiceImpl implements MavenSearchService {

    public <acronym title="Uniform Resource Locator">URL</acronym> find(ArtifactInfo info) {
        try {
            return new <acronym title="Uniform Resource Locator">URL</acronym>(&quot;http://repo1.maven.org/maven2/org/apache/apache/4/apache-4.pom&quot;);
        } catch (MalformedURLException e) {
            throw new RuntimeException(e);
        }
    }

}
</pre>
<p>Zanim odpalimy serwer konieczna będzie jeszcze jedna rzecz - konfiguracja transporu, w naszym przypadku servletu CXF.</p>
<h2>Webapp</h2>
<p>Webapp posiada bezpośrednie zależności do 2 artefaktów CXFa: <b>cxf-rt-transports-http</b> oraz <b>cxf-rt-bindings-http</b>. Druga jest opcjonalna, bez niej CXF nie będzie wyświetlał dostępnych usług w postaci tabelki html.</p>
<p>Przydatna może być wtyczka jetty (sekcja <b>build/plugins</b>), która pozwala na uruchomienie aplikacji bez konieczności instalowania kontenera servletów:</p>
<pre class="brush: xml;">
&lt;plugin&gt;
    &lt;groupId&gt;org.mortbay.jetty&lt;/groupId&gt;
    &lt;artifactId&gt;maven-jetty-plugin&lt;/artifactId&gt;
    &lt;version&gt;6.1.11&lt;/version&gt;
    &lt;configuration&gt;
        &lt;scanIntervalSeconds&gt;10&lt;/scanIntervalSeconds&gt;
        &lt;connectors&gt;
            &lt;connector implementation=&quot;org.mortbay.jetty.nio.SelectChannelConnector&quot;&gt;
                &lt;port&gt;8080&lt;/port&gt;
                &lt;maxIdleTime&gt;60000&lt;/maxIdleTime&gt;
            &lt;/connector&gt;
        &lt;/connectors&gt;
    &lt;/configuration&gt;
&lt;/plugin&gt;
</pre>
<p>Ostatnia zależność odnosi się do implementacji usługi - czyli naszego artefaktu <b>server</b>. Najistotniejsze elementy konfiguracji webappa to web.xml oraz cxf-beans.xml.</p>
<h3>web.xml</h3>
<p>Warto zauważyć w poniższym listingu fajną możliwość, którą daje nam Spring w postaci wildcardów określających położenie konfiguracji - w tym przypadku <b>classpath:/module/*-context.xml</b>. Oznacza to, że Spring przeskanuje wszystkie biblioteki od których zależy projekt i dołączy ich konfigurację do głownej, dzięki czemu będziemy mogli uzyskać bardziej modułową i elastyczną budowę aplikacji. Może <a href="http://www.springframework.org/osgi">Dynamic Modules</a> to nie jest ale na codzień w zupełności wystarcza :).</p>
<pre class="brush: xml;">
&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
&lt;web-app id=&quot;ocs&quot; version=&quot;2.5&quot;
    xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot;
    xmlns=&quot;http://java.sun.com/xml/ns/javaee&quot;
    xmlns:web=&quot;http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd&quot;
    xsi:schemaLocation=&quot;
        http://java.sun.com/xml/ns/javaee
        http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd&quot;
    &gt;

    &lt;!-- Informacje nazewnicze dla kontenera --&gt;
    &lt;display-name&gt;Maven Search Services :: Webapp&lt;/display-name&gt;
    &lt;description&gt;Frontend indeksera.&lt;/description&gt;

    &lt;!-- Lokalizacje plików konfiguracyjnych --&gt;
    &lt;context-param&gt;
        &lt;param-name&gt;contextConfigLocation&lt;/param-name&gt;
        &lt;param-value&gt;
            &lt;!-- Konfiguracja zabezpieczeń opartych o spring secuirty --&gt;
            /WEB-INF/security.xml
            &lt;!-- Konfiguracja CXF --&gt;
            /WEB-INF/cxf-beans.xml
            &lt;!-- Konfiguracja kontekstu --&gt;
            /WEB-INF/applicationContext.xml
            &lt;!-- Wczytanie konfiguracji modułów --&gt;
            classpath:/module/*-context.xml
        &lt;/param-value&gt;
    &lt;/context-param&gt;

    &lt;!-- Servlet obsługujący usługi sieciowe --&gt;
    &lt;servlet&gt;
        &lt;servlet-name&gt;CXFServlet&lt;/servlet-name&gt;
        &lt;servlet-class&gt;org.apache.cxf.transport.servlet.CXFServlet&lt;/servlet-class&gt;
        &lt;load-on-startup&gt;1&lt;/load-on-startup&gt;
    &lt;/servlet&gt;

    &lt;!-- Mapowanie adresu usług sieciowych --&gt;
    &lt;servlet-mapping&gt;
        &lt;servlet-name&gt;CXFServlet&lt;/servlet-name&gt;
        &lt;url-pattern&gt;/services/*&lt;/url-pattern&gt;
    &lt;/servlet-mapping&gt;

    &lt;!-- Inicjowanie kontekstu springa --&gt;
    &lt;listener&gt;
        &lt;listener-class&gt;org.springframework.web.context.ContextLoaderListener&lt;/listener-class&gt;
    &lt;/listener&gt;

&lt;/web-app&gt;
</pre>
<h3>cxf-beans.xml</h3>
<p>Plik ten zawiera definicje konfiguracyjne CXFa. W poniższej formie włączana jest tylko część modułów CXF w celu zmniejszenia użycia zasobów.</p>
<pre class="brush: xml;">
&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
&lt;beans xmlns=&quot;http://www.springframework.org/schema/beans&quot;
    xmlns:cxf=&quot;http://cxf.apache.org/core&quot;
    xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot;
    xsi:schemaLocation=&quot;
        http://cxf.apache.org/core
        http://cxf.apache.org/schemas/core.xsd
        http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
    &quot;&gt;

    &lt;!-- Moduły CXF-a --&gt;
    &lt;import resource=&quot;classpath:META-INF/cxf/cxf.xml&quot;/&gt;
    &lt;import resource=&quot;classpath:META-INF/cxf/cxf-extension-soap.xml&quot;/&gt;
    &lt;import resource=&quot;classpath:META-INF/cxf/cxf-extension-http-binding.xml&quot;/&gt;
    &lt;import resource=&quot;classpath:META-INF/cxf/cxf-servlet.xml&quot;/&gt;

&lt;/beans&gt;
</pre>
<p>Pozostałe pliki konfiguracyjne są praktycznie puste, ponieważ tyczą się obszarów niezwiązanych z tematem tego wpisu. Po tym wszystkim możemy uruchomić naszą aplikację poleceniem <b>mvn jetty:run</b>. Po wejściu na adres http://localhost:8080/webapp/services naszym oczom powinna ukazać się lista podobna do poniższej:<br />
<img src="http://blog.dywicki.pl/wp-content/uploads/2008/07/services.jpg" alt="services" title="services" /><br />
Nie wiem niestety dlaczego CXF generuje zły adres usługi (pomijający mapowanie servletu) oraz ma problemy z wystawieniem WSDLa. Jakkolwiek i bez tego wszystko działa poprawnie - znaczy wywoływanie usług rzecz jasna. :)</p>
<p><a href="http://blog.dywicki.pl/wp-content/uploads/2008/07/soap-ui.jpg" style="text-decoration: none" rel="lightbox"><img src="http://blog.dywicki.pl/wp-content/uploads/2008/07/soap-ui-300x182.jpg" alt="soap-ui" title="soap-ui" width="300" height="182" align="right" /></a> W tym momencie możemy uruchomić <a href="http://www.soapui.org/">Soap UI</a> i wykonać jedyną dostępną metodę - findArtifact.</p>
<h2>Client</h2>
<p>Ostatnim z elementów, który pozostał do omówienia jest klient. Niestety z racji na to, że ta nota już się wystarczająco rozrosła zrobię to w kolejnym wpisie. Mam nadzieję, że nota ta nieco ułatwi przyszłym użytkownikom CXFa jego poznanie. :) Dla tych, którym nie chce się wpisywać tego wszystkiego w edytorze <a href="http://media.dywicki.pl/blog/cxf/cxf.zip">zamieszczam źródła</a> razem z działającym klientem. Projekty nie są nadzwyczajnie dopieszczone, ale w zupełności wystarczą do startu. Znajduje się też tam w pełni działający klient stworzonej usługi. Pozdrawiam i życzę miłej zabawy!</p>]]></content:encoded>
			<wfw:commentRss>http://blog.dywicki.pl/2008/07/23/budowanie-uslugi-sieciowej-w-oparciu-o-apache-cxf/feed/</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
		<item>
		<title>Apache ServiceMix, Open Source ESB</title>
		<link>http://blog.dywicki.pl/2008/06/22/apache-servicemix-open-source-es/</link>
		<comments>http://blog.dywicki.pl/2008/06/22/apache-servicemix-open-source-es/#comments</comments>
		<pubDate>Sun, 22 Jun 2008 18:23:35 +0000</pubDate>
		<dc:creator>Łukasz Dywicki</dc:creator>
				<category><![CDATA[ESB]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Moje publikacje]]></category>
		<category><![CDATA[ServiceMix]]></category>
		<category><![CDATA[XML]]></category>

		<guid isPermaLink="false">http://blog.dywicki.pl/?p=215</guid>
		<description><![CDATA[Jakiś czas temu, jeszcze podczas pracy w poprzedniej firmie przypadło mi zadanie podpięcia się pod magistralę usług opartą o Apache Service Mix (SMX). Był to wówczas dla mnie temat zupełnie nowy, ba nawet nie wiedziałem z czym to się je. :) Koniec końców jednak podpięcie pod ESB (Enterprises Service Bus) nie było w ogóle trudne. [...]]]></description>
			<content:encoded><![CDATA[<p>Jakiś czas temu, jeszcze podczas pracy w poprzedniej firmie przypadło mi zadanie podpięcia się pod magistralę usług opartą o <a href="http://servicemix.apache.org">Apache Service Mix</a> (SMX). Był to wówczas dla mnie temat zupełnie nowy, ba nawet nie wiedziałem z czym to się je. :) Koniec końców jednak podpięcie pod <acronym title="Enterprise Service Bus">ESB</acronym> (Enterprises Service Bus) nie było w ogóle trudne. Po jakimś czasie i drobnych przetasowaniach na płaszczyźnie zawodowej zająłem się SMX-em nie jako klient magistrali a osoba implementująca usługi na szynie a ten wpis jest drobną przeróbką prezentacji, którą przygotowałem w pracy.<br />
<span id="more-215"></span></p>
<h3>Czym jest <acronym title="Enterprise Service Bus">ESB</acronym></h3>
<p>Jednoznaczne określenie terminu <acronym title="Enterprise Service Bus">ESB</acronym> nie jest łatwe, ponieważ wokół tego tematu rozpętana została burza marketingowa. Jedni uważają je za oś <acronym title="Service Oriented Architecture">SOA</acronym> (Service Oriented Architecture) inni jako zło konieczne w dużych instytucjach.</p>
<p>Dlatego pomijając teorię przejdźmy do najistotniejszych cech, jakie oferuje <acronym title="Enterprise Service Bus">ESB</acronym>, niezależnie od producenta oraz osoby definiującej pojęcie. Sam nie chciałbym wdawać się w dyskusję na temat postrzegania i <acronym title="Enterprise Service Bus">ESB</acronym> i <acronym title="Service Oriented Architecture">SOA</acronym>. </p>
<p><img src="http://blog.dywicki.pl/wp-content/uploads/2008/06/esb.jpg" alt="" title="esb" width="500" height="378" class="aligncenter size-full wp-image-217" /><br />
<em>Źródło - <a href="http://www.codeplex.com/esb">CodePlex</a></em></p>
<p>Na załączonym wyżej obrazku widać typową strukturę logiczną w oparciu o <acronym title="Enterprise Service Bus">ESB</acronym>. Z lewej strony mamy komercyjne rozwiązanie – <a href="http://www-306.ibm.com/software/integration/wmq/">MQ Series</a> firmy <a href="http://www.ibm.com/us/">IBM</a>, dalej idąc dołem, widzimy bazę danych, serwer pocztowy a na końcu mainframe. U góry natomiast pojawiają się klienci.</p>
<h3>Ciąg dalszy</h3>
<p>Na bazie tego obrazku można powiedzieć co nieco o tym, czym owa niebieska rurka symbolizująca <acronym title="Enterprise Service Bus">ESB</acronym> jest:</p>
<ul>
<li>Jest to z pewnością centralny rejestr usług firmy, dzięki któremu nie jest konieczne wiązanie aplikacji między sobą. Wiąże się je tylko i wyłącznie z jednym elementem – z magistralą.</li>
<li>Kolejny ważny punkt, to most pomiędzy protokołami. W dobie, gdy wszyscy żyją już Web Services nie można zapomnieć o innych sposobach komunikacji – poczynając od poczciwej <a href="http://pl.wikipedia.org/wiki/CORBA">Corby</a> po kolejki JMS czy też odczyt zasobów z <acronym title="File Transfer Protocol">FTP</acronym>.</li>
<li>Transformacja komunikatów to opcjonalna czynność, której nie widać na wyżej wymienionym obrazku. Jest ona wykonywana pod maską, wewnątrz magistrali, w zależności od potrzeb. W chwili gdy mamy komunikaty z systemu A do systemu B możemy wszystko sprowadzić do jednego uniwersalnego <acronym title="Application Programming Interface">API</acronym> danych.</li>
<li>Inteligentny router informacji. Większość magistral ma coś wspólnego z pojęciem EIP, czyli <a href="http://www.enterpriseintegrationpatterns.com/">Enterprise Integration Patterns</a>. Jednym z tych wzorców jest <a href="http://www.enterpriseintegrationpatterns.com/ContentBasedRouter.html">Content Based Router</a>, to znaczy w zależności od kształtu, zawartości komunikatu, nagłówka, fragmentu, czegokolwiek możemy odbijać komunikat w różnych kierunkach. Dalej z wzorców można wymienić <a href="http://www.enterpriseintegrationpatterns.com/Filter.html">Message Filter</a>, <a href="http://www.enterpriseintegrationpatterns.com/RecipientList.html">Recipient List</a>, <a href="http://www.enterpriseintegrationpatterns.com/RoutingTable.html">Routing Slip</a>, <a href="http://www.enterpriseintegrationpatterns.com/WireTap.html">Wire Tap</a>, <a href="http://www.enterpriseintegrationpatterns.com/Sequencer.html">Splitter</a>, <a href="http://www.enterpriseintegrationpatterns.com/Resequencer.html">Resequencer</a> itd.</li>
<li>Integrator procesów biznesowych (bardziej marketingowo) – po pierwsze odwzorowanie usług magistrali do czynności biznesowych w organizacji a po drugie wsparcie dla procesorów reguł biznesowych (<a href="http://www.oasis-open.org/committees/tc_home.php?wg_abbrev=wsbpel">WS-BPEL</a>).</li>
</ul>
<h3>Service Mix jako <acronym title="Enterprise Service Bus">ESB</acronym></h3>
<p>Mając zestaw wyżej wymienionych cech możemy przejść do omówienia projektu Apache Service Mix.<br />
Może na początku kilka słów o tym, czym jest JBI, ponieważ pojawia się sam skrót, ale nie ma jego omówienia.<br />
Otóż, <a href="http://jcp.org/en/jsr/detail?id=208">JBI</a> w rozwinięciu oznacza Java Business Integration. Jest to standard przyjęty w ramach <a href="http://jcp.org/">Java Community Process</a> w celu określenia norm budowania rozwiązań <acronym title="Service Oriented Architecture">SOA</acronym> (znów buzzworld). Pomijając politykę wielkich korporacji oraz marketing przejdźmy do elementów, które standard ten określa:<br />
<img src="http://blog.dywicki.pl/wp-content/uploads/2008/06/msgflow3.png" alt="Źródło: Java.net" title="Komponenty JBI" align="center" /><br />
<em>Źródło <a href="http://download.java.net/general/open-esb/docs/jbi-admin-guide/">Open <acronym title="Enterprise Service Bus">ESB</acronym> Starter Kit</a></em></p>
<ul>
<li>Typy komponentów:
<ol>
<li>Service Engine (SE) – backend do obsługi zapytań.</li>
<li>Binding Components (BC) – frontend, do nasłuchiwania w danym standardzie.</li>
<li>Shared Libraries (SL) – kod współdzielony przez w/w komponenty.
<li>
<li>Service Assembly (SA) – zbiór usług rozumianych jako jedność przez magistralę (zwykle para BC+SE).</li>
</ol>
<li>Normalized Message Router – jest to serce rozwiązania opartego o JBI, ponieważ w nim są transportowane komunikaty. To on zapewnia przepływ informacji z komponentów bindujących do silników.</li>
<li>Message Exchange Patterns – w oparciu o definicję dla <acronym title="Simple Object Access Protocol">SOAP</acronym> JBI przewiduje następujące typy komunikatów:</li>
<ol>
<li>In-Only – tylko wejście, usługa nie zwraca żadnej odpowiedzi
<li>Rebust In-Only – zwrócony zostanie status po obsłudze zapytania bądź wyjątek.
<li>In-Out – standardowa obsługa wejście-wyjście.
<li>In Optional-Out – wejście z niewiążącą (nieobowiązkową) odpowiedzią.
    </ol>
</ul>
<p>Dostępnych jest kilka implementacji JBI:</p>
<ul>
<li><a href="https://open-esb.dev.java.net/">Open <acronym title="Enterprise Service Bus">ESB</acronym></a></li>
<li><a href="http://servicemix.apache.org">Apache Service Mix</a></li>
<li><a href="http://open.iona.com/products/enterprise-servicemix/">FUSE <acronym title="Enterprise Service Bus">ESB</acronym></a> (na bazie Service Mix)</li>
<li><a href="http://www.bostechcorp.com/products_cb_esb.htm">Bostech Chain Builder <acronym title="Enterprise Service Bus">ESB</acronym></a></li>
<li><a href="http://mule.mulesource.org/display/MULE/Home">Mule</a></li>
<li><a href="http://www.jboss.org/jbossesb/">JBoss <acronym title="Enterprise Service Bus">ESB</acronym></a></li>
<li><a href="http://www.oracle.com/products/middleware/index.html">Fusion Middleware</a></li>
<li><a href="http://www.tibco.com/software/soa/activematrix_service_bus/default.jsp">ActiveMatrix Service Bus</a></li>
</ul>
<h3>Service Mix od środka</h3>
<p>Wewnątrz Service Mix jest spięciem kilku potężnych projektów, rozwijanych od dłuższego czasu, które zdobyły już renomę i popularność. Między innymi można wyróżnić:</p>
<ul>
<li>Pierwszy z tych projektów to <a href="http://springframework.org/">Spring Framework</a>, rozwijany od bodajże 2000 roku, z powodzeniem rywalizujący z architekturami opartymi o EJB. Spring jest nie tylko mechanizmem konfiguracyjnym ale również zbiorem bardzo dobrych komponentów umożliwiających szereg operacji (bazy danych, JMS, przetwarzanie wsadowe, Web Services etc).</li>
<li>Drugi, bardzo ważny projekt to <a href="http://activemq.apache.org/">Active MQ</a>. Największa i najpopularniejsza otwarta implementacja standardu JMS. Jest on używany wewnątrz Service Mix-a jako transporter komunikatów w Normalized Message Router jak i do obsługi końcówek JMS.<br />
        - Wymieniony nieco niżej pod-projekt Active MQ to <a href="http://activemq.apache.org/camel/">Camel</a>. Jest to szkielet przeznaczony do tworzenia reguł routingu. Wspiera różnorakie transporty (<acronym title="HyperText Transfer Protocol">HTTP</acronym>, JMS, JBI, <acronym title="Microsoft">MS</acronym> MQ itp.).</li>
<li><a href="http://geronimo.apache.org/xbean/">XBean</a> jest fragmentem projektu Apache Geronimo (serwer aplikacyjny ze stajni Apache) przeznaczonym do tworzenia konfiguracji i zarządzania komponentami. Jest zbudowany w oparciu o Springa.</li>
<li><a href="http://cxf.apache.org/">Apache CXF</a> jest stosunkowo nowym projektem, który jest używany poprzez Service Mix w celu obsługi zapytań <acronym title="Simple Object Access Protocol">SOAP</acronym> (chociaż możliwe jest użycie innego komponentu).</li>
<li><a href="http://ode.apache.org/">Apache ODE</a> jest silnikiem reguł biznesowych w oparciu o WS-BPEL.</li>
<li>JBoss Drools jest kolejnym procesorem reguł biznesowych. Może być użyty do routingu. Jest dostępny plugin pozwalający na łatwą pracę z tą technologią.</li>
</ul>
<h3>Możliwości Service Mix</h3>
<p>Wyżej wymienione projekty są używane w Service Mix w celu uzyskania typowych funkcjonalności ESB:</p>
<ul>
<li><a href="http://servicemix.apache.org/servicemix-jms.html">JMS</a>, czyli obsługa kolejek</li>
<li><a href="http://servicemix.apache.org/servicemix-bpe.html">WS-BPEL</a>, obsługa reguł biznesowych</li>
<li>Web Services przy pomocy <a href="http://servicemix.apache.org/servicemix-cxf-se.html">CXF</a> jak i modułu <a href="http://servicemix.apache.org/servicemix-jsr181.html">JSR-181</a></li>
<li><a href="http://servicemix.apache.org/servicemix-saxon.html">Transformacje</a> <acronym title="eXtensible Stylesheet Language Transformations">XSLT</acronym> oraz XQuery (w oparciu o Saxona)</li>
<li><a href="http://servicemix.apache.org/servicemix-file.html">File Drop</a> to odczyt i zapis do plików dostępnych lokalnie jak i zdalnie (<a href="http://servicemix.apache.org/servicemix-ftp.html"><acronym title="File Transfer Protocol">FTP</acronym></a>)</li>
<li>Obsługa protokołu <a href="http://servicemix.apache.org/servicemix-xmpp.html">XMPP</a> pozwala na łatwą integrację z komunikatorami zbudowanymi w oparciu o Jabbera.</li>
<li>Dostęp do poczty przy pomocy modułu <a href="http://servicemix.apache.org/servicemix-mail.html">servicemix-mail</a></li>
<li>Komponenty programowe:</li>
<ul>
<li>Dają <a href="http://servicemix.apache.org/servicemix-bean.html">możliwość dopisania</a> własnych "endpointów", czyli implementacji docelowych usług bądź pośredników.</li>
<li>Dodatkowe funkcjonalności (cache, rss, walidacja)</li>
</ul>
<li><a href="http://servicemix.apache.org/servicemix-scripting.html">Języki skryptowe</a> (min <a href="http://groovy.codehaus.org/">Groovy</a>)</li>
</ul>
<h3><acronym title="Enterprise Service Bus">ESB</acronym> – dlaczego Open Source</h3>
<p>Wybór Service Mix-a nie był podyktowany przypadkiem. Jest to bowiem najpopularniejsze tego typu rozwiązanie z otwartym kodem źródłowym. Co więcej, nie jest to projekt rozwijany przez osoby bez doświadczenia, pozostawiony bez wsparcia.<br />
Otwarty kod ułatwia przede wszystkim adaptację tego rozwiązania do potrzeb organizacji a nie odwrotnie – organizacji do potrzeb magistrali. W razie potrzeb jesteśmy w stanie dopisać własne komponenty, obsługę mniej standardowych protokołów na bazie dostarczonych interfejsów czy to w Service Mix czy to w Camelu.<br />
Przyjęte standardy gwarantują ciągłość rozwoju oraz ułatwiają integrację (<a href="http://java.sun.com/javase/technologies/core/mntr-mgmt/javamanagement/">JMX</a> umożliwia łatwe podpięcie konsoli administracyjnej), podczas gdy <a href="http://en.wikipedia.org/wiki/J2EE_Connector_Architecture">J2EE Connector Architecture</a> definiuje kontrakty (zarządzanie połączeniami, transakcjami, bezpieczeństwem).<br />
Nie bez znaczenia jest również koszt, jaki organizacja ponosi w przypadku zdecydowania się na otwarte rozwiązanie. Rozpoczęcie prac z Service Mix-em kosztuje 0 PLN. Każdy, bez rejestracji, podawania jakichkolwiek danych może pobrać źródła albo gotowe dystrybucje i uruchomić je na swoim komputerze. W chwili gdy istnieje takie zapotrzebowanie, organizacja posiada kompetencje i skromny budżet to taka konfiguracja początkowo jest optymalna. Z biegiem czasu gdy zaistnieje konieczność wsparcia czy szkoleń to są one oferowane przez firmę IONA, która jest zaangażowana w rozwój Service Mix-a.</p>
<h3>Service Mix a bezpieczeństwo</h3>
<p>Większość, jeśli nie wszystkie rozwiązania w Javie, które wiążą się z kryptografią są oparte na JCA – <a href="http://java.sun.com/javase/6/docs/technotes/guides/security/crypto/CryptoSpec.html">Java Cryptography Architecture</a>. Jest to zestaw interfejsów oraz ich implementacji zawierający implementację najpopularniejszych algorytmów kryptograficznych jak i <acronym title="Application Programming Interface">API</acronym> umożliwiające tworzenie własnych rozszerzeń (<a href="http://java.sun.com/javase/technologies/security/">JCE</a>).<br />
Standard autoryzacji i uwierzytelniania w Javie to JAAS (<a href="http://java.sun.com/javase/6/docs/technotes/guides/security/jaas/JAASRefGuide.html">Java Authentication and Authorization Service</a>). W oparciu o niego jest budowanych większość rozwiązań związanych z bezpieczeństwem. Nawet największe alternatywy takie jak <a href="http://www.acegisecurity.org/">Acegi Security</a> (obecnie Spring Security posiadają adaptery integrujące je ze standardem). Przy użyciu dostępnych interfejsów możliwe jest dostarczenie własnej implementacji usługi obsługującej autoryzację bądź uwierzytelnianie użytkowników/systemów.<br />
Bezpieczeństwo usług sieciowych jest zależne od wybranego komponentu Service Mix. Pełne wsparcie dla WS-Security oferują komponenty zbudowane w oparciu o Apache CXF (szyfrowanie, podpisywanie komunikatów). Z innych standardów CXF wspiera także WS-Policy, WS-Addressing.<br />
Szyfrowane połączenia są łatwe do uzyskania przy pomocy komponentu <a href="http://servicemix.apache.org/servicemix-http.html">servicemi-http</a>.<br />
Dostępne zabezpieczenia na poziomie wirtualnej maszyny Javy to certyfikowanie (podpisywanie) kodu modułów oraz konfiguracja Security Managera (umożliwia wyłączenie dostępu do pakietów/klas/metod).</p>]]></content:encoded>
			<wfw:commentRss>http://blog.dywicki.pl/2008/06/22/apache-servicemix-open-source-es/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>mod_rewrite plus zmienne z GET</title>
		<link>http://blog.dywicki.pl/2006/02/21/mod_rewrite-plus-zmienne-z-get/</link>
		<comments>http://blog.dywicki.pl/2006/02/21/mod_rewrite-plus-zmienne-z-get/#comments</comments>
		<pubDate>Tue, 21 Feb 2006 13:26:56 +0000</pubDate>
		<dc:creator>Łukasz Dywicki</dc:creator>
				<category><![CDATA[Apache]]></category>

		<guid isPermaLink="false">http://blog2.dywicki.pl/2006/02/21/mod_rewrite-plus-zmienne-z-get/</guid>
		<description><![CDATA[Dzisiaj miałem nietypowy problem - chciałem stworzyć sobie obsługę mod_rewrite ale nie babrać się z wyciąganiem zmiennych które był w żądanym adresie, dlatego też udałem się do google.pl w poszukiwaniu dodatkowych flag, które można ustawiać. Znalazłem bardzo fajną stronkę z kartą podręczną do mod_rewrite - http://www.ilovejackdaniels.com/cheat-sheets/mod_rewrite-cheat-sheet/ jest ich tam więcej - css, php, javascript, html, [...]]]></description>
			<content:encoded><![CDATA[<p>Dzisiaj miałem nietypowy problem - chciałem stworzyć sobie obsługę mod_rewrite ale nie babrać się z wyciąganiem zmiennych które był w żądanym adresie, dlatego też udałem się do google.pl w poszukiwaniu dodatkowych flag, które można ustawiać. Znalazłem bardzo fajną stronkę z kartą podręczną do mod_rewrite - http://www.ilovejackdaniels.com/cheat-sheets/mod_rewrite-cheat-sheet/ jest ich tam więcej - css, php, javascript, html, mysql. A moje rozwiązanie wygląda w następujący sposób:<br />
<code>RewriteEngine  On</code></p>
<p>RewriteBase    /z-tego-adresu/<br />
RewriteCond    %{REQUEST_URI} !^.*\.(css|png|gif|jpe?g|php|js)$<br />
RewriteRule    ^.*$ /z-tego-adresu/index.php?%{REQUEST_URI} [QSA,L]<br />
Oczywiście wymaga dotarcia i obsługi w kodzie, ale GET jest bez zmian.. i to najważniejsze :)</p>]]></content:encoded>
			<wfw:commentRss>http://blog.dywicki.pl/2006/02/21/mod_rewrite-plus-zmienne-z-get/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>
