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