/** * 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.openejb.server.discovery; import org.apache.openejb.loader.Options; import org.apache.openejb.monitoring.Event; import org.apache.openejb.monitoring.Managed; import org.apache.openejb.server.DiscoveryAgent; import org.apache.openejb.server.DiscoveryListener; import org.apache.openejb.server.SelfManaging; import org.apache.openejb.server.ServerService; import org.apache.openejb.server.ServiceException; import org.apache.openejb.util.Duration; import org.apache.openejb.util.LogCategory; import org.apache.openejb.util.Logger; import org.apache.openejb.util.OptionsLog; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.Socket; import java.net.URI; import java.util.LinkedHashSet; import java.util.List; import java.util.Properties; import java.util.Set; import java.util.StringTokenizer; import java.util.concurrent.atomic.AtomicBoolean; /** * @version $Rev$ $Date$ */ public class MultipointDiscoveryAgent implements DiscoveryAgent, ServerService, SelfManaging { private static final Logger log = Logger.getInstance(LogCategory.OPENEJB_SERVER.createChild("discovery").createChild("multipoint"), MultipointDiscoveryAgent.class); private final AtomicBoolean running = new AtomicBoolean(false); @Managed private String host = "127.0.0.1"; @Managed private int port = 4212; private String initialServers = ""; private long heartRate = 500; @Managed(append = false) private Tracker tracker; private MultipointServer multipointServer; private boolean debug = true; private String name; private String discoveryHost; private Set<URI> roots; private Duration reconnectDelay; @Managed private final Event restarts = new Event(); public MultipointDiscoveryAgent() { } public MultipointDiscoveryAgent(final boolean debug, final String name) { this.debug = debug; this.name = name; } @Override public void init(final Properties props) { final Options options = new Options(props); options.setLogger(new OptionsLog(log)); host = props.getProperty("bind", host); port = options.get("port", port); initialServers = options.get("initialServers", initialServers); heartRate = options.get("heart_rate", heartRate); discoveryHost = options.get("discoveryHost", host); name = name != null ? name : options.get("discoveryName", MultipointServer.randomColor()); reconnectDelay = options.get("reconnectDelay", new Duration("30 seconds")); final Set<URI> uris = new LinkedHashSet<URI>(); // Connect the initial set of peer servers final StringTokenizer st = new StringTokenizer(initialServers, ","); while (st.hasMoreTokens()) { final String string = st.nextToken().trim(); if (string.startsWith("conn://")) { final URI uri = URI.create(string); uris.add(uri); } else { final URI uri = URI.create("conn://" + string); uris.add(uri); } } roots = uris; final Tracker.Builder builder = new Tracker.Builder(); builder.setHeartRate(heartRate); builder.setGroup(props.getProperty("group", builder.getGroup())); builder.setMaxMissedHeartbeats(options.get("max_missed_heartbeats", builder.getMaxMissedHeartbeats())); builder.setMaxReconnectDelay(options.get("max_reconnect_delay", builder.getMaxReconnectDelay())); builder.setReconnectDelay(options.get("reconnect_delay", builder.getReconnectDelay())); builder.setExponentialBackoff(options.get("exponential_backoff", builder.getExponentialBackoff())); builder.setMaxReconnectAttempts(options.get("max_reconnect_attempts", builder.getMaxReconnectAttempts())); builder.setDebug(debug); tracker = builder.build(); } @Override public String getIP() { return host; } @Override public String getName() { return "multipoint"; } @Override public int getPort() { return port; } public String getInitialServers() { return initialServers; } @Override public void setDiscoveryListener(final DiscoveryListener listener) { this.tracker.setDiscoveryListener(listener); } @Override public void registerService(final URI serviceUri) throws IOException { tracker.registerService(serviceUri); } @Override public void unregisterService(final URI serviceUri) throws IOException { tracker.unregisterService(serviceUri); } @Override public void reportFailed(final URI serviceUri) { tracker.reportFailed(serviceUri); } public static void main(final String[] args) throws Exception { } /** * start the discovery agent * * @throws ServiceException On error */ @Override @Managed public void start() throws ServiceException { try { if (running.compareAndSet(false, true)) { log.info("MultipointDiscoveryAgent Starting"); multipointServer = new MultipointServer(host, discoveryHost, port, tracker, name, debug, roots, reconnectDelay).start(); log.info("MultipointDiscoveryAgent Started"); this.port = multipointServer.getPort(); } } catch (Exception e) { throw new ServiceException(port + "", e); } } @Managed public void restart() throws ServiceException { stop(); start(); restarts.record(); } /** * stop the channel * * @throws ServiceException On error */ @Override @Managed public void stop() throws ServiceException { if (running.compareAndSet(true, false)) { log.info("MultipointDiscoveryAgent Stopping"); multipointServer.stop(); } } @Override public void service(final InputStream in, final OutputStream out) throws ServiceException, IOException { } @Override public void service(final Socket socket) throws ServiceException, IOException { } public String getHost() { return host; } public void setHost(final String host) { this.host = host; } @Managed public URI getURI() { return multipointServer.getMe(); } @Managed public Set<URI> getRoots() { return multipointServer.getRoots(); } @Managed public long getRuns() { return multipointServer.getRuns().get(); } @Managed public String getRunsLatest() { return multipointServer.getRuns().getLatest(); } @Managed public long getRunsLatestTime() { return multipointServer.getRuns().getLatestTime(); } @Managed public long getHeartbeats() { return multipointServer.getHeartbeats().get(); } @Managed public String getHeartbeatsLatest() { return multipointServer.getHeartbeats().getLatest(); } @Managed public long getHeartbeatsLatestTime() { return multipointServer.getHeartbeats().getLatestTime(); } @Managed public long getSessionsCreated() { return multipointServer.getSessionsCreated().get(); } @Managed public String getSessionsCreatedLatest() { return multipointServer.getSessionsCreated().getLatest(); } @Managed public long getSessionsCreatedLatestTime() { return multipointServer.getSessionsCreated().getLatestTime(); } @Managed public long getReconnects() { return multipointServer.getReconnects().get(); } @Managed public String getReconnectsLatest() { return multipointServer.getReconnects().getLatest(); } @Managed public long getReconnectsLatestTime() { return multipointServer.getReconnects().getLatestTime(); } @Managed public long getJoined() { return multipointServer.getJoined(); } @Managed public List<URI> getSessions() { return multipointServer.getSessions(); } @Managed public List<URI> getConnectionsQueued() { return multipointServer.getConnectionsQueued(); } @Managed public long getReconnectDelay() { return multipointServer.getReconnectDelay(); } }