Skip to content

Commit

Permalink
Merge branch 'main' of https://github.com/reearth/reearth into fix/cr…
Browse files Browse the repository at this point in the history
…eate-workspace-modal-design
  • Loading branch information
nina992 committed Jul 28, 2023
2 parents 37b4574 + 714fb91 commit ae5f49b
Show file tree
Hide file tree
Showing 75 changed files with 562 additions and 622 deletions.
4 changes: 4 additions & 0 deletions server/.env.example
Original file line number Diff line number Diff line change
Expand Up @@ -74,3 +74,7 @@ REEARTH_SES_NAME=
# Storage Google GCS
#REEARTH_GCS_BUCKETNAME=bucket_name
#REEARTH_GCS_PUBLICATIONCACHECONTROL=

# Extension plugin url as csv
# each path should contais `reearth.yml` file
REEARTH_EXT_PLUGIN=http://fileserve.local:8090/pluging-01,http://fileserve.local:8090/pluging-02
3 changes: 3 additions & 0 deletions server/internal/app/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,9 @@ type Config struct {
Auth_TTL *int
Auth_ClientID *string
Auth_JWKSURI *string

// system extensions
Ext_Plugin []string
}

func ReadConfig(debug bool) (*Config, error) {
Expand Down
5 changes: 5 additions & 0 deletions server/internal/app/config/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,11 @@ func TestReadConfig(t *testing.T) {
}, cfg.Auths())
assert.Equal(t, "foo", cfg.Auth_AUD)
assert.Equal(t, map[string]string{}, cfg.Web)

t.Setenv("REEARTH_EXT_PLUGIN", "https://hoge.com/myplugin,https://hoge.com/myplugin2")
cfg, err = ReadConfig(false)
assert.NoError(t, err)
assert.Equal(t, []string{"https://hoge.com/myplugin", "https://hoge.com/myplugin2"}, cfg.Ext_Plugin)
}

func Test_AddHTTPScheme(t *testing.T) {
Expand Down
2 changes: 1 addition & 1 deletion server/internal/app/repo.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ func initReposAndGateways(ctx context.Context, conf *config.Config, debug bool)
log.Fatalf("mongo error: %+v\n", err)
}

repos, err := mongorepo.New(ctx, client.Database("reearth"), mongox.IsTransactionAvailable(conf.DB))
repos, err := mongorepo.NewWithExtensions(ctx, client.Database("reearth"), mongox.IsTransactionAvailable(conf.DB), conf.Ext_Plugin)
if err != nil {
log.Fatalf("Failed to init mongo: %+v\n", err)
}
Expand Down
2 changes: 1 addition & 1 deletion server/internal/infrastructure/adapter/plugin.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import (
"github.com/reearth/reearthx/rerror"
)

// TODO: ここで幅優先探索していくアルゴリズムを書いてmongoからビルトインの検索ロジックを除去する
// TODO: Write a width-first search algorithm here to remove the built-in search logic from mongo
type pluginRepo struct {
readers []repo.Plugin
writer repo.Plugin
Expand Down
45 changes: 45 additions & 0 deletions server/internal/infrastructure/mongo/container.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,21 @@ package mongo
import (
"context"

"github.com/reearth/reearth/server/internal/infrastructure/adapter"
"github.com/reearth/reearth/server/internal/infrastructure/memory"
"github.com/reearth/reearth/server/internal/infrastructure/mongo/migration"
"github.com/reearth/reearth/server/internal/usecase/repo"
"github.com/reearth/reearth/server/pkg/id"
"github.com/reearth/reearth/server/pkg/plugin"
"github.com/reearth/reearth/server/pkg/plugin/manifest"
"github.com/reearth/reearth/server/pkg/property"
"github.com/reearth/reearth/server/pkg/scene"
"github.com/reearth/reearth/server/pkg/user"
"github.com/reearth/reearthx/authserver"
"github.com/reearth/reearthx/log"
"github.com/reearth/reearthx/mongox"
"github.com/reearth/reearthx/util"
"github.com/samber/lo"
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/mongo"
)
Expand Down Expand Up @@ -60,6 +67,44 @@ func New(ctx context.Context, db *mongo.Database, useTransaction bool) (*repo.Co
return c, nil
}

func NewWithExtensions(ctx context.Context, db *mongo.Database, useTransaction bool, src []string) (*repo.Container, error) {
c, err := New(ctx, db, useTransaction)
if err != nil {
return nil, err
}
if len(src) == 0 {
return c, nil
}

ms, err := manifest.ParseFromUrlList(ctx, src)
if err != nil {
return nil, err
}

ids := lo.Map(ms, func(m *manifest.Manifest, _ int) id.PluginID {
return m.Plugin.ID()
})

plugins := lo.Map(ms, func(m *manifest.Manifest, _ int) *plugin.Plugin {
return m.Plugin
})

propertySchemas := lo.FlatMap(ms, func(m *manifest.Manifest, _ int) []*property.Schema {
return m.ExtensionSchema
})

c.Extensions = ids
c.Plugin = adapter.NewPlugin(
[]repo.Plugin{memory.NewPluginWith(plugins...), c.Plugin},
c.Plugin,
)
c.PropertySchema = adapter.NewPropertySchema(
[]repo.PropertySchema{memory.NewPropertySchemaWith(propertySchemas...), c.PropertySchema},
c.PropertySchema,
)
return c, nil
}

func Init(r *repo.Container) error {
if r == nil {
return nil
Expand Down
27 changes: 25 additions & 2 deletions server/internal/usecase/interactor/scene.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import (
"github.com/reearth/reearth/server/pkg/visualizer"
"github.com/reearth/reearthx/rerror"
"github.com/reearth/reearthx/usecasex"
"github.com/samber/lo"
)

type Scene struct {
Expand All @@ -31,6 +32,7 @@ type Scene struct {
transaction usecasex.Transaction
file gateway.File
pluginRegistry gateway.PluginRegistry
extensions []plugin.ID
}

func NewScene(r *repo.Container, g *gateway.Container) interfaces.Scene {
Expand All @@ -45,6 +47,7 @@ func NewScene(r *repo.Container, g *gateway.Container) interfaces.Scene {
transaction: r.Transaction,
file: g.File,
pluginRegistry: g.PluginRegistry,
extensions: r.Extensions,
}
}

Expand All @@ -58,11 +61,25 @@ func (i *Scene) pluginCommon() *pluginCommon {
}

func (i *Scene) Fetch(ctx context.Context, ids []id.SceneID, operator *usecase.Operator) ([]*scene.Scene, error) {
return i.sceneRepo.FindByIDs(ctx, ids)
s, err := i.sceneRepo.FindByIDs(ctx, ids)
if err != nil {
return nil, err
}

lo.ForEach(s, func(s *scene.Scene, _ int) {
injectExtensionsToScene(s, i.extensions)
})

return s, nil
}

func (i *Scene) FindByProject(ctx context.Context, id id.ProjectID, operator *usecase.Operator) (*scene.Scene, error) {
return i.sceneRepo.FindByProject(ctx, id)
s, err := i.sceneRepo.FindByProject(ctx, id)
if err != nil {
return nil, err
}
injectExtensionsToScene(s, i.extensions)
return s, nil
}

func (i *Scene) Create(ctx context.Context, pid id.ProjectID, operator *usecase.Operator) (_ *scene.Scene, err error) {
Expand Down Expand Up @@ -539,3 +556,9 @@ func (i *Scene) RemoveCluster(ctx context.Context, sceneID id.SceneID, clusterID
tx.Commit()
return s, nil
}

func injectExtensionsToScene(s *scene.Scene, ext []plugin.ID) {
lo.ForEach(ext, func(p plugin.ID, _ int) {
s.Plugins().Add(scene.NewPlugin(p, nil))
})
}
3 changes: 3 additions & 0 deletions server/internal/usecase/repo/container.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"errors"

"github.com/reearth/reearth/server/internal/usecase"
"github.com/reearth/reearth/server/pkg/plugin"
"github.com/reearth/reearth/server/pkg/scene"
"github.com/reearth/reearth/server/pkg/user"
"github.com/reearth/reearthx/authserver"
Expand Down Expand Up @@ -33,6 +34,7 @@ type Container struct {
User User
Policy Policy
Transaction usecasex.Transaction
Extensions []plugin.ID
}

func (c *Container) Filtered(workspace WorkspaceFilter, scene SceneFilter) *Container {
Expand All @@ -58,6 +60,7 @@ func (c *Container) Filtered(workspace WorkspaceFilter, scene SceneFilter) *Cont
Transaction: c.Transaction,
User: c.User,
Workspace: c.Workspace,
Extensions: c.Extensions,
}
}

Expand Down
40 changes: 40 additions & 0 deletions server/pkg/plugin/manifest/parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,19 @@ package manifest
//go:generate go run github.com/idubinskiy/schematyper -o schema_gen.go --package manifest ../../../schemas/plugin_manifest.json

import (
"context"
"errors"
"io"
"net/http"
"net/url"

"github.com/goccy/go-yaml"
"github.com/reearth/reearth/server/pkg/plugin"
)

var (
ErrInvalidManifest error = errors.New("invalid manifest")
ErrFailedToFetchManifest error = errors.New("failed to fetch manifest")
ErrFailedToParseManifest error = errors.New("failed to parse plugin manifest")
ErrSystemManifest = errors.New("cannot build system manifest")
)
Expand Down Expand Up @@ -56,3 +60,39 @@ func MustParseSystemFromBytes(source []byte, scene *plugin.SceneID, tl *Translat
}
return m
}

func ParseFromUrl(ctx context.Context, u *url.URL) (*Manifest, error) {
req, err := http.NewRequestWithContext(ctx, http.MethodGet, u.JoinPath("reearth.yml").String(), nil)
if err != nil {
return nil, err
}

res, err := http.DefaultClient.Do(req)
if err != nil {
return nil, err
}
defer func() {
_ = res.Body.Close()
}()
if res.StatusCode != http.StatusOK {
return nil, ErrFailedToFetchManifest
}

return Parse(res.Body, nil, nil)
}

func ParseFromUrlList(ctx context.Context, src []string) ([]*Manifest, error) {
ms := make([]*Manifest, 0, len(src))
for _, s := range src {
u, err := url.Parse(s)
if err != nil {
return nil, err
}
m, err := ParseFromUrl(ctx, u)
if err != nil {
return nil, err
}
ms = append(ms, m)
}
return ms, nil
}
94 changes: 94 additions & 0 deletions server/pkg/plugin/manifest/parser_test.go
Original file line number Diff line number Diff line change
@@ -1,14 +1,19 @@
package manifest

import (
"context"
_ "embed"
"net/http"
"net/url"
"strings"
"testing"

"github.com/jarcoal/httpmock"
"github.com/reearth/reearth/server/pkg/i18n"
"github.com/reearth/reearth/server/pkg/plugin"
"github.com/reearth/reearth/server/pkg/property"
"github.com/reearth/reearth/server/pkg/visualizer"
"github.com/samber/lo"
"github.com/stretchr/testify/assert"
)

Expand Down Expand Up @@ -106,6 +111,95 @@ func TestParse(t *testing.T) {

}

func TestParseFromUrl(t *testing.T) {
tests := []struct {
name string
input string
expected *Manifest
err error
}{
{
name: "success create simple manifest",
input: minimum,
expected: minimumExpected,
err: nil,
},
{
name: "success create manifest",
input: normal,
expected: normalExpected,
err: nil,
},
{
name: "fail not valid JSON",
input: "",
expected: nil,
err: ErrFailedToParseManifest,
},
{
name: "fail system manifest",
input: `{
"system": true,
"id": "reearth",
"title": "bbb",
"version": "1.1.1"
}`,
expected: nil,
err: ErrSystemManifest,
},
{
name: "fail system manifest",
input: `{
"system": true,
"id": "reearth",
"title": "bbb",
"version": "1.1.1"
}`,
expected: nil,
err: ErrFailedToFetchManifest,
},
}

for _, tc := range tests {
tc := tc
t.Run(tc.name, func(t *testing.T) {
// t.Parallel() // in parallel test, httpmock.RegisterResponder is not working, MockTransport should be used

httpmock.Activate()
defer httpmock.Deactivate()
if tc.err != ErrFailedToFetchManifest {
httpmock.RegisterResponder("GET", "https://example.com/myPlugin/reearth.yml", httpmock.NewBytesResponder(http.StatusOK, []byte(tc.input)))
} else {
httpmock.RegisterResponder("GET", "https://example.com/myPlugin/reearth.yml", httpmock.NewBytesResponder(http.StatusNotFound, nil))
}

m, err := ParseFromUrl(context.Background(), lo.Must(url.Parse("https://example.com/myPlugin")))
if tc.err == nil {
if !assert.NoError(t, err) {
return
}
assert.Equal(t, tc.expected, m)
return
}
assert.ErrorIs(t, tc.err, err)
})
}

}
func TestParseFromUrlList(t *testing.T) {

httpmock.Activate()
defer httpmock.Deactivate()
httpmock.RegisterResponder("GET", "https://example.com/myPlugin1/reearth.yml", httpmock.NewBytesResponder(http.StatusOK, []byte(minimum)))
httpmock.RegisterResponder("GET", "https://example.com/myPlugin2/reearth.yml", httpmock.NewBytesResponder(http.StatusOK, []byte(normal)))

m, err := ParseFromUrlList(context.Background(), []string{"https://example.com/myPlugin1", "https://example.com/myPlugin2"})
if !assert.NoError(t, err) {
return
}
assert.Equal(t, []*Manifest{minimumExpected, normalExpected}, m)
}

func TestParseSystemFromBytes(t *testing.T) {
tests := []struct {
name, input string
Expand Down
4 changes: 3 additions & 1 deletion web/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@
"@testing-library/react": "14.0.0",
"@testing-library/user-event": "14.4.3",
"@types/apollo-upload-client": "14.1.0",
"@types/carbon__colors": "10.31.0",
"@types/gapi.auth2": "0.0.57",
"@types/gapi.client": "1.0.5",
"@types/gapi.client.sheets": "4.0.20201031",
Expand Down Expand Up @@ -97,6 +98,7 @@
"@apollo/client": "3.7.14",
"@auth0/auth0-react": "2.1.0",
"@aws-amplify/ui-react": "5.0.2",
"@carbon/colors": "11.18.0",
"@emotion/react": "11.11.0",
"@emotion/styled": "11.11.0",
"@floating-ui/react": "0.24.7",
Expand Down Expand Up @@ -177,4 +179,4 @@
"use-file-input": "1.0.0",
"uuid": "9.0.0"
}
}
}
Loading

0 comments on commit ae5f49b

Please sign in to comment.