github.com/siglens/siglens@v0.0.0-20240328180423-f7ce9ae441ed/pkg/es/writer/esAliases.go (about) 1 /* 2 Copyright 2023. 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 package writer 18 19 import ( 20 "bytes" 21 "fmt" 22 23 jsoniter "github.com/json-iterator/go" 24 "github.com/siglens/siglens/pkg/utils" 25 vtable "github.com/siglens/siglens/pkg/virtualtable" 26 log "github.com/sirupsen/logrus" 27 "github.com/valyala/fasthttp" 28 ) 29 30 func ProcessGetAlias(ctx *fasthttp.RequestCtx, myid uint64) { 31 log.Infof("ProcessGetAlias:") 32 aliasName := utils.ExtractParamAsString(ctx.UserValue("aliasName")) 33 34 respbody := make(map[string]interface{}) 35 pres, indexName := vtable.IsAlias(aliasName, myid) 36 if !pres { 37 respbody["error"] = fmt.Sprintf("alias [%v] missing", aliasName) 38 respbody["status"] = 404 39 utils.WriteJsonResponse(ctx, respbody) 40 ctx.SetStatusCode(fasthttp.StatusNotFound) 41 return 42 } 43 44 // if it is a alias, then we have to do reverse lookup and find the index 45 46 emptyMap := make(map[string]interface{}) 47 abody := make(map[string]interface{}) 48 curIdxAliases, err := vtable.GetAliases(indexName, myid) 49 if err == nil { 50 for k := range curIdxAliases { 51 abody[k] = emptyMap 52 } 53 } 54 tBody := make(map[string]interface{}) 55 tBody["aliases"] = abody 56 respbody[indexName] = tBody 57 58 utils.WriteJsonResponse(ctx, respbody) 59 ctx.SetStatusCode(fasthttp.StatusOK) 60 } 61 62 func ProcessGetAllAliases(ctx *fasthttp.RequestCtx, myid uint64) { 63 64 respbody := make(map[string]interface{}) 65 allIndices, err := vtable.GetVirtualTableNames(myid) 66 if err != nil { 67 log.Errorf("ProcessGetAllAliases: Failed to get aliases for myid=%v, err=%v", myid, err) 68 ctx.SetStatusCode(fasthttp.StatusBadRequest) 69 respbody := make(map[string]interface{}) 70 respbody["error"] = err.Error() 71 utils.WriteJsonResponse(ctx, respbody) 72 return 73 } 74 emptyMap := make(map[string]interface{}) 75 76 for idxName := range allIndices { 77 abody := make(map[string]interface{}) 78 curIdxAliases, err := vtable.GetAliases(idxName, myid) 79 log.Debugf("ProcessGetAllAliases: idxName=%v, curIdxAliases=%v", idxName, curIdxAliases) 80 if err == nil { 81 for k := range curIdxAliases { 82 log.Debugf("ProcessGetAllAliases: idxName=%v, k=%v", idxName, k) 83 abody[k] = emptyMap 84 } 85 } 86 tBody := make(map[string]interface{}) 87 tBody["aliases"] = abody 88 log.Debugf("ProcessGetAllAliases: abody=%v, tBody=%v", abody, tBody) 89 respbody[idxName] = tBody 90 } 91 92 utils.WriteJsonResponse(ctx, respbody) 93 ctx.SetStatusCode(fasthttp.StatusOK) 94 95 } 96 97 func ProcessGetIndexAlias(ctx *fasthttp.RequestCtx, myid uint64) { 98 99 indexName := utils.ExtractParamAsString(ctx.UserValue("indexName")) 100 101 if indexName == "" { 102 log.Errorf("ProcessGetIndexAlias: one of nil indexName=%v", indexName) 103 utils.SetBadMsg(ctx, "") 104 return 105 } 106 log.Infof("ProcessGetIndexAlias: indexName=%v", indexName) 107 108 currentAliases, err := vtable.GetAliases(indexName, myid) 109 if err != nil { 110 log.Errorf("ProcessGetIndexAlias: GetAliases returned err=%v", err) 111 utils.SetBadMsg(ctx, "") 112 return 113 } 114 115 respbody := make(map[string]interface{}) 116 alvalues := make(map[string]interface{}) 117 alvalues["aliases"] = currentAliases 118 respbody[indexName] = alvalues 119 120 utils.WriteJsonResponse(ctx, respbody) 121 ctx.SetStatusCode(fasthttp.StatusOK) 122 } 123 124 func ProcessPutAliasesRequest(ctx *fasthttp.RequestCtx, myid uint64) { 125 indexName := utils.ExtractParamAsString(ctx.UserValue("indexName")) 126 aliasName := utils.ExtractParamAsString(ctx.UserValue("aliasName")) 127 128 if indexName == "" || aliasName == "" { 129 log.Errorf("ProcessPutAliasesRequest: one of nil indexName=%v, aliasName=%v", indexName, aliasName) 130 utils.SetBadMsg(ctx, "") 131 return 132 } 133 log.Infof("ProcessPutAliasesRequest: add alias request, indexName=%v, aliasName=%v", indexName, aliasName) 134 err := vtable.AddAliases(indexName, []string{aliasName}, myid) 135 if err != nil { 136 log.Errorf("ProcessPutAliasesRequest: failed to add alias, indexName=%v, aliasName=%v, err=%v", indexName, aliasName, err) 137 utils.SetBadMsg(ctx, "") 138 return 139 } 140 141 respbody := make(map[string]interface{}) 142 respbody["acknowledged"] = true 143 utils.WriteJsonResponse(ctx, respbody) 144 ctx.SetStatusCode(fasthttp.StatusOK) 145 } 146 147 /* 148 { 149 "actions" : [ 150 { "add" : { "index" : "test1", "alias" : "alias1" } } 151 ] 152 } 153 */ 154 155 func ProcessPostAliasesRequest(ctx *fasthttp.RequestCtx, myid uint64) { 156 r := bytes.NewReader(ctx.PostBody()) 157 158 log.Infof("ProcessPostAliasesRequest: body=%v", string(ctx.PostBody())) 159 160 jsonBody := make(map[string]interface{}) 161 var json = jsoniter.ConfigCompatibleWithStandardLibrary 162 decoder := json.NewDecoder(r) 163 decoder.UseNumber() 164 err := decoder.Decode(&jsonBody) 165 166 if err != nil { 167 log.Errorf("ProcessPostAliasesRequest: error un-marshalling JSON: %v", err) 168 utils.SetBadMsg(ctx, "") 169 return 170 } 171 for key, value := range jsonBody { 172 switch value.(type) { 173 case []interface{}: 174 if key == "actions" { 175 processActions(ctx, jsonBody[key], myid) 176 } else { 177 log.Errorf("ProcessPostAliasesRequest: unknown key: %v", key) 178 utils.SetBadMsg(ctx, "") 179 return 180 } 181 default: 182 log.Errorf("ProcessPostAliasesRequest: unknown type key: %v, value.Type=%T", key, value) 183 utils.SetBadMsg(ctx, "") 184 return 185 } 186 } 187 respbody := make(map[string]interface{}) 188 respbody["acknowledged"] = true 189 utils.WriteJsonResponse(ctx, respbody) 190 ctx.SetStatusCode(fasthttp.StatusOK) 191 } 192 193 /* 194 [{ "add" : { "index" : "test1", "alias" : "alias1" } }] 195 OR 196 [{"remove": {"index": "test1", "alias" : "alias1" } }] 197 */ 198 199 func processActions(ctx *fasthttp.RequestCtx, actions interface{}, myid uint64) { 200 201 switch t := actions.(type) { 202 case []interface{}: 203 for _, value := range t { 204 switch t1 := value.(type) { 205 case map[string]interface{}: 206 for aKey, aValue := range t1 { 207 if aKey == "add" { 208 parseAddAction(ctx, aValue, myid) 209 } else if aKey == "remove" { 210 parseRemoveAction(ctx, aValue, myid) 211 } else { 212 log.Errorf("processActions: unhandled action aKey: %v", aKey) 213 utils.SetBadMsg(ctx, "") 214 return 215 } 216 } 217 default: 218 log.Errorf("processActions: unknown t1.type=%T, t1=%v", t1, t1) 219 utils.SetBadMsg(ctx, "") 220 return 221 } 222 } 223 default: 224 log.Errorf("processActions: unknown actions.(type) value.type=%T", t) 225 utils.SetBadMsg(ctx, "") 226 return 227 } 228 } 229 230 /* 231 { "index" : "test1", "alias" : "alias1" }} 232 */ 233 234 func parseAddAction(ctx *fasthttp.RequestCtx, params interface{}, myid uint64) { 235 log.Infof("parseAddAction: add alias request, params=%v", params) 236 switch t := params.(type) { 237 case map[string]interface{}: 238 aliasName := t["alias"] 239 if aliasName == nil { 240 log.Errorf("parseAddAction: aliasName was nil, params=%v", params) 241 utils.SetBadMsg(ctx, "") 242 return 243 } 244 indexName := t["index"] 245 indices := t["indices"] 246 if indexName == nil && indices == nil { 247 log.Errorf("parseAddAction: both indexName and indices was nil, params=%v", params) 248 utils.SetBadMsg(ctx, "") 249 return 250 } 251 doAddAliases(ctx, indexName, aliasName, indices, myid) 252 default: 253 log.Errorf("parseAddAction: unknown params.(type)=%T params=%v", params, params) 254 utils.SetBadMsg(ctx, "") 255 return 256 } 257 } 258 259 /* 260 { "index" : "test1", "alias" : "alias1" } 261 OR 262 { "indices" : ["test1", "test2"], "alias" : "alias1" } 263 */ 264 265 func doAddAliases(ctx *fasthttp.RequestCtx, indexName interface{}, aliasName interface{}, indices interface{}, myid uint64) { 266 267 log.Infof("doAddAliases: addalias for indexName=%v, aliasName=%v, indices=%v", indexName, aliasName, indices) 268 269 if indexName != nil { 270 err := vtable.AddAliases(indexName.(string), []string{aliasName.(string)}, myid) 271 if err != nil { 272 log.Errorf("doAddAliases: failed to add alias, indexName=%v, aliasName=%v err=%v", indexName.(string), aliasName.(string), err) 273 utils.SetBadMsg(ctx, "") 274 } 275 return 276 } 277 278 switch t := indices.(type) { 279 case []interface{}: 280 for _, iVal := range t { 281 err := vtable.AddAliases(iVal.(string), []string{aliasName.(string)}, myid) 282 if err != nil { 283 log.Errorf("doAddAliases: failed to add alias, indexName=%v, aliasName=%v err=%v", iVal.(string), aliasName.(string), err) 284 } 285 } 286 default: 287 log.Errorf("doAddAliases: unknown indices.(type)=%T indices=%v", indices, indices) 288 utils.SetBadMsg(ctx, "") 289 return 290 } 291 } 292 293 /* 294 295 { "index" : "test1", "alias" : "alias1" } 296 297 */ 298 299 func parseRemoveAction(ctx *fasthttp.RequestCtx, params interface{}, myid uint64) { 300 log.Infof("parseRemoveAction: remove alias request, params=%v", params) 301 switch t := params.(type) { 302 case map[string]interface{}: 303 aliasName := t["alias"] 304 if aliasName == nil { 305 log.Errorf("parseRemoveAction: aliasName was nil, params=%v", params) 306 utils.SetBadMsg(ctx, "") 307 return 308 } 309 indexName := t["index"] 310 if indexName == nil { 311 log.Errorf("parseRemoveAction: both indexName was nil, params=%v", params) 312 utils.SetBadMsg(ctx, "") 313 return 314 } 315 err := vtable.RemoveAliases(indexName.(string), []string{aliasName.(string)}, myid) 316 if err != nil { 317 log.Errorf("parseRemoveAction: failed to remove alias, indexName=%v, aliasName=%v err=%v", indexName.(string), aliasName.(string), err) 318 utils.SetBadMsg(ctx, "") 319 } 320 return 321 default: 322 log.Errorf("parseRemoveAction: unknown params.(type)=%T params=%v", params, params) 323 utils.SetBadMsg(ctx, "") 324 return 325 } 326 } 327 328 func ProcessIndexAliasExist(ctx *fasthttp.RequestCtx, myid uint64) { 329 330 //get indexName and aliasName 331 indexName := utils.ExtractParamAsString(ctx.UserValue("indexName")) 332 aliasName := utils.ExtractParamAsString(ctx.UserValue("aliasName")) 333 if indexName == "" { 334 ctx.SetStatusCode(fasthttp.StatusNotFound) 335 log.Errorf("ProcessIndexAliasExist : indexName is required") 336 ctx.SetContentType(utils.ContentJson) 337 return 338 } 339 alias, _ := vtable.IsAlias(aliasName, myid) 340 341 allIndexNames, _ := vtable.GetVirtualTableNames(myid) 342 343 _, exists := allIndexNames[indexName] 344 if exists { 345 ctx.SetStatusCode(fasthttp.StatusOK) 346 ctx.SetContentType(utils.ContentJson) 347 return 348 } 349 //for alias 350 if aliasName == "" || !alias { 351 ctx.SetStatusCode(fasthttp.StatusNotFound) 352 log.Errorf("ProcessIndexAliasExist : aliasName is required") 353 ctx.SetContentType(utils.ContentJson) 354 } else { 355 ctx.SetStatusCode(fasthttp.StatusOK) 356 ctx.SetContentType(utils.ContentJson) 357 } 358 }