/// <summary> /// Finds the counterparty between us and some other communication party /// </summary> /// <param name="logger"></param> /// <param name="counterpartyHerId">Her id of counterparty</param> /// <returns></returns> public async Task <CollaborationProtocolProfile> FindAgreementForCounterpartyAsync(ILogger logger, int counterpartyHerId) { logger.LogDebug($"Start-FindAgreementForCounterpartyAsync {counterpartyHerId}"); var key = $"CPA_FindAgreementForCounterpartyAsync_{_settings.MyHerId}_{counterpartyHerId}"; var result = await CacheExtensions.ReadValueFromCache <CollaborationProtocolProfile>(logger, _cache, key).ConfigureAwait(false); if (result != null) { var errors = CertificateErrors.None; errors |= CertificateValidator.Validate(result.EncryptionCertificate, X509KeyUsageFlags.DataEncipherment); errors |= CertificateValidator.Validate(result.SignatureCertificate, X509KeyUsageFlags.NonRepudiation); // if the certificates are valid, only then do we return a value from the cache if (errors == CertificateErrors.None) { return(result); } } CPAService.CpaXmlDetails details; try { logger.LogDebug($"StartServiceCall-FindAgreementForCounterparty {counterpartyHerId}"); details = await FindAgreementForCounterparty(logger, counterpartyHerId).ConfigureAwait(false); logger.LogDebug($"EndServiceCall-FindAgreementForCounterparty {counterpartyHerId}"); } catch (FaultException ex) { // if there are error getting a proper CPA, we fallback to getting CPP. logger.LogWarning($"Failed to resolve CPA between {_settings.MyHerId} and {counterpartyHerId}. {ex.Message}"); return(await FindProtocolForCounterpartyAsync(logger, counterpartyHerId)); } if (string.IsNullOrEmpty(details?.CollaborationProtocolAgreementXml)) { return(null); } var doc = XDocument.Parse(details.CollaborationProtocolAgreementXml); if (doc.Root == null) { return(null); } var node = (from x in doc.Root.Elements(_ns + "PartyInfo").Elements(_ns + "PartyId") where x.Value != _settings.MyHerId.ToString() select x.Parent).First(); result = MapFrompartyInfo(node); result.CpaId = Guid.Parse(doc.Root.Attribute(_ns + "cpaid").Value); await CacheExtensions.WriteValueToCache(logger, _cache, key, result, _settings.CachingInterval).ConfigureAwait(false); logger.LogDebug($"End-FindAgreementForCounterpartyAsync {counterpartyHerId}"); return(result); }
/// <summary> /// Finds a CPA based on an id, and returns the CPP profile for the other communication party /// </summary> /// <param name="logger"></param> /// <param name="id">CPA id</param> /// <param name="forceUpdate">Set to true to force cache update.</param> /// <returns></returns> public async Task <CollaborationProtocolProfile> FindAgreementByIdAsync(ILogger logger, Guid id, bool forceUpdate) { logger.LogDebug($"FindAgreementByIdAsync {id}"); var key = $"CPA_FindAgreementByIdAsync_{id}"; var result = forceUpdate ? null : await CacheExtensions.ReadValueFromCache <CollaborationProtocolProfile>(logger, _cache, key).ConfigureAwait(false); if (result != null) { var errors = CertificateErrors.None; errors |= CertificateValidator.Validate(result.EncryptionCertificate, X509KeyUsageFlags.DataEncipherment); errors |= CertificateValidator.Validate(result.SignatureCertificate, X509KeyUsageFlags.NonRepudiation); // if the certificates are valid, only then do we return a value from the cache if (errors == CertificateErrors.None) { return(result); } } CPAService.CpaXmlDetails details; try { details = await FindAgreementById(logger, id).ConfigureAwait(false); } catch (FaultException ex) { throw new RegistriesException(ex.Message, ex) { EventId = EventIds.CollaborationAgreement, Data = { { "CpaId", id } } }; } if (string.IsNullOrEmpty(details?.CollaborationProtocolAgreementXml)) { return(null); } var doc = XDocument.Parse(details.CollaborationProtocolAgreementXml); if (doc.Root == null) { return(null); } var node = (from x in doc.Root.Elements(_ns + "PartyInfo").Elements(_ns + "PartyId") where x.Value != _settings.MyHerId.ToString() select x.Parent).First(); result = MapFrompartyInfo(node); result.CpaId = id; await CacheExtensions.WriteValueToCache(logger, _cache, key, result, _settings.CachingInterval).ConfigureAwait(false); return(result); }
/// <summary> /// Gets the CPP profile for a specific communication party /// </summary> /// <param name="logger"></param> /// <param name="counterpartyHerId">Her Id of communication party</param> /// <returns></returns> public async Task <CollaborationProtocolProfile> FindProtocolForCounterpartyAsync(ILogger logger, int counterpartyHerId) { logger.LogDebug($"FindProtocolForCounterpartyAsync {counterpartyHerId}"); var key = $"CPA_FindProtocolForCounterpartyAsync_{counterpartyHerId}"; var result = await CacheExtensions.ReadValueFromCache <CollaborationProtocolProfile>(logger, _cache, key).ConfigureAwait(false); var xmlString = string.Empty; if (result != null) { var errors = CertificateErrors.None; errors |= CertificateValidator.Validate(result.EncryptionCertificate, X509KeyUsageFlags.DataEncipherment); errors |= CertificateValidator.Validate(result.SignatureCertificate, X509KeyUsageFlags.NonRepudiation); // if the certificates are valid, only then do we return a value from the cache if (errors == CertificateErrors.None) { return(result); } } try { xmlString = await FindProtocolForCounterparty(logger, counterpartyHerId).ConfigureAwait(false); } catch (FaultException <CPAService.GenericFault> ex) { // if this happens, we fall back to the dummy profile further down logger.LogWarning($"Error resolving protocol for counterparty. ErrorCode: {ex.Detail.ErrorCode} Message: {ex.Detail.Message}"); } catch (Exception ex) { throw new RegistriesException(ex.Message, ex) { EventId = EventIds.CollaborationProfile, Data = { { "HerId", counterpartyHerId } } }; } if (string.IsNullOrEmpty(xmlString)) { result = CreateDummyCollaborationProtocolProfile(counterpartyHerId, await _adressRegistry.GetCertificateDetailsForEncryptionAsync(logger, counterpartyHerId).ConfigureAwait(false), await _adressRegistry.GetCertificateDetailsForValidatingSignatureAsync(logger, counterpartyHerId).ConfigureAwait(false)); } else { var doc = XDocument.Parse(xmlString); result = doc.Root == null ? null : MapFrompartyInfo(doc.Root.Element(_ns + "PartyInfo")); } await CacheExtensions.WriteValueToCache(logger, _cache, key, result, _settings.CachingInterval).ConfigureAwait(false); return(result); }
/// <summary> /// Returns communication details for a specific counterparty /// </summary> /// <param name="logger"></param> /// <param name="herId">Her id of counterpary</param> /// <param name="forceUpdate">Set to true to force cache update.</param> /// <returns>Communication details if found, otherwise null</returns> public async Task <CommunicationPartyDetails> FindCommunicationPartyDetailsAsync(ILogger logger, int herId, bool forceUpdate) { var key = $"AR_FindCommunicationPartyDetailsAsync_{herId}"; var party = forceUpdate ? null : await CacheExtensions.ReadValueFromCache <CommunicationParty>(logger, _cache, key).ConfigureAwait(false); if (party == null) { try { party = await FindCommunicationPartyDetails(logger, herId).ConfigureAwait(false); } catch (FaultException ex) { throw new RegistriesException(ex.Message, ex) { EventId = EventIds.CommunicationPartyDetails, Data = { { "HerId", herId } } }; } await CacheExtensions.WriteValueToCache(logger, _cache, key, party, _settings.CachingInterval).ConfigureAwait(false); } return(party == null ? default(CommunicationPartyDetails) : MapCommunicationPartyDetails(party)); }
/// <summary> /// Returns the signature certificate for a specific communication party. /// </summary> /// <param name="logger"></param> /// <param name="herId">Her-ID of the communication party</param> /// <param name="forceUpdate">Set to true to force cache update.</param> /// <returns></returns> public async Task <Abstractions.CertificateDetails> GetCertificateDetailsForValidatingSignatureAsync(ILogger logger, int herId, bool forceUpdate) { var key = $"AR_GetCertificateDetailsForValidationSignature{herId}"; var certificateDetails = forceUpdate ? null : await CacheExtensions.ReadValueFromCache <AddressService.CertificateDetails>(logger, _cache, key).ConfigureAwait(false); if (certificateDetails == null) { try { certificateDetails = await GetCertificateDetailsForValidatingSignatureInternal(logger, herId).ConfigureAwait(false); } catch (FaultException ex) { throw new RegistriesException(ex.Message, ex) { EventId = EventIds.CerificateDetails, Data = { { "HerId", herId } } }; } await CacheExtensions.WriteValueToCache(logger, _cache, key, certificateDetails, _settings.CachingInterval).ConfigureAwait(false); } return(certificateDetails == null ? default(Abstractions.CertificateDetails) : MapCertificateDetails(herId, certificateDetails)); }