How to access endpoints in a controller in Spring? - java

I have a controller class this way with endpoints. I know that we can access RESTful endpoints in a web application through a tool like 'postman' using the URL. But I am not sure how to access these endpoints. This is not a web application.
This is a java application deployed as a JAR on server using embedded tomcat.
How can I access these endpoints?
#Controller
public class TopicStatsController {
#Autowired
private QueueDepths depths;
#RequestMapping("/topicDepth")
#ResponseBody
public Long topicDepth() throws Exception {
return depths.topicDepth();
}
#RequestMapping("/subscribersDepth")
#ResponseBody
public List<Long> subscribersDepth() throws Exception {
return depths.subscribersDepth();
}
}

You can access the endpoints using RestTemplate.
RestTemplate restTemplate = new RestTemplate();
String fooResourceUrl
= "/topicDepth";
ResponseEntity<String> response
= restTemplate.getForEntity(fooResourceUrl + "/1", Long.class);

Your remote must be having an IP address and a port number.
You can use it to hit a GET or POST request.
On localhost - http://localhost:8080/myapp-oracle/api/v1/user
On remote - http://172.16.254.1:8080/myapp-oracle/api/v1/user
Note: You also need to change the http protocol depending upon the server.

Related

How do I write an integration test for a REST API secured with OAuth2 in JUnit5?

I have a client service like this,
#Service
public class PersonClientService {
private final String EXTERNAL_API;
private RestTemplate restTemplate;
#Autowired
public PersonClientService(RestTemplate restTemplate, #Value("${person.url}") String apiUrl) {
this.restTemplate = restTemplate;
EXTERNAL_API = apiUrl
}
public ResponseDTO createData(PersonDTO personDTO) throws Exception {
try {
HttpEntity<PersonDTO> input = new HttpEntity<>(personDTO);
ResponseEntity<ResponseDTO> restponseDTO = restTemplate.exchange(EXTERNAL_API, HttpMethod.POST, input, ResponseDTO.class);
return responseDTO.getBody();
} catch(Exception e) {
//catch exception
}
}
}
Now the rest template here that I am using is secured with OAuth2 implementation and it is using client_id and secret with grant_type as client_credentials to generate a token and then using this token as header to call the EXTERNAL_API
I am following this guide here but it's not really helpful since it is using JUnit4 and I am on JUnit5: https://www.baeldung.com/oauth-api-testing-with-spring-mvc
I'm confused. What do you want to test?
The sample you link is achieving controller unit-testing with mockmvc.
They use an annotation which loads security context. As a consequence test security context must be configured for the request to reach controller endpoint.
I don't see any security rules on your service (#PreAuthorize or something) => you don't need any security context, just don't load security config.
If you add security rules you want to unit test, load security config and setup test security context (either explicitly or with something like https://github.com/ch4mpy/spring-addons/tree/master/samples/webmvc-jwtauthenticationtoken/src/test/java/com/c4_soft/springaddons/samples/webmvc_jwtauthenticationtoken)
The call to external service is a complete different story: the external service is running with a different security context than the one attached to your tested service thread). Either:
#MockBean RestTemplate (and configure mock for the Rest call your service is issuing) => unit test
ensure test configuration for RestTemplate and external service points to the same started authorization server, load rest template config, auto wire RestTemplate as normal and let it issue request for real to actual external service (which must be started too) => integration test.
You should not start with integration test. Unit test are for more stable and easier to maintain.

How do I connect REST services (inside containers) together, in Spring Boot?

I'm supposed to build a system with individual REST services using docker compose. One of them is a web app where a user can login, and one of them is an authentication service, so I need to connect to the rest authentication service using a post request, and get the confirmation.
This is my authentication service:
#RestController
public class AuthenticationController {
private final List<User> users=GetUsers();
#PostMapping ("/verify")
public String greeting(#RequestParam String username, #RequestParam String password) {
for (User u :users)
if (u.getUsername().equals(username)&&u.getPassword().equals(password))
return u.getRole();
return "Invalid Credentials ";
}
}
So, how exactly do I connect from inside the web app code into this service and send a post request?
I know I can send a get using this:
String uri = "http://localhost:8080/verify";
RestTemplate restTemplate = new RestTemplate();
String result = restTemplate.getForObject(uri, String.class);
How would I send a post? And how would it work inside containers? I know I can link them together inside docker compose, but how do I do it on the code level? Do I replace the localhost:8080 with containerName:exposedPort?
As you know, Docker containers are individual Linux virtual machines which means localhost inside a Docker container refers to the container itself, not the host.
Docker compose has a feature called DNS resolutions which basically means you can call other services by their container name or container hash id.
So in your web app, you can call API by containerName:containerPort instead of localhost.
For more information, look at this complete implementation.

How to configure spring boot back end to accept request only from amazon API Gateway?

I have a spring boot app deployed on Elastic Beanstalk accessible through API Gateway, I have enabled client side SSL certificate authentication. But I am confused on how my backend will authenticate with the public key I have ? I just have the public key to authenticate the request. Will help if there is a code snippet.
Assume this is my Controller, How can I verify the request using public key when a request hits this API.
#RestController
public class TestController {
#RequestMapping(path = "/test")
public String get() {
return "Hello";
}
}

POST method in Spring Boot REST service (external Tomcat) return 404 error

I created a REST web service using Spring Boot.
The project is configured to use an external Tomcat.
When using Tomcat 8 it connects successfully and get good responses when i call my GET methods.
However, the POST methods return 404 errors.
#RestController
#RequestMapping("/hashkey")
#EnableAutoConfiguration
public class StringHashingController {
#RequestMapping(method=RequestMethod.POST, consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
public #ResponseBody HashedStringsList hashMe(#RequestParam(value="caller", required=true) String callerId, #RequestBody StringHashingRequestBodyParams hashParam) {
HashedStringsList pList = new HashedStringsList();
//...
return pList;
}
}
I have no problem calling the same post method locally in the IDE (Intellij) through running 'Spring Boot Configuration'.
Is there anything I need to configure in Tomcat or in my code?
Thanks!

spring RESTful service work fine, but throws an exception

I am creating a spring RESTful service, and it is working. My client send an object into a put request and my service receive this object perfectly, but after this, my client receive this exception: "org.springframework.web.client.HttpClientErrorException: 404 Not Found"
This is my client code:
RestTemplate restTemplate = new RestTemplate();
restTemplate.getMessageConverters().add(new MappingJackson2HttpMessageConverter());
Greeting greeting = new Greeting(21l, FileUtils.toByteArray("src/main/resources/test.png"));
String url = "http://localhost:8080/DolphinRestServer/bulletin/put";
restTemplate.put(url,greeting);
And this is my server code:
#Service
#RequestMapping("/bulletin")
public class BulletinService {
#RequestMapping(method = RequestMethod.PUT, value = "/put")
public void put(#RequestBody Greeting greeting){
System.out.println("it's work fine and my greeting is here --------->"+greeting);
}
}
When tested, i get those messages:
-server side:
-Client side:
Your put method has a void return type. Additionally, it does not take the HttpServletResponse as a parameter. According to the Spring MVC documentation, when such a situation arises, Spring MVC uses the URL as the view name and attempts to render it. In your case, Spring MVC is attempting to find and load a view called /bulletin/put, which it can't find and hence the 404 message.
As you can see it is making another request at 20:40:34:085 DolphinRestServer/bulletin/bulletin/put in the server side giving an error page not found.
And it is because you are calling BulletinService twice.
You defined as a bean and it has an annotation. Make sure you are only loading/scanning this package once..
Remove #service annotation on BulletinService

Categories