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
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 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 res.setStatus(HttpServletResponse.SC_BAD_REQUEST);
00204 LogManager.trace(new SynchroException(ex));
00205 } catch (UserNotFoundException ex) {
00206 res.setStatus(HttpServletResponse.SC_FORBIDDEN);
00207 } catch(ProfileNotFoundException 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, Profile 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 || (element.getElementType() == Element.GET)
00229 ){
00230 String serviceName = ((Command)element).getTarget();
00231 String version = null;
00232 this.callService(cred, serviceName, message, answer, terminal, version, profil, fileSystem);
00233 } else if (element.getElementType() == Element.SEQUENCE) {
00234 while (message.hasMoreMessage()) {
00235 ContainerMessage commandContainer = message.nextMessage();
00236 this.dispatchElement(cred, group, commandContainer, answer, terminal, profil, fileSystem);
00237 }
00238 } else if (element.getElementType() == Element.FINAL) {
00239 } else {
00240 Status status = new Status (((RequestCommand)element).getCmdId(), Status.STATUS_WRONG_FORMAT) ;
00241 answer.add(status);
00242 }
00243 } catch (Exception ex) {
00244 try {
00245 LogManager.trace(new SynchroException(ex));
00246 Status status = new Status (((RequestCommand)element).getCmdId(), Status.STATUS_FAILED) ;
00247 answer.add(status);
00248 } catch (Exception e) {
00249 LogManager.trace(new SynchroException(e));
00250 }
00251 }
00252 }
00253
00254 private final void callService(Credential cred, String serviceName, ContainerMessage message, Message answer, UserTerminal terminal, String version, Profile profil, FileSystem fileSystem) throws OpenMSPException {
00255 try {
00256 ProxySyncroTarget proxy = SynchroTargerManager.getManager().getProxySynchroTargetForTerminal(terminal);
00257 if (proxy != null) {
00258 proxy.executeOpenMSPCommande(cred, serviceName, message, answer, terminal, version, profil, fileSystem);
00259 } else {
00260 Status status = new Status (((AbstractCommand)message.getElement()).getCmdId(), Status.STATUS_NOT_FOUND) ;
00261 answer.add(status);
00262 LogManager.traceInfo(LogServices.SYNCHROSERVICE, "Service "+serviceName+" ask by CyberML commande and not available");
00263 }
00264 } catch (Throwable e) {
00265 LogManager.trace(new SynchroException(e));
00266 Status status = new Status (((AbstractCommand)message.getElement()).getCmdId(), Status.STATUS_FAILED) ;
00267 answer.add(status);
00268 }
00269 }
00270
00271 public String getServiceUri() {
00272 return ServiceManager.getManager().getServiceBaseURI()+"/openmspservice";
00273 }
00274
00275 public byte[] uncompressAndDecodeRequest(byte[] request) throws IOException {
00276
00277 byte[] decodedData = GeneralCoder.decodeBase64(request);
00278
00279
00280 ByteArrayOutputStream byteStream = new ByteArrayOutputStream(1024);
00281 ByteArrayInputStream inStream = new ByteArrayInputStream(decodedData);
00282 GZIPInputStream zipStream = new GZIPInputStream(inStream);
00283 try {
00284 byte[] buff = new byte[1024];
00285 int length;
00286 while ((length = zipStream.read(buff)) != -1) {
00287 byteStream.write(buff, 0, length);
00288 }
00289 } finally {
00290 zipStream.close();
00291 byteStream.close();
00292 }
00293 return byteStream.toByteArray();
00294 }
00295 }