Skip to content

Commit

Permalink
DEV-1074: add gRPC connection func
Browse files Browse the repository at this point in the history
  • Loading branch information
Toktar committed Apr 12, 2022
1 parent fe3b4a7 commit ce77811
Show file tree
Hide file tree
Showing 5 changed files with 159 additions and 28 deletions.
3 changes: 3 additions & 0 deletions config.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
networks:
mainnet: https://rpc.cheqd.net:443
testnet: https://api.testnet.cheqd.network:443
51 changes: 41 additions & 10 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,26 +2,43 @@ package main

import (
"net/http"
"os"

"github.com/cheqd/cheqd-did-resolver/services"
"github.com/labstack/echo/v4"
"github.com/labstack/echo/v4/middleware"
"gopkg.in/yaml.v2"

//"net/url"
"strings"
)

func main() {
//setup
requestService := services.NewRequestService()
type Config struct {
Networks map[string]string `yaml:"networks"`
}

func main() {
// Echo instance
e := echo.New()

// Middleware
e.Use(middleware.Logger())
e.Use(middleware.Recover())

//setup
e.StdLogger.Println("get config")
config, err := getConfig("config.yml")
e.StdLogger.Println(config)
if err != nil {
e.Logger.Fatal(err)
}
ledgerService := services.NewLedgerService()
for network, url := range config.Networks {
e.StdLogger.Println(network)
ledgerService.RegisterLedger(network, url)
}
requestService := services.NewRequestService(ledgerService)

// Routes
e.GET("/identifier/:did", func(c echo.Context) error {
did := c.Param("did")
Expand All @@ -32,11 +49,13 @@ func main() {
//}
accept := strings.Split(c.Request().Header.Get("accept"), ";")[0]
resolutionOption := map[string]string{"Accept": accept}
responseBody := requestService.ProcessDIDRequest(did, resolutionOption)
if err != nil {

e.StdLogger.Println("get did")
responseBody, err := requestService.ProcessDIDRequest(did, resolutionOption)
status := http.StatusOK
if err != "" {
status = http.StatusBadRequest
}
return c.String(http.StatusOK, responseBody)
return c.String(status, responseBody)
//opt := resolver.ResolutionOption{Accept: accept}
//rr := resolver.ResolveRepresentation(conn, did, opt)
//
Expand All @@ -57,7 +76,19 @@ func main() {
e.Logger.Fatal(e.Start(":1313"))
}

// Handler
func hello(c echo.Context) error {
return c.String(http.StatusOK, "Hello, World!")
func getConfig(configFileName string) (Config, error) {
f, err := os.Open(configFileName)
if err != nil {
return Config{}, err
}
defer f.Close()

var cfg Config
decoder := yaml.NewDecoder(f)
err = decoder.Decode(&cfg)
if err != nil {
return Config{}, err
}

return cfg, nil
}
35 changes: 35 additions & 0 deletions services/diddoc_service_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package services

import (
"fmt"
"testing"

cheqd "github.com/cheqd/cheqd-node/x/cheqd/types"
"github.com/stretchr/testify/require"
// jsonpb Marshaller is deprecated, but is needed because there's only one way to proto
// marshal in combination with our proto generator version
//nolint
)

func TestMarshallDID(t *testing.T) {
didDocService := DIDDocService{}
verificationMethod1 := cheqd.VerificationMethod{
Id: "did:cheqd:mainnet:N22KY2Dyvmuu2PyyqSFKue#verkey",
Type: "Ed25519VerificationKey2020",
Controller: "did:cheqd:mainnet:N22KY2Dyvmuu2PyyqSFKue",
PublicKeyMultibase: "zAKJP3f7BD6W4iWEQ9jwndVTCBq8ua2Utt8EEjJ6Vxsf",
}
didDoc := cheqd.Did{
Context: []string{"test"},
Id: "did:cheqd:mainnet:N22KY2Dyvmuu2PyyqSFKue",
VerificationMethod: []*cheqd.VerificationMethod{&verificationMethod1},
}

expectedDID := "{\"@context\":[\"test\"],\"id\":\"did:cheqd:mainnet:N22KY2Dyvmuu2PyyqSFKue\",\"verificationMethod\":[{\"controller\":\"did:cheqd:mainnet:N22KY2Dyvmuu2PyyqSFKue\",\"id\":\"did:cheqd:mainnet:N22KY2Dyvmuu2PyyqSFKue#verkey\",\"publicKeyMultibase\":\"zAKJP3f7BD6W4iWEQ9jwndVTCBq8ua2Utt8EEjJ6Vxsf\",\"type\":\"Ed25519VerificationKey2020\"}]}"

jsonDID, err := didDocService.MarshallDID(didDoc)

fmt.Println(jsonDID)
require.EqualValues(t, jsonDID, expectedDID)
require.Empty(t, err)
}
71 changes: 66 additions & 5 deletions services/ledger_service.go
Original file line number Diff line number Diff line change
@@ -1,26 +1,87 @@
package services

import (
"context"
"errors"
"flag"
"strings"
"time"

cheqd "github.com/cheqd/cheqd-node/x/cheqd/types"
"google.golang.org/grpc"
)

type LedgerService struct {
ledgers map[string]string // namespace -> url
}

func (LedgerService) QueryDIDDoc(did string) (cheqd.Did, cheqd.Metadata, error) {
return cheqd.Did{}, cheqd.Metadata{}, nil
func NewLedgerService() LedgerService {
ls := LedgerService{}
ls.ledgers = make(map[string]string)
return ls
}

func (ls LedgerService) QueryDIDDoc(did string) (cheqd.Did, cheqd.Metadata, error) {
serverAddr := ls.ledgers[getNamespace(did)]
println(serverAddr)
conn, err := openGRPCConnection(serverAddr)

if err != nil {
return cheqd.Did{}, cheqd.Metadata{}, err
}

qc := cheqd.NewQueryClient(conn)
defer conn.Close()

didDocResponse, err := qc.Did(context.Background(), &cheqd.QueryGetDidRequest{Id: did})

println(didDocResponse)
return *didDocResponse.Did, *didDocResponse.Metadata, err
}

func (ls *LedgerService) RegisterLedger(namespace string, url string) error {
if !(namespace == "") {
println("RegisterLedger")

if namespace == "" {
println("Namespace cannot be empty")
return errors.New("Namespace cannot be empty")
}
if !(url == "") {
if url == "" {
println("Ledger node url cannot be empty")
return errors.New("Ledger node url cannot be empty")
}
ls.ledgers[namespace] = url
ls.ledgers[namespace] = *flag.String("grpc-server-address-"+namespace, url,
"The target grpc server address in the format of host:port")

println("RegisterLedger end")

return nil
}

func openGRPCConnection(addr string) (conn *grpc.ClientConn, err error) {
opts := []grpc.DialOption{
grpc.WithInsecure(),
grpc.WithBlock(),
}

ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
ctx, cancel = context.WithDeadline(ctx, <-time.After(5*time.Second))
defer cancel()
// if cancel != nil {
// cancel()
// println("openGRPCConnection: cancel")
// return nil, errors.New("gRPC connection haven't opened")
// }
conn, err = grpc.DialContext(ctx, addr, opts...)
if err != nil {
println("openGRPCConnection: context failed")
println(err.Error())
return nil, err
}
println("openGRPCConnection: opened")
return conn, nil
}

func getNamespace(did string) string {
return strings.SplitN(did, ":", 4)[2]
}
27 changes: 14 additions & 13 deletions services/request_service.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,42 +14,43 @@ type RequestService struct {
didDocService DIDDocService
}

func NewRequestService() RequestService {
func NewRequestService(ledgerService LedgerService) RequestService {
return RequestService{
ledgerService: LedgerService{},
ledgerService: ledgerService,
didDocService: DIDDocService{},
}
}

func (rs RequestService) ProcessDIDRequest(did string, params map[string]string) string {
func (rs RequestService) ProcessDIDRequest(did string, params map[string]string) (string, string) {
didResolution := rs.resolve(did, types.ResolutionOption{Accept: params["Accept"]})
resolutionMetadata, err1 := json.Marshal(didResolution.ResolutionMetadata)
didDoc, err2 := rs.didDocService.MarshallDID(didResolution.Did)
metadata, err3 := rs.didDocService.MarshallProto(&didResolution.Metadata)

if err1 != nil || err2 != nil || err3 != nil {
resolutionMetadata := types.NewResolutionMetadata(resolutionOptions.Accept,
resolutionMetadataProto := types.NewResolutionMetadata(params["Accept"],
types.ResolutionRepresentationNotSupported)
resolutionMetadataJson, _ := json.Marshal(didResolution.ResolutionMetadata)
return createJsonResolution("null", "null", string(resolutionMetadataJson))
resolutionMetadataJson, _ := json.Marshal(resolutionMetadataProto)
return createJsonResolution("null", "null", string(resolutionMetadataJson)),
resolutionMetadataProto.ResolutionError
}

if didResolution.ResolutionMetadata.ResolutionError != nil {
return createJsonResolution("null", "null", string(resolutionMetadata))
if didResolution.ResolutionMetadata.ResolutionError != "" {
return createJsonResolution("null", "null", string(resolutionMetadata)),
didResolution.ResolutionMetadata.ResolutionError
}

return createJsonResolution(didDoc, metadata, string(resolutionMetadata))
return createJsonResolution(didDoc, metadata, string(resolutionMetadata)), ""

}

// https://w3c-ccg.github.io/did-resolution/#resolving
func (rs RequestService) resolve(did string, resolutionOptions types.ResolutionOption) types.DidResolution {
didDoc, metadata, err := rs.ledgerService.QueryDIDDoc(did)
didResolutionMetadata := types.NewResolutionMetadata(resolutionOptions.Accept, "")
result := types.DidResolution{didDoc, metadata, didResolutionMetadata}
if err != nil {
didResolutionMetadata.ResolutionError = types.ResolutionNotFound
return types.DidResolution{nil, nil, didResolutionMetadata}
return types.DidResolution{ResolutionMetadata: didResolutionMetadata}
}
return types.DidResolution{didDoc, metadata, didResolutionMetadata}
}
Expand All @@ -63,7 +64,7 @@ func (rs RequestService) resolve(did string, resolutionOptions types.ResolutionO
// return dereferencingMetadata, contentStream, contentMetadata
// }

func createJsonResolution(didDoc string, metadata string, resolutionMetadata string) {
func createJsonResolution(didDoc string, metadata string, resolutionMetadata string) string {
return fmt.Sprintf("{\"didDocument\" : %s,\"didDocumentMetadata\" : %s,\"didResolutionMetadata\" : %s}",
didDoc, metadata, resolutionMetadata), ""
didDoc, metadata, resolutionMetadata)
}

0 comments on commit ce77811

Please sign in to comment.