00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031 package org.objectweb.proactive.core.body.request;
00032
00033 import java.io.ByteArrayInputStream;
00034 import java.io.IOException;
00035 import java.io.StreamCorruptedException;
00036 import java.security.cert.X509Certificate;
00037
00038 import org.apache.log4j.Logger;
00039 import org.objectweb.proactive.Body;
00040 import org.objectweb.proactive.ProActive;
00041 import org.objectweb.proactive.core.UniqueID;
00042 import org.objectweb.proactive.core.body.AbstractBody;
00043 import org.objectweb.proactive.core.body.LocalBodyStore;
00044 import org.objectweb.proactive.core.body.UniversalBody;
00045 import org.objectweb.proactive.core.body.ft.protocols.FTManager;
00046 import org.objectweb.proactive.core.body.future.FutureProxy;
00047 import org.objectweb.proactive.core.body.future.FutureResult;
00048 import org.objectweb.proactive.core.body.message.MessageImpl;
00049 import org.objectweb.proactive.core.body.reply.Reply;
00050 import org.objectweb.proactive.core.body.reply.ReplyImpl;
00051 import org.objectweb.proactive.core.exceptions.proxy.ProxyNonFunctionalException;
00052 import org.objectweb.proactive.core.mop.MethodCall;
00053 import org.objectweb.proactive.core.mop.MethodCallExecutionFailedException;
00054 import org.objectweb.proactive.core.mop.StubObject;
00055 import org.objectweb.proactive.core.util.log.Loggers;
00056 import org.objectweb.proactive.core.util.log.ProActiveLogger;
00057 import org.objectweb.proactive.ext.locationserver.LocationServer;
00058 import org.objectweb.proactive.ext.locationserver.LocationServerFactory;
00059 import org.objectweb.proactive.ext.security.ProActiveSecurity;
00060 import org.objectweb.proactive.ext.security.ProActiveSecurityManager;
00061 import org.objectweb.proactive.ext.security.crypto.Session;
00062 import org.objectweb.proactive.ext.security.exceptions.RenegotiateSessionException;
00063 import org.objectweb.proactive.ext.security.exceptions.SecurityNotAvailableException;
00064
00065 import sun.rmi.server.MarshalInputStream;
00066
00067
00068 public class RequestImpl extends MessageImpl implements Request,
00069 java.io.Serializable {
00070 public static Logger logger = ProActiveLogger.getLogger(Loggers.REQUESTS);
00071 public static Logger loggerNFE = ProActiveLogger.getLogger(Loggers.NFE);
00072 protected MethodCall methodCall;
00073 protected boolean ciphered;
00074
00078 protected int sendCounter;
00079
00082 protected transient UniversalBody sender;
00083 private byte[][] methodCallCiphered;
00084 public long sessionID;
00085 protected String codebase;
00086 private static Boolean enableStackTrace;
00087 private StackTraceElement[] stackTrace;
00088
00089
00090 protected boolean isNFRequest = false;
00091 protected int nfRequestPriority;
00092
00096 private static final int MAX_TRIES = 15;
00097
00098 transient protected LocationServer server;
00099
00100
00101
00102
00103
00104
00105
00106
00107 public RequestImpl(MethodCall methodCall, UniversalBody sender,
00108 boolean isOneWay, long nextSequenceID) {
00109 super(sender.getID(), nextSequenceID, isOneWay, methodCall.getName());
00110 this.methodCall = methodCall;
00111 this.sender = sender;
00112 this.isNFRequest = false;
00113
00114 if (enableStackTrace == null) {
00115
00116
00117 enableStackTrace = new Boolean(!"false".equals(System.getProperty(
00118 "proactive.stack_trace")));
00119 }
00120 if (enableStackTrace.booleanValue()) {
00121 this.stackTrace = new Exception().getStackTrace();
00122 }
00123 }
00124
00125
00126 public RequestImpl(MethodCall methodCall, UniversalBody sender,
00127 boolean isOneWay, long nextSequenceID, boolean isNFRequest) {
00128 super(sender.getID(), nextSequenceID, isOneWay, methodCall.getName());
00129 this.methodCall = methodCall;
00130 this.sender = sender;
00131 this.isNFRequest = isNFRequest;
00132 this.nfRequestPriority = Request.NFREQUEST_NO_PRIORITY;
00133
00134 if (enableStackTrace == null) {
00135
00136
00137 enableStackTrace = new Boolean(!"false".equals(System.getProperty(
00138 "proactive.stack_trace")));
00139 }
00140 if (enableStackTrace.booleanValue()) {
00141 this.stackTrace = new Exception().getStackTrace();
00142 }
00143 }
00144
00145
00146 public RequestImpl(MethodCall methodCall, UniversalBody sender,
00147 boolean isOneWay, long nextSequenceID, boolean isNFRequest, int nfRequestPriority) {
00148 super(sender.getID(), nextSequenceID, isOneWay, methodCall.getName());
00149 this.methodCall = methodCall;
00150 this.sender = sender;
00151 this.isNFRequest = isNFRequest;
00152 this.nfRequestPriority = nfRequestPriority;
00153
00154 if (enableStackTrace == null) {
00155
00156
00157 enableStackTrace = new Boolean(!"false".equals(System.getProperty(
00158 "proactive.stack_trace")));
00159 }
00160 if (enableStackTrace.booleanValue()) {
00161 this.stackTrace = new Exception().getStackTrace();
00162 }
00163 }
00164
00165
00166
00167
00168
00169
00170
00171 public int send(UniversalBody destinationBody)
00172 throws java.io.IOException, RenegotiateSessionException {
00173
00174 sendCounter++;
00175 return sendRequest(destinationBody);
00176 }
00177
00178 public UniversalBody getSender() {
00179 return sender;
00180 }
00181
00182 public Reply serve(Body targetBody) throws ServeException {
00183 if (logger.isDebugEnabled()) {
00184 logger.debug("Serving " + this.getMethodName());
00185 }
00186 FutureResult result = serveInternal(targetBody);
00187 if (logger.isDebugEnabled()) {
00188 logger.debug("result: " + result);
00189 }
00190 if (isOneWay) {
00191 return null;
00192 }
00193 result.augmentException(stackTrace);
00194 stackTrace = null;
00195 return createReply(targetBody, result);
00196 }
00197
00198 public Reply serveAlternate(Body targetBody, ProxyNonFunctionalException nfe) {
00199 if (loggerNFE.isDebugEnabled()) {
00200 loggerNFE.debug("*** Serving an alternate version of " +
00201 this.getMethodName());
00202 if (nfe != null) {
00203 loggerNFE.debug("*** Result " + nfe.getClass().getName());
00204 } else {
00205 loggerNFE.debug("*** Result null");
00206 }
00207 }
00208 if (isOneWay) {
00209 return null;
00210 }
00211 return createReply(targetBody, new FutureResult(null, null, nfe));
00212 }
00213
00214 public boolean hasBeenForwarded() {
00215 return sendCounter > 1;
00216 }
00217
00218 public void resetSendCounter() {
00219 this.sendCounter = 0;
00220 }
00221
00222 public Object getParameter(int index) {
00223 return methodCall.getParameter(index);
00224 }
00225
00226 public MethodCall getMethodCall() {
00227 return methodCall;
00228 }
00229
00230 public void notifyReception(UniversalBody bodyReceiver)
00231 throws java.io.IOException {
00232 if (!hasBeenForwarded()) {
00233 return;
00234 }
00235
00236
00237
00238
00239 if (sender != null) {
00240 sender.updateLocation(bodyReceiver.getID(),
00241 bodyReceiver.getRemoteAdapter());
00242 }
00243 }
00244
00245
00246
00247
00248 protected FutureResult serveInternal(Body targetBody)
00249 throws ServeException {
00250 Object result = null;
00251 Throwable exception = null;
00252 try {
00253
00254 result = methodCall.execute(targetBody.getReifiedObject());
00255 } catch (MethodCallExecutionFailedException e) {
00256
00257 throw new ServeException("serve method " +
00258 methodCall.getReifiedMethod().toString() + " failed", e);
00259 } catch (java.lang.reflect.InvocationTargetException e) {
00260 exception = e.getTargetException();
00261 if (isOneWay) {
00262 throw new ServeException("serve method " +
00263 methodCall.getReifiedMethod().toString() + " failed",
00264 exception);
00265 }
00266 }
00267
00268 return new FutureResult(result, exception, null);
00269 }
00270
00271 protected Reply createReply(Body targetBody, FutureResult result) {
00272 ProActiveSecurityManager psm = null;
00273 try {
00274 psm = ((AbstractBody) ProActive.getBodyOnThis()).getProActiveSecurityManager();
00275 } catch (java.io.IOException e) {
00276 e.printStackTrace();
00277 } catch (SecurityNotAvailableException e) {
00278
00279 }
00280
00281 return new ReplyImpl(targetBody.getID(), sequenceNumber, methodName,
00282 result, psm);
00283 }
00284
00285 public boolean crypt(ProActiveSecurityManager psm,
00286 UniversalBody destinationBody) throws RenegotiateSessionException {
00287 try {
00288 if (logger.isDebugEnabled()) {
00289 ProActiveLogger.getLogger(Loggers.SECURITY_REQUEST).debug(" sending request " +
00290 methodCall.getName());
00291 }
00292 if (!ciphered && !hasBeenForwarded()) {
00293 sessionID = 0;
00294
00295 if (sender == null) {
00296 logger.warn("sender is null but why ?");
00297 }
00298
00299 byte[] certE = destinationBody.getCertificateEncoded();
00300 X509Certificate cert = ProActiveSecurity.decodeCertificate(certE);
00301 sessionID = psm.getSessionIDTo(cert);
00302 if (sessionID != 0) {
00303 methodCallCiphered = psm.encrypt(sessionID, methodCall,
00304 Session.ACT_AS_CLIENT);
00305 ciphered = true;
00306 methodCall = null;
00307 if (logger.isDebugEnabled()) {
00308 ProActiveLogger.getLogger(Loggers.SECURITY_REQUEST)
00309 .debug("methodcallciphered " +
00310 methodCallCiphered + ", ciphered " + ciphered +
00311 ", methodCall " + methodCall);
00312 }
00313 }
00314 }
00315 } catch (SecurityNotAvailableException e) {
00316
00317
00318 logger.debug("Request : security disabled");
00319 } catch (IOException e) {
00320 e.printStackTrace();
00321 }
00322
00323 return true;
00324 }
00325
00326 protected int sendRequest(UniversalBody destinationBody)
00327 throws java.io.IOException, RenegotiateSessionException {
00328 try {
00329 this.crypt(((AbstractBody) ProActive.getBodyOnThis()).getProActiveSecurityManager(),
00330 destinationBody);
00331 } catch (SecurityNotAvailableException e) {
00332
00333 }
00334
00335 int ftres = FTManager.NON_FT;
00336 try {
00337 ftres = destinationBody.receiveRequest(this);
00338 } catch (Exception e) {
00339
00340
00341
00342
00343 try {
00344 backupSolution(destinationBody);
00345 }catch (IOException ioex)
00346 {
00347 throw new IOException(e.getMessage()+ioex.getMessage());
00348 }
00349 }
00350
00351 if (logger.isDebugEnabled()) {
00352 logger.debug(" sending request finished");
00353 }
00354 return ftres;
00355 }
00356
00360 protected void backupSolution(UniversalBody destinationBody)
00361 throws java.io.IOException {
00362 int tries = 0;
00363
00364 UniqueID bodyID = destinationBody.getID();
00365 while (tries < MAX_TRIES) {
00366 UniversalBody remoteBody = null;
00367 try {
00368
00369 UniversalBody mobile = queryServer(bodyID);
00370
00371
00372 FutureProxy futureProxy = (FutureProxy) ((StubObject) mobile)
00373 .getProxy();
00374 remoteBody = (UniversalBody) futureProxy.getResult();
00375
00376 if (remoteBody == null)
00377 throw new IOException("remoteBody is null");
00378
00379 remoteBody.receiveRequest(this);
00380
00381
00382
00383
00384 if (sender != null) {
00385 sender.updateLocation(bodyID, remoteBody);
00386 } else {
00387 LocalBodyStore.getInstance()
00388 .getLocalBody(getSourceBodyID()).updateLocation(
00389 bodyID, remoteBody);
00390 }
00391 return;
00392 } catch (Exception e) {
00393
00394 tries++;
00395
00396
00397
00398
00399
00400
00401
00402
00403 if(tries == MAX_TRIES){
00404 logger.error("FAILED = " + " for method " + methodName
00405 + " exception :" + e.getClass().getName());
00406
00407 throw new IOException("FAILED = " + " for method " + methodName
00408 + " exception :" + e.getClass().getName()+"("+e.getMessage()+")");
00409 }
00410 }
00411 }
00412 }
00413
00414 protected UniversalBody queryServer(UniqueID bodyID) throws IOException {
00415 if (server == null) {
00416 server = LocationServerFactory.getLocationServer();
00417 }
00418 if (server == null){
00419 throw new IOException("No server found");
00420 }
00421 UniversalBody mobile = (UniversalBody) server.searchObject(bodyID);
00422
00423 ProActive.waitFor(mobile);
00424 return mobile;
00425 }
00426
00427
00428 public boolean isCiphered() {
00429 return ciphered;
00430 }
00431
00432 public boolean decrypt(ProActiveSecurityManager psm)
00433 throws RenegotiateSessionException {
00434
00435
00436 ProActiveLogger.getLogger(Loggers.SECURITY_REQUEST).debug(" RequestImpl " +
00437 sessionID + " decrypt : methodcallciphered " + methodCallCiphered +
00438 ", ciphered " + ciphered + ", methodCall " + methodCall);
00439
00440 if ((ciphered) && (psm != null)) {
00441 try {
00442 ProActiveLogger.getLogger(Loggers.SECURITY_REQUEST).debug("ReceiveRequest : this body is " +
00443 psm.getCertificate().getSubjectDN() + " " +
00444 psm.getCertificate().getPublicKey());
00445 byte[] decryptedMethodCall = psm.decrypt(sessionID,
00446 methodCallCiphered, Session.ACT_AS_SERVER);
00447
00448
00449 ByteArrayInputStream bin = new ByteArrayInputStream(decryptedMethodCall);
00450 MarshalInputStream in = new MarshalInputStream(bin);
00451
00452
00453 methodCall = (MethodCall) in.readObject();
00454 in.close();
00455 ciphered = false;
00456
00457
00458 return true;
00459 } catch (ClassNotFoundException e) {
00460 int index = e.toString().indexOf(':');
00461 String className = e.toString().substring(index).trim();
00462 className = className.substring(2);
00463
00464
00465
00466
00467
00468 this.decrypt(psm);
00469
00470
00471
00472
00473 } catch (StreamCorruptedException e) {
00474 e.printStackTrace();
00475 } catch (IOException e) {
00476
00477 throw new RenegotiateSessionException("");
00478 }
00479
00480
00481 }
00482
00483 return false;
00484 }
00485
00486
00487
00488
00489 public long getSessionId() {
00490 return sessionID;
00491 }
00492
00493
00494
00495
00496 private void writeObject(java.io.ObjectOutputStream out)
00497 throws java.io.IOException {
00498 out.defaultWriteObject();
00499 out.writeObject(sender.getRemoteAdapter());
00500 }
00501
00502 private void readObject(java.io.ObjectInputStream in)
00503 throws java.io.IOException, ClassNotFoundException {
00504 in.defaultReadObject();
00505 sender = (UniversalBody) in.readObject();
00506 }
00507
00508
00509
00510
00511
00512 public boolean isFunctionalRequest() {
00513 return isNFRequest;
00514 }
00515
00516 public void setFunctionalRequest(boolean isFunctionalRequest) {
00517 this.isNFRequest = isFunctionalRequest;
00518 }
00519
00520 public void setNFRequestPriority(int nfReqPriority) {
00521 this.nfRequestPriority = nfReqPriority;
00522 }
00523
00524 public int getNFRequestPriority() {
00525 return nfRequestPriority;
00526 }
00527 }