Bug 8415 related: Make TestBundleDiag a lib
[odlparent.git] / bundles-test-lib / src / main / java / org / opendaylight / odlparent / bundlestest / lib / BundleDiagInfosImpl.java
1 /*
2  * Copyright (c) 2016, 2017 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.lib;
9
10 import static org.apache.karaf.bundle.core.BundleState.Active;
11 import static org.apache.karaf.bundle.core.BundleState.Installed;
12
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;
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  * {@link BundleDiagInfos} implementation.
28  *
29  * @author Michael Vorburger.ch
30  */
31 // intentionally just package-local
32 final class BundleDiagInfosImpl implements BundleDiagInfos, Serializable {
33     private static final long serialVersionUID = 1L;
34
35     private static final Map<String, BundleState> WHITELISTED_BUNDLES;
36
37     static {
38         WHITELISTED_BUNDLES = new HashMap<>();
39         WHITELISTED_BUNDLES.put("slf4j.log4j12", Installed);
40     }
41
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;
46
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);
53     }
54
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);
62         }
63
64         for (Bundle bundle : bundleContext.getBundles()) {
65             String bundleSymbolicName = bundle.getSymbolicName();
66             BundleInfo karafBundleInfo = bundleService.getInfo(bundle);
67             BundleState karafBundleState = karafBundleInfo.getState();
68
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;
74             }
75
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);
80                     continue;
81                 }
82             }
83
84             bundleStatesCounters.compute(karafBundleState, (key, counter) -> counter + 1);
85
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);
94             } else {
95                 String msg = "OK " + bundleSymbolicName + ": " + bundleStateDiagText;
96                 okBundleStateInfoTexts.add(msg);
97             }
98         }
99
100         return new BundleDiagInfosImpl(okBundleStateInfoTexts, nokBundleStateInfoTexts,
101                 whitelistedBundleStateInfoTexts, bundleStatesCounters);
102     }
103
104     private static String bundleStatetoText(int state) {
105         switch (state) {
106             case Bundle.INSTALLED:
107                 return "Installed";
108             case Bundle.RESOLVED:
109                 return "Resolved";
110             case Bundle.STARTING:
111                 return "Starting";
112             case Bundle.ACTIVE:
113                 return "Active";
114             case Bundle.STOPPING:
115                 return "Stopping";
116             case Bundle.UNINSTALLED:
117                 return "Uninstalled";
118             default:
119                 return state + "???";
120         }
121     }
122
123     @Override
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;
139         } else {
140             return SystemState.Booting;
141         }
142     }
143
144     @Override
145     public String getFullDiagnosticText() {
146         StringBuilder sb = new StringBuilder(getSummaryText());
147         int failureNumber = 1;
148         for (String nokBundleStateInfoText : getNokBundleStateInfoTexts()) {
149             sb.append('\n');
150             sb.append(failureNumber++);
151             sb.append(". ");
152             sb.append(nokBundleStateInfoText);
153         }
154         return sb.toString();
155     }
156
157     @Override
158     public String getSummaryText() {
159         return "diag: " + getSystemState() + " " + bundleStatesCounters.toString();
160     }
161
162     @Override
163     public List<String> getNokBundleStateInfoTexts() {
164         return immutableCopyOf(nokBundleStateInfoTexts);
165     }
166
167     @Override
168     public List<String> getOkBundleStateInfoTexts() {
169         return immutableCopyOf(okBundleStateInfoTexts);
170     }
171
172     @Override
173     public List<String> getWhitelistedBundleStateInfoTexts() {
174         return immutableCopyOf(whitelistedBundleStateInfoTexts);
175     }
176
177     @Override
178     public String toString() {
179         return getFullDiagnosticText();
180     }
181
182     private List<String> immutableCopyOf(List<String> stringList) {
183         return Collections.unmodifiableList(new ArrayList<>(stringList));
184     }
185
186     private Map<BundleState, Integer> immutableCopyOf(Map<BundleState, Integer> map) {
187         return Collections.unmodifiableMap(new HashMap<>(map));
188     }
189
190 }