Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions connector/azure/devops/.openapi-generator-ignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
**/.gitignore
**/git_push.sh
**/gradle-wrapper.jar
**/gradle-wrapper.properties
**/gradlew.bat
**/gradlew
**/openapi.yaml
**/maven.yml
**/.travis.yml
**/AndroidManifest.xml
**/gradle.properties
**/settings.gradle
**/build.sbt
**/build.gradle
**/README.md
**/.openapi-generator-ignore
**/pom.xml
60 changes: 60 additions & 0 deletions connector/azure/devops/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
plugins {
id 'blaze-query.java-conventions'
id 'org.openapi.generator'
}

dependencies {
api project(':blaze-query-core-api')
api project(':blaze-query-connector-base')
api libs.com.google.code.findbugs.jsr305
api libs.jersey.core.jersey.client
api libs.jersey.inject.jersey.hk2
api libs.jersey.media.jersey.media.multipart
api libs.jersey.media.jersey.media.json.jackson
api libs.jackson.core
api libs.jackson.annotations
api libs.jackson.databind
api libs.org.openapitools.jackson.databind.nullable
api libs.jackson.datatype.jsr310
api libs.com.github.scribejava.scribejava.apis
api libs.jersey.connectors.jersey.apache.connector
testImplementation libs.junit.jupiter
testImplementation project(':blaze-query-core-impl')
testImplementation libs.assertj.core
compileOnly libs.jakarta.annotation.api
}

description = 'blaze-query-connector-azure-devops'

sourceSets {
main {
java {
srcDirs += "${project.buildDir}/generated"
}
}
}

openApiGenerate {
generatorName.set("java")
inputSpec.set("${project.projectDir}/src/main/resources/azure-devops-7.1-openapi-spec.json")
skipValidateSpec.set(true)
outputDir.set(project.layout.buildDirectory.dir("generated").map { it.asFile.absolutePath })
apiPackage.set("com.blazebit.query.connector.devops.api")
invokerPackage.set("com.blazebit.query.connector.devops.invoker")
modelPackage.set("com.blazebit.query.connector.devops.model")
library.set("jersey3")
generateModelTests.set(false)
generateModelDocumentation.set(false)
generateApiTests.set(false)
generateApiDocumentation.set(false)
ignoreFileOverride.set("${project.projectDir}/.openapi-generator-ignore")
configOptions.put("sourceFolder", "/")
configOptions.put("serializationLibrary", "jackson")
configOptions.put("useJakartaEe", "true")
}

tasks.openApiGenerate.inputs.file("${project.projectDir}/.openapi-generator-ignore")

tasks.compileJava.dependsOn tasks.openApiGenerate
tasks.sourcesJar.dependsOn tasks.compileJava
tasks.sourcesJar.dependsOn tasks.openApiGenerate
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
/*
* SPDX-License-Identifier: Apache-2.0
* Copyright Blazebit
*/
package com.blazebit.query.connector.azure.devops;


import com.blazebit.query.connector.base.DataFormats;
import com.blazebit.query.connector.devops.api.AccountsApi;
import com.blazebit.query.connector.devops.api.ProfilesApi;
import com.blazebit.query.connector.devops.invoker.ApiClient;
import com.blazebit.query.connector.devops.invoker.ApiException;
import com.blazebit.query.connector.devops.model.Account;
import com.blazebit.query.spi.DataFetchContext;
import com.blazebit.query.spi.DataFetcher;
import com.blazebit.query.spi.DataFetcherException;
import com.blazebit.query.spi.DataFormat;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

/**
* @author Dimitar Prisadnikov
* @since 1.0.8
*/
public class AccountDataFetcher implements DataFetcher<Account>, Serializable {

public static final AccountDataFetcher INSTANCE = new AccountDataFetcher();

private AccountDataFetcher() {
}

@Override
public List<Account> fetch(DataFetchContext context) {
try {
List<ApiClient> apiClients = DevopsConnectorConfig.API_CLIENT.getAll( context );
List<Account> list = new ArrayList<>();
for ( ApiClient apiClient : apiClients ) {
AccountsApi accountsApi = new AccountsApi( apiClient );
ProfilesApi profilesApi = new ProfilesApi( apiClient );


//TODO: Pagination?
List<Account> organizations = accountsApi.accountsList(
"7.1", null, UUID.fromString( "9d78628b-49ee-6375-8e74-009485f60bfd"), null
);
list.addAll( organizations );
if ( organizations.size() != 100 ) {
break;
}
}
return list;
}
catch (ApiException e) {
throw new DataFetcherException( "Could not fetch account list", e );
}
}

@Override
public DataFormat getDataFormat() {
return DataFormats.beansConvention( Account.class, DevopsConventionContext.INSTANCE );
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/*
* SPDX-License-Identifier: Apache-2.0
* Copyright Blazebit
*/
package com.blazebit.query.connector.azure.devops;

import com.blazebit.query.connector.devops.invoker.ApiClient;
import com.blazebit.query.spi.DataFetcherConfig;

/**
* The configuration properties for the Azure DevOps connector.
*
* @author Dimitar Prisadnikov
* @since 1.0.8
*/
public final class DevopsConnectorConfig {

/**
* Specified the {@link ApiClient} to use for querying data.
*/
public static final DataFetcherConfig<ApiClient> API_CLIENT = DataFetcherConfig.forPropertyName(
"azureDevopsApiClient" );

private DevopsConnectorConfig() {
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
/*
* SPDX-License-Identifier: Apache-2.0
* Copyright Blazebit
*/
package com.blazebit.query.connector.azure.devops;

import com.blazebit.query.connector.base.ConventionContext;
import com.blazebit.query.connector.devops.model.AbstractOpenApiSchema;

import java.lang.reflect.Member;
import java.lang.reflect.Method;

/**
* @author Dimitar Prisadnikov
* @since 1.0.8
*/
public class DevopsConventionContext implements ConventionContext {

public static final ConventionContext INSTANCE = new DevopsConventionContext();

private DevopsConventionContext() {
}

@Override
public boolean nullOnException(Method method) {
// An OpenAPI schema is a union type, so some getters may throw exceptions based on actual instance
return AbstractOpenApiSchema.class.isAssignableFrom( method.getDeclaringClass() );
}

@Override
public ConventionContext getSubFilter(Class<?> concreteClass, Member member) {
if ( AbstractOpenApiSchema.class.isAssignableFrom( concreteClass ) ) {
switch ( member.getName() ) {
case "getSchemas":
case "getActualInstance":
case "getActualInstanceRecursively":
case "getSchemaType":
case "isNullable":
return null;
default:
return this;
}
}
if ( member instanceof Method ) {
Method method = (Method) member;
if ( method.getName().endsWith( "_JsonNullable" ) ) {
return null;
}
}
return this;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/*
* SPDX-License-Identifier: Apache-2.0
* Copyright Blazebit
*/
package com.blazebit.query.connector.azure.devops;

import com.blazebit.query.spi.ConfigurationProvider;
import com.blazebit.query.spi.DataFetcher;
import com.blazebit.query.spi.QuerySchemaProvider;

import java.util.Set;

/**
* The schema provider for the Azure DevOps connector.
*
* @author Dimitar Prisadnikov
* @since 1.0.8
*/
public final class DevopsSchemaProvider implements QuerySchemaProvider {
@Override
public Set<? extends DataFetcher<?>> resolveSchemaObjects(ConfigurationProvider configurationProvider) {
return Set.of(
AccountDataFetcher.INSTANCE
);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
com.blazebit.query.connector.azure.devops.DevopsSchemaProvider
Loading
Loading