Skip to main content


Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Eclipse Projects » Eclipse Scout » Custom Servlet => use SERVICES.getService(..)
Custom Servlet => use SERVICES.getService(..) [message #1441463] Thu, 09 October 2014 19:33 Go to next message
Jeremie Bresson is currently offline Jeremie BressonFriend
Messages: 1252
Registered: October 2011
Senior Member
I have added a page in the wiki providing a description of the different servlets contained in a typical scout server. There is still work to do. Contributions are welcomed (it is a wiki).

I have an example for a Custom Servlet. It is really simple. Based on this example: Returning a JSON object from a Java Servlet, it returns the list of all osgi-bundles available in the server application as JSON String.

The next question is: what if I want to have access to some Scout elements in the server.

In the miniCRM example, let say I want to call SERVICES.getService(StandardOutlineService.class).getCompanyTableData(CompanySearchFormData) in order to return the list of companies as JSON String.

I probably need to instantiate a Scout ServerJob.
How can i do it correctly? For example I will need the server session.

Is the ServiceTunnelServlet suitable? I have the feeling it does too much for this case.

Next sept in this domain: mix this servlet approach with Jax-RS.
Jax-RS is really suitable to handle a lot of REST Services (with a lot of possibilities to build the URLs).
I have sketched this approach here: Calling Scout from Mobile Device.


I hope I will be able to share some findings here.

.
Re: Custom Servlet => use SERVICES.getService(..) [message #1441471 is a reply to message #1441463] Thu, 09 October 2014 19:41 Go to previous messageGo to next message
Jeremie Bresson is currently offline Jeremie BressonFriend
Messages: 1252
Registered: October 2011
Senior Member
By digging into the Forum, I found this message from Ivan: Call Scout Service from webpage. I think it describes more or less what I am looking for (Solution B2).

When I have put a solution together I will post it here.

.
Re: Custom Servlet => use SERVICES.getService(..) [message #1441805 is a reply to message #1441471] Fri, 10 October 2014 08:00 Go to previous messageGo to next message
Dennis Geesen is currently offline Dennis GeesenFriend
Messages: 46
Registered: June 2014
Member
I have a solution for calling server services:

Most of the code was copied from the ServiceTunnelServlet.

Would be nice if someone can varify that this is a solution that does not break any important concepts?!


package de.scout.rest.test.server;

import java.io.IOException;
import java.io.PrintWriter;

import javax.security.auth.Subject;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IConfigurationElement;
import org.eclipse.core.runtime.IExtension;
import org.eclipse.core.runtime.IExtensionPoint;
import org.eclipse.core.runtime.IExtensionRegistry;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.Status;
import org.eclipse.scout.commons.exception.ProcessingException;
import org.eclipse.scout.commons.security.SimplePrincipal;
import org.eclipse.scout.rt.server.IServerSession;
import org.eclipse.scout.rt.server.ServerJob;
import org.eclipse.scout.rt.server.commons.servletfilter.HttpServletEx;
import org.eclipse.scout.rt.server.services.common.session.IServerSessionRegistryService;
import org.eclipse.scout.rt.shared.ui.UserAgent;
import org.eclipse.scout.service.SERVICES;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceReference;

import de.scout.rest.test.server.Activator;
import de.scout.rest.test.shared.ui.forms.CustomerSearchFormData;
import de.scout.rest.test.shared.ui.forms.ICustomerService;

public class TestServlet extends HttpServletEx {
  private static final long serialVersionUID = 1L;
  private Class<IServerSession> m_serverSessionClass;

  @Override
  protected void doGet(HttpServletRequest request, final HttpServletResponse response) throws ServletException, IOException {
    try {
      lazyInit(request, response);
      Subject subject = new Subject();
      subject.getPrincipals().add(new SimplePrincipal("server"));
      UserAgent agent = UserAgent.createDefault();
      if (subject != null && agent != null) {
        IServerSession session = lookupScoutServerSessionOnHttpSession(request, response, subject, agent);


        ServerJob serverJob = new ServerJob("Transactional handler", session, subject) {

          @Override
          protected IStatus runTransaction(IProgressMonitor monitor) throws Exception {
            try {

              int count = SERVICES.getService(IMyTestService.class).getCount();
              response.setContentType("application/json");
              PrintWriter out = response.getWriter();
              out.print("{");
              out.print("\"count\": ");
              out.print(count);
              out.print("}");
              out.close();
            }
            catch (ProcessingException e) {

              e.printStackTrace();
            }
            return Status.OK_STATUS;
          }
        };
        serverJob.setSystem(true);
        serverJob.runNow(new NullProgressMonitor());
      }
      else {
        throw new ServletException("could not create subject or agent!");
      }
    }
    catch (ProcessingException ex) {
      throw new ServletException(ex);
    }
  }

  private IServerSession lookupScoutServerSessionOnHttpSession(HttpServletRequest req, HttpServletResponse res, Subject subject, UserAgent userAgent) throws ProcessingException, ServletException {

    synchronized (req.getSession()) {
      IServerSession serverSession = (IServerSession) req.getSession().getAttribute(IServerSession.class.getName());
      if (serverSession == null) {
        serverSession = SERVICES.getService(IServerSessionRegistryService.class).newServerSession(m_serverSessionClass, subject, userAgent);
        req.getSession().setAttribute(IServerSession.class.getName(), serverSession);
      }
      return serverSession;
    }
  }

  @SuppressWarnings("unchecked")
  protected void lazyInit(HttpServletRequest req, HttpServletResponse res) throws ServletException {

    if (m_serverSessionClass == null) {
      String qname = getServletConfig().getInitParameter("session");
      if (qname != null) {
        int i = qname.lastIndexOf('.');
        try {
          m_serverSessionClass = (Class<IServerSession>) Platform.getBundle(qname.substring(0, i)).loadClass(qname);
        }
        catch (ClassNotFoundException e) {
          throw new ServletException("Loading class " + qname, e);
        }
      }
    }
    if (m_serverSessionClass == null) {
      // find bundle that defines this servlet
      try {
        Bundle bundle = findServletContributor(req.getServletPath());
        if (bundle != null) {
          m_serverSessionClass = (Class<IServerSession>) bundle.loadClass(bundle.getSymbolicName() + ".ServerSession");
        }
      }
      catch (Throwable t) {
        // nop
      }
    }
    if (m_serverSessionClass == null) {
      throw new ServletException("Expected init-param \"session\"");
    }
  }

  @SuppressWarnings("unchecked")
  private Bundle findServletContributor(String alias) throws CoreException {
    BundleContext context = Activator.getDefault().getBundle().getBundleContext();
    ServiceReference ref = context.getServiceReference(IExtensionRegistry.class.getName());
    Bundle bundle = null;
    if (ref != null) {
      IExtensionRegistry reg = (IExtensionRegistry) context.getService(ref);
      if (reg != null) {
        IExtensionPoint xpServlet = reg.getExtensionPoint("org.eclipse.equinox.http.registry.servlets");
        if (xpServlet != null) {
          for (IExtension xServlet : xpServlet.getExtensions()) {
            for (IConfigurationElement cServlet : xServlet.getConfigurationElements()) {
              if (cServlet.getName().equals("servlet")) {
                if (this.getClass().getName().equals(cServlet.getAttribute("class"))) {
                  // half match, go on looping
                  bundle = Platform.getBundle(xServlet.getContributor().getName());
                  if (alias.equals(cServlet.getAttribute("alias"))) {
                    // full match, return
                    return bundle;
                  }
                }
              }
            }
          }
        }
      }
    }
    return bundle;
  }
}

Re: Custom Servlet => use SERVICES.getService(..) [message #1441910 is a reply to message #1441805] Fri, 10 October 2014 10:57 Go to previous messageGo to next message
Jeremie Bresson is currently offline Jeremie BressonFriend
Messages: 1252
Registered: October 2011
Senior Member
Thanks for sharing it here. I think you have done, what I was looking for.

I will do a first review and I will also ask other Scout-commiters to do so.

For the moment all the code is in the ServiceTunnelServlet. I think we should extract the relevant code into an abstract class or a utility method, in order to be able to reuse it in following cases:
* Existing ServiceTunnelServlet
* Custom servlet using Scout services
* Your ProxyServletContainer for the Jax-RS integration.
* ... (maybe more) ...

Fell free to open a change request to track this change. I think we should work on it together. It would be a nice improvement for the scout mars release.

---------------
I got also some inputs from Florian Widmer (he is working on the integration in a scout server of existing code based on struts2 and tiles):
Quote:
The problems are always the same:
* How do I get the correct Context?
* How do the bundles get the correct classloader?


.
Re: Custom Servlet => use SERVICES.getService(..) [message #1443778 is a reply to message #1441910] Mon, 13 October 2014 07:46 Go to previous message
Dennis Geesen is currently offline Dennis GeesenFriend
Messages: 46
Registered: June 2014
Member
Jeremie Bresson wrote on Fri, 10 October 2014 12:57

I think we should work on it together. It would be a nice improvement for the scout mars release.




Yes, definitely.
I'll open a request in the next few days.

[Updated on: Mon, 13 October 2014 07:46]

Report message to a moderator

Previous Topic:Export in Excel and Download a file
Next Topic:How to set a backgroundcolor to a specific button in RAP
Goto Forum:
  


Current Time: Sat Jul 27 12:32:25 GMT 2024

Powered by FUDForum. Page generated in 0.04201 seconds
.:: Contact :: Home ::.

Powered by: FUDforum 3.0.2.
Copyright ©2001-2010 FUDforum Bulletin Board Software

Back to the top