Floci 仿真 AWS BCM Data Exports 服务:CUR 2.0 / FOCUS 1.2 导出管理面完整指南
Floci 仿真 AWS BCM Data Exports 服务CUR 2.0 / FOCUS 1.2 导出管理面完整指南【免费下载链接】flociLight, fluffy, and always free - The AWS Local Emulator alternative项目地址: https://gitcode.com/gh_mirrors/fl/floci导读本文深入讲解 FlociAWS 本地仿真器中bcm-data-exports:*服务的完整实现与用法。该服务仿真 AWS Billing and Cost Management Data ExportsCUR 2.0 / FOCUS 1.2 配套的管理面 API支持创建、查询、更新、删除导出Export及其执行记录Execution并通过与 legacycur:*服务共享的 Parquet 发射流水线在本地 S3 中产出真实的 FOCUS 1.2 列式成本数据文件。读完本文你将掌握该服务的协议入口、全部 7 个操作、校验规则、执行状态机、发射机制与三种运行模式并能用 AWS CLI 和 boto3 在本地完整跑通创建导出 → 生成 Parquet → 轮询执行状态的实战流程。服务概览协议、端点与定位BCM Data Exports 是 CUR 2.0 / FOCUS 1.2 的配套数据导出服务。Floci 仿真的是它的管理面management plane即定义导出任务、查询执行记录的 API而数据产出则交给与 legacycur:*服务共享的 Parquet 发射引擎。协议JSON 1.1请求头X-Amz-Target: AWSBillingAndCostManagementDataExports.ActionEndpoint 前缀bcm-data-exports从源码看路由分发由 BcmDataExportsJsonHandler.java 完成它解析X-Amz-Target头中的 action 名通过 Java 的switch表达式分派到 BcmDataExportsService.java 的对应方法遇到未知 action 则返回400 UnknownOperationException。关系说明BCM Data Exports 与 legacycur:*是同一底层导出流水线的两个不同管理面。两者共享EmissionEngine→FocusRowProjector→ParquetEmitter这条发射链路详见下文发射机制一节区别在于存储键、校验规则与操作命名不同。支持的 7 个操作操作说明含源码行为细节CreateExport创建导出若Name与已有导出重复返回ValidationException见 BcmDataExportsService.java 中findByName去重逻辑GetExport按 ARN 返回单个导出ARN 缺失或不存在时返回ResourceNotFoundExceptionListExports返回调用账户拥有的全部导出管理面返回Exports数组每项为 ExportReference 摘要UpdateExport替换既有导出的可变字段保留ExportArn、CreatedAt、OwnerAccountId等不可变属性DeleteExport幂等删除同一调用内级联删除该导出的全部执行记录避免孤儿记录ListExecutions返回某导出的全部执行记录导出不存在时返回ResourceNotFoundExceptionGetExecution按ExportArnExecutionId返回单条执行记录响应形状要点从序列化器看BcmDataExportsJsonHandler.java 中的序列化逻辑揭示了几个对 SDK 兼容性很关键的细节CreateExport/UpdateExport只返回ExportArn字符串{ExportArn: ...}与 AWS 实际响应一致GetExport返回完整的Export对象其中ExportStatus被包装成ExportStatus.StatusCodeCreatedAtLastUpdatedAt时间戳格式化为 ISO-8601ListExports的每个元素只含ExportArn、ExportName和ExportStatus.StatusCodeGetExecution/ListExecutions返回ExecutionId、ExportArn以及ExecutionStatus含StatusCode、CreatedBy、CreatedAt、CompletedAt、StatusReason。校验规则详解Floci 对Export各字段的校验集中在 BcmDataExportsService.java 的validateExport/validateDestination/validateRefreshCadence三个方法中与 AWS 行为对齐字段规则违规响应Export.Name仅允许字母数字 -与_最长 128 字符ValidationExceptionExport.DataQuery.QueryStatement必填自由形式 SQLFloci 不做解析导出形状由内置 FOCUS schema 决定ValidationExceptionExport.DestinationConfigurations.S3Destination必填S3BucketS3Region为必填ValidationExceptionS3Destination.S3Bucket还需通过S3DestinationValidation.requireValidBucketName的桶名校验3–63 字符、小写字母数字/连字符/点号等ValidationExceptionS3Destination.S3Prefix可选非空时须为安全 key 段requireSafeKeySegmentValidationExceptionS3OutputConfigurations.Format仅PARQUETCSV 未实现传TEXT_OR_CSV返回ValidationExceptionValidationExceptionS3OutputConfigurations.Compression仅PARQUETGZIP未实现ValidationExceptionS3OutputConfigurations.OverwriteCREATE_NEW_REPORT/OVERWRITE_REPORTValidationExceptionS3OutputConfigurations.OutputType仅CUSTOMValidationExceptionRefreshCadence.Frequency仅SYNCHRONOUS撰写本文时 AWS 唯一支持的值ValidationExceptionExport.RefreshCadence必填ValidationException源码中这些白名单以Set常量形式定义BcmDataExportsService.javaALLOWED_FORMAT {PARQUET}、ALLOWED_COMPRESSION {PARQUET}、ALLOWED_OVERWRITE {CREATE_NEW_REPORT, OVERWRITE_REPORT}、ALLOWED_OUTPUT_TYPE {CUSTOM}、ALLOWED_FREQUENCY {SYNCHRONOUS}。S3OutputConfigurations是可选的out ! null时才校验其子字段但一旦提供非法取值会被直接拒绝——这样设计是为了防止能持久化但无人能读取的导出定义Floci 的发射引擎只写 Parquet。存储键与账户隔离BCM 导出数据全程按账户account-scoped隔离存储键设计如下导出ExportaccountId::exportArn执行记录ExecutionaccountId::exportArn::executionId实际写入时通过StorageFactory创建两个后端bcm-exports.json存导出、bcm-executions.json存执行记录见 BcmDataExportsService.java。几个值得注意的账户处理细节Export模型带有一个不在 AWS 线协议中暴露的ownerAccountId字段用于在后台调度场景下定位正确的账户分区见 Export.java删除导出时deleteExport会扫描执行存储中所有以exportArn::为前缀的 key 并一并删除BcmDataExportsService.java确保不产生孤儿执行记录后台每日发射循环通过AccountAwareStorageBackend.scanAllAccounts()putForAccount跨账户读写listAllExportsByAccount()按ownerAccountId分组返回全部账户的导出。执行生命周期Execution Lifecycle在synchronous模式下一次成功的CreateExport会产生恰好一条执行记录其状态流转如下INITIATION_IN_PROCESS 在创建导出时记录 | v DELIVERY_SUCCESS 或 DELIVERY_FAILUREUpdateExport同样会触发状态流转。成功与失败两种终态都能通过GetExecution.Execution.ExecutionStatus观察。从源码实现看CurEmissionScheduler.java执行记录的编排过程是recordExecution()先生成 UUIDexecutionId状态置为INITIATION_IN_PROCESScreatedBy记为USER或SCHEDULE调用EmissionEngine.emitForCurrentMonth()执行发射成功则completeExecution(successtrue)置为DELIVERY_SUCCESS失败则completeExecution(successfalse)置为DELIVERY_FAILURE并把异常信息写入StatusReason。执行模型类 ExportExecution.java 中注释列出的完整状态集合为INITIATION_IN_PROCESS | QUERY_QUEUED | QUERY_IN_PROCESS | QUERY_FAILURE | DELIVERY_IN_PROCESS | DELIVERY_SUCCESS | DELIVERY_FAILUREFloci 当前主要使用首、尾状态。发射机制与 CUR 共享的 Parquet 流水线BCM 导出与cur:*共用同一条 Parquet 发射链路流程如下收集用量行EmissionEngine从所有实现ResourceUsageEnumeratorSPI 的服务收集UsageLine行该 SPI 与 Cost Explorer 服务文档 引入的机制一致见 EmissionEngine.java单个枚举器失败只会告警跳过不影响整体发射投影为 FOCUS 行FocusRowProjector将UsageLine转换为 FOCUS 1.2 / CUR 2.0 列形状使用内置的 Pricing snapshot参见 pricing 文档NDJSON 暂存行序列化为 newline-delimited JSON上传到floci-cur-staging桶key 为cur-staging/reportName/runId.ndjson避免手工拼接 SQL 转义 tag、描述与资源 IDDuckDB 写 Parquetfloci-ducksidecar 执行COPY (SELECT * FROM read_json_auto(staging)) TO dest (FORMAT PARQUET)从 Floci S3 读取暂存对象并直接写回 Floci S3见 ParquetEmitter.java清理暂存在finally块中尽力删除暂存对象与 side-effect CSV避免并发发射累积噪音。每次发射携带全新的runIdUUID最终产物位于s3://S3Bucket/S3Prefix/Name/runId.parquet由于runId每次不同并发发射不会互相覆盖。发射窗口与账户上下文EmissionEngine.emitForCurrentMonth的发射窗口固定为now所在的自然月UTC与 CUR 计费周期一致EmissionEngine.java。ParquetEmitter发射前还会对目标桶名做 S3 命名规则校验并对插值进 SQL 的路径做单引号转义——这是防止通过S3Prefix等字段注入 SQL 的双重安全网。值得注意的实现细节floci-duck的/execute端点为了兼容 Athena 代码路径总是把主sql字段包装成输出 CSV 的 COPY因此 Parquet 写入放在setup_sql原样执行而主sql只是一个无副作用的SELECT 1 AS ok见 ParquetEmitter.java。floci-ducksidecar 与 Athena 一样在首次发射时懒启动。FLOCI_SERVICES_BCM_DATA_EXPORTS_EMIT_MODE三种运行模式值行为synchronous默认每次CreateExport/UpdateExport同步发射一次daily每 24 小时通过共享的 CUR 调度执行器发射一次off仅管理面不产生任何发射调度器实现见 CurEmissionScheduler.javadaily模式在PostConstruct启动一个单线程的ScheduledExecutorService首次延迟 5 秒周期 24 小时与面向用户的 EventBridge Scheduler 派发器刻意分离。每日循环在请求作用域之外运行因此会为每个账户激活合成 CDI 请求作用域runUnderAccount确保 Java 侧暂存写入与 DuckDB 侧读写落在同一账户分区CurEmissionScheduler.java。CreateExport同步发射失败不会回滚导出创建——handler 捕获异常后告警导出依然持久化BcmDataExportsJsonHandler.java失败情况通过执行记录的状态暴露。配置项环境变量默认值说明FLOCI_SERVICES_BCM_DATA_EXPORTS_ENABLEDtrue启用或禁用该服务FLOCI_SERVICES_BCM_DATA_EXPORTS_EMIT_MODEsynchronous运行模式见上表对应配置接口为 EmulatorConfig.java 中的BcmDataExportsServiceConfigenabled()默认trueemitMode()默认synchronous语义与floci.services.cur.emit-mode一致但作用于 BCM 的Export记录。实战示例AWS CLIbashexport AWS_ENDPOINT_URLhttp://localhost:4566 export AWS_DEFAULT_REGIONus-east-1 export AWS_ACCESS_KEY_IDtest export AWS_SECRET_ACCESS_KEYtest # 创建同步导出的 FOCUS 月报 aws bcm-data-exports create-export --export { Name: focus-monthly, DataQuery: {QueryStatement: SELECT * FROM COST_AND_USAGE_REPORT}, DestinationConfigurations: { S3Destination: { S3Bucket: my-billing, S3Prefix: focus, S3Region: us-east-1, S3OutputConfigurations: { Format: PARQUET, Compression: PARQUET, OutputType: CUSTOM, Overwrite: OVERWRITE_REPORT } } }, RefreshCadence: {Frequency: SYNCHRONOUS} } # 列出本账户所有导出 aws bcm-data-exports list-exports # 查看某导出的执行记录 aws bcm-data-exports list-executions \ --export-arn arn:aws:bcm-data-exports:us-east-1:000000000000:export/focus-monthly创建成功后同步发射会在s3://my-billing/focus/focus-monthly/runId.parquet留下真实 Parquet 文件可用aws s3 ls s3://my-billing/focus/focus-monthly/查看产物。boto3Pythonimport boto3 client boto3.client( bcm-data-exports, endpoint_urlhttp://localhost:4566, region_nameus-east-1, ) resp client.create_export(Export{ Name: focus-monthly, DataQuery: {QueryStatement: SELECT * FROM COST_AND_USAGE_REPORT}, DestinationConfigurations: {S3Destination: { S3Bucket: my-billing, S3Prefix: focus, S3Region: us-east-1, S3OutputConfigurations: { Format: PARQUET, Compression: PARQUET, OutputType: CUSTOM, Overwrite: OVERWRITE_REPORT, }, }}, RefreshCadence: {Frequency: SYNCHRONOUS}, }) print(resp[ExportArn])boto3 走endpoint_url访问 Floci 时SDK 会使用正确的X-Amz-Target头create-export、list-exports、list-executions、get-execution等操作均可直接工作。不在范围内Out of ScopeDataQuery.QueryStatement的自定义 SQL 求值Floci 不解析 SQL直接按 FOCUS 形状发射数据查询字符串会被忠实持久化以保证 SDK 往返round-trip正常但对 Parquet 输出没有任何影响成本类别cost categories、计费视图billing views与定价模型覆盖pricing-model overrides超出SYNCHRONOUS的真实RefreshCadence调度目前仅支持SYNCHRONOUS以及 Floci 内部的daily模式TEXT_OR_CSV/GZIP输出发射引擎当前无条件写 ParquetCSV 与 GZIP 尚未实现。延伸阅读服务文档docs/services/cur.md共享发射流水线的 legacy 管理面管理面实现BcmDataExportsService.java协议分发BcmDataExportsJsonHandler.java数据模型Export.java、ExportExecution.java、DataQuery.java、DestinationConfiguration.java、RefreshCadence.java发射编排CurEmissionScheduler.java、EmissionEngine.java、ParquetEmitter.java配置定义EmulatorConfig.java【免费下载链接】flociLight, fluffy, and always free - The AWS Local Emulator alternative项目地址: https://gitcode.com/gh_mirrors/fl/floci创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

相关新闻

前端项目依赖清理实战:5个可被原生API替代的npm包

前端项目依赖清理实战:5个可被原生API替代的npm包

1. 为什么现在可以开始清理 package.json 了如果你维护过超过两年的前端项目,打开package.json大概率会看到这样的景象:dependencies和devDependencies加起来四五十个包,其中有一半你已经想不起来当初为什么装它。更麻烦的是,每次…

2026/9/22 1:03:27 阅读更多 →
Java 8实战:Lambda、Stream和日期时间API核心详解

Java 8实战:Lambda、Stream和日期时间API核心详解

简介:这是一份面向Java开发者及初学者的简明教程PDF,围绕Java 8平台的核心更新,系统讲解默认接口方法、Lambda表达式、函数式接口、方法与构造引用、Stream流、Map扩展、新的时间日期API、Optional容器以及并发增强等关键特性,帮助…

2026/9/22 1:03:28 阅读更多 →
Preact Table 的 AppGroupColumnDef:预绑定组件的增强分组列定义

Preact Table 的 AppGroupColumnDef:预绑定组件的增强分组列定义

前端UI组件 【免费下载链接】table 🤖 Headless UI for building powerful tables & datagrids for TS/JS - React-Table, Vue-Table, Solid-Table, Svelte-Table 项目地址: https://gitcode.com/gh_mirrors/ta/table 点击查看 免费下载 导读 AppG…

2026/9/20 20:39:04 阅读更多 →

最新新闻

3个实战项目踩坑:广告ROI计算错漏全解

3个实战项目踩坑:广告ROI计算错漏全解

3个实战项目踩坑:广告ROI计算错漏全解 版本升级后 API 全变了,我盯着屏幕上的报错日志,手心全是汗。 上周刚接了个电商投放的 实战项目 ,需求很简单:算清楚每个渠道的 广告ROI ,看看哪条路真赚钱,哪条路在烧钱。…

2026/9/22 1:03:19 阅读更多 →
2026最新抖音赚钱吗真相:从底层算法到变现闭环的深度拆解

2026最新抖音赚钱吗真相:从底层算法到变现闭环的深度拆解

2026最新抖音赚钱吗真相:从底层算法到变现闭环的深度拆解 面试时被问“推荐系统的核心逻辑是什么”,你只能支支吾吾说“就是看用户喜好”,面试官皱眉的眼神让你至今难忘。这种 原理答不上来…

2026/9/22 1:03:19 阅读更多 →
苹果公开版避坑指南:3个关键节点告别配置地狱

苹果公开版避坑指南:3个关键节点告别配置地狱

苹果公开版避坑指南:3个关键节点告别配置地狱 配置环境就卡半天,这种痛苦每个转岗的开发者都懂。刚拿到MacBook Air,满怀期待地打开终端,结果Xcode装不上,Swift版本不匹配,Pod依赖冲突,折腾了三天还没跑通一个Hello…

2026/9/22 1:03:19 阅读更多 →
Spring Boot与Elasticsearch 8整合实战指南

Spring Boot与Elasticsearch 8整合实战指南

1. 为什么需要Spring Boot与Elasticsearch整合在当今数据驱动的时代,搜索功能已成为各类应用的标配需求。传统数据库的模糊查询在面对海量数据时往往力不从心,而Elasticsearch作为基于Lucene的分布式搜索引擎,能够轻松应对PB级数据的毫秒级检…

2026/9/22 1:03:19 阅读更多 →
教育模型构建:约束与自主的平衡算法

教育模型构建:约束与自主的平衡算法

1. 教育模型构建背景与核心价值作为一名长期关注教育科技领域的技术开发者,我观察到当前家庭教育普遍存在两种极端倾向:要么是直升机父母式的全方位管控,要么是彻底放养式的自由生长。这两种模式都难以培养出既具备自律能力又保持创新思维的孩…

2026/9/22 1:03:19 阅读更多 →
3个坑让仙台地图渲染崩盘?这份保姆级教程救你

3个坑让仙台地图渲染崩盘?这份保姆级教程救你

3个坑让仙台地图渲染崩盘?这份保姆级教程救你 上周给一个医疗SaaS项目做区域数据可视化,客户点名要集成“仙台地图”组件。我信心满满,结果第一版代码跑起来,控制台直接炸出一屏红字,StackTrace 长得像天书,滚动条都拉不到底。…

2026/9/22 1:02:19 阅读更多 →

日新闻

3台商务办公笔记本实测:手写实现环境配置,告别卡半天

3台商务办公笔记本实测:手写实现环境配置,告别卡半天

3台商务办公笔记本实测:手写实现环境配置,告别卡半天 配置环境就卡半天?别怪机器慢,多半是你没选对工具链。在Java、Go或Python的项目现场, 手写实现…

2026/9/22 0:00:41 阅读更多 →
剑帝加点速查手册:3分钟搞懂核心逻辑

剑帝加点速查手册:3分钟搞懂核心逻辑

剑帝加点速查手册:3分钟搞懂核心逻辑 面试被问原理答不上来,是不是常态?别慌。很多开发者对着 GitHub 开源仓库里的代码发呆,看似简单实则暗藏玄机。今天这份【剑帝加点】速查手册,直接带你拆解核心实现,把面试必考的原理讲透。…

2026/9/22 0:00:41 阅读更多 →
手写实现图片压缩网站核心:搞定WebP转换与质量调优

手写实现图片压缩网站核心:搞定WebP转换与质量调优

手写实现图片压缩网站核心:搞定WebP转换与质量调优 复制来的代码跑不通不知道怎么调?别慌,这种“复制粘贴地狱”在开发圈太常见了。尤其是做 图片压缩网站…

2026/9/22 0:00:41 阅读更多 →

周新闻

Flutter for OpenHarmony游戏卡片渐变背景实战:从原理到性能优化

Flutter for OpenHarmony游戏卡片渐变背景实战:从原理到性能优化

直接铺开项目本身吧。这几个月我一直在折腾一件事:用Flutter给OpenHarmony做一款游戏集合类的App,说白了就是把若干小游戏塞进一个壳里,用统一入口分发。这个方向本身不算新鲜,真正让我花了不少心思的,是首页那堆游戏卡…

2026/9/21 3:13:20 阅读更多 →
Word表格编号全攻略:从列表编号到题注交叉引用

Word表格编号全攻略:从列表编号到题注交叉引用

写Word文档,最让人头疼的往往是那些“看起来不起眼”的小问题。比如表格编号这事:今天在表后面多加了两个空白行,明天给客户交稿前发现整个章节的编号全部错位,光是挨个改序号就能耗掉大半个下午。我前阵子帮人整理一份上百页的技…

2026/9/21 2:19:36 阅读更多 →
从第一个站到第二个站:独立开发者的静态网站选型与落地实践

从第一个站到第二个站:独立开发者的静态网站选型与落地实践

1. 项目概述1.1 核心需求解析做独立开发者这几年,说实话,第一个网站上线的那天晚上我兴奋得没睡着。但等它跑了半年,流量惨淡、功能臃肿、代码自己都懒得看第二遍之后,我才慢慢琢磨明白一个道理:第一个网站是练手&…

2026/9/21 4:51:05 阅读更多 →

月新闻

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能分类:[AI/大模型]细分主题:AI 增强型 CI/CD 流水线自动化与 GitOps 实践:Agent 工作流、工具调用与任务拆解:从原型到生产的验收清单很多团队在尝试用大…

2026/9/21 15:36:51 阅读更多 →
容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场分类:[工程技术]细分主题:Kubernetes 生产环境运维与排障实战:可复制的项目复盘模板与决策记录大部分团队的事故复盘报告,最后都变成了躺在 Confluence 或钉…

2026/9/21 15:36:51 阅读更多 →
容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步

容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步

容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步分类:[工程技术]细分主题:Docker 容器化技术与镜像安全管理:核心链路的逐步实现与关键代码取舍面对一个积累了五六年历史包袱的单体架构应用(包含 Web 接口、后台…

2026/9/19 23:35:34 阅读更多 →