Beispiel #1
0
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)
}
Beispiel #3
0
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)
	}
}
Beispiel #5
0
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)
}
Beispiel #9
0
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)
	}
}
Beispiel #10
0
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
}
Beispiel #11
0
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)
}
Beispiel #12
0
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")
	}
}
Beispiel #13
0
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)
		}
	}
}