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