Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Task/leip 164 upload images #289

Merged
merged 36 commits into from
Nov 15, 2023
Merged
Show file tree
Hide file tree
Changes from 30 commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
4a77c24
Fix typo
hb0 Oct 23, 2023
f79ad53
Support NIO through desugaring
hb0 Oct 23, 2023
1865dea
Rename Default-/FileDao to Default-/FileIOHandler
hb0 Oct 23, 2023
74837a7
[LEIP-174] Add classes for the File table
hb0 Oct 23, 2023
d3b4df7
Add database migration and set version to 19
hb0 Oct 24, 2023
332ed29
Add update method to FileDao
hb0 Oct 24, 2023
87cfb46
Add MeasurementStatus UPLOADING
hb0 Oct 24, 2023
9cc8d74
Refactor onPerformSync to lower complexity
hb0 Oct 24, 2023
827cd8b
Rename UPLOADING state to a more precise SYNCABLE_ATTACHMENTS
hb0 Oct 24, 2023
c8b0a7f
Enable NIO in desugaring in remaining modules
hb0 Oct 25, 2023
d6ee15d
[LEIP-176] Upload attachments
hb0 Oct 25, 2023
b23552b
Add locationTimestamp to File table
hb0 Oct 26, 2023
79a1f05
[LEIP-179] Wrap attachments as cyf
hb0 Oct 26, 2023
48c7123
[LEIP-182] Add file counts to meta data
hb0 Oct 26, 2023
f883eab
Fix upload progress when continuing with later attachments
hb0 Oct 26, 2023
6c41145
Convert CapturingPersistenceBehaviour to kotlin
hb0 Oct 26, 2023
84837a4
[LEIP-186] Mark database operations as suspend
hb0 Oct 26, 2023
8fd0551
[LEIP-184] Add filesSize to metadata
hb0 Oct 26, 2023
35ae540
[LEIP-185] Fix resource failed to call end
hb0 Oct 26, 2023
25680f8
Add FileDaoTest
hb0 Oct 30, 2023
1d88bf9
Fix tests after changing dao functions to suspend
hb0 Oct 30, 2023
7013cc7
Convert ProtoTest to kotlin
hb0 Oct 30, 2023
8d3ec81
Add ProtoTest.testWithFileAttachments
hb0 Oct 30, 2023
236947e
Fix SyncPerformerTest
hb0 Oct 30, 2023
140a5b2
Add SyncPerformerTest.testSendData_withAttachments
hb0 Oct 30, 2023
66b8aa7
[LEIP-181] Add SyncAdapterTest.testOnPerformSync with/out existing at…
hb0 Oct 31, 2023
fcdd8c8
Upgrade Cyface dependencies to beta1
hb0 Oct 31, 2023
37277f7
Upload the attachments to files endpoint
hb0 Oct 31, 2023
2c120f8
Fix tests
hb0 Oct 31, 2023
bf21279
Ignore false-positive lint errors (we use desugaring for NIO)
hb0 Oct 31, 2023
241f558
Update code version
hb0 Oct 31, 2023
201cf86
Upgrade serialization and uploader to final version
hb0 Nov 13, 2023
3498fb1
Fix typo
hb0 Nov 13, 2023
e8a52ec
Adjust to renamed uploader interface
hb0 Nov 13, 2023
d8e2eee
Rename measurement.file to .attachment in persistence
hb0 Nov 13, 2023
c726a86
Rename measurement.files to .attachments
hb0 Nov 13, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,8 @@ ext {

// Cyface dependencies
cyfaceUtilsVersion = "4.0.4"
cyfaceSerializationVersion = "3.0.0"
cyfaceUploaderVersion = "1.0.0"
cyfaceSerializationVersion = "3.2.0-beta1"
cyfaceUploaderVersion = "1.2.0-beta1"
hb0 marked this conversation as resolved.
Show resolved Hide resolved

// Android SDK versions
minSdkVersion = 21 // device support
Expand All @@ -61,6 +61,7 @@ ext {
buildToolsVersion = '34.0.0' // optional, if defined, use latest (SDK Manager > SDK Tools)
// 1.1.0-alpha05: ':persistence:mergeExtDexDebugAndroidTest' fails (transitive dependency)
datastoreVersion = "1.1.0-alpha04" // only 1.1.0 supports multi-process datastore
desugaringVersion = "2.0.3"

// Android dependencies
androidxAnnotationVersion = '1.6.0'
Expand Down
6 changes: 5 additions & 1 deletion datacapturing/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -95,8 +95,10 @@ android {
}
}

// Enabling desugaring to support Java 8 and Java 11 features
compileOptions {
// Enabling desugaring to support Java 8 and Java 11 features
coreLibraryDesugaringEnabled true
// Set Java compatibility
sourceCompatibility rootProject.ext.sourceCompatibility
targetCompatibility rootProject.ext.targetCompatibility
}
Expand All @@ -120,6 +122,8 @@ dependencies {
implementation "androidx.annotation:annotation:$rootProject.ext.androidxAnnotationVersion"
implementation "androidx.appcompat:appcompat:$rootProject.ext.androidxAppCompatVersion"
implementation "androidx.localbroadcastmanager:localbroadcastmanager:$rootProject.ext.localbroadcastmanagerVersion"
// Add support desugaring with for NIO
coreLibraryDesugaring "com.android.tools:desugar_jdk_libs_nio:$rootProject.ext.desugaringVersion"

// `Room` API used to access database
// Further room libraries and Kotlin support see Room guide.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,9 @@ import de.cyface.datacapturing.persistence.WritingDataCompletedCallback
import de.cyface.persistence.DefaultPersistenceLayer
import de.cyface.persistence.PersistenceBehaviour
import de.cyface.persistence.PersistenceLayer
import de.cyface.persistence.dao.DefaultFileDao
import de.cyface.persistence.dao.FileDao
import de.cyface.persistence.exception.NoSuchMeasurementException
import de.cyface.persistence.io.DefaultFileIOHandler
import de.cyface.persistence.io.FileIOHandler
import de.cyface.persistence.model.EventType
import de.cyface.persistence.model.GeoLocation
import de.cyface.persistence.model.MeasurementStatus
Expand Down Expand Up @@ -164,7 +164,7 @@ class CapturedDataWriterTest {
*/
@Test
@Throws(NoSuchFileException::class, InvalidProtocolBufferException::class)
fun testStoreData() {
fun testStoreData() = runBlocking {
// Manually trigger data capturing (new measurement with sensor data and a location)
val (id) = oocut!!.newMeasurement(Modality.UNKNOWN)
val lock: Lock = ReentrantLock()
Expand All @@ -186,6 +186,7 @@ class CapturedDataWriterTest {
)
lock.lock()
try {
@Suppress("BlockingMethodInNonBlockingContext")
condition.await(2, TimeUnit.SECONDS)
} catch (e: InterruptedException) {
throw IllegalStateException(e)
Expand All @@ -195,17 +196,17 @@ class CapturedDataWriterTest {
capturingBehaviour!!.storeLocation(testLocation(1L), id)

// Check if the captured data was persisted
val fileDao: FileDao = DefaultFileDao()
val fileIOHandler: FileIOHandler = DefaultFileIOHandler()
val locations = oocut!!.locationDao!!.getAll()
MatcherAssert.assertThat(locations.size, Is.`is`(IsEqual.equalTo(TEST_LOCATION_COUNT)))

// Point3Ds
val accelerationsFile = loadFile(context!!, fileDao, id, Point3DType.ACCELERATION)
val rotationsFile = loadFile(context!!, fileDao, id, Point3DType.ROTATION)
val directionsFile = loadFile(context!!, fileDao, id, Point3DType.DIRECTION)
val accelerations = deserialize(fileDao, accelerationsFile.file, Point3DType.ACCELERATION)
val rotations = deserialize(fileDao, rotationsFile.file, Point3DType.ROTATION)
val directions = deserialize(fileDao, directionsFile.file, Point3DType.DIRECTION)
val accelerationsFile = loadFile(context!!, fileIOHandler, id, Point3DType.ACCELERATION)
val rotationsFile = loadFile(context!!, fileIOHandler, id, Point3DType.ROTATION)
val directionsFile = loadFile(context!!, fileIOHandler, id, Point3DType.DIRECTION)
val accelerations = deserialize(fileIOHandler, accelerationsFile.file, Point3DType.ACCELERATION)
val rotations = deserialize(fileIOHandler, rotationsFile.file, Point3DType.ROTATION)
val directions = deserialize(fileIOHandler, directionsFile.file, Point3DType.DIRECTION)
val accelerationBatch = accelerations.accelerationsBinary.getAccelerations(0)
MatcherAssert.assertThat(
accelerationBatch.timestampCount, Is.`is`(
Expand Down Expand Up @@ -302,15 +303,15 @@ class CapturedDataWriterTest {
) // because we don't clean it up currently

// Make sure nothing is left of the Point3DFiles
val accelerationsFolder = oocut!!.fileDao.getFolderPath(
val accelerationsFolder = oocut!!.fileIOHandler.getFolderPath(
context!!,
Point3DFile.ACCELERATIONS_FOLDER_NAME
)
val rotationsFolder = oocut!!.fileDao.getFolderPath(
val rotationsFolder = oocut!!.fileIOHandler.getFolderPath(
context!!,
Point3DFile.ROTATIONS_FOLDER_NAME
)
val directionsFolder = oocut!!.fileDao.getFolderPath(
val directionsFolder = oocut!!.fileIOHandler.getFolderPath(
context!!,
Point3DFile.DIRECTIONS_FOLDER_NAME
)
Expand Down Expand Up @@ -339,7 +340,7 @@ class CapturedDataWriterTest {
* Tests whether deleting a measurement actually remove that measurement together with all corresponding data.
*/
@Test
fun testDeleteMeasurement() {
fun testDeleteMeasurement() = runBlocking {

// Arrange
val measurement = oocut!!.newMeasurement(Modality.UNKNOWN)
Expand All @@ -358,6 +359,7 @@ class CapturedDataWriterTest {
capturingBehaviour!!.storeData(testData(), measurementId, callback)
lock.lock()
try {
@Suppress("BlockingMethodInNonBlockingContext")
condition.await(2, TimeUnit.SECONDS)
} catch (e: InterruptedException) {
throw IllegalStateException(e)
Expand All @@ -371,15 +373,15 @@ class CapturedDataWriterTest {
oocut!!.delete(measurement.id)

// Assert
val accelerationFile = oocut!!.fileDao.getFilePath(
val accelerationFile = oocut!!.fileIOHandler.getFilePath(
context!!, measurementId,
Point3DFile.ACCELERATIONS_FOLDER_NAME, Point3DFile.ACCELERATIONS_FILE_EXTENSION
)
val rotationFile = oocut!!.fileDao.getFilePath(
val rotationFile = oocut!!.fileIOHandler.getFilePath(
context!!, measurementId,
Point3DFile.ROTATIONS_FOLDER_NAME, Point3DFile.ROTATION_FILE_EXTENSION
)
val directionFile = oocut!!.fileDao.getFilePath(
val directionFile = oocut!!.fileIOHandler.getFilePath(
context!!, measurementId,
Point3DFile.DIRECTIONS_FOLDER_NAME, Point3DFile.DIRECTION_FILE_EXTENSION
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ class PersistenceLayerTest {
assertThat(oocut!!.hasMeasurement(MeasurementStatus.OPEN), equalTo(false))
oocut!!.newMeasurement(Modality.UNKNOWN)
assertThat(oocut!!.hasMeasurement(MeasurementStatus.OPEN), equalTo(true))
assertThat(oocut!!.loadMeasurements(MeasurementStatus.FINISHED)?.size, equalTo(1))
assertThat(oocut!!.loadMeasurements(MeasurementStatus.FINISHED).size, equalTo(1))
}

/**
Expand All @@ -110,7 +110,7 @@ class PersistenceLayerTest {
*/
@Test
fun testLoadFinishedMeasurements_noMeasurements() {
assertThat(oocut!!.loadMeasurements(MeasurementStatus.FINISHED)?.isEmpty(), equalTo(true))
assertThat(oocut!!.loadMeasurements(MeasurementStatus.FINISHED).isEmpty(), equalTo(true))
}

/**
Expand All @@ -134,11 +134,11 @@ class PersistenceLayerTest {
capturingBehaviour!!.updateRecentMeasurement(MeasurementStatus.FINISHED)
val finishedMeasurements = oocut!!.loadMeasurements(MeasurementStatus.FINISHED)
assertThat(
finishedMeasurements!!.size,
finishedMeasurements.size,
CoreMatchers.`is`(equalTo(1))
)
assertThat(
finishedMeasurements[0]!!.id,
finishedMeasurements[0].id,
CoreMatchers.`is`(equalTo(measurement.id))
)
}
Expand All @@ -158,29 +158,29 @@ class PersistenceLayerTest {
// Check that measurement was marked as synced
val syncedMeasurements = oocut!!.loadMeasurements(MeasurementStatus.SYNCED)
assertThat(
syncedMeasurements!!.size,
syncedMeasurements.size,
CoreMatchers.`is`(equalTo(1))
)
assertThat(
syncedMeasurements[0]!!.id, CoreMatchers.`is`(
syncedMeasurements[0].id, CoreMatchers.`is`(
equalTo(
id
)
)
)

// Check that sensor data was deleted
val accelerationFile = oocut!!.fileDao.getFilePath(
val accelerationFile = oocut!!.fileIOHandler.getFilePath(
context!!, id,
Point3DFile.ACCELERATIONS_FOLDER_NAME, Point3DFile.ACCELERATIONS_FILE_EXTENSION
)
Validate.isTrue(!accelerationFile.exists())
val rotationFile = oocut!!.fileDao.getFilePath(
val rotationFile = oocut!!.fileIOHandler.getFilePath(
context!!, id,
Point3DFile.ROTATIONS_FOLDER_NAME, Point3DFile.ROTATION_FILE_EXTENSION
)
Validate.isTrue(!rotationFile.exists())
val directionFile = oocut!!.fileDao.getFilePath(
val directionFile = oocut!!.fileIOHandler.getFilePath(
context!!, id,
Point3DFile.DIRECTIONS_FOLDER_NAME, Point3DFile.DIRECTION_FILE_EXTENSION
)
Expand All @@ -194,7 +194,7 @@ class PersistenceLayerTest {
*/
@Test
@Throws(NoSuchMeasurementException::class)
fun testGetSyncableMeasurement() {
fun testGetSyncableMeasurement() = runBlocking {

// Create a synchronized measurement
insertSampleMeasurementWithData(context!!, MeasurementStatus.SYNCED, oocut!!, 1, 1)
Expand All @@ -210,9 +210,9 @@ class PersistenceLayerTest {

// Check that syncable measurements = finishedMeasurement
val loadedMeasurements = oocut!!.loadMeasurements(MeasurementStatus.FINISHED)
assertThat(loadedMeasurements!!.size, CoreMatchers.`is`(1))
assertThat(loadedMeasurements.size, CoreMatchers.`is`(1))
assertThat(
loadedMeasurements[0]!!.id, CoreMatchers.`is`(
loadedMeasurements[0].id, CoreMatchers.`is`(
equalTo(
id
)
Expand Down
Loading
Loading