]> git.basschouten.com Git - openhab-addons.git/blob
27e31d09e30a1ea00994c84899bd32a01876e817
[openhab-addons.git] /
1 /**
2  * Copyright (c) 2010-2023 Contributors to the openHAB project
3  *
4  * See the NOTICE file(s) distributed with this work for additional
5  * information.
6  *
7  * This program and the accompanying materials are made available under the
8  * terms of the Eclipse Public License 2.0 which is available at
9  * http://www.eclipse.org/legal/epl-2.0
10  *
11  * SPDX-License-Identifier: EPL-2.0
12  */
13 package org.openhab.binding.mielecloud.internal.config;
14
15 import java.util.Hashtable;
16 import java.util.Map;
17
18 import javax.servlet.ServletException;
19
20 import org.eclipse.jdt.annotation.NonNullByDefault;
21 import org.eclipse.jdt.annotation.Nullable;
22 import org.openhab.binding.mielecloud.internal.config.servlet.AccountOverviewServlet;
23 import org.openhab.binding.mielecloud.internal.config.servlet.CreateBridgeServlet;
24 import org.openhab.binding.mielecloud.internal.config.servlet.FailureServlet;
25 import org.openhab.binding.mielecloud.internal.config.servlet.ForwardToLoginServlet;
26 import org.openhab.binding.mielecloud.internal.config.servlet.PairAccountServlet;
27 import org.openhab.binding.mielecloud.internal.config.servlet.ResourceLoader;
28 import org.openhab.binding.mielecloud.internal.config.servlet.ResultServlet;
29 import org.openhab.binding.mielecloud.internal.config.servlet.SuccessServlet;
30 import org.openhab.binding.mielecloud.internal.webservice.language.CombiningLanguageProvider;
31 import org.openhab.binding.mielecloud.internal.webservice.language.JvmLanguageProvider;
32 import org.openhab.binding.mielecloud.internal.webservice.language.LanguageProvider;
33 import org.openhab.binding.mielecloud.internal.webservice.language.OpenHabLanguageProvider;
34 import org.openhab.core.auth.client.oauth2.OAuthFactory;
35 import org.openhab.core.common.ThreadPoolManager;
36 import org.openhab.core.config.discovery.inbox.Inbox;
37 import org.openhab.core.i18n.LocaleProvider;
38 import org.openhab.core.thing.ThingRegistry;
39 import org.osgi.framework.BundleContext;
40 import org.osgi.service.component.ComponentContext;
41 import org.osgi.service.component.annotations.Activate;
42 import org.osgi.service.component.annotations.Component;
43 import org.osgi.service.component.annotations.Deactivate;
44 import org.osgi.service.component.annotations.Reference;
45 import org.osgi.service.http.HttpContext;
46 import org.osgi.service.http.HttpService;
47 import org.osgi.service.http.NamespaceException;
48 import org.slf4j.Logger;
49 import org.slf4j.LoggerFactory;
50
51 /**
52  * Handles the lifecycle of the Miele Cloud binding's configuration UI.
53  *
54  * @author Björn Lange - Initial Contribution
55  */
56 @Component(service = MieleCloudConfigService.class, immediate = true, configurationPid = "binding.mielecloud.configService")
57 @NonNullByDefault
58 public final class MieleCloudConfigService {
59     private static final String ROOT_ALIAS = "/mielecloud";
60     private static final String PAIR_ALIAS = ROOT_ALIAS + "/pair";
61     private static final String FORWARD_TO_LOGIN_ALIAS = ROOT_ALIAS + "/forwardToLogin";
62     private static final String RESULT_ALIAS = ROOT_ALIAS + "/result";
63     private static final String SUCCESS_ALIAS = ROOT_ALIAS + "/success";
64     private static final String CREATE_BRIDGE_THING_ALIAS = ROOT_ALIAS + "/createBridgeThing";
65     private static final String FAILURE_ALIAS = ROOT_ALIAS + "/failure";
66     private static final String CSS_ALIAS = ROOT_ALIAS + "/assets/css";
67     private static final String JS_ALIAS = ROOT_ALIAS + "/assets/js";
68     private static final String IMG_ALIAS = ROOT_ALIAS + "/assets/img";
69
70     private static final String WEBSITE_RESOURCE_BASE_PATH = "org/openhab/binding/mielecloud/internal/config";
71     private static final String WEBSITE_CSS_RESOURCE_PATH = WEBSITE_RESOURCE_BASE_PATH + "/assets/css";
72     private static final String WEBSITE_JS_RESOURCE_PATH = WEBSITE_RESOURCE_BASE_PATH + "/assets/js";
73     private static final String WEBSITE_IMG_RESOURCE_PATH = WEBSITE_RESOURCE_BASE_PATH + "/assets/img";
74
75     private final Logger logger = LoggerFactory.getLogger(MieleCloudConfigService.class);
76
77     private HttpService httpService;
78     private OAuthFactory oauthFactory;
79     private Inbox inbox;
80     private ThingRegistry thingRegistry;
81     private LocaleProvider localeProvider;
82
83     /**
84      * For integration test purposes only.
85      */
86     @Nullable
87     private AccountOverviewServlet accountOverviewServlet;
88
89     /**
90      * For integration test purposes only.
91      */
92     @Nullable
93     private ForwardToLoginServlet forwardToLoginServlet;
94
95     /**
96      * For integration test purposes only.
97      */
98     @Nullable
99     private ResultServlet resultServlet;
100
101     /**
102      * For integration test purposes only.
103      */
104     @Nullable
105     private SuccessServlet successServlet;
106
107     /**
108      * For integration test purposes only.
109      */
110     @Nullable
111     private CreateBridgeServlet createBridgeServlet;
112
113     @Activate
114     public MieleCloudConfigService(@Reference HttpService httpService, @Reference OAuthFactory oauthFactory,
115             @Reference Inbox inbox, @Reference ThingRegistry thingRegistry, @Reference LocaleProvider localeProvider) {
116         this.httpService = httpService;
117         this.oauthFactory = oauthFactory;
118         this.inbox = inbox;
119         this.thingRegistry = thingRegistry;
120         this.localeProvider = localeProvider;
121     }
122
123     @Nullable
124     public AccountOverviewServlet getAccountOverviewServlet() {
125         return accountOverviewServlet;
126     }
127
128     @Nullable
129     public ForwardToLoginServlet getForwardToLoginServlet() {
130         return forwardToLoginServlet;
131     }
132
133     @Nullable
134     public ResultServlet getResultServlet() {
135         return resultServlet;
136     }
137
138     @Nullable
139     public SuccessServlet getSuccessServlet() {
140         return successServlet;
141     }
142
143     @Nullable
144     public CreateBridgeServlet getCreateBridgeServlet() {
145         return createBridgeServlet;
146     }
147
148     @Activate
149     protected void activate(ComponentContext componentContext, Map<String, Object> properties) {
150         registerWebsite(componentContext.getBundleContext());
151     }
152
153     private void registerWebsite(BundleContext bundleContext) {
154         ResourceLoader resourceLoader = new ResourceLoader(WEBSITE_RESOURCE_BASE_PATH, bundleContext);
155         OAuthAuthorizationHandler authorizationHandler = new OAuthAuthorizationHandlerImpl(oauthFactory,
156                 ThreadPoolManager.getScheduledPool(ThreadPoolManager.THREAD_POOL_NAME_COMMON));
157
158         try {
159             HttpContext httpContext = httpService.createDefaultHttpContext();
160             httpService.registerServlet(ROOT_ALIAS,
161                     accountOverviewServlet = new AccountOverviewServlet(resourceLoader, thingRegistry, inbox),
162                     new Hashtable<>(), httpContext);
163             httpService.registerServlet(PAIR_ALIAS, new PairAccountServlet(resourceLoader), new Hashtable<>(),
164                     httpContext);
165             httpService.registerServlet(FORWARD_TO_LOGIN_ALIAS,
166                     forwardToLoginServlet = new ForwardToLoginServlet(authorizationHandler), new Hashtable<>(),
167                     httpContext);
168             httpService.registerServlet(RESULT_ALIAS, resultServlet = new ResultServlet(authorizationHandler),
169                     new Hashtable<>(), httpContext);
170             httpService.registerServlet(SUCCESS_ALIAS,
171                     successServlet = new SuccessServlet(resourceLoader, createLanguageProvider()), new Hashtable<>(),
172                     httpContext);
173             httpService.registerServlet(CREATE_BRIDGE_THING_ALIAS,
174                     createBridgeServlet = new CreateBridgeServlet(inbox, thingRegistry), new Hashtable<>(),
175                     httpContext);
176             httpService.registerServlet(FAILURE_ALIAS, new FailureServlet(resourceLoader), new Hashtable<>(),
177                     httpContext);
178             httpService.registerResources(CSS_ALIAS, WEBSITE_CSS_RESOURCE_PATH, httpContext);
179             httpService.registerResources(JS_ALIAS, WEBSITE_JS_RESOURCE_PATH, httpContext);
180             httpService.registerResources(IMG_ALIAS, WEBSITE_IMG_RESOURCE_PATH, httpContext);
181             logger.debug("Registered Miele Cloud binding website at /mielecloud");
182         } catch (NamespaceException | ServletException e) {
183             logger.warn(
184                     "Failed to register Miele Cloud binding website. Miele Cloud binding website will not be available.",
185                     e);
186             unregisterWebsite();
187         }
188     }
189
190     private LanguageProvider createLanguageProvider() {
191         return new CombiningLanguageProvider(new OpenHabLanguageProvider(localeProvider), new JvmLanguageProvider());
192     }
193
194     @Deactivate
195     protected void deactivate() {
196         unregisterWebsite();
197     }
198
199     private void unregisterWebsite() {
200         unregisterWebResource(ROOT_ALIAS);
201         unregisterWebResource(PAIR_ALIAS);
202         unregisterWebResource(FORWARD_TO_LOGIN_ALIAS);
203         unregisterWebResource(RESULT_ALIAS);
204         unregisterWebResource(SUCCESS_ALIAS);
205         unregisterWebResource(CREATE_BRIDGE_THING_ALIAS);
206         unregisterWebResource(FAILURE_ALIAS);
207         unregisterWebResource(CSS_ALIAS);
208         unregisterWebResource(JS_ALIAS);
209         unregisterWebResource(IMG_ALIAS);
210         forwardToLoginServlet = null;
211         resultServlet = null;
212         createBridgeServlet = null;
213         logger.debug("Unregistered Miele Cloud binding website at /mielecloud");
214     }
215
216     private void unregisterWebResource(String alias) {
217         try {
218             httpService.unregister(alias);
219         } catch (IllegalArgumentException e) {
220             logger.warn("Failed to unregister Miele Cloud binding website alias {}", alias, e);
221         }
222     }
223 }