InactiveBundlesHealthCheck.java
6.12 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
/*
* Decompiled with CFR 0_118.
*
* Could not load the following classes:
* org.apache.felix.scr.annotations.Activate
* org.apache.felix.scr.annotations.Component
* org.apache.felix.scr.annotations.Deactivate
* org.apache.felix.scr.annotations.Properties
* org.apache.felix.scr.annotations.Property
* org.apache.felix.scr.annotations.PropertyUnbounded
* org.apache.felix.scr.annotations.Service
* org.apache.sling.commons.osgi.PropertiesUtil
* org.apache.sling.hc.api.HealthCheck
* org.apache.sling.hc.api.Result
* org.apache.sling.hc.api.ResultLog
* org.apache.sling.hc.util.FormattingResultLog
* org.osgi.framework.Bundle
* org.osgi.framework.BundleContext
* org.osgi.framework.Version
* org.osgi.service.component.ComponentContext
*/
package com.adobe.granite.bundles.hc.impl;
import java.text.MessageFormat;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Dictionary;
import java.util.HashSet;
import java.util.Hashtable;
import java.util.Set;
import org.apache.felix.scr.annotations.Activate;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Deactivate;
import org.apache.felix.scr.annotations.Properties;
import org.apache.felix.scr.annotations.Property;
import org.apache.felix.scr.annotations.PropertyUnbounded;
import org.apache.felix.scr.annotations.Service;
import org.apache.sling.commons.osgi.PropertiesUtil;
import org.apache.sling.hc.api.HealthCheck;
import org.apache.sling.hc.api.Result;
import org.apache.sling.hc.api.ResultLog;
import org.apache.sling.hc.util.FormattingResultLog;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleContext;
import org.osgi.framework.Version;
import org.osgi.service.component.ComponentContext;
@Component(metatype=1, label="Adobe Granite Active Bundles Health Check", description="This health check scan the current set of OSGi bundles for inactive bundles.")
@Properties(value={@Property(name="hc.name", value={"Active Bundles"}, propertyPrivate=1), @Property(name="hc.tags", unbounded=PropertyUnbounded.ARRAY, label="Tags", description="Tags for this check to be used by composite health checks."), @Property(name="hc.mbean.name", value={"inactiveBundles"}, propertyPrivate=1)})
@Service(value={HealthCheck.class})
public class InactiveBundlesHealthCheck
implements HealthCheck {
@Property(label="Ignored Bundles", description="One or more Bundle Symbolic Names to be ignored.", unbounded=PropertyUnbounded.ARRAY, value={"com.day.crx.crxde-support", "com.adobe.granite.crx-explorer", "com.adobe.granite.crxde-lite"})
private static final String PROP_IGNORED_BUNDLES = "ignored.bundles";
private Set<String> ignoredBundles;
private BundleContext bundleContext;
private Dictionary<Integer, String> bundleState;
private void populateBundleStateDictionary() {
this.bundleState = new Hashtable<Integer, String>();
this.bundleState.put(32, "Active");
this.bundleState.put(2, "Installed");
this.bundleState.put(4, "Resolved");
this.bundleState.put(8, "Starting");
this.bundleState.put(16, "Stopping");
this.bundleState.put(1, "Uninstalled");
}
@Activate
protected void activate(ComponentContext cc) {
this.bundleContext = cc.getBundleContext();
String[] ignored = PropertiesUtil.toStringArray(cc.getProperties().get("ignored.bundles"), (String[])null);
this.ignoredBundles = ignored == null ? Collections.emptySet() : Collections.unmodifiableSet(new HashSet<String>(Arrays.asList(ignored)));
this.populateBundleStateDictionary();
}
@Deactivate
protected void deactivate() {
this.bundleContext = null;
}
public Result execute() {
Bundle[] bundles;
FormattingResultLog resultLog = new FormattingResultLog();
int inactiveBundles = 0;
for (Bundle b : bundles = this.bundleContext.getBundles()) {
if (InactiveBundlesHealthCheck.isBundleActive(b) || this.isIgnored(b)) continue;
++inactiveBundles;
resultLog.warn("Bundle {}:{} is in the following state: {}", new Object[]{b.getSymbolicName(), b.getVersion(), this.bundleState.get(b.getState())});
}
if (this.ignoredBundles != null && this.ignoredBundles.size() > 0) {
StringBuilder builder = new StringBuilder();
for (String bundle : this.ignoredBundles) {
builder.append(bundle).append(", ");
}
builder.delete(builder.length() - 2, builder.length());
resultLog.info("[The following bundles are added to the ignore list and do not count towards the health check output: {}.]( )", new Object[]{builder.toString()});
resultLog.info("[You can add or remove bundles to the ignore list by changing the InactiveBundlesHealthCheck configuration in the administration console.]( )", new Object[0]);
}
if (inactiveBundles > 0) {
String msg = inactiveBundles == 1 ? "[There is one inactive bundle. You can view it or change its status in the administration console.]" : MessageFormat.format("[There are {0} inactive bundles. You can view them or change their status in the administration console.]", inactiveBundles);
resultLog.info(msg + "(/system/console/bundles)", new Object[0]);
} else {
resultLog.debug("No inactive or unresolved bundles were found.", new Object[0]);
}
return new Result((ResultLog)resultLog);
}
private boolean isIgnored(Bundle b) {
return this.ignoredBundles.contains(b.getSymbolicName());
}
private static boolean isBundleActive(Bundle b) {
if (b.getState() == 32) {
return true;
}
if (b.getState() == 8 && InactiveBundlesHealthCheck.isLazyActivatian(b)) {
return true;
}
return InactiveBundlesHealthCheck.getFragmentHostHeader(b) != null;
}
private static String getFragmentHostHeader(Bundle b) {
return (String)b.getHeaders().get("Fragment-Host");
}
private static boolean isLazyActivatian(Bundle b) {
return "lazy".equals(b.getHeaders().get("Bundle-ActivationPolicy"));
}
}