You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@pinot.apache.org by GitBox <gi...@apache.org> on 2021/04/25 01:43:22 UTC
[GitHub] [incubator-pinot] npawar opened a new pull request #6840: Configs APIs
npawar opened a new pull request #6840:
URL: https://github.com/apache/incubator-pinot/pull/6840
## Description
Introducing new `configs` APIs. These serve as a way to operate on the entire Pinot config as 1 unit, consisting of Pinot schema, realtime table config and offline table config.
The motivation for these is that
1. We had already introduced a validation endpoint which validated config and schema together, as users wanted to validate changes of both before applying any of them. This PR is taking that effort all the way to having a completely dedicated configs wrapper.
2. treating them as separate entities is often creating confusion for users.
3. We want to enforce that table config always needs a schema.
## Release Notes
Deprecated /tables/validateTableAndSchema in favor of the new configs/validate API
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@pinot.apache.org
For additional commands, e-mail: commits-help@pinot.apache.org
[GitHub] [incubator-pinot] codecov-commenter commented on pull request #6840: Configs APIs
Posted by GitBox <gi...@apache.org>.
codecov-commenter commented on pull request #6840:
URL: https://github.com/apache/incubator-pinot/pull/6840#issuecomment-826221712
# [Codecov](https://codecov.io/gh/apache/incubator-pinot/pull/6840?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=The+Apache+Software+Foundation) Report
> Merging [#6840](https://codecov.io/gh/apache/incubator-pinot/pull/6840?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=The+Apache+Software+Foundation) (089e2b3) into [master](https://codecov.io/gh/apache/incubator-pinot/commit/ac5aee70bf25aa4680a115434066287e3456ae71?el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=The+Apache+Software+Foundation) (ac5aee7) will **increase** coverage by `22.28%`.
> The diff coverage is `26.08%`.
[](https://codecov.io/gh/apache/incubator-pinot/pull/6840?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=The+Apache+Software+Foundation)
```diff
@@ Coverage Diff @@
## master #6840 +/- ##
=============================================
+ Coverage 43.52% 65.80% +22.28%
- Complexity 7 12 +5
=============================================
Files 1421 1422 +1
Lines 69142 69288 +146
Branches 9987 9999 +12
=============================================
+ Hits 30093 45597 +15504
+ Misses 36504 20453 -16051
- Partials 2545 3238 +693
```
| Flag | Coverage Δ | Complexity Δ | |
|---|---|---|---|
| integration | `?` | `?` | |
| unittests | `65.80% <26.08%> (?)` | `12.00 <0.00> (?)` | |
Flags with carried forward coverage won't be shown. [Click here](https://docs.codecov.io/docs/carryforward-flags?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=The+Apache+Software+Foundation#carryforward-flags-in-the-pull-request-comment) to find out more.
| [Impacted Files](https://codecov.io/gh/apache/incubator-pinot/pull/6840?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=The+Apache+Software+Foundation) | Coverage Δ | Complexity Δ | |
|---|---|---|---|
| [...ache/pinot/controller/api/resources/Constants.java](https://codecov.io/gh/apache/incubator-pinot/pull/6840/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=The+Apache+Software+Foundation#diff-cGlub3QtY29udHJvbGxlci9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvcGlub3QvY29udHJvbGxlci9hcGkvcmVzb3VyY2VzL0NvbnN0YW50cy5qYXZh) | `21.42% <ø> (ø)` | `0.00 <0.00> (ø)` | |
| [...ller/api/resources/PinotConfigRestletResource.java](https://codecov.io/gh/apache/incubator-pinot/pull/6840/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=The+Apache+Software+Foundation#diff-cGlub3QtY29udHJvbGxlci9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvcGlub3QvY29udHJvbGxlci9hcGkvcmVzb3VyY2VzL1Bpbm90Q29uZmlnUmVzdGxldFJlc291cmNlLmphdmE=) | `0.00% <0.00%> (ø)` | `0.00 <0.00> (?)` | |
| [.../controller/helix/ControllerRequestURLBuilder.java](https://codecov.io/gh/apache/incubator-pinot/pull/6840/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=The+Apache+Software+Foundation#diff-cGlub3QtY29udHJvbGxlci9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvcGlub3QvY29udHJvbGxlci9oZWxpeC9Db250cm9sbGVyUmVxdWVzdFVSTEJ1aWxkZXIuamF2YQ==) | `59.16% <0.00%> (+43.37%)` | `0.00 <0.00> (ø)` | |
| [.../java/org/apache/pinot/spi/config/PinotConfig.java](https://codecov.io/gh/apache/incubator-pinot/pull/6840/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=The+Apache+Software+Foundation#diff-cGlub3Qtc3BpL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9waW5vdC9zcGkvY29uZmlnL1Bpbm90Q29uZmlnLmphdmE=) | `0.00% <0.00%> (ø)` | `0.00 <0.00> (?)` | |
| [...he/pinot/segment/local/utils/TableConfigUtils.java](https://codecov.io/gh/apache/incubator-pinot/pull/6840/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=The+Apache+Software+Foundation#diff-cGlub3Qtc2VnbWVudC1sb2NhbC9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvcGlub3Qvc2VnbWVudC9sb2NhbC91dGlscy9UYWJsZUNvbmZpZ1V0aWxzLmphdmE=) | `78.34% <61.84%> (+25.25%)` | `0.00 <0.00> (ø)` | |
| [...oller/api/resources/PinotTableRestletResource.java](https://codecov.io/gh/apache/incubator-pinot/pull/6840/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=The+Apache+Software+Foundation#diff-cGlub3QtY29udHJvbGxlci9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvcGlub3QvY29udHJvbGxlci9hcGkvcmVzb3VyY2VzL1Bpbm90VGFibGVSZXN0bGV0UmVzb3VyY2UuamF2YQ==) | `58.44% <90.47%> (+27.96%)` | `0.00 <0.00> (ø)` | |
| [...a/org/apache/pinot/minion/metrics/MinionMeter.java](https://codecov.io/gh/apache/incubator-pinot/pull/6840/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=The+Apache+Software+Foundation#diff-cGlub3QtbWluaW9uL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9waW5vdC9taW5pb24vbWV0cmljcy9NaW5pb25NZXRlci5qYXZh) | `0.00% <0.00%> (-100.00%)` | `0.00% <0.00%> (ø%)` | |
| [.../apache/pinot/common/metrics/BrokerQueryPhase.java](https://codecov.io/gh/apache/incubator-pinot/pull/6840/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=The+Apache+Software+Foundation#diff-cGlub3QtY29tbW9uL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9waW5vdC9jb21tb24vbWV0cmljcy9Ccm9rZXJRdWVyeVBoYXNlLmphdmE=) | `0.00% <0.00%> (-100.00%)` | `0.00% <0.00%> (ø%)` | |
| [.../apache/pinot/minion/metrics/MinionQueryPhase.java](https://codecov.io/gh/apache/incubator-pinot/pull/6840/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=The+Apache+Software+Foundation#diff-cGlub3QtbWluaW9uL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9waW5vdC9taW5pb24vbWV0cmljcy9NaW5pb25RdWVyeVBoYXNlLmphdmE=) | `0.00% <0.00%> (-100.00%)` | `0.00% <0.00%> (ø%)` | |
| [...pache/pinot/common/utils/grpc/GrpcQueryClient.java](https://codecov.io/gh/apache/incubator-pinot/pull/6840/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=The+Apache+Software+Foundation#diff-cGlub3QtY29tbW9uL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9waW5vdC9jb21tb24vdXRpbHMvZ3JwYy9HcnBjUXVlcnlDbGllbnQuamF2YQ==) | `0.00% <0.00%> (-100.00%)` | `0.00% <0.00%> (ø%)` | |
| ... and [1073 more](https://codecov.io/gh/apache/incubator-pinot/pull/6840/diff?src=pr&el=tree-more&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=The+Apache+Software+Foundation) | |
------
[Continue to review full report at Codecov](https://codecov.io/gh/apache/incubator-pinot/pull/6840?src=pr&el=continue&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=The+Apache+Software+Foundation).
> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=The+Apache+Software+Foundation)
> `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
> Powered by [Codecov](https://codecov.io/gh/apache/incubator-pinot/pull/6840?src=pr&el=footer&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=The+Apache+Software+Foundation). Last update [ac5aee7...089e2b3](https://codecov.io/gh/apache/incubator-pinot/pull/6840?src=pr&el=lastupdated&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=The+Apache+Software+Foundation). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=The+Apache+Software+Foundation).
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@pinot.apache.org
For additional commands, e-mail: commits-help@pinot.apache.org
[GitHub] [incubator-pinot] codecov-commenter edited a comment on pull request #6840: TableConfigs APIs
Posted by GitBox <gi...@apache.org>.
codecov-commenter edited a comment on pull request #6840:
URL: https://github.com/apache/incubator-pinot/pull/6840#issuecomment-826221712
# [Codecov](https://codecov.io/gh/apache/incubator-pinot/pull/6840?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=The+Apache+Software+Foundation) Report
> Merging [#6840](https://codecov.io/gh/apache/incubator-pinot/pull/6840?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=The+Apache+Software+Foundation) (fd4a969) into [master](https://codecov.io/gh/apache/incubator-pinot/commit/ac5aee70bf25aa4680a115434066287e3456ae71?el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=The+Apache+Software+Foundation) (ac5aee7) will **increase** coverage by `22.12%`.
> The diff coverage is `25.17%`.
[](https://codecov.io/gh/apache/incubator-pinot/pull/6840?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=The+Apache+Software+Foundation)
```diff
@@ Coverage Diff @@
## master #6840 +/- ##
=============================================
+ Coverage 43.52% 65.64% +22.12%
- Complexity 7 12 +5
=============================================
Files 1421 1427 +6
Lines 69142 69850 +708
Branches 9987 10107 +120
=============================================
+ Hits 30093 45852 +15759
+ Misses 36504 20723 -15781
- Partials 2545 3275 +730
```
| Flag | Coverage Δ | Complexity Δ | |
|---|---|---|---|
| integration | `?` | `?` | |
| unittests | `65.64% <25.17%> (?)` | `12.00 <0.00> (?)` | |
Flags with carried forward coverage won't be shown. [Click here](https://docs.codecov.io/docs/carryforward-flags?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=The+Apache+Software+Foundation#carryforward-flags-in-the-pull-request-comment) to find out more.
| [Impacted Files](https://codecov.io/gh/apache/incubator-pinot/pull/6840?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=The+Apache+Software+Foundation) | Coverage Δ | Complexity Δ | |
|---|---|---|---|
| [...inot/controller/api/access/AccessControlUtils.java](https://codecov.io/gh/apache/incubator-pinot/pull/6840/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=The+Apache+Software+Foundation#diff-cGlub3QtY29udHJvbGxlci9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvcGlub3QvY29udHJvbGxlci9hcGkvYWNjZXNzL0FjY2Vzc0NvbnRyb2xVdGlscy5qYXZh) | `70.00% <ø> (-10.00%)` | `0.00 <0.00> (ø)` | |
| [.../api/exception/ControllerApplicationException.java](https://codecov.io/gh/apache/incubator-pinot/pull/6840/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=The+Apache+Software+Foundation#diff-cGlub3QtY29udHJvbGxlci9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvcGlub3QvY29udHJvbGxlci9hcGkvZXhjZXB0aW9uL0NvbnRyb2xsZXJBcHBsaWNhdGlvbkV4Y2VwdGlvbi5qYXZh) | `66.66% <ø> (ø)` | `0.00 <0.00> (?)` | |
| [...ller/api/resources/PinotBrokerRestletResource.java](https://codecov.io/gh/apache/incubator-pinot/pull/6840/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=The+Apache+Software+Foundation#diff-cGlub3QtY29udHJvbGxlci9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvcGlub3QvY29udHJvbGxlci9hcGkvcmVzb3VyY2VzL1Bpbm90QnJva2VyUmVzdGxldFJlc291cmNlLmphdmE=) | `60.97% <ø> (+60.97%)` | `0.00 <0.00> (ø)` | |
| [.../controller/api/resources/PinotClusterConfigs.java](https://codecov.io/gh/apache/incubator-pinot/pull/6840/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=The+Apache+Software+Foundation#diff-cGlub3QtY29udHJvbGxlci9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvcGlub3QvY29udHJvbGxlci9hcGkvcmVzb3VyY2VzL1Bpbm90Q2x1c3RlckNvbmZpZ3MuamF2YQ==) | `34.21% <ø> (+34.21%)` | `0.00 <0.00> (ø)` | |
| [...r/api/resources/PinotIngestionRestletResource.java](https://codecov.io/gh/apache/incubator-pinot/pull/6840/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=The+Apache+Software+Foundation#diff-cGlub3QtY29udHJvbGxlci9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvcGlub3QvY29udHJvbGxlci9hcGkvcmVzb3VyY2VzL1Bpbm90SW5nZXN0aW9uUmVzdGxldFJlc291cmNlLmphdmE=) | `0.00% <ø> (ø)` | `0.00 <0.00> (ø)` | |
| [...ources/PinotInstanceAssignmentRestletResource.java](https://codecov.io/gh/apache/incubator-pinot/pull/6840/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=The+Apache+Software+Foundation#diff-cGlub3QtY29udHJvbGxlci9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvcGlub3QvY29udHJvbGxlci9hcGkvcmVzb3VyY2VzL1Bpbm90SW5zdGFuY2VBc3NpZ25tZW50UmVzdGxldFJlc291cmNlLmphdmE=) | `73.22% <ø> (+73.22%)` | `0.00 <0.00> (ø)` | |
| [...er/api/resources/PinotInstanceRestletResource.java](https://codecov.io/gh/apache/incubator-pinot/pull/6840/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=The+Apache+Software+Foundation#diff-cGlub3QtY29udHJvbGxlci9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvcGlub3QvY29udHJvbGxlci9hcGkvcmVzb3VyY2VzL1Bpbm90SW5zdGFuY2VSZXN0bGV0UmVzb3VyY2UuamF2YQ==) | `49.36% <ø> (+31.64%)` | `0.00 <0.00> (ø)` | |
| [.../resources/PinotLeadControllerRestletResource.java](https://codecov.io/gh/apache/incubator-pinot/pull/6840/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=The+Apache+Software+Foundation#diff-cGlub3QtY29udHJvbGxlci9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvcGlub3QvY29udHJvbGxlci9hcGkvcmVzb3VyY2VzL1Bpbm90TGVhZENvbnRyb2xsZXJSZXN0bGV0UmVzb3VyY2UuamF2YQ==) | `0.00% <ø> (ø)` | `0.00 <0.00> (ø)` | |
| [...ller/api/resources/PinotSchemaRestletResource.java](https://codecov.io/gh/apache/incubator-pinot/pull/6840/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=The+Apache+Software+Foundation#diff-cGlub3QtY29udHJvbGxlci9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvcGlub3QvY29udHJvbGxlci9hcGkvcmVzb3VyY2VzL1Bpbm90U2NoZW1hUmVzdGxldFJlc291cmNlLmphdmE=) | `38.39% <ø> (+19.64%)` | `0.00 <0.00> (ø)` | |
| [...ler/api/resources/PinotSegmentRestletResource.java](https://codecov.io/gh/apache/incubator-pinot/pull/6840/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=The+Apache+Software+Foundation#diff-cGlub3QtY29udHJvbGxlci9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvcGlub3QvY29udHJvbGxlci9hcGkvcmVzb3VyY2VzL1Bpbm90U2VnbWVudFJlc3RsZXRSZXNvdXJjZS5qYXZh) | `3.15% <ø> (-13.69%)` | `0.00 <0.00> (ø)` | |
| ... and [1117 more](https://codecov.io/gh/apache/incubator-pinot/pull/6840/diff?src=pr&el=tree-more&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=The+Apache+Software+Foundation) | |
------
[Continue to review full report at Codecov](https://codecov.io/gh/apache/incubator-pinot/pull/6840?src=pr&el=continue&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=The+Apache+Software+Foundation).
> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=The+Apache+Software+Foundation)
> `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
> Powered by [Codecov](https://codecov.io/gh/apache/incubator-pinot/pull/6840?src=pr&el=footer&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=The+Apache+Software+Foundation). Last update [ac5aee7...fd4a969](https://codecov.io/gh/apache/incubator-pinot/pull/6840?src=pr&el=lastupdated&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=The+Apache+Software+Foundation). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=The+Apache+Software+Foundation).
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@pinot.apache.org
For additional commands, e-mail: commits-help@pinot.apache.org
[GitHub] [incubator-pinot] npawar commented on a change in pull request #6840: TableConfigs APIs
Posted by GitBox <gi...@apache.org>.
npawar commented on a change in pull request #6840:
URL: https://github.com/apache/incubator-pinot/pull/6840#discussion_r621588263
##########
File path: pinot-controller/src/main/java/org/apache/pinot/controller/api/resources/PinotTableRestletResource.java
##########
@@ -165,9 +146,13 @@ public SuccessResponse addTable(String tableConfigStr, @Context HttpHeaders http
throw new ControllerApplicationException(LOGGER, e.getMessage(), Response.Status.BAD_REQUEST, e);
}
try {
- ensureMinReplicas(tableConfig);
- ensureStorageQuotaConstraints(tableConfig);
- verifyTableConfigs(tableConfig);
+ try {
+ TableConfigUtils.ensureMinReplicas(tableConfig, _controllerConf.getDefaultTableMinReplicas());
+ TableConfigUtils.ensureStorageQuotaConstraints(tableConfig, _controllerConf.getDimTableMaxSize());
+ checkHybridTableConfig(TableNameBuilder.extractRawTableName(tableName), tableConfig);
+ } catch (Exception e) {
+ throw new PinotHelixResourceManager.InvalidTableConfigException(e);
Review comment:
Done. Moved it to a package along with `TableAlreadyExistsException` and `ControllerApplicationException`
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@pinot.apache.org
For additional commands, e-mail: commits-help@pinot.apache.org
[GitHub] [incubator-pinot] npawar commented on a change in pull request #6840: TableConfigs APIs
Posted by GitBox <gi...@apache.org>.
npawar commented on a change in pull request #6840:
URL: https://github.com/apache/incubator-pinot/pull/6840#discussion_r621587691
##########
File path: pinot-controller/src/main/java/org/apache/pinot/controller/api/resources/TableConfigsRestletResource.java
##########
@@ -0,0 +1,358 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.pinot.controller.api.resources;
+
+import com.fasterxml.jackson.databind.node.ArrayNode;
+import com.google.common.base.Preconditions;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import io.swagger.annotations.ApiParam;
+import java.io.IOException;
+import java.util.Collections;
+import java.util.List;
+import javax.inject.Inject;
+import javax.ws.rs.DELETE;
+import javax.ws.rs.DefaultValue;
+import javax.ws.rs.GET;
+import javax.ws.rs.POST;
+import javax.ws.rs.PUT;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.QueryParam;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.HttpHeaders;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+import org.apache.pinot.common.metrics.ControllerMeter;
+import org.apache.pinot.common.metrics.ControllerMetrics;
+import org.apache.pinot.controller.ControllerConf;
+import org.apache.pinot.controller.api.access.AccessControlFactory;
+import org.apache.pinot.controller.api.access.AccessControlUtils;
+import org.apache.pinot.controller.api.access.AccessType;
+import org.apache.pinot.controller.api.access.Authenticate;
+import org.apache.pinot.controller.helix.core.PinotHelixResourceManager;
+import org.apache.pinot.segment.local.utils.SchemaUtils;
+import org.apache.pinot.segment.local.utils.TableConfigUtils;
+import org.apache.pinot.spi.config.TableConfigs;
+import org.apache.pinot.spi.config.table.TableConfig;
+import org.apache.pinot.spi.data.Schema;
+import org.apache.pinot.spi.utils.JsonUtils;
+import org.apache.pinot.spi.utils.builder.TableNameBuilder;
+import org.glassfish.grizzly.http.server.Request;
+import org.slf4j.LoggerFactory;
+
+
+/**
+ * Endpoints for CRUD of {@link TableConfigs}.
+ * {@link TableConfigs} is a group of the offline table config, realtime table config and schema for the same tableName.
+ */
+@Api(tags = Constants.TABLE_TAG)
+@Path("/")
+public class TableConfigsRestletResource {
+
+ public static org.slf4j.Logger LOGGER = LoggerFactory.getLogger(TableConfigsRestletResource.class);
+
+ @Inject
+ PinotHelixResourceManager _pinotHelixResourceManager;
+
+ @Inject
+ ControllerConf _controllerConf;
+
+ @Inject
+ ControllerMetrics _controllerMetrics;
+
+ @Inject
+ AccessControlFactory _accessControlFactory;
+ AccessControlUtils _accessControlUtils = new AccessControlUtils();
+
+ /**
+ * List all {@link TableConfigs}, where each is a group of the offline table config, realtime table config and schema for the same tableName.
+ * This is equivalent to a list of all raw table names
+ */
+ @GET
+ @Produces(MediaType.APPLICATION_JSON)
+ @Path("/tableConfigs")
+ @Authenticate(AccessType.READ)
+ @ApiOperation(value = "Lists all TableConfigs in cluster", notes = "Lists all TableConfigs in cluster")
+ public String listConfigs() {
+ try {
+ List<String> rawTableNames = _pinotHelixResourceManager.getAllRawTables();
+ Collections.sort(rawTableNames);
+
+ ArrayNode configsList = JsonUtils.newArrayNode();
+ for (String rawTableName : rawTableNames) {
+ configsList.add(rawTableName);
+ }
+ return configsList.toString();
+ } catch (Exception e) {
+ throw new ControllerApplicationException(LOGGER, e.getMessage(), Response.Status.INTERNAL_SERVER_ERROR, e);
+ }
+ }
+
+ /**
+ * Gets the {@link TableConfigs} for the provided raw tableName, by fetching the offline table config for tableName_OFFLINE,
+ * realtime table config for tableName_REALTIME and schema for tableName
+ */
+ @GET
+ @Produces(MediaType.APPLICATION_JSON)
+ @Path("/tableConfigs/{tableName}")
+ @Authenticate(AccessType.READ)
+ @ApiOperation(value = "Get the TableConfigs for a given raw tableName", notes = "Get the TableConfigs for a given raw tableName")
+ public String getConfig(
+ @ApiParam(value = "Raw table name", required = true) @PathParam("tableName") String tableName) {
+
+ try {
+ Schema schema = _pinotHelixResourceManager.getSchema(tableName);
+ TableConfig offlineTableConfig = _pinotHelixResourceManager.getOfflineTableConfig(tableName);
+ TableConfig realtimeTableConfig = _pinotHelixResourceManager.getRealtimeTableConfig(tableName);
+ TableConfigs config = new TableConfigs(tableName, schema, offlineTableConfig, realtimeTableConfig);
+ return config.toPrettyJsonString();
+ } catch (Exception e) {
+ throw new ControllerApplicationException(LOGGER, e.getMessage(), Response.Status.INTERNAL_SERVER_ERROR, e);
+ }
+ }
+
+ /**
+ * Creates a {@link TableConfigs} using the <code>tableConfigsStr</code>, by creating the schema,
+ * followed by the realtime tableConfig and offline tableConfig as applicable, from the {@link TableConfigs}.
+ * Validates the configs before applying.
+ */
+ @POST
+ @Produces(MediaType.APPLICATION_JSON)
+ @Path("/tableConfigs")
+ @ApiOperation(value = "Add the TableConfigs using the tableConfigsStr json", notes = "Add the TableConfigs using the tableConfigsStr json")
+ public SuccessResponse addConfig(String tableConfigsStr, @Context HttpHeaders httpHeaders, @Context Request request) {
+ TableConfigs tableConfigs;
+ try {
+ tableConfigs = JsonUtils.stringToObject(tableConfigsStr, TableConfigs.class);
+ validateConfig(tableConfigs);
+ } catch (Exception e) {
+ throw new ControllerApplicationException(LOGGER, String.format("Invalid TableConfigs. %s", e.getMessage()),
+ Response.Status.BAD_REQUEST, e);
+ }
+
+ TableConfig offlineTableConfig = tableConfigs.getOffline();
+ TableConfig realtimeTableConfig = tableConfigs.getRealtime();
+ Schema schema = tableConfigs.getSchema();
+
+ try {
+ String endpointUrl = request.getRequestURL().toString();
+ validatePermissions(schema.getSchemaName(), AccessType.CREATE, httpHeaders, endpointUrl);
+
+ if (offlineTableConfig != null) {
+ tuneConfig(offlineTableConfig, schema);
+ validatePermissions(offlineTableConfig.getTableName(), AccessType.CREATE, httpHeaders, endpointUrl);
+ }
+ if (realtimeTableConfig != null) {
+ tuneConfig(realtimeTableConfig, schema);
+ validatePermissions(realtimeTableConfig.getTableName(), AccessType.CREATE, httpHeaders, endpointUrl);
+ }
+
+ _pinotHelixResourceManager.addSchema(schema, true);
Review comment:
Done.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@pinot.apache.org
For additional commands, e-mail: commits-help@pinot.apache.org
[GitHub] [incubator-pinot] npawar commented on a change in pull request #6840: Configs APIs
Posted by GitBox <gi...@apache.org>.
npawar commented on a change in pull request #6840:
URL: https://github.com/apache/incubator-pinot/pull/6840#discussion_r619921969
##########
File path: pinot-spi/src/main/java/org/apache/pinot/spi/config/PinotConfig.java
##########
@@ -0,0 +1,76 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.pinot.spi.config;
+
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.core.JsonProcessingException;
+import javax.annotation.Nullable;
+import org.apache.pinot.spi.config.table.TableConfig;
+import org.apache.pinot.spi.data.Schema;
+import org.apache.pinot.spi.utils.JsonUtils;
+
+
+/**
+ * Wrapper for all configs of a table, which include the offline table config, realtime table config and schema.
+ * This helps look at and operate on the pinot configs as a whole unit.
+ */
+public class PinotConfig {
Review comment:
done. Though this now feels too similar to the plain TableConfig
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@pinot.apache.org
For additional commands, e-mail: commits-help@pinot.apache.org
[GitHub] [incubator-pinot] npawar merged pull request #6840: TableConfigs APIs
Posted by GitBox <gi...@apache.org>.
npawar merged pull request #6840:
URL: https://github.com/apache/incubator-pinot/pull/6840
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@pinot.apache.org
For additional commands, e-mail: commits-help@pinot.apache.org
[GitHub] [incubator-pinot] codecov-commenter edited a comment on pull request #6840: Configs APIs
Posted by GitBox <gi...@apache.org>.
codecov-commenter edited a comment on pull request #6840:
URL: https://github.com/apache/incubator-pinot/pull/6840#issuecomment-826221712
# [Codecov](https://codecov.io/gh/apache/incubator-pinot/pull/6840?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=The+Apache+Software+Foundation) Report
> Merging [#6840](https://codecov.io/gh/apache/incubator-pinot/pull/6840?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=The+Apache+Software+Foundation) (089e2b3) into [master](https://codecov.io/gh/apache/incubator-pinot/commit/ac5aee70bf25aa4680a115434066287e3456ae71?el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=The+Apache+Software+Foundation) (ac5aee7) will **increase** coverage by `30.27%`.
> The diff coverage is `28.06%`.
[](https://codecov.io/gh/apache/incubator-pinot/pull/6840?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=The+Apache+Software+Foundation)
```diff
@@ Coverage Diff @@
## master #6840 +/- ##
=============================================
+ Coverage 43.52% 73.79% +30.27%
- Complexity 7 12 +5
=============================================
Files 1421 1422 +1
Lines 69142 69288 +146
Branches 9987 9999 +12
=============================================
+ Hits 30093 51133 +21040
+ Misses 36504 14808 -21696
- Partials 2545 3347 +802
```
| Flag | Coverage Δ | Complexity Δ | |
|---|---|---|---|
| integration | `43.38% <17.78%> (-0.14%)` | `7.00 <0.00> (ø)` | |
| unittests | `65.80% <26.08%> (?)` | `12.00 <0.00> (?)` | |
Flags with carried forward coverage won't be shown. [Click here](https://docs.codecov.io/docs/carryforward-flags?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=The+Apache+Software+Foundation#carryforward-flags-in-the-pull-request-comment) to find out more.
| [Impacted Files](https://codecov.io/gh/apache/incubator-pinot/pull/6840?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=The+Apache+Software+Foundation) | Coverage Δ | Complexity Δ | |
|---|---|---|---|
| [...ache/pinot/controller/api/resources/Constants.java](https://codecov.io/gh/apache/incubator-pinot/pull/6840/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=The+Apache+Software+Foundation#diff-cGlub3QtY29udHJvbGxlci9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvcGlub3QvY29udHJvbGxlci9hcGkvcmVzb3VyY2VzL0NvbnN0YW50cy5qYXZh) | `21.42% <ø> (ø)` | `0.00 <0.00> (ø)` | |
| [...ller/api/resources/PinotConfigRestletResource.java](https://codecov.io/gh/apache/incubator-pinot/pull/6840/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=The+Apache+Software+Foundation#diff-cGlub3QtY29udHJvbGxlci9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvcGlub3QvY29udHJvbGxlci9hcGkvcmVzb3VyY2VzL1Bpbm90Q29uZmlnUmVzdGxldFJlc291cmNlLmphdmE=) | `0.00% <0.00%> (ø)` | `0.00 <0.00> (?)` | |
| [.../controller/helix/ControllerRequestURLBuilder.java](https://codecov.io/gh/apache/incubator-pinot/pull/6840/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=The+Apache+Software+Foundation#diff-cGlub3QtY29udHJvbGxlci9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvcGlub3QvY29udHJvbGxlci9oZWxpeC9Db250cm9sbGVyUmVxdWVzdFVSTEJ1aWxkZXIuamF2YQ==) | `64.16% <0.00%> (+48.37%)` | `0.00 <0.00> (ø)` | |
| [.../java/org/apache/pinot/spi/config/PinotConfig.java](https://codecov.io/gh/apache/incubator-pinot/pull/6840/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=The+Apache+Software+Foundation#diff-cGlub3Qtc3BpL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9waW5vdC9zcGkvY29uZmlnL1Bpbm90Q29uZmlnLmphdmE=) | `0.00% <0.00%> (ø)` | `0.00 <0.00> (?)` | |
| [...he/pinot/segment/local/utils/TableConfigUtils.java](https://codecov.io/gh/apache/incubator-pinot/pull/6840/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=The+Apache+Software+Foundation#diff-cGlub3Qtc2VnbWVudC1sb2NhbC9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvcGlub3Qvc2VnbWVudC9sb2NhbC91dGlscy9UYWJsZUNvbmZpZ1V0aWxzLmphdmE=) | `81.76% <68.42%> (+28.67%)` | `0.00 <0.00> (ø)` | |
| [...oller/api/resources/PinotTableRestletResource.java](https://codecov.io/gh/apache/incubator-pinot/pull/6840/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=The+Apache+Software+Foundation#diff-cGlub3QtY29udHJvbGxlci9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvcGlub3QvY29udHJvbGxlci9hcGkvcmVzb3VyY2VzL1Bpbm90VGFibGVSZXN0bGV0UmVzb3VyY2UuamF2YQ==) | `60.27% <90.47%> (+29.79%)` | `0.00 <0.00> (ø)` | |
| [...a/manager/realtime/RealtimeSegmentDataManager.java](https://codecov.io/gh/apache/incubator-pinot/pull/6840/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=The+Apache+Software+Foundation#diff-cGlub3QtY29yZS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvcGlub3QvY29yZS9kYXRhL21hbmFnZXIvcmVhbHRpbWUvUmVhbHRpbWVTZWdtZW50RGF0YU1hbmFnZXIuamF2YQ==) | `28.57% <0.00%> (-28.58%)` | `0.00% <0.00%> (ø%)` | |
| [...readers/constant/ConstantMVForwardIndexReader.java](https://codecov.io/gh/apache/incubator-pinot/pull/6840/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=The+Apache+Software+Foundation#diff-cGlub3Qtc2VnbWVudC1sb2NhbC9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvcGlub3Qvc2VnbWVudC9sb2NhbC9zZWdtZW50L2luZGV4L3JlYWRlcnMvY29uc3RhbnQvQ29uc3RhbnRNVkZvcndhcmRJbmRleFJlYWRlci5qYXZh) | `14.28% <0.00%> (-28.58%)` | `0.00% <0.00%> (ø%)` | |
| [...ot/segment/local/customobject/MinMaxRangePair.java](https://codecov.io/gh/apache/incubator-pinot/pull/6840/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=The+Apache+Software+Foundation#diff-cGlub3Qtc2VnbWVudC1sb2NhbC9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvcGlub3Qvc2VnbWVudC9sb2NhbC9jdXN0b21vYmplY3QvTWluTWF4UmFuZ2VQYWlyLmphdmE=) | `75.86% <0.00%> (-24.14%)` | `0.00% <0.00%> (ø%)` | |
| [...nction/DistinctCountBitmapAggregationFunction.java](https://codecov.io/gh/apache/incubator-pinot/pull/6840/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=The+Apache+Software+Foundation#diff-cGlub3QtY29yZS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvcGlub3QvY29yZS9xdWVyeS9hZ2dyZWdhdGlvbi9mdW5jdGlvbi9EaXN0aW5jdENvdW50Qml0bWFwQWdncmVnYXRpb25GdW5jdGlvbi5qYXZh) | `41.23% <0.00%> (-11.86%)` | `0.00% <0.00%> (ø%)` | |
| ... and [903 more](https://codecov.io/gh/apache/incubator-pinot/pull/6840/diff?src=pr&el=tree-more&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=The+Apache+Software+Foundation) | |
------
[Continue to review full report at Codecov](https://codecov.io/gh/apache/incubator-pinot/pull/6840?src=pr&el=continue&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=The+Apache+Software+Foundation).
> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=The+Apache+Software+Foundation)
> `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
> Powered by [Codecov](https://codecov.io/gh/apache/incubator-pinot/pull/6840?src=pr&el=footer&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=The+Apache+Software+Foundation). Last update [ac5aee7...089e2b3](https://codecov.io/gh/apache/incubator-pinot/pull/6840?src=pr&el=lastupdated&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=The+Apache+Software+Foundation). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=The+Apache+Software+Foundation).
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@pinot.apache.org
For additional commands, e-mail: commits-help@pinot.apache.org
[GitHub] [incubator-pinot] jackjlli commented on a change in pull request #6840: TableConfigs APIs
Posted by GitBox <gi...@apache.org>.
jackjlli commented on a change in pull request #6840:
URL: https://github.com/apache/incubator-pinot/pull/6840#discussion_r620490715
##########
File path: pinot-controller/src/main/java/org/apache/pinot/controller/api/resources/PinotTableRestletResource.java
##########
@@ -165,9 +146,13 @@ public SuccessResponse addTable(String tableConfigStr, @Context HttpHeaders http
throw new ControllerApplicationException(LOGGER, e.getMessage(), Response.Status.BAD_REQUEST, e);
}
try {
- ensureMinReplicas(tableConfig);
- ensureStorageQuotaConstraints(tableConfig);
- verifyTableConfigs(tableConfig);
+ try {
+ TableConfigUtils.ensureMinReplicas(tableConfig, _controllerConf.getDefaultTableMinReplicas());
+ TableConfigUtils.ensureStorageQuotaConstraints(tableConfig, _controllerConf.getDimTableMaxSize());
+ checkHybridTableConfig(TableNameBuilder.extractRawTableName(tableName), tableConfig);
+ } catch (Exception e) {
+ throw new PinotHelixResourceManager.InvalidTableConfigException(e);
Review comment:
Should we consider taking `InvalidTableConfigException` out of `PinotHelixResourceManager`?
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@pinot.apache.org
For additional commands, e-mail: commits-help@pinot.apache.org
[GitHub] [incubator-pinot] npawar commented on a change in pull request #6840: TableConfigs APIs
Posted by GitBox <gi...@apache.org>.
npawar commented on a change in pull request #6840:
URL: https://github.com/apache/incubator-pinot/pull/6840#discussion_r621773819
##########
File path: pinot-spi/src/main/java/org/apache/pinot/spi/config/TableConfigs.java
##########
@@ -0,0 +1,76 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.pinot.spi.config;
+
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.core.JsonProcessingException;
+import javax.annotation.Nullable;
+import org.apache.pinot.spi.config.table.TableConfig;
+import org.apache.pinot.spi.data.Schema;
+import org.apache.pinot.spi.utils.JsonUtils;
+
+
+/**
+ * Wrapper for all configs of a table, which include the offline table config, realtime table config and schema.
+ * This helps look at and operate on the pinot table configs as a whole unit.
+ */
+public class TableConfigs extends BaseJsonConfig {
+ private final String _tableName;
+ private final Schema _schema;
+ private final TableConfig _offline;
+ private final TableConfig _realtime;
+
+ @JsonCreator
+ public TableConfigs(@JsonProperty(value = "tableName", required = true) String tableName,
+ @JsonProperty(value = "schema", required = true) Schema schema,
+ @JsonProperty(value = "offline") @Nullable TableConfig offline,
+ @JsonProperty(value = "realtime") @Nullable TableConfig realtime) {
Review comment:
Added, but shouldn't `required = true` cover that?
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@pinot.apache.org
For additional commands, e-mail: commits-help@pinot.apache.org
[GitHub] [incubator-pinot] npawar commented on a change in pull request #6840: TableConfigs APIs
Posted by GitBox <gi...@apache.org>.
npawar commented on a change in pull request #6840:
URL: https://github.com/apache/incubator-pinot/pull/6840#discussion_r621587523
##########
File path: pinot-controller/src/main/java/org/apache/pinot/controller/api/resources/TableConfigsRestletResource.java
##########
@@ -0,0 +1,358 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.pinot.controller.api.resources;
+
+import com.fasterxml.jackson.databind.node.ArrayNode;
+import com.google.common.base.Preconditions;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import io.swagger.annotations.ApiParam;
+import java.io.IOException;
+import java.util.Collections;
+import java.util.List;
+import javax.inject.Inject;
+import javax.ws.rs.DELETE;
+import javax.ws.rs.DefaultValue;
+import javax.ws.rs.GET;
+import javax.ws.rs.POST;
+import javax.ws.rs.PUT;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.QueryParam;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.HttpHeaders;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+import org.apache.pinot.common.metrics.ControllerMeter;
+import org.apache.pinot.common.metrics.ControllerMetrics;
+import org.apache.pinot.controller.ControllerConf;
+import org.apache.pinot.controller.api.access.AccessControlFactory;
+import org.apache.pinot.controller.api.access.AccessControlUtils;
+import org.apache.pinot.controller.api.access.AccessType;
+import org.apache.pinot.controller.api.access.Authenticate;
+import org.apache.pinot.controller.helix.core.PinotHelixResourceManager;
+import org.apache.pinot.segment.local.utils.SchemaUtils;
+import org.apache.pinot.segment.local.utils.TableConfigUtils;
+import org.apache.pinot.spi.config.TableConfigs;
+import org.apache.pinot.spi.config.table.TableConfig;
+import org.apache.pinot.spi.data.Schema;
+import org.apache.pinot.spi.utils.JsonUtils;
+import org.apache.pinot.spi.utils.builder.TableNameBuilder;
+import org.glassfish.grizzly.http.server.Request;
+import org.slf4j.LoggerFactory;
+
+
+/**
+ * Endpoints for CRUD of {@link TableConfigs}.
+ * {@link TableConfigs} is a group of the offline table config, realtime table config and schema for the same tableName.
+ */
+@Api(tags = Constants.TABLE_TAG)
+@Path("/")
+public class TableConfigsRestletResource {
+
+ public static org.slf4j.Logger LOGGER = LoggerFactory.getLogger(TableConfigsRestletResource.class);
+
+ @Inject
+ PinotHelixResourceManager _pinotHelixResourceManager;
+
+ @Inject
+ ControllerConf _controllerConf;
+
+ @Inject
+ ControllerMetrics _controllerMetrics;
+
+ @Inject
+ AccessControlFactory _accessControlFactory;
+ AccessControlUtils _accessControlUtils = new AccessControlUtils();
+
+ /**
+ * List all {@link TableConfigs}, where each is a group of the offline table config, realtime table config and schema for the same tableName.
+ * This is equivalent to a list of all raw table names
+ */
+ @GET
+ @Produces(MediaType.APPLICATION_JSON)
+ @Path("/tableConfigs")
+ @Authenticate(AccessType.READ)
+ @ApiOperation(value = "Lists all TableConfigs in cluster", notes = "Lists all TableConfigs in cluster")
+ public String listConfigs() {
+ try {
+ List<String> rawTableNames = _pinotHelixResourceManager.getAllRawTables();
+ Collections.sort(rawTableNames);
+
+ ArrayNode configsList = JsonUtils.newArrayNode();
+ for (String rawTableName : rawTableNames) {
+ configsList.add(rawTableName);
+ }
+ return configsList.toString();
+ } catch (Exception e) {
+ throw new ControllerApplicationException(LOGGER, e.getMessage(), Response.Status.INTERNAL_SERVER_ERROR, e);
+ }
+ }
+
+ /**
+ * Gets the {@link TableConfigs} for the provided raw tableName, by fetching the offline table config for tableName_OFFLINE,
+ * realtime table config for tableName_REALTIME and schema for tableName
+ */
+ @GET
+ @Produces(MediaType.APPLICATION_JSON)
+ @Path("/tableConfigs/{tableName}")
+ @Authenticate(AccessType.READ)
+ @ApiOperation(value = "Get the TableConfigs for a given raw tableName", notes = "Get the TableConfigs for a given raw tableName")
+ public String getConfig(
+ @ApiParam(value = "Raw table name", required = true) @PathParam("tableName") String tableName) {
+
+ try {
+ Schema schema = _pinotHelixResourceManager.getSchema(tableName);
+ TableConfig offlineTableConfig = _pinotHelixResourceManager.getOfflineTableConfig(tableName);
+ TableConfig realtimeTableConfig = _pinotHelixResourceManager.getRealtimeTableConfig(tableName);
+ TableConfigs config = new TableConfigs(tableName, schema, offlineTableConfig, realtimeTableConfig);
+ return config.toPrettyJsonString();
+ } catch (Exception e) {
+ throw new ControllerApplicationException(LOGGER, e.getMessage(), Response.Status.INTERNAL_SERVER_ERROR, e);
+ }
+ }
+
+ /**
+ * Creates a {@link TableConfigs} using the <code>tableConfigsStr</code>, by creating the schema,
+ * followed by the realtime tableConfig and offline tableConfig as applicable, from the {@link TableConfigs}.
+ * Validates the configs before applying.
+ */
+ @POST
+ @Produces(MediaType.APPLICATION_JSON)
+ @Path("/tableConfigs")
+ @ApiOperation(value = "Add the TableConfigs using the tableConfigsStr json", notes = "Add the TableConfigs using the tableConfigsStr json")
+ public SuccessResponse addConfig(String tableConfigsStr, @Context HttpHeaders httpHeaders, @Context Request request) {
+ TableConfigs tableConfigs;
+ try {
+ tableConfigs = JsonUtils.stringToObject(tableConfigsStr, TableConfigs.class);
+ validateConfig(tableConfigs);
+ } catch (Exception e) {
+ throw new ControllerApplicationException(LOGGER, String.format("Invalid TableConfigs. %s", e.getMessage()),
+ Response.Status.BAD_REQUEST, e);
+ }
+
+ TableConfig offlineTableConfig = tableConfigs.getOffline();
+ TableConfig realtimeTableConfig = tableConfigs.getRealtime();
+ Schema schema = tableConfigs.getSchema();
+
+ try {
+ String endpointUrl = request.getRequestURL().toString();
+ validatePermissions(schema.getSchemaName(), AccessType.CREATE, httpHeaders, endpointUrl);
+
+ if (offlineTableConfig != null) {
+ tuneConfig(offlineTableConfig, schema);
+ validatePermissions(offlineTableConfig.getTableName(), AccessType.CREATE, httpHeaders, endpointUrl);
+ }
+ if (realtimeTableConfig != null) {
+ tuneConfig(realtimeTableConfig, schema);
+ validatePermissions(realtimeTableConfig.getTableName(), AccessType.CREATE, httpHeaders, endpointUrl);
+ }
+
+ _pinotHelixResourceManager.addSchema(schema, true);
+ LOGGER.info("Added schema: {}", schema.getSchemaName());
+ if (offlineTableConfig != null) {
+ _pinotHelixResourceManager.addTable(offlineTableConfig);
+ LOGGER.info("Added offline table config: {}", offlineTableConfig.getTableName());
+ }
+ if (realtimeTableConfig != null) {
+ _pinotHelixResourceManager.addTable(realtimeTableConfig);
+ LOGGER.info("Added realtime table config: {}", realtimeTableConfig.getTableName());
+ }
+
+ return new SuccessResponse("TableConfigs " + tableConfigs.getTableName() + " successfully added");
+ } catch (Exception e) {
+ _controllerMetrics.addMeteredGlobalValue(ControllerMeter.CONTROLLER_TABLE_ADD_ERROR, 1L);
+ if (e instanceof PinotHelixResourceManager.InvalidTableConfigException) {
+ throw new ControllerApplicationException(LOGGER,
+ String.format("Invalid TableConfigs: %s", tableConfigs.getTableName()), Response.Status.BAD_REQUEST, e);
+ } else if (e instanceof PinotHelixResourceManager.TableAlreadyExistsException) {
+ throw new ControllerApplicationException(LOGGER, e.getMessage(), Response.Status.CONFLICT, e);
+ } else {
+ throw new ControllerApplicationException(LOGGER, e.getMessage(), Response.Status.INTERNAL_SERVER_ERROR, e);
+ }
+ }
+ }
+
+ /**
+ * Deletes the {@link TableConfigs} by deleting the schema tableName, the offline table config for tableName_OFFLINE and
+ * the realtime table config for tableName_REALTIME
+ */
+ @DELETE
+ @Path("/tableConfigs/{tableName}")
+ @Authenticate(AccessType.DELETE)
+ @Produces(MediaType.APPLICATION_JSON)
+ @ApiOperation(value = "Delete the TableConfigs", notes = "Delete the TableConfigs")
+ public SuccessResponse deleteConfig(
+ @ApiParam(value = "TableConfigs name i.e. raw table name", required = true) @PathParam("tableName") String tableName) {
+
+ try {
+ _pinotHelixResourceManager.deleteRealtimeTable(tableName);
+ LOGGER.info("Deleted realtime table: {}", tableName);
+ _pinotHelixResourceManager.deleteOfflineTable(tableName);
+ LOGGER.info("Deleted offline table: {}", tableName);
+ Schema schema = _pinotHelixResourceManager.getSchema(tableName);
+ if (schema != null) {
+ _pinotHelixResourceManager.deleteSchema(schema);
+ }
+ LOGGER.info("Deleted schema: {}", tableName);
+ return new SuccessResponse("Deleted TableConfigs: " + tableName);
+ } catch (Exception e) {
+ throw new ControllerApplicationException(LOGGER, e.getMessage(), Response.Status.INTERNAL_SERVER_ERROR, e);
+ }
+ }
+
+ /**
+ * Updated the {@link TableConfigs} by updating the schema tableName,
+ * then updating the offline tableConfig or creating a new one if it doesn't already exist in the cluster,
+ * then updating the realtime tableConfig or creating a new one if it doesn't already exist in the cluster.
+ */
+ @PUT
+ @Path("/tableConfigs/{tableName}")
+ @Authenticate(AccessType.UPDATE)
+ @Produces(MediaType.APPLICATION_JSON)
+ @ApiOperation(value = "Update the TableConfigs provided by the tableConfigsStr json", notes = "Update the TableConfigs provided by the tableConfigsStr json")
+ public SuccessResponse updateConfig(
+ @ApiParam(value = "TableConfigs name i.e. raw table name", required = true) @PathParam("tableName") String tableName,
+ @ApiParam(value = "Reload the table if the new schema is backward compatible") @DefaultValue("false") @QueryParam("reload") boolean reload,
+ String tableConfigsStr)
+ throws Exception {
+ TableConfigs tableConfigs;
+ try {
+ tableConfigs = JsonUtils.stringToObject(tableConfigsStr, TableConfigs.class);
+ Preconditions.checkState(tableConfigs.getTableName().equals(tableName),
+ "'tableName' in TableConfigs: %s must match provided tableName: %s", tableConfigs.getTableName(), tableName);
+ validateConfig(tableConfigs);
+ } catch (Exception e) {
+ throw new ControllerApplicationException(LOGGER, String.format("Invalid TableConfigs: %s", tableName),
+ Response.Status.BAD_REQUEST, e);
+ }
+
+ TableConfig offlineTableConfig = tableConfigs.getOffline();
+ TableConfig realtimeTableConfig = tableConfigs.getRealtime();
+ Schema schema = tableConfigs.getSchema();
+
+ try {
Review comment:
Done, checking for existence of tables before allowing PUT
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@pinot.apache.org
For additional commands, e-mail: commits-help@pinot.apache.org
[GitHub] [incubator-pinot] Jackie-Jiang commented on a change in pull request #6840: TableConfigs APIs
Posted by GitBox <gi...@apache.org>.
Jackie-Jiang commented on a change in pull request #6840:
URL: https://github.com/apache/incubator-pinot/pull/6840#discussion_r621710765
##########
File path: pinot-segment-local/src/main/java/org/apache/pinot/segment/local/utils/TableConfigUtils.java
##########
@@ -580,4 +615,120 @@ private static IndexingConfig sanitizeIndexingConfig(IndexingConfig indexingConf
}
return null;
}
+
+ /**
+ * Apply TunerConfig to the tableConfig
+ */
+ public static void applyTunerConfig(TableConfig tableConfig, Schema schema) {
+ TunerConfig tunerConfig = tableConfig.getTunerConfig();
+ if (tunerConfig != null && tunerConfig.getName() != null && !tunerConfig.getName().isEmpty()) {
+ TableConfigTuner tuner = TableConfigTunerRegistry.getTuner(tunerConfig.getName());
+ tuner.init(tunerConfig, schema);
+ tuner.apply(tableConfig);
+ }
+ }
+
+ /**
+ * Ensure that the table config has the minimum number of replicas set as per cluster configs.
+ * If is doesn't, set the required amount of replication in the table config
+ */
+ public static void ensureMinReplicas(TableConfig tableConfig, int defaultTableMinReplicas) {
+ // For self-serviced cluster, ensure that the tables are created with at least min replication factor irrespective
+ // of table configuration value
+ SegmentsValidationAndRetentionConfig segmentsConfig = tableConfig.getValidationConfig();
+ boolean verifyReplicasPerPartition;
+ boolean verifyReplication;
+
+ try {
+ verifyReplicasPerPartition = ReplicationUtils.useReplicasPerPartition(tableConfig);
+ verifyReplication = ReplicationUtils.useReplication(tableConfig);
+ } catch (Exception e) {
+ throw new IllegalStateException(String.format("Invalid tableIndexConfig or streamConfig: %s", e.getMessage()), e);
+ }
+
+ if (verifyReplication) {
+ int requestReplication;
+ try {
+ requestReplication = segmentsConfig.getReplicationNumber();
+ if (requestReplication < defaultTableMinReplicas) {
+ LOGGER.info("Creating table with minimum replication factor of: {} instead of requested replication: {}",
+ defaultTableMinReplicas, requestReplication);
+ segmentsConfig.setReplication(String.valueOf(defaultTableMinReplicas));
+ }
+ } catch (NumberFormatException e) {
+ throw new IllegalStateException("Invalid replication number", e);
+ }
+ }
+
+ if (verifyReplicasPerPartition) {
+ String replicasPerPartitionStr = segmentsConfig.getReplicasPerPartition();
+ if (replicasPerPartitionStr == null) {
+ throw new IllegalStateException("Field replicasPerPartition needs to be specified");
+ }
+ try {
+ int replicasPerPartition = Integer.parseInt(replicasPerPartitionStr);
+ if (replicasPerPartition < defaultTableMinReplicas) {
+ LOGGER.info(
+ "Creating table with minimum replicasPerPartition of: {} instead of requested replicasPerPartition: {}",
+ defaultTableMinReplicas, replicasPerPartition);
+ segmentsConfig.setReplicasPerPartition(String.valueOf(defaultTableMinReplicas));
+ }
+ } catch (NumberFormatException e) {
+ throw new IllegalStateException("Invalid value for replicasPerPartition: '" + replicasPerPartitionStr + "'", e);
+ }
+ }
+ }
+
+ /**
+ * Ensure the table config has storage quota set as per cluster configs.
+ * If it doesn't, set the quota config into the table config
+ */
+ public static void ensureStorageQuotaConstraints(TableConfig tableConfig, String maxAllowedSize) {
+ // Dim tables must adhere to cluster level storage size limits
+ if (tableConfig.isDimTable()) {
+ QuotaConfig quotaConfig = tableConfig.getQuotaConfig();
+ long maxAllowedSizeInBytes = DataSizeUtils.toBytes(maxAllowedSize);
+
+ if (quotaConfig == null) {
+ // set a default storage quota
+ tableConfig.setQuotaConfig(new QuotaConfig(maxAllowedSize, null));
+ LOGGER.info("Assigning default storage quota ({}) for dimension table: {}", maxAllowedSize,
+ tableConfig.getTableName());
+ } else {
+ if (quotaConfig.getStorage() == null) {
+ // set a default storage quota and keep the RPS value
+ tableConfig.setQuotaConfig(new QuotaConfig(maxAllowedSize, quotaConfig.getMaxQueriesPerSecond()));
+ LOGGER.info("Assigning default storage quota ({}) for dimension table: {}", maxAllowedSize,
+ tableConfig.getTableName());
+ } else {
+ if (quotaConfig.getStorageInBytes() > maxAllowedSizeInBytes) {
+ throw new IllegalStateException(String
+ .format("Invalid storage quota: %d, max allowed size: %d", quotaConfig.getStorageInBytes(),
+ maxAllowedSizeInBytes));
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * Consistency checks across the offline and realtime counterparts of a hybrid table
+ */
+ public static void verifyHybridTableConfigs(String rawTableName, TableConfig offlineTableConfig,
+ TableConfig realtimeTableConfig) {
+ if (offlineTableConfig == null || realtimeTableConfig == null) {
+ return;
+ }
+
+ LOGGER.info("Validating realtime and offline configs for the hybrid table: {}", rawTableName);
+ SegmentsValidationAndRetentionConfig offlineSegmentConfig = offlineTableConfig.getValidationConfig();
+ SegmentsValidationAndRetentionConfig realtimeSegmentConfig = realtimeTableConfig.getValidationConfig();
+ String offlineTimeColumnName = offlineSegmentConfig.getTimeColumnName();
+ String realtimeTimeColumnName = realtimeSegmentConfig.getTimeColumnName();
+ if (!Objects.equal(realtimeTimeColumnName, offlineTimeColumnName)) {
Review comment:
Both of the time column name should not be `null` for hybrid table
##########
File path: pinot-spi/src/main/java/org/apache/pinot/spi/config/TableConfigs.java
##########
@@ -0,0 +1,76 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.pinot.spi.config;
+
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.core.JsonProcessingException;
+import javax.annotation.Nullable;
+import org.apache.pinot.spi.config.table.TableConfig;
+import org.apache.pinot.spi.data.Schema;
+import org.apache.pinot.spi.utils.JsonUtils;
+
+
+/**
+ * Wrapper for all configs of a table, which include the offline table config, realtime table config and schema.
+ * This helps look at and operate on the pinot table configs as a whole unit.
+ */
+public class TableConfigs extends BaseJsonConfig {
+ private final String _tableName;
+ private final Schema _schema;
+ private final TableConfig _offline;
+ private final TableConfig _realtime;
+
+ @JsonCreator
+ public TableConfigs(@JsonProperty(value = "tableName", required = true) String tableName,
+ @JsonProperty(value = "schema", required = true) Schema schema,
+ @JsonProperty(value = "offline") @Nullable TableConfig offline,
+ @JsonProperty(value = "realtime") @Nullable TableConfig realtime) {
Review comment:
Add some precondition check here to avoid setting `null` tableName or schema
##########
File path: pinot-segment-local/src/main/java/org/apache/pinot/segment/local/utils/TableConfigUtils.java
##########
@@ -580,4 +615,120 @@ private static IndexingConfig sanitizeIndexingConfig(IndexingConfig indexingConf
}
return null;
}
+
+ /**
+ * Apply TunerConfig to the tableConfig
+ */
+ public static void applyTunerConfig(TableConfig tableConfig, Schema schema) {
+ TunerConfig tunerConfig = tableConfig.getTunerConfig();
+ if (tunerConfig != null && tunerConfig.getName() != null && !tunerConfig.getName().isEmpty()) {
+ TableConfigTuner tuner = TableConfigTunerRegistry.getTuner(tunerConfig.getName());
+ tuner.init(tunerConfig, schema);
+ tuner.apply(tableConfig);
+ }
+ }
+
+ /**
+ * Ensure that the table config has the minimum number of replicas set as per cluster configs.
+ * If is doesn't, set the required amount of replication in the table config
+ */
+ public static void ensureMinReplicas(TableConfig tableConfig, int defaultTableMinReplicas) {
+ // For self-serviced cluster, ensure that the tables are created with at least min replication factor irrespective
+ // of table configuration value
+ SegmentsValidationAndRetentionConfig segmentsConfig = tableConfig.getValidationConfig();
+ boolean verifyReplicasPerPartition;
+ boolean verifyReplication;
+
+ try {
+ verifyReplicasPerPartition = ReplicationUtils.useReplicasPerPartition(tableConfig);
+ verifyReplication = ReplicationUtils.useReplication(tableConfig);
+ } catch (Exception e) {
+ throw new IllegalStateException(String.format("Invalid tableIndexConfig or streamConfig: %s", e.getMessage()), e);
+ }
+
+ if (verifyReplication) {
+ int requestReplication;
+ try {
+ requestReplication = segmentsConfig.getReplicationNumber();
+ if (requestReplication < defaultTableMinReplicas) {
+ LOGGER.info("Creating table with minimum replication factor of: {} instead of requested replication: {}",
+ defaultTableMinReplicas, requestReplication);
+ segmentsConfig.setReplication(String.valueOf(defaultTableMinReplicas));
+ }
+ } catch (NumberFormatException e) {
+ throw new IllegalStateException("Invalid replication number", e);
+ }
+ }
+
+ if (verifyReplicasPerPartition) {
+ String replicasPerPartitionStr = segmentsConfig.getReplicasPerPartition();
+ if (replicasPerPartitionStr == null) {
+ throw new IllegalStateException("Field replicasPerPartition needs to be specified");
+ }
+ try {
+ int replicasPerPartition = Integer.parseInt(replicasPerPartitionStr);
+ if (replicasPerPartition < defaultTableMinReplicas) {
+ LOGGER.info(
+ "Creating table with minimum replicasPerPartition of: {} instead of requested replicasPerPartition: {}",
+ defaultTableMinReplicas, replicasPerPartition);
+ segmentsConfig.setReplicasPerPartition(String.valueOf(defaultTableMinReplicas));
+ }
+ } catch (NumberFormatException e) {
+ throw new IllegalStateException("Invalid value for replicasPerPartition: '" + replicasPerPartitionStr + "'", e);
+ }
+ }
+ }
+
+ /**
+ * Ensure the table config has storage quota set as per cluster configs.
+ * If it doesn't, set the quota config into the table config
+ */
+ public static void ensureStorageQuotaConstraints(TableConfig tableConfig, String maxAllowedSize) {
+ // Dim tables must adhere to cluster level storage size limits
+ if (tableConfig.isDimTable()) {
+ QuotaConfig quotaConfig = tableConfig.getQuotaConfig();
+ long maxAllowedSizeInBytes = DataSizeUtils.toBytes(maxAllowedSize);
+
+ if (quotaConfig == null) {
+ // set a default storage quota
+ tableConfig.setQuotaConfig(new QuotaConfig(maxAllowedSize, null));
+ LOGGER.info("Assigning default storage quota ({}) for dimension table: {}", maxAllowedSize,
+ tableConfig.getTableName());
+ } else {
+ if (quotaConfig.getStorage() == null) {
+ // set a default storage quota and keep the RPS value
+ tableConfig.setQuotaConfig(new QuotaConfig(maxAllowedSize, quotaConfig.getMaxQueriesPerSecond()));
+ LOGGER.info("Assigning default storage quota ({}) for dimension table: {}", maxAllowedSize,
+ tableConfig.getTableName());
+ } else {
+ if (quotaConfig.getStorageInBytes() > maxAllowedSizeInBytes) {
+ throw new IllegalStateException(String
+ .format("Invalid storage quota: %d, max allowed size: %d", quotaConfig.getStorageInBytes(),
+ maxAllowedSizeInBytes));
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * Consistency checks across the offline and realtime counterparts of a hybrid table
+ */
+ public static void verifyHybridTableConfigs(String rawTableName, TableConfig offlineTableConfig,
+ TableConfig realtimeTableConfig) {
+ if (offlineTableConfig == null || realtimeTableConfig == null) {
+ return;
+ }
Review comment:
The passed in config should not be null. You can actually add a precondition on them not null to guard the case where the table config fetch failed in `PinotTableRestletResource.checkHybridTableConfig()`
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@pinot.apache.org
For additional commands, e-mail: commits-help@pinot.apache.org
[GitHub] [incubator-pinot] codecov-commenter edited a comment on pull request #6840: Configs APIs
Posted by GitBox <gi...@apache.org>.
codecov-commenter edited a comment on pull request #6840:
URL: https://github.com/apache/incubator-pinot/pull/6840#issuecomment-826221712
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@pinot.apache.org
For additional commands, e-mail: commits-help@pinot.apache.org
[GitHub] [incubator-pinot] codecov-commenter edited a comment on pull request #6840: TableConfigs APIs
Posted by GitBox <gi...@apache.org>.
codecov-commenter edited a comment on pull request #6840:
URL: https://github.com/apache/incubator-pinot/pull/6840#issuecomment-826221712
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@pinot.apache.org
For additional commands, e-mail: commits-help@pinot.apache.org
[GitHub] [incubator-pinot] npawar commented on a change in pull request #6840: TableConfigs APIs
Posted by GitBox <gi...@apache.org>.
npawar commented on a change in pull request #6840:
URL: https://github.com/apache/incubator-pinot/pull/6840#discussion_r621773819
##########
File path: pinot-spi/src/main/java/org/apache/pinot/spi/config/TableConfigs.java
##########
@@ -0,0 +1,76 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.pinot.spi.config;
+
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.core.JsonProcessingException;
+import javax.annotation.Nullable;
+import org.apache.pinot.spi.config.table.TableConfig;
+import org.apache.pinot.spi.data.Schema;
+import org.apache.pinot.spi.utils.JsonUtils;
+
+
+/**
+ * Wrapper for all configs of a table, which include the offline table config, realtime table config and schema.
+ * This helps look at and operate on the pinot table configs as a whole unit.
+ */
+public class TableConfigs extends BaseJsonConfig {
+ private final String _tableName;
+ private final Schema _schema;
+ private final TableConfig _offline;
+ private final TableConfig _realtime;
+
+ @JsonCreator
+ public TableConfigs(@JsonProperty(value = "tableName", required = true) String tableName,
+ @JsonProperty(value = "schema", required = true) Schema schema,
+ @JsonProperty(value = "offline") @Nullable TableConfig offline,
+ @JsonProperty(value = "realtime") @Nullable TableConfig realtime) {
Review comment:
Shouldn't `required = true` cover that?
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@pinot.apache.org
For additional commands, e-mail: commits-help@pinot.apache.org
[GitHub] [incubator-pinot] npawar commented on a change in pull request #6840: TableConfigs APIs
Posted by GitBox <gi...@apache.org>.
npawar commented on a change in pull request #6840:
URL: https://github.com/apache/incubator-pinot/pull/6840#discussion_r621475762
##########
File path: pinot-controller/src/main/java/org/apache/pinot/controller/api/resources/TableConfigsRestletResource.java
##########
@@ -0,0 +1,358 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.pinot.controller.api.resources;
+
+import com.fasterxml.jackson.databind.node.ArrayNode;
+import com.google.common.base.Preconditions;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import io.swagger.annotations.ApiParam;
+import java.io.IOException;
+import java.util.Collections;
+import java.util.List;
+import javax.inject.Inject;
+import javax.ws.rs.DELETE;
+import javax.ws.rs.DefaultValue;
+import javax.ws.rs.GET;
+import javax.ws.rs.POST;
+import javax.ws.rs.PUT;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.QueryParam;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.HttpHeaders;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+import org.apache.pinot.common.metrics.ControllerMeter;
+import org.apache.pinot.common.metrics.ControllerMetrics;
+import org.apache.pinot.controller.ControllerConf;
+import org.apache.pinot.controller.api.access.AccessControlFactory;
+import org.apache.pinot.controller.api.access.AccessControlUtils;
+import org.apache.pinot.controller.api.access.AccessType;
+import org.apache.pinot.controller.api.access.Authenticate;
+import org.apache.pinot.controller.helix.core.PinotHelixResourceManager;
+import org.apache.pinot.segment.local.utils.SchemaUtils;
+import org.apache.pinot.segment.local.utils.TableConfigUtils;
+import org.apache.pinot.spi.config.TableConfigs;
+import org.apache.pinot.spi.config.table.TableConfig;
+import org.apache.pinot.spi.data.Schema;
+import org.apache.pinot.spi.utils.JsonUtils;
+import org.apache.pinot.spi.utils.builder.TableNameBuilder;
+import org.glassfish.grizzly.http.server.Request;
+import org.slf4j.LoggerFactory;
+
+
+/**
+ * Endpoints for CRUD of {@link TableConfigs}.
+ * {@link TableConfigs} is a group of the offline table config, realtime table config and schema for the same tableName.
+ */
+@Api(tags = Constants.TABLE_TAG)
+@Path("/")
+public class TableConfigsRestletResource {
+
+ public static org.slf4j.Logger LOGGER = LoggerFactory.getLogger(TableConfigsRestletResource.class);
+
+ @Inject
+ PinotHelixResourceManager _pinotHelixResourceManager;
+
+ @Inject
+ ControllerConf _controllerConf;
+
+ @Inject
+ ControllerMetrics _controllerMetrics;
+
+ @Inject
+ AccessControlFactory _accessControlFactory;
+ AccessControlUtils _accessControlUtils = new AccessControlUtils();
+
+ /**
+ * List all {@link TableConfigs}, where each is a group of the offline table config, realtime table config and schema for the same tableName.
+ * This is equivalent to a list of all raw table names
+ */
+ @GET
+ @Produces(MediaType.APPLICATION_JSON)
+ @Path("/tableConfigs")
+ @Authenticate(AccessType.READ)
+ @ApiOperation(value = "Lists all TableConfigs in cluster", notes = "Lists all TableConfigs in cluster")
+ public String listConfigs() {
+ try {
+ List<String> rawTableNames = _pinotHelixResourceManager.getAllRawTables();
+ Collections.sort(rawTableNames);
+
+ ArrayNode configsList = JsonUtils.newArrayNode();
+ for (String rawTableName : rawTableNames) {
+ configsList.add(rawTableName);
+ }
+ return configsList.toString();
+ } catch (Exception e) {
+ throw new ControllerApplicationException(LOGGER, e.getMessage(), Response.Status.INTERNAL_SERVER_ERROR, e);
+ }
+ }
+
+ /**
+ * Gets the {@link TableConfigs} for the provided raw tableName, by fetching the offline table config for tableName_OFFLINE,
+ * realtime table config for tableName_REALTIME and schema for tableName
+ */
+ @GET
+ @Produces(MediaType.APPLICATION_JSON)
+ @Path("/tableConfigs/{tableName}")
+ @Authenticate(AccessType.READ)
+ @ApiOperation(value = "Get the TableConfigs for a given raw tableName", notes = "Get the TableConfigs for a given raw tableName")
+ public String getConfig(
+ @ApiParam(value = "Raw table name", required = true) @PathParam("tableName") String tableName) {
+
+ try {
+ Schema schema = _pinotHelixResourceManager.getSchema(tableName);
+ TableConfig offlineTableConfig = _pinotHelixResourceManager.getOfflineTableConfig(tableName);
+ TableConfig realtimeTableConfig = _pinotHelixResourceManager.getRealtimeTableConfig(tableName);
+ TableConfigs config = new TableConfigs(tableName, schema, offlineTableConfig, realtimeTableConfig);
+ return config.toPrettyJsonString();
+ } catch (Exception e) {
+ throw new ControllerApplicationException(LOGGER, e.getMessage(), Response.Status.INTERNAL_SERVER_ERROR, e);
+ }
+ }
+
+ /**
+ * Creates a {@link TableConfigs} using the <code>tableConfigsStr</code>, by creating the schema,
+ * followed by the realtime tableConfig and offline tableConfig as applicable, from the {@link TableConfigs}.
+ * Validates the configs before applying.
+ */
+ @POST
+ @Produces(MediaType.APPLICATION_JSON)
+ @Path("/tableConfigs")
+ @ApiOperation(value = "Add the TableConfigs using the tableConfigsStr json", notes = "Add the TableConfigs using the tableConfigsStr json")
+ public SuccessResponse addConfig(String tableConfigsStr, @Context HttpHeaders httpHeaders, @Context Request request) {
+ TableConfigs tableConfigs;
+ try {
+ tableConfigs = JsonUtils.stringToObject(tableConfigsStr, TableConfigs.class);
+ validateConfig(tableConfigs);
+ } catch (Exception e) {
+ throw new ControllerApplicationException(LOGGER, String.format("Invalid TableConfigs. %s", e.getMessage()),
+ Response.Status.BAD_REQUEST, e);
+ }
+
+ TableConfig offlineTableConfig = tableConfigs.getOffline();
+ TableConfig realtimeTableConfig = tableConfigs.getRealtime();
+ Schema schema = tableConfigs.getSchema();
+
+ try {
+ String endpointUrl = request.getRequestURL().toString();
+ validatePermissions(schema.getSchemaName(), AccessType.CREATE, httpHeaders, endpointUrl);
+
+ if (offlineTableConfig != null) {
+ tuneConfig(offlineTableConfig, schema);
+ validatePermissions(offlineTableConfig.getTableName(), AccessType.CREATE, httpHeaders, endpointUrl);
+ }
+ if (realtimeTableConfig != null) {
+ tuneConfig(realtimeTableConfig, schema);
+ validatePermissions(realtimeTableConfig.getTableName(), AccessType.CREATE, httpHeaders, endpointUrl);
+ }
+
+ _pinotHelixResourceManager.addSchema(schema, true);
+ LOGGER.info("Added schema: {}", schema.getSchemaName());
+ if (offlineTableConfig != null) {
+ _pinotHelixResourceManager.addTable(offlineTableConfig);
+ LOGGER.info("Added offline table config: {}", offlineTableConfig.getTableName());
+ }
+ if (realtimeTableConfig != null) {
+ _pinotHelixResourceManager.addTable(realtimeTableConfig);
+ LOGGER.info("Added realtime table config: {}", realtimeTableConfig.getTableName());
+ }
+
+ return new SuccessResponse("TableConfigs " + tableConfigs.getTableName() + " successfully added");
+ } catch (Exception e) {
+ _controllerMetrics.addMeteredGlobalValue(ControllerMeter.CONTROLLER_TABLE_ADD_ERROR, 1L);
+ if (e instanceof PinotHelixResourceManager.InvalidTableConfigException) {
+ throw new ControllerApplicationException(LOGGER,
+ String.format("Invalid TableConfigs: %s", tableConfigs.getTableName()), Response.Status.BAD_REQUEST, e);
+ } else if (e instanceof PinotHelixResourceManager.TableAlreadyExistsException) {
+ throw new ControllerApplicationException(LOGGER, e.getMessage(), Response.Status.CONFLICT, e);
+ } else {
+ throw new ControllerApplicationException(LOGGER, e.getMessage(), Response.Status.INTERNAL_SERVER_ERROR, e);
+ }
+ }
+ }
+
+ /**
+ * Deletes the {@link TableConfigs} by deleting the schema tableName, the offline table config for tableName_OFFLINE and
+ * the realtime table config for tableName_REALTIME
+ */
+ @DELETE
+ @Path("/tableConfigs/{tableName}")
+ @Authenticate(AccessType.DELETE)
+ @Produces(MediaType.APPLICATION_JSON)
+ @ApiOperation(value = "Delete the TableConfigs", notes = "Delete the TableConfigs")
+ public SuccessResponse deleteConfig(
+ @ApiParam(value = "TableConfigs name i.e. raw table name", required = true) @PathParam("tableName") String tableName) {
+
+ try {
Review comment:
I am trying to keep it similar to the PinotTableRestletResource, where we call delete whether or not the table exists. I'm guessing it's because delete has multiple steps underneath and we won't know if table got deleted completely by checking `pinotHelixResourceManager.hasOfflineTable(tableName)`.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@pinot.apache.org
For additional commands, e-mail: commits-help@pinot.apache.org
[GitHub] [incubator-pinot] codecov-commenter edited a comment on pull request #6840: TableConfigs APIs
Posted by GitBox <gi...@apache.org>.
codecov-commenter edited a comment on pull request #6840:
URL: https://github.com/apache/incubator-pinot/pull/6840#issuecomment-826221712
# [Codecov](https://codecov.io/gh/apache/incubator-pinot/pull/6840?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=The+Apache+Software+Foundation) Report
> Merging [#6840](https://codecov.io/gh/apache/incubator-pinot/pull/6840?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=The+Apache+Software+Foundation) (f72ec5e) into [master](https://codecov.io/gh/apache/incubator-pinot/commit/ac5aee70bf25aa4680a115434066287e3456ae71?el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=The+Apache+Software+Foundation) (ac5aee7) will **increase** coverage by `30.31%`.
> The diff coverage is `28.06%`.
[](https://codecov.io/gh/apache/incubator-pinot/pull/6840?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=The+Apache+Software+Foundation)
```diff
@@ Coverage Diff @@
## master #6840 +/- ##
=============================================
+ Coverage 43.52% 73.83% +30.31%
- Complexity 7 12 +5
=============================================
Files 1421 1422 +1
Lines 69142 69288 +146
Branches 9987 9999 +12
=============================================
+ Hits 30093 51162 +21069
+ Misses 36504 14776 -21728
- Partials 2545 3350 +805
```
| Flag | Coverage Δ | Complexity Δ | |
|---|---|---|---|
| integration | `43.49% <17.78%> (-0.03%)` | `7.00 <0.00> (ø)` | |
| unittests | `65.78% <26.08%> (?)` | `12.00 <0.00> (?)` | |
Flags with carried forward coverage won't be shown. [Click here](https://docs.codecov.io/docs/carryforward-flags?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=The+Apache+Software+Foundation#carryforward-flags-in-the-pull-request-comment) to find out more.
| [Impacted Files](https://codecov.io/gh/apache/incubator-pinot/pull/6840?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=The+Apache+Software+Foundation) | Coverage Δ | Complexity Δ | |
|---|---|---|---|
| [...ler/api/resources/TableConfigsRestletResource.java](https://codecov.io/gh/apache/incubator-pinot/pull/6840/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=The+Apache+Software+Foundation#diff-cGlub3QtY29udHJvbGxlci9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvcGlub3QvY29udHJvbGxlci9hcGkvcmVzb3VyY2VzL1RhYmxlQ29uZmlnc1Jlc3RsZXRSZXNvdXJjZS5qYXZh) | `0.00% <0.00%> (ø)` | `0.00 <0.00> (?)` | |
| [.../controller/helix/ControllerRequestURLBuilder.java](https://codecov.io/gh/apache/incubator-pinot/pull/6840/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=The+Apache+Software+Foundation#diff-cGlub3QtY29udHJvbGxlci9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvcGlub3QvY29udHJvbGxlci9oZWxpeC9Db250cm9sbGVyUmVxdWVzdFVSTEJ1aWxkZXIuamF2YQ==) | `64.16% <0.00%> (+48.37%)` | `0.00 <0.00> (ø)` | |
| [...java/org/apache/pinot/spi/config/TableConfigs.java](https://codecov.io/gh/apache/incubator-pinot/pull/6840/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=The+Apache+Software+Foundation#diff-cGlub3Qtc3BpL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9waW5vdC9zcGkvY29uZmlnL1RhYmxlQ29uZmlncy5qYXZh) | `0.00% <0.00%> (ø)` | `0.00 <0.00> (?)` | |
| [...he/pinot/segment/local/utils/TableConfigUtils.java](https://codecov.io/gh/apache/incubator-pinot/pull/6840/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=The+Apache+Software+Foundation#diff-cGlub3Qtc2VnbWVudC1sb2NhbC9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvcGlub3Qvc2VnbWVudC9sb2NhbC91dGlscy9UYWJsZUNvbmZpZ1V0aWxzLmphdmE=) | `81.76% <68.42%> (+28.67%)` | `0.00 <0.00> (ø)` | |
| [...oller/api/resources/PinotTableRestletResource.java](https://codecov.io/gh/apache/incubator-pinot/pull/6840/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=The+Apache+Software+Foundation#diff-cGlub3QtY29udHJvbGxlci9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvcGlub3QvY29udHJvbGxlci9hcGkvcmVzb3VyY2VzL1Bpbm90VGFibGVSZXN0bGV0UmVzb3VyY2UuamF2YQ==) | `60.27% <90.47%> (+29.79%)` | `0.00 <0.00> (ø)` | |
| [...a/manager/realtime/RealtimeSegmentDataManager.java](https://codecov.io/gh/apache/incubator-pinot/pull/6840/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=The+Apache+Software+Foundation#diff-cGlub3QtY29yZS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvcGlub3QvY29yZS9kYXRhL21hbmFnZXIvcmVhbHRpbWUvUmVhbHRpbWVTZWdtZW50RGF0YU1hbmFnZXIuamF2YQ==) | `28.57% <0.00%> (-28.58%)` | `0.00% <0.00%> (ø%)` | |
| [...ot/segment/local/customobject/MinMaxRangePair.java](https://codecov.io/gh/apache/incubator-pinot/pull/6840/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=The+Apache+Software+Foundation#diff-cGlub3Qtc2VnbWVudC1sb2NhbC9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvcGlub3Qvc2VnbWVudC9sb2NhbC9jdXN0b21vYmplY3QvTWluTWF4UmFuZ2VQYWlyLmphdmE=) | `75.86% <0.00%> (-24.14%)` | `0.00% <0.00%> (ø%)` | |
| [...nction/DistinctCountBitmapAggregationFunction.java](https://codecov.io/gh/apache/incubator-pinot/pull/6840/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=The+Apache+Software+Foundation#diff-cGlub3QtY29yZS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvcGlub3QvY29yZS9xdWVyeS9hZ2dyZWdhdGlvbi9mdW5jdGlvbi9EaXN0aW5jdENvdW50Qml0bWFwQWdncmVnYXRpb25GdW5jdGlvbi5qYXZh) | `46.90% <0.00%> (-6.19%)` | `0.00% <0.00%> (ø%)` | |
| [.../impl/dictionary/LongOffHeapMutableDictionary.java](https://codecov.io/gh/apache/incubator-pinot/pull/6840/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=The+Apache+Software+Foundation#diff-cGlub3Qtc2VnbWVudC1sb2NhbC9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvcGlub3Qvc2VnbWVudC9sb2NhbC9yZWFsdGltZS9pbXBsL2RpY3Rpb25hcnkvTG9uZ09mZkhlYXBNdXRhYmxlRGljdGlvbmFyeS5qYXZh) | `70.21% <0.00%> (-2.13%)` | `0.00% <0.00%> (ø%)` | |
| [...ion/groupby/AggregationGroupByTrimmingService.java](https://codecov.io/gh/apache/incubator-pinot/pull/6840/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=The+Apache+Software+Foundation#diff-cGlub3QtY29yZS9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvcGlub3QvY29yZS9xdWVyeS9hZ2dyZWdhdGlvbi9ncm91cGJ5L0FnZ3JlZ2F0aW9uR3JvdXBCeVRyaW1taW5nU2VydmljZS5qYXZh) | `94.20% <0.00%> (-1.45%)` | `0.00% <0.00%> (ø%)` | |
| ... and [899 more](https://codecov.io/gh/apache/incubator-pinot/pull/6840/diff?src=pr&el=tree-more&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=The+Apache+Software+Foundation) | |
------
[Continue to review full report at Codecov](https://codecov.io/gh/apache/incubator-pinot/pull/6840?src=pr&el=continue&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=The+Apache+Software+Foundation).
> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=The+Apache+Software+Foundation)
> `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
> Powered by [Codecov](https://codecov.io/gh/apache/incubator-pinot/pull/6840?src=pr&el=footer&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=The+Apache+Software+Foundation). Last update [ac5aee7...f72ec5e](https://codecov.io/gh/apache/incubator-pinot/pull/6840?src=pr&el=lastupdated&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=The+Apache+Software+Foundation). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=The+Apache+Software+Foundation).
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@pinot.apache.org
For additional commands, e-mail: commits-help@pinot.apache.org
[GitHub] [incubator-pinot] npawar commented on a change in pull request #6840: Configs APIs
Posted by GitBox <gi...@apache.org>.
npawar commented on a change in pull request #6840:
URL: https://github.com/apache/incubator-pinot/pull/6840#discussion_r619922070
##########
File path: pinot-controller/src/main/java/org/apache/pinot/controller/api/resources/Constants.java
##########
@@ -30,6 +30,7 @@
public static final String CLUSTER_TAG = "Cluster";
public static final String TABLE_TAG = "Table";
+ public static final String CONFIG_TAG = "Config";
Review comment:
Done.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@pinot.apache.org
For additional commands, e-mail: commits-help@pinot.apache.org
[GitHub] [incubator-pinot] codecov-commenter edited a comment on pull request #6840: TableConfigs APIs
Posted by GitBox <gi...@apache.org>.
codecov-commenter edited a comment on pull request #6840:
URL: https://github.com/apache/incubator-pinot/pull/6840#issuecomment-826221712
# [Codecov](https://codecov.io/gh/apache/incubator-pinot/pull/6840?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=The+Apache+Software+Foundation) Report
> Merging [#6840](https://codecov.io/gh/apache/incubator-pinot/pull/6840?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=The+Apache+Software+Foundation) (fd4a969) into [master](https://codecov.io/gh/apache/incubator-pinot/commit/ac5aee70bf25aa4680a115434066287e3456ae71?el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=The+Apache+Software+Foundation) (ac5aee7) will **increase** coverage by `30.08%`.
> The diff coverage is `26.89%`.
[](https://codecov.io/gh/apache/incubator-pinot/pull/6840?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=The+Apache+Software+Foundation)
```diff
@@ Coverage Diff @@
## master #6840 +/- ##
=============================================
+ Coverage 43.52% 73.60% +30.08%
- Complexity 7 12 +5
=============================================
Files 1421 1427 +6
Lines 69142 69850 +708
Branches 9987 10107 +120
=============================================
+ Hits 30093 51416 +21323
+ Misses 36504 15039 -21465
- Partials 2545 3395 +850
```
| Flag | Coverage Δ | Complexity Δ | |
|---|---|---|---|
| integration | `43.27% <13.79%> (-0.25%)` | `7.00 <0.00> (ø)` | |
| unittests | `65.64% <25.17%> (?)` | `12.00 <0.00> (?)` | |
Flags with carried forward coverage won't be shown. [Click here](https://docs.codecov.io/docs/carryforward-flags?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=The+Apache+Software+Foundation#carryforward-flags-in-the-pull-request-comment) to find out more.
| [Impacted Files](https://codecov.io/gh/apache/incubator-pinot/pull/6840?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=The+Apache+Software+Foundation) | Coverage Δ | Complexity Δ | |
|---|---|---|---|
| [...inot/controller/api/access/AccessControlUtils.java](https://codecov.io/gh/apache/incubator-pinot/pull/6840/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=The+Apache+Software+Foundation#diff-cGlub3QtY29udHJvbGxlci9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvcGlub3QvY29udHJvbGxlci9hcGkvYWNjZXNzL0FjY2Vzc0NvbnRyb2xVdGlscy5qYXZh) | `80.00% <ø> (ø)` | `0.00 <0.00> (ø)` | |
| [.../api/exception/ControllerApplicationException.java](https://codecov.io/gh/apache/incubator-pinot/pull/6840/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=The+Apache+Software+Foundation#diff-cGlub3QtY29udHJvbGxlci9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvcGlub3QvY29udHJvbGxlci9hcGkvZXhjZXB0aW9uL0NvbnRyb2xsZXJBcHBsaWNhdGlvbkV4Y2VwdGlvbi5qYXZh) | `66.66% <ø> (ø)` | `0.00 <0.00> (?)` | |
| [...ller/api/resources/PinotBrokerRestletResource.java](https://codecov.io/gh/apache/incubator-pinot/pull/6840/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=The+Apache+Software+Foundation#diff-cGlub3QtY29udHJvbGxlci9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvcGlub3QvY29udHJvbGxlci9hcGkvcmVzb3VyY2VzL1Bpbm90QnJva2VyUmVzdGxldFJlc291cmNlLmphdmE=) | `60.97% <ø> (+60.97%)` | `0.00 <0.00> (ø)` | |
| [.../controller/api/resources/PinotClusterConfigs.java](https://codecov.io/gh/apache/incubator-pinot/pull/6840/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=The+Apache+Software+Foundation#diff-cGlub3QtY29udHJvbGxlci9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvcGlub3QvY29udHJvbGxlci9hcGkvcmVzb3VyY2VzL1Bpbm90Q2x1c3RlckNvbmZpZ3MuamF2YQ==) | `34.21% <ø> (+34.21%)` | `0.00 <0.00> (ø)` | |
| [...r/api/resources/PinotIngestionRestletResource.java](https://codecov.io/gh/apache/incubator-pinot/pull/6840/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=The+Apache+Software+Foundation#diff-cGlub3QtY29udHJvbGxlci9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvcGlub3QvY29udHJvbGxlci9hcGkvcmVzb3VyY2VzL1Bpbm90SW5nZXN0aW9uUmVzdGxldFJlc291cmNlLmphdmE=) | `0.00% <ø> (ø)` | `0.00 <0.00> (ø)` | |
| [...ources/PinotInstanceAssignmentRestletResource.java](https://codecov.io/gh/apache/incubator-pinot/pull/6840/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=The+Apache+Software+Foundation#diff-cGlub3QtY29udHJvbGxlci9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvcGlub3QvY29udHJvbGxlci9hcGkvcmVzb3VyY2VzL1Bpbm90SW5zdGFuY2VBc3NpZ25tZW50UmVzdGxldFJlc291cmNlLmphdmE=) | `73.22% <ø> (+73.22%)` | `0.00 <0.00> (ø)` | |
| [...er/api/resources/PinotInstanceRestletResource.java](https://codecov.io/gh/apache/incubator-pinot/pull/6840/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=The+Apache+Software+Foundation#diff-cGlub3QtY29udHJvbGxlci9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvcGlub3QvY29udHJvbGxlci9hcGkvcmVzb3VyY2VzL1Bpbm90SW5zdGFuY2VSZXN0bGV0UmVzb3VyY2UuamF2YQ==) | `58.22% <ø> (+40.50%)` | `0.00 <0.00> (ø)` | |
| [.../resources/PinotLeadControllerRestletResource.java](https://codecov.io/gh/apache/incubator-pinot/pull/6840/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=The+Apache+Software+Foundation#diff-cGlub3QtY29udHJvbGxlci9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvcGlub3QvY29udHJvbGxlci9hcGkvcmVzb3VyY2VzL1Bpbm90TGVhZENvbnRyb2xsZXJSZXN0bGV0UmVzb3VyY2UuamF2YQ==) | `0.00% <ø> (ø)` | `0.00 <0.00> (ø)` | |
| [...ller/api/resources/PinotSchemaRestletResource.java](https://codecov.io/gh/apache/incubator-pinot/pull/6840/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=The+Apache+Software+Foundation#diff-cGlub3QtY29udHJvbGxlci9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvcGlub3QvY29udHJvbGxlci9hcGkvcmVzb3VyY2VzL1Bpbm90U2NoZW1hUmVzdGxldFJlc291cmNlLmphdmE=) | `38.39% <ø> (+19.64%)` | `0.00 <0.00> (ø)` | |
| [...ler/api/resources/PinotSegmentRestletResource.java](https://codecov.io/gh/apache/incubator-pinot/pull/6840/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=The+Apache+Software+Foundation#diff-cGlub3QtY29udHJvbGxlci9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvcGlub3QvY29udHJvbGxlci9hcGkvcmVzb3VyY2VzL1Bpbm90U2VnbWVudFJlc3RsZXRSZXNvdXJjZS5qYXZh) | `18.42% <ø> (+1.57%)` | `0.00 <0.00> (ø)` | |
| ... and [948 more](https://codecov.io/gh/apache/incubator-pinot/pull/6840/diff?src=pr&el=tree-more&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=The+Apache+Software+Foundation) | |
------
[Continue to review full report at Codecov](https://codecov.io/gh/apache/incubator-pinot/pull/6840?src=pr&el=continue&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=The+Apache+Software+Foundation).
> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=The+Apache+Software+Foundation)
> `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
> Powered by [Codecov](https://codecov.io/gh/apache/incubator-pinot/pull/6840?src=pr&el=footer&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=The+Apache+Software+Foundation). Last update [ac5aee7...fd4a969](https://codecov.io/gh/apache/incubator-pinot/pull/6840?src=pr&el=lastupdated&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=The+Apache+Software+Foundation). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=The+Apache+Software+Foundation).
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@pinot.apache.org
For additional commands, e-mail: commits-help@pinot.apache.org
[GitHub] [incubator-pinot] codecov-commenter edited a comment on pull request #6840: TableConfigs APIs
Posted by GitBox <gi...@apache.org>.
codecov-commenter edited a comment on pull request #6840:
URL: https://github.com/apache/incubator-pinot/pull/6840#issuecomment-826221712
# [Codecov](https://codecov.io/gh/apache/incubator-pinot/pull/6840?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=The+Apache+Software+Foundation) Report
> Merging [#6840](https://codecov.io/gh/apache/incubator-pinot/pull/6840?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=The+Apache+Software+Foundation) (f72ec5e) into [master](https://codecov.io/gh/apache/incubator-pinot/commit/ac5aee70bf25aa4680a115434066287e3456ae71?el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=The+Apache+Software+Foundation) (ac5aee7) will **increase** coverage by `22.26%`.
> The diff coverage is `26.08%`.
[](https://codecov.io/gh/apache/incubator-pinot/pull/6840?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=The+Apache+Software+Foundation)
```diff
@@ Coverage Diff @@
## master #6840 +/- ##
=============================================
+ Coverage 43.52% 65.78% +22.26%
- Complexity 7 12 +5
=============================================
Files 1421 1422 +1
Lines 69142 69288 +146
Branches 9987 9999 +12
=============================================
+ Hits 30093 45584 +15491
+ Misses 36504 20461 -16043
- Partials 2545 3243 +698
```
| Flag | Coverage Δ | Complexity Δ | |
|---|---|---|---|
| integration | `?` | `?` | |
| unittests | `65.78% <26.08%> (?)` | `12.00 <0.00> (?)` | |
Flags with carried forward coverage won't be shown. [Click here](https://docs.codecov.io/docs/carryforward-flags?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=The+Apache+Software+Foundation#carryforward-flags-in-the-pull-request-comment) to find out more.
| [Impacted Files](https://codecov.io/gh/apache/incubator-pinot/pull/6840?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=The+Apache+Software+Foundation) | Coverage Δ | Complexity Δ | |
|---|---|---|---|
| [...ler/api/resources/TableConfigsRestletResource.java](https://codecov.io/gh/apache/incubator-pinot/pull/6840/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=The+Apache+Software+Foundation#diff-cGlub3QtY29udHJvbGxlci9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvcGlub3QvY29udHJvbGxlci9hcGkvcmVzb3VyY2VzL1RhYmxlQ29uZmlnc1Jlc3RsZXRSZXNvdXJjZS5qYXZh) | `0.00% <0.00%> (ø)` | `0.00 <0.00> (?)` | |
| [.../controller/helix/ControllerRequestURLBuilder.java](https://codecov.io/gh/apache/incubator-pinot/pull/6840/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=The+Apache+Software+Foundation#diff-cGlub3QtY29udHJvbGxlci9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvcGlub3QvY29udHJvbGxlci9oZWxpeC9Db250cm9sbGVyUmVxdWVzdFVSTEJ1aWxkZXIuamF2YQ==) | `59.16% <0.00%> (+43.37%)` | `0.00 <0.00> (ø)` | |
| [...java/org/apache/pinot/spi/config/TableConfigs.java](https://codecov.io/gh/apache/incubator-pinot/pull/6840/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=The+Apache+Software+Foundation#diff-cGlub3Qtc3BpL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9waW5vdC9zcGkvY29uZmlnL1RhYmxlQ29uZmlncy5qYXZh) | `0.00% <0.00%> (ø)` | `0.00 <0.00> (?)` | |
| [...he/pinot/segment/local/utils/TableConfigUtils.java](https://codecov.io/gh/apache/incubator-pinot/pull/6840/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=The+Apache+Software+Foundation#diff-cGlub3Qtc2VnbWVudC1sb2NhbC9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvcGlub3Qvc2VnbWVudC9sb2NhbC91dGlscy9UYWJsZUNvbmZpZ1V0aWxzLmphdmE=) | `78.34% <61.84%> (+25.25%)` | `0.00 <0.00> (ø)` | |
| [...oller/api/resources/PinotTableRestletResource.java](https://codecov.io/gh/apache/incubator-pinot/pull/6840/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=The+Apache+Software+Foundation#diff-cGlub3QtY29udHJvbGxlci9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvcGlub3QvY29udHJvbGxlci9hcGkvcmVzb3VyY2VzL1Bpbm90VGFibGVSZXN0bGV0UmVzb3VyY2UuamF2YQ==) | `58.44% <90.47%> (+27.96%)` | `0.00 <0.00> (ø)` | |
| [...a/org/apache/pinot/minion/metrics/MinionMeter.java](https://codecov.io/gh/apache/incubator-pinot/pull/6840/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=The+Apache+Software+Foundation#diff-cGlub3QtbWluaW9uL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9waW5vdC9taW5pb24vbWV0cmljcy9NaW5pb25NZXRlci5qYXZh) | `0.00% <0.00%> (-100.00%)` | `0.00% <0.00%> (ø%)` | |
| [.../apache/pinot/common/metrics/BrokerQueryPhase.java](https://codecov.io/gh/apache/incubator-pinot/pull/6840/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=The+Apache+Software+Foundation#diff-cGlub3QtY29tbW9uL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9waW5vdC9jb21tb24vbWV0cmljcy9Ccm9rZXJRdWVyeVBoYXNlLmphdmE=) | `0.00% <0.00%> (-100.00%)` | `0.00% <0.00%> (ø%)` | |
| [.../apache/pinot/minion/metrics/MinionQueryPhase.java](https://codecov.io/gh/apache/incubator-pinot/pull/6840/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=The+Apache+Software+Foundation#diff-cGlub3QtbWluaW9uL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9waW5vdC9taW5pb24vbWV0cmljcy9NaW5pb25RdWVyeVBoYXNlLmphdmE=) | `0.00% <0.00%> (-100.00%)` | `0.00% <0.00%> (ø%)` | |
| [...pache/pinot/common/utils/grpc/GrpcQueryClient.java](https://codecov.io/gh/apache/incubator-pinot/pull/6840/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=The+Apache+Software+Foundation#diff-cGlub3QtY29tbW9uL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9waW5vdC9jb21tb24vdXRpbHMvZ3JwYy9HcnBjUXVlcnlDbGllbnQuamF2YQ==) | `0.00% <0.00%> (-100.00%)` | `0.00% <0.00%> (ø%)` | |
| [...pinot/minion/exception/TaskCancelledException.java](https://codecov.io/gh/apache/incubator-pinot/pull/6840/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=The+Apache+Software+Foundation#diff-cGlub3QtbWluaW9uL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9waW5vdC9taW5pb24vZXhjZXB0aW9uL1Rhc2tDYW5jZWxsZWRFeGNlcHRpb24uamF2YQ==) | `0.00% <0.00%> (-100.00%)` | `0.00% <0.00%> (ø%)` | |
| ... and [1073 more](https://codecov.io/gh/apache/incubator-pinot/pull/6840/diff?src=pr&el=tree-more&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=The+Apache+Software+Foundation) | |
------
[Continue to review full report at Codecov](https://codecov.io/gh/apache/incubator-pinot/pull/6840?src=pr&el=continue&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=The+Apache+Software+Foundation).
> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=The+Apache+Software+Foundation)
> `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
> Powered by [Codecov](https://codecov.io/gh/apache/incubator-pinot/pull/6840?src=pr&el=footer&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=The+Apache+Software+Foundation). Last update [ac5aee7...f72ec5e](https://codecov.io/gh/apache/incubator-pinot/pull/6840?src=pr&el=lastupdated&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=The+Apache+Software+Foundation). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=The+Apache+Software+Foundation).
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@pinot.apache.org
For additional commands, e-mail: commits-help@pinot.apache.org
[GitHub] [incubator-pinot] Jackie-Jiang commented on a change in pull request #6840: TableConfigs APIs
Posted by GitBox <gi...@apache.org>.
Jackie-Jiang commented on a change in pull request #6840:
URL: https://github.com/apache/incubator-pinot/pull/6840#discussion_r620748224
##########
File path: pinot-spi/src/main/java/org/apache/pinot/spi/config/TableConfigs.java
##########
@@ -0,0 +1,76 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.pinot.spi.config;
+
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.core.JsonProcessingException;
+import javax.annotation.Nullable;
+import org.apache.pinot.spi.config.table.TableConfig;
+import org.apache.pinot.spi.data.Schema;
+import org.apache.pinot.spi.utils.JsonUtils;
+
+
+/**
+ * Wrapper for all configs of a table, which include the offline table config, realtime table config and schema.
+ * This helps look at and operate on the pinot table configs as a whole unit.
+ */
+public class TableConfigs extends BaseJsonConfig {
+ private final String _tableName;
+ private final Schema _schema;
+ private final TableConfig _offline;
+ private final TableConfig _realtime;
+
+ @JsonCreator
+ public TableConfigs(@JsonProperty(value = "tableName", required = true) String tableName,
+ @JsonProperty(value = "schema", required = true) Schema schema,
+ @JsonProperty(value = "offline") @Nullable TableConfig offline,
+ @JsonProperty(value = "realtime") @Nullable TableConfig realtime) {
+ _tableName = tableName;
+ _offline = offline;
+ _realtime = realtime;
+ _schema = schema;
Review comment:
(ocd) move this after `_tableName`
##########
File path: pinot-controller/src/main/java/org/apache/pinot/controller/api/resources/PinotTableRestletResource.java
##########
@@ -425,12 +414,14 @@ public String checkTableConfig(String tableConfigStr) {
return validateConfig(tableConfig, _pinotHelixResourceManager.getSchemaForTableConfig(tableConfig));
}
+ @Deprecated
@POST
@Path("/tables/validateTableAndSchema")
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
@ApiOperation(value = "Validate table config for a table along with specified schema", notes =
- "Validate given table config and schema. If specified schema is null, attempt to retrieve schema using the "
+ "Deprecated. Use /configs/validate instead."
Review comment:
Update the api path
##########
File path: pinot-controller/src/main/java/org/apache/pinot/controller/api/resources/TableConfigsRestletResource.java
##########
@@ -0,0 +1,358 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.pinot.controller.api.resources;
+
+import com.fasterxml.jackson.databind.node.ArrayNode;
+import com.google.common.base.Preconditions;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import io.swagger.annotations.ApiParam;
+import java.io.IOException;
+import java.util.Collections;
+import java.util.List;
+import javax.inject.Inject;
+import javax.ws.rs.DELETE;
+import javax.ws.rs.DefaultValue;
+import javax.ws.rs.GET;
+import javax.ws.rs.POST;
+import javax.ws.rs.PUT;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.QueryParam;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.HttpHeaders;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+import org.apache.pinot.common.metrics.ControllerMeter;
+import org.apache.pinot.common.metrics.ControllerMetrics;
+import org.apache.pinot.controller.ControllerConf;
+import org.apache.pinot.controller.api.access.AccessControlFactory;
+import org.apache.pinot.controller.api.access.AccessControlUtils;
+import org.apache.pinot.controller.api.access.AccessType;
+import org.apache.pinot.controller.api.access.Authenticate;
+import org.apache.pinot.controller.helix.core.PinotHelixResourceManager;
+import org.apache.pinot.segment.local.utils.SchemaUtils;
+import org.apache.pinot.segment.local.utils.TableConfigUtils;
+import org.apache.pinot.spi.config.TableConfigs;
+import org.apache.pinot.spi.config.table.TableConfig;
+import org.apache.pinot.spi.data.Schema;
+import org.apache.pinot.spi.utils.JsonUtils;
+import org.apache.pinot.spi.utils.builder.TableNameBuilder;
+import org.glassfish.grizzly.http.server.Request;
+import org.slf4j.LoggerFactory;
+
+
+/**
+ * Endpoints for CRUD of {@link TableConfigs}.
+ * {@link TableConfigs} is a group of the offline table config, realtime table config and schema for the same tableName.
+ */
+@Api(tags = Constants.TABLE_TAG)
+@Path("/")
+public class TableConfigsRestletResource {
+
+ public static org.slf4j.Logger LOGGER = LoggerFactory.getLogger(TableConfigsRestletResource.class);
+
+ @Inject
+ PinotHelixResourceManager _pinotHelixResourceManager;
+
+ @Inject
+ ControllerConf _controllerConf;
+
+ @Inject
+ ControllerMetrics _controllerMetrics;
+
+ @Inject
+ AccessControlFactory _accessControlFactory;
+ AccessControlUtils _accessControlUtils = new AccessControlUtils();
+
+ /**
+ * List all {@link TableConfigs}, where each is a group of the offline table config, realtime table config and schema for the same tableName.
+ * This is equivalent to a list of all raw table names
+ */
+ @GET
+ @Produces(MediaType.APPLICATION_JSON)
+ @Path("/tableConfigs")
+ @Authenticate(AccessType.READ)
+ @ApiOperation(value = "Lists all TableConfigs in cluster", notes = "Lists all TableConfigs in cluster")
+ public String listConfigs() {
+ try {
+ List<String> rawTableNames = _pinotHelixResourceManager.getAllRawTables();
+ Collections.sort(rawTableNames);
+
+ ArrayNode configsList = JsonUtils.newArrayNode();
+ for (String rawTableName : rawTableNames) {
+ configsList.add(rawTableName);
+ }
+ return configsList.toString();
+ } catch (Exception e) {
+ throw new ControllerApplicationException(LOGGER, e.getMessage(), Response.Status.INTERNAL_SERVER_ERROR, e);
+ }
+ }
+
+ /**
+ * Gets the {@link TableConfigs} for the provided raw tableName, by fetching the offline table config for tableName_OFFLINE,
+ * realtime table config for tableName_REALTIME and schema for tableName
+ */
+ @GET
+ @Produces(MediaType.APPLICATION_JSON)
+ @Path("/tableConfigs/{tableName}")
+ @Authenticate(AccessType.READ)
+ @ApiOperation(value = "Get the TableConfigs for a given raw tableName", notes = "Get the TableConfigs for a given raw tableName")
+ public String getConfig(
+ @ApiParam(value = "Raw table name", required = true) @PathParam("tableName") String tableName) {
+
+ try {
+ Schema schema = _pinotHelixResourceManager.getSchema(tableName);
+ TableConfig offlineTableConfig = _pinotHelixResourceManager.getOfflineTableConfig(tableName);
+ TableConfig realtimeTableConfig = _pinotHelixResourceManager.getRealtimeTableConfig(tableName);
+ TableConfigs config = new TableConfigs(tableName, schema, offlineTableConfig, realtimeTableConfig);
+ return config.toPrettyJsonString();
Review comment:
We don't usually return pretty string for rest API, use `toJsonString()` instead
##########
File path: pinot-controller/src/main/java/org/apache/pinot/controller/api/resources/TableConfigsRestletResource.java
##########
@@ -0,0 +1,358 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.pinot.controller.api.resources;
+
+import com.fasterxml.jackson.databind.node.ArrayNode;
+import com.google.common.base.Preconditions;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import io.swagger.annotations.ApiParam;
+import java.io.IOException;
+import java.util.Collections;
+import java.util.List;
+import javax.inject.Inject;
+import javax.ws.rs.DELETE;
+import javax.ws.rs.DefaultValue;
+import javax.ws.rs.GET;
+import javax.ws.rs.POST;
+import javax.ws.rs.PUT;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.QueryParam;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.HttpHeaders;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+import org.apache.pinot.common.metrics.ControllerMeter;
+import org.apache.pinot.common.metrics.ControllerMetrics;
+import org.apache.pinot.controller.ControllerConf;
+import org.apache.pinot.controller.api.access.AccessControlFactory;
+import org.apache.pinot.controller.api.access.AccessControlUtils;
+import org.apache.pinot.controller.api.access.AccessType;
+import org.apache.pinot.controller.api.access.Authenticate;
+import org.apache.pinot.controller.helix.core.PinotHelixResourceManager;
+import org.apache.pinot.segment.local.utils.SchemaUtils;
+import org.apache.pinot.segment.local.utils.TableConfigUtils;
+import org.apache.pinot.spi.config.TableConfigs;
+import org.apache.pinot.spi.config.table.TableConfig;
+import org.apache.pinot.spi.data.Schema;
+import org.apache.pinot.spi.utils.JsonUtils;
+import org.apache.pinot.spi.utils.builder.TableNameBuilder;
+import org.glassfish.grizzly.http.server.Request;
+import org.slf4j.LoggerFactory;
+
+
+/**
+ * Endpoints for CRUD of {@link TableConfigs}.
+ * {@link TableConfigs} is a group of the offline table config, realtime table config and schema for the same tableName.
+ */
+@Api(tags = Constants.TABLE_TAG)
+@Path("/")
+public class TableConfigsRestletResource {
+
+ public static org.slf4j.Logger LOGGER = LoggerFactory.getLogger(TableConfigsRestletResource.class);
+
+ @Inject
+ PinotHelixResourceManager _pinotHelixResourceManager;
+
+ @Inject
+ ControllerConf _controllerConf;
+
+ @Inject
+ ControllerMetrics _controllerMetrics;
+
+ @Inject
+ AccessControlFactory _accessControlFactory;
+ AccessControlUtils _accessControlUtils = new AccessControlUtils();
+
+ /**
+ * List all {@link TableConfigs}, where each is a group of the offline table config, realtime table config and schema for the same tableName.
+ * This is equivalent to a list of all raw table names
+ */
+ @GET
+ @Produces(MediaType.APPLICATION_JSON)
+ @Path("/tableConfigs")
+ @Authenticate(AccessType.READ)
+ @ApiOperation(value = "Lists all TableConfigs in cluster", notes = "Lists all TableConfigs in cluster")
+ public String listConfigs() {
+ try {
+ List<String> rawTableNames = _pinotHelixResourceManager.getAllRawTables();
+ Collections.sort(rawTableNames);
+
+ ArrayNode configsList = JsonUtils.newArrayNode();
+ for (String rawTableName : rawTableNames) {
+ configsList.add(rawTableName);
+ }
+ return configsList.toString();
+ } catch (Exception e) {
+ throw new ControllerApplicationException(LOGGER, e.getMessage(), Response.Status.INTERNAL_SERVER_ERROR, e);
+ }
+ }
+
+ /**
+ * Gets the {@link TableConfigs} for the provided raw tableName, by fetching the offline table config for tableName_OFFLINE,
+ * realtime table config for tableName_REALTIME and schema for tableName
+ */
+ @GET
+ @Produces(MediaType.APPLICATION_JSON)
+ @Path("/tableConfigs/{tableName}")
+ @Authenticate(AccessType.READ)
+ @ApiOperation(value = "Get the TableConfigs for a given raw tableName", notes = "Get the TableConfigs for a given raw tableName")
+ public String getConfig(
+ @ApiParam(value = "Raw table name", required = true) @PathParam("tableName") String tableName) {
+
+ try {
+ Schema schema = _pinotHelixResourceManager.getSchema(tableName);
+ TableConfig offlineTableConfig = _pinotHelixResourceManager.getOfflineTableConfig(tableName);
+ TableConfig realtimeTableConfig = _pinotHelixResourceManager.getRealtimeTableConfig(tableName);
+ TableConfigs config = new TableConfigs(tableName, schema, offlineTableConfig, realtimeTableConfig);
+ return config.toPrettyJsonString();
+ } catch (Exception e) {
+ throw new ControllerApplicationException(LOGGER, e.getMessage(), Response.Status.INTERNAL_SERVER_ERROR, e);
+ }
+ }
+
+ /**
+ * Creates a {@link TableConfigs} using the <code>tableConfigsStr</code>, by creating the schema,
+ * followed by the realtime tableConfig and offline tableConfig as applicable, from the {@link TableConfigs}.
+ * Validates the configs before applying.
+ */
+ @POST
+ @Produces(MediaType.APPLICATION_JSON)
+ @Path("/tableConfigs")
+ @ApiOperation(value = "Add the TableConfigs using the tableConfigsStr json", notes = "Add the TableConfigs using the tableConfigsStr json")
+ public SuccessResponse addConfig(String tableConfigsStr, @Context HttpHeaders httpHeaders, @Context Request request) {
+ TableConfigs tableConfigs;
+ try {
+ tableConfigs = JsonUtils.stringToObject(tableConfigsStr, TableConfigs.class);
+ validateConfig(tableConfigs);
+ } catch (Exception e) {
+ throw new ControllerApplicationException(LOGGER, String.format("Invalid TableConfigs. %s", e.getMessage()),
+ Response.Status.BAD_REQUEST, e);
+ }
+
+ TableConfig offlineTableConfig = tableConfigs.getOffline();
+ TableConfig realtimeTableConfig = tableConfigs.getRealtime();
+ Schema schema = tableConfigs.getSchema();
+
+ try {
+ String endpointUrl = request.getRequestURL().toString();
+ validatePermissions(schema.getSchemaName(), AccessType.CREATE, httpHeaders, endpointUrl);
Review comment:
(nit) No need to wrap this one line call into a function, `AccessControl` can be reused here
```suggestion
AccessControl accessControl = _accessControlFactory.create();
_accessControlUtils
.validatePermission(schema.getSchemaName(), AccessType.CREATE, httpHeaders, endpointUrl, accessControl);
...
```
##########
File path: pinot-controller/src/main/java/org/apache/pinot/controller/api/resources/TableConfigsRestletResource.java
##########
@@ -0,0 +1,358 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.pinot.controller.api.resources;
+
+import com.fasterxml.jackson.databind.node.ArrayNode;
+import com.google.common.base.Preconditions;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import io.swagger.annotations.ApiParam;
+import java.io.IOException;
+import java.util.Collections;
+import java.util.List;
+import javax.inject.Inject;
+import javax.ws.rs.DELETE;
+import javax.ws.rs.DefaultValue;
+import javax.ws.rs.GET;
+import javax.ws.rs.POST;
+import javax.ws.rs.PUT;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.QueryParam;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.HttpHeaders;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+import org.apache.pinot.common.metrics.ControllerMeter;
+import org.apache.pinot.common.metrics.ControllerMetrics;
+import org.apache.pinot.controller.ControllerConf;
+import org.apache.pinot.controller.api.access.AccessControlFactory;
+import org.apache.pinot.controller.api.access.AccessControlUtils;
+import org.apache.pinot.controller.api.access.AccessType;
+import org.apache.pinot.controller.api.access.Authenticate;
+import org.apache.pinot.controller.helix.core.PinotHelixResourceManager;
+import org.apache.pinot.segment.local.utils.SchemaUtils;
+import org.apache.pinot.segment.local.utils.TableConfigUtils;
+import org.apache.pinot.spi.config.TableConfigs;
+import org.apache.pinot.spi.config.table.TableConfig;
+import org.apache.pinot.spi.data.Schema;
+import org.apache.pinot.spi.utils.JsonUtils;
+import org.apache.pinot.spi.utils.builder.TableNameBuilder;
+import org.glassfish.grizzly.http.server.Request;
+import org.slf4j.LoggerFactory;
+
+
+/**
+ * Endpoints for CRUD of {@link TableConfigs}.
+ * {@link TableConfigs} is a group of the offline table config, realtime table config and schema for the same tableName.
+ */
+@Api(tags = Constants.TABLE_TAG)
+@Path("/")
+public class TableConfigsRestletResource {
+
+ public static org.slf4j.Logger LOGGER = LoggerFactory.getLogger(TableConfigsRestletResource.class);
+
+ @Inject
+ PinotHelixResourceManager _pinotHelixResourceManager;
+
+ @Inject
+ ControllerConf _controllerConf;
+
+ @Inject
+ ControllerMetrics _controllerMetrics;
+
+ @Inject
+ AccessControlFactory _accessControlFactory;
+ AccessControlUtils _accessControlUtils = new AccessControlUtils();
+
+ /**
+ * List all {@link TableConfigs}, where each is a group of the offline table config, realtime table config and schema for the same tableName.
+ * This is equivalent to a list of all raw table names
+ */
+ @GET
+ @Produces(MediaType.APPLICATION_JSON)
+ @Path("/tableConfigs")
+ @Authenticate(AccessType.READ)
+ @ApiOperation(value = "Lists all TableConfigs in cluster", notes = "Lists all TableConfigs in cluster")
+ public String listConfigs() {
+ try {
+ List<String> rawTableNames = _pinotHelixResourceManager.getAllRawTables();
+ Collections.sort(rawTableNames);
+
+ ArrayNode configsList = JsonUtils.newArrayNode();
+ for (String rawTableName : rawTableNames) {
+ configsList.add(rawTableName);
+ }
+ return configsList.toString();
+ } catch (Exception e) {
+ throw new ControllerApplicationException(LOGGER, e.getMessage(), Response.Status.INTERNAL_SERVER_ERROR, e);
+ }
+ }
+
+ /**
+ * Gets the {@link TableConfigs} for the provided raw tableName, by fetching the offline table config for tableName_OFFLINE,
+ * realtime table config for tableName_REALTIME and schema for tableName
+ */
+ @GET
+ @Produces(MediaType.APPLICATION_JSON)
+ @Path("/tableConfigs/{tableName}")
+ @Authenticate(AccessType.READ)
+ @ApiOperation(value = "Get the TableConfigs for a given raw tableName", notes = "Get the TableConfigs for a given raw tableName")
+ public String getConfig(
+ @ApiParam(value = "Raw table name", required = true) @PathParam("tableName") String tableName) {
+
+ try {
+ Schema schema = _pinotHelixResourceManager.getSchema(tableName);
+ TableConfig offlineTableConfig = _pinotHelixResourceManager.getOfflineTableConfig(tableName);
+ TableConfig realtimeTableConfig = _pinotHelixResourceManager.getRealtimeTableConfig(tableName);
+ TableConfigs config = new TableConfigs(tableName, schema, offlineTableConfig, realtimeTableConfig);
+ return config.toPrettyJsonString();
+ } catch (Exception e) {
+ throw new ControllerApplicationException(LOGGER, e.getMessage(), Response.Status.INTERNAL_SERVER_ERROR, e);
+ }
+ }
+
+ /**
+ * Creates a {@link TableConfigs} using the <code>tableConfigsStr</code>, by creating the schema,
+ * followed by the realtime tableConfig and offline tableConfig as applicable, from the {@link TableConfigs}.
+ * Validates the configs before applying.
+ */
+ @POST
+ @Produces(MediaType.APPLICATION_JSON)
+ @Path("/tableConfigs")
+ @ApiOperation(value = "Add the TableConfigs using the tableConfigsStr json", notes = "Add the TableConfigs using the tableConfigsStr json")
+ public SuccessResponse addConfig(String tableConfigsStr, @Context HttpHeaders httpHeaders, @Context Request request) {
+ TableConfigs tableConfigs;
+ try {
+ tableConfigs = JsonUtils.stringToObject(tableConfigsStr, TableConfigs.class);
+ validateConfig(tableConfigs);
+ } catch (Exception e) {
+ throw new ControllerApplicationException(LOGGER, String.format("Invalid TableConfigs. %s", e.getMessage()),
+ Response.Status.BAD_REQUEST, e);
+ }
+
+ TableConfig offlineTableConfig = tableConfigs.getOffline();
+ TableConfig realtimeTableConfig = tableConfigs.getRealtime();
+ Schema schema = tableConfigs.getSchema();
+
+ try {
+ String endpointUrl = request.getRequestURL().toString();
+ validatePermissions(schema.getSchemaName(), AccessType.CREATE, httpHeaders, endpointUrl);
+
+ if (offlineTableConfig != null) {
+ tuneConfig(offlineTableConfig, schema);
+ validatePermissions(offlineTableConfig.getTableName(), AccessType.CREATE, httpHeaders, endpointUrl);
+ }
+ if (realtimeTableConfig != null) {
+ tuneConfig(realtimeTableConfig, schema);
+ validatePermissions(realtimeTableConfig.getTableName(), AccessType.CREATE, httpHeaders, endpointUrl);
+ }
+
+ _pinotHelixResourceManager.addSchema(schema, true);
+ LOGGER.info("Added schema: {}", schema.getSchemaName());
+ if (offlineTableConfig != null) {
+ _pinotHelixResourceManager.addTable(offlineTableConfig);
+ LOGGER.info("Added offline table config: {}", offlineTableConfig.getTableName());
+ }
+ if (realtimeTableConfig != null) {
+ _pinotHelixResourceManager.addTable(realtimeTableConfig);
+ LOGGER.info("Added realtime table config: {}", realtimeTableConfig.getTableName());
+ }
+
+ return new SuccessResponse("TableConfigs " + tableConfigs.getTableName() + " successfully added");
+ } catch (Exception e) {
+ _controllerMetrics.addMeteredGlobalValue(ControllerMeter.CONTROLLER_TABLE_ADD_ERROR, 1L);
+ if (e instanceof PinotHelixResourceManager.InvalidTableConfigException) {
+ throw new ControllerApplicationException(LOGGER,
+ String.format("Invalid TableConfigs: %s", tableConfigs.getTableName()), Response.Status.BAD_REQUEST, e);
+ } else if (e instanceof PinotHelixResourceManager.TableAlreadyExistsException) {
+ throw new ControllerApplicationException(LOGGER, e.getMessage(), Response.Status.CONFLICT, e);
+ } else {
+ throw new ControllerApplicationException(LOGGER, e.getMessage(), Response.Status.INTERNAL_SERVER_ERROR, e);
+ }
+ }
+ }
+
+ /**
+ * Deletes the {@link TableConfigs} by deleting the schema tableName, the offline table config for tableName_OFFLINE and
+ * the realtime table config for tableName_REALTIME
+ */
+ @DELETE
+ @Path("/tableConfigs/{tableName}")
+ @Authenticate(AccessType.DELETE)
+ @Produces(MediaType.APPLICATION_JSON)
+ @ApiOperation(value = "Delete the TableConfigs", notes = "Delete the TableConfigs")
+ public SuccessResponse deleteConfig(
+ @ApiParam(value = "TableConfigs name i.e. raw table name", required = true) @PathParam("tableName") String tableName) {
+
+ try {
Review comment:
Check table existence before deletion
##########
File path: pinot-controller/src/main/java/org/apache/pinot/controller/api/resources/TableConfigsRestletResource.java
##########
@@ -0,0 +1,358 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.pinot.controller.api.resources;
+
+import com.fasterxml.jackson.databind.node.ArrayNode;
+import com.google.common.base.Preconditions;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import io.swagger.annotations.ApiParam;
+import java.io.IOException;
+import java.util.Collections;
+import java.util.List;
+import javax.inject.Inject;
+import javax.ws.rs.DELETE;
+import javax.ws.rs.DefaultValue;
+import javax.ws.rs.GET;
+import javax.ws.rs.POST;
+import javax.ws.rs.PUT;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.QueryParam;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.HttpHeaders;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+import org.apache.pinot.common.metrics.ControllerMeter;
+import org.apache.pinot.common.metrics.ControllerMetrics;
+import org.apache.pinot.controller.ControllerConf;
+import org.apache.pinot.controller.api.access.AccessControlFactory;
+import org.apache.pinot.controller.api.access.AccessControlUtils;
+import org.apache.pinot.controller.api.access.AccessType;
+import org.apache.pinot.controller.api.access.Authenticate;
+import org.apache.pinot.controller.helix.core.PinotHelixResourceManager;
+import org.apache.pinot.segment.local.utils.SchemaUtils;
+import org.apache.pinot.segment.local.utils.TableConfigUtils;
+import org.apache.pinot.spi.config.TableConfigs;
+import org.apache.pinot.spi.config.table.TableConfig;
+import org.apache.pinot.spi.data.Schema;
+import org.apache.pinot.spi.utils.JsonUtils;
+import org.apache.pinot.spi.utils.builder.TableNameBuilder;
+import org.glassfish.grizzly.http.server.Request;
+import org.slf4j.LoggerFactory;
+
+
+/**
+ * Endpoints for CRUD of {@link TableConfigs}.
+ * {@link TableConfigs} is a group of the offline table config, realtime table config and schema for the same tableName.
+ */
+@Api(tags = Constants.TABLE_TAG)
+@Path("/")
+public class TableConfigsRestletResource {
+
+ public static org.slf4j.Logger LOGGER = LoggerFactory.getLogger(TableConfigsRestletResource.class);
+
+ @Inject
+ PinotHelixResourceManager _pinotHelixResourceManager;
+
+ @Inject
+ ControllerConf _controllerConf;
+
+ @Inject
+ ControllerMetrics _controllerMetrics;
+
+ @Inject
+ AccessControlFactory _accessControlFactory;
+ AccessControlUtils _accessControlUtils = new AccessControlUtils();
+
+ /**
+ * List all {@link TableConfigs}, where each is a group of the offline table config, realtime table config and schema for the same tableName.
+ * This is equivalent to a list of all raw table names
+ */
+ @GET
+ @Produces(MediaType.APPLICATION_JSON)
+ @Path("/tableConfigs")
+ @Authenticate(AccessType.READ)
+ @ApiOperation(value = "Lists all TableConfigs in cluster", notes = "Lists all TableConfigs in cluster")
+ public String listConfigs() {
+ try {
+ List<String> rawTableNames = _pinotHelixResourceManager.getAllRawTables();
+ Collections.sort(rawTableNames);
+
+ ArrayNode configsList = JsonUtils.newArrayNode();
+ for (String rawTableName : rawTableNames) {
+ configsList.add(rawTableName);
+ }
+ return configsList.toString();
+ } catch (Exception e) {
+ throw new ControllerApplicationException(LOGGER, e.getMessage(), Response.Status.INTERNAL_SERVER_ERROR, e);
+ }
+ }
+
+ /**
+ * Gets the {@link TableConfigs} for the provided raw tableName, by fetching the offline table config for tableName_OFFLINE,
+ * realtime table config for tableName_REALTIME and schema for tableName
+ */
+ @GET
+ @Produces(MediaType.APPLICATION_JSON)
+ @Path("/tableConfigs/{tableName}")
+ @Authenticate(AccessType.READ)
+ @ApiOperation(value = "Get the TableConfigs for a given raw tableName", notes = "Get the TableConfigs for a given raw tableName")
+ public String getConfig(
+ @ApiParam(value = "Raw table name", required = true) @PathParam("tableName") String tableName) {
+
+ try {
+ Schema schema = _pinotHelixResourceManager.getSchema(tableName);
+ TableConfig offlineTableConfig = _pinotHelixResourceManager.getOfflineTableConfig(tableName);
+ TableConfig realtimeTableConfig = _pinotHelixResourceManager.getRealtimeTableConfig(tableName);
+ TableConfigs config = new TableConfigs(tableName, schema, offlineTableConfig, realtimeTableConfig);
+ return config.toPrettyJsonString();
+ } catch (Exception e) {
+ throw new ControllerApplicationException(LOGGER, e.getMessage(), Response.Status.INTERNAL_SERVER_ERROR, e);
+ }
+ }
+
+ /**
+ * Creates a {@link TableConfigs} using the <code>tableConfigsStr</code>, by creating the schema,
+ * followed by the realtime tableConfig and offline tableConfig as applicable, from the {@link TableConfigs}.
+ * Validates the configs before applying.
+ */
+ @POST
+ @Produces(MediaType.APPLICATION_JSON)
+ @Path("/tableConfigs")
+ @ApiOperation(value = "Add the TableConfigs using the tableConfigsStr json", notes = "Add the TableConfigs using the tableConfigsStr json")
+ public SuccessResponse addConfig(String tableConfigsStr, @Context HttpHeaders httpHeaders, @Context Request request) {
+ TableConfigs tableConfigs;
+ try {
+ tableConfigs = JsonUtils.stringToObject(tableConfigsStr, TableConfigs.class);
+ validateConfig(tableConfigs);
+ } catch (Exception e) {
+ throw new ControllerApplicationException(LOGGER, String.format("Invalid TableConfigs. %s", e.getMessage()),
+ Response.Status.BAD_REQUEST, e);
+ }
+
+ TableConfig offlineTableConfig = tableConfigs.getOffline();
+ TableConfig realtimeTableConfig = tableConfigs.getRealtime();
+ Schema schema = tableConfigs.getSchema();
+
+ try {
+ String endpointUrl = request.getRequestURL().toString();
+ validatePermissions(schema.getSchemaName(), AccessType.CREATE, httpHeaders, endpointUrl);
+
+ if (offlineTableConfig != null) {
+ tuneConfig(offlineTableConfig, schema);
+ validatePermissions(offlineTableConfig.getTableName(), AccessType.CREATE, httpHeaders, endpointUrl);
+ }
+ if (realtimeTableConfig != null) {
+ tuneConfig(realtimeTableConfig, schema);
+ validatePermissions(realtimeTableConfig.getTableName(), AccessType.CREATE, httpHeaders, endpointUrl);
+ }
+
+ _pinotHelixResourceManager.addSchema(schema, true);
+ LOGGER.info("Added schema: {}", schema.getSchemaName());
+ if (offlineTableConfig != null) {
+ _pinotHelixResourceManager.addTable(offlineTableConfig);
+ LOGGER.info("Added offline table config: {}", offlineTableConfig.getTableName());
+ }
+ if (realtimeTableConfig != null) {
+ _pinotHelixResourceManager.addTable(realtimeTableConfig);
+ LOGGER.info("Added realtime table config: {}", realtimeTableConfig.getTableName());
+ }
+
+ return new SuccessResponse("TableConfigs " + tableConfigs.getTableName() + " successfully added");
+ } catch (Exception e) {
+ _controllerMetrics.addMeteredGlobalValue(ControllerMeter.CONTROLLER_TABLE_ADD_ERROR, 1L);
+ if (e instanceof PinotHelixResourceManager.InvalidTableConfigException) {
+ throw new ControllerApplicationException(LOGGER,
+ String.format("Invalid TableConfigs: %s", tableConfigs.getTableName()), Response.Status.BAD_REQUEST, e);
+ } else if (e instanceof PinotHelixResourceManager.TableAlreadyExistsException) {
+ throw new ControllerApplicationException(LOGGER, e.getMessage(), Response.Status.CONFLICT, e);
+ } else {
+ throw new ControllerApplicationException(LOGGER, e.getMessage(), Response.Status.INTERNAL_SERVER_ERROR, e);
+ }
+ }
+ }
+
+ /**
+ * Deletes the {@link TableConfigs} by deleting the schema tableName, the offline table config for tableName_OFFLINE and
+ * the realtime table config for tableName_REALTIME
+ */
+ @DELETE
+ @Path("/tableConfigs/{tableName}")
+ @Authenticate(AccessType.DELETE)
+ @Produces(MediaType.APPLICATION_JSON)
+ @ApiOperation(value = "Delete the TableConfigs", notes = "Delete the TableConfigs")
+ public SuccessResponse deleteConfig(
+ @ApiParam(value = "TableConfigs name i.e. raw table name", required = true) @PathParam("tableName") String tableName) {
+
+ try {
+ _pinotHelixResourceManager.deleteRealtimeTable(tableName);
+ LOGGER.info("Deleted realtime table: {}", tableName);
+ _pinotHelixResourceManager.deleteOfflineTable(tableName);
+ LOGGER.info("Deleted offline table: {}", tableName);
+ Schema schema = _pinotHelixResourceManager.getSchema(tableName);
+ if (schema != null) {
+ _pinotHelixResourceManager.deleteSchema(schema);
+ }
+ LOGGER.info("Deleted schema: {}", tableName);
+ return new SuccessResponse("Deleted TableConfigs: " + tableName);
+ } catch (Exception e) {
+ throw new ControllerApplicationException(LOGGER, e.getMessage(), Response.Status.INTERNAL_SERVER_ERROR, e);
+ }
+ }
+
+ /**
+ * Updated the {@link TableConfigs} by updating the schema tableName,
+ * then updating the offline tableConfig or creating a new one if it doesn't already exist in the cluster,
+ * then updating the realtime tableConfig or creating a new one if it doesn't already exist in the cluster.
+ */
+ @PUT
+ @Path("/tableConfigs/{tableName}")
+ @Authenticate(AccessType.UPDATE)
+ @Produces(MediaType.APPLICATION_JSON)
+ @ApiOperation(value = "Update the TableConfigs provided by the tableConfigsStr json", notes = "Update the TableConfigs provided by the tableConfigsStr json")
+ public SuccessResponse updateConfig(
+ @ApiParam(value = "TableConfigs name i.e. raw table name", required = true) @PathParam("tableName") String tableName,
+ @ApiParam(value = "Reload the table if the new schema is backward compatible") @DefaultValue("false") @QueryParam("reload") boolean reload,
+ String tableConfigsStr)
+ throws Exception {
+ TableConfigs tableConfigs;
+ try {
+ tableConfigs = JsonUtils.stringToObject(tableConfigsStr, TableConfigs.class);
+ Preconditions.checkState(tableConfigs.getTableName().equals(tableName),
+ "'tableName' in TableConfigs: %s must match provided tableName: %s", tableConfigs.getTableName(), tableName);
+ validateConfig(tableConfigs);
+ } catch (Exception e) {
+ throw new ControllerApplicationException(LOGGER, String.format("Invalid TableConfigs: %s", tableName),
+ Response.Status.BAD_REQUEST, e);
+ }
+
+ TableConfig offlineTableConfig = tableConfigs.getOffline();
+ TableConfig realtimeTableConfig = tableConfigs.getRealtime();
+ Schema schema = tableConfigs.getSchema();
+
+ try {
Review comment:
Check table existence first
##########
File path: pinot-controller/src/main/java/org/apache/pinot/controller/api/resources/PinotTableRestletResource.java
##########
@@ -165,9 +146,13 @@ public SuccessResponse addTable(String tableConfigStr, @Context HttpHeaders http
throw new ControllerApplicationException(LOGGER, e.getMessage(), Response.Status.BAD_REQUEST, e);
}
try {
- ensureMinReplicas(tableConfig);
- ensureStorageQuotaConstraints(tableConfig);
- verifyTableConfigs(tableConfig);
+ try {
+ TableConfigUtils.ensureMinReplicas(tableConfig, _controllerConf.getDefaultTableMinReplicas());
+ TableConfigUtils.ensureStorageQuotaConstraints(tableConfig, _controllerConf.getDimTableMaxSize());
+ checkHybridTableConfig(TableNameBuilder.extractRawTableName(tableName), tableConfig);
+ } catch (Exception e) {
+ throw new PinotHelixResourceManager.InvalidTableConfigException(e);
Review comment:
+1
##########
File path: pinot-controller/src/main/java/org/apache/pinot/controller/api/resources/TableConfigsRestletResource.java
##########
@@ -0,0 +1,358 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.pinot.controller.api.resources;
+
+import com.fasterxml.jackson.databind.node.ArrayNode;
+import com.google.common.base.Preconditions;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import io.swagger.annotations.ApiParam;
+import java.io.IOException;
+import java.util.Collections;
+import java.util.List;
+import javax.inject.Inject;
+import javax.ws.rs.DELETE;
+import javax.ws.rs.DefaultValue;
+import javax.ws.rs.GET;
+import javax.ws.rs.POST;
+import javax.ws.rs.PUT;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.QueryParam;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.HttpHeaders;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+import org.apache.pinot.common.metrics.ControllerMeter;
+import org.apache.pinot.common.metrics.ControllerMetrics;
+import org.apache.pinot.controller.ControllerConf;
+import org.apache.pinot.controller.api.access.AccessControlFactory;
+import org.apache.pinot.controller.api.access.AccessControlUtils;
+import org.apache.pinot.controller.api.access.AccessType;
+import org.apache.pinot.controller.api.access.Authenticate;
+import org.apache.pinot.controller.helix.core.PinotHelixResourceManager;
+import org.apache.pinot.segment.local.utils.SchemaUtils;
+import org.apache.pinot.segment.local.utils.TableConfigUtils;
+import org.apache.pinot.spi.config.TableConfigs;
+import org.apache.pinot.spi.config.table.TableConfig;
+import org.apache.pinot.spi.data.Schema;
+import org.apache.pinot.spi.utils.JsonUtils;
+import org.apache.pinot.spi.utils.builder.TableNameBuilder;
+import org.glassfish.grizzly.http.server.Request;
+import org.slf4j.LoggerFactory;
+
+
+/**
+ * Endpoints for CRUD of {@link TableConfigs}.
+ * {@link TableConfigs} is a group of the offline table config, realtime table config and schema for the same tableName.
+ */
+@Api(tags = Constants.TABLE_TAG)
+@Path("/")
+public class TableConfigsRestletResource {
+
+ public static org.slf4j.Logger LOGGER = LoggerFactory.getLogger(TableConfigsRestletResource.class);
+
+ @Inject
+ PinotHelixResourceManager _pinotHelixResourceManager;
+
+ @Inject
+ ControllerConf _controllerConf;
+
+ @Inject
+ ControllerMetrics _controllerMetrics;
+
+ @Inject
+ AccessControlFactory _accessControlFactory;
+ AccessControlUtils _accessControlUtils = new AccessControlUtils();
+
+ /**
+ * List all {@link TableConfigs}, where each is a group of the offline table config, realtime table config and schema for the same tableName.
+ * This is equivalent to a list of all raw table names
+ */
+ @GET
+ @Produces(MediaType.APPLICATION_JSON)
+ @Path("/tableConfigs")
+ @Authenticate(AccessType.READ)
+ @ApiOperation(value = "Lists all TableConfigs in cluster", notes = "Lists all TableConfigs in cluster")
+ public String listConfigs() {
+ try {
+ List<String> rawTableNames = _pinotHelixResourceManager.getAllRawTables();
+ Collections.sort(rawTableNames);
+
+ ArrayNode configsList = JsonUtils.newArrayNode();
+ for (String rawTableName : rawTableNames) {
+ configsList.add(rawTableName);
+ }
+ return configsList.toString();
+ } catch (Exception e) {
+ throw new ControllerApplicationException(LOGGER, e.getMessage(), Response.Status.INTERNAL_SERVER_ERROR, e);
+ }
+ }
+
+ /**
+ * Gets the {@link TableConfigs} for the provided raw tableName, by fetching the offline table config for tableName_OFFLINE,
+ * realtime table config for tableName_REALTIME and schema for tableName
+ */
+ @GET
+ @Produces(MediaType.APPLICATION_JSON)
+ @Path("/tableConfigs/{tableName}")
+ @Authenticate(AccessType.READ)
+ @ApiOperation(value = "Get the TableConfigs for a given raw tableName", notes = "Get the TableConfigs for a given raw tableName")
+ public String getConfig(
+ @ApiParam(value = "Raw table name", required = true) @PathParam("tableName") String tableName) {
+
+ try {
+ Schema schema = _pinotHelixResourceManager.getSchema(tableName);
+ TableConfig offlineTableConfig = _pinotHelixResourceManager.getOfflineTableConfig(tableName);
+ TableConfig realtimeTableConfig = _pinotHelixResourceManager.getRealtimeTableConfig(tableName);
+ TableConfigs config = new TableConfigs(tableName, schema, offlineTableConfig, realtimeTableConfig);
+ return config.toPrettyJsonString();
+ } catch (Exception e) {
+ throw new ControllerApplicationException(LOGGER, e.getMessage(), Response.Status.INTERNAL_SERVER_ERROR, e);
+ }
+ }
+
+ /**
+ * Creates a {@link TableConfigs} using the <code>tableConfigsStr</code>, by creating the schema,
+ * followed by the realtime tableConfig and offline tableConfig as applicable, from the {@link TableConfigs}.
+ * Validates the configs before applying.
+ */
+ @POST
+ @Produces(MediaType.APPLICATION_JSON)
+ @Path("/tableConfigs")
+ @ApiOperation(value = "Add the TableConfigs using the tableConfigsStr json", notes = "Add the TableConfigs using the tableConfigsStr json")
+ public SuccessResponse addConfig(String tableConfigsStr, @Context HttpHeaders httpHeaders, @Context Request request) {
+ TableConfigs tableConfigs;
+ try {
+ tableConfigs = JsonUtils.stringToObject(tableConfigsStr, TableConfigs.class);
+ validateConfig(tableConfigs);
+ } catch (Exception e) {
+ throw new ControllerApplicationException(LOGGER, String.format("Invalid TableConfigs. %s", e.getMessage()),
+ Response.Status.BAD_REQUEST, e);
+ }
+
+ TableConfig offlineTableConfig = tableConfigs.getOffline();
+ TableConfig realtimeTableConfig = tableConfigs.getRealtime();
+ Schema schema = tableConfigs.getSchema();
+
+ try {
+ String endpointUrl = request.getRequestURL().toString();
+ validatePermissions(schema.getSchemaName(), AccessType.CREATE, httpHeaders, endpointUrl);
+
+ if (offlineTableConfig != null) {
+ tuneConfig(offlineTableConfig, schema);
+ validatePermissions(offlineTableConfig.getTableName(), AccessType.CREATE, httpHeaders, endpointUrl);
+ }
+ if (realtimeTableConfig != null) {
+ tuneConfig(realtimeTableConfig, schema);
+ validatePermissions(realtimeTableConfig.getTableName(), AccessType.CREATE, httpHeaders, endpointUrl);
+ }
+
+ _pinotHelixResourceManager.addSchema(schema, true);
+ LOGGER.info("Added schema: {}", schema.getSchemaName());
+ if (offlineTableConfig != null) {
+ _pinotHelixResourceManager.addTable(offlineTableConfig);
+ LOGGER.info("Added offline table config: {}", offlineTableConfig.getTableName());
+ }
+ if (realtimeTableConfig != null) {
+ _pinotHelixResourceManager.addTable(realtimeTableConfig);
+ LOGGER.info("Added realtime table config: {}", realtimeTableConfig.getTableName());
+ }
+
+ return new SuccessResponse("TableConfigs " + tableConfigs.getTableName() + " successfully added");
+ } catch (Exception e) {
+ _controllerMetrics.addMeteredGlobalValue(ControllerMeter.CONTROLLER_TABLE_ADD_ERROR, 1L);
+ if (e instanceof PinotHelixResourceManager.InvalidTableConfigException) {
+ throw new ControllerApplicationException(LOGGER,
+ String.format("Invalid TableConfigs: %s", tableConfigs.getTableName()), Response.Status.BAD_REQUEST, e);
+ } else if (e instanceof PinotHelixResourceManager.TableAlreadyExistsException) {
+ throw new ControllerApplicationException(LOGGER, e.getMessage(), Response.Status.CONFLICT, e);
+ } else {
+ throw new ControllerApplicationException(LOGGER, e.getMessage(), Response.Status.INTERNAL_SERVER_ERROR, e);
+ }
+ }
+ }
+
+ /**
+ * Deletes the {@link TableConfigs} by deleting the schema tableName, the offline table config for tableName_OFFLINE and
+ * the realtime table config for tableName_REALTIME
+ */
+ @DELETE
+ @Path("/tableConfigs/{tableName}")
+ @Authenticate(AccessType.DELETE)
+ @Produces(MediaType.APPLICATION_JSON)
+ @ApiOperation(value = "Delete the TableConfigs", notes = "Delete the TableConfigs")
+ public SuccessResponse deleteConfig(
+ @ApiParam(value = "TableConfigs name i.e. raw table name", required = true) @PathParam("tableName") String tableName) {
+
+ try {
+ _pinotHelixResourceManager.deleteRealtimeTable(tableName);
+ LOGGER.info("Deleted realtime table: {}", tableName);
+ _pinotHelixResourceManager.deleteOfflineTable(tableName);
+ LOGGER.info("Deleted offline table: {}", tableName);
+ Schema schema = _pinotHelixResourceManager.getSchema(tableName);
+ if (schema != null) {
+ _pinotHelixResourceManager.deleteSchema(schema);
+ }
+ LOGGER.info("Deleted schema: {}", tableName);
+ return new SuccessResponse("Deleted TableConfigs: " + tableName);
+ } catch (Exception e) {
+ throw new ControllerApplicationException(LOGGER, e.getMessage(), Response.Status.INTERNAL_SERVER_ERROR, e);
+ }
+ }
+
+ /**
+ * Updated the {@link TableConfigs} by updating the schema tableName,
+ * then updating the offline tableConfig or creating a new one if it doesn't already exist in the cluster,
+ * then updating the realtime tableConfig or creating a new one if it doesn't already exist in the cluster.
+ */
+ @PUT
+ @Path("/tableConfigs/{tableName}")
+ @Authenticate(AccessType.UPDATE)
+ @Produces(MediaType.APPLICATION_JSON)
+ @ApiOperation(value = "Update the TableConfigs provided by the tableConfigsStr json", notes = "Update the TableConfigs provided by the tableConfigsStr json")
+ public SuccessResponse updateConfig(
+ @ApiParam(value = "TableConfigs name i.e. raw table name", required = true) @PathParam("tableName") String tableName,
+ @ApiParam(value = "Reload the table if the new schema is backward compatible") @DefaultValue("false") @QueryParam("reload") boolean reload,
+ String tableConfigsStr)
+ throws Exception {
+ TableConfigs tableConfigs;
+ try {
+ tableConfigs = JsonUtils.stringToObject(tableConfigsStr, TableConfigs.class);
+ Preconditions.checkState(tableConfigs.getTableName().equals(tableName),
+ "'tableName' in TableConfigs: %s must match provided tableName: %s", tableConfigs.getTableName(), tableName);
+ validateConfig(tableConfigs);
+ } catch (Exception e) {
+ throw new ControllerApplicationException(LOGGER, String.format("Invalid TableConfigs: %s", tableName),
+ Response.Status.BAD_REQUEST, e);
+ }
+
+ TableConfig offlineTableConfig = tableConfigs.getOffline();
+ TableConfig realtimeTableConfig = tableConfigs.getRealtime();
+ Schema schema = tableConfigs.getSchema();
+
+ try {
+ _pinotHelixResourceManager.updateSchema(schema, reload);
+ LOGGER.info("Updated schema: {}", tableName);
+
+ if (offlineTableConfig != null) {
+ tuneConfig(offlineTableConfig, schema);
+ if (_pinotHelixResourceManager.hasOfflineTable(tableName)) {
+ _pinotHelixResourceManager.updateTableConfig(offlineTableConfig);
+ LOGGER.info("Updated offline table config: {}", tableName);
+ } else {
+ _pinotHelixResourceManager.addTable(offlineTableConfig);
+ LOGGER.info("Created offline table config: {}", tableName);
+ }
+ if (realtimeTableConfig != null) {
+ tuneConfig(realtimeTableConfig, schema);
+ if (_pinotHelixResourceManager.hasRealtimeTable(tableName)) {
+ _pinotHelixResourceManager.updateTableConfig(realtimeTableConfig);
+ LOGGER.info("Updated realtime table config: {}", tableName);
+ } else {
+ _pinotHelixResourceManager.addTable(realtimeTableConfig);
+ LOGGER.info("Created realtime table config: {}", tableName);
+ }
+ }
+ }
+ } catch (PinotHelixResourceManager.InvalidTableConfigException e) {
+ _controllerMetrics.addMeteredGlobalValue(ControllerMeter.CONTROLLER_TABLE_UPDATE_ERROR, 1L);
+ throw new ControllerApplicationException(LOGGER,
+ String.format("Invalid TableConfigs for: %s, %s", tableName, e.getMessage()), Response.Status.BAD_REQUEST, e);
+ } catch (Exception e) {
+ _controllerMetrics.addMeteredGlobalValue(ControllerMeter.CONTROLLER_TABLE_UPDATE_ERROR, 1L);
+ throw new ControllerApplicationException(LOGGER,
+ String.format("Failed to update TableConfigs for: %s, %s", tableName, e.getMessage()),
+ Response.Status.INTERNAL_SERVER_ERROR, e);
+ }
+
+ return new SuccessResponse("TableConfigs updated for " + tableName);
+ }
+
+ /**
+ * Validates the {@link TableConfigs} as provided in the tableConfigsStr json, by validating the schema,
+ * the realtime table config and the offline table config
+ */
+ @POST
+ @Path("/tableConfigs/validate")
+ @Produces(MediaType.APPLICATION_JSON)
+ @ApiOperation(value = "Validate the TableConfigs", notes = "Validate the TableConfigs")
+ public String validateConfig(String tableConfigsStr) {
+ TableConfigs tableConfigs;
+ try {
+ tableConfigs = JsonUtils.stringToObject(tableConfigsStr, TableConfigs.class);
+ } catch (IOException e) {
+ throw new ControllerApplicationException(LOGGER, String.format("Invalid TableConfigs json string: %s", tableConfigsStr),
+ Response.Status.BAD_REQUEST, e);
+ }
+ return validateConfig(tableConfigs);
+ }
+
+ private void tuneConfig(TableConfig tableConfig, Schema schema) {
+ TableConfigUtils.applyTunerConfig(tableConfig, schema);
+ TableConfigUtils.ensureMinReplicas(tableConfig, _controllerConf.getDefaultTableMinReplicas());
+ TableConfigUtils.ensureStorageQuotaConstraints(tableConfig, _controllerConf.getDimTableMaxSize());
+ }
+
+ private String validateConfig(TableConfigs tableConfigs) {
+ String tableName = tableConfigs.getTableName();
+ TableConfig offlineTableConfig = tableConfigs.getOffline();
+ TableConfig realtimeTableConfig = tableConfigs.getRealtime();
+ Schema schema = tableConfigs.getSchema();
+ try {
+ Preconditions.checkState(offlineTableConfig != null || realtimeTableConfig != null,
+ "Must provide at least one of 'realtime' or 'offline' table configs for adding TableConfigs: %s", tableName);
+ Preconditions.checkState(schema != null, "Must provide 'schema' for adding TableConfigs: %s", tableName);
+ Preconditions.checkState(!tableName.isEmpty(), "'tableName' cannot be empty in TableConfigs");
+
+ Preconditions
+ .checkState(tableName.equals(schema.getSchemaName()), "'tableName': %s must be equal to 'schemaName' from 'schema': %s",
+ tableName, schema.getSchemaName());
+ SchemaUtils.validate(schema);
+
+ if (offlineTableConfig != null) {
+ String rawTableName = TableNameBuilder.extractRawTableName(offlineTableConfig.getTableName());
+ Preconditions.checkState(rawTableName.equals(tableName),
+ "Name in 'offline' table config: %s must be equal to 'tableName': %s", rawTableName, tableName);
+ TableConfigUtils.validateTableName(offlineTableConfig);
+ TableConfigUtils.validate(offlineTableConfig, schema);
+ }
+ if (realtimeTableConfig != null) {
+ String rawTableName = TableNameBuilder.extractRawTableName(realtimeTableConfig.getTableName());
+ Preconditions.checkState(rawTableName.equals(tableName),
+ "Name in 'realtime' table config: %s must be equal to 'tableName': %s", rawTableName, tableName);
+ TableConfigUtils.validateTableName(realtimeTableConfig);
+ TableConfigUtils.validate(realtimeTableConfig, schema);
+ }
+ TableConfigUtils.verifyHybridTableConfigs(tableName, offlineTableConfig, realtimeTableConfig);
+
+ return tableConfigs.toPrettyJsonString();
Review comment:
```suggestion
return tableConfigs.toJsonString();
```
##########
File path: pinot-segment-local/src/main/java/org/apache/pinot/segment/local/utils/TableConfigUtils.java
##########
@@ -580,4 +616,124 @@ private static IndexingConfig sanitizeIndexingConfig(IndexingConfig indexingConf
}
return null;
}
+
+ /**
+ * Apply TunerConfig to the tableConfig
+ */
+ public static void applyTunerConfig(TableConfig tableConfig, Schema schema) {
+ TunerConfig tunerConfig = tableConfig.getTunerConfig();
+ if (tunerConfig != null && tunerConfig.getName() != null && !tunerConfig.getName().isEmpty()) {
+ TableConfigTuner tuner = TableConfigTunerRegistry.getTuner(tunerConfig.getName());
+ tuner.init(tunerConfig, schema);
+ tuner.apply(tableConfig);
+ }
+ }
+
+ /**
+ * Ensure that the table config has the minimum number of replicas set as per cluster configs.
+ * If is doesn't, set the required amount of replication in the table config
+ */
+ public static void ensureMinReplicas(TableConfig tableConfig, int defaultTableMinReplicas) {
+ // For self-serviced cluster, ensure that the tables are created with at least min replication factor irrespective
+ // of table configuration value
+ SegmentsValidationAndRetentionConfig segmentsConfig = tableConfig.getValidationConfig();
+ boolean verifyReplicasPerPartition;
+ boolean verifyReplication;
+
+ try {
+ verifyReplicasPerPartition = ReplicationUtils.useReplicasPerPartition(tableConfig);
+ verifyReplication = ReplicationUtils.useReplication(tableConfig);
+ } catch (Exception e) {
+ throw new IllegalStateException(String.format("Invalid tableIndexConfig or streamConfig: %s", e.getMessage()), e);
+ }
+
+ if (verifyReplication) {
+ int requestReplication;
+ try {
+ requestReplication = segmentsConfig.getReplicationNumber();
+ if (requestReplication < defaultTableMinReplicas) {
+ LOGGER.info("Creating table with minimum replication factor of: {} instead of requested replication: {}",
+ defaultTableMinReplicas, requestReplication);
+ segmentsConfig.setReplication(String.valueOf(defaultTableMinReplicas));
+ }
+ } catch (NumberFormatException e) {
+ throw new IllegalStateException("Invalid replication number", e);
+ }
+ }
+
+ if (verifyReplicasPerPartition) {
+ String replicasPerPartitionStr = segmentsConfig.getReplicasPerPartition();
+ if (replicasPerPartitionStr == null) {
+ throw new IllegalStateException("Field replicasPerPartition needs to be specified");
+ }
+ try {
+ int replicasPerPartition = Integer.parseInt(replicasPerPartitionStr);
+ if (replicasPerPartition < defaultTableMinReplicas) {
+ LOGGER.info(
+ "Creating table with minimum replicasPerPartition of: {} instead of requested replicasPerPartition: {}",
+ defaultTableMinReplicas, replicasPerPartition);
+ segmentsConfig.setReplicasPerPartition(String.valueOf(defaultTableMinReplicas));
+ }
+ } catch (NumberFormatException e) {
+ throw new IllegalStateException("Invalid value for replicasPerPartition: '" + replicasPerPartitionStr + "'", e);
+ }
+ }
+ }
+
+ /**
+ * Ensure the table config has storage quota set as per cluster configs.
+ * If it doesn't, set the quota config into the table config
+ */
+ public static void ensureStorageQuotaConstraints(TableConfig tableConfig, String maxAllowedSize) {
+ // Dim tables must adhere to cluster level storage size limits
+ if (tableConfig.isDimTable()) {
+ QuotaConfig quotaConfig = tableConfig.getQuotaConfig();
+ long maxAllowedSizeInBytes = DataSizeUtils.toBytes(maxAllowedSize);
+
+ if (quotaConfig == null) {
+ // set a default storage quota
+ tableConfig.setQuotaConfig(new QuotaConfig(maxAllowedSize, null));
+ LOGGER.info("Assigning default storage quota ({}) for dimension table: {}", maxAllowedSize,
+ tableConfig.getTableName());
+ } else {
+ if (quotaConfig.getStorage() == null) {
+ // set a default storage quota and keep the RPS value
+ tableConfig.setQuotaConfig(new QuotaConfig(maxAllowedSize, quotaConfig.getMaxQueriesPerSecond()));
+ LOGGER.info("Assigning default storage quota ({}) for dimension table: {}", maxAllowedSize,
+ tableConfig.getTableName());
+ } else {
+ if (quotaConfig.getStorageInBytes() > maxAllowedSizeInBytes) {
+ throw new IllegalStateException(String
+ .format("Invalid storage quota: %d, max allowed size: %d", quotaConfig.getStorageInBytes(),
+ maxAllowedSizeInBytes));
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * Consistency checks across the offline and realtime counterparts of a hybrid table
+ */
+ public static void verifyHybridTableConfigs(String rawTableName, TableConfig offlineTableConfig,
+ TableConfig realtimeTableConfig) {
+ if (offlineTableConfig == null || realtimeTableConfig == null) {
+ return;
+ }
+
+ LOGGER.info("Validating realtime and offline configs for the hybrid table: {}", rawTableName);
+ String offlineRawTableName = TableNameBuilder.extractRawTableName(offlineTableConfig.getTableName());
+ String realtimeRawTableName = TableNameBuilder.extractRawTableName(realtimeTableConfig.getTableName());
+ Preconditions.checkState(offlineRawTableName.equals(realtimeRawTableName),
+ "Raw table name for offline table: %s does not match raw table name for realtime table: %s");
Review comment:
These validation are already performed on the caller side. We can only validate the cross table part (time column match)
##########
File path: pinot-controller/src/main/java/org/apache/pinot/controller/api/resources/TableConfigsRestletResource.java
##########
@@ -0,0 +1,358 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.pinot.controller.api.resources;
+
+import com.fasterxml.jackson.databind.node.ArrayNode;
+import com.google.common.base.Preconditions;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import io.swagger.annotations.ApiParam;
+import java.io.IOException;
+import java.util.Collections;
+import java.util.List;
+import javax.inject.Inject;
+import javax.ws.rs.DELETE;
+import javax.ws.rs.DefaultValue;
+import javax.ws.rs.GET;
+import javax.ws.rs.POST;
+import javax.ws.rs.PUT;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.QueryParam;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.HttpHeaders;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+import org.apache.pinot.common.metrics.ControllerMeter;
+import org.apache.pinot.common.metrics.ControllerMetrics;
+import org.apache.pinot.controller.ControllerConf;
+import org.apache.pinot.controller.api.access.AccessControlFactory;
+import org.apache.pinot.controller.api.access.AccessControlUtils;
+import org.apache.pinot.controller.api.access.AccessType;
+import org.apache.pinot.controller.api.access.Authenticate;
+import org.apache.pinot.controller.helix.core.PinotHelixResourceManager;
+import org.apache.pinot.segment.local.utils.SchemaUtils;
+import org.apache.pinot.segment.local.utils.TableConfigUtils;
+import org.apache.pinot.spi.config.TableConfigs;
+import org.apache.pinot.spi.config.table.TableConfig;
+import org.apache.pinot.spi.data.Schema;
+import org.apache.pinot.spi.utils.JsonUtils;
+import org.apache.pinot.spi.utils.builder.TableNameBuilder;
+import org.glassfish.grizzly.http.server.Request;
+import org.slf4j.LoggerFactory;
+
+
+/**
+ * Endpoints for CRUD of {@link TableConfigs}.
+ * {@link TableConfigs} is a group of the offline table config, realtime table config and schema for the same tableName.
+ */
+@Api(tags = Constants.TABLE_TAG)
+@Path("/")
+public class TableConfigsRestletResource {
+
+ public static org.slf4j.Logger LOGGER = LoggerFactory.getLogger(TableConfigsRestletResource.class);
+
+ @Inject
+ PinotHelixResourceManager _pinotHelixResourceManager;
+
+ @Inject
+ ControllerConf _controllerConf;
+
+ @Inject
+ ControllerMetrics _controllerMetrics;
+
+ @Inject
+ AccessControlFactory _accessControlFactory;
+ AccessControlUtils _accessControlUtils = new AccessControlUtils();
+
+ /**
+ * List all {@link TableConfigs}, where each is a group of the offline table config, realtime table config and schema for the same tableName.
+ * This is equivalent to a list of all raw table names
+ */
+ @GET
+ @Produces(MediaType.APPLICATION_JSON)
+ @Path("/tableConfigs")
+ @Authenticate(AccessType.READ)
+ @ApiOperation(value = "Lists all TableConfigs in cluster", notes = "Lists all TableConfigs in cluster")
+ public String listConfigs() {
+ try {
+ List<String> rawTableNames = _pinotHelixResourceManager.getAllRawTables();
+ Collections.sort(rawTableNames);
+
+ ArrayNode configsList = JsonUtils.newArrayNode();
+ for (String rawTableName : rawTableNames) {
+ configsList.add(rawTableName);
+ }
+ return configsList.toString();
+ } catch (Exception e) {
+ throw new ControllerApplicationException(LOGGER, e.getMessage(), Response.Status.INTERNAL_SERVER_ERROR, e);
+ }
+ }
+
+ /**
+ * Gets the {@link TableConfigs} for the provided raw tableName, by fetching the offline table config for tableName_OFFLINE,
+ * realtime table config for tableName_REALTIME and schema for tableName
+ */
+ @GET
+ @Produces(MediaType.APPLICATION_JSON)
+ @Path("/tableConfigs/{tableName}")
+ @Authenticate(AccessType.READ)
+ @ApiOperation(value = "Get the TableConfigs for a given raw tableName", notes = "Get the TableConfigs for a given raw tableName")
+ public String getConfig(
+ @ApiParam(value = "Raw table name", required = true) @PathParam("tableName") String tableName) {
+
+ try {
+ Schema schema = _pinotHelixResourceManager.getSchema(tableName);
+ TableConfig offlineTableConfig = _pinotHelixResourceManager.getOfflineTableConfig(tableName);
+ TableConfig realtimeTableConfig = _pinotHelixResourceManager.getRealtimeTableConfig(tableName);
+ TableConfigs config = new TableConfigs(tableName, schema, offlineTableConfig, realtimeTableConfig);
+ return config.toPrettyJsonString();
+ } catch (Exception e) {
+ throw new ControllerApplicationException(LOGGER, e.getMessage(), Response.Status.INTERNAL_SERVER_ERROR, e);
+ }
+ }
+
+ /**
+ * Creates a {@link TableConfigs} using the <code>tableConfigsStr</code>, by creating the schema,
+ * followed by the realtime tableConfig and offline tableConfig as applicable, from the {@link TableConfigs}.
+ * Validates the configs before applying.
+ */
+ @POST
+ @Produces(MediaType.APPLICATION_JSON)
+ @Path("/tableConfigs")
+ @ApiOperation(value = "Add the TableConfigs using the tableConfigsStr json", notes = "Add the TableConfigs using the tableConfigsStr json")
+ public SuccessResponse addConfig(String tableConfigsStr, @Context HttpHeaders httpHeaders, @Context Request request) {
+ TableConfigs tableConfigs;
+ try {
+ tableConfigs = JsonUtils.stringToObject(tableConfigsStr, TableConfigs.class);
+ validateConfig(tableConfigs);
+ } catch (Exception e) {
+ throw new ControllerApplicationException(LOGGER, String.format("Invalid TableConfigs. %s", e.getMessage()),
+ Response.Status.BAD_REQUEST, e);
+ }
+
+ TableConfig offlineTableConfig = tableConfigs.getOffline();
+ TableConfig realtimeTableConfig = tableConfigs.getRealtime();
+ Schema schema = tableConfigs.getSchema();
+
+ try {
+ String endpointUrl = request.getRequestURL().toString();
+ validatePermissions(schema.getSchemaName(), AccessType.CREATE, httpHeaders, endpointUrl);
+
+ if (offlineTableConfig != null) {
+ tuneConfig(offlineTableConfig, schema);
+ validatePermissions(offlineTableConfig.getTableName(), AccessType.CREATE, httpHeaders, endpointUrl);
+ }
+ if (realtimeTableConfig != null) {
+ tuneConfig(realtimeTableConfig, schema);
+ validatePermissions(realtimeTableConfig.getTableName(), AccessType.CREATE, httpHeaders, endpointUrl);
+ }
+
+ _pinotHelixResourceManager.addSchema(schema, true);
+ LOGGER.info("Added schema: {}", schema.getSchemaName());
+ if (offlineTableConfig != null) {
+ _pinotHelixResourceManager.addTable(offlineTableConfig);
+ LOGGER.info("Added offline table config: {}", offlineTableConfig.getTableName());
+ }
+ if (realtimeTableConfig != null) {
+ _pinotHelixResourceManager.addTable(realtimeTableConfig);
+ LOGGER.info("Added realtime table config: {}", realtimeTableConfig.getTableName());
+ }
+
+ return new SuccessResponse("TableConfigs " + tableConfigs.getTableName() + " successfully added");
+ } catch (Exception e) {
+ _controllerMetrics.addMeteredGlobalValue(ControllerMeter.CONTROLLER_TABLE_ADD_ERROR, 1L);
+ if (e instanceof PinotHelixResourceManager.InvalidTableConfigException) {
+ throw new ControllerApplicationException(LOGGER,
+ String.format("Invalid TableConfigs: %s", tableConfigs.getTableName()), Response.Status.BAD_REQUEST, e);
+ } else if (e instanceof PinotHelixResourceManager.TableAlreadyExistsException) {
+ throw new ControllerApplicationException(LOGGER, e.getMessage(), Response.Status.CONFLICT, e);
+ } else {
+ throw new ControllerApplicationException(LOGGER, e.getMessage(), Response.Status.INTERNAL_SERVER_ERROR, e);
+ }
+ }
+ }
+
+ /**
+ * Deletes the {@link TableConfigs} by deleting the schema tableName, the offline table config for tableName_OFFLINE and
+ * the realtime table config for tableName_REALTIME
+ */
+ @DELETE
+ @Path("/tableConfigs/{tableName}")
+ @Authenticate(AccessType.DELETE)
+ @Produces(MediaType.APPLICATION_JSON)
+ @ApiOperation(value = "Delete the TableConfigs", notes = "Delete the TableConfigs")
+ public SuccessResponse deleteConfig(
+ @ApiParam(value = "TableConfigs name i.e. raw table name", required = true) @PathParam("tableName") String tableName) {
+
+ try {
+ _pinotHelixResourceManager.deleteRealtimeTable(tableName);
+ LOGGER.info("Deleted realtime table: {}", tableName);
+ _pinotHelixResourceManager.deleteOfflineTable(tableName);
+ LOGGER.info("Deleted offline table: {}", tableName);
+ Schema schema = _pinotHelixResourceManager.getSchema(tableName);
+ if (schema != null) {
+ _pinotHelixResourceManager.deleteSchema(schema);
+ }
+ LOGGER.info("Deleted schema: {}", tableName);
+ return new SuccessResponse("Deleted TableConfigs: " + tableName);
+ } catch (Exception e) {
+ throw new ControllerApplicationException(LOGGER, e.getMessage(), Response.Status.INTERNAL_SERVER_ERROR, e);
+ }
+ }
+
+ /**
+ * Updated the {@link TableConfigs} by updating the schema tableName,
+ * then updating the offline tableConfig or creating a new one if it doesn't already exist in the cluster,
+ * then updating the realtime tableConfig or creating a new one if it doesn't already exist in the cluster.
+ */
+ @PUT
+ @Path("/tableConfigs/{tableName}")
+ @Authenticate(AccessType.UPDATE)
+ @Produces(MediaType.APPLICATION_JSON)
+ @ApiOperation(value = "Update the TableConfigs provided by the tableConfigsStr json", notes = "Update the TableConfigs provided by the tableConfigsStr json")
+ public SuccessResponse updateConfig(
+ @ApiParam(value = "TableConfigs name i.e. raw table name", required = true) @PathParam("tableName") String tableName,
+ @ApiParam(value = "Reload the table if the new schema is backward compatible") @DefaultValue("false") @QueryParam("reload") boolean reload,
+ String tableConfigsStr)
+ throws Exception {
+ TableConfigs tableConfigs;
+ try {
+ tableConfigs = JsonUtils.stringToObject(tableConfigsStr, TableConfigs.class);
+ Preconditions.checkState(tableConfigs.getTableName().equals(tableName),
+ "'tableName' in TableConfigs: %s must match provided tableName: %s", tableConfigs.getTableName(), tableName);
+ validateConfig(tableConfigs);
+ } catch (Exception e) {
+ throw new ControllerApplicationException(LOGGER, String.format("Invalid TableConfigs: %s", tableName),
+ Response.Status.BAD_REQUEST, e);
+ }
+
+ TableConfig offlineTableConfig = tableConfigs.getOffline();
+ TableConfig realtimeTableConfig = tableConfigs.getRealtime();
+ Schema schema = tableConfigs.getSchema();
+
+ try {
+ _pinotHelixResourceManager.updateSchema(schema, reload);
+ LOGGER.info("Updated schema: {}", tableName);
+
+ if (offlineTableConfig != null) {
+ tuneConfig(offlineTableConfig, schema);
+ if (_pinotHelixResourceManager.hasOfflineTable(tableName)) {
+ _pinotHelixResourceManager.updateTableConfig(offlineTableConfig);
+ LOGGER.info("Updated offline table config: {}", tableName);
+ } else {
+ _pinotHelixResourceManager.addTable(offlineTableConfig);
+ LOGGER.info("Created offline table config: {}", tableName);
+ }
+ if (realtimeTableConfig != null) {
+ tuneConfig(realtimeTableConfig, schema);
+ if (_pinotHelixResourceManager.hasRealtimeTable(tableName)) {
+ _pinotHelixResourceManager.updateTableConfig(realtimeTableConfig);
+ LOGGER.info("Updated realtime table config: {}", tableName);
+ } else {
+ _pinotHelixResourceManager.addTable(realtimeTableConfig);
+ LOGGER.info("Created realtime table config: {}", tableName);
+ }
+ }
+ }
+ } catch (PinotHelixResourceManager.InvalidTableConfigException e) {
+ _controllerMetrics.addMeteredGlobalValue(ControllerMeter.CONTROLLER_TABLE_UPDATE_ERROR, 1L);
+ throw new ControllerApplicationException(LOGGER,
+ String.format("Invalid TableConfigs for: %s, %s", tableName, e.getMessage()), Response.Status.BAD_REQUEST, e);
+ } catch (Exception e) {
+ _controllerMetrics.addMeteredGlobalValue(ControllerMeter.CONTROLLER_TABLE_UPDATE_ERROR, 1L);
+ throw new ControllerApplicationException(LOGGER,
+ String.format("Failed to update TableConfigs for: %s, %s", tableName, e.getMessage()),
+ Response.Status.INTERNAL_SERVER_ERROR, e);
+ }
+
+ return new SuccessResponse("TableConfigs updated for " + tableName);
+ }
+
+ /**
+ * Validates the {@link TableConfigs} as provided in the tableConfigsStr json, by validating the schema,
+ * the realtime table config and the offline table config
+ */
+ @POST
+ @Path("/tableConfigs/validate")
+ @Produces(MediaType.APPLICATION_JSON)
+ @ApiOperation(value = "Validate the TableConfigs", notes = "Validate the TableConfigs")
+ public String validateConfig(String tableConfigsStr) {
+ TableConfigs tableConfigs;
+ try {
+ tableConfigs = JsonUtils.stringToObject(tableConfigsStr, TableConfigs.class);
+ } catch (IOException e) {
+ throw new ControllerApplicationException(LOGGER, String.format("Invalid TableConfigs json string: %s", tableConfigsStr),
+ Response.Status.BAD_REQUEST, e);
+ }
+ return validateConfig(tableConfigs);
+ }
+
+ private void tuneConfig(TableConfig tableConfig, Schema schema) {
+ TableConfigUtils.applyTunerConfig(tableConfig, schema);
+ TableConfigUtils.ensureMinReplicas(tableConfig, _controllerConf.getDefaultTableMinReplicas());
+ TableConfigUtils.ensureStorageQuotaConstraints(tableConfig, _controllerConf.getDimTableMaxSize());
+ }
+
+ private String validateConfig(TableConfigs tableConfigs) {
+ String tableName = tableConfigs.getTableName();
+ TableConfig offlineTableConfig = tableConfigs.getOffline();
+ TableConfig realtimeTableConfig = tableConfigs.getRealtime();
+ Schema schema = tableConfigs.getSchema();
+ try {
+ Preconditions.checkState(offlineTableConfig != null || realtimeTableConfig != null,
+ "Must provide at least one of 'realtime' or 'offline' table configs for adding TableConfigs: %s", tableName);
+ Preconditions.checkState(schema != null, "Must provide 'schema' for adding TableConfigs: %s", tableName);
+ Preconditions.checkState(!tableName.isEmpty(), "'tableName' cannot be empty in TableConfigs");
+
+ Preconditions
+ .checkState(tableName.equals(schema.getSchemaName()), "'tableName': %s must be equal to 'schemaName' from 'schema': %s",
+ tableName, schema.getSchemaName());
+ SchemaUtils.validate(schema);
+
+ if (offlineTableConfig != null) {
+ String rawTableName = TableNameBuilder.extractRawTableName(offlineTableConfig.getTableName());
+ Preconditions.checkState(rawTableName.equals(tableName),
+ "Name in 'offline' table config: %s must be equal to 'tableName': %s", rawTableName, tableName);
+ TableConfigUtils.validateTableName(offlineTableConfig);
+ TableConfigUtils.validate(offlineTableConfig, schema);
+ }
+ if (realtimeTableConfig != null) {
+ String rawTableName = TableNameBuilder.extractRawTableName(realtimeTableConfig.getTableName());
+ Preconditions.checkState(rawTableName.equals(tableName),
+ "Name in 'realtime' table config: %s must be equal to 'tableName': %s", rawTableName, tableName);
+ TableConfigUtils.validateTableName(realtimeTableConfig);
+ TableConfigUtils.validate(realtimeTableConfig, schema);
+ }
+ TableConfigUtils.verifyHybridTableConfigs(tableName, offlineTableConfig, realtimeTableConfig);
Review comment:
Check not null before calling this function
##########
File path: pinot-controller/src/main/java/org/apache/pinot/controller/api/resources/TableConfigsRestletResource.java
##########
@@ -0,0 +1,358 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.pinot.controller.api.resources;
+
+import com.fasterxml.jackson.databind.node.ArrayNode;
+import com.google.common.base.Preconditions;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import io.swagger.annotations.ApiParam;
+import java.io.IOException;
+import java.util.Collections;
+import java.util.List;
+import javax.inject.Inject;
+import javax.ws.rs.DELETE;
+import javax.ws.rs.DefaultValue;
+import javax.ws.rs.GET;
+import javax.ws.rs.POST;
+import javax.ws.rs.PUT;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.QueryParam;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.HttpHeaders;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+import org.apache.pinot.common.metrics.ControllerMeter;
+import org.apache.pinot.common.metrics.ControllerMetrics;
+import org.apache.pinot.controller.ControllerConf;
+import org.apache.pinot.controller.api.access.AccessControlFactory;
+import org.apache.pinot.controller.api.access.AccessControlUtils;
+import org.apache.pinot.controller.api.access.AccessType;
+import org.apache.pinot.controller.api.access.Authenticate;
+import org.apache.pinot.controller.helix.core.PinotHelixResourceManager;
+import org.apache.pinot.segment.local.utils.SchemaUtils;
+import org.apache.pinot.segment.local.utils.TableConfigUtils;
+import org.apache.pinot.spi.config.TableConfigs;
+import org.apache.pinot.spi.config.table.TableConfig;
+import org.apache.pinot.spi.data.Schema;
+import org.apache.pinot.spi.utils.JsonUtils;
+import org.apache.pinot.spi.utils.builder.TableNameBuilder;
+import org.glassfish.grizzly.http.server.Request;
+import org.slf4j.LoggerFactory;
+
+
+/**
+ * Endpoints for CRUD of {@link TableConfigs}.
+ * {@link TableConfigs} is a group of the offline table config, realtime table config and schema for the same tableName.
+ */
+@Api(tags = Constants.TABLE_TAG)
+@Path("/")
+public class TableConfigsRestletResource {
+
+ public static org.slf4j.Logger LOGGER = LoggerFactory.getLogger(TableConfigsRestletResource.class);
+
+ @Inject
+ PinotHelixResourceManager _pinotHelixResourceManager;
+
+ @Inject
+ ControllerConf _controllerConf;
+
+ @Inject
+ ControllerMetrics _controllerMetrics;
+
+ @Inject
+ AccessControlFactory _accessControlFactory;
+ AccessControlUtils _accessControlUtils = new AccessControlUtils();
+
+ /**
+ * List all {@link TableConfigs}, where each is a group of the offline table config, realtime table config and schema for the same tableName.
+ * This is equivalent to a list of all raw table names
+ */
+ @GET
+ @Produces(MediaType.APPLICATION_JSON)
+ @Path("/tableConfigs")
+ @Authenticate(AccessType.READ)
+ @ApiOperation(value = "Lists all TableConfigs in cluster", notes = "Lists all TableConfigs in cluster")
+ public String listConfigs() {
+ try {
+ List<String> rawTableNames = _pinotHelixResourceManager.getAllRawTables();
+ Collections.sort(rawTableNames);
+
+ ArrayNode configsList = JsonUtils.newArrayNode();
+ for (String rawTableName : rawTableNames) {
+ configsList.add(rawTableName);
+ }
+ return configsList.toString();
+ } catch (Exception e) {
+ throw new ControllerApplicationException(LOGGER, e.getMessage(), Response.Status.INTERNAL_SERVER_ERROR, e);
+ }
+ }
+
+ /**
+ * Gets the {@link TableConfigs} for the provided raw tableName, by fetching the offline table config for tableName_OFFLINE,
+ * realtime table config for tableName_REALTIME and schema for tableName
+ */
+ @GET
+ @Produces(MediaType.APPLICATION_JSON)
+ @Path("/tableConfigs/{tableName}")
+ @Authenticate(AccessType.READ)
+ @ApiOperation(value = "Get the TableConfigs for a given raw tableName", notes = "Get the TableConfigs for a given raw tableName")
+ public String getConfig(
+ @ApiParam(value = "Raw table name", required = true) @PathParam("tableName") String tableName) {
+
+ try {
+ Schema schema = _pinotHelixResourceManager.getSchema(tableName);
+ TableConfig offlineTableConfig = _pinotHelixResourceManager.getOfflineTableConfig(tableName);
+ TableConfig realtimeTableConfig = _pinotHelixResourceManager.getRealtimeTableConfig(tableName);
+ TableConfigs config = new TableConfigs(tableName, schema, offlineTableConfig, realtimeTableConfig);
+ return config.toPrettyJsonString();
+ } catch (Exception e) {
+ throw new ControllerApplicationException(LOGGER, e.getMessage(), Response.Status.INTERNAL_SERVER_ERROR, e);
+ }
+ }
+
+ /**
+ * Creates a {@link TableConfigs} using the <code>tableConfigsStr</code>, by creating the schema,
+ * followed by the realtime tableConfig and offline tableConfig as applicable, from the {@link TableConfigs}.
+ * Validates the configs before applying.
+ */
+ @POST
+ @Produces(MediaType.APPLICATION_JSON)
+ @Path("/tableConfigs")
+ @ApiOperation(value = "Add the TableConfigs using the tableConfigsStr json", notes = "Add the TableConfigs using the tableConfigsStr json")
+ public SuccessResponse addConfig(String tableConfigsStr, @Context HttpHeaders httpHeaders, @Context Request request) {
+ TableConfigs tableConfigs;
+ try {
+ tableConfigs = JsonUtils.stringToObject(tableConfigsStr, TableConfigs.class);
+ validateConfig(tableConfigs);
+ } catch (Exception e) {
+ throw new ControllerApplicationException(LOGGER, String.format("Invalid TableConfigs. %s", e.getMessage()),
+ Response.Status.BAD_REQUEST, e);
+ }
+
+ TableConfig offlineTableConfig = tableConfigs.getOffline();
+ TableConfig realtimeTableConfig = tableConfigs.getRealtime();
+ Schema schema = tableConfigs.getSchema();
+
+ try {
+ String endpointUrl = request.getRequestURL().toString();
+ validatePermissions(schema.getSchemaName(), AccessType.CREATE, httpHeaders, endpointUrl);
+
+ if (offlineTableConfig != null) {
+ tuneConfig(offlineTableConfig, schema);
+ validatePermissions(offlineTableConfig.getTableName(), AccessType.CREATE, httpHeaders, endpointUrl);
+ }
+ if (realtimeTableConfig != null) {
+ tuneConfig(realtimeTableConfig, schema);
+ validatePermissions(realtimeTableConfig.getTableName(), AccessType.CREATE, httpHeaders, endpointUrl);
+ }
+
+ _pinotHelixResourceManager.addSchema(schema, true);
Review comment:
Check if the schema/table config already exist before posting them.
If one of the posting failed, we should clean up the already posted configs.
##########
File path: pinot-controller/src/main/java/org/apache/pinot/controller/api/resources/TableConfigsRestletResource.java
##########
@@ -0,0 +1,358 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.pinot.controller.api.resources;
+
+import com.fasterxml.jackson.databind.node.ArrayNode;
+import com.google.common.base.Preconditions;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import io.swagger.annotations.ApiParam;
+import java.io.IOException;
+import java.util.Collections;
+import java.util.List;
+import javax.inject.Inject;
+import javax.ws.rs.DELETE;
+import javax.ws.rs.DefaultValue;
+import javax.ws.rs.GET;
+import javax.ws.rs.POST;
+import javax.ws.rs.PUT;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.QueryParam;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.HttpHeaders;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+import org.apache.pinot.common.metrics.ControllerMeter;
+import org.apache.pinot.common.metrics.ControllerMetrics;
+import org.apache.pinot.controller.ControllerConf;
+import org.apache.pinot.controller.api.access.AccessControlFactory;
+import org.apache.pinot.controller.api.access.AccessControlUtils;
+import org.apache.pinot.controller.api.access.AccessType;
+import org.apache.pinot.controller.api.access.Authenticate;
+import org.apache.pinot.controller.helix.core.PinotHelixResourceManager;
+import org.apache.pinot.segment.local.utils.SchemaUtils;
+import org.apache.pinot.segment.local.utils.TableConfigUtils;
+import org.apache.pinot.spi.config.TableConfigs;
+import org.apache.pinot.spi.config.table.TableConfig;
+import org.apache.pinot.spi.data.Schema;
+import org.apache.pinot.spi.utils.JsonUtils;
+import org.apache.pinot.spi.utils.builder.TableNameBuilder;
+import org.glassfish.grizzly.http.server.Request;
+import org.slf4j.LoggerFactory;
+
+
+/**
+ * Endpoints for CRUD of {@link TableConfigs}.
+ * {@link TableConfigs} is a group of the offline table config, realtime table config and schema for the same tableName.
+ */
+@Api(tags = Constants.TABLE_TAG)
+@Path("/")
+public class TableConfigsRestletResource {
+
+ public static org.slf4j.Logger LOGGER = LoggerFactory.getLogger(TableConfigsRestletResource.class);
+
+ @Inject
+ PinotHelixResourceManager _pinotHelixResourceManager;
+
+ @Inject
+ ControllerConf _controllerConf;
+
+ @Inject
+ ControllerMetrics _controllerMetrics;
+
+ @Inject
+ AccessControlFactory _accessControlFactory;
+ AccessControlUtils _accessControlUtils = new AccessControlUtils();
+
+ /**
+ * List all {@link TableConfigs}, where each is a group of the offline table config, realtime table config and schema for the same tableName.
+ * This is equivalent to a list of all raw table names
+ */
+ @GET
+ @Produces(MediaType.APPLICATION_JSON)
+ @Path("/tableConfigs")
+ @Authenticate(AccessType.READ)
+ @ApiOperation(value = "Lists all TableConfigs in cluster", notes = "Lists all TableConfigs in cluster")
+ public String listConfigs() {
+ try {
+ List<String> rawTableNames = _pinotHelixResourceManager.getAllRawTables();
+ Collections.sort(rawTableNames);
+
+ ArrayNode configsList = JsonUtils.newArrayNode();
+ for (String rawTableName : rawTableNames) {
+ configsList.add(rawTableName);
+ }
+ return configsList.toString();
+ } catch (Exception e) {
+ throw new ControllerApplicationException(LOGGER, e.getMessage(), Response.Status.INTERNAL_SERVER_ERROR, e);
+ }
+ }
+
+ /**
+ * Gets the {@link TableConfigs} for the provided raw tableName, by fetching the offline table config for tableName_OFFLINE,
+ * realtime table config for tableName_REALTIME and schema for tableName
+ */
+ @GET
+ @Produces(MediaType.APPLICATION_JSON)
+ @Path("/tableConfigs/{tableName}")
+ @Authenticate(AccessType.READ)
+ @ApiOperation(value = "Get the TableConfigs for a given raw tableName", notes = "Get the TableConfigs for a given raw tableName")
+ public String getConfig(
+ @ApiParam(value = "Raw table name", required = true) @PathParam("tableName") String tableName) {
+
+ try {
+ Schema schema = _pinotHelixResourceManager.getSchema(tableName);
+ TableConfig offlineTableConfig = _pinotHelixResourceManager.getOfflineTableConfig(tableName);
+ TableConfig realtimeTableConfig = _pinotHelixResourceManager.getRealtimeTableConfig(tableName);
+ TableConfigs config = new TableConfigs(tableName, schema, offlineTableConfig, realtimeTableConfig);
+ return config.toPrettyJsonString();
+ } catch (Exception e) {
+ throw new ControllerApplicationException(LOGGER, e.getMessage(), Response.Status.INTERNAL_SERVER_ERROR, e);
+ }
+ }
+
+ /**
+ * Creates a {@link TableConfigs} using the <code>tableConfigsStr</code>, by creating the schema,
+ * followed by the realtime tableConfig and offline tableConfig as applicable, from the {@link TableConfigs}.
+ * Validates the configs before applying.
+ */
+ @POST
+ @Produces(MediaType.APPLICATION_JSON)
+ @Path("/tableConfigs")
+ @ApiOperation(value = "Add the TableConfigs using the tableConfigsStr json", notes = "Add the TableConfigs using the tableConfigsStr json")
+ public SuccessResponse addConfig(String tableConfigsStr, @Context HttpHeaders httpHeaders, @Context Request request) {
+ TableConfigs tableConfigs;
+ try {
+ tableConfigs = JsonUtils.stringToObject(tableConfigsStr, TableConfigs.class);
+ validateConfig(tableConfigs);
+ } catch (Exception e) {
+ throw new ControllerApplicationException(LOGGER, String.format("Invalid TableConfigs. %s", e.getMessage()),
+ Response.Status.BAD_REQUEST, e);
+ }
+
+ TableConfig offlineTableConfig = tableConfigs.getOffline();
+ TableConfig realtimeTableConfig = tableConfigs.getRealtime();
+ Schema schema = tableConfigs.getSchema();
+
+ try {
+ String endpointUrl = request.getRequestURL().toString();
+ validatePermissions(schema.getSchemaName(), AccessType.CREATE, httpHeaders, endpointUrl);
+
+ if (offlineTableConfig != null) {
+ tuneConfig(offlineTableConfig, schema);
+ validatePermissions(offlineTableConfig.getTableName(), AccessType.CREATE, httpHeaders, endpointUrl);
+ }
+ if (realtimeTableConfig != null) {
+ tuneConfig(realtimeTableConfig, schema);
+ validatePermissions(realtimeTableConfig.getTableName(), AccessType.CREATE, httpHeaders, endpointUrl);
+ }
+
+ _pinotHelixResourceManager.addSchema(schema, true);
+ LOGGER.info("Added schema: {}", schema.getSchemaName());
+ if (offlineTableConfig != null) {
+ _pinotHelixResourceManager.addTable(offlineTableConfig);
+ LOGGER.info("Added offline table config: {}", offlineTableConfig.getTableName());
+ }
+ if (realtimeTableConfig != null) {
+ _pinotHelixResourceManager.addTable(realtimeTableConfig);
+ LOGGER.info("Added realtime table config: {}", realtimeTableConfig.getTableName());
+ }
+
+ return new SuccessResponse("TableConfigs " + tableConfigs.getTableName() + " successfully added");
+ } catch (Exception e) {
+ _controllerMetrics.addMeteredGlobalValue(ControllerMeter.CONTROLLER_TABLE_ADD_ERROR, 1L);
+ if (e instanceof PinotHelixResourceManager.InvalidTableConfigException) {
+ throw new ControllerApplicationException(LOGGER,
+ String.format("Invalid TableConfigs: %s", tableConfigs.getTableName()), Response.Status.BAD_REQUEST, e);
+ } else if (e instanceof PinotHelixResourceManager.TableAlreadyExistsException) {
+ throw new ControllerApplicationException(LOGGER, e.getMessage(), Response.Status.CONFLICT, e);
+ } else {
+ throw new ControllerApplicationException(LOGGER, e.getMessage(), Response.Status.INTERNAL_SERVER_ERROR, e);
+ }
+ }
+ }
+
+ /**
+ * Deletes the {@link TableConfigs} by deleting the schema tableName, the offline table config for tableName_OFFLINE and
+ * the realtime table config for tableName_REALTIME
+ */
+ @DELETE
+ @Path("/tableConfigs/{tableName}")
+ @Authenticate(AccessType.DELETE)
+ @Produces(MediaType.APPLICATION_JSON)
+ @ApiOperation(value = "Delete the TableConfigs", notes = "Delete the TableConfigs")
+ public SuccessResponse deleteConfig(
+ @ApiParam(value = "TableConfigs name i.e. raw table name", required = true) @PathParam("tableName") String tableName) {
+
+ try {
+ _pinotHelixResourceManager.deleteRealtimeTable(tableName);
+ LOGGER.info("Deleted realtime table: {}", tableName);
+ _pinotHelixResourceManager.deleteOfflineTable(tableName);
+ LOGGER.info("Deleted offline table: {}", tableName);
+ Schema schema = _pinotHelixResourceManager.getSchema(tableName);
+ if (schema != null) {
+ _pinotHelixResourceManager.deleteSchema(schema);
+ }
+ LOGGER.info("Deleted schema: {}", tableName);
+ return new SuccessResponse("Deleted TableConfigs: " + tableName);
+ } catch (Exception e) {
+ throw new ControllerApplicationException(LOGGER, e.getMessage(), Response.Status.INTERNAL_SERVER_ERROR, e);
+ }
+ }
+
+ /**
+ * Updated the {@link TableConfigs} by updating the schema tableName,
+ * then updating the offline tableConfig or creating a new one if it doesn't already exist in the cluster,
+ * then updating the realtime tableConfig or creating a new one if it doesn't already exist in the cluster.
+ */
+ @PUT
+ @Path("/tableConfigs/{tableName}")
+ @Authenticate(AccessType.UPDATE)
+ @Produces(MediaType.APPLICATION_JSON)
+ @ApiOperation(value = "Update the TableConfigs provided by the tableConfigsStr json", notes = "Update the TableConfigs provided by the tableConfigsStr json")
+ public SuccessResponse updateConfig(
+ @ApiParam(value = "TableConfigs name i.e. raw table name", required = true) @PathParam("tableName") String tableName,
+ @ApiParam(value = "Reload the table if the new schema is backward compatible") @DefaultValue("false") @QueryParam("reload") boolean reload,
+ String tableConfigsStr)
+ throws Exception {
+ TableConfigs tableConfigs;
+ try {
+ tableConfigs = JsonUtils.stringToObject(tableConfigsStr, TableConfigs.class);
+ Preconditions.checkState(tableConfigs.getTableName().equals(tableName),
+ "'tableName' in TableConfigs: %s must match provided tableName: %s", tableConfigs.getTableName(), tableName);
+ validateConfig(tableConfigs);
+ } catch (Exception e) {
+ throw new ControllerApplicationException(LOGGER, String.format("Invalid TableConfigs: %s", tableName),
+ Response.Status.BAD_REQUEST, e);
+ }
+
+ TableConfig offlineTableConfig = tableConfigs.getOffline();
+ TableConfig realtimeTableConfig = tableConfigs.getRealtime();
+ Schema schema = tableConfigs.getSchema();
+
+ try {
+ _pinotHelixResourceManager.updateSchema(schema, reload);
+ LOGGER.info("Updated schema: {}", tableName);
+
+ if (offlineTableConfig != null) {
+ tuneConfig(offlineTableConfig, schema);
+ if (_pinotHelixResourceManager.hasOfflineTable(tableName)) {
+ _pinotHelixResourceManager.updateTableConfig(offlineTableConfig);
+ LOGGER.info("Updated offline table config: {}", tableName);
+ } else {
+ _pinotHelixResourceManager.addTable(offlineTableConfig);
+ LOGGER.info("Created offline table config: {}", tableName);
+ }
+ if (realtimeTableConfig != null) {
+ tuneConfig(realtimeTableConfig, schema);
+ if (_pinotHelixResourceManager.hasRealtimeTable(tableName)) {
+ _pinotHelixResourceManager.updateTableConfig(realtimeTableConfig);
+ LOGGER.info("Updated realtime table config: {}", tableName);
+ } else {
+ _pinotHelixResourceManager.addTable(realtimeTableConfig);
+ LOGGER.info("Created realtime table config: {}", tableName);
+ }
+ }
+ }
+ } catch (PinotHelixResourceManager.InvalidTableConfigException e) {
+ _controllerMetrics.addMeteredGlobalValue(ControllerMeter.CONTROLLER_TABLE_UPDATE_ERROR, 1L);
+ throw new ControllerApplicationException(LOGGER,
+ String.format("Invalid TableConfigs for: %s, %s", tableName, e.getMessage()), Response.Status.BAD_REQUEST, e);
+ } catch (Exception e) {
+ _controllerMetrics.addMeteredGlobalValue(ControllerMeter.CONTROLLER_TABLE_UPDATE_ERROR, 1L);
+ throw new ControllerApplicationException(LOGGER,
+ String.format("Failed to update TableConfigs for: %s, %s", tableName, e.getMessage()),
+ Response.Status.INTERNAL_SERVER_ERROR, e);
+ }
+
+ return new SuccessResponse("TableConfigs updated for " + tableName);
+ }
+
+ /**
+ * Validates the {@link TableConfigs} as provided in the tableConfigsStr json, by validating the schema,
+ * the realtime table config and the offline table config
+ */
+ @POST
+ @Path("/tableConfigs/validate")
+ @Produces(MediaType.APPLICATION_JSON)
+ @ApiOperation(value = "Validate the TableConfigs", notes = "Validate the TableConfigs")
+ public String validateConfig(String tableConfigsStr) {
+ TableConfigs tableConfigs;
+ try {
+ tableConfigs = JsonUtils.stringToObject(tableConfigsStr, TableConfigs.class);
+ } catch (IOException e) {
+ throw new ControllerApplicationException(LOGGER, String.format("Invalid TableConfigs json string: %s", tableConfigsStr),
+ Response.Status.BAD_REQUEST, e);
+ }
+ return validateConfig(tableConfigs);
+ }
+
+ private void tuneConfig(TableConfig tableConfig, Schema schema) {
+ TableConfigUtils.applyTunerConfig(tableConfig, schema);
+ TableConfigUtils.ensureMinReplicas(tableConfig, _controllerConf.getDefaultTableMinReplicas());
+ TableConfigUtils.ensureStorageQuotaConstraints(tableConfig, _controllerConf.getDimTableMaxSize());
+ }
+
+ private String validateConfig(TableConfigs tableConfigs) {
+ String tableName = tableConfigs.getTableName();
Review comment:
(nit) `rawTableName` for clarity
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@pinot.apache.org
For additional commands, e-mail: commits-help@pinot.apache.org
[GitHub] [incubator-pinot] npawar commented on a change in pull request #6840: Configs APIs
Posted by GitBox <gi...@apache.org>.
npawar commented on a change in pull request #6840:
URL: https://github.com/apache/incubator-pinot/pull/6840#discussion_r619921969
##########
File path: pinot-spi/src/main/java/org/apache/pinot/spi/config/PinotConfig.java
##########
@@ -0,0 +1,76 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.pinot.spi.config;
+
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.core.JsonProcessingException;
+import javax.annotation.Nullable;
+import org.apache.pinot.spi.config.table.TableConfig;
+import org.apache.pinot.spi.data.Schema;
+import org.apache.pinot.spi.utils.JsonUtils;
+
+
+/**
+ * Wrapper for all configs of a table, which include the offline table config, realtime table config and schema.
+ * This helps look at and operate on the pinot configs as a whole unit.
+ */
+public class PinotConfig {
Review comment:
done. Though this now feels too similar to the plain TableConfig
##########
File path: pinot-controller/src/main/java/org/apache/pinot/controller/api/resources/Constants.java
##########
@@ -30,6 +30,7 @@
public static final String CLUSTER_TAG = "Cluster";
public static final String TABLE_TAG = "Table";
+ public static final String CONFIG_TAG = "Config";
Review comment:
Done.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@pinot.apache.org
For additional commands, e-mail: commits-help@pinot.apache.org
[GitHub] [incubator-pinot] Jackie-Jiang commented on a change in pull request #6840: Configs APIs
Posted by GitBox <gi...@apache.org>.
Jackie-Jiang commented on a change in pull request #6840:
URL: https://github.com/apache/incubator-pinot/pull/6840#discussion_r619885268
##########
File path: pinot-spi/src/main/java/org/apache/pinot/spi/config/PinotConfig.java
##########
@@ -0,0 +1,76 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.pinot.spi.config;
+
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.core.JsonProcessingException;
+import javax.annotation.Nullable;
+import org.apache.pinot.spi.config.table.TableConfig;
+import org.apache.pinot.spi.data.Schema;
+import org.apache.pinot.spi.utils.JsonUtils;
+
+
+/**
+ * Wrapper for all configs of a table, which include the offline table config, realtime table config and schema.
+ * This helps look at and operate on the pinot configs as a whole unit.
+ */
+public class PinotConfig {
Review comment:
Extend `BaseJsonConfig` which contains the basic json related methods
##########
File path: pinot-spi/src/main/java/org/apache/pinot/spi/config/PinotConfig.java
##########
@@ -0,0 +1,76 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.pinot.spi.config;
+
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.core.JsonProcessingException;
+import javax.annotation.Nullable;
+import org.apache.pinot.spi.config.table.TableConfig;
+import org.apache.pinot.spi.data.Schema;
+import org.apache.pinot.spi.utils.JsonUtils;
+
+
+/**
+ * Wrapper for all configs of a table, which include the offline table config, realtime table config and schema.
+ * This helps look at and operate on the pinot configs as a whole unit.
+ */
+public class PinotConfig {
Review comment:
`PinotConfig` seems too general. Suggest renaming it to `TableConfigs` because it wraps only the table related configs
##########
File path: pinot-spi/src/main/java/org/apache/pinot/spi/config/PinotConfig.java
##########
@@ -0,0 +1,76 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.pinot.spi.config;
+
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.core.JsonProcessingException;
+import javax.annotation.Nullable;
+import org.apache.pinot.spi.config.table.TableConfig;
+import org.apache.pinot.spi.data.Schema;
+import org.apache.pinot.spi.utils.JsonUtils;
+
+
+/**
+ * Wrapper for all configs of a table, which include the offline table config, realtime table config and schema.
+ * This helps look at and operate on the pinot configs as a whole unit.
+ */
+public class PinotConfig {
+ private final String _configName;
Review comment:
`_tableName`?
##########
File path: pinot-spi/src/main/java/org/apache/pinot/spi/config/PinotConfig.java
##########
@@ -0,0 +1,76 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.pinot.spi.config;
+
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.core.JsonProcessingException;
+import javax.annotation.Nullable;
+import org.apache.pinot.spi.config.table.TableConfig;
+import org.apache.pinot.spi.data.Schema;
+import org.apache.pinot.spi.utils.JsonUtils;
+
+
+/**
+ * Wrapper for all configs of a table, which include the offline table config, realtime table config and schema.
+ * This helps look at and operate on the pinot configs as a whole unit.
+ */
+public class PinotConfig {
+ private final String _configName;
+ private final TableConfig _offlineTableConfig;
+ private final TableConfig _realtimeTableConfig;
+ private final Schema _schema;
+
+ @JsonCreator
+ public PinotConfig(@JsonProperty(value = "configName", required = true) String configName,
+ @JsonProperty(value = "offlineTableConfig") @Nullable TableConfig offlineTableConfig,
Review comment:
Consider simplify the property name to `offline` and `realtime`
##########
File path: pinot-controller/src/main/java/org/apache/pinot/controller/api/resources/Constants.java
##########
@@ -30,6 +30,7 @@
public static final String CLUSTER_TAG = "Cluster";
public static final String TABLE_TAG = "Table";
+ public static final String CONFIG_TAG = "Config";
Review comment:
`Config` seems too general. I would suggest putting these new endpoints under `Table` and use path a different path, e.g. `/tableconfigs`
##########
File path: pinot-spi/src/main/java/org/apache/pinot/spi/config/PinotConfig.java
##########
@@ -0,0 +1,76 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.pinot.spi.config;
+
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.core.JsonProcessingException;
+import javax.annotation.Nullable;
+import org.apache.pinot.spi.config.table.TableConfig;
+import org.apache.pinot.spi.data.Schema;
+import org.apache.pinot.spi.utils.JsonUtils;
+
+
+/**
+ * Wrapper for all configs of a table, which include the offline table config, realtime table config and schema.
+ * This helps look at and operate on the pinot configs as a whole unit.
+ */
+public class PinotConfig {
+ private final String _configName;
+ private final TableConfig _offlineTableConfig;
+ private final TableConfig _realtimeTableConfig;
+ private final Schema _schema;
+
+ @JsonCreator
+ public PinotConfig(@JsonProperty(value = "configName", required = true) String configName,
+ @JsonProperty(value = "offlineTableConfig") @Nullable TableConfig offlineTableConfig,
+ @JsonProperty(value = "realtimeTableConfig") @Nullable TableConfig realtimeTableConfig,
+ @JsonProperty(value = "schema", required = true) Schema schema) {
Review comment:
(nit) Put schema as the second argument because it's mandatory
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@pinot.apache.org
For additional commands, e-mail: commits-help@pinot.apache.org
[GitHub] [incubator-pinot] codecov-commenter commented on pull request #6840: Configs APIs
Posted by GitBox <gi...@apache.org>.
codecov-commenter commented on pull request #6840:
URL: https://github.com/apache/incubator-pinot/pull/6840#issuecomment-826221712
# [Codecov](https://codecov.io/gh/apache/incubator-pinot/pull/6840?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=The+Apache+Software+Foundation) Report
> Merging [#6840](https://codecov.io/gh/apache/incubator-pinot/pull/6840?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=The+Apache+Software+Foundation) (089e2b3) into [master](https://codecov.io/gh/apache/incubator-pinot/commit/ac5aee70bf25aa4680a115434066287e3456ae71?el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=The+Apache+Software+Foundation) (ac5aee7) will **increase** coverage by `22.28%`.
> The diff coverage is `26.08%`.
[](https://codecov.io/gh/apache/incubator-pinot/pull/6840?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=The+Apache+Software+Foundation)
```diff
@@ Coverage Diff @@
## master #6840 +/- ##
=============================================
+ Coverage 43.52% 65.80% +22.28%
- Complexity 7 12 +5
=============================================
Files 1421 1422 +1
Lines 69142 69288 +146
Branches 9987 9999 +12
=============================================
+ Hits 30093 45597 +15504
+ Misses 36504 20453 -16051
- Partials 2545 3238 +693
```
| Flag | Coverage Δ | Complexity Δ | |
|---|---|---|---|
| integration | `?` | `?` | |
| unittests | `65.80% <26.08%> (?)` | `12.00 <0.00> (?)` | |
Flags with carried forward coverage won't be shown. [Click here](https://docs.codecov.io/docs/carryforward-flags?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=The+Apache+Software+Foundation#carryforward-flags-in-the-pull-request-comment) to find out more.
| [Impacted Files](https://codecov.io/gh/apache/incubator-pinot/pull/6840?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=The+Apache+Software+Foundation) | Coverage Δ | Complexity Δ | |
|---|---|---|---|
| [...ache/pinot/controller/api/resources/Constants.java](https://codecov.io/gh/apache/incubator-pinot/pull/6840/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=The+Apache+Software+Foundation#diff-cGlub3QtY29udHJvbGxlci9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvcGlub3QvY29udHJvbGxlci9hcGkvcmVzb3VyY2VzL0NvbnN0YW50cy5qYXZh) | `21.42% <ø> (ø)` | `0.00 <0.00> (ø)` | |
| [...ller/api/resources/PinotConfigRestletResource.java](https://codecov.io/gh/apache/incubator-pinot/pull/6840/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=The+Apache+Software+Foundation#diff-cGlub3QtY29udHJvbGxlci9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvcGlub3QvY29udHJvbGxlci9hcGkvcmVzb3VyY2VzL1Bpbm90Q29uZmlnUmVzdGxldFJlc291cmNlLmphdmE=) | `0.00% <0.00%> (ø)` | `0.00 <0.00> (?)` | |
| [.../controller/helix/ControllerRequestURLBuilder.java](https://codecov.io/gh/apache/incubator-pinot/pull/6840/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=The+Apache+Software+Foundation#diff-cGlub3QtY29udHJvbGxlci9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvcGlub3QvY29udHJvbGxlci9oZWxpeC9Db250cm9sbGVyUmVxdWVzdFVSTEJ1aWxkZXIuamF2YQ==) | `59.16% <0.00%> (+43.37%)` | `0.00 <0.00> (ø)` | |
| [.../java/org/apache/pinot/spi/config/PinotConfig.java](https://codecov.io/gh/apache/incubator-pinot/pull/6840/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=The+Apache+Software+Foundation#diff-cGlub3Qtc3BpL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9waW5vdC9zcGkvY29uZmlnL1Bpbm90Q29uZmlnLmphdmE=) | `0.00% <0.00%> (ø)` | `0.00 <0.00> (?)` | |
| [...he/pinot/segment/local/utils/TableConfigUtils.java](https://codecov.io/gh/apache/incubator-pinot/pull/6840/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=The+Apache+Software+Foundation#diff-cGlub3Qtc2VnbWVudC1sb2NhbC9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvcGlub3Qvc2VnbWVudC9sb2NhbC91dGlscy9UYWJsZUNvbmZpZ1V0aWxzLmphdmE=) | `78.34% <61.84%> (+25.25%)` | `0.00 <0.00> (ø)` | |
| [...oller/api/resources/PinotTableRestletResource.java](https://codecov.io/gh/apache/incubator-pinot/pull/6840/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=The+Apache+Software+Foundation#diff-cGlub3QtY29udHJvbGxlci9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvcGlub3QvY29udHJvbGxlci9hcGkvcmVzb3VyY2VzL1Bpbm90VGFibGVSZXN0bGV0UmVzb3VyY2UuamF2YQ==) | `58.44% <90.47%> (+27.96%)` | `0.00 <0.00> (ø)` | |
| [...a/org/apache/pinot/minion/metrics/MinionMeter.java](https://codecov.io/gh/apache/incubator-pinot/pull/6840/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=The+Apache+Software+Foundation#diff-cGlub3QtbWluaW9uL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9waW5vdC9taW5pb24vbWV0cmljcy9NaW5pb25NZXRlci5qYXZh) | `0.00% <0.00%> (-100.00%)` | `0.00% <0.00%> (ø%)` | |
| [.../apache/pinot/common/metrics/BrokerQueryPhase.java](https://codecov.io/gh/apache/incubator-pinot/pull/6840/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=The+Apache+Software+Foundation#diff-cGlub3QtY29tbW9uL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9waW5vdC9jb21tb24vbWV0cmljcy9Ccm9rZXJRdWVyeVBoYXNlLmphdmE=) | `0.00% <0.00%> (-100.00%)` | `0.00% <0.00%> (ø%)` | |
| [.../apache/pinot/minion/metrics/MinionQueryPhase.java](https://codecov.io/gh/apache/incubator-pinot/pull/6840/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=The+Apache+Software+Foundation#diff-cGlub3QtbWluaW9uL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9waW5vdC9taW5pb24vbWV0cmljcy9NaW5pb25RdWVyeVBoYXNlLmphdmE=) | `0.00% <0.00%> (-100.00%)` | `0.00% <0.00%> (ø%)` | |
| [...pache/pinot/common/utils/grpc/GrpcQueryClient.java](https://codecov.io/gh/apache/incubator-pinot/pull/6840/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=The+Apache+Software+Foundation#diff-cGlub3QtY29tbW9uL3NyYy9tYWluL2phdmEvb3JnL2FwYWNoZS9waW5vdC9jb21tb24vdXRpbHMvZ3JwYy9HcnBjUXVlcnlDbGllbnQuamF2YQ==) | `0.00% <0.00%> (-100.00%)` | `0.00% <0.00%> (ø%)` | |
| ... and [1073 more](https://codecov.io/gh/apache/incubator-pinot/pull/6840/diff?src=pr&el=tree-more&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=The+Apache+Software+Foundation) | |
------
[Continue to review full report at Codecov](https://codecov.io/gh/apache/incubator-pinot/pull/6840?src=pr&el=continue&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=The+Apache+Software+Foundation).
> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=The+Apache+Software+Foundation)
> `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
> Powered by [Codecov](https://codecov.io/gh/apache/incubator-pinot/pull/6840?src=pr&el=footer&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=The+Apache+Software+Foundation). Last update [ac5aee7...089e2b3](https://codecov.io/gh/apache/incubator-pinot/pull/6840?src=pr&el=lastupdated&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=The+Apache+Software+Foundation). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=The+Apache+Software+Foundation).
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@pinot.apache.org
For additional commands, e-mail: commits-help@pinot.apache.org
[GitHub] [incubator-pinot] Jackie-Jiang commented on a change in pull request #6840: Configs APIs
Posted by GitBox <gi...@apache.org>.
Jackie-Jiang commented on a change in pull request #6840:
URL: https://github.com/apache/incubator-pinot/pull/6840#discussion_r619885268
##########
File path: pinot-spi/src/main/java/org/apache/pinot/spi/config/PinotConfig.java
##########
@@ -0,0 +1,76 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.pinot.spi.config;
+
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.core.JsonProcessingException;
+import javax.annotation.Nullable;
+import org.apache.pinot.spi.config.table.TableConfig;
+import org.apache.pinot.spi.data.Schema;
+import org.apache.pinot.spi.utils.JsonUtils;
+
+
+/**
+ * Wrapper for all configs of a table, which include the offline table config, realtime table config and schema.
+ * This helps look at and operate on the pinot configs as a whole unit.
+ */
+public class PinotConfig {
Review comment:
Extend `BaseJsonConfig` which contains the basic json related methods
##########
File path: pinot-spi/src/main/java/org/apache/pinot/spi/config/PinotConfig.java
##########
@@ -0,0 +1,76 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.pinot.spi.config;
+
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.core.JsonProcessingException;
+import javax.annotation.Nullable;
+import org.apache.pinot.spi.config.table.TableConfig;
+import org.apache.pinot.spi.data.Schema;
+import org.apache.pinot.spi.utils.JsonUtils;
+
+
+/**
+ * Wrapper for all configs of a table, which include the offline table config, realtime table config and schema.
+ * This helps look at and operate on the pinot configs as a whole unit.
+ */
+public class PinotConfig {
Review comment:
`PinotConfig` seems too general. Suggest renaming it to `TableConfigs` because it wraps only the table related configs
##########
File path: pinot-spi/src/main/java/org/apache/pinot/spi/config/PinotConfig.java
##########
@@ -0,0 +1,76 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.pinot.spi.config;
+
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.core.JsonProcessingException;
+import javax.annotation.Nullable;
+import org.apache.pinot.spi.config.table.TableConfig;
+import org.apache.pinot.spi.data.Schema;
+import org.apache.pinot.spi.utils.JsonUtils;
+
+
+/**
+ * Wrapper for all configs of a table, which include the offline table config, realtime table config and schema.
+ * This helps look at and operate on the pinot configs as a whole unit.
+ */
+public class PinotConfig {
+ private final String _configName;
Review comment:
`_tableName`?
##########
File path: pinot-spi/src/main/java/org/apache/pinot/spi/config/PinotConfig.java
##########
@@ -0,0 +1,76 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.pinot.spi.config;
+
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.core.JsonProcessingException;
+import javax.annotation.Nullable;
+import org.apache.pinot.spi.config.table.TableConfig;
+import org.apache.pinot.spi.data.Schema;
+import org.apache.pinot.spi.utils.JsonUtils;
+
+
+/**
+ * Wrapper for all configs of a table, which include the offline table config, realtime table config and schema.
+ * This helps look at and operate on the pinot configs as a whole unit.
+ */
+public class PinotConfig {
+ private final String _configName;
+ private final TableConfig _offlineTableConfig;
+ private final TableConfig _realtimeTableConfig;
+ private final Schema _schema;
+
+ @JsonCreator
+ public PinotConfig(@JsonProperty(value = "configName", required = true) String configName,
+ @JsonProperty(value = "offlineTableConfig") @Nullable TableConfig offlineTableConfig,
Review comment:
Consider simplify the property name to `offline` and `realtime`
##########
File path: pinot-controller/src/main/java/org/apache/pinot/controller/api/resources/Constants.java
##########
@@ -30,6 +30,7 @@
public static final String CLUSTER_TAG = "Cluster";
public static final String TABLE_TAG = "Table";
+ public static final String CONFIG_TAG = "Config";
Review comment:
`Config` seems too general. I would suggest putting these new endpoints under `Table` and use path a different path, e.g. `/tableconfigs`
##########
File path: pinot-spi/src/main/java/org/apache/pinot/spi/config/PinotConfig.java
##########
@@ -0,0 +1,76 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.pinot.spi.config;
+
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.core.JsonProcessingException;
+import javax.annotation.Nullable;
+import org.apache.pinot.spi.config.table.TableConfig;
+import org.apache.pinot.spi.data.Schema;
+import org.apache.pinot.spi.utils.JsonUtils;
+
+
+/**
+ * Wrapper for all configs of a table, which include the offline table config, realtime table config and schema.
+ * This helps look at and operate on the pinot configs as a whole unit.
+ */
+public class PinotConfig {
+ private final String _configName;
+ private final TableConfig _offlineTableConfig;
+ private final TableConfig _realtimeTableConfig;
+ private final Schema _schema;
+
+ @JsonCreator
+ public PinotConfig(@JsonProperty(value = "configName", required = true) String configName,
+ @JsonProperty(value = "offlineTableConfig") @Nullable TableConfig offlineTableConfig,
+ @JsonProperty(value = "realtimeTableConfig") @Nullable TableConfig realtimeTableConfig,
+ @JsonProperty(value = "schema", required = true) Schema schema) {
Review comment:
(nit) Put schema as the second argument because it's mandatory
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@pinot.apache.org
For additional commands, e-mail: commits-help@pinot.apache.org