github.com/ethersphere/bee/v2@v2.2.0/pkg/api/stewardship.go (about)

     1  // Copyright 2021 The Swarm Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package api
     6  
     7  import (
     8  	"errors"
     9  	"net/http"
    10  
    11  	"github.com/ethersphere/bee/v2/pkg/postage"
    12  	storage "github.com/ethersphere/bee/v2/pkg/storage"
    13  	"github.com/ethersphere/bee/v2/pkg/swarm"
    14  
    15  	"github.com/ethersphere/bee/v2/pkg/jsonhttp"
    16  	"github.com/gorilla/mux"
    17  )
    18  
    19  // StewardshipPutHandler re-uploads root hash and all of its underlying associated chunks to the network.
    20  func (s *Service) stewardshipPutHandler(w http.ResponseWriter, r *http.Request) {
    21  	logger := s.logger.WithName("put_stewardship").Build()
    22  
    23  	paths := struct {
    24  		Address swarm.Address `map:"address,resolve" validate:"required"`
    25  	}{}
    26  	if response := s.mapStructure(mux.Vars(r), &paths); response != nil {
    27  		response("invalid path params", logger, w)
    28  		return
    29  	}
    30  
    31  	headers := struct {
    32  		BatchID []byte `map:"Swarm-Postage-Batch-Id" validate:"required"`
    33  	}{}
    34  	if response := s.mapStructure(r.Header, &headers); response != nil {
    35  		response("invalid header params", logger, w)
    36  		return
    37  	}
    38  
    39  	var (
    40  		batchID []byte
    41  		err     error
    42  	)
    43  
    44  	batchID = headers.BatchID
    45  	stamper, save, err := s.getStamper(batchID)
    46  	if err != nil {
    47  		switch {
    48  		case errors.Is(err, errBatchUnusable) || errors.Is(err, postage.ErrNotUsable):
    49  			jsonhttp.UnprocessableEntity(w, "batch not usable yet or does not exist")
    50  		case errors.Is(err, postage.ErrNotFound) || errors.Is(err, storage.ErrNotFound):
    51  			jsonhttp.NotFound(w, "batch with id not found")
    52  		case errors.Is(err, errInvalidPostageBatch):
    53  			jsonhttp.BadRequest(w, "invalid batch id")
    54  		default:
    55  			jsonhttp.BadRequest(w, nil)
    56  		}
    57  		return
    58  	}
    59  
    60  	err = s.steward.Reupload(r.Context(), paths.Address, stamper)
    61  	if err != nil {
    62  		logger.Debug("re-upload failed", "chunk_address", paths.Address, "error", err)
    63  		logger.Error(nil, "re-upload failed")
    64  		jsonhttp.InternalServerError(w, "re-upload failed")
    65  		return
    66  	}
    67  
    68  	if err = save(); err != nil {
    69  		logger.Debug("unable to save stamper data", "batchID", batchID, "error", err)
    70  		logger.Error(nil, "unable to save stamper data")
    71  		jsonhttp.InternalServerError(w, "unable to save stamper data")
    72  		return
    73  	}
    74  
    75  	jsonhttp.OK(w, nil)
    76  }
    77  
    78  type isRetrievableResponse struct {
    79  	IsRetrievable bool `json:"isRetrievable"`
    80  }
    81  
    82  // stewardshipGetHandler checks whether the content on the given address is retrievable.
    83  func (s *Service) stewardshipGetHandler(w http.ResponseWriter, r *http.Request) {
    84  	logger := s.logger.WithName("get_stewardship").Build()
    85  
    86  	paths := struct {
    87  		Address swarm.Address `map:"address,resolve" validate:"required"`
    88  	}{}
    89  	if response := s.mapStructure(mux.Vars(r), &paths); response != nil {
    90  		response("invalid path params", logger, w)
    91  		return
    92  	}
    93  
    94  	res, err := s.steward.IsRetrievable(r.Context(), paths.Address)
    95  	if err != nil {
    96  		logger.Debug("is retrievable check failed", "chunk_address", paths.Address, "error", err)
    97  		logger.Error(nil, "is retrievable")
    98  		jsonhttp.InternalServerError(w, "is retrievable check failed")
    99  		return
   100  	}
   101  	jsonhttp.OK(w, isRetrievableResponse{
   102  		IsRetrievable: res,
   103  	})
   104  }