You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tuscany.apache.org by an...@apache.org on 2007/09/08 20:06:53 UTC
svn commit: r573887 - in /incubator/tuscany/java/sca/distribution/webapp:
pom.xml src/main/java/org/apache/tuscany/sca/webapp/WarContextListener.java
src/main/webapp/WEB-INF/web.xml
src/main/webapp/sca-contributions/sample-helloworld-ws-service.jar
Author: antelder
Date: Sat Sep 8 11:06:52 2007
New Revision: 573887
URL: http://svn.apache.org/viewvc?rev=573887&view=rev
Log:
Starting getting webapp distro to work with the new distributed node api
Added:
incubator/tuscany/java/sca/distribution/webapp/src/main/java/org/apache/tuscany/sca/webapp/WarContextListener.java (with props)
incubator/tuscany/java/sca/distribution/webapp/src/main/webapp/sca-contributions/sample-helloworld-ws-service.jar (with props)
Modified:
incubator/tuscany/java/sca/distribution/webapp/pom.xml
incubator/tuscany/java/sca/distribution/webapp/src/main/webapp/WEB-INF/web.xml
Modified: incubator/tuscany/java/sca/distribution/webapp/pom.xml
URL: http://svn.apache.org/viewvc/incubator/tuscany/java/sca/distribution/webapp/pom.xml?rev=573887&r1=573886&r2=573887&view=diff
==============================================================================
--- incubator/tuscany/java/sca/distribution/webapp/pom.xml (original)
+++ incubator/tuscany/java/sca/distribution/webapp/pom.xml Sat Sep 8 11:06:52 2007
@@ -33,6 +33,11 @@
<dependencies>
<dependency>
<groupId>${pom.groupId}</groupId>
+ <artifactId>tuscany-distributed-impl</artifactId>
+ <version>${pom.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>${pom.groupId}</groupId>
<artifactId>tuscany-assembly</artifactId>
<version>${pom.version}</version>
</dependency>
Added: incubator/tuscany/java/sca/distribution/webapp/src/main/java/org/apache/tuscany/sca/webapp/WarContextListener.java
URL: http://svn.apache.org/viewvc/incubator/tuscany/java/sca/distribution/webapp/src/main/java/org/apache/tuscany/sca/webapp/WarContextListener.java?rev=573887&view=auto
==============================================================================
--- incubator/tuscany/java/sca/distribution/webapp/src/main/java/org/apache/tuscany/sca/webapp/WarContextListener.java (added)
+++ incubator/tuscany/java/sca/distribution/webapp/src/main/java/org/apache/tuscany/sca/webapp/WarContextListener.java Sat Sep 8 11:06:52 2007
@@ -0,0 +1,300 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tuscany.sca.webapp;
+
+import java.io.File;
+import java.io.FilenameFilter;
+import java.io.IOException;
+import java.net.MalformedURLException;
+import java.net.URISyntaxException;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import javax.servlet.ServletContext;
+import javax.servlet.ServletContextEvent;
+import javax.servlet.ServletContextListener;
+
+import org.apache.tuscany.sca.assembly.builder.CompositeBuilderException;
+import org.apache.tuscany.sca.contribution.service.ContributionException;
+import org.apache.tuscany.sca.core.assembly.ActivationException;
+import org.apache.tuscany.sca.distributed.node.impl.ContributionManagerImpl;
+import org.apache.tuscany.sca.distributed.node.impl.NodeImpl;
+
+/**
+ * A ServletContextListener for the Tuscany WAR distribution.
+ *
+ * Starts and stops a Tuscany SCA domain Node for the webapp.
+ *
+ * TODO: Use Node instead of NodeImpl?
+ */
+public class WarContextListener implements ServletContextListener {
+ private final static Logger logger = Logger.getLogger(WarContextListener.class.getName());
+
+ protected NodeImpl node;
+ protected AddableURLClassLoader classLoader;
+ protected File repository;
+
+ protected boolean useHotUpdate;
+ protected long hotDeployInterval = 2000; // 2 seconds, 0 = no hot deploy
+ protected Thread hotDeployThread;
+ protected boolean stopHotDeployThread;
+
+ protected HashMap<URL, Long> existingContributions; // value is last modified time
+
+ private String domainName;
+
+ private String nodeName;
+
+ protected static final String NODE_ATTRIBUTE = WarContextListener.class.getName() + ".TuscanyNode";
+ protected static final String REPOSITORY_FOLDER_NAME = "sca-contributions";
+
+ public void contextInitialized(ServletContextEvent event) {
+ ServletContext servletContext = event.getServletContext();
+ initParameters(servletContext);
+ try {
+
+ initNode();
+
+ } catch (Throwable e) {
+ e.printStackTrace();
+ servletContext.log("exception initializing SCA node", e);
+ }
+ }
+
+ protected void initNode() throws ContributionException, ActivationException, IOException, CompositeBuilderException, URISyntaxException { logger.log(Level.INFO, "SCA node starting");
+
+ classLoader = new AddableURLClassLoader(new URL[]{}, Thread.currentThread().getContextClassLoader());
+ Thread.currentThread().setContextClassLoader(classLoader);
+ node = new NodeImpl(domainName, nodeName, classLoader);
+ node.start();
+
+ existingContributions = new HashMap<URL, Long>();
+ URL[] contributions = getContributionJarURLs(repository);
+ for (URL contribution : contributions) {
+ try {
+ addContribution(contribution);
+ } catch (Throwable e) {
+ e.printStackTrace();
+ logger.log(Level.WARNING, "Exception adding contribution: " + e);
+ }
+ }
+
+ initHotDeploy(repository);
+
+ }
+
+ public void contextDestroyed(ServletContextEvent event) {
+ if (node != null) {
+ stopNode();
+ }
+ }
+
+ protected void stopNode() {
+ try {
+
+ node.stop();
+ logger.log(Level.INFO, "SCA node stopped");
+
+ } catch (Throwable e) {
+ e.printStackTrace();
+ logger.log(Level.SEVERE, "exception stopping SCA Node", e);
+ }
+ }
+
+ protected void addContribution(URL contribution) throws CompositeBuilderException, ActivationException, URISyntaxException {
+ classLoader.addURL(contribution);
+ ((ContributionManagerImpl)node.getContributionManager()).addContributionJAR(contribution);
+ existingContributions.put(contribution, new Long(new File(contribution.toURI()).lastModified()));
+ logger.log(Level.INFO, "Added contribution", contribution);
+ }
+
+ protected URL[] getContributionJarURLs(File repositoryDir) {
+
+ String[] jars = repositoryDir.list(new FilenameFilter() {
+ public boolean accept(File dir, String name) {
+ return name.endsWith(".jar");
+ }});
+
+ List<URL> contributionJars = new ArrayList<URL>();
+ if (jars != null) {
+ for (String jar : jars) {
+ try {
+ contributionJars.add(new File(repositoryDir, jar).toURL());
+ } catch (MalformedURLException e) {
+ throw new RuntimeException(e);
+ }
+ }
+ }
+
+ return contributionJars.toArray(new URL[contributionJars.size()]);
+ }
+
+ private void initHotDeploy(final File repository) {
+
+ if (hotDeployInterval == 0) {
+ return; // hotUpdateInterval of 0 disables hotupdate
+ }
+
+ Runnable runable = new Runnable() {
+
+ public void run() {
+ logger.info("Contribution hot deploy activated");
+ while (!stopHotDeployThread) {
+ try {
+ Thread.sleep(hotDeployInterval);
+ } catch (InterruptedException e) {
+ }
+ if (!stopHotDeployThread) {
+ checkForUpdates(repository);
+ }
+ }
+ logger.info("Tuscany contribution hot deploy stopped");
+ }
+ };
+ hotDeployThread = new Thread(runable, "TuscanyHotDeploy");
+ stopHotDeployThread = false;
+ hotDeployThread.start();
+ }
+
+ protected void checkForUpdates(File repository) {
+ URL[] currentContributions = getContributionJarURLs(repository);
+
+ List<URL> addedContributions = getAddedContributions(currentContributions);
+ for (URL contribution : addedContributions) {
+ try {
+ addContribution(contribution);
+ } catch (Throwable e) {
+ e.printStackTrace();
+ logger.log(Level.WARNING, "Exception adding contribution: " + e);
+ }
+ }
+
+ if (useHotUpdate && areContributionsAltered(currentContributions)) {
+ stopNode();
+ try {
+ initNode();
+ } catch (Throwable e) {
+ e.printStackTrace();
+ logger.log(Level.SEVERE, "exception starting SCA Node", e);
+ }
+ }
+ }
+
+ protected List<URL> getAddedContributions(URL[] currentContrabutions) {
+ List<URL> urls = new ArrayList<URL>();
+ for (URL url : currentContrabutions) {
+ if (!existingContributions.containsKey(url)) {
+ urls.add(url);
+ try {
+ logger.info("added contribution: " + new File(url.toURI()).getName());
+ } catch (URISyntaxException e) {
+ throw new RuntimeException(e);
+ }
+ }
+ }
+ return urls;
+ }
+
+ protected boolean areContributionsAltered(URL[] currentContrabutions) {
+ try {
+
+ List removedContributions = getRemovedContributions(currentContrabutions);
+ List updatedContributions = getUpdatedContributions(currentContrabutions);
+
+ return (removedContributions.size() > 0 || updatedContributions.size() > 0);
+
+ } catch (URISyntaxException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ protected List<URL> getUpdatedContributions(URL[] currentContrabutions) throws URISyntaxException {
+ List<URL> urls = new ArrayList<URL>();
+ for (URL url : currentContrabutions) {
+ if (existingContributions.containsKey(url)) {
+ File curentFile = new File(url.toURI());
+ if (curentFile.lastModified() != existingContributions.get(url)) {
+ urls.add(url);
+ logger.info("updated contribution: " + curentFile.getName());
+ }
+ }
+ }
+ return urls;
+ }
+
+ protected List getRemovedContributions(URL[] currentContrabutions) throws URISyntaxException {
+ List<URL> currentUrls = Arrays.asList(currentContrabutions);
+ List<URL> urls = new ArrayList<URL>();
+ for (URL url : existingContributions.keySet()) {
+ if (!currentUrls.contains(url)) {
+ urls.add(url);
+ }
+ }
+ for (URL url : urls) {
+ logger.info("removed contributions: " + new File(url.toURI()).getName());
+ }
+ return urls;
+ }
+
+ protected void initParameters(ServletContext servletContext) {
+ if (servletContext.getInitParameter("domainName") != null) {
+ domainName = servletContext.getInitParameter("domainName");
+ } else {
+ domainName = NodeImpl.LOCAL_DOMAIN_URI;
+ }
+
+ if (servletContext.getInitParameter("nodeName") != null) {
+ nodeName = servletContext.getInitParameter("nodeName");
+ } else {
+ nodeName = NodeImpl.LOCAL_NODE_NAME;
+ }
+
+ if (servletContext.getInitParameter("hotDeployInterval") != null) {
+ hotDeployInterval = Long.parseLong(servletContext.getInitParameter("hotDeployInterval"));
+ }
+
+ useHotUpdate = Boolean.valueOf(servletContext.getInitParameter("hotUpdate")).booleanValue();
+
+ repository = new File(servletContext.getRealPath(REPOSITORY_FOLDER_NAME));
+ }
+
+}
+
+class AddableURLClassLoader extends URLClassLoader {
+
+ public AddableURLClassLoader(URL[] urls, ClassLoader parent) {
+ super(urls, parent);
+ }
+
+ /**
+ * Make URLClassLoader addURL public
+ */
+ @Override
+ public void addURL(URL url) {
+ super.addURL(url);
+ }
+
+}
Propchange: incubator/tuscany/java/sca/distribution/webapp/src/main/java/org/apache/tuscany/sca/webapp/WarContextListener.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: incubator/tuscany/java/sca/distribution/webapp/src/main/java/org/apache/tuscany/sca/webapp/WarContextListener.java
------------------------------------------------------------------------------
svn:keywords = Rev Date
Modified: incubator/tuscany/java/sca/distribution/webapp/src/main/webapp/WEB-INF/web.xml
URL: http://svn.apache.org/viewvc/incubator/tuscany/java/sca/distribution/webapp/src/main/webapp/WEB-INF/web.xml?rev=573887&r1=573886&r2=573887&view=diff
==============================================================================
--- incubator/tuscany/java/sca/distribution/webapp/src/main/webapp/WEB-INF/web.xml (original)
+++ incubator/tuscany/java/sca/distribution/webapp/src/main/webapp/WEB-INF/web.xml Sat Sep 8 11:06:52 2007
@@ -25,35 +25,34 @@
<display-name>Apache Tuscany WebApp Runtime</display-name>
<listener>
- <listener-class>org.apache.tuscany.sca.host.webapp.HotUpdateContextListener</listener-class>
+ <listener-class>org.apache.tuscany.sca.webapp.WarContextListener</listener-class>
</listener>
- <listener>
- <listener-class>org.apache.commons.fileupload.servlet.FileCleanerCleanup</listener-class>
- </listener>
-
- <servlet>
- <servlet-name>TuscanyServlet</servlet-name>
- <servlet-class>org.apache.tuscany.sca.host.webapp.TuscanyServlet</servlet-class>
- </servlet>
-
- <servlet>
- <servlet-name>ContributionUploaderServlet</servlet-name>
- <servlet-class>org.apache.tuscany.sca.webapp.ContributionUploaderServlet</servlet-class>
- </servlet>
-
- <servlet-mapping>
- <servlet-name>TuscanyServlet</servlet-name>
- <url-pattern>/sca/*</url-pattern>
- </servlet-mapping>
+ <context-param>
+ <param-name>domainName</param-name>
+ <param-value>localdomain</param-value>
+ </context-param>
+ <context-param>
+ <param-name>nodeName</param-name>
+ <param-value>localnode</param-value>
+ </context-param>
+ <context-param>
+ <param-name>hotDeployInterval</param-name>
+ <param-value>2000</param-value>
+ </context-param>
+ <context-param>
+ <param-name>hotUpdate</param-name>
+ <param-value>no</param-value>
+ </context-param>
- <servlet-mapping>
- <servlet-name>ContributionUploaderServlet</servlet-name>
- <url-pattern>/ContributionUploader</url-pattern>
- </servlet-mapping>
+ <filter>
+ <filter-name>tuscany</filter-name>
+ <filter-class>org.apache.tuscany.sca.host.webapp.TuscanyServletFilter</filter-class>
+ </filter>
- <welcome-file-list id="WelcomeFileList">
- <welcome-file>scaDomainInfo.jsp</welcome-file>
- </welcome-file-list>
+ <filter-mapping>
+ <filter-name>tuscany</filter-name>
+ <url-pattern>/*</url-pattern>
+ </filter-mapping>
</web-app>
Added: incubator/tuscany/java/sca/distribution/webapp/src/main/webapp/sca-contributions/sample-helloworld-ws-service.jar
URL: http://svn.apache.org/viewvc/incubator/tuscany/java/sca/distribution/webapp/src/main/webapp/sca-contributions/sample-helloworld-ws-service.jar?rev=573887&view=auto
==============================================================================
Binary file - no diff available.
Propchange: incubator/tuscany/java/sca/distribution/webapp/src/main/webapp/sca-contributions/sample-helloworld-ws-service.jar
------------------------------------------------------------------------------
svn:mime-type = application/octet-stream
---------------------------------------------------------------------
To unsubscribe, e-mail: tuscany-commits-unsubscribe@ws.apache.org
For additional commands, e-mail: tuscany-commits-help@ws.apache.org