Search in sources :

Example 1 with InstancePacketGroup

use of me.retrodaredevil.solarthing.packets.collection.InstancePacketGroup in project solarthing by wildmountainfarms.

the class PacketFinder method updateWithRange.

private void updateWithRange(long queryStart, long queryEnd) {
    List<? extends InstancePacketGroup> rawPackets = simpleQueryHandler.queryStatus(queryStart, queryEnd, null);
    synchronized (cacheMap) {
        for (InstancePacketGroup instancePacketGroup : rawPackets) {
            int fragmentId = instancePacketGroup.getFragmentId();
            for (Packet packet : instancePacketGroup.getPackets()) {
                if (packet instanceof Identifiable) {
                    Identifiable identifiable = (Identifiable) packet;
                    IdentifierFragment packetIdentifierFragment = IdentifierFragment.create(fragmentId, identifiable.getIdentifier());
                    cacheMap.putIfAbsent(packetIdentifierFragment, identifiable);
                }
            }
        }
    }
}
Also used : InstancePacketGroup(me.retrodaredevil.solarthing.packets.collection.InstancePacketGroup) Packet(me.retrodaredevil.solarthing.packets.Packet) IdentifierFragment(me.retrodaredevil.solarthing.packets.identification.IdentifierFragment) Identifiable(me.retrodaredevil.solarthing.packets.identification.Identifiable)

Example 2 with InstancePacketGroup

use of me.retrodaredevil.solarthing.packets.collection.InstancePacketGroup in project solarthing by wildmountainfarms.

the class CacheHandler method calculatePeriod.

private List<CacheDataPacket> calculatePeriod(long startPeriodNumber, long endPeriodNumber) {
    Instant firstPeriodStart = getPeriodStartFromNumber(startPeriodNumber);
    Instant lastPeriodEnd = getPeriodStartFromNumber(endPeriodNumber).plus(duration);
    Instant queryStart = firstPeriodStart.minus(INFO_DURATION);
    MillisQuery millisQuery = new MillisQueryBuilder().startKey(queryStart.toEpochMilli()).endKey(lastPeriodEnd.toEpochMilli()).inclusiveEnd(false).build();
    final List<? extends PacketGroup> packetGroups;
    try {
        packetGroups = database.getStatusDatabase().query(millisQuery);
    } catch (SolarThingDatabaseException e) {
        // The consumers of this API may be ok if there are holes in the data rather than getting no data at all, so maybe change this later?
        throw new DatabaseException("Couldn't query status packets for period. startPeriodNumber: " + startPeriodNumber + " endPeriodNumber: " + endPeriodNumber + " firstPeriodStart: " + firstPeriodStart, e);
    }
    List<CacheDataPacket> r = new ArrayList<>();
    Map<String, List<InstancePacketGroup>> sourceMap = PacketGroups.parsePackets(packetGroups, defaultInstanceOptions);
    for (Map.Entry<String, List<InstancePacketGroup>> entry : sourceMap.entrySet()) {
        String sourceId = entry.getKey();
        List<InstancePacketGroup> packets = entry.getValue();
        for (long periodNumber = startPeriodNumber; periodNumber <= endPeriodNumber; periodNumber++) {
            Instant periodStart = getPeriodStartFromNumber(periodNumber);
            for (CacheCreator creator : CACHE_CREATORS) {
                r.add(creator.createFrom(sourceId, packets, periodStart, duration));
            }
        }
    }
    return r;
}
Also used : InstancePacketGroup(me.retrodaredevil.solarthing.packets.collection.InstancePacketGroup) Instant(java.time.Instant) MillisQueryBuilder(me.retrodaredevil.solarthing.database.MillisQueryBuilder) SolarThingDatabaseException(me.retrodaredevil.solarthing.database.exception.SolarThingDatabaseException) CacheDataPacket(me.retrodaredevil.solarthing.type.cache.packets.CacheDataPacket) MillisQuery(me.retrodaredevil.solarthing.database.MillisQuery) DatabaseException(me.retrodaredevil.solarthing.rest.exceptions.DatabaseException) SolarThingDatabaseException(me.retrodaredevil.solarthing.database.exception.SolarThingDatabaseException) CacheCreator(me.retrodaredevil.solarthing.rest.cache.creators.CacheCreator) DefaultIdentificationCacheCreator(me.retrodaredevil.solarthing.rest.cache.creators.DefaultIdentificationCacheCreator)

Example 3 with InstancePacketGroup

use of me.retrodaredevil.solarthing.packets.collection.InstancePacketGroup in project solarthing by wildmountainfarms.

the class InfluxDbPacketSaver method handle.

@Override
public void handle(PacketCollection packetCollection) throws PacketHandleException {
    try (InfluxDB db = createDatabase()) {
        final InstancePacketGroup packetGroup = PacketGroups.parseToInstancePacketGroup(packetCollection, DefaultInstanceOptions.REQUIRE_NO_DEFAULTS);
        DefaultInstanceOptions.requireNoDefaults(packetGroup);
        final String database = databaseNameGetter.getName(packetGroup);
        try {
            QueryResult result = db.query(new Query("CREATE DATABASE " + database, null, true));
            String error = getError(result);
            if (error != null) {
                throw new PacketHandleException("Result got error! error: " + result);
            }
        } catch (InfluxDBException ex) {
            throw new PacketHandleException("Unable to query the database!", ex);
        }
        final RetentionPolicySetting retentionPolicySetting = retentionPolicyGetter.getRetentionPolicySetting();
        final String retentionPolicyName;
        // region Retention Policy Creation Logic
        if (retentionPolicySetting != null) {
            retentionPolicyName = retentionPolicySetting.getName();
            if (retentionPolicyName != null) {
                final RetentionPolicy policy = retentionPolicySetting.getRetentionPolicy();
                if (policy != null) {
                    final String policyString = policy.toPolicyStringInfluxDb1(retentionPolicyName, database);
                    final boolean needsAlter;
                    if (retentionPolicySetting.isTryToCreate()) {
                        final QueryResult result;
                        final String query = "CREATE " + policyString;
                        try {
                            result = db.query(new Query(query, null, true));
                        } catch (InfluxDBException ex) {
                            throw new PacketHandleException("Unable to query database to create retention policy: " + retentionPolicyName + " query: " + query, ex);
                        }
                        String error = getError(result);
                        if (retentionPolicySetting.isIgnoreUnsuccessfulCreate()) {
                            if (error != null) {
                                LOGGER.debug("We're going to ignore this error we got while trying to create a retention policy. Error: {}", error);
                            }
                            needsAlter = false;
                        } else {
                            if (error != null) {
                                LOGGER.debug("Got error while trying to create! Error: " + error);
                            }
                            needsAlter = error != null;
                        }
                        if (needsAlter && !retentionPolicySetting.isAutomaticallyAlter()) {
                            throw new PacketHandleException("Got error while trying to create retention policy: " + retentionPolicyName + ". Error: " + error);
                        }
                    } else {
                        needsAlter = true;
                    }
                    if (needsAlter) {
                        if (retentionPolicySetting.isAutomaticallyAlter()) {
                            final QueryResult alterResult;
                            try {
                                alterResult = db.query(new Query("ALTER " + policyString));
                                LOGGER.info(SolarThingConstants.SUMMARY_MARKER, "Successfully altered {} retention policy!", retentionPolicyName);
                            } catch (InfluxDBException ex) {
                                throw new PacketHandleException("Unable to query database to alter retention policy: " + retentionPolicyName, ex);
                            }
                            String error = getError(alterResult);
                            if (error != null) {
                                throw new PacketHandleException("Unable to alter retention policy: " + retentionPolicyName + ". Error: " + error);
                            }
                        } else {
                            throw new PacketHandleException("Retention policy: " + retentionPolicyName + " needs to be altered but automatically alter is false!");
                        }
                    }
                }
            }
        } else {
            retentionPolicyName = null;
        }
        // endregion
        final long time = packetCollection.getDateMillis();
        final BatchPoints points = BatchPoints.database(database).tag("sourceId", packetGroup.getSourceId()).tag("fragmentId", "" + packetGroup.getFragmentId()).consistency(InfluxDB.ConsistencyLevel.ALL).retentionPolicy(// may be null, but that's OK
        retentionPolicyName).build();
        int packetsWritten = 0;
        for (Packet packet : packetGroup.getPackets()) {
            Point.Builder pointBuilder = pointCreator.createBuilder(packet).time(time, TimeUnit.MILLISECONDS);
            Collection<String> tagKeys = PointUtil.getTagKeys(packet.getClass());
            ObjectNode json = OBJECT_MAPPER.valueToTree(packet);
            for (Map.Entry<String, ValueNode> entry : PointUtil.flattenJsonObject(json)) {
                String key = entry.getKey();
                ValueNode prim = entry.getValue();
                if (tagKeys.contains(key)) {
                    pointBuilder.tag(key, prim.asText());
                }
                if (prim.isNumber()) {
                    // always store as float datatype
                    pointBuilder.addField(key, prim.asDouble());
                } else if (prim.isTextual() || prim.isBinary()) {
                    pointBuilder.addField(key, prim.asText());
                } else if (prim.isBoolean()) {
                    pointBuilder.addField(key, prim.asBoolean());
                } else
                    throw new AssertionError("This primitive isn't a number, string/binary or boolean! It's: " + prim + " class: " + prim.getClass() + " text=" + prim.asText());
            }
            points.point(pointBuilder.build());
            packetsWritten++;
        }
        try {
            db.write(points);
        } catch (InfluxDBException ex) {
            throw new PacketHandleException("We were able to query the database, but unable to write the points to it!", ex);
        }
        LOGGER.debug("Wrote {} packets to InfluxDB! database={} retention policy={}", packetsWritten, database, retentionPolicyName);
    }
}
Also used : InstancePacketGroup(me.retrodaredevil.solarthing.packets.collection.InstancePacketGroup) Packet(me.retrodaredevil.solarthing.packets.Packet) Query(org.influxdb.dto.Query) BatchPoints(org.influxdb.dto.BatchPoints) ObjectNode(com.fasterxml.jackson.databind.node.ObjectNode) Point(org.influxdb.dto.Point) RetentionPolicy(me.retrodaredevil.solarthing.influxdb.retention.RetentionPolicy) Point(org.influxdb.dto.Point) InfluxDBException(org.influxdb.InfluxDBException) QueryResult(org.influxdb.dto.QueryResult) InfluxDB(org.influxdb.InfluxDB) RetentionPolicySetting(me.retrodaredevil.solarthing.influxdb.retention.RetentionPolicySetting) ValueNode(com.fasterxml.jackson.databind.node.ValueNode) Map(java.util.Map) PacketHandleException(me.retrodaredevil.solarthing.packets.handling.PacketHandleException)

Example 4 with InstancePacketGroup

use of me.retrodaredevil.solarthing.packets.collection.InstancePacketGroup in project solarthing by wildmountainfarms.

the class InfluxDb2PacketSaver method handle.

@Override
public void handle(PacketCollection packetCollection) throws PacketHandleException {
    final InstancePacketGroup packetGroup = PacketGroups.parseToInstancePacketGroup(packetCollection, DefaultInstanceOptions.REQUIRE_NO_DEFAULTS);
    DefaultInstanceOptions.requireNoDefaults(packetGroup);
    Organization organization = findOrCreateOrg();
    Bucket bucket = findOrCreateBucket(bucketNameGetter.getName(packetGroup), organization);
    final long time = packetCollection.getDateMillis();
    List<Point> points = new ArrayList<>();
    for (Packet packet : packetGroup.getPackets()) {
        Point point = pointCreator.createBuilder(packet).time(time, WritePrecision.MS);
        Collection<String> tagKeys = PointUtil.getTagKeys(packet.getClass());
        ObjectNode json = OBJECT_MAPPER.valueToTree(packet);
        for (Map.Entry<String, ValueNode> entry : PointUtil.flattenJsonObject(json)) {
            String key = entry.getKey();
            ValueNode prim = entry.getValue();
            if (tagKeys.contains(key)) {
                point.addTag(key, prim.asText());
            }
            if (prim.isNumber()) {
                // always store as float datatype because you can never change the type from int to float easily
                final Number value;
                if (prim.isBigDecimal()) {
                    DecimalNode decimal = (DecimalNode) prim;
                    value = decimal.decimalValue();
                } else {
                    value = prim.asDouble();
                }
                point.addField(key, value);
            } else if (prim.isTextual() || prim.isBinary()) {
                point.addField(key, prim.asText());
            } else if (prim.isBoolean()) {
                point.addField(key, prim.asBoolean());
            } else
                throw new AssertionError("This primitive isn't a number, string/binary or boolean! It's: " + prim + " class: " + prim.getClass() + " text=" + prim.asText());
        }
        points.add(point);
    }
    try {
        client.getWriteApiBlocking().writePoints(bucket.getName(), bucket.getOrgID(), points);
    } catch (InfluxException exception) {
        throw new PacketHandleException("Could not write points", exception);
    }
}
Also used : InstancePacketGroup(me.retrodaredevil.solarthing.packets.collection.InstancePacketGroup) Packet(me.retrodaredevil.solarthing.packets.Packet) Organization(com.influxdb.client.domain.Organization) ObjectNode(com.fasterxml.jackson.databind.node.ObjectNode) ArrayList(java.util.ArrayList) Point(com.influxdb.client.write.Point) Bucket(com.influxdb.client.domain.Bucket) ValueNode(com.fasterxml.jackson.databind.node.ValueNode) InfluxException(com.influxdb.exceptions.InfluxException) DecimalNode(com.fasterxml.jackson.databind.node.DecimalNode) Map(java.util.Map) PacketHandleException(me.retrodaredevil.solarthing.packets.handling.PacketHandleException)

Aggregations

InstancePacketGroup (me.retrodaredevil.solarthing.packets.collection.InstancePacketGroup)4 Packet (me.retrodaredevil.solarthing.packets.Packet)3 ObjectNode (com.fasterxml.jackson.databind.node.ObjectNode)2 ValueNode (com.fasterxml.jackson.databind.node.ValueNode)2 Map (java.util.Map)2 PacketHandleException (me.retrodaredevil.solarthing.packets.handling.PacketHandleException)2 DecimalNode (com.fasterxml.jackson.databind.node.DecimalNode)1 Bucket (com.influxdb.client.domain.Bucket)1 Organization (com.influxdb.client.domain.Organization)1 Point (com.influxdb.client.write.Point)1 InfluxException (com.influxdb.exceptions.InfluxException)1 Instant (java.time.Instant)1 ArrayList (java.util.ArrayList)1 MillisQuery (me.retrodaredevil.solarthing.database.MillisQuery)1 MillisQueryBuilder (me.retrodaredevil.solarthing.database.MillisQueryBuilder)1 SolarThingDatabaseException (me.retrodaredevil.solarthing.database.exception.SolarThingDatabaseException)1 RetentionPolicy (me.retrodaredevil.solarthing.influxdb.retention.RetentionPolicy)1 RetentionPolicySetting (me.retrodaredevil.solarthing.influxdb.retention.RetentionPolicySetting)1 Identifiable (me.retrodaredevil.solarthing.packets.identification.Identifiable)1 IdentifierFragment (me.retrodaredevil.solarthing.packets.identification.IdentifierFragment)1