I'm new to rest webservice and have a novice q'. I've created a rest class and would like to use helper classes to handle certain operations. So for example I've created the following service:
import statements...
#Path("/UserResources")
public class UserResource {
//Create Spring application context
static ClassPathXmlApplicationContext ctx = new
ClassPathXmlApplicationContext("classpath:/spring.xml");
private UserResourceHelper urh = new UserResourceHelper(); // this is the helper
class UserProfileService userProfileService = ctx.getBean(UserProfileService.class);
#POST
#Path("/createUser")
#Consumes(MediaType.APPLICATION_JSON)
public Response createUser(#Context HttpServletRequest request, Object object) {
StringBuffer sb = new StringBuffer();
User user = userProfileService.findByPrimaryKey(object);
sb.append(urh.createUser(object));
return
Response.status(Status.CREATED.getStatusCode()).entity(result.toString()).build(); } }
I have a couple of questions on this approach:
Is this the correct way to instantiate the helper class? Or should I create a constructor and instantiate the class there? for example:
public UserResource (){
urh = new UserResourceHelper();
}
On this approach will there always be a new instance of the UserResourceHelper?
If so that would mean there will not be an issue on concurrency correct? ie. 2 requests coming in at the same time and the 1st object being received by the createUser method would suddenly get replaced by the 2nd object that suddenly came in?
I'm using Hibernate for ORM. Is the way i've instantiated the entities as per my code sample correct?
Thanks for your assistance!
On this approach will there always be a new instance of the UserResourceHelper?
yes. It always creates new instance
Suggestion:
If you want to create a new service for every request, you can make this as a service instead of a helper class and you can autowire the service in the controller.
#Service
public class UserResourceService {
}
and in the controller
public class someController {
#Autowired
private UserResourceService userResourceService;
}
You can use #Autowire annotation in spring boot, it will automatically create instance of class
#Autowire
UserResourceHelper userResourceHelper;
Related
I'm writing a Spring cloud contract into an existing project. When I hit the end point it works fine, but I'm facing issue to set up the messaging side for the producer.
In my controller, I've the following piece of code
{
StudentInfo studentInfo = new StudentInfo();
studentInfo.setProfileId(studId);
studentInfo.setClassDetails(studentService.getClassDetailsInfo(studId));
studentInfo.setMarksInfo(studentService.getMarksInfo(studId));
return employerInfo; }
}
This is an existing end point code in a controller which I cannot change.
Since there are two service calls being called in the method, I'm not able to understand how can I write a producer method which will mock both services response and construct a JSON.
Here is my producer code
StudentInfo mockStudentsResponse = JUnitTestUtil
.toObject(JUnitTestUtil.getFile("studentInfo.json"), StudentInfo .class); // This student info has two class objects inside it 1. ClassDetails and 2.MarksInfo
//How can I mock the response and to which service class
Any ideas would be greatly appreciated.
You should mock out the services inside your controller. When I say service then I mean an application service. Your controller should have application services mocked. That way you send a request to the controller, then the processing of that request ends in the controller. It doesn't go down to any other layers, not to mention get called in other apps.
Example
#RestController
class MyController {
private final Service1 service1;
private final Service2 service2;
#GetMapping("/bla")
String bla() {
String a = service1.a();
String b = service2.b(a);
return a + b;
}
}
Then in the base class you do
class MyBaseClass {
Service1 service1 = Mockito.mock(Service1.class);
Service2 service2 = Mockito.mock(Service2.class);
#BeforeEach
void setup() {
Mockito.when(service1.a()).thenReturn("foo");
Mockito.when(service2.b()).thenReturn("bar");
RestAssuredMockMvc.standaloneSetup(new MyController(service1, service2));
}
}
I have an Spring Rest application, in which there's a requirement to get some access token in a service(Annotated with #Service) class. The token generation is in a separate class(Annotated with #Component) and the requirement given is to get a unique token for each new request. And I'll be using the generated token two times within the same request in the service class. Now the questions are as follows.
I can inject the tokenGenerator class using #Autowired. And get the token, store it in the private instance variable inside the class and use it wherever I wanted inside the service class. Is it the correct approach to store a value that should live as long as the request is alive. When I tested this approach I find the same access token is printed across the methods in service class for a single request. what would go wrong here?
Another approach I tried was using WebApplicationContext.SCOPE_REQUEST on the TokenGenerator class and use the Provider in my service class to get the class instance and then access token from it. This also works the same way as the previous approach. If so why do I even need to use the approach for request scoped values?
Approach 1:
Here I have used the dependency injection to get the access token.
#Component
public class TokenGenerator
{
public string getToken();//okhttp Rest API Call
}
#Service
public class ServiceClass{
#Autowired
TokenGenetor token;
private String tokenValue;//**setTokenValue as setter**
public void method1()
{
setTokenValue(token.getToken());
}
public method2(){print(tokenValue)}// prints 1234abcd
public method3(){print(tokenValue)}// prints 1234abcd
}
Approach 2:
Here I have used the RequestScope to get the access token. and Used the Provider to get the instance in the service class.
#Component
#scope(WebApplicationContext=scope_request)
public class TokenGenerator
{
public string getToken();//okhttp Rest API Call
}
#Service
public class ServiceClass{
#Autowired
private Provider<TokenGenetor> token;
private String tokenValue;//setTokenValue as setter
public void method1()
{
// Not Setting anything
}
public method2(){print(token.get().getToken();)}// prints 1234abcd
public method3(){print(token.get().getToken();)}// prints 1234abcd
}
I have been refactoring a huge method in the project I work and came up with this idea to create a validation service like this -
public class TrickyValidation {
String validationVariable1;
String validationVariable2;
String validationVariable3;
HashMap<String, Object> itemsMap;
Object dependentObject;
#Autowired
SpringService service;
public static boolean doTrickyValidation(HashMap<String, Object> itemsMap, Object dependentObject) {
return new TrickyValidation(itemsMap, dependentObject).validate();
}
private TrickyValidation(Object itemsMap, Object dependentObject) {
this.itemsMap = itemsMap;
this.someDependentObject = dependentObject;
init();
}
private boolean validate() {
// loads of logic for validation by using validationVaribales
return true;
}
private void init() {
// Some methods to extract thease variables from itemsMap, dependentObject etc..
this.validationVariable1 = service.get(dependentObject);
this.validationVariable1 = ...;
this.validationVariable1 = ...;
}
}
My goal what I want to do here is to Encapsulate everything as much as possible and use clean code principles.
I feel a bit here like fighting spring framework because I don't want
that "TrickyValidation" class would be #Servcie and belong to spring container. Will Autowired even work here?
Is it a good design? Most likely I will use this validation in a loop. I like this solution because when I have to validate things I just simply call one and only public static method of this class TrickyValidation.doTrickyValidation(map, obj)
Any suggestions are welcome on how to improve this, or why it's a bad idea.
This code probably won't work because in the init method of the object you're trying to access service which is not autowired into this instance. In general the autowiring works only for objects managed (created by) Spring.
In this case you create "manually" the object of class TrickyValidation...
IMO the better design is to split the "Validator" object that can be Spring managed and the Validation itself that is not spring based.
#Component
public class Validator {
#Autowired
private Service service;
public boolean doTrickyValidation(HashMap<String, Object> itemsMap, Object dependentObject) {
// resolve the validation strategy from the items passed to this method.
TrickyValidation validation = resolveTrickyValidation(itemsPam, dependentObject);
return validation.validate();
}
private TrickyValidation resolveTrickyValidation(...) {
// construct the proper validation strategy
// access service if you want
}
}
I'm relativly new to spring/spring boot.
At the moment I'm using a spring boot rest application which provides an FeignClient to be included in other projects. Now, I want those FeignClients be wrapped by a CircuitBreaker.
The best solution I came up with, is that I dynamically create a proxy which includes the CircuitBreaker implementation which itself calls the created FeignClient.
So let's assume I have the following interface which describes the RestController:
#RequestMapping("/")
public interface MyWebService {
#GetMapping("name")
public String getName();
}
Now, I have the interface for the FeignClient:
#FeignClient("app")
public interface WebServiceClient extends WebService {
}
So.. My goal would be to achieve something like I have another annotation e. g. #WithCircuitBreaker which I then will be scanned for and dynamically create a proxy bean which will be injected instead of the FeignClient bean.
At the moment my code looks like this:
#FeignClient("app")
#WithCircuitBreaker
public interface WebServiceClient extends WebService {
}
As far as I know, I can now create a #Configuration Class which will look like this:
#Configuration
public class WithCircuitBreakerConfiguration implements ImportAware {
private AnnotationMetadata annotationMetadata;
private AnnotationAttributes annotationAttributes;
#Override
public void setImportMetadata(AnnotationMetadata importMetadata) {
this.annotationMetadata = importMetadata;
Map<String, Object> annotatedClasses = importMetadata.getAnnotationAttributes(WithCircuitBreaker.class.getName());
this.annotationAttributes = AnnotationAttributes.fromMap(annotatedClasses);
}
What else to import to create the proxy and inject it?
}
Now I'm at the point, which I don't know how to continue. How to dynamically create a proxy class which does something like this:
public class PorxyedWebService {
private WebService feignClientProxy;
#Autowired
public ProxyedWebService(WebService feignClientProxy) {
this.feignClientProxy = feignClientProxy;
}
public String getName() {
...
<some circuitbreaker stuff>
....
return this.feignClientProxy.getName();
}
}
and then return this proxy instead of the proxy generated from Feign as soon as someone autowires the WebService interface.
I am not a Spring user, but I do know that Spring does not create proxies recursively if e.g. multiple Spring AOP aspects are applied to the same object. Instead, additional interceptors (or advices in AOP language) are registered upon the same proxy. I think you want to use that infrastructure in order to achieve whatever your objective is.
You can just use the resilience4j Spring Boot2 starter.
You can combine the #CircuitBreaker annotation with the #FeignClient annotation at interface level.
You can then use it as follows:
#FeignClient(name = DUMMY_FEIGN_CLIENT_NAME)
#CircuitBreaker(name = DUMMY_FEIGN_CLIENT_NAME)
public interface DummyFeignClient {
String DUMMY_FEIGN_CLIENT_NAME = "dummyFeignClient";
#GetMapping(path = "/api/{param}")
void doSomething(#PathVariable(name = "param") String param);
}
I'm using Spring boot with jetty embedded web server for one Web application.
I want to be 100% sure that the repo class is thread safety.
The repo class
#Repository
#Scope("prototype")
public class RegistrationGroupRepositoryImpl implements RegistrationGroupRepository {
private RegistrationGroup rg = null;
Integer sLastregistrationTypeID = 0;
private UserAccountRegistration uar = null;
private List<RegistrationGroup> registrationGroup = new ArrayList<>();
private NamedParameterJdbcTemplate jdbcTemplate;
#Autowired
public RegistrationGroupRepositoryImpl(DataSource dataSource) {
this.jdbcTemplate = new NamedParameterJdbcTemplate(dataSource);
}
public List<RegistrationGroup> getRegistrationGroups(Integer regId) {
// Some logic here which is stored in stored in the instance variables and registrationGroup is returned from the method
return this.registrationGroup;
}
And the Service class which invoke the getRegistrationGroups method from the repo.
#Service
public class RegistrationService {
#Autowired
private Provider<RegistrationGroupRepository> registrationGroupRepository;
public List<RegistrationGroup> getRegistrationGroup() {
return registrationGroupRepository.getRegistrationGroups(1);
}
}
Can I have race condition situation if two or more request execute the getRegistrationGroups(1) method?
I guess I'm on the safety side because I'm using Method injection (Provider) with prototype bean, and every time I'm getting new instance from the invocation?
First of all, making your Bean a prototype Bean doesn't ensure an instance is created for every method invocation (or every usage, whatever).
In your case you're okay on that point, thanks to the Provider usage.
I noticed however that you're accessing the getRegistrationGroups directly.
return registrationGroupRepository.getRegistrationGroups(1);
How can this code compile? You should call get() on the Provider instance.
return registrationGroupRepository.get().getRegistrationGroups(1);
Answering your question, you should be good to go with this code. I don't like the fact that you're maintaining some sort of state inside RegistrationGroupRepositoryImpl, but that's your choice.
I always prefer having all my fields as final. If one of them requires me to remove the final modifier, there is something wrong with the design.