aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/clients/zmr/ZmrAddressSoapClient.java283
-rw-r--r--eidas_modules/authmodule-eIDAS-v2/src/main/resources/eidas_v2_auth.beans.xml3
-rw-r--r--eidas_modules/authmodule-eIDAS-v2/src/main/resources/messages/eidas_connector_message.properties2
-rw-r--r--eidas_modules/authmodule-eIDAS-v2/src/test/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/test/clients/ZmrAddressSearchClientProductionTest.java169
4 files changed, 456 insertions, 1 deletions
diff --git a/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/clients/zmr/ZmrAddressSoapClient.java b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/clients/zmr/ZmrAddressSoapClient.java
new file mode 100644
index 00000000..d869ca37
--- /dev/null
+++ b/eidas_modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/clients/zmr/ZmrAddressSoapClient.java
@@ -0,0 +1,283 @@
+package at.asitplus.eidas.specific.modules.auth.eidas.v2.clients.zmr;
+
+import java.math.BigInteger;
+import java.net.URL;
+import java.text.MessageFormat;
+import java.util.List;
+
+import javax.annotation.Nonnull;
+import javax.annotation.PostConstruct;
+import javax.xml.ws.BindingProvider;
+
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.lang.Nullable;
+
+import at.asitplus.eidas.specific.modules.auth.eidas.v2.Constants;
+import at.asitplus.eidas.specific.modules.auth.eidas.v2.clients.AbstractSoapClient;
+import at.asitplus.eidas.specific.modules.auth.eidas.v2.exception.EidasSAuthenticationException;
+import at.asitplus.eidas.specific.modules.auth.eidas.v2.exception.ZmrCommunicationException;
+import at.asitplus.eidas.specific.modules.auth.eidas.v2.utils.VersionHolder;
+import at.gv.bmi.namespace.zmr_su.base._20040201_.address.ClientInfoType;
+import at.gv.bmi.namespace.zmr_su.base._20040201_.address.Organisation;
+import at.gv.bmi.namespace.zmr_su.base._20040201_.address.RequestType;
+import at.gv.bmi.namespace.zmr_su.base._20040201_.address.ResponseType;
+import at.gv.bmi.namespace.zmr_su.base._20040201_.address.Service;
+import at.gv.bmi.namespace.zmr_su.base._20040201_.address.ServiceFault_Exception;
+import at.gv.bmi.namespace.zmr_su.base._20040201_.address.ServicePort;
+import at.gv.bmi.namespace.zmr_su.base._20040201_.address.WorkflowInfoClient;
+import at.gv.bmi.namespace.zmr_su.base._20040201_.address.WorkflowInfoServer;
+import at.gv.bmi.namespace.zmr_su.zrm._20040201_.address.Adressdaten;
+import at.gv.bmi.namespace.zmr_su.zrm._20040201_.address.AdresssucheInfoType;
+import at.gv.bmi.namespace.zmr_su.zrm._20040201_.address.AdresssucheRequest;
+import at.gv.bmi.namespace.zmr_su.zrm._20040201_.address.AdresssuchergebnisType;
+import at.gv.egiz.eaaf.core.exceptions.EaafConfigurationException;
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+import lombok.NonNull;
+import lombok.extern.slf4j.Slf4j;
+
+/**
+ * ZMR SOAP client for search-address operations.
+ *
+ * @author tlenz
+ *
+ */
+@Slf4j
+public class ZmrAddressSoapClient extends AbstractSoapClient {
+
+ private static final String CLIENT_DEFAULT = "ZMR-AddressSearch Client";
+ private static final String CLIENT_INFO = "eIDAS MS-Connector v{0}";
+
+ private static final String LOGMSG_ZMR_SOAP_ERROR =
+ "ZMR anwser for transaction: {0} with code: {1} and message: {2}";
+ private static final String LOGMSG_ZMR_ERROR =
+ "Receive an error from ZMR during '{}' operation with msg: {}";
+ private static final String LOGMSG_ZMR_RESP_PROCESS =
+ "Proces ZMR response during '{}' operation failes with msg: {}";
+
+ private static final String ERROR_MATCHING_07 = "module.eidasauth.matching.07";
+ private static final String ERROR_MATCHING_99 = "module.eidasauth.matching.99";
+
+ private static final String PROCESS_GENERAL = "GP_Abfragen";
+ private static final String PROCESS_TASK_ADDRESS_WIZZARD = "ZMR_VO_Adresssuche_im_GWR__6";
+
+ private static final String PROCESS_TASK_RESPONSE_LEVEL_CITY = "Ortschaft";
+ private static final String PROCESS_TASK_RESPONSE_LEVEL_STREET = "Strassenname";
+ private static final String PROCESS_TASK_RESPONSE_LEVEL_NUMBER = "Orientierungsnummer";
+
+
+ private static final String PROCESS_ADDRESS_WIZZARD = "PROCESS_SEARCH_WITH_ADDRESS_WIZZARD";
+
+ private static final String SEARCH_TYPE = "ADRESSSUCHE";
+
+
+ @Autowired VersionHolder versionHolder;
+ private ServicePort zmrClient;
+
+ @Getter
+ @AllArgsConstructor
+ public static class AddressInfo {
+ private final BigInteger processId;
+ private final List<Adressdaten> personResult;
+ private final DetailLevel level;
+
+ }
+
+ public enum DetailLevel { CITY, STREET, NUMBER, UNKNOWN }
+
+ /**
+ * Get address information based on ZMR data.
+ *
+ * @param addressInfo Search parameters
+ * @return Address data
+ * @throws EidasSAuthenticationException In case of an error
+ */
+ public AddressInfo searchAddress(@NonNull Adressdaten addressInfo)
+ throws EidasSAuthenticationException {
+ return searchAddress(addressInfo, null);
+
+ }
+
+ /**
+ * Get address information based on ZMR data.
+ *
+ * @param addressInfo Search parameters
+ * @param prozessInstanzId processId in case of associated requests
+ * @return Address data
+ * @throws EidasSAuthenticationException In case of an error
+ */
+ public AddressInfo searchAddress(@NonNull Adressdaten addressInfo, @Nullable BigInteger prozessInstanzId)
+ throws EidasSAuthenticationException {
+ try {
+ RequestType req = new RequestType();
+
+ // set generic informations
+ req.setClientInfo(generateClientInfos());
+ req.setWorkflowInfoClient(generateWorkFlowInfos(PROCESS_TASK_ADDRESS_WIZZARD, null));
+
+ AdresssucheRequest search = new AdresssucheRequest();
+ req.setAdresssucheRequest(search);
+
+ // set static search type
+ AdresssucheInfoType searchType = new AdresssucheInfoType();
+ searchType.setSuchart(SEARCH_TYPE);
+ search.setAdresssucheInfo(searchType);
+
+ // set search parameters
+ search.setAdressdaten(addressInfo);
+
+ // request ZMR address services
+ log.debug("Requesting ZMR for adddress search ....");
+ ResponseType resp = zmrClient.service(req, null);
+ log.debug("Receice response for address search with #{} elements",
+ resp.getAdresssucheResponse().getAdresssuchergebnis().getGefundeneSaetze());
+
+ return new AddressInfo(
+ extractZmrProcessId(resp.getWorkflowInfoServer()),
+ resp.getAdresssucheResponse().getAdresssuchergebnis().getAdressdaten(),
+ extractAddressDetailLevel(resp.getAdresssucheResponse().getAdresssuchergebnis()));
+
+ } catch (final ServiceFault_Exception e) {
+ final String errorMsg = extractReasonFromError(e);
+ log.warn(LOGMSG_ZMR_ERROR, PROCESS_ADDRESS_WIZZARD, errorMsg);
+ throw new ZmrCommunicationException(ERROR_MATCHING_07, new Object[] { errorMsg }, e);
+
+ } catch (final Exception e) {
+ log.warn(LOGMSG_ZMR_RESP_PROCESS, PROCESS_ADDRESS_WIZZARD, e.getMessage());
+ throw new EidasSAuthenticationException(ERROR_MATCHING_99, new Object[] { e.getMessage() }, e);
+
+ }
+ }
+
+ @PostConstruct
+ private void initialize() throws EaafConfigurationException {
+ // set-up the ZMR client
+ initializeTechnicalZmrClient();
+
+ }
+
+ private void initializeTechnicalZmrClient() throws EaafConfigurationException {
+ log.info("Starting ZMR-AddressSearch Client initialization .... ");
+ final URL url = ZmrAddressSoapClient.class.getResource("/wsdl/addresssearching_client/wsdl/Service.wsdl");
+ final Service zmrService = new Service(url);
+ zmrClient = zmrService.getService();
+
+ final String zmrServiceUrl = basicConfig.getBasicConfiguration(
+ Constants.CONIG_PROPS_EIDAS_ZMRCLIENT_ENDPOINT);
+ if (StringUtils.isEmpty(zmrServiceUrl)) {
+ log.error("No ZMR-AddressSearch service-URL found. ZMR-AddressSearch-Client initalisiation failed.");
+ throw new RuntimeException(
+ "No ZMR-AddressSearch service URL found. ZMR-AddressSearch-Client initalisiation failed.");
+
+ }
+
+ // inject handler
+ log.info("Use ZMR-AddressSearch service-URL: " + zmrServiceUrl);
+ injectBindingProvider((BindingProvider) zmrClient, CLIENT_DEFAULT, zmrServiceUrl,
+ basicConfig.getBasicConfigurationBoolean(Constants.CONIG_PROPS_EIDAS_ZMRCLIENT_DEBUG_TRACEMESSAGES,
+ false));
+
+ // inject http parameters and SSL context
+ log.debug("Inject HTTP client settings ... ");
+ injectHttpClient(zmrClient, HttpClientConfig.builder()
+ .clientName(CLIENT_DEFAULT)
+ .clientType(CLIENT_DEFAULT)
+ .clientUrl(zmrServiceUrl)
+ .connectionTimeout(basicConfig.getBasicConfiguration(
+ Constants.CONIG_PROPS_EIDAS_ZMRCLIENT_TIMEOUT_CONNECTION,
+ Constants.HTTP_CLIENT_DEFAULT_TIMEOUT_CONNECTION))
+ .responseTimeout(basicConfig.getBasicConfiguration(
+ Constants.CONIG_PROPS_EIDAS_ZMRCLIENT_TIMEOUT_RESPONSE,
+ Constants.HTTP_CLIENT_DEFAULT_TIMEOUT_RESPONSE))
+ .keyStoreConfig(buildKeyStoreConfiguration(
+ Constants.CONIG_PROPS_EIDAS_ZMRCLIENT_SSL_KEYSTORE_TYPE,
+ Constants.CONIG_PROPS_EIDAS_ZMRCLIENT_SSL_KEYSTORE_PATH,
+ Constants.CONIG_PROPS_EIDAS_ZMRCLIENT_SSL_KEYSTORE_PASSWORD,
+ Constants.CONIG_PROPS_EIDAS_ZMRCLIENT_SSL_KEYSTORE_NAME,
+ "ZMR-AddressSearch SSL Client-Authentication KeyStore"))
+ .keyAlias(basicConfig.getBasicConfiguration(Constants.CONIG_PROPS_EIDAS_ZMRCLIENT_SSL_KEYS_ALIAS))
+ .keyPassword(basicConfig.getBasicConfiguration(
+ Constants.CONIG_PROPS_EIDAS_ZMRCLIENT_SSL_KEY_PASSWORD))
+ .trustAll(false)
+ .trustStoreConfig(buildKeyStoreConfiguration(
+ Constants.CONIG_PROPS_EIDAS_ZMRCLIENT_SSL_TRUSTSTORE_TYPE,
+ Constants.CONIG_PROPS_EIDAS_ZMRCLIENT_SSL_TRUSTSTORE_PATH,
+ Constants.CONIG_PROPS_EIDAS_ZMRCLIENT_SSL_TRUSTSTORE_PASSWORD,
+ Constants.CONIG_PROPS_EIDAS_ZMRCLIENT_SSL_TRUSTSTORE_NAME,
+ "ZMR-AddressSearch SSL Client-Authentication TrustStore"))
+ .build());
+
+ }
+
+ @Nonnull
+ private ClientInfoType generateClientInfos() {
+ final ClientInfoType clientInfo = new ClientInfoType();
+ final Organisation clientOrganisation = new Organisation();
+ clientInfo.setOrganisation(clientOrganisation);
+
+ // set client information
+ clientInfo.setClient(MessageFormat.format(CLIENT_INFO, versionHolder.getVersion()));
+
+ // set Behoerdennummer as organization identifier
+ clientOrganisation.setBehoerdenNr(basicConfig.getBasicConfiguration(
+ Constants.CONIG_PROPS_EIDAS_ZMRCLIENT_REQ_ORGANIZATION_NR));
+
+ return clientInfo;
+ }
+
+ @Nonnull
+ private static String extractReasonFromError(ServiceFault_Exception e) {
+ if (e.getFaultInfo() != null) {
+ return MessageFormat.format(LOGMSG_ZMR_SOAP_ERROR,
+ e.getFaultInfo().getServerTransaktionNr().toString(),
+ e.getFaultInfo().getErrorCode(),
+ e.getFaultInfo().getErrorMessage());
+
+ } else {
+ log.error("ZMR response without error code", e);
+ return e.getMessage();
+
+ }
+ }
+
+ @Nonnull
+ private static WorkflowInfoClient generateWorkFlowInfos(@Nonnull String subStepName,
+ @Nullable BigInteger prozessInstanzId) {
+ final WorkflowInfoClient infos = new WorkflowInfoClient();
+ infos.setProzessName(PROCESS_GENERAL);
+ infos.setVorgangName(subStepName);
+
+ //set processId that we received from ZMR before, if already available
+ if (prozessInstanzId != null) {
+ infos.setProzessInstanzID(prozessInstanzId);
+
+ }
+
+ return infos;
+
+ }
+
+ private static BigInteger extractZmrProcessId(WorkflowInfoServer workflowInfoServer) {
+ return workflowInfoServer != null ? workflowInfoServer.getProzessInstanzID() : null;
+
+ }
+
+ private static DetailLevel extractAddressDetailLevel(AdresssuchergebnisType value) {
+ switch (value.getDetailgrad()) {
+ case PROCESS_TASK_RESPONSE_LEVEL_CITY:
+ return DetailLevel.CITY;
+
+ case PROCESS_TASK_RESPONSE_LEVEL_STREET:
+ return DetailLevel.STREET;
+
+ case PROCESS_TASK_RESPONSE_LEVEL_NUMBER:
+ return DetailLevel.NUMBER;
+
+ default:
+ return DetailLevel.UNKNOWN;
+
+ }
+ }
+
+}
diff --git a/eidas_modules/authmodule-eIDAS-v2/src/main/resources/eidas_v2_auth.beans.xml b/eidas_modules/authmodule-eIDAS-v2/src/main/resources/eidas_v2_auth.beans.xml
index 85b49186..d82ccec5 100644
--- a/eidas_modules/authmodule-eIDAS-v2/src/main/resources/eidas_v2_auth.beans.xml
+++ b/eidas_modules/authmodule-eIDAS-v2/src/main/resources/eidas_v2_auth.beans.xml
@@ -22,6 +22,9 @@
<bean id="zmrClient"
class="at.asitplus.eidas.specific.modules.auth.eidas.v2.clients.zmr.ZmrSoapClient" />
+
+ <bean id="zmrAddressClient"
+ class="at.asitplus.eidas.specific.modules.auth.eidas.v2.clients.zmr.ZmrAddressSoapClient" />
<!-- bean id="ZmrClientForeIDAS"
class="at.asitplus.eidas.specific.modules.auth.eidas.v2.zmr.DummyZmrClient" /-->
diff --git a/eidas_modules/authmodule-eIDAS-v2/src/main/resources/messages/eidas_connector_message.properties b/eidas_modules/authmodule-eIDAS-v2/src/main/resources/messages/eidas_connector_message.properties
index f47d0f30..3ccfff19 100644
--- a/eidas_modules/authmodule-eIDAS-v2/src/main/resources/messages/eidas_connector_message.properties
+++ b/eidas_modules/authmodule-eIDAS-v2/src/main/resources/messages/eidas_connector_message.properties
@@ -20,4 +20,4 @@ module.eidasauth.matching.02=Matching failed, because ZMR response contains hist
module.eidasauth.matching.03=Matching failed in workflow step: {0} with error: {1}
module.eidasauth.matching.04=An error occurred while loading your data from official registers. Please contact the support.
-module.eidasauth.matching.99=Matching failed, because of an unexpected processing error. Reason: {0} \ No newline at end of file
+module.eidasauth.matching.99=Matching failed, because of an unexpected processing error. Reason: {0}
diff --git a/eidas_modules/authmodule-eIDAS-v2/src/test/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/test/clients/ZmrAddressSearchClientProductionTest.java b/eidas_modules/authmodule-eIDAS-v2/src/test/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/test/clients/ZmrAddressSearchClientProductionTest.java
new file mode 100644
index 00000000..a6ff234b
--- /dev/null
+++ b/eidas_modules/authmodule-eIDAS-v2/src/test/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/test/clients/ZmrAddressSearchClientProductionTest.java
@@ -0,0 +1,169 @@
+package at.asitplus.eidas.specific.modules.auth.eidas.v2.test.clients;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.test.annotation.IfProfileValue;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.TestPropertySource;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+
+import at.asitplus.eidas.specific.modules.auth.eidas.v2.clients.zmr.ZmrAddressSoapClient;
+import at.asitplus.eidas.specific.modules.auth.eidas.v2.clients.zmr.ZmrAddressSoapClient.AddressInfo;
+import at.asitplus.eidas.specific.modules.auth.eidas.v2.clients.zmr.ZmrAddressSoapClient.DetailLevel;
+import at.asitplus.eidas.specific.modules.auth.eidas.v2.exception.EidasSAuthenticationException;
+import at.asitplus.eidas.specific.modules.auth.eidas.v2.utils.LoggingHandler;
+import at.gv.bmi.namespace.zmr_su.zrm._20040201_.address.Adressdaten;
+import at.gv.e_government.reference.namespace.persondata.de._20040201.PostAdresseTyp;
+import at.gv.e_government.reference.namespace.persondata.de._20040201.ZustelladresseTyp;
+import at.gv.egiz.eaaf.core.api.idp.IConfiguration;
+import ch.qos.logback.classic.Level;
+import ch.qos.logback.classic.Logger;
+
+@IfProfileValue(name = "spring.profiles.active", value = "devEnvironment")
+@RunWith(SpringJUnit4ClassRunner.class)
+@ContextConfiguration(locations = {
+ "/SpringTest-context_tasks_test.xml",
+ "/SpringTest-context_basic_realConfig.xml" })
+@TestPropertySource(locations = {
+ // "classpath:/application.properties",
+ "file:/home/tlenz/Projekte/config/ms_connector/default_config.properties",
+})
+public class ZmrAddressSearchClientProductionTest {
+
+
+ @Autowired ZmrAddressSoapClient client;
+ @Autowired IConfiguration basicConfig;
+
+ @BeforeClass
+ public static void classInitializer() {
+ final Logger logger1 = (Logger) LoggerFactory.getLogger(LoggingHandler.class);
+ logger1.setLevel(Level.TRACE);
+
+ final Logger logger2 = (Logger) LoggerFactory.getLogger(ZmrAddressSoapClient.class);
+ logger2.setLevel(Level.TRACE);
+
+ final Logger rootLogger = (Logger) LoggerFactory.getLogger(org.slf4j.Logger.ROOT_LOGGER_NAME);
+ rootLogger.setLevel(Level.INFO);
+
+ }
+
+ @Test
+ public void gemeinde() throws EidasSAuthenticationException {
+ // build dummy request
+ Adressdaten req = new Adressdaten();
+ PostAdresseTyp address = new PostAdresseTyp();
+ address.setGemeinde("Frohnl*");
+ req.setPostAdresse(address);
+
+ // execute test
+ AddressInfo resp = client.searchAddress(req);
+
+ // validate state
+ assertFalse("no results", resp.getPersonResult().isEmpty());
+ assertEquals("wrong detail level", DetailLevel.CITY, resp.getLevel());
+
+
+ }
+
+ @Test
+ public void ortschaftAndGemeinde() throws EidasSAuthenticationException {
+ // build dummy request
+ Adressdaten req = new Adressdaten();
+ PostAdresseTyp address = new PostAdresseTyp();
+ address.setGemeinde("Frohnleiten");
+ address.setOrtschaft("Wannersdorf");
+ req.setPostAdresse(address);
+
+ // execute test
+ AddressInfo resp = client.searchAddress(req);
+
+ // validate state
+ assertFalse("no results", resp.getPersonResult().isEmpty());
+ assertEquals("wrong detail level", DetailLevel.STREET, resp.getLevel());
+
+ }
+
+ @Test
+ public void ortschaftAndGemeindeAndStreet() throws EidasSAuthenticationException {
+ // build dummy request
+ Adressdaten req = new Adressdaten();
+ PostAdresseTyp address = new PostAdresseTyp();
+ address.setGemeinde("Frohnleiten");
+ address.setOrtschaft("Wannersdorf");
+ req.setPostAdresse(address);
+
+ ZustelladresseTyp addressDetail = new ZustelladresseTyp();
+ addressDetail.setStrassenname("Wannersdorf");
+ address.setZustelladresse(addressDetail);
+
+ // execute test
+ AddressInfo resp = client.searchAddress(req);
+
+ // validate state
+ assertFalse("no results", resp.getPersonResult().isEmpty());
+ assertEquals("wrong detail level", DetailLevel.NUMBER, resp.getLevel());
+
+ }
+
+
+ @Test
+ public void ortschaftAndGemeinde2() throws EidasSAuthenticationException {
+ // build dummy request
+ Adressdaten req = new Adressdaten();
+ PostAdresseTyp address = new PostAdresseTyp();
+ address.setGemeinde("Fro*");
+ address.setOrtschaft("Wannersdorf");
+ req.setPostAdresse(address);
+
+ // execute test
+ AddressInfo resp = client.searchAddress(req);
+
+ // validate state
+ assertFalse("no results", resp.getPersonResult().isEmpty());
+ assertEquals("wrong detail level", DetailLevel.CITY, resp.getLevel());
+
+ }
+
+ @Test
+ public void ortschaftAndGemeinde3() throws EidasSAuthenticationException {
+ // build dummy request
+ Adressdaten req = new Adressdaten();
+ PostAdresseTyp address = new PostAdresseTyp();
+ address.setGemeinde("Eggelsberg");
+ address.setOrtschaft("Wannersdorf");
+ req.setPostAdresse(address);
+
+ // execute test
+ AddressInfo resp = client.searchAddress(req);
+
+ // validate state
+ assertFalse("no results", resp.getPersonResult().isEmpty());
+ assertEquals("wrong detail level", DetailLevel.STREET, resp.getLevel());
+
+ }
+
+
+ @Test
+ public void ortschaft() throws EidasSAuthenticationException {
+ // build dummy request
+ Adressdaten req = new Adressdaten();
+ PostAdresseTyp address = new PostAdresseTyp();
+ address.setOrtschaft("Wannersdorf");
+ req.setPostAdresse(address);
+
+ // execute test
+ AddressInfo resp = client.searchAddress(req);
+
+ // validate state
+ assertFalse("no results", resp.getPersonResult().isEmpty());
+ assertEquals("wrong detail level", DetailLevel.CITY, resp.getLevel());
+
+ }
+
+}