private DataChunk readSamples(String channelName, Timestamp from) throws Exception { DataChunk chunk = new DataChunk(chunkSize); BufferedReader br = null; String currentLine = ""; Timestamp lastIndex = indexes.floorKey(from); Integer lineToStart = lastIndex == null ? 1 : indexes.get(lastIndex); Integer lineNumber = -1; try { br = new BufferedReader(new FileReader(csvFile)); while ((currentLine = br.readLine()) != null) { lineNumber++; if (lineNumber < lineToStart) continue; String[] columns = getColumns(currentLine); if (columns[channel_name] != null && columns[channel_name].equals(channelName)) { // Get time stamp final java.sql.Timestamp stamp = java.sql.Timestamp.valueOf(columns[smpl_time]); stamp.setNanos(Integer.valueOf(columns[nanosecs])); final Timestamp time = fromSQLTimestamp(stamp); if (time.compareTo(from) >= 0) { final VType value = decodeValue(columns, time); SourceData data = new SourceData(time, value); if (!chunk.add(data)) { TimeInterval i = chunk.getInterval(); if (i != null) indexes.put(i.getEnd(), lineNumber); break; } } } } } finally { if (br != null) br.close(); } return chunk; }
/** * Add given info value to buffer, tweaking its time stamp if necessary * * @param value Value to archive * @return Value that was actually added, which may have adjusted time stamp */ protected final VType addInfoToBuffer(VType value) { synchronized (this) { if (last_archived_value != null) { final Timestamp last = VTypeHelper.getTimestamp(last_archived_value); if (last.compareTo(VTypeHelper.getTimestamp(value)) >= 0) { // Patch the time stamp final Timestamp next = last.plus(TimeDuration.ofMillis(100)); value = VTypeHelper.transformTimestamp(value, next); } // else: value is OK as is } } addValueToBuffer(value); return value; }
/** * Check a received value for basic problems before passing it on to the sample mechanism * * @param value Value as received from network layer * @return Value to be used for archive */ private VType checkReceivedValue(VType value) { if (value instanceof Time) { try { final Time time = (Time) value; // Invoke time.getTimestamp() to detect RuntimeError in VType 2013/11/01 if (time.isTimeValid() && time.getTimestamp() != null) return value; else { trouble_sample_log.log("'" + getName() + "': Invalid time stamp "); value = VTypeHelper.transformTimestamp(value, Timestamp.now()); } } catch (RuntimeException ex) { Logger.getLogger(getClass().getName()) .log(Level.WARNING, "'" + getName() + "': Exception getting time stamp", ex); value = VTypeHelper.transformTimestamp(value, Timestamp.now()); } } else trouble_sample_log.log("'" + getName() + "': Received no time information for " + value); return value; }
/** * Given the time and first element of the sample, see if there are more array elements. * * @param stamp Time stamp of the sample * @param dbl0 Value of the first (maybe only) array element * @param severity Severity of the sample * @return Array with given element and maybe more. * @throws Exception on error, including 'cancel' */ private double[] readArrayElements( final Timestamp stamp, final double dbl0, final AlarmSeverity severity) throws Exception { // For performance reasons, only look for array data until we hit a scalar sample. if (is_an_array == false) return new double[] {dbl0}; // See if there are more array elements if (sel_array_samples == null) { // Lazy initialization sel_array_samples = reader.getConnection().prepareStatement(reader.getSQL().sample_sel_array_vals); } sel_array_samples.setInt(1, channel_id); sel_array_samples.setTimestamp(2, TimestampHelper.toSQLTimestamp(stamp)); // MySQL keeps nanoseconds in designated column, not TIMESTAMP if (!reader.isOracle()) sel_array_samples.setInt(3, stamp.getNanoSec()); // Assemble array of unknown size in ArrayList .... final ArrayList<Double> vals = new ArrayList<Double>(); reader.addForCancellation(sel_array_samples); try { final ResultSet res = sel_array_samples.executeQuery(); vals.add(new Double(dbl0)); while (res.next()) vals.add(res.getDouble(1)); res.close(); } finally { reader.removeFromCancellation(sel_array_samples); } // Convert to plain double array final int N = vals.size(); final double ret[] = new double[N]; for (int i = 0; i < N; i++) ret[i] = vals.get(i).doubleValue(); // Check if it's in fact just a scalar, and a valid one if (N == 1 && severity != AlarmSeverity.UNDEFINED) { // Found a perfect non-array sample: // Assume that the data is scalar, skip the array check from now on is_an_array = false; } return ret; }
/** * @param time Timestamp to check * @return <code>true</code> if time is too far into the future; better ignore. */ private boolean isFuturistic(final Timestamp time) { final long threshold = System.currentTimeMillis() / 1000 + EngineModel.getIgnoredFutureSeconds(); return time.getSec() >= threshold; }
private Timestamp fromSQLTimestamp(final java.sql.Timestamp sql_time) { final long millisecs = sql_time.getTime(); final long seconds = millisecs / 1000; final int nanoseconds = sql_time.getNanos(); return Timestamp.of(seconds, nanoseconds); }
/** * Represents the connection payload, which consists of the actual JCA Channel and the JCADataSource * (which can be used to extract configuration parameters). * * @author carcassi */ public class JCAConnectionPayload { private final JCADataSource jcaDataSource; private final Channel channel; private final boolean connected; private final boolean longString; private final DBRType fieldType; private final Timestamp eventTime = Timestamp.now(); public JCAConnectionPayload( JCAChannelHandler channleHandler, Channel channel, JCAConnectionPayload previousPayload) { this.jcaDataSource = channleHandler.getJcaDataSource(); this.channel = channel; this.connected = channel != null && channel.getConnectionState() == Channel.ConnectionState.CONNECTED; this.longString = channleHandler.isLongString(); if (channel.getFieldType().getClass() == null && previousPayload != null) { // JNI sets the type to unknown on disconnect. We need // to remember the type before the disconnection this.fieldType = previousPayload.fieldType; } else { this.fieldType = channel.getFieldType(); } } /** * The JCADataSource that is using the channel. * * @return the JCA data source */ public JCADataSource getJcaDataSource() { return jcaDataSource; } /** * The JCA channel. * * @return JCA channel */ public Channel getChannel() { return channel; } public DBRType getFieldType() { return fieldType; } /** * True if the channel is not null and the connection state is connected. * * @return ture if channel exists and is connected */ public boolean isChannelConnected() { return connected; } /** * True if the channel is not null, connected, and can be written to. * * @return true if the channel is ready for write */ public boolean isWriteConnected() { return isChannelConnected() && channel.getWriteAccess(); } /** * Whether the message payload should be handled as a long string. * * @return true if long string support should be used */ public boolean isLongString() { return longString; } /** * Returns the local time of the connection event. * * @return client connection/disconnection time */ public Timestamp getEventTime() { return eventTime; } @Override public String toString() { return "JCAConnection [connected: " + isChannelConnected() + " writeConnected: " + isWriteConnected() + " channel: " + channel + "]"; } }