Beispiel #1
0
 internal static Task ClearCacheAsync(this Portlet portlet, CancellationToken cancellationToken, string correlationID = null, bool clearRelatedDataCache = true, bool clearRelatedHtmlCache = true, bool doRefresh = true)
 => Task.WhenAll(new[]
 {
     portlet.ClearRelatedCacheAsync(cancellationToken, correlationID, clearRelatedDataCache, clearRelatedHtmlCache, doRefresh),
     Utility.Cache.RemoveAsync(portlet, cancellationToken),
     Utility.WriteCacheLogs ? Utility.WriteLogAsync(correlationID, $"Clear cache of a portlet [{portlet.Title} - ID: {portlet.ID}]", ServiceBase.ServiceComponent.CancellationToken, "Caches") : Task.CompletedTask
 });
Beispiel #2
0
        public static Task <List <Portlet> > FindPortletsAsync(this Portlet portlet, CancellationToken cancellationToken = default)
        {
            if (string.IsNullOrWhiteSpace(portlet?.ID) || !portlet.ID.IsValidUUID() || !string.IsNullOrWhiteSpace(portlet.OriginalPortletID))
            {
                return(Task.FromResult(new List <Portlet>()));
            }
            var filter = Filters <Portlet> .Equals("OriginalPortletID", portlet.ID);

            var sort = Sorts <Portlet> .Ascending("DesktopID").ThenByAscending("Zone").ThenByAscending("OrderIndex");

            return(Portlet.FindAsync(filter, sort, 0, 1, Extensions.GetCacheKey(filter, sort), cancellationToken));
        }
Beispiel #3
0
        public static List <Portlet> FindPortlets(this Portlet portlet)
        {
            if (string.IsNullOrWhiteSpace(portlet?.ID) || !portlet.ID.IsValidUUID() || !string.IsNullOrWhiteSpace(portlet.OriginalPortletID))
            {
                return(new List <Portlet>());
            }
            var filter = Filters <Portlet> .Equals("OriginalPortletID", portlet.ID);

            var sort = Sorts <Portlet> .Ascending("DesktopID").ThenByAscending("Zone").ThenByAscending("OrderIndex");

            return(Portlet.Find(filter, sort, 0, 1, Extensions.GetCacheKey(filter, sort)));
        }
Beispiel #4
0
        internal static async Task <JObject> SyncPortletAsync(this RequestInfo requestInfo, CancellationToken cancellationToken = default)
        {
            var data    = requestInfo.GetBodyExpando();
            var portlet = await Portlet.GetAsync <Portlet>(data.Get <string>("ID"), cancellationToken).ConfigureAwait(false);

            if (portlet == null)
            {
                portlet = Portlet.CreateInstance(data);
                await Portlet.CreateAsync(portlet, cancellationToken).ConfigureAwait(false);
            }
            else
            {
                portlet.Fill(data);
                await Portlet.UpdateAsync(portlet, true, cancellationToken).ConfigureAwait(false);
            }

            // clear related cache
            if (requestInfo.GetHeaderParameter("x-converter") != null)
            {
                portlet.ClearRelatedCacheAsync(ServiceBase.ServiceComponent.CancellationToken, requestInfo.CorrelationID).Run();
            }
            else
            {
                await portlet.ClearCacheAsync(cancellationToken, requestInfo.CorrelationID).ConfigureAwait(false);
            }

            // send update messages
            var json       = portlet.ToJson();
            var objectName = portlet.GetTypeName(true);
            await Task.WhenAll(
                Utility.RTUService.SendUpdateMessageAsync(new UpdateMessage
            {
                Type     = $"{requestInfo.ServiceName}#{objectName}#Update",
                Data     = json,
                DeviceID = "*"
            }, cancellationToken),
                Utility.RTUService.SendInterCommunicateMessageAsync(new CommunicateMessage(requestInfo.ServiceName)
            {
                Type           = $"{objectName}#Update",
                Data           = json,
                ExcludedNodeID = Utility.NodeID
            }, cancellationToken)
                ).ConfigureAwait(false);

            // return the response
            return(new JObject
            {
                { "Sync", "Success" },
                { "ID", portlet.ID },
                { "Type", objectName }
            });
        }
Beispiel #5
0
        internal static async Task ProcessInterCommunicateMessageOfPortletAsync(this CommunicateMessage message, CancellationToken cancellationToken = default)
        {
            if (message.Type.IsEndsWith("#Create") || message.Type.IsEndsWith("#Update"))
            {
                Portlet portlet = null;
                if (message.Type.IsEndsWith("#Create"))
                {
                    portlet = message.Data.ToExpandoObject().CreatePortletInstance();
                }
                else
                {
                    portlet = await Portlet.GetAsync <Portlet>(message.Data.Get <string>("ID"), cancellationToken).ConfigureAwait(false);

                    portlet = portlet == null
                                                ? message.Data.ToExpandoObject().CreatePortletInstance()
                                                : portlet.UpdatePortletInstance(message.Data.ToExpandoObject());
                }
                var desktop = await(portlet.DesktopID ?? "").GetDesktopByIDAsync(cancellationToken).ConfigureAwait(false);
                if (desktop != null && desktop._portlets != null)
                {
                    if (!string.IsNullOrWhiteSpace(portlet.OriginalPortletID))
                    {
                        portlet._originalPortlet = await Portlet.GetAsync <Portlet>(portlet.OriginalPortletID, cancellationToken).ConfigureAwait(false);
                    }
                    var index = desktop._portlets.FindIndex(p => p.ID.IsEquals(portlet.ID));
                    if (index < 0)
                    {
                        desktop._portlets.Add(portlet);
                    }
                    else
                    {
                        desktop._portlets[index] = portlet;
                    }
                    desktop.Set();
                }
            }
            else if (message.Type.IsEndsWith("#Delete"))
            {
                var portlet = message.Data.ToExpandoObject().CreatePortletInstance();
                var desktop = await(portlet.DesktopID ?? "").GetDesktopByIDAsync(cancellationToken).ConfigureAwait(false);
                if (desktop != null && desktop._portlets != null)
                {
                    var index = desktop._portlets.FindIndex(p => p.ID.IsEquals(portlet.ID));
                    if (index > -1)
                    {
                        desktop._portlets.RemoveAt(index);
                        desktop.Set();
                    }
                }
            }
        }
Beispiel #6
0
        internal static async Task <JObject> GetPortletAsync(this RequestInfo requestInfo, bool isSystemAdministrator = false, CancellationToken cancellationToken = default)
        {
            // prepare
            var portlet = await Portlet.GetAsync <Portlet>(requestInfo.GetObjectIdentity() ?? "", cancellationToken).ConfigureAwait(false);

            if (portlet == null)
            {
                throw new InformationNotFoundException();
            }
            else if (portlet.Organization == null)
            {
                throw new InformationInvalidException("The organization is invalid");
            }

            // check permission
            var gotRights = isSystemAdministrator || requestInfo.Session.User.IsViewer(null, null, portlet.Organization, requestInfo.CorrelationID);

            if (!gotRights)
            {
                throw new AccessDeniedException();
            }

            // prepare the response
            var response = portlet.ToJson();

            if (string.IsNullOrWhiteSpace(portlet.OriginalPortletID))
            {
                var mappingPortlets = await portlet.FindPortletsAsync(cancellationToken).ConfigureAwait(false) ?? new List <Portlet>();

                response["OtherDesktops"] = mappingPortlets.Where(mappingPortlet => mappingPortlet != null).Select(mappingPortlet => mappingPortlet.DesktopID).Where(id => !string.IsNullOrWhiteSpace(id)).Distinct(StringComparer.OrdinalIgnoreCase).ToJArray();
            }

            // send the update messages and response
            await Utility.RTUService.SendUpdateMessageAsync(new UpdateMessage
            {
                Type             = $"{requestInfo.ServiceName}#{portlet.GetTypeName(true)}#Update",
                Data             = response,
                DeviceID         = "*",
                ExcludedDeviceID = requestInfo.Session.DeviceID
            }, cancellationToken).ConfigureAwait(false);

            return(response);
        }
Beispiel #7
0
        internal static async Task ClearRelatedCacheAsync(this Portlet portlet, CancellationToken cancellationToken = default, string correlationID = null, bool clearDataCache = true, bool clearHtmlCache = true, bool doRefresh = true)
        {
            // data cache keys
            var dataCacheKeys = new List <string>();

            if (clearDataCache)
            {
                dataCacheKeys = Extensions.GetRelatedCacheKeys(Filters <Portlet> .And(Filters <Portlet> .Equals("DesktopID", portlet.DesktopID)), Sorts <Portlet> .Ascending("Zone").ThenByAscending("OrderIndex"));
                if (string.IsNullOrWhiteSpace(portlet.OriginalPortletID))
                {
                    dataCacheKeys = Extensions.GetRelatedCacheKeys(Filters <Portlet> .Equals("OriginalPortletID", portlet.ID), Sorts <Portlet> .Ascending("DesktopID").ThenByAscending("Zone").ThenByAscending("OrderIndex")).Concat(dataCacheKeys).ToList();
                }
            }
            dataCacheKeys = dataCacheKeys.Distinct(StringComparer.OrdinalIgnoreCase).ToList();

            // html cache keys (desktop HTMLs)
            var htmlCacheKeys = new List <string>();

            if (clearHtmlCache)
            {
                var desktopSetCacheKeys = await Utility.GetSetCacheKeysAsync(Filters <Portlet> .Equals("ID", portlet.ID), cancellationToken).ConfigureAwait(false);

                await desktopSetCacheKeys.ForEachAsync(async desktopSetCacheKey =>
                {
                    var cacheKeys = await Utility.Cache.GetSetMembersAsync(desktopSetCacheKey, cancellationToken).ConfigureAwait(false);
                    if (cacheKeys != null && cacheKeys.Count > 0)
                    {
                        htmlCacheKeys = htmlCacheKeys.Concat(cacheKeys).Concat(new[] { desktopSetCacheKey }).ToList();
                    }
                }, true, false).ConfigureAwait(false);
            }
            htmlCacheKeys = htmlCacheKeys.Distinct(StringComparer.OrdinalIgnoreCase).ToList();

            // clear related cache
            await Utility.Cache.RemoveAsync(htmlCacheKeys.Concat(dataCacheKeys).Distinct(StringComparer.OrdinalIgnoreCase).ToList(), cancellationToken).ConfigureAwait(false);

            await Task.WhenAll
            (
                Utility.WriteCacheLogs?Utility.WriteLogAsync(correlationID, $"Clear related cache of a portlet [{portlet.Title} - ID: {portlet.ID}]\r\n- {dataCacheKeys.Count} data keys => {dataCacheKeys.Join(", ")}\r\n- {htmlCacheKeys.Count} html keys => {htmlCacheKeys.Join(", ")}", ServiceBase.ServiceComponent.CancellationToken, "Caches") : Task.CompletedTask,
                doRefresh?$"{Utility.PortalsHttpURI}/~{portlet.Organization.Alias}/".RefreshWebPageAsync(1, correlationID, $"Refresh desktop when related cache of a portlet was clean [{portlet.Title} - ID: {portlet.ID}]") : Task.CompletedTask
            ).ConfigureAwait(false);
        }
Beispiel #8
0
        internal static async Task <List <string> > GetSetCacheKeysAsync(IFilterBy <Portlet> filter, CancellationToken cancellationToken = default)
        {
            var desktopIDs = new List <string>();
            var portlets   = await Portlet.FindAsync(filter, null, 0, 1, null, cancellationToken).ConfigureAwait(false);

            await portlets.ForEachAsync(async portlet =>
            {
                var mappingPortlets = await Portlet.FindAsync(Filters <Portlet> .Equals("OriginalPortletID", portlet.ID), null, 0, 1, null, cancellationToken).ConfigureAwait(false);
                desktopIDs          = desktopIDs.Concat(new[] { portlet.DesktopID }).Concat(mappingPortlets.Select(mappingPortlet => mappingPortlet.DesktopID)).ToList();
            }, true, false).ConfigureAwait(false);

            var desktops = new List <Desktop>();
            await desktopIDs.Where(desktopID => !string.IsNullOrWhiteSpace(desktopID) && desktopID.IsValidUUID()).Distinct(StringComparer.OrdinalIgnoreCase).ToList().ForEachAsync(async desktopID =>
            {
                var desktop = await desktopID.GetDesktopByIDAsync(cancellationToken).ConfigureAwait(false);
                if (desktop != null)
                {
                    desktops.Add(desktop);
                }
            }, true, false).ConfigureAwait(false);

            return(desktops.Select(desktop => desktop.GetSetCacheKey()).ToList());
        }
Beispiel #9
0
        internal static async Task <JObject> DeletePortletAsync(this RequestInfo requestInfo, bool isSystemAdministrator = false, CancellationToken cancellationToken = default)
        {
            // prepare
            var portlet = await Portlet.GetAsync <Portlet>(requestInfo.GetObjectIdentity() ?? "", cancellationToken).ConfigureAwait(false);

            if (portlet == null)
            {
                throw new InformationNotFoundException();
            }
            else if (portlet.Organization == null)
            {
                throw new InformationInvalidException("The organization is invalid");
            }

            // check permission
            var gotRights = isSystemAdministrator || requestInfo.Session.User.IsModerator(null, null, portlet.Organization, requestInfo.CorrelationID);

            if (!gotRights)
            {
                throw new AccessDeniedException();
            }

            // delete portlet
            await Portlet.DeleteAsync <Portlet>(portlet.ID, requestInfo.Session.User.ID, cancellationToken).ConfigureAwait(false);

            portlet.ClearRelatedCacheAsync(ServiceBase.ServiceComponent.CancellationToken, requestInfo.CorrelationID).Run();

            var response       = portlet.ToJson();
            var objectName     = portlet.GetTypeName(true);
            var updateMessages = new List <UpdateMessage>
            {
                new UpdateMessage
                {
                    Type     = $"{requestInfo.ServiceName}#{objectName}#Delete",
                    Data     = response,
                    DeviceID = "*"
                }
            };
            var communicateMessages = new List <CommunicateMessage>
            {
                new CommunicateMessage(requestInfo.ServiceName)
                {
                    Type           = $"{objectName}#Delete",
                    Data           = response,
                    ExcludedNodeID = Utility.NodeID
                }
            };

            // update desktop
            var desktop = portlet.Desktop;

            if (desktop != null && desktop._portlets != null)
            {
                var index = desktop._portlets.FindIndex(p => p.ID.IsEquals(portlet.ID));
                if (index > -1)
                {
                    desktop._portlets.RemoveAt(index);
                    await desktop.SetAsync(false, true, cancellationToken).ConfigureAwait(false);
                }
            }

            // delete mapping portlets
            if (string.IsNullOrWhiteSpace(portlet.OriginalPortletID))
            {
                var mappingPortlets = await portlet.FindPortletsAsync(cancellationToken).ConfigureAwait(false) ?? new List <Portlet>();

                await mappingPortlets.ForEachAsync(async mappingPortlet =>
                {
                    // delete portlet
                    await Portlet.DeleteAsync <Portlet>(mappingPortlet.ID, requestInfo.Session.User.ID, cancellationToken).ConfigureAwait(false);
                    var json = mappingPortlet.ToJson();
                    updateMessages.Add(new UpdateMessage
                    {
                        Type     = $"{requestInfo.ServiceName}#{objectName}#Delete",
                        Data     = json,
                        DeviceID = "*"
                    });

                    // update desktop
                    desktop = mappingPortlet.Desktop;
                    if (desktop != null && desktop._portlets != null)
                    {
                        var index = desktop._portlets.FindIndex(p => p.ID.IsEquals(mappingPortlet.ID));
                        if (index > -1)
                        {
                            desktop._portlets.RemoveAt(index);
                            await desktop.SetAsync(false, true, cancellationToken).ConfigureAwait(false);
                        }
                    }
                    communicateMessages.Add(new CommunicateMessage(requestInfo.ServiceName)
                    {
                        Type           = $"{objectName}#Delete",
                        Data           = json,
                        ExcludedNodeID = Utility.NodeID
                    });
                }).ConfigureAwait(false);
            }
            else
            {
                var originalPortlet = portlet.OriginalPortlet;
                if (originalPortlet != null)
                {
                    await originalPortlet.ClearRelatedCacheAsync(cancellationToken, requestInfo.CorrelationID).ConfigureAwait(false);

                    var json = originalPortlet.ToJson(async originalPortletJson =>
                    {
                        var mappingPortlets = await originalPortlet.FindPortletsAsync(cancellationToken).ConfigureAwait(false) ?? new List <Portlet>();
                        originalPortletJson["OtherDesktops"] = mappingPortlets.Where(mappingPortlet => mappingPortlet != null).Select(mappingPortlet => mappingPortlet.DesktopID).Where(id => !string.IsNullOrWhiteSpace(id)).Distinct(StringComparer.OrdinalIgnoreCase).ToJArray();
                    });
                    updateMessages.Add(new UpdateMessage
                    {
                        Type     = $"{requestInfo.ServiceName}#{objectName}#Update",
                        Data     = json,
                        DeviceID = "*"
                    });
                    communicateMessages.Add(new CommunicateMessage(requestInfo.ServiceName)
                    {
                        Type = $"{objectName}#Update",
                        Data = json
                    });
                }
            }

            // send messages and response
            await Task.WhenAll(
                updateMessages.ForEachAsync(message => Utility.RTUService.SendUpdateMessageAsync(message, cancellationToken), true, false),
                communicateMessages.ForEachAsync(message => Utility.RTUService.SendInterCommunicateMessageAsync(message, cancellationToken))
                ).ConfigureAwait(false);

            return(response);
        }
Beispiel #10
0
        internal static async Task <JObject> UpdatePortletAsync(this RequestInfo requestInfo, bool isSystemAdministrator = false, CancellationToken cancellationToken = default)
        {
            // prepare
            var portlet = await Portlet.GetAsync <Portlet>(requestInfo.GetObjectIdentity() ?? "", cancellationToken).ConfigureAwait(false);

            if (portlet == null)
            {
                throw new InformationNotFoundException();
            }

            // is mapping portlet => then get the original portlet
            if (!string.IsNullOrWhiteSpace(portlet.OriginalPortletID))
            {
                portlet = await Portlet.GetAsync <Portlet>(portlet.OriginalPortletID, cancellationToken).ConfigureAwait(false);
            }
            if (portlet == null)
            {
                throw new InformationNotFoundException();
            }

            // validate check permission
            if (portlet.Organization == null)
            {
                throw new InformationInvalidException("The organization is invalid");
            }

            var gotRights = isSystemAdministrator || requestInfo.Session.User.IsModerator(null, null, portlet.Organization, requestInfo.CorrelationID);

            if (!gotRights)
            {
                throw new AccessDeniedException();
            }

            // update
            var oldDesktopID = portlet.DesktopID;
            var oldZone      = portlet.Zone;
            var request      = requestInfo.GetBodyExpando();

            portlet.UpdatePortletInstance(request, "ID,SystemID,RepositoryID,RepositoryEntityID,OriginalPortletID,Privileges,OrderIndex,Created,CreatedID,LastModified,LastModifiedID", obj =>
            {
                obj.LastModified   = DateTime.Now;
                obj.LastModifiedID = requestInfo.Session.User.ID;
            });

            if ("true".IsEquals(requestInfo.GetParameter("IsAdvancedMode")))
            {
                portlet.RepositoryEntityID = request.Get("RepositoryEntityID", portlet.RepositoryEntityID);
            }

            if (!portlet.DesktopID.IsEquals(oldDesktopID) || !portlet.Zone.IsEquals(oldZone))
            {
                portlet.OrderIndex = await PortletProcessor.GetLastOrderIndexAsync(portlet.DesktopID, portlet.Zone, cancellationToken).ConfigureAwait(false) + 1;
            }

            await Portlet.UpdateAsync(portlet, requestInfo.Session.User.ID, cancellationToken).ConfigureAwait(false);

            portlet.ClearRelatedCacheAsync(ServiceBase.ServiceComponent.CancellationToken, requestInfo.CorrelationID).Run();

            var response            = portlet.ToJson();
            var objectName          = portlet.GetTypeName(true);
            var updateMessages      = new List <UpdateMessage>();
            var communicateMessages = new List <CommunicateMessage>
            {
                new CommunicateMessage(requestInfo.ServiceName)
                {
                    Type           = $"{objectName}#Update",
                    Data           = response,
                    ExcludedNodeID = Utility.NodeID
                }
            };

            // update desktop
            var desktop = portlet.Desktop;

            if (desktop != null && desktop._portlets != null)
            {
                var index = desktop._portlets.FindIndex(p => p.ID.IsEquals(portlet.ID));
                if (index < 0)
                {
                    desktop._portlets.Add(portlet);
                }
                else
                {
                    desktop._portlets[index] = portlet;
                }
                await desktop.SetAsync(false, true, cancellationToken).ConfigureAwait(false);
            }

            // update old desktop
            if (!portlet.DesktopID.IsEquals(oldDesktopID))
            {
                desktop = await oldDesktopID.GetDesktopByIDAsync(cancellationToken).ConfigureAwait(false);

                if (desktop != null)
                {
                    if (desktop._portlets == null)
                    {
                        var index = desktop._portlets.FindIndex(p => p.ID.IsEquals(portlet.ID));
                        if (index > -1)
                        {
                            desktop._portlets.RemoveAt(index);
                            await desktop.SetAsync(false, true, cancellationToken).ConfigureAwait(false);
                        }
                    }
                    updateMessages.Add(new UpdateMessage
                    {
                        Type     = $"{requestInfo.ServiceName}#{objectName}#Delete",
                        Data     = response,
                        DeviceID = "*"
                    });
                    communicateMessages.Add(new CommunicateMessage(requestInfo.ServiceName)
                    {
                        Type           = $"{objectName}#Delete",
                        Data           = response,
                        ExcludedNodeID = Utility.NodeID
                    });
                }
            }

            // update mapping portlets
            var mappingPortlets = await portlet.FindPortletsAsync(cancellationToken).ConfigureAwait(false) ?? new List <Portlet>();

            var mappingDesktops = mappingPortlets.Select(mappingPortlet => mappingPortlet.DesktopID).Distinct(StringComparer.OrdinalIgnoreCase).ToList();
            var otherDesktops   = request.Get <List <string> >("OtherDesktops").Except(new[] { portlet.DesktopID }).Distinct(StringComparer.OrdinalIgnoreCase).ToList() ?? new List <string>();

            // add new
            var beAdded = otherDesktops.Except(mappingDesktops).ToList();
            await beAdded.Select(desktopID => new Portlet
            {
                ID                = UtilityService.NewUUID,
                Title             = portlet.Title,
                SystemID          = portlet.SystemID,
                DesktopID         = desktopID,
                Zone              = portlet.Zone,
                OriginalPortletID = portlet.ID,
                Created           = DateTime.Now,
                CreatedID         = requestInfo.Session.User.ID,
                LastModified      = DateTime.Now,
                LastModifiedID    = requestInfo.Session.User.ID,
                _originalPortlet  = portlet
            })
            .ForEachAsync(async mappingPortlet =>
            {
                // create portlet
                mappingPortlet.OrderIndex = await PortletProcessor.GetLastOrderIndexAsync(mappingPortlet.DesktopID, mappingPortlet.Zone, cancellationToken).ConfigureAwait(false) + 1;
                await Portlet.CreateAsync(mappingPortlet, cancellationToken).ConfigureAwait(false);
                mappingPortlet.ClearRelatedCacheAsync(ServiceBase.ServiceComponent.CancellationToken, requestInfo.CorrelationID).Run();

                var json = mappingPortlet.ToJson();
                updateMessages.Add(new UpdateMessage
                {
                    Type     = $"{requestInfo.ServiceName}#{objectName}#Create",
                    Data     = json,
                    DeviceID = "*"
                });

                // update desktop
                desktop = mappingPortlet.Desktop;
                if (desktop != null)
                {
                    if (desktop._portlets != null)
                    {
                        desktop._portlets.Add(mappingPortlet);
                        await desktop.SetAsync(false, true, cancellationToken).ConfigureAwait(false);
                    }
                    communicateMessages.Add(new CommunicateMessage(requestInfo.ServiceName)
                    {
                        Type           = $"{objectName}#Update",
                        Data           = json,
                        ExcludedNodeID = Utility.NodeID
                    });
                }
            }, true, false).ConfigureAwait(false);

            // delete
            var beDeleted = mappingDesktops.Except(otherDesktops).ToHashSet();
            await mappingPortlets.Where(mappingPortlet => beDeleted.Contains(mappingPortlet.DesktopID)).ForEachAsync(async mappingPortlet =>
            {
                // delete portlet
                await Portlet.DeleteAsync <Portlet>(mappingPortlet.ID, requestInfo.Session.User.ID, cancellationToken).ConfigureAwait(false);
                mappingPortlet.ClearRelatedCacheAsync(ServiceBase.ServiceComponent.CancellationToken, requestInfo.CorrelationID).Run();

                var json = mappingPortlet.ToJson();
                updateMessages.Add(new UpdateMessage
                {
                    Type     = $"{requestInfo.ServiceName}#{objectName}#Delete",
                    Data     = json,
                    DeviceID = "*"
                });

                // update desktop
                desktop = mappingPortlet.Desktop;
                if (desktop != null)
                {
                    if (desktop._portlets != null)
                    {
                        var index = desktop._portlets.FindIndex(p => p.ID.IsEquals(mappingPortlet.ID));
                        if (index > -1)
                        {
                            desktop._portlets.RemoveAt(index);
                            await desktop.SetAsync(false, true, cancellationToken).ConfigureAwait(false);
                        }
                    }
                    communicateMessages.Add(new CommunicateMessage(requestInfo.ServiceName)
                    {
                        Type           = $"{objectName}#Delete",
                        Data           = json,
                        ExcludedNodeID = Utility.NodeID
                    });
                }
            }, true, false).ConfigureAwait(false);

            // update
            var beUpdated = otherDesktops.Except(beDeleted).Except(beAdded).ToHashSet();
            await mappingPortlets.Where(mappingPortlet => beUpdated.Contains(mappingPortlet.DesktopID)).ForEachAsync(async mappingPortlet =>
            {
                // update portlet
                mappingPortlet._originalPortlet = portlet;
                if (!mappingPortlet.Title.IsEquals(portlet.Title) || !mappingPortlet.Zone.IsEquals(portlet.Zone))
                {
                    mappingPortlet.Title = portlet.Title;
                    if (!mappingPortlet.Zone.IsEquals(portlet.Zone))
                    {
                        mappingPortlet.Zone       = portlet.Zone;
                        mappingPortlet.OrderIndex = await PortletProcessor.GetLastOrderIndexAsync(mappingPortlet.DesktopID, mappingPortlet.Zone, cancellationToken).ConfigureAwait(false) + 1;
                    }
                    mappingPortlet.LastModified   = DateTime.Now;
                    mappingPortlet.LastModifiedID = requestInfo.Session.User.ID;
                    await Portlet.UpdateAsync(mappingPortlet, requestInfo.Session.User.ID, cancellationToken).ConfigureAwait(false);
                    mappingPortlet.ClearRelatedCacheAsync(ServiceBase.ServiceComponent.CancellationToken, requestInfo.CorrelationID).Run();
                }
                else
                {
                    await Utility.Cache.SetAsync(mappingPortlet, cancellationToken).ConfigureAwait(false);
                }

                var json = mappingPortlet.ToJson();
                updateMessages.Add(new UpdateMessage
                {
                    Type     = $"{requestInfo.ServiceName}#{objectName}#Update",
                    Data     = json,
                    DeviceID = "*"
                });

                // update desktop
                desktop = mappingPortlet.Desktop;
                if (desktop != null)
                {
                    if (desktop._portlets != null)
                    {
                        var index = desktop._portlets.FindIndex(p => p.ID.IsEquals(mappingPortlet.ID));
                        if (index < 0)
                        {
                            desktop._portlets.Add(mappingPortlet);
                        }
                        else
                        {
                            desktop._portlets[index] = mappingPortlet;
                        }
                        await desktop.SetAsync(false, true, cancellationToken).ConfigureAwait(false);
                    }
                    communicateMessages.Add(new CommunicateMessage(requestInfo.ServiceName)
                    {
                        Type           = $"{objectName}#Update",
                        Data           = json,
                        ExcludedNodeID = Utility.NodeID
                    });
                }
            }, true, false).ConfigureAwait(false);

            // update response JSON with other desktops
            response["OtherDesktops"] = otherDesktops.ToJArray();

            // send messages and response
            updateMessages.Add(new UpdateMessage
            {
                Type     = $"{requestInfo.ServiceName}#{objectName}#Update",
                Data     = response,
                DeviceID = "*"
            });
            await Task.WhenAll(
                updateMessages.ForEachAsync(message => Utility.RTUService.SendUpdateMessageAsync(message, cancellationToken), true, false),
                communicateMessages.ForEachAsync(message => Utility.RTUService.SendInterCommunicateMessageAsync(message, cancellationToken))
                ).ConfigureAwait(false);

            return(response);
        }
Beispiel #11
0
        internal static async Task <JObject> CreatePortletAsync(this RequestInfo requestInfo, bool isSystemAdministrator = false, CancellationToken cancellationToken = default)
        {
            // prepare
            var request        = requestInfo.GetBodyExpando();
            var organizationID = request.Get <string>("SystemID") ?? requestInfo.GetParameter("x-system-id") ?? requestInfo.GetParameter("SystemID");
            var organization   = await(organizationID ?? "").GetOrganizationByIDAsync(cancellationToken).ConfigureAwait(false);

            if (organization == null)
            {
                throw new InformationInvalidException("The organization is invalid");
            }

            // check permission
            var gotRights = isSystemAdministrator || requestInfo.Session.User.IsModerator(null, null, organization, requestInfo.CorrelationID);

            if (!gotRights)
            {
                throw new AccessDeniedException();
            }

            // create new
            var portlet = request.CreatePortletInstance("SystemID,Privileges,OrderIndex,Created,CreatedID,LastModified,LastModifiedID", obj =>
            {
                obj.ID        = string.IsNullOrWhiteSpace(obj.ID) || !obj.ID.IsValidUUID() ? UtilityService.NewUUID : obj.ID;
                obj.SystemID  = organization.ID;
                obj.Created   = obj.LastModified = DateTime.Now;
                obj.CreatedID = obj.LastModifiedID = requestInfo.Session.User.ID;
            });

            portlet.OrderIndex = await PortletProcessor.GetLastOrderIndexAsync(portlet.DesktopID, portlet.Zone, cancellationToken).ConfigureAwait(false) + 1;

            await Portlet.CreateAsync(portlet, cancellationToken).ConfigureAwait(false);

            portlet.ClearRelatedCacheAsync(ServiceBase.ServiceComponent.CancellationToken, requestInfo.CorrelationID).Run();

            var response            = portlet.ToJson();
            var objectName          = portlet.GetTypeName(true);
            var updateMessages      = new List <UpdateMessage>();
            var communicateMessages = new List <CommunicateMessage>
            {
                new CommunicateMessage(requestInfo.ServiceName)
                {
                    Type           = $"{objectName}#Create",
                    Data           = response,
                    ExcludedNodeID = Utility.NodeID
                }
            };

            // update desktop
            var desktop = portlet.Desktop;

            if (desktop != null && desktop._portlets != null)
            {
                desktop._portlets.Add(portlet);
                await desktop.SetAsync(false, true, cancellationToken).ConfigureAwait(false);
            }

            // create mapping portlets
            if (string.IsNullOrWhiteSpace(portlet.OriginalPortletID))
            {
                var otherDesktops = request.Get <List <string> >("OtherDesktops")?.Except(new[] { portlet.DesktopID }).Distinct(StringComparer.OrdinalIgnoreCase).ToList() ?? new List <string>();
                await otherDesktops.ForEachAsync(async desktopID =>
                {
                    // create new
                    var mappingPortlet = new Portlet
                    {
                        ID                = UtilityService.NewUUID,
                        Title             = portlet.Title,
                        SystemID          = portlet.SystemID,
                        DesktopID         = desktopID,
                        Zone              = portlet.Zone,
                        OrderIndex        = await PortletProcessor.GetLastOrderIndexAsync(desktopID, portlet.Zone, cancellationToken).ConfigureAwait(false) + 1,
                        OriginalPortletID = portlet.ID,
                        Created           = DateTime.Now,
                        CreatedID         = requestInfo.Session.User.ID,
                        LastModified      = DateTime.Now,
                        LastModifiedID    = requestInfo.Session.User.ID,
                        _originalPortlet  = portlet
                    };
                    await Portlet.CreateAsync(mappingPortlet, cancellationToken).ConfigureAwait(false);

                    var json = mappingPortlet.ToJson();
                    updateMessages.Add(new UpdateMessage
                    {
                        Type     = $"{requestInfo.ServiceName}#{objectName}#Create",
                        Data     = json,
                        DeviceID = "*"
                    });

                    // update desktop
                    desktop = mappingPortlet.Desktop;
                    if (desktop != null && desktop._portlets != null)
                    {
                        desktop._portlets.Add(mappingPortlet);
                        await desktop.SetAsync(false, true, cancellationToken).ConfigureAwait(false);
                        communicateMessages.Add(new CommunicateMessage(requestInfo.ServiceName)
                        {
                            Type           = $"{objectName}#Create",
                            Data           = json,
                            ExcludedNodeID = Utility.NodeID
                        });
                    }
                }, true, false).ConfigureAwait(false);

                // update response JSON with other desktops
                response["OtherDesktops"] = otherDesktops.ToJArray();
            }

            // fetch original portlet
            else
            {
                portlet._originalPortlet = await Portlet.GetAsync <Portlet>(portlet.OriginalPortletID, cancellationToken).ConfigureAwait(false);

                await Utility.Cache.SetAsync(portlet, cancellationToken).ConfigureAwait(false);
            }

            // send update messages
            updateMessages.Add(new UpdateMessage
            {
                Type     = $"{requestInfo.ServiceName}#{objectName}#Create",
                Data     = response,
                DeviceID = "*"
            });
            await Task.WhenAll(
                updateMessages.ForEachAsync(message => Utility.RTUService.SendUpdateMessageAsync(message, cancellationToken), true, false),
                communicateMessages.ForEachAsync(message => Utility.RTUService.SendInterCommunicateMessageAsync(message, cancellationToken))
                ).ConfigureAwait(false);

            // response
            return(response);
        }
Beispiel #12
0
 public static Portlet UpdatePortletInstance(this Portlet portlet, ExpandoObject data, string excluded = null, Action <Portlet> onCompleted = null)
 => portlet.Fill(data, excluded?.ToHashSet(), _ =>
 {
     portlet.Normalize();
     onCompleted?.Invoke(portlet);
 });
Beispiel #13
0
        internal static async Task <JObject> SearchPortletsAsync(this RequestInfo requestInfo, bool isSystemAdministrator = false, CancellationToken cancellationToken = default)
        {
            // prepare
            var request = requestInfo.GetRequestExpando();

            var query  = request.Get <string>("FilterBy.Query");
            var filter = request.Get <ExpandoObject>("FilterBy")?.ToFilterBy <Portlet>() ?? Filters <Portlet> .And();

            var sort = string.IsNullOrWhiteSpace(query) ? request.Get <ExpandoObject>("SortBy")?.ToSortBy <Portlet>() ?? Sorts <Portlet> .Ascending("DesktopID").ThenByAscending("Zone").ThenByAscending("OrderIndex") : null;

            var pagination = request.Get <ExpandoObject>("Pagination")?.GetPagination() ?? new Tuple <long, int, int, int>(-1, 0, 20, 1);
            var pageSize   = pagination.Item3;
            var pageNumber = pagination.Item4;

            // check permission
            var gotRights = isSystemAdministrator;

            if (!gotRights)
            {
                // get organization
                var organizationID = filter.GetValue("SystemID") ?? requestInfo.GetParameter("SystemID") ?? requestInfo.GetParameter("x-system-id") ?? requestInfo.GetParameter("OrganizationID");
                var organization   = await(organizationID ?? "").GetOrganizationByIDAsync(cancellationToken).ConfigureAwait(false);
                if (organization == null)
                {
                    throw new InformationExistedException("The organization is invalid");
                }

                gotRights = requestInfo.Session.User.IsViewer(null, null, organization, requestInfo.CorrelationID);
                if (!gotRights)
                {
                    throw new AccessDeniedException();
                }
            }

            // process cache
            var json = string.IsNullOrWhiteSpace(query)
                                ? await Utility.Cache.GetAsync <string>(Extensions.GetCacheKeyOfObjectsJson(filter, sort, pageSize, pageNumber), cancellationToken).ConfigureAwait(false)
                                : null;

            if (!string.IsNullOrWhiteSpace(json))
            {
                return(JObject.Parse(json));
            }

            // prepare pagination
            var totalRecords = pagination.Item1 > -1 ? pagination.Item1 : -1;

            if (totalRecords < 0)
            {
                totalRecords = string.IsNullOrWhiteSpace(query)
                                        ? await Portlet.CountAsync(filter, Extensions.GetCacheKeyOfTotalObjects(filter, sort), cancellationToken).ConfigureAwait(false)
                                        : await Portlet.CountAsync(query, filter, cancellationToken).ConfigureAwait(false);
            }

            var totalPages = new Tuple <long, int>(totalRecords, pageSize).GetTotalPages();

            if (totalPages > 0 && pageNumber > totalPages)
            {
                pageNumber = totalPages;
            }

            // search
            var objects = totalRecords > 0
                                ? string.IsNullOrWhiteSpace(query)
                                        ? await Portlet.FindAsync(filter, sort, pageSize, pageNumber, Extensions.GetCacheKey(filter, sort, pageSize, pageNumber), cancellationToken).ConfigureAwait(false)
                                        : await Portlet.SearchAsync(query, filter, pageSize, pageNumber, cancellationToken).ConfigureAwait(false)
                                : new List <Portlet>();

            // build result
            pagination = new Tuple <long, int, int, int>(totalRecords, totalPages, pageSize, pageNumber);
            var response = new JObject
            {
                { "FilterBy", filter.ToClientJson(query) },
                { "SortBy", sort?.ToClientJson() },
                { "Pagination", pagination.GetPagination() },
                { "Objects", objects.ToJsonArray() }
            };

            // update cache
            if (string.IsNullOrWhiteSpace(query))
            {
                await Utility.Cache.SetAsync(Extensions.GetCacheKeyOfObjectsJson(filter, sort, pageSize, pageNumber), response.ToString(Formatting.None), cancellationToken).ConfigureAwait(false);
            }

            // response
            return(response);
        }
Beispiel #14
0
 public static Portlet CreatePortletInstance(this ExpandoObject data, string excluded = null, Action <Portlet> onCompleted = null)
 => Portlet.CreateInstance(data, excluded?.ToHashSet(), portlet =>
 {
     portlet.Normalize();
     onCompleted?.Invoke(portlet);
 });
Beispiel #15
0
        internal static async Task <int> GetLastOrderIndexAsync(string desktopID, string zone, CancellationToken cancellationToken = default)
        {
            var portlets = await Portlet.FindAsync(Filters <Portlet> .And(Filters <Portlet> .Equals("DesktopID", desktopID), Filters <Portlet> .Equals("Zone", zone)), Sorts <Portlet> .Ascending("Zone").ThenByAscending("OrderIndex"), 0, 1, null, cancellationToken).ConfigureAwait(false);

            return(portlets != null && portlets.Count > 0 ? portlets.Last().OrderIndex : -1);
        }