2 * Copyright (c) 2016, 2017 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.bundlestest.lib;
10 import static org.apache.karaf.bundle.core.BundleState.Active;
11 import static org.apache.karaf.bundle.core.BundleState.Installed;
13 import java.io.Serializable;
14 import java.util.ArrayList;
15 import java.util.Collections;
16 import java.util.EnumMap;
17 import java.util.HashMap;
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 * {@link BundleDiagInfos} implementation.
29 * @author Michael Vorburger.ch
31 // intentionally just package-local
32 final class BundleDiagInfosImpl implements BundleDiagInfos, Serializable {
33 private static final long serialVersionUID = 1L;
35 private static final Map<String, BundleState> WHITELISTED_BUNDLES;
38 WHITELISTED_BUNDLES = new HashMap<>();
39 WHITELISTED_BUNDLES.put("slf4j.log4j12", Installed);
42 private final List<String> okBundleStateInfoTexts;
43 private final List<String> nokBundleStateInfoTexts;
44 private final List<String> whitelistedBundleStateInfoTexts;
45 private final Map<BundleState, Integer> bundleStatesCounters;
47 private BundleDiagInfosImpl(List<String> okBundleStateInfoTexts, List<String> nokBundleStateInfoTexts,
48 List<String> whitelistedBundleStateInfoTexts, Map<BundleState, Integer> bundleStatesCounters) {
49 this.okBundleStateInfoTexts = immutableCopyOf(okBundleStateInfoTexts);
50 this.nokBundleStateInfoTexts = immutableCopyOf(nokBundleStateInfoTexts);
51 this.whitelistedBundleStateInfoTexts = immutableCopyOf(whitelistedBundleStateInfoTexts);
52 this.bundleStatesCounters = immutableCopyOf(bundleStatesCounters);
55 public static BundleDiagInfosImpl forContext(BundleContext bundleContext, BundleService bundleService) {
56 List<String> okBundleStateInfoTexts = new ArrayList<>();
57 List<String> nokBundleStateInfoTexts = new ArrayList<>();
58 List<String> whitelistedBundleStateInfoTexts = new ArrayList<>();
59 Map<BundleState, Integer> bundleStatesCounters = new EnumMap<>(BundleState.class);
60 for (BundleState bundleState : BundleState.values()) {
61 bundleStatesCounters.put(bundleState, 0);
64 for (Bundle bundle : bundleContext.getBundles()) {
65 String bundleSymbolicName = bundle.getSymbolicName();
66 BundleInfo karafBundleInfo = bundleService.getInfo(bundle);
67 BundleState karafBundleState = karafBundleInfo.getState();
69 String bundleStateDiagText = "OSGi state = " + bundleStatetoText(bundle.getState())
70 + ", Karaf bundleState = " + karafBundleState;
71 String diagText = bundleService.getDiag(bundle);
72 if (!diagText.isEmpty()) {
73 bundleStateDiagText += ", due to: " + diagText;
76 if (WHITELISTED_BUNDLES.get(bundleSymbolicName) != null) {
77 if (WHITELISTED_BUNDLES.get(bundleSymbolicName).equals(karafBundleState)) {
78 String msg = "WHITELISTED " + bundleSymbolicName + ": " + bundleStateDiagText;
79 whitelistedBundleStateInfoTexts.add(msg);
84 bundleStatesCounters.compute(karafBundleState, (key, counter) -> counter + 1);
86 // BundleState comparison as in Karaf's "diag" command,
87 // see https://github.com/apache/karaf/blob/master/bundle/core/src/main/java/org/apache/karaf/bundle/command/Diag.java
88 // but we intentionally, got a little further than Karaf's "diag" command,
89 // and instead of only checking some states, we check what's really Active,
90 // but accept that some remain just Resolved:
91 if (karafBundleState != Active && !(karafBundleState == BundleState.Resolved)) {
92 String msg = "NOK " + bundleSymbolicName + ": " + bundleStateDiagText;
93 nokBundleStateInfoTexts.add(msg);
95 String msg = "OK " + bundleSymbolicName + ": " + bundleStateDiagText;
96 okBundleStateInfoTexts.add(msg);
100 return new BundleDiagInfosImpl(okBundleStateInfoTexts, nokBundleStateInfoTexts,
101 whitelistedBundleStateInfoTexts, bundleStatesCounters);
104 private static String bundleStatetoText(int state) {
106 case Bundle.INSTALLED:
108 case Bundle.RESOLVED:
110 case Bundle.STARTING:
114 case Bundle.STOPPING:
116 case Bundle.UNINSTALLED:
117 return "Uninstalled";
119 return state + "???";
124 public SystemState getSystemState() {
125 if (bundleStatesCounters.get(BundleState.Failure) > 0) {
126 return SystemState.Failure;
127 } else if (bundleStatesCounters.get(BundleState.Stopping) > 0) {
128 return SystemState.Stopping;
129 } else if (bundleStatesCounters.get(BundleState.Installed) == 0
130 // No, just Resolved is OK, so do not: && bundleStatesCounters.get(BundleState.Resolved) == 0
131 && bundleStatesCounters.get(BundleState.Unknown) == 0
132 && bundleStatesCounters.get(BundleState.GracePeriod) == 0
133 && bundleStatesCounters.get(BundleState.Waiting) == 0
134 && bundleStatesCounters.get(BundleState.Starting) == 0
135 // BundleState.Active *should* be ~= total # of bundles (minus Resolved, and whitelisted installed)
136 && bundleStatesCounters.get(BundleState.Stopping) == 0
137 && bundleStatesCounters.get(BundleState.Failure) == 0) {
138 return SystemState.Active;
140 return SystemState.Booting;
145 public String getFullDiagnosticText() {
146 StringBuilder sb = new StringBuilder(getSummaryText());
147 int failureNumber = 1;
148 for (String nokBundleStateInfoText : getNokBundleStateInfoTexts()) {
150 sb.append(failureNumber++);
152 sb.append(nokBundleStateInfoText);
154 return sb.toString();
158 public String getSummaryText() {
159 return "diag: " + getSystemState() + " " + bundleStatesCounters.toString();
163 public List<String> getNokBundleStateInfoTexts() {
164 return immutableCopyOf(nokBundleStateInfoTexts);
168 public List<String> getOkBundleStateInfoTexts() {
169 return immutableCopyOf(okBundleStateInfoTexts);
173 public List<String> getWhitelistedBundleStateInfoTexts() {
174 return immutableCopyOf(whitelistedBundleStateInfoTexts);
178 public String toString() {
179 return getFullDiagnosticText();
182 private List<String> immutableCopyOf(List<String> stringList) {
183 return Collections.unmodifiableList(new ArrayList<>(stringList));
186 private Map<BundleState, Integer> immutableCopyOf(Map<BundleState, Integer> map) {
187 return Collections.unmodifiableMap(new HashMap<>(map));