One way to start a new Git Spring Boot project

  1. Go to local git repository, create a new folder for your project
  2. On command line inside this new folder type >git init
  3. Open STS, Import > Git > Projects from Git > Existing local repository
  4. Pick your new git repository you just made, click Next
  5. Import using the New Project wizard
  6. Choose Spring Boot > Spring Starter Project.
  7. Copy all the contents of the newly created project to the local git repository manually using Windows Explorer etc.
  8. Commit the new files to the local repository.
  9. Push to remote repository on GitHub if required.
  10. Open STS, Import > Git > Projects from Git > Existing local repository.
  11. Pick your new git repository you just made, click Next.
  12. Import using the Import existing Eclipse Project.
  13. Run As > Spring Boot App, and all should be working.

There must be an easier way that manually copying… but you need to be in a Work-space to use the New Spring Boot project wizard.

Learning Path: Spring: Web Applications with Spring and Angular

I’ve decided to create a proper front-end, so will be taking this Safari course. I also took a Live Lesson, but have yet to properly look at it. Unfortunately, you cannot speed up the videos of the live lessons, and they’re 6 hours long 😦 I like to listen to everything on at least 1.5x, mostly 2x! I may look at the slides later and see if anything is new. So, today I’ll be looking at the above course by two different people. It seems to have been mashed together, so I wonder how contiguous it is…

Adding test MySQL database

The application.properties file for dev is as follows:

spring.datasource.url=jdbc:h2:mem:testdb
spring.h2.console.enabled=true
spring.h2.console.path=/h2

I added a new application-test.properties file to add the MySQL connection details:

spring.datasource.url=jdbc:mysql://localhost/bsctest
spring.datasource.username=test_user
spring.datasource.password=password
spring.datasource.driver-class-name=com.mysql.jdbc.Driver

spring.datasource.test-on-borrow=true
spring.datasource.validation-query=/* ping */

I opened up the MySQL Workbench and created a new schema called bsctest. Then I added the article table. I used the GUI, and it generated the following SQL:

CREATE TABLE `bsctest`.`articles` (
`article_id` INT NOT NULL AUTO_INCREMENT,
`title` VARCHAR(45) NOT NULL,
`summary` VARCHAR(45) NOT NULL,
PRIMARY KEY (`article_id`))
COMMENT = 'Table to hold basic article information for testing.';

This is pretty close to the schema.sql file I have:

CREATE TABLE articles(
article_id int,
title varchar2(50),
summary varchar2(50)
);

so I applied it.

Then I added data.sql with additional MySQL text:

INSERT INTO articles values(1, 'Title 1', 'This is Summary 1 from MySQL.');
INSERT INTO articles values(2, 'Title 2', 'Here is Summary 2 from MySQL.');
INSERT INTO articles values(3, 'Title 3', 'Summary 3 is here from MySQL.');

(Actually, I forgot to add the MySQL bit, realized my application wasn’t refreshing so had no idea if it was using the h2 or MySQL database, so had to do three updates)

The data was successfully inserted into the MySQL database.

Now, I need to use the profiles to pick up the application-test.properties file because it looks like the h2 database is still being used.

Added two run configurations, and they both work fine 😀 Program arguments for test are:

--spring.profiles.active=test

There is nothing for dev, and the default application.properties file is picked up.

 

Profile-specific configuration


Spring Boot allows you to have one common configuration file (application.properties) and then multiple other files, each specific to a profile (application-${profile}.properties).

For instance:

  • application.properties – Common configuration
  • application-dev.properties – Configuration for dev profile
  • application-ci.properties – Configuration for ci profiles

If your application runs with “ci” profile for instance, the default configuration file as well as the ci configuration file (which would contain the datasource configuration properties for ci profile) will be loaded.

To switch profiles you can use one of the following options:

  • JVM property: -Dspring.profiles.active=ci
  • Command line switch: --spring.profiles.active=dev

For unit tests you can use @ActiveProfiles("test") annotation on your test classes to tell Spring that unit tests should be run with test profile.

Also if you don’t want to store production database credentials along with your source code, you can specify external configuration file when you deploy your app in production:

  • Using command line switch: --spring.config.location=/srv/myapp/config.properties
  • Using a JVM property: -Dspring.config.location=/srv/myapp/config.properties

 

I think I’ll create the different properties files for dev-h2 database, and test-MySQL database. Then change based on Profile. My only question is what to do about the pom.xml file. Do I include h2 and mysql?

Hmmm… some people seem to add both. If the application is configured to use MySQL, then it’ll ignore the h2 in the pom.xml file. However, another suggested using Maven Profiles to build different things as you don’t have to package up unused jars to ship to production, and this minimizes any chance of an in-memory database starting up in production. It also gives you the option of minimizing the static resources for speed. I think the gzip compression is done on the server.

http://maven.apache.org/guides/introduction/introduction-to-profiles.html

I think I’ll do both.

Future Optimization

Security (before deploying to AWS!!!)

Caching and cache-busting

Serving static content and gzip encoding it.

https://css-tricks.com/the-difference-between-minification-and-gzipping/

Gzipping reduces the file size about five times as much as minifying does. But, you get a little boost from minifying as well, and since it likely requires little additional effort in a build step, you might as well.

There is also some evidence that browsers can read and parse a minified file faster

 

First Thymeleaf template

Added the thymeleaf starter to my Spring Boot application.

Added a @RequestMapping to my Application java file:

package com.sgbsc;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

@SpringBootApplication
@Controller
public class Bsc1Application {

@RequestMapping("/hello-template")
public String helloTemplate() {
return "hello-template";
}

public static void main(String[] args) {
SpringApplication.run(Bsc1Application.class, args);
}
}

Needed the @Controller to tell Spring what to return for the URL.

In Spring, a Controller is a class which is responsible for preparing  a model Map with data to be displayed by the view as well as choosing the right view itself. It can also directly write into response stream by using @ResponseBody annotation and complete the request.

If we were writing a RESTful application, we’d use @RestController which is a convenience controller meaning @Controller + @ResponseBody.

This application just returns two pages:

index.html

  • sent back automatically by the DispatcherServlet
  • auto-configured by Spring Boot upon seeing @SpringBootApplication and Web starter in pom.xml.
  • It looks for an index.html, and css under the static resources folder.

hello-template.html

  • Spring Boot notices thymeleaf starter in pom.xml
  • Spring’s RequestMappingHandlerMapping is used to maintain the mapping of the request URI to the handler (which are the controller methods annotated with the @RequestMapping annotation). Once the handler is obtained, the DispatcherServlet
    dispatches the request to the appropriate handler adapter.

src/main/resources/static/index.html

<!DOCTYPE html>
<html>
<head>
<meta charset="ISO-8859-1">
<title>bsc1</title>
<link rel="stylesheet" href="/css/bsc1.css"/>
<link rel="shortcut icon" href="/favicon.ico" type="image/x-icon">
<link rel="icon" href="/favicon.ico" type="image/x-icon">
</head>
<body>
<h1>Hello, and welcome to a static "hello world" page!</h1>
</body>
</html>

src/main/resources/static/css/bsc1.css

@charset "ISO-8859-1";
body {
background-color: lightblue;
}

h1 {
color: white;

src/main/resources/static/template/hello-template.html

<!DOCTYPE html>
<html>
<head>
<meta charset="ISO-8859-1">
<title>bsc1 - hello template</title>
<link rel="stylesheet" href="/css/bsc1.css"/>
<link rel="shortcut icon" href="/favicon.ico" type="image/x-icon">
<link rel="icon" href="/favicon.ico" type="image/x-icon">
</head>
<body>
<h1>This is a Thymeleaf template!</h1>
</body>
</html>

I also used a free icon generator to make a favicon.ico and put it under src/main/resources/static too.

First application: bsc1

I created a Spring Boot application, choosing: h2, JDBC and Web.

I’m going to use Profiles as a program argument, leaving the dev as application.properties, then changing out for application-test.properties and using
–spring.profiles.active=test in the Run Configuration.

I’ve hooked it up to the remote repository on GitHub, and am working on the ‘initial’ branch.

I’ve opened it up in the Git window of STS, but I’m using GitHub Desktop to manage commits with help from the command window (as I got into a pickle and had /project/project and couldn’t see anything!)

Anyway… up and running now.

I’m following on 2x speed the O’Reilly Introduction to Spring Boot course with Kevin Bowersox to make a CRUD application.

The Spring in Action 5 book is out next week building a Taco application, so I’d like to make mine first, then make that and apply it to my project as I’m going along. I want a super project in the end full of notes 🙂

I’ve started looking at the tutorial again and he’s using Thymeleaf, then Mustache. Now, in my past I used JSP and this is still used, however, there’s all this new JavaScript stuff with Angular and React too. Spring say that there are known limitations of using JSP in embedded servlet containers. Fair enough then. I found a Spring tutorial:

https://spring.io/guides/tutorials/spring-security-and-angular-js/

And I found a few templating engine examples:

https://www.baeldung.com/spring-template-engines

Hmmm… what to do….

I think I’ll follow the O’Reilly tutorial first, then create a new branch to test out the other front-ends. I’m doing an Angular Live Online Training next week, so maybe I can wrap up the front-end exploration with that and have some great examples 🙂

The path forward

Great! I’ve found my path forward:

Create my basic news app in Spring Boot, playing with web front-ends (e.g. Angular), and learning the Spring stuff. Using Git on GitHub.

Looking at moving said stuff to AWS in a basic way.

Re-writing my code in Spring Cloud and AWS Lambda in a serverless way.

Moving my stuff to AWS in a basic way.

All the while, using my Safari subscription to read and use as much as I can.

Learning AWS, using a cloud guru, probably stop Safari subscription while doing this.

Maybe take some certifications.

Look at automating, CI/CD usign Jenkins or whatever people use. I must remember that I don’t actually want to be a DevOps person, I’m happy creating things and only need to know enough to get my job done.

I might learn Python to help with this, I already know Perl, so it’s not going to be that different.

Then implementing my code with the knowledge I’ve gained.

Cool… let’s get going!

AWS credentials in application.properties

I’m not happy about putting my credentials in the application.properties file. I’m sure there’s a better way to do this. I looked around and found lots of text but no code of help.

I managed to discover this property to be put in application.properties:

#cloud.aws.credentials.accessKey=XXX
#cloud.aws.credentials.secretKey=XXX
cloud.aws.region.static=us-east-2
cloud.aws.credentials.instanceProfile=true

But I got an error when running this command:

curl -H “Content-Type: text/plain” localhost:8080/generateShortcode -d ‘”https://www.google.co.uk/”&#8216;

{
“timestamp”: “2018-10-16T12:28:53.098+0000”,
“status”: 500,
“error”: “Internal Server Error”,
“message”: “Unable to load AWS credentials from any provider in the chain: [com.amazonaws.auth.EC2ContainerCredentialsProviderWrapper@46f388f7: Unable to load credentials from service endpoint, com.amazonaws.auth.profile.ProfileCredentialsProvider@349515a3: No AWS profile named ‘default’]”,
“path”: “/generateShortcode”
}

Google brought me here: https://github.com/aws/aws-sdk-java/issues/1324

SDK has a credential resolution logic to resolve the aws credentials to use when interacting with aws services. See the below link:
http://docs.aws.amazon.com/sdk-for-java/v1/developer-guide/credentials.html

When you see the error “Unable to load AWS credentials from any provider in the chain”, it means we could not find credentials in any of the places the DefaultAWSCredentialsProviderChain looks at. Please make sure the credentials are located at at least one of the places mentioned in the above link.

Urgh, I just put them in… a problem for another day…

Unable to find a region via the region provider chain. Again! Maven install in eclipse.

Tests run: 1, Failures: 0, Errors: 1, Skipped: 0, Time elapsed: 10.008 sec <<< FAILURE!
testLambdaFunctionHandler(com.backtojavaland.imageresizer.LambdaFunctionHandlerTest) Time elapsed: 8.923 sec <<< ERROR!
com.amazonaws.SdkClientException: Unable to find a region via the region provider chain. Must provide an explicit region in the builder or setup environment to supply a region.

This is when following along the tutorial and trying to Run As.. > Maven install

I just can’t get it to work. It should be picking it up from the config file. So I tried adding an environment variable, adding something to settings.xml (although tbh I didn’t know what name to give it). Nothing worked, so I just disabled running tests for the install Run Configuration. At least I have my jar now.

No idea what’g going on!