I have the method:
public HTTPResult get(String url) throws Exception{
try {
ResponseEntity<String> response = restTemplate.getForEntity(url, String.class);
return new HTTPResult(response.getBody(), response.getStatusCode().value());
}
catch (ResourceAccessException e) {
String responseBody = e.getCause().getMessage();
JSONObject obj = new JSONObject(responseBody);
return new HTTPResult(obj.getString("responseBody"), Integer.parseInt(obj.getString("statusCode")));
}
}
I want to do unit testing for it and i am not sure how to proceed:
public class MockHttpServerTest {
private static final int PORT = 51234;
private static final String baseUrl = "http://localhost:" + PORT;
private MockHttpServer server;
private SimpleHttpResponseProvider responseProvider;
private HttpClient client;
#Before
public void setUp() throws Exception {
responseProvider = new SimpleHttpResponseProvider();
server = new MockHttpServer(PORT, responseProvider);
server.start();
client = new DefaultHttpClient();
}
I am getting RED for MockHttpServer & SimpleHttpResponseProvider which should be part of org.apache.wink.client.*; which i am importing. so why do i have red ones? is there some simple way to unit test it?
HTTPResult return me response code and message.
Related
I have this code, It uses the java java.net.http.HttpClient :
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.time.Duration;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit;
public class test {
private static String authorizationHeader = "Bearer ";
public static int MAX_RESEND = 5;
public static int TIME_OUT = 150000;
public static String url = "http://127.0.0.1:5000/api/test";
private static final HttpClient httpClient = HttpClient.newBuilder()
.version(HttpClient.Version.HTTP_1_1)
.connectTimeout(Duration.ofMinutes(3))
.build();
public static HTTPResponse postHttpRequest(HttpClient httpClient, String uri, String body){
HttpResponse.BodyHandler<String> handler = HttpResponse.BodyHandlers.ofString();
HttpRequest request = HttpRequest.newBuilder()
.version(HttpClient.Version.HTTP_1_1)
.timeout(Duration.ofMinutes(5))
.uri(URI.create(uri))
.header("Content-Type", "application/json")
.header("Authorization", authorizationHeader)
.POST(HttpRequest.BodyPublishers.ofString(body))
.build();
CompletableFuture<HttpResponse<String>> response = httpClient.sendAsync(request, handler)
.thenComposeAsync(r -> tryResend(httpClient, request, handler, 1, r, TIME_OUT));
String getResponse = null;
Integer getResponseStatusCode = null;
try {
getResponse = response.thenApply(HttpResponse::body).get(3, TimeUnit.MINUTES);
getResponseStatusCode = response.get().statusCode();
return new HTTPResponse(getResponseStatusCode, getResponse, null) ;
} catch (Exception e) {
return new HTTPResponse(500, e.toString(), e.getMessage());
}
}
public static <T> CompletableFuture<HttpResponse<T>> tryResend(HttpClient client, HttpRequest request, HttpResponse.BodyHandler<T> handler, int count, HttpResponse<T> resp, long timeSleep) {
try {
Thread.sleep(timeSleep);
if (resp.statusCode() == 200 || count >= MAX_RESEND) {
return CompletableFuture.completedFuture(resp);
} else {
return client.sendAsync(request, handler)
.thenComposeAsync(r -> tryResend(client, request, handler, count+1, r, timeSleep));
}
} catch (Exception e) {
throw new RuntimeException(e);
}
}
public static void main(String[] args) {
String body = "{\"app\":\"hi\"}";
HTTPResponse hResponseOrigin = postHttpRequest( httpClient , url , body);
Integer statusCodeOriginResponse = hResponseOrigin.getStatusCode();
String msgOriginResponse = hResponseOrigin.getResponse();
}
}
class HTTPResponse {
private Integer statusCode;
private String response;
private String exception;
public HTTPResponse(Integer statusCode, String response, String exception) {
this.statusCode = statusCode;
this.response = response;
this.exception = exception;
}
public Integer getStatusCode() {
return statusCode;
}
public void setStatusCode(Integer statusCode) {
this.statusCode = statusCode;
}
public String getResponse() {
return response;
}
public void setResponse(String response) {
this.response = response;
}
public String getException() {
return exception;
}
public void setException(String exception) {
this.exception = exception;
}
}
The code tries to do n recursive-requests when the first response of the request is not 200.
The issue always appears on the second retry.
I always get this exception:
java.util.concurrent.TimeoutException
example:
postHttpRequest ---------------------------
http://127.0.0.1:5000/api/test
tryResend ------------------------------------------------------
count zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz
1
res get tryResend ----------zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzxxxxxxxxxxxxxxx
{"app":"hi"}
status code: 500
tryResend ------------------------------------------------------
count zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz
2
res get tryResend ----------zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzxxxxxxxxxxxxxxx
{"app":"hi"}
msgOriginResponse xxxxxxxxxxxxxxxx----------------------------------------------------------------xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
java.util.concurrent.TimeoutException
msgOriginResponse end xxxxxxxxxxxxxxxxx----------------------------------------------------------------xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
How can I fix it?? any recomendation ?
I'm trying to mock a method call from class called RestClient in another called DiscoveryAdapter but as and when i'm trying to do a doReturn it throws a null pointer exception.
In test i'm trying to spy the restClient object in order to mock the method call in DiscoveryAdapter.discovery method but with it throws a null pointer exception when doReturn is called.
Please check the code below.
RestClient.class
#Component
#Scope("prototype")
public class RestClient {
private static final Logger logger = LoggerFactory.getLogger(RestClient.class);
private RestTemplate restTemplate = null;
private PoolingHttpClientConnectionManager syncConnectionManager;
public void init() {
restTemplate = new RestTemplate(new HttpComponentsClientHttpRequestFactory(buildhttpClient()));
}
public String queryRestEndpoints(HereMapsImpl mapType,String basePath,boolean isSSl) {
URI uriObject = null;
String uriPath = mapType.returnUri();
init();
try {
uriObject = RestUtils.buildUriFromString(basePath, isSSl, uriPath);
} catch (URISyntaxException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
logger.info("rest api is {}",uriObject);
//spring api
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
headers.setAccept(Arrays.asList(MediaType.APPLICATION_JSON));
HttpEntity<String> requestEntity = new HttpEntity<String>("",headers);
//rest api call with uriObject
ResponseEntity<String> responseEntity = restTemplate.exchange(uriObject,
HttpMethod.GET, requestEntity, String.class);
if(responseEntity.getStatusCodeValue() >=400 || responseEntity.getStatusCodeValue() <= 500)
logger.info("failed with status code {}",responseEntity.getStatusCodeValue() );
logger.info("checking my response");
logger.info("checking my response here {}",responseEntity.getBody());
return responseEntity.getBody();
}
private CloseableHttpClient buildhttpClient() {
CloseableHttpClient httpClient = null;
httpClient = HttpClientBuilder.create().setConnectionManager(getSyncConnectionManager())
.build();
return httpClient;
}
public PoolingHttpClientConnectionManager getSyncConnectionManager() {
syncConnectionManager = new PoolingHttpClientConnectionManager();
return syncConnectionManager;
}
DisoveryAdapter.class
#Component
public class DisoveryAdapter {
private static final Logger log = LoggerFactory.getLogger(DisoveryAdapter.class);
#Autowired
private RestClient restClient;
public void discovery() {
log.info("starting thread");
String response = restClient.queryRestEndpoints(eatDrink, completeUriPath, true);
log.info("oeat drink response {}",response);
}
}
DiscoveryAdapterTest.class
class HereMapsCheckImpTest {
private static final Logger log = LoggerFactory.getLogger(HereMapsCheckImpTest.class);
private RestClient restClient;
private HereMapsCheckImp hereMaps;
#Before
public void init() {
hereMaps = new HereMapsCheckImp();
restClient = new RestClient();
}
#Test
public void test() {
RestClient spyRestClient = spy(restClient);
log.info("with spring {}",spyRestClient);
doReturn("{\n" +
" color: \"red\",\n" +
" value: \"#f00\"\n" +
"}").when(spyRestClient).queryRestEndpoints(any(),any(),any());
hereMaps.discovery();
verify(spyRestClient).queryRestEndpoints(any(),any(),any());
}
}
I have Azure logic app with request trigger. I want to trigger this logic app from my java application. So, I am trying to call the request trigger url from my java API.
It is working fine if i am using DefaultHttpClient but getting 401 on calling it using RestTemplate in java.
DefaultHttpClient code:
try {
DefaultHttpClient httpClient = new DefaultHttpClient();
HttpGet getRequest = new HttpGet(
"{url of azure logic app trigger}");
//StringEntity input = new StringEntity("{\"qty\":100,\"name\":\"iPad 4\"}");
//input.setContentType("application/json");
//postRequest.setEntity(input);
HttpResponse response = httpClient.execute(getRequest);
BufferedReader br = new BufferedReader(
new InputStreamReader((response.getEntity().getContent())));
String output;
System.out.println("Output from Server .... \n");
while ((output = br.readLine()) != null) {
System.out.println(output);
}
httpClient.getConnectionManager().shutdown();
return("Success");
} catch (ClientProtocolException e) {
// TODO Auto-generated catch block
e.printStackTrace();
return("Error");
} catch (UnsupportedOperationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
return("Error");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
return("Error");
}
RestTemplate Code
#Service
public class SampleService {
#Autowired HttpClientService<String, String> httpClientService;
public String callURL() {
ResponseErrorHandler responseErrorHandler = new ResponseErrorHandler() {
#Override
public boolean hasError(ClientHttpResponse response) throws IOException {
System.out.print(response.toString());
return false;
}
#Override
public void handleError(ClientHttpResponse response) throws IOException {
// TODO Auto-generated method stub
}
};
UriComponentsBuilder builder = UriComponentsBuilder
.fromUriString("{logic app url}")
// Add query parameter
.queryParam("api-version", {api-version})
.queryParam("sp", {sp})
.queryParam("sv", {sv})
.queryParam("sig",{sig});
RequestDetailsDAO requestDetails = new RequestDetailsDAO(builder.build().toUri().toString(), HttpMethod.GET);
String response = httpClientService.execute(requestDetails, null, responseErrorHandler, String.class);
return response.toString();
HttpClientService.java
#Service
public class HttpClientService<T, V> {
public RestTemplate restTemplate;
public HttpClientService(RestTemplateBuilder restTemplateBuilder) {
this.restTemplate = restTemplateBuilder.setConnectTimeout(Duration.ofSeconds(5)).setReadTimeout(Duration.ofSeconds(5)).build();
}
public V execute(RequestDetailsDAO requestDetails, HttpEntity<T> entity, ResponseErrorHandler errorHandler,
Class<V> genericClass) {
restTemplate.setErrorHandler(errorHandler);
ResponseEntity<V> response = restTemplate.exchange(requestDetails.getUrl(), requestDetails.getRequestType(), entity, genericClass);
return response.getBody();
}
}
RequestDetailsDAO.java
public class RequestDetailsDAO {
private String url;
private HttpMethod requestType;
public RequestDetailsDAO(String url, HttpMethod requestTyp) {
super();
this.url = url;
this.requestType = requestTyp;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public HttpMethod getRequestType() {
return requestType;
}
public void setRequestType(HttpMethod requestType) {
this.requestType = requestType;
}
#Override
public String toString() {
return "RequestDetails [url=" + url + ", requestType=" + requestType + "]";
}
}
So, it seems that there's nothing special about LogicApps being called using RestTemplate.
It's just that RestTemplate by default URL encode the Uri given in parameter, and DefaultHttpClient does not - reference: apache vs resttemplate
In case of LogicApp URL, there is this "sp" parameter which is already URL endcoded, when you copy it from LogicApp -
"%2Ftriggers%2Fmanual%2Frun", so you need to decode that and pass "/triggers/manual/run" to UriComponentsBuilder. And then it works.
My code:
RestTemplate restTemplate = new RestTemplate();
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
HttpEntity<Object> request = new HttpEntity<>(requestDto, headers);
UriComponentsBuilder builder = UriComponentsBuilder
.fromUriString("https://prod-123901.westeurope.logic.azure.com:443/workflows/<workflow_id>/triggers/manual/paths/invoke")
.queryParam("api-version", "2016-10-01")
.queryParam("sp", "/triggers/manual/run")
.queryParam("sv", "1.0")
.queryParam("sig", "<your_sig>");
restTemplate.exchange(builder.build().toUri().toString(), HttpMethod.POST, request, Void.class);
update:
requestDto here is your custom dto object that goes in HTTP Body, like for example object of class:
public class RequestDto {
private String id;
private String name;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
Please try with the simple standalone code with RestTemplate and check. I provide below small snippet.
try {
ResponseEntity<ResponseVO> response = restTemplate.exchange({uri of azure logic app trigger}, HttpMethod.GET, request, ResponseVO.class);
} catch (HttpStatusCodeException ex) {
int statusCode = ex.getStatusCode().value();
System.out.println("Status Code :"+statusCode);
ResponseEntity<?> resEntity = ResponseEntity.status(ex.getRawStatusCode()).headers(ex.getResponseHeaders())
.body(ex.getResponseBodyAsString())
}
Here ResponseVO.class is the Response to be mapped to an object, in this case, you can set your own class. In this catch block, you can find the exception details.
I"m given a requirement on how to test HTTP website without UI. Let says, we have a google website search functionalities (Not Web Services) and I need to test it. How to start? Can anyone give some example (JUnit)(Get/Post Method) for me to start this project. I tried reading the official documentation but found nothing about it. Thanks in advance.
You can do it with the following snippet
public class Searcher {
public String search(String searchUrl, String searchWord) throws IOException, URISyntaxException {
try (CloseableHttpClient httpClient = HttpClients.createDefault()) {
URIBuilder builder = new URIBuilder(searchUrl);
builder.setParameter("search_term", searchWord);
HttpGet request = new HttpGet(builder.build());
HttpResponse httpResponse = httpClient.execute(request);
return convertResponseToString(httpResponse);
}
}
private String convertResponseToString(HttpResponse response) throws IOException {
try (Scanner scanner = new Scanner(response.getEntity().getContent(), "UTF-8")) {
String responseString = scanner.useDelimiter("\\Z").next();
return responseString;
}
}
}
public class SearcherTest {
#Rule
public WireMockRule wireMockRule = new WireMockRule(options().dynamicPort());
#Test
public void searchTest() throws IOException, URISyntaxException {
String searchWord = "something";
String expectedResult = "Your expected result";
stubFor(get(urlPathEqualTo("/search"))
.withQueryParam("search_term", equalTo(searchWord))
.willReturn(aResponse()
.withBody(expectedResult)));
Searcher searcher = new Searcher();
String searchResult = searcher.search("http://localhost:" + wireMockRule.port() + "/search", searchWord);
verify(getRequestedFor(urlPathEqualTo("/search"))
.withQueryParam("search_term", equalTo(searchWord)));
assertEquals(expectedResult, searchResult);
}
}
//Back end
#Path("/travelgood")
public class TravelgoodResource {
#POST
#Path("/{bookingNo}/{name}/{number}/{expMonth}/{expYear}")
public boolean bookingFlight(#PathParam("bookingNo") String bookingNo, #PathParam("name") String name, #PathParam("number") String number, #PathParam("expMonth") String expMonth, #PathParam("expYear") String expYear) {
ws.tg.BookType booking = new ws.tg.BookType();
booking.setBookingnumber(Integer.parseInt(bookingNo));
CreditCardInfoType cci = new CreditCardInfoType();
cci.setName(name);
cci.setNumber(number);
CreditCardInfoType.ExpirationDate ed = new CreditCardInfoType.ExpirationDate();
ed.setYear(Integer.parseInt(expYear));
ed.setMonth(Integer.parseInt(expMonth));
cci.setExpirationDate(ed);
booking.setCreditcardinformation(cci);
boolean myBooking = false;
try {
myBooking = bookFlight(booking);
} catch (BookFault ex) {
Logger.getLogger(TravelgoodResource.class.getName()).log(Level.SEVERE, null, ex);
}
return myBooking;
}
private static boolean bookFlight(ws.tg.BookType input2) throws BookFault {
ws.tg.Lameduck2Service service = new ws.tg.Lameduck2Service();
ws.tg.Lameduck2PortType port = service.getLameduck2PortTypeBindingPort();
return port.bookFlight(input2);
}
}
//TEST CLASS (Client)
public class TravelGoodRESTTest {
Client client = Client.create();
#Test
public void TestbookFlight() {
WebResource r = client.resource("htttp://localhost:8080/tg/webresources/travelgood/1/Donovan%20Jasper/50408818/6/9");
System.out.println("testBookFlight: "+r.post(String.class));
}
}
When running a Unit test it gives me the following error:
Caused an ERROR: POST htttp://localhost/8080/tg/webresources/travelgood/1/Donovan%20Jasper/50408818/6/9 returned a response status of 500 internal server error