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

IQSS / dataverse / #22693

03 Jul 2024 01:09PM CUT coverage: 20.626% (-0.09%) from 20.716%
#22693

push

github

web-flow
Merge pull request #10664 from IQSS/develop

merge develop into master for 6.3

195 of 1852 new or added lines in 82 files covered. (10.53%)

72 existing lines in 33 files now uncovered.

17335 of 84043 relevant lines covered (20.63%)

0.21 hits per line

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

0.0
/src/main/java/edu/harvard/iq/dataverse/settings/ConfigCheckService.java
1
package edu.harvard.iq.dataverse.settings;
2

3
import edu.harvard.iq.dataverse.MailServiceBean;
4
import edu.harvard.iq.dataverse.pidproviders.PidProviderFactoryBean;
5
import edu.harvard.iq.dataverse.pidproviders.PidUtil;
6
import edu.harvard.iq.dataverse.settings.SettingsServiceBean.Key;
7
import edu.harvard.iq.dataverse.util.FileUtil;
8
import edu.harvard.iq.dataverse.util.MailSessionProducer;
9
import jakarta.annotation.PostConstruct;
10
import jakarta.ejb.DependsOn;
11
import jakarta.ejb.Singleton;
12
import jakarta.ejb.Startup;
13
import jakarta.inject.Inject;
14
import jakarta.mail.internet.InternetAddress;
15

16
import java.io.IOException;
17
import java.nio.file.FileSystemException;
18
import java.nio.file.Files;
19
import java.nio.file.Path;
20
import java.util.Map;
21
import java.util.Optional;
22
import java.util.logging.Level;
23
import java.util.logging.Logger;
24

25
@Startup
26
@Singleton
27
@DependsOn({"StartupFlywayMigrator", "PidProviderFactoryBean"})
28
public class ConfigCheckService {
×
29
    
30
    private static final Logger logger = Logger.getLogger(ConfigCheckService.class.getCanonicalName());
×
31
    
32
    @Inject
33
    MailSessionProducer mailSessionProducer;
34
    @Inject
35
    MailServiceBean mailService;
36
    @Inject
37
    PidProviderFactoryBean pidProviderFactoryBean;
38

39
    public static class ConfigurationError extends RuntimeException {
40
        public ConfigurationError(String message) {
41
            super(message);
×
42
        }
×
43
    }
44
    
45
    @PostConstruct
46
    public void startup() {
47
        if (!checkSystemDirectories() || !checkPidProviders()) {
×
48
            throw new ConfigurationError("Not all configuration checks passed successfully. See logs above.");
×
49
        }
50
        
51
        // Only checks resulting in warnings, nothing critical that needs to stop deployment
52
        checkSystemMailSetup();
×
53
    }
×
54

55
    /**
56
     * In this method, we check the existence and write-ability of all important directories we use during
57
     * normal operations. It does not include checks for the storage system. If directories are not available,
58
     * try to create them (and fail when not allowed to).
59
     *
60
     * @return True if all checks successful, false otherwise.
61
     */
62
    public boolean checkSystemDirectories() {
63
        Map<Path, String> paths = Map.of(
×
64
                Path.of(JvmSettings.UPLOADS_DIRECTORY.lookup()), "temporary JSF upload space (see " + JvmSettings.UPLOADS_DIRECTORY.getScopedKey() + ")",
×
65
                Path.of(FileUtil.getFilesTempDirectory()), "temporary processing space (see " + JvmSettings.FILES_DIRECTORY.getScopedKey() + ")",
×
66
                Path.of(JvmSettings.DOCROOT_DIRECTORY.lookup()), "docroot space (see " + JvmSettings.DOCROOT_DIRECTORY.getScopedKey() + ")");
×
67
        
68
        boolean success = true;
×
69
        for (Path path : paths.keySet()) {
×
70
            // Check if the configured path is absolute - avoid potential problems with relative paths this way
71
            if (! path.isAbsolute()) {
×
72
                logger.log(Level.SEVERE, () -> "Configured directory " + path + " for " + paths.get(path) + " is not absolute");
×
73
                success = false;
×
74
                continue;
×
75
            }
76
            
77
            if (! Files.exists(path)) {
×
78
                try {
79
                    Files.createDirectories(path);
×
80
                } catch (IOException e) {
×
81
                    String details;
82
                    if (e instanceof FileSystemException) {
×
83
                        details = ": " + e.getClass();
×
84
                    } else {
85
                        details = "";
×
86
                    }
87
                    
88
                    logger.log(Level.SEVERE, () -> "Could not create directory " + path + " for " + paths.get(path) + details);
×
89
                    success = false;
×
90
                }
×
91
            } else if (!Files.isWritable(path)) {
×
92
                logger.log(Level.SEVERE, () -> "Directory " + path + " for " + paths.get(path) + " exists, but is not writeable");
×
93
                success = false;
×
94
            }
95
        }
×
96
        return success;
×
97
    }
98
    
99
    /**
100
     * This method is not expected to make a deployment fail, but send out clear warning messages about missing or
101
     * wrong configuration settings.
102
     */
103
    public void checkSystemMailSetup() {
104
        // Check if a system mail setting has been provided or issue warning about disabled mail notifications
105
        Optional<InternetAddress> mailAddress = mailService.getSystemAddress();
×
106
        
107
        // Not present -> warning
108
        if (mailAddress.isEmpty()) {
×
109
            logger.warning("Could not find a system mail setting in database (key :" + Key.SystemEmail + ", deprecated) or JVM option '" + JvmSettings.SYSTEM_EMAIL.getScopedKey() + "'");
×
110
            logger.warning("Mail notifications and system messages are deactivated until you provide a configuration");
×
111
        }
112
        
113
        // If there is an app server provided mail config, let's determine if the setup is matching
114
        // TODO: when support for appserver provided mail session goes away, this code can be deleted
115
        if (mailSessionProducer.hasSessionFromAppServer()) {
×
116
            if (mailAddress.isEmpty()) {
×
117
                logger.warning("Found a mail session provided by app server, but no system mail address (see logs above)");
×
118
            // Check if the "from" in the session is the same as the system mail address (see issue 4210)
119
            } else {
120
                String sessionFrom = mailSessionProducer.getSession().getProperty("mail.from");
×
121
                if (! mailAddress.get().toString().equals(sessionFrom)) {
×
122
                    logger.warning(() -> String.format(
×
123
                        "Found app server mail session provided 'from' (%s) does not match system mail setting (%s)",
124
                        sessionFrom, mailAddress.get()));
×
125
                }
126
            }
127
        }
128
    }
×
129

130
    /**
131
     * Verifies that at least one PidProvider capable of editing/minting PIDs is
132
     * configured. Requires the @DependsOn("PidProviderFactoryBean") annotation above
133
     * since it is the @PostCOnstruct init() method of that class that loads the PidProviders
134
     *
135
     * @return True if all checks successful, false otherwise.
136
     */
137
    private boolean checkPidProviders() {
138
        // Check if at least one PidProvider capable of editing/minting PIDs is configured.
NEW
139
        boolean valid=true;
×
NEW
140
        if(!(PidUtil.getManagedProviderIds().size() > 0)) {
×
NEW
141
            valid = false;
×
NEW
142
            logger.warning("No PID providers configured");
×
143
        }
NEW
144
        if (pidProviderFactoryBean.getDefaultPidGenerator()==null){
×
NEW
145
            valid=false;
×
NEW
146
            logger.warning("No default PID provider configured");
×
147
        }
NEW
148
        return valid;
×
149
    }
150
}
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

© 2025 Coveralls, Inc