PL-8550 Deploy Polymer client in single WAR (Jelastic)

This commit is contained in:
Andrey Subbotin 2017-07-07 16:06:17 +04:00
parent 755b3ec59f
commit 5cd935d2bc
9 changed files with 148 additions and 66 deletions

View File

@ -82,13 +82,14 @@ def webToolkitModule = project(':cuba-web-toolkit')
def webModule = project(':cuba-web')
def idpModule = project(':cuba-idp')
def uberJarModule = project(':cuba-uberjar')
def frontModule = project(':cuba-front')
def webModuleThemesModule = project(':cuba-web-themes')
def coreTestsModule = project(':cuba-core-tests')
def clientTestsModule = project(':cuba-client-tests')
configure([sharedLibModule, globalModule, coreModule, clientModule, guiModule,
webModule, desktopModule, portalModule, webAuthModule, restApiModule, idpModule, uberJarModule]) {
webModule, desktopModule, portalModule, webAuthModule, restApiModule, idpModule, uberJarModule, frontModule]) {
apply(plugin: 'java')
apply(plugin: 'idea')
apply(plugin: 'maven')
@ -917,6 +918,14 @@ configure(uberJarModule) {
}
}
configure(frontModule) {
dependencies {
compile(bom['org.springframework:spring-webmvc'])
compile(bom['org.springframework:spring-context-support'])
provided(bom['org.apache.tomcat:tomcat-servlet-api'])
}
}
task restart(dependsOn: ['stop', ':cuba-core:deploy', ':cuba-web:deploy', ':cuba-web-toolkit:deploy'],
description: 'Redeploys applications and restarts local Tomcat') {
doLast {

View File

@ -61,6 +61,7 @@
<context:component-scan base-package="com.haulmont.cuba">
<!-- Exclude controllers that are used in cuba-remoting-spring.xml context -->
<context:exclude-filter type="regex" expression="com\.haulmont\.cuba\.core\.controllers\..*"/>
<context:exclude-filter type="regex" expression="com\.haulmont\.cuba\.web\.sys\.AppFront*"/>
</context:component-scan>
<!-- Various beans with non-standard configuration -->

View File

@ -0,0 +1,58 @@
/*
* Copyright (c) 2008-2017 Haulmont.
*
* Licensed 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 com.haulmont.cuba.web.sys;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.ViewResolver;
import org.springframework.web.servlet.config.annotation.DefaultServletHandlerConfigurer;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer;
import org.springframework.web.servlet.view.freemarker.FreeMarkerViewResolver;
@Configuration
@EnableWebMvc
public class AppFrontConfig extends WebMvcConfigurerAdapter {
/**
* Handle static resources for a front app
*/
@Override
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
configurer.enable();
}
@Bean
public FreeMarkerConfigurer freemarkerConfig() {
FreeMarkerConfigurer freemarkerConfig = new FreeMarkerConfigurer();
freemarkerConfig.setTemplateLoaderPath("/front/");
return freemarkerConfig;
}
@Bean
public ViewResolver viewResolver() {
FreeMarkerViewResolver resolver = new FreeMarkerViewResolver("", ".ftl");
resolver.setCache(true);
resolver.setPrefix("");
return resolver;
}
@Bean
public AppFrontController appFrontController() {
return new AppFrontController();
}
}

View File

@ -0,0 +1,35 @@
/*
* Copyright (c) 2008-2017 Haulmont.
*
* Licensed 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 com.haulmont.cuba.web.sys;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
@RequestMapping(value = "index.html")
public class AppFrontController {
@RequestMapping(method = RequestMethod.GET)
public String index(Model model) {
if (System.getProperty("cuba.front.baseUrl") != null) {
model.addAttribute("cubaFrontBaseUrl", System.getProperty("cuba.front.baseUrl"));
}
if (System.getProperty("cuba.front.apiUrl") != null) {
model.addAttribute("cubaFrontApiUrl", System.getProperty("cuba.front.apiUrl"));
}
return "index";
}
}

View File

@ -14,30 +14,20 @@
* limitations under the License.
*/
package com.haulmont.cuba.web.sys.singleapp;
package com.haulmont.cuba.web.sys;
import com.haulmont.cuba.core.sys.AppContext;
import com.haulmont.cuba.core.sys.CubaXmlWebApplicationContext;
import com.haulmont.cuba.web.controllers.StaticContentController;
import org.springframework.beans.MutablePropertyValues;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.RootBeanDefinition;
import org.springframework.context.ApplicationContext;
import org.springframework.web.context.ConfigurableWebApplicationContext;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
import org.springframework.web.context.support.XmlWebApplicationContext;
import org.springframework.web.servlet.DispatcherServlet;
import org.springframework.web.servlet.handler.SimpleUrlHandlerMapping;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Properties;
import java.util.function.Supplier;
public class SingleAppFrontServlet extends DispatcherServlet {
public class AppFrontServlet extends DispatcherServlet {
/*
* The field is used to prevent double initialization of the servlet.
@ -46,11 +36,18 @@ public class SingleAppFrontServlet extends DispatcherServlet {
protected volatile boolean initialized = false;
protected String contextName;
protected Supplier<ApplicationContext> parentContextProvider;
public SingleAppFrontServlet(String contextName) {
public AppFrontServlet() {
this("", null);
}
public AppFrontServlet(String contextName, Supplier<ApplicationContext> parentContextProvider) {
super();
setContextClass(AnnotationConfigWebApplicationContext.class);
setContextConfigLocation(AppFrontConfig.class.getName());
this.contextName = contextName;
this.parentContextProvider = parentContextProvider;
}
@Override
@ -66,7 +63,10 @@ public class SingleAppFrontServlet extends DispatcherServlet {
protected WebApplicationContext initWebApplicationContext() {
WebApplicationContext wac = findWebApplicationContext();
if (wac == null) {
ApplicationContext parent = AppContext.getApplicationContext();
ApplicationContext parent = null;
if (parentContextProvider != null) {
parent = parentContextProvider.get();
}
wac = createWebApplicationContext(parent);
}
@ -83,44 +83,6 @@ public class SingleAppFrontServlet extends DispatcherServlet {
return wac;
}
@Override
protected WebApplicationContext createWebApplicationContext(ApplicationContext parent) {
if (this.logger.isDebugEnabled()) {
this.logger.debug("Servlet with name '" + getServletName() +
"' will try to create custom WebApplicationContext context of class '" +
CubaXmlWebApplicationContext.class.getName() + "'" + ", using parent context [" + parent + "]");
}
ConfigurableWebApplicationContext wac = new XmlWebApplicationContext() {
@Override
protected String[] getDefaultConfigLocations() {
return null;
}
};
wac.setEnvironment(getEnvironment());
wac.setParent(parent);
wac.setConfigLocation(getContextConfigLocation());
configureAndRefreshWebApplicationContext(wac);
initMappings((XmlWebApplicationContext) wac);
return wac;
}
protected void initMappings(XmlWebApplicationContext wac) {
BeanDefinitionRegistry beanDefinitionRegistry = (BeanDefinitionRegistry) wac.getBeanFactory();
beanDefinitionRegistry.registerBeanDefinition("staticContentController", new RootBeanDefinition(StaticContentController.class));
BeanDefinition mappingDefinition = new RootBeanDefinition(SimpleUrlHandlerMapping.class);
MutablePropertyValues propertyValues = mappingDefinition.getPropertyValues();
Properties urls = new Properties();
urls.put("/*", "staticContentController");
propertyValues.add("mappings", urls);
beanDefinitionRegistry.registerBeanDefinition("simpleUrlHandlerMapping", mappingDefinition);
}
@Override
public void init(ServletConfig config) throws ServletException {
if (!initialized) {

View File

@ -136,7 +136,7 @@ public class CubaJettyServer {
handlers.add(createAppContext(serverClassLoader, sharedClassLoader, PORTAL_PATH_IN_JAR, portalContextPath));
}
if (hasFrontApp(serverClassLoader)) {
handlers.add(createFrontAppContext(serverClassLoader));
handlers.add(createFrontAppContext(serverClassLoader, sharedClassLoader));
}
HandlerCollection handlerCollection = new HandlerCollection();
@ -162,12 +162,21 @@ public class CubaJettyServer {
}
protected WebAppContext createFrontAppContext(ClassLoader serverClassLoader) throws URISyntaxException {
URL frontContentUrl = serverClassLoader.getResource(FRONT_PATH_IN_JAR);
protected WebAppContext createFrontAppContext(ClassLoader serverClassLoader, ClassLoader sharedClassLoader) throws URISyntaxException {
ClassLoader frontClassLoader = new URLClassLoader(pathsToURLs(serverClassLoader, getAppClassesPath(FRONT_PATH_IN_JAR)), sharedClassLoader);
WebAppContext frontContext = new WebAppContext();
frontContext.setConfigurations(new Configuration[]{new WebXmlConfiguration()});
frontContext.setContextPath(frontContextPath);
frontContext.setClassLoader(serverClassLoader);
frontContext.setResourceBase(frontContentUrl.toURI().toString());
frontContext.setClassLoader(frontClassLoader);
setResourceBase(serverClassLoader, frontContext, FRONT_PATH_IN_JAR);
System.setProperty("cuba.front.baseUrl", PATH_DELIMITER.equals(frontContextPath) ? frontContextPath :
frontContextPath + PATH_DELIMITER);
System.setProperty("cuba.front.apiUrl", PATH_DELIMITER.equals(contextPath) ? "/rest/" :
contextPath + PATH_DELIMITER + "rest" + PATH_DELIMITER);
return frontContext;
}

View File

@ -18,6 +18,7 @@
package com.haulmont.cuba.web.sys.singleapp;
import com.google.common.base.Splitter;
import com.haulmont.bali.util.ReflectionHelper;
import com.haulmont.cuba.core.sys.AppContext;
import com.haulmont.cuba.core.sys.CubaClassPathXmlApplicationContext;
import com.haulmont.cuba.core.sys.SingleAppResourcePatternResolver;
@ -27,6 +28,7 @@ import com.haulmont.cuba.web.sys.CubaHttpFilter;
import com.haulmont.cuba.web.sys.WebAppContextLoader;
import com.haulmont.restapi.sys.CubaRestApiServlet;
import com.haulmont.restapi.sys.SingleAppRestApiServlet;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.core.io.support.ResourcePatternResolver;
import org.springframework.web.filter.DelegatingFilterProxy;
@ -38,6 +40,7 @@ import java.net.MalformedURLException;
import java.util.EnumSet;
import java.util.HashSet;
import java.util.Set;
import java.util.function.Supplier;
/**
* {@link AppContext} loader of the web application block packed in a WAR together with the middleware block.
@ -134,11 +137,13 @@ public class SingleAppWebContextLoader extends WebAppContextLoader {
//Do nothing
}
if (hasFrontApp) {
DispatcherServlet frontServlet = new SingleAppFrontServlet(FRONT_CONTEXT_NAME);
DispatcherServlet frontServlet;
try {
frontServlet.init(new CubaServletConfig("app_front_servlet", servletContext));
} catch (ServletException e) {
throw new RuntimeException("An error occurred while initializing app_servlet servlet", e);
Class frontServletClass = ReflectionHelper.getClass("com.haulmont.cuba.web.sys.AppFrontServlet");
frontServlet = (DispatcherServlet) ReflectionHelper.newInstance(frontServletClass,
FRONT_CONTEXT_NAME, (Supplier<ApplicationContext>) AppContext::getApplicationContext);
} catch (NoSuchMethodException e) {
throw new RuntimeException("Unable to instantiate app front servlet", e);
}
ServletRegistration.Dynamic cubaServletReg = servletContext.addServlet("app_front_servlet", frontServlet);
cubaServletReg.setLoadOnStartup(3);

View File

@ -28,7 +28,9 @@
<!-- Annotation-based beans -->
<context:component-scan base-package="com.haulmont.cuba"/>
<context:component-scan base-package="com.haulmont.cuba">
<context:exclude-filter type="regex" expression="com\.haulmont\.cuba\.web\.sys\.AppFront*"/>
</context:component-scan>
<!-- Various beans with non-standard configuration -->

View File

@ -17,7 +17,7 @@
include(':cuba-shared-lib', ':cuba-global', ':cuba-core', 'cuba-core-tests', ':cuba-client', ':cuba-client-tests',
':cuba-gui', ':cuba-web-toolkit', ':cuba-web', ':cuba-web-themes', ':cuba-desktop', ':cuba-portal',':cuba-web-auth',
':cuba-rest-api', ':cuba-idp', ':cuba-uberjar')
':cuba-rest-api', ':cuba-idp', ':cuba-uberjar', ':cuba-front')
rootProject.name = 'cuba'
project(':cuba-shared-lib').projectDir = new File(settingsDir, 'modules/shared-lib')
project(':cuba-global').projectDir = new File(settingsDir, 'modules/global')
@ -34,4 +34,5 @@ project(':cuba-web-auth').projectDir = new File(settingsDir, 'modules/web-auth')
project(':cuba-web-themes').projectDir = new File(settingsDir, 'modules/web/themes')
project(':cuba-rest-api').projectDir = new File(settingsDir, 'modules/rest-api')
project(':cuba-idp').projectDir = new File(settingsDir, 'modules/idp')
project(':cuba-uberjar').projectDir = new File(settingsDir, 'modules/uberjar')
project(':cuba-uberjar').projectDir = new File(settingsDir, 'modules/uberjar')
project(':cuba-front').projectDir = new File(settingsDir, 'modules/front')