0

I have a BizTalk Custom Pipeline Component that writes an SFTP file (using SSH.net), triggered by an SFTP (WinSCP) receive location.

The code within the Retry occasionally (around half the time) does not hit either the "Success" nor the logging catch block and no further processing occurs within the Pipeline. I assume that means the thread has been destroyed.

I added the Retry code later to make it try a few times but with the thread being destroyed I don't always get a success or 3 failures.

What could cause this behaviour in BizTalk 2016?

public void Archive(byte[] content,
            string archivePath,
            string userName,
            string password,
            string serverAddress,
            string sshHostKeyFingerprint)
        {
            Retry(3, () =>
            {
                try
                {
                    using (var sftpClient = new SftpClient(serverAddress, userName, password))
                    {
                        if (!string.IsNullOrWhiteSpace(sshHostKeyFingerprint))
                        {
                            sshHostKeyFingerprint = sshHostKeyFingerprint.Split(' ').Last();
                            sftpClient.HostKeyReceived += delegate (object sender, HostKeyEventArgs e)
                            {
                                if (e.FingerPrint.SequenceEqual(ConvertFingerprintToByteArray(sshHostKeyFingerprint)))
                                    e.CanTrust = true;
                                else
                                    e.CanTrust = false;
                            };
                        }
                        sftpClient.Connect();
                        sftpClient.WriteAllBytes(archivePath, content);
                        sftpClient.Disconnect();
                        LogInfo($"Success");
                    }
                }
                catch (Exception exception)
                {
                    // show the bad path for "No such file" errors
                    throw new InvalidOperationException($"Failed to create file '{archivePath}'", exception);
                }
            });
        }

private void Retry(int maxAttempts, Action action)
        {
            int attempt = 1;
            while (attempt <= maxAttempts)
            {
                try
                {
                    action();
                    break; // success
                }
                catch (Exception exception)
                {
                    LogWarning($"Attempt {attempt} Error: {exception.ToString()}");
                    if (attempt == maxAttempts)
                        throw; // final attempt exception propagated
                }
                finally
                {
                    attempt++;
                }
            }
        }
Dijkgraaf
  • 11,049
  • 17
  • 42
  • 54
Kaido
  • 3,383
  • 24
  • 34
  • Is there any reason you are doing this in a Pipeline Component rather than using the SFTP Adapter in a Send Port? Is your Pipeline Component in your receive port or send port? At what stage in the pipeline is the custom component? – Dijkgraaf Feb 10 '21 at 20:42
  • Can the sftp adaptor write the file to another folder on SFTP server? – Kaido Feb 10 '21 at 20:43
  • 1
    Yes, just have a SFTP send port that subscribes to your Receive Port and configure it to point to that folder. – Dijkgraaf Feb 10 '21 at 20:44
  • Thanks @Dijkgraaf this was the inherited solution but I prefer your suggestion and it will be quicker to implement than to fix this. – Kaido Feb 10 '21 at 20:56
  • FYI. One possible failure point is that when you log the warning that the length of the exception could exceed the length that the event log allows, which means it would fail in the catch block. – Dijkgraaf Feb 10 '21 at 22:42
  • I've seen that scenario and so there is message truncation that has been working well. It is a good point though. With the new send port I will need the raw unparsed plaintext file, so i think I'll need a new raw receive as well as per TBerg here https://social.msdn.microsoft.com/Forums/en-US/cdde6d1f-ca72-4433-83d6-c0c4354c36a8/flat-file-import-keep-copy-of-original-delimited-text?forum=biztalkgeneral – Kaido Feb 11 '21 at 09:56
  • Another possibility I hadnt considered until now is that the threads are hung - I dont have development tools in that environment to check – Kaido Feb 11 '21 at 09:58
  • 1
    Another option is to have an archive component that archives to a local folder, where you pick it up with a pass thru receive and send it to the SFTP archive via a pass thru send port. – Dijkgraaf Feb 11 '21 at 19:36
  • Thanks for your help with this @Dijkgraaf - when turning off this feature, i continued to have SFTP issues with the SFTP receives alone. We've now resolved that issue and this one by reducing the connection count setting on the receives to 1. – Kaido Feb 12 '21 at 12:11

0 Answers0