package redisactivity import ( "crypto/sha256" "encoding/hex" "strconv" ) const redisKeyPrefix = "pp:{activity}:" type keyspace struct { prefix string records string unique string idkeys string expiry string available string owners string ownerExpiry string epoch string inventory string stateInventory string } func newKeyspace(namespace string) keyspace { prefix := redisKeyPrefix + namespace return keyspace{ prefix: prefix, records: prefix + ":records", unique: prefix + ":unique", idkeys: prefix + ":idkeys", expiry: prefix + ":expiry", available: prefix + ":available", owners: prefix + ":owners", ownerExpiry: prefix + ":owner-expiry", epoch: prefix + ":epoch", inventory: prefix + ":inventory", stateInventory: prefix + ":state-inventory", } } func stateInventoryField(upstreamID, state string) string { return strconv.Itoa(len(upstreamID)) + ":" + upstreamID + ":" + state } func (keys keyspace) idempotency(clientID, idempotencyKey string) string { return keys.prefix + ":idem:" + digestParts(clientID, idempotencyKey) } func (keys keyspace) operation(operationID string) string { return keys.prefix + ":op:" + digestToken(operationID) } func (keys keyspace) protocol(value string) string { return keys.facet("protocol", value) } func (keys keyspace) region(value string) string { return keys.facet("region", value) } func (keys keyspace) carrier(value string) string { return keys.facet("carrier", value) } func (keys keyspace) upstream(value string) string { return keys.facet("upstream", value) } func (keys keyspace) facet(name, value string) string { return keys.prefix + ":" + name + ":" + digestToken(value) } func digestToken(value string) string { return digestParts(value) } func digestParts(values ...string) string { digest := sha256.New() for _, value := range values { _, _ = digest.Write([]byte(strconv.Itoa(len(value)))) _, _ = digest.Write([]byte{':'}) _, _ = digest.Write([]byte(value)) } return hex.EncodeToString(digest.Sum(nil)) }