github.com/ethersphere/bee/v2@v2.2.0/pkg/api/tag.go (about) 1 // Copyright 2020 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 "encoding/json" 9 "errors" 10 "io" 11 "net/http" 12 "time" 13 14 "github.com/ethersphere/bee/v2/pkg/jsonhttp" 15 storage "github.com/ethersphere/bee/v2/pkg/storage" 16 storer "github.com/ethersphere/bee/v2/pkg/storer" 17 "github.com/ethersphere/bee/v2/pkg/swarm" 18 "github.com/gorilla/mux" 19 ) 20 21 type tagRequest struct { 22 Address swarm.Address `json:"address,omitempty"` 23 } 24 25 type tagResponse struct { 26 Split uint64 `json:"split"` 27 Seen uint64 `json:"seen"` 28 Stored uint64 `json:"stored"` 29 Sent uint64 `json:"sent"` 30 Synced uint64 `json:"synced"` 31 Uid uint64 `json:"uid"` 32 Address swarm.Address `json:"address"` 33 StartedAt time.Time `json:"startedAt"` 34 } 35 36 func newTagResponse(tag storer.SessionInfo) tagResponse { 37 return tagResponse{ 38 Split: tag.Split, 39 Seen: tag.Seen, 40 Stored: tag.Stored, 41 Sent: tag.Sent, 42 Synced: tag.Synced, 43 Uid: tag.TagID, 44 Address: tag.Address, 45 StartedAt: time.Unix(0, tag.StartedAt), 46 } 47 } 48 49 type listTagsResponse struct { 50 Tags []tagResponse `json:"tags"` 51 } 52 53 func (s *Service) createTagHandler(w http.ResponseWriter, r *http.Request) { 54 logger := s.logger.WithName("post_tag").Build() 55 56 tag, err := s.storer.NewSession() 57 if err != nil { 58 logger.Debug("create tag failed", "error", err) 59 logger.Error(nil, "create tag failed") 60 jsonhttp.InternalServerError(w, "cannot create tag") 61 return 62 } 63 w.Header().Set("Cache-Control", "no-cache, private, max-age=0") 64 jsonhttp.Created(w, newTagResponse(tag)) 65 } 66 67 func (s *Service) getTagHandler(w http.ResponseWriter, r *http.Request) { 68 logger := s.logger.WithName("get_tag").Build() 69 70 paths := struct { 71 TagID uint64 `map:"id" validate:"required"` 72 }{} 73 if response := s.mapStructure(mux.Vars(r), &paths); response != nil { 74 response("invalid path params", logger, w) 75 return 76 } 77 78 tag, err := s.storer.Session(paths.TagID) 79 if err != nil { 80 if errors.Is(err, storage.ErrNotFound) { 81 logger.Debug("tag not found", "tag_id", paths.TagID) 82 logger.Error(nil, "tag not found") 83 jsonhttp.NotFound(w, "tag not present") 84 return 85 } 86 logger.Debug("get tag failed", "tag_id", paths.TagID, "error", err) 87 logger.Error(nil, "get tag failed", "tag_id", paths.TagID) 88 jsonhttp.InternalServerError(w, "cannot get tag") 89 return 90 } 91 92 w.Header().Set("Cache-Control", "no-cache, private, max-age=0") 93 jsonhttp.OK(w, newTagResponse(tag)) 94 } 95 96 func (s *Service) deleteTagHandler(w http.ResponseWriter, r *http.Request) { 97 logger := s.logger.WithName("delete_tag").Build() 98 99 paths := struct { 100 TagID uint64 `map:"id" validate:"required"` 101 }{} 102 if response := s.mapStructure(mux.Vars(r), &paths); response != nil { 103 response("invalid path params", logger, w) 104 return 105 } 106 107 if err := s.storer.DeleteSession(paths.TagID); err != nil { 108 if errors.Is(err, storage.ErrNotFound) { 109 logger.Debug("tag not found", "tag_id", paths.TagID) 110 logger.Error(nil, "tag not found") 111 jsonhttp.NotFound(w, "tag not present") 112 return 113 } 114 logger.Debug("get tag failed", "tag_id", paths.TagID, "error", err) 115 logger.Error(nil, "get tag failed", "tag_id", paths.TagID) 116 jsonhttp.InternalServerError(w, "cannot get tag") 117 return 118 } 119 120 jsonhttp.NoContent(w) 121 } 122 123 func (s *Service) doneSplitHandler(w http.ResponseWriter, r *http.Request) { 124 logger := s.logger.WithName("patch_tag").Build() 125 126 paths := struct { 127 TagID uint64 `map:"id" validate:"required"` 128 }{} 129 if response := s.mapStructure(mux.Vars(r), &paths); response != nil { 130 response("invalid path params", logger, w) 131 return 132 } 133 134 body, err := io.ReadAll(r.Body) 135 if err != nil { 136 if jsonhttp.HandleBodyReadError(err, w) { 137 return 138 } 139 logger.Debug("read request body failed", "error", err) 140 logger.Error(nil, "read request body failed") 141 jsonhttp.InternalServerError(w, "cannot read request") 142 return 143 } 144 145 tagr := tagRequest{} 146 if len(body) > 0 { 147 err = json.Unmarshal(body, &tagr) 148 if err != nil { 149 logger.Debug("unmarshal tag name failed", "error", err) 150 logger.Error(nil, "unmarshal tag name failed") 151 jsonhttp.InternalServerError(w, "error unmarshaling metadata") 152 return 153 } 154 } 155 156 tag, err := s.storer.Session(paths.TagID) 157 if err != nil { 158 if errors.Is(err, storage.ErrNotFound) { 159 logger.Debug("tag not found", "tag_id", paths.TagID) 160 logger.Error(nil, "tag not found") 161 jsonhttp.NotFound(w, "tag not present") 162 return 163 } 164 logger.Debug("get tag failed", "tag_id", paths.TagID, "error", err) 165 logger.Error(nil, "get tag failed", "tag_id", paths.TagID) 166 jsonhttp.InternalServerError(w, "cannot get tag") 167 return 168 } 169 170 putter, err := s.storer.Upload(r.Context(), false, tag.TagID) 171 if err != nil { 172 logger.Debug("get tag failed", "tag_id", paths.TagID, "error", err) 173 logger.Error(nil, "get tag failed", "tag_id", paths.TagID) 174 jsonhttp.InternalServerError(w, "cannot get tag") 175 return 176 } 177 178 err = putter.Done(tagr.Address) 179 if err != nil { 180 logger.Debug("done split failed", "address", tagr.Address, "error", err) 181 logger.Error(nil, "done split failed", "address", tagr.Address) 182 jsonhttp.InternalServerError(w, "done split: failed") 183 return 184 } 185 jsonhttp.OK(w, "ok") 186 } 187 188 func (s *Service) listTagsHandler(w http.ResponseWriter, r *http.Request) { 189 logger := s.logger.WithName("get_tags").Build() 190 191 queries := struct { 192 Offset int `map:"offset"` 193 Limit int `map:"limit"` 194 }{ 195 Limit: 100, // Default limit. 196 } 197 if response := s.mapStructure(r.URL.Query(), &queries); response != nil { 198 response("invalid query params", logger, w) 199 return 200 } 201 202 tagList, err := s.storer.ListSessions(queries.Offset, queries.Limit) 203 if err != nil { 204 logger.Debug("listing failed", "offset", queries.Offset, "limit", queries.Limit, "error", err) 205 logger.Error(nil, "listing failed") 206 jsonhttp.InternalServerError(w, err) 207 return 208 } 209 210 tags := make([]tagResponse, len(tagList)) 211 for i, t := range tagList { 212 tags[i] = newTagResponse(t) 213 } 214 215 jsonhttp.OK(w, listTagsResponse{ 216 Tags: tags, 217 }) 218 }