ssm.couchdb.client.CouchdbSsmClient.kt Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of ssm-couchdb-sdk Show documentation
Show all versions of ssm-couchdb-sdk Show documentation
Aggregate all ssm data source to optimize request
The newest version!
package ssm.couchdb.client
import com.ibm.cloud.cloudant.v1.model.ChangesResult
import com.ibm.cloud.cloudant.v1.model.DatabaseInformation
import com.ibm.cloud.cloudant.v1.model.DesignDocument
import com.ibm.cloud.cloudant.v1.model.Document
import com.ibm.cloud.cloudant.v1.model.FindResult
import com.ibm.cloud.cloudant.v1.model.GetDatabaseInformationOptions
import com.ibm.cloud.cloudant.v1.model.GetDesignDocumentOptions
import com.ibm.cloud.cloudant.v1.model.PostChangesOptions
import com.ibm.cloud.cloudant.v1.model.PostFindOptions
import com.ibm.cloud.cloudant.v1.model.PostViewOptions
import com.ibm.cloud.cloudant.v1.model.PutDesignDocumentOptions
import com.ibm.cloud.sdk.core.http.Response
import com.ibm.cloud.sdk.core.service.exception.NotFoundException
import kotlin.coroutines.resume
import kotlin.coroutines.suspendCoroutine
import ssm.chaincode.dsl.model.SessionName
import ssm.chaincode.dsl.model.SsmName
import ssm.couchdb.client.builder.CloudantFixed
import ssm.couchdb.client.builder.SsmCouchDbClientBuilder
import ssm.couchdb.dsl.model.ChangeEventId
import ssm.couchdb.dsl.model.DatabaseName
import ssm.couchdb.dsl.model.DocType
import ssm.sdk.json.JSONConverter
class CouchdbSsmClient(
val cloudant: CloudantFixed,
private val converter: JSONConverter,
) {
companion object {
const val COUNTING_VIEW = "indexType"
const val FABRIC_COUNTING_DOC = "indexTypeDoc"
const val SSM_CHANGES_FILTER = "ssm_changes_filter"
const val SSM_CHANGES_FILTER_FNC = """
function (doc, req) {
if (doc.docType && doc.docType == 'ssm' && doc.name && doc.name == req.query.ssm) {
return true;
} else if (doc.docType && doc.docType == 'state' && doc.ssm && doc.ssm == req.query.ssm) {
if(req.query.session) {
return doc.session == req.query.session
} else {
return true;
}
} else {
return false;
}
}"""
fun builder(): SsmCouchDbClientBuilder {
return SsmCouchDbClientBuilder()
}
}
fun fetchAllByDocType(
dbName: String,
docType: DocType,
filters: Map = emptyMap(),
): List {
val selector = mapOf(
"docType" to mapOf("\$eq" to docType.name)
).plus(filters)
val findOptions = PostFindOptions.Builder()
.db(dbName)
.selector(selector)
.limit(Long.MAX_VALUE)
.build()
val result: Response = cloudant.postFind(findOptions).execute()
return result.result.docs.mapNotNull { document ->
converter.toObject(docType.clazz.java, document.toString())
}
}
fun fetchAll(
dbName: String,
): List {
val findOptions = PostFindOptions.Builder()
.db(dbName)
.selector(emptyMap())
.limit(Long.MAX_VALUE)
.build()
val result: Response = cloudant.postFind(findOptions).execute()
return result.result.docs
}
fun fetchOneByDocTypeAndName(
dbName: String,
docType: DocType,
name: String,
): T? {
val selector = mapOf(
"docType" to mapOf("\$eq" to docType.name),
"name" to name
)
val findOptions = PostFindOptions.Builder()
.db(dbName)
.selector(selector)
.limit(Long.MAX_VALUE)
.build()
val result: Response = cloudant.postFind(findOptions).execute()
return result.result.docs.firstOrNull()?.let { document ->
converter.toObject(docType.clazz.java, document.toString())
}
}
fun getDatabases(): List {
return cloudant.allDbs.execute().result
}
fun getDatabase(dbName: String): DatabaseInformation {
val query = GetDatabaseInformationOptions.Builder().db(dbName).build()
return cloudant.getDatabaseInformation(query).execute().result
}
suspend fun getSsmChanges(
dbName: DatabaseName,
ssmName: SsmName,
sessionName: SessionName?,
lastEventId: ChangeEventId? = null,
limit: Long? = null
): ChangesResult {
installSsmChangesFilter(dbName)
val query = PostChangesOptions.Builder()
.db(dbName)
.lastEventId(lastEventId)
.includeDocs(true)
.filter("filters/$SSM_CHANGES_FILTER")
limit?.let {
query.limit(limit)
}
return cloudant.postChanges(query.build(), ssmName, sessionName).execute().result
}
suspend fun installSsmChangesFilter(dbName: DatabaseName) = suspendCoroutine { continuation ->
try {
cloudant.getDesignDocument(
GetDesignDocumentOptions.Builder()
.db(dbName)
.ddoc("filters")
.build()
).execute().result
continuation.resume(false)
} catch (e: NotFoundException) {
val stateSsmNameFilter = PutDesignDocumentOptions.Builder()
.db(dbName)
.ddoc("filters")
.designDocument(
DesignDocument.Builder().filters(
mapOf(
SSM_CHANGES_FILTER to SSM_CHANGES_FILTER_FNC
)
).build()
).build()
cloudant.putDesignDocument(stateSsmNameFilter).reactiveRequest().doAfterSuccess {
continuation.resume(true)
}.subscribe()
}
}
fun getCount(dbName: String, docType: DocType): Int {
val query = PostViewOptions.Builder()
.db(dbName)
.ddoc(FABRIC_COUNTING_DOC)
.view(COUNTING_VIEW)
.groupLevel(1)
.key(arrayOf(docType.name))
.build()
return (cloudant.postView(query).execute().result.rows.firstOrNull()?.value as Double?)?.toInt() ?: 0
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy