Skip to content

Commit

Permalink
Merge pull request #19 from hyperledger/ffi-abi-conversion
Browse files Browse the repository at this point in the history
Move FFI Code from Core
  • Loading branch information
nguyer authored Jun 22, 2022
2 parents a4927eb + e578ec3 commit 7f6b2ea
Show file tree
Hide file tree
Showing 9 changed files with 571 additions and 0 deletions.
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ require (
github.com/jarcoal/httpmock v1.1.0
github.com/pkg/errors v0.9.1
github.com/rs/cors v1.8.2
github.com/santhosh-tekuri/jsonschema/v5 v5.0.0
github.com/sirupsen/logrus v1.8.1
github.com/spf13/viper v1.12.0
github.com/stretchr/testify v1.7.1
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -389,6 +389,8 @@ github.com/rs/cors v1.8.2 h1:KCooALfAYGs415Cwu5ABvv9n9509fSiG5SQJn/AQo4U=
github.com/rs/cors v1.8.2/go.mod h1:XyqrcTp5zjWr1wsJ8PIRZssZ8b/WMcMf71DJnit4EMU=
github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=
github.com/sagikazarmark/crypt v0.6.0/go.mod h1:U8+INwJo3nBv1m6A/8OBXAq7Jnpspk5AxSgDyEQcea8=
github.com/santhosh-tekuri/jsonschema/v5 v5.0.0 h1:TToq11gyfNlrMFZiYujSekIsPd9AmsA2Bj/iv+s4JHE=
github.com/santhosh-tekuri/jsonschema/v5 v5.0.0/go.mod h1:FKdcjfQW6rpZSnxxUvEA5H/cDPdvJ/SZJQLWWXWGrZ0=
github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc=
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
Expand Down
133 changes: 133 additions & 0 deletions pkg/fftypes/ffi.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
// Copyright © 2022 Kaleido, Inc.
//
// SPDX-License-Identifier: Apache-2.0
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package fftypes

import (
"context"
"database/sql/driver"
"encoding/json"

"github.com/hyperledger/firefly-common/pkg/i18n"
"github.com/santhosh-tekuri/jsonschema/v5"
)

type FFIParamValidator interface {
Compile(ctx jsonschema.CompilerContext, m map[string]interface{}) (jsonschema.ExtSchema, error)
GetMetaSchema() *jsonschema.Schema
GetExtensionName() string
}

type FFIReference struct {
ID *UUID `ffstruct:"FFIReference" json:"id,omitempty"`
Name string `ffstruct:"FFIReference" json:"name,omitempty"`
Version string `ffstruct:"FFIReference" json:"version,omitempty"`
}

type FFI struct {
ID *UUID `ffstruct:"FFI" json:"id,omitempty" ffexcludeinput:"true"`
Message *UUID `ffstruct:"FFI" json:"message,omitempty" ffexcludeinput:"true"`
Namespace string `ffstruct:"FFI" json:"namespace,omitempty" ffexcludeinput:"true"`
Name string `ffstruct:"FFI" json:"name"`
Description string `ffstruct:"FFI" json:"description"`
Version string `ffstruct:"FFI" json:"version"`
Methods []*FFIMethod `ffstruct:"FFI" json:"methods,omitempty"`
Events []*FFIEvent `ffstruct:"FFI" json:"events,omitempty"`
}

type FFIMethod struct {
ID *UUID `ffstruct:"FFIMethod" json:"id,omitempty" ffexcludeinput:"true"`
Interface *UUID `ffstruct:"FFIMethod" json:"interface,omitempty" ffexcludeinput:"true"`
Name string `ffstruct:"FFIMethod" json:"name"`
Namespace string `ffstruct:"FFIMethod" json:"namespace,omitempty" ffexcludeinput:"true"`
Pathname string `ffstruct:"FFIMethod" json:"pathname" ffexcludeinput:"true"`
Description string `ffstruct:"FFIMethod" json:"description"`
Params FFIParams `ffstruct:"FFIMethod" json:"params"`
Returns FFIParams `ffstruct:"FFIMethod" json:"returns"`
Details JSONObject `ffstruct:"FFIMethod" json:"details,omitempty"`
}

type FFIEventDefinition struct {
Name string `ffstruct:"FFIEvent" json:"name"`
Description string `ffstruct:"FFIEvent" json:"description"`
Params FFIParams `ffstruct:"FFIEvent" json:"params"`
Details JSONObject `ffstruct:"FFIEvent" json:"details,omitempty"`
}

type FFIEvent struct {
ID *UUID `ffstruct:"FFIEvent" json:"id,omitempty" ffexcludeinput:"true"`
Interface *UUID `ffstruct:"FFIEvent" json:"interface,omitempty" ffexcludeinput:"true"`
Namespace string `ffstruct:"FFIEvent" json:"namespace,omitempty" ffexcludeinput:"true"`
Pathname string `ffstruct:"FFIEvent" json:"pathname,omitempty" ffexcludeinput:"true"`
Signature string `ffstruct:"FFIEvent" json:"signature" ffexcludeinput:"true"`
FFIEventDefinition
}

type FFIParam struct {
Name string `ffstruct:"FFIParam" json:"name"`
Schema *JSONAny `ffstruct:"FFIParam" json:"schema,omitempty"`
}

type FFIParams []*FFIParam

type FFIGenerationRequest struct {
Namespace string `ffstruct:"FFIGenerationRequest" json:"namespace,omitempty"`
Name string `ffstruct:"FFIGenerationRequest" json:"name"`
Description string `ffstruct:"FFIGenerationRequest" json:"description"`
Version string `ffstruct:"FFIGenerationRequest" json:"version"`
Input *JSONAny `ffstruct:"FFIGenerationRequest" json:"input"`
}

func (f *FFI) Validate(ctx context.Context, existing bool) (err error) {
if err = ValidateFFNameField(ctx, f.Namespace, "namespace"); err != nil {
return err
}
if err = ValidateFFNameField(ctx, f.Name, "name"); err != nil {
return err
}
if err = ValidateFFNameField(ctx, f.Version, "version"); err != nil {
return err
}
return nil
}

func (f *FFI) Topic() string {
return TypeNamespaceNameTopicHash("ffi", f.Namespace, f.Name)
}

func (f *FFI) SetBroadcastMessage(msgID *UUID) {
f.Message = msgID
}

// Scan implements sql.Scanner
func (p *FFIParams) Scan(src interface{}) error {
switch src := src.(type) {
case nil:
p = nil
return nil
case string:
return json.Unmarshal([]byte(src), &p)
case []byte:
return json.Unmarshal(src, &p)
default:
return i18n.NewError(context.Background(), i18n.MsgTypeRestoreFailed, src, p)
}
}

func (p FFIParams) Value() (driver.Value, error) {
bytes, _ := json.Marshal(p)
return bytes, nil
}
96 changes: 96 additions & 0 deletions pkg/fftypes/ffi_param_validator.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
// Copyright © 2022 Kaleido, Inc.
//
// SPDX-License-Identifier: Apache-2.0
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package fftypes

import (
"github.com/santhosh-tekuri/jsonschema/v5"
)

type BaseFFIParamValidator struct{}

func (v BaseFFIParamValidator) Compile(ctx jsonschema.CompilerContext, m map[string]interface{}) (jsonschema.ExtSchema, error) {
return nil, nil
}

func (v *BaseFFIParamValidator) GetMetaSchema() *jsonschema.Schema {
return jsonschema.MustCompileString("ffi.json", `{
"$ref": "#/$defs/ffiParam",
"$defs": {
"integerTypeOptions": {
"type": "object",
"properties": {
"type": {
"type": "string",
"enum": [
"integer",
"string"
]
}
}
},
"ffiParam": {
"oneOf": [
{
"properties": {
"type": {
"type": [
"string"
],
"enum": [
"boolean",
"integer",
"string",
"array",
"object"
]
}
},
"required": [
"type"
]
},
{
"type": "object",
"properties": {
"oneOf": {
"type": "array",
"items": {
"$ref": "#/$defs/integerTypeOptions"
}
}
},
"required": [
"oneOf"
]
}
]
}
}
}`)
}

func (v *BaseFFIParamValidator) GetExtensionName() string {
return "ffi"
}

func NewFFISchemaCompiler() *jsonschema.Compiler {
c := jsonschema.NewCompiler()
c.Draft = jsonschema.Draft2020
v := BaseFFIParamValidator{}
c.RegisterExtension(v.GetExtensionName(), v.GetMetaSchema(), v)
return c
}
35 changes: 35 additions & 0 deletions pkg/fftypes/ffi_param_validator_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
// Copyright © 2022 Kaleido, Inc.
//
// SPDX-License-Identifier: Apache-2.0
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package fftypes

import (
"testing"

"github.com/santhosh-tekuri/jsonschema/v5"
"github.com/stretchr/testify/assert"
)

func TestGetBaseFFIParamValidator(t *testing.T) {
c := NewFFISchemaCompiler()
assert.NotNil(t, c)
}
func TestBaseFFIParamValidatorCompile(t *testing.T) {
v := BaseFFIParamValidator{}
c, err := v.Compile(jsonschema.CompilerContext{}, map[string]interface{}{})
assert.Nil(t, c)
assert.NoError(t, err)
}
Loading

0 comments on commit 7f6b2ea

Please sign in to comment.