func (self *ApierV1) ExportCdrsToZipString(attr utils.AttrExpFileCdrs, reply *string) error { tmpDir := "/tmp" attr.ExportDir = &tmpDir // Enforce exporting to tmp always so we avoid cleanup issues efc := utils.ExportedFileCdrs{} if err := self.ExportCdrsToFile(attr, &efc); err != nil { return err } else if efc.TotalRecords == 0 || len(efc.ExportedFilePath) == 0 { return errors.New("No CDR records to export") } // Create a buffer to write our archive to. buf := new(bytes.Buffer) // Create a new zip archive. w := zip.NewWriter(buf) // read generated file content, err := ioutil.ReadFile(efc.ExportedFilePath) if err != nil { return err } exportFileName := path.Base(efc.ExportedFilePath) f, err := w.Create(exportFileName) if err != nil { return err } _, err = f.Write(content) if err != nil { return err } // Write metadata into a separate file with extension .cgr medaData, err := json.MarshalIndent(efc, "", " ") if err != nil { errors.New("Failed creating metadata content") } medatadaFileName := exportFileName[:len(path.Ext(exportFileName))] + ".cgr" mf, err := w.Create(medatadaFileName) if err != nil { return err } _, err = mf.Write(medaData) if err != nil { return err } // Make sure to check the error on Close. if err := w.Close(); err != nil { return err } if err := os.Remove(efc.ExportedFilePath); err != nil { fmt.Errorf("Failed removing exported file at path: %s", efc.ExportedFilePath) } *reply = base64.StdEncoding.EncodeToString(buf.Bytes()) return nil }
// Export Cdrs to file func (self *ApierV1) ExportCdrsToFile(attr utils.AttrExpFileCdrs, reply *utils.ExportedFileCdrs) error { var err error cdreReloadStruct := <-self.Config.ConfigReloads[utils.CDRE] // Read the content of the channel, locking it defer func() { self.Config.ConfigReloads[utils.CDRE] <- cdreReloadStruct }() // Unlock reloads at exit exportTemplate := self.Config.CdreProfiles[utils.META_DEFAULT] if attr.ExportTemplate != nil && len(*attr.ExportTemplate) != 0 { // Export template prefered, use it var hasIt bool if exportTemplate, hasIt = self.Config.CdreProfiles[*attr.ExportTemplate]; !hasIt { return fmt.Errorf("%s:ExportTemplate", utils.ErrNotFound.Error()) } } if exportTemplate == nil { return fmt.Errorf("%s:ExportTemplate", utils.ErrMandatoryIeMissing.Error()) } cdrFormat := exportTemplate.CdrFormat if attr.CdrFormat != nil && len(*attr.CdrFormat) != 0 { cdrFormat = strings.ToLower(*attr.CdrFormat) } if !utils.IsSliceMember(utils.CdreCdrFormats, cdrFormat) { return fmt.Errorf("%s:%s", utils.ErrMandatoryIeMissing.Error(), "CdrFormat") } fieldSep := exportTemplate.FieldSeparator if attr.FieldSeparator != nil && len(*attr.FieldSeparator) != 0 { fieldSep, _ = utf8.DecodeRuneInString(*attr.FieldSeparator) if fieldSep == utf8.RuneError { return fmt.Errorf("%s:FieldSeparator:%s", utils.ErrServerError.Error(), "Invalid") } } exportDir := exportTemplate.ExportDirectory if attr.ExportDir != nil && len(*attr.ExportDir) != 0 { exportDir = *attr.ExportDir } exportId := strconv.FormatInt(time.Now().Unix(), 10) if attr.ExportId != nil && len(*attr.ExportId) != 0 { exportId = *attr.ExportId } fileName := fmt.Sprintf("cdre_%s.%s", exportId, cdrFormat) if attr.ExportFileName != nil && len(*attr.ExportFileName) != 0 { fileName = *attr.ExportFileName } filePath := path.Join(exportDir, fileName) if cdrFormat == utils.DRYRUN { filePath = utils.DRYRUN } dataUsageMultiplyFactor := exportTemplate.DataUsageMultiplyFactor if attr.DataUsageMultiplyFactor != nil && *attr.DataUsageMultiplyFactor != 0.0 { dataUsageMultiplyFactor = *attr.DataUsageMultiplyFactor } smsUsageMultiplyFactor := exportTemplate.SMSUsageMultiplyFactor if attr.SmsUsageMultiplyFactor != nil && *attr.SmsUsageMultiplyFactor != 0.0 { smsUsageMultiplyFactor = *attr.SmsUsageMultiplyFactor } mmsUsageMultiplyFactor := exportTemplate.MMSUsageMultiplyFactor if attr.MmsUsageMultiplyFactor != nil && *attr.MmsUsageMultiplyFactor != 0.0 { mmsUsageMultiplyFactor = *attr.MmsUsageMultiplyFactor } genericUsageMultiplyFactor := exportTemplate.GenericUsageMultiplyFactor if attr.GenericUsageMultiplyFactor != nil && *attr.GenericUsageMultiplyFactor != 0.0 { genericUsageMultiplyFactor = *attr.GenericUsageMultiplyFactor } costMultiplyFactor := exportTemplate.CostMultiplyFactor if attr.CostMultiplyFactor != nil && *attr.CostMultiplyFactor != 0.0 { costMultiplyFactor = *attr.CostMultiplyFactor } cdrsFltr, err := attr.AsCDRsFilter(self.Config.DefaultTimezone) if err != nil { return utils.NewErrServerError(err) } cdrs, _, err := self.CdrDb.GetCDRs(cdrsFltr, false) if err != nil { return err } else if len(cdrs) == 0 { *reply = utils.ExportedFileCdrs{ExportedFilePath: ""} return nil } cdrexp, err := cdre.NewCdrExporter(cdrs, self.CdrDb, exportTemplate, cdrFormat, fieldSep, exportId, dataUsageMultiplyFactor, smsUsageMultiplyFactor, mmsUsageMultiplyFactor, genericUsageMultiplyFactor, costMultiplyFactor, self.Config.RoundingDecimals, self.Config.HttpSkipTlsVerify) if err != nil { return utils.NewErrServerError(err) } if cdrexp.TotalExportedCdrs() == 0 { *reply = utils.ExportedFileCdrs{ExportedFilePath: ""} return nil } if err := cdrexp.WriteToFile(filePath); err != nil { return utils.NewErrServerError(err) } *reply = utils.ExportedFileCdrs{ExportedFilePath: filePath, TotalRecords: len(cdrs), TotalCost: cdrexp.TotalCost(), FirstOrderId: cdrexp.FirstOrderId(), LastOrderId: cdrexp.LastOrderId()} if !attr.SuppressCgrIds { reply.ExportedCgrIds = cdrexp.PositiveExports() reply.UnexportedCgrIds = cdrexp.NegativeExports() } return nil }