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 package org.openmobileis.synchro.openmsp.server;
00030
00031
00032 import org.openmobileis.common.user.User;
00033 import org.openmobileis.common.user.UserManager;
00034 import org.openmobileis.common.user.UserNotFoundException;
00035 import org.openmobileis.common.user.profile.Profile;
00036 import org.openmobileis.common.user.profile.ProfileDataManager;
00037 import org.openmobileis.common.user.profile.ProfileNotFoundException;
00038 import org.openmobileis.common.util.PropertiesManager;
00039 import org.openmobileis.common.util.codec.GeneralCoder;
00040 import org.openmobileis.common.context.*;
00041 import org.openmobileis.common.util.exception.*;
00042 import org.openmobileis.common.util.log.*;
00043 import org.openmobileis.services.Service;
00044 import org.openmobileis.services.common.ServiceManager;
00045 import org.openmobileis.synchro.openmsp.OpenMSPException;
00046 import org.openmobileis.synchro.openmsp.client.core.OpenMSPSyncMessageFactory;
00047 import org.openmobileis.synchro.openmsp.protocol.AbstractCommand;
00048 import org.openmobileis.synchro.openmsp.protocol.Command;
00049 import org.openmobileis.synchro.openmsp.protocol.ContainerMessage;
00050 import org.openmobileis.synchro.openmsp.protocol.Element;
00051 import org.openmobileis.synchro.openmsp.protocol.Header;
00052 import org.openmobileis.synchro.openmsp.protocol.Message;
00053 import org.openmobileis.synchro.openmsp.protocol.MessageFactory;
00054 import org.openmobileis.synchro.openmsp.protocol.RequestCommand;
00055 import org.openmobileis.synchro.openmsp.protocol.Result;
00056 import org.openmobileis.synchro.openmsp.protocol.Status;
00057 import org.openmobileis.synchro.openmsp.server.synctarget.SynchroTargerManager;
00058 import org.openmobileis.synchro.openmsp.server.synctarget.proxy.ProxySyncroTarget;
00059 import org.openmobileis.synchro.openmsp.server.util.FileSystem;
00060 import org.openmobileis.synchro.openmsp.server.util.FileSystemObjectPool;
00061 import org.openmobileis.synchro.openmsp.server.util.FileSystemObjectPoolSelecter;
00062 import org.openmobileis.synchro.openmsp.server.util.MemoryFile;
00063 import org.openmobileis.synchro.openmsp.server.util.SynchroFileGenerator;
00064 import org.openmobileis.synchro.openmsp.server.util.SynchroFileGeneratorManager;
00065 import org.openmobileis.synchro.security.auth.Credential;
00066 import org.openmobileis.synchro.security.auth.CredentialCodec;
00067
00068 import java.io.IOException;
00069 import java.io.ByteArrayInputStream;
00070 import java.io.ByteArrayOutputStream;
00071 import java.util.zip.*;
00072
00073 import javax.servlet.ServletException;
00074 import javax.servlet.http.HttpServletRequest;
00075 import javax.servlet.http.HttpServletResponse;
00076
00084 public class OpenMSPService extends Service{
00085
00086 public OpenMSPService() {
00087 String synchrologfile = PropertiesManager.getManager().getProperty("org.openmobileis.synchro.openmsp.server.log.filename");
00088 if (synchrologfile != null) {
00089 java.util.Properties props = new java.util.Properties();
00090 props.put("LOGFILE", synchrologfile);
00091 OpenMSPServiceTracer tracer = new OpenMSPServiceTracer();
00092 tracer.setLogTracerProperties(props);
00093 LogManager.attachLogTracerToPriority(LogPriorities.USERSYNCHRO, tracer);
00094 LogManager.traceInfo(0, "Log synchro access in :"+synchrologfile);
00095 }
00096
00097 SynchroFileGeneratorManager.getManager();
00098 }
00099
00100 public void run(HttpServletRequest request, HttpServletResponse res) throws ServletException, IOException {
00101
00102 User user = null;
00103 String group = request.getParameter("openMISGroup");
00104 if (group == null) {
00105 LogManager.traceError(0, "OpenMSPService bad request no openMISGroup parameter.");
00106 res.setStatus(HttpServletResponse.SC_FORBIDDEN);
00107 return;
00108 }
00109
00110 try {
00111
00112 String openMSPString = request.getParameter("openMISData");
00113 try {
00114 openMSPString = new String(uncompressAndDecodeRequest(openMSPString.getBytes()));
00115 } catch (Throwable ex) {
00116
00117 LogManager.traceError(0, ex);
00118 res.setStatus(HttpServletResponse.SC_BAD_REQUEST);
00119 return;
00120 }
00121
00122
00123 Message openMLMessage = MessageFactory.getFactory().getMessage(openMSPString);
00124
00125 Header header = openMLMessage.getHeader();
00126
00127
00128 String[] credential = header.getCredential();
00129 Credential cred = null;
00130 if (credential != null) {
00131 cred = CredentialCodec.getOpenMSPCredential(credential);
00132 String userId = UserManager.getManager().authenticateUser(group, cred.getPrincipal(), cred.getPassword());
00133 user = UserManager.getManager().getUser(group,userId);
00134 } else {
00135 LogManager.traceError(0, "OpenMSPService no credential in OpenMSP request.");
00136 res.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
00137 return;
00138 }
00139 Profile profil = ProfileDataManager.getManager().getProfil(group, user.getProfil());
00140 SessionContext context = SessionContextManager.getManager().getSessionContext();
00141 String useragent = UserTerminal.getUserAgentFromRequest(request);
00142 UserTerminal terminal = new UserTerminal(useragent);
00143 context.setTerminal(terminal);
00144
00145 LogManager.traceDebug(0, "OpenMSPService user profile :"+profil.profilName);
00146
00147 if (!terminal.isOPenMISClient()) {
00148 LogManager.traceError(0, "Synchro terminal is not supported for user:"+user.getLogin());
00149 res.setStatus(HttpServletResponse.SC_UNSUPPORTED_MEDIA_TYPE);
00150 return;
00151 }
00152 context.setUserId(user.getId());
00153 context.setUserGroup(group);
00154
00155
00156 LogManager.traceUserSynchro(LogServices.SYNCHROSERVICE, request.getRemoteAddr()+"#"+user.getId()+"#"+user.getLogin()+"#"+group+"#"+terminal.getClientPlateformType()+"#"+terminal.getSynchroType());
00157
00158 long sessionNumber = header.getSessionID();
00159
00160
00161
00162
00163
00164
00165
00166 String target = header.getTarget();
00167 String source = header.getSource();
00168 if (target.indexOf(OpenMSPSyncMessageFactory.OpenMSPTARGET) == -1) {
00169 res.setStatus(HttpServletResponse.SC_BAD_REQUEST);
00170 }
00171
00172
00173 FileSystemObjectPool pool = FileSystemObjectPoolSelecter.getPool(terminal);
00174 FileSystem fileSystem = pool.getFileSystem();
00175
00176 try {
00177
00178
00179
00180 Message CMLAnswer = MessageFactory.getFactory().createMessage(new Header(sessionNumber+1, target, source , null, null));
00181
00182 openMLMessage.resetCursor();
00183
00184 while (openMLMessage.hasMoreMessage()) {
00185 ContainerMessage CMLRequest = openMLMessage.nextMessage();
00186 this.dispatchElement(cred, group, CMLRequest, CMLAnswer, terminal, profil, fileSystem);
00187 }
00188
00189
00190
00191
00192 ByteArrayInputStream input = new ByteArrayInputStream(CMLAnswer.encode().getBytes());
00193 fileSystem.addFile(new MemoryFile("/cyberML.xml", input));
00194
00195 SynchroFileGenerator fileGenerator = SynchroFileGeneratorManager.getManager().getFileGenerator(terminal);
00196 fileGenerator.generateSynchroFile(terminal, profil, request, res, fileSystem, Long.toString(sessionNumber+1));
00197
00198 res.setStatus(HttpServletResponse.SC_OK);
00199 } finally {
00200 pool.disposeObject(fileSystem);
00201 }
00202 } catch (OpenMSPException ex) {
00203 if (ex.getSyncStatus() != OpenMSPException.NO_STATUS_DEFINED) res.setStatus(ex.getSyncStatus());
00204 else res.setStatus(HttpServletResponse.SC_BAD_REQUEST);
00205 LogManager.trace(new SynchroException(ex));
00206 } catch (UserNotFoundException ex) {
00207 res.setStatus(HttpServletResponse.SC_FORBIDDEN);
00208 } catch(ProfileNotFoundException ex) {
00209 LogManager.traceError(0, "OpenMSPService no Profil for user login :"+user.getLogin());
00210 res.setStatus(HttpServletResponse.SC_FORBIDDEN);
00211 } catch (Throwable ex) {
00212 res.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
00213 LogManager.trace(new SynchroException(ex));
00214 } finally {
00215 if (user != null) {
00216 try {
00217 UserManager.getManager().logoutUser(group, user.getId());
00218 } catch (ServiceException ex) {
00219 LogManager.trace(ex);
00220
00221 }
00222 }
00223 }
00224 }
00225
00226 private final void dispatchElement(Credential cred, String group, ContainerMessage message, Message answer, UserTerminal terminal, Profile profil, FileSystem fileSystem) {
00227 Element element = message.getElement();
00228 try {
00229 if (element.getElementType() == Element.RESULT) {
00230 String serviceName = ((Result)element).getSourceRef();
00231 this.callService(cred, serviceName, message, answer, terminal, profil, fileSystem);
00232 } else if (element.getElementType() == Element.STATUS) {
00233 Status status = new Status (((Status)element).getCmdId(), Status.STATUS_COMMAND_NOT_IMPLEMENTED) ;
00234 answer.add(status);
00235 } else if ((element.getElementType() == Element.SYNC)
00236 || (element.getElementType() == Element.MAP)
00237 || (element.getElementType() == Element.GET)
00238 ){
00239 String serviceName = ((Command)element).getTarget();
00240 this.callService(cred, serviceName, message, answer, terminal, profil, fileSystem);
00241 } else if (element.getElementType() == Element.SEQUENCE) {
00242 while (message.hasMoreMessage()) {
00243 ContainerMessage commandContainer = message.nextMessage();
00244 this.dispatchElement(cred, group, commandContainer, answer, terminal, profil, fileSystem);
00245 }
00246 } else if (element.getElementType() == Element.FINAL) {
00247 } else {
00248 Status status = new Status (((RequestCommand)element).getCmdId(), Status.STATUS_WRONG_FORMAT) ;
00249 answer.add(status);
00250 }
00251 } catch (Exception ex) {
00252 try {
00253 LogManager.trace(new SynchroException(ex));
00254 Status status = new Status (((RequestCommand)element).getCmdId(), Status.STATUS_FAILED) ;
00255 answer.add(status);
00256 } catch (Exception e) {
00257 LogManager.trace(new SynchroException(e));
00258 }
00259 }
00260 }
00261
00262 private final void callService(Credential cred, String serviceName, ContainerMessage message, Message answer, UserTerminal terminal, Profile profil, FileSystem fileSystem) throws OpenMSPException {
00263 try {
00264 ProxySyncroTarget proxy = SynchroTargerManager.getManager().getProxySynchroTargetForTerminal(terminal);
00265 if (proxy != null) {
00266 proxy.executeOpenMSPCommande(cred, serviceName, message, answer, terminal, profil, fileSystem);
00267 } else {
00268 Status status = new Status (((AbstractCommand)message.getElement()).getCmdId(), Status.STATUS_NOT_FOUND) ;
00269 answer.add(status);
00270 LogManager.traceInfo(LogServices.SYNCHROSERVICE, "Service "+serviceName+" ask by CyberML commande and not available");
00271 }
00272 } catch (Throwable e) {
00273 LogManager.trace(new SynchroException(e));
00274 Status status = new Status (((AbstractCommand)message.getElement()).getCmdId(), Status.STATUS_FAILED) ;
00275 answer.add(status);
00276 }
00277 }
00278
00279 public String getServiceUri() {
00280 return ServiceManager.getManager().getServiceBaseURI()+"/openmspservice";
00281 }
00282
00283 public byte[] uncompressAndDecodeRequest(byte[] request) throws IOException {
00284
00285 byte[] decodedData = GeneralCoder.decodeBase64(request);
00286
00287
00288 ByteArrayOutputStream byteStream = new ByteArrayOutputStream(1024);
00289 ByteArrayInputStream inStream = new ByteArrayInputStream(decodedData);
00290 GZIPInputStream zipStream = new GZIPInputStream(inStream);
00291 try {
00292 byte[] buff = new byte[1024];
00293 int length;
00294 while ((length = zipStream.read(buff)) != -1) {
00295 byteStream.write(buff, 0, length);
00296 }
00297 } finally {
00298 zipStream.close();
00299 byteStream.close();
00300 }
00301 return byteStream.toByteArray();
00302 }
00303 }