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

oracle / opengrok / #3671

01 Nov 2023 10:10AM UTC coverage: 66.019% (-9.1%) from 75.16%
#3671

push

web-flow
Fix Sonar codesmell issues (#4460)

Signed-off-by: Gino Augustine <ginoaugustine@gmail.com>

308 of 308 new or added lines in 27 files covered. (100.0%)

38690 of 58604 relevant lines covered (66.02%)

0.66 hits per line

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

14.29
/opengrok-web/src/main/java/org/opengrok/web/WebappListener.java
1
/*
2
 * CDDL HEADER START
3
 *
4
 * The contents of this file are subject to the terms of the
5
 * Common Development and Distribution License (the "License").
6
 * You may not use this file except in compliance with the License.
7
 *
8
 * See LICENSE.txt included in this distribution for the specific
9
 * language governing permissions and limitations under the License.
10
 *
11
 * When distributing Covered Code, include this CDDL HEADER in each
12
 * file and include the License file at LICENSE.txt.
13
 * If applicable, add the following below this CDDL HEADER, with the
14
 * fields enclosed by brackets "[]" replaced with your own identifying
15
 * information: Portions Copyright [yyyy] [name of copyright owner]
16
 *
17
 * CDDL HEADER END
18
 */
19

20
/*
21
 * Copyright (c) 2007, 2023, Oracle and/or its affiliates. All rights reserved.
22
 * Portions Copyright (c) 2018, 2019, Chris Fraire <cfraire@me.com>.
23
 */
24
package org.opengrok.web;
25

26
import io.micrometer.core.instrument.Timer;
27
import jakarta.servlet.ServletContext;
28
import jakarta.servlet.ServletContextEvent;
29
import jakarta.servlet.ServletContextListener;
30
import jakarta.servlet.ServletRequestEvent;
31
import jakarta.servlet.ServletRequestListener;
32
import org.opengrok.indexer.Info;
33
import org.opengrok.indexer.Metrics;
34
import org.opengrok.indexer.analysis.AnalyzerGuru;
35
import org.opengrok.indexer.authorization.AuthorizationFramework;
36
import org.opengrok.indexer.configuration.CommandTimeoutType;
37
import org.opengrok.indexer.configuration.Configuration;
38
import org.opengrok.indexer.configuration.Project;
39
import org.opengrok.indexer.configuration.RuntimeEnvironment;
40
import org.opengrok.indexer.index.IndexCheck;
41
import org.opengrok.indexer.index.IndexCheckException;
42
import org.opengrok.indexer.logger.LoggerFactory;
43
import org.opengrok.indexer.web.SearchHelper;
44
import org.opengrok.web.api.ApiTaskManager;
45
import org.opengrok.web.api.v1.controller.ConfigurationController;
46
import org.opengrok.web.api.v1.controller.ProjectsController;
47
import org.opengrok.web.api.v1.suggester.provider.service.SuggesterServiceFactory;
48

49
import java.io.File;
50
import java.io.IOException;
51
import java.nio.file.Path;
52
import java.time.Duration;
53
import java.time.Instant;
54
import java.util.Optional;
55
import java.util.logging.Level;
56
import java.util.logging.Logger;
57

58
/**
59
 * Initialize webapp context.
60
 *
61
 * @author Trond Norbye
62
 */
63
public final class WebappListener implements ServletContextListener, ServletRequestListener {
1✔
64

65
    private static final Logger LOGGER = LoggerFactory.getLogger(WebappListener.class);
1✔
66
    private final Timer startupTimer = Timer.builder("webapp.startup.latency").
1✔
67
                description("web application startup latency").
1✔
68
                register(Metrics.getPrometheusRegistry());
1✔
69

70
    /**
71
     * {@inheritDoc}
72
     */
73
    @Override
74
    public void contextInitialized(final ServletContextEvent servletContextEvent) {
75
        Instant start = Instant.now();
×
76

77
        ServletContext context = servletContextEvent.getServletContext();
×
78
        RuntimeEnvironment env = RuntimeEnvironment.getInstance();
×
79

80
        LOGGER.log(Level.INFO, "Starting webapp with version {0} ({1})",
×
81
                    new Object[]{Info.getVersion(), Info.getRevision()});
×
82

83
        String configPath = Optional.ofNullable(context.getInitParameter("CONFIGURATION"))
×
84
                .orElseThrow(() -> new WebappError("CONFIGURATION parameter missing in the web.xml file"));
×
85
        try {
86
            env.readConfiguration(new File(configPath), CommandTimeoutType.WEBAPP_START);
×
87
        } catch (IOException ex) {
×
88
            LOGGER.log(Level.WARNING, "Configuration error. Failed to read config file: ", ex);
×
89
        }
×
90

91
        String serverInfo = context.getServerInfo();
×
92
        LOGGER.log(Level.INFO, "running inside {0}", serverInfo);
×
93
        if (serverInfo.startsWith("Apache Tomcat")) {
×
94
            int idx;
95
            if ((idx = serverInfo.indexOf('/')) > 0) {
×
96
                String version = serverInfo.substring(idx + 1);
×
97
                if (!version.startsWith("10.")) {
×
98
                    LOGGER.log(Level.SEVERE, "Unsupported Tomcat version: {0}", version);
×
99
                    throw new WebappError("Unsupported Tomcat version");
×
100
                }
101
            }
102
        }
103

104
        /*
105
         * Create a new instance of authorization framework. If the code above
106
         * (reading the configuration) failed then the plugin directory is
107
         * possibly {@code null} causing the framework to allow every request.
108
         */
109
        env.setAuthorizationFramework(new AuthorizationFramework(env.getPluginDirectory(), env.getPluginStack()));
×
110
        env.getAuthorizationFramework().reload();
×
111

112
        if (env.isWebappCtags() && !env.validateUniversalCtags()) {
×
113
            LOGGER.warning("Didn't find Universal Ctags for --webappCtags");
×
114
        }
115

116
        String pluginDirectory = env.getPluginDirectory();
×
117
        if (pluginDirectory != null && env.isAuthorizationWatchdog()) {
×
118
            env.getWatchDog().start(new File(pluginDirectory));
×
119
        }
120

121
        indexCheck(configPath, env);
×
122

123
        env.startExpirationTimer();
×
124

125
        ApiTaskManager.getInstance().setContextPath(context.getContextPath());
×
126
        // register API task queues
127
        ApiTaskManager.getInstance().addPool(ProjectsController.PROJECTS_PATH, 1);
×
128
        // Used by ConfigurationController#reloadAuthorization()
129
        ApiTaskManager.getInstance().addPool("authorization", 1);
×
130
        ApiTaskManager.getInstance().addPool(ConfigurationController.PATH, 1);
×
131

132
        startupTimer.record(Duration.between(start, Instant.now()));
×
133
    }
×
134

135
    /**
136
     * Check index(es). If projects are enabled, those which failed the test will be marked as not indexed.
137
     * @param configPath path to configuration
138
     * @param env {@link RuntimeEnvironment} instance
139
     */
140
    private static void indexCheck(String configPath, RuntimeEnvironment env) {
141
        try (IndexCheck indexCheck = new IndexCheck(Configuration.read(new File(configPath)))) {
×
142
                indexCheck.check(IndexCheck.IndexCheckMode.VERSION);
×
143
        } catch (IOException e) {
×
144
            LOGGER.log(Level.WARNING, "could not perform index check", e);
×
145
        } catch (IndexCheckException e) {
×
146
            if (env.isProjectsEnabled()) {
×
147
                LOGGER.log(Level.INFO, "marking projects that failed the index check as not indexed");
×
148

149
                for (Path path : e.getFailedPaths()) {
×
150
                    Project project = Project.getProject(path.toFile());
×
151
                    if (project != null) {
×
152
                        project.setIndexed(false);
×
153
                    }
154
                }
×
155
            } else {
156
                // Fail the deployment. The index check would fail only on legitimate version discrepancy.
157
                throw new WebappError("index version check failed", e);
×
158
            }
159
        }
×
160
    }
×
161

162
    /**
163
     * {@inheritDoc}
164
     */
165
    @Override
166
    public void contextDestroyed(final ServletContextEvent servletContextEvent) {
167
        RuntimeEnvironment env = RuntimeEnvironment.getInstance();
×
168
        env.getIndexerParallelizer().bounce();
×
169
        env.getWatchDog().stop();
×
170
        env.stopExpirationTimer();
×
171
        try {
172
            env.shutdownRevisionExecutor();
×
173
            env.shutdownSearchExecutor();
×
174
            env.shutdownDirectoryListingExecutor();
×
175
        } catch (InterruptedException e) {
×
176
            LOGGER.log(Level.WARNING, "Could not shutdown revision executor", e);
×
177
        }
×
178

179
        // need to explicitly close the suggester service because it might have scheduled rebuild which could prevent
180
        // the web application from closing
181
        SuggesterServiceFactory.getDefault().close();
×
182

183
        // destroy queue(s) of API tasks
184
        try {
185
            ApiTaskManager.getInstance().shutdown();
×
186
        } catch (InterruptedException e) {
×
187
            LOGGER.log(Level.WARNING, "could not shutdown API task manager cleanly", e);
×
188
        }
×
189
    }
×
190

191
    /**
192
     * {@inheritDoc}
193
     */
194
    @Override
195
    public void requestInitialized(ServletRequestEvent e) {
196
        // pass
197
    }
1✔
198

199
    /**
200
     * {@inheritDoc}
201
     */
202
    @Override
203
    public void requestDestroyed(ServletRequestEvent e) {
204
        PageConfig.cleanup(e.getServletRequest());
1✔
205
        SearchHelper sh = (SearchHelper) e.getServletRequest().getAttribute(SearchHelper.REQUEST_ATTR);
1✔
206
        if (sh != null) {
1✔
207
            sh.destroy();
×
208
        }
209

210
        AnalyzerGuru.returnAnalyzers();
1✔
211
    }
1✔
212
}
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