diff options
Diffstat (limited to 'eidas_modules/authmodule-eIDAS-v2/src')
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()); +     +  } +   +} | 
