cdf6ce1953123595eb49d8fa24d1332a15cca7e9
[ccsdk/cds.git] / ms / blueprintsprocessor / modules / commons / processor-core / src / main / kotlin / org / onap / ccsdk / cds / blueprintsprocessor / core / LoggerExtensions.kt
1 /*
2  * Copyright © 2018-2019 AT&T Intellectual Property.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 package org.onap.ccsdk.cds.blueprintsprocessor.core
18
19 import kotlinx.coroutines.*
20 import kotlinx.coroutines.reactor.ReactorContext
21 import kotlinx.coroutines.reactor.asCoroutineContext
22 import org.onap.ccsdk.cds.blueprintsprocessor.core.service.MonoMDCCoroutine
23 import org.onap.ccsdk.cds.controllerblueprints.core.MDCContext
24 import reactor.core.publisher.Mono
25 import kotlin.coroutines.CoroutineContext
26 import kotlin.coroutines.EmptyCoroutineContext
27
28 /** Used in Rest controller API methods to populate MDC context to nested coroutines from reactor web filter context. */
29 @UseExperimental(InternalCoroutinesApi::class)
30 fun <T> monoMdc(context: CoroutineContext = EmptyCoroutineContext,
31                 block: suspend CoroutineScope.() -> T?): Mono<T> = Mono.create { sink ->
32
33     val reactorContext = (context[ReactorContext]?.context?.putAll(sink.currentContext())
34             ?: sink.currentContext()).asCoroutineContext()
35     /** Populate MDC context only if present in Reactor Context */
36     val newContext = if (!reactorContext.context.isEmpty
37             && reactorContext.context.hasKey(MDCContext)) {
38         val mdcContext = reactorContext.context.get<MDCContext>(MDCContext)
39         GlobalScope.newCoroutineContext(context + reactorContext + mdcContext)
40     } else GlobalScope.newCoroutineContext(context + reactorContext)
41
42     val coroutine = MonoMDCCoroutine(newContext, sink)
43     sink.onDispose(coroutine)
44     coroutine.start(CoroutineStart.DEFAULT, coroutine, block)
45 }