Skip to content

Commit

Permalink
feat: Add Job Creator support endpoints to the Solver (#498)
Browse files Browse the repository at this point in the history
Add Job Creator support endpoints to the Solver
  • Loading branch information
kelindi authored Jan 29, 2025
1 parent a6ddf89 commit 9afda87
Showing 1 changed file with 119 additions and 60 deletions.
179 changes: 119 additions & 60 deletions pkg/solver/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,9 @@ func (solverServer *solverServer) ListenAndServe(ctx context.Context, cm *system
subrouter.HandleFunc("/job_offers", http.GetHandler(solverServer.getJobOffers)).Methods("GET")
subrouter.HandleFunc("/job_offers", http.PostHandler(solverServer.addJobOffer)).Methods("POST")

subrouter.HandleFunc("/job_offers/{id}", http.GetHandler(solverServer.getJobOffer)).Methods("GET")
subrouter.HandleFunc("/job_offers/{id}/files", solverServer.jobOfferDownloadFiles).Methods("GET")

subrouter.HandleFunc("/resource_offers", http.GetHandler(solverServer.getResourceOffers)).Methods("GET")
subrouter.HandleFunc("/resource_offers", http.PostHandler(solverServer.addResourceOffer)).Methods("POST")

Expand Down Expand Up @@ -244,6 +247,17 @@ func (solverServer *solverServer) getDeals(res corehttp.ResponseWriter, req *cor
*
*
*/

func (solverServer *solverServer) getJobOffer(res corehttp.ResponseWriter, req *corehttp.Request) (data.JobOfferContainer, error) {
vars := mux.Vars(req)
id := vars["id"]
jobOffer, err := solverServer.store.GetJobOffer(id)
if err != nil {
return data.JobOfferContainer{}, err
}
return *jobOffer, nil
}

func (solverServer *solverServer) getDeal(res corehttp.ResponseWriter, req *corehttp.Request) (data.DealContainer, error) {
vars := mux.Vars(req)
id := vars["id"]
Expand Down Expand Up @@ -481,66 +495,7 @@ func (solverServer *solverServer) downloadFiles(res corehttp.ResponseWriter, req
}
}

// Get the directory path
dirPath := GetDealsFilePath(id)

// Read directory contents
files, err := os.ReadDir(dirPath)
if err != nil {
return &http.HTTPError{
Message: fmt.Sprintf("error reading directory: %s", err.Error()),
StatusCode: corehttp.StatusNotFound,
}
}

// Find the first regular file
var targetFile os.DirEntry
for _, file := range files {
info, err := file.Info()
if err != nil {
continue
}
if info.Mode().IsRegular() {
targetFile = file
break
}
}

if targetFile == nil {
return &http.HTTPError{
Message: "no regular files found in directory",
StatusCode: corehttp.StatusNotFound,
}
}

// Get the actual filename
filename := targetFile.Name()
filePath := filepath.Join(dirPath, filename)

// Open the file
file, err := os.Open(filePath)
if err != nil {
return &http.HTTPError{
Message: err.Error(),
StatusCode: corehttp.StatusInternalServerError,
}
}
defer file.Close()

// Set appropriate headers using the actual filename
res.Header().Set("Content-Disposition", fmt.Sprintf("attachment; filename=%s", filename))
res.Header().Set("Content-Type", "application/x-tar")

// Copy the file directly to the response
_, err = io.Copy(res, file)
if err != nil {
return &http.HTTPError{
Message: err.Error(),
StatusCode: corehttp.StatusInternalServerError,
}
}

return nil
return solverServer.handleFileDownload(GetDealsFilePath(deal.ID), res)
}()

if err != nil {
Expand Down Expand Up @@ -625,6 +580,110 @@ func (solverServer *solverServer) uploadFiles(res corehttp.ResponseWriter, req *
}
}

func (solverServer *solverServer) jobOfferDownloadFiles(res corehttp.ResponseWriter, req *corehttp.Request) {
vars := mux.Vars(req)
id := vars["id"]

err := func() *http.HTTPError {
jobOffer, err := solverServer.store.GetJobOffer(id)
if err != nil {
log.Error().Err(err).Msgf("error loading job offer")
return &http.HTTPError{
Message: err.Error(),
StatusCode: corehttp.StatusInternalServerError,
}
}
if jobOffer == nil {
return &http.HTTPError{
Message: err.Error(),
StatusCode: corehttp.StatusNotFound,
}
}

signerAddress, err := http.CheckSignature(req)
if err != nil {
log.Error().Err(err).Msgf("error checking signature")
return &http.HTTPError{
Message: errors.New("not authorized").Error(),
StatusCode: corehttp.StatusUnauthorized,
}
}

if signerAddress != jobOffer.JobCreator {
log.Error().Err(err).Msgf("job creator address does not match signer address")
return &http.HTTPError{
Message: errors.New("not authorized").Error(),
StatusCode: corehttp.StatusUnauthorized,
}
}

return solverServer.handleFileDownload(GetDealsFilePath(jobOffer.DealID), res)
}()

if err != nil {
log.Ctx(req.Context()).Error().Msgf("error for route: %s", err.Error())
corehttp.Error(res, err.Error(), err.StatusCode)
}
}

func (solverServer *solverServer) handleFileDownload(dirPath string, res corehttp.ResponseWriter) *http.HTTPError {
// Read directory contents
files, err := os.ReadDir(dirPath)
if err != nil {
return &http.HTTPError{
Message: fmt.Sprintf("error reading directory: %s", err.Error()),
StatusCode: corehttp.StatusNotFound,
}
}

// Find the first regular file
var targetFile os.DirEntry
for _, file := range files {
info, err := file.Info()
if err != nil {
continue
}
if info.Mode().IsRegular() {
targetFile = file
break
}
}

if targetFile == nil {
return &http.HTTPError{
Message: "no regular files found in directory",
StatusCode: corehttp.StatusNotFound,
}
}

// Get the actual filename and path
filename := targetFile.Name()
filePath := filepath.Join(dirPath, filename)

// Open and serve the file
file, err := os.Open(filePath)
if err != nil {
return &http.HTTPError{
Message: err.Error(),
StatusCode: corehttp.StatusInternalServerError,
}
}
defer file.Close()

res.Header().Set("Content-Disposition", fmt.Sprintf("attachment; filename=%s", filename))
res.Header().Set("Content-Type", "application/x-tar")

_, err = io.Copy(res, file)
if err != nil {
return &http.HTTPError{
Message: err.Error(),
StatusCode: corehttp.StatusInternalServerError,
}
}

return nil
}

// Validation Service

func (solverServer *solverServer) getValidationToken(res corehttp.ResponseWriter, req *corehttp.Request) (*http.ValidationToken, error) {
Expand Down

0 comments on commit 9afda87

Please sign in to comment.