001package org.apache.commons.jcs.utils.discovery; 002 003/* 004 * Licensed to the Apache Software Foundation (ASF) under one 005 * or more contributor license agreements. See the NOTICE file 006 * distributed with this work for additional information 007 * regarding copyright ownership. The ASF licenses this file 008 * to you under the Apache License, Version 2.0 (the 009 * "License"); you may not use this file except in compliance 010 * with the License. You may obtain a copy of the License at 011 * 012 * http://www.apache.org/licenses/LICENSE-2.0 013 * 014 * Unless required by applicable law or agreed to in writing, 015 * software distributed under the License is distributed on an 016 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 017 * KIND, either express or implied. See the License for the 018 * specific language governing permissions and limitations 019 * under the License. 020 */ 021 022import org.apache.commons.logging.Log; 023import org.apache.commons.logging.LogFactory; 024 025import java.util.ArrayList; 026 027/** 028 * Used to periodically broadcast our location to other caches that might be listening. 029 */ 030public class UDPDiscoverySenderThread 031 implements Runnable 032{ 033 /** The logger. */ 034 private static final Log log = LogFactory.getLog( UDPDiscoverySenderThread.class ); 035 036 /** 037 * details of the host, port, and service being advertised to listen for TCP socket connections 038 */ 039 private final UDPDiscoveryAttributes attributes; 040 041 /** List of known regions. */ 042 private ArrayList<String> cacheNames = new ArrayList<String>(); 043 044 /** 045 * @param cacheNames The cacheNames to set. 046 */ 047 protected void setCacheNames( ArrayList<String> cacheNames ) 048 { 049 if ( log.isInfoEnabled() ) 050 { 051 log.info( "Resetting cacheNames = [" + cacheNames + "]" ); 052 } 053 this.cacheNames = cacheNames; 054 } 055 056 /** 057 * @return Returns the cacheNames. 058 */ 059 protected ArrayList<String> getCacheNames() 060 { 061 return cacheNames; 062 } 063 064 /** 065 * Constructs the sender with the port to tell others to connect to. 066 * <p> 067 * On construction the sender will request that the other caches let it know their addresses. 068 * @param attributes host, port, etc. 069 * @param cacheNames List of strings of the names of the region participating. 070 */ 071 public UDPDiscoverySenderThread( UDPDiscoveryAttributes attributes, ArrayList<String> cacheNames ) 072 { 073 this.attributes = attributes; 074 075 this.cacheNames = cacheNames; 076 077 if ( log.isDebugEnabled() ) 078 { 079 log.debug( "Creating sender thread for discoveryAddress = [" + attributes.getUdpDiscoveryAddr() 080 + "] and discoveryPort = [" + attributes.getUdpDiscoveryPort() + "] myHostName = [" 081 + attributes.getServiceAddress() + "] and port = [" + attributes.getServicePort() + "]" ); 082 } 083 084 UDPDiscoverySender sender = null; 085 try 086 { 087 // move this to the run method and determine how often to call it. 088 sender = new UDPDiscoverySender( attributes.getUdpDiscoveryAddr(), attributes.getUdpDiscoveryPort() ); 089 sender.requestBroadcast(); 090 091 if ( log.isDebugEnabled() ) 092 { 093 log.debug( "Sent a request broadcast to the group" ); 094 } 095 } 096 catch ( Exception e ) 097 { 098 log.error( "Problem sending a Request Broadcast", e ); 099 } 100 finally 101 { 102 try 103 { 104 if ( sender != null ) 105 { 106 sender.destroy(); 107 } 108 } 109 catch ( Exception e ) 110 { 111 log.error( "Problem closing Request Broadcast sender", e ); 112 } 113 } 114 } 115 116 /** 117 * Send a message. 118 */ 119 @Override 120 public void run() 121 { 122 UDPDiscoverySender sender = null; 123 try 124 { 125 // create this connection each time. 126 // more robust 127 sender = new UDPDiscoverySender( attributes.getUdpDiscoveryAddr(), attributes.getUdpDiscoveryPort() ); 128 129 sender.passiveBroadcast( attributes.getServiceAddress(), attributes.getServicePort(), cacheNames ); 130 131 // todo we should consider sending a request broadcast every so 132 // often. 133 134 if ( log.isDebugEnabled() ) 135 { 136 log.debug( "Called sender to issue a passive broadcast" ); 137 } 138 139 } 140 catch ( Exception e ) 141 { 142 log.error( "Problem calling the UDP Discovery Sender [" + attributes.getUdpDiscoveryAddr() + ":" 143 + attributes.getUdpDiscoveryPort() + "]", e ); 144 } 145 finally 146 { 147 if (sender != null) 148 { 149 try 150 { 151 sender.destroy(); 152 } 153 catch ( Exception e ) 154 { 155 log.error( "Problem closing Passive Broadcast sender", e ); 156 } 157 } 158 } 159 } 160 161 /** 162 * Issues a remove broadcast to the others. 163 */ 164 protected void shutdown() 165 { 166 UDPDiscoverySender sender = null; 167 try 168 { 169 // create this connection each time. 170 // more robust 171 sender = new UDPDiscoverySender( attributes.getUdpDiscoveryAddr(), attributes.getUdpDiscoveryPort() ); 172 173 sender.removeBroadcast( attributes.getServiceAddress(), attributes.getServicePort(), cacheNames ); 174 175 if ( log.isDebugEnabled() ) 176 { 177 log.debug( "Called sender to issue a remove broadcast in shudown." ); 178 } 179 } 180 catch ( Exception e ) 181 { 182 log.error( "Problem calling the UDP Discovery Sender", e ); 183 } 184 finally 185 { 186 try 187 { 188 if ( sender != null ) 189 { 190 sender.destroy(); 191 } 192 } 193 catch ( Exception e ) 194 { 195 log.error( "Problem closing Remote Broadcast sender", e ); 196 } 197 } 198 } 199}