/**
* Copyright (C) 2011 Brian Ferris <bdferris@onebusaway.org>
*
* Licensed 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.onebusaway.federations;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Periodically publishes service registration information to a
* {@link FederatedServiceRegistry} on a fixed interval. In combination with
* {@link FederatedServiceRegistryConstants#KEY_REGISTRATION_EXPIRES_AFTER}, we
* can implement some basic fail-over capabilities in the service registry such
* that a registry entry is automatically removed after a certain period of time
* if the service hasn't been heard from in a while (ex. the service has
* crashed).
*
* @author bdferris
* @see FederatedServiceRegistryConstants#KEY_REGISTRATION_EXPIRES_AFTER
*/
public class FederatedServiceRegistration {
private static Logger _log = LoggerFactory.getLogger(FederatedServiceRegistration.class);
private FederatedServiceRegistry _registry;
private String _serviceUrl;
private String _serviceClass;
private Map<String, String> _properties = new HashMap<String, String>();
private boolean _initiallyEnabled = true;
private int _updateFrequency = 60;
private ScheduledExecutorService _executor = Executors.newSingleThreadScheduledExecutor();
public void setRegistry(FederatedServiceRegistry registry) {
_registry = registry;
}
public void setServiceUrl(String url) {
_serviceUrl = url;
}
public void setServiceClass(Class<?> serviceClass) {
_serviceClass = serviceClass.getName();
}
public void setProperties(Map<String, String> properties) {
_properties = properties;
}
public void setUpdateFrequency(int updateFrequencyInSeconds) {
_updateFrequency = updateFrequencyInSeconds;
}
public void setInitiallyEnabled(boolean initiallyEnabled) {
_initiallyEnabled = initiallyEnabled;
}
public void start() {
_executor.scheduleAtFixedRate(new ServiceUpdateImpl(), 0, _updateFrequency,
TimeUnit.SECONDS);
}
public void stop() {
_executor.shutdown();
try {
_registry.removeService(_serviceUrl);
} catch (Throwable ex) {
_log.warn("error removing service registration", ex);
}
}
/****
* Private Methods
****/
private class ServiceUpdateImpl implements Runnable {
@Override
public void run() {
try {
Map<String, String> properties = new HashMap<String, String>();
properties.put(
FederatedServiceRegistryConstants.KEY_REGISTRATION_EXPIRES_AFTER,
Integer.toString(_updateFrequency * 2));
properties.put(FederatedServiceRegistryConstants.KEY_INITIALLY_ENABLED,
Boolean.toString(_initiallyEnabled));
properties.putAll(_properties);
_registry.addService(_serviceUrl, _serviceClass, properties);
} catch (Throwable ex) {
_log.warn("error adding service registration", ex);
}
}
}
}