From ec9bb663b463657643c87e2d7116229fb6a5367c Mon Sep 17 00:00:00 2001 From: Thomas <> Date: Fri, 21 Oct 2022 15:45:15 +0200 Subject: feat(matching): add detailed matching results into JSON based statistic logger --- .../specific/modules/auth/eidas/v2/Constants.java | 6 ++ .../log/statistic/DetailedMatchtingStatistic.java | 86 ++++++++++++++++++++++ .../auth/eidas/v2/tasks/AlternativeSearchTask.java | 2 + .../auth/eidas/v2/tasks/InitialSearchTask.java | 13 ++++ .../ReceiveAustrianResidenceGuiResponseTask.java | 2 + .../ReceiveMobilePhoneSignatureResponseTask.java | 7 +- .../auth/eidas/v2/utils/MatchingTaskUtils.java | 22 ++++++ .../core/logger/AdvancedStatisicLogger.java | 30 +++++++- 8 files changed, 161 insertions(+), 7 deletions(-) create mode 100644 modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/log/statistic/DetailedMatchtingStatistic.java diff --git a/modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/Constants.java b/modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/Constants.java index 0d0d11f8..c9d13eaf 100644 --- a/modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/Constants.java +++ b/modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/Constants.java @@ -40,6 +40,12 @@ public class Constants { public static final String DATA_FULL_EIDAS_RESPONSE = "resp_fulleIDASResponse"; public static final String DATA_FULL_EIDAS_RESPONSE_ALTERNATIVE = "resp_fulleIDASResponseAlternative"; + + /** + * Hold statistic information about the matching process. + */ + public static final String DETAILED_MATCHING_STATISTIC = "matching_statistic_data"; + /** * Stored before Step 2 from Matching Concept, input from user eIDAS authn. */ diff --git a/modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/log/statistic/DetailedMatchtingStatistic.java b/modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/log/statistic/DetailedMatchtingStatistic.java new file mode 100644 index 00000000..975d17b4 --- /dev/null +++ b/modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/log/statistic/DetailedMatchtingStatistic.java @@ -0,0 +1,86 @@ +package at.asitplus.eidas.specific.modules.auth.eidas.v2.log.statistic; + +import java.io.Serializable; + +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonInclude.Include; +import com.fasterxml.jackson.annotation.JsonProperty; + +import at.asitplus.eidas.specific.modules.auth.eidas.v2.service.RegisterSearchService.RegisterStatusResults; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.Setter; + +/** + * Detailed statistic of matching operation. + * + * @author tlenz + * + */ +@Getter +@Setter +public class DetailedMatchtingStatistic implements Serializable { + + private static final long serialVersionUID = 8563971979294950484L; + + @JsonProperty("BY_PERSONALID") + private MatchingStepResult personalIdResult; + + @JsonProperty("BY_COUNTRY_SPECIFIC") + private MatchingStepResult ccSpecificResult; + + @JsonProperty("BY_MDS") + private MatchingStepResult mdsResult; + + @JsonProperty("USE_IDA") + private boolean idaLoginUsed = false; + + @JsonProperty("USE_EIDAS") + private int eidasLoginUsed = 0; + + @JsonProperty("USE_ADDRESS") + private int addressSearchUsed = 0; + + /** + * Increment the search address counter. + */ + public void incrementAddressSearch() { + this.addressSearchUsed++; + + } + + /** + * Increment the alternative eIDAS login counter. + */ + public void incrementAlternativEidas() { + this.eidasLoginUsed++; + + } + + /** + * Generate a matching step result from {@link RegisterStatusResults}. + * + * @param result results from a specific register search operation + * @return detailed statistic information + */ + public static MatchingStepResult buildFrom(RegisterStatusResults result) { + return new MatchingStepResult( + result.getResultsZmr().size(), + result.getResultsZmr().size()); + + } + + @Getter + @Setter + @AllArgsConstructor + @JsonInclude(Include.NON_NULL) + private static class MatchingStepResult { + + @JsonProperty("zmr") + private int zmrResults = 0; + + @JsonProperty("ernp") + private int ernpResults = 0; + + } +} diff --git a/modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/tasks/AlternativeSearchTask.java b/modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/tasks/AlternativeSearchTask.java index e4c68d25..604a6588 100644 --- a/modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/tasks/AlternativeSearchTask.java +++ b/modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/tasks/AlternativeSearchTask.java @@ -108,6 +108,8 @@ public class AlternativeSearchTask extends AbstractAuthServletTask { final RegisterStatusResults intermediateMatchingState = MatchingTaskUtils.getIntermediateMatchingResult(pendingReq); + MatchingTaskUtils.getDetailedMatchingStatistic(pendingReq).incrementAlternativEidas(); + //pre-validation of eIDAS data if (!preVerifyAlternativeEidasData(altEidasData, initialEidasData, intermediateMatchingState, executionContext)) { diff --git a/modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/tasks/InitialSearchTask.java b/modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/tasks/InitialSearchTask.java index 8e6c7790..30cb68eb 100644 --- a/modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/tasks/InitialSearchTask.java +++ b/modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/tasks/InitialSearchTask.java @@ -42,6 +42,7 @@ import at.asitplus.eidas.specific.modules.auth.eidas.v2.dao.SimpleEidasData; import at.asitplus.eidas.specific.modules.auth.eidas.v2.exception.EidPostProcessingException; import at.asitplus.eidas.specific.modules.auth.eidas.v2.exception.EidasAttributeException; import at.asitplus.eidas.specific.modules.auth.eidas.v2.exception.WorkflowException; +import at.asitplus.eidas.specific.modules.auth.eidas.v2.log.statistic.DetailedMatchtingStatistic; import at.asitplus.eidas.specific.modules.auth.eidas.v2.service.ICcSpecificEidProcessingService; import at.asitplus.eidas.specific.modules.auth.eidas.v2.service.RegisterSearchService; import at.asitplus.eidas.specific.modules.auth.eidas.v2.service.RegisterSearchService.RegisterOperationStatus; @@ -119,6 +120,10 @@ public class InitialSearchTask extends AbstractAuthServletTask { try { log.trace("Starting step2RegisterSearchWithPersonIdentifier"); RegisterStatusResults searchResult = registerSearchService.searchWithPersonIdentifier(eidasData); + + MatchingTaskUtils.getDetailedMatchingStatistic(pendingReq).setPersonalIdResult( + DetailedMatchtingStatistic.buildFrom(searchResult)); + int resultCount = searchResult.getResultCount(); if (resultCount == 0) { step6CountrySpecificSearch(executionContext, searchResult.getOperationStatus(), eidasData); @@ -146,6 +151,10 @@ public class InitialSearchTask extends AbstractAuthServletTask { log.trace("Starting 'step6CountrySpecificSearch' ... "); RegisterStatusResults searchResult = registerSearchService.searchWithCountrySpecifics( registerOperationStatus, eidasData); + + MatchingTaskUtils.getDetailedMatchingStatistic(pendingReq).setCcSpecificResult( + DetailedMatchtingStatistic.buildFrom(searchResult)); + if (searchResult.getResultCount() == 0) { log.trace("'step6CountrySpecificSearch' ends with no result. Forward to next matching step ... "); step8RegisterSearchWithMds(executionContext, searchResult.getOperationStatus(), eidasData); @@ -167,6 +176,10 @@ public class InitialSearchTask extends AbstractAuthServletTask { throws EaafStorageException, WorkflowException { log.trace("Starting step8RegisterSearchWithMds"); RegisterStatusResults registerData = registerSearchService.searchWithMds(registerOperationStatus, eidasData); + + MatchingTaskUtils.getDetailedMatchingStatistic(pendingReq).setMdsResult( + DetailedMatchtingStatistic.buildFrom(registerData)); + if (registerData.getResultCount() == 0) { log.debug("Matching step: 'step8RegisterSearchWithMds' has no result. Forward to create new ERnP entry ... "); executionContext.put(TRANSITION_TO_CREATE_NEW_ERNP_ENTRY_TASK, true); diff --git a/modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/tasks/ReceiveAustrianResidenceGuiResponseTask.java b/modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/tasks/ReceiveAustrianResidenceGuiResponseTask.java index 403c3355..ecdf8ce0 100644 --- a/modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/tasks/ReceiveAustrianResidenceGuiResponseTask.java +++ b/modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/tasks/ReceiveAustrianResidenceGuiResponseTask.java @@ -138,6 +138,8 @@ public class ReceiveAustrianResidenceGuiResponseTask extends AbstractLocaleAuthS } + MatchingTaskUtils.getDetailedMatchingStatistic(pendingReq).incrementAddressSearch(); + // get pre-processed information SimpleEidasData eidasData = MatchingTaskUtils.getInitialEidasData(pendingReq); RegisterStatusResults initialSearchResult = MatchingTaskUtils.getIntermediateMatchingResult(pendingReq); diff --git a/modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/tasks/ReceiveMobilePhoneSignatureResponseTask.java b/modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/tasks/ReceiveMobilePhoneSignatureResponseTask.java index 57790b01..7db61bd0 100644 --- a/modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/tasks/ReceiveMobilePhoneSignatureResponseTask.java +++ b/modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/tasks/ReceiveMobilePhoneSignatureResponseTask.java @@ -169,9 +169,10 @@ public class ReceiveMobilePhoneSignatureResponseTask extends AbstractAuthServlet // validate SAML2 response validateEntityId(inboundMessage); - log.info("Receive a valid assertion from IDP " + inboundMessage.getEntityID()); - - // load already existing information from session + log.info("Receive a valid assertion from IDP " + inboundMessage.getEntityID()); + MatchingTaskUtils.getDetailedMatchingStatistic(pendingReq).setIdaLoginUsed(true); + + // load already existing information from session SimpleEidasData eidasData = MatchingTaskUtils.getInitialEidasData(pendingReq); RegisterStatusResults initialSearchResult = MatchingTaskUtils.getIntermediateMatchingResult(pendingReq); diff --git a/modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/utils/MatchingTaskUtils.java b/modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/utils/MatchingTaskUtils.java index c350cb05..587a9d3f 100644 --- a/modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/utils/MatchingTaskUtils.java +++ b/modules/authmodule-eIDAS-v2/src/main/java/at/asitplus/eidas/specific/modules/auth/eidas/v2/utils/MatchingTaskUtils.java @@ -20,6 +20,7 @@ import at.asitplus.eidas.specific.core.MsEidasNodeConstants.MatchingStates; import at.asitplus.eidas.specific.modules.auth.eidas.v2.Constants; import at.asitplus.eidas.specific.modules.auth.eidas.v2.dao.MatchedPersonResult; import at.asitplus.eidas.specific.modules.auth.eidas.v2.dao.SimpleEidasData; +import at.asitplus.eidas.specific.modules.auth.eidas.v2.log.statistic.DetailedMatchtingStatistic; import at.asitplus.eidas.specific.modules.auth.eidas.v2.service.ICcSpecificEidProcessingService; import at.asitplus.eidas.specific.modules.auth.eidas.v2.service.RegisterSearchService.RegisterStatusResults; import at.gv.egiz.eaaf.core.api.IRequest; @@ -34,6 +35,27 @@ import lombok.extern.slf4j.Slf4j; @Slf4j public class MatchingTaskUtils { + /** + * Get data object to hold statistics about matching process. + * + * @param pendingReq Current pendingRequest + * @return Matching statistics + * @throws EaafStorageException In case of data can not be add into session + */ + @NonNull + public static DetailedMatchtingStatistic getDetailedMatchingStatistic(IRequest pendingReq) + throws EaafStorageException { + DetailedMatchtingStatistic obj = getAuthProcessDataWrapper(pendingReq).getGenericDataFromSession( + Constants.DETAILED_MATCHING_STATISTIC, DetailedMatchtingStatistic.class); + if (obj == null) { + obj = new DetailedMatchtingStatistic(); + getAuthProcessDataWrapper(pendingReq).setGenericDataToSession(Constants.DETAILED_MATCHING_STATISTIC, obj); + + } + + return obj; + } + /** * Get eIDAS log-in information from session. * diff --git a/ms_specific_connector/src/main/java/at/asitplus/eidas/specific/core/logger/AdvancedStatisicLogger.java b/ms_specific_connector/src/main/java/at/asitplus/eidas/specific/core/logger/AdvancedStatisicLogger.java index f3c43579..6cbe11bf 100644 --- a/ms_specific_connector/src/main/java/at/asitplus/eidas/specific/core/logger/AdvancedStatisicLogger.java +++ b/ms_specific_connector/src/main/java/at/asitplus/eidas/specific/core/logger/AdvancedStatisicLogger.java @@ -16,10 +16,13 @@ import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer; import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer; import at.asitplus.eidas.specific.core.MsEidasNodeConstants; +import at.asitplus.eidas.specific.modules.auth.eidas.v2.log.statistic.DetailedMatchtingStatistic; +import at.asitplus.eidas.specific.modules.auth.eidas.v2.utils.MatchingTaskUtils; import at.gv.egiz.eaaf.core.api.IRequest; import at.gv.egiz.eaaf.core.api.IStatusMessenger; import at.gv.egiz.eaaf.core.api.idp.IAuthData; import at.gv.egiz.eaaf.core.api.logging.IStatisticLogger; +import at.gv.egiz.eaaf.core.exceptions.EaafStorageException; import lombok.Builder; import lombok.Getter; import lombok.RequiredArgsConstructor; @@ -59,7 +62,8 @@ public class AdvancedStatisicLogger implements IStatisticLogger { entry.setSuccess(SuccessEntry.builder() .spSector(protocolRequest.getServiceProviderConfiguration().getAreaSpecificTargetIdentifier()) .citizenCountryCode(authData.getCiticenCountryCode()) - .matchingMethod(extractMatchingState(protocolRequest.getRawData(MsEidasNodeConstants.DATA_MATCHING_STATE))) + .matchingMethod(extractMatchingState(protocolRequest)) + .matchingDetails(extractMatchingDetails(protocolRequest)) .build()); writeEntryToLog(entry); @@ -97,12 +101,29 @@ public class AdvancedStatisicLogger implements IStatisticLogger { ? (String)appId : DEFAULT_NO_SP_ID); } - - private String extractMatchingState(Object state) { + + private String extractMatchingState(IRequest protocolRequest) { + Object state = protocolRequest.getRawData(MsEidasNodeConstants.DATA_MATCHING_STATE); return state != null ? state.toString() : MsEidasNodeConstants.MatchingStates.NO_REQUIRED.toString(); } + private DetailedMatchtingStatistic extractMatchingDetails(IRequest protocolRequest) { + try { + if (!MsEidasNodeConstants.MatchingStates.NO_REQUIRED.toString().equals( + extractMatchingState(protocolRequest))) { + return MatchingTaskUtils.getDetailedMatchingStatistic(protocolRequest); + + } + + } catch (EaafStorageException e) { + log.warn("Can not generate detailed matching statistic", e); + + } + + return null; + } + private void writeEntryToLog(StatisticLogEntry entry) { try { log.info(mapper.writeValueAsString(entry)); @@ -146,7 +167,6 @@ public class AdvancedStatisicLogger implements IStatisticLogger { @Getter @Setter @Builder - @RequiredArgsConstructor @JsonInclude(Include.NON_NULL) private static class SuccessEntry { @@ -159,6 +179,8 @@ public class AdvancedStatisicLogger implements IStatisticLogger { @JsonProperty("finalMatchingMethod") private final String matchingMethod; + @JsonProperty("matchingProcessDetails") + private final DetailedMatchtingStatistic matchingDetails; } -- cgit v1.2.3