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 }
00095
00096 SynchroFileGeneratorManager.getManager();
00097 }
00098
00099 public void run(HttpServletRequest request, HttpServletResponse res) throws ServletException, IOException {
00100
00101 User user = null;
00102 String group = request.getParameter("openMISGroup");
00103 if (group == null) {
00104 LogManager.traceError(0, "OpenMSPService bad request no openMISGroup parameter.");
00105 res.setStatus(HttpServletResponse.SC_FORBIDDEN);
00106 return;
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 Profile profil = ProfileDataManager.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 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 String version = null;
00232 this.callService(cred, serviceName, message, answer, terminal, version, profil, fileSystem);
00233 } else if (element.getElementType() == Element.STATUS) {
00234 Status status = new Status (((Status)element).getCmdId(), Status.STATUS_COMMAND_NOT_IMPLEMENTED) ;
00235 answer.add(status);
00236 } else if ((element.getElementType() == Element.SYNC)
00237 || (element.getElementType() == Element.MAP)
00238 || (element.getElementType() == Element.GET)
00239 ){
00240 String serviceName = ((Command)element).getTarget();
00241 String version = null;
00242 this.callService(cred, serviceName, message, answer, terminal, version, profil, fileSystem);
00243 } else if (element.getElementType() == Element.SEQUENCE) {
00244 while (message.hasMoreMessage()) {
00245 ContainerMessage commandContainer = message.nextMessage();
00246 this.dispatchElement(cred, group, commandContainer, answer, terminal, profil, fileSystem);
00247 }
00248 } else if (element.getElementType() == Element.FINAL) {
00249 } else {
00250 Status status = new Status (((RequestCommand)element).getCmdId(), Status.STATUS_WRONG_FORMAT) ;
00251 answer.add(status);
00252 }
00253 } catch (Exception ex) {
00254 try {
00255 LogManager.trace(new SynchroException(ex));
00256 Status status = new Status (((RequestCommand)element).getCmdId(), Status.STATUS_FAILED) ;
00257 answer.add(status);
00258 } catch (Exception e) {
00259 LogManager.trace(new SynchroException(e));
00260 }
00261 }
00262 }
00263
00264 private final void callService(Credential cred, String serviceName, ContainerMessage message, Message answer, UserTerminal terminal, String version, Profile profil, FileSystem fileSystem) throws OpenMSPException {
00265 try {
00266 ProxySyncroTarget proxy = SynchroTargerManager.getManager().getProxySynchroTargetForTerminal(terminal);
00267 if (proxy != null) {
00268 proxy.executeOpenMSPCommande(cred, serviceName, message, answer, terminal, version, profil, fileSystem);
00269 } else {
00270 Status status = new Status (((AbstractCommand)message.getElement()).getCmdId(), Status.STATUS_NOT_FOUND) ;
00271 answer.add(status);
00272 LogManager.traceInfo(LogServices.SYNCHROSERVICE, "Service "+serviceName+" ask by CyberML commande and not available");
00273 }
00274 } catch (Throwable e) {
00275 LogManager.trace(new SynchroException(e));
00276 Status status = new Status (((AbstractCommand)message.getElement()).getCmdId(), Status.STATUS_FAILED) ;
00277 answer.add(status);
00278 }
00279 }
00280
00281 public String getServiceUri() {
00282 return ServiceManager.getManager().getServiceBaseURI()+"/openmspservice";
00283 }
00284
00285 public byte[] uncompressAndDecodeRequest(byte[] request) throws IOException {
00286
00287 byte[] decodedData = GeneralCoder.decodeBase64(request);
00288
00289
00290 ByteArrayOutputStream byteStream = new ByteArrayOutputStream(1024);
00291 ByteArrayInputStream inStream = new ByteArrayInputStream(decodedData);
00292 GZIPInputStream zipStream = new GZIPInputStream(inStream);
00293 try {
00294 byte[] buff = new byte[1024];
00295 int length;
00296 while ((length = zipStream.read(buff)) != -1) {
00297 byteStream.write(buff, 0, length);
00298 }
00299 } finally {
00300 zipStream.close();
00301 byteStream.close();
00302 }
00303 return byteStream.toByteArray();
00304 }
00305 }