diff --git a/.gitignore b/.gitignore index 6b41e0a8..bb1d3703 100644 --- a/.gitignore +++ b/.gitignore @@ -12,10 +12,7 @@ # Output of the go coverage tool, specifically when used with LiteIDE *.out -# Project-local glide cache, RE: https://github.com/Masterminds/glide/issues/736 -.glide/ -glide.lock -/vendor +vendor/ .idea/ diff --git a/Gopkg.lock b/Gopkg.lock deleted file mode 100644 index 44b59af4..00000000 --- a/Gopkg.lock +++ /dev/null @@ -1,70 +0,0 @@ -# This file is autogenerated, do not edit; changes may be undone by the next 'dep ensure'. - - -[[projects]] - digest = "1:ffe9824d294da03b391f44e1ae8281281b4afc1bdaa9588c9097785e3af10cec" - name = "github.com/davecgh/go-spew" - packages = ["spew"] - pruneopts = "UT" - revision = "8991bc29aa16c548c550c7ff78260e27b9ab7c73" - version = "v1.1.1" - -[[projects]] - digest = "1:0028cb19b2e4c3112225cd871870f2d9cf49b9b4276531f03438a88e94be86fe" - name = "github.com/pmezard/go-difflib" - packages = ["difflib"] - pruneopts = "UT" - revision = "792786c7400a136282c1664665ae0a8db921c6c2" - version = "v1.0.0" - -[[projects]] - digest = "1:274f67cb6fed9588ea2521ecdac05a6d62a8c51c074c1fccc6a49a40ba80e925" - name = "github.com/satori/go.uuid" - packages = ["."] - pruneopts = "UT" - revision = "f58768cc1a7a7e77a3bd49e98cdd21419399b6a3" - version = "v1.2.0" - -[[projects]] - digest = "1:0496f0e99014b7fd0a560c539f51d0882731137b85494142f47e550e4657176a" - name = "github.com/stretchr/testify" - packages = [ - "assert", - "require", - "suite", - ] - pruneopts = "UT" - revision = "221dbe5ed46703ee255b1da0dec05086f5035f62" - version = "v1.4.0" - -[[projects]] - branch = "master" - digest = "1:9d5b5d543996dd584da1db1e0de1926f3e4c3a8dba0fa2f8db70f3ebee2342e0" - name = "golang.org/x/crypto" - packages = [ - "bcrypt", - "blowfish", - ] - pruneopts = "UT" - revision = "bd318be0434a57050ed475e0f45c3dbb16c09c2e" - -[[projects]] - digest = "1:59f10c1537d2199d9115d946927fe31165959a95190849c82ff11e05803528b0" - name = "gopkg.in/yaml.v2" - packages = ["."] - pruneopts = "UT" - revision = "f221b8435cfb71e54062f6c6e99e9ade30b124d5" - version = "v2.2.4" - -[solve-meta] - analyzer-name = "dep" - analyzer-version = 1 - input-imports = [ - "github.com/satori/go.uuid", - "github.com/stretchr/testify/assert", - "github.com/stretchr/testify/require", - "github.com/stretchr/testify/suite", - "golang.org/x/crypto/bcrypt", - ] - solver-name = "gps-cdcl" - solver-version = 1 diff --git a/Gopkg.toml b/Gopkg.toml deleted file mode 100644 index 2aef29f3..00000000 --- a/Gopkg.toml +++ /dev/null @@ -1,38 +0,0 @@ -# Gopkg.toml example -# -# Refer to https://golang.github.io/dep/docs/Gopkg.toml.html -# for detailed Gopkg.toml documentation. -# -# required = ["github.com/user/thing/cmd/thing"] -# ignored = ["github.com/user/project/pkgX", "bitbucket.org/user/project/pkgA/pkgY"] -# -# [[constraint]] -# name = "github.com/user/project" -# version = "1.0.0" -# -# [[constraint]] -# name = "github.com/user/project2" -# branch = "dev" -# source = "github.com/myfork/project2" -# -# [[override]] -# name = "github.com/x/y" -# version = "2.4.0" -# -# [prune] -# non-go = false -# go-tests = true -# unused-packages = true - - -[prune] - go-tests = true - unused-packages = true - -[[constraint]] - name = "github.com/stretchr/testify" - version = "1.4.0" - -[[constraint]] - name = "github.com/satori/go.uuid" - version = "1.2.0" diff --git a/README.md b/README.md index 49c55ce7..bb4c8dec 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ > GoSCIM aims to be a fully featured implementation of [SCIM v2](http://www.simplecloud.info/) specifiction. It provides basic building blocks to SCIM functions and a functional out-of-box server. It is also designed with extensibility in mind to make customizations easy. -**Caution** This is the early stage of `v2.0.0` version of go-scim. We are now at `v2.0.0-m2` ([release notes](https://github.com/imulab/go-scim/releases/tag/v2.0.0-m2)). This second major release will introduce drastic changes to the way resources are handled in the system. +**Caution** This is the early stage of `v2.0.0` version of go-scim. We are now at `v2.0.0-m3` ([release notes](https://github.com/imulab/go-scim/releases/tag/v2.0.0-m3)). This second major release will introduce drastic changes to the way resources are handled in the system. For the currently stable version, checkout tag `v1.0.1`, or go to [here](https://github.com/imulab/go-scim/tree/v1.0.1). @@ -18,15 +18,20 @@ For the currently stable version, checkout tag `v1.0.1`, or go to [here](https:/ ## Installation and Usage -The project is in the early stage of `v2.0.0`. The current milestone does not have the ready-to-go server implementation yet. This will come in later milestones. - -As for now, to check out the functionalities included in the tests: +The project is in the early stage of `v2.0.0`. As for now, to check out the functionalities included in the tests: ``` -$ dep ensure -$ go test ./pkg/... +# cd into one of core, protocol, server +$ go test ./... ``` +## Migration to Go modules + +Since `v2.0.0-m3`, the project has migrated from [dep](https://golang.github.io/dep/) to [go modules](https://github.com/golang/go/wiki/Modules). This allows users to import the exact project modules separately as needed, and also allows their functions to evolve independently. + +The project will continue to use a single tag until the official release of `v2.0.0`. On the official release, all modules will be tagged separately as +`v2.0.0` (for instance, `core/v2.0.0`, and `server/v2.0.0`). After that, modules will evolve independently. + ## Documentation Index (TBD) - [Project orientation](#) @@ -42,8 +47,7 @@ $ go test ./pkg/... While the fundamentals of the functions are delivered in `v2.0.0-m1`, we are still hard at work to deliver the rest. In the coming weeks and months, the rest of functions towrads `v2.0.0` will be released. In addition to the scheduled functions, tests and documentations will also be added. -- `v2.0.0-m3` to introduce group membership synchronization and a working server. -- `v2.0.0-m4` to (re-)introduce mongo db persistence +- `v2.0.0-m4` to (re-)introduce mongo db persistence, and integration test on the server - `v2.0.0-m5` to tackle resource root query and bulk operations. - `v2.0.0-rc1` to complete tests and documentations diff --git a/pkg/core/annotations/internal.go b/core/annotations/annotations.go similarity index 100% rename from pkg/core/annotations/internal.go rename to core/annotations/annotations.go diff --git a/pkg/core/errors/error.go b/core/errors/error.go similarity index 100% rename from pkg/core/errors/error.go rename to core/errors/error.go diff --git a/pkg/core/errors/factory.go b/core/errors/factory.go similarity index 100% rename from pkg/core/errors/factory.go rename to core/errors/factory.go diff --git a/pkg/core/expr/constants.go b/core/expr/constants.go similarity index 100% rename from pkg/core/expr/constants.go rename to core/expr/constants.go diff --git a/pkg/core/expr/expression.go b/core/expr/expression.go similarity index 100% rename from pkg/core/expr/expression.go rename to core/expr/expression.go diff --git a/pkg/core/expr/filter.go b/core/expr/filter.go similarity index 99% rename from pkg/core/expr/filter.go rename to core/expr/filter.go index c7dc97bc..85477b46 100644 --- a/pkg/core/expr/filter.go +++ b/core/expr/filter.go @@ -2,7 +2,7 @@ package expr import ( "fmt" - "github.com/imulab/go-scim/pkg/core/errors" + "github.com/imulab/go-scim/core/errors" "strings" ) diff --git a/pkg/core/expr/filter_test.go b/core/expr/filter_test.go similarity index 100% rename from pkg/core/expr/filter_test.go rename to core/expr/filter_test.go diff --git a/pkg/core/expr/path.go b/core/expr/path.go similarity index 99% rename from pkg/core/expr/path.go rename to core/expr/path.go index 3a67eb4b..50206a9b 100644 --- a/pkg/core/expr/path.go +++ b/core/expr/path.go @@ -2,7 +2,7 @@ package expr import ( "fmt" - "github.com/imulab/go-scim/pkg/core/errors" + "github.com/imulab/go-scim/core/errors" "strconv" "strings" ) diff --git a/pkg/core/expr/path_test.go b/core/expr/path_test.go similarity index 100% rename from pkg/core/expr/path_test.go rename to core/expr/path_test.go diff --git a/pkg/core/expr/urn.go b/core/expr/urn.go similarity index 97% rename from pkg/core/expr/urn.go rename to core/expr/urn.go index 44f413ae..de015102 100644 --- a/pkg/core/expr/urn.go +++ b/core/expr/urn.go @@ -1,7 +1,7 @@ package expr import ( - "github.com/imulab/go-scim/pkg/core/spec" + "github.com/imulab/go-scim/core/spec" ) var urnsCache = &urns{} diff --git a/core/go.mod b/core/go.mod new file mode 100644 index 00000000..32a93ace --- /dev/null +++ b/core/go.mod @@ -0,0 +1,3 @@ +module github.com/imulab/go-scim/core + +require github.com/stretchr/testify v1.4.0 diff --git a/core/go.sum b/core/go.sum new file mode 100644 index 00000000..f95b92ad --- /dev/null +++ b/core/go.sum @@ -0,0 +1,12 @@ +github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/imulab/go-scim v1.0.1 h1:nWUJF3q0MQWwtGvSHdoylNfAuUeWBMuVL5pSMJ9EG1k= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk= +github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= diff --git a/pkg/tests/create_handler_test_suite/user_resource_type.json b/core/internal/json_deserialize_test_suite/user_resource_type.json similarity index 100% rename from pkg/tests/create_handler_test_suite/user_resource_type.json rename to core/internal/json_deserialize_test_suite/user_resource_type.json diff --git a/pkg/tests/create_handler_test_suite/user_schema.json b/core/internal/json_deserialize_test_suite/user_schema.json similarity index 100% rename from pkg/tests/create_handler_test_suite/user_schema.json rename to core/internal/json_deserialize_test_suite/user_schema.json diff --git a/pkg/tests/create_service_test_suite/user_resource_type.json b/core/internal/json_serialize_test_suite/user_resource_type.json similarity index 100% rename from pkg/tests/create_service_test_suite/user_resource_type.json rename to core/internal/json_serialize_test_suite/user_resource_type.json diff --git a/pkg/tests/create_service_test_suite/user_schema.json b/core/internal/json_serialize_test_suite/user_schema.json similarity index 100% rename from pkg/tests/create_service_test_suite/user_schema.json rename to core/internal/json_serialize_test_suite/user_schema.json diff --git a/pkg/tests/default_lock_test_suite/user_resource_type.json b/core/internal/resource_test_suite/user_resource_type.json similarity index 100% rename from pkg/tests/default_lock_test_suite/user_resource_type.json rename to core/internal/resource_test_suite/user_resource_type.json diff --git a/pkg/tests/from_for_property_test_suite/user_schema.json b/core/internal/resource_test_suite/user_schema.json similarity index 100% rename from pkg/tests/from_for_property_test_suite/user_schema.json rename to core/internal/resource_test_suite/user_schema.json diff --git a/pkg/tests/subscriber_test_suite/user_enterprise_extension_schema.json b/core/internal/subscriber_test_suite/user_enterprise_extension_schema.json similarity index 100% rename from pkg/tests/subscriber_test_suite/user_enterprise_extension_schema.json rename to core/internal/subscriber_test_suite/user_enterprise_extension_schema.json diff --git a/pkg/tests/subscriber_test_suite/user_resource_type.json b/core/internal/subscriber_test_suite/user_resource_type.json similarity index 100% rename from pkg/tests/subscriber_test_suite/user_resource_type.json rename to core/internal/subscriber_test_suite/user_resource_type.json diff --git a/pkg/tests/crud_test_suite/user_schema.json b/core/internal/subscriber_test_suite/user_schema.json similarity index 100% rename from pkg/tests/crud_test_suite/user_schema.json rename to core/internal/subscriber_test_suite/user_schema.json diff --git a/pkg/core/json/adapt.go b/core/json/adapt.go similarity index 84% rename from pkg/core/json/adapt.go rename to core/json/adapt.go index 30d1780f..8a7b17cb 100644 --- a/pkg/core/json/adapt.go +++ b/core/json/adapt.go @@ -1,6 +1,6 @@ package json -import "github.com/imulab/go-scim/pkg/core/prop" +import "github.com/imulab/go-scim/core/prop" type ResourceMarshalAdapter struct { Resource *prop.Resource diff --git a/pkg/core/json/deserialize.go b/core/json/deserialize.go similarity index 99% rename from pkg/core/json/deserialize.go rename to core/json/deserialize.go index 063e9b6f..90703d61 100644 --- a/pkg/core/json/deserialize.go +++ b/core/json/deserialize.go @@ -1,9 +1,9 @@ package json import ( - "github.com/imulab/go-scim/pkg/core/errors" - "github.com/imulab/go-scim/pkg/core/prop" - "github.com/imulab/go-scim/pkg/core/spec" + "github.com/imulab/go-scim/core/errors" + "github.com/imulab/go-scim/core/prop" + "github.com/imulab/go-scim/core/spec" "strconv" ) diff --git a/pkg/core/json/deserialize_test.go b/core/json/deserialize_test.go similarity index 99% rename from pkg/core/json/deserialize_test.go rename to core/json/deserialize_test.go index 9a485fc1..cfef7ddd 100644 --- a/pkg/core/json/deserialize_test.go +++ b/core/json/deserialize_test.go @@ -2,8 +2,8 @@ package json import ( "encoding/json" - "github.com/imulab/go-scim/pkg/core/prop" - "github.com/imulab/go-scim/pkg/core/spec" + "github.com/imulab/go-scim/core/prop" + "github.com/imulab/go-scim/core/spec" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/suite" "io/ioutil" @@ -14,7 +14,7 @@ import ( func TestDeserialize(t *testing.T) { s := new(JSONDeserializeTestSuite) - s.resourceBase = "../../tests/json_deserialize_test_suite" + s.resourceBase = "../internal/json_deserialize_test_suite" suite.Run(t, s) } diff --git a/pkg/core/json/options.go b/core/json/options.go similarity index 100% rename from pkg/core/json/options.go rename to core/json/options.go diff --git a/pkg/core/json/safe.go b/core/json/safe.go similarity index 100% rename from pkg/core/json/safe.go rename to core/json/safe.go diff --git a/pkg/core/json/scanner.go b/core/json/scanner.go similarity index 99% rename from pkg/core/json/scanner.go rename to core/json/scanner.go index cf444965..8b958581 100644 --- a/pkg/core/json/scanner.go +++ b/core/json/scanner.go @@ -5,7 +5,7 @@ package json import ( "fmt" - "github.com/imulab/go-scim/pkg/core/errors" + "github.com/imulab/go-scim/core/errors" "strconv" ) diff --git a/pkg/core/json/serialize.go b/core/json/serialize.go similarity index 98% rename from pkg/core/json/serialize.go rename to core/json/serialize.go index ca7879d6..8425c337 100644 --- a/pkg/core/json/serialize.go +++ b/core/json/serialize.go @@ -2,9 +2,9 @@ package json import ( "bytes" - "github.com/imulab/go-scim/pkg/core/errors" - "github.com/imulab/go-scim/pkg/core/prop" - "github.com/imulab/go-scim/pkg/core/spec" + "github.com/imulab/go-scim/core/errors" + "github.com/imulab/go-scim/core/prop" + "github.com/imulab/go-scim/core/spec" "math" "strconv" "strings" diff --git a/pkg/core/json/serialize_test.go b/core/json/serialize_test.go similarity index 98% rename from pkg/core/json/serialize_test.go rename to core/json/serialize_test.go index 94995d02..40c66090 100644 --- a/pkg/core/json/serialize_test.go +++ b/core/json/serialize_test.go @@ -2,9 +2,9 @@ package json import ( "encoding/json" - "github.com/imulab/go-scim/pkg/core/expr" - "github.com/imulab/go-scim/pkg/core/prop" - "github.com/imulab/go-scim/pkg/core/spec" + "github.com/imulab/go-scim/core/expr" + "github.com/imulab/go-scim/core/prop" + "github.com/imulab/go-scim/core/spec" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "github.com/stretchr/testify/suite" @@ -15,7 +15,7 @@ import ( func TestSerialize(t *testing.T) { s := new(JSONSerializeTestSuite) - s.resourceBase = "../../tests/json_serialize_test_suite" + s.resourceBase = "../internal/json_serialize_test_suite" suite.Run(t, s) } diff --git a/pkg/core/prop/binary.go b/core/prop/binary.go similarity index 98% rename from pkg/core/prop/binary.go rename to core/prop/binary.go index 17f8979c..9f14627b 100644 --- a/pkg/core/prop/binary.go +++ b/core/prop/binary.go @@ -3,8 +3,8 @@ package prop import ( "encoding/base64" "fmt" - "github.com/imulab/go-scim/pkg/core/errors" - "github.com/imulab/go-scim/pkg/core/spec" + "github.com/imulab/go-scim/core/errors" + "github.com/imulab/go-scim/core/spec" "hash/fnv" ) diff --git a/pkg/core/prop/boolean.go b/core/prop/boolean.go similarity index 97% rename from pkg/core/prop/boolean.go rename to core/prop/boolean.go index a931f062..5171050a 100644 --- a/pkg/core/prop/boolean.go +++ b/core/prop/boolean.go @@ -2,8 +2,8 @@ package prop import ( "fmt" - "github.com/imulab/go-scim/pkg/core/errors" - "github.com/imulab/go-scim/pkg/core/spec" + "github.com/imulab/go-scim/core/errors" + "github.com/imulab/go-scim/core/spec" ) type booleanProperty struct { diff --git a/pkg/core/prop/complex.go b/core/prop/complex.go similarity index 98% rename from pkg/core/prop/complex.go rename to core/prop/complex.go index 2695cf5b..8bfeba18 100644 --- a/pkg/core/prop/complex.go +++ b/core/prop/complex.go @@ -2,8 +2,8 @@ package prop import ( "encoding/binary" - "github.com/imulab/go-scim/pkg/core/errors" - "github.com/imulab/go-scim/pkg/core/spec" + "github.com/imulab/go-scim/core/errors" + "github.com/imulab/go-scim/core/spec" "hash/fnv" "strings" ) diff --git a/pkg/core/prop/container.go b/core/prop/container.go similarity index 100% rename from pkg/core/prop/container.go rename to core/prop/container.go diff --git a/pkg/core/prop/datetime.go b/core/prop/datetime.go similarity index 98% rename from pkg/core/prop/datetime.go rename to core/prop/datetime.go index fe419f95..3cbd9e6b 100644 --- a/pkg/core/prop/datetime.go +++ b/core/prop/datetime.go @@ -2,8 +2,8 @@ package prop import ( "fmt" - "github.com/imulab/go-scim/pkg/core/errors" - "github.com/imulab/go-scim/pkg/core/spec" + "github.com/imulab/go-scim/core/errors" + "github.com/imulab/go-scim/core/spec" "time" ) diff --git a/pkg/core/prop/decimal.go b/core/prop/decimal.go similarity index 97% rename from pkg/core/prop/decimal.go rename to core/prop/decimal.go index 7bf62661..2ad8b95e 100644 --- a/pkg/core/prop/decimal.go +++ b/core/prop/decimal.go @@ -2,8 +2,8 @@ package prop import ( "fmt" - "github.com/imulab/go-scim/pkg/core/errors" - "github.com/imulab/go-scim/pkg/core/spec" + "github.com/imulab/go-scim/core/errors" + "github.com/imulab/go-scim/core/spec" ) type decimalProperty struct { diff --git a/pkg/core/prop/event.go b/core/prop/event.go similarity index 100% rename from pkg/core/prop/event.go rename to core/prop/event.go diff --git a/pkg/core/prop/factory.go b/core/prop/factory.go similarity index 99% rename from pkg/core/prop/factory.go rename to core/prop/factory.go index 42eeee4b..5ac7d382 100644 --- a/pkg/core/prop/factory.go +++ b/core/prop/factory.go @@ -1,7 +1,7 @@ package prop import ( - "github.com/imulab/go-scim/pkg/core/spec" + "github.com/imulab/go-scim/core/spec" "strings" ) diff --git a/pkg/core/prop/integer.go b/core/prop/integer.go similarity index 98% rename from pkg/core/prop/integer.go rename to core/prop/integer.go index e12383d1..d3e24c82 100644 --- a/pkg/core/prop/integer.go +++ b/core/prop/integer.go @@ -2,8 +2,8 @@ package prop import ( "fmt" - "github.com/imulab/go-scim/pkg/core/errors" - "github.com/imulab/go-scim/pkg/core/spec" + "github.com/imulab/go-scim/core/errors" + "github.com/imulab/go-scim/core/spec" ) type integerProperty struct { diff --git a/pkg/core/prop/integer_test.go b/core/prop/integer_test.go similarity index 99% rename from pkg/core/prop/integer_test.go rename to core/prop/integer_test.go index b66b3e49..e95b996b 100644 --- a/pkg/core/prop/integer_test.go +++ b/core/prop/integer_test.go @@ -2,7 +2,7 @@ package prop import ( "encoding/json" - "github.com/imulab/go-scim/pkg/core/spec" + "github.com/imulab/go-scim/core/spec" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/suite" "testing" diff --git a/pkg/core/prop/multi.go b/core/prop/multi.go similarity index 98% rename from pkg/core/prop/multi.go rename to core/prop/multi.go index 027b2e8d..f475588f 100644 --- a/pkg/core/prop/multi.go +++ b/core/prop/multi.go @@ -2,9 +2,9 @@ package prop import ( "encoding/binary" - "github.com/imulab/go-scim/pkg/core/annotations" - "github.com/imulab/go-scim/pkg/core/errors" - "github.com/imulab/go-scim/pkg/core/spec" + "github.com/imulab/go-scim/core/annotations" + "github.com/imulab/go-scim/core/errors" + "github.com/imulab/go-scim/core/spec" "hash/fnv" ) diff --git a/pkg/core/prop/navigator.go b/core/prop/navigator.go similarity index 99% rename from pkg/core/prop/navigator.go rename to core/prop/navigator.go index 4b212096..9df32cb6 100644 --- a/pkg/core/prop/navigator.go +++ b/core/prop/navigator.go @@ -1,7 +1,7 @@ package prop import ( - "github.com/imulab/go-scim/pkg/core/errors" + "github.com/imulab/go-scim/core/errors" ) // Create a new navigator to traverse the property. diff --git a/pkg/core/prop/property.go b/core/prop/property.go similarity index 99% rename from pkg/core/prop/property.go rename to core/prop/property.go index 8f052566..32830394 100644 --- a/pkg/core/prop/property.go +++ b/core/prop/property.go @@ -1,6 +1,6 @@ package prop -import "github.com/imulab/go-scim/pkg/core/spec" +import "github.com/imulab/go-scim/core/spec" // Property holds a piece of data and is describe by an Attribute. A property can exist by itself, or it can exist // as a sub property of another property, in which case, the containing property is known as a container property. diff --git a/pkg/core/prop/reference.go b/core/prop/reference.go similarity index 97% rename from pkg/core/prop/reference.go rename to core/prop/reference.go index c83c5b34..15dc4aad 100644 --- a/pkg/core/prop/reference.go +++ b/core/prop/reference.go @@ -2,8 +2,8 @@ package prop import ( "fmt" - "github.com/imulab/go-scim/pkg/core/errors" - "github.com/imulab/go-scim/pkg/core/spec" + "github.com/imulab/go-scim/core/errors" + "github.com/imulab/go-scim/core/spec" "hash/fnv" "strings" ) diff --git a/pkg/core/prop/resource.go b/core/prop/resource.go similarity index 98% rename from pkg/core/prop/resource.go rename to core/prop/resource.go index 3cbca757..82cdea74 100644 --- a/pkg/core/prop/resource.go +++ b/core/prop/resource.go @@ -1,7 +1,7 @@ package prop import ( - "github.com/imulab/go-scim/pkg/core/spec" + "github.com/imulab/go-scim/core/spec" ) // Create a new resource of the given resource type. The method panics if something went wrong. diff --git a/pkg/core/prop/resource_test.go b/core/prop/resource_test.go similarity index 98% rename from pkg/core/prop/resource_test.go rename to core/prop/resource_test.go index e49c57c2..48f598eb 100644 --- a/pkg/core/prop/resource_test.go +++ b/core/prop/resource_test.go @@ -2,7 +2,7 @@ package prop import ( "encoding/json" - "github.com/imulab/go-scim/pkg/core/spec" + "github.com/imulab/go-scim/core/spec" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/suite" "io/ioutil" @@ -22,7 +22,7 @@ type ( func TestResource(t *testing.T) { s := new(ResourceTestSuite) - s.resourceBase = "../../tests/resource_test_suite" + s.resourceBase = "../internal/resource_test_suite" suite.Run(t, s) } diff --git a/pkg/core/prop/string.go b/core/prop/string.go similarity index 98% rename from pkg/core/prop/string.go rename to core/prop/string.go index 8abc9ba3..4fe63ded 100644 --- a/pkg/core/prop/string.go +++ b/core/prop/string.go @@ -2,8 +2,8 @@ package prop import ( "fmt" - "github.com/imulab/go-scim/pkg/core/errors" - "github.com/imulab/go-scim/pkg/core/spec" + "github.com/imulab/go-scim/core/errors" + "github.com/imulab/go-scim/core/spec" "hash/fnv" "strings" ) diff --git a/pkg/core/prop/string_test.go b/core/prop/string_test.go similarity index 99% rename from pkg/core/prop/string_test.go rename to core/prop/string_test.go index 01e081ae..cafa1e45 100644 --- a/pkg/core/prop/string_test.go +++ b/core/prop/string_test.go @@ -2,7 +2,7 @@ package prop import ( "encoding/json" - "github.com/imulab/go-scim/pkg/core/spec" + "github.com/imulab/go-scim/core/spec" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/suite" "testing" diff --git a/pkg/core/prop/subscribe.go b/core/prop/subscribe.go similarity index 98% rename from pkg/core/prop/subscribe.go rename to core/prop/subscribe.go index e2ba057f..759713ed 100644 --- a/pkg/core/prop/subscribe.go +++ b/core/prop/subscribe.go @@ -1,8 +1,8 @@ package prop import ( - "github.com/imulab/go-scim/pkg/core/annotations" - "github.com/imulab/go-scim/pkg/core/spec" + "github.com/imulab/go-scim/core/annotations" + "github.com/imulab/go-scim/core/spec" ) // A subscriber to the event. diff --git a/pkg/core/prop/subscribe_test.go b/core/prop/subscribe_test.go similarity index 99% rename from pkg/core/prop/subscribe_test.go rename to core/prop/subscribe_test.go index dd9a19b9..f5af335b 100644 --- a/pkg/core/prop/subscribe_test.go +++ b/core/prop/subscribe_test.go @@ -2,7 +2,7 @@ package prop import ( "encoding/json" - "github.com/imulab/go-scim/pkg/core/spec" + "github.com/imulab/go-scim/core/spec" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "github.com/stretchr/testify/suite" @@ -13,7 +13,7 @@ import ( func TestSubscribers(t *testing.T) { s := new(SubscriberTestSuite) - s.resourceBase = "../../tests/subscriber_test_suite" + s.resourceBase = "../internal/subscriber_test_suite" suite.Run(t, s) } diff --git a/pkg/core/prop/visit.go b/core/prop/visit.go similarity index 100% rename from pkg/core/prop/visit.go rename to core/prop/visit.go diff --git a/pkg/core/spec/attribute.go b/core/spec/attribute.go similarity index 99% rename from pkg/core/spec/attribute.go rename to core/spec/attribute.go index b1ee2c78..19751899 100644 --- a/pkg/core/spec/attribute.go +++ b/core/spec/attribute.go @@ -3,7 +3,7 @@ package spec import ( "encoding/json" "fmt" - "github.com/imulab/go-scim/pkg/core/annotations" + "github.com/imulab/go-scim/core/annotations" "sort" "strings" ) diff --git a/pkg/core/spec/mutability.go b/core/spec/mutability.go similarity index 100% rename from pkg/core/spec/mutability.go rename to core/spec/mutability.go diff --git a/pkg/core/spec/resource_type.go b/core/spec/resource_type.go similarity index 98% rename from pkg/core/spec/resource_type.go rename to core/spec/resource_type.go index 59b7ca4a..50a5ce9f 100644 --- a/pkg/core/spec/resource_type.go +++ b/core/spec/resource_type.go @@ -2,7 +2,7 @@ package spec import ( "encoding/json" - "github.com/imulab/go-scim/pkg/core/annotations" + "github.com/imulab/go-scim/core/annotations" ) // A SCIM resource type is a collection of schemas to describe a resource. diff --git a/pkg/core/spec/returned.go b/core/spec/returned.go similarity index 100% rename from pkg/core/spec/returned.go rename to core/spec/returned.go diff --git a/pkg/core/spec/schema.go b/core/spec/schema.go similarity index 99% rename from pkg/core/spec/schema.go rename to core/spec/schema.go index db5c06b8..2e22d630 100644 --- a/pkg/core/spec/schema.go +++ b/core/spec/schema.go @@ -2,7 +2,7 @@ package spec import ( "encoding/json" - "github.com/imulab/go-scim/pkg/core/annotations" + "github.com/imulab/go-scim/core/annotations" ) // Central repository for schemas diff --git a/pkg/core/spec/service_provider_config.go b/core/spec/service_provider_config.go similarity index 100% rename from pkg/core/spec/service_provider_config.go rename to core/spec/service_provider_config.go diff --git a/pkg/core/spec/type.go b/core/spec/type.go similarity index 100% rename from pkg/core/spec/type.go rename to core/spec/type.go diff --git a/pkg/core/spec/uniqueness.go b/core/spec/uniqueness.go similarity index 100% rename from pkg/core/spec/uniqueness.go rename to core/spec/uniqueness.go diff --git a/pkg/protocol/log/default.go b/pkg/protocol/log/default.go deleted file mode 100644 index 9e4defe3..00000000 --- a/pkg/protocol/log/default.go +++ /dev/null @@ -1,34 +0,0 @@ -package log - -import ( - "log" - "time" -) - -// Returns a Logger that uses Golang's native log package for logging. The logger also outputs the -// logging timestamp in RFC3339 format. -func Default() Logger { - return defaultLogger{} -} - -type defaultLogger struct{} - -func (d defaultLogger) Info(format string, args ...interface{}) { - log.Printf("[INFO] %s - "+format+"\n", append([]interface{}{time.Now().Format(time.RFC3339)}, args...)) -} - -func (d defaultLogger) Debug(format string, args ...interface{}) { - log.Printf("[DEBUG] %s - "+format+"\n", append([]interface{}{time.Now().Format(time.RFC3339)}, args...)) -} - -func (d defaultLogger) Error(format string, args ...interface{}) { - log.Printf("[ERROR] %s - "+format+"\n", append([]interface{}{time.Now().Format(time.RFC3339)}, args...)) -} - -func (d defaultLogger) Warning(format string, args ...interface{}) { - log.Printf("[WARNING] %s - "+format+"\n", append([]interface{}{time.Now().Format(time.RFC3339)}, args...)) -} - -func (d defaultLogger) Fatal(format string, args ...interface{}) { - log.Fatalf("[FATAL] %s - "+format+"\n", append([]interface{}{time.Now().Format(time.RFC3339)}, args...)) -} diff --git a/pkg/protocol/log/none.go b/pkg/protocol/log/none.go deleted file mode 100644 index 0ac7cc58..00000000 --- a/pkg/protocol/log/none.go +++ /dev/null @@ -1,18 +0,0 @@ -package log - -// Returns a Logger that does nothing. -func None() Logger { - return noOpLogger{} -} - -type noOpLogger struct{} - -func (n noOpLogger) Info(format string, args ...interface{}) {} - -func (n noOpLogger) Debug(format string, args ...interface{}) {} - -func (n noOpLogger) Error(format string, args ...interface{}) {} - -func (n noOpLogger) Warning(format string, args ...interface{}) {} - -func (n noOpLogger) Fatal(format string, args ...interface{}) {} diff --git a/pkg/tests/default_lock_test_suite/user_schema.json b/pkg/tests/default_lock_test_suite/user_schema.json deleted file mode 100644 index 245aaacf..00000000 --- a/pkg/tests/default_lock_test_suite/user_schema.json +++ /dev/null @@ -1,611 +0,0 @@ -{ - "id": "urn:ietf:params:scim:schemas:core:2.0:User", - "name": "User", - "description": "Defined attributes for the user schema", - "attributes": [ - { - "id": "urn:ietf:params:scim:schemas:core:2.0:User:userName", - "name": "userName", - "type": "string", - "required": true, - "uniqueness": "server", - "_index": 100, - "_path": "userName" - }, - { - "id": "urn:ietf:params:scim:schemas:core:2.0:User:name", - "name": "name", - "type": "complex", - "subAttributes": [ - { - "id": "urn:ietf:params:scim:schemas:core:2.0:User:name.formatted", - "name": "formatted", - "type": "string", - "_index": 0, - "_path": "name.formatted", - "_annotations": ["@Identity"] - }, - { - "id": "urn:ietf:params:scim:schemas:core:2.0:User:name.familyName", - "name": "familyName", - "type": "string", - "_index": 1, - "_path": "name.familyName", - "_annotations": ["@Identity"] - }, - { - "id": "urn:ietf:params:scim:schemas:core:2.0:User:name.givenName", - "name": "givenName", - "type": "string", - "_index": 2, - "_path": "name.givenName", - "_annotations": ["@Identity"] - }, - { - "id": "urn:ietf:params:scim:schemas:core:2.0:User:name.middleName", - "name": "middleName", - "type": "string", - "_index": 3, - "_path": "name.middleName", - "_annotations": ["@Identity"] - }, - { - "id": "urn:ietf:params:scim:schemas:core:2.0:User:name.honorificPrefix", - "name": "honorificPrefix", - "type": "string", - "_index": 4, - "_path": "name.honorificPrefix", - "_annotations": ["@Identity"] - }, - { - "id": "urn:ietf:params:scim:schemas:core:2.0:User:name.honorificSuffix", - "name": "honorificSuffix", - "type": "string", - "_index": 5, - "_path": "name.honorificSuffix", - "_annotations": ["@Identity"] - } - ], - "_index": 101, - "_path": "name" - }, - { - "id": "urn:ietf:params:scim:schemas:core:2.0:User:displayName", - "name": "displayName", - "type": "string", - "_index": 102, - "_path": "displayName" - }, - { - "id": "urn:ietf:params:scim:schemas:core:2.0:User:nickName", - "name": "nickName", - "type": "string", - "_index": 103, - "_path": "nickName" - }, - { - "id": "urn:ietf:params:scim:schemas:core:2.0:User:profileUrl", - "name": "profileUrl", - "type": "reference", - "referenceTypes": [ - "external" - ], - "_index": 104, - "_path": "profileUrl" - }, - { - "id": "urn:ietf:params:scim:schemas:core:2.0:User:title", - "name": "title", - "type": "string", - "_index": 105, - "_path": "title" - }, - { - "id": "urn:ietf:params:scim:schemas:core:2.0:User:userType", - "name": "userType", - "type": "string", - "canonicalValues": [ - "Contractor", - "Employee", - "Intern", - "Temp", - "External", - "Internal", - "Unknown" - ], - "_index": 106, - "_path": "userType" - }, - { - "id": "urn:ietf:params:scim:schemas:core:2.0:User:preferredLanguage", - "name": "preferredLanguage", - "type": "string", - "canonicalValues": [ - "zh_CN", - "en_US", - "en_CA" - ], - "_index": 107, - "_path": "preferredLanguage" - }, - { - "id": "urn:ietf:params:scim:schemas:core:2.0:User:locale", - "name": "locale", - "type": "string", - "canonicalValues": [ - "en_CA", - "fr_CA", - "en_US", - "zh_CN" - ], - "_index": 108, - "_path": "locale" - }, - { - "id": "urn:ietf:params:scim:schemas:core:2.0:User:timezone", - "name": "timezone", - "type": "string", - "canonicalValues": [ - "Asia/Shanghai", - "Asia/Beijing", - "America/New_York", - "America/Toronto" - ], - "_index": 109, - "_path": "timezone" - }, - { - "id": "urn:ietf:params:scim:schemas:core:2.0:User:active", - "name": "active", - "type": "boolean", - "_index": 110, - "_path": "active" - }, - { - "id": "urn:ietf:params:scim:schemas:core:2.0:User:password", - "name": "password", - "type": "string", - "mutability": "writeOnly", - "returned": "never", - "_index": 111, - "_path": "password" - }, - { - "id": "urn:ietf:params:scim:schemas:core:2.0:User:emails", - "name": "emails", - "type": "complex", - "multiValued": true, - "required": true, - "subAttributes": [ - { - "id": "urn:ietf:params:scim:schemas:core:2.0:User:emails.value", - "name": "value", - "type": "string", - "_index": 0, - "_path": "emails.value", - "_annotations": ["@Identity"] - }, - { - "id": "urn:ietf:params:scim:schemas:core:2.0:User:emails.type", - "name": "type", - "type": "string", - "canonicalValues": [ - "work", - "home", - "other" - ], - "_index": 1, - "_path": "emails.type", - "_annotations": ["@Identity"] - }, - { - "id": "urn:ietf:params:scim:schemas:core:2.0:User:emails.primary", - "name": "primary", - "type": "boolean", - "_index": 2, - "_path": "emails.primary", - "_annotations": ["@Identity"] - }, - { - "id": "urn:ietf:params:scim:schemas:core:2.0:User:emails.display", - "name": "display", - "type": "string", - "_index": 3, - "_path": "emails.display" - } - ], - "_index": 112, - "_path": "emails" - }, - { - "id": "urn:ietf:params:scim:schemas:core:2.0:User:phoneNumbers", - "name": "phoneNumbers", - "type": "complex", - "multiValued": true, - "subAttributes": [ - { - "id": "urn:ietf:params:scim:schemas:core:2.0:User:phoneNumbers.value", - "name": "value", - "type": "string", - "_index": 0, - "_path": "phoneNumbers.value", - "_annotations": ["@Identity"] - }, - { - "id": "urn:ietf:params:scim:schemas:core:2.0:User:phoneNumbers.type", - "name": "type", - "type": "string", - "canonicalValues": [ - "work", - "home", - "mobile", - "fax", - "pager", - "other" - ], - "_index": 1, - "_path": "phoneNumbers.type", - "_annotations": ["@Identity"] - }, - { - "id": "urn:ietf:params:scim:schemas:core:2.0:User:phoneNumbers.primary", - "name": "primary", - "type": "boolean", - "_index": 2, - "_path": "phoneNumbers.primary", - "_annotations": ["@Primary"] - }, - { - "id": "urn:ietf:params:scim:schemas:core:2.0:User:phoneNumbers.display", - "name": "display", - "type": "string", - "_index": 3, - "_path": "phoneNumbers.display" - } - ], - "_index": 113, - "_path": "phoneNumbers" - }, - { - "id": "urn:ietf:params:scim:schemas:core:2.0:User:ims", - "name": "ims", - "type": "complex", - "multiValued": true, - "subAttributes": [ - { - "id": "urn:ietf:params:scim:schemas:core:2.0:User:ims.value", - "name": "value", - "type": "string", - "_index": 0, - "_path": "ims.value", - "_annotations": ["@Identity"] - }, - { - "id": "urn:ietf:params:scim:schemas:core:2.0:User:ims.type", - "name": "type", - "type": "string", - "canonicalValues": [ - "skype", - "qq", - "wechat", - "weibo", - "other" - ], - "_index": 1, - "_path": "ims.type", - "_annotations": ["@Identity"] - }, - { - "id": "urn:ietf:params:scim:schemas:core:2.0:User:ims.primary", - "name": "primary", - "type": "boolean", - "_index": 2, - "_path": "ims.primary", - "_annotations": ["@Primary"] - }, - { - "id": "urn:ietf:params:scim:schemas:core:2.0:User:ims.display", - "name": "display", - "type": "string", - "_index": 3, - "_path": "ims.display" - } - ], - "_index": 114, - "_path": "ims" - }, - { - "id": "urn:ietf:params:scim:schemas:core:2.0:User:photos", - "name": "photos", - "type": "complex", - "multiValued": true, - "subAttributes": [ - { - "id": "urn:ietf:params:scim:schemas:core:2.0:User:photos.value", - "name": "value", - "type": "reference", - "referenceTypes": [ - "external" - ], - "_index": 0, - "_path": "photos.value", - "_annotations": ["@Identity"] - }, - { - "id": "urn:ietf:params:scim:schemas:core:2.0:User:photos.type", - "name": "type", - "type": "string", - "canonicalValues": [ - "photo", - "thumbnail" - ], - "_index": 1, - "_path": "photos.type", - "_annotations": ["@Identity"] - }, - { - "id": "urn:ietf:params:scim:schemas:core:2.0:User:photos.primary", - "name": "primary", - "type": "boolean", - "_index": 2, - "_path": "photos.primary", - "_annotations": ["@Primary"] - } - ], - "_index": 115, - "_path": "photos" - }, - { - "id": "urn:ietf:params:scim:schemas:core:2.0:User:addresses", - "name": "addresses", - "type": "complex", - "multiValued": true, - "subAttributes": [ - { - "id": "urn:ietf:params:scim:schemas:core:2.0:User:addresses.formatted", - "name": "formatted", - "type": "string", - "_index": 0, - "_path": "photos.formatted" - }, - { - "id": "urn:ietf:params:scim:schemas:core:2.0:User:addresses.streetAddress", - "name": "streetAddress", - "type": "string", - "_index": 1, - "_path": "photos.streetAddress", - "_annotations": ["@Identity"] - }, - { - "id": "urn:ietf:params:scim:schemas:core:2.0:User:addresses.locality", - "name": "locality", - "type": "string", - "_index": 2, - "_path": "photos.locality", - "_annotations": ["@Identity"] - }, - { - "id": "urn:ietf:params:scim:schemas:core:2.0:User:addresses.region", - "name": "region", - "type": "string", - "_index": 3, - "_path": "photos.region", - "_annotations": ["@Identity"] - }, - { - "id": "urn:ietf:params:scim:schemas:core:2.0:User:addresses.postalCode", - "name": "postalCode", - "type": "string", - "_index": 4, - "_path": "photos.postalCode", - "_annotations": ["@Identity"] - }, - { - "id": "urn:ietf:params:scim:schemas:core:2.0:User:addresses.country", - "name": "country", - "type": "string", - "_index": 5, - "_path": "photos.country", - "_annotations": ["@Identity"] - }, - { - "id": "urn:ietf:params:scim:schemas:core:2.0:User:addresses.type", - "name": "type", - "type": "string", - "canonicalValues": [ - "work", - "home", - "id", - "driver", - "other" - ], - "_index": 6, - "_path": "photos.type", - "_annotations": ["@Identity"] - }, - { - "id": "urn:ietf:params:scim:schemas:core:2.0:User:addresses.primary", - "name": "primary", - "type": "boolean", - "_index": 7, - "_path": "photos.primary", - "_annotations": ["@Primary"] - } - ], - "_index": 116, - "_path": "addresses" - }, - { - "id": "urn:ietf:params:scim:schemas:core:2.0:User:groups", - "name": "groups", - "type": "complex", - "multiValued": true, - "mutability": "readOnly", - "subAttributes": [ - { - "id": "urn:ietf:params:scim:schemas:core:2.0:User:groups.value", - "name": "value", - "type": "string", - "mutability": "readOnly", - "_index": 0, - "_path": "groups.value", - "_annotations": ["@Identity"] - }, - { - "id": "urn:ietf:params:scim:schemas:core:2.0:User:groups.$ref", - "name": "$ref", - "type": "reference", - "mutability": "readOnly", - "_index": 1, - "_path": "groups.$ref", - "_annotations": ["@Identity"] - }, - { - "id": "urn:ietf:params:scim:schemas:core:2.0:User:groups.type", - "name": "type", - "type": "string", - "mutability": "readOnly", - "canonicalValues": [ - "direct", - "indirect" - ], - "_index": 2, - "_path": "groups.type" - }, - { - "id": "urn:ietf:params:scim:schemas:core:2.0:User:groups.display", - "name": "display", - "type": "string", - "mutability": "readOnly", - "_index": 3, - "_path": "groups.display" - } - ], - "_index": 117, - "_path": "groups" - }, - { - "id": "urn:ietf:params:scim:schemas:core:2.0:User:entitlements", - "name": "entitlements", - "type": "complex", - "multiValued": true, - "subAttributes": [ - { - "id": "urn:ietf:params:scim:schemas:core:2.0:User:entitlements.value", - "name": "value", - "type": "string", - "_index": 0, - "_path": "entitlements.value", - "_annotations": ["@Identity"] - }, - { - "id": "urn:ietf:params:scim:schemas:core:2.0:User:entitlements.type", - "name": "type", - "type": "string", - "_index": 0, - "_path": "entitlements.type", - "_annotations": ["@Identity"] - }, - { - "id": "urn:ietf:params:scim:schemas:core:2.0:User:entitlements.primary", - "name": "primary", - "type": "boolean", - "_index": 0, - "_path": "entitlements.primary", - "_annotations": ["@Primary"] - }, - { - "id": "urn:ietf:params:scim:schemas:core:2.0:User:entitlements.display", - "name": "display", - "type": "string", - "_index": 0, - "_path": "entitlements.display" - } - ], - "_index": 118, - "_path": "entitlements" - }, - { - "id": "urn:ietf:params:scim:schemas:core:2.0:User:roles", - "name": "roles", - "type": "complex", - "multiValued": true, - "subAttributes": [ - { - "id": "urn:ietf:params:scim:schemas:core:2.0:User:roles.value", - "name": "value", - "type": "string", - "_index": 0, - "_path": "roles.value", - "_annotations": ["@Identity"] - }, - { - "id": "urn:ietf:params:scim:schemas:core:2.0:User:roles.type", - "name": "type", - "type": "string", - "_index": 1, - "_path": "roles.type", - "_annotations": ["@Identity"] - }, - { - "id": "urn:ietf:params:scim:schemas:core:2.0:User:roles.primary", - "name": "primary", - "type": "boolean", - "_index": 2, - "_path": "roles.primary", - "_annotations": ["@Primary"] - }, - { - "id": "urn:ietf:params:scim:schemas:core:2.0:User:roles.display", - "name": "display", - "type": "string", - "_index": 3, - "_path": "roles.display" - } - ], - "_index": 119, - "_path": "roles" - }, - { - "id": "urn:ietf:params:scim:schemas:core:2.0:User:x509Certificates", - "name": "x509Certificates", - "type": "complex", - "multiValued": true, - "subAttributes": [ - { - "id": "urn:ietf:params:scim:schemas:core:2.0:User:x509Certificates.value", - "name": "value", - "type": "binary", - "_index": 0, - "_path": "x509Certificates.value", - "_annotations": ["@Identity"] - }, - { - "id": "urn:ietf:params:scim:schemas:core:2.0:User:x509Certificates.type", - "name": "type", - "type": "string", - "_index": 1, - "_path": "x509Certificates.type", - "_annotations": ["@Identity"] - }, - { - "id": "urn:ietf:params:scim:schemas:core:2.0:User:x509Certificates.primary", - "name": "primary", - "type": "boolean", - "_index": 2, - "_path": "x509Certificates.primary", - "_annotations": ["@Primary"] - }, - { - "id": "urn:ietf:params:scim:schemas:core:2.0:User:x509Certificates.display", - "name": "display", - "type": "string", - "_index": 3, - "_path": "x509Certificates.display" - } - ], - "_index": 120, - "_path": "x509Certificates" - } - ] -} \ No newline at end of file diff --git a/pkg/tests/resource_test_suite/user_resource_type.json b/pkg/tests/resource_test_suite/user_resource_type.json deleted file mode 100644 index 907c4aad..00000000 --- a/pkg/tests/resource_test_suite/user_resource_type.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "id": "User", - "name": "User", - "description": "User resource type", - "endpoint": "https://scim.imulab.io/Users", - "schema": "urn:ietf:params:scim:schemas:core:2.0:User", - "schemaExtensions": [] -} \ No newline at end of file diff --git a/pkg/protocol/crud/crud.go b/protocol/crud/crud.go similarity index 92% rename from pkg/protocol/crud/crud.go rename to protocol/crud/crud.go index 94748804..9c8def92 100644 --- a/pkg/protocol/crud/crud.go +++ b/protocol/crud/crud.go @@ -1,9 +1,9 @@ package crud import ( - "github.com/imulab/go-scim/pkg/core/errors" - "github.com/imulab/go-scim/pkg/core/expr" - "github.com/imulab/go-scim/pkg/core/prop" + "github.com/imulab/go-scim/core/errors" + "github.com/imulab/go-scim/core/expr" + "github.com/imulab/go-scim/core/prop" ) // Add value to SCIM resource at the given SCIM path. If SCIM path is empty, value will be added diff --git a/pkg/protocol/crud/crud_test.go b/protocol/crud/crud_test.go similarity index 98% rename from pkg/protocol/crud/crud_test.go rename to protocol/crud/crud_test.go index 1e5e8697..646baedc 100644 --- a/pkg/protocol/crud/crud_test.go +++ b/protocol/crud/crud_test.go @@ -2,10 +2,10 @@ package crud import ( "encoding/json" - "github.com/imulab/go-scim/pkg/core/expr" - scimJSON "github.com/imulab/go-scim/pkg/core/json" - "github.com/imulab/go-scim/pkg/core/prop" - "github.com/imulab/go-scim/pkg/core/spec" + "github.com/imulab/go-scim/core/expr" + scimJSON "github.com/imulab/go-scim/core/json" + "github.com/imulab/go-scim/core/prop" + "github.com/imulab/go-scim/core/spec" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/suite" "io/ioutil" @@ -15,7 +15,7 @@ import ( func TestCRUD(t *testing.T) { s := new(CRUDTestSuite) - s.resourceBase = "../../tests/crud_test_suite" + s.resourceBase = "./internal/crud_test_suite" suite.Run(t, s) } diff --git a/pkg/protocol/crud/evaluate.go b/protocol/crud/evaluate.go similarity index 96% rename from pkg/protocol/crud/evaluate.go rename to protocol/crud/evaluate.go index 186122d7..ebbb8e42 100644 --- a/pkg/protocol/crud/evaluate.go +++ b/protocol/crud/evaluate.go @@ -1,10 +1,10 @@ package crud import ( - "github.com/imulab/go-scim/pkg/core/errors" - "github.com/imulab/go-scim/pkg/core/expr" - "github.com/imulab/go-scim/pkg/core/prop" - "github.com/imulab/go-scim/pkg/core/spec" + "github.com/imulab/go-scim/core/errors" + "github.com/imulab/go-scim/core/expr" + "github.com/imulab/go-scim/core/prop" + "github.com/imulab/go-scim/core/spec" "strconv" "strings" ) diff --git a/pkg/tests/create_handler_test_suite/user_001.json b/protocol/crud/internal/crud_test_suite/user_001.json similarity index 100% rename from pkg/tests/create_handler_test_suite/user_001.json rename to protocol/crud/internal/crud_test_suite/user_001.json diff --git a/pkg/tests/crud_test_suite/user_resource_type.json b/protocol/crud/internal/crud_test_suite/user_resource_type.json similarity index 100% rename from pkg/tests/crud_test_suite/user_resource_type.json rename to protocol/crud/internal/crud_test_suite/user_resource_type.json diff --git a/pkg/tests/delete_handler_test_suite/user_schema.json b/protocol/crud/internal/crud_test_suite/user_schema.json similarity index 100% rename from pkg/tests/delete_handler_test_suite/user_schema.json rename to protocol/crud/internal/crud_test_suite/user_schema.json diff --git a/pkg/tests/sort_resource_test_suite/user_000.json b/protocol/crud/internal/sort_resource_test_suite/user_000.json similarity index 100% rename from pkg/tests/sort_resource_test_suite/user_000.json rename to protocol/crud/internal/sort_resource_test_suite/user_000.json diff --git a/pkg/tests/sort_resource_test_suite/user_001.json b/protocol/crud/internal/sort_resource_test_suite/user_001.json similarity index 100% rename from pkg/tests/sort_resource_test_suite/user_001.json rename to protocol/crud/internal/sort_resource_test_suite/user_001.json diff --git a/pkg/tests/sort_resource_test_suite/user_002.json b/protocol/crud/internal/sort_resource_test_suite/user_002.json similarity index 100% rename from pkg/tests/sort_resource_test_suite/user_002.json rename to protocol/crud/internal/sort_resource_test_suite/user_002.json diff --git a/pkg/tests/sort_resource_test_suite/user_003.json b/protocol/crud/internal/sort_resource_test_suite/user_003.json similarity index 100% rename from pkg/tests/sort_resource_test_suite/user_003.json rename to protocol/crud/internal/sort_resource_test_suite/user_003.json diff --git a/pkg/tests/sort_resource_test_suite/user_004.json b/protocol/crud/internal/sort_resource_test_suite/user_004.json similarity index 100% rename from pkg/tests/sort_resource_test_suite/user_004.json rename to protocol/crud/internal/sort_resource_test_suite/user_004.json diff --git a/pkg/tests/sort_resource_test_suite/user_005.json b/protocol/crud/internal/sort_resource_test_suite/user_005.json similarity index 100% rename from pkg/tests/sort_resource_test_suite/user_005.json rename to protocol/crud/internal/sort_resource_test_suite/user_005.json diff --git a/pkg/tests/delete_handler_test_suite/user_resource_type.json b/protocol/crud/internal/sort_resource_test_suite/user_resource_type.json similarity index 100% rename from pkg/tests/delete_handler_test_suite/user_resource_type.json rename to protocol/crud/internal/sort_resource_test_suite/user_resource_type.json diff --git a/pkg/tests/delete_service_test_suite/user_schema.json b/protocol/crud/internal/sort_resource_test_suite/user_schema.json similarity index 100% rename from pkg/tests/delete_service_test_suite/user_schema.json rename to protocol/crud/internal/sort_resource_test_suite/user_schema.json diff --git a/pkg/protocol/crud/query.go b/protocol/crud/query.go similarity index 97% rename from pkg/protocol/crud/query.go rename to protocol/crud/query.go index 4795780e..f8453801 100644 --- a/pkg/protocol/crud/query.go +++ b/protocol/crud/query.go @@ -1,10 +1,10 @@ package crud import ( - "github.com/imulab/go-scim/pkg/core/errors" - "github.com/imulab/go-scim/pkg/core/expr" - "github.com/imulab/go-scim/pkg/core/prop" - "github.com/imulab/go-scim/pkg/core/spec" + "github.com/imulab/go-scim/core/errors" + "github.com/imulab/go-scim/core/expr" + "github.com/imulab/go-scim/core/prop" + "github.com/imulab/go-scim/core/spec" "sort" ) diff --git a/pkg/protocol/crud/query_test.go b/protocol/crud/query_test.go similarity index 97% rename from pkg/protocol/crud/query_test.go rename to protocol/crud/query_test.go index 0c33569b..b24a34b0 100644 --- a/pkg/protocol/crud/query_test.go +++ b/protocol/crud/query_test.go @@ -2,10 +2,10 @@ package crud import ( "encoding/json" - "github.com/imulab/go-scim/pkg/core/expr" - scimJSON "github.com/imulab/go-scim/pkg/core/json" - "github.com/imulab/go-scim/pkg/core/prop" - "github.com/imulab/go-scim/pkg/core/spec" + "github.com/imulab/go-scim/core/expr" + scimJSON "github.com/imulab/go-scim/core/json" + "github.com/imulab/go-scim/core/prop" + "github.com/imulab/go-scim/core/spec" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/suite" "io/ioutil" @@ -15,7 +15,7 @@ import ( func TestSortResource(t *testing.T) { s := new(SortResourceTestSuite) - s.resourceBase = "../../tests/sort_resource_test_suite" + s.resourceBase = "./internal/sort_resource_test_suite" suite.Run(t, s) } diff --git a/pkg/protocol/crud/traverse.go b/protocol/crud/traverse.go similarity index 92% rename from pkg/protocol/crud/traverse.go rename to protocol/crud/traverse.go index 1983f23f..f8d89a1a 100644 --- a/pkg/protocol/crud/traverse.go +++ b/protocol/crud/traverse.go @@ -1,9 +1,9 @@ package crud import ( - "github.com/imulab/go-scim/pkg/core/errors" - "github.com/imulab/go-scim/pkg/core/expr" - "github.com/imulab/go-scim/pkg/core/prop" + "github.com/imulab/go-scim/core/errors" + "github.com/imulab/go-scim/core/expr" + "github.com/imulab/go-scim/core/prop" ) // Walk down the currently focused property in the navigator, following the current node in the query expression, diff --git a/pkg/protocol/db/db.go b/protocol/db/db.go similarity index 93% rename from pkg/protocol/db/db.go rename to protocol/db/db.go index 1cdfd2f0..d1082332 100644 --- a/pkg/protocol/db/db.go +++ b/protocol/db/db.go @@ -2,8 +2,8 @@ package db import ( "context" - "github.com/imulab/go-scim/pkg/core/prop" - "github.com/imulab/go-scim/pkg/protocol/crud" + "github.com/imulab/go-scim/core/prop" + "github.com/imulab/go-scim/protocol/crud" ) // Abstraction for the database that provides the main persistence and look up capabilities. diff --git a/pkg/tests/delete_handler_test_suite/user_001.json b/protocol/db/internal/memory_db_test_suite/user_001.json similarity index 100% rename from pkg/tests/delete_handler_test_suite/user_001.json rename to protocol/db/internal/memory_db_test_suite/user_001.json diff --git a/pkg/tests/memory_db_test_suite/user_002.json b/protocol/db/internal/memory_db_test_suite/user_002.json similarity index 100% rename from pkg/tests/memory_db_test_suite/user_002.json rename to protocol/db/internal/memory_db_test_suite/user_002.json diff --git a/pkg/tests/memory_db_test_suite/user_003.json b/protocol/db/internal/memory_db_test_suite/user_003.json similarity index 100% rename from pkg/tests/memory_db_test_suite/user_003.json rename to protocol/db/internal/memory_db_test_suite/user_003.json diff --git a/pkg/tests/memory_db_test_suite/user_004.json b/protocol/db/internal/memory_db_test_suite/user_004.json similarity index 100% rename from pkg/tests/memory_db_test_suite/user_004.json rename to protocol/db/internal/memory_db_test_suite/user_004.json diff --git a/pkg/tests/memory_db_test_suite/user_005.json b/protocol/db/internal/memory_db_test_suite/user_005.json similarity index 100% rename from pkg/tests/memory_db_test_suite/user_005.json rename to protocol/db/internal/memory_db_test_suite/user_005.json diff --git a/pkg/tests/memory_db_test_suite/user_006.json b/protocol/db/internal/memory_db_test_suite/user_006.json similarity index 100% rename from pkg/tests/memory_db_test_suite/user_006.json rename to protocol/db/internal/memory_db_test_suite/user_006.json diff --git a/pkg/tests/memory_db_test_suite/user_007.json b/protocol/db/internal/memory_db_test_suite/user_007.json similarity index 100% rename from pkg/tests/memory_db_test_suite/user_007.json rename to protocol/db/internal/memory_db_test_suite/user_007.json diff --git a/pkg/tests/memory_db_test_suite/user_008.json b/protocol/db/internal/memory_db_test_suite/user_008.json similarity index 100% rename from pkg/tests/memory_db_test_suite/user_008.json rename to protocol/db/internal/memory_db_test_suite/user_008.json diff --git a/pkg/tests/memory_db_test_suite/user_009.json b/protocol/db/internal/memory_db_test_suite/user_009.json similarity index 100% rename from pkg/tests/memory_db_test_suite/user_009.json rename to protocol/db/internal/memory_db_test_suite/user_009.json diff --git a/pkg/tests/memory_db_test_suite/user_010.json b/protocol/db/internal/memory_db_test_suite/user_010.json similarity index 100% rename from pkg/tests/memory_db_test_suite/user_010.json rename to protocol/db/internal/memory_db_test_suite/user_010.json diff --git a/pkg/tests/delete_service_test_suite/user_resource_type.json b/protocol/db/internal/memory_db_test_suite/user_resource_type.json similarity index 100% rename from pkg/tests/delete_service_test_suite/user_resource_type.json rename to protocol/db/internal/memory_db_test_suite/user_resource_type.json diff --git a/pkg/tests/get_handler_test_suite/user_schema.json b/protocol/db/internal/memory_db_test_suite/user_schema.json similarity index 100% rename from pkg/tests/get_handler_test_suite/user_schema.json rename to protocol/db/internal/memory_db_test_suite/user_schema.json diff --git a/pkg/protocol/db/memory.go b/protocol/db/memory.go similarity index 93% rename from pkg/protocol/db/memory.go rename to protocol/db/memory.go index b0bb416d..dd162a5b 100644 --- a/pkg/protocol/db/memory.go +++ b/protocol/db/memory.go @@ -2,10 +2,10 @@ package db import ( "context" - "github.com/imulab/go-scim/pkg/core/errors" - "github.com/imulab/go-scim/pkg/core/expr" - "github.com/imulab/go-scim/pkg/core/prop" - "github.com/imulab/go-scim/pkg/protocol/crud" + "github.com/imulab/go-scim/core/errors" + "github.com/imulab/go-scim/core/expr" + "github.com/imulab/go-scim/core/prop" + "github.com/imulab/go-scim/protocol/crud" "sync" ) diff --git a/pkg/protocol/db/memory_test.go b/protocol/db/memory_test.go similarity index 98% rename from pkg/protocol/db/memory_test.go rename to protocol/db/memory_test.go index 691a39d6..68870f9a 100644 --- a/pkg/protocol/db/memory_test.go +++ b/protocol/db/memory_test.go @@ -3,10 +3,10 @@ package db import ( "context" "encoding/json" - scimJSON "github.com/imulab/go-scim/pkg/core/json" - "github.com/imulab/go-scim/pkg/core/prop" - "github.com/imulab/go-scim/pkg/core/spec" - "github.com/imulab/go-scim/pkg/protocol/crud" + scimJSON "github.com/imulab/go-scim/core/json" + "github.com/imulab/go-scim/core/prop" + "github.com/imulab/go-scim/core/spec" + "github.com/imulab/go-scim/protocol/crud" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "github.com/stretchr/testify/suite" @@ -17,7 +17,7 @@ import ( func TestMemoryDB(t *testing.T) { s := new(MemoryDBTestSuite) - s.resourceBase = "../../tests/memory_db_test_suite" + s.resourceBase = "./internal/memory_db_test_suite" suite.Run(t, s) } diff --git a/protocol/event/composite.go b/protocol/event/composite.go new file mode 100644 index 00000000..83f53e9a --- /dev/null +++ b/protocol/event/composite.go @@ -0,0 +1,33 @@ +package event + +import ( + "context" + "github.com/imulab/go-scim/core/prop" +) + +// Return a composite publisher which invokes the given publishers one by one on events. +func Of(publishers ...Publisher) Publisher { + return &composite{publishers: publishers} +} + +type composite struct { + publishers []Publisher +} + +func (c *composite) ResourceCreated(ctx context.Context, created *prop.Resource) { + for _, p := range c.publishers { + p.ResourceCreated(ctx, created) + } +} + +func (c *composite) ResourceUpdated(ctx context.Context, updated *prop.Resource, original *prop.Resource) { + for _, p := range c.publishers { + p.ResourceUpdated(ctx, updated, original) + } +} + +func (c *composite) ResourceDeleted(ctx context.Context, deleted *prop.Resource) { + for _, p := range c.publishers { + p.ResourceDeleted(ctx, deleted) + } +} diff --git a/pkg/protocol/event/event.go b/protocol/event/event.go similarity index 93% rename from pkg/protocol/event/event.go rename to protocol/event/event.go index 925e1cd0..a2c15a9d 100644 --- a/pkg/protocol/event/event.go +++ b/protocol/event/event.go @@ -2,7 +2,7 @@ package event import ( "context" - "github.com/imulab/go-scim/pkg/core/prop" + "github.com/imulab/go-scim/core/prop" ) // Publisher provides hooks for implementations to react to certain events during protocol execution. diff --git a/protocol/go.mod b/protocol/go.mod new file mode 100644 index 00000000..32c13f64 --- /dev/null +++ b/protocol/go.mod @@ -0,0 +1,10 @@ +module github.com/imulab/go-scim/protocol + +require ( + github.com/imulab/go-scim/core v0.0.0 + github.com/satori/go.uuid v1.2.0 + github.com/stretchr/testify v1.4.0 + golang.org/x/crypto v0.0.0-20191206172530-e9b2fee46413 +) + +replace github.com/imulab/go-scim/core => ../core diff --git a/protocol/go.sum b/protocol/go.sum new file mode 100644 index 00000000..e110b8be --- /dev/null +++ b/protocol/go.sum @@ -0,0 +1,21 @@ +github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/imulab/go-scim v1.0.1 h1:nWUJF3q0MQWwtGvSHdoylNfAuUeWBMuVL5pSMJ9EG1k= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/satori/go.uuid v1.2.0 h1:0uYX9dsZ2yD7q2RtLRtPSdGDWzjeM3TbMJP9utgA0ww= +github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk= +github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20191206172530-e9b2fee46413 h1:ULYEB3JvPRE/IfO+9uO7vKV/xzVTO7XPAwm8xbf4w2g= +golang.org/x/crypto v0.0.0-20191206172530-e9b2fee46413/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= diff --git a/pkg/protocol/groupsync/diff.go b/protocol/groupsync/diff.go similarity index 93% rename from pkg/protocol/groupsync/diff.go rename to protocol/groupsync/diff.go index f5583253..9ad69e9c 100644 --- a/pkg/protocol/groupsync/diff.go +++ b/protocol/groupsync/diff.go @@ -1,7 +1,7 @@ package groupsync import ( - "github.com/imulab/go-scim/pkg/core/prop" + "github.com/imulab/go-scim/core/prop" ) const ( @@ -92,3 +92,11 @@ func (d *Diff) ForEachLeft(callback func(id string)) { callback(k) } } + +func (d *Diff) CountJoined() int { + return len(d.joined) +} + +func (d *Diff) CountLeft() int { + return len(d.left) +} diff --git a/pkg/tests/group_sync_refresh_test_suite/group_001.json b/protocol/groupsync/internal/group_sync_refresh_test_suite/group_001.json similarity index 100% rename from pkg/tests/group_sync_refresh_test_suite/group_001.json rename to protocol/groupsync/internal/group_sync_refresh_test_suite/group_001.json diff --git a/pkg/tests/group_sync_refresh_test_suite/group_002.json b/protocol/groupsync/internal/group_sync_refresh_test_suite/group_002.json similarity index 100% rename from pkg/tests/group_sync_refresh_test_suite/group_002.json rename to protocol/groupsync/internal/group_sync_refresh_test_suite/group_002.json diff --git a/pkg/tests/group_sync_refresh_test_suite/group_resource_type.json b/protocol/groupsync/internal/group_sync_refresh_test_suite/group_resource_type.json similarity index 100% rename from pkg/tests/group_sync_refresh_test_suite/group_resource_type.json rename to protocol/groupsync/internal/group_sync_refresh_test_suite/group_resource_type.json diff --git a/pkg/tests/group_sync_refresh_test_suite/group_schema.json b/protocol/groupsync/internal/group_sync_refresh_test_suite/group_schema.json similarity index 100% rename from pkg/tests/group_sync_refresh_test_suite/group_schema.json rename to protocol/groupsync/internal/group_sync_refresh_test_suite/group_schema.json diff --git a/pkg/tests/delete_service_test_suite/user_001.json b/protocol/groupsync/internal/group_sync_refresh_test_suite/user_001.json similarity index 100% rename from pkg/tests/delete_service_test_suite/user_001.json rename to protocol/groupsync/internal/group_sync_refresh_test_suite/user_001.json diff --git a/pkg/tests/get_handler_test_suite/user_resource_type.json b/protocol/groupsync/internal/group_sync_refresh_test_suite/user_resource_type.json similarity index 100% rename from pkg/tests/get_handler_test_suite/user_resource_type.json rename to protocol/groupsync/internal/group_sync_refresh_test_suite/user_resource_type.json diff --git a/pkg/tests/get_service_test_suite/user_schema.json b/protocol/groupsync/internal/group_sync_refresh_test_suite/user_schema.json similarity index 100% rename from pkg/tests/get_service_test_suite/user_schema.json rename to protocol/groupsync/internal/group_sync_refresh_test_suite/user_schema.json diff --git a/pkg/protocol/groupsync/internal/init.go b/protocol/groupsync/internal/init.go similarity index 88% rename from pkg/protocol/groupsync/internal/init.go rename to protocol/groupsync/internal/init.go index c5249b08..e93b9a50 100644 --- a/pkg/protocol/groupsync/internal/init.go +++ b/protocol/groupsync/internal/init.go @@ -2,7 +2,7 @@ package internal import ( "encoding/json" - "github.com/imulab/go-scim/pkg/core/spec" + "github.com/imulab/go-scim/core/spec" ) func init() { diff --git a/pkg/protocol/groupsync/internal/resource_type.go b/protocol/groupsync/internal/resource_type.go similarity index 84% rename from pkg/protocol/groupsync/internal/resource_type.go rename to protocol/groupsync/internal/resource_type.go index b280c207..0c52431e 100644 --- a/pkg/protocol/groupsync/internal/resource_type.go +++ b/protocol/groupsync/internal/resource_type.go @@ -1,6 +1,6 @@ package internal -import "github.com/imulab/go-scim/pkg/core/spec" +import "github.com/imulab/go-scim/core/spec" var ( ResourceType *spec.ResourceType diff --git a/pkg/protocol/groupsync/internal/schema.go b/protocol/groupsync/internal/schema.go similarity index 97% rename from pkg/protocol/groupsync/internal/schema.go rename to protocol/groupsync/internal/schema.go index 18d73dfc..ab7de842 100644 --- a/pkg/protocol/groupsync/internal/schema.go +++ b/protocol/groupsync/internal/schema.go @@ -1,7 +1,7 @@ package internal import ( - "github.com/imulab/go-scim/pkg/core/spec" + "github.com/imulab/go-scim/core/spec" ) var ( diff --git a/pkg/protocol/groupsync/listener.go b/protocol/groupsync/listener.go similarity index 90% rename from pkg/protocol/groupsync/listener.go rename to protocol/groupsync/listener.go index fe4ad1c4..56698c90 100644 --- a/pkg/protocol/groupsync/listener.go +++ b/protocol/groupsync/listener.go @@ -2,12 +2,12 @@ package groupsync import ( "context" - "github.com/imulab/go-scim/pkg/core/prop" - "github.com/imulab/go-scim/pkg/protocol/crud" - "github.com/imulab/go-scim/pkg/protocol/db" - "github.com/imulab/go-scim/pkg/protocol/event" - "github.com/imulab/go-scim/pkg/protocol/log" - "github.com/imulab/go-scim/pkg/protocol/services/filter" + "github.com/imulab/go-scim/core/prop" + "github.com/imulab/go-scim/protocol/crud" + "github.com/imulab/go-scim/protocol/db" + "github.com/imulab/go-scim/protocol/event" + "github.com/imulab/go-scim/protocol/log" + "github.com/imulab/go-scim/protocol/services/filter" ) const ( @@ -131,7 +131,10 @@ func (l *membershipListener) dumpErrorToLog(before *prop.Resource, after *prop.R groupID = after.ID() } } - l.log.Error("failed to create group sync job [id=%s]: %s", groupID, err.Error()) + l.log.Error("failed to create group sync job", log.Args{ + "groupId": groupID, + "error": err, + }) } func (l *membershipListener) fillGroup(gs *prop.Resource, group *prop.Resource) error { diff --git a/pkg/protocol/groupsync/refresh.go b/protocol/groupsync/refresh.go similarity index 96% rename from pkg/protocol/groupsync/refresh.go rename to protocol/groupsync/refresh.go index 94506f00..1bff5fef 100644 --- a/pkg/protocol/groupsync/refresh.go +++ b/protocol/groupsync/refresh.go @@ -3,9 +3,9 @@ package groupsync import ( "context" "fmt" - "github.com/imulab/go-scim/pkg/core/prop" - "github.com/imulab/go-scim/pkg/protocol/crud" - "github.com/imulab/go-scim/pkg/protocol/db" + "github.com/imulab/go-scim/core/prop" + "github.com/imulab/go-scim/protocol/crud" + "github.com/imulab/go-scim/protocol/db" ) // Create a new refresher in order to refresh the group property of the user resource. diff --git a/pkg/protocol/groupsync/refresh_test.go b/protocol/groupsync/refresh_test.go similarity index 92% rename from pkg/protocol/groupsync/refresh_test.go rename to protocol/groupsync/refresh_test.go index f0b01bb3..ee02406a 100644 --- a/pkg/protocol/groupsync/refresh_test.go +++ b/protocol/groupsync/refresh_test.go @@ -3,10 +3,10 @@ package groupsync import ( "context" "encoding/json" - scimJSON "github.com/imulab/go-scim/pkg/core/json" - "github.com/imulab/go-scim/pkg/core/prop" - "github.com/imulab/go-scim/pkg/core/spec" - "github.com/imulab/go-scim/pkg/protocol/db" + scimJSON "github.com/imulab/go-scim/core/json" + "github.com/imulab/go-scim/core/prop" + "github.com/imulab/go-scim/core/spec" + "github.com/imulab/go-scim/protocol/db" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "github.com/stretchr/testify/suite" @@ -17,7 +17,7 @@ import ( func TestGroupSyncRefresh(t *testing.T) { s := new(GroupSyncRefreshTestSuite) - s.resourceBase = "../../tests/group_sync_refresh_test_suite" + s.resourceBase = "./internal/group_sync_refresh_test_suite" suite.Run(t, s) } diff --git a/pkg/protocol/groupsync/resource.go b/protocol/groupsync/resource.go similarity index 69% rename from pkg/protocol/groupsync/resource.go rename to protocol/groupsync/resource.go index 3fc731e5..d57ae89e 100644 --- a/pkg/protocol/groupsync/resource.go +++ b/protocol/groupsync/resource.go @@ -1,8 +1,8 @@ package groupsync import ( - "github.com/imulab/go-scim/pkg/core/spec" - "github.com/imulab/go-scim/pkg/protocol/groupsync/internal" + "github.com/imulab/go-scim/core/spec" + "github.com/imulab/go-scim/protocol/groupsync/internal" ) // Get the group sync resource schema diff --git a/pkg/protocol/groupsync/worker.go b/protocol/groupsync/worker.go similarity index 94% rename from pkg/protocol/groupsync/worker.go rename to protocol/groupsync/worker.go index dcac9bcf..1b2d8e25 100644 --- a/pkg/protocol/groupsync/worker.go +++ b/protocol/groupsync/worker.go @@ -3,11 +3,11 @@ package groupsync import ( "context" "fmt" - "github.com/imulab/go-scim/pkg/core/errors" - "github.com/imulab/go-scim/pkg/core/prop" - "github.com/imulab/go-scim/pkg/protocol/crud" - "github.com/imulab/go-scim/pkg/protocol/db" - "github.com/imulab/go-scim/pkg/protocol/log" + "github.com/imulab/go-scim/core/errors" + "github.com/imulab/go-scim/core/prop" + "github.com/imulab/go-scim/protocol/crud" + "github.com/imulab/go-scim/protocol/db" + "github.com/imulab/go-scim/protocol/log" "time" ) @@ -216,7 +216,9 @@ func (w *worker) nextSync() *prop.Resource { } func (w *worker) sleep(seconds int) { - w.log.Info("sleeping for %d seconds before continue.", seconds) + w.log.Info("sleeping before continue.", log.Args{ + "seconds": seconds, + }) timer := time.NewTimer(time.Duration(seconds) * time.Second) <-timer.C } diff --git a/pkg/protocol/handler/conditional.go b/protocol/handler/conditional.go similarity index 91% rename from pkg/protocol/handler/conditional.go rename to protocol/handler/conditional.go index 122d2bdf..f912a7f9 100644 --- a/pkg/protocol/handler/conditional.go +++ b/protocol/handler/conditional.go @@ -1,8 +1,8 @@ package handler import ( - "github.com/imulab/go-scim/pkg/core/prop" - "github.com/imulab/go-scim/pkg/protocol/http" + "github.com/imulab/go-scim/core/prop" + "github.com/imulab/go-scim/protocol/http" "strings" ) diff --git a/pkg/protocol/handler/create.go b/protocol/handler/create.go similarity index 65% rename from pkg/protocol/handler/create.go rename to protocol/handler/create.go index d1b94710..6d07f6f8 100644 --- a/pkg/protocol/handler/create.go +++ b/protocol/handler/create.go @@ -1,13 +1,13 @@ package handler import ( - "github.com/imulab/go-scim/pkg/core/errors" - "github.com/imulab/go-scim/pkg/core/json" - "github.com/imulab/go-scim/pkg/core/prop" - "github.com/imulab/go-scim/pkg/core/spec" - "github.com/imulab/go-scim/pkg/protocol/http" - "github.com/imulab/go-scim/pkg/protocol/log" - "github.com/imulab/go-scim/pkg/protocol/services" + "github.com/imulab/go-scim/core/errors" + "github.com/imulab/go-scim/core/json" + "github.com/imulab/go-scim/core/prop" + "github.com/imulab/go-scim/core/spec" + "github.com/imulab/go-scim/protocol/http" + "github.com/imulab/go-scim/protocol/log" + "github.com/imulab/go-scim/protocol/services" ) type Create struct { @@ -17,13 +17,15 @@ type Create struct { } func (h *Create) Handle(request http.Request, response http.Response) { - h.Log.Info("request to create resource") + h.Log.Info("request to create resource", log.Args{}) var payload *prop.Resource { raw, err := request.Body() if err != nil { - h.Log.Error("failed to read request body: %s", err.Error()) + h.Log.Error("failed to read request body", log.Args{ + "error": err, + }) WriteError(response, errors.Internal("failed to read request body")) return } @@ -31,7 +33,9 @@ func (h *Create) Handle(request http.Request, response http.Response) { payload = prop.NewResource(h.ResourceType) err = json.Deserialize(raw, payload) if err != nil { - h.Log.Error("failed to parse request body: %s", err.Error()) + h.Log.Error("failed to parse request body", log.Args{ + "error": err, + }) WriteError(response, err) return } diff --git a/pkg/protocol/handler/create_test.go b/protocol/handler/create_test.go similarity index 91% rename from pkg/protocol/handler/create_test.go rename to protocol/handler/create_test.go index 887c00bc..4dbbebf2 100644 --- a/pkg/protocol/handler/create_test.go +++ b/protocol/handler/create_test.go @@ -3,14 +3,14 @@ package handler import ( "context" "encoding/json" - scimJSON "github.com/imulab/go-scim/pkg/core/json" - "github.com/imulab/go-scim/pkg/core/prop" - "github.com/imulab/go-scim/pkg/core/spec" - "github.com/imulab/go-scim/pkg/protocol/db" - "github.com/imulab/go-scim/pkg/protocol/http" - "github.com/imulab/go-scim/pkg/protocol/log" - "github.com/imulab/go-scim/pkg/protocol/services" - filters "github.com/imulab/go-scim/pkg/protocol/services/filter" + scimJSON "github.com/imulab/go-scim/core/json" + "github.com/imulab/go-scim/core/prop" + "github.com/imulab/go-scim/core/spec" + "github.com/imulab/go-scim/protocol/db" + "github.com/imulab/go-scim/protocol/http" + "github.com/imulab/go-scim/protocol/log" + "github.com/imulab/go-scim/protocol/services" + filters "github.com/imulab/go-scim/protocol/services/filter" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "github.com/stretchr/testify/suite" @@ -22,7 +22,7 @@ import ( func TestCreateHandler(t *testing.T) { s := new(CreateHandlerTestSuite) - s.resourceBase = "../../tests/create_handler_test_suite" + s.resourceBase = "./internal/create_handler_test_suite" suite.Run(t, s) } diff --git a/pkg/protocol/handler/delete.go b/protocol/handler/delete.go similarity index 78% rename from pkg/protocol/handler/delete.go rename to protocol/handler/delete.go index 0dd07f86..21770b94 100644 --- a/pkg/protocol/handler/delete.go +++ b/protocol/handler/delete.go @@ -1,9 +1,9 @@ package handler import ( - "github.com/imulab/go-scim/pkg/protocol/http" - "github.com/imulab/go-scim/pkg/protocol/log" - "github.com/imulab/go-scim/pkg/protocol/services" + "github.com/imulab/go-scim/protocol/http" + "github.com/imulab/go-scim/protocol/log" + "github.com/imulab/go-scim/protocol/services" ) type Delete struct { diff --git a/pkg/protocol/handler/delete_test.go b/protocol/handler/delete_test.go similarity index 90% rename from pkg/protocol/handler/delete_test.go rename to protocol/handler/delete_test.go index 4d0ec617..d28afb16 100644 --- a/pkg/protocol/handler/delete_test.go +++ b/protocol/handler/delete_test.go @@ -3,13 +3,13 @@ package handler import ( "context" "encoding/json" - scimJSON "github.com/imulab/go-scim/pkg/core/json" - "github.com/imulab/go-scim/pkg/core/prop" - "github.com/imulab/go-scim/pkg/core/spec" - "github.com/imulab/go-scim/pkg/protocol/db" - "github.com/imulab/go-scim/pkg/protocol/http" - "github.com/imulab/go-scim/pkg/protocol/log" - "github.com/imulab/go-scim/pkg/protocol/services" + scimJSON "github.com/imulab/go-scim/core/json" + "github.com/imulab/go-scim/core/prop" + "github.com/imulab/go-scim/core/spec" + "github.com/imulab/go-scim/protocol/db" + "github.com/imulab/go-scim/protocol/http" + "github.com/imulab/go-scim/protocol/log" + "github.com/imulab/go-scim/protocol/services" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "github.com/stretchr/testify/suite" @@ -21,7 +21,7 @@ import ( func TestDeleteHandler(t *testing.T) { s := new(DeleteHandlerTestSuite) - s.resourceBase = "../../tests/delete_handler_test_suite" + s.resourceBase = "./internal/delete_handler_test_suite" suite.Run(t, s) } diff --git a/pkg/protocol/handler/get.go b/protocol/handler/get.go similarity index 82% rename from pkg/protocol/handler/get.go rename to protocol/handler/get.go index b44e8c3e..bf1b582b 100644 --- a/pkg/protocol/handler/get.go +++ b/protocol/handler/get.go @@ -1,12 +1,12 @@ package handler import ( - "github.com/imulab/go-scim/pkg/core/errors" - "github.com/imulab/go-scim/pkg/core/json" - "github.com/imulab/go-scim/pkg/protocol/crud" - "github.com/imulab/go-scim/pkg/protocol/http" - "github.com/imulab/go-scim/pkg/protocol/log" - "github.com/imulab/go-scim/pkg/protocol/services" + "github.com/imulab/go-scim/core/errors" + "github.com/imulab/go-scim/core/json" + "github.com/imulab/go-scim/protocol/crud" + "github.com/imulab/go-scim/protocol/http" + "github.com/imulab/go-scim/protocol/log" + "github.com/imulab/go-scim/protocol/services" "strings" ) @@ -24,7 +24,9 @@ func (h *Get) Handle(request http.Request, response http.Response) { ) { resourceIDParam = request.PathParam(h.ResourceIDPathParam) - h.Log.Info("request to get resource [id=%s]", resourceIDParam) + h.Log.Info("request to get resource.", log.Args{ + "resourceId": resourceIDParam, + }) if len(resourceIDParam) == 0 { WriteError(response, errors.InvalidRequest("missing resource id")) return diff --git a/pkg/protocol/handler/get_test.go b/protocol/handler/get_test.go similarity index 95% rename from pkg/protocol/handler/get_test.go rename to protocol/handler/get_test.go index f25b6c89..18daf6f9 100644 --- a/pkg/protocol/handler/get_test.go +++ b/protocol/handler/get_test.go @@ -3,13 +3,13 @@ package handler import ( "context" "encoding/json" - scimJSON "github.com/imulab/go-scim/pkg/core/json" - "github.com/imulab/go-scim/pkg/core/prop" - "github.com/imulab/go-scim/pkg/core/spec" - "github.com/imulab/go-scim/pkg/protocol/db" - "github.com/imulab/go-scim/pkg/protocol/http" - "github.com/imulab/go-scim/pkg/protocol/log" - "github.com/imulab/go-scim/pkg/protocol/services" + scimJSON "github.com/imulab/go-scim/core/json" + "github.com/imulab/go-scim/core/prop" + "github.com/imulab/go-scim/core/spec" + "github.com/imulab/go-scim/protocol/db" + "github.com/imulab/go-scim/protocol/http" + "github.com/imulab/go-scim/protocol/log" + "github.com/imulab/go-scim/protocol/services" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "github.com/stretchr/testify/suite" @@ -21,7 +21,7 @@ import ( func TestGetHandler(t *testing.T) { s := new(GetHandlerTestSuite) - s.resourceBase = "../../tests/get_handler_test_suite" + s.resourceBase = "./internal/get_handler_test_suite" suite.Run(t, s) } diff --git a/pkg/protocol/handler/handler.go b/protocol/handler/handler.go similarity index 90% rename from pkg/protocol/handler/handler.go rename to protocol/handler/handler.go index ccea7601..4a478d19 100644 --- a/pkg/protocol/handler/handler.go +++ b/protocol/handler/handler.go @@ -2,8 +2,8 @@ package handler import ( "encoding/json" - "github.com/imulab/go-scim/pkg/core/errors" - "github.com/imulab/go-scim/pkg/protocol/http" + "github.com/imulab/go-scim/core/errors" + "github.com/imulab/go-scim/protocol/http" ) // Handler function implemented by endpoint handlers in this package. diff --git a/pkg/tests/create_handler_test_suite/user_000.json b/protocol/handler/internal/create_handler_test_suite/user_000.json similarity index 100% rename from pkg/tests/create_handler_test_suite/user_000.json rename to protocol/handler/internal/create_handler_test_suite/user_000.json diff --git a/pkg/tests/create_service_test_suite/user_001.json b/protocol/handler/internal/create_handler_test_suite/user_001.json similarity index 100% rename from pkg/tests/create_service_test_suite/user_001.json rename to protocol/handler/internal/create_handler_test_suite/user_001.json diff --git a/pkg/tests/create_handler_test_suite/user_002.json b/protocol/handler/internal/create_handler_test_suite/user_002.json similarity index 100% rename from pkg/tests/create_handler_test_suite/user_002.json rename to protocol/handler/internal/create_handler_test_suite/user_002.json diff --git a/pkg/tests/from_for_property_test_suite/user_resource_type.json b/protocol/handler/internal/create_handler_test_suite/user_resource_type.json similarity index 100% rename from pkg/tests/from_for_property_test_suite/user_resource_type.json rename to protocol/handler/internal/create_handler_test_suite/user_resource_type.json diff --git a/pkg/tests/json_deserialize_test_suite/user_schema.json b/protocol/handler/internal/create_handler_test_suite/user_schema.json similarity index 100% rename from pkg/tests/json_deserialize_test_suite/user_schema.json rename to protocol/handler/internal/create_handler_test_suite/user_schema.json diff --git a/pkg/tests/delete_handler_test_suite/service_provider_config.json b/protocol/handler/internal/delete_handler_test_suite/service_provider_config.json similarity index 100% rename from pkg/tests/delete_handler_test_suite/service_provider_config.json rename to protocol/handler/internal/delete_handler_test_suite/service_provider_config.json diff --git a/pkg/tests/get_handler_test_suite/user_001.json b/protocol/handler/internal/delete_handler_test_suite/user_001.json similarity index 100% rename from pkg/tests/get_handler_test_suite/user_001.json rename to protocol/handler/internal/delete_handler_test_suite/user_001.json diff --git a/pkg/tests/get_service_test_suite/user_resource_type.json b/protocol/handler/internal/delete_handler_test_suite/user_resource_type.json similarity index 100% rename from pkg/tests/get_service_test_suite/user_resource_type.json rename to protocol/handler/internal/delete_handler_test_suite/user_resource_type.json diff --git a/pkg/tests/group_sync_refresh_test_suite/user_schema.json b/protocol/handler/internal/delete_handler_test_suite/user_schema.json similarity index 100% rename from pkg/tests/group_sync_refresh_test_suite/user_schema.json rename to protocol/handler/internal/delete_handler_test_suite/user_schema.json diff --git a/pkg/tests/get_service_test_suite/user_001.json b/protocol/handler/internal/get_handler_test_suite/user_001.json similarity index 100% rename from pkg/tests/get_service_test_suite/user_001.json rename to protocol/handler/internal/get_handler_test_suite/user_001.json diff --git a/pkg/tests/group_sync_refresh_test_suite/user_resource_type.json b/protocol/handler/internal/get_handler_test_suite/user_resource_type.json similarity index 100% rename from pkg/tests/group_sync_refresh_test_suite/user_resource_type.json rename to protocol/handler/internal/get_handler_test_suite/user_resource_type.json diff --git a/pkg/tests/memory_db_test_suite/user_schema.json b/protocol/handler/internal/get_handler_test_suite/user_schema.json similarity index 100% rename from pkg/tests/memory_db_test_suite/user_schema.json rename to protocol/handler/internal/get_handler_test_suite/user_schema.json diff --git a/pkg/tests/patch_handler_test_suite/patch_001.json b/protocol/handler/internal/patch_handler_test_suite/patch_001.json similarity index 100% rename from pkg/tests/patch_handler_test_suite/patch_001.json rename to protocol/handler/internal/patch_handler_test_suite/patch_001.json diff --git a/pkg/tests/patch_handler_test_suite/patch_002.json b/protocol/handler/internal/patch_handler_test_suite/patch_002.json similarity index 100% rename from pkg/tests/patch_handler_test_suite/patch_002.json rename to protocol/handler/internal/patch_handler_test_suite/patch_002.json diff --git a/pkg/tests/delete_service_test_suite/service_provider_config.json b/protocol/handler/internal/patch_handler_test_suite/service_provider_config.json similarity index 100% rename from pkg/tests/delete_service_test_suite/service_provider_config.json rename to protocol/handler/internal/patch_handler_test_suite/service_provider_config.json diff --git a/pkg/tests/patch_handler_test_suite/user_000.json b/protocol/handler/internal/patch_handler_test_suite/user_000.json similarity index 100% rename from pkg/tests/patch_handler_test_suite/user_000.json rename to protocol/handler/internal/patch_handler_test_suite/user_000.json diff --git a/pkg/tests/memory_db_test_suite/user_resource_type.json b/protocol/handler/internal/patch_handler_test_suite/user_resource_type.json similarity index 100% rename from pkg/tests/memory_db_test_suite/user_resource_type.json rename to protocol/handler/internal/patch_handler_test_suite/user_resource_type.json diff --git a/pkg/tests/patch_handler_test_suite/user_schema.json b/protocol/handler/internal/patch_handler_test_suite/user_schema.json similarity index 100% rename from pkg/tests/patch_handler_test_suite/user_schema.json rename to protocol/handler/internal/patch_handler_test_suite/user_schema.json diff --git a/pkg/tests/patch_handler_test_suite/service_provider_config.json b/protocol/handler/internal/query_handler_test_suite/service_provider_config.json similarity index 100% rename from pkg/tests/patch_handler_test_suite/service_provider_config.json rename to protocol/handler/internal/query_handler_test_suite/service_provider_config.json diff --git a/pkg/tests/group_sync_refresh_test_suite/user_001.json b/protocol/handler/internal/query_handler_test_suite/user_001.json similarity index 100% rename from pkg/tests/group_sync_refresh_test_suite/user_001.json rename to protocol/handler/internal/query_handler_test_suite/user_001.json diff --git a/pkg/tests/query_handler_test_suite/user_002.json b/protocol/handler/internal/query_handler_test_suite/user_002.json similarity index 100% rename from pkg/tests/query_handler_test_suite/user_002.json rename to protocol/handler/internal/query_handler_test_suite/user_002.json diff --git a/pkg/tests/query_handler_test_suite/user_003.json b/protocol/handler/internal/query_handler_test_suite/user_003.json similarity index 100% rename from pkg/tests/query_handler_test_suite/user_003.json rename to protocol/handler/internal/query_handler_test_suite/user_003.json diff --git a/pkg/tests/query_handler_test_suite/user_004.json b/protocol/handler/internal/query_handler_test_suite/user_004.json similarity index 100% rename from pkg/tests/query_handler_test_suite/user_004.json rename to protocol/handler/internal/query_handler_test_suite/user_004.json diff --git a/pkg/tests/query_handler_test_suite/user_005.json b/protocol/handler/internal/query_handler_test_suite/user_005.json similarity index 100% rename from pkg/tests/query_handler_test_suite/user_005.json rename to protocol/handler/internal/query_handler_test_suite/user_005.json diff --git a/pkg/tests/query_handler_test_suite/user_006.json b/protocol/handler/internal/query_handler_test_suite/user_006.json similarity index 100% rename from pkg/tests/query_handler_test_suite/user_006.json rename to protocol/handler/internal/query_handler_test_suite/user_006.json diff --git a/pkg/tests/query_handler_test_suite/user_007.json b/protocol/handler/internal/query_handler_test_suite/user_007.json similarity index 100% rename from pkg/tests/query_handler_test_suite/user_007.json rename to protocol/handler/internal/query_handler_test_suite/user_007.json diff --git a/pkg/tests/query_handler_test_suite/user_008.json b/protocol/handler/internal/query_handler_test_suite/user_008.json similarity index 100% rename from pkg/tests/query_handler_test_suite/user_008.json rename to protocol/handler/internal/query_handler_test_suite/user_008.json diff --git a/pkg/tests/query_handler_test_suite/user_009.json b/protocol/handler/internal/query_handler_test_suite/user_009.json similarity index 100% rename from pkg/tests/query_handler_test_suite/user_009.json rename to protocol/handler/internal/query_handler_test_suite/user_009.json diff --git a/pkg/tests/query_handler_test_suite/user_010.json b/protocol/handler/internal/query_handler_test_suite/user_010.json similarity index 100% rename from pkg/tests/query_handler_test_suite/user_010.json rename to protocol/handler/internal/query_handler_test_suite/user_010.json diff --git a/pkg/tests/patch_handler_test_suite/user_resource_type.json b/protocol/handler/internal/query_handler_test_suite/user_resource_type.json similarity index 100% rename from pkg/tests/patch_handler_test_suite/user_resource_type.json rename to protocol/handler/internal/query_handler_test_suite/user_resource_type.json diff --git a/pkg/tests/patch_service_test_suite/user_schema.json b/protocol/handler/internal/query_handler_test_suite/user_schema.json similarity index 100% rename from pkg/tests/patch_service_test_suite/user_schema.json rename to protocol/handler/internal/query_handler_test_suite/user_schema.json diff --git a/pkg/tests/patch_service_test_suite/service_provider_config.json b/protocol/handler/internal/replace_handler_test_suite/service_provider_config.json similarity index 100% rename from pkg/tests/patch_service_test_suite/service_provider_config.json rename to protocol/handler/internal/replace_handler_test_suite/service_provider_config.json diff --git a/pkg/tests/patch_service_test_suite/user_000.json b/protocol/handler/internal/replace_handler_test_suite/user_000.json similarity index 100% rename from pkg/tests/patch_service_test_suite/user_000.json rename to protocol/handler/internal/replace_handler_test_suite/user_000.json diff --git a/pkg/tests/replace_handler_test_suite/user_001.json b/protocol/handler/internal/replace_handler_test_suite/user_001.json similarity index 100% rename from pkg/tests/replace_handler_test_suite/user_001.json rename to protocol/handler/internal/replace_handler_test_suite/user_001.json diff --git a/pkg/tests/replace_handler_test_suite/user_002.json b/protocol/handler/internal/replace_handler_test_suite/user_002.json similarity index 100% rename from pkg/tests/replace_handler_test_suite/user_002.json rename to protocol/handler/internal/replace_handler_test_suite/user_002.json diff --git a/pkg/tests/json_deserialize_test_suite/user_resource_type.json b/protocol/handler/internal/replace_handler_test_suite/user_resource_type.json similarity index 100% rename from pkg/tests/json_deserialize_test_suite/user_resource_type.json rename to protocol/handler/internal/replace_handler_test_suite/user_resource_type.json diff --git a/pkg/tests/replace_handler_test_suite/user_schema.json b/protocol/handler/internal/replace_handler_test_suite/user_schema.json similarity index 100% rename from pkg/tests/replace_handler_test_suite/user_schema.json rename to protocol/handler/internal/replace_handler_test_suite/user_schema.json diff --git a/pkg/tests/query_handler_test_suite/service_provider_config.json b/protocol/handler/internal/service_provider_config_handler_test_suite/service_provider_config.json similarity index 100% rename from pkg/tests/query_handler_test_suite/service_provider_config.json rename to protocol/handler/internal/service_provider_config_handler_test_suite/service_provider_config.json diff --git a/pkg/protocol/handler/patch.go b/protocol/handler/patch.go similarity index 78% rename from pkg/protocol/handler/patch.go rename to protocol/handler/patch.go index 1ad73423..d20add57 100644 --- a/pkg/protocol/handler/patch.go +++ b/protocol/handler/patch.go @@ -2,11 +2,11 @@ package handler import ( "encoding/json" - "github.com/imulab/go-scim/pkg/core/errors" - scimJSON "github.com/imulab/go-scim/pkg/core/json" - "github.com/imulab/go-scim/pkg/protocol/http" - "github.com/imulab/go-scim/pkg/protocol/log" - "github.com/imulab/go-scim/pkg/protocol/services" + "github.com/imulab/go-scim/core/errors" + scimJSON "github.com/imulab/go-scim/core/json" + "github.com/imulab/go-scim/protocol/http" + "github.com/imulab/go-scim/protocol/log" + "github.com/imulab/go-scim/protocol/services" ) type Patch struct { @@ -25,12 +25,18 @@ func (h *Patch) Handle(request http.Request, response http.Response) { raw, err := request.Body() if err != nil { - h.Log.Error("failed to read request body for patching resource [id=%s]: %s", payload.ResourceID, err.Error()) + h.Log.Error("failed to read request body for patching resource", log.Args{ + "resourceId": payload.ResourceID, + "error": err, + }) WriteError(response, errors.Internal("failed to read request body")) return } if err := json.Unmarshal(raw, payload); err != nil { - h.Log.Error("failed to parse request body for patching resource [id=%s]: %s", payload.ResourceID, err.Error()) + h.Log.Error("failed to parse request body for patching resource", log.Args{ + "resourceId": payload.ResourceID, + "error": err, + }) WriteError(response, err) return } diff --git a/pkg/protocol/handler/patch_test.go b/protocol/handler/patch_test.go similarity index 94% rename from pkg/protocol/handler/patch_test.go rename to protocol/handler/patch_test.go index 071f56ba..970581b4 100644 --- a/pkg/protocol/handler/patch_test.go +++ b/protocol/handler/patch_test.go @@ -3,14 +3,14 @@ package handler import ( "context" "encoding/json" - scimJSON "github.com/imulab/go-scim/pkg/core/json" - "github.com/imulab/go-scim/pkg/core/prop" - "github.com/imulab/go-scim/pkg/core/spec" - "github.com/imulab/go-scim/pkg/protocol/db" - "github.com/imulab/go-scim/pkg/protocol/http" - "github.com/imulab/go-scim/pkg/protocol/log" - "github.com/imulab/go-scim/pkg/protocol/services" - filters "github.com/imulab/go-scim/pkg/protocol/services/filter" + scimJSON "github.com/imulab/go-scim/core/json" + "github.com/imulab/go-scim/core/prop" + "github.com/imulab/go-scim/core/spec" + "github.com/imulab/go-scim/protocol/db" + "github.com/imulab/go-scim/protocol/http" + "github.com/imulab/go-scim/protocol/log" + "github.com/imulab/go-scim/protocol/services" + filters "github.com/imulab/go-scim/protocol/services/filter" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "github.com/stretchr/testify/suite" @@ -22,7 +22,7 @@ import ( func TestPatchHandler(t *testing.T) { s := new(PatchHandlerTestSuite) - s.resourceBase = "../../tests/patch_handler_test_suite" + s.resourceBase = "./internal/patch_handler_test_suite" suite.Run(t, s) } diff --git a/pkg/protocol/handler/query.go b/protocol/handler/query.go similarity index 92% rename from pkg/protocol/handler/query.go rename to protocol/handler/query.go index e8964e75..c785037e 100644 --- a/pkg/protocol/handler/query.go +++ b/protocol/handler/query.go @@ -2,12 +2,12 @@ package handler import ( "encoding/json" - "github.com/imulab/go-scim/pkg/core/errors" - scimJSON "github.com/imulab/go-scim/pkg/core/json" - "github.com/imulab/go-scim/pkg/protocol/crud" - "github.com/imulab/go-scim/pkg/protocol/http" - "github.com/imulab/go-scim/pkg/protocol/log" - "github.com/imulab/go-scim/pkg/protocol/services" + "github.com/imulab/go-scim/core/errors" + scimJSON "github.com/imulab/go-scim/core/json" + "github.com/imulab/go-scim/protocol/crud" + "github.com/imulab/go-scim/protocol/http" + "github.com/imulab/go-scim/protocol/log" + "github.com/imulab/go-scim/protocol/services" "strconv" "strings" ) @@ -20,7 +20,9 @@ type Query struct { func (h *Query) Handle(request http.Request, response http.Response) { qr, err := h.parseRequest(request) if err != nil { - h.Log.Error("failed to parse query request: %s", err.Error()) + h.Log.Error("failed to parse query request", log.Args{ + "error": err, + }) WriteError(response, err) return } diff --git a/pkg/protocol/handler/query_test.go b/protocol/handler/query_test.go similarity index 96% rename from pkg/protocol/handler/query_test.go rename to protocol/handler/query_test.go index 30f02e37..c01a93a0 100644 --- a/pkg/protocol/handler/query_test.go +++ b/protocol/handler/query_test.go @@ -3,13 +3,13 @@ package handler import ( "context" "encoding/json" - scimJSON "github.com/imulab/go-scim/pkg/core/json" - "github.com/imulab/go-scim/pkg/core/prop" - "github.com/imulab/go-scim/pkg/core/spec" - "github.com/imulab/go-scim/pkg/protocol/db" - "github.com/imulab/go-scim/pkg/protocol/http" - "github.com/imulab/go-scim/pkg/protocol/log" - "github.com/imulab/go-scim/pkg/protocol/services" + scimJSON "github.com/imulab/go-scim/core/json" + "github.com/imulab/go-scim/core/prop" + "github.com/imulab/go-scim/core/spec" + "github.com/imulab/go-scim/protocol/db" + "github.com/imulab/go-scim/protocol/http" + "github.com/imulab/go-scim/protocol/log" + "github.com/imulab/go-scim/protocol/services" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "github.com/stretchr/testify/suite" @@ -22,7 +22,7 @@ import ( func TestQueryHandler(t *testing.T) { s := new(QueryHandlerTestSuite) - s.resourceBase = "../../tests/query_handler_test_suite" + s.resourceBase = "./internal/query_handler_test_suite" suite.Run(t, s) } diff --git a/pkg/protocol/handler/replace.go b/protocol/handler/replace.go similarity index 73% rename from pkg/protocol/handler/replace.go rename to protocol/handler/replace.go index f7dabcca..94fd372a 100644 --- a/pkg/protocol/handler/replace.go +++ b/protocol/handler/replace.go @@ -1,13 +1,13 @@ package handler import ( - "github.com/imulab/go-scim/pkg/core/errors" - "github.com/imulab/go-scim/pkg/core/json" - "github.com/imulab/go-scim/pkg/core/prop" - "github.com/imulab/go-scim/pkg/core/spec" - "github.com/imulab/go-scim/pkg/protocol/http" - "github.com/imulab/go-scim/pkg/protocol/log" - "github.com/imulab/go-scim/pkg/protocol/services" + "github.com/imulab/go-scim/core/errors" + "github.com/imulab/go-scim/core/json" + "github.com/imulab/go-scim/core/prop" + "github.com/imulab/go-scim/core/spec" + "github.com/imulab/go-scim/protocol/http" + "github.com/imulab/go-scim/protocol/log" + "github.com/imulab/go-scim/protocol/services" ) type Replace struct { @@ -24,11 +24,16 @@ func (h *Replace) Handle(request http.Request, response http.Response) { ) { resourceIDParam = request.PathParam(h.ResourceIDPathParam) - h.Log.Info("request to replace resource [id=%s]", resourceIDParam) + h.Log.Info("request to replace resource", log.Args{ + "resourceId": resourceIDParam, + }) raw, err := request.Body() if err != nil { - h.Log.Error("failed to read request body for replacing resource [id=%s]: %s", resourceIDParam, err.Error()) + h.Log.Error("failed to read request body for replacing resource", log.Args{ + "resourceId": resourceIDParam, + "error": err, + }) WriteError(response, errors.Internal("failed to read request body")) return } @@ -36,7 +41,10 @@ func (h *Replace) Handle(request http.Request, response http.Response) { payload = prop.NewResource(h.ResourceType) err = json.Deserialize(raw, payload) if err != nil { - h.Log.Error("failed to parse request body for replacing resource [id=%s]: %s", resourceIDParam, err.Error()) + h.Log.Error("failed to parse request body for replacing resource", log.Args{ + "resourceId": resourceIDParam, + "error": err, + }) WriteError(response, err) return } diff --git a/pkg/protocol/handler/replace_test.go b/protocol/handler/replace_test.go similarity index 92% rename from pkg/protocol/handler/replace_test.go rename to protocol/handler/replace_test.go index a4615e51..a224903a 100644 --- a/pkg/protocol/handler/replace_test.go +++ b/protocol/handler/replace_test.go @@ -3,14 +3,14 @@ package handler import ( "context" "encoding/json" - scimJSON "github.com/imulab/go-scim/pkg/core/json" - "github.com/imulab/go-scim/pkg/core/prop" - "github.com/imulab/go-scim/pkg/core/spec" - "github.com/imulab/go-scim/pkg/protocol/db" - "github.com/imulab/go-scim/pkg/protocol/http" - "github.com/imulab/go-scim/pkg/protocol/log" - "github.com/imulab/go-scim/pkg/protocol/services" - filters "github.com/imulab/go-scim/pkg/protocol/services/filter" + scimJSON "github.com/imulab/go-scim/core/json" + "github.com/imulab/go-scim/core/prop" + "github.com/imulab/go-scim/core/spec" + "github.com/imulab/go-scim/protocol/db" + "github.com/imulab/go-scim/protocol/http" + "github.com/imulab/go-scim/protocol/log" + "github.com/imulab/go-scim/protocol/services" + filters "github.com/imulab/go-scim/protocol/services/filter" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "github.com/stretchr/testify/suite" @@ -22,7 +22,7 @@ import ( func TestReplaceHandler(t *testing.T) { s := new(ReplaceHandlerTestSuite) - s.resourceBase = "../../tests/replace_handler_test_suite" + s.resourceBase = "./internal/replace_handler_test_suite" suite.Run(t, s) } diff --git a/pkg/protocol/handler/service_provider_config.go b/protocol/handler/service_provider_config.go similarity index 72% rename from pkg/protocol/handler/service_provider_config.go rename to protocol/handler/service_provider_config.go index dc5431cf..9bc57955 100644 --- a/pkg/protocol/handler/service_provider_config.go +++ b/protocol/handler/service_provider_config.go @@ -2,9 +2,9 @@ package handler import ( "encoding/json" - "github.com/imulab/go-scim/pkg/core/spec" - "github.com/imulab/go-scim/pkg/protocol/http" - "github.com/imulab/go-scim/pkg/protocol/log" + "github.com/imulab/go-scim/core/spec" + "github.com/imulab/go-scim/protocol/http" + "github.com/imulab/go-scim/protocol/log" ) type ServiceProviderConfig struct { @@ -14,7 +14,7 @@ type ServiceProviderConfig struct { } func (h *ServiceProviderConfig) Handle(_ http.Request, response http.Response) { - h.Log.Info("get service provider config") + h.Log.Info("get service provider config", log.Args{}) if len(h.cache) == 0 { if raw, err := json.Marshal(h.SPC); err != nil { diff --git a/pkg/protocol/handler/service_provider_config_test.go b/protocol/handler/service_provider_config_test.go similarity index 89% rename from pkg/protocol/handler/service_provider_config_test.go rename to protocol/handler/service_provider_config_test.go index 5bb5d47d..6de7d999 100644 --- a/pkg/protocol/handler/service_provider_config_test.go +++ b/protocol/handler/service_provider_config_test.go @@ -2,9 +2,9 @@ package handler import ( "encoding/json" - "github.com/imulab/go-scim/pkg/core/spec" - "github.com/imulab/go-scim/pkg/protocol/http" - "github.com/imulab/go-scim/pkg/protocol/log" + "github.com/imulab/go-scim/core/spec" + "github.com/imulab/go-scim/protocol/http" + "github.com/imulab/go-scim/protocol/log" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/suite" "io/ioutil" @@ -15,7 +15,7 @@ import ( func TestServiceProviderConfigHandler(t *testing.T) { s := new(ServiceProviderConfigHandlerTestSuite) - s.resourceBase = "../../tests/service_provider_config_handler_test_suite" + s.resourceBase = "./internal/service_provider_config_handler_test_suite" suite.Run(t, s) } diff --git a/pkg/protocol/http/default.go b/protocol/http/default.go similarity index 100% rename from pkg/protocol/http/default.go rename to protocol/http/default.go diff --git a/pkg/protocol/http/internal.go b/protocol/http/internal.go similarity index 100% rename from pkg/protocol/http/internal.go rename to protocol/http/internal.go diff --git a/pkg/protocol/http/provider.go b/protocol/http/provider.go similarity index 100% rename from pkg/protocol/http/provider.go rename to protocol/http/provider.go diff --git a/protocol/log/args.go b/protocol/log/args.go new file mode 100644 index 00000000..c05bda5a --- /dev/null +++ b/protocol/log/args.go @@ -0,0 +1,26 @@ +package log + +import ( + "fmt" + "strings" +) + +type Args map[string]interface{} + +func (a Args) Count() int { + return len(a) +} + +func (a Args) ForEach(f func(k string, v interface{})) { + for k, v := range a { + f(k, v) + } +} + +func (a Args) String() string { + s := make([]string, 0) + a.ForEach(func(k string, v interface{}) { + s = append(s, fmt.Sprintf("%s=%v", k, v)) + }) + return strings.Join(s, " ") +} \ No newline at end of file diff --git a/protocol/log/default.go b/protocol/log/default.go new file mode 100644 index 00000000..19dfd54b --- /dev/null +++ b/protocol/log/default.go @@ -0,0 +1,34 @@ +package log + +import ( + "log" + "time" +) + +// Returns a Logger that uses Golang's native log package for logging. The logger also outputs the +// logging timestamp in RFC3339 format. +func Default() Logger { + return defaultLogger{} +} + +type defaultLogger struct{} + +func (d defaultLogger) Info(message string, args Args) { + log.Printf("[INFO] %s - %s %s\n", time.Now().Format(time.RFC3339), message, args.String()) +} + +func (d defaultLogger) Debug(message string, args Args) { + log.Printf("[DEBUG] %s - %s %s\n", time.Now().Format(time.RFC3339), message, args.String()) +} + +func (d defaultLogger) Error(message string, args Args) { + log.Printf("[ERROR] %s - %s %s\n", time.Now().Format(time.RFC3339), message, args.String()) +} + +func (d defaultLogger) Warning(message string, args Args) { + log.Printf("[WARNING] %s - %s %s\n", time.Now().Format(time.RFC3339), message, args.String()) +} + +func (d defaultLogger) Fatal(message string, args Args) { + log.Fatalf("[FATAL] %s - %s %s\n", time.Now().Format(time.RFC3339), message, args.String()) +} diff --git a/protocol/log/level.go b/protocol/log/level.go new file mode 100644 index 00000000..60d8a2eb --- /dev/null +++ b/protocol/log/level.go @@ -0,0 +1,32 @@ +package log + +import "strings" + +type Level int + +const ( + LevelFatal Level = iota + LevelError + LevelWarning + LevelInfo + LevelDebug +) + +// Matches the log level of FATAL/ERROR/WARNING/INFO/DEBUG case insensitively. +// Defaults to INFO if mismatches. +func LevelOf(value string) Level { + switch strings.ToUpper(value) { + case "FATAL": + return LevelFatal + case "ERROR": + return LevelError + case "WARNING": + return LevelWarning + case "INFO": + return LevelInfo + case "DEBUG": + return LevelDebug + default: + return LevelInfo + } +} \ No newline at end of file diff --git a/pkg/protocol/log/logger.go b/protocol/log/logger.go similarity index 52% rename from pkg/protocol/log/logger.go rename to protocol/log/logger.go index ea86e94e..9aee56fb 100644 --- a/pkg/protocol/log/logger.go +++ b/protocol/log/logger.go @@ -3,13 +3,13 @@ package log // Service provider for logging. type Logger interface { // Log message with INFO level. - Info(format string, args ...interface{}) + Info(message string, args Args) // Log message with DEBUG level. - Debug(format string, args ...interface{}) + Debug(message string, args Args) // Log message with ERROR level. - Error(format string, args ...interface{}) + Error(message string, args Args) // Log message with WARNING level. - Warning(format string, args ...interface{}) + Warning(message string, args Args) // Log message with FATAL level. - Fatal(format string, args ...interface{}) + Fatal(message string, args Args) } diff --git a/protocol/log/none.go b/protocol/log/none.go new file mode 100644 index 00000000..59b5bff5 --- /dev/null +++ b/protocol/log/none.go @@ -0,0 +1,18 @@ +package log + +// Returns a Logger that does nothing. +func None() Logger { + return noOpLogger{} +} + +type noOpLogger struct{} + +func (n noOpLogger) Info(message string, args Args) {} + +func (n noOpLogger) Debug(message string, args Args) {} + +func (n noOpLogger) Error(message string, args Args) {} + +func (n noOpLogger) Warning(message string, args Args) {} + +func (n noOpLogger) Fatal(message string, args Args) {} diff --git a/pkg/protocol/services/create.go b/protocol/services/create.go similarity index 59% rename from pkg/protocol/services/create.go rename to protocol/services/create.go index 096ef3aa..ff00e48e 100644 --- a/pkg/protocol/services/create.go +++ b/protocol/services/create.go @@ -2,11 +2,11 @@ package services import ( "context" - "github.com/imulab/go-scim/pkg/core/prop" - "github.com/imulab/go-scim/pkg/protocol/db" - "github.com/imulab/go-scim/pkg/protocol/event" - "github.com/imulab/go-scim/pkg/protocol/log" - "github.com/imulab/go-scim/pkg/protocol/services/filter" + "github.com/imulab/go-scim/core/prop" + "github.com/imulab/go-scim/protocol/db" + "github.com/imulab/go-scim/protocol/event" + "github.com/imulab/go-scim/protocol/log" + "github.com/imulab/go-scim/protocol/services/filter" ) type ( @@ -27,22 +27,27 @@ type ( ) func (s *CreateService) CreateResource(ctx context.Context, request *CreateRequest) (cr *CreateResponse, err error) { - s.Logger.Debug("received create request") - for _, f := range s.Filters { err = f.Filter(ctx, request.Payload) if err != nil { - s.Logger.Error("create request encounter error during filter: %s", err.Error()) + s.Logger.Error("create request encounter error during filter.", log.Args{ + "error": err, + }) return } } err = s.Database.Insert(ctx, request.Payload) if err != nil { - s.Logger.Error("resource [id=%s] failed to insert into persistence: %s", request.Payload.ID(), err.Error()) + s.Logger.Error("failed to insert into persistence", log.Args{ + "resourceId": request.Payload.ID(), + "error": err, + }) return } - s.Logger.Debug("resource [id=%s] inserted into persistence", request.Payload.ID()) + s.Logger.Debug("inserted into persistence", log.Args{ + "resourceId": request.Payload.ID(), + }) if s.Event != nil { s.Event.ResourceCreated(ctx, request.Payload) diff --git a/pkg/protocol/services/create_test.go b/protocol/services/create_test.go similarity index 91% rename from pkg/protocol/services/create_test.go rename to protocol/services/create_test.go index 9d46b64b..451fb14a 100644 --- a/pkg/protocol/services/create_test.go +++ b/protocol/services/create_test.go @@ -3,13 +3,13 @@ package services import ( "context" "encoding/json" - "github.com/imulab/go-scim/pkg/core/errors" - scimJSON "github.com/imulab/go-scim/pkg/core/json" - "github.com/imulab/go-scim/pkg/core/prop" - "github.com/imulab/go-scim/pkg/core/spec" - "github.com/imulab/go-scim/pkg/protocol/db" - "github.com/imulab/go-scim/pkg/protocol/log" - "github.com/imulab/go-scim/pkg/protocol/services/filter" + "github.com/imulab/go-scim/core/errors" + scimJSON "github.com/imulab/go-scim/core/json" + "github.com/imulab/go-scim/core/prop" + "github.com/imulab/go-scim/core/spec" + "github.com/imulab/go-scim/protocol/db" + "github.com/imulab/go-scim/protocol/log" + "github.com/imulab/go-scim/protocol/services/filter" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/suite" "io/ioutil" @@ -19,7 +19,7 @@ import ( func TestCreateService(t *testing.T) { s := new(CreateServiceTestSuite) - s.resourceBase = "../../tests/create_service_test_suite" + s.resourceBase = "./internal/create_service_test_suite" suite.Run(t, s) } diff --git a/pkg/protocol/services/delete.go b/protocol/services/delete.go similarity index 63% rename from pkg/protocol/services/delete.go rename to protocol/services/delete.go index b7a5eacf..1749fc7d 100644 --- a/pkg/protocol/services/delete.go +++ b/protocol/services/delete.go @@ -2,12 +2,12 @@ package services import ( "context" - "github.com/imulab/go-scim/pkg/core/errors" - "github.com/imulab/go-scim/pkg/core/prop" - "github.com/imulab/go-scim/pkg/core/spec" - "github.com/imulab/go-scim/pkg/protocol/db" - "github.com/imulab/go-scim/pkg/protocol/event" - "github.com/imulab/go-scim/pkg/protocol/log" + "github.com/imulab/go-scim/core/errors" + "github.com/imulab/go-scim/core/prop" + "github.com/imulab/go-scim/core/spec" + "github.com/imulab/go-scim/protocol/db" + "github.com/imulab/go-scim/protocol/event" + "github.com/imulab/go-scim/protocol/log" ) type ( @@ -24,8 +24,6 @@ type ( ) func (s *DeleteService) DeleteResource(ctx context.Context, request *DeleteRequest) error { - s.Logger.Debug("received delete request [id=%s]", request.ResourceID) - resource, err := s.Database.Get(ctx, request.ResourceID, nil) if err != nil { return err @@ -38,10 +36,15 @@ func (s *DeleteService) DeleteResource(ctx context.Context, request *DeleteReque err = s.Database.Delete(ctx, request.ResourceID) if err != nil { - s.Logger.Error("resource [id=%s] failed to delete from persistence: %s", request.ResourceID, err.Error()) + s.Logger.Error("failed to delete from persistence", log.Args{ + "resourceId": request.ResourceID, + "error": err, + }) return err } - s.Logger.Debug("resource [id=%s] deleted from persistence", request.ResourceID) + s.Logger.Debug("deleted from persistence", log.Args{ + "resourceId": request.ResourceID, + }) if s.Event != nil { s.Event.ResourceDeleted(ctx, resource) diff --git a/pkg/protocol/services/delete_test.go b/protocol/services/delete_test.go similarity index 92% rename from pkg/protocol/services/delete_test.go rename to protocol/services/delete_test.go index 985b816d..4ae29fda 100644 --- a/pkg/protocol/services/delete_test.go +++ b/protocol/services/delete_test.go @@ -3,11 +3,11 @@ package services import ( "context" "encoding/json" - scimJSON "github.com/imulab/go-scim/pkg/core/json" - "github.com/imulab/go-scim/pkg/core/prop" - "github.com/imulab/go-scim/pkg/core/spec" - "github.com/imulab/go-scim/pkg/protocol/db" - "github.com/imulab/go-scim/pkg/protocol/log" + scimJSON "github.com/imulab/go-scim/core/json" + "github.com/imulab/go-scim/core/prop" + "github.com/imulab/go-scim/core/spec" + "github.com/imulab/go-scim/protocol/db" + "github.com/imulab/go-scim/protocol/log" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "github.com/stretchr/testify/suite" @@ -18,7 +18,7 @@ import ( func TestDeleteService(t *testing.T) { s := new(DeleteServiceTestSuite) - s.resourceBase = "../../tests/delete_service_test_suite" + s.resourceBase = "./internal/delete_service_test_suite" suite.Run(t, s) } diff --git a/pkg/protocol/services/filter/clear_ro.go b/protocol/services/filter/clear_ro.go similarity index 91% rename from pkg/protocol/services/filter/clear_ro.go rename to protocol/services/filter/clear_ro.go index a7ba1f0c..414309da 100644 --- a/pkg/protocol/services/filter/clear_ro.go +++ b/protocol/services/filter/clear_ro.go @@ -2,8 +2,8 @@ package filter import ( "context" - "github.com/imulab/go-scim/pkg/core/prop" - "github.com/imulab/go-scim/pkg/core/spec" + "github.com/imulab/go-scim/core/prop" + "github.com/imulab/go-scim/core/spec" "strings" ) diff --git a/pkg/protocol/services/filter/copy_ro.go b/protocol/services/filter/copy_ro.go similarity index 90% rename from pkg/protocol/services/filter/copy_ro.go rename to protocol/services/filter/copy_ro.go index 5beb0b59..326a1de4 100644 --- a/pkg/protocol/services/filter/copy_ro.go +++ b/protocol/services/filter/copy_ro.go @@ -2,9 +2,9 @@ package filter import ( "context" - "github.com/imulab/go-scim/pkg/core/annotations" - "github.com/imulab/go-scim/pkg/core/prop" - "github.com/imulab/go-scim/pkg/core/spec" + "github.com/imulab/go-scim/core/annotations" + "github.com/imulab/go-scim/core/prop" + "github.com/imulab/go-scim/core/spec" "strings" ) diff --git a/pkg/protocol/services/filter/filter.go b/protocol/services/filter/filter.go similarity index 97% rename from pkg/protocol/services/filter/filter.go rename to protocol/services/filter/filter.go index 01933095..0fc55f78 100644 --- a/pkg/protocol/services/filter/filter.go +++ b/protocol/services/filter/filter.go @@ -2,8 +2,8 @@ package filter import ( "context" - "github.com/imulab/go-scim/pkg/core/prop" - "github.com/imulab/go-scim/pkg/core/spec" + "github.com/imulab/go-scim/core/prop" + "github.com/imulab/go-scim/core/spec" ) // Responsible of filtering a resource, like carrying out operations on a resource such as diff --git a/pkg/protocol/services/filter/filter_test.go b/protocol/services/filter/filter_test.go similarity index 96% rename from pkg/protocol/services/filter/filter_test.go rename to protocol/services/filter/filter_test.go index e90b8e84..6260a42c 100644 --- a/pkg/protocol/services/filter/filter_test.go +++ b/protocol/services/filter/filter_test.go @@ -3,9 +3,9 @@ package filter import ( "context" "encoding/json" - scimJSON "github.com/imulab/go-scim/pkg/core/json" - "github.com/imulab/go-scim/pkg/core/prop" - "github.com/imulab/go-scim/pkg/core/spec" + scimJSON "github.com/imulab/go-scim/core/json" + "github.com/imulab/go-scim/core/prop" + "github.com/imulab/go-scim/core/spec" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/suite" "io/ioutil" @@ -15,7 +15,7 @@ import ( func TestFromForProperty(t *testing.T) { s := new(FromForPropertyTestSuite) - s.resourceBase = "../../../tests/from_for_property_test_suite" + s.resourceBase = "./internal/from_for_property_test_suite" suite.Run(t, s) } diff --git a/pkg/protocol/services/filter/id.go b/protocol/services/filter/id.go similarity index 93% rename from pkg/protocol/services/filter/id.go rename to protocol/services/filter/id.go index ba5228d6..e84a5975 100644 --- a/pkg/protocol/services/filter/id.go +++ b/protocol/services/filter/id.go @@ -2,7 +2,7 @@ package filter import ( "context" - "github.com/imulab/go-scim/pkg/core/prop" + "github.com/imulab/go-scim/core/prop" uuid "github.com/satori/go.uuid" ) diff --git a/pkg/tests/from_for_property_test_suite/user_001.json b/protocol/services/filter/internal/from_for_property_test_suite/user_001.json similarity index 100% rename from pkg/tests/from_for_property_test_suite/user_001.json rename to protocol/services/filter/internal/from_for_property_test_suite/user_001.json diff --git a/pkg/tests/from_for_property_test_suite/user_002.json b/protocol/services/filter/internal/from_for_property_test_suite/user_002.json similarity index 100% rename from pkg/tests/from_for_property_test_suite/user_002.json rename to protocol/services/filter/internal/from_for_property_test_suite/user_002.json diff --git a/pkg/tests/json_serialize_test_suite/user_resource_type.json b/protocol/services/filter/internal/from_for_property_test_suite/user_resource_type.json similarity index 100% rename from pkg/tests/json_serialize_test_suite/user_resource_type.json rename to protocol/services/filter/internal/from_for_property_test_suite/user_resource_type.json diff --git a/pkg/tests/json_serialize_test_suite/user_schema.json b/protocol/services/filter/internal/from_for_property_test_suite/user_schema.json similarity index 100% rename from pkg/tests/json_serialize_test_suite/user_schema.json rename to protocol/services/filter/internal/from_for_property_test_suite/user_schema.json diff --git a/pkg/protocol/services/filter/meta.go b/protocol/services/filter/meta.go similarity index 96% rename from pkg/protocol/services/filter/meta.go rename to protocol/services/filter/meta.go index d17a746e..757e5d51 100644 --- a/pkg/protocol/services/filter/meta.go +++ b/protocol/services/filter/meta.go @@ -5,9 +5,9 @@ import ( "crypto/sha1" "encoding/binary" "fmt" - "github.com/imulab/go-scim/pkg/core/errors" - "github.com/imulab/go-scim/pkg/core/prop" - "github.com/imulab/go-scim/pkg/core/spec" + "github.com/imulab/go-scim/core/errors" + "github.com/imulab/go-scim/core/prop" + "github.com/imulab/go-scim/core/spec" "math/rand" "time" ) diff --git a/pkg/protocol/services/filter/password.go b/protocol/services/filter/password.go similarity index 93% rename from pkg/protocol/services/filter/password.go rename to protocol/services/filter/password.go index bc64f183..691951d3 100644 --- a/pkg/protocol/services/filter/password.go +++ b/protocol/services/filter/password.go @@ -2,8 +2,8 @@ package filter import ( "context" - "github.com/imulab/go-scim/pkg/core/errors" - "github.com/imulab/go-scim/pkg/core/prop" + "github.com/imulab/go-scim/core/errors" + "github.com/imulab/go-scim/core/prop" "golang.org/x/crypto/bcrypt" ) diff --git a/pkg/protocol/services/filter/validation.go b/protocol/services/filter/validation.go similarity index 94% rename from pkg/protocol/services/filter/validation.go rename to protocol/services/filter/validation.go index 9d256ca2..51f24231 100644 --- a/pkg/protocol/services/filter/validation.go +++ b/protocol/services/filter/validation.go @@ -3,11 +3,11 @@ package filter import ( "context" "fmt" - "github.com/imulab/go-scim/pkg/core/annotations" - "github.com/imulab/go-scim/pkg/core/errors" - "github.com/imulab/go-scim/pkg/core/prop" - "github.com/imulab/go-scim/pkg/core/spec" - "github.com/imulab/go-scim/pkg/protocol/db" + "github.com/imulab/go-scim/core/annotations" + "github.com/imulab/go-scim/core/errors" + "github.com/imulab/go-scim/core/prop" + "github.com/imulab/go-scim/core/spec" + "github.com/imulab/go-scim/protocol/db" "strings" ) diff --git a/pkg/protocol/services/filter/visitor.go b/protocol/services/filter/visitor.go similarity index 98% rename from pkg/protocol/services/filter/visitor.go rename to protocol/services/filter/visitor.go index 658d4d3f..2bedfa08 100644 --- a/pkg/protocol/services/filter/visitor.go +++ b/protocol/services/filter/visitor.go @@ -2,8 +2,8 @@ package filter import ( "context" - "github.com/imulab/go-scim/pkg/core/prop" - "github.com/imulab/go-scim/pkg/core/spec" + "github.com/imulab/go-scim/core/prop" + "github.com/imulab/go-scim/core/spec" ) type ( diff --git a/pkg/protocol/services/get.go b/protocol/services/get.go similarity index 63% rename from pkg/protocol/services/get.go rename to protocol/services/get.go index 7e370d7b..3781baff 100644 --- a/pkg/protocol/services/get.go +++ b/protocol/services/get.go @@ -2,10 +2,10 @@ package services import ( "context" - "github.com/imulab/go-scim/pkg/core/prop" - "github.com/imulab/go-scim/pkg/protocol/crud" - "github.com/imulab/go-scim/pkg/protocol/db" - "github.com/imulab/go-scim/pkg/protocol/log" + "github.com/imulab/go-scim/core/prop" + "github.com/imulab/go-scim/protocol/crud" + "github.com/imulab/go-scim/protocol/db" + "github.com/imulab/go-scim/protocol/log" ) type ( @@ -25,11 +25,12 @@ type ( ) func (s *GetService) GetResource(ctx context.Context, request *GetRequest) (*GetResponse, error) { - s.Logger.Debug("received get request [id=%s]", request.ResourceID) - resource, err := s.Database.Get(ctx, request.ResourceID, request.Projection) if err != nil { - s.Logger.Error("failed to get resource [id=%s] from persistence: %s", request.ResourceID, err.Error()) + s.Logger.Error("failed to get resource from persistence", log.Args{ + "resourceId": request.ResourceID, + "error": err, + }) return nil, err } diff --git a/pkg/protocol/services/get_test.go b/protocol/services/get_test.go similarity index 91% rename from pkg/protocol/services/get_test.go rename to protocol/services/get_test.go index 267fdd86..8aac81fd 100644 --- a/pkg/protocol/services/get_test.go +++ b/protocol/services/get_test.go @@ -3,11 +3,11 @@ package services import ( "context" "encoding/json" - scimJSON "github.com/imulab/go-scim/pkg/core/json" - "github.com/imulab/go-scim/pkg/core/prop" - "github.com/imulab/go-scim/pkg/core/spec" - "github.com/imulab/go-scim/pkg/protocol/db" - "github.com/imulab/go-scim/pkg/protocol/log" + scimJSON "github.com/imulab/go-scim/core/json" + "github.com/imulab/go-scim/core/prop" + "github.com/imulab/go-scim/core/spec" + "github.com/imulab/go-scim/protocol/db" + "github.com/imulab/go-scim/protocol/log" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "github.com/stretchr/testify/suite" @@ -18,7 +18,7 @@ import ( func TestGetService(t *testing.T) { s := new(GetServiceTestSuite) - s.resourceBase = "../../tests/get_service_test_suite" + s.resourceBase = "./internal/get_service_test_suite" suite.Run(t, s) } diff --git a/pkg/tests/crud_test_suite/user_001.json b/protocol/services/internal/create_service_test_suite/user_001.json similarity index 100% rename from pkg/tests/crud_test_suite/user_001.json rename to protocol/services/internal/create_service_test_suite/user_001.json diff --git a/pkg/tests/create_service_test_suite/user_002.json b/protocol/services/internal/create_service_test_suite/user_002.json similarity index 100% rename from pkg/tests/create_service_test_suite/user_002.json rename to protocol/services/internal/create_service_test_suite/user_002.json diff --git a/pkg/tests/create_service_test_suite/user_003.json b/protocol/services/internal/create_service_test_suite/user_003.json similarity index 100% rename from pkg/tests/create_service_test_suite/user_003.json rename to protocol/services/internal/create_service_test_suite/user_003.json diff --git a/pkg/tests/replace_handler_test_suite/user_resource_type.json b/protocol/services/internal/create_service_test_suite/user_resource_type.json similarity index 100% rename from pkg/tests/replace_handler_test_suite/user_resource_type.json rename to protocol/services/internal/create_service_test_suite/user_resource_type.json diff --git a/pkg/tests/resource_test_suite/user_schema.json b/protocol/services/internal/create_service_test_suite/user_schema.json similarity index 100% rename from pkg/tests/resource_test_suite/user_schema.json rename to protocol/services/internal/create_service_test_suite/user_schema.json diff --git a/pkg/tests/query_service_test_suite/service_provider_config.json b/protocol/services/internal/delete_service_test_suite/service_provider_config.json similarity index 100% rename from pkg/tests/query_service_test_suite/service_provider_config.json rename to protocol/services/internal/delete_service_test_suite/service_provider_config.json diff --git a/pkg/tests/memory_db_test_suite/user_001.json b/protocol/services/internal/delete_service_test_suite/user_001.json similarity index 100% rename from pkg/tests/memory_db_test_suite/user_001.json rename to protocol/services/internal/delete_service_test_suite/user_001.json diff --git a/pkg/tests/patch_service_test_suite/user_resource_type.json b/protocol/services/internal/delete_service_test_suite/user_resource_type.json similarity index 100% rename from pkg/tests/patch_service_test_suite/user_resource_type.json rename to protocol/services/internal/delete_service_test_suite/user_resource_type.json diff --git a/pkg/tests/query_handler_test_suite/user_schema.json b/protocol/services/internal/delete_service_test_suite/user_schema.json similarity index 100% rename from pkg/tests/query_handler_test_suite/user_schema.json rename to protocol/services/internal/delete_service_test_suite/user_schema.json diff --git a/pkg/tests/query_handler_test_suite/user_001.json b/protocol/services/internal/get_service_test_suite/user_001.json similarity index 100% rename from pkg/tests/query_handler_test_suite/user_001.json rename to protocol/services/internal/get_service_test_suite/user_001.json diff --git a/pkg/tests/query_handler_test_suite/user_resource_type.json b/protocol/services/internal/get_service_test_suite/user_resource_type.json similarity index 100% rename from pkg/tests/query_handler_test_suite/user_resource_type.json rename to protocol/services/internal/get_service_test_suite/user_resource_type.json diff --git a/pkg/tests/query_service_test_suite/user_schema.json b/protocol/services/internal/get_service_test_suite/user_schema.json similarity index 100% rename from pkg/tests/query_service_test_suite/user_schema.json rename to protocol/services/internal/get_service_test_suite/user_schema.json diff --git a/pkg/tests/replace_handler_test_suite/service_provider_config.json b/protocol/services/internal/patch_service_test_suite/service_provider_config.json similarity index 100% rename from pkg/tests/replace_handler_test_suite/service_provider_config.json rename to protocol/services/internal/patch_service_test_suite/service_provider_config.json diff --git a/pkg/tests/replace_handler_test_suite/user_000.json b/protocol/services/internal/patch_service_test_suite/user_000.json similarity index 100% rename from pkg/tests/replace_handler_test_suite/user_000.json rename to protocol/services/internal/patch_service_test_suite/user_000.json diff --git a/pkg/tests/patch_service_test_suite/user_001.json b/protocol/services/internal/patch_service_test_suite/user_001.json similarity index 100% rename from pkg/tests/patch_service_test_suite/user_001.json rename to protocol/services/internal/patch_service_test_suite/user_001.json diff --git a/pkg/tests/query_service_test_suite/user_resource_type.json b/protocol/services/internal/patch_service_test_suite/user_resource_type.json similarity index 100% rename from pkg/tests/query_service_test_suite/user_resource_type.json rename to protocol/services/internal/patch_service_test_suite/user_resource_type.json diff --git a/pkg/tests/sort_resource_test_suite/user_schema.json b/protocol/services/internal/patch_service_test_suite/user_schema.json similarity index 100% rename from pkg/tests/sort_resource_test_suite/user_schema.json rename to protocol/services/internal/patch_service_test_suite/user_schema.json diff --git a/pkg/tests/replace_service_test_suite/service_provider_config.json b/protocol/services/internal/query_service_test_suite/service_provider_config.json similarity index 100% rename from pkg/tests/replace_service_test_suite/service_provider_config.json rename to protocol/services/internal/query_service_test_suite/service_provider_config.json diff --git a/pkg/tests/query_service_test_suite/user_001.json b/protocol/services/internal/query_service_test_suite/user_001.json similarity index 100% rename from pkg/tests/query_service_test_suite/user_001.json rename to protocol/services/internal/query_service_test_suite/user_001.json diff --git a/pkg/tests/query_service_test_suite/user_002.json b/protocol/services/internal/query_service_test_suite/user_002.json similarity index 100% rename from pkg/tests/query_service_test_suite/user_002.json rename to protocol/services/internal/query_service_test_suite/user_002.json diff --git a/pkg/tests/query_service_test_suite/user_003.json b/protocol/services/internal/query_service_test_suite/user_003.json similarity index 100% rename from pkg/tests/query_service_test_suite/user_003.json rename to protocol/services/internal/query_service_test_suite/user_003.json diff --git a/pkg/tests/query_service_test_suite/user_004.json b/protocol/services/internal/query_service_test_suite/user_004.json similarity index 100% rename from pkg/tests/query_service_test_suite/user_004.json rename to protocol/services/internal/query_service_test_suite/user_004.json diff --git a/pkg/tests/query_service_test_suite/user_005.json b/protocol/services/internal/query_service_test_suite/user_005.json similarity index 100% rename from pkg/tests/query_service_test_suite/user_005.json rename to protocol/services/internal/query_service_test_suite/user_005.json diff --git a/pkg/tests/query_service_test_suite/user_006.json b/protocol/services/internal/query_service_test_suite/user_006.json similarity index 100% rename from pkg/tests/query_service_test_suite/user_006.json rename to protocol/services/internal/query_service_test_suite/user_006.json diff --git a/pkg/tests/query_service_test_suite/user_007.json b/protocol/services/internal/query_service_test_suite/user_007.json similarity index 100% rename from pkg/tests/query_service_test_suite/user_007.json rename to protocol/services/internal/query_service_test_suite/user_007.json diff --git a/pkg/tests/query_service_test_suite/user_008.json b/protocol/services/internal/query_service_test_suite/user_008.json similarity index 100% rename from pkg/tests/query_service_test_suite/user_008.json rename to protocol/services/internal/query_service_test_suite/user_008.json diff --git a/pkg/tests/query_service_test_suite/user_009.json b/protocol/services/internal/query_service_test_suite/user_009.json similarity index 100% rename from pkg/tests/query_service_test_suite/user_009.json rename to protocol/services/internal/query_service_test_suite/user_009.json diff --git a/pkg/tests/query_service_test_suite/user_010.json b/protocol/services/internal/query_service_test_suite/user_010.json similarity index 100% rename from pkg/tests/query_service_test_suite/user_010.json rename to protocol/services/internal/query_service_test_suite/user_010.json diff --git a/pkg/tests/sort_resource_test_suite/user_resource_type.json b/protocol/services/internal/query_service_test_suite/user_resource_type.json similarity index 100% rename from pkg/tests/sort_resource_test_suite/user_resource_type.json rename to protocol/services/internal/query_service_test_suite/user_resource_type.json diff --git a/pkg/tests/subscriber_test_suite/user_schema.json b/protocol/services/internal/query_service_test_suite/user_schema.json similarity index 100% rename from pkg/tests/subscriber_test_suite/user_schema.json rename to protocol/services/internal/query_service_test_suite/user_schema.json diff --git a/pkg/tests/service_provider_config_handler_test_suite/service_provider_config.json b/protocol/services/internal/replace_service_test_suite/service_provider_config.json similarity index 100% rename from pkg/tests/service_provider_config_handler_test_suite/service_provider_config.json rename to protocol/services/internal/replace_service_test_suite/service_provider_config.json diff --git a/pkg/tests/replace_service_test_suite/user_000.json b/protocol/services/internal/replace_service_test_suite/user_000.json similarity index 100% rename from pkg/tests/replace_service_test_suite/user_000.json rename to protocol/services/internal/replace_service_test_suite/user_000.json diff --git a/pkg/tests/replace_service_test_suite/user_001.json b/protocol/services/internal/replace_service_test_suite/user_001.json similarity index 100% rename from pkg/tests/replace_service_test_suite/user_001.json rename to protocol/services/internal/replace_service_test_suite/user_001.json diff --git a/pkg/tests/replace_service_test_suite/user_002.json b/protocol/services/internal/replace_service_test_suite/user_002.json similarity index 100% rename from pkg/tests/replace_service_test_suite/user_002.json rename to protocol/services/internal/replace_service_test_suite/user_002.json diff --git a/pkg/tests/replace_service_test_suite/user_003.json b/protocol/services/internal/replace_service_test_suite/user_003.json similarity index 100% rename from pkg/tests/replace_service_test_suite/user_003.json rename to protocol/services/internal/replace_service_test_suite/user_003.json diff --git a/pkg/tests/replace_service_test_suite/user_resource_type.json b/protocol/services/internal/replace_service_test_suite/user_resource_type.json similarity index 100% rename from pkg/tests/replace_service_test_suite/user_resource_type.json rename to protocol/services/internal/replace_service_test_suite/user_resource_type.json diff --git a/pkg/tests/replace_service_test_suite/user_schema.json b/protocol/services/internal/replace_service_test_suite/user_schema.json similarity index 100% rename from pkg/tests/replace_service_test_suite/user_schema.json rename to protocol/services/internal/replace_service_test_suite/user_schema.json diff --git a/pkg/protocol/services/patch.go b/protocol/services/patch.go similarity index 84% rename from pkg/protocol/services/patch.go rename to protocol/services/patch.go index 5428aecd..20d46599 100644 --- a/pkg/protocol/services/patch.go +++ b/protocol/services/patch.go @@ -3,16 +3,16 @@ package services import ( "context" "encoding/json" - "github.com/imulab/go-scim/pkg/core/errors" - "github.com/imulab/go-scim/pkg/core/expr" - scimJSON "github.com/imulab/go-scim/pkg/core/json" - "github.com/imulab/go-scim/pkg/core/prop" - "github.com/imulab/go-scim/pkg/core/spec" - "github.com/imulab/go-scim/pkg/protocol/crud" - "github.com/imulab/go-scim/pkg/protocol/db" - "github.com/imulab/go-scim/pkg/protocol/event" - "github.com/imulab/go-scim/pkg/protocol/log" - "github.com/imulab/go-scim/pkg/protocol/services/filter" + "github.com/imulab/go-scim/core/errors" + "github.com/imulab/go-scim/core/expr" + scimJSON "github.com/imulab/go-scim/core/json" + "github.com/imulab/go-scim/core/prop" + "github.com/imulab/go-scim/core/spec" + "github.com/imulab/go-scim/protocol/crud" + "github.com/imulab/go-scim/protocol/db" + "github.com/imulab/go-scim/protocol/event" + "github.com/imulab/go-scim/protocol/log" + "github.com/imulab/go-scim/protocol/services/filter" ) const ( @@ -64,10 +64,11 @@ func (s *PatchService) PatchResource(ctx context.Context, request *PatchRequest) return nil, err } - s.Logger.Debug("received patch request [id=%s]", request.ResourceID) - if err := request.Validate(); err != nil { - s.Logger.Error("patch request for [id=%s] is invalid: %s", request.ResourceID, err.Error()) + s.Logger.Error("patch request is invalid", log.Args{ + "resourceId": request.ResourceID, + "error": err, + }) return nil, err } @@ -84,7 +85,10 @@ func (s *PatchService) PatchResource(ctx context.Context, request *PatchRequest) resource := ref.Clone() for _, f := range s.PrePatchFilters { if err := f.FilterRef(ctx, resource, ref); err != nil { - s.Logger.Error("patch request encounter error during filter for resource [id=%s]: %s", request.ResourceID, err.Error()) + s.Logger.Error("patch request encounter error during filter for resource", log.Args{ + "resourceId": request.ResourceID, + "error": err, + }) return nil, err } } @@ -112,7 +116,10 @@ func (s *PatchService) PatchResource(ctx context.Context, request *PatchRequest) for _, f := range s.PostPatchFilters { if err := f.FilterRef(ctx, resource, ref); err != nil { - s.Logger.Error("patch request encounter error during filter for resource [id=%s]: %s", request.ResourceID, err.Error()) + s.Logger.Error("patch request encounter error during filter for resource", log.Args{ + "resourceId": request.ResourceID, + "error": err, + }) return nil, err } } @@ -121,10 +128,15 @@ func (s *PatchService) PatchResource(ctx context.Context, request *PatchRequest) if resource.Version() != ref.Version() { err = s.Database.Replace(ctx, resource) if err != nil { - s.Logger.Error("resource [id=%s] failed to save into persistence: %s", request.ResourceID, err.Error()) + s.Logger.Error("failed to save to persistence", log.Args{ + "resourceId": request.ResourceID, + "error": err, + }) return nil, err } - s.Logger.Debug("resource [id=%s] saved in persistence", request.ResourceID) + s.Logger.Debug("saved in persistence", log.Args{ + "resourceId": request.ResourceID, + }) if s.Event != nil { s.Event.ResourceUpdated(ctx, resource, ref) diff --git a/pkg/protocol/services/patch_test.go b/protocol/services/patch_test.go similarity index 96% rename from pkg/protocol/services/patch_test.go rename to protocol/services/patch_test.go index bc4fce69..808bfdf6 100644 --- a/pkg/protocol/services/patch_test.go +++ b/protocol/services/patch_test.go @@ -3,13 +3,13 @@ package services import ( "context" "encoding/json" - "github.com/imulab/go-scim/pkg/core/expr" - scimJSON "github.com/imulab/go-scim/pkg/core/json" - "github.com/imulab/go-scim/pkg/core/prop" - "github.com/imulab/go-scim/pkg/core/spec" - "github.com/imulab/go-scim/pkg/protocol/db" - "github.com/imulab/go-scim/pkg/protocol/log" - "github.com/imulab/go-scim/pkg/protocol/services/filter" + "github.com/imulab/go-scim/core/expr" + scimJSON "github.com/imulab/go-scim/core/json" + "github.com/imulab/go-scim/core/prop" + "github.com/imulab/go-scim/core/spec" + "github.com/imulab/go-scim/protocol/db" + "github.com/imulab/go-scim/protocol/log" + "github.com/imulab/go-scim/protocol/services/filter" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "github.com/stretchr/testify/suite" @@ -20,7 +20,7 @@ import ( func TestPatchService(t *testing.T) { s := new(PatchServiceTestSuite) - s.resourceBase = "../../tests/patch_service_test_suite" + s.resourceBase = "./internal/patch_service_test_suite" suite.Run(t, s) } diff --git a/pkg/protocol/services/query.go b/protocol/services/query.go similarity index 88% rename from pkg/protocol/services/query.go rename to protocol/services/query.go index 3e06dac3..473db856 100644 --- a/pkg/protocol/services/query.go +++ b/protocol/services/query.go @@ -2,13 +2,13 @@ package services import ( "context" - "github.com/imulab/go-scim/pkg/core/errors" - "github.com/imulab/go-scim/pkg/core/expr" - "github.com/imulab/go-scim/pkg/core/prop" - "github.com/imulab/go-scim/pkg/core/spec" - "github.com/imulab/go-scim/pkg/protocol/crud" - "github.com/imulab/go-scim/pkg/protocol/db" - "github.com/imulab/go-scim/pkg/protocol/log" + "github.com/imulab/go-scim/core/errors" + "github.com/imulab/go-scim/core/expr" + "github.com/imulab/go-scim/core/prop" + "github.com/imulab/go-scim/core/spec" + "github.com/imulab/go-scim/protocol/crud" + "github.com/imulab/go-scim/protocol/db" + "github.com/imulab/go-scim/protocol/log" ) type ( @@ -76,7 +76,9 @@ func (s *QueryService) QueryResource(ctx context.Context, request *QueryRequest) resp.Resources, err = s.Database.Query(ctx, request.Filter, request.Sort, request.Pagination, request.Projection) if err != nil { - s.Logger.Error("failed to query resource: %s", err.Error()) + s.Logger.Error("failed to query resource", log.Args{ + "error": err, + }) return } resp.ItemsPerPage = len(resp.Resources) diff --git a/pkg/protocol/services/query_test.go b/protocol/services/query_test.go similarity index 96% rename from pkg/protocol/services/query_test.go rename to protocol/services/query_test.go index 448515d4..826546cf 100644 --- a/pkg/protocol/services/query_test.go +++ b/protocol/services/query_test.go @@ -3,12 +3,12 @@ package services import ( "context" "encoding/json" - scimJSON "github.com/imulab/go-scim/pkg/core/json" - "github.com/imulab/go-scim/pkg/core/prop" - "github.com/imulab/go-scim/pkg/core/spec" - "github.com/imulab/go-scim/pkg/protocol/crud" - "github.com/imulab/go-scim/pkg/protocol/db" - "github.com/imulab/go-scim/pkg/protocol/log" + scimJSON "github.com/imulab/go-scim/core/json" + "github.com/imulab/go-scim/core/prop" + "github.com/imulab/go-scim/core/spec" + "github.com/imulab/go-scim/protocol/crud" + "github.com/imulab/go-scim/protocol/db" + "github.com/imulab/go-scim/protocol/log" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "github.com/stretchr/testify/suite" @@ -19,7 +19,7 @@ import ( func TestQueryService(t *testing.T) { s := new(QueryServiceTestSuite) - s.resourceBase = "../../tests/query_service_test_suite" + s.resourceBase = "./internal/query_service_test_suite" suite.Run(t, s) } diff --git a/pkg/protocol/services/replace.go b/protocol/services/replace.go similarity index 71% rename from pkg/protocol/services/replace.go rename to protocol/services/replace.go index 4c24c8a0..a18a903d 100644 --- a/pkg/protocol/services/replace.go +++ b/protocol/services/replace.go @@ -2,13 +2,13 @@ package services import ( "context" - "github.com/imulab/go-scim/pkg/core/errors" - "github.com/imulab/go-scim/pkg/core/prop" - "github.com/imulab/go-scim/pkg/core/spec" - "github.com/imulab/go-scim/pkg/protocol/db" - "github.com/imulab/go-scim/pkg/protocol/event" - "github.com/imulab/go-scim/pkg/protocol/log" - "github.com/imulab/go-scim/pkg/protocol/services/filter" + "github.com/imulab/go-scim/core/errors" + "github.com/imulab/go-scim/core/prop" + "github.com/imulab/go-scim/core/spec" + "github.com/imulab/go-scim/protocol/db" + "github.com/imulab/go-scim/protocol/event" + "github.com/imulab/go-scim/protocol/log" + "github.com/imulab/go-scim/protocol/services/filter" ) type ( @@ -33,8 +33,6 @@ type ( ) func (s *ReplaceService) ReplaceResource(ctx context.Context, request *ReplaceRequest) (*ReplaceResponse, error) { - s.Logger.Debug("received replace request [id=%s]", request.ResourceID) - ref, err := s.Database.Get(ctx, request.ResourceID, nil) if err != nil { return nil, err @@ -47,7 +45,10 @@ func (s *ReplaceService) ReplaceResource(ctx context.Context, request *ReplaceRe for _, f := range s.Filters { if err := f.FilterRef(ctx, request.Payload, ref); err != nil { - s.Logger.Error("replace request encounter error during filter for resource [id=%s]: %s", request.ResourceID, err.Error()) + s.Logger.Error("replace request encounter error during filter for resource", log.Args{ + "resourceId": request.ResourceID, + "error": err, + }) return nil, err } } @@ -56,10 +57,15 @@ func (s *ReplaceService) ReplaceResource(ctx context.Context, request *ReplaceRe if request.Payload.Version() != ref.Version() { err = s.Database.Replace(ctx, request.Payload) if err != nil { - s.Logger.Error("resource [id=%s] failed to save into persistence: %s", request.ResourceID, err.Error()) + s.Logger.Error("failed to save into persistence", log.Args{ + "resourceId": request.ResourceID, + "error": err, + }) return nil, err } - s.Logger.Debug("resource [id=%s] saved in persistence", request.ResourceID) + s.Logger.Debug("saved in persistence", log.Args{ + "resourceId": request.ResourceID, + }) if s.Event != nil { s.Event.ResourceUpdated(ctx, request.Payload, ref) diff --git a/pkg/protocol/services/replace_test.go b/protocol/services/replace_test.go similarity index 93% rename from pkg/protocol/services/replace_test.go rename to protocol/services/replace_test.go index 2468a02c..ed001204 100644 --- a/pkg/protocol/services/replace_test.go +++ b/protocol/services/replace_test.go @@ -3,12 +3,12 @@ package services import ( "context" "encoding/json" - scimJSON "github.com/imulab/go-scim/pkg/core/json" - "github.com/imulab/go-scim/pkg/core/prop" - "github.com/imulab/go-scim/pkg/core/spec" - "github.com/imulab/go-scim/pkg/protocol/db" - "github.com/imulab/go-scim/pkg/protocol/log" - "github.com/imulab/go-scim/pkg/protocol/services/filter" + scimJSON "github.com/imulab/go-scim/core/json" + "github.com/imulab/go-scim/core/prop" + "github.com/imulab/go-scim/core/spec" + "github.com/imulab/go-scim/protocol/db" + "github.com/imulab/go-scim/protocol/log" + "github.com/imulab/go-scim/protocol/services/filter" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "github.com/stretchr/testify/suite" @@ -19,7 +19,7 @@ import ( func TestReplaceService(t *testing.T) { s := new(ReplaceServiceTestSuite) - s.resourceBase = "../../tests/replace_service_test_suite" + s.resourceBase = "./internal/replace_service_test_suite" suite.Run(t, s) } diff --git a/server/api/cmd.go b/server/api/cmd.go new file mode 100644 index 00000000..a4541b53 --- /dev/null +++ b/server/api/cmd.go @@ -0,0 +1,118 @@ +package api + +import ( + "fmt" + "github.com/imulab/go-scim/protocol/log" + "github.com/julienschmidt/httprouter" + "github.com/urfave/cli/v2" + "net/http" +) + +type args struct { + serviceProviderConfigPath string + userResourceTypePath string + groupResourceTypePath string + schemasFolderPath string + memoryDB bool + httpPort int + rabbitMqAddress string +} + +func Command() *cli.Command { + args := new(args) + return &cli.Command{ + Name: "api", + Usage: "Serves API for SCIM (Simple Cloud Identity Management) protocol", + Description: "Manage state of resources defined in the SCIM (Simple Cloud Identity Management) protocol", + Flags: []cli.Flag{ + &cli.StringFlag{ + Name: "user", + Aliases: []string{"u"}, + Usage: "Absolute file path to User resource type JSON definition", + EnvVars: []string{"USER_RESOURCE_TYPE"}, + Required: true, + Destination: &args.userResourceTypePath, + }, + &cli.StringFlag{ + Name: "group", + Aliases: []string{"g"}, + Usage: "Absolute file path to Group resource type JSON definition", + EnvVars: []string{"GROUP_RESOURCE_TYPE"}, + Required: true, + Destination: &args.groupResourceTypePath, + }, + &cli.StringFlag{ + Name: "schemas", + Aliases: []string{"s"}, + Usage: "Absolute path to the folder containing all schema JSON definitions", + EnvVars: []string{"SCHEMAS"}, + Required: true, + Destination: &args.schemasFolderPath, + }, + &cli.StringFlag{ + Name: "spc", + Aliases: []string{"c"}, + Usage: "Absolute path to Service Provider Config JSON definition", + EnvVars: []string{"SERVICE_PROVIDER_CONFIG"}, + Required: true, + Destination: &args.serviceProviderConfigPath, + }, + &cli.BoolFlag{ + Name: "memory", + Usage: "Use in memory database", + Value: false, + Destination: &args.memoryDB, + }, + &cli.StringFlag{ + Name: "rabbit-address", + Usage: "AMQP connection string to RabbitMQ", + EnvVars: []string{"RABBIT_ADDRESS"}, + Required: true, + Value: "amqp://guest:guest@localhost:5672/", + Destination: &args.rabbitMqAddress, + }, + &cli.IntFlag{ + Name: "port", + Aliases: []string{"p"}, + Usage: "HTTP port that the server listens on", + EnvVars: []string{"HTTP_PORT"}, + Value: 8080, + Destination: &args.httpPort, + }, + }, + Action: func(context *cli.Context) error { + var appCtx *appContext + { + appCtx = new(appContext) + if err := appCtx.initialize(args); err != nil { + return err + } + appCtx.logger.Info("application appContext initialized", log.Args{}) + } + + var router = httprouter.New() + { + router.GET("/ServiceProviderConfig", routeHandler(appCtx.serviceProviderConfigHandler.Handle)) + + router.GET("/Users/:id", routeHandler(appCtx.userGetHandler.Handle)) + router.GET("/Users", routeHandler(appCtx.userQueryHandler.Handle)) + router.POST("/Users", routeHandler(appCtx.userCreateHandler.Handle)) + router.PUT("/Users/:id", routeHandler(appCtx.userReplaceHandler.Handle)) + router.PATCH("/Users/:id", routeHandler(appCtx.userPatchHandler.Handle)) + router.DELETE("/Users/:id", routeHandler(appCtx.userDeleteHandler.Handle)) + + router.GET("/Groups/:id", routeHandler(appCtx.groupGetHandler.Handle)) + router.GET("/Groups", routeHandler(appCtx.groupQueryHandler.Handle)) + router.POST("/Groups", routeHandler(appCtx.groupCreateHandler.Handle)) + router.PUT("/Groups/:id", routeHandler(appCtx.groupReplaceHandler.Handle)) + router.PATCH("/Groups/:id", routeHandler(appCtx.groupPatchHandler.Handle)) + router.DELETE("/Groups/:id", routeHandler(appCtx.groupDeleteHandler.Handle)) + } + + appCtx.logger.Info("listening for incoming requests", log.Args{ + "port": args.httpPort, + }) + return http.ListenAndServe(fmt.Sprintf(":%d", args.httpPort), router) + }, + } +} diff --git a/server/api/context.go b/server/api/context.go new file mode 100644 index 00000000..727ecdc4 --- /dev/null +++ b/server/api/context.go @@ -0,0 +1,376 @@ +package api + +import ( + "encoding/json" + "github.com/imulab/go-scim/core/expr" + "github.com/imulab/go-scim/core/spec" + "github.com/imulab/go-scim/protocol/db" + "github.com/imulab/go-scim/protocol/event" + "github.com/imulab/go-scim/protocol/handler" + "github.com/imulab/go-scim/protocol/log" + "github.com/imulab/go-scim/protocol/services" + "github.com/imulab/go-scim/protocol/services/filter" + "github.com/imulab/go-scim/server/groupsync" + "github.com/imulab/go-scim/server/logger" + "github.com/streadway/amqp" + "io/ioutil" + "os" + "path/filepath" + "strings" +) + +type appContext struct { + serviceProviderConfig *spec.ServiceProviderConfig + serviceProviderConfigHandler *handler.ServiceProviderConfig + rabbitMqCh *amqp.Channel + logger log.Logger + + // user related + userResourceType *spec.ResourceType + userDatabase db.DB + userCreateService *services.CreateService + userReplaceService *services.ReplaceService + userPatchService *services.PatchService + userDeleteService *services.DeleteService + userGetService *services.GetService + userQueryService *services.QueryService + userCreateHandler *handler.Create + userReplaceHandler *handler.Replace + userPatchHandler *handler.Patch + userDeleteHandler *handler.Delete + userGetHandler *handler.Get + userQueryHandler *handler.Query + + // group related + groupResourceType *spec.ResourceType + groupDatabase db.DB + groupCreateService *services.CreateService + groupReplaceService *services.ReplaceService + groupPatchService *services.PatchService + groupDeleteService *services.DeleteService + groupGetService *services.GetService + groupQueryService *services.QueryService + groupCreateHandler *handler.Create + groupReplaceHandler *handler.Replace + groupPatchHandler *handler.Patch + groupDeleteHandler *handler.Delete + groupGetHandler *handler.Get + groupQueryHandler *handler.Query + + // todo root related: bulk, root query +} + +func (c *appContext) initialize(args *args) error { + if err := c.loadLogger(); err != nil { + return err + } + if err := c.loadServiceProviderConfig(args.serviceProviderConfigPath, c.serviceProviderConfig); err != nil { + return err + } + if err := c.loadSchemasInFolder(args.schemasFolderPath); err != nil { + return err + } + if err := c.loadRabbitMqChannel(args); err != nil { + return err + } + + // user related + if err := c.loadResourceType(args.userResourceTypePath, c.userResourceType); err != nil { + return err + } + if err := c.loadUserDatabase(args); err != nil { + return err + } + if err := c.loadUserServices(); err != nil { + return err + } + if err := c.loadUserHandlers(); err != nil { + return err + } + + // group related + if err := c.loadResourceType(args.groupResourceTypePath, c.groupResourceType); err != nil { + return err + } + if err := c.loadGroupDatabase(args); err != nil { + return err + } + if err := c.loadGroupServices(); err != nil { + return err + } + if err := c.loadGroupHandlers(); err != nil { + return err + } + + return nil +} + +func (c *appContext) loadUserHandlers() error { + c.userCreateHandler = &handler.Create{ + Log: c.logger, + Service: c.userCreateService, + ResourceType: c.userResourceType, + } + c.userReplaceHandler = &handler.Replace{ + Log: c.logger, + Service: c.userReplaceService, + ResourceIDPathParam: "id", + ResourceType: c.userResourceType, + } + c.userPatchHandler = &handler.Patch{ + Log: c.logger, + Service: c.userPatchService, + ResourceIDPathParam: "id", + } + c.userDeleteHandler = &handler.Delete{ + Log: c.logger, + Service: c.userDeleteService, + ResourceIDPathParam: "id", + } + c.userGetHandler = &handler.Get{ + Log: c.logger, + Service: c.userGetService, + ResourceIDPathParam: "id", + } + c.userQueryHandler = &handler.Query{ + Log: c.logger, + Service: c.userQueryService, + } + return nil +} + +func (c *appContext) loadGroupHandlers() error { + c.groupCreateHandler = &handler.Create{ + Log: c.logger, + Service: c.groupCreateService, + ResourceType: c.userResourceType, + } + c.groupReplaceHandler = &handler.Replace{ + Log: c.logger, + Service: c.groupReplaceService, + ResourceIDPathParam: "id", + ResourceType: c.groupResourceType, + } + c.groupPatchHandler = &handler.Patch{ + Log: c.logger, + Service: c.groupPatchService, + ResourceIDPathParam: "id", + } + c.groupDeleteHandler = &handler.Delete{ + Log: c.logger, + Service: c.groupDeleteService, + ResourceIDPathParam: "id", + } + c.groupGetHandler = &handler.Get{ + Log: c.logger, + Service: c.groupGetService, + ResourceIDPathParam: "id", + } + c.groupQueryHandler = &handler.Query{ + Log: c.logger, + Service: c.groupQueryService, + } + return nil +} + +func (c *appContext) loadUserServices() error { + c.userCreateService = &services.CreateService{ + Logger: c.logger, + Database: c.userDatabase, + Filters: []filter.ForResource{ + filter.ClearReadOnly(), + filter.ID(), + filter.Password(10), + filter.Meta(), + filter.Validation(c.userDatabase), + }, + } + c.userReplaceService = &services.ReplaceService{ + Logger: c.logger, + Database: c.userDatabase, + ServiceProviderConfig: c.serviceProviderConfig, + Filters: []filter.ForResource{ + filter.ClearReadOnly(), + filter.CopyReadOnly(), + filter.Password(10), + filter.Validation(c.userDatabase), + filter.Meta(), + }, + } + c.userPatchService = &services.PatchService{ + Logger: c.logger, + Database: c.userDatabase, + ServiceProviderConfig: c.serviceProviderConfig, + PrePatchFilters: []filter.ForResource{}, + PostPatchFilters: []filter.ForResource{ + filter.CopyReadOnly(), + filter.Password(10), + filter.Validation(c.userDatabase), + filter.Meta(), + }, + } + c.userDeleteService = &services.DeleteService{ + Logger: c.logger, + Database: c.userDatabase, + ServiceProviderConfig: c.serviceProviderConfig, + } + c.userGetService = &services.GetService{ + Logger: c.logger, + Database: c.userDatabase, + } + c.userQueryService = &services.QueryService{ + Logger: c.logger, + Database: c.userDatabase, + ServiceProviderConfig: c.serviceProviderConfig, + } + return nil +} + +func (c *appContext) loadGroupServices() error { + syncSender, err := groupsync.Sender(c.rabbitMqCh, c.logger) + if err != nil { + return err + } + c.groupCreateService = &services.CreateService{ + Logger: c.logger, + Database: c.groupDatabase, + Filters: []filter.ForResource{ + filter.ClearReadOnly(), + filter.ID(), + filter.Meta(), + filter.Validation(c.groupDatabase), + }, + Event: event.Of(syncSender), + } + c.groupReplaceService = &services.ReplaceService{ + Logger: c.logger, + Database: c.groupDatabase, + ServiceProviderConfig: c.serviceProviderConfig, + Filters: []filter.ForResource{ + filter.ClearReadOnly(), + filter.CopyReadOnly(), + filter.Validation(c.groupDatabase), + filter.Meta(), + }, + Event: event.Of(syncSender), + } + c.groupPatchService = &services.PatchService{ + Logger: c.logger, + Database: c.groupDatabase, + ServiceProviderConfig: c.serviceProviderConfig, + PrePatchFilters: []filter.ForResource{}, + PostPatchFilters: []filter.ForResource{ + filter.CopyReadOnly(), + filter.Validation(c.groupDatabase), + filter.Meta(), + }, + Event: event.Of(syncSender), + } + c.groupDeleteService = &services.DeleteService{ + Logger: c.logger, + Database: c.groupDatabase, + ServiceProviderConfig: c.serviceProviderConfig, + Event: syncSender, + } + c.groupGetService = &services.GetService{ + Logger: c.logger, + Database: c.groupDatabase, + } + c.groupQueryService = &services.QueryService{ + Logger: c.logger, + Database: c.groupDatabase, + ServiceProviderConfig: c.serviceProviderConfig, + } + return nil +} + +func (c *appContext) loadUserDatabase(args *args) error { + c.userDatabase = db.Memory() + return nil +} + +func (c *appContext) loadGroupDatabase(args *args) error { + c.groupDatabase = db.Memory() + return nil +} + +func (c *appContext) loadResourceType(path string, dest *spec.ResourceType) error { + raw, err := c.readFile(path) + if err != nil { + return err + } + dest = new(spec.ResourceType) + err = json.Unmarshal(raw, dest) + if err != nil { + return err + } + expr.Register(dest) + return nil +} + +func (c *appContext) loadSchemasInFolder(folder string) error { + return filepath.Walk(folder, func(path string, info os.FileInfo, err error) error { + if err != nil { + return err + } + if strings.HasSuffix(info.Name(), ".json") { + raw, err := c.readFile(path) + if err != nil { + return err + } + schema := new(spec.Schema) + err = json.Unmarshal(raw, schema) + if err != nil { + return err + } + spec.SchemaHub.Put(schema) + } + return nil + }) +} + +func (c *appContext) loadLogger() error { + c.logger = logger.Zero() + return nil +} + +func (c *appContext) loadServiceProviderConfig(path string, dest *spec.ServiceProviderConfig) error { + raw, err := c.readFile(path) + if err != nil { + return err + } + dest = new(spec.ServiceProviderConfig) + if err = json.Unmarshal(raw, dest); err != nil { + return err + } + c.serviceProviderConfigHandler = &handler.ServiceProviderConfig{ + Log: c.logger, + SPC: dest, + } + return nil +} + +func (c *appContext) loadRabbitMqChannel(args *args) (err error) { + conn, err := amqp.Dial(args.rabbitMqAddress) + if err != nil { + return err + } + ch, err := conn.Channel() + if err != nil { + return err + } + c.rabbitMqCh = ch + return +} + +func (c *appContext) readFile(path string) ([]byte, error) { + f, err := os.Open(path) + if err != nil { + return nil, err + } + raw, err := ioutil.ReadAll(f) + if err != nil { + return nil, err + } + return raw, nil +} diff --git a/server/api/http.go b/server/api/http.go new file mode 100644 index 00000000..20084361 --- /dev/null +++ b/server/api/http.go @@ -0,0 +1,54 @@ +package api + +import ( + "context" + scimHttp "github.com/imulab/go-scim/protocol/http" + "github.com/julienschmidt/httprouter" + "io/ioutil" + "net/http" +) + +func routeHandler(h func(request scimHttp.Request, response scimHttp.Response)) func(w http.ResponseWriter, r *http.Request, ps httprouter.Params) { + return func(rw http.ResponseWriter, r *http.Request, ps httprouter.Params) { + h(&httpRequest{ + req: r, + ps: ps, + }, scimHttp.DefaultResponse(rw)) + } +} + +type httpRequest struct { + req *http.Request + ps httprouter.Params +} + +func (r *httpRequest) Context() context.Context { + return r.req.Context() +} + +func (r *httpRequest) Method() string { + return r.req.Method +} + +func (r *httpRequest) Header(key string) string { + return r.req.Header.Get(key) +} + +func (r *httpRequest) PathParam(param string) string { + return r.ps.ByName(param) +} + +func (r *httpRequest) QueryParam(param string) string { + return r.req.URL.Query().Get(param) +} + +func (r *httpRequest) ContentType() string { + return r.req.Header.Get("Content-Type") +} + +func (r *httpRequest) Body() ([]byte, error) { + defer func() { + _ = r.req.Body.Close() + }() + return ioutil.ReadAll(r.req.Body) +} diff --git a/server/go.mod b/server/go.mod new file mode 100644 index 00000000..cfafe8fb --- /dev/null +++ b/server/go.mod @@ -0,0 +1,15 @@ +module github.com/imulab/go-scim/server + +require ( + github.com/imulab/go-scim/core v0.0.0 + github.com/imulab/go-scim/protocol v0.0.0 + github.com/julienschmidt/httprouter v1.3.0 + github.com/rs/zerolog v1.17.2 + github.com/satori/go.uuid v1.2.0 + github.com/streadway/amqp v0.0.0-20190827072141-edfb9018d271 + github.com/urfave/cli/v2 v2.0.0 +) + +replace github.com/imulab/go-scim/core => ../core + +replace github.com/imulab/go-scim/protocol => ../protocol diff --git a/server/go.sum b/server/go.sum new file mode 100644 index 00000000..ccd342f7 --- /dev/null +++ b/server/go.sum @@ -0,0 +1,43 @@ +github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= +github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d h1:U+s90UTSYgptZMwQh2aRr3LuazLJIa+Pg3Kc1ylSYVY= +github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= +github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/julienschmidt/httprouter v1.3.0 h1:U0609e9tgbseu3rBINet9P48AI/D3oJs4dN7jwJOQ1U= +github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM= +github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ= +github.com/rs/zerolog v1.17.2 h1:RMRHFw2+wF7LO0QqtELQwo8hqSmqISyCJeFeAAuWcRo= +github.com/rs/zerolog v1.17.2/go.mod h1:9nvC1axdVrAHcu/s9taAVfBuIdTZLVQmKQyvrUjF5+I= +github.com/russross/blackfriday/v2 v2.0.1 h1:lPqVAte+HuHNfhJ/0LC98ESWRz8afy9tM/0RK8m9o+Q= +github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/satori/go.uuid v1.2.0 h1:0uYX9dsZ2yD7q2RtLRtPSdGDWzjeM3TbMJP9utgA0ww= +github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0= +github.com/shurcooL/sanitized_anchor_name v1.0.0 h1:PdmoCO6wvbs+7yrJyMORt4/BmY5IYyJwS/kOiWx8mHo= +github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= +github.com/streadway/amqp v0.0.0-20190827072141-edfb9018d271 h1:WhxRHzgeVGETMlmVfqhRn8RIeeNoPr2Czh33I4Zdccw= +github.com/streadway/amqp v0.0.0-20190827072141-edfb9018d271/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk= +github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= +github.com/urfave/cli/v2 v2.0.0 h1:+HU9SCbu8GnEUFtIBfuUNXN39ofWViIEJIp6SURMpCg= +github.com/urfave/cli/v2 v2.0.0/go.mod h1:SE9GqnLQmjVa0iPEY0f1w3ygNIYcIJ0OKPMoW2caLfQ= +github.com/zenazn/goji v0.9.0/go.mod h1:7S9M489iMyHBNxwZnk9/EHS098H4/F6TATF2mIxtB1Q= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20191206172530-e9b2fee46413 h1:ULYEB3JvPRE/IfO+9uO7vKV/xzVTO7XPAwm8xbf4w2g= +golang.org/x/crypto v0.0.0-20191206172530-e9b2fee46413/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/tools v0.0.0-20190828213141-aed303cbaa74/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= diff --git a/server/groupsync/cmd.go b/server/groupsync/cmd.go new file mode 100644 index 00000000..e52011d8 --- /dev/null +++ b/server/groupsync/cmd.go @@ -0,0 +1,63 @@ +package groupsync + +import ( + "context" + "github.com/imulab/go-scim/protocol/log" + "github.com/urfave/cli/v2" + "os" + "os/signal" + "syscall" +) + +type args struct { + //serviceProviderConfigPath string + //userResourceTypePath string + //groupResourceTypePath string + //schemasFolderPath string + //memoryDB bool + requeueLimit int + rabbitMqAddress string +} + +func Command() *cli.Command { + args := new(args) + return &cli.Command{ + Name: "group-sync", + Aliases: []string{"gs", "sync"}, + Description: "Asynchronously refresh user resource for group membership changes", + Flags: []cli.Flag{ + &cli.StringFlag{ + Name: "rabbit-address", + Usage: "AMQP connection string to RabbitMQ", + EnvVars: []string{"RABBIT_ADDRESS"}, + Destination: &args.rabbitMqAddress, + Required: true, + Value: "amqp://guest:guest@localhost:5672/", + }, + }, + Action: func(cliContext *cli.Context) error { + appCtx := new(appContext) + if err := appCtx.initialize(args); err != nil { + return err + } + defer func() { + _ = appCtx.rabbitCh.Close() + }() + + ctx, cancelFunc := context.WithCancel(context.Background()) + safeExit, err := StartConsumer(ctx, appCtx, args) + if err != nil { + return err + } + + term := make(chan os.Signal) + signal.Notify(term, syscall.SIGINT, syscall.SIGTERM) + <-term + appCtx.logger.Info("received terminate signal, waiting to abort", log.Args{}) + cancelFunc() + <-safeExit + + return nil + }, + } +} diff --git a/server/groupsync/consumer.go b/server/groupsync/consumer.go new file mode 100644 index 00000000..d1a3762c --- /dev/null +++ b/server/groupsync/consumer.go @@ -0,0 +1,196 @@ +package groupsync + +import ( + "context" + "encoding/json" + "fmt" + "github.com/imulab/go-scim/core/prop" + "github.com/imulab/go-scim/protocol/db" + "github.com/imulab/go-scim/protocol/groupsync" + "github.com/imulab/go-scim/protocol/log" + uuid "github.com/satori/go.uuid" + "github.com/streadway/amqp" + "time" +) + +// Start the message consuming process with the cancellable context and return a safe exit channel. The cancellable +// context can be used to notify the consumer that it should abort. However, the consumer only checks for this signal +// before processing each message and hence may not immediately abort. The returned safe exit channel can be received +// by the caller process when the consumer is truly ready to exit. +func StartConsumer(ctx context.Context, appCtx *appContext, args *args) (safeExit chan struct{}, err error) { + if err := declareRabbitQueue(appCtx.rabbitCh, appCtx.logger); err != nil { + return nil, err + } + c := &consumer{ + ch: appCtx.rabbitCh, + userDB: appCtx.userDB, + groupDB: appCtx.groupDB, + trialLimit: args.requeueLimit, + logger: appCtx.logger, + } + safeExit, err = c.Consume(ctx) + return +} + +type consumer struct { + ch *amqp.Channel + userDB db.DB + groupDB db.DB + trialLimit int + logger log.Logger +} + +func (c *consumer) Consume(ctx context.Context) (chan struct{}, error) { + msgs, err := c.ch.Consume( + queueName, + "", + true, + false, + false, + false, + nil, + ) + if err != nil { + c.logger.Error("failed to consume message", log.Args{ + "error": err, + }) + return nil, err + } + + exitChan := make(chan struct{}, 1) + + go func() { + for msg := range msgs { + select { + case <-ctx.Done(): + exitChan <- struct{}{} + return + default: + c.handle(msg) + } + } + }() + + return exitChan, nil +} + +func (c *consumer) handle(msg amqp.Delivery) { + message := new(message) + if err := json.Unmarshal(msg.Body, message); err != nil { + c.logger.Error("message body is corrupted, will drop message", log.Args{ + "error": err, + "message": string(msg.Body), + }) + return + } + + if c.trialLimit > 0 && message.Trial > c.trialLimit { + c.logger.Error("message had exceeded trial limit, will drop message", log.Args{ + "message": string(msg.Body), + "trial": message.Trial, + "limit": c.trialLimit, + }) + return + } + + if user, err := c.userDB.Get(context.Background(), message.MemberID, nil); err == nil && user != nil { + if err := c.syncUserGroup(user); err != nil { + c.logger.Error("error encountered while syncing user group, will requeue", log.Args{ + "error": err, + "message": fmt.Sprintf("%+v", message), + }) + c.send(message) + } else { + c.logger.Info("successfully synced user group", log.Args{ + "userId": message.MemberID, + }) + } + return + } + + c.logger.Debug("message does not entail user, assuming group resource", log.Args{ + "message": fmt.Sprintf("%+v", message), + }) + + if group, err := c.groupDB.Get(context.Background(), message.MemberID, nil); err == nil && group != nil { + if err := c.expandSyncScope(message, group); err != nil { + c.logger.Error("error encountered while expanding sync scope for group member, will requeue", log.Args{ + "error": err, + "message": fmt.Sprintf("%+v", message), + }) + c.send(message) + } else { + c.logger.Info("successfully expand sync scope for group", log.Args{ + "groupId": message.MemberID, + }) + } + return + } + + c.logger.Error("message entail neither user nor group, aborted", log.Args{ + "message": fmt.Sprintf("%+v", message), + }) +} + +func (c *consumer) syncUserGroup(user *prop.Resource) error { + if err := groupsync.Refresher(c.groupDB).Refresh(context.Background(), user); err != nil { + return err + } + if err := c.userDB.Replace(context.Background(), user); err != nil { + return err + } + return nil +} + +func (c *consumer) expandSyncScope(originalMsg *message, group *prop.Resource) error { + if nav := group.NewFluentNavigator().FocusName("members"); nav.Error() != nil { + return nav.Error() + } else { + _ = nav.CurrentAsContainer().ForEachChild(func(index int, child prop.Property) error { + if vp := child.(prop.Container).ChildAtIndex("value"); vp != nil && !vp.IsUnassigned() { + c.send(&message{ + GroupID: originalMsg.GroupID, + MemberID: vp.Raw().(string), + }) + } + return nil + }) + return nil + } +} + +func (c *consumer) send(message *message) { + message.Trial++ + + action := "send" + if message.Trial > 1 { + action = "requeue" + } + + raw, err := json.Marshal(message) + if err != nil { + c.logger.Error(fmt.Sprintf("failed to parse message to JSON, will not %s", action), log.Args{ + "error": err, + "message": fmt.Sprintf("%+v", message), + }) + return + } + err = c.ch.Publish( + exchangeName, + queueName, + false, + false, + amqp.Publishing{ + ContentType: "application/json", + MessageId: uuid.NewV4().String(), + Timestamp: time.Now(), + Body: raw, + }, + ) + if err != nil { + c.logger.Error(fmt.Sprintf("failed to %s message to rabbit", action), log.Args{ + "error": err, + "message": fmt.Sprintf("%+v", message), + }) + } +} diff --git a/server/groupsync/context.go b/server/groupsync/context.go new file mode 100644 index 00000000..7a0b62d9 --- /dev/null +++ b/server/groupsync/context.go @@ -0,0 +1,59 @@ +package groupsync + +import ( + "github.com/imulab/go-scim/protocol/db" + "github.com/imulab/go-scim/protocol/log" + "github.com/imulab/go-scim/server/logger" + "github.com/streadway/amqp" +) + +type appContext struct { + logger log.Logger + userDB db.DB + groupDB db.DB + rabbitCh *amqp.Channel +} + +func (c *appContext) initialize(args *args) error { + if err := c.loadLogger(); err != nil { + return err + } + if err := c.loadUserDatabase(args); err != nil { + return err + } + if err := c.loadGroupDatabase(args); err != nil { + return err + } + if err := c.loadRabbitMqChannel(args); err != nil { + return err + } + return nil +} + +func (c *appContext) loadLogger() error { + c.logger = logger.Zero() + return nil +} + +func (c *appContext) loadUserDatabase(args *args) error { + c.userDB = db.Memory() + return nil +} + +func (c *appContext) loadGroupDatabase(args *args) error { + c.groupDB = db.Memory() + return nil +} + +func (c *appContext) loadRabbitMqChannel(args *args) error { + conn, err := amqp.Dial(args.rabbitMqAddress) + if err != nil { + return err + } + ch, err := conn.Channel() + if err != nil { + return err + } + c.rabbitCh = ch + return nil +} diff --git a/server/groupsync/rabbit.go b/server/groupsync/rabbit.go new file mode 100644 index 00000000..7d085f4b --- /dev/null +++ b/server/groupsync/rabbit.go @@ -0,0 +1,37 @@ +package groupsync + +import ( + "github.com/imulab/go-scim/protocol/log" + "github.com/streadway/amqp" +) + +const ( + exchangeName = "" + queueName = "group_sync" +) + +// Declare a durable and non-autoDelete RabbitMQ queue with the name "group_sync". +func declareRabbitQueue(ch *amqp.Channel, logger log.Logger) error { + _, err := ch.QueueDeclare( + queueName, + true, + false, + false, + false, + nil, + ) + if err != nil { + logger.Error("failed to declare rabbit queue", log.Args{ + "error": err, + }) + } + return nil +} + +// Message sent to notify the sync worker to sync the user resource with MemberID, or expand +// the group resource with MemberID into more sync tasks. +type message struct { + GroupID string `json:"group_id"` + MemberID string `json:"member_id"` + Trial int `json:"trial"` +} diff --git a/server/groupsync/sender.go b/server/groupsync/sender.go new file mode 100644 index 00000000..6d44e3a9 --- /dev/null +++ b/server/groupsync/sender.go @@ -0,0 +1,91 @@ +package groupsync + +import ( + "context" + "encoding/json" + "fmt" + "github.com/imulab/go-scim/core/prop" + "github.com/imulab/go-scim/protocol/event" + "github.com/imulab/go-scim/protocol/groupsync" + "github.com/imulab/go-scim/protocol/log" + uuid "github.com/satori/go.uuid" + "github.com/streadway/amqp" + "time" +) + +// Create a new sender that listens to membership changes and publishes group sync messages. +func Sender(ch *amqp.Channel, logger log.Logger) (event.Publisher, error) { + if err := declareRabbitQueue(ch, logger); err != nil { + return nil, err + } + return &sender{ + ch: ch, + logger: logger, + }, nil +} + +type sender struct { + ch *amqp.Channel + logger log.Logger +} + +func (s *sender) ResourceCreated(ctx context.Context, created *prop.Resource) { + go s.notify(created, groupsync.Compare(nil, created)) +} + +func (s *sender) ResourceUpdated(ctx context.Context, updated *prop.Resource, original *prop.Resource) { + go s.notify(updated, groupsync.Compare(original, updated)) +} + +func (s *sender) ResourceDeleted(ctx context.Context, deleted *prop.Resource) { + go s.notify(deleted, groupsync.Compare(deleted, nil)) +} + +func (s *sender) notify(group *prop.Resource, diff *groupsync.Diff) { + if diff.CountJoined()+diff.CountLeft() == 0 { + return + } + diff.ForEachJoined(func(id string) { + s.submitMessage(group, id) + }) + diff.ForEachLeft(func(id string) { + s.submitMessage(group, id) + }) +} + +func (s *sender) submitMessage(group *prop.Resource, memberId string) { + msg := &message{ + GroupID: group.ID(), + MemberID: memberId, + Trial: 1, + } + + raw, err := json.Marshal(msg) + if err != nil { + s.logger.Error("failed to render message to json", log.Args{ + "error": err, + "groupId": group.ID(), + "memberId": memberId, + }) + return + } + + err = s.ch.Publish( + exchangeName, + queueName, + false, + false, + amqp.Publishing{ + ContentType: "application/json", + MessageId: uuid.NewV4().String(), + Timestamp: time.Now(), + Body: raw, + }, + ) + if err != nil { + s.logger.Error("failed to send message to rabbit", log.Args{ + "error": err, + "message": fmt.Sprintf("%+v", msg), + }) + } +} diff --git a/server/logger/zero.go b/server/logger/zero.go new file mode 100644 index 00000000..14ad0d7b --- /dev/null +++ b/server/logger/zero.go @@ -0,0 +1,37 @@ +package logger + +import ( + "github.com/imulab/go-scim/protocol/log" + "github.com/rs/zerolog" + "os" +) + +func Zero() log.Logger { + return &zeroLogger{ + logger: zerolog.New(os.Stderr).With().Timestamp().Logger(), + } +} + +type zeroLogger struct { + logger zerolog.Logger +} + +func (l *zeroLogger) Info(message string, args log.Args) { + l.logger.Info().Fields(args).Msg(message) +} + +func (l *zeroLogger) Debug(message string, args log.Args) { + l.logger.Debug().Fields(args).Msg(message) +} + +func (l *zeroLogger) Error(message string, args log.Args) { + l.logger.Error().Fields(args).Msg(message) +} + +func (l *zeroLogger) Warning(message string, args log.Args) { + l.logger.Warn().Fields(args).Msg(message) +} + +func (l *zeroLogger) Fatal(message string, args log.Args) { + l.logger.Fatal().Fields(args).Msg(message) +} diff --git a/server/main.go b/server/main.go new file mode 100644 index 00000000..13adb42b --- /dev/null +++ b/server/main.go @@ -0,0 +1,30 @@ +package main + +import ( + "github.com/imulab/go-scim/server/api" + "github.com/imulab/go-scim/server/groupsync" + "github.com/urfave/cli/v2" + "log" + "os" +) + +func main() { + app := &cli.App{ + Name: "scim", + Usage: "Simple Cloud Identity Management", + Commands: []*cli.Command{ + api.Command(), + groupsync.Command(), + }, + HideVersion: true, + Authors: []*cli.Author{ + { + Name: "Weinan Qiu", + Email: "davidiamyou@gmail.com", + }, + }, + } + if err := app.Run(os.Args); err != nil { + log.Fatal(err) + } +}