]> git.basschouten.com Git - openhab-addons.git/blob
3629031b14ca032d910d1493ada37955de45121b
[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.dbquery.internal;
14
15 import java.util.Collection;
16 import java.util.List;
17 import java.util.concurrent.ScheduledFuture;
18 import java.util.concurrent.TimeUnit;
19
20 import org.eclipse.jdt.annotation.NonNullByDefault;
21 import org.eclipse.jdt.annotation.Nullable;
22 import org.openhab.binding.dbquery.action.DBQueryActions;
23 import org.openhab.binding.dbquery.internal.domain.Database;
24 import org.openhab.core.thing.Bridge;
25 import org.openhab.core.thing.ChannelUID;
26 import org.openhab.core.thing.ThingStatus;
27 import org.openhab.core.thing.ThingStatusDetail;
28 import org.openhab.core.thing.binding.BaseBridgeHandler;
29 import org.openhab.core.thing.binding.ThingHandlerService;
30 import org.openhab.core.types.Command;
31 import org.slf4j.Logger;
32 import org.slf4j.LoggerFactory;
33
34 /**
35  * Base implementation common to all implementation of database bridge
36  *
37  * @author Joan Pujol - Initial contribution
38  */
39 @NonNullByDefault
40 public abstract class DatabaseBridgeHandler extends BaseBridgeHandler {
41     private static final long RETRY_CONNECTION_ATTEMPT_TIME_SECONDS = 60;
42     private final Logger logger = LoggerFactory.getLogger(DatabaseBridgeHandler.class);
43     private Database database = Database.EMPTY;
44     private @Nullable ScheduledFuture<?> retryConnectionAttemptFuture;
45
46     public DatabaseBridgeHandler(Bridge bridge) {
47         super(bridge);
48     }
49
50     @Override
51     public void initialize() {
52         initConfig();
53
54         database = createDatabase();
55
56         connectDatabase();
57     }
58
59     private void connectDatabase() {
60         logger.debug("connectDatabase {}", database);
61         var completable = database.connect();
62         updateStatus(ThingStatus.UNKNOWN);
63         completable.thenAccept(result -> {
64             if (result) {
65                 logger.trace("Succesfully connected to database {}", getThing().getUID());
66                 updateStatus(ThingStatus.ONLINE);
67             } else {
68                 updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR, "Connect to database failed");
69                 if (retryConnectionAttemptFuture == null) {
70                     scheduleRetryConnectionAttempt();
71                 }
72             }
73         });
74     }
75
76     protected void scheduleRetryConnectionAttempt() {
77         logger.trace("Scheduled retry connection attempt every {}", RETRY_CONNECTION_ATTEMPT_TIME_SECONDS);
78         retryConnectionAttemptFuture = scheduler.scheduleWithFixedDelay(this::connectDatabase,
79                 RETRY_CONNECTION_ATTEMPT_TIME_SECONDS, RETRY_CONNECTION_ATTEMPT_TIME_SECONDS, TimeUnit.SECONDS);
80     }
81
82     protected abstract void initConfig();
83
84     @Override
85     public void dispose() {
86         cancelRetryConnectionAttemptIfPresent();
87         disconnectDatabase();
88     }
89
90     protected void cancelRetryConnectionAttemptIfPresent() {
91         ScheduledFuture<?> currentFuture = retryConnectionAttemptFuture;
92         if (currentFuture != null) {
93             currentFuture.cancel(true);
94         }
95     }
96
97     private void disconnectDatabase() {
98         var completable = database.disconnect();
99         updateStatus(ThingStatus.UNKNOWN);
100         completable.thenAccept(result -> {
101             if (result) {
102                 updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.GONE, "Successfully disconnected to database");
103             } else {
104                 updateStatus(ThingStatus.UNKNOWN, ThingStatusDetail.COMMUNICATION_ERROR,
105                         "Disconnect to database failed");
106             }
107         });
108     }
109
110     @Override
111     public void handleCommand(ChannelUID channelUID, Command command) {
112         // No commands supported
113     }
114
115     abstract Database createDatabase();
116
117     public Database getDatabase() {
118         return database;
119     }
120
121     @Override
122     public Collection<Class<? extends ThingHandlerService>> getServices() {
123         return List.of(DBQueryActions.class);
124     }
125 }