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.GetterUtil;
21 import com.liferay.portal.kernel.util.IPDetector;
22 import com.liferay.portal.kernel.util.OSDetector;
23 import com.liferay.portal.kernel.util.SocketUtil;
24 import com.liferay.portal.kernel.util.StringBundler;
25 import com.liferay.portal.kernel.util.StringPool;
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 (!PropsValues.CLUSTER_LINK_ENABLED) {
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 _log.error(e, e);
89 }
90 }
91
92 public abstract void destroy();
93
94 public boolean isEnabled() {
95 return PropsValues.CLUSTER_LINK_ENABLED;
96 }
97
98 protected JChannel createChannel(
99 String properties, Receiver receiver, String clusterName)
100 throws ChannelException {
101
102 JChannel channel = new JChannel(properties);
103
104 channel.setReceiver(receiver);
105
106 channel.connect(clusterName);
107
108 if (_log.isInfoEnabled()) {
109 _log.info(
110 "Create a new channel with properties " +
111 channel.getProperties());
112 }
113
114 return channel;
115 }
116
117 protected List<Address> getAddresses(JChannel channel) {
118 View view = channel.getView();
119
120 Vector<org.jgroups.Address> jGroupsAddresses = view.getMembers();
121
122 if (jGroupsAddresses == null) {
123 return Collections.EMPTY_LIST;
124 }
125
126 List<Address> addresses = new ArrayList<Address>(
127 jGroupsAddresses.size());
128
129 for (org.jgroups.Address jgroupsAddress : jGroupsAddresses) {
130 addresses.add(new AddressImpl(jgroupsAddress));
131 }
132
133 return addresses;
134 }
135
136 protected void initBindAddress() throws IOException {
137 String autodetectAddress = PropsValues.CLUSTER_LINK_AUTODETECT_ADDRESS;
138
139 if (Validator.isNull(autodetectAddress)) {
140 return;
141 }
142
143 String host = autodetectAddress;
144 int port = 80;
145
146 int index = autodetectAddress.indexOf(StringPool.COLON);
147
148 if (index != -1) {
149 host = autodetectAddress.substring(0, index);
150 port = GetterUtil.getInteger(
151 autodetectAddress.substring(index + 1), port);
152 }
153
154 if (_log.isInfoEnabled()) {
155 _log.info(
156 "Autodetecting JGroups outgoing IP address and interface for " +
157 host + ":" + port);
158 }
159
160 SocketUtil.BindInfo bindInfo = SocketUtil.getBindInfo(host, port);
161
162 InetAddress inetAddress = bindInfo.getInetAddress();
163 NetworkInterface networkInterface = bindInfo.getNetworkInterface();
164
165 System.setProperty("jgroups.bind_addr", inetAddress.getHostAddress());
166 System.setProperty(
167 "jgroups.bind_interface", networkInterface.getName());
168
169 if (_log.isInfoEnabled()) {
170 _log.info(
171 "Setting JGroups outgoing IP address to " +
172 inetAddress.getHostAddress() + " and interface to " +
173 networkInterface.getName());
174 }
175 }
176
177 protected abstract void initChannels() throws ChannelException;
178
179 protected void initSystemProperties() {
180 for (String systemProperty :
181 PropsValues.CLUSTER_LINK_CHANNEL_SYSTEM_PROPERTIES) {
182
183 int index = systemProperty.indexOf(StringPool.COLON);
184
185 if (index == -1) {
186 continue;
187 }
188
189 String key = systemProperty.substring(0, index);
190 String value = systemProperty.substring(index + 1);
191
192 System.setProperty(key, value);
193
194 if (_log.isDebugEnabled()) {
195 _log.debug(
196 "Setting system property {key=" + key + ", value=" + value +
197 "}");
198 }
199 }
200 }
201
202 private static Log _log = LogFactoryUtil.getLog(ClusterBase.class);
203
204 private static boolean _initialized;
205
206 }