func (im *Model) registerHostName(hostName string) { attribs := []dynamodb.Attribute{ *dynamodb.NewStringAttribute(cPrimKey, hostName), *dynamodb.NewStringAttribute("ts", fmt.Sprintf("%d", time.Now().Unix())), } if _, err := im.table.PutItem(hostName, cPrimKey, attribs); err != nil { log.Fatal("The hostname can't be registered on the instances table, Error:", err) } }
func (s *QueryBuilderSuite) TestAddExpectedQuery(c *gocheck.C) { primary := dynamodb.NewStringAttribute("domain", "") key := dynamodb.PrimaryKey{primary, nil} table := s.server.NewTable("sites", key) q := dynamodb.NewQuery(table) q.AddKey(table, &dynamodb.Key{HashKey: "test"}) expected := []dynamodb.Attribute{ *dynamodb.NewStringAttribute("domain", "expectedTest").SetExists(true), *dynamodb.NewStringAttribute("testKey", "").SetExists(false), } q.AddExpected(expected) queryJson, err := simplejson.NewJson([]byte(q.String())) if err != nil { c.Fatal(err) } expectedJson, err := simplejson.NewJson([]byte(` { "Expected": { "domain": { "Exists": "true", "Value": { "S": "expectedTest" } }, "testKey": { "Exists": "false" } }, "Key": { "domain": { "S": "test" } }, "TableName": "sites" } `)) if err != nil { c.Fatal(err) } c.Check(queryJson, gocheck.DeepEquals, expectedJson) }
func (s *ItemSuite) TestPutGetDeleteItem(c *C) { attrs := []dynamodb.Attribute{ *dynamodb.NewStringAttribute("Attr1", "Attr1Val"), } var rk string if s.WithRange { rk = "1" } // Put if ok, err := s.table.PutItem("NewHashKeyVal", rk, attrs); !ok { c.Fatal(err) } // Get to verify Put operation pk := &dynamodb.Key{HashKey: "NewHashKeyVal", RangeKey: rk} item, err := s.table.GetItem(pk) if err != nil { c.Fatal(err) } if val, ok := item["TestHashKey"]; ok { c.Check(val, DeepEquals, dynamodb.NewStringAttribute("TestHashKey", "NewHashKeyVal")) } else { c.Error("Expect TestHashKey to be found") } if s.WithRange { if val, ok := item["TestRangeKey"]; ok { c.Check(val, DeepEquals, dynamodb.NewNumericAttribute("TestRangeKey", "1")) } else { c.Error("Expect TestRangeKey to be found") } } // Delete if ok, _ := s.table.DeleteItem(pk); !ok { c.Fatal(err) } // Get to verify Delete operation _, err = s.table.GetItem(pk) c.Check(err.Error(), Matches, "Item not found") }
func (s *QueryBuilderSuite) TestGetItemQuery(c *gocheck.C) { primary := dynamodb.NewStringAttribute("domain", "") key := dynamodb.PrimaryKey{primary, nil} table := s.server.NewTable("sites", key) q := dynamodb.NewQuery(table) q.AddKey(table, &dynamodb.Key{HashKey: "test"}) { queryJson, err := simplejson.NewJson([]byte(q.String())) if err != nil { c.Fatal(err) } expectedJson, err := simplejson.NewJson([]byte(` { "Key": { "domain": { "S": "test" } }, "TableName": "sites" } `)) if err != nil { c.Fatal(err) } c.Check(queryJson, gocheck.DeepEquals, expectedJson) } // Use ConsistentRead { q.ConsistentRead(true) queryJson, err := simplejson.NewJson([]byte(q.String())) if err != nil { c.Fatal(err) } expectedJson, err := simplejson.NewJson([]byte(` { "ConsistentRead": "true", "Key": { "domain": { "S": "test" } }, "TableName": "sites" } `)) if err != nil { c.Fatal(err) } c.Check(queryJson, gocheck.DeepEquals, expectedJson) } }
func (s *ItemSuite) TestUpdateItem_new(c *C) { attrs := []dynamodb.Attribute{ *dynamodb.NewStringAttribute("intval", "1"), } var rk string if s.WithRange { rk = "1" } pk := &dynamodb.Key{HashKey: "UpdateKeyVal", RangeKey: rk} num := func(a, b string) dynamodb.Attribute { return *dynamodb.NewNumericAttribute(a, b) } checkVal := func(i string) { if item, err := s.table.GetItem(pk); err != nil { c.Error(err) } else { c.Check(item["intval"], DeepEquals, dynamodb.NewNumericAttribute("intval", i)) } } if ok, err := s.table.PutItem("UpdateKeyVal", rk, attrs); !ok { c.Error(err) } checkVal("1") // Simple Increment s.table.UpdateItem(pk).UpdateExpression("SET intval = intval + :incr", num(":incr", "5")).Execute() checkVal("6") conditionalUpdate := func(check string) { s.table.UpdateItem(pk). ConditionExpression("intval = :check"). UpdateExpression("SET intval = intval + :incr"). ExpressionAttributes(num(":check", check), num(":incr", "4")). Execute() } // Conditional increment should be a no-op. conditionalUpdate("42") checkVal("6") // conditional increment should succeed this time conditionalUpdate("6") checkVal("10") // Update with new values getting values result, err := s.table.UpdateItem(pk). ReturnValues(dynamodb.UPDATED_NEW). UpdateExpression("SET intval = intval + :incr", num(":incr", "2")). Execute() c.Check(err, IsNil) c.Check(result.Attributes["intval"], DeepEquals, num("intval", "12")) checkVal("12") }
func (s *QueryBuilderSuite) TestAddKeyConditions(c *gocheck.C) { primary := dynamodb.NewStringAttribute("domain", "") key := dynamodb.PrimaryKey{primary, nil} table := s.server.NewTable("sites", key) q := dynamodb.NewQuery(table) acs := []dynamodb.AttributeComparison{ *dynamodb.NewStringAttributeComparison("domain", "EQ", "example.com"), *dynamodb.NewStringAttributeComparison("path", "EQ", "/"), } q.AddKeyConditions(acs) queryJson, err := simplejson.NewJson([]byte(q.String())) if err != nil { c.Fatal(err) } expectedJson, err := simplejson.NewJson([]byte(` { "KeyConditions": { "domain": { "AttributeValueList": [ { "S": "example.com" } ], "ComparisonOperator": "EQ" }, "path": { "AttributeValueList": [ { "S": "/" } ], "ComparisonOperator": "EQ" } }, "TableName": "sites" } `)) if err != nil { c.Fatal(err) } c.Check(queryJson, gocheck.DeepEquals, expectedJson) }
func (s *QueryBuilderSuite) TestUpdateQuery(c *gocheck.C) { primary := dynamodb.NewStringAttribute("domain", "") rangek := dynamodb.NewNumericAttribute("time", "") key := dynamodb.PrimaryKey{primary, rangek} table := s.server.NewTable("sites", key) countAttribute := dynamodb.NewNumericAttribute("count", "4") attributes := []dynamodb.Attribute{*countAttribute} q := dynamodb.NewQuery(table) q.AddKey(table, &dynamodb.Key{HashKey: "test", RangeKey: "1234"}) q.AddUpdates(attributes, "ADD") queryJson, err := simplejson.NewJson([]byte(q.String())) if err != nil { c.Fatal(err) } expectedJson, err := simplejson.NewJson([]byte(` { "AttributeUpdates": { "count": { "Action": "ADD", "Value": { "N": "4" } } }, "Key": { "domain": { "S": "test" }, "time": { "N": "1234" } }, "TableName": "sites" } `)) if err != nil { c.Fatal(err) } c.Check(queryJson, gocheck.DeepEquals, expectedJson) }
func (s *QueryBuilderSuite) TestAddUpdates(c *gocheck.C) { primary := dynamodb.NewStringAttribute("domain", "") key := dynamodb.PrimaryKey{primary, nil} table := s.server.NewTable("sites", key) q := dynamodb.NewQuery(table) q.AddKey(table, &dynamodb.Key{HashKey: "test"}) attr := dynamodb.NewStringSetAttribute("StringSet", []string{"str", "str2"}) q.AddUpdates([]dynamodb.Attribute{*attr}, "ADD") queryJson, err := simplejson.NewJson([]byte(q.String())) if err != nil { c.Fatal(err) } expectedJson, err := simplejson.NewJson([]byte(` { "AttributeUpdates": { "StringSet": { "Action": "ADD", "Value": { "SS": ["str", "str2"] } } }, "Key": { "domain": { "S": "test" } }, "TableName": "sites" } `)) if err != nil { c.Fatal(err) } c.Check(queryJson, gocheck.DeepEquals, expectedJson) }
func (um *Model) initTable() { pKey := dynamodb.PrimaryKey{dynamodb.NewStringAttribute(cPrimKey, ""), nil} um.table = um.conn.NewTable(um.tableName, pKey) res, err := um.table.DescribeTable() if err != nil { log.Info("Creating a new table on DynamoDB:", um.tableName) td := dynamodb.TableDescriptionT{ TableName: um.tableName, AttributeDefinitions: []dynamodb.AttributeDefinitionT{ dynamodb.AttributeDefinitionT{cPrimKey, "S"}, }, KeySchema: []dynamodb.KeySchemaT{ dynamodb.KeySchemaT{cPrimKey, "HASH"}, }, ProvisionedThroughput: dynamodb.ProvisionedThroughputT{ ReadCapacityUnits: cDefaultWRCapacity, WriteCapacityUnits: cDefaultWRCapacity, }, } if _, err := um.conn.CreateTable(td); err != nil { log.Error("Error trying to create a table on Dynamo DB, table:", um.tableName, "Error:", err) } if res, err = um.table.DescribeTable(); err != nil { log.Error("Error trying to describe a table on Dynamo DB, table:", um.tableName, "Error:", err) } } for "ACTIVE" != res.TableStatus { if res, err = um.table.DescribeTable(); err != nil { log.Error("Can't describe Dynamo DB instances table, Error:", err) } log.Debug("Waiting for active table, current status:", res.TableStatus) time.Sleep(time.Second) } }
func (us *User) persist() bool { userJSONInfo, _ := json.Marshal(us) userJSONLogs, _ := json.Marshal(us.logs) userJSONBillHist, _ := json.Marshal(us.billHist) attribs := []dynamodb.Attribute{ *dynamodb.NewStringAttribute(cPrimKey, us.uid), *dynamodb.NewStringAttribute("key", us.key), *dynamodb.NewStringAttribute("info", string(userJSONInfo)), *dynamodb.NewStringAttribute("bill_hist", string(userJSONBillHist)), *dynamodb.NewStringAttribute("logs", string(userJSONLogs)), *dynamodb.NewStringAttribute("enabled", string(us.Enabled)), } if _, err := us.md.table.PutItem(us.uid, cPrimKey, attribs); err != nil { log.Error("A new user can't be registered on the users table, Error:", err) return false } return true }
func (s *QueryBuilderSuite) TestAddWriteRequestItems(c *gocheck.C) { primary := dynamodb.NewStringAttribute("WidgetFoo", "") secondary := dynamodb.NewNumericAttribute("Created", "") key := dynamodb.PrimaryKey{primary, secondary} table := s.server.NewTable("FooData", key) primary2 := dynamodb.NewStringAttribute("TestHashKey", "") secondary2 := dynamodb.NewNumericAttribute("TestRangeKey", "") key2 := dynamodb.PrimaryKey{primary2, secondary2} table2 := s.server.NewTable("TestTable", key2) q := dynamodb.NewEmptyQuery() attribute1 := dynamodb.NewNumericAttribute("testing", "4") attribute2 := dynamodb.NewNumericAttribute("testingbatch", "2111") attribute3 := dynamodb.NewStringAttribute("testingstrbatch", "mystr") item1 := []dynamodb.Attribute{*attribute1, *attribute2, *attribute3} attribute4 := dynamodb.NewNumericAttribute("testing", "444") attribute5 := dynamodb.NewNumericAttribute("testingbatch", "93748249272") attribute6 := dynamodb.NewStringAttribute("testingstrbatch", "myotherstr") item2 := []dynamodb.Attribute{*attribute4, *attribute5, *attribute6} attributeDel1 := dynamodb.NewStringAttribute("TestHashKeyDel", "DelKey") attributeDel2 := dynamodb.NewNumericAttribute("TestRangeKeyDel", "7777777") itemDel := []dynamodb.Attribute{*attributeDel1, *attributeDel2} attributeTest1 := dynamodb.NewStringAttribute("TestHashKey", "MyKey") attributeTest2 := dynamodb.NewNumericAttribute("TestRangeKey", "0193820384293") itemTest := []dynamodb.Attribute{*attributeTest1, *attributeTest2} tableItems := map[*dynamodb.Table]map[string][][]dynamodb.Attribute{} actionItems := make(map[string][][]dynamodb.Attribute) actionItems["Put"] = [][]dynamodb.Attribute{item1, item2} actionItems["Delete"] = [][]dynamodb.Attribute{itemDel} tableItems[table] = actionItems actionItems2 := make(map[string][][]dynamodb.Attribute) actionItems2["Put"] = [][]dynamodb.Attribute{itemTest} tableItems[table2] = actionItems2 q.AddWriteRequestItems(tableItems) queryJson, err := simplejson.NewJson([]byte(q.String())) if err != nil { c.Fatal(err) } expectedJson, err := simplejson.NewJson([]byte(` { "RequestItems": { "TestTable": [ { "PutRequest": { "Item": { "TestRangeKey": { "N": "0193820384293" }, "TestHashKey": { "S": "MyKey" } } } } ], "FooData": [ { "PutRequest": { "Item": { "testingstrbatch": { "S": "mystr" }, "testingbatch": { "N": "2111" }, "testing": { "N": "4" } } } }, { "PutRequest": { "Item": { "testingstrbatch": { "S": "myotherstr" }, "testingbatch": { "N": "93748249272" }, "testing": { "N": "444" } } } }, { "DeleteRequest": { "Key": { "TestRangeKeyDel": { "N": "7777777" }, "TestHashKeyDel": { "S": "DelKey" } } } } ] } } `)) if err != nil { c.Fatal(err) } c.Check(queryJson, gocheck.DeepEquals, expectedJson) }
func (s *ItemSuite) TestConditionalPutUpdateDeleteItem(c *C) { if s.WithRange { // No rangekey test required return } attrs := []dynamodb.Attribute{ *dynamodb.NewStringAttribute("Attr1", "Attr1Val"), } pk := &dynamodb.Key{HashKey: "NewHashKeyVal"} // Put if ok, err := s.table.PutItem("NewHashKeyVal", "", attrs); !ok { c.Fatal(err) } { // Put with condition failed expected := []dynamodb.Attribute{ *dynamodb.NewStringAttribute("Attr1", "expectedAttr1Val").SetExists(true), *dynamodb.NewStringAttribute("AttrNotExists", "").SetExists(false), } if ok, err := s.table.ConditionalPutItem("NewHashKeyVal", "", attrs, expected); ok { c.Errorf("Expect condition does not meet.") } else { c.Check(err.Error(), Matches, "ConditionalCheckFailedException.*") } // Add attributes with condition failed if ok, err := s.table.ConditionalAddAttributes(pk, attrs, expected); ok { c.Errorf("Expect condition does not meet.") } else { c.Check(err.Error(), Matches, "ConditionalCheckFailedException.*") } // Update attributes with condition failed if ok, err := s.table.ConditionalUpdateAttributes(pk, attrs, expected); ok { c.Errorf("Expect condition does not meet.") } else { c.Check(err.Error(), Matches, "ConditionalCheckFailedException.*") } // Delete attributes with condition failed if ok, err := s.table.ConditionalDeleteAttributes(pk, attrs, expected); ok { c.Errorf("Expect condition does not meet.") } else { c.Check(err.Error(), Matches, "ConditionalCheckFailedException.*") } } { expected := []dynamodb.Attribute{ *dynamodb.NewStringAttribute("Attr1", "Attr1Val").SetExists(true), } // Add attributes with condition met addNewAttrs := []dynamodb.Attribute{ *dynamodb.NewNumericAttribute("AddNewAttr1", "10"), *dynamodb.NewNumericAttribute("AddNewAttr2", "20"), } if ok, err := s.table.ConditionalAddAttributes(pk, addNewAttrs, nil); !ok { c.Errorf("Expect condition met. %s", err) } // Update attributes with condition met updateAttrs := []dynamodb.Attribute{ *dynamodb.NewNumericAttribute("AddNewAttr1", "100"), } if ok, err := s.table.ConditionalUpdateAttributes(pk, updateAttrs, expected); !ok { c.Errorf("Expect condition met. %s", err) } // Delete attributes with condition met deleteAttrs := []dynamodb.Attribute{ *dynamodb.NewNumericAttribute("AddNewAttr2", ""), } if ok, err := s.table.ConditionalDeleteAttributes(pk, deleteAttrs, expected); !ok { c.Errorf("Expect condition met. %s", err) } // Get to verify operations that condition are met item, err := s.table.GetItem(pk) if err != nil { c.Fatal(err) } if val, ok := item["AddNewAttr1"]; ok { c.Check(val, DeepEquals, dynamodb.NewNumericAttribute("AddNewAttr1", "100")) } else { c.Error("Expect AddNewAttr1 attribute to be added and updated") } if _, ok := item["AddNewAttr2"]; ok { c.Error("Expect AddNewAttr2 attribute to be deleted") } } { // Put with condition met expected := []dynamodb.Attribute{ *dynamodb.NewStringAttribute("Attr1", "Attr1Val").SetExists(true), } newattrs := []dynamodb.Attribute{ *dynamodb.NewStringAttribute("Attr1", "Attr2Val"), } if ok, err := s.table.ConditionalPutItem("NewHashKeyVal", "", newattrs, expected); !ok { c.Errorf("Expect condition met. %s", err) } // Get to verify Put operation that condition are met item, err := s.table.GetItem(pk) if err != nil { c.Fatal(err) } if val, ok := item["Attr1"]; ok { c.Check(val, DeepEquals, dynamodb.NewStringAttribute("Attr1", "Attr2Val")) } else { c.Error("Expect Attr1 attribute to be updated") } } { // Delete with condition failed expected := []dynamodb.Attribute{ *dynamodb.NewStringAttribute("Attr1", "expectedAttr1Val").SetExists(true), } if ok, err := s.table.ConditionalDeleteItem(pk, expected); ok { c.Errorf("Expect condition does not meet.") } else { c.Check(err.Error(), Matches, "ConditionalCheckFailedException.*") } } { // Delete with condition met expected := []dynamodb.Attribute{ *dynamodb.NewStringAttribute("Attr1", "Attr2Val").SetExists(true), } if ok, _ := s.table.ConditionalDeleteItem(pk, expected); !ok { c.Errorf("Expect condition met.") } // Get to verify Delete operation _, err := s.table.GetItem(pk) c.Check(err.Error(), Matches, "Item not found") } }
func checkStream(table *dynamodb.Table, c *C) { // list the table's streams streams, err := table.ListStreams("") if err != nil { c.Fatal(err) } c.Check(len(streams), Not(Equals), 0) c.Check(streams[0].TableName, Equals, table.Name) // stick a couple of items in the table attrs := []dynamodb.Attribute{ *dynamodb.NewStringAttribute("TestAttr", "0"), } if ok, err := table.PutItem("0", "0", attrs); !ok { c.Fatal(err) } attrs = []dynamodb.Attribute{ *dynamodb.NewStringAttribute("TestAttr", "1"), } if ok, err := table.PutItem("1", "1", attrs); !ok { c.Fatal(err) } // create a stream object stream := table.Server.NewStream(streams[0].StreamArn) // describe the steam desc, err := stream.DescribeStream("") if err != nil { c.Fatal(err) } tableDesc, err := table.DescribeTable() if err != nil { c.Fatal(err) } c.Check(desc.KeySchema[0], Equals, tableDesc.KeySchema[0]) c.Check(desc.StreamArn, Equals, streams[0].StreamArn) c.Check(desc.StreamStatus, Equals, "ENABLED") c.Check(desc.StreamViewType, Equals, tableDesc.StreamSpecification.StreamViewType) c.Check(desc.TableName, Equals, table.Name) c.Check(len(desc.Shards), Equals, 1) // get a shard iterator shardIt, err := stream.GetShardIterator(desc.Shards[0].ShardId, "TRIM_HORIZON", "") if err != nil { c.Fatal(err) } c.Check(len(shardIt), Not(Equals), 0) // poll for records nextIt, records, err := stream.GetRecords(shardIt) if err != nil { c.Fatal(err) } c.Check(len(nextIt), Not(Equals), 0) c.Check(len(records), Equals, 2) for index, record := range records { c.Check(record.EventSource, Equals, "aws:dynamodb") c.Check(record.EventName, Equals, "INSERT") c.Check(len(record.EventID), Not(Equals), 0) // look at the actual record streamRec := record.StreamRecord c.Check(streamRec.StreamViewType, Equals, desc.StreamViewType) c.Check(len(streamRec.SequenceNumber), Not(Equals), 0) if streamRec.SizeBytes <= 0 { c.Errorf("Expected greater-than-zero size, got: %d", streamRec.SizeBytes) } // check the keys if streamRec.StreamViewType == "KEYS_ONLY" { checkKeys(streamRec.Keys, index, c) } // check the image if streamRec.StreamViewType == "NEW_IMAGE" { checkNewImage(streamRec.NewImage, index, c) } } }