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