Beispiel #1
0
        /// <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);
        }
Beispiel #2
0
        private byte[] WrapPayLoadWithSbdh(
            Stream byteArrayInputStream,
            PeppolStandardBusinessHeader effectivesbh)
        {
            SbdhWrapper sbdhWrapper = new SbdhWrapper();

            return(sbdhWrapper.Wrap(byteArrayInputStream, effectivesbh.ToVefa()));
        }
Beispiel #3
0
        private PeppolStandardBusinessHeader ParsePayLoadAndDeduceSbdh(
            PeppolStandardBusinessHeader optionallyParsedSbdh)
        {
            if (optionallyParsedSbdh != null)
            {
                return(optionallyParsedSbdh);
            }

            return(new PeppolStandardBusinessHeader(this.contentDetector.Parse(this.payload.ToStream())));
        }
Beispiel #4
0
        /// <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()));
        }
Beispiel #5
0
        /// <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);
        }
Beispiel #6
0
        /// <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);
        }
Beispiel #7
0
 public void Reset()
 {
     this.suppliedHeaderFields            = new PeppolStandardBusinessHeader();
     this.effectiveStandardBusinessHeader = null;
 }
Beispiel #8
0
        /// <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);
            }
        }