Categorygithub.com/lingio/go-common
modulepackage
1.36.0
Repository: https://github.com/lingio/go-common.git
Documentation: pkg.go.dev

# README

go-common

spanner

setup local spanner

  • requires gcloud (install)
    • snap is not supported, uninstall and use link above!
  • requires gcloud configuration emulator
  • requires spanner emulator component

Setting up emulator config:

# Setup gcloud configuration
gcloud config configurations create --activate emulator
gcloud config set auth/disable_credentials true
gcloud config set project lingio-test
gcloud config set api_endpoint_overrides/spanner http://localhost:9020/

Installing the local spanner emulator:

gcloud components update
# Install as needed when prompted.
# If gcloud is installed via google-cloud-cli, ensure apt install command starts with google-cloud-cli instead of google-cloud-sdk
gcloud emulators spanner start

Finally, copy staging database to local emulator.

cd ~/my-service/
bash ~/go-common/script/setup-spanner-emulator.sh gcp-project-id spanner-instance-id database-name

There are certain limitations.

spanner-tools

Some useful commands that wrench and spanner-cli does not cover.

Especially, copying data from staging to local emulator is much faster than with spanner-cli.

This program is installed by setup-spanner-emulator.sh

go install github.com/lingio/go-common/script/spanner-tools@latest
spanner-tools -h

storagegen

go install github.com/lingio/go-common/storagegen@latest
storagegen path/to/service/storage/spec.json

spec.json:

{
  "serviceName": "person-service",
  "buckets": [
    {
      "typeName": "People",       // final type name: {typeName}Store
      "dbTypeName": "DbPerson",   // stored and returned type: models.{dbTypeName}
      "bucketName": "people",     // object store bucket name
      "version": "v1",            // change this if the stored data structure is changed
      "getAll": false,            // enable to generate code for listing all objects
      "filenameFormat": "%s.json" // fmt.Sprintf format, must have exactly one %s (ID)
      "secondaryIndexes": [       // generate additional Get methods
        // GetByPhone, builds index on models.{dbTypeName}.Phone
        { "key": "Phone", "type": "unique" },
        // GetByEmail, builds index on *models.{dbTypeName}.Email if it not nil
        { "keys": [{ "key": "Email", "optional": true }], "type": "unique" },
        // GetByPartnerAndEmail, builds a compound index on models.{dbTypeName}.Partner and *models.{dbTypeName}.Email if it not nil
        { "keys": [{ "key": "Partner" }, { "key": "Email", "optional": true }], "type": "unique", "name": "PartnerAndEmail" },
        // GetAllByPartnerAndStudentGroup
        {
          "keys": [
            { "key": "Partner" },
            { "key": "Student", "optional": true, "exclFromIndex": true },
            { "key": "Student.GroupID", "param": "groupID" }
          ],
          "type": "set",
          "name": "PartnerAndStudentGroup"
        },
        // GetAllByPartner, builds index on models.{dbTypeName}.Partner
        { "key": "Partner", "type": "set"}
      ],
      // directstore.tmpl: encrypted object store
      // cachedstore.tmpl: cache + encrypted object store
      // blobstore.tmpl: directstore for []byte data
      "template": "cachedstore.tmpl",
      "config": {
        // Defaults to "application/json". Will be applied on object Put.
        "contentType": "application/json",
        // Defaults to "". Will be applied on object Put.
        "contentDisposition": ""
      }
    }
  ]
}

scripts

  • script/objcopy: read/write objects from/to bucket from one s3 endpoint

    MINIO_SECRET=xyz go run ./script/objcopy --from=path/to/{stage,local,local-stage}.json --bucket=xyz

  • script/encrypt: encrypt or decrypt plaintext objects on stdin

    ENCRYPTION_KEY=256bitkey go run ./script/encrypt

  • script/fromfile: read filenames from stdin and write object to stdout

    find ./dir -not -type d | go run ./script/fromfile

  • script/tofile: read objects from stdin and write files

    ... go run ./script/objcopy | go run ./script/tofile -root=./dir

  • script/objify: like fromfile but reads raw json objects

    cat data.jsonl | go run ./script/objify

Write plaintext objects to disk from an encrypted object storage
# assuming encrypted bucket
$ MINIO_SECRET=minioadmin go run ./script/objcopy --from=../service/config/local-stage.json --bucket=people | \
ENCRYPTION_KEY=256bit-key go run ./script/encrypt --decrypt | \
go run ./script/tofile --root=./files --rename="people-data-{KEY}{EXT}"
Write encrypted objects to an encrypted object storage from disk
# assuming encrypted bucket
$ find ../files -maxdepth 1 -not -type d | gp run ./script/fromfile | \
ENCRYPTION_KEY=256bit-key go run ./script/encrypt | \
MINIO_SECRET=minioadmin go run ./script/objcopy --to=../service/config/local-stage.json --bucket=people

# Packages

No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author

# Functions

No description provided by the author
AuthTokenFrom extracts the embedded JWT.
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
DecodeSpannerStructFields copies all visible fields from source to target by struct field name.
EncodeSpannerStructFields copies all visible fields from source to target by struct field name.
Errorf returns a common lingio error wrapping the provided error.
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
LogAuditEvent outputs the provided app context.
No description provided by the author
NewBucketBrowser exposes a set of storage interfaces over a HTTP API using reflection.
No description provided by the author
No description provided by the author
NewEncryptedStore initializes a lingio store with secure v2 crypto.
No description provided by the author
No description provided by the author
NewInsecureEncryptedStore initializes a lingio store with insecure v1 crypto.
NewObjectStore attempts to initialize a new bucket if it does not already exist.
NewRedisCache returns an initialized redis cache using name and version.
No description provided by the author
ProjectDecoded projects struct of type I to struct of type T using [DecodeSpannerStructFields].
ProjectIdentity is a dummy projection.
No description provided by the author
RegisterRedisOnConnectHook registers a func to be called whenever the redis client establishes a new connection to the redis server.
RequestIDFromContext extracts an embedded request id.
No description provided by the author
RespondError is deprecated.
No description provided by the author
No description provided by the author
SetMemoryLimitFromCgroup autodetects current cgroup memory.max and provides the go runtime with a soft memory limit (GOMEMLIMIT) computed as f times the cgroup value.
No description provided by the author
SetupRedisClient will attempt to 1) create a failover redis client by looking up sentinel addrs using the provided service DNS, or 2) attempt to create a simple redis client using the provided simpleAddr.
Shuffle calls swap len-1 times to swap index i with j.
No description provided by the author
SpannerQueryTyped returns all rows from query, deserialized to struct T.
SpannerQueryTypedAndDecode returns all rows from query, deserialized to struct I and then decoded into struct T using [DecodeSpannerStructField].
SpannerReadProjected returns projection `T -> P` of all rows in iterator.
SpannerReadTyped returns all rows in keySet from primary index, deserialized to struct T.
SpannerReadTypedAndDecode returns all rows in keySet from the primary index, deserialized to struct I and then decoded into struct T using [DecodeSpannerStructFields].
SpannerReadTypedAndDecodeUsingIndex is identical to [SpannerReadTypedAndDecode] but uses the provided index.
SpannerReadTypedAndDecodeWithOptions returns all rows in keySet from the primary index, deserialized to struct I and then decoded into struct T using [DecodeSpannerStructFields].
SpannerReadTypedUsingIndex is identical to [SpannerReadTyped] but uses the provided index.
SpannerReadTypedWithOptions returns all rows in keySet from primary index, deserialized to struct T.
SpannerStructFieldNames returns a list with names of all struct fields.
StatusProbeServer starts a http server on 0.0.0.0:port with the specified probes.
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
UserIDFrom extracts an embedded userID from WithUserID.
WithAction returns a copy of the passed context with the specified action.
WithBucket returns a copy of the passed context with the specified bucket name.
WithObject returns a copy of the passed context with the object ID.
No description provided by the author

# Constants

No description provided by the author
No description provided by the author

# Variables

No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
ErrBucketDoesNotExist is a proxy for detecting this particular error case in calling code.
No description provided by the author
No description provided by the author

# Structs

BucketBrowser s.
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
EncryptedStore.
No description provided by the author
Error describes a traced HTTP error message with contextual details.
No description provided by the author
No description provided by the author
No description provided by the author
MinioConfig describes the required fields to setup a s3 minio client.
No description provided by the author
ObjectInfo.
No description provided by the author
ObjectStore implements the Lingio CRUD database interface on top of minio's object storage engine.
No description provided by the author
RedisCache is a named and versioned cache for a specific collections.
RedisConfig describes connectivity options for setting up a redis client using the included SetupRedisClient func in this pkg.
RedisSetupErr wraps an underlying error that occured during cache setup.
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author

# Interfaces

No description provided by the author
LingioStore is a simple file-based CRUD database interface.
StatusProbe describes a simple interface for querying service status.

# Type aliases

AtomicBool.
Backoff returns the time to wait for request retry attempt.
No description provided by the author
No description provided by the author
No description provided by the author
ShouldRetry returns whether a request can be retried: err = request error attempt = 0-based retry counter.