001
014
015 package com.liferay.portal.kernel.resiliency.spi.remote;
016
017 import com.liferay.portal.kernel.deploy.hot.DependencyManagementThreadLocal;
018 import com.liferay.portal.kernel.log.Log;
019 import com.liferay.portal.kernel.log.LogFactoryUtil;
020 import com.liferay.portal.kernel.nio.intraband.RegistrationReference;
021 import com.liferay.portal.kernel.nio.intraband.welder.Welder;
022 import com.liferay.portal.kernel.nio.intraband.welder.WelderFactoryUtil;
023 import com.liferay.portal.kernel.process.ProcessCallable;
024 import com.liferay.portal.kernel.process.ProcessException;
025 import com.liferay.portal.kernel.process.ProcessExecutor;
026 import com.liferay.portal.kernel.process.log.ProcessOutputStream;
027 import com.liferay.portal.kernel.resiliency.mpi.MPI;
028 import com.liferay.portal.kernel.resiliency.mpi.MPIHelperUtil;
029 import com.liferay.portal.kernel.resiliency.spi.SPI;
030 import com.liferay.portal.kernel.resiliency.spi.SPIConfiguration;
031 import com.liferay.portal.kernel.resiliency.spi.agent.SPIAgent;
032 import com.liferay.portal.kernel.resiliency.spi.agent.SPIAgentFactoryUtil;
033 import com.liferay.portal.kernel.resiliency.spi.provider.SPISynchronousQueueUtil;
034 import com.liferay.portal.kernel.util.PropsKeys;
035 import com.liferay.portal.kernel.util.ReflectionUtil;
036
037 import java.io.IOException;
038 import java.io.ObjectInputStream;
039 import java.io.ObjectOutputStream;
040
041 import java.lang.reflect.Field;
042
043 import java.rmi.Remote;
044 import java.rmi.RemoteException;
045 import java.rmi.server.UnicastRemoteObject;
046
047 import java.util.UUID;
048 import java.util.concurrent.ConcurrentMap;
049
050
053 public abstract class RemoteSPI implements ProcessCallable<SPI>, Remote, SPI {
054
055 public RemoteSPI(SPIConfiguration spiConfiguration) {
056 this.spiConfiguration = spiConfiguration;
057
058 mpi = MPIHelperUtil.getMPI();
059
060 UUID uuidObject = UUID.randomUUID();
061
062 uuid = uuidObject.toString();
063
064 welder = WelderFactoryUtil.createWelder();
065 }
066
067 @Override
068 public SPI call() throws ProcessException {
069 try {
070 ProcessExecutor.ProcessContext.attach(
071 spiConfiguration.getSPIId(), spiConfiguration.getPingInterval(),
072 new SPIShutdownHook());
073
074 SPI spi = (SPI)UnicastRemoteObject.exportObject(this, 0);
075
076 RegisterCallback registerCallback = new RegisterCallback(uuid, spi);
077
078 ProcessOutputStream processOutputStream =
079 ProcessExecutor.ProcessContext.getProcessOutputStream();
080
081 processOutputStream.writeProcessCallable(registerCallback);
082
083 registrationReference = welder.weld(MPIHelperUtil.getIntraband());
084
085 ConcurrentMap<String, Object> attributes =
086 ProcessExecutor.ProcessContext.getAttributes();
087
088 attributes.put(SPI.SPI_INSTANCE_PUBLICATION_KEY, this);
089
090 return spi;
091 }
092 catch (RemoteException re) {
093 throw new ProcessException("Failed to export SPI as RMI stub.", re);
094 }
095 catch (IOException ioe) {
096 throw new ProcessException(ioe);
097 }
098 }
099
100 @Override
101 public MPI getMPI() {
102 return mpi;
103 }
104
105 @Override
106 public RegistrationReference getRegistrationReference() {
107 return registrationReference;
108 }
109
110 @Override
111 public SPIAgent getSPIAgent() {
112 if (spiAgent == null) {
113 spiAgent = SPIAgentFactoryUtil.createSPIAgent(
114 spiConfiguration, registrationReference);
115 }
116
117 return spiAgent;
118 }
119
120 @Override
121 public SPIConfiguration getSPIConfiguration() {
122 return spiConfiguration;
123 }
124
125 public String getUUID() {
126 return uuid;
127 }
128
129 public Welder getWelder() {
130 return welder;
131 }
132
133 @Override
134 public boolean isAlive() {
135 return true;
136 }
137
138 protected final MPI mpi;
139 protected RegistrationReference registrationReference;
140 protected transient volatile SPIAgent spiAgent;
141 protected final SPIConfiguration spiConfiguration;
142 protected final String uuid;
143 protected final Welder welder;
144
145 protected static class RegisterCallback implements ProcessCallable<SPI> {
146
147 public RegisterCallback(String spiUUID, SPI spi) {
148 _spiUUID = spiUUID;
149 _spi = spi;
150 }
151
152 @Override
153 public SPI call() throws ProcessException {
154 try {
155 SPISynchronousQueueUtil.notifySynchronousQueue(_spiUUID, _spi);
156 }
157 catch (InterruptedException ie) {
158 throw new ProcessException(ie);
159 }
160
161 return _spi;
162 }
163
164 private static final long serialVersionUID = 1L;
165
166 private final SPI _spi;
167 private final String _spiUUID;
168
169 }
170
171 protected class SPIShutdownHook implements ProcessExecutor.ShutdownHook {
172
173 @Override
174 public boolean shutdown(int shutdownCode, Throwable shutdownThrowable) {
175 try {
176 RemoteSPI.this.stop();
177 }
178 catch (RemoteException re) {
179 _log.error("Unable to stop SPI", re);
180 }
181
182 try {
183 RemoteSPI.this.destroy();
184 }
185 catch (RemoteException re) {
186 _log.error("Unable to destroy SPI", re);
187 }
188
189 return true;
190 }
191
192 }
193
194 private void readObject(ObjectInputStream objectInputStream)
195 throws ClassNotFoundException, IOException {
196
197 objectInputStream.defaultReadObject();
198
199 System.setProperty(
200 PropsKeys.INTRABAND_IMPL, objectInputStream.readUTF());
201 System.setProperty(
202 PropsKeys.INTRABAND_TIMEOUT_DEFAULT, objectInputStream.readUTF());
203 System.setProperty(
204 PropsKeys.INTRABAND_WELDER_IMPL, objectInputStream.readUTF());
205 System.setProperty(
206 "portal:" + PropsKeys.LIFERAY_HOME, objectInputStream.readUTF());
207
208
209
210 System.setProperty("portal:" + PropsKeys.AUTO_DEPLOY_ENABLED, "false");
211
212
213
214 System.setProperty("portal:" + PropsKeys.CLUSTER_LINK_ENABLED, "false");
215
216
217
218 try {
219 Field enabledField = ReflectionUtil.getDeclaredField(
220 DependencyManagementThreadLocal.class, "_enabled");
221
222 enabledField.set(
223 null,
224 new ThreadLocal<Boolean>() {
225
226 @Override
227 public Boolean get() {
228 return Boolean.FALSE;
229 }
230
231 });
232 }
233 catch (Exception e) {
234 throw new IOException("Unable to disable dependency management", e);
235 }
236
237
238
239 System.setProperty("spi.id", "-" + spiConfiguration.getSPIId());
240 }
241
242 private void writeObject(ObjectOutputStream objectOutputStream)
243 throws IOException {
244
245 objectOutputStream.defaultWriteObject();
246
247 objectOutputStream.writeUTF(
248 System.getProperty(PropsKeys.INTRABAND_IMPL));
249 objectOutputStream.writeUTF(
250 System.getProperty(PropsKeys.INTRABAND_TIMEOUT_DEFAULT));
251 objectOutputStream.writeUTF(
252 System.getProperty(PropsKeys.INTRABAND_WELDER_IMPL));
253 objectOutputStream.writeUTF(System.getProperty(PropsKeys.LIFERAY_HOME));
254 }
255
256 private static Log _log = LogFactoryUtil.getLog(RemoteSPI.class);
257
258 }