Skip to content

Commit 47d16b1

Browse files
authored
0.42.0
- Jacoco code coverage - Added DSBaseConnection for short lived periodic connections
2 parents 463c077 + 41fe46a commit 47d16b1

File tree

8 files changed

+281
-174
lines changed

8 files changed

+281
-174
lines changed

build.gradle

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ subprojects {
55
apply plugin: 'maven'
66

77
group 'org.iot-dsa'
8-
version '0.41.0'
8+
version '0.42.0'
99

1010
sourceCompatibility = 1.6
1111
targetCompatibility = 1.6
@@ -26,10 +26,11 @@ subprojects {
2626
}
2727

2828
jacocoTestReport {
29+
2930
reports {
3031
xml.enabled true
3132
csv.enabled false
32-
html.enabled false
33+
html.enabled true
3334
}
3435
}
3536

dslink-v2/src/main/java/com/acuity/iot/dsa/dslink/protocol/v1/DS1LinkConnection.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,7 @@ protected DSTransport makeTransport(DS1ConnectionInit init) {
148148
}
149149

150150
@Override
151-
protected void onConnect() {
151+
protected void doConnect() {
152152
try {
153153
DS1ConnectionInit init = connectionInit;
154154
//Don't reuse the connection init if there is connection problem.

dslink-v2/src/main/java/com/acuity/iot/dsa/dslink/protocol/v2/DS2LinkConnection.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,7 @@ protected DSBinaryTransport makeTransport() {
135135
}
136136

137137
@Override
138-
protected void onConnect() {
138+
protected void doConnect() {
139139
try {
140140
transport = makeTransport();
141141
put(TRANSPORT, transport);
Lines changed: 202 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,202 @@
1+
package org.iot.dsa.conn;
2+
3+
import org.iot.dsa.node.DSIStatus;
4+
import org.iot.dsa.node.DSInfo;
5+
import org.iot.dsa.node.DSNode;
6+
import org.iot.dsa.node.DSStatus;
7+
import org.iot.dsa.node.DSString;
8+
import org.iot.dsa.time.DSDateTime;
9+
import org.iot.dsa.util.DSException;
10+
11+
/**
12+
* Basic representation of a connection, which is subclassed by DSConnection to be stateful,
13+
* but can be subclassed directly for simpler / short lived connections.
14+
* <p>
15+
* Subclasses should call canConnect() and only execute connection logic only if it returns true.
16+
* If the subclass adds an enabled child, they should call canConnect() to update the status
17+
* accordingly.
18+
*
19+
* @author Aaron Hansen
20+
*/
21+
public abstract class DSBaseConnection extends DSNode implements DSIStatus {
22+
23+
///////////////////////////////////////////////////////////////////////////
24+
// Class Fields
25+
///////////////////////////////////////////////////////////////////////////
26+
27+
static final String LAST_OK = "Last Ok";
28+
static final String LAST_FAIL = "Last Fail";
29+
static final String STATUS = "Status";
30+
static final String STATUS_TEXT = "Status Text";
31+
32+
///////////////////////////////////////////////////////////////////////////
33+
// Instance Fields
34+
///////////////////////////////////////////////////////////////////////////
35+
36+
protected DSInfo lastFail = getInfo(LAST_FAIL);
37+
protected DSInfo lastOk = getInfo(LAST_OK);
38+
protected long lastOkMillis;
39+
protected DSInfo status = getInfo(STATUS);
40+
protected DSInfo statusText = getInfo(STATUS_TEXT);
41+
42+
///////////////////////////////////////////////////////////////////////////
43+
// Public Methods
44+
///////////////////////////////////////////////////////////////////////////
45+
46+
/**
47+
* Sets the down status flag and updates the reason only if the reason doesn't match the
48+
* current value.
49+
*
50+
* @param reason Optional
51+
*/
52+
public void connDown(String reason) {
53+
debug(debug() ? getPath() + ": connDown - " + reason : null);
54+
put(lastFail, DSDateTime.currentTime());
55+
if (!getStatus().isDown()) {
56+
put(status, getStatus().add(DSStatus.DOWN));
57+
}
58+
if (reason != null) {
59+
if (!statusText.getElement().toString().equals(reason)) {
60+
put(statusText, DSString.valueOf(reason));
61+
}
62+
}
63+
}
64+
65+
66+
/**
67+
* Updates the last ok timestamp, remove down and fault status, and clears the status text,
68+
* if needed.
69+
*/
70+
public void connOk() {
71+
trace(trace() ? getPath() + ": connOk" : null);
72+
long now = System.currentTimeMillis();
73+
if ((now - lastOkMillis) > 1000) { //prevents subscription to last ok time from going crazy
74+
put(lastOk, DSDateTime.valueOf(now));
75+
}
76+
lastOkMillis = now;
77+
if (getStatus().isFault()) {
78+
put(status, getStatus().remove(DSStatus.FAULT));
79+
}
80+
if (getStatus().isDown()) {
81+
put(status, getStatus().remove(DSStatus.DOWN));
82+
}
83+
if (!getStatusText().isEmpty()) {
84+
put(statusText, DSString.EMPTY);
85+
}
86+
}
87+
88+
/**
89+
* The last time connOk was called.
90+
*/
91+
public long getLastOk() {
92+
return lastOkMillis;
93+
}
94+
95+
@Override
96+
public DSStatus getStatus() {
97+
return (DSStatus) status.getObject();
98+
}
99+
100+
public String getStatusText() {
101+
return statusText.getElement().toString();
102+
}
103+
104+
/**
105+
* Checks the status for the fault flag.
106+
*/
107+
protected boolean isConfigOk() {
108+
return !getStatus().isFault();
109+
}
110+
111+
/**
112+
* Override point for connections that add an enabled child value.
113+
*
114+
* @return Default implementation returns true.
115+
*/
116+
public boolean isEnabled() {
117+
return true;
118+
}
119+
120+
/**
121+
* True if running, enabled and config is ok.
122+
*/
123+
public boolean isOperational() {
124+
return isRunning() && isConfigOk() && isEnabled();
125+
}
126+
127+
///////////////////////////////////////////////////////////////////////////
128+
// Protected Methods
129+
///////////////////////////////////////////////////////////////////////////
130+
131+
/**
132+
* Checks config, deals with any errors and returns whether or not this is operational.
133+
*/
134+
protected boolean canConnect() {
135+
if (isEnabled()) {
136+
if (getStatus().isDisabled()) {
137+
put(status, getStatus().remove(DSStatus.disabled));
138+
}
139+
} else {
140+
if (!getStatus().isDisabled()) {
141+
put(status, DSStatus.disabled);
142+
}
143+
return false;
144+
}
145+
try {
146+
checkConfig();
147+
return isOperational();
148+
} catch (Throwable x) {
149+
error(error() ? getPath() : null, x);
150+
configFault(DSException.makeMessage(x));
151+
}
152+
return false;
153+
}
154+
155+
/**
156+
* Validate configuration, then call configOk, configFault, or just throw an exception.
157+
*/
158+
protected abstract void checkConfig();
159+
160+
/**
161+
* Puts the connection into the fault state and optionally sets the message.
162+
*
163+
* @param msg Optional
164+
*/
165+
protected void configFault(String msg) {
166+
debug(debug() ? getPath() + ": configFault - " + msg : null);
167+
put(lastFail, DSDateTime.currentTime());
168+
if (msg != null) {
169+
if (!getStatusText().equals(msg)) {
170+
put(statusText, DSString.valueOf(msg));
171+
}
172+
}
173+
if (!getStatus().isFault()) {
174+
put(status, getStatus().add(DSStatus.FAULT));
175+
}
176+
}
177+
178+
/**
179+
* Removes fault state. Does not clear status text, that will be cleared by connOk.
180+
*/
181+
protected void configOk() {
182+
debug(debug() ? getPath() + ": configOk " : null);
183+
if (getStatus().isFault()) {
184+
put(status, getStatus().remove(DSStatus.FAULT));
185+
}
186+
}
187+
188+
@Override
189+
protected void declareDefaults() {
190+
declareDefault(STATUS, DSStatus.down).setReadOnly(true).setTransient(true);
191+
declareDefault(STATUS_TEXT, DSString.EMPTY).setReadOnly(true).setTransient(true);
192+
declareDefault(LAST_OK, DSDateTime.NULL).setReadOnly(true);
193+
declareDefault(LAST_FAIL, DSDateTime.NULL).setReadOnly(true);
194+
}
195+
196+
@Override
197+
protected String getLogName() {
198+
return getLogName("connection");
199+
}
200+
201+
202+
}

0 commit comments

Comments
 (0)