Quick refresher on Java Spring Framework with REST Webservices.
Spring Framework is a Java platform that provides comprehensive infrastructure support for developing Java applications. Spring handles the infrastructure so you can focus on your application.
- Prefered IDE: VSCode
- VSCode extensions:
- Spring Boot Dashboard
- Spring Boot Extension Pack
- Spring Boot Tools
- Spring Initializer Java Support
- Test Runner for Java
- Maven for Java -> if Mac ->
xcode-select --install
->brew install maven
- Debugger for Java
- Extension Pack for Java
- Java prettier formatter
- XML
- Start webservices:
./mvnw spring-boot:run
or VSCode UI
- Build your project with
mvn install
command - Upload the deployable
.jar
file to a production server - Run application with
java -jar
command
- Navigate to
/mobile-app-ws
directroy folder - Run
./mvnw install
this will compile, build the project and unit tests - Run
./mvnw spring-boot:run
this will run the RESTful webservices application in a apache tomcat server container
Run
./mvnw install` this will compile, build the project and unit tests (create jar in target)cd /mobile-app-ws/target
cp mobile-app-ws-0.0.1-SNAPSHOT.jar /Users/{user-name}/Desktop
- Navigate to desktop where the jar has been copied
java -jar mobile-app-ws-0.0.1-SNAPSHOT.jar
- Update
pom.xml
->
<packaging>war</packaging>
./mvnw clean
clears out target folder./mvnw install
creates the war package in/target
- Install tomcat zip from http://tomcat.apache.org (with the appropriate corrosponding java version)
- Unzip on to desktop
- Switch directories to
cd /Desktop/apache-tomcat-9.0.65/bin/
- Elevate permissions to make script files executable
chmod a+x *.sh
- Run
./startup.sh
- Navigate to http://localhost:8080 (tomat is running!)
- Run
./shutdown.sh
- Create Tomcat user for deployments
- Switch directoires to
cd /Desktop/apach-tomcat-9.0.65/conf
- Open
tomcat-users.xml
- Add
<role rolename="manager-gui"/>
<user username="admin" password="admin" roles="manager-gui"/>
- Go to maven project directory where the war package has been created
/mobile-app-ws/target/
- Rename
mobile-app-ws-0.0.1-SNAPSHOT.war
->mobile-app-ws.war
- Deploy war on tomcat 'WAR file to deploy':
- Webservices are deployed :)
- Login to https://aws.amazon.com/
- Navigate to EC2 Dashboard
- Select availability zone
- Select 'Launch instance'
- Configuration settings:
- Name and tags: 'DemoAPIServer'
- App and OS Images: Amazon Linux (Free tier)
- Instance type: t2.micro (Free tier)
- Key pair (login): Create private key for login
- Storage (volumes): 8GB (Free tier)
- Network settings: SSH, HTTP, HTTPS, Custom TCP port 8080
- Advanced settings: Shutdown behaviour: Stop
- Launch the instance
- Navigate to EC2 Running containers
- Get Public IPv4 DNS name to start SSH the connection
- SSH into AWS instance:
sudo su
(if required)chmod 400 myprivatekey.cer
(if required)ssh -i myprivatekey.cer ec2-user@{DNS-name}
- Install updates:
sudo yum update
- Check Java version:
sudo java -version
- Check all Java packages available:
sudo yum list java
- Install Java:
sudo yum install java-1.8.0
- Switch Java version:
sudo /usr/sbin/alternatives --config java
sudo /usr/sbin/alternatives --config javac
- Go to https://tomcat.apache.org/ select the version and get the url link for the
tar.gz
file type - Download tomcat with the link extracted (example):
sudo wget https://dlcdn.apache.org/tomcat/tomcat-9/v9.0.65/bin/apache-tomcat-9.0.65.tar.gz
- Check file is there:
ls
- Extract files:
sudo tar xvf apache-tomcat-9.0.65.tar.gz -C /usr/share
- Check its extracted:
ls -lrt /usr/share
- Rename tomact directory:
sudo ln -s /usr/share/apache-tomcat-9.0.65 /usr/share/tomcat9
ls -lrt /usr/share
is now:tomcat9 -> /usr/share/apache-tomcat-9.0.65
:)
- Create a new tomcat group:
sudo groupadd --system tomcat
sudo useradd -d /usr/share/tomcat9 -r -s /bin/false -g tomcat tomcat
sudo chown -R tomcat:tomcat /usr/share/apache-tomcat-9.0.65
(set tomcat folder permissions for this new user)
- Make tomcat start on reboot (will need to create a service file)
sudo vi /etc/systemd/system/tomcat9.service
- Copy and paste these setting into this file:
[Unit]
Description=Tomcat Server
After=syslog.target network.target
[Service]
Type=forking
User=tomcat
Group=tomcat
Environment=JAVA_HOME=/usr/lib/jvm/jre
Environment='JAVA_OPTS=-Djava.awt.headless=true'
Environment=CATALINA_HOME=/usr/share/tomcat9
Environment=CATALINA_BASE=/usr/share/tomcat9
Environment=CATALINA_PID=/usr/share/tomcat9/temp/tomcat.pid
Environment='CATALINA_OPTS=-Xms512M -Xmx1024M'
ExecStart=/usr/share/tomcat9/bin/catalina.sh start
ExecStop=/usr/share/tomcat9/bin/catalina.sh stop
[Install]
WantedBy=multi-user.target
sudo systemctl daemon-reload
- Start tomcat
sudo systemctl enable tomcat9
sudo systemctl start tomcat9
(to stopsudo systemctl stop tomcat9
)
- Navigate to tomcat URL
- {AWS Public IPv4 DNS}.com:8080
sudo vi /usr/share/tomcat9/webapps/manager/META-INF/context.xml
- Comment out line (key i -> INSERT to edit):
<!-- <Valve className="org.apache.catalina.valves.RemoteAddrValve"
allow="127\.\d+\.\d+\.\d+|::1|0:0:0:0:0:0:0:1" /> -->
- esc +
:wq
to save changes - sudo systemctl restart tomcat9
sudo vi /usr/share/tomcat9/conf/tomcat-users.xml
- (Copy and paste from the tomcat 401 page) (key i -> INSERT to edit):
<role rolename="manager-gui"/>
<user username="tomcat" password="s3cret" roles="manager-gui"/>
- esc +
:wq
to save changes
sudo systemctl restart tomcat9
sudo yum install https://dev.mysql.com/get/mysql80-community-release-el7-6.noarch.rpm
sudo amazon-linux-extras install epel -y
sudo yum install mysql-community-server
- Optional: Navigate to
/etc/yum.repos.d/mysql-community.repo
and disable gpg if you trust repos
gpgcheck=0
sudo systemctl enable --now mysqld
systemctl status mysqld
sudo grep 'temporary password' /var/log/mysqld.log
sudo mysql_secure_installation
- Set new password
- Remove anonymous users? - Yes
- Disallow root login remotely? - Yes
- Remove test Database? - Yes
- Reload privilege tables now? - Yes
mysql -u root -p
- Login
- Sign into user root:
mysql -u root -p
create database photo_app;
show databases;
create user '{my username here}'@'localhost' identified by '{my password here}';
grant all privileges on photo_app.* to '{my username here}'@'localhost';
- Make changes to take affect:
flush privileges;
exit
mysql -u {my username here} -p;
show databases
;
- Navigate to maven webservices project: e.g.
cd mobile-app-ws
./mvnw install
- Go to
cd mobile-app-ws/target/mobile-app-ws-0.0.1-SNAPSHOT.war
- Rename it if needed
- Navigate to tomcat URL
- {AWS Public IPv4 DNS}.com:8080
- Login if needed
- Navigate to tomcat web application manager
- Deploy
.war
file to "War file to deploy
One of the fastest and simplest ways of deploying spring boot applications. You simply upload your application and your application will automatically handle your capacity provisioning, load balancing, auto-scaling and application health monitoring.
So you could use your application in a production environment within just a few minutes, without any infrastrucutre or resource configuration work yourself.
Elastic beanstalk is:
- Easy to use service
- Deploying applications
- Scaling applications
As depicted below, you will get an EC2 instance started and configured auotmatically, additionally to that you wll get an autoscaling, so if need your EC2 instance, this can scale up and handle more traffic.
To load balance the incoming traffic, Elastic Load Balancer is created and configured for you automatically, the incoming HTTP traffic will be equally balanced between the running EC2 instances.
Amazon RDS can be used here to, Amazon RDS is a relational database and this supports many different types of relational databases, for this demo I will be using MySQL again. Also by using Amazon RDS, you will also get autoscaling included here too, you do not need to aquire specialist or develop additional skills here, Amazon RDS will do it for you! :)
So as our spring boot application scales up and down it will work with MySQL server that will use Amazon RDS service. By deploying your application with Beanstalk and running your database in Amazon RDS, you access capabilities of production ready environment in just a few minutes! No need to manually configure infrastructure, and no need for installing and maintaining database software, you get this all provided by Amazon.
- Login to AWS and search for RDS
- Select databases -> create database
- Database configuration: (Free tier configuration/none production)
- Engine type: MySQL
- Edition: MySQL Community
- Templates: Free Tier! :)
- DB instance identifier:
photoappuserapi
- Credentials Settings: set username and password
- Instance configuration: Burstable classes (includes t classes) (db.t3.micro)
- Storage settings: (keep as they are)
- Connectivity:
-
- Public Access: true
-
- VPC: Default
-
- DB Subnet Group: Default
-
- Database port: 3306
- Database Authentication: Password authentication
- Initial Databse name:
photoappusers_db
- Backups: disable
- Encryption: disable
- Select database instance in AWS and select inbound rules
- Select AWS/Aurora TCP - default at port 3306
- In the
applicaiton.properties
in the main maven project - update appropriately:
server.error.whitelabel.enabled=false
spring.datasource.username={username}
spring.datasource.password={password}
spring.datasource.url=jdbc:mysql://{rds-endpoint-address.amazonaws.com}:3306/{database name configuration}
spring.jpa.hibernate.ddl-auto=update
tokenSecret=tokenSecret
server.error.include-stacktrace=never
server.servlet.context-path=/mobile-app-ws
- Run
./mvnw package
(Take the compiled code and package it in its distributable format, such as a JAR or WAR)
- In AWS search for Elastic Beanstalk, once navigates select:
- Create Application
- Then configure/create web app
- Application name:
PhotoAppUsersApi
- Platform:
Tomcat
- Application code: "Upload your code"
- Source code origin: "local file" -> upload file ->
mobile-app-ws-0.0.1-SNAPSHOT.war
- Stat application (The rest of the configuration can be skipped for this)
- Elastic Beanstalk App has been deployed :)
- Open Postman
- Test the sign up
http://{{aws-beanstalk-instance-name}}/users
-
Headers:
-
- Content-Type:
application/json
- Content-Type:
-
- Accept:
application/json
- Accept:
-
Body:
{
"firstName":"Joe",
"lastName":"Bloggs",
"email":"joe@bloggs.com",
"password":"AmazingPassword"
}
- Update
Pom.xml
-
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-security</artifactId> </dependency>
https://docs.spring.io/spring-security/site/docs/3.0.x/reference/el-access.html
Cross Origin Resource Scripting - is only required when we need to allow different domain names or other origins (this include port numbers, comm protocols) to access our API, this is disabed by default in Springboot.
Example below of the cross origin annoation, this can be applied on the controller request methods or the entire class itself:
@CrossOrigin(origins = "*") @CrossOrigin(origins = "http://localhost:8080","http://localhost:8081")
- Verification service: https://github.com/seanmayer/verification-service
- Restful webservices: https://github.com/seanmayer/java-restful-refresher
- Navigate to Amazon Simple Email Service:
-
Ensure that you have selected the region you want to target these emails (please note that the sender/source domain will need to be verified with AWS)
-
Select Create Identity:
- From here you will then be able to add your email address you want to use for sending emails out, this will then need to be verified in your inbox.
- Navigate to Amazon Notification Service:
- Create topic, with name "bounces":
- Set topic to default configurations:
- Topic has now been created, and now is viewable on the dashboard:
- Repeat this process again but this time make a topic for "complain":
- Navigate to Subscriptions:
- Configure subscription for "bounces" to the email address you want:
- Confirm subscription via the email you set, received in the inbox
-
Repeat this process again for complain
-
Navigate back to SNS and select configurations for the email address you set on feedback notifications:
- Configure SNS configuration on feedback notifications to the email that has been set both for bounces and complain:
- After setting this, you should get confirmation in your inbox that this it is set.
- Navigate to support center to create a ticket
- Raise a support ticket with a service limit increase
- Limit Type: SES Sending Limits
- New limit value: 100
- Region: {region you are using}
- Naviate to security credentials by select username top right corner:
- Once in the console select users and create new user
- User configuration
- user name: {username}
- access type: programmatic access
- set permission group: {create permission group -> name it:
SES-SERVICE-USERS
selectAmazonSESFullAccess
-> create group} - Once completed make note of "Access key ID" and "Secret access key" (only available once!)
Used for access details and authenticate with AWS.
- Create a new file containing this, and paste the following lines you have just create in prior steps:
[default]
aws_access_key_id = YOUR_AWS_ACCESS_KEY_ID
aws_secret_access_key = YOUR_AWS_SECRET_ACCESS_KEY
- Save the file (do not use a file extension when saving the file):
If Linux/Mac OS:
~/.aws/credentials
If Windows:
C:\Users\USERNAME\.aws\credentials
-
Create war package from https://github.com/seanmayer/verification-service ->
mvn clean
->mvn install
-
Deploy the .war to your local tomcat server
-
Open brower and check: http://localhost:8080/verification-service/email-verification.html
-
Create war package from https://github.com/seanmayer/java-restful-refresher ->
mvn clean
->mvn install
- Please note if you get an error on deployment that is:
Deploy Upload Failed, Exception: [org.apache.tomcat.util.http.fileupload.impl.SizeLimitExceededException
please got to web.xml of the manager application (for instance it could be under/tomcat9/webapps/manager/WEB-INF/web.xml
. Increase the max-file-size and max-request-size
-
Run Sign up in the local postman collection
/postman/REST Refresher.postman_collection.json
-
Open MySQL workbench and preview the users table, find the new user you have created and copy the
email-verification_token
field. -
With the token apply this to the token param in Sign up verification in the local postman collection
/postman/REST Refresher.postman_collection.json
and then run it -
Repeat step 5 and 6. But this time go to your browser to verify this token with verfication webpage instead:
http://localhost:8080/verification-service/email-verification.html?token={you-copied-token}
- Removed dependency dotenv package was breaking the .war file:
<dependency>
<groupId>io.github.cdimascio</groupId>
<artifactId>dotenv-java</artifactId>
<version>2.2.4</version>
</dependency>
-
Add aws variables to
AmazonSES.java
in this repo, andemail-verification.html
in https://github.com/seanmayer/verification-service -
Maven clean and install both repos and deploy the .war(s) to your AWS/tomcat instance
-
Now you should be able to run the signup in postman with the SES email address, this will then sign up the user in the RDS database and send a verification link, once the link is navigated it will verify the email address and update the database entry that the email is verified :)
-
For setup, please reference commit id: https://github.com/seanmayer/java-restful-refresher/commit/5de8ce0ad5bb5f77638e8740cacc4f780a4a628c (and post commits after)
-
Run project
-
Navigate to http://localhost:8888/mobile-app-ws/h2-console/ a) you can change h2 path in
application.properties
filespring.h2.console.path=/h2-console
\ -
H2 console supports a number of relational databases that you can connect to besides H2
-
Using the
application.properties
file configuration you should be able to use the connection details defined in there to connect to H2 database:
Run JUnit tests here: https://github.com/seanmayer/mobile-app-ws-rest-assured-test
Further Integration tests using native queries and JPQL queries in /src/test/java/com/appsdeveloperblog/app/ws/io/repositories
API Documentation.
References:
JSON: http://localhost:8080/mobile-app-ws/v2/api-docs
Browser docs: http://localhost:8080/mobile-app-ws/swagger-ui.html
You can also share your API/docs to: https://swagger.io/tools/swaggerhub/
That is all, I hope you found this guide helpful :)