Example #1
0
        internal Document GetItemHelper(Key key, GetItemOperationConfig config, bool isAsync)
        {
            var currentConfig = config ?? new GetItemOperationConfig();
            var request       = new GetItemRequest
            {
                TableName      = TableName,
                Key            = key,
                ConsistentRead = currentConfig.ConsistentRead
            };

            ((Amazon.Runtime.Internal.IAmazonWebServiceRequest)request).AddBeforeRequestHandler(isAsync ?
                                                                                                new RequestEventHandler(UserAgentRequestEventHandlerAsync) :
                                                                                                new RequestEventHandler(UserAgentRequestEventHandlerSync)
                                                                                                );
            if (currentConfig.AttributesToGet != null)
            {
                request.AttributesToGet = currentConfig.AttributesToGet;
            }

            var result       = DDBClient.GetItem(request);
            var attributeMap = result.Item;

            if (attributeMap == null || attributeMap.Count == 0)
            {
                return(null);
            }
            return(Document.FromAttributeMap(attributeMap));
        }
Example #2
0
        internal Document PutItemHelper(Document doc, PutItemOperationConfig config, bool isAsync)
        {
            var currentConfig = config ?? new PutItemOperationConfig();

            PutItemRequest req = new PutItemRequest
            {
                TableName = TableName,
                Item      = doc.ToAttributeMap()
            };

            req.BeforeRequestEvent += isAsync ?
                                      new RequestEventHandler(UserAgentRequestEventHandlerAsync) :
                                      new RequestEventHandler(UserAgentRequestEventHandlerSync);
            if (currentConfig.Expected != null)
            {
                req.Expected = currentConfig.Expected.ToExpectedAttributeMap();
            }
            if (currentConfig.ReturnValues == ReturnValues.AllOldAttributes)
            {
                req.ReturnValues = EnumToStringMapper.Convert(currentConfig.ReturnValues);
            }

            var resp = DDBClient.PutItem(req);

            doc.CommitChanges();

            Document ret = null;

            if (currentConfig.ReturnValues == ReturnValues.AllOldAttributes)
            {
                ret = Document.FromAttributeMap(resp.Attributes);
            }
            return(ret);
        }
Example #3
0
        internal Document GetItemHelper(Key key, GetItemOperationConfig config)
        {
            var currentConfig = config ?? new GetItemOperationConfig();
            var request       = new GetItemRequest
            {
                TableName      = TableName,
                Key            = key,
                ConsistentRead = currentConfig.ConsistentRead
            };

            this.AddRequestHandler(request, isAsync: false);

            if (currentConfig.AttributesToGet != null)
            {
                request.AttributesToGet = currentConfig.AttributesToGet;
            }

            var result       = DDBClient.GetItem(request);
            var attributeMap = result.Item;

            if (attributeMap == null || attributeMap.Count == 0)
            {
                return(null);
            }
            return(this.FromAttributeMap(attributeMap));
        }
Example #4
0
        internal async Task <Document> GetItemHelperAsync(Key key, GetItemOperationConfig config, CancellationToken cancellationToken)
        {
            var currentConfig = config ?? new GetItemOperationConfig();
            var request       = new GetItemRequest
            {
                TableName      = TableName,
                Key            = key,
                ConsistentRead = currentConfig.ConsistentRead
            };

            this.AddRequestHandler(request, isAsync: true);

            if (currentConfig.AttributesToGet != null)
            {
                request.AttributesToGet = currentConfig.AttributesToGet;
            }

            var result = await DDBClient.GetItemAsync(request, cancellationToken).ConfigureAwait(false);

            var attributeMap = result.Item;

            if (attributeMap == null || attributeMap.Count == 0)
            {
                return(null);
            }
            return(this.FromAttributeMap(attributeMap));
        }
Example #5
0
        internal Document DeleteHelper(Key key, DeleteItemOperationConfig config, bool isAsync)
        {
            var currentConfig = config ?? new DeleteItemOperationConfig();

            var req = new DeleteItemRequest
            {
                TableName = TableName,
                Key       = key
            };

            req.BeforeRequestEvent += isAsync ?
                                      new RequestEventHandler(UserAgentRequestEventHandlerAsync) :
                                      new RequestEventHandler(UserAgentRequestEventHandlerSync);
            if (currentConfig.ReturnValues == ReturnValues.AllOldAttributes)
            {
                req.ReturnValues = EnumToStringMapper.Convert(currentConfig.ReturnValues);
            }
            if (currentConfig.Expected != null)
            {
                req.Expected = currentConfig.Expected.ToExpectedAttributeMap();
            }

            var attributes = DDBClient.DeleteItem(req).Attributes;

            Document ret = null;

            if (currentConfig.ReturnValues == ReturnValues.AllOldAttributes)
            {
                ret = Document.FromAttributeMap(attributes);
            }
            return(ret);
        }
Example #6
0
        internal Document UpdateHelper(Document doc, Key key, UpdateItemOperationConfig config, bool isAsync)
        {
            var currentConfig = config ?? new UpdateItemOperationConfig();

            // If the keys have been changed, treat entire document as having changed
            bool haveKeysChanged             = HaveKeysChanged(doc);
            bool updateChangedAttributesOnly = !haveKeysChanged;

            var attributeUpdates = doc.ToAttributeUpdateMap(updateChangedAttributesOnly);

            foreach (var keyName in this.keyNames)
            {
                attributeUpdates.Remove(keyName);
            }

            UpdateItemRequest req = new UpdateItemRequest
            {
                TableName        = TableName,
                Key              = key,
                AttributeUpdates = attributeUpdates.Count == 0 ? null : attributeUpdates, // pass null if keys-only update
                ReturnValues     = EnumMapper.Convert(currentConfig.ReturnValues)
            };

            req.BeforeRequestEvent += isAsync ?
                                      new RequestEventHandler(UserAgentRequestEventHandlerAsync) :
                                      new RequestEventHandler(UserAgentRequestEventHandlerSync);
            if (currentConfig.Expected != null && currentConfig.ExpectedState != null)
            {
                throw new InvalidOperationException("Expected and ExpectedState cannot be set at the same time");
            }
            if (currentConfig.Expected != null)
            {
                req.Expected = currentConfig.Expected.ToExpectedAttributeMap();
            }
            if (currentConfig.ExpectedState != null &&
                currentConfig.ExpectedState.ExpectedValues != null &&
                currentConfig.ExpectedState.ExpectedValues.Count > 0)
            {
                req.Expected = currentConfig.ExpectedState.ToExpectedAttributeMap();
                if (req.Expected.Count > 1)
                {
                    req.ConditionalOperator = EnumMapper.Convert(currentConfig.ExpectedState.ConditionalOperator);
                }
            }

            var resp = DDBClient.UpdateItem(req);
            var returnedAttributes = resp.Attributes;

            doc.CommitChanges();

            Document ret = null;

            if (currentConfig.ReturnValues != ReturnValues.None)
            {
                ret = Document.FromAttributeMap(returnedAttributes);
            }
            return(ret);
        }
Example #7
0
        internal Document PutItemHelper(Document doc, PutItemOperationConfig config, bool isAsync)
        {
            var currentConfig = config ?? new PutItemOperationConfig();

            PutItemRequest req = new PutItemRequest
            {
                TableName = TableName,
                Item      = doc.ToAttributeMap(Conversion)
            };

            ((Amazon.Runtime.Internal.IAmazonWebServiceRequest)req).AddBeforeRequestHandler(isAsync ?
                                                                                            new RequestEventHandler(UserAgentRequestEventHandlerAsync) :
                                                                                            new RequestEventHandler(UserAgentRequestEventHandlerSync));

            if (currentConfig.ReturnValues == ReturnValues.AllOldAttributes)
            {
                req.ReturnValues = EnumMapper.Convert(currentConfig.ReturnValues);
            }

            ValidateConditional(currentConfig);


            if (currentConfig.Expected != null)
            {
                req.Expected = currentConfig.Expected.ToExpectedAttributeMap(Conversion);
            }
            else if (currentConfig.ExpectedState != null &&
                     currentConfig.ExpectedState.ExpectedValues != null &&
                     currentConfig.ExpectedState.ExpectedValues.Count > 0)
            {
                req.Expected = currentConfig.ExpectedState.ToExpectedAttributeMap(Conversion);
                if (req.Expected.Count > 1)
                {
                    req.ConditionalOperator = EnumMapper.Convert(currentConfig.ExpectedState.ConditionalOperator);
                }
            }
            else if (currentConfig.ConditionalExpression != null && currentConfig.ConditionalExpression.IsSet)
            {
                currentConfig.ConditionalExpression.ApplyExpression(req, this.Conversion);
            }

            var resp = DDBClient.PutItem(req);

            doc.CommitChanges();

            Document ret = null;

            if (currentConfig.ReturnValues == ReturnValues.AllOldAttributes)
            {
                ret = Document.FromAttributeMap(resp.Attributes);
            }
            return(ret);
        }
Example #8
0
        internal async Task <Document> PutItemHelperAsync(Document doc, PutItemOperationConfig config, CancellationToken cancellationToken)
        {
            var currentConfig = config ?? new PutItemOperationConfig();

            PutItemRequest req = new PutItemRequest
            {
                TableName = TableName,
                Item      = this.ToAttributeMap(doc)
            };

            this.AddRequestHandler(req, isAsync: true);

            if (currentConfig.ReturnValues == ReturnValues.AllOldAttributes)
            {
                req.ReturnValues = EnumMapper.Convert(currentConfig.ReturnValues);
            }

            ValidateConditional(currentConfig);


            if (currentConfig.Expected != null)
            {
                req.Expected = this.ToExpectedAttributeMap(currentConfig.Expected);
            }
            else if (currentConfig.ExpectedState != null &&
                     currentConfig.ExpectedState.ExpectedValues != null &&
                     currentConfig.ExpectedState.ExpectedValues.Count > 0)
            {
                req.Expected = currentConfig.ExpectedState.ToExpectedAttributeMap(this);
                if (req.Expected.Count > 1)
                {
                    req.ConditionalOperator = EnumMapper.Convert(currentConfig.ExpectedState.ConditionalOperator);
                }
            }
            else if (currentConfig.ConditionalExpression != null && currentConfig.ConditionalExpression.IsSet)
            {
                currentConfig.ConditionalExpression.ApplyExpression(req, this);
            }

            var resp = await DDBClient.PutItemAsync(req, cancellationToken).ConfigureAwait(false);

            doc.CommitChanges();

            Document ret = null;

            if (currentConfig.ReturnValues == ReturnValues.AllOldAttributes)
            {
                ret = this.FromAttributeMap(resp.Attributes);
            }
            return(ret);
        }
Example #9
0
        internal Document DeleteHelper(Key key, DeleteItemOperationConfig config, bool isAsync)
        {
            var currentConfig = config ?? new DeleteItemOperationConfig();

            var req = new DeleteItemRequest
            {
                TableName = TableName,
                Key       = key
            };

            req.BeforeRequestEvent += isAsync ?
                                      new RequestEventHandler(UserAgentRequestEventHandlerAsync) :
                                      new RequestEventHandler(UserAgentRequestEventHandlerSync);
            if (currentConfig.ReturnValues == ReturnValues.AllOldAttributes)
            {
                req.ReturnValues = EnumMapper.Convert(currentConfig.ReturnValues);
            }

            ValidateConditional(currentConfig);

            if (currentConfig.Expected != null)
            {
                req.Expected = currentConfig.Expected.ToExpectedAttributeMap(Conversion);
            }
            else if (currentConfig.ExpectedState != null &&
                     currentConfig.ExpectedState.ExpectedValues != null &&
                     currentConfig.ExpectedState.ExpectedValues.Count > 0)
            {
                req.Expected = currentConfig.ExpectedState.ToExpectedAttributeMap(Conversion);
                if (req.Expected.Count > 1)
                {
                    req.ConditionalOperator = EnumMapper.Convert(currentConfig.ExpectedState.ConditionalOperator);
                }
            }
            else if (currentConfig.ConditionalExpression != null && currentConfig.ConditionalExpression.IsSet)
            {
                currentConfig.ConditionalExpression.ApplyExpression(req, this.Conversion);
            }

            var attributes = DDBClient.DeleteItem(req).Attributes;

            Document ret = null;

            if (currentConfig.ReturnValues == ReturnValues.AllOldAttributes)
            {
                ret = Document.FromAttributeMap(attributes);
            }
            return(ret);
        }
Example #10
0
        internal async Task <Document> DeleteHelperAsync(Key key, DeleteItemOperationConfig config, CancellationToken cancellationToken)
        {
            var currentConfig = config ?? new DeleteItemOperationConfig();

            var req = new DeleteItemRequest
            {
                TableName = TableName,
                Key       = key
            };

            this.AddRequestHandler(req, isAsync: true);

            if (currentConfig.ReturnValues == ReturnValues.AllOldAttributes)
            {
                req.ReturnValues = EnumMapper.Convert(currentConfig.ReturnValues);
            }

            ValidateConditional(currentConfig);

            if (currentConfig.Expected != null)
            {
                req.Expected = this.ToExpectedAttributeMap(currentConfig.Expected);
            }
            else if (currentConfig.ExpectedState != null &&
                     currentConfig.ExpectedState.ExpectedValues != null &&
                     currentConfig.ExpectedState.ExpectedValues.Count > 0)
            {
                req.Expected = currentConfig.ExpectedState.ToExpectedAttributeMap(this);
                if (req.Expected.Count > 1)
                {
                    req.ConditionalOperator = EnumMapper.Convert(currentConfig.ExpectedState.ConditionalOperator);
                }
            }
            else if (currentConfig.ConditionalExpression != null && currentConfig.ConditionalExpression.IsSet)
            {
                currentConfig.ConditionalExpression.ApplyExpression(req, this);
            }

            var attributes = (await DDBClient.DeleteItemAsync(req, cancellationToken).ConfigureAwait(false)).Attributes;

            Document ret = null;

            if (currentConfig.ReturnValues == ReturnValues.AllOldAttributes)
            {
                ret = this.FromAttributeMap(attributes);
            }
            return(ret);
        }
Example #11
0
        internal Document PutItemHelper(Document doc, PutItemOperationConfig config, bool isAsync)
        {
            var currentConfig = config ?? new PutItemOperationConfig();

            PutItemRequest req = new PutItemRequest
            {
                TableName = TableName,
                Item      = doc.ToAttributeMap()
            };

            req.BeforeRequestEvent += isAsync ?
                                      new RequestEventHandler(UserAgentRequestEventHandlerAsync) :
                                      new RequestEventHandler(UserAgentRequestEventHandlerSync);
            if (currentConfig.ReturnValues == ReturnValues.AllOldAttributes)
            {
                req.ReturnValues = EnumMapper.Convert(currentConfig.ReturnValues);
            }
            if (currentConfig.Expected != null && currentConfig.ExpectedState != null)
            {
                throw new InvalidOperationException("Expected and ExpectedState cannot be set at the same time");
            }
            if (currentConfig.Expected != null)
            {
                req.Expected = currentConfig.Expected.ToExpectedAttributeMap();
            }
            if (currentConfig.ExpectedState != null &&
                currentConfig.ExpectedState.ExpectedValues != null &&
                currentConfig.ExpectedState.ExpectedValues.Count > 0)
            {
                req.Expected = currentConfig.ExpectedState.ToExpectedAttributeMap();
                if (req.Expected.Count > 1)
                {
                    req.ConditionalOperator = EnumMapper.Convert(currentConfig.ExpectedState.ConditionalOperator);
                }
            }

            var resp = DDBClient.PutItem(req);

            doc.CommitChanges();

            Document ret = null;

            if (currentConfig.ReturnValues == ReturnValues.AllOldAttributes)
            {
                ret = Document.FromAttributeMap(resp.Attributes);
            }
            return(ret);
        }
Example #12
0
        internal Document DeleteHelper(Key key, DeleteItemOperationConfig config, bool isAsync)
        {
            var currentConfig = config ?? new DeleteItemOperationConfig();

            var req = new DeleteItemRequest
            {
                TableName = TableName,
                Key       = key
            };

            req.BeforeRequestEvent += isAsync ?
                                      new RequestEventHandler(UserAgentRequestEventHandlerAsync) :
                                      new RequestEventHandler(UserAgentRequestEventHandlerSync);
            if (currentConfig.ReturnValues == ReturnValues.AllOldAttributes)
            {
                req.ReturnValues = EnumMapper.Convert(currentConfig.ReturnValues);
            }
            if (currentConfig.Expected != null && currentConfig.ExpectedState != null)
            {
                throw new InvalidOperationException("Expected and ExpectedState cannot be set at the same time");
            }
            if (currentConfig.Expected != null)
            {
                req.Expected = currentConfig.Expected.ToExpectedAttributeMap();
            }
            if (currentConfig.ExpectedState != null &&
                currentConfig.ExpectedState.ExpectedValues != null &&
                currentConfig.ExpectedState.ExpectedValues.Count > 0)
            {
                req.Expected = currentConfig.ExpectedState.ToExpectedAttributeMap();
                if (req.Expected.Count > 1)
                {
                    req.ConditionalOperator = EnumMapper.Convert(currentConfig.ExpectedState.ConditionalOperator);
                }
            }

            var attributes = DDBClient.DeleteItem(req).Attributes;

            Document ret = null;

            if (currentConfig.ReturnValues == ReturnValues.AllOldAttributes)
            {
                ret = Document.FromAttributeMap(attributes);
            }
            return(ret);
        }
Example #13
0
        public async Task <APIGatewayProxyResponse> OnConnectHandler(APIGatewayProxyRequest request, ILambdaContext context)
        {
            try
            {
                var connectionId = request.RequestContext.ConnectionId;
                context.Logger.LogLine($"ConnectionId: {connectionId}");

                var ddbRequest = new PutItemRequest
                {
                    TableName = ConnectionMappingTable,
                    Item      = new Dictionary <string, AttributeValue>
                    {
                        { ConnectionIdField, new AttributeValue {
                              S = connectionId
                          } }
                    }
                };

                await DDBClient.PutItemAsync(ddbRequest);

                return(new APIGatewayProxyResponse
                {
                    StatusCode = 200,
                    Body = "Connected."
                });
            }
            catch (Exception e)
            {
                context.Logger.LogLine("Error connecting: " + e.Message);
                context.Logger.LogLine(e.StackTrace);
                return(new APIGatewayProxyResponse
                {
                    StatusCode = 500,
                    Body = $"Failed to connect: {e.Message}"
                });
            }
        }
Example #14
0
        public async Task <APIGatewayProxyResponse> SendMessageHandler(APIGatewayProxyRequest request, ILambdaContext context)
        {
            try
            {
                // Construct the API Gateway endpoint that incoming message will be broadcasted to.
                var domainName = request.RequestContext.DomainName;
                var stage      = request.RequestContext.Stage;
                var endpoint   = $"https://{domainName}/{stage}";
                context.Logger.LogLine($"API Gateway management endpoint: {endpoint}");

                // The body will look something like this: {"message":"sendmessage", "data":"What are you doing?"}
                JsonDocument message = JsonDocument.Parse(request.Body);

                // Grab the data from the JSON body which is the message to broadcasted.
                JsonElement dataProperty;
                if (!message.RootElement.TryGetProperty("data", out dataProperty))
                {
                    context.Logger.LogLine("Failed to find data element in JSON document");
                    return(new APIGatewayProxyResponse
                    {
                        StatusCode = (int)HttpStatusCode.BadRequest
                    });
                }

                var data   = dataProperty.GetString();
                var stream = new MemoryStream(UTF8Encoding.UTF8.GetBytes(data));

                // List all of the current connections. In a more advanced use case the table could be used to grab a group of connection ids for a chat group.
                var scanRequest = new ScanRequest
                {
                    TableName            = ConnectionMappingTable,
                    ProjectionExpression = ConnectionIdField
                };

                var scanResponse = await DDBClient.ScanAsync(scanRequest);

                // Construct the IAmazonApiGatewayManagementApi which will be used to send the message to.
                var apiClient = ApiGatewayManagementApiClientFactory(endpoint);

                // Loop through all of the connections and broadcast the message out to the connections.
                var count = 0;
                foreach (var item in scanResponse.Items)
                {
                    var postConnectionRequest = new PostToConnectionRequest
                    {
                        ConnectionId = item[ConnectionIdField].S,
                        Data         = stream
                    };

                    try
                    {
                        context.Logger.LogLine($"Post to connection {count}: {postConnectionRequest.ConnectionId}");
                        stream.Position = 0;
                        await apiClient.PostToConnectionAsync(postConnectionRequest);

                        count++;
                    }
                    catch (AmazonServiceException e)
                    {
                        // API Gateway returns a status of 410 GONE then the connection is no
                        // longer available. If this happens, delete the identifier
                        // from our DynamoDB table.
                        if (e.StatusCode == HttpStatusCode.Gone)
                        {
                            var ddbDeleteRequest = new DeleteItemRequest
                            {
                                TableName = ConnectionMappingTable,
                                Key       = new Dictionary <string, AttributeValue>
                                {
                                    { ConnectionIdField, new AttributeValue {
                                          S = postConnectionRequest.ConnectionId
                                      } }
                                }
                            };

                            context.Logger.LogLine($"Deleting gone connection: {postConnectionRequest.ConnectionId}");
                            await DDBClient.DeleteItemAsync(ddbDeleteRequest);
                        }
                        else
                        {
                            context.Logger.LogLine($"Error posting message to {postConnectionRequest.ConnectionId}: {e.Message}");
                            context.Logger.LogLine(e.StackTrace);
                        }
                    }
                }

                return(new APIGatewayProxyResponse
                {
                    StatusCode = (int)HttpStatusCode.OK,
                    Body = "Data sent to " + count + " connection" + (count == 1 ? "" : "s")
                });
            }
            catch (Exception e)
            {
                context.Logger.LogLine("Error disconnecting: " + e.Message);
                context.Logger.LogLine(e.StackTrace);
                return(new APIGatewayProxyResponse
                {
                    StatusCode = (int)HttpStatusCode.InternalServerError,
                    Body = $"Failed to send message: {e.Message}"
                });
            }
        }
Example #15
0
        internal async Task <Document> UpdateHelperAsync(Document doc, Key key, UpdateItemOperationConfig config, CancellationToken cancellationToken)
        {
            var currentConfig = config ?? new UpdateItemOperationConfig();

            // If the keys have been changed, treat entire document as having changed
            bool haveKeysChanged             = HaveKeysChanged(doc);
            bool updateChangedAttributesOnly = !haveKeysChanged;

            var attributeUpdates = this.ToAttributeUpdateMap(doc, updateChangedAttributesOnly);

            foreach (var keyName in this.KeyNames)
            {
                attributeUpdates.Remove(keyName);
            }

            UpdateItemRequest req = new UpdateItemRequest
            {
                TableName        = TableName,
                Key              = key,
                AttributeUpdates = attributeUpdates.Count == 0 ? null : attributeUpdates, // pass null if keys-only update
                ReturnValues     = EnumMapper.Convert(currentConfig.ReturnValues)
            };

            this.AddRequestHandler(req, isAsync: true);

            ValidateConditional(currentConfig);

            if (currentConfig.Expected != null)
            {
                req.Expected = this.ToExpectedAttributeMap(currentConfig.Expected);
            }
            else if (currentConfig.ExpectedState != null &&
                     currentConfig.ExpectedState.ExpectedValues != null &&
                     currentConfig.ExpectedState.ExpectedValues.Count > 0)
            {
                req.Expected = currentConfig.ExpectedState.ToExpectedAttributeMap(this);
                if (req.Expected.Count > 1)
                {
                    req.ConditionalOperator = EnumMapper.Convert(currentConfig.ExpectedState.ConditionalOperator);
                }
            }
            else if (currentConfig.ConditionalExpression != null && currentConfig.ConditionalExpression.IsSet)
            {
                currentConfig.ConditionalExpression.ApplyExpression(req, this);

                string statement;
                Dictionary <string, AttributeValue> expressionAttributeValues;
                Dictionary <string, string>         expressionAttributeNames;
                Common.ConvertAttributeUpdatesToUpdateExpression(attributeUpdates, out statement, out expressionAttributeValues, out expressionAttributeNames);

                req.AttributeUpdates = null;
                req.UpdateExpression = statement;

                if (req.ExpressionAttributeValues == null)
                {
                    req.ExpressionAttributeValues = expressionAttributeValues;
                }
                else
                {
                    foreach (var kvp in expressionAttributeValues)
                    {
                        req.ExpressionAttributeValues.Add(kvp.Key, kvp.Value);
                    }
                }

                if (req.ExpressionAttributeNames == null)
                {
                    req.ExpressionAttributeNames = expressionAttributeNames;
                }
                else
                {
                    foreach (var kvp in expressionAttributeNames)
                    {
                        req.ExpressionAttributeNames.Add(kvp.Key, kvp.Value);
                    }
                }
            }

            var resp = await DDBClient.UpdateItemAsync(req, cancellationToken).ConfigureAwait(false);

            var returnedAttributes = resp.Attributes;

            doc.CommitChanges();

            Document ret = null;

            if (currentConfig.ReturnValues != ReturnValues.None)
            {
                ret = this.FromAttributeMap(returnedAttributes);
            }
            return(ret);
        }
Example #16
0
        internal Document UpdateHelper(Document doc, Key key, UpdateItemOperationConfig config, bool isAsync)
        {
            var currentConfig = config ?? new UpdateItemOperationConfig();

            // If the keys have been changed, treat entire document as having changed
            bool haveKeysChanged             = HaveKeysChanged(doc);
            bool updateChangedAttributesOnly = !haveKeysChanged;

            var attributeUpdates = doc.ToAttributeUpdateMap(Conversion, updateChangedAttributesOnly);

            foreach (var keyName in this.KeyNames)
            {
                attributeUpdates.Remove(keyName);
            }

            UpdateItemRequest req = new UpdateItemRequest
            {
                TableName        = TableName,
                Key              = key,
                AttributeUpdates = attributeUpdates.Count == 0 ? null : attributeUpdates, // pass null if keys-only update
                ReturnValues     = EnumMapper.Convert(currentConfig.ReturnValues)
            };


            ((Amazon.Runtime.Internal.IAmazonWebServiceRequest)req).AddBeforeRequestHandler(isAsync ?
                                                                                            new RequestEventHandler(UserAgentRequestEventHandlerAsync) :
                                                                                            new RequestEventHandler(UserAgentRequestEventHandlerSync)
                                                                                            );

            ValidateConditional(currentConfig);

            if (currentConfig.Expected != null)
            {
                req.Expected = currentConfig.Expected.ToExpectedAttributeMap(Conversion);
            }
            else if (currentConfig.ExpectedState != null &&
                     currentConfig.ExpectedState.ExpectedValues != null &&
                     currentConfig.ExpectedState.ExpectedValues.Count > 0)
            {
                req.Expected = currentConfig.ExpectedState.ToExpectedAttributeMap(Conversion);
                if (req.Expected.Count > 1)
                {
                    req.ConditionalOperator = EnumMapper.Convert(currentConfig.ExpectedState.ConditionalOperator);
                }
            }
            else if (currentConfig.ConditionalExpression != null && currentConfig.ConditionalExpression.IsSet)
            {
                currentConfig.ConditionalExpression.ApplyExpression(req, this.Conversion);

                string statement;
                Dictionary <string, AttributeValue> expressionAttributeValues;
                Dictionary <string, string>         expressionAttributeNames;
                Common.ConvertAttributeUpdatesToUpdateExpression(attributeUpdates, out statement, out expressionAttributeValues, out expressionAttributeNames);

                req.AttributeUpdates = null;
                req.UpdateExpression = statement;

                if (req.ExpressionAttributeValues == null)
                {
                    req.ExpressionAttributeValues = expressionAttributeValues;
                }
                else
                {
                    foreach (var kvp in expressionAttributeValues)
                    {
                        req.ExpressionAttributeValues.Add(kvp.Key, kvp.Value);
                    }
                }

                if (req.ExpressionAttributeNames == null)
                {
                    req.ExpressionAttributeNames = expressionAttributeNames;
                }
                else
                {
                    foreach (var kvp in expressionAttributeNames)
                    {
                        req.ExpressionAttributeNames.Add(kvp.Key, kvp.Value);
                    }
                }
            }

            var resp = DDBClient.UpdateItem(req);
            var returnedAttributes = resp.Attributes;

            doc.CommitChanges();

            Document ret = null;

            if (currentConfig.ReturnValues != ReturnValues.None)
            {
                ret = Document.FromAttributeMap(returnedAttributes);
            }
            return(ret);
        }
Example #17
0
        public async Task <APIGatewayProxyResponse> SendMessageHandler(APIGatewayProxyRequest request, ILambdaContext context)
        {
            try
            {
                // Construct the API Gateway endpoint that incoming message will be broadcasted to.
                var domainName   = request.RequestContext.DomainName;
                var stage        = request.RequestContext.Stage;
                var endpoint     = $"https://{domainName}/{stage}";
                var connectionId = request.RequestContext.ConnectionId;
                context.Logger.LogLine($"API Gateway management endpoint: {endpoint}");

                JsonDocument message = JsonDocument.Parse(request.Body);

                // Grab the data from the JSON body which is the message to broadcasted.
                JsonElement dataProperty;
                if (!message.RootElement.TryGetProperty("data", out dataProperty))
                {
                    context.Logger.LogLine("Failed to find data element in JSON document");
                    return(new APIGatewayProxyResponse
                    {
                        StatusCode = (int)HttpStatusCode.BadRequest
                    });
                }
                var options = new JsonSerializerOptions
                {
                    PropertyNameCaseInsensitive = true,
                };
                ChatMessageRequest messageRequest = JsonSerializer.Deserialize <ChatMessageRequest>(dataProperty.ToString(), options);
                string             date           = (DateTime.UtcNow.Subtract(new DateTime(1970, 1, 1))).TotalSeconds.ToString();
                await DDBUtils.PutMessage(messageRequest.Message, messageRequest.RoomID, messageRequest.UserID, date);

                ChatMessageResponse chatMsg = new ChatMessageResponse
                {
                    Success = true,
                    Message = messageRequest.Message,
                    Date    = date,
                    Author  = messageRequest.UserID,
                    RoomId  = messageRequest.RoomID
                };

                string data   = JsonSerializer.Serialize(chatMsg);
                var    stream = new MemoryStream(UTF8Encoding.UTF8.GetBytes(data));

                var queryRequest = new QueryRequest
                {
                    TableName = RoomsConnectionsTable,
                    KeyConditionExpression    = "RoomId = :ri",
                    ExpressionAttributeValues = new Dictionary <string, AttributeValue> {
                        { ":ri", new AttributeValue {
                              S = messageRequest.RoomID
                          } }
                    },
                    ProjectionExpression = "RoomId, ConnectionId"
                };

                var queryResponse = await DDBClient.QueryAsync(queryRequest);

                // Construct the IAmazonApiGatewayManagementApi which will be used to send the message to.
                var apiClient = ApiGatewayManagementApiClientFactory(endpoint);

                // Loop through all of the connections and broadcast the message out to the connections.
                var count = 0;
                foreach (var item in queryResponse.Items)
                {
                    var postConnectionRequest = new PostToConnectionRequest
                    {
                        ConnectionId = item["ConnectionId"].S,
                        Data         = stream
                    };

                    try
                    {
                        context.Logger.LogLine($"Post to connection {count}: {postConnectionRequest.ConnectionId}");
                        stream.Position = 0;
                        await apiClient.PostToConnectionAsync(postConnectionRequest);

                        count++;
                    }
                    catch (AmazonServiceException e)
                    {
                        // API Gateway returns a status of 410 GONE then the connection is no
                        // longer available. If this happens, delete the identifier
                        // from our DynamoDB table.
                        if (e.StatusCode == HttpStatusCode.Gone)
                        {
                            var ddbDeleteRequest = new DeleteItemRequest
                            {
                                TableName = RoomsConnectionsTable,
                                Key       = new Dictionary <string, AttributeValue>
                                {
                                    { "RoomId", new AttributeValue {
                                          S = item["RoomId"].S
                                      } },
                                    { "ConnectionId", new AttributeValue {
                                          S = postConnectionRequest.ConnectionId
                                      } }
                                }
                            };

                            context.Logger.LogLine($"Deleting gone connection: {postConnectionRequest.ConnectionId}");
                            await DDBClient.DeleteItemAsync(ddbDeleteRequest);
                        }
                        else
                        {
                            context.Logger.LogLine($"Error posting message to {postConnectionRequest.ConnectionId}: {e.Message}");
                            context.Logger.LogLine(e.StackTrace);
                        }
                    }
                }

                return(new APIGatewayProxyResponse
                {
                    StatusCode = (int)HttpStatusCode.OK,
                    Body = "Data sent to " + count + " connection" + (count == 1 ? "" : "s")
                });
            }
            catch (Exception e)
            {
                context.Logger.LogLine("Error sending message: " + e.Message);
                context.Logger.LogLine(e.StackTrace);
                return(new APIGatewayProxyResponse
                {
                    StatusCode = (int)HttpStatusCode.InternalServerError,
                    Body = $"Failed to send message: {e.Message}"
                });
            }
        }
Example #18
0
        public async Task <APIGatewayProxyResponse> LoginHandler(APIGatewayProxyRequest request, ILambdaContext context)
        {
            try
            {
                var connectionId = request.RequestContext.ConnectionId;
                var options      = new JsonSerializerOptions
                {
                    PropertyNameCaseInsensitive = true,
                };
                LoginRequest logRequest = JsonSerializer.Deserialize <LoginRequest>(request.Body, options);
                var          ddbRequest = new PutItemRequest
                {
                    TableName = UsersRoomsTable,
                    Item      = new Dictionary <string, AttributeValue>
                    {
                        { "NodeId", new AttributeValue {
                              S = "user-" + logRequest.UserID
                          } },
                        { "TargetId", new AttributeValue {
                              S = "user-" + logRequest.UserID
                          } },
                        { "UserId", new AttributeValue {
                              S = logRequest.UserID
                          } }
                    }
                };

                await DDBUtils.AddUserToHisRooms(logRequest.UserID, connectionId);

                await DDBClient.PutItemAsync(ddbRequest);

                var customRoomsInfo = await DDBUtils.GetUserCustomRooms(logRequest.UserID);

                LoginResponse responseMsg = new LoginResponse()
                {
                    Success          = true,
                    Users            = await DDBUtils.GetAllUsers(),
                    CustomRoomsNames = customRoomsInfo.Item1,
                    CustomRoomsIds   = customRoomsInfo.Item2
                };

                return(new APIGatewayProxyResponse
                {
                    StatusCode = (int)HttpStatusCode.OK,
                    Body = JsonSerializer.Serialize(responseMsg)
                });
            }
            catch (Exception e)
            {
                context.Logger.LogLine("Error logging in: " + e.Message);
                context.Logger.LogLine(e.StackTrace);
                LoginResponse responseMsg = new LoginResponse()
                {
                    Success = false
                };
                return(new APIGatewayProxyResponse
                {
                    StatusCode = (int)HttpStatusCode.InternalServerError,
                    Body = JsonSerializer.Serialize(responseMsg)
                });
            }
        }