001/**
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements.  See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License.  You may obtain a copy of the License at
008 *
009 *      http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017package org.apache.camel.blueprint;
018
019import java.io.PrintWriter;
020import java.io.StringWriter;
021import java.util.Map;
022
023import org.apache.karaf.bundle.core.BundleState;
024import org.apache.karaf.bundle.core.BundleStateService;
025import org.osgi.framework.Bundle;
026import org.osgi.framework.BundleContext;
027import org.osgi.framework.ServiceRegistration;
028
029/**
030 * A service for Karaf to get extended Bundle information related to Camel Context(s) declared in Blueprint
031 * container.
032 */
033public class KarafBundleStateService implements BundleStateService {
034
035    BlueprintCamelStateService camelStateService;
036
037    public KarafBundleStateService(BlueprintCamelStateService camelStateService) {
038        this.camelStateService = camelStateService;
039    }
040
041    @Override
042    public String getName() {
043        return "Camel Blueprint";
044    }
045
046    @Override
047    public String getDiag(Bundle bundle) {
048        if (getState(bundle) == BundleState.Failure) {
049            // return stacktraces for failed camel contexts
050            Map<String, Throwable> exceptions = camelStateService.getExceptions(bundle);
051            StringWriter sw = new StringWriter();
052            for (String contextId : exceptions.keySet()) {
053                sw.append("Camel context \"").append(contextId).append("\"\n");
054                Throwable t = exceptions.get(contextId);
055                if (t instanceof NullPointerException) {
056                    sw.append("Exception: NullPointerException\n");
057                } else if (t.getMessage() != null) {
058                    sw.append("Exception: ").append(t.getMessage()).append("\n");
059                }
060                t.printStackTrace(new PrintWriter(sw));
061                sw.append("\n");
062            }
063            return sw.toString();
064        }
065        return null;
066    }
067
068    @Override
069    public BundleState getState(Bundle bundle) {
070        BundleState effective = BundleState.Unknown;
071        for (BlueprintCamelStateService.State s : camelStateService.getStates(bundle)) {
072            if (effective == BundleState.Unknown || s == BlueprintCamelStateService.State.Failure) {
073                switch (s) {
074                case Starting:
075                    effective = BundleState.Starting;
076                    break;
077                case Active:
078                    effective = BundleState.Active;
079                    break;
080                case Failure:
081                    effective = BundleState.Failure;
082                    break;
083                default:
084                    break;
085                }
086            }
087        }
088        return effective;
089    }
090
091    public ServiceRegistration<?> register(BundleContext context) {
092        return context.registerService(BundleStateService.class, this, null);
093    }
094
095}