Connecting to a remote RabbitMQ server using letsencrypt ssl - spring-amqp

I have this configuration to be able to connect to compose.io rabbitmq service
package com.gandalf.configuration;
import org.springframework.amqp.rabbit.connection.CachingConnectionFactory;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.amqp.rabbit.config.SimpleRabbitListenerContainerFactory;
import org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer;
import org.springframework.amqp.rabbit.listener.adapter.MessageListenerAdapter;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.rabbit.core.RabbitAdmin;
import org.springframework.amqp.core.AmqpAdmin;
import org.springframework.amqp.core.Queue;
import org.springframework.amqp.rabbit.connection.RabbitConnectionFactoryBean;
#Configuration
public class SpringAmqpConfiguration {
#Bean
public ConnectionFactory connectionFactory() {
CachingConnectionFactory connectionFactory = new CachingConnectionFactory();
connectionFactory.setAddresses("portal274-33.***,....");
connectionFactory.setUsername("amqpuser");
connectionFactory.setPassword("muggledone");
connectionFactory.setUseSsl(true);
return connectionFactory;
}
#Bean
public SimpleRabbitListenerContainerFactory rabbitListenerContainerFactory() {
SimpleRabbitListenerContainerFactory factory = new SimpleRabbitListenerContainerFactory();
factory.setConnectionFactory(connectionFactory());
factory.setConcurrentConsumers(3);
//If you want a fixed number of consumers, omit the max.
factory.setMaxConcurrentConsumers(10);
return factory;
}
#Bean
public RabbitTemplate rabbitTemplate() {
RabbitTemplate template = new RabbitTemplate(connectionFactory());
return template;
}
}
However, upon running the program, i get an error in this line
connectionFactory.setUseSsl(true);
This is the error i get
Compilation failure
/SpringAmqpConfiguration.java:[24,26] cannot find symbol
[ERROR] symbol: method setUseSsl(boolean)
[ERROR] location: variable connectionFactory of type org.springframework.amqp.rabbit.connection.CachingConnectionFactory
Why is connectionFactory.setUseSsl(true); not being found?.

There is no property useSsl on the CachingConnectionFactory; there is a useSslProtocol property on the underlying com.rabbitmq.client.ConnectionFactory.
Use connectionFactory.getRabbitConnectionFactory().useSslProtocol().

Related

Appium parallel test threadlocal

I am trying to run parallel test through selenium grid.
I know I have to use "thread local" for parallel execution,
but I have a problem with my code.
Cannot invoke "io.appium.java_client.android.AndroidDriver.findElementByAccessibilityId(String)" because "driver" is null
can you please solve it
package appiumset;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.concurrent.TimeUnit;
import org.openqa.selenium.remote.DesiredCapabilities;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Parameters;
import io.appium.java_client.AppiumDriver;
import io.appium.java_client.MobileElement;
import io.appium.java_client.android.AndroidDriver;
import io.appium.java_client.remote.AndroidMobileCapabilityType;
import io.appium.java_client.remote.MobileCapabilityType;
public class _2_Deviceinfo {
public ThreadLocal<AppiumDriver> driver = new ThreadLocal<>();
public void setDriver(AppiumDriver driver) {
this.driver.set(driver);
}
public AppiumDriver getDriver() {
return this.driver.get();
}
#Parameters({"device", "apppackage", "activity","version","appiumServer" , "systemPort", "platformName"})
#BeforeMethod
public synchronized void deviceSetUp(String device, String apppackage, String activity, String version, String appiumServer, String systemPort, String platformName) throws InterruptedException, MalformedURLException {
System.out.println("****************************************");
System.out.println("Setting up device and desired capabilities");
DesiredCapabilities cap = new DesiredCapabilities();
URL url = new URL(appiumServer);
setDriver(new AndroidDriver<>(url, cap));
cap.setCapability(MobileCapabilityType.DEVICE_NAME, device);
cap.setCapability(MobileCapabilityType.UDID, device);
cap.setCapability(AndroidMobileCapabilityType.SYSTEM_PORT, systemPort);
cap.setCapability(MobileCapabilityType.NEW_COMMAND_TIMEOUT, 120);
cap.setCapability(MobileCapabilityType.PLATFORM_NAME, platformName);
//cap.setCapability(MobileCapabilityType., BrowserType.ANDROID);
cap.setCapability(MobileCapabilityType.PLATFORM_VERSION, version);
cap.setCapability(AndroidMobileCapabilityType.APP_PACKAGE, apppackage);
cap.setCapability(AndroidMobileCapabilityType.APP_ACTIVITY, activity);
cap.setCapability("automationName", "UiAutomator2");
cap.setCapability("noReset","false");
cap.setCapability("FullReset","true");
cap.setCapability("APP_WAIT_ACTIVITY", "*");
cap.setCapability("autowebview","false");
}
#AfterMethod
public void closeDriver() {
getDriver().quit();
}
}
I can't find the driver (AppiumDriver)
package appiumset;
import java.net.MalformedURLException;
import java.util.concurrent.TimeUnit;
import org.testng.annotations.Test;
import io.appium.java_client.AppiumDriver;
import io.appium.java_client.MobileElement;
import io.appium.java_client.android.AndroidDriver;
public class _3_Onboarding extends _1_Appstart {
#Test
public void onboarding() throws MalformedURLException, InterruptedException {
System.out.println("_3_Onboarding Start");
MobileElement arrow = driver.findElementByAccessibilityId("next");
arrow.click();
System.out.println("next-done");
}
}
call getdriver() method of your class _2_Deviceinfo to your test class.
Appiumdriver<?> driver = getDriver();
MobileElement arrow = driver.findElementByAccessibilityId("next");
arrow.click();

My SparkJava resource server gets 403 errors when trying to validate access tokens

I want to set up a very basic REST API using Spark-java, which just checks an access token obtained from my own authorisation server. It creates a GET request to the authorisation server's /oauth/authorize endpoint followed by ?token=$ACCESS_TOKEN.
Whenever I try this, I get diverted to the /error endpoint and a 403 error.
Here's my API class:
import org.apache.http.client.methods.HttpGet;
import org.apache.http.entity.ContentType;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import spark.utils.StringUtils;
import java.io.IOException;
import static spark.Spark.*;
public class SampleAPI {
private static final Logger logger = LoggerFactory.getLogger("SampleAPI");
public static void main(String[] args) {
// Run on port 9782
port(9782);
// Just returns "Hello there" to the client's console
before((preRequest, preResponse) -> {
System.out.println("Getting token from request");
final String authHeader = preRequest.headers("Authorization");
//todo validate token, don't just accept it because it's not null/empty
if(StringUtils.isEmpty(authHeader) || !isAuthenticated(authHeader)){
halt(401, "Access not authorised");
} else {
System.out.println("Token = " + authHeader);
}
});
get("/", (res, req) -> "Hello there");
}
private static boolean isAuthenticated(final String authHeader) {
String url = "http://localhost:9780/oauth/authorize";
//"Bearer " is before the actual token in authHeader, so we need to extract the token itself as a substring
String token = authHeader.substring(7);
HttpGet getAuthRequest = new HttpGet(url + "?token=" + token);
getAuthRequest.setHeader("Content-Type", ContentType.APPLICATION_FORM_URLENCODED.getMimeType());
CloseableHttpClient httpClient = HttpClients.createMinimal();
try {
CloseableHttpResponse response = httpClient.execute(getAuthRequest);
int statusCode = response.getStatusLine().getStatusCode();
System.out.println("Status code " + statusCode + " returned for access token " + authHeader);
return statusCode == 200;
} catch (IOException ioException) {
System.out.println("Exception when trying to validate access token " + ioException);
}
return false;
}
}
The System.out.println statements are just for debugging.
Here's my authorisation server's WebSecurityConfigurerAdapter class:
package main.config;
import main.service.ClientAppDetailsService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.factory.PasswordEncoderFactories;
import org.springframework.security.crypto.password.PasswordEncoder;
#Configuration
#EnableWebSecurity(debug = true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
#Autowired
private UserDetailsService userDetailsService;
#Override
#Bean
public AuthenticationManager authenticationManagerBean() throws Exception {
//returns AuthenticationManager from the superclass for authenticating users
return super.authenticationManagerBean();
}
#Bean
public PasswordEncoder getPasswordEncoder() {
return PasswordEncoderFactories.createDelegatingPasswordEncoder();
}
#Override
public void configure(WebSecurity web) throws Exception {
//Allow for DB access without any credentials
web.ignoring().antMatchers("/h2-console/**");
}
#Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
//configures user details, and uses the custom UserDetailsService to check user credentials
auth.userDetailsService(userDetailsService).passwordEncoder(getPasswordEncoder());
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests().anyRequest().authenticated();
//disable CORS and CSRF protection for Postman testing
http.cors().disable().anonymous().disable();
http.headers().frameOptions().disable();
http.csrf().disable();
}
}
And here's my authorisation server's application.properties:
server.port=9780
#in-memory database, will get populated using data.sql
spring.datasource.url=jdbc:h2:mem:testdb
spring.datasource.driverClassName=org.h2.Driver
spring.datasource.username=admin
spring.datasource.password=syst3m
spring.jpa.database-platform=org.hibernate.dialect.H2Dialect
spring.jpa.properties.hibernate.format_sql=true
#adds to existing DB instead of tearing it down and re-populating it every time the app is started
spring.jpa.hibernate.ddl-auto=update
spring.h2.console.enabled=true
spring.h2.console.path=/h2-console
spring.h2.console.settings.trace=false
spring.h2.console.settings.web-allow-others=false
What have I done wrong? Do I need to specify my API as a resource server using Spring Security? Do I need to add it to the authorisation server's application.properties?
If you want to use Spring as a security framework then the most common option is to configure it as a resource server. Here is a getting started tutorial. The API will then never get redirected.
With Spark another option is to just provide a basic filter that uses a JWT validation library, such as jose4j. This tends to provide better control over error responses and gives you better visibility over what is going on. See this Kotlin example, which will be easy enough to translate to Java.

spring-data-elasticsearch latest version throws NullPointer exception with Elasticsearch 8.1 version

Planning to use elasticsearch 8.1 version and use 'org.springframework.boot:spring-boot-starter-data-elasticsearch' in
our project.
Repository.save() throws following exception.
java.lang.NullPointerException: null
at java.base/java.util.Objects.requireNonNull(Objects.java:221)
at org.elasticsearch.action.DocWriteResponse.(DocWriteResponse.java:116)
at org.elasticsearch.action.index.IndexResponse.(IndexResponse.java:43)
The same code with Elasticsearch 7.15.2 works fine.
I see the supported matrix here https://docs.spring.io/spring-data/elasticsearch/docs/current/reference/html/#preface.requirements
Where to see the road map of Spring boot elasticsearch data plugin? When Do we get the plugin support for the 8.1 version of
Elasticsearch?
Thanks in advance
Adding the following headers resolved the issue.
Accept: "application/vnd.elasticsearch+json;compatible-with=7"
Content-Type: "application/vnd.elasticsearch+json;compatible-with=7"
Its better to change your code which is used for creating client
package com.search.elasticsearchapp.config;
import org.apache.http.Header;
import org.apache.http.HttpHost;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.client.CredentialsProvider;
import org.apache.http.impl.client.BasicCredentialsProvider;
import org.apache.http.message.BasicHeader;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestClientBuilder;
import org.elasticsearch.client.RestHighLevelClient;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.elasticsearch.repository.config.EnableElasticsearchRepositories;
import org.springframework.http.HttpHeaders;
#Configuration
#EnableElasticsearchRepositories(basePackages = "*")
public class TestClient {
#Value("${elasticsearch.host}")
private String host;
#Value("${elasticsearch.port}")
private int port;
#Value("${elasticsearch.protocol}")
private String protocol;
#Value("${elasticsearch.username}")
private String userName;
#Value("${elasticsearch.password}")
private String password;
#Bean(destroyMethod = "close")
public RestHighLevelClient restClient() {
final CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
credentialsProvider.setCredentials(AuthScope.ANY, new UsernamePasswordCredentials(userName, password));
RestClientBuilder builder = RestClient.builder(new HttpHost(host, port, protocol))
.setHttpClientConfigCallback(httpClientBuilder -> httpClientBuilder.setDefaultCredentialsProvider(credentialsProvider))
.setDefaultHeaders(compatibilityHeaders());
return new RestHighLevelClient(builder);
}
private Header[] compatibilityHeaders() {
return new Header[]{new BasicHeader(HttpHeaders.ACCEPT, "application/vnd.elasticsearch+json;compatible-with=7"), new BasicHeader(HttpHeaders.CONTENT_TYPE, "application/vnd.elasticsearch+json;compatible-with=7")};
}
}

OAUTH error="access_denied", error_description="Error requesting access token." when trying to access tokens

the code that i wrote:
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.oauth2.client.DefaultOAuth2ClientContext;
import org.springframework.security.oauth2.client.OAuth2RestOperations;
import org.springframework.security.oauth2.client.OAuth2RestTemplate;
import org.springframework.security.oauth2.client.resource.OAuth2ProtectedResourceDetails;
import org.springframework.security.oauth2.client.token.AccessTokenRequest;
import org.springframework.security.oauth2.client.token.DefaultAccessTokenRequest;
import org.springframework.security.oauth2.client.token.grant.client.ClientCredentialsResourceDetails;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableOAuth2Client;
#EnableOAuth2Client
#Configuration
public class OAuth2SecurityConfig {
private static Logger logger = LoggerFactory.getLogger(OAuth2SecurityConfig.class);
#Value("${tokenUrl}")
private String tokenUrl;
#Value("${oauthClientId}")
private String oauthClientId;
#Value("${oauthClientPassword}")
private String oauthClientPassword;
#Value("${oauthGrantType}")
private String oauthGrantType;
#Bean
protected OAuth2ProtectedResourceDetails resourceDetails() {
logger.info("inside resourceDetails");
ClientCredentialsResourceDetails resourceDetails = new ClientCredentialsResourceDetails();
resourceDetails.setAccessTokenUri(tokenUrl);
resourceDetails.setClientId(oauthClientId);
resourceDetails.setClientSecret(oauthClientPassword);
resourceDetails.setGrantType(oauthGrantType);
logger.info("resourceDetails: "+ resourceDetails.toString());
logger.info("resourceDetails: "+ resourceDetails.getAccessTokenUri());
return resourceDetails;
}
#Bean
public OAuth2RestOperations restTemplateToken() {
logger.info("inside restTemplateToken");
AccessTokenRequest request = new DefaultAccessTokenRequest();
return new OAuth2RestTemplate(resourceDetails(), new DefaultOAuth2ClientContext(request));
}
}
The file where I am accessing the tokens I have given this line to fetch it after autowiring OAuth2RestOperations :
#Autowired
private OAuth2RestOperations restTemplateToken;
inside Method....
OAuth2AccessToken accessToken = restTemplateToken.getAccessToken();
When i execute it I am getting error like :
error="access_denied", error_description="Error requesting access token."
Not sure why it is failing. Please help.
Thanks.

Null pointer exception when jenkins version is set to 2.X

I have a plugin with jenkins version set to 1.580.3.And when I upgrade the jenkins version to 1.642.3<=version , it is throwing a null pointer exception.Below is the stacktrace
java.lang.NullPointerException
at hudson.model.Label.hashCode(Label.java:528)
at java.util.HashMap.hash(HashMap.java:338)
at java.util.HashMap.put(HashMap.java:611)
at java.util.HashSet.add(HashSet.java:219)
at java.util.Collections.addAll(Collections.java:5401)
at com.google.common.collect.Sets.newHashSet(Sets.java:183)
at com.ericsson.oss.axis.ATest.setUp(ATest.java:45)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.junit.internal.runners.MethodRoadie.runBefores(MethodRoadie.java:132)
at org.junit.internal.runners.MethodRoadie.runBeforesThenTestThenAfters(MethodRoadie.java:95)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl$PowerMockJUnit44MethodRunner.executeTest(PowerMockJUnit44RunnerDelegateImpl.java:294)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit47RunnerDelegateImpl$PowerMockJUnit47MethodRunner.executeTestInSuper(PowerMockJUnit47RunnerDelegateImpl.java:127)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit47RunnerDelegateImpl$PowerMockJUnit47MethodRunner.executeTest(PowerMockJUnit47RunnerDelegateImpl.java:82)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl$PowerMockJUnit44MethodRunner.runBeforesThenTestThenAfters(PowerMockJUnit44RunnerDelegateImpl.java:282)
at org.junit.internal.runners.MethodRoadie.runTest(MethodRoadie.java:86)
at org.junit.internal.runners.MethodRoadie.run(MethodRoadie.java:49)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl.invokeTestMethod(PowerMockJUnit44RunnerDelegateImpl.java:207)
below is my code
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.nullValue;
import static org.hamcrest.core.Is.is;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.when;
import java.util.ArrayList;
import java.util.List;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.jvnet.jenkins.plugins.nodelabelparameter.LabelParameterValue;
import org.mockito.Answers;
import org.mockito.Mock;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
import com.XXXXX.JenkinsUtils;(internal)
import com.google.common.collect.Sets;
import hudson.model.AbstractBuild;
import hudson.model.Label;
import hudson.model.ParameterValue;
import hudson.model.ParametersAction;
import jenkins.model.Jenkins;
#RunWith(PowerMockRunner.class)
#PrepareForTest( JenkinsUtils.class)
public class A{
#Mock
private Label label;
#Mock
private Jenkins jenkins;
#Mock(answer = Answers.RETURNS_DEEP_STUBS)
private AbstractBuild build;
#Before
public void setUp() {
PowerMockito.mockStatic(JenkinsUtils.class);
try {
doReturn(Sets.newHashSet(label)).when(jenkins).getLabels();
} catch (Exception e) {
e.printStackTrace();
}
}
}
#RunWith(PowerMockRunner.class)
#PrepareForTest(NodeLabelParameterUtils.class )
public class B{
private BaselineDefinedMessageDispatcher unit;
private BuildData buildData = new BuildData();
private MyBuildDetails myBuildDetails;
#Mock(answer = Answers.RETURNS_DEEP_STUBS)
private AbstractBuild build;
#Mock
private BuildLogger buildLogger;
#Mock
private Label label;
#Mock
private Computer computer;
#Mock
private PretendSlave node;
#Mock
private FreeStyleProject project;
#Mock
private Jenkins jenkins;
#Mock
private EnvironmentVariableResolver envVarsResolver;
#Before
public void setUp() throws IOException, InterruptedException, Descriptor.FormException {
unit = spy(new BaselineDefinedMessageDispatcher(null, null));
unit.setBuildLogger(mock(BuildLogger.class));
MyBuildDetails = mock(MyBuildDetails.class);
doReturn("expectedSlaveHost").when(unit).getHostNameFromSlave(any(Node.class));
doReturn(project).when(build).getProject();
doReturn(Sets.<Node>newHashSet(node)).when(label).getNodes();
doReturn(node).when(build).getBuiltOn();
doReturn(jenkins).when(unit).getJenkinsInstance();
doReturn(Sets.newHashSet(label)).when(jenkins).getLabels();
PowerMockito.mockStatic(A.class);
when(envVarsResolver.processString(anyString())).thenAnswer(new Answer<String>() {
#Override
public String answer(InvocationOnMock invocationOnMock) throws Throwable {
return (String) invocationOnMock.getArguments()[0];
}
});
}
The following dependencies are being used
powermock-api-mockito - 1.6.3
mockito-core - 1.9.5
junit - 4.11
java - 1.8
jenkins.version - 1.642.3
I get the error exactly at doReturn(Sets.newHashSet(label)).when(jenkins).getLabels(); in class A.
This is a maven project and when jenkins version is set to 1.580.3 mvn clean install is success but when it is version>=1.642.3 it is failing.
My aim is to upgrade jenkins verison to 2.X.I went through manyworkarounds in stackoverflow but nothing worked
Any help is appreciated
Edit:
Looks like my orignal answer was just incorrect.
The NPE comes from the fact that the abstract Label class has a constructor parameter called name. This parameter is used to calculate the hashcode of the label.
If you mock it this name is null and you get the NPE.
The question now is do you need to create a mock of this or can you actually use a real instance? In the exmaple below I just used one of the implementations of that class LabelAtom. If a mock is required because you need to define some behaviour on the object that you can not get otherwise, you probably have to use a spy.
(Tested with org.jenkins-ci.main:jenkins-core:2.85)
import static org.mockito.Mockito.doReturn;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.powermock.modules.junit4.PowerMockRunner;
import com.google.common.collect.Sets;
import hudson.model.Label;
import hudson.model.labels.LabelAtom;
import jenkins.model.Jenkins;
#RunWith(PowerMockRunner.class)
public class Test {
#Mock
private Jenkins jenkins;
private Label label;
#Before
public void setUp() {
Assert.assertNotNull(jenkins);
label = new LabelAtom("someName");
// or if a mock is required
//label = Mockito.spy(new LabelAtom("someName"));
doReturn(Sets.newHashSet(label)).when(jenkins).getLabels();
}
#Test
public void test() {
}
}
Regarding the WithOrWithoutExpectedArguments I was not able to reproduce that one.

Resources