2 * Copyright (c) 2016 Red Hat, Inc. and others. All rights reserved.
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
8 package org.opendaylight.odlparent.bundles4test;
10 import static org.apache.karaf.bundle.core.BundleState.Active;
11 import static org.apache.karaf.bundle.core.BundleState.Installed;
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;
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;
27 * System readiness diagnostic summary information.
29 * @author Michael Vorburger.ch
31 public class BundleDiagInfos {
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;
38 private static final Map<String, BundleState> WHITELISTED_BUNDLES = ImmutableMap.of(
39 "slf4j.log4j12", Installed);
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);
50 for (Bundle bundle : bundleContext.getBundles()) {
51 String bundleSymbolicName = bundle.getSymbolicName();
52 BundleInfo karafBundleInfo = bundleService.getInfo(bundle);
53 BundleState karafBundleState = karafBundleInfo.getState();
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;
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);
70 bundleStatesCounters.compute(karafBundleState, (key, counter) -> counter + 1);
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);
81 String msg = "OK " + bundleSymbolicName + ": " + bundleStateDiagText;
82 okBundleStateInfoTexts.add(msg);
86 return new BundleDiagInfos(okBundleStateInfoTexts, nokBundleStateInfoTexts,
87 whitelistedBundleStateInfoTexts, bundleStatesCounters);
90 private static String bundleStatetoText(int state) {
92 case Bundle.INSTALLED:
100 case Bundle.STOPPING:
102 case Bundle.UNINSTALLED:
103 return "Uninstalled";
105 return state + "???";
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);
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;
133 return SystemState.Booting;
137 public String getFullDiagnosticText() {
138 StringBuilder sb = new StringBuilder(getSummaryText());
139 int failureNumber = 1;
140 for (String nokBundleStateInfoText : getNokBundleStateInfoTexts()) {
142 sb.append(failureNumber++);
144 sb.append(nokBundleStateInfoText);
146 return sb.toString();
149 public String getSummaryText() {
150 return "diag: " + getSystemState() + " " + bundleStatesCounters.toString();
153 public List<String> getNokBundleStateInfoTexts() {
154 return ImmutableList.copyOf(nokBundleStateInfoTexts);
157 public List<String> getOkBundleStateInfoTexts() {
158 return ImmutableList.copyOf(okBundleStateInfoTexts);
161 public List<String> getWhitelistedBundleStateInfoTexts() {
162 return ImmutableList.copyOf(whitelistedBundleStateInfoTexts);
166 public String toString() {
167 return getFullDiagnosticText();