diff --git a/src/main/java/edu/ohio/ais/rundeck/HttpBuilder.java b/src/main/java/edu/ohio/ais/rundeck/HttpBuilder.java index 9da715e..ec3d7f4 100644 --- a/src/main/java/edu/ohio/ais/rundeck/HttpBuilder.java +++ b/src/main/java/edu/ohio/ais/rundeck/HttpBuilder.java @@ -4,6 +4,7 @@ import com.dtolabs.rundeck.core.execution.workflow.steps.StepException; import com.dtolabs.rundeck.core.execution.workflow.steps.StepFailureReason; import com.dtolabs.rundeck.core.storage.ResourceMeta; +import com.dtolabs.rundeck.core.utils.IPropertyLookup; import com.dtolabs.rundeck.plugins.PluginLogger; import com.dtolabs.rundeck.plugins.step.PluginStepContext; import com.google.gson.Gson; @@ -88,13 +89,14 @@ public enum Reason implements FailureReason { } - public CloseableHttpClient getHttpClient(Map options) throws GeneralSecurityException { + public CloseableHttpClient getHttpClient(Map options) throws GeneralSecurityException, StepException { HttpClientBuilder httpClientBuilder = HttpClientBuilder.create(); httpClientBuilder.disableAuthCaching(); httpClientBuilder.disableAutomaticRetries(); - if(options.containsKey("sslVerify") && !Boolean.parseBoolean(options.get("sslVerify").toString())) { + + if(!getBooleanOption(options, "sslVerify", true)) { log.log(5,"Disabling all SSL certificate verification."); SSLContextBuilder sslContextBuilder = new SSLContextBuilder(); sslContextBuilder.loadTrustMaterial(null, new TrustStrategy() { @@ -107,8 +109,27 @@ public boolean isTrusted(X509Certificate[] x509Certificates, String s) throws Ce httpClientBuilder.setSSLHostnameVerifier(new NoopHostnameVerifier()); httpClientBuilder.setSSLContext(sslContextBuilder.build()); } - if(options.containsKey("proxySettings") && Boolean.parseBoolean(options.get("proxySettings").toString())){ - HttpHost proxy = new HttpHost(options.get("proxyIP").toString(), Integer.valueOf((String)options.get("proxyPort")), "http"); + if(getBooleanOption(options, "useSystemProxySettings", false) && !getBooleanOption(options, "proxySettings", false)) { + log.log(5, "Using proxy settings set on system"); + String proxyHost = System.getProperty("http.proxyHost"); + String proxyPort = System.getProperty("http.proxyPort"); + if (proxyPort.isEmpty() || proxyHost.isEmpty()) { + throw new StepException("proxyHost and proxyPort are required to use System Proxy Settings", StepFailureReason.ConfigurationFailure); + } + HttpHost proxy = new HttpHost(proxyHost, Integer.parseInt(proxyPort), "http"); + httpClientBuilder.setProxy(proxy); + } + if (getBooleanOption(options, "proxySettings", false)) { + String proxyIP = getStringOption(options, "proxyIP", ""); + String proxyPort = getStringOption(options, "proxyPort", ""); + + if (proxyIP.isEmpty() || proxyPort.isEmpty()) { + throw new StepException("Proxy IP and Proxy Port are required to use Proxy Settings.", StepFailureReason.ConfigurationFailure); + } + + log.log(5, "proxy IP set in job: " + proxyIP); + log.log(5, "proxy Port set in job: " + proxyPort); + HttpHost proxy = new HttpHost(proxyIP, Integer.parseInt(proxyPort), "http"); httpClientBuilder.setProxy(proxy); } @@ -132,19 +153,19 @@ public void doRequest(Map options, HttpUriRequest request, Integ try { response = this.getHttpClient(options).execute(request); - if(options.containsKey("printResponseCode") && Boolean.parseBoolean(options.get("printResponseCode").toString())) { + if(getBooleanOption(options,"printResponseCode",false)) { String responseCode = response.getStatusLine().toString(); log.log(2, "Response Code: " + responseCode); } //print the response content - if(options.containsKey("printResponse") && Boolean.parseBoolean(options.get("printResponse").toString())) { + if(getBooleanOption(options,"printResponse",false)) { output = getOutputForResponse(this.prettyPrint(response)); //print response log.log(2, output); } - if(options.containsKey("printResponseToFile") && Boolean.parseBoolean(options.get("printResponseToFile").toString())){ + if(getBooleanOption(options,"printResponseToFile",false)){ File file = new File(options.get("file").toString()); BufferedWriter writer = new BufferedWriter(new FileWriter(file)); if( output.isEmpty() ){ @@ -158,7 +179,7 @@ public void doRequest(Map options, HttpUriRequest request, Integ } //check response status - if(options.containsKey("checkResponseCode") && Boolean.parseBoolean(options.get("checkResponseCode").toString())) { + if(getBooleanOption(options,"checkResponseCode",false)) { if(options.containsKey("responseCode")){ int responseCode = Integer.valueOf( (String) options.get("responseCode")); @@ -335,14 +356,14 @@ public String prettyPrint(HttpResponse response){ String getAuthHeader(PluginStepContext pluginStepContext, Map options) throws StepException { - String authentication = options.containsKey("authentication") ? options.get("authentication").toString() : AUTH_NONE; + String authentication = getStringOption(options, "authentication",AUTH_NONE); //moving the password to the key storage String password=null; String authHeader = null; if(options.containsKey("password") ){ - String passwordRaw = options.containsKey("password") ? options.get("password").toString() : null; + String passwordRaw = getStringOption(options, "password"); //to avid the test error add a try-catch //if it didn't find the key path, it will use the password directly byte[] content = SecretBundleUtil.getStoragePassword(pluginStepContext.getExecutionContext(),passwordRaw ); @@ -356,7 +377,7 @@ String getAuthHeader(PluginStepContext pluginStepContext, Map o if(authentication.equals(AUTH_BASIC)) { // Setup the authentication header for BASIC - String username = options.containsKey("username") ? options.get("username").toString() : null; + String username = getStringOption(options, "username"); if(username == null || password == null) { throw new StepException("Username and password not provided for BASIC Authentication", @@ -369,9 +390,12 @@ String getAuthHeader(PluginStepContext pluginStepContext, Map o authHeader = "Basic " + com.dtolabs.rundeck.core.utils.Base64.encode(authHeader); } else if (authentication.equals(AUTH_OAUTH2)) { // Get an OAuth token and setup the auth header for OAuth - String tokenEndpoint = options.containsKey("oauthTokenEndpoint") ? options.get("oauthTokenEndpoint").toString() : null; - String validateEndpoint = options.containsKey("oauthValidateEndpoint") ? options.get("oauthValidateEndpoint").toString() : null; - String clientId = options.containsKey("username") ? options.get("username").toString() : null; + String tokenEndpoint = getStringOption(options, "oauthTokenEndpoint"); + String validateEndpoint = getStringOption(options, "oauthValidateEndpoint"); + String clientId = getStringOption(options, "username"); + + + String clientSecret = password; @@ -460,5 +484,76 @@ public void setHeaders(String headers, RequestBuilder request){ } } + static void propertyResolver(String pluginType, String property, Map Configuration, PluginStepContext context, String SERVICE_PROVIDER_NAME) { + + String projectPrefix = "project.plugin." + pluginType + "." + SERVICE_PROVIDER_NAME + "."; + String frameworkPrefix = "framework.plugin." + pluginType + "." + SERVICE_PROVIDER_NAME + "."; + + Map projectProperties = context.getFramework().getFrameworkProjectMgr().getFrameworkProject(context.getFrameworkProject()).getProperties(); + IPropertyLookup frameworkProperties = context.getFramework().getPropertyLookup(); + + if(!Configuration.containsKey(property) && projectProperties.containsKey(projectPrefix + property)) { + + Configuration.put(property, projectProperties.get(projectPrefix + property)); + + } else if (!Configuration.containsKey(property) && frameworkProperties.hasProperty(frameworkPrefix + property)) { + + Configuration.put(property, frameworkProperties.getProperty(frameworkPrefix + property)); + + } + } + + /** + * Retrieves a string value from the options map. + * If the key does not exist or the value is null, it returns null. + * + * @param options the map containing option keys and values + * @param key the key whose associated value is to be returned + * @return the string value associated with the specified key, or null if the key does not exist or the value is null + */ + static String getStringOption(Map options, String key) { + return getStringOption(options, key, null); + } + + /** + * Retrieves a string value from the options map. + * If the key does not exist or the value is null, it returns the specified default value. + * + * @param options the map containing option keys and values + * @param key the key whose associated value is to be returned + * @param defValue the default value to return if the key does not exist or the value is null + * @return the string value associated with the specified key, or the default value if the key does not exist or the value is null + */ + static String getStringOption(Map options, String key, String defValue) { + return options.containsKey(key) && options.get(key) != null ? options.get(key).toString() : defValue; + } + + /** + * Retrieves an integer value from the options map. + * If the key does not exist or the value is null, it returns the specified default value. + * + * @param options the map containing option keys and values + * @param key the key whose associated value is to be returned + * @param defValue the default value to return if the key does not exist or the value is null + * @return the integer value associated with the specified key, or the default value if the key does not exist or the value is null + * @throws NumberFormatException if the value cannot be parsed as an integer + */ + public static Integer getIntOption(Map options, String key, Integer defValue) { + return options.containsKey(key) && options.get(key) != null ? Integer.parseInt(options.get(key).toString()) : defValue; + } + + /** + * Retrieves a boolean value from the options map. + * If the key does not exist or the value is null, it returns the specified default value. + * + * @param options the map containing option keys and values + * @param key the key whose associated value is to be returned + * @param defValue the default value to return if the key does not exist or the value is null + * @return the boolean value associated with the specified key, or the default value if the key does not exist or the value is null + */ + public static Boolean getBooleanOption(Map options, String key, Boolean defValue) { + return options.containsKey(key) && options.get(key) != null ? Boolean.parseBoolean(options.get(key).toString()) : defValue; + } + } diff --git a/src/main/java/edu/ohio/ais/rundeck/HttpDescription.java b/src/main/java/edu/ohio/ais/rundeck/HttpDescription.java index db1034f..de7ac43 100644 --- a/src/main/java/edu/ohio/ais/rundeck/HttpDescription.java +++ b/src/main/java/edu/ohio/ais/rundeck/HttpDescription.java @@ -2,6 +2,7 @@ import com.dtolabs.rundeck.core.plugins.configuration.Describable; import com.dtolabs.rundeck.core.plugins.configuration.Description; +import com.dtolabs.rundeck.core.plugins.configuration.PropertyScope; import com.dtolabs.rundeck.core.plugins.configuration.StringRenderingConstants; import com.dtolabs.rundeck.plugins.util.DescriptionBuilder; import com.dtolabs.rundeck.plugins.util.PropertyBuilder; @@ -165,6 +166,13 @@ public Description getDescription() { .defaultValue("false") .renderingOption(StringRenderingConstants.GROUP_NAME,"Print") .build()) + .property(PropertyBuilder.builder() + .title("System Proxy Settings") + .booleanType("useSystemProxySettings") + .description("Choose whether to use proxy settings set on the JVM.") + .defaultValue("false") + .scope(PropertyScope.Project) + .build()) .build(); } } diff --git a/src/main/java/edu/ohio/ais/rundeck/HttpWorkflowNodeStepPlugin.java b/src/main/java/edu/ohio/ais/rundeck/HttpWorkflowNodeStepPlugin.java index ff4cd30..d11ab1b 100644 --- a/src/main/java/edu/ohio/ais/rundeck/HttpWorkflowNodeStepPlugin.java +++ b/src/main/java/edu/ohio/ais/rundeck/HttpWorkflowNodeStepPlugin.java @@ -5,16 +5,20 @@ import com.dtolabs.rundeck.core.execution.ExecutionContext; import com.dtolabs.rundeck.core.execution.proxy.ProxySecretBundleCreator; import com.dtolabs.rundeck.core.execution.proxy.SecretBundle; +import com.dtolabs.rundeck.core.execution.utils.ResolverUtil; import com.dtolabs.rundeck.core.execution.workflow.steps.StepException; import com.dtolabs.rundeck.core.execution.workflow.steps.StepFailureReason; import com.dtolabs.rundeck.core.execution.workflow.steps.node.NodeStepException; import com.dtolabs.rundeck.core.plugins.Plugin; import com.dtolabs.rundeck.core.plugins.configuration.Describable; import com.dtolabs.rundeck.core.plugins.configuration.Description; +import com.dtolabs.rundeck.core.utils.IPropertyLookup; import com.dtolabs.rundeck.plugins.PluginLogger; import com.dtolabs.rundeck.plugins.ServiceNameConstants; +import com.dtolabs.rundeck.plugins.descriptions.PluginProperty; import com.dtolabs.rundeck.plugins.step.NodeStepPlugin; import com.dtolabs.rundeck.plugins.step.PluginStepContext; +import com.dtolabs.rundeck.plugins.util.DescriptionBuilder; import edu.ohio.ais.rundeck.util.OAuthClient; import edu.ohio.ais.rundeck.util.SecretBundleUtil; import org.apache.http.HttpEntity; @@ -25,6 +29,10 @@ import java.io.UnsupportedEncodingException; import java.util.*; +import static edu.ohio.ais.rundeck.HttpBuilder.propertyResolver; +import static edu.ohio.ais.rundeck.HttpBuilder.getIntOption; +import static edu.ohio.ais.rundeck.HttpBuilder.getStringOption; + @Plugin(name = HttpWorkflowNodeStepPlugin.SERVICE_PROVIDER_NAME, service = ServiceNameConstants.WorkflowNodeStep) public class HttpWorkflowNodeStepPlugin implements NodeStepPlugin, Describable, ProxySecretBundleCreator { public static final String SERVICE_PROVIDER_NAME = "edu.ohio.ais.rundeck.HttpWorkflowNodeStepPlugin"; @@ -40,7 +48,6 @@ public class HttpWorkflowNodeStepPlugin implements NodeStepPlugin, Describable, */ public static final Integer DEFAULT_TIMEOUT = 30*1000; - /** * Synchronized map of all existing OAuth clients. This is indexed by * the Client ID and the token URL so that we can store and re-use access tokens. @@ -58,13 +65,17 @@ public Description getDescription() { public void executeNodeStep(PluginStepContext context, Map configuration, INodeEntry entry) throws NodeStepException { PluginLogger log = context.getLogger(); - // Parse out the options - String remoteUrl = configuration.containsKey("remoteUrl") ? configuration.get("remoteUrl").toString() : null; - String method = configuration.containsKey("method") ? configuration.get("method").toString() : null; + Description description = new HttpDescription(SERVICE_PROVIDER_NAME, "HTTP Request Node Step", "Performs an HTTP request with or without authentication (per node)").getDescription(); + description.getProperties().forEach(prop-> + propertyResolver("WorkflowNodeStep", prop.getName(), configuration, context, SERVICE_PROVIDER_NAME) + ); - Integer timeout = configuration.containsKey("timeout") ? Integer.parseInt(configuration.get("timeout").toString()) : DEFAULT_TIMEOUT; - String headers = configuration.containsKey("headers") ? configuration.get("headers").toString() : null; - String body = configuration.containsKey("body") ? configuration.get("body").toString() : null; + // Parse out the options + String remoteUrl = getStringOption(configuration, "remoteUrl"); + String method = getStringOption(configuration, "method"); + Integer timeout =getIntOption(configuration,"timeout", DEFAULT_TIMEOUT); + String headers = getStringOption(configuration, "headers"); + String body = getStringOption(configuration, "body"); log.log(5, "remoteUrl: " + remoteUrl); log.log(5, "method: " + method); @@ -146,4 +157,5 @@ public SecretBundle prepareSecretBundleWorkflowNodeStep(ExecutionContext context public List listSecretsPathWorkflowNodeStep(ExecutionContext context, INodeEntry node, Map configuration) { return SecretBundleUtil.getListSecrets(configuration); } + } diff --git a/src/main/java/edu/ohio/ais/rundeck/HttpWorkflowStepPlugin.java b/src/main/java/edu/ohio/ais/rundeck/HttpWorkflowStepPlugin.java index fbe4dbb..88fec4f 100644 --- a/src/main/java/edu/ohio/ais/rundeck/HttpWorkflowStepPlugin.java +++ b/src/main/java/edu/ohio/ais/rundeck/HttpWorkflowStepPlugin.java @@ -23,6 +23,10 @@ import java.io.*; import java.util.*; +import static edu.ohio.ais.rundeck.HttpBuilder.propertyResolver; +import static edu.ohio.ais.rundeck.HttpBuilder.getIntOption; +import static edu.ohio.ais.rundeck.HttpBuilder.getStringOption; + /** * Main implementation of the plugin. This will handle fetching @@ -69,12 +73,17 @@ public Description getDescription() { public void executeStep(PluginStepContext pluginStepContext, Map options) throws StepException { PluginLogger log = pluginStepContext.getLogger(); + Description description = new HttpDescription(SERVICE_PROVIDER_NAME, "HTTP Request Node Step", "Performs an HTTP request with or without authentication (per node)").getDescription(); + description.getProperties().forEach(prop-> + propertyResolver("WorkflowStep",prop.getName(), options, pluginStepContext, SERVICE_PROVIDER_NAME) + ); + // Parse out the options - String remoteUrl = options.containsKey("remoteUrl") ? options.get("remoteUrl").toString() : null; - String method = options.containsKey("method") ? options.get("method").toString() : null; - Integer timeout = options.containsKey("timeout") ? Integer.parseInt(options.get("timeout").toString()) : DEFAULT_TIMEOUT; - String headers = options.containsKey("headers") ? options.get("headers").toString() : null; - String body = options.containsKey("body") ? options.get("body").toString() : null; + String remoteUrl = getStringOption(options, "remoteUrl"); + String method = getStringOption(options, "method"); + Integer timeout =getIntOption(options,"timeout", DEFAULT_TIMEOUT); + String headers = getStringOption(options, "headers"); + String body = getStringOption(options, "body"); if(remoteUrl == null || method == null) { throw new StepException("Remote URL and Method are required.", StepFailureReason.ConfigurationFailure); diff --git a/src/test/java/edu/ohio/ais/rundeck/HttpBuilderTest.java b/src/test/java/edu/ohio/ais/rundeck/HttpBuilderTest.java new file mode 100644 index 0000000..91189a6 --- /dev/null +++ b/src/test/java/edu/ohio/ais/rundeck/HttpBuilderTest.java @@ -0,0 +1,78 @@ +package edu.ohio.ais.rundeck; + +import org.junit.Test; + +import java.util.HashMap; +import java.util.Map; + +import static edu.ohio.ais.rundeck.HttpBuilder.*; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; + +public class HttpBuilderTest { + + @Test + public void testGetStringOption() { + Map options = new HashMap<>(); + + String result = getStringOption(options, "missingKey"); + assertNull("Expected null when key is missing", result); + + options.put("nullKey", null); + result = getStringOption(options, "nullKey"); + assertNull("Expected null when value is null", result); + + options.put("key", "value"); + result = getStringOption(options, "key"); + assertEquals("Expected the value associated with the key", "value", result); + } + + @Test + public void testGetStringOptionWithDefault() { + Map options = new HashMap<>(); + + String result = getStringOption(options, "missingKey", "defaultValue"); + assertEquals("Expected the default value when key is missing", "defaultValue", result); + + options.put("nullKey", null); + result = getStringOption(options, "nullKey", "defaultValue"); + assertEquals("Expected the default value when value is null", "defaultValue", result); + + options.put("key", "value"); + result = getStringOption(options, "key", "defaultValue"); + assertEquals("Expected the value associated with the key", "value", result); + } + + @Test + public void testGetIntOption() { + Map options = new HashMap<>(); + + Integer result = getIntOption(options, "missingKey", 42); + assertEquals("Expected the default value when key is missing", Integer.valueOf(42), result); + + options.put("nullKey", null); + result = getIntOption(options, "nullKey", 42); + assertEquals("Expected the default value when value is null", Integer.valueOf(42), result); + + options.put("key", 99); + result = getIntOption(options, "key", 42); + assertEquals("Expected the value associated with the key", Integer.valueOf(99), result); + } + + @Test + public void testGetBooleanOption() { + Map options = new HashMap<>(); + + Boolean result = getBooleanOption(options, "missingKey", true); + assertEquals("Expected the default value when key is missing", Boolean.TRUE, result); + + options.put("nullKey", null); + result = getBooleanOption(options, "nullKey", true); + assertEquals("Expected the default value when value is null", Boolean.TRUE, result); + + options.put("key", false); + result = getBooleanOption(options, "key", true); + assertEquals("Expected the value associated with the key", Boolean.FALSE, result); + } + +} diff --git a/src/test/java/edu/ohio/ais/rundeck/HttpWorkflowNodeStepPluginTest.java b/src/test/java/edu/ohio/ais/rundeck/HttpWorkflowNodeStepPluginTest.java index 85aea58..60453b7 100644 --- a/src/test/java/edu/ohio/ais/rundeck/HttpWorkflowNodeStepPluginTest.java +++ b/src/test/java/edu/ohio/ais/rundeck/HttpWorkflowNodeStepPluginTest.java @@ -1,11 +1,15 @@ package edu.ohio.ais.rundeck; +import com.dtolabs.rundeck.core.common.Framework; +import com.dtolabs.rundeck.core.common.FrameworkProject; +import com.dtolabs.rundeck.core.common.FrameworkProjectMgr; import com.dtolabs.rundeck.core.common.INodeEntry; import com.dtolabs.rundeck.core.execution.ExecutionContext; import com.dtolabs.rundeck.core.execution.ExecutionLogger; import com.dtolabs.rundeck.core.execution.workflow.steps.StepFailureReason; import com.dtolabs.rundeck.core.execution.workflow.steps.node.NodeStepException; import com.dtolabs.rundeck.core.plugins.configuration.Description; +import com.dtolabs.rundeck.core.utils.IPropertyLookup; import com.dtolabs.rundeck.plugins.PluginLogger; import com.dtolabs.rundeck.plugins.step.PluginStepContext; import com.github.tomakehurst.wiremock.client.WireMock; @@ -27,6 +31,7 @@ import java.util.Map; import static org.junit.Assert.*; +import static org.mockito.Matchers.anyString; import static org.mockito.Mockito.when; public class HttpWorkflowNodeStepPluginTest { @@ -176,6 +181,20 @@ public void setUp() { when(pluginContext.getLogger()).thenReturn(pluginLogger); when(pluginContext.getExecutionContext()).thenReturn(executionContext); + // Mock the necessary objects + Framework framework = Mockito.mock(Framework.class); + FrameworkProjectMgr frameworkProjectMgr = Mockito.mock(FrameworkProjectMgr.class); + FrameworkProject frameworkProject = Mockito.mock(FrameworkProject.class); + IPropertyLookup frameworkProperties = Mockito.mock(IPropertyLookup.class); + + // Mock the interactions + when(pluginContext.getFramework()).thenReturn(framework); + when(framework.getFrameworkProjectMgr()).thenReturn(frameworkProjectMgr); + when(frameworkProjectMgr.getFrameworkProject(anyString())).thenReturn(frameworkProject); + when(frameworkProject.getProperties()).thenReturn(new HashMap()); + when(framework.getPropertyLookup()).thenReturn(frameworkProperties); + when(frameworkProperties.hasProperty(anyString())).thenReturn(true); + dataContext =new HashMap<>(); when(pluginContext.getDataContext()).thenReturn(dataContext); @@ -316,6 +335,7 @@ public void canHandleAuthenticationRequired() throws NodeStepException { options.put("remoteUrl", OAuthClientTest.BASE_URI + ERROR_URL_401); options.put("method", "GET"); + options.put("authentication", HttpBuilder.AUTH_BASIC); this.plugin.executeNodeStep(pluginContext, options, node ); } diff --git a/src/test/java/edu/ohio/ais/rundeck/HttpWorkflowStepPluginTest.java b/src/test/java/edu/ohio/ais/rundeck/HttpWorkflowStepPluginTest.java index ba7ccf1..88773a8 100644 --- a/src/test/java/edu/ohio/ais/rundeck/HttpWorkflowStepPluginTest.java +++ b/src/test/java/edu/ohio/ais/rundeck/HttpWorkflowStepPluginTest.java @@ -1,10 +1,14 @@ package edu.ohio.ais.rundeck; +import com.dtolabs.rundeck.core.common.Framework; +import com.dtolabs.rundeck.core.common.FrameworkProject; +import com.dtolabs.rundeck.core.common.FrameworkProjectMgr; import com.dtolabs.rundeck.core.execution.ExecutionContext; import com.dtolabs.rundeck.core.execution.workflow.steps.PluginStepContextImpl; import com.dtolabs.rundeck.core.execution.workflow.steps.StepException; import com.dtolabs.rundeck.core.execution.workflow.steps.StepFailureReason; import com.dtolabs.rundeck.core.plugins.configuration.Description; +import com.dtolabs.rundeck.core.utils.IPropertyLookup; import com.dtolabs.rundeck.plugins.PluginLogger; import com.dtolabs.rundeck.plugins.step.PluginStepContext; import com.github.tomakehurst.wiremock.client.WireMock; @@ -20,6 +24,7 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.fail; +import static org.mockito.Matchers.anyString; import static org.mockito.Mockito.when; public class HttpWorkflowStepPluginTest { @@ -163,6 +168,19 @@ public void setUp() { dataContext =new HashMap<>(); Mockito.when(pluginContext.getDataContext()).thenReturn(dataContext); + // Mock the necessary objects + Framework framework = Mockito.mock(Framework.class); + FrameworkProjectMgr frameworkProjectMgr = Mockito.mock(FrameworkProjectMgr.class); + FrameworkProject frameworkProject = Mockito.mock(FrameworkProject.class); + IPropertyLookup frameworkProperties = Mockito.mock(IPropertyLookup.class); + + when(pluginContext.getFramework()).thenReturn(framework); + when(framework.getFrameworkProjectMgr()).thenReturn(frameworkProjectMgr); + when(frameworkProjectMgr.getFrameworkProject(anyString())).thenReturn(frameworkProject); + when(frameworkProject.getProperties()).thenReturn(new HashMap()); + when(framework.getPropertyLookup()).thenReturn(frameworkProperties); + when(frameworkProperties.hasProperty(anyString())).thenReturn(true); + } @Test() @@ -293,6 +311,7 @@ public void canHandleAuthenticationRequired() throws StepException { options.put("remoteUrl", OAuthClientTest.BASE_URI + ERROR_URL_401); options.put("method", "GET"); + options.put("authentication", HttpBuilder.AUTH_BASIC); this.plugin.executeStep(pluginContext, options); }