Quickstart your SpringBoot with Spring Initializr

#Introduction

Spring offers a Spring Initializr to bootstrap your application quickly The most simple way to use it is to do this :

curl https://start.spring.io/starter.zip -o demo.zip

It will download a demo.zip file to your filesystem that you can extract:

  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100 50954  100 50954    0     0  38634      0  0:00:01  0:00:01 --:--:-- 38660

ls -ltr
total 104
-rw-r--r--  1 ddewaele  staff  50954 May 21 00:54 demo.zip

The zip file contains a complete spring boot application.

unzip demo.zip 
Archive:  demo.zip
  inflating: mvnw
   creating: .mvn/
   creating: .mvn/wrapper/
   creating: src/
   creating: src/main/
   creating: src/main/java/
   creating: src/main/java/com/
   creating: src/main/java/com/example/
   creating: src/main/resources/
   creating: src/test/
   creating: src/test/java/
   creating: src/test/java/com/
   creating: src/test/java/com/example/
  inflating: .mvn/wrapper/maven-wrapper.jar
  inflating: .mvn/wrapper/maven-wrapper.properties
  inflating: mvnw.cmd
  inflating: pom.xml
  inflating: src/main/java/com/example/DemoApplication.java
  inflating: src/main/resources/application.properties
  inflating: src/test/java/com/example/DemoApplicationTests.java

You can customize the cURL command by providing some additional parameters (groupId,artifactId,….)

curl https://start.spring.io/starter.tgz -d dependencies=web,actuator -d groupId=com.ecs -d artifactId=hawkbit.client -d language=java -d type=maven-project -d baseDir=hawkbit.client | tar -xzvf -

References

Spring initializr Github Spring Starter

In this guide I’m going to show you how you can use the Hawkbit API to generate key resources. Hawkbit comes with a great API to create the following entities :

  • Software Module Type
  • Software Module
  • Distribution Set Type
  • Distribution Type

We’ll cover all of them here.

Introduction

The mgmt api client contains a org.eclipse.hawkbit.mgmt.client.scenarios.GettingStartedDefaultScenario class that sets up some data. We’ll customize this data to suit our needs.

Software modules and types

We start with software module types and software modules

Hawkbit comes with a SoftwareModuleTypeResourceClient that we can use to create softwaremoduletypes

/**
 * Client binding for the oftwareModuleType resource of the management API.
 */
@FeignClient(url = "${hawkbit.url:localhost:8080}/rest/v1/softwaremoduletypes")
public interface SoftwareModuleTypeResourceClient extends SoftwareModuleTypeRestApi {

}

We start by creating 3 software module types. A software module type is simply a name.

Note : Unclear at this point what the firmware / software distinction refers to.

String softwareModuleType1 = "Base OS Image";
String softwareModuleType2 = "Software Module";
String softwareModuleType3 = "Configuration Module";

LOGGER.info("Creating software module type {}", softwareModuleType1);
final List<SoftwareModuleTypeRest> createdSoftwareModuleTypes1 = softwareModuleTypeResource
        .createSoftwareModuleTypes(
        		new SoftwareModuleTypeBuilder().key(softwareModuleType1).name(softwareModuleType1).maxAssignments(1).build())
        .getBody();

LOGGER.info("Creating software module type {}", softwareModuleType2);
final List<SoftwareModuleTypeRest> createdSoftwareModuleTypes2 = softwareModuleTypeResource
        .createSoftwareModuleTypes(
        		new SoftwareModuleTypeBuilder().key(softwareModuleType2).name(softwareModuleType2).maxAssignments(1).build())
        .getBody();


LOGGER.info("Creating software module type {}", softwareModuleType3);
final List<SoftwareModuleTypeRest> createdSoftwareModuleTypes3 = softwareModuleTypeResource
        .createSoftwareModuleTypes(
        		new SoftwareModuleTypeBuilder().key(softwareModuleType3).name(softwareModuleType3).maxAssignments(1).build())
        .getBody();

With the 3 software module types created, we can start creating our actual software modules based on those types. A software module has a version.

final String softwareModule1 = "IxorTalk Base Image";
final String softwareModule2 = "IxorTalk Customer1 Software";
final String softwareModule3 = "IxorTalk Customer1 Config";

final String swVersion1 = "1.0";
final String swVersion2 = "2.1";
final String swVersion3 = "1.2";

LOGGER.info("Creating software module {}:{}", softwareModule1, swVersion1);
final List<SoftwareModuleRest> softwareModulesRest1 = softwareModuleResource.createSoftwareModules(
        new SoftwareModuleBuilder().name(softwareModule1).version(swVersion1).type(softwareModuleType1).build())
        .getBody();
LOGGER.info("Creating software module {}:{}", softwareModule2, swVersion2);
final List<SoftwareModuleRest> softwareModulesRest2 = softwareModuleResource.createSoftwareModules(
        new SoftwareModuleBuilder().name(softwareModule2).version(swVersion2).type(softwareModuleType2).build())
        .getBody();
LOGGER.info("Creating software module {}:{}", softwareModule3, swVersion3);
final List<SoftwareModuleRest> softwareModulesRest3 = softwareModuleResource.createSoftwareModules(
        new SoftwareModuleBuilder().name(softwareModule3).version(swVersion3).type(softwareModuleType3).build())
        .getBody();

Distribution Set Type

Distribution Set Types define the different Distribution Sets that we can create. The Distribution Set Type defines what type of Software Module Types we can assign to this Distribution Set Type.

Note : Discuss manadatory / optional components.

Here we are going to create 5 different distribution set types. They represent some combinations that we’ll allow.

String distributionSetType1 = "IxorTalk OS Image";
String distributionSetType2 = "IxorTalk OS Image with optional Software";
String distributionSetType3 = "IxorTalk OS Image with optional Software / Config";
String distributionSetType4 = "IxorTalk Software";
String distributionSetType5 = "IxorTalk Config";
String distributionSetType6 = "IxorTalk Software and Config";


// create one DistributionSetType
LOGGER.info("Creating distribution set type {}", distributionSetType1);
distributionSetTypeResource.createDistributionSetTypes(new DistributionSetTypeBuilder().key(distributionSetType1)
        .name(distributionSetType1).mandatorymodules(
        		createdSoftwareModuleTypes1.get(0).getModuleId()
        		).build());

LOGGER.info("Creating distribution set type {}", distributionSetType2);
distributionSetTypeResource.createDistributionSetTypes(new DistributionSetTypeBuilder().key(distributionSetType2)
        .name(distributionSetType2).mandatorymodules(
        		createdSoftwareModuleTypes1.get(0).getModuleId(),
        		createdSoftwareModuleTypes2.get(0).getModuleId()
        		).build());

LOGGER.info("Creating distribution set type {}", distributionSetType3);
distributionSetTypeResource.createDistributionSetTypes(new DistributionSetTypeBuilder().key(distributionSetType3)
        .name(distributionSetType3).mandatorymodules(
        		createdSoftwareModuleTypes1.get(0).getModuleId(),
        		createdSoftwareModuleTypes2.get(0).getModuleId(),
        		createdSoftwareModuleTypes3.get(0).getModuleId()
        		).build());

LOGGER.info("Creating distribution set type {}", distributionSetType4);
distributionSetTypeResource.createDistributionSetTypes(new DistributionSetTypeBuilder().key(distributionSetType4)
        .name(distributionSetType4).mandatorymodules(
        		createdSoftwareModuleTypes2.get(0).getModuleId()
        		).build());

LOGGER.info("Creating distribution set type {}", distributionSetType5);
distributionSetTypeResource.createDistributionSetTypes(new DistributionSetTypeBuilder().key(distributionSetType5)
        .name(distributionSetType5).mandatorymodules(
        		createdSoftwareModuleTypes3.get(0).getModuleId()
        		).build());

LOGGER.info("Creating distribution set type {}", distributionSetType6);
distributionSetTypeResource.createDistributionSetTypes(new DistributionSetTypeBuilder().key(distributionSetType6)
        .name(distributionSetType6).mandatorymodules(
        		createdSoftwareModuleTypes2.get(0).getModuleId(),
        		createdSoftwareModuleTypes3.get(0).getModuleId()
        		).build());

Distribution Set

An actual distribution set is based on the types above.

final String dsName1= "IxorTalk full distribution";
final String dsVersion1 = "1.0.0";
LOGGER.info("Creating distribution set {}:{}", dsName1, dsVersion1);
final List<DistributionSetRest> distributionSetsRest1 = distributionSetResource.createDistributionSets(
        new DistributionSetBuilder().name(dsName1).version(dsVersion1).type(distributionSetType3).build())
        .getBody();

final String dsName2= "IxorTalk SW distribution";
final String dsVersion2 = "2.0.0";
LOGGER.info("Creating distribution set {}:{}", dsName2, dsVersion2);
final List<DistributionSetRest> distributionSetsRest2 = distributionSetResource.createDistributionSets(
        new DistributionSetBuilder().name(dsName2).version(dsVersion2).type(distributionSetType4).build())
        .getBody();

final String dsName3= "IxorTalk Config distribution";
final String dsVersion3 = "2.1.0";
LOGGER.info("Creating distribution set {}:{}", dsName3, dsVersion3);
final List<DistributionSetRest> distributionSetsRest3 = distributionSetResource.createDistributionSets(
        new DistributionSetBuilder().name(dsName3).version(dsVersion3).type(distributionSetType5).build())
        .getBody();

Once the distribution types are created, we can start assigning software modules to them

LOGGER.info("Assign software module {}:{} to distribution set {}:{}", softwareModule1, swVersion1,
        dsName1, dsVersion1);
distributionSetResource.assignSoftwareModules(distributionSetsRest1.get(0).getDsId(),
        new SoftwareModuleAssigmentBuilder()
			.id(softwareModulesRest1.get(0).getModuleId())
			.id(softwareModulesRest2.get(0).getModuleId())
	        .id(softwareModulesRest3.get(0).getModuleId())
			.build());

LOGGER.info("Assign software module {}:{} to distribution set {}:{}", softwareModule2, swVersion2,
		dsName2, dsVersion2);
distributionSetResource.assignSoftwareModules(distributionSetsRest2.get(0).getDsId(),
        new SoftwareModuleAssigmentBuilder()
			.id(softwareModulesRest2.get(0).getModuleId())
			.build());

LOGGER.info("Assign software module {}:{} to distribution set {}:{}", softwareModule3, swVersion3,
		dsName3, dsVersion3);
distributionSetResource.assignSoftwareModules(distributionSetsRest3.get(0).getDsId(),
        new SoftwareModuleAssigmentBuilder()
	        .id(softwareModulesRest3.get(0).getModuleId())
			.build());

Full code

Here be a sample post with a custom background image. To utilize this “feature” just add the following YAML to a post’s front matter.

image:
  background: filename.png

This little bit of YAML makes the assumption that your background image asset is in the /images folder. If you place it somewhere else or are hotlinking from the web, just include the full http(s):// URL. Either way you should have a background image that is tiled. If the background image is transparent, the default background color will show through. Setting a background in a page/post will take precedence over the one set in _config.yml.

If you want to set a background image for the entire site just add background: filename.png to your _config.yml and BOOM — background images on every page!

Background images from Subtle Patterns (Subtle Patterns) / CC BY-SA 3.0
Syntax Highlighting Post

Syntax highlighting is a feature that displays source code, in different colors and fonts according to the category of terms. This feature facilitates writing in a structured language such as a programming language or a markup language as both structures and syntax errors are visually distinct. Highlighting does not affect the meaning of the text itself; it is intended only for human readers.1

Highlighted Code Blocks

To modify styling and highlight colors edit /_sass/_syntax.scss.

#container {
    float: left;
    margin: 0 -240px 0 0;
    width: 100%;
}
<nav class="pagination" role="navigation">
    {% if page.previous %}
        <a href="{{ site.url }}{{ page.previous.url }}" class="btn" title="{{ page.previous.title }}">Previous article</a>
    {% endif %}
    {% if page.next %}
        <a href="{{ site.url }}{{ page.next.url }}" class="btn" title="{{ page.next.title }}">Next article</a>
    {% endif %}
</nav><!-- /.pagination -->
module Jekyll
  class TagIndex < Page
    def initialize(site, base, dir, tag)
      @site = site
      @base = base
      @dir = dir
      @name = 'index.html'
      self.process(@name)
      self.read_yaml(File.join(base, '_layouts'), 'tag_index.html')
      self.data['tag'] = tag
      tag_title_prefix = site.config['tag_title_prefix'] || 'Tagged: '
      tag_title_suffix = site.config['tag_title_suffix'] || '&#8211;'
      self.data['title'] = "#{tag_title_prefix}#{tag}"
      self.data['description'] = "An archive of posts tagged #{tag}."
    end
  end
end

Standard Code Block

<nav class="pagination" role="navigation">
    {% if page.previous %}
        <a href="{{ site.url }}{{ page.previous.url }}" class="btn" title="{{ page.previous.title }}">Previous article</a>
    {% endif %}
    {% if page.next %}
        <a href="{{ site.url }}{{ page.next.url }}" class="btn" title="{{ page.next.title }}">Next article</a>
    {% endif %}
</nav><!-- /.pagination -->

Fenced Code Blocks

To modify styling and highlight colors edit /_sass/_coderay.scss. Line numbers and a few other things can be modified in _config.yml. Consult Jekyll’s documentation for more information.

#container {
    float: left;
    margin: 0 -240px 0 0;
    width: 100%;
}
<nav class="pagination" role="navigation">
    {% if page.previous %}
        <a href="{{ site.url }}{{ page.previous.url }}" class="btn" title="{{ page.previous.title }}">Previous article</a>
    {% endif %}
    {% if page.next %}
        <a href="{{ site.url }}{{ page.next.url }}" class="btn" title="{{ page.next.title }}">Next article</a>
    {% endif %}
</nav><!-- /.pagination -->
module Jekyll
  class TagIndex < Page
    def initialize(site, base, dir, tag)
      @site = site
      @base = base
      @dir = dir
      @name = 'index.html'
      self.process(@name)
      self.read_yaml(File.join(base, '_layouts'), 'tag_index.html')
      self.data['tag'] = tag
      tag_title_prefix = site.config['tag_title_prefix'] || 'Tagged: '
      tag_title_suffix = site.config['tag_title_suffix'] || '&#8211;'
      self.data['title'] = "#{tag_title_prefix}#{tag}"
      self.data['description'] = "An archive of posts tagged #{tag}."
    end
  end
end

Sample Link Post

This theme supports link posts, made famous by John Gruber. To use, just add link: http://url-you-want-linked to the post’s YAML front matter and you’re done.