Mockito Restemplate Verify not invoked - java

I a trying to mock restetmplate but don't why I am getting the below error. I am using doreturn to verify the invocation of the resttemplate.Is there by other way to mock the rest template and mock the HTTP request
class ToTest{
public ResponseEntity<String> getValue(){
if (StringUtils.isNotEmpty(token)) {
HttpHeaders headers = new HttpHeaders();
headers.set("Authorization", "Bearer " + token);
headers.setContentType(MediaType.APPLICATION_JSON);
UriComponentsBuilder builder = UriComponentsBuilder.fromHttpUrl(etsServiceResourceDetails.getAccessTokenUri())
.queryParam("test","tsetValue");
builder.queryParam("some","someValue");
HttpEntity<?> entity = new HttpEntity<>(headers);
try {
response = restTemplate.exchange(builder.toUriString(), HttpMethod.GET, entity, String.class);
}
catch (RestClientResponseException ex ) {
log.error(ex);
if ( ex.getRawStatusCode() == HttpStatus.NOT_FOUND.value()) {
return ResponseEntity.notFound().build();
}
}
}
}
}
Unit Test for the rest Temaplate
#Test
public void testExchange() {
String token="abbjabxkcbkscksckbckbkcbksckckkcb";
MultiValueMap<String, String> queryParams = new LinkedMultiValueMap<>();
queryParams.add("query", "star");
queryParams.add("test", "star2");
UriComponents uriComponents = UriComponentsBuilder.newInstance().scheme("http").host("localhost:8080/some/add").path("/").queryParams(queryParams).buildAndExpand();
RestTemplate r = new RestTemplate();
RestTemplate r1 = spy(r);
HttpHeaders headers = new HttpHeaders();
headers.set("Authorization", "Bearer " + token);
headers.setContentType(MediaType.APPLICATION_JSON);
HttpEntity<?> entity = new HttpEntity<>(headers);
// ResponseEntity responserm=
//r1.exchange(uriComponents.toUriString(),HttpMethod.GET,entity,String.class); //I am getting error org.springframework.web.client.ResourceAccessException: I/O error on GET request for "http://localhost:8080
doReturn(new ResponseEntity("", HttpStatus.OK)).when(r1).exchange(anyString(), any(HttpMethod.class), any(HttpEntity.class), any(Class.class));
verify(r1, times(1)).exchange(eq(uriComponents.toUriString()), any(), any(), eq(String.class));
assertEquals("check", "http://localhost:8080/some/add/?query=s1&test=s2", uriComponents.toUriString());
}
Errors
-> at org.springframework.web.client.RestTemplate.exchange(RestTemplate.java:581)
Actually, there were zero interactions with this mock.
Wanted but not invoked:

Related

401 unauthorized : [no body] with root cause in JAVA Spring

I'm creating my first REST API using JAVA Spring and when I'm making a rest call to an external API, I get
401 Unauthorized: [no body]
I think my problem is here:
requestParams.add("Grant_type", "client_credentials");
I saw some questions related to this but none well able to solve my problem.
Spring REST template - 401 Unauthorized error
Spring Boot Callable - 401 Unauthorized: [no body]
JAVA code:
public String getAuth(String client_id, String app_secret) {
String auth = client_id + ":" + app_secret;
return Base64.getEncoder().encodeToString(auth.getBytes());
}
#GetMapping(value = "/token")
public Object generateAccessToken() {
String auth = this.getAuth(
"CLIENT_ID",
"APP_SECRET"
);
RestTemplate restTemplate = new RestTemplate();
String base = "https://external-api.com";
HttpHeaders headers = new HttpHeaders();
headers.set("Authorization", "Basic " + auth);
MultiValueMap<String, String> requestParams = new LinkedMultiValueMap<>();
requestParams.add("Grant_type", "client_credentials");
ResponseEntity<Object> response = restTemplate.postForEntity(
base + "/v1/oauth2/token",
requestParams,
Object.class,
headers
);
return response.getBody();
}
Here's the solution to my own question.
This is what I had to change;
MultiValueMap<String, String> requestBody = new LinkedMultiValueMap<>();
requestBody.add("grant_type", "client_credentials");
HttpEntity<?> request = new HttpEntity<>(requestBody, headers);
ResponseEntity<String> response = restTemplate.postForEntity(
base +"/v1/oauth2/token",
request,
String.class
);
Here's the final solution:
public String generateAccessToken() {
String base = "example-api.com";
String auth = this.getAuth(
"client id",
"app_id"
);
// create an instance of RestTemplate
RestTemplate restTemplate = new RestTemplate();
// create headers
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
headers.set("Authorization", "Basic " + auth);
MultiValueMap<String, String> requestBody = new LinkedMultiValueMap<>();
requestBody.add("grant_type", "client_credentials");
HttpEntity<?> request = new HttpEntity<>(requestBody, headers);
ResponseEntity<String> response = restTemplate.postForEntity(
base +"/v1/oauth2/token",
request,
String.class
);
// check response
if (response.getStatusCode() == HttpStatus.OK) {
System.out.println("Request Successful");
System.out.println(response.getBody());
} else {
System.out.println("Request Failed");
System.out.println(response.getStatusCode());
}
JSONObject object = new JSONObject(response.getBody());
return object.getString("access_token");
}

Proper way to get Oath2 access token and call another service in Java Spring Boot

I want to get the oath2 access token and using this I want to call an another service.
Below code does the same it gets the access token and call an another API using that. Using the below code I am able to do what ever I want with the below code.
But I am new to Spring Security I just want to know if there is a better way to do this. Like rather than making a separate call to get the token and then call the service can i do it in a single call? Or Using any other class provided by Spring can I write this in a better way ?
public class TestAPIToken{
#RequestMapping(value = "/showEmployees", method = RequestMethod.GET)
public ModelAndView showEmployees(#RequestParam("code") String code) throws JsonProcessingException, IOException {
String accessToken = getAccessToken();
System.out.println("API Token ---------" + accessToken);
HttpEntity<String> response = getResponseByCallingWithToken(accessToken);
System.out.println("API Response ---------" + response.getBody());
return null;
}
private HttpEntity<String> getResponseByCallingWithToken(String accessToken) {
HttpHeaders headers = new HttpHeaders();
headers.setAccept(Arrays.asList(MediaType.APPLICATION_JSON));
headers.add("Authorization", "Bearer " + accessToken);
UriComponentsBuilder builder = UriComponentsBuilder.fromHttpUrl(url)
.queryParam("msisdn", msisdn)
.queryParam("email", email);
HttpEntity<?> entity = new HttpEntity<>(headers);
HttpEntity<String> response = restTemplate.exchange(
builder.toUriString(),
HttpMethod.GET,
entity,
String.class);
reponse.getBody();
return response;
}
private String getAccessToken() {
ResponseEntity<String> response = null;
System.out.println("Authorization Code------" + code);
RestTemplate restTemplate = new RestTemplate();
// According OAuth documentation we need to send the client id and secret key in the header for authentication
String encodedCredentials = new String(Base64.encodeBase64(credentials.getBytes()));
HttpHeaders headers = new HttpHeaders();
headers.setAccept(Arrays.asList(MediaType.APPLICATION_JSON));
headers.add("Authorization", "Basic " + encodedCredentials);
MultiValueMap<String, String> body = new LinkedMultiValueMap<>();
body.add("scope","scope,value");
body.add("grant_type","scope,value");
HttpEntity<String> request = new HttpEntity<String>(body, headers);
String access_token_url = "http://localhost:8080/oauth2/token";
ResponseEntity<TokenModel> response = restTemplate.exchange(access_token_url, HttpMethod.POST, request, TokenModel.class);
String accessToken = response.getBody().access_token;
return accessToken;
}
}
class TokenModel{
String access_token;
String scope;
String token_type;
String expires_in;
}
I am new to Spring security. Please help even if this seems simple to you
NB: This question does not have an exact duplicate

Rest template for postForEntity with file & other properties

I want to upload the file with Json request in rest template along with other properties. But I couldn't able to do this.
#Bean
public RestTemplate getRestTemplate(RestTemplateBuilder restTemplateBuilder) {
return restTemplateBuilder.build();
}
#Autowired
private RestTemplate restTemplate;
#Scheduled(fixedDelay = 1000)
public void _do() throws Exception {
HashMap<String, String> documentProperties = new HashMap<>();
documentProperties.put("number", "123");
MultipartFile file = Somefile;
UploadDocumentRequest uploadDocumentRequest = new UploadDocumentRequest();
uploadDocumentRequest.setDocumentClass("DocClass");
uploadDocumentRequest.setDocumentProperties(documentProperties);
uploadDocumentRequest.setFile(file); ----???
ResponseEntity<String> value = restTemplate.postForEntity("URL", uploadDocumentRequest, String.class);
}
You have to create HttpEntity with header and body.
Set the content-type header value to MediaType.MULTIPART_FORM_DATA.
Build the request body as an instance of LinkedMultiValueMap class.
Construct an HttpEntity instance that wraps the header and the body object and post it using a RestTemplate.
A sample code is shown as follows:
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.MULTIPART_FORM_DATA);
MultiValueMap<String, Object> body = new LinkedMultiValueMap<>();
body.add("file", getFileToBeUploaded());
HttpEntity<MultiValueMap<String, Object>> requestEntity = new HttpEntity<>(body, headers);
RestTemplate restTemplate = new RestTemplate();
ResponseEntity<String> response = restTemplate.postForEntity(serviveUrl, requestEntity, String.class);

How to Spring Retryable with http status code

I'm currently using spring 2 with restTemplate and I would like to have a retry sending a post request only with a certain status codes or any of code 500.
How do I do this?
Here is my code
#Retryable(value = RestClientException.class, exclude = {UnknownHostException.class},
backoff=#Backoff(delayExpression = 10000,
multiplierExpression = 2,
maxDelayExpression = 50000))
public HttpStatus postRequest(final File file) throws RestClientException {
MultiValueMap<String, Object> body = new LinkedMultiValueMap<>();
body.add("file", new FileSystemResource(file));
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.MULTIPART_FORM_DATA);
headers.set("Token", mytoken);
HttpEntity<MultiValueMap<String, Object>> requestEntity = new HttpEntity<>(body, headers);
ResponseEntity<String> response = restTemplate.exchange(URI, HttpMethod.POST,requestEntity, String.class);
return response.getStatusCode();
}

Consuming HTTP POST method which is secured with Basic Auth in spring

I want to consume a post method which is secured using basicAuth. I am using springBoot, Spring RestTemplate to consume it.
I've tried like this:
#CrossOrigin(origins = "*", maxAge = 3600)
#RequestMapping(value = "/ValidateAnswers", method = RequestMethod.POST)
public ResponseEntity<String> ValidateAnswers(#RequestBody Object requestIbject,
HttpServletRequest request, HttpServletResponse response) {
final String uri = "foo:8080//validateAnswers";
// hiding full path here,
RestTemplate restTemplate = new RestTemplate();
String plainClientCredentials = "user:pass";
String base64ClientCredentials = new String(
Base64.encodeBase64(plainClientCredentials.getBytes()));
HttpHeaders headers = new HttpHeaders();
headers.add("Authorization", "Basic " + base64ClientCredentials);
HttpEntity<String> entity = new HttpEntity<String>("parameters",
headers);
ResponseEntity<String> respEntity = restTemplate.postForObject(uri, requestIbject, String.class);
// .exchange(uri,
// HttpMethod.POST, entity, String.class);
System.err.println("=------------Response--------------");
System.err.println("----" + respEntity);
return respEntity;
}
How do I pass the headers with basicAuth and post request body ?
if you using spring > 4.3.1
RestTemplate restTemplate = new RestTemplate();
restTemplate.getInterceptors().add(new BasicAuthorizationInterceptor("user", "password"));
From your code snippets I don't think you should use post method, try get first. And refer to my previous test:
public class Test {
private HttpHeaders getHeaders(){
String plainCredentials="admin:admin";
String base64Credentials = Base64.getEncoder().encodeToString(plainCredentials.getBytes());
HttpHeaders headers = new HttpHeaders();
headers.add("Authorization", "Basic " + base64Credentials);
return headers;
}
#Test
public void testLogin() {
RestTemplate restTemplate = new RestTemplate();
HttpEntity<String> request = new HttpEntity<String>(getHeaders());
ResponseEntity<String> response = restTemplate.exchange("http://localhost:8080/login", HttpMethod.GET,
request, String.class);
System.out.println(response.getBody());
}
}

Categories