Как я могу распаковать файл gzip в пользовательском конвейере

Я попытался создать собственный конвейер BizTalk 2013 R2 (получение или отправка), который может распаковывать файл xxx.GZ, содержащий несколько файлов txt, на порт отправки.

Вот что я пробовал до сих пор:

PS. Я использовал классы .Net IO GZip.

  1. Создал приложение BTS, настроил место получения и порт отправки.

  2. Место получения использует пользовательский конвейер, который я создал, вот мой код пользовательского конвейера, который я пробовал:

        public void Disassemble(IPipelineContext pc, IBaseMessage inmsg)
        {
            IBaseMessagePart bodyPart = inmsg.BodyPart;
    
            if (bodyPart != null)
            {
                Stream originalStream = bodyPart.GetOriginalDataStream();
    
               if (originalStream != null)
                {                     
                    using (GZipStream gZipInputStream = new GZipStream(new MemoryStream(originalStream.ReadByte()), CompressionMode.Decompress))
                    {    
                        MemoryStream memStream = new MemoryStream();
                        byte[] buffer = new Byte[1024];
    
                        int bytesRead = 1024;
                        while (bytesRead != 0)
                        {
                            bytesRead = gZipInputStream.Read(buffer, 0, buffer.Length);
    
                            gZipInputStream.CopyTo(buffer, 0);
                            memStream.Write(buffer, 0, bytesRead);
                        }
    
                        IBaseMessage outMessage;
                        outMessage = pc.GetMessageFactory().CreateMessage();
                        outMessage.AddPart("Body", pc.GetMessageFactory().CreateMessagePart(), true);
                        memStream.Position = 0;
                        outMessage.BodyPart.Data = memStream;
    
                        outMessage.Context = PipelineUtil.CloneMessageContext(inmsg.Context);
    
                        _msgs.Enqueue(outMessage);
    
                        }
                    }   
            }
    
        }
    

Этот код, кажется, не работает, как я хочу. просто отправьте файл GZ, не распаковывая его, на порт отправки. Я использую реализованный конвейер в порту местоположения приема. Вот как это работает: Когда BizTalk получает файл, упакованный GZ, в место его приема, он просто отправляет файл на порт отправки, подписанный на это место получения. Похоже, что конвейер ничего не делает с потоком GZ. Что он должен сделать, так это распаковать файл GZ и отправить все распакованные файлы на порт отправки, это указывает на папку, в которую необходимо поместить файлы для распаковки.

Я безуспешно пытался использовать Google, и существующие образцы, похоже, не работают для меня.

Так может ли кто-нибудь помочь мне или сказать, что я делаю неправильно в своем коде. Я просто хочу реализовать собственный конвейер C# BizTalk 2013 R2 (получение или отправка), который может распаковывать полученный файл GZ, содержащий некоторые файлы txt, в порт отправки (указать папку)?

Обновление:

Поскольку версия Dissambler не работала, я создал версию с декодированием.

Вот код декодирования в конвейере:

                #region IComponent members
    /// <summary>
    /// Implements IComponent.Execute method.
    /// </summary>
    /// <param name="pc">Pipeline context</param>
    /// <param name="inmsg">Input message</param>
    /// <returns>Original input message</returns>
    /// <remarks>
    /// IComponent.Execute method is used to initiate
    /// the processing of the message in this pipeline component.
    /// </remarks>
    public Microsoft.BizTalk.Message.Interop.IBaseMessage Execute(Microsoft.BizTalk.Component.Interop.IPipelineContext pc, Microsoft.BizTalk.Message.Interop.IBaseMessage inmsg)
    {
        if (null == pc) throw new ArgumentNullException("pContext", "Pipeline context can not be null");

        if (null == inmsg) throw new ArgumentNullException("pInMsg", "Input message can not be null");

        IBaseMessagePart bodyPart = inmsg.BodyPart;

        if (bodyPart != null)
        {
            GZipStream strm = new GZipStream(bodyPart.GetOriginalDataStream(), CompressionMode.Decompress);
            bodyPart.Data = strm;
            pc.ResourceTracker.AddResource(strm);
        }

        return inmsg;
    }
    #endregion

Как я могу получить правильное имя файла для каждого файла в файле GZip? Поэтому, когда сообщение отправляется на порт отправки, оно должно записать файл с правильным именем.


person Balatharan    schedule 03.10.2016    source источник
comment
Привет, Он не выдает никаких ошибок, а просто отправляет файл GZ, не распаковывая его, на порт отправки. Я использую реализованный конвейер в порту местоположения получения. Вот как это работает: Когда BizTalk получает файл, упакованный GZ, в место его приема, он просто отправляет файл на порт отправки, подписанный на это место получения. Похоже, что конвейер ничего не делает с потоком GZ. Что он должен сделать, так это распаковать файл GZ и отправить все распакованные файлы на порт отправки, указывая на папку, в которую необходимо поместить файлы для распаковки.   -  person Balatharan    schedule 04.10.2016
comment
Мне просто интересно, нужно ли мне реализовать часть дизассемблирования или декодера в конвейере, чтобы распаковать файл gz.?   -  person Balatharan    schedule 04.10.2016
comment
Затем отредактируйте свой вопрос и добавьте эти детали в вопрос. Я был бы склонен поместить его в часть декодирования конвейера, так как вы можете также иметь плоский файл или компонент конвейера дизассемблера xml, выполняющийся после него, если это необходимо, вы НЕ можете иметь два компонента, которые оба выполняются на этапе дизассемблера. Если это stage содержит более одного компонента, запускается только первый компонент, распознающий формат сообщения. Если ни один из компонентов на этапе не распознает формат сообщения, обработка сообщения завершается ошибкой. msdn.microsoft.com/en-us/library /ee268059(v=bts.10).aspx   -  person Dijkgraaf    schedule 04.10.2016
comment
Также вы пытались подключить визуальную студию к процессу хоста и поместить точки останова в свой собственный компонент конвейера?   -  person Dijkgraaf    schedule 04.10.2016
comment
В Stackoverflow считается плохой практикой в ​​основном изменять вопрос, чтобы он делал ответ недействительным. В этом случае вам следует опубликовать новую проблему как новый вопрос (со ссылкой на исходный вопрос, если это проясняет ситуацию) или добавить дополнительные детали к вопросу (как я сделал с помощью отката и редактирования).   -  person Dijkgraaf    schedule 04.10.2016


Ответы (1)


Похоже, вы реализовали пользовательский компонент конвейера как этап дизассемблирования, на самом деле он должен быть компонентом конвейера этапа декодирования по следующим двум причинам.

  1. На этапе дизассемблирования у вас может быть только один исполняемый компонент. Это означает, что у вас не может быть исполняемого плоского файла, XML или JSON-диссемблера.
  2. Если это компонент этапа дизассемблирования, вам также необходимо реализовать зонд, чтобы увидеть, распознано ли сообщение, иначе оно не будет выполнено.

См. MSDN Конвейеры получения.

Этап декодирования

  • This stage is used for components that decode or decrypt the message.
    • The MIME/SMIME Decoder pipeline component or a custom decoding component should be placed in this stage if the incoming messages need to be decoded from one format to another.
  • Этот этап принимает одно сообщение и создает одно сообщение.
  • Этот этап может содержать от нуля до 255 компонентов.
  • Все компоненты на этом этапе выполняются.

Этап разборки

Этот этап используется для компонентов, которые анализируют или дизассемблируют сообщение.

  • Компоненты на этом этапе проверяют сообщение, чтобы убедиться, что формат сообщения распознан. На основе распознавания формата один из компонентов дизассемблирует сообщение.
  • Если этот этап содержит более одного компонента, запускается только первый компонент, распознающий формат сообщения. Если ни один из компонентов на этапе не распознает формат сообщения, обработка сообщения завершается ошибкой.
  • Этот этап должен включать все пользовательские компоненты, которые реализуют специальное поведение для дизассемблирования содержимого сообщения.
  • Этот этап может содержать от нуля до 255 компонентов. Если на этапе нет компонентов, сообщение передается.

Обновление: с обновлением вашего вопроса становится немного сложнее. Если вам нужно разделить сообщение на несколько сообщений, единственный этап, на котором вы можете это сделать, — это этап разборки. Поэтому вам придется вернуться к этой версии, отладить ее и выяснить, почему она не выполняет распаковку.

Существует старый образец кода для дизассемблера Zip UnzipDisassembler — A настраиваемый компонент конвейера для BizTalk Server 2004, предназначенный для файлов Zip, а не Gzip. Но он следует той же схеме. Вам также понадобится метод, аналогичный GetNextEntry, для публикации сообщения и последующего анализа следующего файла. Именно на этапе создания outmsg вы можете установить свойства контекста, такие как имя файла.

person Dijkgraaf    schedule 04.10.2016
comment
Привет спасибо. Я нашел образец из BizTalk 2006 SDK и создал конвейер декодирования, как вы упомянули, и теперь он работает нормально. Но у меня есть проблема с получением правильного имени файла, кажется, что он использует имя файла gzip для всех файлов. Я просто изменил пример кода выше. - person Balatharan; 04.10.2016