Skip to content

How to properly use apex/gatway ? #42

@KOSSOKO

Description

@KOSSOKO

Hello, i'm trying to migrate this Go project to lambda : https://github.com/readium/readium-lcp-server/tree/master/lcpserver

I found Apex/gateway, and it seems to be the solution. But i have few questions because my case is a bit complex and example provided doesnt help to understand how to correctly migrate.

The lcp server is divided in 3 parts:
lcpserver.go where main have the listenAndServe:

	s := lcpserver.New(":"+parsedPort, readonly, &idx, &store, &lst, &cert, packager, authenticator)
	if readonly {
		log.Println("License server running in readonly mode on port " + parsedPort)
	} else {
		log.Println("License server running on port " + parsedPort)
	}
	log.Println("Using database " + dbURI)
	log.Println("Public base URL=" + config.Config.LcpServer.PublicBaseUrl)
	log.Println("License links:")
	for nameOfLink, link := range config.Config.License.Links {
		log.Println("  " + nameOfLink + " => " + link)
	}

	if err := s.ListenAndServe(); err != nil {
		log.Println("Error " + err.Error())
	
```}

server.go in wich we have all redirection and the new above and all handlefunc:

func New(bindAddr string, readonly bool, idx *index.Index, st *storage.Store, lst *license.Store, cert *tls.Certificate, packager *pack.Packager, basicAuth *auth.BasicAuth) *Server {

sr := api.CreateServerRouter("")

s := &Server{
	Server: http.Server{
		Handler:        sr.N,
		Addr:           bindAddr,
		WriteTimeout:   240 * time.Second,
		ReadTimeout:    5 * time.Second,
		MaxHeaderBytes: 1 << 20,
	},
	readonly: readonly,
	idx:      idx,
	st:       st,
	lst:      lst,
	cert:     cert,
	source:   pack.ManualSource{},
}

// Route.PathPrefix: http://www.gorillatoolkit.org/pkg/mux#Route.PathPrefix
// Route.Subrouter: http://www.gorillatoolkit.org/pkg/mux#Route.Subrouter
// Router.StrictSlash: http://www.gorillatoolkit.org/pkg/mux#Router.StrictSlash

// methods related to EPUB encrypted content

contentRoutesPathPrefix := "/contents"
contentRoutes := sr.R.PathPrefix(contentRoutesPathPrefix).Subrouter().StrictSlash(false)

s.handleFunc(sr.R, contentRoutesPathPrefix, apilcp.ListContents).Methods("GET")

// get encrypted content by content id (a uuid)
s.handleFunc(contentRoutes, "/{content_id}", apilcp.GetContent).Methods("GET")
// get all licenses associated with a given content
s.handlePrivateFunc(contentRoutes, "/{content_id}/licenses", apilcp.ListLicensesForContent, basicAuth).Methods("GET")

if !readonly {
	// put content to the storage
	s.handlePrivateFunc(contentRoutes, "/{content_id}", apilcp.AddContent, basicAuth).Methods("PUT")
	// generate a license for given content
	s.handlePrivateFunc(contentRoutes, "/{content_id}/license", apilcp.GenerateLicense, basicAuth).Methods("POST")
	// deprecated, from a typo in the lcp server spec
	s.handlePrivateFunc(contentRoutes, "/{content_id}/licenses", apilcp.GenerateLicense, basicAuth).Methods("POST")
	// generate a licensed publication
	s.handlePrivateFunc(contentRoutes, "/{content_id}/publication", apilcp.GenerateLicensedPublication, basicAuth).Methods("POST")
	// deprecated, from a typo in the lcp server spec
	s.handlePrivateFunc(contentRoutes, "/{content_id}/publications", apilcp.GenerateLicensedPublication, basicAuth).Methods("POST")
}

// methods related to licenses

licenseRoutesPathPrefix := "/licenses"
licenseRoutes := sr.R.PathPrefix(licenseRoutesPathPrefix).Subrouter().StrictSlash(false)

s.handlePrivateFunc(sr.R, licenseRoutesPathPrefix, apilcp.ListLicenses, basicAuth).Methods("GET")
// get a license
s.handlePrivateFunc(licenseRoutes, "/{license_id}", apilcp.GetLicense, basicAuth).Methods("GET")
s.handlePrivateFunc(licenseRoutes, "/{license_id}", apilcp.GetLicense, basicAuth).Methods("POST")
// get a licensed publication via a license id
s.handlePrivateFunc(licenseRoutes, "/{license_id}/publication", apilcp.GetLicensedPublication, basicAuth).Methods("POST")
if !readonly {
	// update a license
	s.handlePrivateFunc(licenseRoutes, "/{license_id}", apilcp.UpdateLicense, basicAuth).Methods("PATCH")
}

s.source.Feed(packager.Incoming)
return s

}

and licence.go in which we have the apis, for example

// GenerateLicense generates and returns a new license,
// for a given content identified by its id
// plus a partial license given as input
func GenerateLicense(w http.ResponseWriter, r *http.Request, s Server) {

vars := mux.Vars(r)
// get the content id from the request URL
contentID := vars["content_id"]

log.Println("Generate License for content id", contentID)

// get the input body
// note: no need to create licIn / licOut here, as the input body contains
// info that we want to keep in the full license.
var lic license.License
err := DecodeJSONLicense(r, &lic)
if err != nil {
	problem.Error(w, r, problem.Problem{Detail: err.Error()}, http.StatusBadRequest)
	return
}
// check mandatory information in the input body
err = checkGenerateLicenseInput(&lic)
if err != nil {
	problem.Error(w, r, problem.Problem{Detail: err.Error()}, http.StatusBadRequest)
	return
}
// init the license with an id and issue date
license.Initialize(contentID, &lic)

// normalize the start and end date, UTC, no milliseconds
setRights(&lic)

// build the license
err = buildLicense(&lic, s)
if err != nil {
	problem.Error(w, r, problem.Problem{Detail: err.Error()}, http.StatusInternalServerError)
	return
}

// store the license in the db
err = s.Licenses().Add(lic)
if err != nil {
	problem.Error(w, r, problem.Problem{Detail: err.Error()}, http.StatusInternalServerError)
	//problem.Error(w, r, problem.Problem{Detail: err.Error(), Instance: contentID}, http.StatusInternalServerError)
	return
}
// set http headers
w.Header().Add("Content-Type", api.ContentType_LCP_JSON)
w.Header().Add("Content-Disposition", `attachment; filename="license.lcpl"`)
w.WriteHeader(http.StatusCreated)
// send back the license
// do not escape characters
enc := json.NewEncoder(w)
enc.SetEscapeHTML(false)
enc.Encode(lic)

// notify the lsd server of the creation of the license.
// this is an asynchronous call.
go notifyLsdServer(lic, s)

}


If i understand well how apex/gateway works, i have just to change `ListenAndServe()` in lcpserver.go and replace it by `gateway.ListenAndServe(":3000", nil)`  ?
What about API gateway ? Should i create each ressource or use as posted in some examples on internet ?
Thanks for your answer
![image](https://user-images.githubusercontent.com/11942543/111508441-00771300-874c-11eb-97de-c8603725d023.png)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions