DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Please enter at least three characters to search
Refcards Trend Reports
Events Video Library
Refcards
Trend Reports

Events

View Events Video Library

Zones

Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks

Last call! Secure your stack and shape the future! Help dev teams across the globe navigate their software supply chain security challenges.

Modernize your data layer. Learn how to design cloud-native database architectures to meet the evolving demands of AI and GenAI workloads.

Releasing software shouldn't be stressful or risky. Learn how to leverage progressive delivery techniques to ensure safer deployments.

Avoid machine learning mistakes and boost model performance! Discover key ML patterns, anti-patterns, data strategies, and more.

Related

  • A Comparison of Current Kubernetes Distributions
  • 7 Microservices Best Practices for Developers
  • How Your Application Architecture Has Evolved
  • Minions in Minikube - A Kubernetes Intro for Java Developers

Trending

  • DGS GraphQL and Spring Boot
  • Start Coding With Google Cloud Workstations
  • The Cypress Edge: Next-Level Testing Strategies for React Developers
  • Ethical AI in Agile
  1. DZone
  2. Testing, Deployment, and Maintenance
  3. Deployment
  4. Apache Karaf Microservices

Apache Karaf Microservices

Apache Karaf provides a lightweight container for deploying various components and applications. Learn to set up Karaf on Docker.

By 
Piotr Mińkowski user avatar
Piotr Mińkowski
·
May. 16, 17 · Tutorial
Likes (12)
Comment
Save
Tweet
Share
24.3K Views

Join the DZone community and get the full member experience.

Join For Free

Apache Karaf is a small OSGi based runtime which provides a lightweight container onto which various components and applications can be deployed.

Apache Karaf can be run as a standalone container and provides some enterprise-ready features like shell console, remote access, hot deployment, and dynamic configuration. It can be the perfect solution for microservices. The idea of microservices on Apache Karaf has already been introduced a few years ago. In March of 2010, Peter Kriens, software architect at OSGi Alliance, said, “What I am promoting is the idea of µServices, the concepts of an OSGi service as a design primitive.”

Karaf on Docker

First, we need to run Docker container with Apache Karaf. Surprisingly, there is no official repository with such an image. I found an image on Docker Hub with Karaf here. Unfortunately, there is no port 8181 exposed – default Karaf web port. We will use this image to create our own with 8181 port available outside. Here’s our Dockerfile.

FROM java:8-jdk
MAINTAINER Piotr Minkowski <piotr.minkowski@gmail.com>
ENV JAVA_HOME /usr/lib/jvm/java-8-openjdk-amd64

ENV KARAF_VERSION=4.0.8

RUN wget http://www-us.apache.org/dist/karaf/${KARAF_VERSION}/apache-karaf-${KARAF_VERSION}.tar.gz; \
    mkdir /opt/karaf; \
    tar --strip-components=1 -C /opt/karaf -xzf apache-karaf-${KARAF_VERSION}.tar.gz; \
    rm apache-karaf-${KARAF_VERSION}.tar.gz; \
    mkdir /deploy; \
    sed -i 's/^\(felix\.fileinstall\.dir\s*=\s*\).*$/\1\/deploy/' /opt/karaf/etc/org.apache.felix.fileinstall-deploy.cfg

VOLUME ["/deploy"]
EXPOSE 1099 8101 8181 44444
ENTRYPOINT ["/opt/karaf/bin/karaf"]

Then, by running Docker commands below we are building our image from Dockerfile and starting new Karaf container.

docker build -t karaf-api .
docker run -d --name karaf -p 1099:1099 -p 8101:8101 -p 8181:8181 -p 44444:44444 karaf-api

Now, we can login to a new Docker container. Karaf is installed in /opt/karaf directory. We should run the client by calling ./client in /opt/karaf/bin directory. Then we should install Apache Felix web console which is by default available under port 8181. You can check it out by calling on web browser http://192.168.99.100:8181/system/console. The default username and password is karaf. In the web console, you can check the full list of features installed on our OSGi container. You can also display that list in the Karaf console using the feature:list command. After web console installation, you decide if you prefer using Karaf command line or Apache Felix console for further actions. For our sample application, we need to add some OSGi repositories and features. First, we are adding Apache CXF framework repository and its features for HTTP and RESTful web services. Then we are adding a repository for the jackson framework and some jackson and Jetty server features.

docker exec -i -t karaf /bin/bash (1)
cd /opt/karaf/bin
./client (2)
karaf@root()> feature:install webconsole (3)
karaf@root()> feature:list (4)
karaf@root()> feature:repo-add cxf 3.1.10 (5)
karaf@root()> feature:install http cxf-jaxrs cxf (6)
karaf@root()> feature:repo-add mvn:org.code-house.jackson/features/2.7.6/xml/features (7)
karaf@root()> feature:install jackson-jaxrs-json-provider jetty (8)

Microservices

Our environment has been configured. Now, we can take a brief look at the sample application. It’s really simple. It has only three modules: account-cxf, customer-cxf, sample-api. In the sample-api module, we have base service interfaces and model objects. In account-cxf and customer-cxf, there are service implementations and OSGi services declarations in the Blueprint file. The sample application source code is available on GitHub. Here’s the account service controller class and its interface below.

public class AccountServiceImpl implements AccountService {

    private List<Account> accounts;

    public AccountServiceImpl() {
        accounts = new ArrayList<>();
        accounts.add(new Account(1, "1234567890", 12345, 1));
        accounts.add(new Account(2, "1234567891", 6543, 2));
        accounts.add(new Account(3, "1234567892", 45646, 3));
    }

    public Account findById(Integer id) {
        return accounts.stream().filter(a -> a.getId().equals(id)).findFirst().get();
    }

    public List<Account> findAll() {
        return accounts;
    }

    public Account add(Account account) {
        accounts.add(account);
        account.setId(accounts.size());
        return account;
    }

    @Override
    public List<Account> findAllByCustomerId(Integer customerId) {
        return accounts.stream().filter(a -> a.getCustomerId().equals(customerId)).collect(Collectors.toList());
    }

}

TheAccountService interface is in the sample-api module. We use JAX-RS annotations for declaring REST endpoints.

public interface AccountService {

    @GET
    @Path("/{id}")
    @Produces("application/json")
    public Account findById(@PathParam("id") Integer id);

    @GET
    @Path("/")
    @Produces("application/json")
    public List<Account> findAll();

    @GET
    @Path("/customer/{customerId}")
    @Produces("application/json")
    public List<Account> findAllByCustomerId(@PathParam("customerId") Integer customerId);

    @POST
    @Path("/")
    @Consumes("application/json")
    @Produces("application/json")
    public Account add(Account account);

}

Here you can see the OSGi services declaration in the blueprint.xml file. We have declared theAccountServiceIpl bean and set that bean as a service for JAX-RS endpoint. This endpoint uses JacksonJsonProvider as a data format provider. There is also an important OSGi service declaration with AccountService referencing  AccountServiceImpl. This service will be available for other microservices deployed on the Karaf container, for example, customer-cxf.

<cxf:bus id="accountRestBus">
</cxf:bus>

<bean id="accountServiceImpl" class="pl.piomin.services.cxf.account.service.AccountServiceImpl"/>
<service ref="accountServiceImpl" interface="pl.piomin.services.cxf.api.AccountService" />

<jaxrs:server address="/account" id="accountService">
    <jaxrs:serviceBeans>
        <ref component-id="accountServiceImpl" />
    </jaxrs:serviceBeans>
    <jaxrs:features>
        <cxf:logging />
    </jaxrs:features>
    <jaxrs:providers>
        <bean class="com.fasterxml.jackson.jaxrs.json.JacksonJsonProvider"/>
    </jaxrs:providers>
</jaxrs:server>

Now, let’s take a look at the customer-cxf microservice. Here’s the OSGi blueprint of that service. The JAX-RS server declaration is pretty similar to account-cxf. There is only one addition to the earlier OSGi blueprint – the reference to AccountService. This reference is injected into CustomerServiceImpl.

<reference id="accountService"       interface="pl.piomin.services.cxf.api.AccountService" />

<bean id="customerServiceImpl"       class="pl.piomin.services.cxf.customer.service.CustomerServiceImpl">
    <property name="accountService" ref="accountService" />
</bean>

<jaxrs:server address="/customer" id="customerService">
    <jaxrs:serviceBeans>
        <ref component-id="customerServiceImpl" />
    </jaxrs:serviceBeans>
    <jaxrs:features>
        <cxf:logging />
    </jaxrs:features>
    <jaxrs:providers>
        <bean class="com.fasterxml.jackson.jaxrs.json.JacksonJsonProvider" />
    </jaxrs:providers>
</jaxrs:server>

CustomerService uses an OSGi reference to AccountService in findById method to collect all accounts belonged to the customer with the specified id path parameter, and also exposes some other operations.

public class CustomerServiceImpl implements CustomerService {

    private AccountService accountService;

    private List<Customer> customers;

    public CustomerServiceImpl() {
        customers = new ArrayList<>();
        customers.add(new Customer(1, "XXX", "1234567890"));
        customers.add(new Customer(2, "YYY", "1234567891"));
        customers.add(new Customer(3, "ZZZ", "1234567892"));
    }

    @Override
    public Customer findById(Integer id) {
        Customer c = customers.stream().filter(a -> a.getId().equals(id)).findFirst().get();
        c.setAccounts(accountService.findAllByCustomerId(id));
        return c;
    }

    @Override
    public List<Customer> findAll() {
        return customers;
    }

    @Override
    public Customer add(Customer customer) {
        customers.add(customer);
        customer.setId(customers.size());
        return customer;
    }

    public AccountService getAccountService() {
        return accountService;
    }

    public void setAccountService(AccountService accountService) {
        this.accountService = accountService;
    }

}

Each service has a packaging type bundle inside pom.xml and uses maven-bundle-plugin during the build process. After running mvn clean install on the root project, all bundles will be generated in the target catalog.You can install them using Apache Felix web console or Karaf command line client in that order: sample-api, account-cxf, customer-cxf.

Testing

Finally, you can see a list of available CXF endpoints on Karaf by calling http://192.168.99.100:8181/cxf in your web browser. Call http://192.168.99.100:8181/cxf/customer/1 to test findById in CustomerService. You should see JSON with customer data and all accounts collected from the account microservice.

Treat this post as a short introduction to microservices conception on the Apache Karaf OSGi container. I presented how to use CXF endpoints on the Karaf container as a kind of service gateway and OSGi services for inter-communication process between deployed microservices. Instead of the OSGi reference, we could use JAX-RS proxy client for connecting with account service from customer service. You can find some basic examples of that concept on the web. There are also available more advanced solutions for service registration and discovery on Karaf: for example, remote service call with Apache ZooKeeper. I think we will take a closer look at them in subsequent posts.

microservice Docker (software) Web Service

Published at DZone with permission of Piotr Mińkowski, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

Related

  • A Comparison of Current Kubernetes Distributions
  • 7 Microservices Best Practices for Developers
  • How Your Application Architecture Has Evolved
  • Minions in Minikube - A Kubernetes Intro for Java Developers

Partner Resources

×

Comments
Oops! Something Went Wrong

The likes didn't load as expected. Please refresh the page and try again.

ABOUT US

  • About DZone
  • Support and feedback
  • Community research
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Core Program
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 100
  • Nashville, TN 37211
  • support@dzone.com

Let's be friends:

Likes
There are no likes...yet! 👀
Be the first to like this post!
It looks like you're not logged in.
Sign in to see who liked this post!