diff --git a/Dockerfile b/Dockerfile
new file mode 100644
index 00000000..81dcaf00
--- /dev/null
+++ b/Dockerfile
@@ -0,0 +1,24 @@
+##########################################################################
+# GO BUILDER
+##########################################################################
+FROM golang:1.13-buster AS builder
+
+WORKDIR /build/scim
+
+COPY . ./
+
+RUN make build
+
+##########################################################################
+# FINAL IMAGE
+##########################################################################
+FROM debian:buster-slim
+
+# copy binary
+COPY --from=builder /build/scim/bin/linux_amd64/scim /usr/bin/scim
+
+# copy public files
+COPY --from=builder /build/scim/public /usr/share/scim/public
+
+# run
+CMD ["/usr/bin/scim"]
diff --git a/Makefile b/Makefile
new file mode 100644
index 00000000..05a7af4c
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,60 @@
+.PHONY: all build deps binary test doc
+
+OK_COLOR=\033[32;01m
+NO_COLOR=\033[0m
+ERROR_COLOR=\033[31;01m
+WARN_COLOR=\033[33;01m
+
+NOW = $(shell date -u '+%Y%m%d%I%M%S')
+
+DOCKER := docker
+GO := go
+GO_ENV := $(shell $(GO) env GOOS GOARCH)
+GOOS ?= $(word 1,$(GO_ENV))
+GOARCH ?= $(word 2,$(GO_ENV))
+GOFLAGS ?= $(GOFLAGS:)
+ROOT_DIR := $(realpath .)
+
+# GOOS/GOARCH of the build host, used to determine whether we're cross-compiling or not
+BUILDER_GOOS_GOARCH="$(GOOS)_$(GOARCH)"
+
+ifneq ($(GOOS), darwin)
+ EXTLDFLAGS = # EXTLDFLAGS = -extldflags "-lm -lstdc++ -static"
+else
+ EXTLDFLAGS =
+endif
+
+GO_LINKER_FLAGS ?= --ldflags \
+ '$(EXTLDFLAGS) -s -w '
+
+all: build
+
+build: deps binary
+
+deps:
+ @echo "$(OK_COLOR)==> Fetching dependencies...$(NO_COLOR)"
+ $(GO) mod download
+
+binary:
+ @echo "$(OK_COLOR)==> Building binary ($(GOOS)/$(GOARCH))...$(NO_COLOR)"
+ $(GO) build -a $(GOFLAGS) $(GO_LINKER_FLAGS) -o bin/$(GOOS)_$(GOARCH)/scim
+
+test: deps
+ @echo "$(OK_COLOR)==> Running tests...$(NO_COLOR)"
+ $(GO) test $(GOFLAGS) -race ./...
+
+doc:
+ mkdir -p /tmp/tmpgoroot/doc
+ rm -rf /tmp/tmpgopath/src/github.com/imulab/go-scim
+ mkdir -p /tmp/tmpgopath/src/github.com/imulab/go-scim
+ tar -c --exclude='.git' --exclude='tmp' . | tar -x -C /tmp/tmpgopath/src/github.com/imulab/go-scim
+ @echo "$(OK_COLOR)==> Open http://localhost:6060/pkg/github.com/imulab/go-scim$(NO_COLOR)"
+ GOROOT=/tmp/tmpgoroot/ GOPATH=/tmp/tmpgopath/ godoc -http=localhost:6060
+
+docker:
+ @echo "$(OK_COLOR)==> Building image scim:latest$(NO_COLOR)"
+ docker build -t scim:latest .
+
+compose:
+ @echo "$(OK_COLOR)==> Starting local stack$(NO_COLOR)"
+ docker-compose up
\ No newline at end of file
diff --git a/README.md b/README.md
index b245d972..2c19bc2e 100644
--- a/README.md
+++ b/README.md
@@ -1,30 +1,30 @@
-# GoSCIM
-
-
+
> GoSCIM aims to be a fully featured implementation of [SCIM v2](http://www.simplecloud.info/) specification. It
provides opinion-free and extensible building blocks, as well as an opinionated server implementation.
-## T.L.D.R
+## :rocket: TLDR
+
+###### *Requirements:* [Docker](https://docs.docker.com/get-started/) and [Docker Compose](https://docs.docker.com/compose/gettingstarted/)
```bash
-make
-docker-compose up --build
+# Builds docker image and starts local docker-compose stack
+make docker compose
```
-## Project structure
+## :file_folder: Project structure
Since v1, the project has grown into three independent modules.
-- `github.com/imulab/go-scim/pkg/v2` module evolved from most of the original building blocks. This module provides
-customizable, extensible and opinion free implementation of the SCIM specification.
-- `github.com/imulab/go-scim/mongo/v2` module evolved from the original mongo package. This module provides persistence
-capabilities to MongoDB.
-- `github.com/imulab/go-scim` module evolved from the original example server implementation. It is now a __opinionated__
-personal server implementation that depends on the above two modules.
+- [pkg module](https://github.com/imulab/go-scim/tree/master/pkg/v2) evolved from most of the original building blocks.
+This module provides customizable, extensible and opinion free implementation of the SCIM specification.
+- [mongo module](https://github.com/imulab/go-scim/tree/master/mongo/v2) evolved from the original mongo package.
+This module provides persistence capabilities to MongoDB.
+- [server module](https://github.com/imulab/go-scim) evolved from the original example server implementation. It is now
+an __opinionated__ personal server implementation that depends on the above two modules.
-Documentation for the [pkg](https://github.com/imulab/go-scim/tree/master/pkg/v2) and [mongo](https://github.com/imulab/go-scim/tree/master/mongo/v2) module can be viewed in their respective directories.
+Documentation for the individual modules can be viewed in their respective directories and godoc badge links.
-## End of v1
+## :no_entry_sign: End of v1
Due to limited time and resource and a drastic new design in v2, the building blocks and mongo package from v1 will no
longer be maintained. The `github.com/imulab/go-scim` will go on as an opinionated personal implementation, which may or
diff --git a/cmd/api/context.go b/cmd/api/context.go
index 72affec2..abe3fe00 100644
--- a/cmd/api/context.go
+++ b/cmd/api/context.go
@@ -2,6 +2,7 @@ package api
import (
"context"
+ "github.com/imulab/go-scim/cmd/internal/groupsync"
scimmongo "github.com/imulab/go-scim/mongo/v2"
"github.com/imulab/go-scim/pkg/v2/db"
"github.com/imulab/go-scim/pkg/v2/service"
@@ -348,6 +349,10 @@ func (ctx *applicationContext) RabbitMQChannel() *amqp.Channel {
ctx.logInitFailure("rabbit channel", err)
panic(err)
}
+ if err := groupsync.DeclareQueue(c); err != nil {
+ ctx.logInitFailure("rabbit channel", err)
+ panic(err)
+ }
ctx.rabbitMqChannel = c
ctx.logInitialized("rabbit channel")
}
diff --git a/cmd/groupsync/consumer.go b/cmd/groupsync/consumer.go
index 1bfff1b8..725f1b3d 100644
--- a/cmd/groupsync/consumer.go
+++ b/cmd/groupsync/consumer.go
@@ -35,10 +35,12 @@ func (c *consumer) Start(ctx context.Context) (safeExit chan struct{}, err error
nil,
)
if err != nil {
- c.logger.Err(err).Msg("Failed to consume message")
+ c.logger.Err(err).Msg("failed to consume message")
return
}
+ c.logger.Info().Msg("group sync consumer starts to listen for messages")
+
safeExit = make(chan struct{}, 1)
go func() {
diff --git a/cmd/groupsync/context.go b/cmd/groupsync/context.go
index 396d30c9..aecde596 100644
--- a/cmd/groupsync/context.go
+++ b/cmd/groupsync/context.go
@@ -2,6 +2,7 @@ package groupsync
import (
"context"
+ gs "github.com/imulab/go-scim/cmd/internal/groupsync"
scimmongo "github.com/imulab/go-scim/mongo/v2"
"github.com/imulab/go-scim/pkg/v2/db"
"github.com/imulab/go-scim/pkg/v2/groupsync"
@@ -177,6 +178,10 @@ func (ctx *applicationContext) RabbitMQChannel() *amqp.Channel {
ctx.logInitFailure("rabbit channel", err)
panic(err)
}
+ if err := gs.DeclareQueue(c); err != nil {
+ ctx.logInitFailure("rabbit channel", err)
+ panic(err)
+ }
ctx.rabbitMqChannel = c
ctx.logInitialized("rabbit channel")
}
diff --git a/cmd/internal/groupsync/rabbit.go b/cmd/internal/groupsync/rabbit.go
index e1536b7d..388b4d36 100644
--- a/cmd/internal/groupsync/rabbit.go
+++ b/cmd/internal/groupsync/rabbit.go
@@ -1,7 +1,22 @@
package groupsync
+import "github.com/streadway/amqp"
+
// Queue name in RabbitMQ, used by consumer and producer to exchange message.
const RabbitQueueName = "group_sync"
// Exchange name in RabbitMQ
const RabbitExchangeName = ""
+
+// Declare a queue in RabbitMQ named RabbitQueueName.
+func DeclareQueue(ch *amqp.Channel) error {
+ _, err := ch.QueueDeclare(
+ RabbitQueueName,
+ true,
+ false,
+ false,
+ false,
+ nil,
+ )
+ return err
+}
diff --git a/docker-compose.yml b/docker-compose.yml
new file mode 100644
index 00000000..04210d2d
--- /dev/null
+++ b/docker-compose.yml
@@ -0,0 +1,107 @@
+version: "3"
+services:
+ mediainit:
+ image: alpine:3.10
+ entrypoint: /bin/sh -c "chown -v nobody:nogroup /data/db && chmod -v 777 /data/db"
+ container_name: mediainit
+ restart: "no"
+ volumes:
+ - 'mongo_data:/data/db'
+
+ db:
+ image: "bitnami/mongodb:latest"
+ environment:
+ - MONGODB_EXTRA_FLAGS=--wiredTigerCacheSizeGB=2 --bind_ip_all
+ - MONGODB_USERNAME=user
+ - MONGODB_PASSWORD=password123
+ - MONGODB_DATABASE=scim_database
+ volumes:
+ - 'mongo_data:/data/db'
+ ports:
+ - '27017:27017'
+ networks:
+ - app-tier
+
+ rabbit:
+ image: "bitnami/rabbitmq:latest"
+ environment:
+ - RABBITMQ_USERNAME=user
+ - RABBITMQ_PASSWORD=password123
+ - RABBITMQ_NODE_NAME=user@rabbit
+ ports:
+ - '4369:4369'
+ - '5672:5672'
+ - '25672:25672'
+ - '15672:15672'
+ networks:
+ - app-tier
+ volumes:
+ - 'rabbitmq_data:/bitnami'
+
+ group:
+ image: "scim:latest"
+ build:
+ context: .
+ command: ["/usr/bin/scim", "group-sync"]
+ environment:
+ - REQUEUE_LIMIT=1
+ - MONGO_HOST=db
+ - MONGO_PORT=27017
+ - MONGO_USERNAME=user
+ - MONGO_PASSWORD=password123
+ - MONGO_DATABASE=scim_database
+ - MONGO_OPT=authMechanism=SCRAM-SHA-1
+ - RABBIT_HOST=rabbit
+ - RABBIT_PORT=5672
+ - RABBIT_USERNAME=user
+ - RABBIT_PASSWORD=password123
+ - SERVICE_PROVIDER_CONFIG=/usr/share/scim/public/service_provider_config.json
+ - SCHEMAS_DIR=/usr/share/scim/public/schemas
+ - USER_RESOURCE_TYPE=/usr/share/scim/public/resource_types/user_resource_type.json
+ - GROUP_RESOURCE_TYPE=/usr/share/scim/public/resource_types/group_resource_type.json
+ - MONGO_METADATA_DIR=/usr/share/scim/public/mongo_metadata
+ networks:
+ - app-tier
+ depends_on:
+ - db
+ - rabbit
+
+ server:
+ image: "scim:latest"
+ build:
+ context: .
+ command: ["/usr/bin/scim", "api"]
+ environment:
+ - HTTP_PORT=5000
+ - MONGO_HOST=db
+ - MONGO_PORT=27017
+ - MONGO_USERNAME=user
+ - MONGO_PASSWORD=password123
+ - MONGO_DATABASE=scim_database
+ - MONGO_OPT=authMechanism=SCRAM-SHA-1
+ - RABBIT_HOST=rabbit
+ - RABBIT_PORT=5672
+ - RABBIT_USERNAME=user
+ - RABBIT_PASSWORD=password123
+ - SERVICE_PROVIDER_CONFIG=/usr/share/scim/public/service_provider_config.json
+ - SCHEMAS_DIR=/usr/share/scim/public/schemas
+ - USER_RESOURCE_TYPE=/usr/share/scim/public/resource_types/user_resource_type.json
+ - GROUP_RESOURCE_TYPE=/usr/share/scim/public/resource_types/group_resource_type.json
+ - MONGO_METADATA_DIR=/usr/share/scim/public/mongo_metadata
+ ports:
+ - "5000:5000"
+ networks:
+ - app-tier
+ depends_on:
+ - db
+ - rabbit
+
+volumes:
+ rabbitmq_data:
+ driver: local
+ mongo_data:
+ driver: local
+
+networks:
+ app-tier:
+ driver: bridge
\ No newline at end of file
diff --git a/godoc.sh b/godoc.sh
deleted file mode 100755
index 5eb460be..00000000
--- a/godoc.sh
+++ /dev/null
@@ -1,8 +0,0 @@
-#/bin/bash
-
-mkdir -p /tmp/tmpgoroot/doc
-rm -rf /tmp/tmpgopath/src/github.com/imulab/go-scim
-mkdir -p /tmp/tmpgopath/src/github.com/imulab/go-scim
-tar -c --exclude='.git' --exclude='tmp' . | tar -x -C /tmp/tmpgopath/src/github.com/imulab/go-scim
-echo -e "open http://localhost:6060/pkg/github.com/imulab/go-scim\n"
-GOROOT=/tmp/tmpgoroot/ GOPATH=/tmp/tmpgopath/ godoc -http=localhost:6060
\ No newline at end of file
diff --git a/mongo/v2/README.md b/mongo/v2/README.md
index cccc1140..05a4edd4 100644
--- a/mongo/v2/README.md
+++ b/mongo/v2/README.md
@@ -1,8 +1,19 @@
# MongoDB Module
+[![GoDoc](https://godoc.org/github.com/imulab/go-scim/mongo/v2?status.svg)](https://godoc.org/github.com/imulab/go-scim/mongo/v2)
+
This module provides the capability to persist SCIM resources in MongoDB.
-## Persistence
+## :bulb: Usage
+
+To get this package:
+
+```bash
+# make sure Go 1.13
+go get github.com/imulab/go-scim/mongo/v2
+```
+
+## :floppy_disk: Persistence
This basic `db.DB` implementation in this module assumes one-to-one mapping between a SCIM resource type and a MongoDB
collection.
@@ -46,7 +57,7 @@ specifies the path name from the document root. Use `ReadMetadata` to register b
The module utilizes the atomicity of MongoDB and safely performs modification operations without explicitly locking the
resource. `Replace` and `Delete` operations would only perform data modification if the `id` and `meta.version` fields
-matches the record in MongoDB. If no match was found, a `preCondition` error is returned to indicate some current process
+matches the record in MongoDB. If no match was found, a `conflict` error is returned to indicate some current process
must have modified the resource in between.
### Projection
@@ -57,10 +68,10 @@ This is done intentionally, as `db.DB` is not a client facing component with res
parameters supplied should have been pre-sanitized so that it does not contradict with the `returned` property.
There are also cases where callers may wish to carry out operations after the query on fields not requested by the client.
-In this case, callers can use `DBOptions.IgnoreProjection()` to disable projection altogether so the database always
+In this case, callers can use `Options.IgnoreProjection()` to disable projection altogether so the database always
return the full version of the resource.
-## Serialization
+## :black_nib: Serialization
This module provides direct serialization and de-deserialization between SCIM resource and MongoDB BSON format, without
the transition of an intermediary data format.
@@ -68,7 +79,7 @@ the transition of an intermediary data format.
The serialization of the less significant components like filter, sort, pagination and projection are still being
converted to `bson.D`, before being serialized to BSON and sent to MongoDB.
-## Testing
+## :construction: Testing
This module uses [org/dockertest](https://github.com/ory/dockertest) to setup testing docker containers at test run time.
The environment variables to customize the local docker connection are:
diff --git a/pkg/v2/README.md b/pkg/v2/README.md
index 4b0f9eb2..aa099f1a 100644
--- a/pkg/v2/README.md
+++ b/pkg/v2/README.md
@@ -1,5 +1,7 @@
# SCIM
+[![GoDoc](https://godoc.org/github.com/imulab/go-scim/pkg/v2?status.svg)](https://godoc.org/github.com/imulab/go-scim/pkg/v2)
+
This module implements features described in [RFC 7643 - SCIM: Core Schema](https://tools.ietf.org/html/rfc7643) and
[RFC 7644 - SCIM: Protocol](https://tools.ietf.org/html/rfc7644), along with custom features that address specific
implementation difficulties.
@@ -19,7 +21,7 @@ It is not the goal of this package to enable every possible use case, or to prov
>
> We apologize for any inconvenience caused by this decision. The original v1 can still be checked out via tags.
-## Usage
+## :bulb: Usage
To get this package:
@@ -28,7 +30,7 @@ To get this package:
go get github.com/imulab/go-scim/pkg/v2
```
-## Features in v2
+## :gift: Features in v2
- :free: Reflection free operations on resources
- :mailbox_with_mail: Property subscribers
@@ -37,7 +39,7 @@ go get github.com/imulab/go-scim/pkg/v2
- :thumbsup: Robust SCIM path and filter parsing
- :fast_forward: Resource filters to allow for custom resource processing
-## Project Structure
+## :file_folder: Project Structure
Features in this module are separated into different directories:
- `spec` directory implements the foundation of SCIM resource type definition
@@ -52,7 +54,7 @@ Features in this module are separated into different directories:
For detailed documentation, please check out README of individual directories, or GoDoc.
-## Road Map
+## :bullettrain_side: Road Map
After delivering the v2.0.0 which will cover most features, efforts will be directed toward:
- ResourceType(s) and Schema(s) endpoints (see [issue 40](https://github.com/imulab/go-scim/issues/40))