You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Enhance iceberg-go to Support Nessie API for All Catalog Operations #291
The current Catalog interface in iceberg-go is designed for the Iceberg REST catalog, but it does not fully align with Project Nessie’s API requirements. Nessie uses different API paths, request payloads, and reference (branch/tag) handling, which needs adjustments across all catalog operations. And it has different API versions too.
For example, Namespace Creation
CreateNamespace function in catalog/rest.go uses POST method while nessie v1 api uses PUT method
API PATH is also different. I have seen similar issues with multiple functions
I am willing to make changes to support Nessie apis, would appreciate some guidance on how to go about it?
Should we modify current catalog/rest
Use ref and other required params from context.Context for Nessie API.
Dynamically determine API paths based on whether Nessie or Iceberg REST Catalog is being used.
Create a new catalog/nessie to support and maintain nessie specific functionality separately
@Fokko@kevinjqliu can you two chime in here? My personal opinion is that we were following the REST spec, so if Nessie isn't following the REST spec, we should do a separate catalog. But, is this actually just a case where Nessie was being more strict than the spec necessarily required? Were we not actually following the spec correctly? Or is Nessie just wrong?
hey @zeroshade thats a great question. Based on my understanding, Nessie has 2 sets of APIs, its own catalog API and an Iceberg REST compliant API.
Heres the nessie docs on iceberg rest api https://projectnessie.org/guides/try-nessie/
Based on this comment, Nessie should have support for Iceberg REST API. In fact, there are many users of pyiceberg interacting with Nessie.
There are subtle difference in behaviors. One big one is apache/iceberg-python#1105 where Nessie only shows 1 snapshot. This is part of the Nessie implementation so not much we can do.
@shubham-tomar Given that users are using pyiceberg with nessie without needing separate changes to behavior, and iceberg-go is compliant with the REST api (as I based the implementation on pyiceberg), do we actually need changes to the behaviors to support nessie?
Since iceberg-go is a client library for the Apache Iceberg project, I would say adding the custom catalog implementation for Nessie native API's is out of scope. Perhaps the implementation can be adopted by the Nessie project itself
I'd say the same. Just wanted to get other opinions to make sure i'm not alone on that one. The catalog package makes it easy to register new implementations so that any other project (or separate repo) could potentially embed the REST catalog and then override the necessary changes for Nessie's specific features rather than us having to maintain it here.
I want to use Nessie as a catalog for Iceberg in my data pipeline, which is entirely written in Go. Given the discussion around my PR, I want to clarify the best approach moving forward.
Would it make sense to fork iceberg-go and create a dedicated catalog/nessie package that:
Implements Nessie-specific API paths and structures while keeping compatibility with Iceberg.
Use the core functionalities of iceberg-go, ensuring minimal duplication and consistency with the Iceberg ecosystem.
This way, I wouldn’t modify catalog/rest directly but instead build a separate Nessie catalog implementation within my fork. Does this sound like the right approach, or do you have alternative recommendations?
Essentially i wanted to use Nessie for branching logic, and iceberg-go for data CRUD operations
@shubham-tomar you don't need to fork iceberg-go. You simply just need to implement the catalog interface. Once you register the catalog with the registry, you can use it with the rest of the iceberg-go library as-is.
That's why it's separated using the interfaces. You won't need to fork the whole library (and you shouldn't!)
This URI seems wrong? http://localhost:19120/iceberg/v1/main%7Cs3%3A%2F%2Fwarehouse/namespaces/my_namespace_1/tables
Looking at Nessie's API description, i'm not seeing /v1/main anywhere in the REST api, it also seems wrong that it would include s3://warehouse/..... in the URI. Is this using the existing REST catalog in iceberg-go or your custom catalog for nessie interactions?
I am using the existing catalog/rest (not my custom nessie code)
It is the Prefix which is being added, but the same URI is used to create and list namespaces (which is working)
> go run main.go
Ignoring extension file:unknown.yaml err:failure reading YAML failed to parse unknown as FuncDefArgType, Skipping it
DEBUG: Inside init
DEBUG: uri -> http://localhost:19120/iceberg
DEBUG: r.baseURI, r.props -> http://localhost:19120/iceberg/v1/main%7Cs3%3A%2F%2Fwarehouse map[prefix:main%7Cs3%3A%2F%2Fwarehouse warehouse:s3://warehouse]
DEBUG: ops.prefix -> main%7Cs3%3A%2F%2Fwarehouse
Successfully Loaded catalog: &{0x14000145d40 0x14000262810 nessieCatalog map[prefix:main%7Cs3%3A%2F%2Fwarehouse warehouse:s3://warehouse]}
DEBUG: Inside ListNamespaces
- [my_namespace_1]
DEBUG: Inside CreateTable
DEBUG: ns, tbl, r.baseURI -> my_namespace_1 iceberg_table_1 http://localhost:19120/iceberg/v1/main%7Cs3%3A%2F%2Fwarehouse
2025/02/16 18:46:50 Failed to create table: failed to create table: WebApplicationException: HTTP 400 Bad Request
In Nessie logs, i can see this error problem: Cannot build IcebergCreateTableRequest, some of required attributes are not set [stageCreate]
nessie | 2025-02-17 10:27:54,004 INFO [io.qua.htt.access-log] (executor-thread-1) 192.168.65.1 - - [17/Feb/2025:10:27:54 +0000] "GET /iceberg/v1/config?warehouse=s3%3A%2F%2Fwarehouse HTTP/1.1" 200 1591
nessie | 2025-02-17 10:27:54,017 INFO [io.qua.htt.access-log] (executor-thread-1) 192.168.65.1 - - [17/Feb/2025:10:27:54 +0000] "GET /iceberg/v1/main%7Cs3%3A%2F%2Fwarehouse/namespaces HTTP/1.1" 200 73
nessie | 2025-02-17 10:27:54,021 WARN [org.pro.cat.ser.res.IcebergErrorMapper] (executor-thread-1) Unhandled exception returned as HTTP/500: jakarta.ws.rs.WebApplicationException: HTTP 400 Bad Request: jakarta.ws.rs.WebApplicationException: HTTP 400 Bad Request
nessie | Caused by: com.fasterxml.jackson.databind.exc.ValueInstantiationException: Cannot construct instance of `org.projectnessie.catalog.formats.iceberg.rest.ImmutableIcebergCreateTableRequest`, problem: Cannot build IcebergCreateTableRequest, some of required attributes are not set [stageCreate]
nessie | at [Source: REDACTED (`StreamReadFeature.INCLUDE_SOURCE_IN_LOCATION` disabled); line: 1, column: 556]
nessie | at com.fasterxml.jackson.databind.exc.ValueInstantiationException.from(ValueInstantiationException.java:47)
If i set this StageCreate: true it is able to create table but since it is stage create i am not able to see this in catalog
if i try to register it it is failing
failed to register table: failed to register table: NoSuchTableException: Table does not exist: my_namespace_1.iceberg_table_1
in nessie logs, it gives 404 maybe because iceberg_table_1 does not exist
Thank you @zeroshade , i have shared my docker-compose file above in the comments, let me know if you would need any other info for reproducing this.
Meanwhile i will also look if i can find something.
You're right, looks like a mistake on our end here. It should definitely be source and destination go ahead and add it to the same PR! I should look into trying to create an integration test framework so that we can ensure that the methods are correct
This URI seems wrong? http://localhost:19120/iceberg/v1/main%7Cs3%3A%2F%2Fwarehouse/namespaces/my_namespace_1/tables
Looking at Nessie's API description, i'm not seeing /v1/main anywhere in the REST api, it also seems wrong that it would include s3://warehouse/..... in the URI. Is this using the existing REST catalog in iceberg-go or your custom catalog for nessie interactions?
This is the issue that many people are running into. Is that endpoint wrong? This is what I get when I try to load_catalog, and I get a 404. Others apparently do not.
This is the issue that many people are running into. Is that endpoint wrong? This is what I get when I try to load_catalog, and I get a 404. Others apparently do not.
In my case there was issue with my local nessie config, that weired thing main%7Cs3%3A%2F%2Fwarehouse
is prefix which was being added to the uri because i was sending warehouse path and all which is not required
You're right, looks like a mistake on our end here. It should definitely be source and destination go ahead and add it to the same PR! I should look into trying to create an integration test framework so that we can ensure that the methods are correct
Activity
shubham-tomar commentedon Feb 9, 2025
I have created a PR to support Nessie via catalog/rest (namespace related functionalities)
zeroshade commentedon Feb 10, 2025
@Fokko @kevinjqliu can you two chime in here? My personal opinion is that we were following the REST spec, so if Nessie isn't following the REST spec, we should do a separate catalog. But, is this actually just a case where Nessie was being more strict than the spec necessarily required? Were we not actually following the spec correctly? Or is Nessie just wrong?
kevinjqliu commentedon Feb 10, 2025
hey @zeroshade thats a great question. Based on my understanding, Nessie has 2 sets of APIs, its own catalog API and an Iceberg REST compliant API.
Heres the nessie docs on iceberg rest api https://projectnessie.org/guides/try-nessie/
Based on this comment, Nessie should have support for Iceberg REST API. In fact, there are many users of pyiceberg interacting with Nessie.
There are subtle difference in behaviors. One big one is apache/iceberg-python#1105 where Nessie only shows 1 snapshot. This is part of the Nessie implementation so not much we can do.
zeroshade commentedon Feb 10, 2025
@shubham-tomar Given that users are using pyiceberg with nessie without needing separate changes to behavior, and iceberg-go is compliant with the REST api (as I based the implementation on pyiceberg), do we actually need changes to the behaviors to support nessie?
kevinjqliu commentedon Feb 10, 2025
Since iceberg-go is a client library for the Apache Iceberg project, I would say adding the custom catalog implementation for Nessie native API's is out of scope. Perhaps the implementation can be adopted by the Nessie project itself
zeroshade commentedon Feb 10, 2025
I'd say the same. Just wanted to get other opinions to make sure i'm not alone on that one. The catalog package makes it easy to register new implementations so that any other project (or separate repo) could potentially embed the REST catalog and then override the necessary changes for Nessie's specific features rather than us having to maintain it here.
I'll comment on the PR accordingly.
shubham-tomar commentedon Feb 12, 2025
Hi @zeroshade, @kevinjqliu,
I want to use Nessie as a catalog for Iceberg in my data pipeline, which is entirely written in Go. Given the discussion around my PR, I want to clarify the best approach moving forward.
Would it make sense to fork iceberg-go and create a dedicated catalog/nessie package that:
This way, I wouldn’t modify catalog/rest directly but instead build a separate Nessie catalog implementation within my fork. Does this sound like the right approach, or do you have alternative recommendations?
Essentially i wanted to use Nessie for branching logic, and iceberg-go for data CRUD operations
Thanks for your guidance!
kevinjqliu commentedon Feb 12, 2025
Yes you're essentially building a "nessie-go-client" based off of the Nessie REST API, which is different from Iceberg's REST API
Nessie already has 2 other clients, python and java
zeroshade commentedon Feb 12, 2025
@shubham-tomar you don't need to fork iceberg-go. You simply just need to implement the catalog interface. Once you register the catalog with the registry, you can use it with the rest of the iceberg-go library as-is.
That's why it's separated using the interfaces. You won't need to fork the whole library (and you shouldn't!)
shubham-tomar commentedon Feb 12, 2025
Got it, thank you for your guidance.
zeroshade commentedon Feb 12, 2025
@shubham-tomar If you end up needing help, please reach out because I would really prefer to avoid needing to fork this whole lib 😄
shubham-tomar commentedon Feb 15, 2025
Hi @zeroshade, i am facing issue while creating table
This is how i am loading catalog
Successfully Loaded catalog: &{0x14000aef710 0x14000b02270 nessieCatalog map[prefix:main%7Cs3%3A%2F%2Fwarehouse warehouse:s3://warehouse]}
Do endpoint: http://localhost:19120/iceberg/v1/main%7Cs3%3A%2F%2Fwarehouse/namespaces
i am able to create and List Namespace,
Create Table function
I have add logs in catalog/rest for debugging and getting this
Looks like some s3 config is missing but i am not able to figure out what exactly is missing, let me know
My nessie and minio configs
zeroshade commentedon Feb 15, 2025
This URI seems wrong?
http://localhost:19120/iceberg/v1/main%7Cs3%3A%2F%2Fwarehouse/namespaces/my_namespace_1/tablesLooking at Nessie's API description, i'm not seeing
/v1/mainanywhere in the REST api, it also seems wrong that it would includes3://warehouse/.....in the URI. Is this using the existing REST catalog in iceberg-go or your custom catalog for nessie interactions?shubham-tomar commentedon Feb 16, 2025
I am using the existing catalog/rest (not my custom nessie code)
It is the Prefix which is being added, but the same URI is used to create and list namespaces (which is working)
In Nessie logs, i can see this error
problem: Cannot build IcebergCreateTableRequest, some of required attributes are not set [stageCreate]
shubham-tomar commentedon Feb 17, 2025
If i set this StageCreate: true it is able to create table but since it is stage create i am not able to see this in catalog
if i try to register it it is failing
in nessie logs, it gives 404 maybe because iceberg_table_1 does not exist
how to go about it
zeroshade commentedon Feb 17, 2025
I'll see if i can find some time this week to spin up a nessie catalog myself and see if I can figure out what's going wrong
shubham-tomar commentedon Feb 18, 2025
Thank you @zeroshade , i have shared my docker-compose file above in the comments, let me know if you would need any other info for reproducing this.
Meanwhile i will also look if i can find something.
shubham-tomar commentedon Feb 19, 2025
Hi @zeroshade, i think i found the issue, it is rather very small fix
PR:link
shubham-tomar commentedon Feb 19, 2025
Also, i faced issue with RenameTable function
type payload struct {
Source identifier
json:"source"Destination identifier
json:"destination"}
above payload works but we have from, to, is this changed recently? should i add this in the same PR?
zeroshade commentedon Feb 19, 2025
You're right, looks like a mistake on our end here. It should definitely be
sourceanddestinationgo ahead and add it to the same PR! I should look into trying to create an integration test framework so that we can ensure that the methods are correctadamcodes716 commentedon Feb 19, 2025
This is the issue that many people are running into. Is that endpoint wrong? This is what I get when I try to load_catalog, and I get a 404. Others apparently do not.
shubham-tomar commentedon Feb 20, 2025
In my case there was issue with my local nessie config, that weired thing main%7Cs3%3A%2F%2Fwarehouse
is prefix which was being added to the uri because i was sending warehouse path and all which is not required
below function implementation works for me
shubham-tomar commentedon Feb 20, 2025
Done
ci(catalog/rest): initial framework for rest catalog integration tests (