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.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 }
00095 }
00096
00097 public void run(HttpServletRequest request, HttpServletResponse res) throws ServletException, IOException {
00098
00099 User user = null;
00100 String group = request.getParameter("openMISGroup");
00101 if (group == null) {
00102 LogManager.traceError(0, "OpenMSPService bad request no openMISGroup parameter.");
00103 res.setStatus(HttpServletResponse.SC_FORBIDDEN);
00104 return;
00105 }
00106
00107
00108
00109 try {
00110
00111 String openMSPString = request.getParameter("openMISData");
00112 try {
00113 openMSPString = new String(uncompressAndDecodeRequest(openMSPString.getBytes()));
00114 } catch (Throwable ex) {
00115
00116 LogManager.traceError(0, ex);
00117 res.setStatus(HttpServletResponse.SC_BAD_REQUEST);
00118 return;
00119 }
00120
00121
00122 Message openMLMessage = MessageFactory.getFactory().getMessage(openMSPString);
00123
00124 Header header = openMLMessage.getHeader();
00125
00126
00127 String[] credential = header.getCredential();
00128 Credential cred = null;
00129 if (credential != null) {
00130 cred = CredentialCodec.getOpenMSPCredential(credential);
00131 String userId = UserManager.getManager().authenticateUser(group, cred.getPrincipal(), cred.getPassword());
00132 user = UserManager.getManager().getUser(group,userId);
00133 } else {
00134 LogManager.traceError(0, "OpenMSPService no credential in OpenMSP request.");
00135 res.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
00136 return;
00137 }
00138 Profil profil = ProfilDataManager.getManager().getProfil(group, user.getProfil());
00139 SessionContext context = SessionContextManager.getManager().getSessionContext();
00140 UserTerminal terminal = (UserTerminal)context.getTerminal();
00141 if (terminal == null) {
00142 String useragent = UserTerminal.getUserAgentFromRequest(request);
00143 terminal = new UserTerminal(useragent);
00144 context.setTerminal(terminal);
00145 }
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()+"#"+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 res.setStatus(HttpServletResponse.SC_BAD_REQUEST);
00204 LogManager.trace(new SynchroException(ex));
00205 } catch (UserNotFoundException ex) {
00206 res.setStatus(HttpServletResponse.SC_FORBIDDEN);
00207 } catch(ProfilNotFoundException ex) {
00208 LogManager.traceError(0, "OpenMSPService no Profil for user login :"+user.getLogin());
00209 res.setStatus(HttpServletResponse.SC_FORBIDDEN);
00210 } catch (Throwable ex) {
00211 res.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
00212 LogManager.trace(new SynchroException(ex));
00213 }
00214 }
00215
00216 private final void dispatchElement(Credential cred, String group, ContainerMessage message, Message answer, UserTerminal terminal, Profil profil, FileSystem fileSystem) {
00217 Element element = message.getElement();
00218 try {
00219 if (element.getElementType() == Element.RESULT) {
00220 String serviceName = ((Result)element).getSourceRef();
00221 String version = null;
00222 this.callService(cred, serviceName, message, answer, terminal, version, profil, fileSystem);
00223 } else if (element.getElementType() == Element.STATUS) {
00224 Status status = new Status (((Status)element).getCmdId(), Status.STATUS_COMMAND_NOT_IMPLEMENTED) ;
00225 answer.add(status);
00226 } else if ((element.getElementType() == Element.SYNC)
00227 || (element.getElementType() == Element.MAP)
00228 ){
00229 String serviceName = ((Command)element).getTarget();
00230 String version = null;
00231 this.callService(cred, serviceName, message, answer, terminal, version, profil, fileSystem);
00232 } else if (element.getElementType() == Element.SEQUENCE) {
00233 while (message.hasMoreMessage()) {
00234 ContainerMessage commandContainer = message.nextMessage();
00235 this.dispatchElement(cred, group, commandContainer, answer, terminal, profil, fileSystem);
00236 }
00237 } else if (element.getElementType() == Element.FINAL) {
00238 } else {
00239 Status status = new Status (((RequestCommand)element).getCmdId(), Status.STATUS_WRONG_FORMAT) ;
00240 answer.add(status);
00241 }
00242 } catch (Exception ex) {
00243 try {
00244 LogManager.trace(new SynchroException(ex));
00245 Status status = new Status (((RequestCommand)element).getCmdId(), Status.STATUS_FAILED) ;
00246 answer.add(status);
00247 } catch (Exception e) {
00248 LogManager.trace(new SynchroException(e));
00249 }
00250 }
00251 }
00252
00253 private final void callService(Credential cred, String serviceName, ContainerMessage message, Message answer, UserTerminal terminal, String version, Profil profil, FileSystem fileSystem) throws OpenMSPException {
00254 try {
00255 ProxySyncroTarget proxy = SynchroTargerManager.getManager().getProxySynchroTargetForTerminal(terminal);
00256 if (proxy != null) {
00257 proxy.executeOpenMSPCommande(cred, serviceName, message, answer, terminal, version, profil, fileSystem);
00258 } else {
00259 Status status = new Status (((AbstractCommand)message.getElement()).getCmdId(), Status.STATUS_NOT_FOUND) ;
00260 answer.add(status);
00261 LogManager.traceInfo(LogServices.SYNCHROSERVICE, "Service "+serviceName+" ask by CyberML commande and not available");
00262 }
00263 } catch (Throwable e) {
00264 LogManager.trace(new SynchroException(e));
00265 Status status = new Status (((AbstractCommand)message.getElement()).getCmdId(), Status.STATUS_FAILED) ;
00266 answer.add(status);
00267 }
00268 }
00269
00270 public String getServiceUri() {
00271 return ServiceManager.getManager().getServiceBaseURI()+"/openmspservice";
00272 }
00273
00274 public byte[] uncompressAndDecodeRequest(byte[] request) throws IOException {
00275
00276 byte[] decodedData = GeneralCoder.decodeBase64(request);
00277
00278
00279 ByteArrayOutputStream byteStream = new ByteArrayOutputStream(1024);
00280 ByteArrayInputStream inStream = new ByteArrayInputStream(decodedData);
00281 GZIPInputStream zipStream = new GZIPInputStream(inStream);
00282 try {
00283 byte[] buff = new byte[1024];
00284 int length;
00285 while ((length = zipStream.read(buff)) != -1) {
00286 byteStream.write(buff, 0, length);
00287 }
00288 } finally {
00289 zipStream.close();
00290 byteStream.close();
00291 }
00292 return byteStream.toByteArray();
00293 }
00294 }