/*******************************************************************************
* Copyright (c) 2009 Neil Bartlett.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Neil Bartlett - initial API and implementation
******************************************************************************/
package com.rabbitmq.client.osgi.exchange;
import java.io.IOException;
import java.util.Map;
import java.util.Properties;
import org.apache.log4j.Logger;
import org.osgi.framework.BundleContext;
import org.osgi.framework.Filter;
import org.osgi.framework.FrameworkUtil;
import org.osgi.framework.InvalidSyntaxException;
import org.osgi.framework.ServiceReference;
import org.osgi.framework.ServiceRegistration;
import org.osgi.util.tracker.ServiceTracker;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ShutdownSignalException;
import com.rabbitmq.client.osgi.api.Exchange;
import com.rabbitmq.client.osgi.common.Pair;
import com.rabbitmq.client.osgi.common.ServiceProperties;
public class ConnectionExchangeTracker extends ServiceTracker {
private static final Logger LOG = Logger.getLogger(ConnectionExchangeTracker.class);
private final String connName;
private final String exchangeName;
private final String type;
private final boolean passive;
private final boolean durable;
private final boolean autoDelete;
private final Map<String, Object> arguments;
public ConnectionExchangeTracker(BundleContext context, String connName, String exchangeName, String type, boolean passive, boolean durable, boolean autoDelete, Map<String, Object> arguments) {
super(context, createFilter(connName), null);
this.connName = connName;
this.exchangeName = exchangeName;
this.type = type;
this.passive = passive;
this.durable = durable;
this.autoDelete = autoDelete;
this.arguments = arguments;
}
private static Filter createFilter(String connName) {
String filterStr = String.format("(%s=%s)", ServiceProperties.CONNECTION_NAME, connName);
try {
return FrameworkUtil.createFilter(filterStr);
} catch (InvalidSyntaxException e) {
// shouldn't happen
throw new RuntimeException(e);
}
}
@Override
public Object addingService(ServiceReference reference) {
Connection conn = (Connection) context.getService(reference);
Channel channel = null;
try {
channel = conn.createChannel();
LOG.debug("ConnectionExchangeTracker: connection '" + connName + "' ADDED, registering exchange '" + exchangeName + "'");
channel.exchangeDeclare(exchangeName, type, passive, durable, autoDelete, arguments);
ChannelExchange exchange = new ChannelExchange(exchangeName, channel);
Properties props = new Properties();
props.put(ServiceProperties.EXCHANGE_NAME, exchangeName);
props.put(ServiceProperties.EXCHANGE_CONNECTION, connName);
props.put(ServiceProperties.EXCHANGE_TYPE, type);
ServiceRegistration reg = context.registerService(Exchange.class.getName(), exchange, props);
Pair<Channel, ServiceRegistration> pair = new Pair<Channel, ServiceRegistration>(channel, reg);
return pair;
} catch (IOException e) {
LOG.error("Error opening channel", e);
return null;
} finally {
try {
channel.close();
} catch (IOException e) {
LOG.error("Error closing channel", e);
}
}
}
@Override
public void removedService(ServiceReference reference, Object service) {
@SuppressWarnings("unchecked")
Pair<Channel, ServiceRegistration> pair = (Pair<Channel, ServiceRegistration>) service;
LOG.debug("ConnectionExchangeTracker: connection '" + connName + "' REMOVED, unregistering exchange '" + exchangeName + "'");
pair.getSnd().unregister();
try {
pair.getFst().close();
} catch (IOException e) {
LOG.error("Error closing channel", e);
} catch (ShutdownSignalException e) {
LOG.warn("Channel already closed");
}
context.ungetService(reference);
}
public String getConnectionName() {
return connName;
}
public String getExchangeName() {
return exchangeName;
}
}