Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

Creating Java-Based Microservices for Abixen Platform: Part 3

DZone's Guide to

Creating Java-Based Microservices for Abixen Platform: Part 3

This installment in the Java-based microservices series will show you how to configure your newly created custom functional microservice in Abixen Platform.

· Integration Zone
Free Resource

Share, secure, distribute, control, and monetize your APIs with the platform built with performance, time-to-value, and growth in mind. Free 90-day trial of 3Scale by Red Hat

This article on the configuration of a newly created functional microservice in Abixen Platform. The project is available on GitHub. Creating a custom functional microservice using the benefits delivered by Abixen Platform is simple work for a developer. All he has to do is to extend the existing API and do an implementation. Leveraging helps as well to keep the high standards of the custom code, in accordance with good practices served by the application.

Configuration of Spring Beans

Since we are going to create a microservice based on Spring Boot, we have to configure a main application’s class. In our example let’s call the class as PlatformWebContentApplication. Below you can find a source code of the class:

@EnableRetry
@SpringBootApplication
@EnableRedisHttpSession
@EnableEurekaClient
@EnableCircuitBreaker
@EnableFeignClients(basePackages = {PlatformWebContentServicePackages.CLIENT})
public class PlatformWebContentApplication extends SpringBootServletInitializer {

    @Override
    protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
        return application.sources(PlatformWebContentApplication.class);
    }

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

}

There are annotations here to configure our application in an elegant way:

  • @EnableRetry: allows a connection to a configuration server to be re-tried.

  • @SpringBootApplication: makes it as a Spring Boot application.

  • @EnableRedisHttpSession: because we are going to share sessions across all microservices.

  • @EnableEurekaClient: allows use of a convenient API of registry service.

  • @EnableCircuitBreaker: tells Spring Cloud that a reading application uses circuit breakers and to enable their monitoring, opening, and closing. It's supported by Hystrix.

  • @EnableFeignClients: allows use of Feign Client - an easy API to communicate with others microservices.

The next class we have to describe is PlatformWebContentServiceConfiguration with the following listing:

@Configuration
@ComponentScan(basePackages = {CONFIG, CONTROLLER, FACADE, SERVICE, REPOSITORY, CONVERTER, COMMON_CONVERTER, INTEGRATION, SECURITY})
public class PlatformWebContentServiceConfiguration {

}

It is a very simple configuration class indicating which packages should be scanned by Spring.

Our microservice will use a database. That's why it's desirable to do a database configuration. For this purpose, we will create three configuration classes: PlatformWebContentServiceDataSourceConfiguration, PlatformWebContentServiceJpaConfiguration, and PlatformWebContentServiceLiquibaseConfiguration.

The first of them, PlatformWebContentServiceDataSourceConfiguration, is responsible for a configuration of datasource:

package com.abixen.platform.service.webcontent.configuration;

import com.abixen.platform.common.configuration.AbstractPlatformDataSourceConfiguration;
import org.springframework.context.annotation.Configuration;


@Configuration
public class PlatformWebContentServiceDataSourceConfiguration extends AbstractPlatformDataSourceConfiguration {

}

As you can see, Abixen Platform provides ready-made abstract classes to be inherited. For datasources, there is AbstractPlatformDataSourceConfiguration. Doing a really small piece of code we can implement a bean of the datasource configuration. The next one is PlatformWebContentServiceJpaConfiguration and is responsible for JPA configuration, since we are going to use Spring Data JPA:

@Configuration
@Import(PlatformWebContentServiceDataSourceConfiguration.class)
@EnableTransactionManagement
@EnableJpaAuditing(auditorAwareRef = "platformAuditorAware")
@EnableJpaRepositories(basePackages = {PlatformWebContentServicePackages.REPOSITORY})
public class PlatformWebContentServiceJpaConfiguration extends AbstractJpaConfiguration {

    @Autowired
    public PlatformWebContentServiceJpaConfiguration(DataSource dataSource, AbstractPlatformJdbcConfigurationProperties platformJdbcConfiguration) {
        super(dataSource, platformJdbcConfiguration, PlatformWebContentServicePackages.DOMAIN);
    }

    public AuditorAware platformAuditorAware() {
        return new PlatformAuditorAware();
    }
}

Similarly, we can also inherit from an abstract class AbstractJpaConfiguration and implement a few lines of code getting a comprehensive configuration of JPA with following functionalities:

  • Transactional: because we have the annotation @EnableTransactionManagement.

  • Auditing mechanism: referring to platformAuditorAware from the common package of Abixen Platform, we have this functionality.

  • Repositories of Spring Data JPA: adding the annotation EnableJpaRepositories and indicating a package which must be scanned.

At the end of database-related configuration, we would like to manage versions of SQL scripts using Liquibase; that's why we have to add its configuration:

package com.abixen.platform.service.webcontent.configuration;

import com.abixen.platform.common.configuration.AbstractLiquibaseConfiguration;
import org.springframework.context.annotation.Configuration;


@Configuration
public class PlatformWebContentServiceLiquibaseConfiguration extends AbstractLiquibaseConfiguration {

}

All we have to do is add a new configuration class inheriting from the AbstractLiquibaseConfiguration class. Besides this class, we have to add XML files of the configuration for particular settings.

Our microservice will be secured by Spring Security. We need to configure it:

@EnableWebSecurity
@Configuration
public class PlatformWebContentServiceSecurityConfiguration extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
                .authorizeRequests()
                .antMatchers("/api/configuration").permitAll()
                .antMatchers("/service/abixen/web-content/application/**").permitAll()
                .antMatchers("/service/abixen/web-content/control-panel/**").permitAll()
                .anyRequest().authenticated()
                .and()
                .httpBasic().disable();
    }

}

This configuration class comprises regular configurations of Spring Security. Since each functional microservice must keep a configuration endpoint (the core microservice gets configuration over this address) a developer is obliged to permit the endpoint /api/configuration for all of them. Moreover, it is required to permit access to static resources, both the application part and the control panel one ( /service/abixen/web-content/application/** )

and /service/abixen/web-content/control-panel/** ) for all.

A functional microservice can manage its internal objects. In a case when a user would like to remove an instance of the microservice using the Enterprise Content Managment System delivered by Abixen Platform, the microservice must clean up owned objects. For that, the platform has an embedded mechanism of communication over the queue, RabbitMQ. We have to define a configuration:

@Profile({DEV, DOCKER})
@Slf4j
@Configuration
public class PlatformModuleRabbitMQConfiguration extends AbstractRabbitMQConfiguration {

    private static final String QUEUE_NAME = "abixen-platform-web-content-service";


    public PlatformModuleRabbitMQConfiguration() {
        super(QUEUE_NAME);
    }

    @Bean
    MessageListenerAdapter listenerAdapter(MessageReceiver messageReceiver) {
        return new MessageListenerAdapter(messageReceiver, "receiveMessage");
    }

}

Like for previous configurations, we can inherit from an abstract class called AbstractRabbitMQConfiguration and prepare a short configuration. The core microservice will automatically notify our microservice over this channel.

Abixen Platform supports Spring Sleuth as well. We can realize it in our microservice by adding a short configuration:

package com.abixen.platform.service.webcontent.configuration;

import com.abixen.platform.common.configuration.AbstractSleuthConfiguration;
import org.springframework.context.annotation.Configuration;

@Configuration
public class PlatformWebContentServiceSleuthConfiguration extends AbstractSleuthConfiguration {

}

The configuration bean must inherit of AbstractSleuthConfiguration, and that's it!

What Next?

In the first three articles of this series, I have gone through a preparation of the most important and needed configuration files. In the next article, I’m going to depict how a technical structure is designed in the functional microservice of Abixen Platform.

Explore the core elements of owning an API strategy and best practices for effective API programs. Download the API Owner's Manual, brought to you by 3Scale by Red Hat

Topics:
spring cloud ,microservice architecture ,microservices ,abixen platform

Opinions expressed by DZone contributors are their own.

THE DZONE NEWSLETTER

Dev Resources & Solutions Straight to Your Inbox

Thanks for subscribing!

Awesome! Check your inbox to verify your email so you can start receiving the latest in tech news and resources.

X

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}