All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.github.numichi.reactive.logger.reactor.MDCContext.kt Maven / Gradle / Ivy

package io.github.numichi.reactive.logger.reactor

import io.github.numichi.reactive.logger.Configuration
import io.github.numichi.reactive.logger.MDC
import io.github.numichi.reactive.logger.coroutine.readMdc
import io.github.numichi.reactive.logger.coroutine.readOrDefaultMdc
import io.github.numichi.reactive.logger.exceptions.ReadException
import io.github.numichi.reactive.logger.hook.mdcReferenceContentLoad
import io.github.numichi.reactive.logger.internal.toSafeMdcMap
import io.github.numichi.reactive.logger.internal.toSafeMdcPair
import reactor.core.publisher.Mono
import reactor.util.context.Context
import reactor.util.context.ContextView
import reactor.util.function.Tuple2
import java.util.function.Function

object MDCContext {
    //region put
    @JvmStatic
    fun put(
        context: Context,
        vararg mdc: MDC,
    ): Context {
        val addedKeys = mutableSetOf()
        var newContext = context

        for (m in mdc) {
            check(!addedKeys.contains(m.contextKey)) { "Duplicate context key writing." }
            addedKeys.add(m.contextKey)
            newContext = newContext.put(m.contextKey, m.data)
        }

        return newContext
    }
    //endregion

    //region merge
    @JvmStatic
    fun modify(
        context: Context,
        contextKey: Any,
        data: Map,
    ): Context {
        val mdc =
            try {
                read(context, contextKey)
            } catch (e: ReadException) {
                MDC(contextKey)
            }

        return put(context, mdc.plus(data.toSafeMdcMap()))
    }

    @JvmStatic
    fun modify(
        context: Context,
        contextKey: Any,
        data: Tuple2,
    ): Context {
        return modify(context, contextKey, data.toSafeMdcMap())
    }

    @JvmStatic
    fun modify(
        context: Context,
        contextKey: Any,
        data: Pair,
    ): Context {
        return modify(context, contextKey, mapOf(data.toSafeMdcPair()))
    }

    @JvmStatic
    fun modify(
        context: Context,
        data: Map,
    ): Context {
        return modify(context, Configuration.defaultReactorContextMdcKey, data)
    }

    @JvmStatic
    fun modify(
        context: Context,
        data: Tuple2,
    ): Context {
        return modify(context, Configuration.defaultReactorContextMdcKey, data)
    }

    @JvmStatic
    fun modify(
        context: Context,
        data: Pair,
    ): Context {
        return modify(context, Configuration.defaultReactorContextMdcKey, data)
    }

    @JvmStatic
    fun modify(
        context: Context,
        data: MDC,
    ): Context {
        return modify(context, data.contextKey, data.data)
    }
    //endregion

    //region get
    @JvmStatic
    fun read(): Mono {
        return read(Configuration.defaultReactorContextMdcKey)
    }

    @JvmStatic
    fun read(contextKey: Any): Mono {
        return Mono.deferContextual { contextView: ContextView ->
            try {
                Mono.just(read(contextView, contextKey))
            } catch (e: ReadException) {
                Mono.error(e)
            }
        }
    }

    @JvmStatic
    fun read(contextView: ContextView): MDC {
        return read(contextView, Configuration.defaultReactorContextMdcKey)
    }

    @JvmStatic
    fun read(
        contextView: ContextView,
        contextKey: Any,
    ): MDC {
        return readMdc(contextView, contextKey)
    }

    @JvmStatic
    fun readOrDefault(): Mono {
        return readOrDefault(Configuration.defaultReactorContextMdcKey)
    }

    @JvmStatic
    fun readOrDefault(contextKey: Any): Mono {
        return Mono.deferContextual { contextView: ContextView ->
            try {
                Mono.just(readOrDefault(contextView, contextKey))
            } catch (e: ReadException) {
                Mono.error(e)
            }
        }
    }

    @JvmStatic
    fun readOrDefault(contextView: ContextView): MDC {
        return readOrDefault(contextView, Configuration.defaultReactorContextMdcKey)
    }

    @JvmStatic
    fun readOrDefault(
        contextView: ContextView,
        contextKey: Any,
    ): MDC {
        return readOrDefaultMdc(contextView, contextKey)
    }
    //endregion

    //region modify
    @JvmStatic
    fun modify(
        context: Context,
        contextKey: Any,
        func: Function,
    ): Context {
        val mdc =
            try {
                read(context, contextKey)
            } catch (e: ReadException) {
                MDC(contextKey)
            }

        return put(context, func.apply(mdc))
    }

    @JvmStatic
    fun modify(
        context: Context,
        func: Function,
    ): Context {
        return modify(context, Configuration.defaultReactorContextMdcKey, func)
    }
    //endregion

    //region snapshot
    @JvmStatic
    fun snapshot(): Mono {
        return snapshot(Configuration.defaultReactorContextMdcKey)
    }

    @JvmStatic
    fun snapshot(contextKey: Any): Mono {
        return Mono.deferContextual { contextView: ContextView ->
            Mono.just(snapshot(contextView, contextKey))
        }
    }

    @JvmStatic
    fun snapshot(contextView: ContextView): MDC {
        return snapshot(contextView, Configuration.defaultReactorContextMdcKey)
    }

    @JvmStatic
    fun snapshot(
        contextView: ContextView,
        contextKey: Any,
    ): MDC {
        return mdcReferenceContentLoad(contextView, MDC(contextKey))
    }
    //endregion
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy