blob: b6f9dfb8a5654256459577d82d94f4d7388c24df [file] [log] [blame]
/*
* 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;
}
}