use of org.apache.camel.component.salesforce.SalesforceConsumer in project camel by apache.
the class SubscriptionHelper method doStart.
@Override
protected void doStart() throws Exception {
// create CometD client
this.client = createClient(component);
// reset all error conditions
handshakeError = null;
handshakeException = null;
connectError = null;
connectException = null;
// listener for handshake error or exception
if (handshakeListener == null) {
// first start
handshakeListener = new ClientSessionChannel.MessageListener() {
public void onMessage(ClientSessionChannel channel, Message message) {
LOG.debug("[CHANNEL:META_HANDSHAKE]: {}", message);
if (!message.isSuccessful()) {
LOG.warn("Handshake failure: {}", message);
handshakeError = (String) message.get(ERROR_FIELD);
handshakeException = getFailure(message);
if (handshakeError != null) {
// refresh oauth token, if it's a 401 error
if (handshakeError.startsWith("401::")) {
try {
LOG.info("Refreshing OAuth token...");
session.login(session.getAccessToken());
LOG.info("Refreshed OAuth token for re-handshake");
} catch (SalesforceException e) {
LOG.error("Error renewing OAuth token on 401 error: " + e.getMessage(), e);
}
}
}
// restart if handshake fails for any reason
restartClient();
} else if (!listenerMap.isEmpty()) {
reconnecting = true;
}
}
};
}
client.getChannel(META_HANDSHAKE).addListener(handshakeListener);
// listener for connect error
if (connectListener == null) {
connectListener = new ClientSessionChannel.MessageListener() {
public void onMessage(ClientSessionChannel channel, Message message) {
LOG.debug("[CHANNEL:META_CONNECT]: {}", message);
if (!message.isSuccessful()) {
LOG.warn("Connect failure: {}", message);
connectError = (String) message.get(ERROR_FIELD);
connectException = getFailure(message);
} else if (reconnecting) {
reconnecting = false;
LOG.debug("Refreshing subscriptions to {} channels on reconnect", listenerMap.size());
// reconnected to Salesforce, subscribe to existing channels
final Map<SalesforceConsumer, ClientSessionChannel.MessageListener> map = new HashMap<SalesforceConsumer, ClientSessionChannel.MessageListener>();
map.putAll(listenerMap);
listenerMap.clear();
for (Map.Entry<SalesforceConsumer, ClientSessionChannel.MessageListener> entry : map.entrySet()) {
final SalesforceConsumer consumer = entry.getKey();
final String topicName = consumer.getTopicName();
subscribe(topicName, consumer);
}
}
}
};
}
client.getChannel(META_CONNECT).addListener(connectListener);
// handle fatal disconnects by reconnecting asynchronously
if (disconnectListener == null) {
disconnectListener = new ClientSessionChannel.MessageListener() {
@Override
public void onMessage(ClientSessionChannel clientSessionChannel, Message message) {
restartClient();
}
};
}
client.getChannel(META_DISCONNECT).addListener(disconnectListener);
// connect to Salesforce cometd endpoint
client.handshake();
final long waitMs = MILLISECONDS.convert(CONNECT_TIMEOUT, SECONDS);
if (!client.waitFor(waitMs, BayeuxClient.State.CONNECTED)) {
if (handshakeException != null) {
throw new CamelException(String.format("Exception during HANDSHAKE: %s", handshakeException.getMessage()), handshakeException);
} else if (handshakeError != null) {
throw new CamelException(String.format("Error during HANDSHAKE: %s", handshakeError));
} else if (connectException != null) {
throw new CamelException(String.format("Exception during CONNECT: %s", connectException.getMessage()), connectException);
} else if (connectError != null) {
throw new CamelException(String.format("Error during CONNECT: %s", connectError));
} else {
throw new CamelException(String.format("Handshake request timeout after %s seconds", CONNECT_TIMEOUT));
}
}
}
use of org.apache.camel.component.salesforce.SalesforceConsumer in project camel by apache.
the class SubscriptionHelper method restartClient.
// launch an async task to restart
private void restartClient() {
// launch a new restart command
final SalesforceHttpClient httpClient = component.getConfig().getHttpClient();
httpClient.getExecutor().execute(new Runnable() {
@Override
public void run() {
LOG.info("Restarting on unexpected disconnect from Salesforce...");
boolean abort = false;
// wait for disconnect
LOG.debug("Waiting to disconnect...");
while (!client.isDisconnected()) {
try {
Thread.sleep(DISCONNECT_INTERVAL);
} catch (InterruptedException e) {
LOG.error("Aborting restart on interrupt!");
abort = true;
}
}
if (!abort) {
// update restart attempt backoff
final long backoff = restartBackoff.getAndAdd(backoffIncrement);
if (backoff > maxBackoff) {
LOG.error("Restart aborted after exceeding {} msecs backoff", maxBackoff);
abort = true;
} else {
// pause before restart attempt
LOG.debug("Pausing for {} msecs before restart attempt", backoff);
try {
Thread.sleep(backoff);
} catch (InterruptedException e) {
LOG.error("Aborting restart on interrupt!");
abort = true;
}
}
if (!abort) {
Exception lastError = new SalesforceException("Unknown error", null);
try {
// reset client
doStop();
// register listeners and restart
doStart();
} catch (Exception e) {
LOG.error("Error restarting: " + e.getMessage(), e);
lastError = e;
}
if (client.isHandshook()) {
LOG.info("Successfully restarted!");
// reset backoff interval
restartBackoff.set(client.getBackoffIncrement());
} else {
LOG.error("Failed to restart after pausing for {} msecs", backoff);
if ((backoff + backoffIncrement) > maxBackoff) {
// notify all consumers
String abortMsg = "Aborting restart attempt due to: " + lastError.getMessage();
SalesforceException ex = new SalesforceException(abortMsg, lastError);
for (SalesforceConsumer consumer : listenerMap.keySet()) {
consumer.handleException(abortMsg, ex);
}
}
}
}
}
}
});
}
Aggregations