Checkstyle: no space inside parentheses
[odlparent.git] / bundles-test / src / main / java / org / opendaylight / odlparent / bundlestest / BundleDiagInfos.java
1 /*
2  * Copyright (c) 2016 Red Hat, Inc. and others. All rights reserved.
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6  * and is available at http://www.eclipse.org/legal/epl-v10.html
7  */
8 package org.opendaylight.odlparent.bundlestest;
9
10 import static org.apache.karaf.bundle.core.BundleState.Active;
11 import static org.apache.karaf.bundle.core.BundleState.Installed;
12
13 import com.google.common.base.Strings;
14 import com.google.common.collect.ImmutableList;
15 import com.google.common.collect.ImmutableMap;
16 import java.util.ArrayList;
17 import java.util.EnumMap;
18 import java.util.List;
19 import java.util.Map;
20 import org.apache.karaf.bundle.core.BundleInfo;
21 import org.apache.karaf.bundle.core.BundleService;
22 import org.apache.karaf.bundle.core.BundleState;
23 import org.osgi.framework.Bundle;
24 import org.osgi.framework.BundleContext;
25
26 /**
27  * System readiness diagnostic summary information.
28  *
29  * @author Michael Vorburger.ch
30  */
31 public class BundleDiagInfos {
32
33     private final List<String> okBundleStateInfoTexts;
34     private final List<String> nokBundleStateInfoTexts;
35     private final List<String> whitelistedBundleStateInfoTexts;
36     private final Map<BundleState, Integer> bundleStatesCounters;
37
38     private static final Map<String, BundleState> WHITELISTED_BUNDLES = ImmutableMap.of(
39             "slf4j.log4j12", Installed);
40
41     public static BundleDiagInfos forContext(BundleContext bundleContext, BundleService bundleService) {
42         List<String> okBundleStateInfoTexts = new ArrayList<>();
43         List<String> nokBundleStateInfoTexts = new ArrayList<>();
44         List<String> whitelistedBundleStateInfoTexts = new ArrayList<>();
45         Map<BundleState, Integer> bundleStatesCounters = new EnumMap<>(BundleState.class);
46         for (BundleState bundleState : BundleState.values()) {
47             bundleStatesCounters.put(bundleState, 0);
48         }
49
50         for (Bundle bundle : bundleContext.getBundles()) {
51             String bundleSymbolicName = bundle.getSymbolicName();
52             BundleInfo karafBundleInfo = bundleService.getInfo(bundle);
53             BundleState karafBundleState = karafBundleInfo.getState();
54
55             String bundleStateDiagText = "OSGi state = " + bundleStatetoText(bundle.getState())
56                 + ", Karaf bundleState = " + karafBundleState;
57             String diagText = bundleService.getDiag(bundle);
58             if (!Strings.isNullOrEmpty(diagText)) {
59                 bundleStateDiagText += ", due to: " + diagText;
60             }
61
62             if (WHITELISTED_BUNDLES.get(bundleSymbolicName) != null) {
63                 if (WHITELISTED_BUNDLES.get(bundleSymbolicName).equals(karafBundleState)) {
64                     String msg = "WHITELISTED " + bundleSymbolicName + ": " + bundleStateDiagText;
65                     whitelistedBundleStateInfoTexts.add(msg);
66                     continue;
67                 }
68             }
69
70             bundleStatesCounters.compute(karafBundleState, (key, counter) -> counter + 1);
71
72             // BundleState comparison as in Karaf's "diag" command,
73             // see https://github.com/apache/karaf/blob/master/bundle/core/src/main/java/org/apache/karaf/bundle/command/Diag.java
74             // but we intentionally, got a little further than Karaf's "diag" command,
75             // and instead of only checking some states, we check what's really Active,
76             // but accept that some remain just Resolved:
77             if (karafBundleState != Active && !(karafBundleState == BundleState.Resolved)) {
78                 String msg = "NOK " + bundleSymbolicName + ": " + bundleStateDiagText;
79                 nokBundleStateInfoTexts.add(msg);
80             } else {
81                 String msg = "OK " + bundleSymbolicName + ": " + bundleStateDiagText;
82                 okBundleStateInfoTexts.add(msg);
83             }
84         }
85
86         return new BundleDiagInfos(okBundleStateInfoTexts, nokBundleStateInfoTexts,
87                 whitelistedBundleStateInfoTexts, bundleStatesCounters);
88     }
89
90     private static String bundleStatetoText(int state) {
91         switch (state) {
92             case Bundle.INSTALLED:
93                 return "Installed";
94             case Bundle.RESOLVED:
95                 return "Resolved";
96             case Bundle.STARTING:
97                 return "Starting";
98             case Bundle.ACTIVE:
99                 return "Active";
100             case Bundle.STOPPING:
101                 return "Stopping";
102             case Bundle.UNINSTALLED:
103                 return "Uninstalled";
104             default:
105                 return state + "???";
106         }
107     }
108
109     private BundleDiagInfos(List<String> okBundleStateInfoTexts, List<String> nokBundleStateInfoTexts,
110             List<String> whitelistedBundleStateInfoTexts, Map<BundleState, Integer> bundleStatesCounters) {
111         this.okBundleStateInfoTexts = ImmutableList.copyOf(okBundleStateInfoTexts);
112         this.nokBundleStateInfoTexts = ImmutableList.copyOf(nokBundleStateInfoTexts);
113         this.whitelistedBundleStateInfoTexts = ImmutableList.copyOf(whitelistedBundleStateInfoTexts);
114         this.bundleStatesCounters = ImmutableMap.copyOf(bundleStatesCounters);
115     }
116
117     public SystemState getSystemState() {
118         if (bundleStatesCounters.get(BundleState.Failure) > 0) {
119             return SystemState.Failure;
120         } else if (bundleStatesCounters.get(BundleState.Stopping) > 0) {
121             return SystemState.Stopping;
122         } else if (bundleStatesCounters.get(BundleState.Installed) == 0
123                 // No, just Resolved is OK, so do not: && bundleStatesCounters.get(BundleState.Resolved) == 0
124                 && bundleStatesCounters.get(BundleState.Unknown) == 0
125                 && bundleStatesCounters.get(BundleState.GracePeriod) == 0
126                 && bundleStatesCounters.get(BundleState.Waiting) == 0
127                 && bundleStatesCounters.get(BundleState.Starting) == 0
128                 // BundleState.Active *should* be ~= total # of bundles (minus Resolved, and whitelisted installed)
129                 && bundleStatesCounters.get(BundleState.Stopping) == 0
130                 && bundleStatesCounters.get(BundleState.Failure) == 0) {
131             return SystemState.Active;
132         } else {
133             return SystemState.Booting;
134         }
135     }
136
137     public String getFullDiagnosticText() {
138         StringBuilder sb = new StringBuilder(getSummaryText());
139         int failureNumber = 1;
140         for (String nokBundleStateInfoText : getNokBundleStateInfoTexts()) {
141             sb.append('\n');
142             sb.append(failureNumber++);
143             sb.append(". ");
144             sb.append(nokBundleStateInfoText);
145         }
146         return sb.toString();
147     }
148
149     public String getSummaryText() {
150         return "diag: " + getSystemState() + " " + bundleStatesCounters.toString();
151     }
152
153     public List<String> getNokBundleStateInfoTexts() {
154         return ImmutableList.copyOf(nokBundleStateInfoTexts);
155     }
156
157     public List<String> getOkBundleStateInfoTexts() {
158         return ImmutableList.copyOf(okBundleStateInfoTexts);
159     }
160
161     public List<String> getWhitelistedBundleStateInfoTexts() {
162         return ImmutableList.copyOf(whitelistedBundleStateInfoTexts);
163     }
164
165     @Override
166     public String toString() {
167         return getFullDiagnosticText();
168     }
169 }