Java vevtænastu vegleiðing

Niðanfyri verður eitt einfalt Java-dømi gjøgnumgingið, sum vísur hvussu ein veitaratænasta kann mennast til Heldina.

Málið er at menna ein web-tænastu við funktiónini addNumbers(a,b) sum svarar við úrslitinum a+b.

Gjøgnumgongdin byggur á tilfarið frá Java-workshoppini um Heldina, men útgreinar nærri hvørji stig eru neyðugt fyri at fáa ment ein veitara.

Tak niður fílur til menning av vevtæanstu í JAVA her

Karmar

Áðrenn tað er møguligt at kalla ein veitari umvegis Heldina, so er neyðugt at fáa skrásett og góðkent íbinding av vevtænastuveitara í trygdarambætaranum.

Vegleiðingar hesum viðvíkandi eru at finna á síðuni http://www.talgildu.fo/heldin/heldin/

Í samband við hetta dømi havi eg skrásett og fingið góðkent ein veitari við navninum kli-util-v1 skrásettur í test-trygdarambætaranum hjá Klintra. Tá skrásetingin er góðkend sæst hetta í umsitingarskipanini hjá trygdarambætaranum.

Fyri at síggja hvussu skrásetingin sæst í trygdarambætaranum, so havi eg niðanfyri loggað á umsitinginasíðuna hjá trygdarambætaranum. Í valmyndini havi eg valt "Databases/Registries".

Nú sæst eitt yvirlit yvir skrásettar vevtænastuveitarar. Um veitarin ikki var góðkendur, so hevði veitara-navnið verið litað reytt.

Umhvørvi

Til menningina er brúkt fylgjandi amboð og umhvørvi á eini Windows 10 farteldu:

  • Java 1.8.101
  • Eclipse Luna
  • Apache CXF 3.1.11
  • Apache Tomcat 7.0.75
  • SoapUI 5.2.1

Harumframt havi eg havt ein servara tøkan, sum er atkomiligur frá trygdarambætaranum. Tað er her eg má koyra vevtænastuna soleiðis at hon kann røkkast av trygdarambætaranum.

Um og hvussu hetta er neyðygt, avhongur í hvørjum einstøkum førum av hvar trygdarambætarin er installeraður.

Stovnað prosjekt

Tendra Eclipse og stovna eitt nýtt prosjekt. Í valmyndini velur tú "File->New->Dynamic Web Project".

  • Gev prosjektinum navn "HeldinVeitari".
  • Vel eina "Project Location"
  • Peika á Apache Tomcat 7 sum "Target runtime"
  • Trýst á ”Finish” soleiðis at prosjektið verður stovnað

Stovna WSDL-fílu

Dokumentatiónin av X-Road viðmælur at vevtænastan fyrst verður definera í WSDL-skjalinum. Eisini nevnt Contract-First.

Afturat vanligu WSDL 1.1 spesifikatiónini, so krevur Heldin at nøkur serlig name space og feltir sum eru ásett í WSDL-skjalinum (sí http://x-road.ee/docs/eng/x-road_service_protocol.pdf.

Ein skabelón er at finna á fylgjandi leinkji: https://github.com/Klintra/HeldinProducerDemo/blob/master/WSDL%20template/heldinWsdlTemplate.wsdl

Kopiera alt innihaldið frá wsdl-skabelóni til ný-stovnaðu WSDL-fíluna.

WSDL-fílan skal nú tillagast til vevtænastu-veitaran og funktiónin configurerast við funktiónini addNumbers.

Áset veitara-navn í WSDL-fílu

Fyrst skal navnið á veitara-tænastuni ásetast í WSDL-fíluna.

Hetta er á øllum teimum støðum har tað í skabelónini stendur <!--PRODUCER-->.

Brúka "Find/Replace" í Eclipse og broyt <!--PRODUCER--> til kli-util-v1. Hetta skal viðføra 5 rættingar í WSDL-skjalinum.

Tillaga WSDL-fílu, schema

Næsta broytingin í WSDL-fíluni er at áseta schema-broytingar til request og response elementini.

XML-kodan niðanfyri vísur WSDL-elementini fyri addNumbers og addNumbersResponse.

Legg merki til:

  • xrd:title feltini, sum eru frá x-road namespace'inum.
  • Request-parametrarnir verða endurtiknir í addNumbersResponse definitiónini.

Kopiera WSDL-koduna niðanfyri inn í WSDL-fíluna har tað stendur Insert implementation specific schema:

WSDL-kodan at kopiera:

<element name="addNumbers">
<complexType>
  <sequence>
	<element name="request">
	  <complexType>
		<sequence>
		  <element name="firstInteger" type="integer">
			<annotation>
			  <appinfo>
				<xrd:title xml:lang="en">First integer in addition</xrd:title>
			  </appinfo>
			</annotation>
		  </element>
		  <element name="secondInteger" type="integer">
			<annotation>
			  <appinfo>
				<xrd:title xml:lang="en">Second integer in addition</xrd:title>
			  </appinfo>
			</annotation>
		  </element>
		</sequence>
	  </complexType>
	</element>
  </sequence>
</complexType>
</element>
<element name="addNumbersResponse">
<complexType>
  <sequence>
	<element name="request">
	  <complexType>
		<sequence>
		  <element name="firstInteger" type="integer">
		  </element>
		  <element name="secondInteger" type="integer">
		  </element>
		</sequence>
	  </complexType>
	</element>
	<element name="response">
	  <complexType>
		<sequence>
		  <element minOccurs="0" name="faultCode" type="xrd:faultCode"/>
		  <element minOccurs="0" name="faultString" type="xrd:faultString"/>
		  <element name="result" type="integer">
			<annotation>
			  <appinfo>
				<xrd:title xml:lang="en">Result of addition</xrd:title>
			  </appinfo>
			</annotation>
		  </element>
		</sequence>
	  </complexType>
	</element>
  </sequence>
</complexType>
</element>

Tillaga WSDL-fílu, messages

Næst skulu message-elementini kopierast inn í WSDL-fíluna har tað stendur Insert implementation specific messages:

WSDL-kodan at kopiera:

<message name="addNumbers">
	<part name="body" element="tns:addNumbers"/>
</message>
<message name="addNumbersResponse">
	<part name="body" element="tns:addNumbersResponse"/>
</message>

Tillaga WSDL-fílu, portType/operation

Undir portType í WSDL-skjalinum skal nú definerast operatiónin addNumbers.

Kopiera WSDL-koduna niðanfyri inn har sum tað stendur insert implementation specific operations.

WSDL-koda at kopiera:

	<operation name="addNumbers">
		<documentation><xrd:title>addNumbers</xrd:title></documentation>
		<input message="tns:addNumbers"/>
		<output message="tns:addNumbersResponse"/>
	</operation>

Tillaga WSDL-fílu, binding/operation

Til seinast skal operatiónin addNumbers eisini skrásetast sum ein SOAP-tænasta í WSDL-skjalinum.

Kopiera koduna niðanfyri inn í WSDL-fíluna har tað stendur Insert implementation specific binding.

Legg merki til:

  • Serliga xrd:version felti
  • Definitiónina av header-feltinum í bæði input og output pørtunum.

WSDL-kodan at kopiera:

	<operation name="addNumbers">
		<soap:operation soapAction="" style="document"/>
		<xrd:version>v1</xrd:version>
		<input>
			<soap:body parts="body" use="literal"/>
			<soap:header message="tns:standardheader" part="consumer" use="literal"/>
			<soap:header message="tns:standardheader" part="producer" use="literal"/>
			<soap:header message="tns:standardheader" part="userId" use="literal"/>
			<soap:header message="tns:standardheader" part="id" use="literal"/>
			<soap:header message="tns:standardheader" part="service" use="literal"/>
		</input>
		<output>
			<soap:body parts="body" use="literal"/>
			<soap:header message="tns:standardheader" part="consumer" use="literal"/>
			<soap:header message="tns:standardheader" part="producer" use="literal"/>
			<soap:header message="tns:standardheader" part="userId" use="literal"/>
			<soap:header message="tns:standardheader" part="id" use="literal"/>
			<soap:header message="tns:standardheader" part="service" use="literal"/>
		</output>
	</operation>

Knýta Apache CXF til prosjekt

Áðrenn vit fara at framleiða Java-kodu frá WSDL-fíluni, er neyðugt at knýta CXF til Eclipse-prosjektið.

Høgra-klikk á prosjektið í Eclipse og vel "Properties".

Leita eftir "Java Build Path" sum myndin vísur niðanfyri.

Vel "Add Library" og "CXF Runtime".

Á næsta skermi er helst neyðugt at stovna eina tilvísing til Apache CXF.

Trýst á "Configure installed libraries" og vel "Add...".

Vel faldaran har Apache CXF 3.1.11 er installera og trýst á "Finish". Á næsta skerminum setur tú flugubein við nýggju tilvísingina til Apache CXF 3.1.11 og trýstur á "Ok".

Vel tilvísingina til "Apache CXF 3.1.11" og trýst á "Finish".

Nú skuldi yvirlitið yvir Libraries sæð soleiðis út:

Framleiða Java-fílur frá WSDL

Út frá kontraktini í WSDL-fíluni kunnu vit nú brúka wsdl2java frá Apache CXF at framleiða java-koduna, sum verður grundarlagið undir SOAP veitaratænastuni.

Í hesum døminum gangið eg út frá at Apache CXF er installera í faldaran c:\tools\apache-cxf-3.1.11\

Opna Windows cmd-promptin og far til rót-faldaran í Eclipse-prosjektinum og koyr fylgjandi kommandi:

c:\tools\apache-cxf-3.1.11\bin\wsdl2java.bat -d src -p http://kli-util-v1.x-road.eu/producer=eu.x_road.kli_util_v1.producer -impl -validate -exsh true -dns true -dex true -autoNameResolution -verbose -defaultValues -fe jaxws21 -db jaxb -wv 1.1 WebContent\wsdl\heldinProducerDemo.wsdl

Niðanfyri sæst hvussu úrslitið er á skerminum aftaná at kommandoin er koyrd:

Dagfør fílurnar í Eclipse-prosjektinum eftirkanna at framleidda kodan liggur á røttum stað.

Skriva java-koduna til veitaratænastuna

Vit eru nú komin hartil, at klárt er at skriva koduna til funktiónina addNumbers.

Harumframt skulu vit eisini skriva funktiónina listMethods, sum Heldin krevur skal lista tær funktiónir sum veitara-tænastan skal bjóða fram á Heldini.

Funktiónin addNumbers

Opna fíluna eu.x_road.kli_util_v1.producer.HeldinProducerPortImpl og innset koduna niðanfyri í staðin fyri koduna sum wsdl2java hevur framleitt til funktiónina addNumbers:

public void addNumbers(eu.x_road.kli_util_v1.producer.AddNumbers.Request request, java.lang.String consumer, 
	java.lang.String producer, java.lang.String userId, java.lang.String id, java.lang.String service, 
	javax.xml.ws.Holder<eu.x_road.kli_util_v1.producer.AddNumbersResponse.Request> request1, 
	javax.xml.ws.Holder<eu.x_road.kli_util_v1.producer.AddNumbersResponse.Response> response, 
	javax.xml.ws.Holder<java.lang.String> consumer1, javax.xml.ws.Holder<java.lang.String> producer1, 
	javax.xml.ws.Holder<java.lang.String> userId1, javax.xml.ws.Holder<java.lang.String> id1, 
	javax.xml.ws.Holder<java.lang.String> service1) { 
    LOG.info("Executing operation addNumbers");
    try {
    	int firstInteger = request.getFirstInteger().intValue();
    	int secondInteger = request.getSecondInteger().intValue();
    	int result = firstInteger + secondInteger;
    	
    	eu.x_road.kli_util_v1.producer.AddNumbersResponse.Request request1Value = new eu.x_road.kli_util_v1.producer.AddNumbersResponse.Request();
        request1Value.setFirstInteger(new java.math.BigInteger(Integer.toString(firstInteger)));
        request1Value.setSecondInteger(new java.math.BigInteger(Integer.toString(secondInteger)));
        request1.value = request1Value;

        eu.x_road.kli_util_v1.producer.AddNumbersResponse.Response responseValue = new eu.x_road.kli_util_v1.producer.AddNumbersResponse.Response();
        responseValue.setResult(new java.math.BigInteger(Integer.toString(result)));
        response.value = responseValue;

        consumer1.value = consumer;
        producer1.value = producer;
        userId1.value = userId;
        id1.value = id;
        service1.value = service;
    } catch (java.lang.Exception ex) {
        ex.printStackTrace();
        throw new RuntimeException(ex);
    }
}

Ger síðani tað saman fyri funktiónina listMethods.

public eu.x_road.xsd.x_road.ListMethodsResponse listMethods(java.lang.Object body) { 
    LOG.info("Executing operation listMethods");
    System.out.println(body);
    try {
        eu.x_road.xsd.x_road.ListMethodsResponse _return = new eu.x_road.xsd.x_road.ListMethodsResponse();
        eu.x_road.xsd.x_road.ListMethodsResponse.Response _returnResponse = new eu.x_road.xsd.x_road.ListMethodsResponse.Response();
        java.util.List<java.lang.String> _returnResponseItem = new java.util.ArrayList<java.lang.String>();
        java.lang.String _returnResponseItemVal1 = "kli-util-v1.addNumbers.v1";
        _returnResponseItem.add(_returnResponseItemVal1);
        _returnResponse.getItem().addAll(_returnResponseItem);
        _return.setResponse(_returnResponse);
        return _return;
    } catch (java.lang.Exception ex) {
        ex.printStackTrace();
        throw new RuntimeException(ex);
    }
}

Legg merki til navna-mynstri sum verður til navnið hjá funktiónini í Heldini kli-util-v1.addNumbers.v1.

  • Fyrsti partur av navninum er navnið á veitaratænastuni, soleiðis sum vit hava kalla hana í Heldini.
  • Síðani kemur navni á sjálvari funktiónini
  • Til seinast kemur útgávu-nummari, sum eisini er at finna aftur í WSDL-fíluni.

Harumframt sæst í addNumbers hvussu virðini í request-headaranum verður kopiera til response-headaran.

Klárgering áðrenn tænastan kann koyra í Tomcat

Áðrenn vit kunnu royndarkoyra tænastuna í Tomcat, skulu vit fyrst klárgera Tomcat, og síðani klárgera tvær konfiguratións-fílur:

  • web.xml til konfigurerar Tomcat
  • cxf-beans.xml sum konfigurerar CXF

Tomcat

Opna yvirlitið yvir servara í Eclipse við at trýsta á "Window->Show View->Servers".

Trýst á leinkjuna fyri at stovna nýggjan servara.

Vel Tomcat 7 og trýst á "Next".

Peika á faldaran har Apache Tomcat 7 er installera og trýst á "Finish".

web.xml

Høgra-klikk á prosjektið, og trýst á "Java EE Tools -> Generate Deployment Descriptor Stub":

Kopiera koduna niðanfyri inn í web.xml fíluna sum er at finna í faldaranum "WebContent/WEB-INF":

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" version="3.0">
  <display-name>HeldinProducerDemo</display-name>
  <welcome-file-list>
	<welcome-file>index.html</welcome-file>
	<welcome-file>index.htm</welcome-file>
	<welcome-file>index.jsp</welcome-file>
	<welcome-file>default.html</welcome-file>
	<welcome-file>default.htm</welcome-file>
	<welcome-file>default.jsp</welcome-file>
  </welcome-file-list>
  <servlet>
	<servlet-name>CXFServlet</servlet-name>
	<servlet-class>
		org.apache.cxf.transport.servlet.CXFServlet
	</servlet-class>
	<init-param>
	  <param-name>config-location</param-name>
	  <param-value>/WEB-INF/cxf-beans.xml</param-value>    
	</init-param>
	<load-on-startup>1</load-on-startup>
  </servlet>
 
  <servlet-mapping>
	<servlet-name>CXFServlet</servlet-name>
	<url-pattern>/services/*</url-pattern>
  </servlet-mapping>
</web-app>

cxf-beans.xml

Stovna fíluna cxf-beans.xml í faldaran "WebContent/WEB-INF" og kopiera koduna niðanfyri inn í fíluna:

<?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-2.5.xsd http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd">
	<import resource="classpath:META-INF/cxf/cxf.xml" />
	<!-- import resource="classpath:META-INF/cxf/cxf-extension-soap.xml" / -->
	<import resource="classpath:META-INF/cxf/cxf-servlet.xml" />
	<jaxws:endpoint xmlns:tns="http://kli-util-v1.x-road.eu/producer"
		id="heldinporttype" implementor="eu.x_road.kli_util_v1.producer.HeldinProducerPortImpl"
		wsdlLocation="wsdl/heldinVeitari.wsdl" endpointName="tns:HeldinProducerPort"
		serviceName="tns:HeldinProducerSoapService" address="/HeldinProducer">
		<jaxws:features>
			<bean class="org.apache.cxf.feature.LoggingFeature" />
		</jaxws:features>
	</jaxws:endpoint>
</beans>

Royndarkoyra tænastu

Nú er klárt at royndarkoyra tænastuna í Tomcat.

  • Høgraklikk á prosjektið í Eclipse og vel "Run As -> Run on Server"
  • Vel Tomcat í yvirlitnum
  • Trýst á "Finish"

Tá servarin koyrir, opna so síðuna

http://localhost:8080/HeldinVeitari/services

Hetta skuldu nú víst:

WSDL fílan er at finna á http://localhost:8080/HeldinVeitari/services/HeldinProducer?wsdl

Kalla tænastuna lokalt

Nú er møguligt kalla tænastuna frá t.d. SoapUI OpenSource

Opna SoapUI og vel "File->New SOAP Project"

Gev prosjektinum eitt navn og skriva addressuna á WSDL-fíluni í feltið "Initial WSDL".

Stovna nú ein nýggjan SOAP fyrispurning við at dupult-klikkja á "AddNumbers->Request1" sum víst niðanfyri:

Í løtuni er líkamikið hvat vit skriva í headaran, men skriva tvey tøl í parametur-feltini hjá addNumbers, og kalla SOAP-tænastuna við at trýsta á grøna pílin.

Úrslitið skuldi verið sum á myndini niðanfyri:

Kalla tænastu frá Heldini

Næsta stigið er at koyra tænastuna soleiðis at vit kunnu kalla hana frá Heldini.

Til hetta krevst at tænastan koyrir á einari maskinu sum kann kallast frá trygdarambætara.

Í slíkum førum kann verða neyðugt at pakka applikatiónina niður í eina .war-fílu og koyra hana á einari aðrari maskinu.

Í hesum døminum havi eg innstallera Tomcat á ein servara sum er atkomiligur frá trygdarambætaranum.

Fremst í hesi vegleiðing nevndu vit skrásetingina av einum góðkendum vevtænastuveitara í trygdarambætaranum.

Loggað aftur á umsitingina av trygdarambætaranum og í valmyndini velur tú "Databases/Registries". Vel trygdarambætaran (í mínum føri kli-util-v1) sum skal verða brúkari av vev-tænastuni, og trýst á "Adapter Settings".

Í mínum føri brúki eg sama trygdarambætara sum brúkara

Á hesum skerminum er nú møguligt at uppseta tilvísingarnar til vævtænastuna.

Tá hetta er gjørt trýstur tú á "Save" og vendur aftur til yvirlitið "Databases".

Fyri at geva tær sjálvum atgongd at kalla tænastuna er neyðugt við uppseting í "Access Rights".

Rættindini verða ásett við at velja tína organisatión, og síðani tað funktiónina sum skal hava atgongd at kalla veitaratænastuna.

Um tín organisatión ikki sæst í listanum, trýst so á "Add" og síðani flugubein í "Display Organizations" ovast til høgru. Vel tína organization og trýst á "Save" Nú skuldi organsatiónin verið sjónlig

Um funktiónin addNumbers ikki sæst í listanum til høgru, royn so at trýsta á knappin "Refresh" niðast til høgru.

Tá rættindini eru upp á pláss, skuldi verið møguligt at kalla tænastuna umvegis heldini.

Far aftur til SoapUI og vel "File->New SOAP Project".

Í mínum førum skal eg nú peika til fylgjandi URL fyri at lesa WSDL-fíluna:

 http://trygdarambætari/cgi-bin/uriproxy?producer=kli-util-v1

Í hesum førinum er trygdarambætari navnið ella ip-addressan á trygdarambætaranum sum er brúkari av vevtænastuni.

Stovna aftur ein addNumbers-request, men minst til at rætta URL'in soleiðis at hann peikar á "/cgi-bin/consumer_proxy" á trygdarambætara sum er vevtænastu-brúkari. Í mínum føri er URL'urin:

http://trygdarambætari/cgi-bin/consumer_proxy

Dømi niðanfyri vísur fyrispurning og svar, av einum kallið yvir Heldina:

Far beinleiðis til

Spurningar um evnið?