Example #1
0
        public async Task <PublishToTagResult> PublishToTagAsync()
        {
            if (!tagOperator.IsTaggingAvailable())
            {
                return(new PublishToTagFailedResult(new TaggingNotAvailableException()));
            }

            string    tag      = model.Tag;
            DynamoTag tagEntry = await tagOperator.tagTableOperator.GetTagAsync(tag);

            if (tagEntry == null)
            {
                return(new PublishToTagFailedResult(new TagNotFoundException(tag)));
            }
            switch (tagEntry.TaggingTypeEnum)
            {
            case PNTagType.Iterative:
                List <DynamoIterativeTag> tags = await tagOperator.iterativeTagTableOperator.GetAllSubscribersForTagAsync(tagEntry.Tag);

                IterativeTagResponseTuple resultTuples = await PublishToIterativeTagAsync(tags);
                await RemoveUnsuccessfulEndpoints(resultTuples);

                var returnTuples = resultTuples.Select(t => new Tuple <PublishToSNSResult, PushNotificationSubscriber>(t.Item1, PushNotificationSubscriber.From(t.Item2.Subscriber)));
                return(new PublishToIterativeTagResult(tag, returnTuples));

            case PNTagType.SNSTopic:
                PublishToSNSResult result = await PublishToSnsTopicTag(tagEntry.SnsTopicArn);

                return(new PublishToSNSTopicTagResult(tag, result));

            default:
                throw new TagNotFoundException(tag);
            }
        }
        public async Task <TagCRUDSuccessfulResult> RemoveUserFromTagsAsync(string userId, List <PNTag> tags, bool removeAllTags = false)
        {
            TagCRUDSuccessfulResult result = new TagCRUDSuccessfulResult();

            if (removeAllTags)
            {
                int modification = await RemoveAllTagsOfUserAsync(userId);

                result.NumberOfModifications = modification;
                return(result);
            }
            else
            {
                foreach (var tagToRemove in tags)
                {
                    DynamoTag tag = await tagTableOperator.GetTagAsync(tagToRemove.Tag);

                    if (tag == null)
                    {
                        continue;
                    }
                    List <DynamoSubscriber> dynamoSubscribers = await subscriberTableOperator.GetAllSubcribersOfUserAsync(userId);

                    var subscribers = dynamoSubscribers.Select(s => s.Subscriber).ToList();

                    await RemoveSubscribersFromTagAsync(tag.Tag, subscribers, tag.TaggingTypeEnum);

                    result.NumberOfModifications = result.NumberOfModifications + subscribers.Count;
                }
            }
            return(result);
        }
        protected async Task SubscribeToSNSTopicTagAsync(string topicTag, string userId, string token, string appIdentifier, string endpointArn)
        {
            if (string.IsNullOrEmpty(topicTag))
            {
                return;
            }
            DynamoTag pnTag = await tagTableOperator.GetTagAsync(topicTag);

            if (pnTag != null && pnTag.TaggingTypeEnum != PNTagType.SNSTopic)
            {
                throw new OverrideExistingTagTypeException(pnTag.Tag, pnTag.TaggingTypeEnum.ToString());
            }
            string topicArn = pnTag?.SnsTopicArn;

            if (string.IsNullOrEmpty(topicArn))
            {
                CreateTopicRequest ctReq = new CreateTopicRequest();
                ctReq.Name = appIdentifier + "___" + topicTag;
                CreateTopicResponse ctResponse = await snsClient.CreateTopicAsync(ctReq);

                topicArn = ctResponse.TopicArn;
            }


            SubscribeRequest sReq = new SubscribeRequest();

            sReq.TopicArn = topicArn;
            sReq.Protocol = "application";
            sReq.Endpoint = endpointArn;
            SubscribeResponse sResponse = await snsClient.SubscribeAsync(sReq);


            if (pnTag == null)
            {
                pnTag                 = new DynamoTag();
                pnTag.Tag             = topicTag;
                pnTag.TaggingTypeEnum = PNTagType.SNSTopic;
                pnTag.SnsTopicArn     = topicArn;
                await tagTableOperator.AddTagAsync(pnTag);
            }

            DynamoSNSTopicTag entry = new DynamoSNSTopicTag
            {
                Tag        = topicTag,
                Subscriber = new Subscriber {
                    UserId = userId, Token = token
                },
                SnsSubscriptionArn = sResponse.SubscriptionArn
            };
            await snsTopicTagTableOperator.AddTagAsync(entry);

            // await tagTableService.IncrementNumberOfSubscribers(pnTag.Tag, 1);
        }
        public async Task SubscribeToIterativeTagAsync(string iterativeTag, string userId, string token, string endpointArn, Platform platform)
        {
            string tag = iterativeTag;

            if (string.IsNullOrEmpty(tag))
            {
                return;
            }
            DynamoTag pnTag = await tagTableOperator.GetTagAsync(iterativeTag);

            if (pnTag != null && pnTag.TaggingTypeEnum != PNTagType.Iterative)
            {
                throw new OverrideExistingTagTypeException(pnTag.Tag, pnTag.TaggingTypeEnum.ToString());
            }

            if (pnTag == null)
            {
                pnTag                 = new DynamoTag();
                pnTag.Tag             = iterativeTag;
                pnTag.TaggingTypeEnum = PNTagType.Iterative;
                await tagTableOperator.AddTagAsync(pnTag);
            }

            Func <DateTime?> calculateTTL = (() =>
            {
                if (Provider.IterativeTagTimeToLive.HasValue)
                {
                    return(DateTime.UtcNow.Add(Provider.IterativeTagTimeToLive.Value));
                }
                return(null);
            });

            DynamoIterativeTag entry = new DynamoIterativeTag
            {
                Tag        = tag,
                Subscriber = new Subscriber {
                    UserId = userId, Token = token
                },
                EndpointArn = endpointArn,
                Platform    = platform,
                ttl         = calculateTTL()
            };

            await iterativeTagTableOperator.AddSubscriberAsync(entry);

            // await tagTableService.IncrementNumberOfSubscribers(pnTag.Tag, 1);
        }
        public async Task <TaggingOperationResult> DeleteTagAsync(PNTag tag)
        {
            DynamoTag pnTag = await tagTableOperator.GetTagAsync(tag.Tag);

            if (pnTag == null)
            {
                return(new TagCRUDFailedResult(new TagNotFoundException(tag.Tag)));
            }

            int totalDeleted = 0;

            if (pnTag.TaggingTypeEnum == PNTagType.Iterative)
            {
                //Warning: You could delete by rangekey conditional expression. Check later
                var iterativeTags = await iterativeTagTableOperator.GetAllSubscribersForTagAsync(tag.Tag);

                var subscribers = iterativeTags.Select(t => t.Subscriber).ToList();
                await RemoveSubscribersFromIterativeTagAsync(pnTag.Tag, subscribers);

                totalDeleted = totalDeleted + subscribers.Count;
            }

            if (pnTag.TaggingTypeEnum == PNTagType.SNSTopic)
            {
                var snsTags = await snsTopicTagTableOperator.GetAllSubscribersForTagAsync(tag.Tag);

                var subscribers = snsTags.Select(t =>
                {
                    var subscriber = t.Subscriber;
                    subscriber.SNSSubscriptionArn = t.SnsSubscriptionArn;
                    return(subscriber);
                }).ToList();
                await RemoveSubscribersFromSNSTopicTagAsync(pnTag.Tag, subscribers);

                totalDeleted = totalDeleted + subscribers.Count;
            }
            await RemoveDynamoTagAsync(pnTag.Tag);

            TagCRUDSuccessfulResult result = new TagCRUDSuccessfulResult();

            result.NumberOfModifications = totalDeleted;
            return(result);
        }
        protected async Task RemoveSubscriberFromSNSTopicTagAsync(string tag, Subscriber subscriber, bool checkDeleteTopic)
        {
            string subscribtionArn = subscriber.SNSSubscriptionArn;

            if (string.IsNullOrEmpty(subscribtionArn))
            {
                DynamoSNSTopicTag snsTagEntry = await snsTopicTagTableOperator.GetTagForSubscriberAsync(tag, subscriber);

                if (snsTagEntry == null)
                {
                    return;
                }
                subscribtionArn = snsTagEntry.SnsSubscriptionArn;
            }

            var t1 = snsClient.UnsubscribeAsync(subscribtionArn);
            var t2 = snsTopicTagTableOperator.RemoveSubsriberFromTagAsync(tag, subscriber);
            await Task.WhenAll(t1, t2);

            // await tagTableService.DecrementNumberOfSubscribers(tag, 1);

            if (checkDeleteTopic)
            {
                DynamoTag tagEntry = await tagTableOperator.GetTagAsync(tag);

                if (tagEntry != null)
                {
                    // Topic attributes have out-of-date data. Check later
                    GetTopicAttributesResponse taResponse = await snsClient.GetTopicAttributesAsync(tagEntry.SnsTopicArn);

                    int numberOfSubs = 0;
                    if (int.TryParse(taResponse.Attributes["SubscriptionsConfirmed"], out numberOfSubs))
                    {
                        if (numberOfSubs <= 0)
                        {
                            await snsClient.DeleteTopicAsync(tagEntry.SnsTopicArn);
                            await RemoveDynamoTagAsync(tagEntry.Tag);
                        }
                    }
                }
            }
        }