From 2179311a1d49c0ee30c772142896c2dcb1761379 Mon Sep 17 00:00:00 2001 From: Wolfgang Hottgenroth Date: Tue, 21 Nov 2017 22:16:34 +0100 Subject: [PATCH] database engine initially works --- .../measurementCollector/DatabaseEngine.class | Bin 3894 -> 10368 bytes bin/measurementCollector.props | 8 +- bin/measurementDataEngine.props | 4 + .../measurementCollector/DatabaseEngine.java | 97 +++++++++++++++--- src/measurementCollector.props | 8 +- src/measurementDataEngine.props | 4 + 6 files changed, 97 insertions(+), 24 deletions(-) diff --git a/bin/de/hottis/measurementCollector/DatabaseEngine.class b/bin/de/hottis/measurementCollector/DatabaseEngine.class index b8e2962f3f6105bd45b3929507089d8ce14e8cd1..fbf930b21022851782062b3c6b12e25addeae503 100644 GIT binary patch literal 10368 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 delta 1884 zcmZuxYgbfN7=HGgVa}Q11kAv2)fw&shmiqNK_M@p1`4T(6h@Z;jyMDd8V0elMpG-x z65ZV_vdn7IN+q2^G+XtlwOXy!59n(j`T?!gs%6o;_mF<+!#Vri`@DNU&-=X3*@t$f zd^tbb`x<{M?o-jm;2sI@4~Is>)^MoPikZV^RL453 z=fBtkj*U8sP|T|{INQo^WEjpaJgB0Z!OwqImQ~2y?Sim9V(lGw5$aAI521q=M#dwS zh8`YtEMvXA)6tUOg-3MsiR=tB8Xb?Sc$C4%Z#jHC>1bzR{-;8sZn-rMWoHz$V4l*TmNo!Uk6~Klf!h_#v-G zZHeOz9VaovpvA^_#i9{wn4fSJdG_M84lX5}4o6}d-r~QytF=tLgEK1L<@FxJj`#3B z@Ap(WRD8f-$Qs66nMCYEe$-Re-i32IK9+r%4o9gCpD+|{3dh0&;Yo9|H5{?b(x^FT zM)sRSr8OEpW3bhh3QnI3wig83w!$i6>a^htUY2iUWugmTiS}J0z?##!%d>m-MaQSZ z1EXeZZLfwa++I*#j;|SV@Ahf)fkAU378$n~)JV)6Yqw&&F{|0@?fRb_K2um3M;Y}; zp(g_x3Zc@Q!AXCU4K6Y^8DGX^dpVNn>AOe9xs*fJmoXV%j?`v3l8I@|pxhEHqrCKv z!?h^FzS*B8o?y$4JC;N@oF-RYY2K=DXhGXwMlH4qiqWA zr*}CK1^sUhNwI(c3dv(d1XfHXm7tNLcFHJCLtzs((~LmHA564FM8(93+ZLMWca}s| z3=g1#-h%B6&22P>h>GFqT);LP47(th!VbB%ORgo5-6f~H7x1tRbF@7Ne&V@jiLsBw z1+8QfryN?(Lk0YCRMJp|dITih{4~}Q-3m(X$76KVlGf z{p11$()5~$o+;$ANx3|*Q*6+Abp#$H@D&m-o-W+G1jsN#C)@B8CEE#hR7%iCDhtH| z#!Xm#o{4!xlb9sH$(xw!Gv+bvq{#-i^4q>+DLi`@HA{-$KptvDH3=>nk_HSc0mjSl z!hf}}!-Oe}aXEomQO-@o`#gu|aYUS+!cosFDZHA(>$1oMGO5H<3D||~O=lK=Pdi3* z=}noTw9$w91-#Ah9cH_OKfoZtTa+I;SSdlpA38zGWd`cj}6cQ4Mnw?nu zrd#g27+k=Y3Mg(kvp6W1F3Z->kzxT7ww`+3L08O4>VDd#z4EtMO|xcdbPHvzrMy;z zC|*sMerp`-$$uMZ+a~NLi}ulMh}<`fPHM$goFL6k(oHafZp_k_^Voq)*eR7XWKS queue) { super("MeasurementCollector.DatabaseEngine"); @@ -31,6 +42,8 @@ public class DatabaseEngine extends Thread implements ITriggerable { this.triggerFlag = false; this.period = Integer.parseInt(this.config.getProperty(DATABASE_ENGINE_PERIOD_PROP)); this.dbUrl = this.config.getProperty(DATABASE_URL_PROP); + this.dbUsername = this.config.getProperty(DATABASE_USER_PROP); + this.dbPassword = this.config.getProperty(DATABASE_PASSWORD_PROP); } public void requestShutdown() { @@ -53,12 +66,48 @@ public class DatabaseEngine extends Thread implements ITriggerable { public void init() throws MeasurementCollectorException { timer = new Timer("DatabaseEngineTrigger"); timer.schedule(new TriggerTimer(this), 0, period * 1000); + try { + Class.forName(config.getProperty(DATABASE_DRIVER_PROP)); + } catch (ClassNotFoundException e) { + logger.error("Database driver class not found", e); + throw new MeasurementCollectorException("Database driver class not found", e); + } } private String createStatementFromDataObject(ADataObject ado) { - return ""; + StringBuffer sb = new StringBuffer(); + sb.append("INSERT INTO " + ado.getTableName()); + sb.append("(name,ts,"); + sb.append(String.join(",", ado.getValues().keySet())); + sb.append(") "); + sb.append("VALUES(?,?,"); + + String[] marks = (String[]) ado.getValues().values().stream() + .map(c -> "?") + .toArray(String[]::new); + sb.append(String.join(",", marks)); + + sb.append(")"); + return sb.toString(); } + private void bindValue(PreparedStatement pstmt, int pos, Object o) throws SQLException { + if (o instanceof Integer) { + pstmt.setInt(pos, (Integer)o); + } else if (o instanceof Byte) { + pstmt.setByte(pos, (Byte)o); + } else if (o instanceof Double) { + pstmt.setDouble(pos, (Double)o); + } else if (o instanceof String) { + pstmt.setString(pos, (String)o); + } else if (o instanceof LocalDateTime) { + pstmt.setTimestamp(pos, Timestamp.valueOf(((LocalDateTime)o))); + } else { + throw new SQLException("illegal parameter type: " + o.getClass().getName()); + } + } + + @Override public synchronized void run() { while (! stop) { @@ -73,46 +122,62 @@ public class DatabaseEngine extends Thread implements ITriggerable { logger.debug("DatabaseEngine has received trigger"); Connection dbCon = null; + HashMap preparedStatements = new HashMap(); try { int itemCnt = 0; while (true) { - PreparedStatement pstmt = null; try { ADataObject ado = queue.dequeue(); if (ado == null) { logger.warn("DatabaseEngine found no data"); break; } - String stmtTxt = createStatementFromDataObject(ado); - pstmt = dbCon.prepareStatement(stmtTxt); + dbCon = DriverManager.getConnection(dbUrl, dbUsername, dbPassword); + + String key = ado.getClass().getName(); + PreparedStatement pstmt; + if (! preparedStatements.containsKey(key)) { + pstmt = dbCon.prepareStatement(createStatementFromDataObject(ado)); + preparedStatements.put(key, pstmt); + } else { + pstmt = preparedStatements.get(key); + } + bindValue(pstmt, 1, ado.getName()); + bindValue(pstmt, 2, ado.getTimestamp()); + int pos = 3; for (Object o : ado.getValues().values()) { - + bindValue(pstmt, pos, o); + pos++; } itemCnt++; logger.info("DatabaseEngine received (" + itemCnt + ") " + ado); + logger.info("Statement is " + pstmt.toString()); + pstmt.execute(); + logger.info("Database insert executed"); + pstmt.clearParameters(); } catch (SQLException e) { logger.error("SQLException in inner database engine loop", e); - } finally { - if (pstmt != null) { - try { - pstmt.close(); - pstmt = null; - } catch (SQLException e) { - logger.warn("SQLException when closing statement, nothing will be done"); - } - } } } } catch (Exception e) { logger.error("Exception in outer database engine loop", e); } finally { - if (dbCon ! null) { + for (PreparedStatement p : preparedStatements.values()) { + try { + p.close(); + } catch (SQLException e) { + logger.warn("SQLException when closing prepared statement, nothing will be done"); + } + } + preparedStatements.clear(); + if (dbCon != null) { try { dbCon.close(); - dbCon = null; } catch (SQLException e) { logger.warn("SQLException when closing connection, nothing will be done"); + } finally { + dbCon = null; } } } diff --git a/src/measurementCollector.props b/src/measurementCollector.props index 5feeb1b..f4350d7 100644 --- a/src/measurementCollector.props +++ b/src/measurementCollector.props @@ -1,7 +1,7 @@ -;mqtt.broker = tcp://172.16.2.15:1883 -mqtt.broker = tcp://eupenstrasse20.dynamic.hottis.de:2883 -mqtt.username = tron -mqtt.password = geheim123 +mqtt.broker = tcp://172.16.2.15:1883 +;mqtt.broker = tcp://eupenstrasse20.dynamic.hottis.de:2883 +;mqtt.username = tron +;mqtt.password = geheim123 mbus.dataparser.1 = light,Light,de.hottis.measurementCollector.FinderOnePhasePowerMeter mbus.dataparser.2 = computer,Computer,de.hottis.measurementCollector.FinderOnePhasePowerMeter diff --git a/src/measurementDataEngine.props b/src/measurementDataEngine.props index 29772d4..7310c4e 100644 --- a/src/measurementDataEngine.props +++ b/src/measurementDataEngine.props @@ -1,4 +1,8 @@ db.period = 3600 +db.url = jdbc:mysql://localhost/smarthome +db.driver = com.mysql.jdbc.Driver +db.user = smarthome +db.password = smarthome123 jms.broker = tcp://localhost:61616 jms.clientid = mdb