Skip to content

Commit

Permalink
Introduce cluster profile related plugin API calls into EA extension …
Browse files Browse the repository at this point in the history
…v5 (gocd#5937)

* Introduce following new extension API calls:
	- get-cluster-profile-metadata
	- get-cluster-profile-view
	- validate-cluster-profile

* Modify Cluster Profile API to validate cluster profiles upon creation and
  update.
  • Loading branch information
GaneshSPatil committed Mar 11, 2019
1 parent b3bdfbc commit e1e8a7f
Show file tree
Hide file tree
Showing 18 changed files with 268 additions and 36 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,18 @@ public ValidationResult validate(final String pluginId, final Map<String, String
return getVersionedElasticAgentExtension(pluginId).validateElasticProfile(pluginId, configuration);
}

List<PluginConfiguration> getClusterProfileMetadata(String pluginId) {
return getVersionedElasticAgentExtension(pluginId).getClusterProfileMetadata(pluginId);
}

String getClusterProfileView(String pluginId) {
return getVersionedElasticAgentExtension(pluginId).getClusterProfileView(pluginId);
}

public ValidationResult validateClusterProfile(final String pluginId, final Map<String, String> configuration) {
return getVersionedElasticAgentExtension(pluginId).validateClusterProfile(pluginId, configuration);
}

com.thoughtworks.go.plugin.domain.common.Image getIcon(String pluginId) {
return getVersionedElasticAgentExtension(pluginId).getIcon(pluginId);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@

import com.thoughtworks.go.domain.JobIdentifier;
import com.thoughtworks.go.plugin.access.elastic.models.AgentMetadata;
import com.thoughtworks.go.plugin.access.elastic.v3.ElasticAgentExtensionV3;
import com.thoughtworks.go.plugin.api.response.validation.ValidationResult;
import com.thoughtworks.go.plugin.domain.common.PluginConfiguration;
import com.thoughtworks.go.plugin.domain.elastic.Capabilities;
Expand All @@ -37,6 +36,12 @@ public interface VersionedElasticAgentExtension {

ValidationResult validateElasticProfile(String pluginId, Map<String, String> configuration);

List<PluginConfiguration> getClusterProfileMetadata(String pluginId);

String getClusterProfileView(String pluginId);

ValidationResult validateClusterProfile(String pluginId, Map<String, String> configuration);

void createAgent(String pluginId, String autoRegisterKey, String environment, Map<String, String> configuration, JobIdentifier jobIdentifier);

void serverPing(String pluginId);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -158,4 +158,19 @@ public String onSuccess(String responseBody, Map<String, String> responseHeaders
public void jobCompletion(String pluginId, String elasticAgentId, JobIdentifier jobIdentifier) {
LOG.debug("Plugin: '{}' uses elastic agent extension v3 and job completion is not supported by elastic agent V3", pluginId);
}

@Override
public List<PluginConfiguration> getClusterProfileMetadata(String pluginId) {
throw new UnsupportedOperationException(String.format("Plugin: '%s' uses elastic agent extension v3 and cluster profile extension calls are not supported by elastic agent V3", pluginId));
}

@Override
public String getClusterProfileView(String pluginId) {
throw new UnsupportedOperationException(String.format("Plugin: '%s' uses elastic agent extension v3 and cluster profile extension calls are not supported by elastic agent V3", pluginId));
}

@Override
public ValidationResult validateClusterProfile(String pluginId, Map<String, String> configuration) {
throw new UnsupportedOperationException(String.format("Plugin: '%s' uses elastic agent extension v3 and cluster profile extension calls are not supported by elastic agent V3", pluginId));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,16 @@
import com.thoughtworks.go.plugin.api.response.validation.ValidationResult;
import com.thoughtworks.go.plugin.domain.common.PluginConfiguration;
import com.thoughtworks.go.plugin.domain.elastic.Capabilities;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.List;
import java.util.Map;

import static com.thoughtworks.go.plugin.access.elastic.v4.ElasticAgentPluginConstantsV4.*;

public class ElasticAgentExtensionV4 implements VersionedElasticAgentExtension {
private static final Logger LOG = LoggerFactory.getLogger(ElasticAgentExtensionV4.class);
public static final String VERSION = "4.0";
private final PluginRequestHelper pluginRequestHelper;
private final ElasticAgentExtensionConverterV4 elasticAgentExtensionConverterV4;
Expand Down Expand Up @@ -95,6 +98,20 @@ public ValidationResult onSuccess(String responseBody, Map<String, String> respo
});
}

@Override
public List<PluginConfiguration> getClusterProfileMetadata(String pluginId) {
throw new UnsupportedOperationException(String.format("Plugin: '%s' uses elastic agent extension v4 and cluster profile extension calls are not supported by elastic agent V4", pluginId));
}

@Override
public String getClusterProfileView(String pluginId) {
throw new UnsupportedOperationException(String.format("Plugin: '%s' uses elastic agent extension v4 and cluster profile extension calls are not supported by elastic agent V4", pluginId));
}

@Override
public ValidationResult validateClusterProfile(String pluginId, Map<String, String> configuration) {
throw new UnsupportedOperationException(String.format("Plugin: '%s' uses elastic agent extension v4 and cluster profile extension calls are not supported by elastic agent V4", pluginId));
}

@Override
public void createAgent(String pluginId, final String autoRegisterKey, final String environment, final Map<String, String> configuration, JobIdentifier jobIdentifier) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,40 @@ public ValidationResult onSuccess(String responseBody, Map<String, String> respo
});
}

@Override
public List<PluginConfiguration> getClusterProfileMetadata(String pluginId) {
return pluginRequestHelper.submitRequest(pluginId, REQUEST_GET_CLUSTER_PROFILE_METADATA, new DefaultPluginInteractionCallback<List<PluginConfiguration>>() {
@Override
public List<PluginConfiguration> onSuccess(String responseBody, Map<String, String> responseHeaders, String resolvedExtensionVersion) {
return elasticAgentExtensionConverterV5.getElasticProfileMetadataResponseFromBody(responseBody);
}
});
}

@Override
public String getClusterProfileView(String pluginId) {
return pluginRequestHelper.submitRequest(pluginId, REQUEST_GET_CLUSTER_PROFILE_VIEW, new DefaultPluginInteractionCallback<String>() {
@Override
public String onSuccess(String responseBody, Map<String, String> responseHeaders, String resolvedExtensionVersion) {
return elasticAgentExtensionConverterV5.getProfileViewResponseFromBody(responseBody);
}
});
}

@Override
public ValidationResult validateClusterProfile(String pluginId, Map<String, String> configuration) {
return pluginRequestHelper.submitRequest(pluginId, REQUEST_VALIDATE_CLUSTER_PROFILE, new DefaultPluginInteractionCallback<ValidationResult>() {
@Override
public String requestBody(String resolvedExtensionVersion) {
return elasticAgentExtensionConverterV5.validateElasticProfileRequestBody(configuration);
}

@Override
public ValidationResult onSuccess(String responseBody, Map<String, String> responseHeaders, String resolvedExtensionVersion) {
return elasticAgentExtensionConverterV5.getElasticProfileValidationResultResponseFromBody(responseBody);
}
});
}

@Override
public void createAgent(String pluginId, final String autoRegisterKey, final String environment, final Map<String, String> configuration, JobIdentifier jobIdentifier) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,10 @@ public interface ElasticAgentPluginConstantsV5 {
String REQUEST_VALIDATE_PROFILE = REQUEST_PREFIX + ".validate-profile";
String REQUEST_GET_PLUGIN_SETTINGS_ICON = REQUEST_PREFIX + ".get-icon";

String REQUEST_GET_CLUSTER_PROFILE_METADATA = REQUEST_PREFIX + ".get-cluster-profile-metadata";
String REQUEST_GET_CLUSTER_PROFILE_VIEW = REQUEST_PREFIX + ".get-cluster-profile-view";
String REQUEST_VALIDATE_CLUSTER_PROFILE = REQUEST_PREFIX + ".validate-cluster-profile";

String REQUEST_STATUS_REPORT = REQUEST_PREFIX + ".status-report";
String REQUEST_AGENT_STATUS_REPORT = REQUEST_PREFIX + ".agent-status-report";
String REQUEST_CAPABILITIES = REQUEST_PREFIX + ".get-capabilities";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,18 +40,13 @@
import org.mockito.ArgumentCaptor;
import org.mockito.Mock;

import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.*;

import static com.thoughtworks.go.plugin.access.elastic.v3.ElasticAgentPluginConstantsV3.*;
import static com.thoughtworks.go.plugin.domain.common.PluginConstants.ELASTIC_AGENT_EXTENSION;
import static net.javacrumbs.jsonunit.fluent.JsonFluentAssert.assertThatJson;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.*;
import static org.junit.Assert.assertThat;
import static org.hamcrest.Matchers.containsInAnyOrder;
import static org.hamcrest.Matchers.hasSize;
import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.verifyZeroInteractions;
Expand Down Expand Up @@ -250,6 +245,30 @@ public void shouldGetAgentStatusReport() {
assertExtensionRequest("3.0", REQUEST_AGENT_STATUS_REPORT, requestBody);
}

@Test
public void shouldNotSupportGetClusterProfileConfigurationCall() {
thrown.expect(UnsupportedOperationException.class);
thrown.expectMessage(String.format("Plugin: '%s' uses elastic agent extension v3 and cluster profile extension calls are not supported by elastic agent V3", PLUGIN_ID));

extensionV3.getClusterProfileMetadata(PLUGIN_ID);
}

@Test
public void shouldNotSupportGetClusterProfileViewCall() {
thrown.expect(UnsupportedOperationException.class);
thrown.expectMessage(String.format("Plugin: '%s' uses elastic agent extension v3 and cluster profile extension calls are not supported by elastic agent V3", PLUGIN_ID));

extensionV3.getClusterProfileView(PLUGIN_ID);
}

@Test
public void shouldNotSupportValidateClusterProfileCall() {
thrown.expect(UnsupportedOperationException.class);
thrown.expectMessage(String.format("Plugin: '%s' uses elastic agent extension v3 and cluster profile extension calls are not supported by elastic agent V3", PLUGIN_ID));

extensionV3.validateClusterProfile(PLUGIN_ID, new HashMap<>());
}

@Test
public void shouldDoNothingWhenPluginDoesNotJobCompletionRequest() {
String elasticAgentId = "agent1";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,18 +40,13 @@
import org.mockito.ArgumentCaptor;
import org.mockito.Mock;

import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.*;

import static com.thoughtworks.go.plugin.access.elastic.v4.ElasticAgentPluginConstantsV4.*;
import static com.thoughtworks.go.plugin.domain.common.PluginConstants.ELASTIC_AGENT_EXTENSION;
import static net.javacrumbs.jsonunit.fluent.JsonFluentAssert.assertThatJson;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.*;
import static org.junit.Assert.assertThat;
import static org.hamcrest.Matchers.containsInAnyOrder;
import static org.hamcrest.Matchers.hasSize;
import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.when;
Expand Down Expand Up @@ -273,6 +268,31 @@ public void shouldGetAgentStatusReport() {
assertExtensionRequest("4.0", REQUEST_AGENT_STATUS_REPORT, requestBody);
}


@Test
public void shouldNotSupportGetClusterProfileConfigurationCall() {
thrown.expect(UnsupportedOperationException.class);
thrown.expectMessage(String.format("Plugin: '%s' uses elastic agent extension v4 and cluster profile extension calls are not supported by elastic agent V4", PLUGIN_ID));

extensionV4.getClusterProfileMetadata(PLUGIN_ID);
}

@Test
public void shouldNotSupportGetClusterProfileViewCall() {
thrown.expect(UnsupportedOperationException.class);
thrown.expectMessage(String.format("Plugin: '%s' uses elastic agent extension v4 and cluster profile extension calls are not supported by elastic agent V4", PLUGIN_ID));

extensionV4.getClusterProfileView(PLUGIN_ID);
}

@Test
public void shouldNotSupportValidateClusterProfileCall() {
thrown.expect(UnsupportedOperationException.class);
thrown.expectMessage(String.format("Plugin: '%s' uses elastic agent extension v4 and cluster profile extension calls are not supported by elastic agent V4", PLUGIN_ID));

extensionV4.validateClusterProfile(PLUGIN_ID, new HashMap<>());
}

@Test
public void allRequestMustHaveRequestPrefix() {
assertThat(REQUEST_PREFIX, is("cd.go.elastic-agent"));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@
import java.util.List;
import java.util.Map;

import static com.thoughtworks.go.plugin.access.elastic.v4.ElasticAgentPluginConstantsV4.*;
import static com.thoughtworks.go.plugin.access.elastic.v5.ElasticAgentPluginConstantsV5.*;
import static com.thoughtworks.go.plugin.domain.common.PluginConstants.ELASTIC_AGENT_EXTENSION;
import static net.javacrumbs.jsonunit.fluent.JsonFluentAssert.assertThatJson;
import static org.hamcrest.Matchers.*;
Expand Down Expand Up @@ -148,6 +148,51 @@ public void shouldValidateProfile() {
assertExtensionRequest("5.0", REQUEST_VALIDATE_PROFILE, "{}");
}


@Test
public void shouldGetClusterProfileMetadata() {
String responseBody = "[{\"key\":\"Username\",\"metadata\":{\"required\":true,\"secure\":false}},{\"key\":\"Password\",\"metadata\":{\"required\":true,\"secure\":true}}]";
when(pluginManager.submitTo(eq(PLUGIN_ID), eq(ELASTIC_AGENT_EXTENSION), requestArgumentCaptor.capture())).thenReturn(DefaultGoPluginApiResponse.success(responseBody));

final List<PluginConfiguration> metadata = extensionV5.getClusterProfileMetadata(PLUGIN_ID);

assertThat(metadata, hasSize(2));
assertThat(metadata, containsInAnyOrder(
new PluginConfiguration("Username", new Metadata(true, false)),
new PluginConfiguration("Password", new Metadata(true, true))
));

assertExtensionRequest("5.0", REQUEST_GET_CLUSTER_PROFILE_METADATA, null);
}

@Test
public void shouldGetClusterProfileView() {
String responseBody = "{ \"template\": \"<div>This is profile view snippet</div>\" }";
when(pluginManager.submitTo(eq(PLUGIN_ID), eq(ELASTIC_AGENT_EXTENSION), requestArgumentCaptor.capture())).thenReturn(DefaultGoPluginApiResponse.success(responseBody));

final String view = extensionV5.getClusterProfileView(PLUGIN_ID);

assertThat(view, is("<div>This is profile view snippet</div>"));

assertExtensionRequest("5.0", REQUEST_GET_CLUSTER_PROFILE_VIEW, null);
}

@Test
public void shouldValidateClusterProfile() {
String responseBody = "[{\"message\":\"Url must not be blank.\",\"key\":\"Url\"},{\"message\":\"SearchBase must not be blank.\",\"key\":\"SearchBase\"}]";
when(pluginManager.submitTo(eq(PLUGIN_ID), eq(ELASTIC_AGENT_EXTENSION), requestArgumentCaptor.capture())).thenReturn(DefaultGoPluginApiResponse.success(responseBody));

final ValidationResult result = extensionV5.validateClusterProfile(PLUGIN_ID, Collections.emptyMap());

assertThat(result.isSuccessful(), is(false));
assertThat(result.getErrors(), containsInAnyOrder(
new ValidationError("Url", "Url must not be blank."),
new ValidationError("SearchBase", "SearchBase must not be blank.")
));

assertExtensionRequest("5.0", REQUEST_VALIDATE_CLUSTER_PROFILE, "{}");
}

@Test
public void shouldMakeCreateAgentCall() {
final Map<String, String> profile = Collections.singletonMap("ServerURL", "https://example.com/go");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,14 @@
import com.thoughtworks.go.config.CruiseConfig;
import com.thoughtworks.go.config.elastic.ClusterProfile;
import com.thoughtworks.go.config.elastic.ClusterProfiles;
import com.thoughtworks.go.plugin.access.elastic.ElasticAgentExtension;
import com.thoughtworks.go.server.domain.Username;
import com.thoughtworks.go.server.service.GoConfigService;
import com.thoughtworks.go.server.service.result.HttpLocalizedOperationResult;

public class AddClusterProfileCommand extends ClusterProfileCommand {
public AddClusterProfileCommand(GoConfigService goConfigService, ClusterProfile clusterProfile, Username username, HttpLocalizedOperationResult result) {
super(goConfigService, clusterProfile, username, result);
public AddClusterProfileCommand(ElasticAgentExtension extension, GoConfigService goConfigService, ClusterProfile clusterProfile, Username username, HttpLocalizedOperationResult result) {
super(extension, goConfigService, clusterProfile, username, result);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import com.thoughtworks.go.config.elastic.ClusterProfile;
import com.thoughtworks.go.config.elastic.ClusterProfiles;
import com.thoughtworks.go.i18n.LocalizedMessage;
import com.thoughtworks.go.plugin.access.elastic.ElasticAgentExtension;
import com.thoughtworks.go.plugin.api.response.validation.ValidationResult;
import com.thoughtworks.go.server.domain.Username;
import com.thoughtworks.go.server.service.GoConfigService;
Expand All @@ -29,8 +30,11 @@
import java.util.Map;

public abstract class ClusterProfileCommand extends PluginProfileCommand<ClusterProfile, ClusterProfiles> {
public ClusterProfileCommand(GoConfigService goConfigService, ClusterProfile clusterProfile, Username username, HttpLocalizedOperationResult result) {
private final ElasticAgentExtension extension;

public ClusterProfileCommand(ElasticAgentExtension extension, GoConfigService goConfigService, ClusterProfile clusterProfile, Username username, HttpLocalizedOperationResult result) {
super(goConfigService, clusterProfile, username, result);
this.extension = extension;
}

@Override
Expand All @@ -40,8 +44,7 @@ protected ClusterProfiles getPluginProfiles(CruiseConfig preprocessedConfig) {

@Override
public ValidationResult validateUsingExtension(String pluginId, Map<String, String> configuration) {
//todo: @Vrushali and @Ganesh did this. change this to talk to real extension.
return new ValidationResult();
return extension.validateClusterProfile(pluginId, configuration);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,14 @@
import com.thoughtworks.go.config.elastic.ClusterProfile;
import com.thoughtworks.go.config.elastic.ClusterProfiles;
import com.thoughtworks.go.i18n.LocalizedMessage;
import com.thoughtworks.go.plugin.access.elastic.ElasticAgentExtension;
import com.thoughtworks.go.server.domain.Username;
import com.thoughtworks.go.server.service.GoConfigService;
import com.thoughtworks.go.server.service.result.HttpLocalizedOperationResult;

public class DeleteClusterProfileCommand extends ClusterProfileCommand {
public DeleteClusterProfileCommand(GoConfigService goConfigService, ClusterProfile clusterProfile, Username currentUser, HttpLocalizedOperationResult result) {
super(goConfigService, clusterProfile, currentUser, result);
public DeleteClusterProfileCommand(ElasticAgentExtension extension, GoConfigService goConfigService, ClusterProfile clusterProfile, Username currentUser, HttpLocalizedOperationResult result) {
super(extension, goConfigService, clusterProfile, currentUser, result);
}

@Override
Expand Down
Loading

0 comments on commit e1e8a7f

Please sign in to comment.