pin.go 4.03 KB
Newer Older
Peter Mrekaj's avatar
Peter Mrekaj committed
1 2 3 4 5 6 7 8 9 10 11 12
// Copyright 2021 The Swarm Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package api

import (
	"errors"
	"net/http"

	"github.com/ethersphere/bee/pkg/jsonhttp"
	"github.com/ethersphere/bee/pkg/pinning"
13
	"github.com/ethersphere/bee/pkg/storage"
Peter Mrekaj's avatar
Peter Mrekaj committed
14 15 16 17
	"github.com/ethersphere/bee/pkg/swarm"
	"github.com/gorilla/mux"
)

18
// pinRootHash pins root hash of given reference. This method is idempotent.
Peter Mrekaj's avatar
Peter Mrekaj committed
19
func (s *server) pinRootHash(w http.ResponseWriter, r *http.Request) {
20
	ref, err := swarm.ParseHexAddress(mux.Vars(r)["reference"])
Peter Mrekaj's avatar
Peter Mrekaj committed
21
	if err != nil {
22 23 24
		s.logger.Debugf("pin root hash: unable to parse reference %q: %v", ref, err)
		s.logger.Error("pin root hash: unable to parse reference")
		jsonhttp.BadRequest(w, "bad reference")
Peter Mrekaj's avatar
Peter Mrekaj committed
25 26 27
		return
	}

28
	has, err := s.pinning.HasPin(ref)
Peter Mrekaj's avatar
Peter Mrekaj committed
29
	if err != nil {
30
		s.logger.Debugf("pin root hash: checking of tracking pin for %q failed: %v", ref, err)
Peter Mrekaj's avatar
Peter Mrekaj committed
31 32 33 34 35 36 37 38 39
		s.logger.Error("pin root hash: checking of tracking pin failed")
		jsonhttp.InternalServerError(w, nil)
		return
	}
	if has {
		jsonhttp.OK(w, nil)
		return
	}

40 41 42 43 44
	switch err = s.pinning.CreatePin(r.Context(), ref, true); {
	case errors.Is(err, storage.ErrNotFound):
		jsonhttp.NotFound(w, nil)
		return
	case err != nil:
45
		s.logger.Debugf("pin root hash: creation of tracking pin for %q failed: %v", ref, err)
Peter Mrekaj's avatar
Peter Mrekaj committed
46 47 48 49 50
		s.logger.Error("pin root hash: creation of tracking pin failed")
		jsonhttp.InternalServerError(w, nil)
		return
	}

51
	jsonhttp.Created(w, nil)
Peter Mrekaj's avatar
Peter Mrekaj committed
52 53 54 55
}

// unpinRootHash unpin's an already pinned root hash. This method is idempotent.
func (s *server) unpinRootHash(w http.ResponseWriter, r *http.Request) {
56
	ref, err := swarm.ParseHexAddress(mux.Vars(r)["reference"])
Peter Mrekaj's avatar
Peter Mrekaj committed
57
	if err != nil {
58 59 60
		s.logger.Debugf("unpin root hash: unable to parse reference: %v", err)
		s.logger.Error("unpin root hash: unable to parse reference")
		jsonhttp.BadRequest(w, "bad reference")
Peter Mrekaj's avatar
Peter Mrekaj committed
61 62 63
		return
	}

64
	has, err := s.pinning.HasPin(ref)
Peter Mrekaj's avatar
Peter Mrekaj committed
65
	if err != nil {
66
		s.logger.Debugf("pin root hash: checking of tracking pin for %q failed: %v", ref, err)
Peter Mrekaj's avatar
Peter Mrekaj committed
67 68 69 70 71 72 73 74 75
		s.logger.Error("pin root hash: checking of tracking pin failed")
		jsonhttp.InternalServerError(w, nil)
		return
	}
	if !has {
		jsonhttp.NotFound(w, nil)
		return
	}

76
	switch err := s.pinning.DeletePin(r.Context(), ref); {
Peter Mrekaj's avatar
Peter Mrekaj committed
77
	case errors.Is(err, pinning.ErrTraversal):
78
		s.logger.Debugf("unpin root hash: deletion of pin for %q failed: %v", ref, err)
Peter Mrekaj's avatar
Peter Mrekaj committed
79 80 81
		jsonhttp.InternalServerError(w, nil)
		return
	case err != nil:
82
		s.logger.Debugf("unpin root hash: deletion of pin for %q failed: %v", ref, err)
Peter Mrekaj's avatar
Peter Mrekaj committed
83 84 85 86 87 88 89 90
		s.logger.Error("unpin root hash: deletion of pin for failed")
		jsonhttp.InternalServerError(w, nil)
		return
	}

	jsonhttp.OK(w, nil)
}

91
// getPinnedRootHash returns back the given reference if its root hash is pinned.
Peter Mrekaj's avatar
Peter Mrekaj committed
92
func (s *server) getPinnedRootHash(w http.ResponseWriter, r *http.Request) {
93
	ref, err := swarm.ParseHexAddress(mux.Vars(r)["reference"])
Peter Mrekaj's avatar
Peter Mrekaj committed
94
	if err != nil {
95 96 97
		s.logger.Debugf("pinned root hash: unable to parse reference %q: %v", ref, err)
		s.logger.Error("pinned root hash: unable to parse reference")
		jsonhttp.BadRequest(w, "bad reference")
Peter Mrekaj's avatar
Peter Mrekaj committed
98 99 100
		return
	}

101
	has, err := s.pinning.HasPin(ref)
Peter Mrekaj's avatar
Peter Mrekaj committed
102
	if err != nil {
103 104
		s.logger.Debugf("pinned root hash: unable to check reference %q in the localstore: %v", ref, err)
		s.logger.Error("pinned root hash: unable to check reference in the localstore")
Peter Mrekaj's avatar
Peter Mrekaj committed
105 106 107 108 109 110 111 112 113 114
		jsonhttp.InternalServerError(w, nil)
		return
	}

	if !has {
		jsonhttp.NotFound(w, nil)
		return
	}

	jsonhttp.OK(w, struct {
115
		Reference swarm.Address `json:"reference"`
Peter Mrekaj's avatar
Peter Mrekaj committed
116
	}{
117
		Reference: ref,
Peter Mrekaj's avatar
Peter Mrekaj committed
118 119 120
	})
}

121
// listPinnedRootHashes lists all the references of the pinned root hashes.
Peter Mrekaj's avatar
Peter Mrekaj committed
122 123 124
func (s *server) listPinnedRootHashes(w http.ResponseWriter, r *http.Request) {
	pinned, err := s.pinning.Pins()
	if err != nil {
125 126
		s.logger.Debugf("list pinned root references: unable to list references: %v", err)
		s.logger.Error("list pinned root references: unable to list references")
Peter Mrekaj's avatar
Peter Mrekaj committed
127 128 129 130 131
		jsonhttp.InternalServerError(w, nil)
		return
	}

	jsonhttp.OK(w, struct {
132
		References []swarm.Address `json:"references"`
Peter Mrekaj's avatar
Peter Mrekaj committed
133
	}{
134
		References: pinned,
Peter Mrekaj's avatar
Peter Mrekaj committed
135 136
	})
}