JavaMelody
=========================

The goal of JavaMelody is to monitor Java or Java EE applications in QA and production environments.

See the [Project Home](../../wiki), [Screenshots](../../wiki/Screenshots#charts), [User's guide](../../wiki/UserGuide) and [Release notes](../../wiki/ReleaseNotes) in the wiki,
or see downloads in [Releases](../../releases), [Issues](../../issues) and [Pull requests](../../pulls).

License [Apache-2.0](http://www.apache.org/licenses/LICENSE-2.0)

[![Maven Central](https://maven-badges.herokuapp.com/maven-central/net.bull.javamelody/javamelody-core/badge.svg)](https://maven-badges.herokuapp.com/maven-central/net.bull.javamelody/javamelody-core)
[![Percentage of issues still open](http://isitmaintained.com/badge/open/javamelody/javamelody.svg)](http://isitmaintained.com/project/javamelody/javamelody "Percentage of issues still open")
[![Build Status](https://travis-ci.com/javamelody/javamelody.svg?branch=master)](https://travis-ci.com/javamelody/javamelody)
![GitHub stars](https://img.shields.io/github/stars/javamelody/javamelody?style=social)
![Twitter Follow](https://img.shields.io/twitter/follow/java_melody?label=Follow&style=social)


# Welcome to Spine Event Engine

[![Ubuntu build][ubuntu-build-badge]][gh-actions]
[![codecov.io](https://codecov.io/github/SpineEventEngine/core-java/coverage.svg?branch=master)](https://codecov.io/github/SpineEventEngine/core-java?branch=master)
[![license](https://img.shields.io/badge/license-Apache%20License%202.0-blue.svg?style=flat)](http://www.apache.org/licenses/LICENSE-2.0)

[gh-actions]: https://github.com/SpineEventEngine/core-java/actions
[ubuntu-build-badge]: https://github.com/SpineEventEngine/core-java/actions/workflows/build-on-ubuntu.yml/badge.svg

[Spine Event Engine][spine-site] is a Java framework for building Event Sourcing and CQRS
applications that are accessed by clients built with JavaScript, Java Nano (Android), Dart, and Java.

## Releases

The project is under active ongoing development.
You are welcome to experiment and [provide your feedback][email-developers].

The latest stable version is [1.9.0][latest-release].

## Contents

This repository contains the code of:
 - core types;
 - client API;
 - server API;
 - testing utilities for the client- and server-side code.

## Quick start and examples

Please see the [“Quick Start” guide][quick-start] which goes through a Hello World project showing
how to create a Spine-based project.

More introductory application examples are available from
the [Spine Examples][spine-examples] GitHub organization.

## Building from sources

Starting version `2.0.0-SNAPSHOT.82` building Spine modules requires JDK 11. Prior versions
could be built with JDK 8 only.

Gradle is used as a build and dependency management system.

This repository uses [configuration files][config] shared across several Spine libs. They are
plugged in as a Git sub-module. Please use the following command to initialize it:

```sh
git submodule update --init --recursive
```

Also, a `pull` script is located in the root of `core-java` repository. Use it to update to the
latest version of the configuration files.

## Important warnings
* The code annotated with `@Internal` are not parts of public API of the framework, therefore should
  not be used from outside of the framework.

* The public API marked as `@Experimental` may be used at own risk; it can change at any time,
  and has no guarantee of API stability or backward-compatibility.

* The API annotated with `@SPI` is for those who intend to extend the framework,
  or provide custom storage implementations.

If you need to use API with one of these annotations, please [contact us][email-developers].

[email-developers]: mailto:developers@spine.io
[latest-release]: https://github.com/SpineEventEngine/core-java/releases/tag/v1.9.0
[spine-site]: https://spine.io/
[quick-start]: https://spine.io/docs/quick-start
[spine-examples]: https://github.com/spine-examples
[todo-list]: https://github.com/spine-examples/todo-list
[v2]: https://github.com/orgs/SpineEventEngine/projects/13
[config]: https://github.com/SpineEventEngine/config/


Annotation Tools README file
----------------------------

This directory contains the Annotation Tools.
Its main component is the Annotation File Utilities.

The Annotation File Utilities homepage and documentation is at
  https://checkerframework.org/annotation-file-utilities/
and it also appears in this repository as
  `annotation-file-utilities/annotation-file-utilities.html` .


## Overview
core-ng is a webapp framework, it's designed to support our own projects.

[![Build](https://github.com/neowu/core-ng-project/actions/workflows/build.yml/badge.svg)](https://github.com/neowu/core-ng-project/actions/workflows/build.yml)
[![CodeQL](https://github.com/neowu/core-ng-project/actions/workflows/codeql.yml/badge.svg)](https://github.com/neowu/core-ng-project/actions/workflows/codeql.yml)
[![Code Coverage](https://codecov.io/gh/neowu/core-ng-project/branch/master/graph/badge.svg)](https://codecov.io/gh/neowu/core-ng-project)

## Maven repo
```
repositories {
    maven {
        url = uri("https://neowu.github.io/maven-repo/")
        content {
            includeGroupByRegex("core\\.framework.*")
        }
    }
    maven {
        url = uri("https://maven.codelibs.org/")
        content {
            includeGroup("org.codelibs.elasticsearch.module")
        }
    }
}
```

## Wiki
[https://github.com/neowu/core-ng-project/wiki](https://github.com/neowu/core-ng-project/wiki)

## Change log
please check [CHANGELOG.md](CHANGELOG.md)


# GraphQL Java

Discuss and ask questions in our Discussions: https://github.com/graphql-java/graphql-java/discussions

This is a [GraphQL](https://github.com/graphql/graphql-spec) Java implementation.

Latest build in Maven central: https://repo1.maven.org/maven2/com/graphql-java/graphql-java/

[![Build](https://github.com/graphql-java/graphql-java/actions/workflows/master.yml/badge.svg)](https://github.com/graphql-java/graphql-java/actions/workflows/master.yml)
[![Latest Release](https://img.shields.io/maven-central/v/com.graphql-java/graphql-java?versionPrefix=22.)](https://maven-badges.herokuapp.com/maven-central/com.graphql-java/graphql-java/)
[![Latest Snapshot](https://img.shields.io/maven-central/v/com.graphql-java/graphql-java?label=maven-central%20snapshot&versionPrefix=0)](https://maven-badges.herokuapp.com/maven-central/com.graphql-java/graphql-java/)
[![MIT licensed](https://img.shields.io/badge/license-MIT-green)](https://github.com/graphql-java/graphql-java/blob/master/LICENSE.md)

### Documentation

The GraphQL Java book, from the maintainers: [GraphQL with Java and Spring](https://leanpub.com/graphql-java/)

See our tutorial for beginners: [Getting started with GraphQL Java and Spring Boot](https://www.graphql-java.com/tutorials/getting-started-with-spring-boot/)

For further details, please see the documentation: https://www.graphql-java.com/documentation/getting-started

If you're looking to learn more, we (the maintainers) have written a book! [GraphQL with Java and Spring](https://leanpub.com/graphql-java) includes everything you need to know to build a production ready GraphQL service. The book is available on [Leanpub](https://leanpub.com/graphql-java) and [Amazon](https://www.amazon.com/GraphQL-Java-Spring-Andreas-Marek-ebook/dp/B0C96ZYWPF/).

Please take a look at our [list of releases](https://github.com/graphql-java/graphql-java/releases) if you want to learn more about new releases and the changelog.

### Code of Conduct

Please note that this project is released with a [Contributor Code of Conduct](CODE_OF_CONDUCT.md).
By contributing to this project (commenting or opening PR/Issues etc) you are agreeing to follow this conduct, so please
take the time to read it.

### License

Copyright (c) 2015, Andreas Marek and [Contributors](https://github.com/graphql-java/graphql-java/graphs/contributors)

### Supported by

![YourKit](https://www.yourkit.com/images/yklogo.png)

[YourKit](https://www.yourkit.com/) supports this project by providing the YourKit Java Profiler.


# RSocket

[![Join the chat at https://gitter.im/RSocket/RSocket-Java](https://badges.gitter.im/rsocket/rsocket-java.svg)](https://gitter.im/rsocket/rsocket-java)

RSocket is a binary protocol for use on byte stream transports such as TCP, WebSockets, and Aeron.

It enables the following symmetric interaction models via async message passing over a single connection:

- request/response (stream of 1)
- request/stream (finite stream of many)
- fire-and-forget (no response)
- event subscription (infinite stream of many)

Learn more at http://rsocket.io

## Build and Binaries

[![Build Status](https://github.com/rsocket/rsocket-java/actions/workflows/gradle-main.yml/badge.svg?branch=master)](https://github.com/rsocket/rsocket-java/actions/workflows/gradle-main.yml)

⚠ The `master` branch is now dedicated to development of the `1.2.x` line.

Releases and milestones are available via Maven Central.

Example:

```groovy
repositories {
    mavenCentral()
    maven { url 'https://repo.spring.io/milestone' }  // Reactor milestones (if needed)
}
dependencies {
    implementation 'io.rsocket:rsocket-core:1.2.0-SNAPSHOT'
    implementation 'io.rsocket:rsocket-transport-netty:1.2.0-SNAPSHOT'
}
```

Snapshots are available via [oss.jfrog.org](oss.jfrog.org) (OJO).

Example:

```groovy
repositories {
    maven { url 'https://maven.pkg.github.com/rsocket/rsocket-java' }
    maven { url 'https://repo.spring.io/snapshot' }  // Reactor snapshots (if needed)
}
dependencies {
    implementation 'io.rsocket:rsocket-core:1.2.0-SNAPSHOT'
    implementation 'io.rsocket:rsocket-transport-netty:1.2.0-SNAPSHOT'
}
```

## Development

Install the google-java-format in Intellij, from Plugins preferences.
Enable under Preferences -> Other Settings -> google-java-format Settings

Format automatically with

```
$./gradlew goJF
```

## Debugging
Frames can be printed out to help debugging. Set the logger `io.rsocket.FrameLogger` to debug to print the frames.

## Requirements

- Java 8 - heavy dependence on Java 8 functional APIs and java.time, also on Reactor
- Android O - https://github.com/rsocket/rsocket-demo-android-java8

## Trivial Client

```java
package io.rsocket.transport.netty;

import io.rsocket.Payload;
import io.rsocket.RSocket;
import io.rsocket.core.RSocketConnector;
import io.rsocket.transport.netty.client.WebsocketClientTransport;
import io.rsocket.util.DefaultPayload;
import reactor.core.publisher.Flux;

import java.net.URI;

public class ExampleClient {
    public static void main(String[] args) {
        WebsocketClientTransport ws = WebsocketClientTransport.create(URI.create("ws://rsocket-demo.herokuapp.com/ws"));
        RSocket clientRSocket = RSocketConnector.connectWith(ws).block();

        try {
            Flux<Payload> s = clientRSocket.requestStream(DefaultPayload.create("peace"));

            s.take(10).doOnNext(p -> System.out.println(p.getDataUtf8())).blockLast();
        } finally {
            clientRSocket.dispose();
        }
    }
}
```

## Zero Copy
By default to make RSocket easier to use it copies the incoming Payload. Copying the payload comes at cost to performance
and latency. If you want to use zero copy you must disable this. To disable copying you must include a `payloadDecoder`
argument in your `RSocketFactory`. This will let you manage the Payload without copying the data from the underlying
transport. You must free the Payload when you are done with them
or you will get a memory leak. Used correctly this will reduce latency and increase performance.

### Example Server setup
```java
RSocketServer.create(new PingHandler())
        // Enable Zero Copy
        .payloadDecoder(PayloadDecoder.ZERO_COPY)
        .bind(TcpServerTransport.create(7878))
        .block()
        .onClose()
        .block();
```

### Example Client setup
```java
RSocket clientRSocket =
        RSocketConnector.create()
            // Enable Zero Copy
            .payloadDecoder(PayloadDecoder.ZERO_COPY)
            .connect(TcpClientTransport.create(7878))
            .block();
```

## Bugs and Feedback

For bugs, questions and discussions please use the [Github Issues](https://github.com/RSocket/reactivesocket-java/issues).

## LICENSE

Copyright 2015-2020 the original author or authors.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.


////
DO NOT EDIT THIS FILE. IT WAS GENERATED.
Manual changes to this file will be lost when it is generated again.
Edit the files in the src/main/asciidoc/ directory instead.
////

:jdkversion: 17
:github-tag: master
:github-repo: spring-cloud/spring-cloud-stream

:github-raw: https://raw.githubusercontent.com/{github-repo}/{github-tag}
:github-code: https://github.com/{github-repo}/tree/{github-tag}

image::https://circleci.com/gh/spring-cloud/spring-cloud-stream.svg?style=svg["CircleCI", link="https://circleci.com/gh/spring-cloud/spring-cloud-stream"]
image::https://codecov.io/gh/spring-cloud/spring-cloud-stream/branch/{github-tag}/graph/badge.svg["codecov", link="https://codecov.io/gh/spring-cloud/spring-cloud-stream"]
image::https://badges.gitter.im/spring-cloud/spring-cloud-stream.svg[Gitter, link="https://gitter.im/spring-cloud/spring-cloud-stream?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge"]

// ======================================================================================

== Introduction
Spring Cloud Stream is a framework for building message-driven microservice applications.
Spring Cloud Stream builds upon Spring Boot to create standalone, production-grade Spring applications and uses Spring Integration to provide connectivity to message brokers.
It provides opinionated configuration of middleware from several vendors, introducing the concepts of persistent publish-subscribe semantics, consumer groups, and partitions.
These are called binder implementations in the parlance of Spring Cloud Stream.
Out of the box, Spring Cloud Stream provides binder implementations for Apache Kafka and RabbitMQ.
While these two binder implementations are based on Message Channels, Spring Cloud Stream also provides another binder implementation for Kafka Streams that does not use message channels, but native Kafka Streams types such as KStream, KTable etc.

Below, you can find more information on how to use these various out-of-the-box binder implementations in your applications.

== Apache Kafka Binder

=== Usage

To use Apache Kafka binder, you need to add `spring-cloud-stream-binder-kafka` as a dependency to your Spring Cloud Stream application, as shown in the following example for Maven:

[source,xml]
----
<dependency>
  <groupId>org.springframework.cloud</groupId>
  <artifactId>spring-cloud-stream-binder-kafka</artifactId>
</dependency>
----

Alternatively, you can also use the Spring Cloud Stream Kafka Starter, as shown in the following example for Maven:

[source,xml]
----
<dependency>
  <groupId>org.springframework.cloud</groupId>
  <artifactId>spring-cloud-starter-stream-kafka</artifactId>
</dependency>
----

== Apache Kafka Streams Binder

=== Usage

To use Apache Kafka Streams binder, you need to add `spring-cloud-stream-binder-kafka-streams` as a dependency to your Spring Cloud Stream application, as shown in the following example for Maven:

[source,xml]
----
<dependency>
  <groupId>org.springframework.cloud</groupId>
  <artifactId>spring-cloud-stream-binder-kafka-streams</artifactId>
</dependency>
----

== RabbitMQ Binder
=== Usage

To use the RabbitMQ binder, you can add it to your Spring Cloud Stream application, by using the following Maven coordinates:

[source,xml]
----
<dependency>
  <groupId>org.springframework.cloud</groupId>
  <artifactId>spring-cloud-stream-binder-rabbit</artifactId>
</dependency>
----

Alternatively, you can use the Spring Cloud Stream RabbitMQ Starter, as follows:

[source,xml]
----
<dependency>
  <groupId>org.springframework.cloud</groupId>
  <artifactId>spring-cloud-starter-stream-rabbit</artifactId>
</dependency>
----

== Resources

For more information, please visit the https://spring.io/projects/spring-cloud-stream[project website]:

== Building

:jdkversion: 17

=== Basic Compile and Test

To build the source you will need to install JDK {jdkversion}.

Spring Cloud uses Maven for most build-related activities, and you
should be able to get off the ground quite quickly by cloning the
project you are interested in and typing

----
$ ./mvnw install
----

NOTE: You can also install Maven (>=3.3.3) yourself and run the `mvn` command
in place of `./mvnw` in the examples below. If you do that you also
might need to add `-P spring` if your local Maven settings do not
contain repository declarations for spring pre-release artifacts.

NOTE: Be aware that you might need to increase the amount of memory
available to Maven by setting a `MAVEN_OPTS` environment variable with
a value like `-Xmx512m -XX:MaxPermSize=128m`. We try to cover this in
the `.mvn` configuration, so if you find you have to do it to make a
build succeed, please raise a ticket to get the settings added to
source control.

The projects that require middleware (i.e. Redis) for testing generally
require that a local instance of [Docker](https://www.docker.com/get-started) is installed and running.

=== Documentation

The spring-cloud-build module has a "docs" profile, and if you switch
that on it will try to build asciidoc sources from
`src/main/asciidoc`. As part of that process it will look for a
`README.adoc` and process it by loading all the includes, but not
parsing or rendering it, just copying it to `${main.basedir}`
(defaults to `${basedir}`, i.e. the root of the project). If there are
any changes in the README it will then show up after a Maven build as
a modified file in the correct place. Just commit it and push the change.

=== Working with the code
If you don't have an IDE preference we would recommend that you use
https://www.springsource.com/developer/sts[Spring Tools Suite] or
https://eclipse.org[Eclipse] when working with the code. We use the
https://eclipse.org/m2e/[m2eclipse] eclipse plugin for maven support. Other IDEs and tools
should also work without issue as long as they use Maven 3.3.3 or better.

==== Activate the Spring Maven profile
Spring Cloud projects require the 'spring' Maven profile to be activated to resolve
the spring milestone and snapshot repositories. Use your preferred IDE to set this
profile to be active, or you may experience build errors.

==== Importing into eclipse with m2eclipse
We recommend the https://eclipse.org/m2e/[m2eclipse] eclipse plugin when working with
eclipse. If you don't already have m2eclipse installed it is available from the "eclipse
marketplace".

NOTE: Older versions of m2e do not support Maven 3.3, so once the
projects are imported into Eclipse you will also need to tell
m2eclipse to use the right profile for the projects.  If you
see many different errors related to the POMs in the projects, check
that you have an up to date installation.  If you can't upgrade m2e,
add the "spring" profile to your `settings.xml`. Alternatively you can
copy the repository settings from the "spring" profile of the parent
pom into your `settings.xml`.

==== Importing into eclipse without m2eclipse
If you prefer not to use m2eclipse you can generate eclipse project metadata using the
following command:

[indent=0]
----
	$ ./mvnw eclipse:eclipse
----

The generated eclipse projects can be imported by selecting `import existing projects`
from the `file` menu.

== Contributing

:spring-cloud-build-branch: master

Spring Cloud is released under the non-restrictive Apache 2.0 license,
and follows a very standard Github development process, using Github
tracker for issues and merging pull requests into master. If you want
to contribute even something trivial please do not hesitate, but
follow the guidelines below.

=== Sign the Contributor License Agreement
Before we accept a non-trivial patch or pull request we will need you to sign the
https://cla.pivotal.io/sign/spring[Contributor License Agreement].
Signing the contributor's agreement does not grant anyone commit rights to the main
repository, but it does mean that we can accept your contributions, and you will get an
author credit if we do.  Active contributors might be asked to join the core team, and
given the ability to merge pull requests.

=== Code of Conduct
This project adheres to the Contributor Covenant https://github.com/spring-cloud/spring-cloud-build/blob/master/docs/src/main/asciidoc/code-of-conduct.adoc[code of
conduct]. By participating, you  are expected to uphold this code. Please report
unacceptable behavior to spring-code-of-conduct@pivotal.io.

=== Code Conventions and Housekeeping
None of these is essential for a pull request, but they will all help.  They can also be
added after the original pull request but before a merge.

* Use the Spring Framework code format conventions. If you use Eclipse
  you can import formatter settings using the
  `eclipse-code-formatter.xml` file from the
  https://raw.githubusercontent.com/spring-cloud/spring-cloud-build/master/spring-cloud-dependencies-parent/eclipse-code-formatter.xml[Spring
  Cloud Build] project. If using IntelliJ, you can use the
  https://plugins.jetbrains.com/plugin/6546[Eclipse Code Formatter
  Plugin] to import the same file.
* Make sure all new `.java` files to have a simple Javadoc class comment with at least an
  `@author` tag identifying you, and preferably at least a paragraph on what the class is
  for.
* Add the ASF license header comment to all new `.java` files (copy from existing files
  in the project)
* Add yourself as an `@author` to the .java files that you modify substantially (more
  than cosmetic changes).
* Add some Javadocs and, if you change the namespace, some XSD doc elements.
* A few unit tests would help a lot as well -- someone has to do it.
* If no-one else is using your branch, please rebase it against the current master (or
  other target branch in the main project).
* When writing a commit message please follow https://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html[these conventions],
  if you are fixing an existing issue please add `Fixes gh-XXXX` at the end of the commit
  message (where XXXX is the issue number).

=== Checkstyle

Spring Cloud Build comes with a set of checkstyle rules. You can find them in the `spring-cloud-build-tools` module. The most notable files under the module are:

.spring-cloud-build-tools/
----
└── src
    ├── checkstyle
    │   └── checkstyle-suppressions.xml <3>
    └── main
        └── resources
            ├── checkstyle-header.txt <2>
            └── checkstyle.xml <1>
----
<1> Default Checkstyle rules
<2> File header setup
<3> Default suppression rules

==== Checkstyle configuration

Checkstyle rules are *disabled by default*. To add checkstyle to your project just define the following properties and plugins.

.pom.xml
----
<properties>
<maven-checkstyle-plugin.failsOnError>true</maven-checkstyle-plugin.failsOnError> <1>
        <maven-checkstyle-plugin.failsOnViolation>true
        </maven-checkstyle-plugin.failsOnViolation> <2>
        <maven-checkstyle-plugin.includeTestSourceDirectory>true
        </maven-checkstyle-plugin.includeTestSourceDirectory> <3>
</properties>

<build>
        <plugins>
            <plugin> <4>
                <groupId>io.spring.javaformat</groupId>
                <artifactId>spring-javaformat-maven-plugin</artifactId>
            </plugin>
            <plugin> <5>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-checkstyle-plugin</artifactId>
            </plugin>
        </plugins>

    <reporting>
        <plugins>
            <plugin> <5>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-checkstyle-plugin</artifactId>
            </plugin>
        </plugins>
    </reporting>
</build>
----
<1> Fails the build upon Checkstyle errors
<2> Fails the build upon Checkstyle violations
<3> Checkstyle analyzes also the test sources
<4> Add the Spring Java Format plugin that will reformat your code to pass most of the Checkstyle formatting rules
<5> Add checkstyle plugin to your build and reporting phases

If you need to suppress some rules (e.g. line length needs to be longer), then it's enough for you to define a file under `${project.root}/src/checkstyle/checkstyle-suppressions.xml` with your suppressions. Example:

.projectRoot/src/checkstyle/checkstyle-suppresions.xml
----
<?xml version="1.0"?>
<!DOCTYPE suppressions PUBLIC
		"-//Puppy Crawl//DTD Suppressions 1.1//EN"
		"https://www.puppycrawl.com/dtds/suppressions_1_1.dtd">
<suppressions>
	<suppress files=".*ConfigServerApplication\.java" checks="HideUtilityClassConstructor"/>
	<suppress files=".*ConfigClientWatch\.java" checks="LineLengthCheck"/>
</suppressions>
----

It's advisable to copy the `${spring-cloud-build.rootFolder}/.editorconfig` and `${spring-cloud-build.rootFolder}/.springformat` to your project. That way, some default formatting rules will be applied. You can do so by running this script:

```bash
$ curl https://raw.githubusercontent.com/spring-cloud/spring-cloud-build/master/.editorconfig -o .editorconfig
$ touch .springformat
```

=== IDE setup

==== Intellij IDEA

In order to setup Intellij you should import our coding conventions, inspection profiles and set up the checkstyle plugin.
The following files can be found in the https://github.com/spring-cloud/spring-cloud-build/tree/master/spring-cloud-build-tools[Spring Cloud Build] project.

.spring-cloud-build-tools/
----
└── src
    ├── checkstyle
    │   └── checkstyle-suppressions.xml <3>
    └── main
        └── resources
            ├── checkstyle-header.txt <2>
            ├── checkstyle.xml <1>
            └── intellij
                ├── Intellij_Project_Defaults.xml <4>
                └── Intellij_Spring_Boot_Java_Conventions.xml <5>
----
<1> Default Checkstyle rules
<2> File header setup
<3> Default suppression rules
<4> Project defaults for Intellij that apply most of Checkstyle rules
<5> Project style conventions for Intellij that apply most of Checkstyle rules

.Code style

image::https://raw.githubusercontent.com/spring-cloud/spring-cloud-build/{spring-cloud-build-branch}/docs/src/main/asciidoc/images/intellij-code-style.png[Code style]

Go to `File` -> `Settings` -> `Editor` -> `Code style`. There click on the icon next to the `Scheme` section. There, click on the `Import Scheme` value and pick the `Intellij IDEA code style XML` option. Import the `spring-cloud-build-tools/src/main/resources/intellij/Intellij_Spring_Boot_Java_Conventions.xml` file.

.Inspection profiles

image::https://raw.githubusercontent.com/spring-cloud/spring-cloud-build/{spring-cloud-build-branch}/docs/src/main/asciidoc/images/intellij-inspections.png[Code style]

Go to `File` -> `Settings` -> `Editor` -> `Inspections`. There click on the icon next to the `Profile` section. There, click on the `Import Profile` and import the `spring-cloud-build-tools/src/main/resources/intellij/Intellij_Project_Defaults.xml` file.

.Checkstyle

To have Intellij work with Checkstyle, you have to install the `Checkstyle` plugin. It's advisable to also install the `Assertions2Assertj` to automatically convert the JUnit assertions

image::https://raw.githubusercontent.com/spring-cloud/spring-cloud-build/{spring-cloud-build-branch}/docs/src/main/asciidoc/images/intellij-checkstyle.png[Checkstyle]

Go to `File` -> `Settings` -> `Other settings` -> `Checkstyle`. There click on the `+` icon in the `Configuration file` section. There, you'll have to define where the checkstyle rules should be picked from. In the image above, we've picked the rules from the cloned Spring Cloud Build repository. However, you can point to the Spring Cloud Build's GitHub repository (e.g. for the `checkstyle.xml` : `https://raw.githubusercontent.com/spring-cloud/spring-cloud-build/master/spring-cloud-build-tools/src/main/resources/checkstyle.xml`). We need to provide the following variables:

- `checkstyle.header.file` - please point it to the Spring Cloud Build's, `spring-cloud-build-tools/src/main/resources/checkstyle-header.txt` file either in your cloned repo or via the `https://raw.githubusercontent.com/spring-cloud/spring-cloud-build/master/spring-cloud-build-tools/src/main/resources/checkstyle-header.txt` URL.
- `checkstyle.suppressions.file` - default suppressions. Please point it to the Spring Cloud Build's, `spring-cloud-build-tools/src/checkstyle/checkstyle-suppressions.xml` file either in your cloned repo or via the `https://raw.githubusercontent.com/spring-cloud/spring-cloud-build/master/spring-cloud-build-tools/src/checkstyle/checkstyle-suppressions.xml` URL.
- `checkstyle.additional.suppressions.file` - this variable corresponds to suppressions in your local project. E.g. you're working on `spring-cloud-contract`. Then point to the `project-root/src/checkstyle/checkstyle-suppressions.xml` folder. Example for `spring-cloud-contract` would be: `/home/username/spring-cloud-contract/src/checkstyle/checkstyle-suppressions.xml`.

IMPORTANT: Remember to set the `Scan Scope` to `All sources` since we apply checkstyle rules for production and test sources.

=== Duplicate Finder

Spring Cloud Build brings along the  `basepom:duplicate-finder-maven-plugin`, that enables flagging duplicate and conflicting classes and resources on the java classpath.

==== Duplicate Finder configuration

Duplicate finder is *enabled by default* and will run in the `verify` phase of your Maven build, but it will only take effect in your project if you add the `duplicate-finder-maven-plugin` to the `build` section of the projecst's `pom.xml`.

.pom.xml
[source,xml]
----
<build>
    <plugins>
        <plugin>
            <groupId>org.basepom.maven</groupId>
            <artifactId>duplicate-finder-maven-plugin</artifactId>
        </plugin>
    </plugins>
</build>
----

For other properties, we have set defaults as listed in the https://github.com/basepom/duplicate-finder-maven-plugin/wiki[plugin documentation].

You can easily override them but setting the value of the selected property prefixed with `duplicate-finder-maven-plugin`. For example, set `duplicate-finder-maven-plugin.skip` to `true` in order to skip duplicates check in your build.

If you need to add `ignoredClassPatterns` or `ignoredResourcePatterns` to your setup, make sure to add them in the plugin configuration section of your project:

[source,xml]
----
<build>
    <plugins>
        <plugin>
            <groupId>org.basepom.maven</groupId>
            <artifactId>duplicate-finder-maven-plugin</artifactId>
            <configuration>
                <ignoredClassPatterns>
                    <ignoredClassPattern>org.joda.time.base.BaseDateTime</ignoredClassPattern>
                    <ignoredClassPattern>.*module-info</ignoredClassPattern>
                </ignoredClassPatterns>
                <ignoredResourcePatterns>
                    <ignoredResourcePattern>changelog.txt</ignoredResourcePattern>
                </ignoredResourcePatterns>
            </configuration>
        </plugin>
    </plugins>
</build>

----


# Kubernetes & OpenShift Java Client [![Join the chat at https://gitter.im/fabric8io/kubernetes-client](https://badges.gitter.im/fabric8io/kubernetes-client.svg)](https://gitter.im/fabric8io/kubernetes-client?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
This client provides access to the full [Kubernetes](http://kubernetes.io/) &
[OpenShift](http://openshift.org/) REST APIs via a fluent DSL.

[![Build](https://github.com/fabric8io/kubernetes-client/workflows/Build/badge.svg)](https://github.com/fabric8io/kubernetes-client/actions?query=workflow%3ABuild)
[![Sonar Scanner](https://github.com/fabric8io/kubernetes-client/workflows/Sonar%20Scanner/badge.svg)](https://github.com/fabric8io/kubernetes-client/actions?query=workflow%3A%22Sonar+Scanner%22)
[![Bugs](https://sonarcloud.io/api/project_badges/measure?project=fabric8io_kubernetes-client&metric=bugs)](https://sonarcloud.io/dashboard?id=fabric8io_kubernetes-client)
[![E2E Tests](https://github.com/fabric8io/kubernetes-client/workflows/E2E%20Tests/badge.svg)](https://github.com/fabric8io/kubernetes-client/actions?query=workflow%3A%22E2E+Tests%22)
[![Release](https://img.shields.io/github/v/release/fabric8io/kubernetes-client)](https://search.maven.org/search?q=g:io.fabric8%20a:kubernetes-client)
[![Twitter](https://img.shields.io/twitter/follow/fabric8io?style=social)](https://twitter.com/fabric8io)

| Module | Maven Central | Javadoc |
|-|:-:|:-:|
| kubernetes-client | [![Maven Central](https://maven-badges.herokuapp.com/maven-central/io.fabric8/kubernetes-client/badge.svg?color=blue)](https://maven-badges.herokuapp.com/maven-central/io.fabric8/kubernetes-client) | [![Javadocs](https://www.javadoc.io/badge/io.fabric8/kubernetes-client.svg?color=blue)](https://www.javadoc.io/doc/io.fabric8/kubernetes-client) |
| openshift-client | [![Maven Central](https://maven-badges.herokuapp.com/maven-central/io.fabric8/openshift-client/badge.svg?color=blue)](https://maven-badges.herokuapp.com/maven-central/io.fabric8/openshift-client) | [![Javadocs](https://www.javadoc.io/badge/io.fabric8/openshift-client.svg?color=blue)](https://www.javadoc.io/doc/io.fabric8/openshift-client) |

| Extensions | Maven Central | Javadoc |
|-|:-:|:-:|
| knative-client | [![Maven Central](https://maven-badges.herokuapp.com/maven-central/io.fabric8/knative-client/badge.svg?color=blue)](https://maven-badges.herokuapp.com/maven-central/io.fabric8/knative-client) | [![Javadocs](https://www.javadoc.io/badge/io.fabric8/knative-client.svg?color=blue)](https://www.javadoc.io/doc/io.fabric8/knative-client) |
| tekton-client | [![Maven Central](https://maven-badges.herokuapp.com/maven-central/io.fabric8/tekton-client/badge.svg?color=blue)](https://maven-badges.herokuapp.com/maven-central/io.fabric8/tekton-client) | [![Javadocs](https://www.javadoc.io/badge/io.fabric8/tekton-client.svg?color=blue)](https://www.javadoc.io/doc/io.fabric8/tekton-client) |
| servicecatalog-client | [![Maven Central](https://maven-badges.herokuapp.com/maven-central/io.fabric8/servicecatalog-client/badge.svg?color=blue)](https://maven-badges.herokuapp.com/maven-central/io.fabric8/servicecatalog-client) | [![Javadocs](https://www.javadoc.io/badge/io.fabric8/servicecatalog-client.svg?color=blue)](https://www.javadoc.io/doc/io.fabric8/servicecatalog-client) |
| chaosmesh-client | [![Maven Central](https://maven-badges.herokuapp.com/maven-central/io.fabric8/chaosmesh-client/badge.svg?color=blue)](https://maven-badges.herokuapp.com/maven-central/io.fabric8/chaosmesh-client) | [![Javadocs](https://www.javadoc.io/badge/io.fabric8/chaosmesh-client.svg?color=blue)](https://www.javadoc.io/doc/io.fabric8/chaosmesh-client) |
| volumesnapshot-client | [![Maven Central](https://maven-badges.herokuapp.com/maven-central/io.fabric8/volumesnapshot-client/badge.svg?color=blue)](https://maven-badges.herokuapp.com/maven-central/io.fabric8/volumesnapshot-client) | [![Javadocs](https://www.javadoc.io/badge/io.fabric8/volumesnapshot-client.svg?color=blue)](https://www.javadoc.io/doc/io.fabric8/volumesnapshot-client) |
| volcano-client | [![Maven Central](https://maven-badges.herokuapp.com/maven-central/io.fabric8/volcano-client/badge.svg?color=blue)](https://maven-badges.herokuapp.com/maven-central/io.fabric8/volcano-client) | [![Javadocs](https://www.javadoc.io/badge/io.fabric8/volcano-client.svg?color=blue)](https://www.javadoc.io/doc/io.fabric8/volcano-client) |
| istio-client | [![Maven Central](https://maven-badges.herokuapp.com/maven-central/io.fabric8/istio-client/badge.svg?color=blue)](https://maven-badges.herokuapp.com/maven-central/io.fabric8/istio-client) | [![Javadocs](https://www.javadoc.io/badge/io.fabric8/istio-client.svg?color=blue)](https://www.javadoc.io/doc/io.fabric8/istio-client) |
| open-cluster-management-client | [![Maven Central](https://maven-badges.herokuapp.com/maven-central/io.fabric8/open-cluster-management-client/badge.svg?color=blue)](https://maven-badges.herokuapp.com/maven-central/io.fabric8/open-cluster-management-client) | [![Javadocs](https://www.javadoc.io/badge/io.fabric8/open-cluster-management-client.svg?color=blue)](https://www.javadoc.io/doc/io.fabric8/open-cluster-management-client) |

## Contents
- [Usage](#usage)
    - [Creating a client](#creating-a-client)
    - [Configuring the client](#configuring-the-client)
    - [Loading resources from external sources](#loading-resources-from-external-sources)
    - [Passing a reference of a resource to the client](#passing-a-reference-of-a-resource-to-the-client)
    - [Adapting a client](#adapting-the-client)
        - [Adapting and close](#adapting-and-close)
- [Generating CRD from Java](doc/CRD-generator.md)
- [Generating Java from CRD](doc/java-generation-from-CRD.md)
- [Mocking Kubernetes](#mocking-kubernetes)
- [Who Uses Fabric8 Kubernetes Client?](#who-uses-kubernetes--openshift-java-client)
- [Kubernetes Operators in Java Written using Fabric8 Kubernetes Client](./doc/KubernetesOperatorsInJavaWrittenUsingFabric8.md)
- [Kubernetes and Red Hat OpenShift Compatibility](#compatibility)
- [Kubernetes Client CHEAT SHEET](https://github.com/fabric8io/kubernetes-client/blob/main/doc/CHEATSHEET.md)
- [Kubectl Java Equivalents](#kubectl-java-equivalents)
- [FAQs](doc/FAQ.md) - which includes details about project dependencies.

## Usage

### Creating a client
The easiest way to create a client is:

```java
KubernetesClient client = new KubernetesClientBuilder().build();
```

`DefaultOpenShiftClient` implements both the `KubernetesClient` & `OpenShiftClient` interface so if you need the
OpenShift extensions, such as `Build`s, etc then simply do:

```java
OpenShiftClient osClient = new KubernetesClientBuilder().build().adapt(OpenShiftClient.class);
```

### Configuring the client

This will use settings from different sources in the following order of priority:

* System properties
* Environment variables
* Kube config file
* Service account token & mounted CA certificate

System properties are preferred over environment variables. The following system properties & environment variables can be used for configuration:

| Property / Environment Variable                                                                                | Description                                                                                | Default value                                         |
|-----------------------------------------------------------------------------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------|-------------------------------------------------------|
| `kubernetes.disable.autoConfig` / `KUBERNETES_DISABLE_AUTOCONFIG`                                               | Disable automatic configuration (KubernetesClient would not look in `~/.kube/config`, mounted ServiceAccount, environment variables or System properties for Kubernetes cluster information)                                                                                | `false`                                               |
| `kubernetes.master` / `KUBERNETES_MASTER`                                                                       | Kubernetes master URL                                                                                | `https://kubernetes.default.svc`                      |
| `kubernetes.api.version` / `KUBERNETES_API_VERSION`                                                             | API version                                                                                | `v1`                                                  |
| `openshift.url` / `OPENSHIFT_URL`                                                                               | OpenShift master URL                                                                                | Kubernetes master URL value                           |
| `kubernetes.oapi.version` / `KUBERNETES_OAPI_VERSION`                                                           | OpenShift API version                                                                                | `v1`                                                  |
| `kubernetes.trust.certificates` / `KUBERNETES_TRUST_CERTIFICATES`                                               | Trust all certificates                                                                                | `false`                                               |
| `kubernetes.disable.hostname.verification` / `KUBERNETES_DISABLE_HOSTNAME_VERIFICATION`                         |                                                                                | `false`                                               |
| `kubernetes.certs.ca.file` / `KUBERNETES_CERTS_CA_FILE`                                                         |                                                                                |                                                       |
| `kubernetes.certs.ca.data` / `KUBERNETES_CERTS_CA_DATA`                                                         |                                                                                |                                                       |
| `kubernetes.certs.client.file` / `KUBERNETES_CERTS_CLIENT_FILE`                                                 |                                                                                |                                                       |
| `kubernetes.certs.client.data` / `KUBERNETES_CERTS_CLIENT_DATA`                                                 |                                                                                |                                                       |
| `kubernetes.certs.client.key.file` / `KUBERNETES_CERTS_CLIENT_KEY_FILE`                                         |                                                                                |                                                       |
| `kubernetes.certs.client.key.data` / `KUBERNETES_CERTS_CLIENT_KEY_DATA`                                         |                                                                                |                                                       |
| `kubernetes.certs.client.key.algo` / `KUBERNETES_CERTS_CLIENT_KEY_ALGO`                                         | Client key encryption algorithm                                                                                | `RSA`                                                 |
| `kubernetes.certs.client.key.passphrase` / `KUBERNETES_CERTS_CLIENT_KEY_PASSPHRASE`                             |                                                                                |                                                       |
| `kubernetes.auth.basic.username` / `KUBERNETES_AUTH_BASIC_USERNAME`                                             |                                                                                |                                                       |
| `kubernetes.auth.basic.password` / `KUBERNETES_AUTH_BASIC_PASSWORD`                                             |                                                                                |                                                       |
| `kubernetes.auth.serviceAccount.token` / `KUBERNETES_AUTH_SERVICEACCOUNT_TOKEN`                                 | Name of the service account token file                                                                                | `/var/run/secrets/kubernetes.io/serviceaccount/token` |
| `kubernetes.auth.tryKubeConfig` / `KUBERNETES_AUTH_TRYKUBECONFIG`                                               | Configure client using Kubernetes config                                                                                | `true`                                                |
| `kubeconfig` / `KUBECONFIG`                                                                                | Name of the kubernetes config file to read                                                                                | `~/.kube/config`                                      |
| `kubernetes.auth.tryServiceAccount` / `KUBERNETES_AUTH_TRYSERVICEACCOUNT`                                       | Configure client from Service account                                                                                | `true`                                                |
| `kubernetes.tryNamespacePath` / `KUBERNETES_TRYNAMESPACEPATH`                                                   | Configure client namespace from Kubernetes service account namespace path                                                                | `true`                                                |
| `kubernetes.auth.token` / `KUBERNETES_AUTH_TOKEN`                                                               |                                                                                |                                                       |
| `kubernetes.watch.reconnectInterval` / `KUBERNETES_WATCH_RECONNECTINTERVAL`                                     | Watch reconnect interval in ms                                                                                | `1000`                                                |
| `kubernetes.watch.reconnectLimit` / `KUBERNETES_WATCH_RECONNECTLIMIT`                                           | Number of reconnect attempts (-1 for infinite)                                                                                | `-1`                                                  |
| `kubernetes.connection.timeout` / `KUBERNETES_CONNECTION_TIMEOUT`                                               | Connection timeout in ms (0 for no timeout)                                                                                | `10000`                                               |
| `kubernetes.request.timeout` / `KUBERNETES_REQUEST_TIMEOUT`                                                     | Read timeout in ms                                                                                | `10000`                                               |
| `kubernetes.upload.connection.timeout` / `KUBERNETES_UPLOAD_CONNECTION_TIMEOUT`                                 | Pod upload connection timeout in ms                                                                                | `10000`                                               |
| `kubernetes.upload.request.timeout` / `KUBERNETES_UPLOAD_REQUEST_TIMEOUT`                                       | Pod upload request timeout in ms                                                                                | `120000`                                              |
| `kubernetes.request.retry.backoffLimit` / `KUBERNETES_REQUEST_RETRY_BACKOFFLIMIT`                               | Number of retry attempts (-1 for infinite)                                                                                | `10`                                                  |
| `kubernetes.request.retry.backoffInterval` / `KUBERNETES_REQUEST_RETRY_BACKOFFINTERVAL`                         | Retry initial backoff interval in ms                                                                                | `100`                                                 |
| `kubernetes.rolling.timeout` / `KUBERNETES_ROLLING_TIMEOUT`                                                     | Rolling timeout in ms                                                                                | `900000`                                              |
| `kubernetes.logging.interval` / `KUBERNETES_LOGGING_INTERVAL`                                                   | Logging interval in ms                                                                                | `20000`                                               |
| `kubernetes.scale.timeout` / `KUBERNETES_SCALE_TIMEOUT`                                                         | Scale timeout in ms                                                                                | `600000`                                              |
| `kubernetes.websocket.timeout` / `KUBERNETES_WEBSOCKET_TIMEOUT`                                                 | Websocket timeout in ms                                                                                | `5000`                                                |
| `kubernetes.websocket.ping.interval` / `KUBERNETES_WEBSOCKET_PING_INTERVAL`                                     | Websocket ping interval in ms                                                                                | `30000`                                               |
| `kubernetes.max.concurrent.requests` / `KUBERNETES_MAX_CONCURRENT_REQUESTS`                                     |                                                                                | `64`                                                  |
| `kubernetes.max.concurrent.requests.per.host` / `KUBERNETES_MAX_CONCURRENT_REQUESTS_PER_HOST`                   |                                                                                | `5`                                                   |
| `kubernetes.impersonate.username` / `KUBERNETES_IMPERSONATE_USERNAME`                                           | `Impersonate-User` HTTP header value                                                                                |                                                       |
| `kubernetes.impersonate.group` / `KUBERNETES_IMPERSONATE_GROUP`                                                 | `Impersonate-Group` HTTP header value                                                                                |                                                       |
| `kubernetes.tls.versions` / `KUBERNETES_TLS_VERSIONS`                                                           | TLS versions separated by `,`                                                                                | `TLSv1.2,TLSv1.3`                                     |
| `kubernetes.truststore.file` / `KUBERNETES_TRUSTSTORE_FILE`                                                     |                                                                                |                                                       |
| `kubernetes.truststore.passphrase` / `KUBERNETES_TRUSTSTORE_PASSPHRASE`                                         |                                                                                |                                                       |
| `kubernetes.keystore.file` / `KUBERNETES_KEYSTORE_FILE`                                                         |                                                                                |                                                       |
| `kubernetes.keystore.passphrase` / `KUBERNETES_KEYSTORE_PASSPHRASE`                                             |                                                                                |                                                       |
| `kubernetes.backwardsCompatibilityInterceptor.disable` / `KUBERNETES_BACKWARDSCOMPATIBILITYINTERCEPTOR_DISABLE` | Disable the `BackwardsCompatibilityInterceptor`                                                                                | `true`                                                |
| `no.proxy` / `NO_PROXY`                                                                                | comma-separated list of domain extensions [proxy](http://www.gnu.org/software/wget/manual/html_node/Proxies.html) should not be used for |                                                       |

Alternatively you can use the `ConfigBuilder` to create a config object for the Kubernetes client:

```java
Config config = new ConfigBuilder().withMasterUrl("https://mymaster.com").build();
KubernetesClient client = new KubernetesClientBuilder().withConfig(config).build();
```

###
Using the DSL is the same for all resources.

List resources:

```java
NamespaceList myNs = client.namespaces().list();

ServiceList myServices = client.services().list();

ServiceList myNsServices = client.services().inNamespace("default").list();
```

Get a resource:

```java
Namespace myns = client.namespaces().withName("myns").get();

Service myservice = client.services().inNamespace("default").withName("myservice").get();
```

Delete:

```java
Namespace myns = client.namespaces().withName("myns").delete();

Service myservice = client.services().inNamespace("default").withName("myservice").delete();
```

Editing resources uses the inline builders from the Kubernetes Model:

```java
Namespace myns = client.namespaces().withName("myns").edit(n -> new NamespaceBuilder(n)
                   .editMetadata()
                     .addToLabels("a", "label")
                   .endMetadata()
                   .build());

Service myservice = client.services().inNamespace("default").withName("myservice").edit(s -> new ServiceBuilder(s)
                     .editMetadata()
                       .addToLabels("another", "label")
                     .endMetadata()
                     .build());
```

In the same spirit you can inline builders to create:

```java
Namespace myns = client.namespaces().create(new NamespaceBuilder()
                   .withNewMetadata()
                     .withName("myns")
                     .addToLabels("a", "label")
                   .endMetadata()
                   .build());

Service myservice = client.services().inNamespace("default").create(new ServiceBuilder()
                     .withNewMetadata()
                       .withName("myservice")
                       .addToLabels("another", "label")
                     .endMetadata()
                     .build());
```

You can also set the apiVersion of the resource like in the case of SecurityContextConstraints :

```java
SecurityContextConstraints scc = new SecurityContextConstraintsBuilder()
		.withApiVersion("v1")
		.withNewMetadata().withName("scc").endMetadata()
		.withAllowPrivilegedContainer(true)
		.withNewRunAsUser()
		.withType("RunAsAny")
		.endRunAsUser()
		.build();
```

### Following events

Use `io.fabric8.kubernetes.api.model.Event` as T for Watcher:

```java
client.events().inAnyNamespace().watch(new Watcher<Event>() {

  @Override
  public void eventReceived(Action action, Event resource) {
    System.out.println("event " + action.name() + " " + resource.toString());
  }

  @Override
  public void onClose(KubernetesClientException cause) {
    System.out.println("Watcher close due to " + cause);
  }

});
```

### Working with extensions

The kubernetes API defines a bunch of extensions like `daemonSets`, `jobs`, `ingresses` and so forth which are all usable in the `extensions()` DSL:

e.g. to list the jobs...

```
jobs = client.batch().jobs().list();
```

### Loading resources from external sources

There are cases where you want to read a resource from an external source, rather than defining it using the clients DSL.
For those cases the client allows you to load the resource from:

- A file *(Supports both java.io.File and java.lang.String)*
- A url
- An input stream

Once the resource is loaded, you can treat it as you would, had you created it yourself.

For example lets read a pod, from a yml file and work with it:

    Pod refreshed = client.load('/path/to/a/pod.yml').fromServer().get();
    client.load('/workspace/pod.yml').delete();
    LogWatch handle = client.load('/workspace/pod.yml').watchLog(System.out);

### Passing a reference of a resource to the client

In the same spirit you can use an object created externally (either a reference or using its string representation).

For example:

    Pod pod = someThirdPartyCodeThatCreatesAPod();
    client.resource(pod).delete();

### Adapting the client

The client supports plug-able adapters. An example adapter is the [OpenShift Adapter](openshift-client/src/main/java/io/fabric8/openshift/client/OpenShiftExtensionAdapter.java)
which allows adapting an existing [KubernetesClient](kubernetes-client-api/src/main/java/io/fabric8/kubernetes/client/KubernetesClient.java) instance to an [OpenShiftClient](openshift-client-api/src/main/java/io/fabric8/openshift/client/OpenShiftClient.java) one.

 For example:

```java
KubernetesClient client = new KubernetesClientBuilder().build();

OpenShiftClient oClient = client.adapt(OpenShiftClient.class);
```

The client also support the isAdaptable() method which checks if the adaptation is possible and returns true if it does.

```java
KubernetesClient client = new KubernetesClientBuilder().build();
if (client.isAdaptable(OpenShiftClient.class)) {
    OpenShiftClient oClient = client.adapt(OpenShiftClient.class);
} else {
    throw new Exception("Adapting to OpenShiftClient not support. Check if adapter is present, and that env provides /oapi root path.");
}
```

#### Adapting and close
Note that when using adapt() both the adaptee and the target will share the same resources (underlying http client, thread pools etc).
This means that close() is not required to be used on every single instance created via adapt.
Calling close() on any of the adapt() managed instances or the original instance, will properly clean up all the resources and thus none of the instances will be usable any longer.

## Mocking Kubernetes

Along with the client this project also provides a kubernetes mock server that you can use for testing purposes.
The mock server is based on `https://github.com/square/okhttp/tree/master/mockwebserver` but is empowered by the DSL and features provided by `https://github.com/fabric8io/mockwebserver`.

The Mock Web Server has two modes of operation:

- Expectations mode
- CRUD mode

### Expectations mode

It's the typical mode where you first set which are the expected http requests and which should be the responses for each request.
More details on usage can be found at: https://github.com/fabric8io/mockwebserver

This mode has been extensively used for testing the client itself. Make sure you check [kubernetes-test](kubernetes-tests/src/test/java/io/fabric8/kubernetes/client/mock).

To add a Kubernetes server to your test:
```java
@Rule
public KubernetesServer server = new KubernetesServer();
```
### CRUD mode

Defining every single request and response can become tiresome. Given that in most cases the mock webserver is used to perform simple crud based operations, a crud mode has been added.
When using the crud mode, the mock web server will store, read, update and delete kubernetes resources using an in memory map and will appear as a real api server.

To add a Kubernetes Server in crud mode to your test:
```java
@Rule
public KubernetesServer server = new KubernetesServer(true, true);
```
Then you can use the server like:
```java
@Test
public void testInCrudMode() {
    KubernetesClient client = server.getClient();
    final CountDownLatch deleteLatch = new CountDownLatch(1);
    final CountDownLatch closeLatch = new CountDownLatch(1);

    //CREATE
    client.pods().inNamespace("ns1").create(new PodBuilder().withNewMetadata().withName("pod1").endMetadata().build());

    //READ
    podList = client.pods().inNamespace("ns1").list();
    assertNotNull(podList);
    assertEquals(1, podList.getItems().size());

    //WATCH
    Watch watch = client.pods().inNamespace("ns1").withName("pod1").watch(new Watcher<Pod>() {
        @Override
        public void eventReceived(Action action, Pod resource) {
            switch (action) {
                case DELETED:
                    deleteLatch.countDown();
                    break;
                default:
                    throw new AssertionFailedError(action.toString().concat(" isn't recognised."));
            }
        }

        @Override
        public void onClose(KubernetesClientException cause) {
            closeLatch.countDown();
        }
    });

    //DELETE
    client.pods().inNamespace("ns1").withName("pod1").delete();

    //READ AGAIN
    podList = client.pods().inNamespace("ns1").list();
    assertNotNull(podList);
    assertEquals(0, podList.getItems().size());

    assertTrue(deleteLatch.await(1, TimeUnit.MINUTES));
    watch.close();
    assertTrue(closeLatch.await(1, TimeUnit.MINUTES));
}
```
### JUnit5 support through extension

You can use KubernetesClient mocking mechanism with JUnit5. Since it doesn't support `@Rule` and `@ClassRule` there is dedicated annotation `@EnableKubernetesMockClient`.
If you would like to create instance of mocked `KubernetesClient` for each test (JUnit4 `@Rule`) you need to declare instance of `KubernetesClient` as shown below.
```java
@EnableKubernetesMockClient
class ExampleTest {

    KubernetesClient client;

    @Test
    public void testInStandardMode() {
            ...
    }
}
```
In case you would like to define static instance of mocked server per all the test (JUnit4 `@ClassRule`) you need to declare instance of `KubernetesClient` as shown below.
You can also enable crudMode by using annotation field `crud`.
```java
@EnableKubernetesMockClient(crud = true)
class ExampleTest {

    static KubernetesClient client;

    @Test
    public void testInCrudMode() {
            // ...
    }
}
```

## Testing Against real Kubernetes API Server with Kube API Test

In order to test against real Kubernetes API the project provides a lightweight approach, thus starting up Kubernetes API Server and etcd binaries.

```java
@EnableKubeAPIServer
class KubeAPITestSample {

  static KubernetesClient client;

  @Test
  void testWithClient() {
    // test using the client against real K8S API Server
  }
}
```

For details see docs for [Kube API Test](doc/kube-api-test.md).

## Compatibility

### Kubernetes

Starting from v5.5, the Kubernetes Client should be compatible with **any** supported Kubernetes cluster version.
We provide DSL methods (for example `client.pods()`, `client.namespaces()`, and so on) for the most commonly used Kubernetes resources. If the resource you're looking for is not available through the DSL, you can always use the generic `client.resource()` method to interact with it. You can also open a [new issue](https://github.com/fabric8io/kubernetes-client/issues/new/choose) to request the addition of a new resource to the DSL.

We provide Kubernetes Java model types (for example `Pod`) and their corresponding builders (for example `PodBuilder`) for every vanilla Kubernetes resource (and some extensions). If you don't find a specific resource, and you think that it should be part of the Kubernetes Client, please open a [new issue](https://github.com/fabric8io/kubernetes-client/issues/new/choose).

### OpenShift

Starting from v5.5, the OpenShift Client should be compatible with **any** OpenShift cluster version currently supported by Red Hat.
The Fabric8 Kubernetes Client is one of the few Kubernetes Java clients that provides full support for any supported OpenShift cluster version. If you find any incompatibility or something missing, please open a [new issue](https://github.com/fabric8io/kubernetes-client/issues/new/choose).

## Major Changes in Kubernetes Client 4.0.0
All the resource objects used here will be according to OpenShift 3.9.0  and Kubernetes 1.9.0. All the resource objects will give all the fields according to OpenShift 3.9.0 and Kubernetes 1.9.0

* SecurityContextConstraints has been moved to OpenShift client from Kubernetes Client
* Job dsl is in both `batch` and `extensions`(Extensions is deprecated)
* DaemonSet dsl is in both `apps` and `extensions`(Extensions is deprecated)
* Deployment dsl is in both `apps` and `extensions`(Extensions is deprecated)
* ReplicaSet dsl is in both `apps` and `extensions`(Extensions is deprecated)
* NetworkPolicy dsl is in both `network` and `extensions`(Extensions is deprecated)
* Storage Class moved from `client base DSL` to `storage` DSL
* PodSecurityPolicies moved from `client base DSL` and `extensions` to only `extensions`
* ThirdPartyResource has been removed.

## Who uses Kubernetes & OpenShift Java client?

  Extensions:
  - [Service Catalog API](https://github.com/fabric8io/kubernetes-client/tree/master/extensions/service-catalog)
  - [Knative](https://github.com/fabric8io/kubernetes-client/tree/master/extensions/knative)
  - [Tekton](https://github.com/fabric8io/kubernetes-client/tree/master/extensions/tekton)
  - [Volcano](https://github.com/fabric8io/kubernetes-client/tree/master/extensions/volcano)
  - [Istio](https://github.com/fabric8io/kubernetes-client/tree/master/extensions/istio)
  - [Open Cluster Management](https://github.com/fabric8io/kubernetes-client/tree/master/extensions/open-cluster-management)
  - [Camel-k](https://camel.apache.org/camel-k/next/apis/java.html) - [Maven Central](https://search.maven.org/artifact/org.apache.camel.k/camel-k-crds)

  Frameworks/Libraries/Tools:
  - [Arquillian Cube](http://arquillian.org/arquillian-cube/)
  - [Apache Camel](https://github.com/apache/camel/blob/master/README.md)
  - [Apache Flink](https://github.com/apache/flink/tree/master/flink-kubernetes)
  - [Apache Spark](https://github.com/apache/spark/tree/master/resource-managers/kubernetes)
  - [Jaeger Kubernetes](https://github.com/jaegertracing/jaeger-kubernetes)
  - [Loom](https://github.com/datawire/loom)
  - [Microsoft Azure Libraries for Java](https://github.com/Azure/azure-libraries-for-java)
  - [Spinnaker Halyard](https://github.com/spinnaker/halyard)
  - [Spring Cloud Connectors for Kubernetes](https://github.com/spring-cloud/spring-cloud-kubernetes-connector)
  - [Spring Cloud Kubernetes](https://github.com/fabric8io/spring-cloud-kubernetes)

  CI Plugins:
  - [Deployment Pipeline Plugin (Jenkins)](https://github.com/pearsontechnology/deployment-pipeline-jenkins-plugin)
  - [Kubernetes Elastic Agent (GoCD)](https://github.com/gocd/kubernetes-elastic-agents)
  - [Kubernetes Plugin (Jenkins)](https://github.com/jenkinsci/kubernetes-plugin)
  - [Kubernetes Pipeline Plugin (Jenkins)](https://github.com/jenkinsci/kubernetes-pipeline-plugin)
  - [OpenShift Sync Plugin (Jenkins)](https://github.com/openshift/jenkins-sync-plugin)
  - [Kubernetes Plugin (Teamcity from Jetbrains)](https://github.com/JetBrains/teamcity-kubernetes-plugin)
  - [Kubernetes Agents for Bamboo (WindTunnel Technologies)](https://marketplace.atlassian.com/apps/1222674/kubernetes-agents-for-bamboo)

  Build Tools:
  - [Fabric8 Maven Plugin](https://github.com/fabric8io/fabric8-maven-plugin)
  - [Eclipse JKube](https://github.com/eclipse/jkube)
  - [Gradle Kubernetes Plugin](https://github.com/bmuschko/gradle-kubernetes-plugin)

  Platforms:
  - [Apache Openwhisk](https://github.com/apache/incubator-openwhisk)
  - [Eclipse che](https://www.eclipse.org/che/)
  - [Openshift.io (Launcher service)](https://github.com/fabric8-launcher)
  - [Spotify Styx](https://github.com/spotify/styx)
  - [Strimzi](https://github.com/strimzi/)
  - [Syndesis](https://syndesis.io/)
  - [StackGres](https://stackgres.io/)
  - [Boomerang Flow](https://github.com/boomerang-io)
  - [Apache Kyuubi](https://github.com/apache/kyuubi)

  Proprietary Platforms:
  - [vCommander](https://www.embotics.com/hybrid-cloud-management-platform)

As our community grows, we would like to track keep track of our users. Please send a PR with your organization/community name.

## Tests we run for every new Pull Request
There are the links of the Github Actions and Jenkins for the tests which run for every new Pull Request. You can view all the recent builds also.

* [Regression Tests](https://github.com/fabric8io/kubernetes-client/actions)
* [Unit Tests](https://ci.fabric8.io/job/kubernetes-client-pullreq/)

To get the updates about the releases, you can join https://groups.google.com/forum/embed/?place=forum/fabric8-devclients

## Kubectl Java Equivalents
This table provides `kubectl` to Kubernetes Java Client mappings. Most of the mappings are quite straightforward and are one liner
operations. However, some might require slightly more code to achieve same result:

| kubectl                                                                          | Fabric8 Kubernetes Client                                                                                |
|----------------------------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `kubectl config view`                                                            | [ConfigViewEquivalent.java](./kubernetes-examples/src/main/java/io/fabric8/kubernetes/examples/kubectl/equivalents/ConfigViewEquivalent.java)                                                     |
| `kubectl config get-contexts`                                                    | [ConfigGetContextsEquivalent.java](./kubernetes-examples/src/main/java/io/fabric8/kubernetes/examples/kubectl/equivalents/ConfigGetContextsEquivalent.java)                                       |
| `kubectl config current-context`                                                 | [ConfigGetCurrentContextEquivalent.java](./kubernetes-examples/src/main/java/io/fabric8/kubernetes/examples/kubectl/equivalents/ConfigGetCurrentContextEquivalent.java)                           |
| `kubectl config use-context minikube`                                            | [ConfigUseContext.java](./kubernetes-examples/src/main/java/io/fabric8/kubernetes/examples/kubectl/equivalents/ConfigUseContext.java)                                                             |
| `kubectl config view -o jsonpath='{.users[*].name}'`                             | [ConfigGetCurrentContextEquivalent.java](./kubernetes-examples/src/main/java/io/fabric8/kubernetes/examples/kubectl/equivalents/ConfigGetCurrentContextEquivalent.java)                           |
| `kubectl get pods --all-namespaces`                                              | [PodListGlobalEquivalent.java](./kubernetes-examples/src/main/java/io/fabric8/kubernetes/examples/kubectl/equivalents/PodListGlobalEquivalent.java)                                               |
| `kubectl get pods`                                                               | [PodListEquivalent.java](./kubernetes-examples/src/main/java/io/fabric8/kubernetes/examples/kubectl/equivalents/PodListEquivalent.java)                                                           |
| `kubectl get pods -w`                                                            | [PodWatchEquivalent.java](./kubernetes-examples/src/main/java/io/fabric8/kubernetes/examples/kubectl/equivalents/PodWatchEquivalent.java)                                                         |
| `kubectl get pods --sort-by='.metadata.creationTimestamp'`                       | [PodListGlobalEquivalent.java](./kubernetes-examples/src/main/java/io/fabric8/kubernetes/examples/kubectl/equivalents/PodListGlobalEquivalent.java)                                               |
| `kubectl run`                                                                    | [PodRunEquivalent.java](./kubernetes-examples/src/main/java/io/fabric8/kubernetes/examples/kubectl/equivalents/PodRunEquivalent.java)                                                             |
| `kubectl create -f test-pod.yaml`                                                | [PodCreateYamlEquivalent.java](./kubernetes-examples/src/main/java/io/fabric8/kubernetes/examples/kubectl/equivalents/PodCreateYamlEquivalent.java)                                               |
| `kubectl exec my-pod -- ls /`                                                    | [PodExecEquivalent.java](./kubernetes-examples/src/main/java/io/fabric8/kubernetes/examples/kubectl/equivalents/PodExecEquivalent.java)                                                           |
| `kubectl attach my-pod`                                                          | [PodAttachEquivalent.java](./kubernetes-examples/src/main/java/io/fabric8/kubernetes/examples/kubectl/equivalents/PodAttachEquivalent.java)                                                       |
| `kubectl delete pod my-pod`                                                      | [PodDelete.java](./kubernetes-examples/src/main/java/io/fabric8/kubernetes/examples/kubectl/equivalents/PodDelete.java)                                                                           |
| `kubectl delete -f test-pod.yaml`                                                | [PodDeleteViaYaml.java](./kubernetes-examples/src/main/java/io/fabric8/kubernetes/examples/kubectl/equivalents/PodDeleteViaYaml.java)                                                             |
| `kubectl cp /foo_dir my-pod:/bar_dir`                                            | [UploadDirectoryToPod.java](./kubernetes-examples/src/main/java/io/fabric8/kubernetes/examples/kubectl/equivalents/UploadDirectoryToPod.java)                                                     |
| `kubectl cp my-pod:/tmp/foo /tmp/bar`                                            | [DownloadFileFromPod.java](./kubernetes-examples/src/main/java/io/fabric8/kubernetes/examples/kubectl/equivalents/DownloadFileFromPod.java)                                                       |
| `kubectl cp my-pod:/tmp/foo -c c1 /tmp/bar`                                      | [DownloadFileFromMultiContainerPod.java](./kubernetes-examples/src/main/java/io/fabric8/kubernetes/examples/kubectl/equivalents/DownloadFileFromMultiContainerPod.java)                           |
| `kubectl cp /foo_dir my-pod:/tmp/bar_dir`                                        | [UploadFileToPod.java](./kubernetes-examples/src/main/java/io/fabric8/kubernetes/examples/kubectl/equivalents/UploadFileToPod.java)                                                               |
| `kubectl logs pod/my-pod`                                                        | [PodLogsEquivalent.java](./kubernetes-examples/src/main/java/io/fabric8/kubernetes/examples/kubectl/equivalents/PodLogsEquivalent.java)                                                           |
| `kubectl logs pod/my-pod -f`                                                     | [PodLogsFollowEquivalent.java](./kubernetes-examples/src/main/java/io/fabric8/kubernetes/examples/kubectl/equivalents/PodLogsFollowEquivalent.java)                                               |
| `kubectl logs pod/my-pod -c c1`                                                  | [PodLogsMultiContainerEquivalent.java](./kubernetes-examples/src/main/java/io/fabric8/kubernetes/examples/kubectl/equivalents/PodLogsMultiContainerEquivalent.java)                               |
| `kubectl port-forward my-pod 8080:80`                                            | [PortForwardEquivalent.java](./kubernetes-examples/src/main/java/io/fabric8/kubernetes/examples/kubectl/equivalents/PortForwardEquivalent.java)                                                   |
| `kubectl get pods --selector=version=v1 -o jsonpath='{.items[*].metadata.name}'` | [PodListFilterByLabel.java](./kubernetes-examples/src/main/java/io/fabric8/kubernetes/examples/kubectl/equivalents/PodListFilterByLabel.java)                                                     |
| `kubectl get pods --field-selector=status.phase=Running`                         | [PodListFilterFieldSelector.java](./kubernetes-examples/src/main/java/io/fabric8/kubernetes/examples/kubectl/equivalents/PodListFilterFieldSelector.java)                                         |
| `kubectl get pods --show-labels`                                                 | [PodShowLabels.java](./kubernetes-examples/src/main/java/io/fabric8/kubernetes/examples/kubectl/equivalents/PodShowLabels.java)                                                                   |
| `kubectl label pods my-pod new-label=awesome`                                    | [PodAddLabel.java](./kubernetes-examples/src/main/java/io/fabric8/kubernetes/examples/kubectl/equivalents/PodAddLabel.java)                                                                       |
| `kubectl annotate pods my-pod icon-url=http://goo.gl/XXBTWq`                     | [PodAddAnnotation.java](./kubernetes-examples/src/main/java/io/fabric8/kubernetes/examples/kubectl/equivalents/PodAddAnnotation.java)                                                             |
| `kubectl get configmap cm1 -o jsonpath='{.data.database}'`                       | [ConfigMapJsonPathEquivalent.java](./kubernetes-examples/src/main/java/io/fabric8/kubernetes/examples/kubectl/equivalents/ConfigMapJsonPathEquivalent.java)                                       |
| `kubectl create -f test-svc.yaml`                                                | [LoadAndCreateService.java](./kubernetes-examples/src/main/java/io/fabric8/kubernetes/examples/kubectl/equivalents/LoadAndCreateService.java)                                                     |
| `kubectl create -f test-deploy.yaml`                                             | [LoadAndCreateDeployment.java](./kubernetes-examples/src/main/java/io/fabric8/kubernetes/examples/kubectl/equivalents/LoadAndCreateDeployment.java)                                               |
| `kubectl set image deploy/d1 nginx=nginx:v2`                                     | [RolloutSetImageEquivalent.java](./kubernetes-examples/src/main/java/io/fabric8/kubernetes/examples/kubectl/equivalents/RolloutSetImageEquivalent.java)                                           |
| `kubectl scale --replicas=4 deploy/nginx-deployment`                             | [ScaleEquivalent.java](./kubernetes-examples/src/main/java/io/fabric8/kubernetes/examples/kubectl/equivalents/ScaleEquivalent.java)                                                               |
| `kubectl scale statefulset --selector=app=my-database --replicas=4`              | [ScaleWithLabelsEquivalent.java](./kubernetes-examples/src/main/java/io/fabric8/kubernetes/examples/kubectl/equivalents/ScaleWithLabelsEquivalent.java)                                           |
| `kubectl rollout restart deploy/d1`                                              | [RolloutRestartEquivalent.java](./kubernetes-examples/src/main/java/io/fabric8/kubernetes/examples/kubectl/equivalents/RolloutRestartEquivalent.java)                                             |
| `kubectl rollout pause deploy/d1`                                                | [RolloutPauseEquivalent.java](./kubernetes-examples/src/main/java/io/fabric8/kubernetes/examples/kubectl/equivalents/RolloutPauseEquivalent.java)                                                 |
| `kubectl rollout resume deploy/d1`                                               | [RolloutResumeEquivalent.java](./kubernetes-examples/src/main/java/io/fabric8/kubernetes/examples/kubectl/equivalents/RolloutResumeEquivalent.java)                                               |
| `kubectl rollout undo deploy/d1`                                                 | [RolloutUndoEquivalent.java](./kubernetes-examples/src/main/java/io/fabric8/kubernetes/examples/kubectl/equivalents/RolloutUndoEquivalent.java)                                                   |
| `kubectl create -f test-crd.yaml`                                                | [LoadAndCreateCustomResourceDefinition.java](./kubernetes-examples/src/main/java/io/fabric8/kubernetes/examples/kubectl/equivalents/LoadAndCreateCustomResourceDefinition.java)                   |
| `kubectl create -f customresource.yaml`                                          | [CustomResourceCreateDemo.java](./kubernetes-examples/src/main/java/io/fabric8/kubernetes/examples/kubectl/equivalents/CustomResourceCreateDemo.java)                                             |
| `kubectl create -f customresource.yaml`                                          | [CustomResourceCreateDemoTypeless.java](./kubernetes-examples/src/main/java/io/fabric8/kubernetes/examples/kubectl/equivalents/CustomResourceCreateDemoTypeless.java)                             |
| `kubectl get ns`                                                                 | [NamespaceListEquivalent.java](./kubernetes-examples/src/main/java/io/fabric8/kubernetes/examples/kubectl/equivalents/NamespaceListEquivalent.java)                                               |
| `kubectl create namespace test`                                                                 | [NamespaceCreateEquivalent.java](./kubernetes-examples/src/main/java/io/fabric8/kubernetes/examples/kubectl/equivalents/NamespaceCreateEquivalent.java)                                               |
| `kubectl apply -f test-resource-list.yml`                                        | [CreateOrReplaceResourceList.java](./kubernetes-examples/src/main/java/io/fabric8/kubernetes/examples/kubectl/equivalents/CreateOrReplaceResourceList.java)                                       |
| `kubectl get events`                                                             | [EventsGetEquivalent.java](./kubernetes-examples/src/main/java/io/fabric8/kubernetes/examples/kubectl/equivalents/EventsGetEquivalent.java)                                                       |
| `kubectl top nodes`                                                              | [TopEquivalent.java](./kubernetes-examples/src/main/java/io/fabric8/kubernetes/examples/kubectl/equivalents/TopEquivalent.java)                                                                   |
| `kubectl auth can-i create deployment.apps`                                      | [CanIEquivalent.java](./kubernetes-examples/src/main/java/io/fabric8/kubernetes/examples/kubectl/equivalents/CanIEquivalent.java)                                                                 |
| `kubectl create -f test-csr-v1.yml`                                              | [CertificateSigningRequestCreateYamlEquivalent.java](./kubernetes-examples/src/main/java/io/fabric8/kubernetes/examples/kubectl/equivalents/CertificateSigningRequestCreateYamlEquivalent.java)   |
| `kubectl certificate approve my-cert`                                            | [CertificateSigningRequestApproveYamlEquivalent.java](./kubernetes-examples/src/main/java/io/fabric8/kubernetes/examples/kubectl/equivalents/CertificateSigningRequestApproveYamlEquivalent.java) |
| `kubectl certificate deny my-cert`                                               | [CertificateSigningRequestDenyYamlEquivalent.java](./kubernetes-examples/src/main/java/io/fabric8/kubernetes/examples/kubectl/equivalents/CertificateSigningRequestDenyYamlEquivalent.java)       |
| `kubectl create -f quota.yaml --namespace=default`                               | [CreateResourceQuotaInNamespaceYamlEquivalent.java](./kubernetes-examples/src/main/java/io/fabric8/kubernetes/examples/kubectl/equivalents/CreateResourceQuotaInNamespaceYamlEquivalent.java)     |


[![Verify Codebase](https://github.com/hal/elemento/actions/workflows/verify.yml/badge.svg)](https://github.com/hal/elemento/actions/workflows/verify.yml) [![Javadoc](https://img.shields.io/badge/JavaDoc-Online-green)](https://hal.github.io/elemento/apidocs/) [![Maven Central](https://img.shields.io/maven-central/v/org.jboss.elemento/elemento-core)](https://search.maven.org/search?q=g:org.jboss.elemento%20AND%20a:elemento-core) ![GWT3/J2CL compatible](https://img.shields.io/badge/GWT3/J2CL-compatible-brightgreen.svg) [![Chat on Gitter](https://badges.gitter.im/hal/elemento.svg)](https://gitter.im/hal/elemento)

# Elemento

Elemento simplifies working with [Elemental2](https://github.com/google/elemental2). In a nutshell Elemento brings the following features to the table:

- Type safe [builders](https://hal-console.gitbook.io/elemento/builder-api), [event handlers](https://hal-console.gitbook.io/elemento/event-handlers) and [CSS selectors](https://hal-console.gitbook.io/elemento/selectors)
- [Helper methods](https://hal-console.gitbook.io/elemento/dom) to manipulate the DOM tree
- Simple, non-invasive, slash-based [router](https://hal-console.gitbook.io/elemento/router) with support for parameters and asynchronous loaders (`/a/:b/c`)
- Execute [asynchronous tasks](https://hal-console.gitbook.io/elemento/flow) in parallel, in sequence or as long as a certain condition is met.
- Thin [logging](https://hal-console.gitbook.io/elemento/logger) wrapper around `console.log` using categories, log levels, and a predefined log format.
- Ready to be used with [GWT](https://www.gwtproject.org/) and [J2CL](https://github.com/google/j2cl)
- Minimal dependencies
    - [Elemental2](https://github.com/google/elemental2) (`elemental2-core`, `elemental2-dom` and `elemental2-webstorage`)
    - GWT ([`org.gwtproject.event:gwt-event`](https://github.com/gwtproject/gwt-event)
      and [`org.gwtproject.safehtml:gwt-safehtml`](https://github.com/gwtproject/gwt-safehtml))

# Get Help

If you need help feel free to contact us at Gitter, browse the API documentation or file an issue.

- [Documentation](https://hal-console.gitbook.io/elemento/)
- [Gitter Channel](https://gitter.im/hal/elemento)
- [API documentation](https://hal.github.io/elemento/apidocs/)
- [Issues](https://github.com/hal/elemento/issues)

# Contributing

If you want to contribute to Elemento, please follow the steps in [contribution](CONTRIBUTING.md).


[![Build Status - CI](https://github.com/spring-cloud/spring-cloud-dataflow/actions/workflows/ci.yml/badge.svg)](https://github.com/spring-cloud/spring-cloud-dataflow/actions/workflows/ci.yml)

*Spring Cloud Data Flow* is a microservices-based toolkit for building streaming and batch data processing pipelines in
Cloud Foundry and Kubernetes.

Data processing pipelines consist of Spring Boot apps, built using the [Spring Cloud Stream](https://github.com/spring-cloud/spring-cloud-stream)
or [Spring Cloud Task](https://github.com/spring-cloud/spring-cloud-task) microservice frameworks.

This makes Spring Cloud Data Flow ideal for a range of data processing use cases, from import/export to event streaming
and predictive analytics.

----

## Components

**Architecture**: The Spring Cloud Data Flow Server is a Spring Boot application that provides RESTful API and REST clients
(Shell, Dashboard, Java DSL).
A single Spring Cloud Data Flow installation can support orchestrating the deployment of streams and tasks to Local,
Cloud Foundry, and Kubernetes.

Familiarize yourself with the Spring Cloud Data Flow [architecture](https://dataflow.spring.io/docs/concepts/architecture/)
and [feature capabilities](https://dataflow.spring.io/features/).

**Deployer SPI**: A Service Provider Interface (SPI) is defined in the [Spring Cloud Deployer](https://github.com/spring-cloud/spring-cloud-deployer)
project. The Deployer SPI provides an abstraction layer for deploying the apps for a given streaming or batch data pipeline
and managing the application lifecycle.

Spring Cloud Deployer Implementations:

* [Local](https://github.com/spring-cloud/spring-cloud-deployer-local)
* [Cloud Foundry](https://github.com/spring-cloud/spring-cloud-deployer-cloudfoundry)
* [Kubernetes](https://github.com/spring-cloud/spring-cloud-deployer-kubernetes)

**Domain Model**: The Spring Cloud Data Flow [domain module](https://github.com/spring-cloud/spring-cloud-dataflow/tree/master/spring-cloud-dataflow-core)
includes the concept of a *stream* that is a composition of Spring Cloud Stream applications in a linear data pipeline
from a *source* to a *sink*, optionally including *processor* application(s) in between. The domain also includes the
concept of a *task*, which may be any process that does not run indefinitely, including [Spring Batch](https://github.com/spring-projects/spring-batch)
jobs.

**Application Registry**: The [App Registry](https://github.com/spring-cloud/spring-cloud-dataflow/tree/master/spring-cloud-dataflow-registry)
maintains the metadata of the catalog of reusable applications.
For example, if relying on Maven coordinates, an application URI would be of the format:
`maven://<groupId>:<artifactId>:<version>`.

**Shell/CLI**: The [Shell](https://github.com/spring-cloud/spring-cloud-dataflow/tree/master/spring-cloud-dataflow-shell)
connects to the Spring Cloud Data Flow Server's REST API and supports a DSL that simplifies the process of defining a
stream or task and managing its lifecycle.

----

## Building

Clone the repo and type

    $ ./mvnw -s .settings.xml clean install

Looking for more information? Follow this [link](https://github.com/spring-cloud/spring-cloud-dataflow/blob/master/spring-cloud-dataflow-docs/src/main/asciidoc/appendix-building.adoc).

### Building on Windows

When using Git on Windows to check out the project, it is important to handle line-endings correctly during checkouts.
By default Git will change the line-endings during checkout to `CRLF`. This is, however, not desired for _Spring Cloud Data Flow_
as this may lead to test failures under Windows.

Therefore, please ensure that you set Git property `core.autocrlf` to `false`, e.g. using: `$ git config core.autocrlf false`.
For more information please refer to the [Git documentation, Formatting and Whitespace](https://git-scm.com/book/en/v2/Customizing-Git-Git-Configuration).

----

## Running Locally w/ Oracle
By default, the Dataflow server jar does not include the Oracle database driver dependency.
If you want to use Oracle for development/testing when running locally, you can specify the `local-dev-oracle` Maven profile when building.
The following command will include the Oracle driver dependency in the jar:
```
$ ./mvnw -s .settings.xml clean package -Plocal-dev-oracle
```
You can follow the steps in the [Oracle on Mac ARM64](https://github.com/spring-cloud/spring-cloud-dataflow/wiki/Oracle-on-Mac-ARM64#run-container-in-docker) Wiki to run Oracle XE locally in Docker with Dataflow pointing at it.

> **NOTE:** If you are not running Mac ARM64 just skip the steps related to Homebrew and Colima

----

## Running Locally w/ Microsoft SQL Server
By default, the Dataflow server jar does not include the MSSQL database driver dependency.
If you want to use MSSQL for development/testing when running locally, you can specify the `local-dev-mssql` Maven profile when building.
The following command will include the MSSQL driver dependency in the jar:
```
$ ./mvnw -s .settings.xml clean package -Plocal-dev-mssql
```
You can follow the steps in the [MSSQL on Mac ARM64](https://github.com/spring-cloud/spring-cloud-dataflow/wiki/MSSQL-on-Mac-ARM64#running-dataflow-locally-against-mssql) Wiki to run MSSQL locally in Docker with Dataflow pointing at it.

> **NOTE:** If you are not running Mac ARM64 just skip the steps related to Homebrew and Colima

----

## Running Locally w/ IBM DB2
By default, the Dataflow server jar does not include the DB2 database driver dependency.
If you want to use DB2 for development/testing when running locally, you can specify the `local-dev-db2` Maven profile when building.
The following command will include the DB2 driver dependency in the jar:
```
$ ./mvnw -s .settings.xml clean package -Plocal-dev-db2
```
You can follow the steps in the [DB2 on Mac ARM64](https://github.com/spring-cloud/spring-cloud-dataflow/wiki/DB2-on-Mac-ARM64#running-dataflow-locally-against-db2) Wiki to run DB2 locally in Docker with Dataflow pointing at it.

> **NOTE:** If you are not running Mac ARM64 just skip the steps related to Homebrew and Colima

----

## Contributing

We welcome contributions! See the [CONTRIBUTING](./CONTRIBUTING.adoc) guide for details.

----

## Code formatting guidelines

* The directory ./src/eclipse has two files for use with code formatting, `eclipse-code-formatter.xml` for the majority of the code formatting rules and `eclipse.importorder` to order the import statements.

* In eclipse you import these files by navigating `Windows -> Preferences` and then the menu items `Preferences > Java > Code Style > Formatter` and `Preferences > Java > Code Style > Organize Imports` respectfully.

* In `IntelliJ`, install the plugin `Eclipse Code Formatter`.  You can find it by searching the "Browse Repositories" under the plugin option within `IntelliJ` (Once installed you will need to reboot Intellij for it to take effect).
Then navigate to `Intellij IDEA > Preferences` and select the Eclipse Code Formatter.  Select the `eclipse-code-formatter.xml` file for the field `Eclipse Java Formatter config file` and the file `eclipse.importorder` for the field `Import order`.
Enable the `Eclipse code formatter` by clicking `Use the Eclipse code formatter` then click the *OK* button.
** NOTE: If you configure the `Eclipse Code Formatter` from `File > Other Settings > Default Settings` it will set this policy across all of your Intellij projects.

## License

Spring Cloud Data Flow is Open Source software released under the [Apache 2.0 license](https://www.apache.org/licenses/LICENSE-2.0.html).