Skip to content

Commit

Permalink
Merge pull request #1 from it-chain/develop
Browse files Browse the repository at this point in the history
Develop
  • Loading branch information
hea9549 authored Aug 4, 2018
2 parents 1e8d99c + 4b32d3a commit 645541f
Show file tree
Hide file tree
Showing 11 changed files with 1,253 additions and 0 deletions.
41 changes: 41 additions & 0 deletions cell.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
/*
* Copyright 2018 It-chain
*
* 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
*
* https://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 sdk

import "github.com/it-chain/leveldb-wrapper"

type Cell struct {
DBHandler *leveldbwrapper.DBHandle
}

func NewCell(name string) *Cell {
path := "./wsdb"
dbProvider := leveldbwrapper.CreateNewDBProvider(path)
return &Cell{
DBHandler: dbProvider.GetDBHandle(name),
}
}

func (c Cell) PutData(key string, value []byte) error {
return c.DBHandler.Put([]byte(key), value, true)
}

func (c Cell) GetData(key string) ([]byte, error) {
value, err := c.DBHandler.Get([]byte(key))
return value, err
}
151 changes: 151 additions & 0 deletions example/handler/handler.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
/*
* Copyright 2018 It-chain
*
* 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
*
* https://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 handler

import (
"strconv"

"errors"

"fmt"

"github.com/it-chain/sdk"
"github.com/it-chain/sdk/logger"
"github.com/it-chain/sdk/pb"
)

type HandlerExample struct {
}

func (*HandlerExample) Name() string {
return "sample"
}

func (*HandlerExample) Versions() []string {
vers := make([]string, 0)
vers = append(vers, "1.0")
vers = append(vers, "1.2")
return vers
}

func (*HandlerExample) Handle(request *pb.Request, cell *sdk.Cell) (*pb.Response, error) {
switch request.Type {
case "invoke":
return handleInvoke(request, cell)
case "query":
return handleQuery(request, cell)
case "test":
fmt.Println("req : " + request.Uuid)
if request.Uuid == "0" {
cell.PutData("test", []byte("0"))
return responseSuccess(request, []byte(string(0))), nil
}
data, err := cell.GetData("test")
if err != nil {
return responseError(request, err), err
}
if len(data) == 0 {
err := errors.New("no data err")
return responseError(request, err), err
}
strData := string(data)
intData, err := strconv.Atoi(strData)
if err != nil {
return responseError(request, err), err
}
intData = intData + 1
changeData := strconv.Itoa(intData)
err = cell.PutData("test", []byte(changeData))
if err != nil {
return responseError(request, err), err
}
return responseSuccess(request, []byte(changeData)), nil
default:
logger.Fatal(nil, "unknown request type")
err := errors.New("unknown request type")
return responseError(request, err), err
}
}
func handleQuery(request *pb.Request, cell *sdk.Cell) (*pb.Response, error) {
switch request.FunctionName {
case "getA":
b, err := cell.GetData("A")
if err != nil {
return responseError(request, err), err
}
return responseSuccess(request, b), nil

default:
err := errors.New("unknown query method")
return responseError(request, err), err
}
}
func handleInvoke(request *pb.Request, cell *sdk.Cell) (*pb.Response, error) {
switch request.FunctionName {
case "initA":
err := cell.PutData("A", []byte("0"))
if err != nil {
return responseError(request, err), err
}
return responseSuccess(request, nil), nil
case "incA":
data, err := cell.GetData("A")
if err != nil {
return responseError(request, err), err
}
if len(data) == 0 {
err := errors.New("no data err")
return responseError(request, err), err
}
strData := string(data)
intData, err := strconv.Atoi(strData)
if err != nil {
return responseError(request, err), err
}
intData++
changeData := strconv.Itoa(intData)
err = cell.PutData("A", []byte(changeData))
if err != nil {
return responseError(request, err), err
}
return responseSuccess(request, nil), nil
default:
err := errors.New("unknown invoke method")
return responseError(request, err), err
}
}

func responseError(request *pb.Request, err error) *pb.Response {
return &pb.Response{
Uuid: request.Uuid,
Type: request.Type,
Result: false,
Data: nil,
Error: err.Error(),
}
}

func responseSuccess(request *pb.Request, data []byte) *pb.Response {
return &pb.Response{
Uuid: request.Uuid,
Type: request.Type,
Result: true,
Data: data,
Error: "",
}
}
46 changes: 46 additions & 0 deletions example/icode.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
/*
* Copyright 2018 It-chain
*
* 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
*
* https://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 main

import (
"os"

"github.com/it-chain/sdk"
"github.com/it-chain/sdk/example/handler"
"github.com/it-chain/sdk/logger"
"github.com/jessevdk/go-flags"
)

var opts struct {
Port int `short:"p" long:"port" description:"set port"`
}

func main() {
logger.EnableFileLogger(true, "./icode.log")
parser := flags.NewParser(&opts, flags.Default)
_, err := parser.Parse()
if err != nil {
logger.Error(nil, "fail parse args: "+err.Error())
os.Exit(1)
}

exHandler := &handler.HandlerExample{}
ibox := sdk.NewIBox(opts.Port)
ibox.SetHandler(exHandler)
ibox.On(30)
}
113 changes: 113 additions & 0 deletions example/icode_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
/*
* Copyright 2018 It-chain
*
* 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
*
* https://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 main

import (
"context"
"fmt"
"io"
"strconv"
"testing"
"time"

"sync"

"github.com/it-chain/sdk"
"github.com/it-chain/sdk/example/handler"
"github.com/it-chain/sdk/logger"
"github.com/it-chain/sdk/pb"
"github.com/stretchr/testify/assert"
"google.golang.org/grpc"
)

func TestICode(t *testing.T) {
logger.EnableFileLogger(true, "./icode.log")

wg := sync.WaitGroup{}
wg.Add(1)
exHandler := &handler.HandlerExample{}
ibox := sdk.NewIBox(5000)
ibox.SetHandler(exHandler)
go func() {
err := ibox.On(30)
if err != nil {
panic("error in listen server" + err.Error())
}
}()
time.Sleep(3 * time.Second)
start := time.Now()
stream, _ := DialMockClient("127.0.0.1:5000", func(response *pb.Response, e error) {
if e != nil {
fmt.Println(e)
}
if response.Data != nil {
fmt.Println("id : " + response.Uuid + ",res : " + string(response.Data))
}
if response.Uuid == "9999" {
end := time.Now()
assert.WithinDuration(t, end, start, 2*time.Second)
wg.Done()
}
})
for i := 0; i < 10000; i++ {
stream.clientStream.Send(&pb.Request{
Uuid: strconv.Itoa(i),
Type: "test",
FunctionName: "test_request",
Args: nil,
})
}

wg.Wait()
}

type MockClient struct {
clientStream pb.BistreamService_RunICodeClient
}

func DialMockClient(serverIp string, handler func(*pb.Response, error)) (*MockClient, context.CancelFunc) {

dialContext, _ := context.WithTimeout(context.Background(), 3*time.Second)

conn, err := grpc.DialContext(dialContext, serverIp, grpc.WithInsecure())
if err != nil {
panic("error in dial")
}
client := pb.NewBistreamServiceClient(conn)
ctx, cf := context.WithCancel(context.Background())
clientStream, err := client.RunICode(ctx)
if err != nil {
panic("error in run Icode" + err.Error())
}
mockClient := MockClient{
clientStream: clientStream,
}
go func() {
for {
res, err := clientStream.Recv()
if err == io.EOF {
fmt.Println("io.EOF handle finish.")
return
}

handler(res, err)

}
}()
return &mockClient, cf
}
26 changes: 26 additions & 0 deletions handler.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/*
* Copyright 2018 It-chain
*
* 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
*
* https://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 sdk

import "github.com/it-chain/sdk/pb"

type TransactionHandler interface {
Name() string
Versions() []string
Handle(request *pb.Request, cell *Cell) (*pb.Response, error)
}
Loading

0 comments on commit 645541f

Please sign in to comment.