Cilj ovog projekta je prikazati načina na koji se može implementirati komunikacija sa pristupnom točkom. Sam projekt sadrži već gotovu implementaciju jednog scenarija u obliku sekvencijalnih JUnit 5 testova. Testni scenariji se mogu vidjeti u klasi PristupnaTockaTest.
Kreriana mrežna adresa na Pristupnoj Točki, te dodijeljeni servisni i aplikativni korisnički računi sa lozinkama
Pristup internetu
Alat za upravljanje certifikatima po izboru:
IDE po izboru
VS Code sa podškom za Java-u
Projekt se može kreirati na više načina, koristeći IDE, terminal ili ručno. Za naš projekt je bitno sljedeće:
pti-hello-world
hr.pti.hw
App.java
pom.xml
pti-hello-world ├── pom.xml └── src └── main └── java └── hr └── pti └── hw └── App.java
package hr.pti.hw; public class App { public static void main(String[] args) {} }
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>hr.pti.hw</groupId> <artifactId>pti-hello-world</artifactId> <version>1.0.0</version> <packaging>jar</packaging> <properties> <exec.mainClass>hr.pti.hw.App</exec.mainClass> </properties> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.10.1</version> <configuration> <source>11</source> <target>11</target> </configuration> </plugin> </plugins> </build> </project>
Za provjeru da je projekt u redu, probajte izvršiti sljedeću naredbu u terminalu:
# Za ovu naredbu je preduvjet da je Apache Maven dostupan u terminalu # Alternativa je da jednostavno probate pokrenuti App.java klasu iz IDE-a mvn exec:java
Za komunikaciju sa pristupnom točkom potrebno je uspostaviti tzv. SSL handshake. Za to nam je potreban trusted certifikat kojeg možemo skinuti direktno sa pristupne točke putem npr. browser-a (skinuti certifikati imaju ekstenziju .cer, .pem isl.). Taj certifikat je potom potrebno pohraniti u tzv. Java truststore koji se koristi prilikom uspostave HTTP konekcije sa pristupnom točkom.
Ukoliko želite preskočiti ovaj korak, projekt sadrži već pripremljen truststore sa svim certifikatima koje je moguce skinuti sa pristupne točke. Password za taj truststore je changeit
. Sve certifikate (za komunikaciju je potreban samo jedan, onaj sa CN=*.pristupnatocka.hr) koje možete skinuti sa testne pristupne točke također možete pronaći u direktoriju cert.
Kreirani truststore potrebno je smjesiti u direktorij src/main/resources
pti-hello-world ├── pom.xml └── src └── main ├── java │ └── hr │ └── pti │ └── hw │ └── App.java └── resources └── truststore.jks
Tehnički gledano ovaj korak nije potreban da bi se razmjenjivale SOAP poruke ali uvelike olakšava posao konverzije XML poruka u Java objekte što olakšava korištenje i slanje samih poruka u kodu. XML primjere poruka koje u konačnici nastaju iz generiranih Java klasa možete vidjeti u direktoriju soap-messages.
WSDL testne pristupne točke dostupan je na wsdl url.
WSDL je potrebno pohraniti kao datoteku s nazivom npr. backend.wsdl
u direktorij src/main/resources
. Projekt sadrži već pripremljenu backend.wsdl datoteku.
pti-hello-world ├── pom.xml └── src └── main ├── java │ └── hr │ └── pti │ └── hw │ └── App.java └── resources ├── backend.wsdl └── truststore.jks
backend.wsdl
datotekePostoji nekoliko načina na koji se mogu generirati Java klase koje će nam služiti za komunikaicju sa pristupnom točkom. Mi ćemo u našem primjeru koristiti Apache Maven plugin cxf-codegen-plugin.
Ažurirajte pom.xml datoteku na sljedeći način:
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>hr.pti.hw</groupId> <artifactId>pti-hello-world</artifactId> <version>1.0.0</version> <packaging>jar</packaging> <properties> <exec.mainClass>hr.pti.hw.App</exec.mainClass> <cxf.version>4.0.0</cxf.version> </properties> <dependencies> <dependency> <groupId>org.apache.cxf</groupId> <artifactId>cxf-rt-frontend-jaxws</artifactId> <version>${cxf.version}</version> </dependency> <dependency> <groupId>org.apache.cxf</groupId> <artifactId>cxf-rt-transports-http</artifactId> <version>${cxf.version}</version> </dependency> <dependency> <groupId>org.junit.jupiter</groupId> <artifactId>junit-jupiter-api</artifactId> <version>5.9.0</version> <scope>test</scope> </dependency> <dependency> <groupId>org.junit.jupiter</groupId> <artifactId>junit-jupiter-params</artifactId> <version>5.9.0</version> <scope>test</scope> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.10.1</version> <configuration> <source>11</source> <target>11</target> </configuration> </plugin> </plugins> </build> </project>
Za generiranje Java klasa pokrenite Maven naredbu
mvn clean compile
Ukoliko je sve dobro prošlo, u direktoriju src/main/java
bi se trebali pojaviti novi direktoriji backend
i org
unutar kojih se nalaze generirane Java klase.
U direktoriju src/main/java/hr/pti/hw
krerirajte Java klasu PTClient.java
.
Ova klasa je samo bazični primjer kako bi neka konfiguracija klijenta mogla izgledati.
Klase koje su koriste u kodu (počinju sa backend.ecodex.org) su nastale generiranje koda temeljem backend.wsdl
datoteke.
package hr.pti.hw; import backend.ecodex.org._1_1.BackendInterface; import backend.ecodex.org._1_1.BackendService11; import jakarta.xml.ws.BindingProvider; import java.io.IOException; import java.io.InputStream; import java.security.GeneralSecurityException; import java.security.KeyStore; import javax.net.ssl.TrustManagerFactory; import jakarta.xml.ws.soap.SOAPBinding; import org.apache.cxf.configuration.jsse.TLSClientParameters; import org.apache.cxf.endpoint.Client; import org.apache.cxf.frontend.ClientProxy; import org.apache.cxf.jaxws.JaxWsProxyFactoryBean; import org.apache.cxf.transport.http.HTTPConduit; public final class PTClient { public static BackendInterface buildClient( String url, String user, String userPassword, InputStream truststore, String truststorePassword) throws IOException, GeneralSecurityException { JaxWsProxyFactoryBean proxyFactory = new JaxWsProxyFactoryBean(); proxyFactory.setServiceClass(BackendService11.class); BackendInterface backendInterface = proxyFactory.create(BackendInterface.class); Client client = ClientProxy.getClient(backendInterface); HTTPConduit httpConduit = (HTTPConduit) client.getConduit(); TLSClientParameters tlsCP = new TLSClientParameters(); tlsCP.setDisableCNCheck(true); // Koristimo truststore koji smo kreirali u koraku 2. // Učitaj store KeyStore keyStore = KeyStore.getInstance("JKS"); keyStore.load(truststore, truststorePassword.toCharArray()); // Iz store povuci trusted certifikate i koristi ih za TLS TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); tmf.init(keyStore); tlsCP.setTrustManagers(tmf.getTrustManagers()); httpConduit.setTlsClientParameters(tlsCP); BindingProvider bindingProvider = (BindingProvider) backendInterface; bindingProvider.getRequestContext().put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, url); bindingProvider.getRequestContext().put(BindingProvider.USERNAME_PROPERTY, user); bindingProvider.getRequestContext().put(BindingProvider.PASSWORD_PROPERTY, userPassword); SOAPBinding soapBinding = (SOAPBinding) bindingProvider.getBinding(); soapBinding.setMTOMEnabled(true); return backendInterface; } }
U našem slučaju, pozvat ćemo metodu getStatus
koja vraća status za zatraženi messageID
.
Ažurirajte App.java
klasu na sljedeći način:
package hr.pti.hw; import backend.ecodex.org._1_1.BackendInterface; import backend.ecodex.org._1_1.MessageStatus; import backend.ecodex.org._1_1.StatusFault; import backend.ecodex.org._1_1.StatusRequest; import java.io.IOException; import java.security.GeneralSecurityException; import java.util.UUID; public class App { public static void main(String[] args) throws IOException, GeneralSecurityException, StatusFault { // Koristimo PTClient.java klasu iz prethodnog koraka BackendInterface client = PTClient.buildClient( // Testna pristupna točka tenanta jpt99901 // Na svim mjestima zamijenite jpt99901 sa svojim identifikatorom "https://jpt99901.test.pristupnatocka.hr/ws", // Dodijeljeni servisni korisnik "jpt99901", // Lozinka dodijeljenog servisnog korisnika "Password123456789!", App.class.getResourceAsStream("/truststore.jks"), "changeit"); // Kreiraj poruku StatusRequest statusRequest = new StatusRequest(); statusRequest.setMessageID(UUID.randomUUID().toString()); // Zatraži status poruke od pristupne točke MessageStatus status = client.getStatus(statusRequest); // S obzirom na to da smo zatražili status poruke sa messageID koji ne postoji, // pristupna točka bi trebala vratiti odgovor NOT_FOUND System.out.println(status); } }
Program pokrenite iz IDE-a ili koristeći Apache Maven naredbu:
mvn exec:java
Primjere kreiranja i slanja ostalih vrsta poruka možete vidjeti u PristupnaTockaTest.java klasi.
Testni scenarij prikazuje slanje poruke iz jedne pristupne točke na drugu. Samo slanje poruke je konfigurabilno putem sistemskih varijabli.
# URL pristupne točke
pt.url=
# ID inicijatora na pristupnoj točki
pt.from=
# ID primatelja na pristupnoj točki
pt.to=
# Lozinka korisnika koji šalje poruku
pt.password=
# Primjer pokretanja testnog scenarija se pokreće sljedećom Apache Maven naredbom # Zamijenite jpt99901 sa svojim identifikatorom i upotrijebite dodijeljenu lozinku mvn \ -Dpt.url="https://jpt99901.test.pristupnatocka.hr/ws" \ -Dpt.from=jpt99901 \ -Dpt.to=jpt99901 \ -Dpt.password=Password123456789! \ compile test
Poruka koja se šalje je asice-sample.asice i možete ju otvorite sa nekim alatom koji zna raditi sa .zip
arhivama kao npr. 7-zip isl.
Da bi uspješno testirali slanje poruke iz vlastitog sustava možete koristiti dostupnu testnu pristupnu točku koja sadrži predefiniranog tenanta kojem možete poslati poruku.
URL - mrežna adresa | PartyId |
---|---|
https://jpt99901.test.pristupnatocka.hr/ws | jpt99901 |
PartyId je obavezni dio mrežne adrese pristupne točke. Iz svake mrežne adrese može se dobiti i pripadni identifikator (PartyId), tj. vlasnik mrežne adrese.