-
-
Notifications
You must be signed in to change notification settings - Fork 427
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[WIP] Use OSGi Compendium R7 JAX-RS Whiteboard pattern for REST #739
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Seems to clean up some stuff.
As org.openhab.core.io.rest.sitemap
and org.openhab.core.io.rest.sse
already use glassfish
API, we could also use it here -- IMHO.
It seems Travis and Jenkins CI build fail.
The REST documentation provided by Swagger still works? Okay, you already have written, it need "probably" an update... Did you check?
if (configuration != null) { | ||
Dictionary properties = configuration.getProperties(); | ||
public void activate(Map<String, Object> properties) { | ||
restRoot = (String) properties.getOrDefault(Constants.ROOT_PROPERTY, RESTConstants.REST_URI); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Another option would be to call toString()
instead of this cast. I assume it could also be a number if I set 123
in the configuration file.
httpService.registerServlet(restRoot, servletContainer, initParams, null); | ||
logger.info("openHAB REST started on {}", restRoot); | ||
} catch (ServletException | NamespaceException e) { | ||
logger.warn("Could not start REST API on {}: {}", restRoot, e.getMessage(), e); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does it make sense to catch that exception?
Shouldn't the caller be informed that the activation failed?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That depends if we see REST as essential. But yeah I'll change that
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My understanding has been that the root resource is exactly used for this purpose (REST).
Does it provide any other stuff, so it would make sense to mark it active
if the ServletException
or NamespaceException
has been thrown. So, does the service make sense without the servlet registration succeeded?
/** | ||
* Debounce reloading of the servlet container | ||
*/ | ||
private void scheduleReload() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Are you sure that all methods called by SCR will be called from the same thread?
If we want to be on the safe side, we could add a synchronized to that method.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It should be the one and only service resolution thread in my naive assumption, but yes I agree. That should be synchronized
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
IIRC there has been already some comments about that topic.
There is no word in the spec that optional dependencies and the activation etc. are called from the same thread (AFAIK -- but I could be wrong).
The The replaced dependency was also using the ServletContainer so I'm not introducing new dependencies to the table. |
This pull request has been mentioned on openHAB Community. There might be relevant details there: https://community.openhab.org/t/setup-maintenance-a-paper-ui-replacement-proposal/72614/7 |
I don't know.
My comment should already state that it is okay for me. 😉 |
protected void setConfigurationAdmin(ConfigurationAdmin configurationAdmin) { | ||
this.configurationAdmin = configurationAdmin; | ||
@Override | ||
public String getRESTroot() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
CamelCase -> getRESTRoot
* | ||
* @author David Graeff - Initial contribution | ||
*/ | ||
public interface RESTservice { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
CamelCase -> RESTService
* @author David Graeff - Initial contribution | ||
*/ | ||
public interface RESTservice { | ||
String getRESTroot(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
-> getRESTRoot
protected @NonNullByDefault({}) HttpService httpService; | ||
private @NonNullByDefault({}) ServletContainer servletContainer; | ||
|
||
private final ScheduledExecutorService scheduler = Executors.newSingleThreadScheduledExecutor(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This adds a permanent additional (and during runtime idle) thread. I'd prefer to instead use the common thread pool for this job.
I had a good read on OSGi core and compendium releases recently and I'm proposing another solution later that day. It builds on JAX-RS 2.1 for SSE (This closes #743) and the JAX-RS Whiteboard Pattern for REST. |
There has been already some work on a Karaf feature for the whiteboard pattern (see Karaf mailing list). |
Fortunately the JAX-RS whiteboard pattern is part of the compendium specification. We don't need a R7 OSGi core. I will try to remove pax-web or jersey while I'm on it. We don't need 3 competing javax.servlet providing libraries. |
@davidgraeff Did you move forward? |
I have a branch that fully works with the R7 compendium Jax-RS whiteboard pattern. Everything based on the standard API, no glassfish or other implemention specific stuff. I need to adapt this PR's title & description. It is a few more lines to review, because I'm using the newest variant of jax-rs and reworked our REST bundles. SLOC are dropped by 3k. I just didn't came to test all the finicky SSE parts with the Sitemap bundle, where you register a client first etc. That's so much antipattern, so not really supported by how Jax-RS SSE works, and I think websockets should have been used here. That's why I'm so unmotivated to finish this bundle also considering that sitemaps will be dropped. |
* Remove all associated quirks and workarounds ("core.io.rest.optimize") * Simplify RootResource of org.openhab.core.io.rest. We don't need to update osgi-jax-rs-connector's configuration anymore. * Add JerseyServletContainerInitializer to satisfy pax-web. Should be removed when pax-web is not used anymore. * Update all REST bundles to use proper Jax-RS API The RESTdoc bundle in the webui repo probably requires an update to accomodate Signed-off-by: David Graeff <[email protected]>
Signed-off-by: David Graeff <[email protected]>
} else { | ||
try { | ||
return TransformationHelper.isTransform(pattern) | ||
? new StateDescription(desc.getMinimum(), desc.getMaximum(), desc.getStep(), "", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I need to cheery pick #655 changes and apply them to this file again.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wouldn't it make sense to rebase the working branch on a regular basis?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I rebased, but for this particular file I chose to just take mine to not break the PR. But will reapply the made changes.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why will this PR be broken if you rebase to the master?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Again: I have rebased. Just for this one file I had conflicts that I didn't feel comfortable to hackish resolve them, so I just kept my changes, but annotated with a comment to remind me to cheery pick the changes back.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I had only a few minutes, ...
Will have a look at the next days.
Or you ping me if you think you are finished.
<dependency> | ||
<groupId>org.osgi</groupId> | ||
<artifactId>org.osgi.service.jaxrs</artifactId> | ||
<version>1.0.0</version> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That should be already part of org.osgi:osgi.cmpn:7.0.0
(declared above).
<scope>compile</scope> | ||
</dependency> | ||
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
trailing whitespaces
protected void unsetLocaleService(LocaleService localeService) { | ||
this.localeService = null; | ||
} | ||
@Component(immediate = true) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For here and other places: I assume immediate = true
is not necessary at all if the whiteboard pattern is used.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That might be true, not sure.
In contrast to the pure whiteboard pattern found in literature the jax-rs application is created procedural, via code, and not declarative. That's done to be able to change the root path of the application. And I don't know exactly if the components must be started for this to work.
this.localeService = null; | ||
} | ||
@Component(immediate = true) | ||
@JaxrsApplicationSelect("(osgi.jaxrs.name=" + RESTService.REST_APP_NAME + ")") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For here and other places: Shouldn't something similar to
@JaxrsApplicationSelect
@JaxrsName(RESTService.REST_APP_NAME)
work too?
My understanding has been that the property type has been introduced to not use constructs like "(osgi.jaxrs.name=" + RESTService.REST_APP_NAME + ")"
anymore.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes I guess so. Eclipse just went nuts on me and didn't resolve JaxrsName
when I made those changes.
What's the current state here? I didn't look into the details, but it feels to be a risky change, while if all works out, it is a worthwhile cleanup of the code base. Background of my question is #597: This seems to be a rather critical issue by now as it occurs almost on every initial setup. If this PR here might soon be ready, we could check if it solves this problem on the way - if not, we will probably have to invest time to solve it in the current code base. |
It will probably fix the issue. The Jax-rs implementation independent SSE parts are used. But I'm also stuck because of SSE. It was used in the sitemaps part in a way that it was not intended to be used and the API does not allow the same pattern. |
This pull request has been mentioned on openHAB Community. There might be relevant details there: https://community.openhab.org/t/problem-install-eclipse-ide/75140/22 |
I will not continue to work on this PR. So it might be closed or taken over :) |
@davidgraeff That's really sad. |
Exactly. Unfortunately that makes OH unattractive to me. I picked OH because I had hoped to benefit from synergistic effects. Instead I wrote or rewrote all required addons myself (MQTT, Network Binding, Yamaha Binding, Hue Emulation, Deconz, Hue). That's not an issue itself, the community benefits, was my thought. But this phobic clinging to old concepts here in core is what turns me away tbh. I see huge problems with the current REST interface (openhab/openhab-webui#24 (comment) for details) and updating the software stack is just the tip of the iceberg. And I don't see that changing, now that Yannick has written a new UI that again uses Sitemaps (sigh...). |
I assume I don't share all your motivation or thinking about a fast moving target as I also need to support commercial products. Using specifications and simplifications of R7 makes IMHO really sense. If there is no one who would like to work on that code and there are just consumers that state we need to keep such code working, I don't know how to move forward... @davidgraeff Can you tell me about the work that is done on openHAB 3? Who will contribute? Who will move openHAB forward (not organization but the code base)? |
Not sure if you refer to me? If so, you are wrong here. I was very happy to see this PR and hoped we can get rid off a lot of code and dependencies here. So I share the disappointment that @davidgraeff gives up on it.
If this is the part that led you to give up on it, could you at least provide some details on how far you got here, what obstacles there were and what exactly you consider an antipattern that cannot be resolved without removing complete features? Is SSE working for item streams and the problem is only with SSE for sitemaps? Could you exclude the sitemap SSE support from this PR and for the moment keep the Glassfish dependency for it and I can look into it separately? |
I haven't read the SSE specification, but the subscribe/unsubscribe pattern that is used by Sitemap has no matching API and I haven't seen it anywhere else. I guess the idiomatic way would be to open / close connections on unique http endpoints if its about unique event streams. Right now some kind of manual multiplexing and session tracking is performed.
I can't recall it exactly, but I think that was my first attempt actually. Overlapping APIs and library responsibilities and therefore build and runtime failures made me start to touch that part as well. |
@davidgraeff While my modifications of the eclipsesource JAX-RS publisher I realized (again) that it uses a custom service tracker to register resources (also for message body reader / writer, our REST resources, ...). |
Yes of course. If you get the eclipsesource bundle to run with recent whiteboard pattern compatible jax-rs libraries. At the moment it is hard-wired to jersey .22 afaik. Should be doable. This PR does not only contain the whiteboard pattern migration (that would be a few hundred lines of annotation changes only). It is also modernizing, by using recent jax-rs features, and cutting down a lot of code. This will also work with the old eclipsesource bundle, if jersey can be updated to a more recent version. I wanted to get rid of eclipsesource, because of double service activation in the first place. It activates a service to check if it's suitable and shuts it down again. If you have service inter-dependencies, some of your services get activated multiple times, just to get shut down again. Absolute anti-pattern imo. |
@davidgraeff I played around with SSE today a little bit to migrate some projects to pure javax.ws.rs package space without depending on a specific implementation. As all the time a new A very simple working implementation can be found here: There is one REST endpoint to register for listening and an broadcast interface that can be used by other components to broadcast events. |
👍
I agree. Apparently I did not read the api specification / contract well enough. It's a slightly different situation for Sitemaps (multiple SSE endpoints) and I think the original code tried to harmonize multiple use cases and I followed along with this implementation. |
For the documentation (Swagger) you could be perhaps interested in something like that:
|
I think @davidgraeff abandoned this due to sitemaps. I can't tell... @maggu2810 are you picking it up to complete the sitemap side of it? |
The question is if this can be done in smaller parts. There are quite some merge conflicts accumulating. I guess it needs to be merged in one go though. |
No, I don't. |
Signed-off-by: Scott Rushworth [email protected] (github: openhab-5iver)
Fixes #726
osgi-jax-rs-connector's configuration anymore.
removed when pax-web is not used anymore.
TODO:
The RESTdoc bundle in the webui repo probably requires an update
to query the introduced
RESTservice
interface for the REST root.Signed-off-by: David Graeff [email protected]