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