make sure Git GC errors are visible on the secondary node
[teamcity/git-plugin.git] / git-server-tc / src / jetbrains / buildServer / buildTriggers / vcs / git / health / GitGcErrorsHealthPage.java
1 /*
2  * Copyright 2000-2018 JetBrains s.r.o.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 package jetbrains.buildServer.buildTriggers.vcs.git.health;
18
19 import com.intellij.openapi.diagnostic.Logger;
20 import com.intellij.openapi.util.Pair;
21 import jetbrains.buildServer.buildTriggers.vcs.git.MirrorManager;
22 import jetbrains.buildServer.serverSide.ServerPaths;
23 import jetbrains.buildServer.serverSide.auth.Permission;
24 import jetbrains.buildServer.serverSide.healthStatus.HealthStatusItem;
25 import jetbrains.buildServer.util.FileUtil;
26 import jetbrains.buildServer.web.openapi.PagePlaces;
27 import jetbrains.buildServer.web.openapi.PluginDescriptor;
28 import jetbrains.buildServer.web.openapi.healthStatus.HealthStatusItemPageExtension;
29 import jetbrains.buildServer.web.util.SessionUser;
30 import org.jetbrains.annotations.NotNull;
31
32 import javax.servlet.http.HttpServletRequest;
33 import java.io.File;
34 import java.io.IOException;
35 import java.util.Map;
36 import java.util.Set;
37 import java.util.TreeMap;
38
39 public class GitGcErrorsHealthPage extends HealthStatusItemPageExtension {
40
41   private static final Logger LOG = Logger.getInstance(GitGcErrorsHealthPage.class.getName());
42   private final ServerPaths myServerPaths;
43   private final MirrorManager myMirrorManager;
44
45   public GitGcErrorsHealthPage(@NotNull PluginDescriptor pluginDescriptor,
46                                @NotNull PagePlaces pagePlaces,
47                                @NotNull ServerPaths serverPaths,
48                                @NotNull MirrorManager mirrorManager) {
49     super(GitGcErrorsHealthReport.REPORT_TYPE, pagePlaces);
50     myServerPaths = serverPaths;
51     myMirrorManager = mirrorManager;
52     setIncludeUrl(pluginDescriptor.getPluginResourcesPath("health/gitGcErrorsReport.jsp"));
53     setVisibleOutsideAdminArea(false);
54     register();
55   }
56
57   @Override
58   public boolean isAvailable(@NotNull HttpServletRequest request) {
59     if (!super.isAvailable(request))
60       return false;
61     if (!SessionUser.getUser(request).isPermissionGrantedGlobally(Permission.MANAGE_SERVER_INSTALLATION)) return false;
62     HealthStatusItem item = getStatusItem(request);
63     Object path = item.getAdditionalData().get(GitGcErrorsHealthReport.ERRORS_KEY);
64     return path instanceof Map && !((Map) path).isEmpty();
65   }
66
67   @Override
68   public void fillModel(@NotNull final Map<String, Object> model, @NotNull final HttpServletRequest request) {
69     HealthStatusItem item = getStatusItem(request);
70     Object errors = item.getAdditionalData().get(GitGcErrorsHealthReport.ERRORS_KEY);
71     Map<String, Pair<String, String>> sortedErrors = new TreeMap<>();
72     if (errors instanceof Map) {
73       String baseDir;
74       try {
75         baseDir = myServerPaths.getDataDirectory().getCanonicalPath();
76       } catch (IOException e) {
77         baseDir = myServerPaths.getDataDirectory().getAbsolutePath();
78       }
79
80       //noinspection unchecked
81       Set<Map.Entry> entries = ((Map)errors).entrySet();
82       for (Map.Entry entry : entries) {
83         Object key = entry.getKey();
84         Object value = entry.getValue();
85         if (key instanceof File && value instanceof String) {
86           try {
87             String relativePath = FileUtil.getRelativePath(baseDir, ((File)key).getCanonicalPath(), File.separatorChar);
88             String url = myMirrorManager.getUrl(((File)key).getName());
89             if (url != null) {
90               sortedErrors.put(url, Pair.create("<TeamCity data dir>" + File.separatorChar + relativePath, (String) value));
91             }
92           } catch (IOException e) {
93             LOG.warnAndDebugDetails("Error while preparing health report data", e);
94           }
95         }
96       }
97     }
98     model.put("errors", sortedErrors);
99   }
100 }