package org.onap.ccsdk.cds.blueprintsprocessor.rest.service
-import kotlinx.coroutines.*
+import kotlinx.coroutines.AbstractCoroutine
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.CoroutineStart
+import kotlinx.coroutines.GlobalScope
+import kotlinx.coroutines.InternalCoroutinesApi
+import kotlinx.coroutines.coroutineScope
+import kotlinx.coroutines.handleCoroutineException
+import kotlinx.coroutines.newCoroutineContext
import kotlinx.coroutines.reactor.ReactorContext
import kotlinx.coroutines.reactor.asCoroutineContext
+import kotlinx.coroutines.withContext
import org.apache.http.message.BasicHeader
+import org.onap.ccsdk.cds.controllerblueprints.core.BluePrintConstants
import org.onap.ccsdk.cds.controllerblueprints.core.BluePrintConstants.ONAP_INVOCATION_ID
import org.onap.ccsdk.cds.controllerblueprints.core.BluePrintConstants.ONAP_PARTNER_NAME
import org.onap.ccsdk.cds.controllerblueprints.core.BluePrintConstants.ONAP_REQUEST_ID
import java.time.ZoneOffset
import java.time.ZonedDateTime
import java.time.format.DateTimeFormatter
-import java.util.*
+import java.util.UUID
import kotlin.coroutines.CoroutineContext
import kotlin.coroutines.EmptyCoroutineContext
fun httpInvoking(headers: Array<BasicHeader>) {
headers.plusElement(BasicHeader(ONAP_REQUEST_ID, MDC.get("InvocationID").defaultToUUID()))
headers.plusElement(BasicHeader(ONAP_INVOCATION_ID, UUID.randomUUID().toString()))
- val partnerName = System.getProperty("APPNAME") ?: "BlueprintsProcessor"
- headers.plusElement(BasicHeader(ONAP_PARTNER_NAME, partnerName))
+ headers.plusElement(BasicHeader(ONAP_PARTNER_NAME, BluePrintConstants.APP_NAME))
}
}
val resHeaders = response.headers
resHeaders[ONAP_REQUEST_ID] = MDC.get("RequestID")
resHeaders[ONAP_INVOCATION_ID] = MDC.get("InvocationID")
- val partnerName = System.getProperty("APPNAME") ?: "BlueprintsProcessor"
- resHeaders[ONAP_PARTNER_NAME] = partnerName
+ resHeaders[ONAP_PARTNER_NAME] = BluePrintConstants.APP_NAME
} catch (e: Exception) {
log.warn("couldn't set response headers", e)
} finally {
}
}
+/** Used in Rest controller API methods to populate MDC context to nested coroutines from reactor web filter context. */
+suspend fun <T> mdcWebCoroutineScope(
+ block: suspend CoroutineScope.() -> T
+) = coroutineScope {
+ val reactorContext = this.coroutineContext[ReactorContext]
+ /** Populate MDC context only if present in Reactor Context */
+ val newContext = if (reactorContext != null &&
+ !reactorContext.context.isEmpty &&
+ reactorContext.context.hasKey(MDCContext)
+ ) {
+ val mdcContext = reactorContext.context.get<MDCContext>(MDCContext)
+ if (mdcContext != null)
+ newCoroutineContext(this.coroutineContext + reactorContext + mdcContext)
+ else
+ newCoroutineContext(this.coroutineContext + reactorContext)
+ } else this.coroutineContext
+ // Execute the block with new and old context
+ withContext(newContext) {
+ block()
+ }
+}
+@Deprecated(
+ message = "Now CDS supports Coruoutin rest controller",
+ replaceWith = ReplaceWith("mdcWebCoroutineScope")
+)
/** Used in Rest controller API methods to populate MDC context to nested coroutines from reactor web filter context. */
@UseExperimental(InternalCoroutinesApi::class)
-fun <T> monoMdc(context: CoroutineContext = EmptyCoroutineContext,
- block: suspend CoroutineScope.() -> T?): Mono<T> = Mono.create { sink ->
+fun <T> monoMdc(
+ context: CoroutineContext = EmptyCoroutineContext,
+ block: suspend CoroutineScope.() -> T?
+): Mono<T> = Mono.create { sink ->
val reactorContext = (context[ReactorContext]?.context?.putAll(sink.currentContext())
- ?: sink.currentContext()).asCoroutineContext()
+ ?: sink.currentContext()).asCoroutineContext()
/** Populate MDC context only if present in Reactor Context */
- val newContext = if (!reactorContext.context.isEmpty
- && reactorContext.context.hasKey(MDCContext)) {
+ val newContext = if (!reactorContext.context.isEmpty &&
+ reactorContext.context.hasKey(MDCContext)
+ ) {
val mdcContext = reactorContext.context.get<MDCContext>(MDCContext)
GlobalScope.newCoroutineContext(context + reactorContext + mdcContext)
} else GlobalScope.newCoroutineContext(context + reactorContext)
@InternalCoroutinesApi
class MonoMDCCoroutine<in T>(
- parentContext: CoroutineContext,
- private val sink: MonoSink<T>
+ parentContext: CoroutineContext,
+ private val sink: MonoSink<T>
) : AbstractCoroutine<T>(parentContext, true), Disposable {
+
private var disposed = false
override fun onCompleted(value: T) {