diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
index 4bd8c5e68..55593c973 100644
--- a/.github/workflows/release.yml
+++ b/.github/workflows/release.yml
@@ -51,6 +51,7 @@ jobs:
Copy-Item secring.gpg components/serialization/json/ -Verbose
Copy-Item secring.gpg components/serialization/multipart/ -Verbose
Copy-Item secring.gpg components/http/okHttp/ -Verbose
+ Copy-Item secring.gpg components/bundle/ -Verbose
shell: pwsh
working-directory: ./
- name: Build with Gradle
@@ -96,6 +97,7 @@ jobs:
Copy-Item secring.gpg components/serialization/json/ -Verbose
Copy-Item secring.gpg components/serialization/multipart/ -Verbose
Copy-Item secring.gpg components/http/okHttp/ -Verbose
+ Copy-Item secring.gpg components/bundle/ -Verbose
shell: pwsh
working-directory: ./
- name: Build with Gradle
@@ -122,6 +124,9 @@ jobs:
- name: Publish Release okHttp
run: ./gradlew --no-daemon :components:http:okHttp:$PUBLISH_TASK -PmavenCentralSnapshotArtifactSuffix=""
working-directory: ./
+ - name: Publish Release bundle
+ run: ./gradlew --no-daemon :components:bundle:$PUBLISH_TASK -PmavenCentralSnapshotArtifactSuffix=""
+ working-directory: ./
- name: Release
uses: anton-yurchenko/git-release@v6.0
env:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index be7bfce6d..02d6a85bb 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -7,6 +7,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [Unreleased]
+## [1.2.0] - 2024-07-25
+
+### Changed
+
+- Adds bundle package for Kiota [#1420](https://github.com/microsoft/kiota-java/issues/1420).
+
## [1.1.14] - 2024-06-10
### Changed
diff --git a/components/bundle/.gitignore b/components/bundle/.gitignore
new file mode 100644
index 000000000..20a548b24
--- /dev/null
+++ b/components/bundle/.gitignore
@@ -0,0 +1,10 @@
+# Ignore Gradle project-specific cache directory
+.gradle
+
+# Ignore Gradle build output directory
+build
+
+
+.settings
+.project
+.classpath
\ No newline at end of file
diff --git a/components/bundle/android/.gitignore b/components/bundle/android/.gitignore
new file mode 100644
index 000000000..f06dfad69
--- /dev/null
+++ b/components/bundle/android/.gitignore
@@ -0,0 +1,2 @@
+.gradle
+build
\ No newline at end of file
diff --git a/components/bundle/android/AndroidManifest.xml b/components/bundle/android/AndroidManifest.xml
new file mode 100644
index 000000000..2932f8879
--- /dev/null
+++ b/components/bundle/android/AndroidManifest.xml
@@ -0,0 +1,23 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/components/bundle/android/build.gradle b/components/bundle/android/build.gradle
new file mode 100644
index 000000000..e4135d1b9
--- /dev/null
+++ b/components/bundle/android/build.gradle
@@ -0,0 +1,73 @@
+buildscript {
+ repositories {
+ google()
+ gradlePluginPortal()
+ maven {
+ url "https://plugins.gradle.org/m2/"
+ }
+ maven { url 'https://oss.sonatype.org/content/repositories/snapshots' }
+ }
+
+ dependencies {
+ classpath "com.gradle:gradle-enterprise-gradle-plugin:3.17.5"
+ classpath "com.android.tools.build:gradle:8.5.1"
+ classpath "com.github.ben-manes:gradle-versions-plugin:0.51.0"
+ }
+}
+
+repositories {
+ google()
+ gradlePluginPortal()
+}
+
+apply plugin: "com.android.library"
+apply plugin: "com.github.ben-manes.versions"
+
+android {
+ namespace "com.microsoft.kiota.bundle"
+ compileSdkVersion 35
+
+ defaultConfig {
+ versionCode 1
+ versionName "1.0"
+ minSdkVersion 26
+ targetSdkVersion 35
+ }
+
+ buildTypes {
+ release {
+ minifyEnabled false
+ }
+ }
+
+ compileOptions {
+ sourceCompatibility JavaVersion.VERSION_1_8
+ targetCompatibility JavaVersion.VERSION_1_8
+ }
+
+ lintOptions {
+ textOutput "stdout"
+ checkAllWarnings true
+ warningsAsErrors true
+ disable "UnusedResources" // Unused will be removed on release
+ disable "IconExpectedSize" // Using the material icons provided from Google
+ disable "GoogleAppIndexingApiWarning" // We might want to index our app later
+ disable "InvalidPackage" // Butterknife, Okio and Realm
+ disable "ResourceType" // Annotation binding
+ disable "GradleDependency"
+ disable "NewerVersionAvailable"
+ disable "DuplicatePlatformClasses" // xpp3 added by azure-identity
+ }
+ sourceSets {
+ main {
+ java.srcDirs = ['../src/main/java']
+ res.srcDirs = ['../src/main/java']
+ manifest.srcFile 'AndroidManifest.xml'
+ }
+ androidTest {
+ setRoot '../src/test'
+ }
+ }
+}
+
+apply from: "../gradle/dependencies.gradle"
diff --git a/components/bundle/android/gradle.properties b/components/bundle/android/gradle.properties
new file mode 100644
index 000000000..3b7dc4668
--- /dev/null
+++ b/components/bundle/android/gradle.properties
@@ -0,0 +1 @@
+mavenArtifactId = microsoft-kiota-bundle
diff --git a/components/bundle/build.gradle b/components/bundle/build.gradle
new file mode 100644
index 000000000..a08c0788c
--- /dev/null
+++ b/components/bundle/build.gradle
@@ -0,0 +1,227 @@
+plugins {
+ // Apply the java-library plugin to add support for Java Library
+ id 'java-library'
+ id 'eclipse'
+ id 'maven-publish'
+ id 'signing'
+ id 'jacoco'
+ id 'com.github.spotbugs'
+ id 'com.diffplug.spotless'
+}
+
+java {
+ modularity.inferModulePath = true
+ withSourcesJar()
+ withJavadocJar()
+}
+
+test {
+ useJUnitPlatform()
+ finalizedBy jacocoTestReport // report is always generated after tests run
+}
+
+jacocoTestReport {
+ dependsOn test // tests are required to run before generating the report
+ reports.xml.required = true
+}
+
+jacoco {
+ toolVersion = "0.8.11"
+}
+
+spotbugsMain {
+ excludeFilter = file("spotBugsExcludeFilter.xml")
+ reports {
+ html {
+ required
+ outputLocation = file("$buildDir/reports/spotbugs/main/spotbugs.html")
+ stylesheet = 'fancy-hist.xsl'
+ }
+ }
+}
+
+spotbugsTest {
+ excludeFilter = file("spotBugsExcludeFilter.xml")
+ reports {
+ html {
+ required
+ outputLocation = file("$buildDir/reports/spotbugs/test/spotbugs.html")
+ stylesheet = 'fancy-hist.xsl'
+ }
+ }
+}
+
+sourceSets {
+ main {
+ java {
+ exclude 'pom.xml'
+ }
+ }
+}
+
+// In this section you declare where to find the dependencies of your project
+repositories {
+ // You can declare any Maven/Ivy/file repository here.
+ mavenCentral()
+}
+
+apply from: "gradle/dependencies.gradle"
+
+def pomConfig = {
+ licenses {
+ license([:]) {
+ name "MIT License"
+ url "http://opensource.org/licenses/MIT"
+ distribution "repo"
+ }
+ }
+}
+
+//Publishing tasks-
+//Maven Central Snapshot: publishMavenPublicationToMavenRepository
+//Maven Central Release: publishmavenPublicationToMaven2Repository
+
+tasks.jar {
+ manifest {
+ attributes('Automatic-Module-Name': project.property('mavenGroupId'))
+ }
+}
+
+publishing {
+
+ publications {
+ maven(MavenPublication) {
+ customizePom(pom)
+ groupId project.property('mavenGroupId')
+ artifactId project.property('mavenArtifactId')
+ version "${mavenMajorVersion}.${mavenMinorVersion}.${mavenPatchVersion}${mavenCentralSnapshotArtifactSuffix}"
+ from components.java
+ pom.withXml {
+ def pomFile = file("${project.buildDir}/generated-pom.xml")
+ writeTo(pomFile)
+ }
+ }
+ }
+ repositories {
+ maven {
+ url = 'https://oss.sonatype.org/content/repositories/snapshots'
+ name = 'sonatypeSnapshot'
+
+ credentials {
+ if (project.rootProject.file('local.properties').exists()) {
+ Properties properties = new Properties()
+ properties.load(project.rootProject.file('local.properties').newDataInputStream())
+ username = properties.getProperty('sonatypeUsername')
+ password = properties.getProperty('sonatypePassword')
+ }
+ }
+ }
+
+ maven {
+ url = 'https://oss.sonatype.org/service/local/staging/deploy/maven2'
+ name = 'sonatype'
+
+ credentials {
+ if (project.rootProject.file('local.properties').exists()) {
+ Properties properties = new Properties()
+ properties.load(project.rootProject.file('local.properties').newDataInputStream())
+ username = properties.getProperty('sonatypeUsername')
+ password = properties.getProperty('sonatypePassword')
+ }
+ }
+ }
+ }
+}
+
+signing {
+ sign publishing.publications.maven
+}
+tasks.withType(Sign)*.enabled = mavenCentralPublishingEnabled.toBoolean()
+
+def fixAscNames = { name ->
+ if(name.contains('pom')) {
+ "${project.property('mavenArtifactId')}-${mavenMajorVersion}.${mavenMinorVersion}.${mavenPatchVersion}.pom.asc"
+ } else {
+ name.replace('microsoft-kiota-bundle', "${project.property('mavenArtifactId')}-${mavenMajorVersion}.${mavenMinorVersion}.${mavenPatchVersion}")
+ }
+}
+
+compileJava {
+ options.compilerArgs << "-parameters"
+ sourceCompatibility = '1.8'
+ targetCompatibility = '1.8'
+}
+
+def getVersionCode() {
+ return mavenMajorVersion.toInteger() * 10000 + mavenMinorVersion.toInteger() * 100 + mavenPatchVersion.toInteger()
+}
+
+def getVersionName() {
+ return "${mavenMajorVersion}.${mavenMinorVersion}.${mavenPatchVersion}${mavenArtifactSuffix}"
+}
+
+artifacts {
+ archives jar
+}
+
+def customizePom(pom) {
+ pom.withXml {
+ def root = asNode()
+
+ root.dependencies.removeAll { dep ->
+ dep.scope == "test"
+ }
+
+ root.children().last() + {
+ resolveStrategy = Closure.DELEGATE_FIRST
+
+ description 'Microsoft Kiota-Bundle'
+ name 'Microsoft Kiota-Java Bundle'
+ url 'https://github.com/microsoft/kiota-java'
+ organization {
+ name 'Microsoft'
+ url 'https://github.com/microsoft/kiota-java'
+ }
+ issueManagement {
+ system 'GitHub'
+ url 'https://github.com/microsoft/kiota-java/issues'
+ }
+ licenses {
+ license {
+ name "MIT License"
+ url "http://opensource.org/licenses/MIT"
+ distribution "repo"
+ }
+ }
+ scm {
+ url 'https://github.com/microsoft/kiota-java'
+ connection 'scm:git:git://github.com/microsoft/kiota-java.git'
+ developerConnection 'scm:git:ssh://git@github.com:microsoft/kiota-java.git'
+ }
+ developers {
+ developer {
+ name 'Microsoft'
+ }
+ }
+ }
+ }
+}
+
+gradle.taskGraph.whenReady { taskGraph ->
+ if (project.rootProject.file('local.properties').exists()) {
+ Properties properties = new Properties()
+ properties.load(project.rootProject.file('local.properties').newDataInputStream())
+ tasks.withType(Sign)*.enabled = (properties.containsKey('enableSigning')) ? properties.getProperty('enableSigning').toBoolean() : false
+ allprojects { ext."signing.keyId" = properties.getProperty('signing.keyId') }
+ allprojects { ext."signing.secretKeyRingFile" = properties.getProperty('signing.secretKeyRingFile') }
+ allprojects { ext."signing.password" = properties.getProperty('signing.password') }
+ }
+}
+
+model {
+ tasks.generatePomFileForMavenPublication {
+ destination = file("${project.buildDir}/generated-pom.xml")
+ }
+}
+
+apply from: file('../../spotless.groovy')
diff --git a/components/bundle/gradle.properties b/components/bundle/gradle.properties
new file mode 100644
index 000000000..3b7dc4668
--- /dev/null
+++ b/components/bundle/gradle.properties
@@ -0,0 +1 @@
+mavenArtifactId = microsoft-kiota-bundle
diff --git a/components/bundle/gradle/dependencies.gradle b/components/bundle/gradle/dependencies.gradle
new file mode 100644
index 000000000..cf254bc4b
--- /dev/null
+++ b/components/bundle/gradle/dependencies.gradle
@@ -0,0 +1,18 @@
+dependencies {
+ // Use JUnit Jupiter API for testing.
+ testImplementation 'org.junit.jupiter:junit-jupiter-api:5.10.3'
+ testImplementation 'org.junit.jupiter:junit-jupiter-params:5.10.3'
+
+ // Use JUnit Jupiter Engine for testing.
+ testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine'
+ testImplementation 'org.mockito:mockito-inline:5.2.0'
+
+ implementation 'jakarta.annotation:jakarta.annotation-api:2.1.1'
+
+ api project(':components:abstractions')
+ api project(':components:http:okHttp')
+ implementation project(':components:serialization:json')
+ implementation project(':components:serialization:text')
+ implementation project(':components:serialization:multipart')
+ implementation project(':components:serialization:form')
+}
diff --git a/components/bundle/java-8/.gitignore b/components/bundle/java-8/.gitignore
new file mode 100644
index 000000000..7f6823bcc
--- /dev/null
+++ b/components/bundle/java-8/.gitignore
@@ -0,0 +1,2 @@
+.gradle
+build/
diff --git a/components/bundle/java-8/build.gradle b/components/bundle/java-8/build.gradle
new file mode 100644
index 000000000..6ad52d9f9
--- /dev/null
+++ b/components/bundle/java-8/build.gradle
@@ -0,0 +1,28 @@
+plugins {
+ // Apply the java-library plugin to add support for Java Library
+ id 'java-library'
+ id 'eclipse'
+}
+
+repositories {
+ mavenCentral()
+}
+
+sourceSets {
+ main {
+ java {
+ srcDirs = ['../src']
+ exclude 'test/**'
+ }
+ }
+}
+
+java {
+ toolchain {
+ languageVersion = JavaLanguageVersion.of(8)
+ }
+ withSourcesJar()
+ withJavadocJar()
+}
+
+apply from: "../gradle/dependencies.gradle"
diff --git a/components/bundle/java-8/gradle.properties b/components/bundle/java-8/gradle.properties
new file mode 100644
index 000000000..3b7dc4668
--- /dev/null
+++ b/components/bundle/java-8/gradle.properties
@@ -0,0 +1 @@
+mavenArtifactId = microsoft-kiota-bundle
diff --git a/components/bundle/spotBugsExcludeFilter.xml b/components/bundle/spotBugsExcludeFilter.xml
new file mode 100644
index 000000000..ebca482dc
--- /dev/null
+++ b/components/bundle/spotBugsExcludeFilter.xml
@@ -0,0 +1,6 @@
+
+
+
\ No newline at end of file
diff --git a/components/bundle/src/main/java/com/microsoft/kiota/bundle/DefaultRequestAdapter.java b/components/bundle/src/main/java/com/microsoft/kiota/bundle/DefaultRequestAdapter.java
new file mode 100644
index 000000000..45fe5bd74
--- /dev/null
+++ b/components/bundle/src/main/java/com/microsoft/kiota/bundle/DefaultRequestAdapter.java
@@ -0,0 +1,100 @@
+package com.microsoft.kiota.bundle;
+
+import com.microsoft.kiota.ApiClientBuilder;
+import com.microsoft.kiota.authentication.AuthenticationProvider;
+import com.microsoft.kiota.http.ObservabilityOptions;
+import com.microsoft.kiota.http.OkHttpRequestAdapter;
+import com.microsoft.kiota.serialization.*;
+
+import jakarta.annotation.Nonnull;
+import jakarta.annotation.Nullable;
+
+import okhttp3.Call;
+
+/** RequestAdapter implementation for Kiota Bundle */
+public class DefaultRequestAdapter extends OkHttpRequestAdapter {
+
+ /**
+ * Instantiates a DefaultRequestAdapter with the provided authentication provider.
+ * @param authenticationProvider the authentication provider to use for authenticating requests.
+ */
+ public DefaultRequestAdapter(@Nonnull final AuthenticationProvider authenticationProvider) {
+ this(authenticationProvider, null);
+ }
+
+ /**
+ * Instantiates a new DefaultRequestAdapter with the provided authentication provider, and the parse node factory.
+ * @param authenticationProvider the authentication provider to use for authenticating requests.
+ * @param parseNodeFactory the parse node factory to use for parsing responses.
+ */
+ @SuppressWarnings("LambdaLast")
+ public DefaultRequestAdapter(
+ @Nonnull final AuthenticationProvider authenticationProvider,
+ @Nullable final ParseNodeFactory parseNodeFactory) {
+ this(authenticationProvider, parseNodeFactory, null);
+ }
+
+ /**
+ * Instantiates a new DefaultRequestAdapter with the provided authentication provider, parse node factory, and the serialization writer factory.
+ * @param authenticationProvider the authentication provider to use for authenticating requests.
+ * @param parseNodeFactory the parse node factory to use for parsing responses.
+ * @param serializationWriterFactory the serialization writer factory to use for serializing requests.
+ */
+ @SuppressWarnings("LambdaLast")
+ public DefaultRequestAdapter(
+ @Nonnull final AuthenticationProvider authenticationProvider,
+ @Nullable final ParseNodeFactory parseNodeFactory,
+ @Nullable final SerializationWriterFactory serializationWriterFactory) {
+ this(authenticationProvider, parseNodeFactory, serializationWriterFactory, null);
+ }
+
+ /**
+ * Instantiates a new DefaultRequestAdapter with the provided authentication provider, parse node factory, serialization writer factory, and the http client.
+ * @param authenticationProvider the authentication provider to use for authenticating requests.
+ * @param parseNodeFactory the parse node factory to use for parsing responses.
+ * @param serializationWriterFactory the serialization writer factory to use for serializing requests.
+ * @param client the http client to use for sending requests.
+ */
+ @SuppressWarnings("LambdaLast")
+ public DefaultRequestAdapter(
+ @Nonnull final AuthenticationProvider authenticationProvider,
+ @Nullable final ParseNodeFactory parseNodeFactory,
+ @Nullable final SerializationWriterFactory serializationWriterFactory,
+ @Nullable final Call.Factory client) {
+ this(authenticationProvider, parseNodeFactory, serializationWriterFactory, client, null);
+ }
+
+ /**
+ * Instantiates a new DefaultRequestAdapter with the provided authentication provider, parse node factory, serialization writer factory, http client and observability options.
+ * @param authenticationProvider the authentication provider to use for authenticating requests.
+ * @param parseNodeFactory the parse node factory to use for parsing responses.
+ * @param serializationWriterFactory the serialization writer factory to use for serializing requests.
+ * @param client the http client to use for sending requests.
+ * @param observabilityOptions the observability options to use for sending requests.
+ */
+ @SuppressWarnings("LambdaLast")
+ public DefaultRequestAdapter(
+ @Nonnull final AuthenticationProvider authenticationProvider,
+ @Nullable final ParseNodeFactory parseNodeFactory,
+ @Nullable final SerializationWriterFactory serializationWriterFactory,
+ @Nullable final Call.Factory client,
+ @Nullable final ObservabilityOptions observabilityOptions) {
+ super(
+ authenticationProvider,
+ parseNodeFactory,
+ serializationWriterFactory,
+ client,
+ observabilityOptions);
+ setupDefaults();
+ }
+
+ private void setupDefaults() {
+ ApiClientBuilder.registerDefaultSerializer(JsonSerializationWriterFactory::new);
+ ApiClientBuilder.registerDefaultSerializer(TextSerializationWriterFactory::new);
+ ApiClientBuilder.registerDefaultSerializer(FormSerializationWriterFactory::new);
+ ApiClientBuilder.registerDefaultSerializer(MultipartSerializationWriterFactory::new);
+ ApiClientBuilder.registerDefaultDeserializer(JsonParseNodeFactory::new);
+ ApiClientBuilder.registerDefaultDeserializer(FormParseNodeFactory::new);
+ ApiClientBuilder.registerDefaultDeserializer(TextParseNodeFactory::new);
+ }
+}
diff --git a/components/bundle/src/test/java/com/microsoft/kiota/bundle/BundleTests.java b/components/bundle/src/test/java/com/microsoft/kiota/bundle/BundleTests.java
new file mode 100644
index 000000000..529dd0151
--- /dev/null
+++ b/components/bundle/src/test/java/com/microsoft/kiota/bundle/BundleTests.java
@@ -0,0 +1,64 @@
+package com.microsoft.kiota.bundle;
+
+import static org.junit.jupiter.api.Assertions.*;
+import static org.mockito.Mockito.mock;
+
+import com.microsoft.kiota.authentication.AuthenticationProvider;
+import com.microsoft.kiota.serialization.ParseNodeFactoryRegistry;
+import com.microsoft.kiota.serialization.SerializationWriterFactoryRegistry;
+
+import org.junit.jupiter.api.Test;
+
+class BundleTests {
+ @Test
+ void throwsErrorNullAuthenticationProvider() throws Exception {
+ var exception =
+ assertThrows(NullPointerException.class, () -> new DefaultRequestAdapter(null));
+ assertEquals("parameter authenticationProvider cannot be null", exception.getMessage());
+ }
+
+ @Test
+ void serializersAreRegisteredAsExpected() throws Exception {
+ final var authenticationProviderMock = mock(AuthenticationProvider.class);
+ var defaultRequestAdapter = new DefaultRequestAdapter(authenticationProviderMock);
+ assertEquals("", defaultRequestAdapter.getBaseUrl());
+
+ // validate
+ var serializerCount =
+ SerializationWriterFactoryRegistry.defaultInstance.contentTypeAssociatedFactories
+ .size();
+ var deserializerCount =
+ ParseNodeFactoryRegistry.defaultInstance.contentTypeAssociatedFactories.size();
+
+ assertEquals(4, serializerCount); // four serializers present
+ assertEquals(3, deserializerCount); // three deserializers present
+
+ var serializerKeys =
+ SerializationWriterFactoryRegistry.defaultInstance.contentTypeAssociatedFactories
+ .keySet();
+ var deserializerKeys =
+ ParseNodeFactoryRegistry.defaultInstance.contentTypeAssociatedFactories.keySet();
+
+ assertTrue(serializerKeys.contains("application/json"));
+ assertTrue(
+ deserializerKeys.contains(
+ "application/json")); // Serializer and deserializer present for
+ // application/json
+
+ assertTrue(serializerKeys.contains("text/plain"));
+ assertTrue(
+ deserializerKeys.contains(
+ "text/plain")); // Serializer and deserializer present for text/plain
+
+ assertTrue(serializerKeys.contains("application/x-www-form-urlencoded"));
+ assertTrue(
+ deserializerKeys.contains(
+ "application/x-www-form-urlencoded")); // Serializer and deserializer
+ // present for
+ // application/x-www-form-urlencoded
+
+ assertTrue(
+ serializerKeys.contains(
+ "multipart/form-data")); // Serializer present for multipart/form-data
+ }
+}
diff --git a/gradle.properties b/gradle.properties
index 0ea37183a..b09f5e443 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -25,8 +25,8 @@ org.gradle.caching=true
mavenGroupId = com.microsoft.kiota
mavenMajorVersion = 1
-mavenMinorVersion = 1
-mavenPatchVersion = 14
+mavenMinorVersion = 2
+mavenPatchVersion = 0
mavenArtifactSuffix =
#These values are used to run functional tests
diff --git a/settings.gradle b/settings.gradle
index 64c232f1d..5d8ce78ad 100644
--- a/settings.gradle
+++ b/settings.gradle
@@ -18,3 +18,5 @@ include ':components:serialization:text' + suffix
include ':components:serialization:multipart' + suffix
include ':components:authentication:azure' + suffix
include ':components:http:okHttp' + suffix
+include ':components:bundle' + suffix
+