/* * Autopsy Forensic Browser * * Copyright 2015 Basis Technology Corp. * Contact: carrier <at> sleuthkit <dot> org * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.sleuthkit.autopsy.experimental.autoingest; import java.nio.ByteBuffer; import java.util.Date; /** * A coordination service node data transfer object for an auto ingest job * manifest. The data include: processing status, priority, the number of times * the auto ingest job for the manifest has crashed during processing, and the * date the auto ingest job for the manifest was completed. */ final class ManifestNodeData { private static final int DEFAULT_PRIORITY = 0; private final boolean coordSvcNodeDataWasSet; private ProcessingStatus status; private int priority; private int numberOfCrashes; private long completedDate; private boolean errorsOccurred; /** * Constructs a coordination service node data data transfer object for an * auto ingest manifest from the raw bytes obtained from the coordination * service. * * @param nodeData The raw bytes received from the coordination service. */ ManifestNodeData(byte[] nodeData) { ByteBuffer buffer = ByteBuffer.wrap(nodeData); this.coordSvcNodeDataWasSet = buffer.hasRemaining(); if (this.coordSvcNodeDataWasSet) { int rawStatus = buffer.getInt(); if (ProcessingStatus.PENDING.ordinal() == rawStatus) { this.status = ProcessingStatus.PENDING; } else if (ProcessingStatus.PROCESSING.ordinal() == rawStatus) { this.status = ProcessingStatus.PROCESSING; } else if (ProcessingStatus.COMPLETED.ordinal() == rawStatus) { this.status = ProcessingStatus.COMPLETED; }else if (ProcessingStatus.DELETED.ordinal() == rawStatus) { this.status = ProcessingStatus.DELETED; } this.priority = buffer.getInt(); this.numberOfCrashes = buffer.getInt(); this.completedDate = buffer.getLong(); int errorFlag = buffer.getInt(); this.errorsOccurred = (1 == errorFlag); } else { this.status = ProcessingStatus.PENDING; this.priority = DEFAULT_PRIORITY; this.numberOfCrashes = 0; this.completedDate = 0L; this.errorsOccurred = false; } } /** * Constructs a coordination service node data data transfer object for an * auto ingest manifest from values provided by the auto ingest system. * * @param status The processing status of the manifest. * @param priority The priority of the manifest. * @param numberOfCrashes The number of times auto ingest jobs for the * manifest have crashed during processing. * @param completedDate The date the auto ingest job for the manifest was * completed. */ ManifestNodeData(ProcessingStatus status, int priority, int numberOfCrashes, Date completedDate, boolean errorOccurred) { this.coordSvcNodeDataWasSet = false; this.status = status; this.priority = priority; this.numberOfCrashes = numberOfCrashes; this.completedDate = completedDate.getTime(); this.errorsOccurred = errorOccurred; } /** * Indicates whether or not the coordination service node data was set, * i.e., this object was constructed from raw bytes from the ccordination * service node for the manifest. * * @return True or false. */ // RJCTODO: This is confusing, consider changing the API so that the use case is to // check the length of the node data from the coordination service before // constructing an instance of this object. That would be much more clear! boolean coordSvcNodeDataWasSet() { return this.coordSvcNodeDataWasSet; } /** * Gets the processing status of the manifest * * @return The processing status of the manifest. */ ProcessingStatus getStatus() { return this.status; } /** * Sets the processing status of the manifest * * @param status The processing status of the manifest. */ void setStatus(ProcessingStatus status) { this.status = status; } /** * Gets the priority of the manifest. * * @return The priority of the manifest. */ int getPriority() { return this.priority; } /** * Sets the priority of the manifest. A higher number indicates a higheer * priority. * * @param priority The priority of the manifest. */ void setPriority(int priority) { this.priority = priority; } /** * Gets the number of times auto ingest jobs for the manifest have crashed * during processing. * * @return The number of times auto ingest jobs for the manifest have * crashed during processing. */ int getNumberOfCrashes() { return this.numberOfCrashes; } /** * Sets the number of times auto ingest jobs for the manifest have crashed * during processing. * * @param numberOfCrashes The number of times auto ingest jobs for the * manifest have crashed during processing. */ void setNumberOfCrashes(int numberOfCrashes) { this.numberOfCrashes = numberOfCrashes; } /** * Gets the date the auto ingest job for the manifest was completed. * * @return The date the auto ingest job for the manifest was completed. The * epoch (January 1, 1970, 00:00:00 GMT) indicates the date is not * set, i.e., Date.getTime() returns 0L. */ Date getCompletedDate() { return new Date(this.completedDate); } /** * Sets the date the auto ingest job for the manifest was completed. * * @param completedDate The date the auto ingest job for the manifest was * completed. Use the epoch (January 1, 1970, 00:00:00 * GMT) to indicate the date is not set, i.e., new * Date(0L). */ void setCompletedDate(Date completedDate) { this.completedDate = completedDate.getTime(); } /** * Queries whether or not any errors occurred during the processing of the * auto ingest job for the manifest. * * @return True or false. */ boolean getErrorsOccurred() { return this.errorsOccurred; } /** * Sets whether or not any errors occurred during the processing of the auto * ingest job for the manifest. * * @param errorsOccurred True or false. */ void setErrorsOccurred(boolean errorsOccurred) { this.errorsOccurred = errorsOccurred; } /** * Gets the node data as raw bytes that can be sent to the coordination * service. * * @return The manifest node data as a byte array. */ byte[] toArray() { ByteBuffer buffer = ByteBuffer.allocate(Integer.BYTES * 4 + Long.BYTES); buffer.putInt(this.status.ordinal()); buffer.putInt(this.priority); buffer.putInt(this.numberOfCrashes); buffer.putLong(this.completedDate); buffer.putInt(this.errorsOccurred ? 1 : 0); return buffer.array(); } /** * Processing status for the auto ingest job for the manifest. */ enum ProcessingStatus { PENDING, PROCESSING, COMPLETED, DELETED } }