Skip to content

Commit 6b512f2

Browse files
committed
v0.4.1 update
minor refactoring minor bug fixes fix infinite loop self-update bug add more verbose log messages when in debug mode add descriptive error message for HTTP code 0 in HTML pages
1 parent 2903d61 commit 6b512f2

File tree

11 files changed

+90
-30
lines changed

11 files changed

+90
-30
lines changed

root/info.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<extension version="1">
22
<name>PostgreSQL_Connect</name>
33
<description>Periodically synchronizes data to an external PostgreSQL database.</description>
4-
<version>0.4.0</version>
4+
<version>0.4.1</version>
55
<vendor>Automatic Controls Equipment Systems, Inc.</vendor>
66
<system-menu-provider>aces.webctrl.postgresql.web.SystemMenuEditor</system-menu-provider>
77
</extension>

src/aces/webctrl/postgresql/core/Config.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,11 +52,11 @@ public static boolean load(){
5252
password = s.readString();
5353
cron.set(s.readString());
5454
if (!s.end()){
55-
Initializer.log("Configuration file corrupted. Parameters reverted to defaults.");
55+
Initializer.log("Configuration file corrupted. Parameters reverted to defaults.",true);
5656
revertDefaults();
5757
}
5858
}catch(Throwable t){
59-
Initializer.log("Configuration file corrupted. Parameters reverted to defaults.");
59+
Initializer.log("Configuration file corrupted. Parameters reverted to defaults.",true);
6060
Initializer.log(t);
6161
revertDefaults();
6262
}

src/aces/webctrl/postgresql/core/ConnectSFTP.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ public ConnectSFTP(){
1111
final String username = Sync.settings.get("ftp_username");
1212
final String password = Sync.settings.get("ftp_password");
1313
if (host==null || port==null || username==null || password==null){
14-
Initializer.log("Failed to connect to SFTP server because connection settings were not provided.");
14+
Initializer.log("Failed to connect to SFTP server because connection settings were not provided.",true);
1515
return;
1616
}
1717
try{

src/aces/webctrl/postgresql/core/CronExpression.java

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,8 @@
11
package aces.webctrl.postgresql.core;
22
import java.util.*;
33
import java.time.*;
4-
import java.time.format.*;
54
import org.springframework.scheduling.support.*;
65
public class CronExpression {
7-
public final static DateTimeFormatter format = DateTimeFormatter.ofPattern("MM/dd/yyyy HH:mm:ss").withZone(ZoneId.systemDefault());
86
private volatile String expr = null;
97
private volatile CronSequenceGenerator gen = null;
108
private volatile long next = -1L;
@@ -71,6 +69,6 @@ public String getNextString(String def){
7169
* @return a formatted datetime {@code String} representing the specified instant in time.
7270
*/
7371
public static String format(long epochMilli){
74-
return format.format(Instant.ofEpochMilli(epochMilli));
72+
return Utility.timestampFormat.format(Instant.ofEpochMilli(epochMilli));
7573
}
7674
}

src/aces/webctrl/postgresql/core/HelperAPI.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -283,7 +283,7 @@ public static boolean downloadAddons(ArrayList<AddonDownload> whitelist){
283283
Initializer.log(t);
284284
}
285285
}else{
286-
Initializer.log("Failed to download \""+x.path+"\" from FTP server.");
286+
Initializer.log("Failed to download \""+x.path+"\" from FTP server.",true);
287287
}
288288
}
289289
}
@@ -310,7 +310,7 @@ public static boolean selfUpdate(){
310310
}
311311
}
312312
Thread.sleep(timeout);
313-
Files.move(Initializer.tmpAddonFile, Initializer.addonsDir.resolve(Initializer.getName()+".update"));
313+
Files.move(Initializer.tmpAddonFile, Initializer.addonsDir.resolve(Initializer.getName()+".update"), StandardCopyOption.REPLACE_EXISTING);
314314
final Path addon = Initializer.addonsDir.resolve(Initializer.AUTO_UPDATE_ADDON+".addon");
315315
Utility.extractResource("aces/webctrl/postgresql/resources/"+Initializer.AUTO_UPDATE_ADDON+".addon", addon);
316316
if (!Files.exists(addon)){
@@ -337,7 +337,7 @@ public static boolean selfUpdate(){
337337
for (AddOn x:server.scanForAddOns()){
338338
if (x!=null && Initializer.AUTO_UPDATE_ADDON.equalsIgnoreCase(x.getName())){
339339
final WebApp.State s = x.getState();
340-
if (s==WebApp.State.RUNNING || s==WebApp.State.STARTING || s==WebApp.State.STARTUP_ERROR){
340+
if (s==WebApp.State.RUNNING || s==WebApp.State.STARTING){
341341
return true;
342342
}
343343
break;

src/aces/webctrl/postgresql/core/Initializer.java

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,6 @@ public class Initializer implements ServletContextListener {
3535
private volatile static Thread mainThread = null;
3636
/** Becomes true when the servlet context is destroyed */
3737
public volatile static boolean stop = false;
38-
/** Becomes true when the main processing thread terminates */
39-
private volatile static boolean stopped = false;
4038
/** Used to initiate immediate manual syncs. */
4139
private final static Object syncNotifier = new Object();
4240
/** Whether to initiate an immediate sync. */
@@ -73,18 +71,25 @@ public class Initializer implements ServletContextListener {
7371
}
7472
mainThread = new Thread(){
7573
public void run(){
74+
try{
75+
if (Files.exists(addonsDir.resolve(Initializer.AUTO_UPDATE_ADDON+".addon"))){
76+
Sync.delayUpdate = true;
77+
}
78+
}catch(Throwable t){
79+
log(t);
80+
}
7681
long time, x;
7782
while (!stop){
7883
try{
7984
while (!stop){
8085
time = System.currentTimeMillis();
8186
if (time>=nextSave){
82-
HelperAPI.removeAddon(AUTO_UPDATE_ADDON, true);
8387
Config.save();
8488
nextSave = time+86400000L;
8589
if (stop){ break; }
8690
}
8791
if (syncNow || (x=Config.cron.getNext())!=-1 && time>=x){
92+
HelperAPI.removeAddon(AUTO_UPDATE_ADDON, true);
8893
new Sync(Event.GENERAL);
8994
Config.cron.reset();
9095
syncNow = false;
@@ -102,7 +107,6 @@ public void run(){
102107
}
103108
}catch(InterruptedException e){}
104109
}
105-
stopped = true;
106110
}
107111
};
108112
status = "Initialized";
@@ -123,9 +127,10 @@ public void run(){
123127
}
124128
Config.save();
125129
//Wait for the primary processing thread to terminate.
126-
while (!stopped){
130+
while (true){
127131
try{
128132
mainThread.join();
133+
break;
129134
}catch(InterruptedException e){}
130135
}
131136
}
@@ -179,6 +184,14 @@ public synchronized static void log(String str){
179184
logger.println(str);
180185
checkLogCache();
181186
}
187+
/**
188+
* Logs a message.
189+
*/
190+
public synchronized static void log(String str, boolean error){
191+
logCache.add(new LogMessage(str, error));
192+
logger.println(str);
193+
checkLogCache();
194+
}
182195
/**
183196
* Logs an error.
184197
*/

src/aces/webctrl/postgresql/core/LogMessage.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,11 @@ public LogMessage(String message){
99
this.message = message;
1010
err = false;
1111
}
12+
public LogMessage(String message, boolean err){
13+
stamp = OffsetDateTime.now();
14+
this.message = message;
15+
this.err = err;
16+
}
1217
public LogMessage(Throwable t){
1318
stamp = OffsetDateTime.now();
1419
message = Utility.getStackTrace(t);

src/aces/webctrl/postgresql/core/Sync.java

Lines changed: 45 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ public class Sync {
2121
public volatile static boolean lastGeneralSyncSuccessful = false;
2222
public static volatile boolean versionCompatible = false;
2323
public volatile boolean success = false;
24+
public volatile static boolean delayUpdate = false;
2425
/** Stores a partial list of mappings from the operator reference name in the WebCTRL database to the operator username in the PostgreSQL database. */
2526
private final static HashMap<String,String> refusernameCache = new HashMap<String,String>();
2627
/**
@@ -30,7 +31,7 @@ public Sync(Event event, String... args){
3031
synchronized (Sync.class){
3132
if (Initializer.stop && event!=Event.SHUTDOWN){ return; }
3233
try{
33-
final boolean debug = "true".equalsIgnoreCase(settings.get("debug"));
34+
boolean debug = "true".equalsIgnoreCase(settings.get("debug"));
3435
final String url = "jdbc:postgresql://"+Config.connectionURL;
3536
final String username = Config.username;
3637
final String password = Config.password;
@@ -72,6 +73,9 @@ public Sync(Event event, String... args){
7273
try(
7374
Statement s = con.createStatement();
7475
){
76+
if (debug){
77+
Initializer.log(args[0]);
78+
}
7579
fillCache(args[0],s);
7680
}
7781
}
@@ -92,11 +96,18 @@ public Sync(Event event, String... args){
9296
for (int i=1;i<args.length;++i){
9397
if (Initializer.stop){ return; }
9498
if (debug){
95-
Initializer.log(args[i]);
99+
if (args[i].startsWith("INSERT INTO webctrl.operator_whitelist") && !args[i].contains("{SSHA512}")){
100+
Initializer.log("INSERT INTO webctrl.operator_whitelist VALUES (***);");
101+
}else{
102+
Initializer.log(args[i]);
103+
}
96104
}
97105
s.executeUpdate(args[i]);
98106
}
99107
con.commit();
108+
if (debug){
109+
Initializer.log(args[0]);
110+
}
100111
fillCache(args[0],s);
101112
}
102113
con.commit();
@@ -133,7 +144,9 @@ public Sync(Event event, String... args){
133144
PreparedStatement s = con.prepareStatement("DELETE FROM webctrl.operator_blacklist WHERE \"username\" = ?;");
134145
){
135146
s.setString(1,data.username);
136-
s.executeUpdate();
147+
if (s.executeUpdate()>0 && debug){
148+
Initializer.log("Deleted "+data.username+" from operator_blacklist.");
149+
}
137150
}
138151
}
139152
try(
@@ -163,7 +176,9 @@ public Sync(Event event, String... args){
163176
PreparedStatement s = con.prepareStatement("INSERT INTO webctrl.operator_blacklist VALUES(?);");
164177
){
165178
s.setString(1,oldUsername);
166-
s.executeUpdate();
179+
if (s.executeUpdate()>0 && debug){
180+
Initializer.log("Inserted "+oldUsername+" into operator_blacklist.");
181+
}
167182
}
168183
}
169184
con.commit();
@@ -211,23 +226,40 @@ public void execute(SystemAccess sys){
211226
}
212227
con.commit();
213228
settings = map;
229+
final boolean d = "true".equalsIgnoreCase(map.get("debug"));
230+
if (d^debug){
231+
debug = d;
232+
Initializer.log("Debug mode "+(d?"en":"dis")+"abled.");
233+
}
214234
v = map.get("version");
215235
final int ver = Utility.compareVersions(Initializer.addonVersion,v);
216236
versionCompatible = ver>=0;
217-
if (!versionCompatible){
237+
if (versionCompatible){
238+
delayUpdate = false;
239+
}else{
218240
String update = map.get("auto_update");
219241
if (update!=null){
220242
update = update.trim();
221243
}
222244
if (update!=null && (update.equalsIgnoreCase("true") || update.equalsIgnoreCase("1"))){
223-
HelperAPI.selfUpdate();
224-
Initializer.log("Attempting auto-update from v"+Initializer.addonVersion+" to v"+v);
225-
Initializer.stop = true;
226-
success = true;
245+
if (delayUpdate){
246+
delayUpdate = false;
247+
Initializer.log("Warning - Infinite self-update loop detected.", true);
248+
}else if (HelperAPI.selfUpdate()){
249+
Initializer.log("Attempting auto-update from v"+Initializer.addonVersion+" to v"+v);
250+
Initializer.stop = true;
251+
success = true;
252+
return;
253+
}else{
254+
Initializer.log("Warning - Self-update function failed.", true);
255+
}
227256
}else{
228-
Initializer.status = "Version Mismatch: "+Initializer.addonVersion+" != "+v;
257+
String s = "Version Mismatch: "+Initializer.addonVersion+" != "+v;
258+
Initializer.status = s;
259+
if (debug){
260+
Initializer.log(s);
261+
}
229262
}
230-
return;
231263
}
232264
}
233265
if (Initializer.stop){ return; }
@@ -475,7 +507,7 @@ public void execute(SystemAccess sys){
475507
if (!(t instanceof InterruptedException)){
476508
final String s = "Sync error during: "+event.name();
477509
Initializer.status = s;
478-
Initializer.log(s);
510+
Initializer.log(s,true);
479511
Initializer.log(t);
480512
}
481513
}finally{
@@ -504,7 +536,7 @@ private int newServer(Connection con) throws Throwable {
504536
}
505537
if (ID<0){
506538
con.rollback();
507-
Initializer.log("Failed to automatically set server ID.");
539+
Initializer.log("Failed to automatically set server ID.",true);
508540
return -1;
509541
}else{
510542
con.commit();

src/aces/webctrl/postgresql/resources/MainPage.html

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,8 @@
5959
if (this.readyState===4){
6060
if (this.status===200){
6161
statusBox.innerText = "Sync Initiated";
62+
}else if (this.status==0){
63+
statusBox.innerText = "Request timed out.";
6264
}else{
6365
statusBox.innerText = "HTTP Error "+this.status;
6466
}
@@ -80,6 +82,8 @@
8082
if (this.status===200){
8183
statusBox.innerText = "Reset Successful";
8284
idBox.innerText = "-1";
85+
}else if (this.status==0){
86+
statusBox.innerText = "Request timed out.";
8387
}else{
8488
statusBox.innerText = "HTTP Error "+this.status;
8589
}
@@ -100,6 +104,8 @@
100104
if (this.readyState===4){
101105
if (this.status===200){
102106
statusBox.innerText = this.responseText=="1"?"SFTP Connection Successful":"SFTP Connection Failed";
107+
}else if (this.status==0){
108+
statusBox.innerText = "Request timed out.";
103109
}else{
104110
statusBox.innerText = "HTTP Error "+this.status;
105111
}
@@ -121,6 +127,8 @@
121127
parseRefresh(this.responseText);
122128
passwordField.value = "";
123129
unregisterChange();
130+
}else if (this.status==0){
131+
statusBox.innerText = "Request timed out.";
124132
}else{
125133
statusBox.innerText = "HTTP Error "+this.status;
126134
}
@@ -143,6 +151,8 @@
143151
if (this.readyState===4){
144152
if (this.status===200){
145153
parseRefresh(this.responseText);
154+
}else if (this.status==0){
155+
statusBox.innerText = "Request timed out.";
146156
}else{
147157
statusBox.innerText = "HTTP Error "+this.status;
148158
}

src/aces/webctrl/postgresql/resources/SaveOperator.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
11
const req = new XMLHttpRequest();
22
req.open("POST","__PREFIX__/SaveOperator");
33
req.setRequestHeader("content-type", "application/x-www-form-urlencoded");
4-
req.timeout = 20000;
4+
req.timeout = 10000;
55
req.onreadystatechange = function(){
66
if (this.readyState===4){
77
if (this.status===200){
88
alert(this.responseText);
9+
}else if (this.status==0){
10+
alert("Request timed out.");
911
}else{
1012
alert("An error has occurred.");
1113
}

0 commit comments

Comments
 (0)