Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

RSE-979: Fix: Remove dependency from rd-api-client #8852

Merged
merged 5 commits into from
Feb 7, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions core/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ dependencies {
"org.yaml:snakeyaml:${snakeyamlVersion}",
'com.squareup.retrofit2:retrofit:2.9.0',
'com.squareup.retrofit2:converter-jackson:2.9.0',
'com.squareup.retrofit2:converter-jaxb:2.9.0',
'javax.servlet:javax.servlet-api:4.0.1'


Expand Down
38 changes: 38 additions & 0 deletions core/src/main/java/com/dtolabs/rundeck/net/api/RundeckApi.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package com.dtolabs.rundeck.net.api;
import okhttp3.RequestBody;
import retrofit2.Call;
import retrofit2.http.*;
import com.dtolabs.rundeck.net.model.ProjectImportStatus;

import java.util.Map;


/**
* Interface for Rundeck API using retrofit annotations
*/
@SuppressWarnings("JavaDoc")
public interface RundeckApi {

/**
* Import project archive (<=v18)
*
* @param project project
*
* @return archive response
*/
@Headers("Accept: application/json")
@PUT("project/{project}/import")
Call<ProjectImportStatus> importProjectArchive(
@Path("project") String project,
@Query("jobUuidOption") String jobUuidOption,
@Query("importExecutions") Boolean importExecutions,
@Query("importConfig") Boolean importConfig,
@Query("importACL") Boolean importACL,
@Query("importScm") Boolean importScm,
@Query("importWebhooks") Boolean importWebhooks,
@Query("whkRegenAuthTokens") Boolean whkRegenAuthTokens,
@Query("importNodesSources") Boolean importNodesSources,
@QueryMap Map<String,String> params,
@Body RequestBody body
);
}
88 changes: 88 additions & 0 deletions core/src/main/java/com/dtolabs/rundeck/net/api/RundeckClient.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
package com.dtolabs.rundeck.net.api;

import com.dtolabs.rundeck.net.model.ProjectImportStatus;
import okhttp3.MediaType;
import okhttp3.RequestBody;
import retrofit2.Response;
import retrofit2.Retrofit;
import java.io.IOException;
import java.util.Map;
import retrofit2.converter.jackson.JacksonConverterFactory;
import retrofit2.converter.jaxb.JaxbConverterFactory;

import okhttp3.OkHttpClient;


public class RundeckClient {

public static final String APPLICATION_ZIP = "application/zip";
public static final MediaType MEDIA_TYPE_ZIP = MediaType.parse(APPLICATION_ZIP);
private final RundeckApi rundeckApi;
private final Retrofit retrofit;

public RundeckClient(String url, String apiToken) {
OkHttpClient.Builder okhttp = new OkHttpClient.Builder();
okhttp.addInterceptor(chain -> chain.proceed(chain.request().newBuilder().header("X-Rundeck-Auth-Token", apiToken).build()));
final String apiBaseUrl;
apiBaseUrl = buildApiUrlForVersion(url, 39);

retrofit = new Retrofit.Builder()
.baseUrl(apiBaseUrl)
.client(okhttp.build())
.addConverterFactory(JacksonConverterFactory.create())
.addConverterFactory(JaxbConverterFactory.create())
.build();

rundeckApi = retrofit.create(RundeckApi.class);
}

public RundeckClient(RundeckApi rundeckApi, Retrofit retrofit){
this.rundeckApi = rundeckApi;
this.retrofit = retrofit;
}
public Response<ProjectImportStatus> importProjectArchive(
String projectName,
String jobUuidOption,
Boolean importExecutions,
Boolean importConfig,
Boolean importACL,
Boolean importScm,
Boolean importWebhooks,
Boolean whkRegenAuthTokens,
Boolean importNodesSources,
Map<String,String> params,
RequestBody requestBody
) throws IOException {

return rundeckApi.importProjectArchive(
projectName,
jobUuidOption,
importExecutions,
importConfig,
importACL,
importScm,
importWebhooks,
whkRegenAuthTokens,
importNodesSources,
params,
requestBody
).execute();
}

private static String buildApiUrlForVersion(String baseUrl, final int apiVers) {
if (!baseUrl.matches("^.*/api/\\d+/?$")) {
return normalizeUrlPath(baseUrl) + "api/" + (apiVers) + "/";
}
return normalizeUrlPath(baseUrl);
}

private static String normalizeUrlPath(String baseUrl) {
if (!baseUrl.matches(".*/$")) {
return baseUrl + "/";
}
return baseUrl;
}
public Retrofit getRetrofit() {
return retrofit;
}
}
12 changes: 0 additions & 12 deletions rundeckapp/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -80,12 +80,6 @@ configurations {
runtimeClasspath {
extendsFrom developmentOnly
}
pluginLibs

//declare implementation to extend from pluginLibs so it inherits the dependencies
implementation {
extendsFrom pluginLibs
}

implementation.exclude module: "spring-boot-starter-tomcat"
implementation.exclude module: "spring-boot-cli"
Expand All @@ -111,12 +105,6 @@ sourceSets {
dependencies {
//Rundeck plugin dependencies
pluginFiles project.findProperty('bundledPlugins')?:[]
pluginLibs("org.rundeck.api:rd-api-client:2.0.5"){
exclude group: 'javax.xml.bind'
exclude group: 'com.fasterxml.jackson.core'
exclude group: 'com.fasterxml.jackson.dataformat'
exclude group: 'jakarta.xml.bind', module: 'jakarta.xml.bind-api'
}

testImplementation group: 'com.squareup.retrofit2', name: 'retrofit-mock', version: '2.9.0'

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import com.dtolabs.rundeck.core.common.IRundeckProject
import com.dtolabs.rundeck.core.execution.ExecutionReference
import com.dtolabs.rundeck.core.plugins.configuration.Property
import com.dtolabs.rundeck.core.plugins.configuration.Validator
import com.dtolabs.rundeck.net.api.RundeckClient
import com.dtolabs.rundeck.net.model.ErrorDetail
import com.dtolabs.rundeck.net.model.ErrorResponse
import com.dtolabs.rundeck.util.XmlParserUtil
Expand Down Expand Up @@ -65,7 +66,6 @@ import rundeck.data.report.SaveReportRequestImpl
import org.rundeck.app.data.providers.v1.report.ExecReportDataProvider
import org.rundeck.app.services.ExecutionFile
import org.rundeck.app.services.ExecutionFileProducer
import org.rundeck.client.RundeckClient
import org.rundeck.core.auth.AuthConstants
import org.rundeck.util.Toposort
import org.slf4j.Logger
Expand Down Expand Up @@ -98,9 +98,7 @@ import java.util.regex.Pattern
import java.util.stream.Collectors
import java.util.zip.ZipInputStream
import java.util.zip.ZipOutputStream
import org.rundeck.client.util.Client
import org.rundeck.client.api.RundeckApi
import org.rundeck.client.api.model.ProjectImportStatus
import com.dtolabs.rundeck.net.model.ProjectImportStatus
import okhttp3.RequestBody
import retrofit2.Response

Expand Down Expand Up @@ -687,7 +685,7 @@ class ProjectService implements InitializingBean, ExecutionFileProducer, EventPu
) throws ProjectServiceException {
File file = exportProjectToFile(project, framework, listener, archiveParams.toArchiveOptions(), authContext)

ProjectImportStatus ret = importArchiveToInstance(file, archiveParams, RundeckClient.builder().baseUrl(archiveParams.url).tokenAuth(archiveParams.apitoken).apiVersion(39).build())
ProjectImportStatus ret = importArchiveToInstance(file, archiveParams, new RundeckClient(archiveParams.url,archiveParams.apitoken))

ImportResponse response = new ImportResponse(file: file, errors: ret.errors, ok: ret.getResultSuccess(),
executionErrors: ret.executionErrors, aclErrors: ret.aclErrors)
Expand Down Expand Up @@ -716,12 +714,13 @@ class ProjectService implements InitializingBean, ExecutionFileProducer, EventPu
* @param exportArchiveParams metadata of the archive to export from this server
* @return an import status object where the import progress of the destiny server is updated
*/
static ProjectImportStatus importArchiveToInstance(File archiveToExport, ProjectArchiveParams exportArchiveParams, Client<RundeckApi> rundeckClient) throws RuntimeException {
static ProjectImportStatus importArchiveToInstance(File archiveToExport, ProjectArchiveParams exportArchiveParams, RundeckClient rundeckClient) throws RuntimeException {
ProjectImportStatus response = new ProjectImportStatus()
response.successful = true
boolean importWebhookOpt = exportArchiveParams.exportComponents[WebhooksProjectComponent.COMPONENT_NAME]

Response<ProjectImportStatus> status = rundeckClient.getService().importProjectArchive(exportArchiveParams.getTargetproject(),
Response<ProjectImportStatus> status = rundeckClient.importProjectArchive(
exportArchiveParams.getTargetproject(),
exportArchiveParams.preserveuuid?'preserve':'remove',
exportArchiveParams.exportExecutions,
exportArchiveParams.exportConfigs,
Expand All @@ -731,8 +730,8 @@ class ProjectService implements InitializingBean, ExecutionFileProducer, EventPu
importWebhookOpt && !Boolean.getBoolean(exportArchiveParams.exportOpts[WebhooksProjectComponent.COMPONENT_NAME]['inludeAuthTokens']),
exportArchiveParams.exportConfigs,
prependStringToKeysInMap('importComponents', exportArchiveParams.exportComponents),
RequestBody.create(archiveToExport, Client.MEDIA_TYPE_ZIP)
).execute()
RequestBody.create(archiveToExport, RundeckClient.MEDIA_TYPE_ZIP)
)

if(status.isSuccessful()){
if(null != status.body()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,9 @@ import com.dtolabs.rundeck.core.common.Framework
import com.dtolabs.rundeck.core.common.IFramework
import com.dtolabs.rundeck.core.common.IRundeckProject
import com.dtolabs.rundeck.core.common.ProjectManager
import org.rundeck.client.api.model.ProjectImportStatus
import com.dtolabs.rundeck.net.api.RundeckApi
import com.dtolabs.rundeck.net.api.RundeckClient
import com.dtolabs.rundeck.net.model.ProjectImportStatus
import com.dtolabs.rundeck.util.ZipBuilder
import grails.async.Promises
import grails.events.bus.EventBus
Expand All @@ -53,8 +55,6 @@ import org.rundeck.app.components.project.ProjectComponent
import rundeck.data.report.SaveReportRequestImpl
import org.rundeck.app.data.providers.GormExecReportDataProvider
import org.rundeck.app.services.ExecutionFile
import org.rundeck.client.util.Client
import org.rundeck.client.api.RundeckApi
import org.rundeck.core.auth.AuthConstants
import org.slf4j.Logger
import retrofit2.Call
Expand Down Expand Up @@ -1812,6 +1812,7 @@ class ProjectServiceSpec extends Specification implements ServiceUnitTest<Projec
def "should result success and no error msgs when export to another instance is success"() {
given:
ProjectArchiveParams exportArchiveParams = new ProjectArchiveParams([
targetproject:'project-target',
project : 'project-target',
preserveuuid : 'preserve',
exportExecutions : true,
Expand Down Expand Up @@ -1843,6 +1844,7 @@ class ProjectServiceSpec extends Specification implements ServiceUnitTest<Projec

ProjectArchiveParams exportArchiveParams = new ProjectArchiveParams([
project : 'project-target',
targetproject:'project-target',
preserveuuid : 'preserve',
exportExecutions : true,
exportConfigs : true,
Expand Down Expand Up @@ -3276,8 +3278,8 @@ abstract class MockRundeckApi implements RundeckApi{
}


Client<RundeckApi> getRundeckClient(){
return new Client<>(this, retrofit,null, null, 0, false, null)
RundeckClient getRundeckClient(){
return new RundeckClient(this, retrofit)
}

private void setupRetrofit(){
Expand Down