Hi, what do you means with “injection”? how to achieve that?
I found a solution using a @Reference to bind the factory to the servlet. At that moment the servlet is started and calls the factory to set a flag. This flag is used to delay the asynchronous thing initialization. At the end the thing initialization waits until the servrlet signals “initialized”. Ok, it works, but I would expect a smarter solution, because the concept of start levels is well know in the OSGi spec. I couldn’t find a way to add the level to the @Component or something like shat and couldn’t find an example (e.g. other bindings, google).
I use the activate() mechanism to register the url
@Activate
protected void activate(Map<String, Object> config) {
try {
httpService.registerServlet(PAIRING_NOTIFY_URI, this, null, httpService.createDefaultHttpContext());
logger.info("Servlet started at '{}'", PAIRING_NOTIFY_URI);
} catch (ServletException | NamespaceException e) {
logger.error("Could not start: {} ({})", e.getMessage(), e.getClass());
}
}
and learned that at that point the handler factory is not bound. So I used the bind call to signal the status to the handler factory.
@Reference(cardinality = ReferenceCardinality.OPTIONAL, policy = ReferencePolicy.DYNAMIC)
public void setMagentaTVHandlerFactory(MagentaTVHandlerFactory handlerFactory) {
logger.debug("HandlerFactory bound to NotifyServlet");
this.handlerFactory = handlerFactory;
handlerFactory.setNotifyServletStatus(true);
}
The thing initialization is started asynchronous
@Override
public void initialize() {
// The framework requires you to return from this method quickly. For that the initialization itself is executed
// asynchronously
logger.debug("Initialize Thing...");
updateStatus(ThingStatus.UNKNOWN);
scheduler.execute(() -> {
String errorMessage = "";
try {
...
and then I wait on the initialization signal from the servlet.
// wait for NotifyServlet to initialze
if (!handlerFactory.getNotifyServletStatus()) {
logger.debug("Waiting on NotifyServlet to start...");
int iRetries = 30;
while ((iRetries-- > 0) && !handlerFactory.getNotifyServletStatus()) {
logger.trace("Waiting for init, {} sec remaining", iRetries);
Thread.sleep(1000);
}
if ((iRetries <= 0) && !handlerFactory.getNotifyServletStatus()) {
errorMessage = "Can't initialize, NotifyServlet not started!";
}
} else {
connectReceiver(); // throws exception on error
}
As said: works, but feels like a hack for something, which is supported by the OSGi spec.
If you want to look at the details, this is the repo:
https://github.com/markus7017/openhab2-addons/tree/add_linting/addons/binding/org.openhab.binding.magentatv