| /* |
| * Licensed to the Apache Software Foundation (ASF) under one or more |
| * contributor license agreements. See the NOTICE file distributed with |
| * this work for additional information regarding copyright ownership. |
| * The ASF licenses this file to You under the Apache License, Version 2.0 |
| * (the "License"); you may not use this file except in compliance with |
| * the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| package org.apache.camel.core.osgi; |
| |
| import java.util.Dictionary; |
| import java.util.Hashtable; |
| |
| import org.apache.camel.spi.CamelEvent; |
| import org.apache.camel.support.EventNotifierSupport; |
| |
| import org.osgi.framework.Bundle; |
| import org.osgi.framework.BundleContext; |
| import org.osgi.framework.Constants; |
| import org.osgi.framework.Version; |
| import org.osgi.service.event.Event; |
| import org.osgi.service.event.EventAdmin; |
| import org.osgi.util.tracker.ServiceTracker; |
| |
| /** |
| * This {@link org.apache.camel.spi.EventNotifier} is in charge of propagating events |
| * to OSGi {@link EventAdmin} if present. |
| */ |
| public class OsgiEventAdminNotifier extends EventNotifierSupport { |
| |
| public static final String TYPE = "type"; |
| public static final String EVENT = "event"; |
| public static final String TIMESTAMP = "timestamp"; |
| public static final String BUNDLE = "bundle"; |
| public static final String BUNDLE_ID = "bundle.id"; |
| public static final String BUNDLE_SYMBOLICNAME = "bundle.symbolicName"; |
| public static final String BUNDLE_VERSION = "bundle.version"; |
| public static final String CAUSE = "cause"; |
| |
| public static final String TOPIC_CAMEL_EVENTS = "org/apache/camel/"; |
| public static final String TOPIC_CAMEL_CONTEXT_EVENTS = TOPIC_CAMEL_EVENTS + "context/"; |
| public static final String TOPIC_CAMEL_EXCHANGE_EVENTS = TOPIC_CAMEL_EVENTS + "exchange/"; |
| public static final String TOPIC_CAMEL_SERVICE_EVENTS = TOPIC_CAMEL_EVENTS + "service/"; |
| public static final String TOPIC_CAMEL_ROUTE_EVENTS = TOPIC_CAMEL_EVENTS + "route/"; |
| |
| private final BundleContext bundleContext; |
| private final ServiceTracker<EventAdmin, EventAdmin> tracker; |
| |
| public OsgiEventAdminNotifier(BundleContext bundleContext) { |
| this.bundleContext = bundleContext; |
| this.tracker = new ServiceTracker<>(bundleContext, EventAdmin.class.getName(), null); |
| setIgnoreExchangeEvents(true); |
| } |
| |
| public void notify(CamelEvent event) throws Exception { |
| EventAdmin eventAdmin = tracker.getService(); |
| if (eventAdmin == null) { |
| return; |
| } |
| |
| Dictionary<String, Object> props = new Hashtable<>(); |
| props.put(TYPE, getType(event)); |
| props.put(EVENT, event); |
| props.put(TIMESTAMP, System.currentTimeMillis()); |
| props.put(BUNDLE, bundleContext.getBundle()); |
| props.put(BUNDLE_SYMBOLICNAME, bundleContext.getBundle().getSymbolicName()); |
| props.put(BUNDLE_ID, bundleContext.getBundle().getBundleId()); |
| props.put(BUNDLE_VERSION, getBundleVersion(bundleContext.getBundle())); |
| try { |
| props.put(CAUSE, event.getClass().getMethod("getCause").invoke(event)); |
| } catch (Throwable t) { |
| // ignore |
| } |
| eventAdmin.postEvent(new Event(getTopic(event), props)); |
| } |
| |
| public boolean isEnabled(CamelEvent event) { |
| return true; |
| } |
| |
| @Override |
| protected void doStart() throws Exception { |
| tracker.open(); |
| } |
| |
| @Override |
| protected void doStop() throws Exception { |
| tracker.close(); |
| } |
| |
| public static String toUpper(String text) { |
| StringBuilder sb = new StringBuilder(); |
| for (int i = 0; i < text.length(); i++) { |
| char c = text.charAt(i); |
| if (Character.isUpperCase(c) && sb.length() > 0) { |
| sb.append('_'); |
| } |
| sb.append(Character.toUpperCase(c)); |
| } |
| return sb.toString(); |
| } |
| |
| public static String getType(CamelEvent event) { |
| return event.getType().name(); |
| } |
| |
| public static String getTopic(CamelEvent event) { |
| String topic; |
| String type = getType(event); |
| if (type.startsWith("CamelContext")) { |
| topic = TOPIC_CAMEL_CONTEXT_EVENTS; |
| type = type.substring("CamelContext".length()); |
| } else if (type.startsWith("Exchange")) { |
| topic = TOPIC_CAMEL_EXCHANGE_EVENTS; |
| type = type.substring("Exchange".length()); |
| } else if (type.startsWith("Route")) { |
| topic = TOPIC_CAMEL_ROUTE_EVENTS; |
| type = type.substring("Route".length()); |
| } else if (type.startsWith("Service")) { |
| topic = TOPIC_CAMEL_SERVICE_EVENTS; |
| type = type.substring("Service".length()); |
| } else { |
| topic = TOPIC_CAMEL_EVENTS + "unknown/"; |
| } |
| topic += toUpper(type); |
| return topic; |
| } |
| |
| public static Version getBundleVersion(Bundle bundle) { |
| Dictionary<?, ?> headers = bundle.getHeaders(); |
| String version = (String)headers.get(Constants.BUNDLE_VERSION); |
| return (version != null) ? Version.parseVersion(version) : Version.emptyVersion; |
| } |
| |
| } |