因此,我注意到了一个我想分享的奇怪行为,看看是否有人遇到过类似的问题。 我们在Prem解决方案中使用我们提取文件或http事件请求,将其映射到传出xml xsd / schema,然后稍后在prem中创建文件。
问题在于,我们保存文件的系统与逻辑应用程序协作不佳,逻辑应用程序有时无法正常运行,因为系统在逻辑应用程序可以完成写入全部内容之前先获取文件。 接收文件的系统仅读取.xml文件,因此尽管我们应该首先将文件重命名为tmp,让逻辑应用创建文件然后重命名。 在开始将其实际应用到逻辑应用程序之前,此解决方案听起来很简单。
如果我们使用具有重命名文件功能的FileSystem函数,并使用prem上创建文件中的参数“ Name”
{
"statusCode": 404,
"message": "Resource not found"
}
我们收到消息404,提示找不到资源,这使很多事情变得复杂,我检查了该帐户的特权,这应该不是问题。 我们还尝试了列出文件夹中的所有文件,创建foreach,然后添加规则和“重命名文件”功能。这使它可以工作,但是逻辑应用程序不能很好地解决使用该解决方案接收文件的问题。 但是,重命名文件在foreach循环中有效,并且我们从根文件夹或普通文件夹中提取列表中的文件名。
答案 0 :(得分:0)
因此,在与Microsoft在Azure上的支持进行讨论之后,他们实际上已经确认“创建文件”功能存在错误。 看来在该功能期间实际上丢失了所有数据和信息,支持技术人员不知道为什么会发生这种情况,但是他们曾举报过类似的案例。 我没有偶然发现任何这些帖子,但是我将发布解决方法如何解决问题。 仅供参考,支持团队已进一步研究此案,以便天青的开发人员应对此进行调查,因为创建文件时丢失的不仅仅是“名称”标签(实际上所有有价值的选项都丢失了)。
因此,我们首先初始化变量,然后在创建文件之前通过两个步骤实际设置变量名称:
使用临时名称和GUID设置名称。
下一步是使用函数“ Set Variable Temp FileName”中使用的临时名称创建文件。
在“重命名文件”功能上,我们使用存储临时文件的路径并添加\“ FILENAME”
并添加我们要使用的“新名称”。
这被证明是可行的,但是是一种解决方法,支持人员确认,在使用临时名称创建文件并将其更改为所需名称后,您应该能够使用“ RenameFile”。 但是由于创建文件根本不发送或传递此列表中的任何信息,因此我们必须初始化变量以使其起作用。
如果有人偶然发现了一个问题,即后端系统在逻辑应用程序管理文件创建之前先读取文件,那么您需要一些解决方法,这对我很有用。 希望对您有帮助!
答案 1 :(得分:0)
我们最近遇到了同样的问题;并且重命名文件的解决方法也失败。 原因似乎是,Azure On Prem Gateway创建了一个文件(或重命名了一个文件),然后在检查文件是否存在之前释放其锁。在释放锁和检查文件是否存在之间的间隙中,文件可能会被拾取(删除),从而使LogicApps认为该步骤失败(报告404错误),从而造成混乱。
我们的解决方法是创建一个Windows服务,该服务托管在文件服务器上(这样它们就可以在网络上其他任何内容之前响应文件更改)。该服务具有一个配置文件,该文件接受路径和文件过滤器的列表,并且使用FileSystemWatcher监视新文件或重命名的文件。当它检测到匹配项时,将对文件进行读取锁定。这确保了它不会被任何写入文件的操作所阻塞(即,这样,在获得自己的锁之前不必等待On Prem Gateway的写入过程完成),但是在我们的服务持有其锁的同时,文件也不会已删除(因此,消费者无法删除文件/购买时间以使On Prem Gateway进行写入后读取并报告成功)。我们的服务会在定义的时间段后释放自己的锁(我们已经走了30秒钟,尽管您可能花更少的时间逃脱)。此时,使用者可以成功使用文件。
以下文件监视和锁定逻辑的基本代码:
sing System;
using System.IO;
using System.Diagnostics;
using System.Threading.Tasks;
namespace AzureFileGatewayHelper
{
public class Interceptor: IDisposable
{
object lockable = new object();
bool disposed = false;
readonly FileSystemWatcher watcher;
readonly int lockTimeInMS;
public Interceptor(string path, string filter, int lockTimeInSeconds)
{
lockTimeInMS = lockTimeInSeconds * 1000;
watcher = new FileSystemWatcher();
watcher.Path = path;
watcher.Filter = filter;
watcher.NotifyFilter = NotifyFilters.LastAccess
| NotifyFilters.LastWrite
| NotifyFilters.FileName
| NotifyFilters.DirectoryName;
watcher.Created += OnIncercept;
watcher.Renamed += OnIncercept;
}
public Interceptor(InterceptorConfigElement config) : this(config.Path, config.Filter, config.TimeToLockInSeconds) { Debug.WriteLine($"Loaded config ${config.Key}: Path: '${config.Path}'; Filter: '${config.Filter}'; LockTime: : '${config.TimeToLockInSeconds}'."); }
public void Start()
{
watcher.EnableRaisingEvents = true;
}
public void Stop()
{
if (watcher != null)
watcher.EnableRaisingEvents = false;
}
private async void OnIncercept(object source, FileSystemEventArgs e)
{
using (var fs = new FileStream(e.FullPath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
{
Debug.WriteLine($"Locked: {e.FullPath} {e.ChangeType}");
await Task.Delay(lockTimeInMS);
}
Debug.WriteLine($"Unlocked {e.FullPath} {e.ChangeType}");
}
public void Dispose()
{
if (disposed) return;
lock (lockable)
{
if (disposed) return;
Stop();
watcher?.Dispose();
disposed = true;
}
}
}
}