Separating jhipster back-end and front-end into two projects? - java

I'm trying jhipster with token-based authentication. It works perfectly.
Now, I want to run back-end and front-end code on different domains. How can I do this?
This is what I tried:
Run yo jhipster and select token-based authentication option:
Welcome to the JHipster Generator
? (1/13) What is the base name of your application? jhipster
? (2/13) What is your default Java package name? com.mycompany.myapp
? (3/13) Do you want to use Java 8? Yes (use Java 8)
? (4/13) Which *type* of authentication would you like to use? Token-based authentication (stateless, with a token)
? (5/13) Which *type* of database would you like to use? SQL (H2, MySQL, PostgreSQL)
? (6/13) Which *production* database would you like to use? MySQL
? (7/13) Which *development* database would you like to use? H2 in-memory with Web console
? (8/13) Do you want to use Hibernate 2nd level cache? Yes, with ehcache (local cache, for a single node)
? (9/13) Do you want to use clustered HTTP sessions? No
? (10/13) Do you want to use WebSockets? No
? (11/13) Would you like to use Maven or Gradle for building the backend? Maven (recommended)
? (12/13) Would you like to use Grunt or Gulp.js for building the frontend? Grunt (recommended)
? (13/13) Would you like to use the Compass CSS Authoring Framework? No
...
I'm all done. Running bower install & npm install for you
^C
Make two copies of the project as jhipster/backend and jhipster/frontend
Delete unnecessary files from back-end and front-end
rm -rf backend/.bowerrc
rm -rf backend/.jshintrc
rm -rf backend/bower.json
rm -rf backend/Gruntfile.js
rm -rf backend/package.json
rm -rf backend/src/main/webapp
rm -rf backend/src/test/javascript
rm -rf frontend/pom.xml
rm -rf frontend/src/main/java
rm -rf frontend/src/main/resources
rm -rf frontend/src/test/gatling
rm -rf frontend/src/test/java
rm -rf frontend/src/test/resources
Make changes in code to completely remove backend/frontend dependency
frontend/Gruntfile.js
...
var parseVersionFromPomXml = function() {
return '1.2.2.RELEASE';
};
...
browserSync: { ..., proxy: "localhost:8081" }
frontend/src/main/webapp/scripts/app/app.js
angular.module('jhipsterApp', [...])
.constant('API_URL', 'http://localhost:8080/')
.run( ... )
frontend/src/main/webapp/scripts/**/*.service.js
angular.module('jhipsterApp').factory(..., API_URL) {
return $http.post(API_URL + 'api/authenticate', ...);
}
angular.module('jhipsterApp').factory('Account', function Account($resource, API_URL) {
return $resource(API_URL + 'api/account', {}, {...});
}
// Make similar changes in all service files.
backend/pom.xml
Remove yeoman-maven-plugin
backend/src/main/java/com/mycompany/myapp/SimpleCORSFilter.java
// Copied from here: https://spring.io/guides/gs/rest-service-cors/
#Component
public class SimpleCORSFilter implements Filter {
public void doFilter(...) {
...
response.setHeader("Access-Control-Allow-Origin", "*");
...
}
}
Run
Terminal Tab #1: BACKEND
cd backend
mvn spring-boot:run
...
[INFO] com.mycompany.myapp.Application - Started Application in 11.529 seconds (JVM running for 12.079)
[INFO] com.mycompany.myapp.Application - Access URLs:
----------------------------------------------------------
Local: http://127.0.0.1:8080
External: http://192.168.56.1:8080
----------------------------------------------------------
Terminal Tab #2: FRONTEND
cd frontend/src/main/webapp
npm install -g http-server
http-server
Starting up http-server, serving ./ on: http://0.0.0.0:8081
Hit CTRL-C to stop the server
Terminal Tab #3: GRUNT
cd frontend
bower install
npm install
grunt serve
...
[BS] Proxying: http://localhost:8081
[BS] Access URLs:
-------------------------------------
Local: http://localhost:3000
External: http://10.34.16.128:3000
-------------------------------------
UI: http://localhost:3001
UI External: http://10.34.16.128:3001
-------------------------------------
Browse http://localhost:3000/#/login
Enter username:password as admin:admin
Our BACKEND tab reads:
[DEBUG] com.mycompany.myapp.security.Http401UnauthorizedEntryPoint - Pre-authenticated entry point called. Rejecting access
Apparently, I'm doing something wrong. What is it?

When requests fail due to CORS, there is no visible error on the backend. The HTTP request actually succeeds, but is blocked on the front-end side by javascript. A message like this one will appear in the JS console.
XMLHttpRequest cannot load http://localhost:8080/api/authenticate. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:9000' is therefore not allowed access.
The error message you're seeing is actually related to authentication. When you enable CORS, your JS will send ''pre-flight'' requests using the HTTP OPTIONS method. JHipster isn't configured to allow the OPTIONS method globally. I ran into this exact same problem myself while doing the same thing you did. The fix is very simple: just add this line to your com.mycompany.config.SecurityConfiguration immediately preceding (before) the first antMatchers entry.
.antMatchers(org.springframework.http.HttpMethod.OPTIONS, "/api/**").permitAll()
This will explicitly allow all requests with the OPTIONS method. The OPTIONS method is used in CORS as a way to read all of the headers and see what HTTP methods are allowed in the CORS request.
Finally, in your SimpleCORSFilter class, you should also add these headers:
response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE");
response.setHeader("Access-Control-Max-Age", "86400"); // 24 Hours
response.setHeader("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept, x-auth-token");

Separating frontend and backend in JHipster application is quite simple. Please follow the steps mentioned below if you want to setup frontend and backend applications separately and individually using JHipster:
Create two directories for frontend and backend applications
mkdir frontend
mkdir backend
change your directory to frontend and run the JHipster command to create just frontend module
cd frontend
jhipster --skip-server --db=sql --auth=jwt
if all works fine, run npm start command to run your frontend application.
I'm using mysql for db and JWT for auth and if you want to use websockets you add: "--websocket=spring-websocket"
Now, change your directory to the backend and run JHipster command to create just backend module
cd .. //as we are ing backend directory currently
cd backend
jhipster --skip-client
Run your backend application as you run your spring boot application
Now, your frontend and backend application are running separately and individually and frontend is coordinating with the backend application via REST API calls.

In addition to xeorem's answer above, I also had to modify the parse-links-service.js to handle the preflight OPTIONS responses, which don't have the "link" response header:
var links = {};
if (!angular.isObject()) {
// CORS OPTIONS responses
return links;
}
if (header.length == 0) {
throw new Error("input must not be of zero length");
}
// Split parts by comma
var parts = header.split(',');
...
Instead of adding API_URL to app.js, modify Gruntfile.js and add the API_URL to the ngConstants block for both DEV and PROD environments.

You can use CORS filter from Tomcat. Put Tomcat dependency in the pom.xml:
<dependency>
<groupId>org.apache.tomcat</groupId>
<artifactId>tomcat-catalina</artifactId>
<version>8.0.15</version>
<scope>provided</scope>
</dependency>
Use whatever version of Tomcat you use.
Add CORS filter initialization in WebConfigurer:
private void initCorsFilter(ServletContext servletContext, EnumSet<DispatcherType> disps) {
log.debug("Registering CORS Filter");
FilterRegistration.Dynamic corsFilter = servletContext.addFilter("corsFilter", new CorsFilter());
Map<String, String> parameters = new HashMap<>();
parameters.put("cors.allowed.headers", "Content-Type,X-Requested-With,accept,Origin,Access-Control-Request-Method,Access-Control-Request-Headers,Authorization");
parameters.put("cors.allowed.methods", "GET,POST,HEAD,OPTIONS,PUT,DELETE");
corsFilter.setInitParameters(parameters);
corsFilter.addMappingForUrlPatterns(disps, false, "/*");
corsFilter.setAsyncSupported(true);
}
put this line in WebConfigurer.onStartup(...), put it as close to the top as possible.
...
initCorsFilter(servletContext, disps);
...

I'm using Jhipster version 4.14.5
I have copied the following files to a project-forntend folder:
.bowerrc
gulp
pom.xml
yarn.lock
gulpfile.js
readme.md
bower_components
.gitattributes
src/main/web
bower.json
.gitignore
package.json
target/www
Then ran:
yarn install
bower install
gulp install
Then changed to the gulp/config.js file to :
apiPort: 8081
uri: 'http://localhost:'
Then started the project by running:
gulp serve

Related

Uploading jar to Apache Livy interactive session

Using Amazon emr-5.30.1 with Livy 0.7 and Spark 2.4.5
We are willing to use Apache Livy as a REST Service for spark.
The mode we want to work with is session and not batch.
Trying to upload a jar to the session (by the formal API) using:
curl -X POST \
-d '{"conf": {"kind" : "spark","jars": "s3://cjspro-emr-data/spark-examples.jar"}}' \
-H "Content-Type: application/json" localhost:8998/sessions
Looking at the session logs gives the impression that the jar is not being uploaded.
Not to mention that code snippets that are using the requested jar not working.
Any help?
I am not sure if the jar reference from s3 will work or not but we did the same using bootstrap actions and updating the spark config.
Step 1: Create a bootstrap script and add the following code;
aws s3 cp s3://cjspro-emr-data/spark-examples.jar /home/hadoop/jars/
Step 2: While creating Livy session, set the following spark config using the conf key in Livy sessions API
'conf':{'spark.driver.extraClassPath':'/home/hadoop/jars/*,
'spark.executor.extraClassPath':'/home/hadoop/jars/*'}
Step 3: Send the jars to be added to the session using the jars key in Livy session API.
'jars':['local:/home/hadoop/spark-examples.jar']
So the final data to create a Livy session would look like;
{
'kind':'pyspark',
'conf':'above mentioned dict',
'jars':['local:/home/hadoop/spark-examples.jar'],
'executorCores':'',
'executorMemory':'',
.
.
.
}

Cannot connect to Wildfly in Dockerfile

I'm creating a custom Dockerfile with extensions for official keycloak docker image. I want to change web-context and add some custom providers.
Here's my Dockerfile:
FROM jboss/keycloak:7.0.0
COPY startup-config.cli /opt/jboss/tools/cli/startup-config.cli
RUN /opt/jboss/keycloak/bin/jboss-cli.sh --connect --controller=localhost:9990 --file="/opt/jboss/tools/cli/startup-config.cli"
ENV KEYCLOAK_USER=admin
ENV KEYCLOAK_PASSWORD=admin
and startup-config.cli file:
/subsystem=keycloak-server/:write-attribute(name=web-context,value="keycloak/auth")
/subsystem=keycloak-server/:add(name=providers,value="module:module:x.y.z.some-custom-provider")
Bu unfortunately I receive such error:
The controller is not available at localhost:9990: java.net.ConnectException: WFLYPRT0053: Could not connect to remote+http://localhost:9990. The connection failed: WFLYPRT0053: Could not connect to remote+http://localhost:9990. The connection failed: Connection refused
The command '/bin/sh -c /opt/jboss/keycloak/bin/jboss-cli.sh --connect --controller=localhost:9990 --file="/opt/jboss/tools/cli/startup-config.cli"' returned a non-zero code: 1
Is it a matter of invalid localhost? How should I refer to the management API?
Edit: I also tried with ENTRYPOINT instead of RUN, but the same error occurred during container initialization.
You are trying to have Wildfly load your custom config file at build-time here. The trouble is, that the Wildfly server is not running while the Dockerfile is building.
Wildfly actually already has you covered regarding automatically loading custom config, there is built in support for what you want to do. You simply need to put your config file in a "magic location" inside the image.
You need to drop your config file here:
/opt/jboss/startup-scripts/
So that your Dockerfile looks like this:
FROM jboss/keycloak:7.0.0
COPY startup-config.cli /opt/jboss/startup-scripts/startup-config.cli
ENV KEYCLOAK_USER=admin
ENV KEYCLOAK_PASSWORD=admin
Excerpt from the keycloak documentation:
Adding custom script using Dockerfile
A custom script can be added by
creating your own Dockerfile:
FROM keycloak
COPY custom-scripts/ /opt/jboss/startup-scripts/
Now you can simply start the image, and the built features in keycloak (Wildfly feature really) will go look for a config in that spedific directory, and then attempt to load it up.
Edit from comment with final solution:
While the original answer solved the issue with being able to pass configuration to the server at all, an issue remained with the content of the script. The following error was received when starting the container:
=========================================================================
Executing cli script: /opt/jboss/startup-scripts/startup-config.cli
No connection to the controller.
=========================================================================
The issue turned out to be in the startup-config.cli script, where the jboss command embed-server was missing, needed to initiate a connection to the jboss instance. Also missing was the closing stop-embedded-server command. More about configuring jboss in this manner in the docs here: CHAPTER 8. EMBEDDING A SERVER FOR OFFLINE CONFIGURATION
The final script:
embed-server --std-out=echo
/subsystem=keycloak-server/theme=defaults/:write-attribute(name=cacheThemes,value=false)
/subsystem=keycloak-server/theme=defaults/:write-attribute(name=cacheTemplates,value=false)
stop-embedded-server
WildFly management interfaces are not available when building the Docker image. Your only option is to start the CLI in embedded mode as discussed here Running CLI commands in WildFly Dockerfile.
A more advanced approach consists in using the S2I installation scripts to trigger CLI commands.

Java/jmeter http request fails but curl works

I am trying a very basic http request with jmeter, but it seems to always get the error below. I have tried a simple get against google which is fine but the internal servers are not :
java.net.NoRouteToHostException: No route to host (Host unreachable)
I can curl the same url successfully with a 200 response, so not sure if its jmeter or java? The only thing that is unique is that our internal servers are resolving with ipv6, but I would not think that would be the problem?
Try adding the next line to system.properties file (lives in "bin" folder of your JMeter installation)
java.net.preferIPv6Addresses=true
Or pass the aforementioned property via -D command-line argument like:
jmeter -Djava.net.preferIPv6Addresses=true -n -t test.jmx -l result.jtl
References:
Java: Networking Properties
Configuring JMeter
Apache JMeter Properties Customization Guide
Overriding Properties Via The Command Line

java.io.IOException: No X-Jenkins-CLI2-Port (jenkins cli not working )

I'm trying to run the following command:
java -jar jenkins-cli.jar -s http://jenkins_URL/ --username myusername --password mypassword help
But I'm getting the error :
java.io.IOException: No X-Jenkins-CLI2-Port among [null, X-Required-Permission, X-Jenkins, X-You-Are-In-Group, X-Hudson, Content-Length, Expires, X-You-Are-Authenticated-As, X-Permission-Implied-By, Set-Cookie, Server, X-Content-Type-Options, Date, X-Jenkins-Session, Content-Type]
at hudson.cli.CLI.getCliTcpPort(CLI.java:284)
at hudson.cli.CLI.(CLI.java:128)
at hudson.cli.CLIConnectionFactory.connect(CLIConnectionFactory.java:72)
at hudson.cli.CLI._main(CLI.java:473)
at hudson.cli.CLI.main(CLI.java:384)
Suppressed: java.io.IOException: Server returned HTTP response code: 403 for URL: http://52.9.217.252:8888/cli
at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1628)
at hudson.cli.FullDuplexHttpStream.(FullDuplexHttpStream.java:78)
at hudson.cli.CLI.connectViaHttp(CLI.java:152)
at hudson.cli.CLI.(CLI.java:132)
... 3 more
my config.xml file
<?xml version='1.0' encoding='UTF-8'?>
<hudson>
<disabledAdministrativeMonitors/>
<version>1.0</version>
<numExecutors>2</numExecutors>
<mode>NORMAL</mode>
<useSecurity>true</useSecurity>
<authorizationStrategy class="hudson.security.FullControlOnceLoggedInAuthorizationStrategy">
<denyAnonymousReadAccess>false</denyAnonymousReadAccess>
</authorizationStrategy>
<securityRealm class="hudson.security.HudsonPrivateSecurityRealm">
<disableSignup>true</disableSignup>
<enableCaptcha>false</enableCaptcha>
</securityRealm>
<disableRememberMe>false</disableRememberMe>
<projectNamingStrategy class="jenkins.model.ProjectNamingStrategy$DefaultProjectNamingStrategy"/>
<workspaceDir>${ITEM_ROOTDIR}/workspace</workspaceDir>
<buildsDir>${ITEM_ROOTDIR}/builds</buildsDir>
<jdks/>
<viewsTabBar class="hudson.views.DefaultViewsTabBar"/>
<myViewsTabBar class="hudson.views.DefaultMyViewsTabBar"/>
<clouds/>
<scmCheckoutRetryCount>0</scmCheckoutRetryCount>
<views>
<hudson.model.AllView>
<owner class="hudson" reference="../../.."/>
<name>All</name>
<filterExecutors>false</filterExecutors>
<filterQueue>false</filterQueue>
<properties class="hudson.model.View$PropertyList"/>
</hudson.model.AllView>
</views>
<primaryView>All</primaryView>
<slaveAgentPort>-1</slaveAgentPort>
<label></label>
<crumbIssuer class="hudson.security.csrf.DefaultCrumbIssuer">
<excludeClientIPFromCrumb>false</excludeClientIPFromCrumb>
</crumbIssuer>
<nodeProperties/>
<globalNodeProperties/>
</hudson>
There is an official solution at the Jenkins Wiki Page for CLI.
The solution is
Go to Manage Jenkins (in the Jenkins UI)
-> Configure Global Security
-> "TCP port for JNLP agents": choose fixed or random
For those looking on how to make this work programatically (unattended).
You have to change
<jenkins.CLI>
<enabled>false</enabled>
</jenkins.CLI>
to
<jenkins.CLI>
<enabled>true</enabled>
</jenkins.CLI>
in /var/lib/jenkins/jenkins.CLI.xml and restart jenkins
To be sure it's not an username and/or password error change this line:
<denyAnonymousReadAccess>true</denyAnonymousReadAccess>
into:
<denyAnonymousReadAccess>false</denyAnonymousReadAccess>
in your config.xml file.
Now you can connect to your jenkins interface to debug your credentials
Don't forget to reset it to true.
If you're not clear why it fails, run under strace/dtruss debugger, e.g.
$ strace -fs1000 -e trace=network java -jar jenkins-cli.jar -s http://localhost:8080/ help
If you've got:
HTTP/1.1 403 No valid crumb was included in the request
error, then you need to either provide crumb in the request, or disable CSRF Protection.
Using Jenkins CLI it's not working yet when the crumb issuer is enabled, so you can use curl instead. For example (replace localhost with your Jenkins address):
Note your user API Token (/user/USER/configure).
Get your crumb:
CRUMB=$(curl -s 'http://USER:TOKEN#localhost:8080/crumbIssuer/api/xml?xpath=concat(//crumbRequestField,":",//crumb)')
Invoke some command (e.g. list the jobs):
curl -H $CRUMB http://USER:TOKEN#localhost:8080/api/json
Related: Jenkins REST API Create job

Unable to clone/push/pull a project on Git Bash

I previously worked on a project in Ruby on Rails using Vagrant as development environment. After I finished the project, I started to work in a project in Java, but when i try to clone the project into my workspace, i'm getting this error on Git Bash console:
git clone git#git.address.com:mari/project.git
Cloning into 'project'
/usr/local/rvm/rubies/ruby-1.9.3-p429/lib/ruby/1.9.1/net/http.rb:763:in 'initialize': No route to host - connect(2) (Errno::EHOSUNREACH)
from /usr/local/rvm/rubies/ruby-1.9.3-p429/lib/ruby/1.9.1/net/http.rb:763:in 'open'
from /usr/local/rvm/rubies/ruby-1.9.3-p429/lib/ruby/1.9.1/net/http.rb:763:in 'block in connect'
from /usr/local/rvm/rubies/ruby-1.9.3-p429/lib/ruby/1.9.1/net/http.rb:55:in 'timeout'
from /usr/local/rvm/rubies/ruby-1.9.3-p429/lib/ruby/1.9.1/net/http.rb:100:in 'timeout'
from /usr/local/rvm/rubies/ruby-1.9.3-p429/lib/ruby/1.9.1/net/http.rb:763:in 'connect'
from /usr/local/rvm/rubies/ruby-1.9.3-p429/lib/ruby/1.9.1/net/http.rb:756:in 'do_start'
from /usr/local/rvm/rubies/ruby-1.9.3-p429/lib/ruby/1.9.1/net/http.rb:745:in 'start'
from /opt/git/gitlab-shell/lib/gitlab_net.rb:56:in 'get'
from /opt/git/gitlab-shell/lib/gitlab_net.rb:17:in 'allowed?'
from /opt/git/gitlab-shell/lib/gitlab_net.rb:51:in 'validate_access'
from /opt/git/gitlab-shell/lib/gitlab_net.rb:21:in 'exec'
from /opt/git/gitlab-shell/lib/gitlab_net.rb:16:in '<main>'
fatal: Could not read from remote repository.
Please make sure you have the correct access rights and the repository exists.
NOTE: I've tried this solution (Change the URI (URL) for a remote Git repository) and didn't work. Any idea what might be happening?
EDIT: I'm using Windows, but the VM used on Vagrant is Linux.
Try adding the protocol to the beginning of the remote url:
ssh://git#git.address.com/mari/project.git
Also don't use a : to seperate path and uri, but use a / instead.
Of course, you can use another protocol as ssh.
try git remote url like this
http://<username>#git.address.com/<path>.git

Categories

Resources