Apicurio / apicurio-registry

An API/Schema registry - stores APIs and Schemas.
https://www.apicur.io/registry/
Apache License 2.0
587 stars 260 forks source link

Override default base URL's for accessing Apicurio registry UI #1672

Open kallimaniamit opened 3 years ago

kallimaniamit commented 3 years ago

Subject of the issue Override default base URL's for accessing Apicurio registry UI I have deployed Apicurio docker image(apicurio/apicurio-registry-sql:2.0.0.Final) with postgres dependency in kubernetes. Currently we access any service deployed in dev kubernetes cluster using this format : "https://services-kube-dev-wdl.ilnx.com/middleware-test-il-apicurio-service/".

After successful deployment, I tried to access apicurio ui using URL : https://services-kube-dev-wdl.ilnx.com/middleware-test-il-apicurio-service/ui but its getting redirected to the URL : https://services-kube-dev-wdl.ilnx.com/ui

Can somebody help how to avoid this redirection from https://services-kube-dev-wdl.ilnx.com/middleware-test-il-apicurio-service/ui to https://services-kube-dev-wdl.ilnx.com/ui

Tried below thing but it is not working: set environment variable : REGISTRY_UI_CONFIG_UIURL="https://services-kube-dev-wdl.ilnx.com/middleware-test-il-apicurio-service" for kubernetes deployment.(overrides default url's) link : https://www.apicur.io/registry/docs/apicurio-registry/2.0.1.Final/getting-started/assembly-managing-registry-artifacts-ui.html

EricWittmann commented 3 years ago

Oh interesting. So basically if I'm reading this correctly, you have added a context path. What happens if you go here:

https://services-kube-dev-wdl.ilnx.com/middleware-test-il-apicurio-service/ui

Does that also redirect you?

EricWittmann commented 3 years ago

I'm guessing that will not redirect you but will also probably not work. I think we may be making some strong assumptions about where the UI lives relative to the root context. This may not work without modifications to the application.

Some details:

Initial Redirect to /ui

The initial redirect you are hitting comes from here: https://github.com/Apicurio/apicurio-registry/blob/master/app/src/main/resources-unfiltered/META-INF/resources/index.html#L7

We may be able to change that to be a relative path redirect so that it works under this use-case. We'll need to test that.

React App config

For the React application to work properly, I think the host index.html file needs to know its location. Because I think single-page application navigation needs to have the base href set, like here:

https://github.com/Apicurio/apicurio-registry/blob/master/ui/src/index.html#L7

You'll notice that points to "/" rather than "/ui/". The reason is that when running the UI in dev mode, we need it set to "/", but when packaged up as part of the deployed application it needs to be "/ui/". So we dynamically set that here:

https://github.com/Apicurio/apicurio-registry/blob/master/app/src/main/java/io/apicurio/registry/ui/servlets/BaseHrefFilter.java#L67

I think we would need to make this configurable instead of hard-coded to "/ui/".

Additionally, when reloading a non-root page in the UI (e.g. any page with additional path elements) the application needs to actually load the React host index.html file - so we have a servlet for that here:

https://github.com/Apicurio/apicurio-registry/blob/master/app/src/main/java/io/apicurio/registry/ui/servlets/ReactAppServlet.java#L39

Conclusion

I suspect that for this use-case to be supported, we will need to make the changes above. The trick for us will be how to configure a test environment to actually test whatever support we implement. Clearly we will need to make some of our servlets/filters configurable so they no longer assume the UI is deployed to /ui. Beyond that, testing is needed.

kallimaniamit commented 3 years ago

Is there plan to make this "/ui" configurable instead of hard-coded to "/ui/". defined in this class : https://github.com/Apicurio/apicurio-registry/blob/master/app/src/main/java/io/apicurio/registry/ui/servlets/BaseHrefFilter.java#L67

EricWittmann commented 3 years ago

Right, see my analysis in the comment above. We didn't have any plans to do that before, since this is the first time it's been an issue. But it seems like a reasonable and easy thing to do.

zapho commented 1 year ago

Hi. We're planning to use apicurio registry (2.0.0.Final) behind a reverse proxy where it must be accessed through a specific sub path (e.g. https://my-reverse-proxy/sub/path/schema-registry. The reverse proxy the forwards the call to http://apicurio-instance:8080 Currently this is not working:

javax.ws.rs.NotFoundException: RESTEASY003210: Could not find resource for full path: http://my-reverse-proxy/sub/path/schema-registry

I tried to tune this with REGISTRY_UI_CONFIG_APIURL and REGISTRY_UI_CONFIG_UIURL but to no avail.

Is there some configuration to apply to support the change of root path or, as this issue suggests, apicurio registry does not support this scenario?

Thanks.

Prop4et commented 3 months ago

The workaround i found to make it work (partially) behind emissary ingress is to have:

mlosicki commented 3 months ago

@Prop4et I tried your setup on docker-compose + HAProxy and observe the same thing. What fixes it for me is:

      - REGISTRY_UI_CONFIG_UI_CONTEXT_PATH=/kafka-registry/ui/

If you look at the 2.6.x branch, the only reference to REGISTRY_UI_CONFIG_UIURL property is in the docs. The code uses registry.ui.config.uiContextPath=${REGISTRY_UI_CONFIG_UI_CONTEXT_PATH:/ui/} which what needs to be set.

However, I still observe 2 issues:

HTTPS proxy

I reconfigure my (working) HTTP HAProxy as follows:

      - REGISTRY_URL_OVERRIDE_PORT=9043
      - REGISTRY_UI_CONFIG_APIURL=https://localhost:9043/kafka-registry/apis/registry

If I try to upload an artifact, I get "Access permissions needed" and a 403 on the POST https://localhost:9043/apicurio/apis/registry/v2/groups/$group/artifacts request. If I try the same with a http proxy, it works just fine. Maybe this is related to https://github.com/Apicurio/apicurio-registry/issues/4446 ?

API doc

If I visit the API Docs via my https proxy, it "works" but the css/js etc. are not loaded correctly, they ignore the new context path. For example, visiting https://localhost:9043/apicurio/apis/registry/v2 tries to load https://localhost:9043/resources/js/redoc.standalone.js which fails since it misses the context path. There's a BaseHrefFilter that rewrites the base path (using those properties above) which is what makes the /ui/ path work, but there's no <base> tag in the index.html, so all other resources besides the index.html are not loaded correctly (I think).

BTW, wouldn't it be simpler if the proxy itself communicates what is the correct url using X-Forwarded* headers instead of those absolute URLs and other env vars above? Looking at URLUtil, there's already some support for that, but it is missing X-Forwarded-Port and X-Forwarded-Prefix. With those two added, it should be possible to reconstruct the full external URL "dynamically" i.e. without any preconfigured env vars no?

PS

This is a Quarkus app, so one could also override the value of registry.ui.config.uiContextPath with REGISTRY_UI_CONFIG_UICONTEXTPATH=.... Quarkus docs explain how to set those params via env vars (which take priority over the application.properties file). If you are confused what is set to what (like I was), you can configure logging as follows: ``` - QUARKUS_CONFIG_LOG_VALUES=true - QUARKUS_LOG_CATEGORY__IO_SMALLRYE_CONFIG__LEVEL=DEBUG - QUARKUS_LOG_CATEGORY__IO_APICURIO_REGISTRY_UI__LEVEL=DEBUG ``` Note that you need relatively recent Quarkus version for this (tested on Quarkus 3.8.4).

Prop4et commented 2 months ago

Late response 'cause i forgot. With REGISTRY_UI_CONFIG_UI_CONTEXT_PATH configured instead of REGISTRY_UI_CONFIG_UIURL the registry interactions work smoothly with all the other bits of configuration i shared before. Thanks a lot for that, i looked for something like that for a while but seems like i looked at the wrong thing. I omitted that in what i shared i override the java_opts to add the origins that i need to avoid the 403 error. I didn't share that because i am actually deploying everything on a k8s cluster so i don't know how much it could fix other configurations I know about the quarkus app and all that stuff (i'm actually developing things with quarkus) but i wanted to keep the whole thing the closest possible to the original existing image