001
014
015 package com.liferay.portal.cluster;
016
017 import com.liferay.portal.kernel.cluster.Address;
018 import com.liferay.portal.kernel.io.Serializer;
019 import com.liferay.portal.kernel.log.Log;
020 import com.liferay.portal.kernel.log.LogFactoryUtil;
021 import com.liferay.portal.kernel.util.CharPool;
022 import com.liferay.portal.kernel.util.GetterUtil;
023 import com.liferay.portal.kernel.util.InetAddressUtil;
024 import com.liferay.portal.kernel.util.SocketUtil;
025 import com.liferay.portal.kernel.util.Validator;
026 import com.liferay.portal.util.PropsValues;
027
028 import java.io.Serializable;
029
030 import java.net.InetAddress;
031 import java.net.NetworkInterface;
032
033 import java.nio.ByteBuffer;
034
035 import java.util.ArrayList;
036 import java.util.Collections;
037 import java.util.List;
038
039 import org.jgroups.JChannel;
040 import org.jgroups.Receiver;
041 import org.jgroups.View;
042
043
046 public abstract class ClusterBase {
047
048 public void afterPropertiesSet() {
049 if (!isEnabled()) {
050 return;
051 }
052
053 if (!_initialized) {
054 initSystemProperties();
055
056 try {
057 initBindAddress();
058 }
059 catch (Exception e) {
060 if (_log.isWarnEnabled()) {
061 _log.warn("Failed to initialize outgoing IP address", e);
062 }
063 }
064
065 _initialized = true;
066 }
067
068 try {
069 initChannels();
070 }
071 catch (Exception e) {
072 if (_log.isErrorEnabled()) {
073 _log.error("Unable to initialize channels", e);
074 }
075
076 throw new IllegalStateException(e);
077 }
078 }
079
080 public abstract void destroy();
081
082 public boolean isEnabled() {
083 return PropsValues.CLUSTER_LINK_ENABLED;
084 }
085
086 protected void sendJGroupsMessage(
087 JChannel jChannel, org.jgroups.Address destAddress,
088 Serializable serializable)
089 throws Exception {
090
091 Serializer serializer = new Serializer();
092
093 serializer.writeObject(serializable);
094
095 ByteBuffer byteBuffer = serializer.toByteBuffer();
096
097 jChannel.send(
098 destAddress, byteBuffer.array(), byteBuffer.position(),
099 byteBuffer.remaining());
100
101 if (_log.isDebugEnabled()) {
102 _log.debug("Send message " + serializable);
103 }
104 }
105
106 protected JChannel createJChannel(
107 String properties, Receiver receiver, String clusterName)
108 throws Exception {
109
110 JChannel jChannel = new JChannel(properties);
111
112 jChannel.setReceiver(receiver);
113
114 jChannel.connect(clusterName);
115
116 if (_log.isInfoEnabled()) {
117 _log.info(
118 "Create a new channel with properties " +
119 jChannel.getProperties());
120 }
121
122 return jChannel;
123 }
124
125 protected List<Address> getAddresses(JChannel channel) {
126 BaseReceiver baseReceiver = (BaseReceiver)channel.getReceiver();
127
128 View view = baseReceiver.getView();
129
130 List<org.jgroups.Address> jGroupsAddresses = view.getMembers();
131
132 if (jGroupsAddresses == null) {
133 return Collections.emptyList();
134 }
135
136 List<Address> addresses = new ArrayList<Address>(
137 jGroupsAddresses.size());
138
139 for (org.jgroups.Address jgroupsAddress : jGroupsAddresses) {
140 addresses.add(new AddressImpl(jgroupsAddress));
141 }
142
143 return addresses;
144 }
145
146 protected void initBindAddress() throws Exception {
147 String autodetectAddress = PropsValues.CLUSTER_LINK_AUTODETECT_ADDRESS;
148
149 if (Validator.isNull(autodetectAddress)) {
150 bindInetAddress = InetAddressUtil.getLocalInetAddress();
151
152 return;
153 }
154
155 String host = autodetectAddress;
156 int port = 80;
157
158 int index = autodetectAddress.indexOf(CharPool.COLON);
159
160 if (index != -1) {
161 host = autodetectAddress.substring(0, index);
162 port = GetterUtil.getInteger(
163 autodetectAddress.substring(index + 1), port);
164 }
165
166 if (_log.isInfoEnabled()) {
167 _log.info(
168 "Autodetecting JGroups outgoing IP address and interface for " +
169 host + ":" + port);
170 }
171
172 SocketUtil.BindInfo bindInfo = SocketUtil.getBindInfo(host, port);
173
174 bindInetAddress = bindInfo.getInetAddress();
175 NetworkInterface networkInterface = bindInfo.getNetworkInterface();
176
177 System.setProperty(
178 "jgroups.bind_addr", bindInetAddress.getHostAddress());
179 System.setProperty(
180 "jgroups.bind_interface", networkInterface.getName());
181
182 if (_log.isInfoEnabled()) {
183 _log.info(
184 "Setting JGroups outgoing IP address to " +
185 bindInetAddress.getHostAddress() + " and interface to " +
186 networkInterface.getName());
187 }
188 }
189
190 protected abstract void initChannels() throws Exception;
191
192 protected void initSystemProperties() {
193 for (String systemProperty :
194 PropsValues.CLUSTER_LINK_CHANNEL_SYSTEM_PROPERTIES) {
195
196 int index = systemProperty.indexOf(CharPool.COLON);
197
198 if (index == -1) {
199 continue;
200 }
201
202 String key = systemProperty.substring(0, index);
203 String value = systemProperty.substring(index + 1);
204
205 System.setProperty(key, value);
206
207 if (_log.isDebugEnabled()) {
208 _log.debug(
209 "Setting system property {key=" + key + ", value=" + value +
210 "}");
211 }
212 }
213 }
214
215 protected static InetAddress bindInetAddress;
216
217 private static Log _log = LogFactoryUtil.getLog(ClusterBase.class);
218
219 private static boolean _initialized;
220
221 }