APIs & services / asset-service

Upload a land KML geofence.

Endpointtoday's app
Call
POST /gateway/asset-service/api/v1/asset/attachment
Service
asset-service
Features
Geofencing
When
Queued sync (FARMER_ASSETS SYNC_POST_GEOFENCING)
Auth
X-SESSIONID stamped when queued (CoreAPI dooWithRetry); X-REQUESTID idempotency key
In the App Service

Use case

Uploads the KML boundary a cadre drew or captured for a land parcel on the Geofencing screen. It is queued as a FARMER_ASSETS SYNC_POST_GEOFENCING ledger entry, which normally depends on the asset POST so the server asset id exists. FarmerAssetsWorker.postGeofencing builds a multipart operation from geoFencingFilePath and skips it if geoFencingFileName is null. On 2xx, IEAssetGeofencingPostRH parses the AttachmentResponse and stores attachmentDateTime and id against the asset, then closes the ledger. On error it retries later.

Headers

HeaderValueNotes
X-SESSIONID<session id>Stamped by CoreAPI when the queued operation runs (CoreAPIDefaultImpl.doOperation). On a 401 the token is invalidated and the call retried. BaseResponseHandler also refreshes the session after a 500 on a gateway URL (first 5 attempts).
X-REQUESTID(removed)CoreAPIDefaultImpl.processOperation removes X-REQUESTID for multipart requests, so file uploads have no idempotency key.
Content-Typemultipart/form-data; boundary=<generated>Built by CoreAPI makeMultiPartHttpRequest because the operation has a File param.

Parameters

ParamInRequiredExampleNotes
fileformYesland_5501_geofence.kmlKML file from FarmerAssets.geoFencingFilePath. PII: farm boundary coordinates.
assetIdformYes5501Server asset id (entity.id).
assetCodeformNoAST-0001entity.assetCode.
saveFileContentformYestrueAsks the server to keep the KML content inline (it comes back as attachmentKindMetaData in the bulk GET).

Request

Example request body (synthetic data)
{
  "file": {
    "part": "binary KML (application/vnd.google-earth.kml+xml or octet-stream)"
  },
  "assetId": {
    "part": "text: 5501"
  },
  "assetCode": {
    "part": "text: AST-0001"
  },
  "saveFileContent": {
    "part": "text: true"
  }
}
FieldTypeRequiredNotes
filefileYesLocal KML from the geofence capture.
assetIdintYesfarmerassets.id.
assetCodestringNofarmerassets.assetCode.
saveFileContentbooleanYesAlways true.

Response

Example response body (synthetic data)
{
  "id": 42001,
  "uuid": "a1b2c3d4-0000-4000-8000-000000000042",
  "attachmentUUID": "a1b2c3d4-0000-4000-8000-000000000042",
  "fileName": "land_5501_geofence.kml",
  "attachmentDateTime": "2025-06-02 10:15:00",
  "attachmentKind": "ATTACHMENT_KIND.FILE",
  "attachmentKindMetaData": "<?xml version=\"1.0\"?><kml>...polygon...</kml>",
  "attachmentKindIdentifier": null,
  "tempAttachmentURL": "https://<signed-download-host>/<path>?<signature>",
  "appCreatedAt": "1748859300000"
}
FieldTypeRequiredNotes
idintStored as geoFencingId.
attachmentDateTimestringStored as geoFencingCreatedOn. Required (!!).
(others)mixedNot read by the app.

Errors

StatusWhenWhat the app does
401Session expiredCoreAPI invalidates the session id and retries once. If it still fails, the response handler returns TryAgain.LATER and the operation stays in the queue.
409Duplicate X-REQUESTIDSyncQueueProcessor records the request id and swaps in a fresh X-REQUESTID for the next attempt.
4xx/5xx (other)Server rejects or failsonError returns TryAgain.LATER (IEAssetGeofencingPostRH). Each failure is logged in the local error_log table (URL, body, headers). Every 10th attempt (up to attempt 5000) the whole operation is copied to Firestore urvi_sync_log. A 500 on a gateway URL in the first 5 attempts forces a session refresh.

Source

  • data/src/main/java/org/mindtree/app/agricultor/data/sync/work/FarmerAssetsWorker.kt
  • data/src/main/java/org/mindtree/app/agricultor/data/sync/rh/IEAssetGeofencingPostRH.kt
  • data/src/main/java/org/mindtree/app/agricultor/data/setup/AttachmentResponse.kt
  • core-api/src/main/java/com/mindtree/bridge/coreapi/impl/CoreAPIDefaultImpl.java