diff --git a/apis/attributes_it_test.go b/apis/attributes_it_test.go
index 855586fe7..2fdcb280e 100644
--- a/apis/attributes_it_test.go
+++ b/apis/attributes_it_test.go
@@ -44,7 +44,6 @@ var (
sTestsAlsPrf = []func(t *testing.T){
testAttributeSInitCfg,
testAttributeSInitDataDb,
-
testAttributeSStartEngine,
testAttributeSRPCConn,
testGetAttributeProfileBeforeSet,
diff --git a/apis/loaders_it_test.go b/apis/loaders_it_test.go
index d405ce4d8..d1d39b10d 100644
--- a/apis/loaders_it_test.go
+++ b/apis/loaders_it_test.go
@@ -1577,7 +1577,7 @@ func TestLoadersLoad(t *testing.T) {
data := engine.NewInternalDB(nil, nil, cfg.DataDbCfg().Items)
dm := engine.NewDataManager(data, cfg.CacheCfg(), nil)
fltrs := engine.NewFilterS(cfg, nil, dm)
- ldrS := loaders.NewLoaders(cfg, dm, fltrs, nil)
+ ldrS := loaders.NewLoaderS(cfg, dm, fltrs, nil)
lSv1 := NewLoaderSv1(ldrS)
args := &loaders.ArgsProcessFolder{
diff --git a/apis/loaders_test.go b/apis/loaders_test.go
index 995b5bc03..aeb308477 100644
--- a/apis/loaders_test.go
+++ b/apis/loaders_test.go
@@ -32,7 +32,7 @@ func TestLoadersNewLoaderSv1(t *testing.T) {
data := engine.NewInternalDB(nil, nil, cfg.DataDbCfg().Items)
dm := engine.NewDataManager(data, cfg.CacheCfg(), nil)
fltrs := engine.NewFilterS(cfg, nil, dm)
- ldrS := loaders.NewLoaders(cfg, dm, fltrs, nil)
+ ldrS := loaders.NewLoaderS(cfg, dm, fltrs, nil)
exp := &LoaderSv1{
ldrS: ldrS,
diff --git a/apis/tpes.go b/apis/tpes.go
index 782da2d7b..0ae1a0965 100644
--- a/apis/tpes.go
+++ b/apis/tpes.go
@@ -19,6 +19,7 @@ along with this program. If not, see
package apis
import (
+ "github.com/cgrates/birpc/context"
"github.com/cgrates/cgrates/tpes"
)
@@ -30,3 +31,7 @@ type TPeSv1 struct {
tpes *tpes.TPeS
ping
}
+
+func (tpE *TPeSv1) ExportTariffPlan(ctx *context.Context, args *tpes.ArgsExportTP, reply *[]byte) error {
+ return tpE.tpes.V1ExportTariffPlan(ctx, args, reply)
+}
diff --git a/apis/tpes_it_test.go b/apis/tpes_it_test.go
index facbb034b..fa9f42d99 100644
--- a/apis/tpes_it_test.go
+++ b/apis/tpes_it_test.go
@@ -29,6 +29,7 @@ import (
"github.com/cgrates/birpc/context"
"github.com/cgrates/cgrates/config"
"github.com/cgrates/cgrates/engine"
+ "github.com/cgrates/cgrates/tpes"
"github.com/cgrates/cgrates/utils"
)
@@ -39,17 +40,17 @@ var (
tpeSConfigDIR string //run tests for specific configuration
sTestTpes = []func(t *testing.T){
- testTpeSInitCfg,
- testTpeSInitDataDb,
-
- testTpeSStartEngine,
- testTpeSRPCConn,
- testTpeSPing,
- testTpeSKillEngine,
+ testTPeSInitCfg,
+ testTPeSInitDataDb,
+ testTPeSStartEngine,
+ testTPeSRPCConn,
+ testTPeSPing,
+ testTPeSExportTariffPlan,
+ testTPeSKillEngine,
}
)
-func TestTpeSIT(t *testing.T) {
+func TestTPeSIT(t *testing.T) {
switch *dbType {
case utils.MetaInternal:
tpeSConfigDIR = "tutinternal"
@@ -67,7 +68,7 @@ func TestTpeSIT(t *testing.T) {
}
}
-func testTpeSInitCfg(t *testing.T) {
+func testTPeSInitCfg(t *testing.T) {
var err error
tpesCfgPath = path.Join(*dataDir, "conf", "samples", tpeSConfigDIR)
tpesCfg, err = config.NewCGRConfigFromPath(context.Background(), tpesCfgPath)
@@ -76,29 +77,161 @@ func testTpeSInitCfg(t *testing.T) {
}
}
-func testTpeSInitDataDb(t *testing.T) {
+func testTPeSInitDataDb(t *testing.T) {
if err := engine.InitDataDB(tpesCfg); err != nil {
t.Fatal(err)
}
}
// Start CGR Engine
-func testTpeSStartEngine(t *testing.T) {
+func testTPeSStartEngine(t *testing.T) {
if _, err := engine.StopStartEngine(tpesCfgPath, *waitRater); err != nil {
t.Fatal(err)
}
}
-func testTpeSPing(t *testing.T) {
+func testTPeSPing(t *testing.T) {
var reply string
- if err := tpeSRPC.Call(context.Background(), utils.TpeSv1Ping, &utils.CGREvent{}, &reply); err != nil {
+ if err := tpeSRPC.Call(context.Background(), utils.TPeSv1Ping, &utils.CGREvent{}, &reply); err != nil {
t.Error(err)
} else if reply != utils.Pong {
t.Errorf("Unexpected reply returned: %s", reply)
}
}
-func testTpeSRPCConn(t *testing.T) {
+func testTPeSExportTariffPlan(t *testing.T) {
+ attrPrf := &engine.APIAttributeProfileWithAPIOpts{
+ APIAttributeProfile: &engine.APIAttributeProfile{
+ Tenant: utils.CGRateSorg,
+ ID: "TEST_ATTRIBUTES_IT_TEST",
+ FilterIDs: []string{"*string:~*req.Account:1002", "*exists:~*opts.*usage:"},
+ Attributes: []*engine.ExternalAttribute{
+ {
+ Path: utils.AccountField,
+ Type: utils.MetaConstant,
+ Value: "1002",
+ },
+ {
+ Path: "*tenant",
+ Type: utils.MetaConstant,
+ Value: "cgrates.itsyscom",
+ },
+ },
+ Weights: utils.DynamicWeights{
+ {
+ Weight: 20,
+ },
+ },
+ },
+ }
+ var reply string
+ if err := tpeSRPC.Call(context.Background(), utils.AdminSv1SetAttributeProfile,
+ attrPrf, &reply); err != nil {
+ t.Error(err)
+ } else if reply != utils.OK {
+ t.Error(err)
+ }
+ attrPrf1 := &engine.APIAttributeProfileWithAPIOpts{
+ APIAttributeProfile: &engine.APIAttributeProfile{
+ Tenant: utils.CGRateSorg,
+ ID: "TEST_ATTRIBUTES_IT_TEST_SECOND",
+ FilterIDs: []string{"*string:~*opts.*context:*sessions", "*exists:~*opts.*usage:"},
+ Attributes: []*engine.ExternalAttribute{
+ {
+ Path: "*tenant",
+ Type: utils.MetaConstant,
+ Value: "cgrates.itsyscom",
+ },
+ },
+ },
+ }
+ var reply1 string
+ if err := tpeSRPC.Call(context.Background(), utils.AdminSv1SetAttributeProfile,
+ attrPrf1, &reply1); err != nil {
+ t.Error(err)
+ } else if reply1 != utils.OK {
+ t.Error(err)
+ }
+ rsPrf1 := &engine.ResourceProfileWithAPIOpts{
+ ResourceProfile: &engine.ResourceProfile{
+ Tenant: "cgrates.org",
+ ID: "ResGroup1",
+ FilterIDs: []string{"*string:~*req.Account:1001"},
+ Limit: 10,
+ AllocationMessage: "Approved",
+ Weights: utils.DynamicWeights{
+ {
+ Weight: 20,
+ }},
+ ThresholdIDs: []string{utils.MetaNone},
+ },
+ }
+
+ var replystr string
+ if err := tpeSRPC.Call(context.Background(), utils.AdminSv1SetResourceProfile,
+ rsPrf1, &replystr); err != nil {
+ t.Error(err)
+ } else if replystr != utils.OK {
+ t.Error("Unexpected reply returned", replystr)
+ }
+
+ rsPrf2 := &engine.ResourceProfileWithAPIOpts{
+ ResourceProfile: &engine.ResourceProfile{
+ Tenant: "cgrates.org",
+ ID: "ResGroup2",
+ FilterIDs: []string{"*string:~*req.Account:1001"},
+ Limit: 10,
+ AllocationMessage: "Approved",
+ Weights: utils.DynamicWeights{
+ {
+ Weight: 10,
+ }},
+ ThresholdIDs: []string{utils.MetaNone},
+ },
+ }
+
+ if err := tpeSRPC.Call(context.Background(), utils.AdminSv1SetResourceProfile,
+ rsPrf2, &replystr); err != nil {
+ t.Error(err)
+ } else if replystr != utils.OK {
+ t.Error("Unexpected reply returned", replystr)
+ }
+ var replyBts []byte
+ if err := tpeSRPC.Call(context.Background(), utils.TPeSv1ExportTariffPlan, &tpes.ArgsExportTP{
+ Tenant: "cgrates.org",
+ ExportItems: map[string][]string{
+ utils.MetaAttributes: {"TEST_ATTRIBUTES_IT_TEST", "TEST_ATTRIBUTES_IT_TEST_SECOND"},
+ utils.MetaResources: {"ResGroup1", "ResGroup2"},
+ },
+ }, &replyBts); err != nil {
+ t.Error(err)
+ } /*
+ t.Errorf("received: %v", string(replyBts))
+
+ rdr, err := zip.NewReader(bytes.NewReader(replyBts), int64(len(reply)))
+ if err != nil {
+ t.Error(err)
+ }
+ csvRply := make([][]string, 6)
+ for _, f := range rdr.File {
+ rc, err := f.Open()
+ if err != nil {
+ t.Fatal(err)
+ }
+ info := csv.NewReader(rc)
+ //info.FieldsPerRecord = -1
+ csvRply, err = info.ReadAll()
+ if err != nil {
+ t.Error(err)
+ }
+ rc.Close()
+ }
+ t.Errorf("received: %v", utils.ToJSON(csvRply))
+ */
+
+}
+
+func testTPeSRPCConn(t *testing.T) {
var err error
tpeSRPC, err = newRPCClient(tpesCfg.ListenCfg()) // We connect over JSON so we can also troubleshoot if needed
if err != nil {
@@ -107,7 +240,7 @@ func testTpeSRPCConn(t *testing.T) {
}
//Kill the engine when it is about to be finished
-func testTpeSKillEngine(t *testing.T) {
+func testTPeSKillEngine(t *testing.T) {
if err := engine.KillEngine(100); err != nil {
t.Error(err)
}
diff --git a/data/conf/samples/attributes_internal/cgrates.json b/data/conf/samples/attributes_internal/cgrates.json
index 677472746..e489b28c6 100644
--- a/data/conf/samples/attributes_internal/cgrates.json
+++ b/data/conf/samples/attributes_internal/cgrates.json
@@ -17,5 +17,9 @@
"admins": {
"enabled": true,
+ },
+
+ "tpes": {
+ "enabled": true,
}
}
\ No newline at end of file
diff --git a/data/conf/samples/tutmongo/cgrates.json b/data/conf/samples/tutmongo/cgrates.json
index a3c1787f5..880b0c247 100644
--- a/data/conf/samples/tutmongo/cgrates.json
+++ b/data/conf/samples/tutmongo/cgrates.json
@@ -21,10 +21,6 @@
"db_port": 27017,
},
-
-
-
-
"rals": {
"enabled": true,
"thresholds_conns": ["*internal"],
diff --git a/ers/ers_reload_it_test.go b/ers/ers_reload_it_test.go
index 1ad568f1e..45894b1b6 100644
--- a/ers/ers_reload_it_test.go
+++ b/ers/ers_reload_it_test.go
@@ -41,7 +41,6 @@ var (
reloadTests = []func(t *testing.T){
testReloadITCreateCdrDirs,
testReloadITInitConfig,
- testReloadITInitCdrDb,
testReloadITResetDataDb,
testReloadITStartEngine,
testReloadITRpcConn,
diff --git a/loaders/loaders.go b/loaders/loaders.go
index ea8759802..b85ea0297 100644
--- a/loaders/loaders.go
+++ b/loaders/loaders.go
@@ -32,7 +32,7 @@ import (
"github.com/cgrates/ltcache"
)
-func NewLoaders(cfg *config.CGRConfig, dm *engine.DataManager,
+func NewLoaderS(cfg *config.CGRConfig, dm *engine.DataManager,
filterS *engine.FilterS,
connMgr *engine.ConnManager) (ldrS *LoaderS) {
ldrS = &LoaderS{cfg: cfg, cache: make(map[string]*ltcache.Cache)}
diff --git a/loaders/loaders_test.go b/loaders/loaders_test.go
index 6471b836a..f7c28bc47 100644
--- a/loaders/loaders_test.go
+++ b/loaders/loaders_test.go
@@ -48,7 +48,7 @@ func TestNewLoaderService(t *testing.T) {
for k, cfg := range cfg.LoaderCfg()[0].Cache {
cache[k] = ltcache.NewCache(cfg.Limit, cfg.TTL, cfg.StaticTTL, nil)
}
- ld := NewLoaders(cfg, dm, fS, cM)
+ ld := NewLoaderS(cfg, dm, fS, cM)
if exp := (&LoaderS{
cfg: cfg,
cache: cache,
@@ -146,7 +146,7 @@ func TestLoaderServiceV1Run(t *testing.T) {
dm := engine.NewDataManager(engine.NewInternalDB(nil, nil, cfg.DataDbCfg().Items), cfg.CacheCfg(), cM)
fS := engine.NewFilterS(cfg, cM, dm)
- ld := NewLoaders(cfg, dm, fS, cM)
+ ld := NewLoaderS(cfg, dm, fS, cM)
var rply string
if err := ld.V1Run(context.Background(), &ArgsProcessFolder{
APIOpts: map[string]interface{}{
@@ -222,7 +222,7 @@ func TestLoaderServiceV1RunErrors(t *testing.T) {
dm := engine.NewDataManager(engine.NewInternalDB(nil, nil, cfg.DataDbCfg().Items), cfg.CacheCfg(), cM)
fS := engine.NewFilterS(cfg, cM, dm)
- ld := NewLoaders(cfg, dm, fS, cM)
+ ld := NewLoaderS(cfg, dm, fS, cM)
var rply string
expErrMsg := "SERVER_ERROR: inline parse error for string: <*string>"
@@ -340,7 +340,7 @@ func TestLoaderServiceV1ImportZip(t *testing.T) {
dm := engine.NewDataManager(engine.NewInternalDB(nil, nil, cfg.DataDbCfg().Items), cfg.CacheCfg(), cM)
fS := engine.NewFilterS(cfg, cM, dm)
- ld := NewLoaders(cfg, dm, fS, cM)
+ ld := NewLoaderS(cfg, dm, fS, cM)
var rply string
if err := ld.V1ImportZip(context.Background(), &ArgsProcessZip{
Data: buf.Bytes(),
@@ -396,7 +396,7 @@ func TestLoaderServiceV1ImportZipErrors(t *testing.T) {
dm := engine.NewDataManager(engine.NewInternalDB(nil, nil, cfg.DataDbCfg().Items), cfg.CacheCfg(), cM)
fS := engine.NewFilterS(cfg, cM, dm)
- ld := NewLoaders(cfg, dm, fS, cM)
+ ld := NewLoaderS(cfg, dm, fS, cM)
var rply string
expErrMsg := "SERVER_ERROR: inline parse error for string: <*string>"
diff --git a/services/cgr-engine.go b/services/cgr-engine.go
index 42c6304bb..219e00aae 100644
--- a/services/cgr-engine.go
+++ b/services/cgr-engine.go
@@ -184,7 +184,7 @@ func (cgr *CGREngine) InitServices(httpPrfPath string, cpuPrfFl io.Closer, memPr
cgr.cM.AddInternalConn(utils.ConcatenatedKey(utils.MetaInternal, utils.MetaDispatchers), utils.DispatcherSv1, cgr.iDispatcherSCh)
cgr.cM.AddInternalConn(utils.ConcatenatedKey(utils.MetaInternal, utils.MetaAccounts), utils.AccountSv1, iAccountSCh)
cgr.cM.AddInternalConn(utils.ConcatenatedKey(utils.MetaInternal, utils.MetaActions), utils.ActionSv1, iActionSCh)
- cgr.cM.AddInternalConn(utils.ConcatenatedKey(utils.MetaInternal, utils.MetaTpes), utils.TpeSv1, iTpeSCh)
+ cgr.cM.AddInternalConn(utils.ConcatenatedKey(utils.MetaInternal, utils.MetaTpes), utils.TPeSv1, iTpeSCh)
cgr.gvS = NewGlobalVarS(cgr.cfg, cgr.srvDep)
cgr.dmS = NewDataDBService(cgr.cfg, cgr.cM, cgr.srvDep)
diff --git a/services/loaders.go b/services/loaders.go
index 8d30a145e..48ed7e1eb 100644
--- a/services/loaders.go
+++ b/services/loaders.go
@@ -83,7 +83,7 @@ func (ldrs *LoaderService) Start(ctx *context.Context, _ context.CancelFunc) (er
ldrs.Lock()
defer ldrs.Unlock()
- ldrs.ldrs = loaders.NewLoaders(ldrs.cfg, datadb, filterS, ldrs.connMgr)
+ ldrs.ldrs = loaders.NewLoaderS(ldrs.cfg, datadb, filterS, ldrs.connMgr)
if !ldrs.ldrs.Enabled() {
return
diff --git a/services/loaders_test.go b/services/loaders_test.go
index 2b1df24c4..5f3c52a36 100644
--- a/services/loaders_test.go
+++ b/services/loaders_test.go
@@ -62,7 +62,7 @@ func TestLoaderSCoverage(t *testing.T) {
if srv.IsRunning() {
t.Errorf("Expected service to be down")
}
- srv.ldrs = loaders.NewLoaders(cfg, &engine.DataManager{},
+ srv.ldrs = loaders.NewLoaderS(cfg, &engine.DataManager{},
&engine.FilterS{}, nil)
if !srv.IsRunning() {
t.Errorf("Expected service to be running")
diff --git a/tpes/tpe_attributes.go b/tpes/tpe_attributes.go
index aab46e4cb..58368ab1c 100644
--- a/tpes/tpe_attributes.go
+++ b/tpes/tpe_attributes.go
@@ -42,9 +42,11 @@ func newTPAttributes(dm *engine.DataManager) *TPAttributes {
// exportItems for TPAttributes will implement the imethod for tpExporter interface
func (tpAttr TPAttributes) exportItems(ctx *context.Context, tnt string, itmIDs []string) (expContent []byte, err error) {
- //attrBts := make(map[string][]byte)
+ expContent = make([]byte, len(itmIDs))
+
for _, attrID := range itmIDs {
- attrPrf, err := tpAttr.dm.GetAttributeProfile(ctx, tnt, attrID, true, true, utils.NonTransactional)
+ var attrPrf *engine.AttributeProfile
+ attrPrf, err = tpAttr.dm.GetAttributeProfile(ctx, tnt, attrID, true, true, utils.NonTransactional)
if err != nil {
if err.Error() == utils.ErrNotFound.Error() {
utils.Logger.Warning(fmt.Sprintf("<%s> cannot find AttributeProfile with id: <%v>", utils.TPeS, attrID))
@@ -52,29 +54,28 @@ func (tpAttr TPAttributes) exportItems(ctx *context.Context, tnt string, itmIDs
}
return nil, err
}
-
attrMdl := engine.APItoModelTPAttribute(engine.AttributeProfileToAPI(attrPrf))
- if err := writeOut(utils.AttributesCsv, attrMdl); err != nil {
- return nil, err
+ if len(attrMdl) == 0 {
+ return
}
-
+ // for every profile, convert it into model to be writable in csv format
+ buff := new(bytes.Buffer) // the info will be stored into a buffer
+ csvWriter := csv.NewWriter(buff)
+ csvWriter.Comma = utils.CSVSep
+ for _, tpItem := range attrMdl {
+ // transform every record into a []string
+ record, err := engine.CsvDump(tpItem)
+ if err != nil {
+ return nil, err
+ }
+ // record is a line of a csv file
+ if err := csvWriter.Write(record); err != nil {
+ return nil, err
+ }
+ }
+ csvWriter.Flush()
+ // append our bytes stored in buffer for every profile
+ expContent = append(expContent, buff.Bytes()...)
}
return
}
-
-func writeOut(fileName string, tpData engine.AttributeMdls) error {
- buff := new(bytes.Buffer)
-
- csvWriter := csv.NewWriter(buff)
- for _, tpItem := range tpData {
- record, err := engine.CsvDump(tpItem)
- if err != nil {
- return err
- }
- if err := csvWriter.Write(record); err != nil {
- return err
- }
- }
-
- return nil
-}
diff --git a/tpes/tpe_resources.go b/tpes/tpe_resources.go
new file mode 100644
index 000000000..2a7dc59d6
--- /dev/null
+++ b/tpes/tpe_resources.go
@@ -0,0 +1,76 @@
+/*
+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
+*/
+
+package tpes
+
+import (
+ "bytes"
+ "encoding/csv"
+ "fmt"
+
+ "github.com/cgrates/birpc/context"
+
+ "github.com/cgrates/cgrates/engine"
+ "github.com/cgrates/cgrates/utils"
+)
+
+type TPResources struct {
+ dm *engine.DataManager
+}
+
+// newTPResources is the constructor for TPResources
+func newTPResources(dm *engine.DataManager) *TPResources {
+ return &TPResources{
+ dm: dm,
+ }
+}
+
+// exportItems for TPResources will implement the imethod for tpExporter interface
+func (tpAttr TPResources) exportItems(ctx *context.Context, tnt string, itmIDs []string) (expContent []byte, err error) {
+ expContent = make([]byte, len(itmIDs))
+
+ for _, attrID := range itmIDs {
+ resPrf, err := tpAttr.dm.GetResourceProfile(ctx, tnt, attrID, true, true, utils.NonTransactional)
+ if err != nil {
+ if err.Error() == utils.ErrNotFound.Error() {
+ utils.Logger.Warning(fmt.Sprintf("<%s> cannot find ResourceProfile with id: <%v>", utils.TPeS, attrID))
+ continue
+ }
+ return nil, err
+ }
+ resMdl := engine.APItoModelResource(engine.ResourceProfileToAPI(resPrf))
+ // for every profile, convert it into model to be writable in csv format
+ buff := new(bytes.Buffer) // the info will be stored into a buffer
+ csvWriter := csv.NewWriter(buff)
+ csvWriter.Comma = utils.CSVSep
+ for _, tpItem := range resMdl {
+ record, err := engine.CsvDump(tpItem)
+ if err != nil {
+ return nil, err
+ }
+ // record is a line of a csv file
+ if err := csvWriter.Write(record); err != nil {
+ return nil, err
+ }
+ }
+ csvWriter.Flush()
+ // append our bytes stored in buffer for every profile
+ expContent = append(expContent, buff.Bytes()...)
+ }
+ return
+}
diff --git a/tpes/tpes.go b/tpes/tpes.go
index 9fa0af091..68df022dd 100644
--- a/tpes/tpes.go
+++ b/tpes/tpes.go
@@ -19,7 +19,11 @@ along with this program. If not, see
package tpes
import (
+ "archive/zip"
+ "bytes"
"fmt"
+ "io"
+ "time"
"github.com/cgrates/birpc/context"
@@ -61,7 +65,7 @@ type ArgsExportTP struct {
}
// V1ExportTariffPlan is the API executed to export tariff plan items
-func (tpE *TPeS) V1ExportTariffPlan(ctx *context.Context, args *ArgsExportTP, reply map[string][]byte) (err error) {
+func (tpE *TPeS) V1ExportTariffPlan(ctx *context.Context, args *ArgsExportTP, reply *[]byte) (err error) {
if args.Tenant == utils.EmptyString {
args.Tenant = tpE.cfg.GeneralCfg().DefaultTenant
}
@@ -71,13 +75,31 @@ func (tpE *TPeS) V1ExportTariffPlan(ctx *context.Context, args *ArgsExportTP, re
}
}
- expotedItems := make(map[string][]byte, len(tpE.exps))
- // code to export to zip comes here
+ buff := new(bytes.Buffer)
+ zBuff := zip.NewWriter(buff)
for expType, expItms := range args.ExportItems {
- if expotedItems[expType], err = tpE.exps[expType].exportItems(ctx, args.Tenant, expItms); err != nil {
+ var wrtr io.Writer
+ //here we will create all the header for each subsystem type for the csv
+ if wrtr, err = zBuff.CreateHeader(&zip.FileHeader{
+ Method: zip.Deflate, // to be compressed
+ Name: getFileName(expType),
+ Modified: time.Now(),
+ }); err != nil {
+ return
+ }
+ var expBts []byte
+ // expBts will containt the bytes with all profiles in CSV format
+ if expBts, err = tpE.exps[expType].exportItems(ctx, args.Tenant, expItms); err != nil {
return utils.NewErrServerError(err)
}
+ // write all the bytes into our zip
+ if _, err = wrtr.Write(expBts); err != nil {
+ return
+ }
}
- reply = expotedItems
+ if err = zBuff.Close(); err != nil {
+ return err
+ }
+ *reply = buff.Bytes()
return
}
diff --git a/tpes/tpexporter.go b/tpes/tpexporter.go
index 9c34770a4..9a32c65ec 100644
--- a/tpes/tpexporter.go
+++ b/tpes/tpexporter.go
@@ -26,17 +26,18 @@ import (
var tpExporterTypes = utils.NewStringSet([]string{
utils.MetaAttributes,
- /* utils.MetaResources,
- utils.MetaFilters,
- utils.MetaStats,
- utils.MetaThresholds,
- utils.MetaRoutes,
- utils.MetaChargers,
- utils.MetaDispatchers,
- utils.MetaDispatcherHosts,
- utils.MetaRateProfiles,
- utils.MetaActions,
- utils.MetaAccounts */})
+ utils.MetaResources,
+ /*
+ utils.MetaFilters,
+ utils.MetaStats,
+ utils.MetaThresholds,
+ utils.MetaRoutes,
+ utils.MetaChargers,
+ utils.MetaDispatchers,
+ utils.MetaDispatcherHosts,
+ utils.MetaRateProfiles,
+ utils.MetaActions,
+ utils.MetaAccounts */})
// tpExporter is the interface implementing exports of tariff plan items
type tpExporter interface {
@@ -48,7 +49,43 @@ func newTPExporter(expType string, dm *engine.DataManager) (tpE tpExporter, err
switch expType {
case utils.MetaAttributes:
return newTPAttributes(dm), nil
+ case utils.MetaResources:
+ return newTPResources(dm), nil
default:
return nil, utils.ErrPrefix(utils.ErrUnsupportedTPExporterType, expType)
}
}
+
+func getFileName(subsystem string) string {
+ switch subsystem {
+ case utils.MetaAttributes:
+ return utils.AttributesCsv
+ case utils.MetaResources:
+ return utils.ResourcesCsv
+ default:
+ return utils.EmptyString
+ }
+}
+
+/*
+func writeOut(tpData []interface{}) (csvBts []byte, err error) {
+ if len(tpData) == 0 {
+ return
+ }
+ buff := new(bytes.Buffer)
+ csvWriter := csv.NewWriter(buff)
+ csvWriter.Comma = utils.CSVSep
+ for _, tpItem := range tpData {
+ record, err := engine.CsvDump(tpItem)
+ if err != nil {
+ return nil, err
+ }
+ if err := csvWriter.Write(record); err != nil {
+ return nil, err
+ }
+ }
+
+ csvWriter.Flush()
+ return buff.Bytes(), nil
+}
+*/
diff --git a/utils/consts.go b/utils/consts.go
index deade7cab..619729285 100644
--- a/utils/consts.go
+++ b/utils/consts.go
@@ -1251,10 +1251,11 @@ const (
ServiceManagerV1Ping = "ServiceManagerV1.Ping"
)
-// TpeSv1 APIs
+// TPeSv1 APIs
const (
- TpeSv1 = "TpeSv1"
- TpeSv1Ping = "TpeSv1.Ping"
+ TPeSv1 = "TPeSv1"
+ TPeSv1Ping = "TPeSv1.Ping"
+ TPeSv1ExportTariffPlan = "TPeSv1.ExportTariffPlan"
)
// ConfigSv1 APIs