diff options
9 files changed, 176 insertions, 81 deletions
diff --git a/basicConfig/properties/messages.properties b/basicConfig/properties/messages.properties index 4d9f48a0..51a5f27a 100644 --- a/basicConfig/properties/messages.properties +++ b/basicConfig/properties/messages.properties @@ -123,4 +123,8 @@ gui.residency.cancel=Cancel gui.residency.search=Search gui.residency.proceed=Proceed gui.residency.updated=Updated your input -gui.residency.error=Error on Backend Call
\ No newline at end of file +gui.residency.error=Error on Backend Call +gui.residency.input.municipality=Municipality +gui.residency.input.village=Village +gui.residency.input.street=Street +gui.residency.input.number=Number
\ No newline at end of file diff --git a/basicConfig/properties/messages_de.properties b/basicConfig/properties/messages_de.properties index cfbd98da..c2d1edba 100644 --- a/basicConfig/properties/messages_de.properties +++ b/basicConfig/properties/messages_de.properties @@ -122,4 +122,8 @@ gui.residency.cancel=Abbrechen gui.residency.search=Suche gui.residency.proceed=Weiter gui.residency.updated=Eingabe aktualisiert -gui.residency.error=Fehler bei Addresssuche
\ No newline at end of file +gui.residency.error=Fehler bei Addresssuche +gui.residency.input.municipality=Gemeinde +gui.residency.input.village=Ortschaft +gui.residency.input.street=Straße +gui.residency.input.number=Nummer
\ No newline at end of file diff --git a/basicConfig/templates/residency.html b/basicConfig/templates/residency.html index 96fa13f8..3c3c05d7 100644 --- a/basicConfig/templates/residency.html +++ b/basicConfig/templates/residency.html @@ -20,7 +20,8 @@ url: "http://localhost:8080/ms_connector/residency/search", data: $("#inputForm").serialize() }).done(function (data, textStatus, jqXHR) { - $("#inputCity").val(data["city"]); + $("#inputMunicipality").val(data["municipality"]); + $("#inputVillage").val(data["village"]); $("#inputStreet").val(data["street"]); $("#inputNumber").val(data["number"]); $("#textInfo").text(updatedText); @@ -43,11 +44,15 @@ <div> <p><span id="textInfo">Infotext</span></p> </div> - <form id="inputForm" class="block" method="post" action="$contextPath$submitEndpoint" + <form id="inputForm" method="post" action="$contextPath$submitEndpoint" th:attr="action=@{${submitEndpoint}}"> <div> - <label for="inputCity">City</label> - <input type="text" id="inputCity" name="city" value="City"/> + <label for="inputMunicipality">Municipality</label> + <input type="text" id="inputMunicipality" name="municipality" value="Municipality"/> + </div> + <div> + <label for="inputVillage">Village</label> + <input type="text" id="inputVillage" name="village" value="Village"/> </div> <div> <label for="inputStreet">Street</label> diff --git a/connector/src/main/java/at/asitplus/eidas/specific/connector/controller/AdresssucheController.java b/connector/src/main/java/at/asitplus/eidas/specific/connector/controller/AdresssucheController.java index 35f56012..8b25a7bd 100644 --- a/connector/src/main/java/at/asitplus/eidas/specific/connector/controller/AdresssucheController.java +++ b/connector/src/main/java/at/asitplus/eidas/specific/connector/controller/AdresssucheController.java @@ -25,13 +25,19 @@ package at.asitplus.eidas.specific.connector.controller; import at.asitplus.eidas.specific.connector.MsEidasNodeConstants; import at.asitplus.eidas.specific.connector.gui.StaticGuiBuilderConfiguration; +import at.asitplus.eidas.specific.modules.auth.eidas.v2.clients.zmr.ZmrAddressSoapClient; +import at.asitplus.eidas.specific.modules.auth.eidas.v2.exception.EidasSAuthenticationException; +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.gui.IGuiBuilderConfiguration; import at.gv.egiz.eaaf.core.api.gui.ISpringMvcGuiFormBuilder; import at.gv.egiz.eaaf.core.api.idp.IConfiguration; import at.gv.egiz.eaaf.core.api.utils.IPendingRequestIdGenerationStrategy; import at.gv.egiz.eaaf.core.exceptions.GuiBuildException; -import at.gv.egiz.eaaf.core.exceptions.PendingReqIdValidationException; import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import org.jetbrains.annotations.NotNull; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.core.io.ResourceLoader; import org.springframework.http.ResponseEntity; @@ -62,6 +68,9 @@ public class AdresssucheController { private ResourceLoader resourceLoader; @Autowired + private ZmrAddressSoapClient client; + + @Autowired private IPendingRequestIdGenerationStrategy pendingReqGeneration; @RequestMapping(value = {"/test"}, method = {RequestMethod.GET}) @@ -79,11 +88,12 @@ public class AdresssucheController { } @RequestMapping(value = {"/residency/search"}, method = {RequestMethod.POST}) - public ResponseEntity<AdresssucheOutput> search(@RequestParam("city") String city, + public ResponseEntity<AdresssucheOutput> search(@RequestParam("municipality") String municipality, + @RequestParam("village") String village, @RequestParam("street") String street, @RequestParam("number") String number, @RequestParam("pendingid") String pendingId) { - log.info("Search with '{}', '{}', '{}'", city, street, number); + log.info("Search with '{}', '{}', '{}'", municipality, street, number); // TODO validate pendingId // try { // pendingReqGeneration.validateAndGetPendingRequestId(pendingId); @@ -91,23 +101,74 @@ public class AdresssucheController { // log.warn("Search with pendingId '{}' is not valid", pendingId); // return ResponseEntity.badRequest().build(); // } - AdresssucheOutput output = new AdresssucheOutput("Where the streets have no name", "No Name", "42"); - return ResponseEntity.ok(output); + try { + Adressdaten searchInput = buildSearchInput(municipality, village, street, number); + ZmrAddressSoapClient.AddressInfo searchOutput = client.searchAddress(searchInput); + AdresssucheOutput output = buildResponse(searchOutput); + return ResponseEntity.ok(output); + } catch (EidasSAuthenticationException e) { + log.warn("Search failed", e); + return ResponseEntity.badRequest().build(); + } + } + + private AdresssucheOutput buildResponse(ZmrAddressSoapClient.AddressInfo searchOutput) { + if (searchOutput.getPersonResult().isEmpty()) { + log.warn("No result from ZMR"); + return new AdresssucheOutput(null, null, null, null); + } + Adressdaten adressdaten = searchOutput.getPersonResult().iterator().next(); + String municipality = adressdaten.getPostAdresse().getGemeinde(); + String village = adressdaten.getPostAdresse().getOrtschaft(); + String street = adressdaten.getPostAdresse().getZustelladresse().getStrassenname(); + String number = adressdaten.getPostAdresse().getZustelladresse().getOrientierungsnummer(); + log.debug("Result from ZMR: '{}', '{}', '{}', '{}'", municipality, village, street, number); + return new AdresssucheOutput(municipality, village, street, number); + } + + @NotNull + private Adressdaten buildSearchInput(String municipality, String village, String street, String number) { + PostAdresseTyp postAdresse = new PostAdresseTyp(); + if (StringUtils.isNotBlank(municipality)) { + postAdresse.setGemeinde(municipality); + } + if (StringUtils.isNotBlank(village)) { + postAdresse.setOrtschaft(village); + } + if (StringUtils.isNotBlank(street) || StringUtils.isNotBlank(number)) { + ZustelladresseTyp zustelladresse = new ZustelladresseTyp(); + if (StringUtils.isNotBlank(street)) { + zustelladresse.setStrassenname(street); + } + if (StringUtils.isNotBlank(number)) { + zustelladresse.setOrientierungsnummer(number); + } + postAdresse.setZustelladresse(zustelladresse); + } + Adressdaten searchInput = new Adressdaten(); + searchInput.setPostAdresse(postAdresse); + return searchInput; } public static class AdresssucheOutput { - private final String city; + private final String municipality; + private final String village; private final String street; private final String number; - public AdresssucheOutput(String city, String street, String number) { - this.city = city; + public AdresssucheOutput(String municipality, String village, String street, String number) { + this.municipality = municipality; + this.village = village; this.street = street; this.number = number; } - public String getCity() { - return city; + public String getMunicipality() { + return municipality; + } + + public String getVillage() { + return village; } public String getStreet() { @@ -121,7 +182,8 @@ public class AdresssucheController { @Override public String toString() { return "AdresssucheOutput{" + - "city='" + city + '\'' + + "municipality='" + municipality + '\'' + + ", village='" + village + '\'' + ", street='" + street + '\'' + ", number='" + number + '\'' + '}'; diff --git a/connector/src/main/resources/templates/residency.html b/connector/src/main/resources/templates/residency.html index 44ae4bd5..38f490ca 100644 --- a/connector/src/main/resources/templates/residency.html +++ b/connector/src/main/resources/templates/residency.html @@ -20,7 +20,8 @@ url: "http://localhost:8080/ms_connector/residency/search", data: $("#inputForm").serialize() }).done(function (data, textStatus, jqXHR) { - $("#inputCity").val(data["city"]); + $("#inputMunicipality").val(data["municipality"]); + $("#inputVillage").val(data["village"]); $("#inputStreet").val(data["street"]); $("#inputNumber").val(data["number"]); $("#textInfo").text(updatedText); @@ -43,11 +44,15 @@ <div> <p><span id="textInfo">Infotext</span></p> </div> - <form id="inputForm" class="block" method="post" action="$contextPath$submitEndpoint" + <form id="inputForm" method="post" action="$contextPath$submitEndpoint" th:attr="action=@{${submitEndpoint}}"> <div> - <label for="inputCity">City</label> - <input type="text" id="inputCity" name="city" value="City"/> + <label for="inputMunicipality">Municipality</label> + <input type="text" id="inputMunicipality" name="municipality" value="Municipality"/> + </div> + <div> + <label for="inputVillage">Village</label> + <input type="text" id="inputVillage" name="village" value="Village"/> </div> <div> <label for="inputStreet">Street</label> diff --git a/connector/src/test/resources/config/properties/messages.properties b/connector/src/test/resources/config/properties/messages.properties index 8ffc5560..1e0f04d0 100644 --- a/connector/src/test/resources/config/properties/messages.properties +++ b/connector/src/test/resources/config/properties/messages.properties @@ -110,4 +110,8 @@ gui.residency.cancel=Cancel gui.residency.search=Search gui.residency.proceed=Proceed gui.residency.updated=Updated your input -gui.residency.error=Error on Backend Call
\ No newline at end of file +gui.residency.error=Error on Backend Call +gui.residency.input.municipality=Municipality +gui.residency.input.village=Village +gui.residency.input.street=Street +gui.residency.input.number=Number
\ No newline at end of file diff --git a/connector/src/test/resources/config/properties/messages_de.properties b/connector/src/test/resources/config/properties/messages_de.properties index a79aa41a..e0eea9d1 100644 --- a/connector/src/test/resources/config/properties/messages_de.properties +++ b/connector/src/test/resources/config/properties/messages_de.properties @@ -111,4 +111,8 @@ gui.residency.cancel=Abbrechen gui.residency.search=Suche gui.residency.proceed=Weiter gui.residency.updated=Eingabe aktualisiert -gui.residency.error=Fehler bei Addresssuche
\ No newline at end of file +gui.residency.error=Fehler bei Addresssuche +gui.residency.input.municipality=Gemeinde +gui.residency.input.village=Ortschaft +gui.residency.input.street=Straße +gui.residency.input.number=Nummer
\ No newline at end of file diff --git a/connector/src/test/resources/config/templates/residency.html b/connector/src/test/resources/config/templates/residency.html index 8845cba0..17e21044 100644 --- a/connector/src/test/resources/config/templates/residency.html +++ b/connector/src/test/resources/config/templates/residency.html @@ -20,7 +20,8 @@ url: "http://localhost:8080/ms_connector/residency/search", data: $("#inputForm").serialize() }).done(function (data, textStatus, jqXHR) { - $("#inputCity").val(data["city"]); + $("#inputMunicipality").val(data["municipality"]); + $("#inputVillage").val(data["village"]); $("#inputStreet").val(data["street"]); $("#inputNumber").val(data["number"]); $("#textInfo").text(updatedText); @@ -43,11 +44,15 @@ <div> <p><span id="textInfo">Infotext</span></p> </div> - <form id="inputForm" class="block" method="post" action="$contextPath$submitEndpoint" + <form id="inputForm" method="post" action="$contextPath$submitEndpoint" th:attr="action=@{${submitEndpoint}}"> <div> - <label for="inputCity">City</label> - <input type="text" id="inputCity" name="city" value="City"/> + <label for="inputMunicipality">Municipality</label> + <input type="text" id="inputMunicipality" name="municipality" value="Municipality"/> + </div> + <div> + <label for="inputVillage">Village</label> + <input type="text" id="inputVillage" name="village" value="Village"/> </div> <div> <label for="inputStreet">Street</label> 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 index d869ca37..5fb839af 100644 --- 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 @@ -39,18 +39,18 @@ 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}"; + "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 = @@ -58,37 +58,37 @@ public class ZmrAddressSoapClient extends AbstractSoapClient { 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; + + + @Autowired VersionHolder versionHolder; private ServicePort zmrClient; - + @Getter @AllArgsConstructor - public static class AddressInfo { + 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. - * + * Get address information based on ZMR data. + * * @param addressInfo Search parameters * @return Address data * @throws EidasSAuthenticationException In case of an error @@ -96,12 +96,12 @@ public class ZmrAddressSoapClient extends AbstractSoapClient { public AddressInfo searchAddress(@NonNull Adressdaten addressInfo) throws EidasSAuthenticationException { return searchAddress(addressInfo, null); - + } - + /** - * Get address information based on ZMR data. - * + * Get address information based on ZMR data. + * * @param addressInfo Search parameters * @param prozessInstanzId processId in case of associated requests * @return Address data @@ -111,33 +111,33 @@ public class ZmrAddressSoapClient extends AbstractSoapClient { 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); + 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()); - + log.debug("Receice response for address search with #{} elements", + resp.getAdresssucheResponse().getAdresssuchergebnis().getGefundeneSaetze()); + return new AddressInfo( - extractZmrProcessId(resp.getWorkflowInfoServer()), - resp.getAdresssucheResponse().getAdresssuchergebnis().getAdressdaten(), + 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); @@ -154,7 +154,7 @@ public class ZmrAddressSoapClient extends AbstractSoapClient { private void initialize() throws EaafConfigurationException { // set-up the ZMR client initializeTechnicalZmrClient(); - + } private void initializeTechnicalZmrClient() throws EaafConfigurationException { @@ -206,10 +206,10 @@ public class ZmrAddressSoapClient extends AbstractSoapClient { Constants.CONIG_PROPS_EIDAS_ZMRCLIENT_SSL_TRUSTSTORE_PASSWORD, Constants.CONIG_PROPS_EIDAS_ZMRCLIENT_SSL_TRUSTSTORE_NAME, "ZMR-AddressSearch SSL Client-Authentication TrustStore")) - .build()); - + .build()); + } - + @Nonnull private ClientInfoType generateClientInfos() { final ClientInfoType clientInfo = new ClientInfoType(); @@ -218,14 +218,14 @@ public class ZmrAddressSoapClient extends AbstractSoapClient { // 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) { @@ -239,10 +239,10 @@ public class ZmrAddressSoapClient extends AbstractSoapClient { return e.getMessage(); } - } - + } + @Nonnull - private static WorkflowInfoClient generateWorkFlowInfos(@Nonnull String subStepName, + private static WorkflowInfoClient generateWorkFlowInfos(@Nonnull String subStepName, @Nullable BigInteger prozessInstanzId) { final WorkflowInfoClient infos = new WorkflowInfoClient(); infos.setProzessName(PROCESS_GENERAL); @@ -251,33 +251,35 @@ public class ZmrAddressSoapClient extends AbstractSoapClient { //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; + return workflowInfoServer != null ? workflowInfoServer.getProzessInstanzID() : null; } - + private static DetailLevel extractAddressDetailLevel(AdresssuchergebnisType value) { + if (value.getDetailgrad() == null) + return DetailLevel.UNKNOWN; 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; - + } } - + } |