KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > objectstyle > cayenne > event > JavaGroupsBridge


1 /* ====================================================================
2  *
3  * The ObjectStyle Group Software License, version 1.1
4  * ObjectStyle Group - http://objectstyle.org/
5  *
6  * Copyright (c) 2002-2005, Andrei (Andrus) Adamchik and individual authors
7  * of the software. All rights reserved.
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions
11  * are met:
12  *
13  * 1. Redistributions of source code must retain the above copyright
14  * notice, this list of conditions and the following disclaimer.
15  *
16  * 2. Redistributions in binary form must reproduce the above copyright
17  * notice, this list of conditions and the following disclaimer in
18  * the documentation and/or other materials provided with the
19  * distribution.
20  *
21  * 3. The end-user documentation included with the redistribution, if any,
22  * must include the following acknowlegement:
23  * "This product includes software developed by independent contributors
24  * and hosted on ObjectStyle Group web site (http://objectstyle.org/)."
25  * Alternately, this acknowlegement may appear in the software itself,
26  * if and wherever such third-party acknowlegements normally appear.
27  *
28  * 4. The names "ObjectStyle Group" and "Cayenne" must not be used to endorse
29  * or promote products derived from this software without prior written
30  * permission. For written permission, email
31  * "andrus at objectstyle dot org".
32  *
33  * 5. Products derived from this software may not be called "ObjectStyle"
34  * or "Cayenne", nor may "ObjectStyle" or "Cayenne" appear in their
35  * names without prior written permission.
36  *
37  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
38  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
39  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
40  * DISCLAIMED. IN NO EVENT SHALL THE OBJECTSTYLE GROUP OR
41  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
42  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
43  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
44  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
45  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
46  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
47  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
48  * SUCH DAMAGE.
49  * ====================================================================
50  *
51  * This software consists of voluntary contributions made by many
52  * individuals and hosted on ObjectStyle Group web site. For more
53  * information on the ObjectStyle Group, please see
54  * <http://objectstyle.org/>.
55  */

56 package org.objectstyle.cayenne.event;
57
58 import java.io.Serializable JavaDoc;
59
60 import org.apache.log4j.Logger;
61 import org.jgroups.Channel;
62 import org.jgroups.JChannel;
63 import org.jgroups.Message;
64 import org.jgroups.MessageListener;
65 import org.jgroups.blocks.PullPushAdapter;
66
67 /**
68  * Implementation of EventBridge that passes and receives events via JavaGroups
69  * communication software.
70  *
71  * @author Andrei Adamchik
72  * @since 1.1
73  */

74 public class JavaGroupsBridge extends EventBridge implements MessageListener {
75     private static Logger logObj = Logger.getLogger(JavaGroupsBridge.class);
76
77     // TODO: Meaning of "state" in JGroups is not yet clear to me
78
protected byte[] state;
79
80     protected Channel channel;
81     protected PullPushAdapter adapter;
82     protected String JavaDoc multicastAddress;
83     protected String JavaDoc multicastPort;
84     protected String JavaDoc configURL;
85
86     /**
87      * Creates new instance of JavaGroupsBridge.
88      */

89     public JavaGroupsBridge(EventSubject localSubject, String JavaDoc externalSubject) {
90         super(localSubject, externalSubject);
91     }
92
93     public String JavaDoc getConfigURL() {
94         return configURL;
95     }
96
97     public void setConfigURL(String JavaDoc configURL) {
98         this.configURL = configURL;
99     }
100
101     public String JavaDoc getMulticastAddress() {
102         return multicastAddress;
103     }
104
105     public void setMulticastAddress(String JavaDoc multicastAddress) {
106         this.multicastAddress = multicastAddress;
107     }
108
109     public String JavaDoc getMulticastPort() {
110         return multicastPort;
111     }
112
113     public void setMulticastPort(String JavaDoc multicastPort) {
114         this.multicastPort = multicastPort;
115     }
116
117     public byte[] getState() {
118         return state;
119     }
120
121     public void setState(byte[] state) {
122         this.state = state;
123     }
124
125     /**
126      * Implementation of org.javagroups.MessageListener - a callback method to process
127      * incoming messages.
128      */

129     public void receive(Message message) {
130         try {
131             if (logObj.isDebugEnabled()) {
132                 logObj.debug("Received Message from: " + message.getSrc());
133             }
134
135             CayenneEvent event = messageObjectToEvent((Serializable JavaDoc) message.getObject());
136             if (event != null) {
137                 if (logObj.isDebugEnabled()) {
138                     logObj.debug("Received CayenneEvent: " + event.getClass().getName());
139                 }
140
141                 onExternalEvent(event);
142             }
143         } catch (Exception JavaDoc ex) {
144             logObj.info("Exception while processing message: ", ex);
145         }
146
147     }
148
149     protected void startupExternal() throws Exception JavaDoc {
150         // TODO: need to do more research to figure out the best default transport settings
151
// to avoid fragmentation, etc.
152

153         // if config file is set, use it, otherwise use a default
154
// set of properties, trying to configure multicast address and port
155
if (configURL != null) {
156             logObj.debug("creating channel with configuration from " + configURL);
157             channel = new JChannel(configURL);
158         } else {
159             String JavaDoc configString = buildConfigString();
160             logObj.debug("creating channel with properties: " + configString);
161             channel = new JChannel(configString);
162         }
163
164         // Important - discard messages from self
165
channel.setOpt(Channel.LOCAL, Boolean.FALSE);
166         channel.connect(externalSubject);
167         logObj.debug("channel connected.");
168
169         if (receivesExternalEvents()) {
170             adapter = new PullPushAdapter(channel, this);
171         }
172     }
173
174     /**
175      * Creates JavaGroups configuration String, using preconfigured
176      * multicast port and address.
177      */

178     protected String JavaDoc buildConfigString() {
179         if (multicastAddress == null) {
180             throw new IllegalStateException JavaDoc("'multcastAddress' is not set");
181         }
182
183         if (multicastPort == null) {
184             throw new IllegalStateException JavaDoc("'multcastPort' is not set");
185         }
186
187         return "UDP(mcast_addr="
188             + multicastAddress
189             + ";mcast_port="
190             + multicastPort
191             + ";ip_ttl=32):"
192             + "PING(timeout=3000;num_initial_members=6):"
193             + "FD(timeout=3000):"
194             + "VERIFY_SUSPECT(timeout=1500):"
195             + "pbcast.NAKACK(gc_lag=10;retransmit_timeout=600,1200,2400,4800):"
196             + "pbcast.STABLE(desired_avg_gossip=10000):"
197             + "FRAG:"
198             + "pbcast.GMS(join_timeout=5000;join_retry_timeout=2000;"
199             + "shun=true;print_local_addr=false)";
200     }
201
202     protected void shutdownExternal() throws Exception JavaDoc {
203         try {
204             if (adapter != null) {
205                 adapter.stop();
206             }
207
208             channel.close();
209         } finally {
210             adapter = null;
211             channel = null;
212         }
213     }
214
215     protected void sendExternalEvent(CayenneEvent localEvent) throws Exception JavaDoc {
216         logObj.debug("Sending event remotely: " + localEvent);
217         Message message = new Message(null, null, eventToMessageObject(localEvent));
218         channel.send(message);
219     }
220
221     /**
222      * Converts CayenneEvent to a serializable object that will be sent via JMS.
223      * Default implementation simply returns the event, but subclasses can customize
224      * this behavior.
225      */

226     protected Serializable JavaDoc eventToMessageObject(CayenneEvent event) throws Exception JavaDoc {
227         return event;
228     }
229
230     /**
231      * Converts a Serializable instance to CayenneEvent. Returns null if the object
232      * is not supported. Default implementation simply tries to cast the object to
233      * CayenneEvent, but subclasses can customize this behavior.
234      */

235     protected CayenneEvent messageObjectToEvent(Serializable JavaDoc object) throws Exception JavaDoc {
236         return (object instanceof CayenneEvent) ? (CayenneEvent) object : null;
237     }
238 }
239
Popular Tags