1
14
15 package com.liferay.portal.cluster;
16
17 import com.liferay.portal.kernel.cluster.Address;
18 import com.liferay.portal.kernel.log.Log;
19 import com.liferay.portal.kernel.log.LogFactoryUtil;
20 import com.liferay.portal.kernel.util.CharPool;
21 import com.liferay.portal.kernel.util.GetterUtil;
22 import com.liferay.portal.kernel.util.IPDetector;
23 import com.liferay.portal.kernel.util.OSDetector;
24 import com.liferay.portal.kernel.util.SocketUtil;
25 import com.liferay.portal.kernel.util.StringBundler;
26 import com.liferay.portal.kernel.util.Validator;
27 import com.liferay.portal.util.PropsValues;
28
29 import java.io.IOException;
30
31 import java.net.InetAddress;
32 import java.net.NetworkInterface;
33
34 import java.util.ArrayList;
35 import java.util.Collections;
36 import java.util.List;
37 import java.util.Vector;
38
39 import org.jgroups.ChannelException;
40 import org.jgroups.JChannel;
41 import org.jgroups.Receiver;
42 import org.jgroups.View;
43
44
49 public abstract class ClusterBase {
50
51 public void afterPropertiesSet() {
52 if (!isEnabled()) {
53 return;
54 }
55
56 if (!_initialized) {
57 if (OSDetector.isUnix() && IPDetector.isSupportsV6() &&
58 !IPDetector.isPrefersV4() && _log.isWarnEnabled()) {
59
60 StringBundler sb = new StringBundler(4);
61
62 sb.append(
63 "You are on an Unix server with IPv6 enabled. JGroups ");
64 sb.append("may not work with IPv6. If you see a multicast ");
65 sb.append("error, try adding java.net.preferIPv4Stack=true ");
66 sb.append("as a JVM startup parameter.");
67
68 _log.warn(sb.toString());
69 }
70
71 initSystemProperties();
72
73 try {
74 initBindAddress();
75 }
76 catch (IOException ioe) {
77 if (_log.isWarnEnabled()) {
78 _log.warn("Failed to initialize outgoing IP address", ioe);
79 }
80 }
81 _initialized = true;
82 }
83
84 try {
85 initChannels();
86 }
87 catch (Exception e) {
88 if (_log.isErrorEnabled()) {
89 _log.error("Unable to initialize channels", e);
90 }
91
92 throw new IllegalStateException(e);
93 }
94 }
95
96 public abstract void destroy();
97
98 public boolean isEnabled() {
99 return PropsValues.CLUSTER_LINK_ENABLED;
100 }
101
102 protected JChannel createJChannel(
103 String properties, Receiver receiver, String clusterName)
104 throws ChannelException {
105
106 JChannel jChannel = new JChannel(properties);
107
108 jChannel.setReceiver(receiver);
109
110 jChannel.connect(clusterName);
111
112 if (_log.isInfoEnabled()) {
113 _log.info(
114 "Create a new channel with properties " +
115 jChannel.getProperties());
116 }
117
118 return jChannel;
119 }
120
121 protected List<Address> getAddresses(JChannel channel) {
122 View view = channel.getView();
123
124 Vector<org.jgroups.Address> jGroupsAddresses = view.getMembers();
125
126 if (jGroupsAddresses == null) {
127 return Collections.EMPTY_LIST;
128 }
129
130 List<Address> addresses = new ArrayList<Address>(
131 jGroupsAddresses.size());
132
133 for (org.jgroups.Address jgroupsAddress : jGroupsAddresses) {
134 addresses.add(new AddressImpl(jgroupsAddress));
135 }
136
137 return addresses;
138 }
139
140 protected void initBindAddress() throws IOException {
141 String autodetectAddress = PropsValues.CLUSTER_LINK_AUTODETECT_ADDRESS;
142
143 if (Validator.isNull(autodetectAddress)) {
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 ChannelException;
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 private static Log _log = LogFactoryUtil.getLog(ClusterBase.class);
208
209 private static boolean _initialized;
210
211 protected InetAddress bindInetAddress;
212
213 }