Skip to content

Commit fe2e579

Browse files
authored
Merge branch 'main' into maint/update-third-party-licenses
2 parents 8892206 + 1cafc2e commit fe2e579

File tree

11 files changed

+230
-12
lines changed

11 files changed

+230
-12
lines changed

client/src/com/mirth/connect/client/ui/Frame.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -724,14 +724,15 @@ public void dispose() {
724724
private void loadExtensionMetaData() throws ClientException {
725725
loadedPlugins = mirthClient.getPluginMetaData();
726726
loadedConnectors = mirthClient.getConnectorMetaData();
727+
Set<String> disabledExtensions = mirthClient.getDisabledExtensions();
727728

728729
// Register extension JAX-RS providers with the client
729730
Set<String> apiProviderPackages = new HashSet<String>();
730731
Set<String> apiProviderClasses = new HashSet<String>();
731732

732733
for (Object extensionMetaData : CollectionUtils.union(loadedPlugins.values(), loadedConnectors.values())) {
733734
MetaData metaData = (MetaData) extensionMetaData;
734-
if (mirthClient.isExtensionEnabled(metaData.getName())) {
735+
if (!disabledExtensions.contains(metaData.getName())) {
735736
for (ApiProvider provider : metaData.getApiProviders(Version.getLatest())) {
736737
switch (provider.getType()) {
737738
case SERVLET_INTERFACE_PACKAGE:

client/src/com/mirth/connect/client/ui/LoadedExtensions.java

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -102,12 +102,20 @@ public void initialize() {
102102
// initialized again
103103
clearExtensionMaps();
104104

105+
Set<String> disabledExtensions;
106+
try {
107+
disabledExtensions = PlatformUI.MIRTH_FRAME.mirthClient.getDisabledExtensions();
108+
} catch (Exception e) {
109+
PlatformUI.MIRTH_FRAME.alertThrowable(PlatformUI.MIRTH_FRAME, e);
110+
return;
111+
}
112+
105113
// Order all the plugins by their weight before loading any of them.
106114
Map<String, String> pluginNameMap = new HashMap<String, String>();
107115
NavigableMap<Integer, List<String>> weightedPlugins = new TreeMap<Integer, List<String>>();
108116
for (PluginMetaData metaData : PlatformUI.MIRTH_FRAME.getPluginMetaData().values()) {
109117
try {
110-
if (PlatformUI.MIRTH_FRAME.mirthClient.isExtensionEnabled(metaData.getName())) {
118+
if (!disabledExtensions.contains(metaData.getName())) {
111119
extensionVersions.put(metaData.getName(), metaData.getPluginVersion());
112120
if (metaData.getClientClasses() != null) {
113121
for (PluginClass pluginClass : metaData.getClientClasses()) {
@@ -150,7 +158,7 @@ public void initialize() {
150158
// Load connector code template plugins before anything else
151159
for (ConnectorMetaData metaData : PlatformUI.MIRTH_FRAME.getConnectorMetaData().values()) {
152160
try {
153-
if (PlatformUI.MIRTH_FRAME.mirthClient.isExtensionEnabled(metaData.getName())) {
161+
if (!disabledExtensions.contains(metaData.getName())) {
154162
extensionVersions.put(metaData.getName(), metaData.getPluginVersion());
155163
if (StringUtils.isNotEmpty(metaData.getTemplateClassName())) {
156164
Class<?> clazz = Class.forName(metaData.getTemplateClassName());
@@ -205,7 +213,7 @@ public void initialize() {
205213

206214
for (ConnectorMetaData metaData : PlatformUI.MIRTH_FRAME.getConnectorMetaData().values()) {
207215
try {
208-
if (PlatformUI.MIRTH_FRAME.mirthClient.isExtensionEnabled(metaData.getName())) {
216+
if (!disabledExtensions.contains(metaData.getName())) {
209217

210218
String connectorName = metaData.getName();
211219
ConnectorSettingsPanel connectorSettingsPanel = (ConnectorSettingsPanel) Class.forName(metaData.getClientClassName()).newInstance();

donkey/src/main/java/com/mirth/connect/donkey/server/data/jdbc/JdbcDao.java

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2935,6 +2935,15 @@ private Map<Long, Map<Integer, Map<String, Object>>> getMetaDataMaps(String chan
29352935
statement = connection.prepareStatement(querySource.getQuery("getMetaDataMapByMessageId", values));
29362936
resultSet = statement.executeQuery();
29372937

2938+
ResultSetMetaData resultSetMetaData = resultSet.getMetaData();
2939+
int columnCount = resultSetMetaData.getColumnCount();
2940+
MetaDataColumnType[] columnTypes = new MetaDataColumnType[columnCount + 1];
2941+
String[] columnNames = new String[columnCount + 1];
2942+
for (int i = 1; i <= columnCount; i++) {
2943+
columnTypes[i] = MetaDataColumnType.fromSqlType(resultSetMetaData.getColumnType(i));
2944+
columnNames[i] = resultSetMetaData.getColumnName(i).toUpperCase();
2945+
}
2946+
29382947
while (resultSet.next()) {
29392948
Long messageId = resultSet.getLong("message_id");
29402949
Integer metaDataId = resultSet.getInt("metadata_id");
@@ -2951,28 +2960,24 @@ private Map<Long, Map<Integer, Map<String, Object>>> getMetaDataMaps(String chan
29512960
connectorMetaDataMap.put(metaDataId, metaDataMap);
29522961
}
29532962

2954-
ResultSetMetaData resultSetMetaData = resultSet.getMetaData();
2955-
int columnCount = resultSetMetaData.getColumnCount();
2956-
29572963
for (int i = 1; i <= columnCount; i++) {
2958-
MetaDataColumnType metaDataColumnType = MetaDataColumnType.fromSqlType(resultSetMetaData.getColumnType(i));
29592964
Object value = null;
29602965

2961-
switch (metaDataColumnType) {//@formatter:off
2966+
switch (columnTypes[i]) {//@formatter:off
29622967
case STRING:
29632968
value = resultSet.getString(i);
29642969
if (encryptor != null && StringUtils.startsWith((String) value, Encryptor.HEADER_INDICATOR)) {
29652970
try {
29662971
value = encryptor.decrypt((String) value);
29672972
} catch (Exception e) {
2968-
logger.debug("Unable to decrypt custom metadata column " + resultSetMetaData.getColumnName(i).toUpperCase() + " for channel " + channelId + ", messsage " + messageId + "-" + metaDataId, e);
2973+
logger.debug("Unable to decrypt custom metadata column " + columnNames[i] + " for channel " + channelId + ", messsage " + messageId + "-" + metaDataId, e);
29692974
}
29702975
}
29712976
break;
29722977
case NUMBER: value = resultSet.getBigDecimal(i); break;
29732978
case BOOLEAN: value = resultSet.getBoolean(i); break;
29742979
case TIMESTAMP:
2975-
2980+
29762981
Timestamp timestamp = resultSet.getTimestamp(i);
29772982
if (timestamp != null) {
29782983
value = Calendar.getInstance();
@@ -2983,7 +2988,7 @@ private Map<Long, Map<Integer, Map<String, Object>>> getMetaDataMaps(String chan
29832988
default: throw new Exception("Unrecognized MetaDataColumnType");
29842989
} //@formatter:on
29852990

2986-
metaDataMap.put(resultSetMetaData.getColumnName(i).toUpperCase(), value);
2991+
metaDataMap.put(columnNames[i], value);
29872992
}
29882993
}
29892994

server/src/com/mirth/connect/client/core/Client.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2622,6 +2622,16 @@ public boolean isExtensionEnabled(String extensionName) throws ClientException {
26222622
return getServlet(ExtensionServletInterface.class).isExtensionEnabled(extensionName);
26232623
}
26242624

2625+
/**
2626+
* Returns the disabled extensions on the classpath.
2627+
*
2628+
* @see ExtensionServletInterface#getDisabledExtensions
2629+
*/
2630+
@Override
2631+
public Set<String> getDisabledExtensions() throws ClientException {
2632+
return getServlet(ExtensionServletInterface.class).getDisabledExtensions();
2633+
}
2634+
26252635
/**
26262636
* Enables or disables an extension.
26272637
*

server/src/com/mirth/connect/client/core/api/servlets/ExtensionServletInterface.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,16 @@ public void uninstallExtension(@Param("extensionPath") @RequestBody(description
111111
@MirthOperation(name = "isExtensionEnabled", display = "Check if extension is enabled", auditable = false)
112112
public boolean isExtensionEnabled(@Param("extensionName") @Parameter(description = "The name of the extension to retrieve.", required = true) @PathParam("extensionName") String extensionName) throws ClientException;
113113

114+
@GET
115+
@Path("/disabled")
116+
@Operation(summary = "Returns the disabled extensions on the classpath.")
117+
@ApiResponse(content = { @Content(mediaType = MediaType.APPLICATION_XML, examples = {
118+
@ExampleObject(name = "disabledExtensions", value = "<set><string>Channel Reader</string></set>") }),
119+
@Content(mediaType = MediaType.APPLICATION_JSON, examples = {
120+
@ExampleObject(name = "disabledExtensions", value = "[\"Channel Reader\"]") }) })
121+
@MirthOperation(name = "getDisabledExtensions", display = "Get disabled extensions", auditable = false)
122+
public Set<String> getDisabledExtensions() throws ClientException;
123+
114124
@POST
115125
@Path("/{extensionName}/_setEnabled")
116126
@Operation(summary = "Enables or disables an extension.")

server/src/com/mirth/connect/server/api/servlets/ExtensionServlet.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,11 @@ public boolean isExtensionEnabled(String extensionName) {
102102
return extensionController.isExtensionEnabled(extensionName);
103103
}
104104

105+
@Override
106+
public Set<String> getDisabledExtensions() {
107+
return extensionController.getDisabledExtensions();
108+
}
109+
105110
@Override
106111
public void setExtensionEnabled(String extensionName, boolean enabled) {
107112
try {

server/src/com/mirth/connect/server/controllers/DefaultExtensionController.java

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
import java.util.HashMap;
2424
import java.util.HashSet;
2525
import java.util.LinkedHashMap;
26+
import java.util.LinkedHashSet;
2627
import java.util.List;
2728
import java.util.Map;
2829
import java.util.NavigableMap;
@@ -364,6 +365,25 @@ public boolean isExtensionEnabled(String extensionName) {
364365
return extensionStatuses.isEnabled(extensionName);
365366
}
366367

368+
@Override
369+
public Set<String> getDisabledExtensions() {
370+
Set<String> disabledExtensions = new LinkedHashSet<String>();
371+
372+
for (MetaData metaData : getPluginMetaData().values()) {
373+
if (!isExtensionEnabled(metaData.getName())) {
374+
disabledExtensions.add(metaData.getName());
375+
}
376+
}
377+
378+
for (MetaData metaData : getConnectorMetaData().values()) {
379+
if (!isExtensionEnabled(metaData.getName())) {
380+
disabledExtensions.add(metaData.getName());
381+
}
382+
}
383+
384+
return disabledExtensions;
385+
}
386+
367387
@Override
368388
public void startPlugins() {
369389
for (ServerPlugin serverPlugin : serverPlugins) {

server/src/com/mirth/connect/server/controllers/ExtensionController.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,11 @@ public static ExtensionController getInstance() {
8686
*/
8787
public abstract boolean isExtensionEnabled(String name);
8888

89+
/**
90+
* Returns the names of disabled extensions on the classpath.
91+
*/
92+
public abstract Set<String> getDisabledExtensions();
93+
8994
/**
9095
* Invokes the start method on all loaded server plugins.
9196
*/
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
// SPDX-License-Identifier: MPL-2.0
2+
// SPDX-FileCopyrightText: 2026 Mitch Gaffigan <[email protected]>
3+
4+
package com.mirth.connect.server.launcher;
5+
6+
import java.io.File;
7+
import java.io.IOException;
8+
import java.nio.charset.StandardCharsets;
9+
import java.util.List;
10+
11+
import org.apache.commons.io.FileUtils;
12+
13+
public class Log4jMigrations {
14+
private static final String INVALID_LOG4J_PROPERTY = "dir.logs";
15+
16+
private Log4jMigrations() {}
17+
18+
public static void migrateConfiguration(File propertiesFile) {
19+
if (!propertiesFile.exists() || !propertiesFile.isFile()) {
20+
return;
21+
}
22+
23+
try {
24+
List<String> lines = FileUtils.readLines(propertiesFile, StandardCharsets.UTF_8);
25+
if (stripDirLogs(lines)) {
26+
FileUtils.writeLines(propertiesFile, StandardCharsets.UTF_8.name(), lines, System.lineSeparator(), false);
27+
}
28+
} catch (IOException e) {
29+
System.err.println("Failed to migrate Log4j configuration: " + propertiesFile.getAbsolutePath());
30+
e.printStackTrace();
31+
}
32+
}
33+
34+
private static boolean stripDirLogs(List<String> lines) {
35+
return lines.removeIf(line -> isPropertyLine(line, INVALID_LOG4J_PROPERTY));
36+
}
37+
38+
private static boolean isPropertyLine(String line, String propertyName) {
39+
String trimmedLine = line.trim();
40+
int equalsIndex = trimmedLine.indexOf('=');
41+
return equalsIndex >= 0 && trimmedLine.substring(0, equalsIndex).trim().equals(propertyName);
42+
}
43+
}

server/src/com/mirth/connect/server/launcher/MirthLauncher.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ public class MirthLauncher {
4040
private static final String EXTENSIONS_DIR = "./extensions";
4141
private static final String SERVER_LAUNCHER_LIB_DIR = "./server-launcher-lib";
4242
private static final String MIRTH_PROPERTIES_FILE = "./conf/mirth.properties";
43+
private static final String LOG4J_PROPERTIES_FILE = "./conf/log4j2.properties";
4344
private static final String PROPERTY_APP_DATA_DIR = "dir.appdata";
4445
private static final String PROPERTY_INCLUDE_CUSTOM_LIB = "server.includecustomlib";
4546
private static final String[] LOG4J_JAR_FILES = { "./server-lib/log4j/log4j-core-2.25.3.jar",
@@ -53,6 +54,8 @@ public class MirthLauncher {
5354
public static void main(String[] args) {
5455
JarFile mirthClientCoreJarFile = null;
5556
try {
57+
Log4jMigrations.migrateConfiguration(new File(LOG4J_PROPERTIES_FILE));
58+
5659
List<URL> classpathUrls = new ArrayList<>();
5760
// Always add log4j
5861
for (String log4jJar : LOG4J_JAR_FILES) {

0 commit comments

Comments
 (0)