From 49ec45c8e85edb834faeaae19fa4c136fa56436b Mon Sep 17 00:00:00 2001 From: anchita-g <109063673+anchita-g@users.noreply.github.com> Date: Thu, 21 Sep 2023 15:09:34 +0530 Subject: [PATCH] Introducing Upload Strategies (#2171) * refactoring for upload request generator * spotless application * spotless application * added UploadRequestGeneratorFactory * Spotless applications * review comments * Upload Strategy * Adding factories * patch generator mode in same class as patch generator * making local fetch mode not internal * addressed review comments * using bundle request --- .../fhir/sync/upload/UploadStrategy.kt | 93 +++++++++++++++++++ .../fhir/sync/upload/patch/PatchGenerator.kt | 19 ++++ 2 files changed, 112 insertions(+) create mode 100644 engine/src/main/java/com/google/android/fhir/sync/upload/UploadStrategy.kt diff --git a/engine/src/main/java/com/google/android/fhir/sync/upload/UploadStrategy.kt b/engine/src/main/java/com/google/android/fhir/sync/upload/UploadStrategy.kt new file mode 100644 index 0000000000..ef082becc3 --- /dev/null +++ b/engine/src/main/java/com/google/android/fhir/sync/upload/UploadStrategy.kt @@ -0,0 +1,93 @@ +/* + * Copyright 2023 Google LLC + * + * 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 com.google.android.fhir.sync.upload + +import com.google.android.fhir.sync.upload.patch.PatchGeneratorMode +import com.google.android.fhir.sync.upload.request.UploadRequestGeneratorMode +import org.hl7.fhir.r4.model.Bundle +import org.hl7.fhir.r4.model.codesystems.HttpVerb + +/** + * Strategy to define how to upload the [LocalChange]s to the FHIR server. + * + * Each strategy comprises of deciding appropriate modes for [LocalChangeFetcher], + * [PatchGeneratorMode], [UploadRequestGeneratorMode]. The strategies mentioned here are exhaustive + * as the different modes for the components mentioned above can only be used together in some + * specific ways. + */ +sealed class UploadStrategy +private constructor( + internal val localChangesFetchMode: LocalChangesFetchMode, + internal val patchGeneratorMode: PatchGeneratorMode, + internal val requestGeneratorMode: UploadRequestGeneratorMode, +) { + object SingleChangePut : + UploadStrategy( + LocalChangesFetchMode.EarliestChange, + PatchGeneratorMode.PerChange, + UploadRequestGeneratorMode.UrlRequest(HttpVerb.PUT, HttpVerb.PATCH), + ) + + object SingleChangePost : + UploadStrategy( + LocalChangesFetchMode.EarliestChange, + PatchGeneratorMode.PerChange, + UploadRequestGeneratorMode.UrlRequest(HttpVerb.POST, HttpVerb.PATCH), + ) + + object SingleResourcePut : + UploadStrategy( + LocalChangesFetchMode.PerResource, + PatchGeneratorMode.PerResource, + UploadRequestGeneratorMode.UrlRequest(HttpVerb.PUT, HttpVerb.PATCH), + ) + + object SingleResourcePost : + UploadStrategy( + LocalChangesFetchMode.PerResource, + PatchGeneratorMode.PerResource, + UploadRequestGeneratorMode.UrlRequest(HttpVerb.POST, HttpVerb.PATCH), + ) + + object AllChangesBundlePut : + UploadStrategy( + LocalChangesFetchMode.AllChanges, + PatchGeneratorMode.PerChange, + UploadRequestGeneratorMode.BundleRequest(Bundle.HTTPVerb.PUT, Bundle.HTTPVerb.PATCH), + ) + + object AllChangesBundlePost : + UploadStrategy( + LocalChangesFetchMode.AllChanges, + PatchGeneratorMode.PerChange, + UploadRequestGeneratorMode.BundleRequest(Bundle.HTTPVerb.POST, Bundle.HTTPVerb.PATCH), + ) + + object AllChangesSquashedBundlePut : + UploadStrategy( + LocalChangesFetchMode.AllChanges, + PatchGeneratorMode.PerResource, + UploadRequestGeneratorMode.BundleRequest(Bundle.HTTPVerb.PUT, Bundle.HTTPVerb.PATCH), + ) + + object AllChangesSquashedBundlePost : + UploadStrategy( + LocalChangesFetchMode.AllChanges, + PatchGeneratorMode.PerResource, + UploadRequestGeneratorMode.BundleRequest(Bundle.HTTPVerb.POST, Bundle.HTTPVerb.PATCH), + ) +} diff --git a/engine/src/main/java/com/google/android/fhir/sync/upload/patch/PatchGenerator.kt b/engine/src/main/java/com/google/android/fhir/sync/upload/patch/PatchGenerator.kt index f0ff53f7ce..090e85e2b7 100644 --- a/engine/src/main/java/com/google/android/fhir/sync/upload/patch/PatchGenerator.kt +++ b/engine/src/main/java/com/google/android/fhir/sync/upload/patch/PatchGenerator.kt @@ -35,3 +35,22 @@ internal interface PatchGenerator { */ fun generate(localChanges: List): List } + +internal object PatchGeneratorFactory { + fun byMode( + mode: PatchGeneratorMode, + ): PatchGenerator = + when (mode) { + is PatchGeneratorMode.PerChange -> PerChangePatchGenerator + is PatchGeneratorMode.PerResource -> PerResourcePatchGenerator + } +} + +/** + * Mode to decide the type of [PatchGenerator] that needs to be used to upload the [LocalChange]s + */ +internal sealed class PatchGeneratorMode { + object PerResource : PatchGeneratorMode() + + object PerChange : PatchGeneratorMode() +}