/// <summary> /// Create new queue entry /// </summary> public PubSubNotifyQueueEntry(Type tmodelType, PubSubEventType eventType, object data) { this.TargetType = tmodelType; this.EventType = eventType; this.Data = data; this.NotificationDate = DateTimeOffset.Now; }
/// <summary> /// Get all dispatchers and subscriptions /// </summary> protected IEnumerable <IPubSubDispatcher> GetDispatchers(PubSubEventType eventType, Object data) { using (AuthenticationContext.EnterSystemContext()) { var resourceName = data.GetType().GetSerializationName(); var subscriptions = this.m_pubSubManager .FindSubscription(o => o.ResourceTypeName == resourceName && o.IsActive && (o.NotBefore == null || o.NotBefore < DateTimeOffset.Now) && (o.NotAfter == null || o.NotAfter > DateTimeOffset.Now)) .Where(o => o.Event.HasFlag(eventType)) .Where(s => { // Attempt to compile the filter criteria into an executable function if (!this.m_filterCriteria.TryGetValue(s.Key.Value, out Func <Object, bool> fn)) { Expression dynFn = null; var parameter = Expression.Parameter(data.GetType()); foreach (var itm in s.Filter) { var fFn = QueryExpressionParser.BuildLinqExpression(data.GetType(), NameValueCollection.ParseQueryString(itm), "p", forceLoad: true, lazyExpandVariables: true); if (dynFn is LambdaExpression le) { dynFn = Expression.Lambda( Expression.And( Expression.Invoke(le, parameter), Expression.Invoke(fFn, parameter) ), parameter); } else { dynFn = fFn; } } if (dynFn == null) { dynFn = Expression.Lambda(Expression.Constant(true), parameter); } parameter = Expression.Parameter(typeof(object)); fn = Expression.Lambda(Expression.Invoke(dynFn, Expression.Convert(parameter, data.GetType())), parameter).Compile() as Func <Object, bool>; this.m_filterCriteria.TryAdd(s.Key.Value, fn); } return(fn(data)); }); // Now we want to filter by channel, since the channel is really what we're interested in foreach (var chnl in subscriptions.GroupBy(o => o.ChannelKey)) { var channelDef = this.m_pubSubManager.GetChannel(chnl.Key); var factory = DispatcherFactoryUtil.FindDispatcherFactoryById(channelDef.DispatcherFactoryId); yield return(factory.CreateDispatcher(chnl.Key, new Uri(channelDef.Endpoint), channelDef.Settings.ToDictionary(o => o.Name, o => o.Value))); } } }
/// <summary> /// Update subscription /// </summary> public PubSubSubscriptionDefinition UpdateSubscription(Guid key, string name, string description, PubSubEventType events, string hdsiFilter, string supportAddress = null, DateTimeOffset?notBefore = null, DateTimeOffset?notAfter = null) { try { using (var client = this.GetRestClient()) { return(client.Put <PubSubSubscriptionDefinition, PubSubSubscriptionDefinition>($"PubSubSubscription/{key}", new PubSubSubscriptionDefinition() { Description = description, Event = events, Filter = new List <string>() { hdsiFilter }, Name = name, NotAfter = notAfter?.DateTime, NotBefore = notBefore?.DateTime, SupportContact = supportAddress })); } } catch (Exception e) { this.m_tracer.TraceError("Error creating subscription - {0}", e); throw new Exception($"Error creating subscription", e); } }
/// <summary> /// Register subscription /// </summary> public PubSubSubscriptionDefinition RegisterSubscription(Type modelType, string name, string description, PubSubEventType events, string hdsiFilter, Guid channelId, string supportAddress = null, DateTimeOffset?notBefore = null, DateTimeOffset?notAfter = null) { try { using (var client = this.GetRestClient()) { return(client.Post <PubSubSubscriptionDefinition, PubSubSubscriptionDefinition>($"PubSubSubscription", new PubSubSubscriptionDefinition() { ChannelKey = channelId, Description = description, Event = events, Filter = new List <string>() { hdsiFilter }, Name = name, NotAfter = notAfter?.DateTime, NotBefore = notBefore?.DateTime, ResourceTypeName = modelType.GetSerializationName(), SupportContact = supportAddress })); } } catch (Exception e) { this.m_tracer.TraceError("Error creating subscription - {0}", e); throw new Exception($"Error creating subscription", e); } }
/// <summary> /// Register subscription /// </summary> public PubSubSubscriptionDefinition RegisterSubscription <TModel>(string name, string description, PubSubEventType events, Expression <Func <TModel, bool> > filter, Guid channelId, string supportAddress = null, DateTimeOffset?notBefore = null, DateTimeOffset?notAfter = null) { var filterHdsi = QueryExpressionBuilder.BuildQuery(filter); return(this.RegisterSubscription(typeof(TModel), name, description, events, new NameValueCollection(filterHdsi.ToArray()).ToString(), channelId, supportAddress, notBefore, notAfter)); }
/// <summary> /// Update the subscription /// </summary> public PubSubSubscriptionDefinition UpdateSubscription(Guid key, string name, string description, PubSubEventType events, string hdsiFilter, String supportAddress = null, DateTimeOffset?notBefore = null, DateTimeOffset?notAfter = null) { this.m_policyEnforcementService.Demand(PermissionPolicyIdentifiers.CreatePubSubSubscription); using (var conn = this.m_configuration.Provider.GetWriteConnection()) { try { conn.Open(); using (var tx = conn.BeginTransaction()) { var dbExisting = conn.FirstOrDefault <DbSubscription>(o => o.Key == key); if (dbExisting == null) { throw new KeyNotFoundException($"Subscription {key} not found"); } // Get the authorship var se = this.m_securityRepository.GetSecurityEntity(AuthenticationContext.Current.Principal); if (se == null) { throw new KeyNotFoundException($"Unable to determine structure data for {AuthenticationContext.Current.Principal.Identity.Name}"); } dbExisting.UpdatedByKey = se.Key.Value; dbExisting.UpdatedTime = DateTimeOffset.Now; dbExisting.ObsoletedByKey = null; dbExisting.ObsoletionTime = null; dbExisting.ObsoletedBySpecified = dbExisting.ObsoletionTimeSpecified = true; dbExisting.Name = name; dbExisting.IsActive = false; // we disable the subscription to allow for review dbExisting.NotAfter = notAfter; dbExisting.NotBefore = notBefore; dbExisting.Description = description; dbExisting.SupportContact = supportAddress; dbExisting.Event = (int)events; conn.Update(dbExisting); conn.Delete <DbSubscriptionFilter>(o => o.SubscriptionKey == dbExisting.Key); // Insert settings conn.InsertAll(hdsiFilter.Split('&').Select(s => new DbSubscriptionFilter() { SubscriptionKey = dbExisting.Key.Value, Filter = s })); var retVal = this.MapInstance(conn, dbExisting); this.m_cache?.Add(retVal); tx.Commit(); this.Subscribed?.Invoke(this, new DataPersistedEventArgs <PubSubSubscriptionDefinition>(retVal, TransactionMode.Commit, AuthenticationContext.Current.Principal)); return(this.MapInstance(conn, dbExisting)); } } catch (Exception e) { throw new Exception($"Error updating subscription {key}", e); } } }
/// <summary> /// Register a subscription for <paramref name="modelType"/> /// </summary> public PubSubSubscriptionDefinition RegisterSubscription(Type modelType, string name, string description, PubSubEventType events, string hdsiFilter, Guid channelId, String supportAddress = null, DateTimeOffset?notBefore = null, DateTimeOffset?notAfter = null) { this.m_policyEnforcementService.Demand(PermissionPolicyIdentifiers.CreatePubSubSubscription); var subscription = new PubSubSubscriptionDefinition() { ChannelKey = channelId, Event = events, Filter = String.IsNullOrEmpty(hdsiFilter) ? null : new List <string>(hdsiFilter.Split('&')), IsActive = false, Name = name, Description = description, SupportContact = supportAddress, NotBefore = notBefore?.DateTime, NotAfter = notAfter?.DateTime, ResourceTypeName = modelType.GetSerializationName() }; var preEvent = new DataPersistingEventArgs <PubSubSubscriptionDefinition>(subscription, TransactionMode.Commit, AuthenticationContext.Current.Principal); this.Subscribing?.Invoke(this, preEvent); if (preEvent.Cancel) { this.m_tracer.TraceWarning("Pre-Event Hook Indicates Cancel"); return(preEvent.Data); } using (var conn = this.m_configuration.Provider.GetWriteConnection()) { try { conn.Open(); using (var tx = conn.BeginTransaction()) { // First construct db instance var dbSubscription = this.m_mapper.MapModelInstance <PubSubSubscriptionDefinition, DbSubscription>(subscription); // Get the authorship var se = this.m_securityRepository.GetSecurityEntity(AuthenticationContext.Current.Principal); if (se == null) { throw new KeyNotFoundException($"Unable to determine structure data for {AuthenticationContext.Current.Principal.Identity.Name}"); } dbSubscription.CreatedByKey = se.Key.Value; dbSubscription.CreationTime = DateTimeOffset.Now; dbSubscription = conn.Insert(dbSubscription); // Insert settings if (subscription.Filter != null) { foreach (var itm in subscription.Filter) { conn.Insert(new DbSubscriptionFilter() { SubscriptionKey = dbSubscription.Key.Value, Filter = itm }); } } tx.Commit(); subscription = this.MapInstance(conn, dbSubscription); this.Subscribed?.Invoke(this, new DataPersistedEventArgs <PubSubSubscriptionDefinition>(subscription, TransactionMode.Commit, AuthenticationContext.Current.Principal)); this.m_cache?.Add(subscription); return(subscription); } } catch (Exception e) { throw new Exception($"Error inserting subscription {subscription}", e); } } }