how to request data from our spring boot micro-service to external server for a given id's? - spring-boot

Currently I have created 2 microservices and and getting the data from one service to another using RestTemplate.
Microservice -1:
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import java.util.ArrayList;
import java.util.List;
#RestController
public class StringDataController {
List<String> stringList = new ArrayList<>();
#RequestMapping(value = "/securities/list", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
public List<String> sendStringData(){
stringList.add("12345");
stringList.add("23435");
stringList.add("23436");
return stringList;
}
}
Microservice-2:
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
import java.util.List;
#RestController
#EnableAutoConfiguration
public class ExternalRequestController {
#Value ("${sampleMS1.uri}")
String sampleMS1URI;
#RequestMapping(value="/listdata", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
public void receiveStringFromAnotherMS(){
List<String> list = null;
list = new RestTemplate().getForObject(sampleMS1URI,List.class);
System.out.println(list.toString());
System.out.println("-->"+list);
}
}
Now, I have to send the List(String)(list of ID's) data to some external server and response should get Map(K,V) ==> key as a String and Value as a Double.
Note: The external server is not handling by us, so we can only request the data with List of id's and then they should sending the response with price data of specific id's.
Can anyone suggest me a way to do it ?
I am new to Spring & Spring boot.
Thank you!

Related

RestAssured, H2, SpringBootTest Transaction Management. Persisted data not available when calling REST Interface

I wrote a simple SpringBootTest where I tried to read test data from a JSON file and insert it into the database in the #BeforeEach annotated method. When querying the data in the test method, I indeed find the data in the repository. When the REST interface is called via RestAssured and the corresponding method is executed, no data is found via the respository. However, when setting rollback=false in the test, I can find the data in the H2 database. Test code as follows:
package mypackage;
import static io.restassured.RestAssured.get;
import static org.hamcrest.Matchers.hasItems;
import static org.mockito.ArgumentMatchers.eq;
import java.io.IOException;
import java.net.URISyntaxException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.List;
import java.util.Objects;
import mypackage.MessageEntity;
import mypackage.MessageRepo;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import io.restassured.RestAssured;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.web.server.LocalServerPort;
import org.springframework.test.annotation.Rollback;
import org.springframework.test.context.ActiveProfiles;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.support.TransactionCallback;
import org.springframework.transaction.support.TransactionTemplate;
#EnableAutoConfiguration
#SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, properties = { "spring.main.lazy-initialization=true",
"spring.datasource.url=jdbc:h2:file:C:/mydatabase", "spring.jpa.properties.hibernate.default_schema=",
"spring.jpa.hibernate.ddl-auto=create", "spring.datasource.driverClassName=org.h2.Driver",
"spring.jpa.properties.hibernate.show_sql=true", "spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.H2Dialect",
"spring.datasource.username=sa" })
#ActiveProfiles("test")
class MyWebServiceTest{
#Autowired
MessageRepo messageRepo;
#LocalServerPort
int port;
#Autowired
private PlatformTransactionManager platformTransactionManager;
#BeforeEach
void beforeAll() throws IOException, URISyntaxException {
RestAssured.baseURI = "http://localhost/webservice";
RestAssured.port = port;
TransactionTemplate transactionTemplate = new TransactionTemplate(this.platformTransactionManager);
final List<MessageEntity> messages = setupMessages();
transactionTemplate.execute((TransactionCallback<Object>) status -> messageRepo.saveAllAndFlush(messages));
}
#Test
#Transactional
#Rollback(false)
void test() {
System.out.println(messageRepo.findAll()); // successfully retrieves data
get("/messages").then().assertThat().body("$", hasItems(67)).and().statusCode(eq(200)); // in the corresponding method of the WebService, no data is found
}
private List<MessageEntity> setupMessages() throws IOException, URISyntaxException {
final String messagesString = Files.readString(
Paths.get(Objects.requireNonNull(MyWebServiceTest.class.getResource("/messages.json")).toURI()));
return new ObjectMapper().readValue(messagesString, new TypeReference<List<MessageEntity>>() {
});
}
}
I tried to persist the data in the #BeforeEach in different ways, tried flushing etc, but the data is not available when doing messageRepo.findAll() in the method called in the REST-Interface. I would expect the inserted data to be also available there. However, the data is available in the test method, but not at the REST endpoint.
Do you have any idea why this is happening and what I can try to get the desired result with my test data? Thanks!

Spring not picking up RestController endpoint

I have my spring project setup as shown below, but I am getting a 404 on the /custom endpoint. All answers I've found similar to this problem highlighted that the controller layer needs to be in a package below the project layer however I have it set out like this so I'm unsure why Spring isn't recognising the endpoint.
package com.myproject.controller;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
#RestController
#RequestMapping("custom")
public class CustomPathController {
#GetMapping
public ResponseEntity<Void> test() {
return new ResponseEntity<>(HttpStatus.OK);
}
}
package com.myproject;
import com.ryantenney.metrics.spring.config.annotation.EnableMetrics;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.transaction.annotation.EnableTransactionManagement;
#EnableMetrics
#EnableJpaRepositories
#SpringBootApplication
public class MyProject {
public static void main(String[] args) {
SpringApplication.run(MyProject.class, args);
}
}
There must have been a port clash as a PC restart has fixed the issue

Restful Response Showing \n Instead of New Line

I am trying to generate a TEXT/PLAIN response for my Spring application.
When I am debugging the code, I see the string nicely formatted:
LINE1
LINE2
...
But when I see the response in Postman I see that the output is all messed up like
LINE1\nLIINE2\n....
I am not sure if the set up the controller properly or not!
Here is my Controller class:
import java.io.StringReader;
import java.util.concurrent.atomic.AtomicLong;
import java.util.logging.Logger;
import javax.ws.rs.Consumes;
import javax.ws.rs.Produces;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Unmarshaller;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
#RestController
#Configuration
#EnableAutoConfiguration
public class ConfigGeneratorController {
private final AtomicLong counter = new AtomicLong();
Logger logger = null;
#RequestMapping(value = "/configGenerator", method = {RequestMethod.POST})
#Consumes({MediaType.APPLICATION_XML_VALUE,MediaType.APPLICATION_JSON_VALUE})
#Produces({MediaType.TEXT_PLAIN_VALUE})
public ConfigGenerator configGenerator(#RequestBody String xml) {
logger = Logger.getLogger(ConfigGeneratorController.class.getName());
.
.
.
bunch of code
.
.
.
return new ConfigGenerator(counter.incrementAndGet(), String.format(actionMonitor.getGeneratedConfig().replaceAll("^\t+", "")));
}
}
actionMonitor.getGeneratedConfig() is the method that returns the string.

REST API call: Missing URI template variable 'productoId' for method parameter of type Long

Im trying to do a query in Spring boot to database (http://localhost:8180/products/2) and the server responds with:
This application has no explicit mapping for /error, so you are seeing this as a fallback.
Thu Oct 26 01:29:12 COT 2017 There was an unexpected error
(type=Internal Server Error, status=500). Missing URI template
variable 'productoId' for method parameter of type Long
This the interface
package com.beitech.orders.repository;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import com.beitech.orders.model.Product;
public interface ProductJpaRepository extends JpaRepository<Product, Long> {
Product findByProductoId(Long productoId);
#Query(value = "SELECT * FROM PRODUCT WHERE PRODUCTO_ID = ?1", nativeQuery = true)
Product findByproductoId3(Long productoId);
}
This is the controller:
package com.beitech.orders.controller;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.beitech.orders.model.Product;
import com.beitech.orders.repository.ProductJpaRepository;
#RestController
#RequestMapping("/products")
public class ProductController {
#Autowired
private ProductJpaRepository productJpaRepository;
#GetMapping(value = "/allProducts")
public List<Product> findAll(){
return productJpaRepository.findAll();
}
#GetMapping(value = "/{productId}")
public Product findByProductoId(#PathVariable final Long productoId){
return productJpaRepository.findByProductoId(productoId);
}
}
You defined
#GetMapping(value = "/{productId}")
#PathVariable final Long productoId){
There is a mismatch there between productId and productoId. If you want productId to be bound to Long productoId then you would have to declare #PathVariable(name="productId") or alternatively just rename productoId to productId or vice versa.

Post url seems not been called with spring security

My issue is that, when I call the url http://localhost:8080/site/data/gouv/ with postman with corresponding form data parameters, nothing happens. It seems even the call is not catched by the controller because there is no log.
Postman page
Here is the controller :
package com.mintad.spring.controllers;
import java.io.BufferedInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import com.site.common.beans.Gouv;
import com.site.common.service.GouvService;
import au.com.bytecode.opencsv.CSVReader;
#RestController
#RequestMapping("/data")
public class DataController {
#Autowired
private GouvService gouvService;
#RequestMapping(value = "/gouvernorate", method = RequestMethod.POST)
public ResponseEntity<Gouv> addGouvernorate(#RequestBody Gouv gouv) throws IOException {
gouvService.addGouv(gouv);
return new ResponseEntity<Gouv>(gouv, HttpStatus.OK);
}
}
I've tried to call the url with Jsoup as follows :
String base64login = new String(Base64.encode("sof:1".getBytes()));
Document docs = Jsoup.connect("http://localhost:8080/site/data/gouv/").header("Authorization", "Basic " + base64login).
data("name", "name").
data("delegation", "delegation").
data("district", "district").
data("postalCode", "postalCode").post();
But in vain.
Any help please ? I'm using spring security 4.0.4.RELEASE and Spring 4.2.5.RELEASE

Resources