Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add MDC interfaces and base classes (DAT-12601) #3567

Merged
merged 8 commits into from Dec 14, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
19 changes: 18 additions & 1 deletion liquibase-core/pom.xml
Expand Up @@ -283,7 +283,24 @@
</execution>
</executions>
</plugin>

<!-- Generate META-INF/services files automatically for the services specified below. -->
<plugin>
<groupId>eu.somatik.serviceloader-maven-plugin</groupId>
<artifactId>serviceloader-maven-plugin</artifactId>
<version>1.4.0</version>
<configuration>
<services>
<param>liquibase.logging.mdc.MdcManager</param>
</services>
</configuration>
<executions>
<execution>
<goals>
<goal>generate</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
31 changes: 31 additions & 0 deletions liquibase-core/src/main/java/liquibase/Beta.java
@@ -0,0 +1,31 @@
package liquibase;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
* Signifies that a public API (public class, method or field) is subject to incompatible changes,
* or even removal, in a future release. An API bearing this annotation is exempt from any
* compatibility guarantees made by its containing library. Note that the presence of this
* annotation implies nothing about the quality or performance of the API in question, only the fact
* that it is not "API-frozen."
*
* <p>It is generally safe for <i>applications</i> to depend on beta APIs, at the cost of some extra
* work during upgrades. However it is generally inadvisable for <i>libraries</i> (which get
* included on users' CLASSPATHs, outside the library developers' control) to do so.
*
* @author Kevin Bourrillion
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Was this code a contribution? If not, do we want to change the author name?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've been thinking about this and I think I'll leave the author name intact. Kevin is actually the author, not me.

*/
@Retention(RetentionPolicy.CLASS)
@Target({
ElementType.ANNOTATION_TYPE,
ElementType.CONSTRUCTOR,
ElementType.FIELD,
ElementType.METHOD,
ElementType.TYPE
})
@Documented
public @interface Beta {}
51 changes: 49 additions & 2 deletions liquibase-core/src/main/java/liquibase/Scope.java
Expand Up @@ -7,17 +7,20 @@
import liquibase.database.jvm.JdbcConnection;
import liquibase.exception.UnexpectedLiquibaseException;
import liquibase.listener.LiquibaseListener;
import liquibase.logging.LogService;
import liquibase.logging.Logger;
import liquibase.logging.*;
import liquibase.logging.core.JavaLogService;
import liquibase.logging.core.LogServiceFactory;
import liquibase.logging.mdc.MdcManager;
import liquibase.logging.mdc.MdcManagerFactory;
import liquibase.logging.mdc.MdcObject;
import liquibase.osgi.Activator;
import liquibase.resource.ClassLoaderResourceAccessor;
import liquibase.resource.ResourceAccessor;
import liquibase.servicelocator.ServiceLocator;
import liquibase.servicelocator.StandardServiceLocator;
import liquibase.ui.ConsoleUIService;
import liquibase.ui.UIService;
import liquibase.util.CollectionUtil;
import liquibase.util.SmartMap;
import liquibase.util.StringUtil;

Expand Down Expand Up @@ -64,6 +67,7 @@ public enum Attr {
private Scope parent;
private SmartMap values = new SmartMap();
private String scopeId;
private static final Map<String, List<MdcObject>> addedMdcEntries = new HashMap<>();

private LiquibaseListener listener;

Expand Down Expand Up @@ -230,6 +234,12 @@ public static void exit(String scopeId) throws Exception {
throw new RuntimeException("Cannot end scope " + scopeId + " when currently at scope " + currentScope.scopeId);
}

// clear the MDC values added in this scope
List<MdcObject> mdcObjects = addedMdcEntries.get(currentScope.scopeId);
for (MdcObject mdcObject : CollectionUtil.createIfNull(mdcObjects)) {
mdcObject.close();
}

scopeManager.setCurrentScope(currentScope.getParent());
}

Expand Down Expand Up @@ -377,6 +387,43 @@ public Charset getFileEncoding() {
return get(Attr.fileEncoding, Charset.defaultCharset());
}

/**
* Get the current MDC manager.
*/
public MdcManager getMdcManager() {
MdcManagerFactory mdcManagerFactory = getSingleton(MdcManagerFactory.class);
return mdcManagerFactory.getMdcManager();
}

/**
* Add a key value pair to the MDC using the MDC manager. This key value pair will be automatically removed from the
* MDC when this scope exits.
*/
public MdcObject addMdcValue(String key, String value) {
return addMdcValue(key, value, true);
}

/**
* Add a key value pair to the MDC using the MDC manager.
* @param removeWhenScopeExits if true, this key value pair will be automatically removed from the MDC when this
* scope exits. If there is not a demonstrable reason for setting this parameter to false
* then it should be set to true.
*/
public MdcObject addMdcValue(String key, String value, boolean removeWhenScopeExits) {
MdcObject mdcObject = getMdcManager().put(key, value);
if (removeWhenScopeExits) {
Scope currentScope = getCurrentScope();
String scopeId = currentScope.scopeId;
if (addedMdcEntries.containsKey(scopeId)) {
addedMdcEntries.get(scopeId).add(mdcObject);
} else {
addedMdcEntries.put(scopeId, new ArrayList<>(Collections.singletonList(mdcObject)));
}
}

return mdcObject;
}

/**
* Returns {@link LiquibaseListener}s defined in this scope and/or all its parents that are of the given type.
*/
Expand Down