Google App Engine different web.xml config per environment? - google-app-engine

I'm developing a Java app to be deployed on Google App Engine. Google App Engine allows me to include a web.xml file in my WEB-INF folder in which I can configure different levels of auth for different URLs.
If I want only admin users to be able to access the foobar URL, I can use this config:
<security-constraint>
<web-resource-collection>
<web-resource-name>aname</web-resource-name>
<url-pattern>/foobar/*</url-pattern>
</web-resource-collection>
<user-data-constraint>
<transport-guarantee>CONFIDENTIAL</transport-guarantee>
</user-data-constraint>
</security-constraint>
If I want any users - even unauthenticated users - to be able to access the foobar URL, I can use this config:
<security-constraint>
<user-data-constraint>
<transport-guarantee>CONFIDENTIAL</transport-guarantee>
</user-data-constraint>
</security-constraint>
Here's the problem. In my test environment, I would like to authorize only admins to access foobar. But in my production environment, I would like to allow all users (included unauthenticated users) to access foobar. How can I achieve this? How can I change the web.xml config per environment?

You can keep different web.xml for each environments and replace while deploying into each environment.
E.g web_dev.xml, web_test.xml, web_prod.xml
Replace web_prod.xml to web.xml

I decided to implement a solution similar to what Vikram suggested, but slightly different.
Rather than having a single web.xml file in my WEB-INF folder:
- WEB-INF
+ web.xml
I instead created two folders (one for each environment) in my WEB-INF folder:
- WEB-INF
+ local
| + web.xml
+ prod
+ web.xml
Now, in order for Google App Engine to pick up the config file, it needs to be located in WEB-INF, not in the subdirectories I've created. Therefore, during the build, I use the Maven War Plugin to copy the files from one of the two folders into the parent folder.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.4</version>
<configuration>
<webResources>
<resource>
<directory>${basedir}/src/main/webapp/WEB-INF/${configDirectory}</directory>
<filtering>false</filtering>
<targetPath>WEB-INF</targetPath>
<includes>
<include>web.xml</include>
</includes>
</resource>
</webResources>
</configuration>
</plugin>
And I use Maven Profiles to specify the name of the folder containing the files which I want to actually use.
<profiles>
<profile>
<id>local</id>
<properties>
<configDirectory>local</configDirectory>
</properties>
</profile>
<profile>
<id>prod</id>
<properties>
<configDirectory>prod</configDirectory>
</properties>
</profile>
</profiles>
So, the web.xml file gets copied from the correct subdirectory to the parent directory, thereby allowing me to control which config gets used each time I build the app.

Related

queue.yaml not deployed when i use mvn appengine:deploy

I updated my pom.xml to use the new mvn appengine plugin
<plugin>
<groupId>com.google.cloud.tools</groupId>
<artifactId>appengine-maven-plugin</artifactId>
<version>1.2.0</version>
<configuration>
<project>{project_id}</project>
<devserver.host>0.0.0.0</devserver.host>
<devserver.port>1984</devserver.port>
</configuration>
</plugin>
Now when I run mvn appengine:deploy it converts my queue.xml to queue.yaml in the staging directory. However this queue configuration is not deployed.
I have tried so many ways to deploy it to google cloud but nothing worked. This setup is for my cloud endpoints project setup. The documentations do not cover this.
This is the maven plugin code i added after trying your suggestion out .
<plugin>
<groupId>com.google.cloud.tools</groupId>
<artifactId>appengine-maven-plugin</artifactId>
<version>1.2.0</version>
<configuration>
<project>{project_id}</project>
<devserver.host>0.0.0.0</devserver.host>
<devserver.port>1984</devserver.port>
</configuration>
</plugin>
I opened a similar issue on the project board
By default, only the app.yaml file is deployed (which represents the application).
If you want (in addition, or only) the queue.yaml, or even the cron or index, you need to specify those files inside the plugin configuration.
<plugin>
<groupId>com.google.cloud.tools</groupId>
<artifactId>appengine-maven-plugin</artifactId>
<version>${appengine.maven.plugin.version}</version>
<configuration>
<deployables>
<param>target/appengine-staging/app.yaml</param>
<param>target/appengine-staging/cron.yaml</param>
<param>target/appengine-staging/queue.yaml</param>
<param>target/appengine-staging/index.yaml</param>
</deployables>
</configuration>
</plugin>
Please remember that if you specificy certain files, the app.yaml files should be added as well. It is deployed by default only if the deployabels parameter is missing.
Playing with this parameter you can choose which files to deploy

How to set version when deploying gae java?

Since Intellij Idea IDE gae deployment plugin does not work, I have to use mvn appengine:update. It always deploy to version 1, ignoring version in appengine-web.xml.
How to set version with mvn appengine:update deployment?
Another way is, don't add anything on the app engine plugin as it is hard to changes each time the pom.xml better pass the version information from the command line, like this
mvn clean package appengine:deploy -Dapp.deploy.version=your-version-here
reference document here
You can set it via a Maven property:
<properties>
<appengine.appId>my-application-id</appengine.appId>
<appengine.version>my-application-version</appengine.version>
</properties>
PS: I'm also setting the applicationId here, you don't necessarily need that.
Add the following into the plugins section in the project pom.xml file:
<plugin>
<groupId>com.google.cloud.tools</groupId>
<artifactId>appengine-maven-plugin</artifactId>
<version>2.2.0</version>
<configuration>
<deploy.projectId>java</deploy.projectId>
<deploy.version>1</deploy.version>
</configuration>
</plugin>
Set the version in plugin property
<plugin>
<groupId>com.google.cloud.tools</groupId>
<artifactId>appengine-maven-plugin</artifactId>
<version>1.3.2</version>
<configuration>
<version>2</version>
</configuration>
</plugin>

Deploying CXF webservices in Tomcat

I am trying to deploy a web service in Tomcat7 using maven.
Below I provide some configuration info:
web.xml
...
<servlet-mapping>
<servlet-name>CXFServlet</servlet-name>
<url-pattern>/services/*</url-pattern>
</servlet-mapping>
...
pom.xml
...
<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>tomcat-maven-plugin</artifactId>
<version>1.1</version>
<configuration>
<url>http://localhost:8080/manager/text</url>
<server>TomcatServer</server>
<path>/services/userinfo</path>
...
Given the <url-pattern>/services/*</url-pattern> and <path>/services/userinfo</path> configuration, the URL http://localhost:8080/services/userinfo shows 404.
If using instead <url-pattern>/*</url-pattern> everything works as expected (i.e. http://localhost:8080/services/userinfo shows the list of available methods).
The question:
Why /services/* doesn't work in my case?
The path in your tomcat-maven-plugin configuration
<path>/services/userinfo</path>
defines where you are deploying the webapp (the context root). In this case, you are deploying it to
http://localhost:8080/services/userinfo
Check out the webapps directory in your Tomcat installation.
Since you are defining the CXFServlet mapping as /services/*, the CXF service list would show at
http://localhost:8080/services/userinfo/services/
When you re-defined the mapping to /*, it just appeared to work as expected, but that was only because the context root you used and the service listing path you expected were the same.

Trying to Programmatically Expire the HTTP Response Headers

Our Team is building a C# project with a Silverlight module. We deploy to a Windows 2008 with IIS 7. I’m trying to Programmatically Expire the HTTP Response Headers Associated with a Folder called ClientBin immediately. I know how to do it manually through IIS Manager. ( Basically, I go to the HTTP Response Headers Section of the folder or file that is of interest, and then I use "Set Common Headers...." to expire immediately.) However, we will be Redeploying to IIS a number of times, and I want to ensure that it is programmatically done because it’s a headache to keep Reconfiguring all the time.
Should I do it from the C# code of my project or is it better practice to do it using WMI scripting?
#kev and #jeff-cuscutis have provided the ways to configure expiration of the HTTP Response Headers using XML configuration in the web.config file of a ASP.NET application
How to configure static content cache per folder and extension in IIS7?
ou can set specific cache-headers for a whole folder in either your root web.config:
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<!-- Note the use of the 'location' tag to specify which
folder this applies to-->
<location path="images">
<system.webServer>
<staticContent>
<clientCache cacheControlMode="UseMaxAge" cacheControlMaxAge="00:00:15" />
</staticContent>
</system.webServer>
</location>
</configuration>
Or you can specify these in a web.config file in the content folder:
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<system.webServer>
<staticContent>
<clientCache cacheControlMode="UseMaxAge" cacheControlMaxAge="00:00:15" />
</staticContent>
</system.webServer>
</configuration>
I'm not aware of a built in mechanism to target specific file types.
You can do it on a per file basis. Use the path attribute to include the filename
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<location path="YourFileNameHere.xml">
<system.webServer>
<staticContent>
<clientCache cacheControlMode="DisableCache" />
</staticContent>
</system.webServer>
</location>
</configuration>

Maven command: mvn tomcat:run

When using mvn tomcat:run, Maven downloads the Tomcat bundles into the target directory and the plugin starts this Tomcat instance with the web project. This Tomcat instance is not visible in Eclipse's server view.
But I have a local Tomcat 6 installed, can I configure the Tomcat Plugin in a way that it uses this local Tommcat instance (under CATALINA_HOME) instead of installing a new version into the target project?
This is by design. The official doc for tomcat:run says:
When developping a war project, you usually build your war and deploy it to an installed Tomcat instance. This is time and resources consuming and take time to install locally the instance.
The run mojo give you the opportunity to save that by simply running your war inside an embeded Tomcat instance in your Maven build.
So I have to start the installed Tomcat instance in the server view and then the maven plugin is using this server instance for goals other then tomcat:run.
1)upgrade your Tomcat to Tomcat 7,
2)Configure your Tomcat users.xml to include a set of credentials :
<tomcat-users>
<role rolename="manager-gui"/>
<role rolename="manager-script"/>
<role rolename="manager-jmx"/>
<role rolename="manager-status"/>
<role rolename="manager"/>
<role rolename="admin-gui"/>
<role rolename="admin-script"/>
<role rolename="admin"/>
<role rolename="manager-gui"/>
<role rolename="manager-script"/>
<user password="password" roles="manager-gui, manager-script, manager-jmx, manager-status, manager, admin-gui, admin-script, admin" username="admin"/>
</tomcat-users>
Your Maven .settings.xml:
<server>
<id>local_tomcat</id>
<username>admin</username>
<password>password</password>
</server>
Create a new 'dev' profile with new Tomcat plugin:
<profile>
<id>dev</id>
<build>
<finalName>tjb</finalName>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat-maven-plugin</artifactId>
<version>2.0-beta-1</version>
<configuration>
<url>http://localhost:8080/manager/text</url>
<server>local_tomcat</server>
<path>/</path>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.1.1</version>
</plugin>
</plugins>
</pluginManagement>
</build>
</profile>

Resources