/// <summary> /// Returns a list of "restricted" header names that will be overridden when calling #createEffectiveHeader /// The restricted header names are SenderId, RecipientId, DocumentTypeIdentifier and ProfileTypeIdentifier /// Compares values that exist both as parsed and supplied headers. /// Ignores values that only exists in one of them (that allows for sending new and unknown document types) /// </summary> protected List <String> FindRestricedHeadersThatWillBeOverridden( PeppolStandardBusinessHeader parsed, PeppolStandardBusinessHeader supplied) { List <String> headers = new List <String>(); if ((parsed.SenderId != null) && (supplied.SenderId != null) && (!supplied.SenderId.Equals(parsed.SenderId))) { headers.Add("SenderId"); } if ((parsed.RecipientId != null) && (supplied.RecipientId != null) && (!supplied.RecipientId.Equals(parsed.RecipientId))) { headers.Add("RecipientId"); } if ((parsed.DocumentTypeIdentifier != null) && (supplied.DocumentTypeIdentifier != null) && (!supplied.DocumentTypeIdentifier.Equals( parsed.DocumentTypeIdentifier))) { headers.Add("DocumentTypeIdentifier"); } if ((parsed.ProfileTypeIdentifier != null) && (supplied.ProfileTypeIdentifier != null) && (!supplied.ProfileTypeIdentifier .Equals(parsed.ProfileTypeIdentifier))) { headers.Add("ProfileTypeIdentifier"); } return(headers); }
private byte[] WrapPayLoadWithSbdh( Stream byteArrayInputStream, PeppolStandardBusinessHeader effectivesbh) { SbdhWrapper sbdhWrapper = new SbdhWrapper(); return(sbdhWrapper.Wrap(byteArrayInputStream, effectivesbh.ToVefa())); }
private PeppolStandardBusinessHeader ParsePayLoadAndDeduceSbdh( PeppolStandardBusinessHeader optionallyParsedSbdh) { if (optionallyParsedSbdh != null) { return(optionallyParsedSbdh); } return(new PeppolStandardBusinessHeader(this.contentDetector.Parse(this.payload.ToStream()))); }
/// <summary> /// Builds the actual <see cref="ITransmissionRequest"/>. /// /// The <see cref="PeppolStandardBusinessHeader"/> is build as following /// /// <ol> /// <li>If the payload contains an SBHD, allow override if global "overrideAllowed" flag is set, otherwise use the one parsed</li> /// <li>If the payload does not contain an SBDH, parse payload to determine some of the SBDH attributes and allow override if global "overrideAllowed" flag is set.</li> /// </ol> /// </summary> /// <returns>Prepared transmission request</returns> public ITransmissionRequest Build() { if (this.payload.Length < 2) { throw new HyperwayTransmissionException("You have forgotten to provide payload"); } PeppolStandardBusinessHeader optionalParsedSbdh = null; try { optionalParsedSbdh = new PeppolStandardBusinessHeader(SbdhParser.Parse(this.payload.ToStream())); } catch (InvalidOperationException) { // No action. } // Calculates the effectiveStandardBusinessHeader to be used this.effectiveStandardBusinessHeader = this.MakeEffectiveSbdh(optionalParsedSbdh, this.suppliedHeaderFields); // If the endpoint has not been overridden by the caller, look up the endpoint address in // the SMP using the data supplied in the payload if (this.IsEndpointSuppliedByCaller() && this.IsOverrideAllowed()) { Log.Warn("Endpoint was set by caller not retrieved from SMP, make sure this is intended behaviour."); } else { Endpoint endpointLookedup = this.lookupService.Lookup(this.effectiveStandardBusinessHeader.ToVefa(), null); if (this.IsEndpointSuppliedByCaller() && !this.endpoint.Equals(endpointLookedup)) { throw new InvalidOperationException("You are not allowed to override the EndpointAddress from SMP."); } this.endpoint = endpointLookedup; } // make sure payload is encapsulated in SBDH if (optionalParsedSbdh == null) { // Wraps the payload with an SBDH, as this is required for AS2 this.payload = this.WrapPayLoadWithSbdh(this.payload.ToStream(), this.effectiveStandardBusinessHeader); } // Transfers all the properties of this object into the newly created TransmissionRequest return(new DefaultTransmissionRequest( this.GetEffectiveStandardBusinessHeader().ToVefa(), this.GetPayload(), this.GetEndpoint())); }
/// <summary> /// Merges the SBDH parsed from the payload with the SBDH data supplied by the caller, i.e. the caller wishes to /// override the contents of the SBDH parsed. That is, if the payload contains an SBDH /// </summary> /// <param name="optionalParsedSbdh">the SBDH as parsed (extracted) from the payload.</param> /// <param name="peppolSbdhSuppliedByCaller">the SBDH data supplied by the caller in order to override data from the payload</param> /// <returns>the merged, effective SBDH created by combining the two data sets</returns> private PeppolStandardBusinessHeader MakeEffectiveSbdh( PeppolStandardBusinessHeader optionalParsedSbdh, PeppolStandardBusinessHeader peppolSbdhSuppliedByCaller) { PeppolStandardBusinessHeader effectiveSbdh; if (this.IsOverrideAllowed()) { if (peppolSbdhSuppliedByCaller.IsComplete()) { // we have sufficient meta data (set explicitly by the caller using API functions) effectiveSbdh = peppolSbdhSuppliedByCaller; } else { // missing meta data, parse payload, which does not contain SBHD, in order to deduce missing fields PeppolStandardBusinessHeader parsedPeppolStandardBusinessHeader = this.ParsePayLoadAndDeduceSbdh(optionalParsedSbdh); effectiveSbdh = this.CreateEffectiveHeader(parsedPeppolStandardBusinessHeader, peppolSbdhSuppliedByCaller); } } else { // override is not allowed, make sure we do not override any restricted headers PeppolStandardBusinessHeader parsedPeppolStandardBusinessHeader = this.ParsePayLoadAndDeduceSbdh(optionalParsedSbdh); List <String> overriddenHeaders = this.FindRestricedHeadersThatWillBeOverridden( parsedPeppolStandardBusinessHeader, peppolSbdhSuppliedByCaller); if (overriddenHeaders.Count == 0) { effectiveSbdh = this.CreateEffectiveHeader( parsedPeppolStandardBusinessHeader, peppolSbdhSuppliedByCaller); } else { var txtValues = overriddenHeaders.ToArray().ToStringValues(); throw new InvalidOperationException( "Your are not allowed to override " + txtValues + " in production mode, makes sure headers match the ones in the document."); } } if (!effectiveSbdh.IsComplete()) { var txtValues = effectiveSbdh.ListMissingProperties().ToArray().ToStringValues(); throw new InvalidOperationException( $"TransmissionRequest can not be built, missing {txtValues} metadata."); } return(effectiveSbdh); }
/// <summary> /// Merges the supplied header fields with the SBDH parsed or derived from the payload thus allowing the caller /// to explicitly override whatever has been supplied in the payload. /// </summary> /// <param name="parsed">the PeppolStandardBusinessHeader parsed from the payload</param> /// <param name="supplied">the header fields supplied by the caller</param> /// <returns>the merged and effective headers</returns> protected PeppolStandardBusinessHeader CreateEffectiveHeader(PeppolStandardBusinessHeader parsed, PeppolStandardBusinessHeader supplied) { // Creates a copy of the original business headers PeppolStandardBusinessHeader mergedHeaders = new PeppolStandardBusinessHeader(parsed); if (supplied.SenderId != null) { mergedHeaders.SenderId = supplied.SenderId; } if (supplied.RecipientId != null) { mergedHeaders.RecipientId = supplied.RecipientId; } if (supplied.DocumentTypeIdentifier != null) { mergedHeaders.DocumentTypeIdentifier = supplied.DocumentTypeIdentifier; } if (supplied.ProfileTypeIdentifier != null) { mergedHeaders.ProfileTypeIdentifier = supplied.ProfileTypeIdentifier; } // If instanceId was supplied by caller, use it otherwise, create new if (supplied.InstanceId != null) { mergedHeaders.InstanceId = supplied.InstanceId; } else { mergedHeaders.InstanceId = new InstanceId(); } if (supplied.CreationDateAndTime != null) { mergedHeaders.CreationDateAndTime = supplied.CreationDateAndTime; } return(mergedHeaders); }
public void Reset() { this.suppliedHeaderFields = new PeppolStandardBusinessHeader(); this.effectiveStandardBusinessHeader = null; }
/// <summary> /// Parses and extracts the data needed to create a PeppolStandardBusinessHeader object. The inputstream supplied /// should not be wrapped in an SBDH. /// </summary> /// <param name="inputStream"></param> /// <returns></returns> public PeppolStandardBusinessHeader OriginalParse(Stream inputStream) { try { XDocument document = XDocument.Load(inputStream); var nsResolver = new HardCodedNamespaceResolver(); PeppolStandardBusinessHeader sbdh = PeppolStandardBusinessHeader.CreatePeppolStandardBusinessHeaderWithNewDate(); // use the plain UBL header parser to decode format and create correct document parser PlainUblHeaderParser headerParser = new PlainUblHeaderParser(document, nsResolver); // make sure we actually have a UBL type document if (headerParser.CanParse()) { sbdh.DocumentTypeIdentifier = headerParser.FetchDocumentTypeId().ToVefa(); sbdh.ProfileTypeIdentifier = headerParser.FetchProcessTypeId(); // try to use a specialized document parser to fetch more document details IPeppolDocumentParser documentParser = null; try { documentParser = headerParser.CreateDocumentParser(); } catch (Exception) { /* * allow this to happen so that "unknown" PEPPOL documents still * can be used by explicitly setting sender and receiver thru API */ } /* However, if we found an eligible parser, we should be able to determine the sender and receiver */ if (documentParser != null) { try { sbdh.SenderId = documentParser.Sender; } catch (Exception) { // Continue with recipient } try { sbdh.RecipientId = documentParser.Receiver; } catch (Exception) { // Just continue } } } return(sbdh); } catch (Exception e) { throw new HyperwayContentException("Unable to parse document " + e.Message, e); } }