Hosting angular JS / HTML 5 web app on google app engine? - angularjs

I am looking at Hosting angular JS / HTML 5 web app on google app engine as a single page app. All my services are also on google app engine within the same project.
I have generated the basic directory structure for angularJS using yeoman generator.
Just created a directory under the /war/ folder of app engine project and placed the angular code in that.
EVERYTHING IS WORKING FINE !!!
Then Question ?
Is this the right way to place a HTML page directly in the WAR folder of an App engine ? Or should I be placing HTML files under the SRC folder of an app engine project and pull them into war during deploy time ?
Lets say million users try to access this single page web app, will such a hosting model help in scaling up ? Will app engine create more instances to serve this page.html ?
Note: I am 'NOT' using anything GWT for UI. Its just a single page app under a war folder !
Appreciate your inputs.
Srik

I believe this is entirely up to your preferences. I put my angular apps in /src/main/node and copy the output of grunt during maven package phase like so:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.4</version>
<configuration>
<archiveClasses>true</archiveClasses>
<webResources>
<!-- in order to interpolate version from pom into appengine-web.xml -->
<resource>
<directory>${basedir}/src/main/webapp/WEB-INF</directory>
<filtering>true</filtering>
<targetPath>WEB-INF</targetPath>
</resource>
<resource>
<directory>${basedir}/src/main/node/dist</directory>
<filtering>false</filtering>
<targetPath>/</targetPath>
</resource>
</webResources>
</configuration>
</plugin>
While this seems the cleanest solution for me, you may not feel the same way. It really doesn't matter how your static content gets into your war as long as it does.
There will be no instances for this. Static content (like html, js, css files) are served through Google's static content proxy, which is a content delivery network. So yes it will scale but you don't need instances for static content.

Related

running react bundle in Azure web app does not load json file

After building my react project it creates a bundle of files .js .json and index.html files.
I created a windows web app in azure.
When I deploy the bundle the page loads but none of the .json files do not load. I have seen other examples they talk webconfig changes but since this is a react project that does not apply.
I manually add a web.config in 'dist/prod' with the following to make it work.
<?xml version="1.0"?>
<configuration>
<system.webServer>
<staticContent>
<mimeMap fileExtension=".json" mimeType="application/json" />
</staticContent>
</system.webServer>
</configuration>
try it.
Note this for only static json files if your going to look dynamic content.you need add handler in config.files

Versioning with endpoint V2 on GAE

I have the live version of my app deployed with its endpoints (no problem with that).
I also want to easily be able to test other versions (e.g. staging).
With endpointV1: no problem.
With endpointV2:
Everything works fine if I deploy to the live version (at https://[PROJECT-ID].appspot.com but does not work for other versions.
After deploying to staging at https://staging-dot-[PROJECT-ID].appspot.com the deployment is successful, but when the frontend calls the backend, the request is received by the backend (I can see it in the GAE logs and trace list), but it does not make it to or though endpointV2 and responds 404 NOT FOUND:
"errors": [
{
"domain": "global",
"reason": "notFound",
"message": "\u003chtml\u003e\u003chead\u003e\n\u003cmeta http-equiv=\"content-type\" content=\"text/html;charset=utf-8\"\u003e\n\u003ctitle\u003e404 NOT_FOUND\u003c/title\u003e\n\u003c/head\u003e\n\u003cbody text=#000000 bgcolor=#ffffff\u003e\n\u003ch1\u003eError: NOT_FOUND\u003c/h1\u003e\n\u003c/body\u003e\u003c/html\u003e\n"
}
I now use the following maven plugins:
<plugin>
<groupId>com.google.cloud.tools</groupId>
<artifactId>appengine-maven-plugin</artifactId>
<version>1.3.1</version>
<configuration>
<!-- deploy configuration -->
</configuration>
</plugin>
<plugin>
<groupId>com.google.cloud.tools</groupId>
<artifactId>endpoints-framework-maven-plugin</artifactId>
<version>1.0.0</version>
</plugin>
I have adjusted the versions in appengine.xml and in the Google Cloud plugin. How can I configure endpoint to work with a specific module version instead of only the main version?
While not really an answer, I saw this:
When deploying a legacy type endpoint (V1), everything works fine, https://3-dot-xx.appspot.com/_ah/api/discovery/v1/apis will show the APIs deployed to version 3
When deploying a new type endpoint (v2), eg 2-dot-, it depends on the last V1 endpoint deployed on the version.
if it is a new version with no V1 endpoint deployed before, it works and the new endpoint is shown on 2-dot-
if there was a V1 endpoint deployed here before, it will show the old V1 apis and naturally generate a 404 when accessing, as the actually running GAE version is different
if the version was never deployed at all (eg asdf-dot-), or using the default (without the -dot- etc), it will show the default version and access it correctly.
if there never was a V1 service deployed, but a V2 service, it works fine when deploying a new V2 service
So, it seems like there is a bug that will prevent you from using stable names for testing / staging environments if you already had a V1 service running on them. It would be very helpful if someone from Google could confirm this bug and suggest an appropriate workaround before I have to do a lot of costly changes to change URLs.
The short answer for me was: do not reuse version names that were previously used with endpointV1.
E.g. I had a testing-dot-MYPROJECT.appspot.com.
I now use a different version: test-dot-MYPROJECT.appspot.com.
For the long answer, have a look at cputoaster's answer.

Angular app on Azure Web app fails with "The resource you are looking for has been removed, had its name changed, or is temporarily unavailable."

I just published an Angular app to Azure Web Apps, after confirming general operation locally. However, I now get the following error (HTTP Error 404.0 - Not Found), specifically the D:\home\site\wwwroot\bin\www file:
However, using the Kudu tools, I can see that the file is indeed there:
What could cause this error?
By default, IIS blocks serving content from certain folders, including bin. You can either a) move the www folder out of the bin directory, or b) you could add the following configuration to the web.config:
<configuration>
<system.webServer>
<security>
<requestFiltering>
<hiddenSegments>
<remove segment="bin" />
</hiddenSegments>
</requestFiltering>
</security>
</system.webServer>
</configuration>
The 404.0 Error on bin\www was a bit of a misdirection. After putting a console.log in the www file and watching output, I found out that indeed bin\www was being called properly. The problem was further in and related to the serving of static content, initially the index.html file.
I was previously using the following to serve up index.html:
var serveStatic = require('serve-static');
...
app.use(serveStatic('.', { 'index': ['index.html'] }));
For some reason, while this worked locally, this didn't work once published to Azure Web App. So I decided to use a method that had worked for others. First I moved index.html to /public, and then used express.static:
app.use(express.static(__dirname + '/public'));
It should also be noted, that the associated web.config file must also have information related to the static content, for example: How to enable static files (and less support) when hosting a nodejs app within IIS using IISNode

build configuration : Java backend (Spring + Maven) with JS project (Angular)

we would like to improve build configuration/integration of Java + JavaScript projects.
back-end : Java app, Spring framework, REST API + maven as build tool
front-end : HTML + CSS + JavaScript, (based on ng-boilerplate project template - it separates nicely all modules,services,directives,shared assets) and it's using few JavaScript tools like npm, Bower, Karma + Grunt
Workspace configuration is pretty simple - each project in separate directory :
/workspace
/JavaBackend
/JsFrontend
Problem is that developers are dealing with “Origin null is not allowed by Access-Control-Allow-Origin" messages in browsers as they run AJAX queries from front-end (from file://..../JSApp/build/index.hml) and Java App server is on localhost:8080. We could switch browser security off or modify headers to allow cross origin requests but we think it's not good way how to achieve that.
We don't want to have JS resources inside of Java project in /src/main/webapps/ as in production environment apps will be deployed on different machines and each app has it's own build server.
Do you have experience with similar project configuration ? What would you recommend to us ?
Meanwhile we will experiment with Tomcat 7 to check if it can e.g. serve external static resources (js stuff) out of context of java app
For development purposes, I would let Tomcat include the front-end folder in the server.xml by means of a <Context> tag. The folder can be arbitrary and even in another repository (e.g. /GitRepos/ApplicationGui/app).
...
<Host appBase="webapps" autoDeploy="true" name="localhost" unpackWARs="true">
<Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs" pattern="%h %l %u %t "%r" %s %b" prefix="localhost_access_log." suffix=".txt"/>
<Context docBase="/workspace/JsFrontend" path="/"/>
<Context docBase="FlexibleOrders" path="/FlexibleOrders" reloadable="true" source="org.eclipse.jst.j2ee.server:FlexibleOrders"/>
</Host>
</Engine>
</Service>
</Server>
In production, I would recommend to make a Maven artefact out of the front-end. It can be then included via dependency in the backend like this:
<dependency>
<groupId>org.enterprise</groupId>
<artifactId>application-gui</artifactId>
<version>1.0.0-SNAPSHOT</version>
</dependency>
See this blog for a complete configuration for production:
http://wiki.switajski.de/2016/01/24/how-to-create-maven-artifact-with-static-web-resources.html

Can DropWizard serve assets from outside the jar file?

In looking at the documentation, it appears that DropWizard is only able to serve static content living in src/main/resources. I'd like to keep my static files in a separate directory outside the jar file. Is that possible? Or do most people use nginx/Apache for their static content?
yes, it can, using this plugin - https://github.com/bazaarvoice/dropwizard-configurable-assets-bundle
Working off of Marcello Nuccio's answer, it still took me the better part of my day to get it right, so here is what I did in a bit more detail.
Let's say I have this directory structure:
my-dropwizard-server.jar
staticdocs
assets
image.png
Then this is what you have to do to make it work:
1) In your dropwizard Application class, add a new AssetsBundle. If you want your assets to be served from a different URL, change the second parameter.
#Override
public void initialize(Bootstrap<AppConfiguration> bootstrap) {
bootstrap.addBundle(new AssetsBundle("/assets/", "/assets/"));
}
2) Add the document root to your classpath by configuring the maven-jar-plugin like this. (Getting the "./staticdocs/" in the correct form took me a while. Classpaths are unforgiving.)
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.4</version>
<configuration>
<archive>
<manifest>
<addDefaultImplementationEntries>true</addDefaultImplementationEntries>
<addClasspath>true</addClasspath>
</manifest>
<manifestEntries>
<Class-Path>./staticdocs/</Class-Path>
</manifestEntries>
</archive>
</configuration>
</plugin>
3) This step is entirely optional. If you want to serve your Jersey REST Resources from a different root path (e.g. "app"), add the following to your configuration YML:
server:
rootPath: /app/*
Now you can access your static content like this, for example:
localhost:8080/assets/image.png
The user manual says:
use an extended AssetsBundle constructor to serve resources in the assets folder from the root path.
i.e. the files are loaded as resources from the classpath. Then you only need to properly set the classpath for the service.
With the default configuration, this means that you need to call the document root assets, and put the parent folder of the document root in the classpath. Then, for example, assets/foo.html will be available at
http://localhost:8080/assets/foo.html
There is a upto-date dropwizard-configurable-assets-bundle maintained at official dropwizard-bundles. You can find it at github https://github.com/dropwizard-bundles/dropwizard-configurable-assets-bundle. Current version supports dropwizard 0.9.2
This can be used to serve static files from arbitrary file system path.
The vast majority of websites that serve static content do so through a dedicated webserver, or, at larger scale, a CDN.
Occasionally, you might want to deploy an application as a self-contained unit complete with all assets which is where Dropwizard comes in.
It is possible to get Dropwizard to serve up assets from outside the classpath, but the easiest way to do this is to write your own asset endpoint that reads from an externally configured file path.
To complement craddack's answer: Correct, you can use the regular AssetsBundle as long as you add the assets to your classpath.
If you use gradle and oneJar, you can add a directory to the classpath in the oneJar task:
task oneJar(type: OneJar) {
mainClass = '...'
additionalDir = file('...')
manifest {
attributes 'Class-Path': '.. here goes the directory ..'
}
}
see https://github.com/rholder/gradle-one-jar

Resources