github.com/mdaxf/iac@v0.0.0-20240519030858-58a061660378/job/admin/command (about) 1 // Copyright 2020 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package admin 16 17 import ( 18 "github.com/pkg/errors" 19 ) 20 21 // Command is an experimental interface 22 // We try to use this to decouple modules 23 // All other modules depends on this, and they register the command they support 24 // We may change the API in the future, so be careful about this. 25 type Command interface { 26 Execute(params ...interface{}) *Result 27 } 28 29 var CommandNotFound = errors.New("Command not found") 30 31 type Result struct { 32 // Status is the same as http.Status 33 Status int 34 Error error 35 Content interface{} 36 } 37 38 func (r *Result) IsSuccess() bool { 39 return r.Status >= 200 && r.Status < 300 40 } 41 42 // CommandRegistry stores all commands 43 // name => command 44 type moduleCommands map[string]Command 45 46 // Get returns command with the name 47 func (m moduleCommands) Get(name string) Command { 48 c, ok := m[name] 49 if ok { 50 return c 51 } 52 return &doNothingCommand{} 53 } 54 55 // module name => moduleCommand 56 type commandRegistry map[string]moduleCommands 57 58 // Get returns module's commands 59 func (c commandRegistry) Get(moduleName string) moduleCommands { 60 if mcs, ok := c[moduleName]; ok { 61 return mcs 62 } 63 res := make(moduleCommands) 64 c[moduleName] = res 65 return res 66 } 67 68 var cmdRegistry = make(commandRegistry) 69 70 // RegisterCommand is not thread-safe 71 // do not use it in concurrent case 72 func RegisterCommand(module string, commandName string, command Command) { 73 cmdRegistry.Get(module)[commandName] = command 74 } 75 76 func GetCommand(module string, cmdName string) Command { 77 return cmdRegistry.Get(module).Get(cmdName) 78 } 79 80 type doNothingCommand struct{} 81 82 func (d *doNothingCommand) Execute(params ...interface{}) *Result { 83 return &Result{ 84 Status: 404, 85 Error: CommandNotFound, 86 } 87 }