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