Skip to content

Commit

Permalink
Merge pull request #837 from mesg-foundation/feature/marketplace-api
Browse files Browse the repository at this point in the history
Marketplace service new api for manifest
  • Loading branch information
NicolasMahe authored Mar 29, 2019
2 parents 8a5af82 + 61fe9fe commit ac6b59a
Show file tree
Hide file tree
Showing 9 changed files with 918 additions and 226 deletions.
5 changes: 2 additions & 3 deletions commands/commands.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,8 @@ type ServiceExecutor interface {

// MarketplaceExecutor is an interface that handles marketplace commands.
type MarketplaceExecutor interface {
CreateManifest(path string, hash string) (provider.MarketplaceManifestData, error)
UploadServiceFiles(path string, manifest provider.MarketplaceManifestData) (protocol string, source string, err error)
PublishServiceVersion(sid, manifest, manifestProtocol, from string) (provider.Transaction, error)
UploadSource(path string) (deployment provider.MarketplaceDeployedSource, err error)
PublishServiceVersion(service provider.MarketplaceManifestServiceData, from string) (provider.Transaction, error)
CreateServiceOffer(sid string, price string, duration string, from string) (provider.Transaction, error)
Purchase(sid, offerIndex, from string) ([]provider.Transaction, error)
SendSignedTransaction(signedTransaction string) (provider.TransactionReceipt, error)
Expand Down
74 changes: 35 additions & 39 deletions commands/marketplace_publish.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,26 @@ package commands

import (
"fmt"
"strings"

"github.com/mesg-foundation/core/commands/provider"
"github.com/mesg-foundation/core/service/importer"
"github.com/mesg-foundation/core/utils/pretty"
"github.com/mesg-foundation/core/utils/readme"
"github.com/spf13/cobra"
survey "gopkg.in/AlecAivazis/survey.v1"
)

const (
// marketplaceServiceHashVersion is the version of the service hash used by the core.
marketplaceServiceHashVersion = "1"
)

type marketplacePublishCmd struct {
baseMarketplaceCmd

path string
manifest provider.MarketplaceManifestData
service provider.MarketplaceService
path string
sid string
hash string

e Executor
}
Expand All @@ -35,45 +41,22 @@ func newMarketplacePublishCmd(e Executor) *marketplacePublishCmd {
}

func (c *marketplacePublishCmd) preRunE(cmd *cobra.Command, args []string) error {
var (
err error
question = "a new service"
)

if err := c.askAccountAndPassphrase(); err != nil {
return err
}

c.path = getFirstOrCurrentPath(args)

sid, hash, err := deployService(c.e, c.path, map[string]string{})
var err error
c.sid, c.hash, err = deployService(c.e, c.path, map[string]string{})
if err != nil {
return err
}
fmt.Printf("%s Service deployed with sid %s and hash %s\n", pretty.SuccessSign, pretty.Success(sid), pretty.Success(hash))

c.manifest, err = c.e.CreateManifest(c.path, hash)
if err != nil {
return err
}

pretty.Progress("Getting service data...", func() {
c.service, err = c.e.GetService(c.manifest.Service.Definition.Sid)
})
outputError, isMarketplaceError := err.(provider.MarketplaceErrorOutput)
if err != nil && !isMarketplaceError {
return err
}
if outputError.Code != "notFound" {
question = "a new version of service"
if !strings.EqualFold(c.service.Owner, c.account) {
return fmt.Errorf("the service's owner %q is different than the specified account", c.service.Owner)
}
}
fmt.Printf("%s Service deployed with sid %s and hash %s\n", pretty.SuccessSign, pretty.Success(c.sid), pretty.Success(c.hash))

var confirmed bool
if err := survey.AskOne(&survey.Confirm{
Message: fmt.Sprintf("Are you sure to publish %s %q from path %q using account %q?", question, c.manifest.Service.Definition.Sid, c.path, c.account),
Message: fmt.Sprintf("Are you sure to publish a new version of service %q from path %q using account %q?", c.sid, c.path, c.account),
}, &confirmed, nil); err != nil {
return err
}
Expand All @@ -86,21 +69,34 @@ func (c *marketplacePublishCmd) preRunE(cmd *cobra.Command, args []string) error

func (c *marketplacePublishCmd) runE(cmd *cobra.Command, args []string) error {
var (
tx provider.Transaction
err error
manifestProtocol string
manifestSource string
tx provider.Transaction
err error
deployment provider.MarketplaceDeployedSource
)

pretty.Progress("Uploading service source code on the marketplace...", func() {
// TODO: add a progress for the upload
manifestProtocol, manifestSource, err = c.e.UploadServiceFiles(c.path, c.manifest)
deployment, err = c.e.UploadSource(c.path)
})
if err != nil {
return err
}
definition, err := importer.From(c.path)
if err != nil {
return err
}
readme, err := readme.Lookup(c.path)
if err != nil {
return err
}
pretty.Progress("Publishing service on the marketplace...", func() {
tx, err = c.e.PublishServiceVersion(c.manifest.Service.Definition.Sid, manifestSource, manifestProtocol, c.account)
tx, err = c.e.PublishServiceVersion(provider.MarketplaceManifestServiceData{
Definition: *definition,
Hash: c.hash,
HashVersion: marketplaceServiceHashVersion,
Readme: readme,
Deployment: deployment,
}, c.account)
if err != nil {
return
}
Expand All @@ -110,9 +106,9 @@ func (c *marketplacePublishCmd) runE(cmd *cobra.Command, args []string) error {
return err
}
fmt.Printf("%s Service published with success\n", pretty.SuccessSign)
fmt.Printf("%s See it on the marketplace: https://marketplace.mesg.com/services/%s\n", pretty.SuccessSign, c.manifest.Service.Definition.Sid)
fmt.Printf("%s See it on the marketplace: https://marketplace.mesg.com/services/%s\n", pretty.SuccessSign, c.sid)

fmt.Printf("%s To create a service offer, execute the command:\n\tmesg-core marketplace create-offer %s\n", pretty.SuccessSign, c.manifest.Service.Definition.Sid)
fmt.Printf("%s To create a service offer, execute the command:\n\tmesg-core marketplace create-offer %s\n", pretty.SuccessSign, c.sid)

return nil
}
102 changes: 16 additions & 86 deletions commands/mocks/Executor.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

51 changes: 10 additions & 41 deletions commands/provider/marketplace_provider.go
Original file line number Diff line number Diff line change
@@ -1,14 +1,11 @@
package provider

import (
"bytes"
"encoding/json"

"github.com/docker/docker/pkg/archive"
"github.com/mesg-foundation/core/ipfs"
"github.com/mesg-foundation/core/protobuf/coreapi"
"github.com/mesg-foundation/core/service/importer"
"github.com/mesg-foundation/core/utils/readme"
)

// MarketplaceProvider is a struct that provides all methods required by service command.
Expand All @@ -22,12 +19,10 @@ func NewMarketplaceProvider(c coreapi.CoreClient) *MarketplaceProvider {
}

// PublishServiceVersion executes the create service version task
func (p *MarketplaceProvider) PublishServiceVersion(sid, manifest, manifestProtocol, from string) (Transaction, error) {
func (p *MarketplaceProvider) PublishServiceVersion(service MarketplaceManifestServiceData, from string) (Transaction, error) {
input := marketplacePublishServiceVersionTaskInputs{
marketplaceTransactionTaskInputs: marketplaceTransactionTaskInputs{From: from},
Sid: sid,
Manifest: manifest,
ManifestProtocol: manifestProtocol,
Service: service,
}
var output Transaction
return output, p.call("publishServiceVersion", input, &output)
Expand Down Expand Up @@ -85,49 +80,23 @@ func (p *MarketplaceProvider) IsAuthorized(sid string, versionHash string, addre
return output.Authorized, output.Sid, output.Source, output.Type, p.call("isAuthorized", input, &output)
}

// UploadServiceFiles upload the tarball and the definition file, and returns the address of the definition file
func (p *MarketplaceProvider) UploadServiceFiles(path string, manifest MarketplaceManifestData) (protocol string, source string, err error) {
// UploadSource upload the tarball, and returns the address of the uploaded sources
func (p *MarketplaceProvider) UploadSource(path string) (MarketplaceDeployedSource, error) {
// upload service source to IPFS
tar, err := archive.TarWithOptions(path, &archive.TarOptions{
Compression: archive.Gzip,
})
if err != nil {
return "", "", err
return MarketplaceDeployedSource{}, err
}
tarballResponse, err := ipfs.Add("tarball", tar)
if err != nil {
return "", "", err
}

manifest.Service.Deployment.Type = marketplaceDeploymentType
manifest.Service.Deployment.Source = tarballResponse.Hash

// upload manifest
manifestData, err := json.Marshal(manifest)
if err != nil {
return "", "", err
}
definitionResponse, err := ipfs.Add("manifest", bytes.NewReader(manifestData))
if err != nil {
return "", "", err
}

return marketplaceDeploymentType, definitionResponse.Hash, nil
}

// CreateManifest creates the manifest file for the service in path.
func (p *MarketplaceProvider) CreateManifest(path string, hash string) (MarketplaceManifestData, error) {
var data MarketplaceManifestData
definition, err := importer.From(path)
if err != nil {
return data, err
return MarketplaceDeployedSource{}, err
}
data.Version = marketplacePublishVersion
data.Service.Hash = hash
data.Service.HashVersion = marketplaceServiceHashVersion
data.Service.Definition = *definition
data.Service.Readme, err = readme.Lookup(path)
return data, err
return MarketplaceDeployedSource{
Type: marketplaceDeploymentType,
Source: tarballResponse.Hash,
}, nil
}

func (p *MarketplaceProvider) call(task string, inputs interface{}, output interface{}) error {
Expand Down
Loading

0 comments on commit ac6b59a

Please sign in to comment.