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); }
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); }