GithubHelp home page GithubHelp logo

apache / karaf-minho Goto Github PK

View Code? Open in Web Editor NEW
6.0 11.0 5.0 15.24 MB

Apache Karaf Minho

Home Page: https://karaf.apache.org/

License: Apache License 2.0

Java 98.62% Shell 1.38%
cloud karaf minho modulith osgi runtime service spring-boot

karaf-minho's Introduction

Apache Karaf Minho

Github CI Build Github CI Deploy

Apache Karaf Minho is an application runtime, able to operate different kind of applications using application manager services.

It provides extensible launchers per application kind and out of the box services that any application running on Minho can leverage without cost.

Apache Karaf Minho is composed by:

  • Minho boot (Minho) bootstraps the runtimes for your applications, the runtimes are discovered and extensible
  • an API to interact with the boot if you need
  • profiles to easily add cross runtimes dependencies
  • services to easily add cross runtimes features (log, configurations, URL handlers, ...)
  • boot applications

Minho boot can be described/configure programmatically or by a provided JSON file.

Minho Boot

Minho boot is the main runtime orchestrator. It basically loads Minho Services via SPI, and it's configured via Config.

Config can be provided programmatically:

Config config = new Config();
...
Minho minho = Minho.build(config);
minho.init();
minho.start();

or loaded from an external resource like minho.json:

{
 "properties": {
    "foo": "bar"
 },
 "applications": [
    {
        "url": "/path/to/my/jar"
    }
 ]
}

Minho Boot is looking for minho.json file (aka Minho Config):

  • as system property: -Dminho.config=/path/to/minho.json
  • as environment variable: export MINHO_CONFIG=/path/to/minho.json
  • in the current classpath

Minho Services

A Minho Service is a class implementing the org.apache.karaf.minho.boot.spi.Service interface, and loaded via META-INF/services/org.apache.karaf.minho.boot.spi.Service, containing the FQDN of the implementation class.

The service doesn't have to implement any method by default. Optionally, you can define the following methods:

public class MyService implements org.apache.karaf.minho.boot.spi.Service {
    
    @Override
    public String name() {
        // return the service name
        return "my-service";
    }
    
    @Override
    public void onRegister(ServiceRegistry serviceRegistry) throws Exception {
        // callback method, called when the service is registered in the Minho Service Registry
        // you can interact with the Minho Service Registry `serviceRegistry` here, looking for services, etc
    }
    
    @Override
    public int priority() {
        // return the service priority, default is 1000. Lower priority are started before higher priority.
        return 1001;
    }
    
}

Runtime

Minho Boot provides a runtime with:

  • a launcher
  • a service registry (ServiceRegistry) where all services will be located
  • a config service (ConfigService) loads Minho config
  • a lifecycle service (LifeCycleService) is responsible to callback start and stop methods from the services

Then, org.apache.karaf.minho.boot.Karaf launcher can start (Minho.builder().build().start()) all Minho services located in the classloader, you can repackage all dependencies (jar) in a single uber jar.

Minho itself provides several "additional" services:

  • classpath: protocol handler
  • archive extractor
  • JSON configuration loader
  • Properties configuration loader
  • welcome banner
  • a much more! (take a look on the documentation for details)

Application manager services can also deploy "third party" applications, for instance:

  • OSGi application manager is able to deploy OSGi applications (bundles, Karaf 4 features)
  • Spring Boot application manager is able to deploy Spring Boot applications

Minho Services can be configured via the properties, using the service name as prefix.

You can configure launcher in minho.json:

    "properties": {
        "osgi.storageDirectory": "/path/to/storage",
        "spring-boot.cache": "/path/to/cache
    },

Each service is responsible to retrieve the Config service from the service registry, and get the properties.

Third party applications

When you use a third party application manager service, you can define the applications you want to deploy via Config service.

For instance, you can use the following minho.json configuration file:

{
  "properties": {
    "osgi.storageDirectory": "path/to/store",
    "osgi.cache": "path/to/cache"
  },
  "applications": [
    {
      "url": "https://repo1.maven.org/maven2/commons-lang/commons-lang/2.6/commons-lang-2.6.jar",
      "type": "osgi"
    }
  ]
}

Here, you can see how to configure and deploy commons-lang-2.6.jar in the OSGi application manager.

Run

You can use Apache Karaf Minho in your code, simply bootstrapping it and running with:

Minho minho = Minho.build(config);
minho.init();
minho.start();

or simply run with a minho.json:

$ java -jar minho.jar -Dminho.config=minho.json

Minho is launching all you describe in the minho.json.

karaf-minho's People

Contributors

dependabot[bot] avatar fpapon avatar iskey avatar jbonofre avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

karaf-minho's Issues

Improve Maven Parser dependencies resolver

Maven Parser.getDependencies() is not accurate:

  • it doesn't retrieve all dependencies
  • it fails to resolve some transitive dependencies

It should mimic the maven-dependency-plugin resolve mojo and the result should be the same as dependency:resolve goal.

Should the `JettyWebContainerService` has a higher priority than the `JerseyRestService` ?

It seems that the JettyWebContainerService should have a higher priority than JerseyRestService.

On the Ubuntu 22.04.1 LTS distribution, I got this error.

2023-01-17 14:56:21 INFO   org.apache.karaf.minho.boot.service.ServiceRegistry add Adding minho-rest-service service (1000)
Exception in thread "main" java.lang.IllegalStateException: Can't register minho-rest-service
	at org.apache.karaf.minho.boot.service.ServiceRegistry.add(ServiceRegistry.java:88)
	at java.base/java.util.stream.ForEachOps$ForEachOp$OfRef.accept(ForEachOps.java:183)
	at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
	at java.base/java.util.stream.SortedOps$RefSortingSink.end(SortedOps.java:395)
	at java.base/java.util.stream.Sink$ChainedReference.end(Sink.java:258)
	at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:510)
	at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:499)
	at java.base/java.util.stream.ForEachOps$ForEachOp.evaluateSequential(ForEachOps.java:150)
	at java.base/java.util.stream.ForEachOps$ForEachOp$OfRef.evaluateSequential(ForEachOps.java:173)
	at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
	at java.base/java.util.stream.ReferencePipeline.forEach(ReferencePipeline.java:596)
	at org.apache.karaf.minho.boot.Minho.start(Minho.java:58)
	at org.apache.karaf.minho.boot.Main.main(Main.java:63)
Caused by: java.lang.IllegalStateException: minho-http-service is not found in the service registry
	at org.apache.karaf.minho.rest.jersey.JerseyRestService.onRegister(JerseyRestService.java:52)
	at org.apache.karaf.minho.boot.service.ServiceRegistry.add(ServiceRegistry.java:86)
	... 12 more

Add exploded mode support in spring-boot

Right now, Minho only supports repackaged spring boot application jar, wrapping all jar in uber jar. Then, Minho uses JarLauncher to launch the spring boot application.

However, this is not the running mode recommended by spring boot. Minho should support running spring boot application in exploded mode (similar to spring-boot:run maven goal).

It means that Minho needs:

  • to scan @SpringBootApplication annotation to find the Main class
  • to have a way (using spring boot app pom for instance) to find all dependencies to populate the classloader, leveraging Minho tooling for instance
  • don't use JarLauncher but create classloader and run instead

This preparation step should be performed at build time (in Minho tooling), not at build time.

Add `minho-k8s` service

The idea is to create a Kubernetes client as a service in the registry.

Then, other services can get the client from the registry and interact with k8s.

Move to minho namespace and hide karaf one

Goal of this ticket is to use groupId and package org.apache.minho and not mention karaf in it since project is quite indenpendent.
Will likely help to understand what we run, in particular when we'll run OSGi container (Apache Karaf) inside Apache Karaf Minho.

Side note: important step: request minho group to infra on nexus.

`minho-spring-boot` application manager should look for `spring-boot` type

Currently, the minho-spring-boot application manager is looking for application type minho-spring-boot-module-manager-service due to the following code snippet:

                if (application.getType() == null) {
                    if (canHandle(application.getUrl())) {
                        applications.add(application);
                    }
                } else if (application.getType().equals(name())) {
                    applications.add(application);
                }

This is wrong as it uses name() method which is different from the expected type value.

Improve message when spring-boot application is not found

With the minho-spring-boot application manager, the user can load several spring-boot application via the ConfigService#Applications. For instance, he can define spring-boot applications via minho.json file:

{
  "applications": [
    {
      "name": "one-app",
      "type": "spring-boot",
      "url": "file:./app/my-spring-boot-app-1.0-SNAPSHOT.jar",
      "properties": {
        "args": "--server.port=8181"
      }
    }
  ]
}

If the minho-spring-boot application manager doesn't find the jar on the provided url, the user get this error:

INFO: Starting Spring Boot module file:./app/my-spring-boot-app-1.0-SNAPSHOT.jar
Exception in thread "main" java.lang.IllegalStateException: Can't start lifecycle service
        at org.apache.karaf.minho.boot.service.LifeCycleService.start(LifeCycleService.java:66)
        at org.apache.karaf.minho.boot.service.ServiceRegistry.lambda$start$2(ServiceRegistry.java:128)
        at java.base/java.util.Optional.ifPresent(Optional.java:178)
        at org.apache.karaf.minho.boot.service.ServiceRegistry.start(ServiceRegistry.java:126)
        at org.apache.karaf.minho.boot.Minho.start(Minho.java:59)
        at org.apache.karaf.minho.boot.Main.main(Main.java:63)
        Suppressed: java.lang.RuntimeException: Can't start Spring Boot module file:./app/my-spring-boot-app-1.0-SNAPSHOT.jar
                at org.apache.karaf.minho.springboot.SpringBootApplicationManagerService.lambda$onRegister$0(SpringBootApplicationManagerService.java:57)
                at java.base/java.lang.Iterable.forEach(Iterable.java:75)
                at org.apache.karaf.minho.springboot.SpringBootApplicationManagerService.lambda$onRegister$1(SpringBootApplicationManagerService.java:53)
                at org.apache.karaf.minho.boot.service.LifeCycleService.lambda$start$0(LifeCycleService.java:69)
                at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
                at org.apache.karaf.minho.boot.service.LifeCycleService.start(LifeCycleService.java:67)
                ... 5 more
        Caused by: java.lang.ClassNotFoundException: org.springframework.boot.loader.JarLauncher
                at java.base/java.net.URLClassLoader.findClass(URLClassLoader.java:445)
                at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:587)
                at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:520)
                at org.apache.karaf.minho.springboot.SpringBootApplicationManagerService.start(SpringBootApplicationManagerService.java:106)
                at org.apache.karaf.minho.springboot.SpringBootApplicationManagerService.lambda$onRegister$0(SpringBootApplicationManagerService.java:55)
                ... 10 more

It could be confusing as the problem is not really ClassNotFoundException: org.springframework.boot.loader.JarLauncher but actually the application jar file is not found.

The minho-spring-boot application manager should first check if the jar exists on the provided URL and throw a clean message if not.

Add `minho-py` service

We can use graalvm for python in the minho-pyservice.
Using JSR223, we can eventually abstract the language.
The challenge is to handle the env setup (using pipenv or like).

Add OSGi service registry bridge

The purpose of the OSGi bridge service is to register an OSGi service tracker, listening any OSGi service and exposing these services in the Minho ServiceRegistry.

Add filtering support on `ServiceRegistry`

It's possible to register several services with the same class in the ServiceRegistry.
In that case, it would be great to extend the service registry with a service key/name, and be able to do serviceRegistry.get("key", MyInterface.class).

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.