Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
org.coos.messaging.impl.DefaultEndpoint Maven / Gradle / Ivy
/**
* COOS - Connected Objects Operating System (www.connectedobjects.org).
*
* Copyright (C) 2009 Telenor ASA and Tellu AS. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This library is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published
* by the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see .
*
* You may also contact one of the following for additional information:
* Telenor ASA, Snaroyveien 30, N-1331 Fornebu, Norway (www.telenor.no)
* Tellu AS, Hagalokkveien 13, N-1383 Asker, Norway (www.tellu.no)
*/
package org.coos.messaging.impl;
import org.coos.messaging.AsyncCallback;
import org.coos.messaging.ConnectingException;
import org.coos.messaging.Consumer;
import org.coos.messaging.Endpoint;
import org.coos.messaging.EndpointException;
import org.coos.messaging.Exchange;
import org.coos.messaging.ExchangePattern;
import org.coos.messaging.InteractionHelper;
import org.coos.messaging.Link;
import org.coos.messaging.Message;
import org.coos.messaging.Notification;
import org.coos.messaging.Plugin;
import org.coos.messaging.Processor;
import org.coos.messaging.ProcessorException;
import org.coos.messaging.Producer;
import org.coos.messaging.Service;
import org.coos.messaging.SubscriptionFilter;
import org.coos.messaging.util.ExecutorService;
import org.coos.messaging.util.Executors;
import org.coos.messaging.util.Log;
import org.coos.messaging.util.LogFactory;
import org.coos.messaging.util.URIHelper;
import org.coos.messaging.util.URIProtocolHelper;
import org.coos.messaging.util.UuidGenerator;
import org.coos.messaging.util.UuidHelper;
import org.coos.module.CommonConstants;
import org.coos.module.EdgeLCMMessageFactory;
import org.coos.module.EdgeMessageProperties;
import org.coos.module.LCMEdgeMessageFactory;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Timer;
import java.util.TimerTask;
import java.util.Vector;
/**
* @author Knut Eilif Husa, Tellu AS
* @author anders
*/
public abstract class DefaultEndpoint extends DefaultProcessor implements Endpoint {
private String uri;
private String endpointUuid;
private Plugin plugin;
private final Vector aliases = new Vector();
private final Hashtable outLinks = new Hashtable();
private final Vector services = new Vector();
private final Hashtable exchanges = new Hashtable();
private final Hashtable callbacks = new Hashtable();
private UuidGenerator uuidGenerator = new UuidGenerator();
private int maxPoolSize = DEFAULT_MAX_POOL_SIZE;
protected ExecutorService threadPool;
private long timeout;
protected Vector deferQueue = new Vector();
protected Log log = LogFactory.getLog(this.getClass().getName());
private String endpointState = STATE_READY;
private Hashtable childStates = new Hashtable();
protected boolean heartbeat;
protected Timer timer;
protected DefaultEndpoint() {
}
public DefaultEndpoint(String uri, Processor processor) {
// This is for test purposes since this constructor only is called in
// tests
this.uri = uri;
outLinks.put("coos", processor);
threadPool = Executors.newThreadPool(2);
uuidGenerator = new UuidGenerator("xId-" +
((getName() == null) ? getEndpointUuid() : getName()));
setEndpointState(Endpoint.STATE_RUNNING);
}
@Override public void setName(String name) {
if ((name != null) && !UuidHelper.isUuid(name)) {
aliases.addElement(name);
}
super.setName(name);
}
public Consumer createConsumer() {
// TODO Auto-generated method stub
return null;
}
public Producer createProducer() {
// TODO Auto-generated method stub
return null;
}
public String getEndpointUuid() {
return endpointUuid;
}
public void setEndpointUuid(String endpointUuid) {
endpointUuid = UuidHelper.getQualifiedUuid(endpointUuid);
this.endpointUuid = endpointUuid;
log.putMDC("UUID", endpointUuid);
}
public String getEndpointState() {
return endpointState;
}
public void setEndpointState(String endpointState) {
this.endpointState = endpointState;
if (isStateRunning()) {
for (int i = 0; i < deferQueue.size(); i++) {
Message message = (Message) deferQueue.elementAt(i);
processMessage(message);
}
deferQueue.removeAllElements();
}
}
public void setChildEndpointState(String childName, String state) {
childStates.put(childName, state);
}
public String getChildEndpointState(String childName) {
return (String) childStates.get(childName);
}
@Override public void setProperties(Hashtable properties) {
this.properties = properties;
String timoutStr = (String) properties.get(PROP_EXCHANGE_TIMEOUT);
if (timoutStr != null) {
timeout = Long.parseLong(timoutStr);
} else {
timeout = DEFAULT_TIMEOUT;
}
maxPoolSize = Integer.parseInt(getProperty(PROP_MAX_POOL_SIZE,
String.valueOf(DEFAULT_MAX_POOL_SIZE)));
}
public void setTimeout(long timeout) {
this.timeout = timeout;
}
public void setMaxPoolSize(int maxPoolSize) {
this.maxPoolSize = maxPoolSize;
}
public Exchange createExchange() {
Exchange exchange = new DefaultExchange(new ExchangePattern(ExchangePattern.OutIn));
return exchange;
}
public Exchange createExchange(ExchangePattern pattern) {
Exchange exchange = new DefaultExchange(pattern);
return exchange;
}
public String getEndpointUri() {
return uri;
}
public void setEndpointUri(String endpointUri) {
this.uri = endpointUri;
log.putMDC("URI", endpointUri);
}
public String createUuid() {
return uuidGenerator.generateId();
}
/**
* Method that registers endpoint into lifecycle manager.
*
* @throws EndpointException
* if registration fails
*/
private void registerLCM() throws EndpointException {
// registration to LCM
boolean failIfError = false;
String lcmRegReq = (String) properties.get(PROP_LCM_REGISTRATION_REQUIRED);
if ((lcmRegReq != null) && lcmRegReq.equals("true")) {
failIfError = true;
}
log.info("Registering endpoint: " + uri + " to LifeCycleManager.");
String pollingInterval = getProperty(PROP_LCM_POLLING_INTERVAL);
Exchange ex;
if (pollingInterval == null)
ex = LCMEdgeMessageFactory.createRegisterEndpointExchange(endpointState,
getChildStates(), DEFAULT_LCM_POLLING_INTERVAL);
else
ex = LCMEdgeMessageFactory.createRegisterEndpointExchange(endpointState,
getChildStates(), Long.parseLong(pollingInterval));
InteractionHelper helper = new InteractionHelper(this);
ex = helper.request(LIFE_CYCLE_MANGER_ADDRESS, ex);
if (ex.getFaultMessage() != null) {
if (failIfError)
throw new EndpointException("Registration to LifeCycleManager failed due to :" +
ex.getFaultMessage().getHeader(Message.ERROR_REASON));
} else {
Message reply = ex.getInBoundMessage();
if ((reply == null) ||
reply.getHeader(Message.MESSAGE_NAME).equals(CommonConstants.REPLY_NACK)) {
if (failIfError)
throw new EndpointException("Registration to lifecycle manager failed");
// else
// log.
}
}
}
private void unRegisterLCM() throws EndpointException {
// unregistration to LCM
log.info("UnRegistering endpoint: " + uri + " from LifeCycleManager.");
InteractionHelper helper = new InteractionHelper(this);
Exchange ex = LCMEdgeMessageFactory.createUnregisterEndpointExchange();
ex = helper.request(LIFE_CYCLE_MANGER_ADDRESS, ex);
if (ex.getFaultMessage() != null) {
log.info("Endpoint: " + getEndpointUri() +
", Unregistration to LifeCycleManager failed due to: " +
ex.getFaultMessage().getHeader(Message.ERROR_REASON));
} else {
Message reply = ex.getInBoundMessage();
if ((reply == null) ||
reply.getHeader(Message.MESSAGE_NAME).equals(CommonConstants.REPLY_NACK)) {
log.info("Endpoint: " + getEndpointUri() +
", Unregistration to lifecycle manager failed");
}
}
}
private void reportChildren() throws EndpointException {
log.info("Reporting state: " + endpointState + " to LifeCycleManager.");
Exchange ex = LCMEdgeMessageFactory.createSetChildrenStatesExchange(childStates);
InteractionHelper helper = new InteractionHelper(this);
ex = helper.request(LIFE_CYCLE_MANGER_ADDRESS, ex);
if (ex.getFaultMessage() != null) {
throw new EndpointException("Children reply to LifeCycleManager failed due to :" +
ex.getFaultMessage().getHeader(Message.ERROR_REASON));
}
Message reply = ex.getInBoundMessage();
String signalName = reply.getHeader(Message.MESSAGE_NAME);
if (signalName.equals(CommonConstants.REPLY_NACK)) {
throw new EndpointException("Children reply to lifecycle manager failed");
}
}
public void reportState() throws EndpointException {
boolean failIfError = false;
String lcmRegReq = (String) properties.get(PROP_LCM_REGISTRATION_REQUIRED);
if ((lcmRegReq != null) && lcmRegReq.equals("true")) {
failIfError = true;
}
log.info("Sending state: " + getEndpointState() + " to LifeCycleManager.");
Exchange ex = LCMEdgeMessageFactory.createSetStateExchange(getEndpointState());
InteractionHelper helper = new InteractionHelper(this);
ex = helper.request(LIFE_CYCLE_MANGER_ADDRESS, ex);
if (ex.getFaultMessage() != null) {
if (failIfError)
throw new EndpointException("Pushing state to Lifecycle Mangager failed :" +
ex.getFaultMessage().getHeader(Message.ERROR_REASON));
} else {
Message reply = ex.getInBoundMessage();
String signalName = reply.getHeader(Message.MESSAGE_NAME);
if (signalName.equals(CommonConstants.REPLY_NACK)) {
if (failIfError)
throw new EndpointException("Pushing state to Lifecycle Manager failed.");
// else
// log.
}
}
}
public void reportChildState(String childName) throws EndpointException {
boolean failIfError = false;
String lcmRegReq = (String) properties.get(PROP_LCM_REGISTRATION_REQUIRED);
if ((lcmRegReq != null) && lcmRegReq.equals("true")) {
failIfError = true;
}
String childState = (String) getChildStates().get(childName);
log.info("Sending state: " + childState + " of child: " + childName +
" to LifeCycleManager.");
Exchange ex = LCMEdgeMessageFactory.createRegisterEndpointChildExchange(childName,
childState);
InteractionHelper helper = new InteractionHelper(this);
ex = helper.request(LIFE_CYCLE_MANGER_ADDRESS, ex);
if (ex.getFaultMessage() != null) {
if (failIfError)
throw new EndpointException("Pushing child-state to Lifecycle Mangager failed :" +
ex.getFaultMessage().getHeader(Message.ERROR_REASON));
} else {
Message reply = ex.getInBoundMessage();
String signalName = reply.getHeader(Message.MESSAGE_NAME);
if (signalName.equals(CommonConstants.REPLY_NACK)) {
if (failIfError)
throw new EndpointException("Pushing child-state to Lifecycle Manager failed.");
// else
// log.
}
}
}
/**
* Sync processing of inBound messages
*
* @param exchange
* @return
*/
public Exchange processExchange(Exchange exchange) {
if (exchange.isProcessed()) {
exchange.setException(new EndpointException(
"Exchange can not be reused. Is already processed"));
log.warn("Endpoint: " + uri + ", Exception processing exchange, already processed: " +
exchange);
return exchange;
}
Processor processor = prepareExchange(exchange);
log.debug("Endpoint: " + uri + ", Processing outgoing exchange: " + exchange);
if (exchange.getFaultMessage() != null) {
return exchange;
}
synchronized (exchange) {
try {
processor.processMessage(exchange.getOutBoundMessage());
} catch (ProcessorException e) {
Message fault = new DefaultMessage();
fault.setReceiverEndpointUri(getEndpointUri());
fault.setHeader(Message.TYPE_MSG, Message.TYPE_ERROR);
fault.setHeader(Message.ERROR_REASON, e.getMessage());
fault.setHeader(Message.EXCHANGE_ID, exchange.getExchangeId());
exchange.setFaultMessage(fault);
exchange.setException(e);
log.warn("Endpoint: " + uri + ", Exception processing exchange: " + exchange);
return exchange;
}
ExchangePattern xp = exchange.getPattern();
if (xp.equals(ExchangePattern.OutIn) || xp.equals(ExchangePattern.RobustOutOnly)) {
try {
exchange.wait(timeout);
if (!exchange.isProcessed()) {
log.warn("Endpoint: " + uri + ", exchange: " + exchange + " timed out (" +
timeout + " ms).");
Message fault = new DefaultMessage();
fault.setReceiverEndpointUri(getEndpointUri());
fault.setHeader(Message.TYPE, Message.TYPE_ERROR);
fault.setHeader(Message.ERROR_REASON, "Exchange timeout");
fault.setHeader(Message.ERROR_CODE, "504");
fault.setHeader(Message.EXCHANGE_ID, exchange.getExchangeId());
exchange.setFaultMessage(fault);
}
} catch (InterruptedException e) {
log.warn("Endpoint: " + uri + ", exchange: " + exchange +
" interrupted. Ignored.", e);
}
}
}
return exchange;
}
/**
* Simple method to send a message to a receiver, using a set exchange pattern. Returns the inbound Message object from the used exchange.
* @param msg
* @param receiver - coos url of the receiver
* @param exchangePattern
* @return
*/
public Message sendMessage(Message msg, String receiver, String exchangePattern) {
Exchange e = createExchange(new ExchangePattern(exchangePattern));
msg.setReceiverEndpointUri(receiver);
e.setOutBoundMessage(msg);
Exchange response = processExchange(e);
return response.getInBoundMessage();
}
/**
* Prepares the exchange before it is processed. This includes checking that
* sender and receiver adresses are resolved
*
* @param exchange
* the exchange
*/
private Processor prepareExchange(Exchange exchange) {
try {
// if (!isStateRunning()&&!endpointState.equals(STATE_STARTING)) {
// throw new EndpointException("Endpoint not able to handle exchanges. Endpoint State is: "
// + endpointState);
// }
String senderUri = exchange.getOutBoundMessage().getSenderEndpointUri();
URIHelper helper;
if ((senderUri == null) || senderUri.equals("")) {
helper = new URIHelper(uri);
} else {
helper = new URIHelper(senderUri);
}
helper.setEndpoint(endpointUuid);
exchange.getOutBoundMessage().setSenderEndpointUri(helper.getEndpointUri());
String uri = exchange.getOutBoundMessage().getReceiverEndpointUri();
if (exchange.getExchangeId() == null) {
exchange.setExchangeId(uuidGenerator.generateId());
}
ExchangePattern xPattern = exchange.getPattern();
if (xPattern.equals(ExchangePattern.OutIn) ||
xPattern.equals(ExchangePattern.RobustOutOnly)) {
exchanges.put(exchange.getExchangeId(), exchange);
}
if (exchange.getPattern().equals(ExchangePattern.InOut)) {
//If this is a reply we search through the message for header values that are to be passed
//along with the reply
exchange.getOutBoundMessage().setHeader(Message.EXCHANGE_ID,
exchange.getInBoundMessage().getHeader(Message.EXCHANGE_ID));
Message outMsg = exchange.getOutBoundMessage();
Message inMsg = exchange.getInBoundMessage();
Enumeration keys = inMsg.getHeaders().keys();
while (keys.hasMoreElements()) {
String key = (String) keys.nextElement();
if (key.startsWith(Message.EXCHANGE_PREFIX)) {
outMsg.setHeader(key, exchange.getInBoundMessage().getHeader(key));
}
}
} else {
exchange.getOutBoundMessage().setHeader(Message.EXCHANGE_ID,
exchange.getExchangeId());
}
exchange.getOutBoundMessage().setHeader(Message.EXCHANGE_PATTERN,
exchange.getPattern().toString());
if (exchange.getOutBoundMessage().getType() == null) {
exchange.getOutBoundMessage().setHeader(Message.TYPE, Message.TYPE_MSG);
}
if (xPattern.equals(ExchangePattern.RobustOutOnly)) {
long rdTimeout = timeout / 2;
exchange.getOutBoundMessage().setHeader(Message.ROBUST_DELIVERY_TIME,
String.valueOf(rdTimeout));
exchange.getOutBoundMessage().setHeader(Message.ROBUST_DELIVERY_ACK_URI,
helper.getEndpointUri());
}
String protocol = URIProtocolHelper.getProtocol(uri);
Processor processor = resolveOutgoingProcessor(protocol);
if (protocol.startsWith("coos")) {
helper = new URIHelper(uri);
exchange.getOutBoundMessage().setReceiverEndpointName(helper.getEndpoint());
exchange.getOutBoundMessage().setSenderEndpointName(((getName() == null)
? getEndpointUuid() : getName()));
}
return processor;
} catch (Exception e) {
log.warn("Exception caught by prepareExchange().", e);
exchange.setFaultMessage(new DefaultMessage().setHeader(Message.ERROR_REASON,
"Exception: " + e.getClass().getName() + ", Message: " + e.getMessage()));
exchange.setException(e);
}
return null;
}
private boolean isStateRunning() {
if (endpointState.equals(STATE_RUNNING)) {
return true;
}
if (endpointState.equals(STATE_STARTING) || endpointState.equals(STATE_INSTALLED) ||
endpointState.equals(STATE_PAUSED) || endpointState.equals(STATE_READY) ||
endpointState.equals(STATE_STARTUP_FAILED) ||
endpointState.equals(STATE_UNINNSTALLED) || endpointState.equals(STATE_UPDATING) ||
endpointState.equals(STATE_UPGRADING))
return false;
return true;
}
protected Processor resolveOutgoingProcessor(String protocol) throws EndpointException {
Processor processor = (Processor) outLinks.get(protocol);
if (processor == null) {
throw new EndpointException("No channel defined for protocol: " + protocol);
}
return processor;
}
/**
* Async processing of outbound messages
*
* @param exchange
* @param callback
*/
public void processExchange(Exchange exchange, AsyncCallback callback) {
log.debug("Endpoint: " + uri + ", Processing outgoing exchange: " + exchange);
Processor processor = prepareExchange(exchange);
if (exchange.getFaultMessage() != null) {
callback.processExchange(exchange);
return;
}
exchanges.put(exchange.getExchangeId(), exchange);
callbacks.put(exchange.getExchangeId(), callback);
synchronized (exchange) {
try {
processor.processMessage(exchange.getOutBoundMessage());
} catch (ProcessorException e) {
Message fault = new DefaultMessage();
fault.setHeader(Message.TYPE_MSG, Message.TYPE_ERROR);
fault.setHeader(Message.ERROR_REASON, e.getMessage());
fault.setHeader(Message.EXCHANGE_ID, exchange.getExchangeId());
fault.setHeader(Message.EXCHANGE_PATTERN, exchange.getPattern().toString());
processMessage(fault);
}
}
}
/**
* Processing of Inbound messages
*
* @param msg
*/
public void processMessage(Message msg) {
//if(coContainer != null)
msg.setDeserializeClassLoader(coContainer);
String msgType = msg.getHeader(Message.TYPE);
if (msgType.equals(Message.TYPE_MSG) || msgType.equals(Message.TYPE_ERROR)) {
if (msg.getName().equals(Notification.NOTIFY)) {
msg = new DefaultNotification(msg);
}
String xpattern = msg.getHeader(Message.EXCHANGE_PATTERN);
ExchangePattern xp = new ExchangePattern(xpattern);
final String xId = msg.getHeader(Message.EXCHANGE_ID);
final Message retMsg = msg;
try {
retMsg.getBody();
} catch (Exception e) {
retMsg.setHeader(Message.TYPE, Message.TYPE_ERROR);
retMsg.setHeader(Message.ERROR_REASON, "Deserialization error: " + e.getMessage());
}
Consumer consumer = createConsumer();
// Error handling
if (msg.getHeader(Message.TYPE).equals(Message.TYPE_ERROR)) {
if ((xId != null) && exchanges.containsKey(xId)) {
final Exchange exchange = (Exchange) exchanges.remove(xId);
log.warn("Endpoint: " + uri + ", Processing incoming exchange: " + exchange +
": fault :" + retMsg);
exchange.setFaultMessage(retMsg);
exchange.setProcessed(true);
if (callbacks.containsKey(xId)) {
threadPool.execute(new Runnable() {
public void run() {
// this is an async return
AsyncCallback callback = (AsyncCallback) callbacks.remove(xId);
callback.processExchange(exchange);
}
});
} else {
// this is a sync return
// todo when moved to java 1.6 can check if current thread holds lock
// New thread is only necessary in that case
new Thread(new Runnable() {
public void run() {
synchronized (exchange) {
exchange.notifyAll();
}
}
}).start();
}
} else {
log.warn("Endpoint: " + uri + ", Error message:" + retMsg);
}
} else {
// Message handling
Exchange exchange = null;
if ((xId != null) && exchanges.containsKey(xId) && !xp.isOutBoundInitiated()) {
// this is a return or a message to same endpoint.
final Exchange exchange2 = (Exchange) exchanges.remove(xId);
log.debug("Endpoint: " + uri + ", Processing incoming exchange: " + exchange2);
if (xp.equals(ExchangePattern.InOut)) {
exchange2.setInBoundMessage(retMsg);
}
exchange2.setProcessed(true);
if (callbacks.containsKey(xId)) {
threadPool.execute(new Runnable() {
public void run() {
// this is an async return
AsyncCallback callback = (AsyncCallback) callbacks.remove(xId);
callback.processExchange(exchange2);
}
});
} else {
// this is a sync return
// todo when moved to java 1.6 can check if current thread holds lock
// New thread is only necessary in that case
new Thread(new Runnable() {
public void run() {
synchronized (exchange2) {
exchange2.notifyAll();
}
}
}).start();
}
} else if (consumer != null) {
if (msg.getHeader(Message.MESSAGE_NAME).equals(
EdgeLCMMessageFactory.EDGE_REQUEST_STATE)) {
threadPool.execute(new Runnable() {
public void run() {
try {
reportState();
} catch (EndpointException e) {
log.warn(
"Exception caught by processMessage(). Message " +
EdgeLCMMessageFactory.EDGE_REQUEST_STATE, e);
}
}
});
return;
} else if (msg.getHeader(Message.MESSAGE_NAME).equals(
EdgeLCMMessageFactory.EDGE_REQUEST_CHILD_STATE)) {
final String childAddress = (String) msg.getBodyAsProperties().get(
EdgeMessageProperties.EDGE_PROP_CHILD_NAME);
threadPool.execute(new Runnable() {
public void run() {
try {
reportChildState(childAddress);
} catch (EndpointException e) {
log.warn(
"Exception caught by processMessage(). Message " +
EdgeLCMMessageFactory.EDGE_REQUEST_CHILD_STATE, e);
}
}
});
return;
} else if (
msg.getHeader(Message.MESSAGE_NAME).equals(
EdgeLCMMessageFactory.EDGE_REQUEST_CHILDREN) &&
(msg.getBodyAsProperties().get(
EdgeMessageProperties.EDGE_PROP_CHILDREN) == null)) {
threadPool.execute(new Runnable() {
public void run() {
try {
reportChildren();
} catch (EndpointException e) {
log.warn(
"Exception caught by processMessage(). Message " +
EdgeLCMMessageFactory.EDGE_REQUEST_CHILDREN, e);
}
}
});
return;
}
// this is an initiating request, will only be handled in
// state running, else it will be deferred to
// the endpoint reaches state running
if (checkDefer(msg))
return;
if (xpattern.equals(ExchangePattern.OutIn)) {
exchange = createExchange(new ExchangePattern(ExchangePattern.InOut));
} else {
// default behaviour is inOnly
if (xpattern.equals(ExchangePattern.RobustOutOnly)) {
DefaultMessage confMsg = new DefaultMessage();
confMsg.setHeader(Message.DELIVERY_STATUS, Message.DELIVERY_SUCCESS);
Exchange e = createExchange(new ExchangePattern(
ExchangePattern.RobustInOnly));
e.setExchangeId(msg.getHeader(Message.EXCHANGE_ID));
confMsg.setReceiverEndpointUri(msg.getHeader(
Message.ROBUST_DELIVERY_ACK_URI));
e.setOutBoundMessage(confMsg);
log.debug("Endpoint: " + uri + ", Sending robust ack: " + e);
processExchange(e);
}
exchange = createExchange(new ExchangePattern(ExchangePattern.InOnly));
}
if (exchange != null) {
exchange.setInBoundMessage(msg);
exchange.setExchangeId(xId);
final Exchange exchange1 = exchange;
final Consumer consumer1 = consumer;
threadPool.execute(new Runnable() {
public void run() {
// Todo might insert e semaphore here to control
// concurrent access to consumer
log.debug(
"Endpoint: " + uri + ", Processing incoming exchange: " +
exchange1);
consumer1.process(exchange1);
}
});
}
}
}
}
}
protected boolean checkDefer(Message msg) {
if (ExchangePattern.InOut.equals(msg.getHeader(Message.EXCHANGE_PATTERN)) ||
isStateRunning()) {
return false;
}
log.debug("State isn't Running (" + endpointState + "). Deferring message to queue.");
deferQueue.addElement(msg);
return true;
}
public Vector getServices() {
return services;
}
public final void initializeEndpoint() {
uuidGenerator = new UuidGenerator("xId-" +
((getName() == null) ? getEndpointUuid() : getName()));
threadPool = Executors.newThreadPool(maxPoolSize);
deferQueue.removeAllElements();
if (getEndpointState().equals(STATE_READY)) {
try {
preStart();
start();
postStart();
} catch (Exception e) {
log.error("Startup failed.", e);
setEndpointState(STATE_STARTUP_FAILED);
}
}
}
protected void preStart() throws EndpointException {
String s = (!name.equals(endpointUuid)) ? ("(name=" + name + ")") : "";
log.info("Starting endpoint: " + endpointUuid + s);
setEndpointState(STATE_STARTING);
// if (producer instanceof Service && !(producer instanceof Endpoint)) {
// services.addElement(producer);
// ((Service) producer).start();
// }
}
public void start() throws Exception {
// Override this method
}
protected void postStart() throws EndpointException {
createProducer();
setEndpointState(STATE_RUNNING);
// register to the life cycle manager
String lcmRegEnabled = getProperty(PROP_LCM_REGISTRATION_ENABLED);
if ((lcmRegEnabled == null) || !lcmRegEnabled.equalsIgnoreCase("false")) {
registerLCM();
heartbeat = true;
startLCMHeartbeat();
}
String s = (!name.equals(endpointUuid)) ? ("(name=" + name + ")") : "";
log.info("Successfully started endpoint: " + endpointUuid + s);
}
private void startLCMHeartbeat() {
timer = new Timer("LCMTimer", true);
long delay = Long.parseLong(getProperty(PROP_LCM_HEARTBEAT_INTERVAL, "120000"));
if (delay > 0) {
TimerTask task = new TimerTask() {
@Override public void run() {
threadPool.execute(new Runnable() {
public void run() {
try {
reportState();
} catch (EndpointException e) {
}
}
});
}
};
timer.schedule(task, delay, delay);
}
}
public void stop() throws Exception {
// Override this method
}
public final void shutDownEndpoint() {
if (!isStateRunning()) {
return;
}
log.info("Stopping endpoint: " + uri);
setEndpointState(STATE_STOPPING);
try {
stop();
} catch (Exception e) {
log.error("Exception caught while stopping endpoint.", e);
}
for (int i = 0; i < services.size(); i++) {
Service service = (Service) services.elementAt(i);
try {
service.stop();
} catch (Exception e) {
log.error("Exception caught while stopping endpoint.", e);
}
}
// unregister to the life cycle manager
if (timer != null)
timer.cancel();
String lcmRegEnabled = getProperty(PROP_LCM_REGISTRATION_ENABLED);
if ((lcmRegEnabled == null) || !lcmRegEnabled.equalsIgnoreCase("false")) {
try {
unRegisterLCM();
} catch (EndpointException e) {
log.error("EndpointException caught while stopping endpoint.", e);
} catch (Exception e) {
log.error("Unknown Exception caught while stopping endpoint.", e);
}
}
if (threadPool != null) // Null if endpoint was not started successfully
// (ie couldn't connect)
threadPool.stop();
setEndpointState(STATE_READY);
}
public void addLink(String protocol, Link link) throws ConnectingException {
outLinks.put(protocol, link);
}
public void addAlias(String alias) {
if ((alias != null) && !UuidHelper.isUuid(alias) &&
UuidHelper.isValidAliasForUuid(alias, getEndpointUuid())) {
aliases.addElement(alias);
updateAliases();
} else {
log.warn("Cannot assign this endpoint alias:" + alias +
". Only alias with segment 'dico', 'localcoos' or '" +
UuidHelper.getSegmentFromEndpointNameOrEndpointUuid(getEndpointUuid()) +
"' is allowed.");
}
}
public void removeAlias(String alias) {
aliases.removeElement(alias);
updateAliases();
}
public Vector getAliases() {
return aliases;
}
private void updateAliases() {
Link link = (Link) outLinks.get("coos");
if (link != null) {
Message msg = new DefaultMessage("alias", Message.TYPE_ALIAS);
msg.setReceiverEndpointUri("coos://" + link.getDestinationUuid());
msg.setBody(aliases);
Exchange ex = createExchange(new ExchangePattern(ExchangePattern.OutOnly));
ex.setOutBoundMessage(msg);
processExchange(ex);
}
}
public Processor getDefaultProcessor() {
return this;
}
public Link getLink(String id) {
return (Link) outLinks.get(id);
}
public void removeLink(String id) {
outLinks.remove(id);
}
public void removeLinkById(String linkId) {
// TODO Auto-generated method stub
}
public boolean subscribe(SubscriptionFilter filter) {
log.debug("Endpoint: " + uri + " subscribing: " + filter);
filter.setReceiverEndpointUri(NOTIFICATION_BROKER_ADDRESS);
filter.setSenderEndpointUri(uri);
filter.setHeader(Message.MESSAGE_NAME, SubscriptionFilter.SUBSCRIBE);
Exchange ex = createExchange(new ExchangePattern(ExchangePattern.OutIn));
ex.setOutBoundMessage(filter);
processExchange(ex);
if (ex.getFaultMessage() != null) {
return false;
}
return true;
}
public void unsubscribe() {
log.debug("Endpoint: " + uri + " unSubscribing all");
Message msg = new DefaultMessage(SubscriptionFilter.UNSUBSCRIBE_ALL);
msg.setReceiverEndpointUri(NOTIFICATION_BROKER_ADDRESS);
msg.setSenderEndpointUri(uri);
Exchange ex = createExchange(new ExchangePattern(ExchangePattern.OutOnly));
ex.setOutBoundMessage(msg);
processExchange(ex);
}
public void unsubscribe(SubscriptionFilter filter) {
log.debug("Endpoint: " + uri + " unSubscribing: " + filter);
filter.setReceiverEndpointUri(NOTIFICATION_BROKER_ADDRESS);
filter.setSenderEndpointUri(uri);
filter.setHeader(Message.MESSAGE_NAME, SubscriptionFilter.UNSUBSCRIBE);
Exchange ex = createExchange(new ExchangePattern(ExchangePattern.OutOnly));
ex.setOutBoundMessage(filter);
processExchange(ex);
}
public void publish(Notification notification) {
log.debug("Endpoint: " + uri + " publishing: " + notification);
notification.setReceiverEndpointUri(NOTIFICATION_BROKER_ADDRESS);
notification.setSenderEndpointUri(uri);
Exchange ex = createExchange(new ExchangePattern(ExchangePattern.OutOnly));
ex.setOutBoundMessage(notification);
processExchange(ex);
}
public void setChildStates(Hashtable childStates) {
this.childStates = childStates;
}
public Hashtable getChildStates() {
return childStates;
}
@Override public Hashtable getProperties() {
return properties;
}
public void setLinkAliases(Vector regAliases, Link outlink) {
// Not implemented
}
public Plugin getPlugin() {
return plugin;
}
public void setPlugin(Plugin plugin) {
this.plugin = plugin;
}
}