• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

openmrs / openmrs-core / 26342103616

23 May 2026 07:56PM UTC coverage: 65.186% (-0.03%) from 65.217%
26342103616

push

github

web-flow
Backport: stop echoing properties to stdout + fix openmrs-extra typo (2.7.x) (#6120)

* Stop echoing openmrs-server.properties to stdout on startup (#6115)

The merged runtime/server properties file contains DB credentials plus
any property supplied via OMRS_EXTRA_* / OMRS_CONFIG_PROPERTY_* env vars
(API keys, bearer tokens, OAuth secrets, ...). When the container's
stdout is captured by a log sink (Docker, GitHub Actions, ELK, Loki),
those values are exposed in plaintext.

This was recently observed: a downstream module's OpenRouter API key,
supplied as OMRS_CONFIG_PROPERTY_CHARTSEARCHAI_LLM_REMOTE_APIKEY,
ended up in a public GitHub Actions log because the container's
stdout was captured.

Nothing consumes this stdout — startup.sh sources startup-init.sh and
the Java app reads the file from disk via -DOPENMRS_INSTALLATION_SCRIPT.
The cat was added in TRUNK-6184 as a diagnostic alongside OMRS_EXTRA_
support, not as an interface. Operators who need to inspect the
rendered file can read it directly from $OMRS_HOME inside the container.

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* Fix typo in openmrs-extra.properties.tmp path

The line that appends a trailing newline to the merged extras tmp file
referenced `openmrs-exta.properties.tmp` (missing 'r') instead of
`openmrs-extra.properties.tmp`. At every Docker container startup this
created a stray empty file `openmrs-exta.properties.tmp` in the working
directory and the intended trailing newline was never appended to the
real tmp file. In practice the downstream concatenation onto
$OMRS_SERVER_PROPERTIES_FILE was unaffected because each line is already
terminated with \n by `echo -e`, but the typo'd file name was clearly
unintended.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

23602 of 36207 relevant lines covered (65.19%)

0.65 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

0.0
/api/src/main/java/org/openmrs/messagesource/impl/DefaultMessageSourceServiceImpl.java
1
/**
2
 * This Source Code Form is subject to the terms of the Mozilla Public License,
3
 * v. 2.0. If a copy of the MPL was not distributed with this file, You can
4
 * obtain one at http://mozilla.org/MPL/2.0/. OpenMRS is also distributed under
5
 * the terms of the Healthcare Disclaimer located at http://openmrs.org/license.
6
 *
7
 * Copyright (C) OpenMRS Inc. OpenMRS is a registered trademark and the OpenMRS
8
 * graphic logo is a trademark of OpenMRS Inc.
9
 */
10
package org.openmrs.messagesource.impl;
11

12
import java.io.InputStream;
13
import java.util.Collection;
14
import java.util.Locale;
15
import java.util.Properties;
16
import java.util.Set;
17

18
import org.openmrs.messagesource.MessageSourceService;
19
import org.openmrs.messagesource.MutableMessageSource;
20
import org.openmrs.messagesource.PresentationMessage;
21
import org.openmrs.util.OpenmrsClassLoader;
22
import org.openmrs.util.OpenmrsUtil;
23
import org.springframework.context.MessageSource;
24
import org.springframework.context.MessageSourceResolvable;
25
import org.springframework.context.NoSuchMessageException;
26

27
/**
28
 * Loads messages from the default message properties file before spring starts up
29
 */
30
public class DefaultMessageSourceServiceImpl implements MessageSourceService {
31

32
        private Properties props = new Properties();
×
33
        
34
        /**
35
         * Private class to hold the one instance. This is an alternative to
36
         * storing the instance object on {@link DefaultMessageSourceServiceImpl} itself so that garbage collection
37
         * can happen correctly.
38
         */
39
        private static class DefaultMessageSourceServiceImplHolder {
40

41
                private DefaultMessageSourceServiceImplHolder() {
42
                }
43

44
                private static DefaultMessageSourceServiceImpl INSTANCE = null;
×
45
        }
46
        
47
        /**
48
         * Get the static/singular instance
49
         *
50
         * @return DefaultMessageSourceServiceImpl
51
         */
52
        public static DefaultMessageSourceServiceImpl getInstance() {
53
                if (DefaultMessageSourceServiceImplHolder.INSTANCE == null) {
×
54
                        DefaultMessageSourceServiceImplHolder.INSTANCE = new DefaultMessageSourceServiceImpl();
×
55
                }
56
                
57
                return DefaultMessageSourceServiceImplHolder.INSTANCE;
×
58
        }
59
        
60
        private DefaultMessageSourceServiceImpl() {
×
61
                InputStream stream = OpenmrsClassLoader.getInstance().getResourceAsStream("messages.properties");
×
62
                if (stream != null) {
×
63
                        OpenmrsUtil.loadProperties(props, stream);
×
64
                }
65
        }
×
66
        
67
        @Override
68
        public String getMessage(String code, Object[] args, String defaultMessage, Locale locale) {
69
                return getMessage(code);
×
70
        }
71

72
        @Override
73
        public String getMessage(String code, Object[] args, Locale locale) throws NoSuchMessageException {
74
                return getMessage(code);
×
75
        }
76
        
77
        @Override
78
        public String getMessage(String s) {
79
                return (String)props.get(s);
×
80
        }
81
        
82
        @Override
83
        public Collection<Locale> getLocales() {
84
                return null;
×
85
        }
86

87
        @Override
88
        public Collection<PresentationMessage> getPresentations() {
89
                return null;
×
90
        }
91

92
        @Override
93
        public Collection<PresentationMessage> getPresentationsInLocale(Locale locale) {
94
                return null;
×
95
        }
96

97
        @Override
98
        public void addPresentation(PresentationMessage message) {
99
                
100
        }
×
101

102
        @Override
103
        public PresentationMessage getPresentation(String key, Locale forLocale) {
104
                return null;
×
105
        }
106

107
        @Override
108
        public void removePresentation(PresentationMessage message) {
109
                
110
        }
×
111

112
        @Override
113
        public void merge(MutableMessageSource fromSource, boolean overwrite) {
114
                
115
        }
×
116

117
        @Override
118
        public String getMessage(MessageSourceResolvable resolvable, Locale locale) throws NoSuchMessageException {
119
                return null;
×
120
        }
121

122
        @Override
123
        public void setParentMessageSource(MessageSource parent) {
124
                
125
        }
×
126

127
        @Override
128
        public MessageSource getParentMessageSource() {
129
                return null;
×
130
        }
131

132
        @Override
133
        public MutableMessageSource getActiveMessageSource() {
134
                return null;
×
135
        }
136

137
        @Override
138
        public void setActiveMessageSource(MutableMessageSource activeMessageSource) {
139
                
140
        }
×
141

142
        @Override
143
        public Set<MutableMessageSource> getMessageSources() {
144
                return null;
×
145
        }
146

147
        @Override
148
        public void setMessageSources(Set<MutableMessageSource> availableMessageSources) {
149

150
        }
×
151
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc