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