use of me.retrodaredevil.solarthing.database.exception.UpdateConflictSolarThingDatabaseException in project solarthing by wildmountainfarms.
the class AlterManagerAction method doSendCommand.
private void doSendCommand(VersionedPacket<StoredAlterPacket> versionedPacket, ScheduledCommandPacket scheduledCommandPacket) {
LOGGER.info(SolarThingConstants.SUMMARY_MARKER, "Sending command from data: " + scheduledCommandPacket.getData());
ScheduledCommandData data = scheduledCommandPacket.getData();
RequestCommandPacket requestCommandPacket = new ImmutableRequestCommandPacket(data.getCommandName());
// Having a document ID based off of the StoredAlterPacket's _id helps make sure we don't process it twice in case we are unable to delete it.
// -- if there's an update conflict while uploading, we know we already processed it
String documentId = "scheduled-request-" + versionedPacket.getPacket().getDbId();
PacketCollectionCreator creator = commandManager.makeCreator(sourceId, zoneId, InstanceTargetPackets.create(data.getTargetFragmentIds()), requestCommandPacket, zonedDateTime -> documentId);
executorService.execute(() -> {
Instant uploadingNow = Instant.now();
PacketCollection packetCollection = creator.create(uploadingNow);
boolean shouldDeleteAlter = false;
try {
database.getOpenDatabase().uploadPacketCollection(packetCollection, null);
LOGGER.info(SolarThingConstants.SUMMARY_MARKER, "Successfully uploaded packet collection that schedules command from data: " + scheduledCommandPacket.getData() + " document ID: " + documentId);
shouldDeleteAlter = true;
} catch (UpdateConflictSolarThingDatabaseException e) {
LOGGER.error("Got update conflict exception while uploading document ID: " + documentId + ". Will inspect existing document and overwrite if it's a malicious actor...", e);
VersionedPacket<StoredPacketGroup> existingDocument = null;
try {
existingDocument = database.getOpenDatabase().getPacketCollection(documentId);
} catch (SolarThingDatabaseException ex) {
LOGGER.error("Could not retrieve document with document ID: " + documentId, ex);
}
if (existingDocument != null) {
if (isDocumentMadeByUs(uploadingNow, data, existingDocument.getPacket())) {
LOGGER.info(SolarThingConstants.SUMMARY_MARKER, "False alarm everyone. The packet in the database was made by us and its timestamp is reasonable. document ID: " + documentId);
shouldDeleteAlter = true;
} else {
LOGGER.warn(SolarThingConstants.SUMMARY_MARKER, "The packet in the database with document ID: " + documentId + " was not made by us. Could be a malicious actor. We will overwrite that packet.");
try {
database.getOpenDatabase().uploadPacketCollection(packetCollection, existingDocument.getUpdateToken());
shouldDeleteAlter = true;
} catch (SolarThingDatabaseException ex) {
LOGGER.error("Could not overwrite malicious packet. Will likely try again. document ID: " + documentId, ex);
}
}
}
} catch (SolarThingDatabaseException e) {
LOGGER.error("Failed to upload our request command packet. documentId: " + documentId, e);
}
if (shouldDeleteAlter) {
try {
database.getAlterDatabase().delete(versionedPacket);
} catch (SolarThingDatabaseException e) {
LOGGER.error("Error while deleting an alter document. document ID: " + versionedPacket.getPacket().getDbId() + " update token: " + versionedPacket.getUpdateToken(), e);
}
}
});
}
use of me.retrodaredevil.solarthing.database.exception.UpdateConflictSolarThingDatabaseException in project solarthing by wildmountainfarms.
the class CouchDbAlterDatabase method delete.
@Override
public void delete(String documentId, UpdateToken updateToken) throws SolarThingDatabaseException {
RevisionUpdateToken revisionUpdateToken = CouchDbSolarThingDatabase.checkUpdateToken(updateToken);
String revision = revisionUpdateToken.getRevision();
try {
database.deleteDocument(documentId, revision);
} catch (CouchDbUnauthorizedException e) {
throw new UnauthorizedSolarThingDatabaseException(e);
} catch (CouchDbUpdateConflictException e) {
throw new UpdateConflictSolarThingDatabaseException("Update conflict on delete. Must not be latest revision. documentId: " + documentId + " revision: " + revision, e);
} catch (CouchDbNotFoundException e) {
throw new NotFoundSolarThingDatabaseException("(Not found) Could not delete documentId: " + documentId + " revision: " + revision, e);
} catch (CouchDbException e) {
throw new SolarThingDatabaseException("Could not delete documentId: " + documentId + " revision: " + revision, e);
}
}
use of me.retrodaredevil.solarthing.database.exception.UpdateConflictSolarThingDatabaseException in project solarthing by wildmountainfarms.
the class SecurityPacketReceiver method uploadSecurityEventPacket.
private void uploadSecurityEventPacket(SecurityEventPacket packet) {
Instant now = Instant.now();
String id = "security-event-status-" + fragmentId + "-" + packet.getRequestDocumentId();
PacketCollection packetCollection = PacketCollections.create(now, Arrays.asList(packet, InstanceFragmentIndicatorPackets.create(fragmentId), InstanceSourcePackets.create(sourceId)), id);
executorService.execute(() -> {
for (int tryIndex = 0; tryIndex < 3; tryIndex++) {
try {
eventDatabase.uploadPacketCollection(packetCollection, null);
break;
} catch (UpdateConflictSolarThingDatabaseException e) {
LOGGER.warn("Got update conflict exception for id: " + id, e);
// We will assume we have already uploaded this packet to the database
break;
} catch (UnauthorizedSolarThingDatabaseException e) {
LOGGER.warn("Not authorized to upload to events database", e);
break;
} catch (SolarThingDatabaseException e) {
LOGGER.error("Could not upload security event packet. tryIndex: " + tryIndex + " id: " + id, e);
}
try {
Thread.sleep((tryIndex + 1) * 100);
} catch (InterruptedException e) {
LOGGER.error("Was interrupted", e);
Thread.currentThread().interrupt();
}
}
});
}
Aggregations