mirror of
https://github.com/cgrates/cgrates.git
synced 2026-02-11 18:16:24 +05:00
Add ConfigSv1 in Dispatcher
This commit is contained in:
43
apier/v1/config.go
Normal file
43
apier/v1/config.go
Normal file
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
Real-time Online/Offline Charging System (OCS) for Telecom & ISP environments
|
||||
Copyright (C) ITsysCOM GmbH
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
*/
|
||||
|
||||
package v1
|
||||
|
||||
import (
|
||||
"github.com/cgrates/cgrates/config"
|
||||
"github.com/cgrates/cgrates/utils"
|
||||
)
|
||||
|
||||
func NewConfigSv1(cfg *config.CGRConfig) *ConfigSv1 {
|
||||
return &ConfigSv1{cfg: cfg}
|
||||
}
|
||||
|
||||
// Exports RPC from ConfigSv1
|
||||
type ConfigSv1 struct {
|
||||
cfg *config.CGRConfig
|
||||
}
|
||||
|
||||
func (cSv1 *ConfigSv1) GetJSONSection(section *config.StringWithArgDispatcher, reply *map[string]interface{}) (err error) {
|
||||
return cSv1.cfg.V1GetConfigSection(section, reply)
|
||||
}
|
||||
|
||||
// Call implements rpcclient.RpcClientConnection interface for internal RPC
|
||||
func (cSv1 *ConfigSv1) Call(serviceMethod string,
|
||||
args interface{}, reply interface{}) error {
|
||||
return utils.APIerRPCCall(cSv1, serviceMethod, args, reply)
|
||||
}
|
||||
@@ -21,6 +21,7 @@ package v1
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/cgrates/cgrates/config"
|
||||
"github.com/cgrates/cgrates/dispatchers"
|
||||
"github.com/cgrates/cgrates/engine"
|
||||
"github.com/cgrates/cgrates/sessions"
|
||||
@@ -744,3 +745,17 @@ func (dS *DispatcherSServiceManagerV1) StopService(args dispatchers.ArgStartServ
|
||||
func (dS *DispatcherSServiceManagerV1) ServiceStatus(args dispatchers.ArgStartServiceWithApiKey, reply *string) error {
|
||||
return dS.dS.ServiceManagerV1ServiceStatus(args, reply)
|
||||
}
|
||||
|
||||
func NewDispatcherConfigSv1(dps *dispatchers.DispatcherService) *DispatcherConfigSv1 {
|
||||
return &DispatcherConfigSv1{dS: dps}
|
||||
}
|
||||
|
||||
// Exports RPC from CDRsV1
|
||||
type DispatcherConfigSv1 struct {
|
||||
dS *dispatchers.DispatcherService
|
||||
}
|
||||
|
||||
// Ping used to detreminate if component is active
|
||||
func (dS *DispatcherConfigSv1) GetJSONSection(args *config.StringWithArgDispatcher, reply *map[string]interface{}) (err error) {
|
||||
return dS.dS.ConfigSv1GetJSONSection(args, reply)
|
||||
}
|
||||
|
||||
@@ -1239,6 +1239,9 @@ func startDispatcherService(internalDispatcherSChan, internalAttributeSChan chan
|
||||
server.RpcRegisterName(utils.CDRsV1,
|
||||
v1.NewDispatcherSCDRsV1(dspS))
|
||||
|
||||
server.RpcRegisterName(utils.ConfigSv1,
|
||||
v1.NewDispatcherConfigSv1(dspS))
|
||||
|
||||
internalDispatcherSChan <- dspS
|
||||
}
|
||||
|
||||
@@ -1450,6 +1453,15 @@ func schedCDRsConns(internalCDRSChan, internalDispatcherSChan chan rpcclient.Rpc
|
||||
engine.SetSchedCdrsConns(cdrsConn)
|
||||
}
|
||||
|
||||
func initConfigSv1(internalConfigChan chan rpcclient.RpcClientConnection,
|
||||
server *utils.Server) {
|
||||
cfgSv1 := v1.NewConfigSv1(cfg)
|
||||
if !cfg.DispatcherSCfg().Enabled {
|
||||
server.RpcRegister(cfgSv1)
|
||||
}
|
||||
internalConfigChan <- cfgSv1
|
||||
}
|
||||
|
||||
func memProfFile(memProfPath string) bool {
|
||||
f, err := os.Create(memProfPath)
|
||||
if err != nil {
|
||||
@@ -1638,6 +1650,7 @@ func main() {
|
||||
internalApierV1Chan := make(chan rpcclient.RpcClientConnection, 1)
|
||||
internalApierV2Chan := make(chan rpcclient.RpcClientConnection, 1)
|
||||
internalServeManagerChan := make(chan rpcclient.RpcClientConnection, 1)
|
||||
internalConfigChan := make(chan rpcclient.RpcClientConnection, 1)
|
||||
|
||||
// init internalRPCSet
|
||||
engine.IntRPC = engine.NewRPCClientSet()
|
||||
@@ -1660,6 +1673,8 @@ func main() {
|
||||
engine.IntRPC.AddInternalRPCClient(utils.SupplierSv1, internalSupplierSChan)
|
||||
engine.IntRPC.AddInternalRPCClient(utils.ThresholdSv1, internalThresholdSChan)
|
||||
engine.IntRPC.AddInternalRPCClient(utils.ServiceManagerV1, internalServeManagerChan)
|
||||
engine.IntRPC.AddInternalRPCClient(utils.ServManagerV1, internalServeManagerChan)
|
||||
engine.IntRPC.AddInternalRPCClient(utils.ConfigSv1, internalConfigChan)
|
||||
}
|
||||
|
||||
// init CacheS
|
||||
@@ -1675,6 +1690,8 @@ func main() {
|
||||
// init SchedulerS
|
||||
initSchedulerS(internalSchedSChan, srvManager, server)
|
||||
|
||||
initConfigSv1(internalConfigChan, server)
|
||||
|
||||
// Start Scheduler
|
||||
if cfg.SchedulerCfg().Enabled {
|
||||
go srvManager.StartScheduler(true)
|
||||
|
||||
@@ -19,6 +19,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
package config
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/url"
|
||||
@@ -216,6 +217,7 @@ func NewCGRConfigFromPath(path string) (*CGRConfig, error) {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
cfg.ConfigPath = path
|
||||
if isUrl(path) {
|
||||
return loadConfigFromHttp(cfg, path) // prefix protocol
|
||||
}
|
||||
@@ -296,6 +298,7 @@ func loadConfigFromHttp(cfg *CGRConfig, urlPaths string) (*CGRConfig, error) {
|
||||
type CGRConfig struct {
|
||||
MaxCallDuration time.Duration // The maximum call duration (used by responder when querying DerivedCharging) // ToDo: export it in configuration file
|
||||
DataFolderPath string // Path towards data folder, for tests internal usage, not loading out of .json options
|
||||
ConfigPath string // Path towards config
|
||||
|
||||
// Cache defaults loaded from json and needing clones
|
||||
dfltCdreProfile *CdreCfg // Default cdreConfig profile
|
||||
@@ -1186,3 +1189,90 @@ func (cfg *CGRConfig) AnalyzerSCfg() *AnalyzerSCfg {
|
||||
func (cfg *CGRConfig) ApierCfg() *ApierCfg {
|
||||
return cfg.apier
|
||||
}
|
||||
|
||||
// Call implements rpcclient.RpcClientConnection interface for internal RPC
|
||||
func (cSv1 *CGRConfig) Call(serviceMethod string,
|
||||
args interface{}, reply interface{}) error {
|
||||
return utils.APIerRPCCall(cSv1, serviceMethod, args, reply)
|
||||
}
|
||||
|
||||
type StringWithArgDispatcher struct {
|
||||
*utils.ArgDispatcher
|
||||
utils.TenantArg
|
||||
Section string
|
||||
}
|
||||
|
||||
//V1GetConfigSection will retrieve from CGRConfig a section
|
||||
func (cfg *CGRConfig) V1GetConfigSection(args *StringWithArgDispatcher, reply *map[string]interface{}) (err error) {
|
||||
var jsonString string
|
||||
switch args.Section {
|
||||
case GENERAL_JSN:
|
||||
jsonString = utils.ToJSON(cfg.GeneralCfg())
|
||||
case DATADB_JSN:
|
||||
jsonString = utils.ToJSON(cfg.DataDbCfg())
|
||||
case STORDB_JSN:
|
||||
jsonString = utils.ToJSON(cfg.StorDbCfg())
|
||||
case TlsCfgJson:
|
||||
jsonString = utils.ToJSON(cfg.TlsCfg())
|
||||
case CACHE_JSN:
|
||||
jsonString = utils.ToJSON(cfg.CacheCfg())
|
||||
case LISTEN_JSN:
|
||||
jsonString = utils.ToJSON(cfg.ListenCfg())
|
||||
case HTTP_JSN:
|
||||
jsonString = utils.ToJSON(cfg.HTTPCfg())
|
||||
case FILTERS_JSON:
|
||||
jsonString = utils.ToJSON(cfg.FilterSCfg())
|
||||
case RALS_JSN:
|
||||
jsonString = utils.ToJSON(cfg.RalsCfg())
|
||||
case SCHEDULER_JSN:
|
||||
jsonString = utils.ToJSON(cfg.SchedulerCfg())
|
||||
case CDRS_JSN:
|
||||
jsonString = utils.ToJSON(cfg.CdrsCfg())
|
||||
case SessionSJson:
|
||||
jsonString = utils.ToJSON(cfg.SessionSCfg())
|
||||
case FS_JSN:
|
||||
jsonString = utils.ToJSON(cfg.FsAgentCfg())
|
||||
case KamailioAgentJSN:
|
||||
jsonString = utils.ToJSON(cfg.KamAgentCfg())
|
||||
case AsteriskAgentJSN:
|
||||
jsonString = utils.ToJSON(cfg.AsteriskAgentCfg())
|
||||
case DA_JSN:
|
||||
jsonString = utils.ToJSON(cfg.DiameterAgentCfg())
|
||||
case RA_JSN:
|
||||
jsonString = utils.ToJSON(cfg.RadiusAgentCfg())
|
||||
case DNSAgentJson:
|
||||
jsonString = utils.ToJSON(cfg.DNSAgentCfg())
|
||||
case ATTRIBUTE_JSN:
|
||||
jsonString = utils.ToJSON(cfg.AttributeSCfg())
|
||||
case ChargerSCfgJson:
|
||||
jsonString = utils.ToJSON(cfg.ChargerSCfg())
|
||||
case RESOURCES_JSON:
|
||||
jsonString = utils.ToJSON(cfg.ResourceSCfg())
|
||||
case STATS_JSON:
|
||||
jsonString = utils.ToJSON(cfg.StatSCfg())
|
||||
case THRESHOLDS_JSON:
|
||||
jsonString = utils.ToJSON(cfg.ThresholdSCfg())
|
||||
case SupplierSJson:
|
||||
jsonString = utils.ToJSON(cfg.SupplierSCfg())
|
||||
case SURETAX_JSON:
|
||||
jsonString = utils.ToJSON(cfg.SureTaxCfg())
|
||||
case DispatcherJson:
|
||||
jsonString = utils.ToJSON(cfg.DispatcherSCfg())
|
||||
case LoaderJson:
|
||||
jsonString = utils.ToJSON(cfg.LoaderCfg())
|
||||
case CgrLoaderCfgJson:
|
||||
jsonString = utils.ToJSON(cfg.LoaderCgrCfg())
|
||||
case CgrMigratorCfgJson:
|
||||
jsonString = utils.ToJSON(cfg.MigratorCgrCfg())
|
||||
case Apier:
|
||||
jsonString = utils.ToJSON(cfg.ApierCfg())
|
||||
case CDRC_JSN:
|
||||
jsonString = utils.ToJSON(cfg.CdrcProfiles)
|
||||
case CDRE_JSN:
|
||||
jsonString = utils.ToJSON(cfg.CdreProfiles)
|
||||
default:
|
||||
return errors.New("Invalid section")
|
||||
}
|
||||
json.Unmarshal([]byte(jsonString), reply)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -1754,3 +1754,30 @@ func TestCgrCfgJSONDefaultApierCfg(t *testing.T) {
|
||||
t.Errorf("received: %+v, expecting: %+v", cgrCfg.apier, aCfg)
|
||||
}
|
||||
}
|
||||
|
||||
func TestCgrCfgV1GetConfigSection(t *testing.T) {
|
||||
JSN_CFG := `
|
||||
{
|
||||
"listen": {
|
||||
"rpc_json": ":2012",
|
||||
"rpc_gob": ":2013",
|
||||
"http": ":2080",
|
||||
}
|
||||
}`
|
||||
expected := map[string]interface{}{
|
||||
"HTTPListen": ":2080",
|
||||
"HTTPTLSListen": "127.0.0.1:2280",
|
||||
"RPCGOBListen": ":2013",
|
||||
"RPCGOBTLSListen": "127.0.0.1:2023",
|
||||
"RPCJSONListen": ":2012",
|
||||
"RPCJSONTLSListen": "127.0.0.1:2022",
|
||||
}
|
||||
var rcv map[string]interface{}
|
||||
if cgrCfg, err := NewCGRConfigFromJsonStringWithDefaults(JSN_CFG); err != nil {
|
||||
t.Error(err)
|
||||
} else if err := cgrCfg.V1GetConfigSection(&StringWithArgDispatcher{Section: LISTEN_JSN}, &rcv); err != nil {
|
||||
t.Error(err)
|
||||
} else if !reflect.DeepEqual(expected, rcv) {
|
||||
t.Errorf("Expected: %+v, received: %+v", expected, rcv)
|
||||
}
|
||||
}
|
||||
|
||||
66
console/get_json_section.go
Normal file
66
console/get_json_section.go
Normal file
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
Real-time Online/Offline Charging System (OCS) for Telecom & ISP environments
|
||||
Copyright (C) ITsysCOM GmbH
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
*/
|
||||
|
||||
package console
|
||||
|
||||
import (
|
||||
"github.com/cgrates/cgrates/config"
|
||||
"github.com/cgrates/cgrates/utils"
|
||||
)
|
||||
|
||||
func init() {
|
||||
c := &CmdGetJSONConfig{
|
||||
name: "get_json_section",
|
||||
rpcMethod: utils.ConfigSv1GetJSONSection,
|
||||
rpcParams: &config.StringWithArgDispatcher{},
|
||||
}
|
||||
commands[c.Name()] = c
|
||||
c.CommandExecuter = &CommandExecuter{c}
|
||||
}
|
||||
|
||||
// Commander implementation
|
||||
type CmdGetJSONConfig struct {
|
||||
name string
|
||||
rpcMethod string
|
||||
rpcParams *config.StringWithArgDispatcher
|
||||
*CommandExecuter
|
||||
}
|
||||
|
||||
func (self *CmdGetJSONConfig) Name() string {
|
||||
return self.name
|
||||
}
|
||||
|
||||
func (self *CmdGetJSONConfig) RpcMethod() string {
|
||||
return self.rpcMethod
|
||||
}
|
||||
|
||||
func (self *CmdGetJSONConfig) RpcParams(reset bool) interface{} {
|
||||
if reset || self.rpcParams == nil {
|
||||
self.rpcParams = &config.StringWithArgDispatcher{}
|
||||
}
|
||||
return self.rpcParams
|
||||
}
|
||||
|
||||
func (self *CmdGetJSONConfig) PostprocessRpcParams() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self *CmdGetJSONConfig) RpcResult() interface{} {
|
||||
var s map[string]interface{}
|
||||
return &s
|
||||
}
|
||||
@@ -17,3 +17,4 @@ cgrates.org,ATTR_API_SCHD_AUTH,*auth,*string:~APIKey:sched12345,,,APIMethods,*co
|
||||
cgrates.org,ATTR_API_CDRS_AUTH,*auth,*string:~APIKey:cdrs12345,,,APIMethods,*constant,CDRsV1.Ping&CDRsV1.ProcessEvent&CDRsV1.GetCDRs&CDRsV1.CountCDRs&CDRsV1.ProcessCDR&CDRsV1.ProcessExternalCDR,false,20
|
||||
cgrates.org,ATTR_API_DSP_AUTH,*auth,*string:~APIKey:dsp12345,,,APIMethods,*constant,DispatcherSv1.Ping&DispatcherSv1.GetProfileForEvent,false,20
|
||||
cgrates.org,ATTR_API_PSE_AUTH,*auth,*string:~APIKey:pse12345,,,APIMethods,*constant,SessionSv1.Ping&SessionSv1.AuthorizeEvent&SessionSv1.AuthorizeEventWithDigest&SessionSv1.InitiateSession&SessionSv1.InitiateSessionWithDigest&SessionSv1.UpdateSession&SessionSv1.SyncSessions&SessionSv1.TerminateSession&SessionSv1.ProcessCDR&SessionSv1.ProcessEvent&SessionSv1.GetActiveSessions&SessionSv1.GetActiveSessionsCount&SessionSv1.ForceDisconnect&SessionSv1.GetPassiveSessions&SessionSv1.GetPassiveSessionsCount&SessionSv1.ReplicateSessions&SessionSv1.SetPassiveSession&AttributeSv1.ProcessEvent&Responder.Debit&ResourceSv1.AllocateResources&ChargerSv1.ProcessEvent&Responder.MaxDebit,false,20
|
||||
cgrates.org,ATTR_API_CFG_AUTH,*auth,*string:~APIKey:cfg12345,,,APIMethods,*constant,ConfigSv1.GetJSONSection,false,20
|
||||
|
||||
|
40
dispatchers/config.go
Normal file
40
dispatchers/config.go
Normal file
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
Real-time Online/Offline Charging System (OCS) for Telecom & ISP environments
|
||||
Copyright (C) ITsysCOM GmbH
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
*/
|
||||
|
||||
package dispatchers
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/cgrates/cgrates/config"
|
||||
"github.com/cgrates/cgrates/utils"
|
||||
)
|
||||
|
||||
func (dS *DispatcherService) ConfigSv1GetJSONSection(args *config.StringWithArgDispatcher, reply *map[string]interface{}) (err error) {
|
||||
if args.ArgDispatcher == nil {
|
||||
return utils.NewErrMandatoryIeMissing("ArgDispatcher")
|
||||
}
|
||||
if dS.attrS != nil {
|
||||
if err = dS.authorize(utils.ConfigSv1GetJSONSection,
|
||||
args.Tenant, args.APIKey, utils.TimePointer(time.Now())); err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
return dS.Dispatch(&utils.CGREvent{Tenant: args.Tenant},
|
||||
utils.MetaConfig, args.RouteID, utils.ConfigSv1GetJSONSection, args, reply)
|
||||
}
|
||||
63
dispatchers/config_it_test.go
Normal file
63
dispatchers/config_it_test.go
Normal file
@@ -0,0 +1,63 @@
|
||||
// +build integration
|
||||
|
||||
/*
|
||||
Real-time Online/Offline Charging System (OCS) for Telecom & ISP environments
|
||||
Copyright (C) ITsysCOM GmbH
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
*/
|
||||
|
||||
package dispatchers
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
"github.com/cgrates/cgrates/config"
|
||||
"github.com/cgrates/cgrates/utils"
|
||||
)
|
||||
|
||||
var sTestsDspConfig = []func(t *testing.T){
|
||||
testDspConfigSv1GetJSONSection,
|
||||
}
|
||||
|
||||
//Test start here
|
||||
func TestDspConfigITMySQL(t *testing.T) {
|
||||
testDsp(t, sTestsDspConfig, "TestDspConfigITMySQL", "all", "all2", "dispatchers", "tutorial", "oldtutorial", "dispatchers")
|
||||
}
|
||||
|
||||
func testDspConfigSv1GetJSONSection(t *testing.T) {
|
||||
expected := map[string]interface{}{
|
||||
"HTTPListen": ":6080",
|
||||
"HTTPTLSListen": "127.0.0.1:2280",
|
||||
"RPCGOBListen": ":6013",
|
||||
"RPCGOBTLSListen": "127.0.0.1:2023",
|
||||
"RPCJSONListen": ":6012",
|
||||
"RPCJSONTLSListen": "127.0.0.1:2022",
|
||||
}
|
||||
var reply map[string]interface{}
|
||||
if err := dispEngine.RCP.Call(utils.ConfigSv1GetJSONSection, &config.StringWithArgDispatcher{
|
||||
TenantArg: utils.TenantArg{
|
||||
Tenant: "cgrates.org",
|
||||
},
|
||||
ArgDispatcher: &utils.ArgDispatcher{
|
||||
APIKey: utils.StringPointer("cfg12345"),
|
||||
},
|
||||
Section: "listen",
|
||||
}, &reply); err != nil {
|
||||
t.Error(err)
|
||||
} else if !reflect.DeepEqual(expected, reply) {
|
||||
t.Errorf("Expected: %+v, received: %+v", expected, reply)
|
||||
}
|
||||
}
|
||||
@@ -390,6 +390,7 @@ const (
|
||||
MetaAttributes = "*attributes"
|
||||
MetaServiceManager = "*servicemanager"
|
||||
MetaChargers = "*chargers"
|
||||
MetaConfig = "*config"
|
||||
MetaDispatchers = "*dispatchers"
|
||||
MetaDispatcherHosts = "*dispatcher_hosts"
|
||||
MetaResources = "*resources"
|
||||
@@ -752,6 +753,11 @@ const (
|
||||
ServiceManagerV1Ping = "ServiceManagerV1.Ping"
|
||||
)
|
||||
|
||||
const (
|
||||
ConfigSv1 = "ConfigSv1"
|
||||
ConfigSv1GetJSONSection = "ConfigSv1.GetJSONSection"
|
||||
)
|
||||
|
||||
// SupplierS APIs
|
||||
const (
|
||||
SupplierSv1GetSuppliers = "SupplierSv1.GetSuppliers"
|
||||
|
||||
Reference in New Issue
Block a user