View Javadoc

1   /*
2    * Copyright (C) 2007 ETH Zurich
3    *
4    * This file is part of Fosstrak (www.fosstrak.org).
5    *
6    * Fosstrak is free software; you can redistribute it and/or
7    * modify it under the terms of the GNU Lesser General Public
8    * License version 2.1, as published by the Free Software Foundation.
9    *
10   * Fosstrak is distributed in the hope that it will be useful,
11   * but WITHOUT ANY WARRANTY; without even the implied warranty of
12   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13   * Lesser General Public License for more details.
14   *
15   * You should have received a copy of the GNU Lesser General Public
16   * License along with Fosstrak; if not, write to the Free
17   * Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18   * Boston, MA  02110-1301  USA
19   */
20  
21  package org.fosstrak.epcis.repository.query;
22  
23  import java.io.FileInputStream;
24  import java.io.IOException;
25  import java.io.InputStream;
26  import java.util.Properties;
27  
28  import javax.naming.Context;
29  import javax.naming.InitialContext;
30  import javax.naming.NamingException;
31  import javax.servlet.ServletConfig;
32  import javax.servlet.ServletContext;
33  import javax.servlet.ServletException;
34  import javax.sql.DataSource;
35  import javax.xml.ws.Endpoint;
36  
37  import org.fosstrak.epcis.soap.EPCISServicePortType;
38  import org.apache.commons.logging.Log;
39  import org.apache.commons.logging.LogFactory;
40  import org.apache.cxf.BusFactory;
41  import org.apache.cxf.interceptor.LoggingInInterceptor;
42  import org.apache.cxf.interceptor.LoggingOutInterceptor;
43  import org.apache.cxf.transport.servlet.CXFNonSpringServlet;
44  
45  /**
46   * This HttpServlet is used to initialize the QueryOperationsModule. It will
47   * read the application's properties file from the class path, read the data
48   * source from a JNDI name, and load the CXF Web service bus in order to set up
49   * the QueryOperationsModule with the required values.
50   * <p>
51   * Note: this servlet is only required if you do not wire the application with
52   * Spring! To use this servlet, and bypass Spring, replace
53   * <code>WEB-INF/web.xml</code> with <code>WEB-INF/non-spring-web.xml</code>.
54   * 
55   * @author Marco Steybe
56   */
57  public class QueryInitServlet extends CXFNonSpringServlet {
58  
59      private static final long serialVersionUID = -5839101192038037389L;
60  
61      private static final String APP_CONFIG_LOCATION = "appConfigLocation";
62      private static final String PROP_MAX_QUERY_ROWS = "maxQueryResultRows";
63      private static final String PROP_MAX_QUERY_TIME = "maxQueryExecutionTime";
64      private static final String PROP_TRIGGER_CHECK_SEC = "trigger.condition.check.sec";
65      private static final String PROP_TRIGGER_CHECK_MIN = "trigger.condition.check.min";
66      private static final String PROP_SERVICE_VERSION = "service.version";
67      private static final String PROP_JNDI_DATASOURCE_NAME = "jndi.datasource.name";
68  
69      private static final Log LOG = LogFactory.getLog(QueryInitServlet.class);
70  
71      private Properties properties;
72  
73      /**
74       * {@inheritDoc}
75       * 
76       * @see org.apache.cxf.transport.servlet.CXFNonSpringServlet#loadBus(javax.servlet.ServletConfig)
77       */
78      public void loadBus(ServletConfig servletConfig) throws ServletException {
79          super.loadBus(servletConfig);
80          BusFactory.setDefaultBus(getBus());
81          if (LOG.isDebugEnabled()) {
82              getBus().getInInterceptors().add(new LoggingInInterceptor());
83              getBus().getOutInterceptors().add(new LoggingOutInterceptor());
84              getBus().getOutFaultInterceptors().add(new LoggingOutInterceptor());
85              getBus().getInFaultInterceptors().add(new LoggingInInterceptor());
86          }
87          EPCISServicePortType service = setupQueryOperationsModule(servletConfig);
88  
89          LOG.debug("Publishing query operations module service at /query");
90          Endpoint.publish("/query", service);
91      }
92  
93      private EPCISServicePortType setupQueryOperationsModule(ServletConfig servletConfig) {
94          loadApplicationProperties(servletConfig);
95          String jndiName = properties.getProperty(PROP_JNDI_DATASOURCE_NAME);
96          DataSource dataSource = loadDataSource(jndiName);
97  
98          LOG.debug("Initializing query operations module");
99          QueryOperationsModule module = new QueryOperationsModule();
100         module.setMaxQueryRows(Integer.parseInt(properties.getProperty(PROP_MAX_QUERY_ROWS)));
101         module.setMaxQueryTime(Integer.parseInt(properties.getProperty(PROP_MAX_QUERY_TIME)));
102         module.setTriggerConditionMinutes(properties.getProperty(PROP_TRIGGER_CHECK_MIN));
103         module.setTriggerConditionSeconds(properties.getProperty(PROP_TRIGGER_CHECK_SEC));
104         module.setServiceVersion(properties.getProperty(PROP_SERVICE_VERSION));
105         module.setDataSource(dataSource);
106         module.setServletContext(servletConfig.getServletContext());
107         module.setBackend(new QueryOperationsBackendSQL());
108 
109         LOG.debug("Initializing query operations web service");
110         QueryOperationsWebService service = new QueryOperationsWebService(module);
111         return service;
112     }
113 
114     /**
115      * Loads the application property file and populates a java.util.Properties
116      * instance.
117      * 
118      * @param servletConfig
119      *            The ServletConfig used to locate the application property
120      *            file.
121      */
122     private void loadApplicationProperties(ServletConfig servletConfig) {
123         properties = new Properties();
124 
125         // read application.properties from classpath
126         String path = "/";
127         String appConfigFile = "application.properties";
128         InputStream is = QueryInitServlet.class.getResourceAsStream(path + appConfigFile);
129 
130         try {
131             if (is == null) {
132                 // read properties from file specified in servlet context
133                 ServletContext ctx = servletConfig.getServletContext();
134                 path = ctx.getRealPath("/");
135                 appConfigFile = ctx.getInitParameter(APP_CONFIG_LOCATION);
136                 is = new FileInputStream(path + appConfigFile);
137             }
138             properties.load(is);
139             is.close();
140             LOG.info("Loaded application properties from " + path + appConfigFile);
141         } catch (IOException e) {
142             LOG.error("Unable to load application properties from " + path + appConfigFile, e);
143         }
144     }
145 
146     /**
147      * Loads the data source from the application context via JNDI.
148      * 
149      * @param jndiName
150      *            The name of the JNDI data source holding the connection to the
151      *            database.
152      * @return The application DataSource instance.
153      */
154     private DataSource loadDataSource(String jndiName) {
155         DataSource dataSource = null;
156         try {
157             Context ctx = new InitialContext();
158             dataSource = (DataSource) ctx.lookup(jndiName);
159             LOG.info("Loaded data source via JNDI from " + jndiName);
160         } catch (NamingException e) {
161             LOG.error("Unable to load data source via JNDI from " + jndiName, e);
162         }
163         return dataSource;
164     }
165 }