Spring-Hateoas: exception in creating a new link - spring

Overview:
I am going to add a new link based on Spring-Hateoas-Doc to the JSON response by using the following command:
linkTo(methodOn(ProductRepository.class).findOne(10L)).withRel("product");
Problem:
However I got the following exception:
java.lang.IllegalArgumentException: 'uriTemplate' must not be null
So I would be grateful if anyone could suggest me a genuine solution.

I found the issue. As I my processor class is not a rest controller, this issue has been raised.
To solve it , I used the entityLinks instead, as follows:
#Controller
public class StockMovementsProcessor implements ResourceProcessor<Resource<StockMovementsProjection>> {
#Autowired
private EntityLinks entityLinks;
#Override
public Resource<StockMovementsProjection> process(Resource<StockMovementsProjection> stockMovementsProjectionResource) {
StockMovementsProjection stockMovementsProjection = stockMovementsProjectionResource.getContent();
stockMovementsProjectionResource.add(entityLinks.linkFor(Product.class).slash(10L).withRel("product"));
return stockMovementsProjectionResource;
}
}
And it created the following link for me:
http://localhost/products/10

if you are using hateos version 0.20.0 then try upgrading it to 23 using below maven dependency
<dependency>
<groupId>org.springframework.hateoas</groupId>
<artifactId>spring-hateoas</artifactId>
<version>0.23.0.RELEASE</version>
</dependency>

Related

Spring boot Issue IllegalArgumentException when using Order By in Repository

im having an annoying issue where I cant seem to find a solution for.
Im currently implementing a way to read only the top 500 Entries ordered by Date. If I dont enter the Order By, Spring boot delivers the top 500 which is fine, but as soon as I include the Order By Option I get this Error:
Caused by: java.lang.IllegalArgumentException: Failed to create query for method public abstract java.util.List com.sma.db.repositories.LogRepository.findTop500ByOrderBylogsLogTimeDesc()! No property orderBylogsLogTimeDesc found for type LogEntity!
at org.springframework.data.jpa.repository.query.PartTreeJpaQuery.<init>(PartTreeJpaQuery.java:96) ~[spring-data-jpa-2.3.5.RELEASE.jar:2.3.5.RELEASE]
As it seems, Spring boot includes the Order by and and looks for a property named orderbylogsLogTimeDesc . What I also dont understand is, why order is written in lower cases.
Does anyone know a solution for this? It is really annoying and I cant seem to find a solution :(
Repository:
#Repository
public interface LogRepository extends JpaRepository<LogEntity, Long>{
// List<FeedEntity> deleteByfeedTimestamp(Date feed_timestamp);
List<LogEntity>findTop500ByOrderBylogsLogTimeDesc();
}
Entity:
#Column(name = "logs_logtime")
private Date logsLogTime;
public Date getLogsLogTime() {
return logsLogTime;
}
public void setLogsLogTime(Date logsLogTime) {
this.logsLogTime = logsLogTime;
}
Service:
#Service
public class LogService {
#Autowired
private LogRepository repo;
public List<LogEntity> getLogs() {
return repo.findTop500ByOrderBylogsLogTimeDesc();
}
Ive found the solution in the end: I had to write LogsLogTime instead of logsLogTime... . It works now :) Thanks!
Maybe you have to specify the field twice, have you tried:
List<LogEntity>findTop500ByLogsLogTimeOrderByLogsLogTimeDesc();
You guys gave me an idea. I actually found the Issue! When i typed LogsLogTime it worked as in:
findTop500ByOrderByLogsLogTimeDesc

Injection of bean inside ClientHeadersFactory doesn't work

I'm building a Quarkus app which handles http requests with resteasy and calls another api with restclient and I need to propagate a header and add another one on the fly so I added a class that implements ClientHeadersFactory.
Here's the code:
#ApplicationScoped
public abstract class MicroServicesHeaderHandler implements ClientHeadersFactory {
#Inject
MicroServicesConfig config;
#Override
public MultivaluedMap<String, String> update(MultivaluedMap<String, String> incomingHeaders,
MultivaluedMap<String, String> clientOutgoingHeaders) {
// Will be merged with outgoing headers
return new MultivaluedHashMap<>() {{
put("Authorization", Collections.singletonList("Bearer " + config.getServices().get(getServiceName()).getAccessToken()));
put("passport", Collections.singletonList(incomingHeaders.getFirst("passport")));
}};
}
protected abstract String getServiceName();
My issue is that the injection of the config doesn't work. I tried both with #Inject and #Context, as mentioned in the javadoc of ClientHeadersFactory. I also tried to make the class non abstract but it doesn't change anything.
MicroServicesConfig is a #Startup bean because it needs to be initialized before Quarkus.run() is called, otherwise the hot reload doesn't work anymore, since it's required to handle requests.
Here's the code FYI:
#Getter
#Startup
#ApplicationScoped
public final class MicroServicesConfig {
private final Map<String, MicroService> services;
MicroServicesConfig(AKV akv, ABS abs) {
// some code to retrieve an encrypted file from a secure storage, decrypt it and initialize the map out of it
}
It appears to be an issue with ClientHeadersFactory because if I inject my bean in my main class (#QuarkusMain), it works. I'm then able to assign the map to a public static map that I can then access from my HeaderHandler with Application.myPublicStaticMap but that's ugly so I would really prefer to avoid that.
I've searched online and saw several people having the same issue but according to this blogpost, or this one, it should work as of Quarkus 1.3 and MicroProfile 3.3 (RestClient 1.4) and I'm using Quarkus 1.5.2.
Even the example in the second link doesn't work for me with the injection of UriInfo so the issue doesn't come from the bean I'm trying to inject.
I've been struggling with this for weeks and I'd really like to get rid of my workaround now.
I'm probably just missing something but it's driving me crazy.
Thanks in advance for your help.
This issue has finally been solved in Quarkus 1.8.

SpringBoot log4j AppenderSkeleton The method append(LoggingEvent) must override or implement a supertype method

I'm trying to create a custom appender using log4j after looking at the given example -
Link:- How to create my own Appender in log4j?
I did as follows:-
import org.apache.log4j.AppenderSkeleton;
import org.apache.log4j.spi.LoggingEvent;
public class MyCustomAppender extends AppenderSkeleton
{
private MailServiceImpl mail = new MailServiceImpl();
#Override
public void close() {
}
#Override
public boolean requiresLayout() {
return false;
}
#Override
protected void append(LoggingEvent event) {
mail.sendMail(event.toString());
}
}
It gives me error because of the overridden methods - The method append(LoggingEvent) of type MyCustomAppender must override or implement a supertype method. I tried to search for solution but found none. And nobody seem to have faced the problem. Where am I going wrong? Please help me.
I believe you are looking for a solution for Log4j2 but the stackoverflow page you are linking to is over 3 years old ( might be an older version of Log4j )
Looking at javadoc of older version it does show AppenderSkeleton could be used to override the appender() method however you mention you get a compile error
The method append(LoggingEvent) of type MyCustomAppender must override
or implement a supertype method
This is because there is no such method to override in Log4j2
Please provide version of what Log4j you are using, meanwhile have a look at this answer incase you are using Log4j2

Testing Spring Boot rest controller, unable to locate package for is()

I'm writing a test for a REST controller in Spring Boot. Is uses is(), but my IDE is not suggesting what package this is in so I'm unable to find it.
Here's my test method;
#Test
public void printerIsReady() throws Exception {
/* Set the contents of status.txt to anything other than 3 */
String statusFilePath = printerPath + "/status.txt";
PrinterFileHelper.writeToFile("5", statusFilePath);
this.mockMvc.perform(get("/printer"))
.andExpect(status().isOk())
.andExpect(jsonPath("$.status", is("READY")));
}
I'm finding a lot of examples online that use the is() method, but it's not clear at all what package I need to be adding in order to access it.
I found the answer here How to check String in response body with mockMvc
The package you need to import is;
import static org.hamcrest.Matchers.*;
I needed to add the package to my pom.xml file
<dependency>
<groupId>org.testinfected.hamcrest-matchers</groupId>
<artifactId>core-matchers</artifactId>
<version>1.5</version>
</dependency>

spring hateoas linkTo method with withSelfRel() not working when spring controller method mapped with multiple path values

I am facing issue when Spring controller method having multiple path values while using Hateoas linkTo to get the links
Spring controller method is as follows
`
#RestController`enter code here`
#RequestMapping("/northwindmodel.svc")
#ExposesResourceFor(Category.class)
public class CategoryController {
#RequestMapping(value = **{"/Categories({categoryID})","/Categories(CategoryID={categoryID}"}**, method = RequestMethod.GET, headers = "Accept=application/json, application/xml", produces = { "application/json" })
public ResponseEntity<Result> read(#PathVariable(value ="categoryID")Integer categoryID) throws NoRecordFoundException{
Category category = this.getService().read(categoryID);
return new ResponseEntity<Result>(new Result(getAssembler().toResource(category) ),HttpStatus.OK);
}
}
`
Resource Assembler method for link
Link link = linkTo(methodOn(CategoryController.class).read(categoryID)).withSelfRel();
as controller read method has two paths as
1./Categories({categoryID})
2./Categories(CategoryID={categoryID}
I think linkTo method is unable to decide which path to pick and failing with error as
java.lang.IllegalStateException: Multiple method level mappings defined on method public org.springframework.http.ResponseEntity
can somebody please help me in this issue?
Thanks
-Trim
resolved this issue by upgrading hateoas lib to 0.20 from 0.16
<dependency>
<groupId>org.springframework.hateoas</groupId>
<artifactId>spring-hateoas</artifactId>
<version>0.20.0.RELEASE</version>
</dependency>

Resources