PHPFixing
  • Privacy Policy
  • TOS
  • Ask Question
  • Contact Us
  • Home
  • PHP
  • Programming
  • SQL Injection
  • Web3.0
Showing posts with label spring. Show all posts
Showing posts with label spring. Show all posts

Saturday, November 12, 2022

[FIXED] How do I tell Spring cache not to cache null value in @Cacheable annotation

 November 12, 2022     caching, memcached, spring     No comments   

Issue

Is there a way to specify that if the method returns null value, then don't cache the result in @Cacheable annotation for a method like this?

@Cacheable(value="defaultCache", key="#pk")
public Person findPerson(int pk) {
   return getSession.getPerson(pk);
}

Update: here is the JIRA issue submitted regarding caching null value last November, which hasn't resolved yet: [#SPR-8871] @Cachable condition should allow referencing return value - Spring Projects Issue Tracker


Solution

Hooray, as of Spring 3.2 the framework allows for this using Spring SPEL and unless. Note from the java doc surrounding Cacheable:

http://static.springsource.org/spring/docs/3.2.x/javadoc-api/org/springframework/cache/annotation/Cacheable.html

public abstract String unless

Spring Expression Language (SpEL) attribute used to veto method caching.

Unlike condition(), this expression is evaluated after the method has been called and can therefore refer to the result. Default is "", meaning that caching is never vetoed.

The important aspect is that unless is evaluated after the method has been called. This makes perfect sense because the method will never get executed if the key is already in the cache.

So in the above example you would simply annotate as follows (#result is available to test the return value of a method):

@Cacheable(value="defaultCache", key="#pk", unless="#result == null")
public Person findPerson(int pk) {
   return getSession.getPerson(pk);
}

I would imagine this condition arises from the use of pluggable cache implementations such as Ehcache which allows caching of nulls. Depending on your use case scenario this may or may not be desirable.



Answered By - TechTrip
Answer Checked By - David Goodson (PHPFixing Volunteer)
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg

Friday, November 4, 2022

[FIXED] How to replace null value of object into list without for expression

 November 04, 2022     collections, java, java-stream, lambda, spring     No comments   

Issue

How i can do this code with stream and lambda functions, in JAVA 8:

//Replace null values with "NO"
for (Product product:
             listProduct) {
            if(product.getIsBreakStock().equals(null)) product.setIsBreakStock("NO");
}

I try with replaceAll function tutorial and foreach(), but IDE throw me an error:

listProduct.forEach(p -> 
                p.getIsBreakStock().equals(null) ? p.setIsBreakStock("NO") : p);

Required type: void Provided: Product


Solution

maybe this will help

    listProduct.stream().filter(p -> p.getIsBreakStock() == null).peek(p ->  p.setIsBreakStock("NO") ).collect(Collectors.toList());


Answered By - iroli
Answer Checked By - Timothy Miller (PHPFixing Admin)
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg

Wednesday, November 2, 2022

[FIXED] How to read files from the sub folder of resource folder with using toURI

 November 02, 2022     file, java, spring, spring-boot     No comments   

Issue

How to read files from the sub folder of resource folder with using URI

    How to read files from the sub folder of resource folder.

I have some json file in resources folder like :

src 
    main
        resources 
            jsonData
                d1.json
                d2.json
                d3.json

Now I want to read this in my class which is

src 
    main
        java
            com
                myFile
                    classes 

here is what I am trying.

 File[] fileList = (new File(getClass().getResource("/jaonData").toURI())).listFiles();
    
            for (File file : listOfFiles) {
                if (file.isFile()) {
                   // my operation of Data.
                }
            }

my things are working fine but the problem what I am getting is i don't want to use toURI as it is getting failed.


Solution

You're probably not using Spring Boot, so how to read folder from the resolurces files in spring boot, : Getting error while running from Jar won't help you much.

I'll repeat myself from a comment to that question:

Everything inside a JAR file is not a file, and cannot be accessed using File, FileInputStream, etc. There are no official mechanisms to access directories in JAR files.

Fortunately, there is a non-official way, and that uses the fact that you can open a JAR file as a separate file system.

Here's a way that works both with file-based file systems and resources in a JAR file:

private void process() throws IOException {
    Path classBase = getClassBase();
    if (Files.isDirectory(classBase)) {
        process(classBase);
    } else {
        // classBase is the JAR file; open it as a file system
        try (FileSystem fs = FileSystems.newFileSystem(classBase, getClass().getClassLoader())) {
            Path root = fs.getPath("/");
            return loadFromBasePath(root);
        }
    }
} 

private Path getClassBase() {
    ProtectionDomain protectionDomain = getClass().getProtectionDomain();
    CodeSource codeSource = protectionDomain.getCodeSource();
    URL location = codeSource.getLocation();
    try {
        return Paths.get(location.toURI());
    } catch (URISyntaxException e) {
        throw new IllegalStateException(e);
    }
}

private void processRoot(Path root) throws IOException {
    // use root as if it's either the root of the JAR, or target/classes
    // for instance
    Path jsonData = root.resolve("jsonData");
    // Use Files.walk or Files.newDirectoryStream(jsonData)
}

If you don't like using ProtectionDomain, you can use another little trick, that makes use of the fact that every class file can be read as resource:

private Path getClassBase() {
    String resourcePath = '/' + getClass().getName().replace('.', '/') + ".class";
    URL url = getClass().getResource(resourcePath);
    String uriValue = url.toString();
    if (uriValue.endsWith('!' + resourcePath)) {
        // format: jar:<file>!<resourcePath>
        uriValue = uriValue.substring(4, uriValue.length() - resourcePath.length() - 1);
    } else {
        // format: <folder><resourcePath>
        uriValue = uriValue.substring(0, uriValue.length() - resourcePath.length());
    }
    return Paths.get(URI.create(uriValue));
}


Answered By - Rob Spoor
Answer Checked By - Senaida (PHPFixing Volunteer)
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg

Saturday, October 29, 2022

[FIXED] How to translate from native sql to querydsl expression right?

 October 29, 2022     java, left-join, querydsl, spring, sql     No comments   

Issue

Given the following native SQL query:

@Query(
value =
"SELECT "
+ "jp.BLABSTATUSID BlabStatus, "
+ "s.BLABSTATUSBEZ BlabStatusBez, "
+ "COUNT(*) sumvalue "
+ "FROM JP jp "
+ " LEFT JOIN BLAB_STATUS s "
+ " ON jp.BLABSTATUSID = s.BLABSTATUSID "
+ "GROUP BY jp.BLABSTATUSID, s.BLABSTATUSBEZ",
nativeQuery = true)

that I use in my Java / spring context, I have to switch to querydsl.

I tried:

final QJpEntity e = jpEntity;
final QBlabStatusEntity f = blabStatusEntity;

    return jpaQueryFactory
        .from(e)
        .leftJoin(e.blabStatus, blabStatusEntity)
        .on(blabStatusEntity.blabstatusid)
        .groupBy(e.blabStatus.blabstatusid, f.blabstatusbez)
        .select(
            Projections.constructor(
                JPStatisticCounter.class,
                e.blabStatus,
                f.blabstatusbez,
                e.count()))
        .fetch();

but it cannot compile because it seems syntactically wrong.

Any ideas?


Solution

solved, it was a constructor type mismatch



Answered By - DerBenniAusA
Answer Checked By - Gilberto Lyons (PHPFixing Admin)
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg

Monday, October 24, 2022

[FIXED] How to use stable RestHighLevelClient with Elasticsearch?

 October 24, 2022     elasticsearch, java, spring, spring-boot, spring-data-elasticsearch     No comments   

Issue

I have searched for so many posts but I couldn't find a proper way to use Elastic Search with spring boot application because I am totally new to elastic search.

My only dependency is: org.springframework.boot spring-boot-starter-data-elasticsearch 2.7.3

My config class is:

import org.elasticsearch.client.RestHighLevelClient;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.elasticsearch.client.ClientConfiguration;
import org.springframework.data.elasticsearch.client.RestClients;
import org.springframework.data.elasticsearch.config.AbstractElasticsearchConfiguration;
import org.springframework.data.elasticsearch.repository.config.EnableElasticsearchRepositories;

@Configuration
@EnableElasticsearchRepositories(basePackages = "com.backend.repository.elasticsearchrepository")
@ComponentScan(basePackages = {"com.backend.model.elasticsearchmodel"})
public class ElasticSearchConfig extends AbstractElasticsearchConfiguration {

    @Value("${spring.elasticsearch.url}")
    public String elasticsearchUrl;

    @Value("${spring.elasticsearch.username}")
    public String username;

    @Value("${spring.elasticsearch.password}")
    public String password;


    @Bean
    @Override
    public RestHighLevelClient elasticsearchClient() {
        final ClientConfiguration config = ClientConfiguration.builder()
                .connectedTo(elasticsearchUrl)
                .withBasicAuth(username, password)
                .build();

        return RestClients.create(config).rest();
    }
}

Here RestHighLevelClient is shown as deprecated. And my repository class is:

package com.backend.repository.elasticsearchrepository;

import com.backend.model.elasticsearchmodel.EsOffice;
import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;

import java.util.UUID;

public interface ESOfficeRepository extends ElasticsearchRepository<EsOffice, UUID> {
}

When I call the methods of this repository then it works fine but while storing the data it is returning error message even if it adds the data successfully.

2022-10-15 00:00:15.608 ERROR 51607 --- [nio-8080-exec-2] c.a.a.exception.GlobalExceptionHandler   : Unable to parse response body for Response{requestLine=POST /office/_doc?timeout=1m HTTP/1.1, host=http://localhost:9200, response=HTTP/1.1 201 Created}; nested exception is java.lang.RuntimeException: Unable to parse response body for Response{requestLine=POST /office/_doc?timeout=1m HTTP/1.1, host=http://localhost:9200, response=HTTP/1.1 201 Created}

Which POM dependency + what kind of repository should I use and How can I configure it in my config file ? I need these 3 that compatible with each other ?


Solution

Spring Data Elasticsearch 4.4 (which is pulled in by Spring Boot 2.7.3) is build with the Elasticsearch libraries in version 7.17, this is problematic when running against an Elasticsearch cluster in version 8. Youhave basically two options:

  1. Downgrade your cluster to version 7.17.6 (the latest 7.17 currently available) i f this is possible.

  2. You can try and see if setting the compatibility headers (see the Spring Data Elasticsearch documentation section 5.3.1 for more info). This should work, but I encountered cases where the response from the cluster still wasn't readable with a 7.17 client. - I had issues opened with Elasticsearch and they were resolved, but there still might be hidden traps.



Answered By - P.J.Meisch
Answer Checked By - Gilberto Lyons (PHPFixing Admin)
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg

Tuesday, October 18, 2022

[FIXED] Why do I have ' Builder lifecycle 'creator' failed with status code 51' when I run 'mvn spring-boot:build-image'

 October 18, 2022     docker, java, maven, spring, spring-boot     No comments   

Issue

I'm learning Docker and I'm trying to create an Image of my current Spring project.

I'm trying to run mvn spring-boot:build-image to create a docker image for my Spring Boot project, but I got this error when I execute it :

 Failed to execute goal org.springframework.boot:spring-boot-maven-plugin:2.7.0:build-image (default-cli) on project dwh-webservices: Execution default-cli of goal org.springframework.boot:spring-boot-maven-plugin:2.7.0:build
-image failed: Builder lifecycle 'creator' failed with status code 51 

I didn't find anything similar on the web, so I'm asking the question here.

Here is my pom.xml. If you need more, feel free to ask.

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.7.0</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.business</groupId>
    <artifactId>dwh-webservices</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>DWH_WebServices</name>
    <description>DWH_WebServices</description>
    <properties>
        <java.version>17</java.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>

        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
            <version>RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
            <version>RELEASE</version>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.28</version>
            <type>jar</type>
        </dependency>
        <dependency>
            <groupId>javax.xml.bind</groupId>
            <artifactId>jaxb-api</artifactId>
            <version>2.3.1</version>
        </dependency>
        <dependency>
            <groupId>org.javassist</groupId>
            <artifactId>javassist</artifactId>
            <version>3.25.0-GA</version>
        </dependency>
        <dependency>
            <groupId>com.microsoft.sqlserver</groupId>
            <artifactId>mssql-jdbc</artifactId>
            <version>6.2.2.jre8</version>
        </dependency>
        <dependency>
            <groupId>com.google.guava</groupId>
            <artifactId>guava</artifactId>
            <version>31.0.1-jre</version>
        </dependency>
    </dependencies>


    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

Am I doing something wrong ? Am I missing something ?


Solution

I had the same issue a few days ago.

The problem was that my company is rewriting the TSL certificate, so I was unable to download it :

Get "https://repo.spring.io/release/org/springframework/cloud/spring-cloud-bindings/1.10.0/spring-cloud-bindings-1.10.0.jar": x509: certificate signed by unknown authority

I had to add it manually. I follow this and it worked.

Hope it helps.



Answered By - Louis Chopard
Answer Checked By - Marilyn (PHPFixing Volunteer)
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg

Tuesday, October 11, 2022

[FIXED] Why can't i update an entity when it has a unique constraint on a column

 October 11, 2022     hibernate, java, phpmyadmin, spring, thymeleaf     No comments   

Issue

i am working on my first school project with springboot and thymeleaf . I am supposed to create a crud for two OneToMANY related entities : User and Comments. I succeded in making the comments' CRUD but i'm having a hard time with the users' Update portion , there seems to be an error related to the UniqueConstraint on the login column but i don't understand why, so can someone enlighten me as to what i'm doing wrong and how to fix it ? Here is my work :

  1. User Entity :

@Entity
@Table(name="users",uniqueConstraints = { @UniqueConstraint( 
     name="UniqueUser" , columnNames = {"login"} )})
public class User implements Serializable{
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;

@Column

private String nom;
@Column


private String prenom;
@Column
 
private String login;
@Column

private String password;

@OneToMany(cascade = CascadeType.ALL , fetch = FetchType.EAGER)
@JoinColumn(name = "user_id")
private List<Comment> comments = new ArrayList<>();

public User() {
}
public User(String nom, String prenom, String login, String password) {
    this.nom = nom;
    this.prenom = prenom;
    this.login = login;
    this.password = password;
}

public long getId() {
    return id;
}

public void setId(long Id) {
    this.id = id;
}

public String getNom() {
    return nom;
}

public void setNom(String nom) {
    this.nom = nom;
}

public String getPrenom() {
    return prenom;
}

public void setPrenom(String prenom) {
    this.prenom = prenom;
}

public String getLogin() {
    return login;
}

public void setLogin(String login) {
    this.login = login;
}

public String getPassword() {
    return password;
}

public void setPassword(String password) {
    this.password = password;
}

public List<Comment> getComments() {
    return comments;
}

public void setComments(List<Comment> comments) {
    this.comments = comments;
}    

}

2.Update form :

<form action="#" th:action="@{/saveUpdateUser}" th:object="${user}" method="POST">
                    
                    <input type="hidden" th:field="*{id}"/>
                    <input type="hidden" th:field="*{comments}"/>
                    <label for="nom">Nom:</label>
                   
                         <input id="nom" type="text" class="form-control" th:field="*{nom}"/>
                    </div>
                    
                    <label for="prenom" class="form-label">Prenom:</label>
                  
                         <input id="prenom" type="text" class="form-control" th:field="*{prenom}"/>
                                            
                     <label for="login" class="form-label">Login:</label>
                
                         <input id="login" type="text" class="form-control" th:field="*{login}"/>
                    
                     
                    <label for="pass" class="form-label">Password:</label>
                  
                         <input id="pass" type="text" class="form-control" th:field="*{password}"/>
                  
      
                    <div>
                        <button type="submit" class="btn btn-danger">Submit</button>
                   </div>
                </form>

3.Controller portion for the users' update

    @GetMapping("/updateUser/{id}")
public String viewUpdateUser(@PathVariable (value="id") long id,Model model)
{
     Optional<User> optional = userRepository.findById(id);
    User user = null;
    if(optional.isPresent())
        user = optional.get();
    else
        throw new RuntimeException ("User not found for id:: " + id);
    model.addAttribute("user",user);
    return "update_user";
}
@PostMapping("saveUpdateUser")
public String saveUpdateUser(@ModelAttribute("user") @Valid User user,Errors errors)
{
    if(errors.hasErrors())
        return "update_user";
    userRepository.save(user);
    return "redirect:/Users";
}

2.The error :

 Whitelabel Error Page
This application has no explicit mapping for /error, so you are seeing this as a fallback.

Sat Dec 18 11:28:09 CET 2021
There was an unexpected error (type=Internal Server Error, status=500).
could not execute statement; SQL [n/a]; constraint [null]; nested exception is org.hibernate.exception.ConstraintViolationException: could not execute statement
org.springframework.dao.DataIntegrityViolationException: could not execute statement; SQL [n/a]; constraint [null]; nested exception is org.hibernate.exception.ConstraintViolationException: could not execute statement
    at org.springframework.orm.jpa.vendor.HibernateJpaDialect.convertHibernateAccessException(HibernateJpaDialect.java:276)
    at org.springframework.orm.jpa.vendor.HibernateJpaDialect.translateExceptionIfPossible(HibernateJpaDialect.java:233)
    at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.translateExceptionIfPossible(AbstractEntityManagerFactoryBean.java:551)
    at org.springframework.dao.support.ChainedPersistenceExceptionTranslator.translateExceptionIfPossible(ChainedPersistenceExceptionTranslator.java:61)
    at org.springframework.dao.support.DataAccessUtils.translateIfNecessary(DataAccessUtils.java:242)
    at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:152)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
    at org.springframework.data.jpa.repository.support.CrudMethodMetadataPostProcessor$CrudMethodMetadataPopulatingMethodInterceptor.invoke(CrudMethodMetadataPostProcessor.java:174)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
    at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:97)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
    at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:215)
    at com.sun.proxy.$Proxy110.save(Unknown Source)
    at projet.sgbd.controller.CommentController.saveUpdateUser(CommentController.java:165)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:566)
    at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:205)
    at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:150)
    at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:117)
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:895)
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:808)
    at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87)
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1067)
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:963)
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006)
    at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:909)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:681)
    at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:764)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:227)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
    at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
    at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
    at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
    at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:197)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:97)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:540)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:135)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:78)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:357)
    at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:382)
    at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65)
    at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:895)
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1722)
    at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
    at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191)
    at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659)
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
    at java.base/java.lang.Thread.run(Thread.java:834)
Caused by: org.hibernate.exception.ConstraintViolationException: could not execute statement
    at org.hibernate.exception.internal.SQLExceptionTypeDelegate.convert(SQLExceptionTypeDelegate.java:59)
    at org.hibernate.exception.internal.StandardSQLExceptionConverter.convert(StandardSQLExceptionConverter.java:37)
    at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:113)
    at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:99)
    at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.executeUpdate(ResultSetReturnImpl.java:200)
    at org.hibernate.dialect.identity.GetGeneratedKeysDelegate.executeAndExtract(GetGeneratedKeysDelegate.java:57)
    at org.hibernate.id.insert.AbstractReturningDelegate.performInsert(AbstractReturningDelegate.java:43)
    at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:3279)
    at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:3885)
    at org.hibernate.action.internal.EntityIdentityInsertAction.execute(EntityIdentityInsertAction.java:84)
    at org.hibernate.engine.spi.ActionQueue.execute(ActionQueue.java:645)
    at org.hibernate.engine.spi.ActionQueue.addResolvedEntityInsertAction(ActionQueue.java:282)
    at org.hibernate.engine.spi.ActionQueue.addInsertAction(ActionQueue.java:263)
    at org.hibernate.engine.spi.ActionQueue.addAction(ActionQueue.java:317)
    at org.hibernate.event.internal.AbstractSaveEventListener.addInsertAction(AbstractSaveEventListener.java:330)
    at org.hibernate.event.internal.AbstractSaveEventListener.performSaveOrReplicate(AbstractSaveEventListener.java:287)
    at org.hibernate.event.internal.AbstractSaveEventListener.performSave(AbstractSaveEventListener.java:193)
    at org.hibernate.event.internal.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:123)
    at org.hibernate.event.internal.DefaultPersistEventListener.entityIsTransient(DefaultPersistEventListener.java:185)
    at org.hibernate.event.internal.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:128)
    at org.hibernate.event.internal.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:55)
    at org.hibernate.event.service.internal.EventListenerGroupImpl.fireEventOnEachListener(EventListenerGroupImpl.java:107)
    at org.hibernate.internal.SessionImpl.firePersist(SessionImpl.java:774)
    at org.hibernate.internal.SessionImpl.persist(SessionImpl.java:760)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:566)
    at org.springframework.orm.jpa.ExtendedEntityManagerCreator$ExtendedEntityManagerInvocationHandler.invoke(ExtendedEntityManagerCreator.java:362)
    at com.sun.proxy.$Proxy104.persist(Unknown Source)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:566)
    at org.springframework.orm.jpa.SharedEntityManagerCreator$SharedEntityManagerInvocationHandler.invoke(SharedEntityManagerCreator.java:311)
    at com.sun.proxy.$Proxy104.persist(Unknown Source)
    at org.springframework.data.jpa.repository.support.SimpleJpaRepository.save(SimpleJpaRepository.java:624)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:566)
    at org.springframework.data.repository.core.support.RepositoryMethodInvoker$RepositoryFragmentMethodInvoker.lambda$new$0(RepositoryMethodInvoker.java:289)
    at org.springframework.data.repository.core.support.RepositoryMethodInvoker.doInvoke(RepositoryMethodInvoker.java:137)
    at org.springframework.data.repository.core.support.RepositoryMethodInvoker.invoke(RepositoryMethodInvoker.java:121)
    at org.springframework.data.repository.core.support.RepositoryComposition$RepositoryFragments.invoke(RepositoryComposition.java:529)
    at org.springframework.data.repository.core.support.RepositoryComposition.invoke(RepositoryComposition.java:285)
    at org.springframework.data.repository.core.support.RepositoryFactorySupport$ImplementationMethodExecutionInterceptor.invoke(RepositoryFactorySupport.java:638)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
    at org.springframework.data.repository.core.support.QueryExecutorMethodInterceptor.doInvoke(QueryExecutorMethodInterceptor.java:163)
    at org.springframework.data.repository.core.support.QueryExecutorMethodInterceptor.invoke(QueryExecutorMethodInterceptor.java:138)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
    at org.springframework.data.projection.DefaultMethodInvokingMethodInterceptor.invoke(DefaultMethodInvokingMethodInterceptor.java:80)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
    at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:123)
    at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:388)
    at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:119)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
    at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:137)
    ... 58 more
Caused by: java.sql.SQLIntegrityConstraintViolationException: Duplicata du champ 'Siri' pour la clef 'UniqueUser'
    at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:117)
    at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:122)
    at com.mysql.cj.jdbc.ClientPreparedStatement.executeInternal(ClientPreparedStatement.java:953)
    at com.mysql.cj.jdbc.ClientPreparedStatement.executeUpdateInternal(ClientPreparedStatement.java:1098)
    at com.mysql.cj.jdbc.ClientPreparedStatement.executeUpdateInternal(ClientPreparedStatement.java:1046)
    at com.mysql.cj.jdbc.ClientPreparedStatement.executeLargeUpdate(ClientPreparedStatement.java:1371)
    at com.mysql.cj.jdbc.ClientPreparedStatement.executeUpdate(ClientPreparedStatement.java:1031)
    at com.zaxxer.hikari.pool.ProxyPreparedStatement.executeUpdate(ProxyPreparedStatement.java:61)
    at com.zaxxer.hikari.pool.HikariProxyPreparedStatement.executeUpdate(HikariProxyPreparedStatement.java)
    at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.executeUpdate(ResultSetReturnImpl.java:197)
    ... 111 more

I hope it's fine to add all this error page . Please tell me in case i should provide more details


Solution

Finally it's working! It fixed itself(still don't understand). Anyways , thanks for your suggestions.



Answered By - SkyMth
Answer Checked By - Pedro (PHPFixing Volunteer)
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg

Thursday, October 6, 2022

[FIXED] What are the best practices for calculating statistics in REST API applications

 October 06, 2022     api, java, rest, spring, statistics     No comments   

Issue

I am trying to make a service that will calculate statistics for each month.

I did smth like this:

public Map<String, BigDecimal> getStatistic() {
        List<Order> orders = orderService.findAll(Sort.by(Sort.Direction.ASC, "creationDate")).toList();
        SortedMap<String, BigDecimal> statisticsMap = new TreeMap<>();
        MathContext mc = new MathContext(3);
        for (Order order : orders) {
            List<FraudDishV1Response> dishesOfOrder = order.getDishIds()
                    .stream()
                    .map(dishId -> dishV1Client.getDishById(dishId))
                    .collect(Collectors.toList());
            BigDecimal total = calculateTotal(dishesOfOrder);
            String date = order.getCreatedDate().format(DateTimeFormatter.ofPattern("yyyy-MM"));
            statisticsMap.merge(date, total, (a, b) -> a.add(b, mc));
        }
        return statisticsMap;
    }

But it takes a long time if there are lots of etries in the database. Are there any best practices for working with statistics in REST API applications?

And also I'd like to know if it is a good way to save the statistics in a separate repository? It will save time for calculating statistics, but during creating a record in the database, you will also have to update the statistics db.


Solution

Well, I did't stop and made several solutions step by step...

Step 1: Use streams. Before that, calculating statistics for 10,000 OrderEntities records took 18 seconds. Now it has accelerated to 14 seconds.

Step 2: Using parallelStream instead of streams. Parallel streams accelerated the calculation of statistics to 6 seconds! I was even surprised.

public SortedMap<String, BigDecimal> getStatisticsByParallelStreams() {
        List<OrderEntity> orders = new ArrayList<>();
        orderService.findAll(Sort.by(Sort.Direction.ASC, "createdDate")).forEach(orders::add);

        MathContext mc = new MathContext(3);
        return orders.stream().collect(Collectors.toMap(
                order -> order.getCreatedDate().format(DateTimeFormatter.ofPattern("yyyy-MM")),
                order -> calculateTotal(order.getDishIds()
                        .parallelStream()
                        .map(dishId -> dishV1Client.getDishById(dishId))
                        .collect(Collectors.toList())),
                (a, b) -> a.add(b, mc),
                TreeMap::new
        ));
    }

Step 3: Optimizing requests to another microservice. I connected the JProfiler to the app and I have found out that I offen do extra requests to the another microservice. After it firstly I made a request to receive all Dishes, and then during calculating statistics, I use a recieved List of Dishes. And thus I speeded it up to 1.5 seconds!:

public SortedMap<String, BigDecimal> getStatisticsByParallelStreams() {
        List<OrderEntity> orders = new ArrayList<>();
        orderService.findAll(Sort.by(Sort.Direction.ASC, "createdDate")).forEach(orders::add);

        List<FraudDishV1Response> dishes = dishV1Client.getDishes();

        MathContext mc = new MathContext(3);
        return orders.stream().collect(Collectors.toMap(
                order -> order.getCreatedDate().format(DateTimeFormatter.ofPattern("yyyy-MM")),
                order -> calculateTotal(order.getDishIds()
                        .parallelStream()
                        .map(dishId -> getDishResponseById(dishes, dishId))
                        .collect(Collectors.toList())),
                (a, b) -> a.add(b, mc),
                TreeMap::new
        ));
    }


Answered By - andrew kot
Answer Checked By - Pedro (PHPFixing Volunteer)
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg

Tuesday, September 20, 2022

[FIXED] How to create a Model class having map as one of the variables

 September 20, 2022     hashmap, java, spring, spring-boot     No comments   

Issue

I am trying to create a model class for something like this

{
    "id": null,
    "name": "TestCompany",
    "domainName": "comany.domain",
    "status": 0,
    "brandAttributes": {
        "contact_person_name": "HS",
        "website_url": "company@gmail.com",
        "address": "Bengaluru",
        "contact_person_email": "hs@gmail.com"
    }
}

Solution

You can use nested class or 2 class to archive the Model

class ModelDTO{
    private String id;
    private String name;
    private String domainName;
    private long status;
    private BrandAttributes brandAttributes;
    
    class BrandAttributes{
        private String contact_person_name;
        private String website_url;
        private String address;
        private String contact_person_email;
    }
}

or

class ModelDTO{
    private String id;
    private String name;
    private String domainName;
    private long status;
    private BrandAttributes brandAttributes;
}
    class BrandAttributes{
        private String contact_person_name;
        private String website_url;
        private String address;
        private String contact_person_email;
    }


Answered By - Lokeshwar G
Answer Checked By - Pedro (PHPFixing Volunteer)
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg

[FIXED] Why Spring batch JobParameters using LinkedHashMap

 September 20, 2022     hashmap, java, linkedhashmap, spring, spring-batch     No comments   

Issue

Compared to HashMap, LinkedHashMap guarantees input order.

In Spring Batch, I think HashMap is enough to save JobParameter, but I don't know why JobParameters used LinkedHashMap. What do you think about this?

Below are some of the implementations of JobParameters. Github Link

public class JobParameters implements Serializable {

    private final Map<String,JobParameter> parameters;

    public JobParameters() {
        this.parameters = new LinkedHashMap<>();
    }

    public JobParameters(Map<String,JobParameter> parameters) {
        this.parameters = new LinkedHashMap<>(parameters);
    }

    // ...

Solution

There is no ordering between job parameters. The usage of a linked hash map is not justified in my opinion.

You can open an issue with a link to this SO thread and we will consider changing that in Spring Batch.



Answered By - Mahmoud Ben Hassine
Answer Checked By - Marilyn (PHPFixing Volunteer)
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg

Tuesday, September 6, 2022

[FIXED] How to deploy Static Vue application with Spring Boot on a Weblogic Server?

 September 06, 2022     spring, spring-boot, vue.js, web-deployment, weblogic     No comments   

Issue

I have a Spring boot application deployed on a Weblogic server, and I want to add a Vue/vite frontend to it. I created a Vue project and then built it into static assets. I then placed the contents of the resulting Dist folder (index.html and assets folder) into src/main/resources/static of the Spring Boot project.

Then I generate the war file using Maven, and host that on Weblogic. The Spring Boot section of the app functions as normal, but when I navigate to weblogicurl/myapp/index.html- it is just a blank page rather than the complete frontend I'm expecting. Upon inspection, the blank index.html does have the standard Vue div element with id of "app", so weblogic is detecting and showing the static frontend. However, it is not able to pull any assets to actually display html or use the js - as it is 404ing when index.html tries to pull those built files.

enter image description here

I'm thinking that maybe it's because index.html is trying to pull the js and css assets from /weblogicurl/assets rather than /weblogicurl/myapp/assets but I'm not entirely sure as I'm unfamiliar with the intended structure of a Spring Boot Web app hosted on Weblogic. If that is the case, how would I resolve it? Though maybe it's some other issue, so any input would be greatly appreciated.


Solution

Turns out the problem was indeed that it was pulling assets from /weblogicurl rather than /weblogicurl/myapp.

Adding base: '/myapp/' to my vite.config.ts (or vue.config.js for non vite) resolved it.



Answered By - Magitrix Alyxra
Answer Checked By - David Marino (PHPFixing Volunteer)
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg

Monday, September 5, 2022

[FIXED] How to listen to keyspace events using Spring Data Redis with a GCP managed cluster?

 September 05, 2022     google-cloud-platform, redis, spring, spring-data-redis     No comments   

Issue

I am using secondary indexes with Redis thanks to Spring Data Redis @Indexed annotations. My entry has a TTL. This has a side effect of keeping the indexes after the expiration of the main entry. This is expected, and Spring can listen to keyspace expiry events to remove those indexes once the main TTL is done.

However, enabling the listening to keyspace expiry events with Spring, I face the following error at startup:

ERR unknown command 'CONFIG'

This is how I configured the listener:

@EnableRedisRepositories(enableKeyspaceEvents = EnableKeyspaceEvents.ON_STARTUP)

What can I do to make this work?


Solution

This problem is linked to the fact that the Redis cluster is managed, and as such remote clients can't call CONFIG on it. When enabling the Spring keyspace event listener, it tries to configure Redis to emit keyspace expiry events, by setting the notify-keyspace-events config key to "Ex".

The workaround to this is:

  1. Configure your MemoryStore on GCP, adding the notify-keyspace-events key with "Ex" as value.
  2. Use @EnableRedisRepositories(enableKeyspaceEvents = EnableKeyspaceEvents.ON_STARTUP, keyspaceNotificationsConfigParameter = "") for your client configuration. The explicitely empty String prevents Spring from trying to override the remote configuration.


Answered By - Docteur
Answer Checked By - Gilberto Lyons (PHPFixing Admin)
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg

[FIXED] How to use spring-data-redis without spring boot java project

 September 05, 2022     java, redis, spring, spring-boot     No comments   

Issue

Want to use spring-data-redis with standalone maven java project

e.g 

package com.test.mvn.redis.test_redis;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;

/**
 * Hello world!
 *
 */
public class App 
{
    @Autowired
    private StudentRepository studentRepository;
    
    @Bean
    JedisConnectionFactory jedisConnectionFactory() {
        JedisConnectionFactory jedisConFactory
          = new JedisConnectionFactory();
        jedisConFactory.setHostName("localhost");
        jedisConFactory.setPort(6379);
        return jedisConFactory;
    }

    @Bean
    public RedisTemplate<String, Object> redisTemplate() {
        RedisTemplate<String, Object> template = new RedisTemplate<>();
        template.setConnectionFactory(jedisConnectionFactory());
        return template;
    }
    
    public void saveData()
    {
        Student student = new Student(
              "Eng2015001", "John Doe", Student.Gender.MALE, 1);
            studentRepository.save(student);
            System.out.println("Data saved successfully");
    }
    public static void main( String[] args )
    {
        System.out.println( "Hello World!" );
        App app =new App();
        app.saveData();
    }
}

    package com.test.mvn.redis.test_redis;

import org.springframework.data.repository.CrudRepository;
import org.springframework.stereotype.Repository;

@Repository
public interface StudentRepository extends CrudRepository<Student, String> {
}

My pom.xml 4.0.0

    <groupId>com.test.mvn.redis</groupId>
    <artifactId>test-redis</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>jar</packaging>

    <name>test-redis</name>
    <url>http://maven.apache.org</url>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.data</groupId>
            <artifactId>spring-data-redis</artifactId>
            <version>2.3.3.RELEASE</version>
        </dependency>

        <dependency>
            <groupId>redis.clients</groupId>
            <artifactId>jedis</artifactId>
            <version>3.3.0</version>
            <type>jar</type>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>3.8.1</version>
            <scope>test</scope>
        </dependency>
        <!-- source code support dependencies -->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.24</version>
            <optional>true</optional>
        </dependency>
    </dependencies>
</project>

Please let me know is it correct approach or do i need to use different redis java library for standalone java project. Want to add data from java to redis without rest controller.Basic requirement is to add data from java plain (maven) project to redis.


Solution

You already use @Autowired, @Bean and some more, so you definitely need spring-core artifact.

But for those type of examples like what you mention in your question (a simple command line java program with just a main method), spring has created another approach.

Read this article on how to creat a simple command line program with features of spring available.

Important to note. The use of property spring.main.web-application-type=NONE is a must, so that spring does not start any embedded web server like tomcat when the jar file is executed.



Answered By - Panagiotis Bougioukos
Answer Checked By - Marilyn (PHPFixing Volunteer)
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg

[FIXED] How to set valid certification path when connecting to redis using SSL in Spring Boot?

 September 05, 2022     database, redis, spring, spring-boot, ssl     No comments   

Issue

I want to connect to redis by using SSL. I set up host, port etc. but when i'm setting...

spring.redis.ssl=true

and when i run the application i got following error:

org.springframework.data.redis.RedisConnectionFailureException:
Unable to connect to Redis; nested exception is io.lettuce.core.RedisConnectionException: Unable to connect to
XXX:XXX
at
org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory$ExceptionTranslatingConnectionProvider.translateException(LettuceConnectionFactory.java:1689) ~[spring-data-redis-2.5.7.jar:2.5.7]

Caused by: javax.net.ssl.SSLHandshakeException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target at java.base/sun.security.ssl.Alert.createSSLException(Alert.java:131) ~[na:na] at java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:349) ~[na:na]

Actually my certificate (test.pem) is in resources folder in spring boot apllication project. Where should i put the certificate file or how to set the path to this file? I want to set it by application.yml or by java code.


Solution

This configuration works in my case:

@Configuration
@RequiredArgsConstructor
public class RedisSSLConfiguration {

  @Value("${spring.redis.host}")
  private String host;

  @Value("${spring.redis.port}")
  private int port;

  @Value("${spring.redis.password}")
  private String password;

  @Value("${spring.redis.ssl:false}")
  private boolean sslEnabled;

  private final ResourceLoader resourceLoader;

  @Bean
  RedisConnectionFactory redisConnectionFactory() throws IOException {
    RedisStandaloneConfiguration redisStandaloneConfiguration = new RedisStandaloneConfiguration();
    redisStandaloneConfiguration.setHostName(host);
    redisStandaloneConfiguration.setPort(port);
    redisStandaloneConfiguration.setPassword(password);

    LettuceClientConfiguration.LettuceClientConfigurationBuilder lettuceClientConfigurationBuilder =
        LettuceClientConfiguration.builder();

    if (sslEnabled){
      SslOptions sslOptions = SslOptions.builder()
          .trustManager(resourceLoader.getResource("classpath:redis.pem").getFile())
          .build();

      ClientOptions clientOptions = ClientOptions
          .builder()
          .sslOptions(sslOptions)
          .protocolVersion(ProtocolVersion.RESP3)
          .build();

      lettuceClientConfigurationBuilder
          .clientOptions(clientOptions)
          .useSsl();
    }

    LettuceClientConfiguration lettuceClientConfiguration = lettuceClientConfigurationBuilder.build();

    return new LettuceConnectionFactory(redisStandaloneConfiguration, lettuceClientConfiguration);
  }

}


Answered By - Alchemisz
Answer Checked By - Mary Flores (PHPFixing Volunteer)
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg

[FIXED] How to cache bson ObjectId

 September 05, 2022     caching, kotlin, mongodb, redis, spring     No comments   

Issue

I have a question regarding ObjectId caching.

I am caching mongoDB document using redis, and when I check the cached value, only the timeStamp and date of the ObjectId are cached as shown below, and they are being retrieved with values different from the ObjectId of the actual document.

"id":{
  "@class":"org.bson.types.ObjectId",
  "timestamp":1658025133,
  "date":["java.util.Date",1658025133000]
},

Actual ObjectId: 6311ba39c31566544746d31b

ObjectId retrieved as cached result: 6311ba3911d1d82cb7892c73

How can I cache it so that it is fetched as an actual ObjectId value?


Solution

You need to add custom serializer to serialize ObjectId into String

@JsonComponent
class ObjectIdSerializer : StdSerializer<ObjectId>(ObjectId::class.java) {
  override fun serialize(value: ObjectId, gen: JsonGenerator, provider: SerializerProvider) {
    return gen.writeString(value.toString())
  }
}

Then

objectMapper().registerModule(SimpleModule().addSerializer(ObjectIdSerializer()))


Answered By - sidgate
Answer Checked By - Robin (PHPFixing Admin)
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg

Saturday, September 3, 2022

[FIXED] How to set a custom principal object during or after JWT authentication?

 September 03, 2022     authentication, jwt, spring, spring-boot, spring-security     No comments   

Issue

I've changed the way a user is authenticated in my backend. From now on I am receiving JWT tokens from Firebase which are then validated on my Spring Boot server.

This is working fine so far but there's one change which I am not too happy about and it's that the principal-object is now a org.springframework.security.oauth2.jwt.Jwt and not a AppUserEntity, the user-model, like before.

// Note: "authentication" is a JwtAuthenticationToken

Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
Jwt jwt = (Jwt) authentication.getPrincipal();

So, after some reading and debugging I found that the BearerTokenAuthenticationFilter essentially sets the Authentication object like so:

// BearerTokenAuthenticationFilter.java

AuthenticationManager authenticationManager = this.authenticationManagerResolver.resolve(request);

// Note: authenticationResult is our JwtAuthenticationToken
Authentication authenticationResult = authenticationManager.authenticate(authenticationRequest);  

SecurityContext context = SecurityContextHolder.createEmptyContext();
context.setAuthentication(authenticationResult);
SecurityContextHolder.setContext(context);

and as we can see, this on the other hand comes from the authenticationManager which is a org.springframework.security.authentication.ProviderManager and so on. The rabbit hole goes deep.

I didn't find anything that would allow me to somehow replace the Authentication.

So what's the plan?

Since Firebase is now taking care of user authentication, a user can be created without my backend knowing about it yet. I don't know if this is the best way to do it but I intend to simply create a user record in my database once I discover a valid JWT-token of a user which does not exist yet.

Further, a lot of my business logic currently relies on the principal being a user-entity business object. I could change this code but it's tedious work and who doesn't want to look back on a few lines of legacy code?


Solution

I did it a bit different than Julian Echkard.

In my WebSecurityConfigurerAdapter I am setting a Customizer like so:

@Override
protected void configure(HttpSecurity http) throws Exception {
    http.oauth2ResourceServer()
            .jwt(new JwtResourceServerCustomizer(this.customAuthenticationProvider));
}

The customAuthenticationProvider is a JwtResourceServerCustomizer which I implemented like this:

public class JwtResourceServerCustomizer implements Customizer<OAuth2ResourceServerConfigurer<HttpSecurity>.JwtConfigurer> {

    private final JwtAuthenticationProvider customAuthenticationProvider;

    public JwtResourceServerCustomizer(JwtAuthenticationProvider customAuthenticationProvider) {
        this.customAuthenticationProvider = customAuthenticationProvider;
    }

    @Override
    public void customize(OAuth2ResourceServerConfigurer<HttpSecurity>.JwtConfigurer jwtConfigurer) {
        String key = UUID.randomUUID().toString();
        AnonymousAuthenticationProvider anonymousAuthenticationProvider = new AnonymousAuthenticationProvider(key);
        ProviderManager providerManager = new ProviderManager(this.customAuthenticationProvider, anonymousAuthenticationProvider);
        jwtConfigurer.authenticationManager(providerManager);
    }
}

I'm configuring the NimbusJwtDecoder like so:

@Component
public class JwtConfig {

    @Bean
    public JwtDecoder jwtDecoder() {
        String jwkUri = "https://www.googleapis.com/service_accounts/v1/jwk/securetoken@system.gserviceaccount.com";
        return NimbusJwtDecoder.withJwkSetUri(jwkUri)
                .build();
    }

}

And finally, we need a custom AuthenticationProvider which will return the Authentication object we desire:

@Component
public class JwtAuthenticationProvider implements AuthenticationProvider {

    private final JwtDecoder jwtDecoder;

    @Autowired
    public JwtAuthenticationProvider(JwtDecoder jwtDecoder) {
        this.jwtDecoder = jwtDecoder;
    }

    @Override
    public Authentication authenticate(Authentication authentication) throws AuthenticationException {
        BearerTokenAuthenticationToken token = (BearerTokenAuthenticationToken) authentication;

        Jwt jwt;
        try {
            jwt = this.jwtDecoder.decode(token.getToken());
        } catch (JwtValidationException ex) {
            return null;
        }

        List<GrantedAuthority> authorities = new ArrayList<>();

        if (jwt.hasClaim("roles")) {
            List<String> rolesClaim = jwt.getClaim("roles");
            List<RoleEntity.RoleType> collect = rolesClaim
                    .stream()
                    .map(RoleEntity.RoleType::valueOf)
                    .collect(Collectors.toList());

            for (RoleEntity.RoleType role : collect) {
                authorities.add(new SimpleGrantedAuthority(role.toString()));
            }
        }

        return new JwtAuthenticationToken(jwt, authorities);
    }

    @Override
    public boolean supports(Class<?> authentication) {
        return authentication.equals(BearerTokenAuthenticationToken.class);
    }

}


Answered By - Stefan Falk
Answer Checked By - Pedro (PHPFixing Volunteer)
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg

Friday, August 19, 2022

[FIXED] How to set environment variable or system property in spring tests?

 August 19, 2022     environment-variables, java, spring, spring-test     No comments   

Issue

I'd like to write some tests that check the XML Spring configuration of a deployed WAR. Unfortunately some beans require that some environment variables or system properties are set. How can I set an environment variable before the spring beans are initialized when using the convenient test style with @ContextConfiguration?

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath:whereever/context.xml")
public class TestWarSpringContext { ... }

If I configure the application context with annotations, I don't see a hook where I can do something before the spring context is initialized.


Solution

You can initialize the System property in a static initializer:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath:whereever/context.xml")
public class TestWarSpringContext {

    static {
        System.setProperty("myproperty", "foo");
    }

}

The static initializer code will be executed before the spring application context is initialized.



Answered By - Jimmy Praet
Answer Checked By - Pedro (PHPFixing Volunteer)
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg

[FIXED] How to fix environment.getActiveProfiles() is null in UnitTest Java

 August 19, 2022     environment-variables, java, junit, spring, unit-testing     No comments   

Issue

I have a piece of Java code which uses an environment variable and the behaviour of the code depends on the value of this variable. And then I created the UnitTest of it in TestClass and debug to see the result.

Then I found null from environment.getActiveProfiles()

enter image description here

I set the environment in serviceImpl by this way

@Autowired
private Environment environment;

I've already mocked some environment here in TestClass

@Mock
private Environment environment; 
...
...
String[] activeProfiles =  new String[]{"dev"};
ActiveProfilesResponse activeProfilesResponse = new ActiveProfilesResponse();
activeProfilesResponse.setProfiles(List.of(activeProfiles));
when(environment.getActiveProfiles()).thenReturn(activeProfiles);

and also provides @ActiveProfiles("dev") in that TestClass

Do I need to add any mock or anything else for it ?


Solution

Your environment is null, hence the NullPointerException. This means that your mocked Environment from the test class is not injected into your test subject class. You haven't shown us the part of your class where environment is supposed to be set. But, for example, if it is injected in the constructor, make sure your test class initializes your class with new YourClass(environment); and not new YourClass(null);.



Answered By - ZeroOne
Answer Checked By - Mary Flores (PHPFixing Volunteer)
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg

Friday, August 5, 2022

[FIXED] How to extract authentication token in @Controller

 August 05, 2022     oauth, rest, single-sign-on, spring, spring-security     No comments   

Issue

I have Spring Boot app that uses OAuth 2.0 and Authorization Server. When I try to access a secured page, I get a redirect to the login page of my authorization server (Blitz Identity Provider) and everything works like it should.

My problem is that I can't extract authorization token in @Controller (on the secured page). That token I want to use later to authorize in second application.

  • Tried this thing (in answer) and it worked, I got my token back, but as you can see, it's a hardcode of username and password parameters and it's like login over login -- I don't need to login for a second time (on authenticated page).
  • Tried to output authentication.getDetails(), it shows token type and token like < TOKEN >, but it's not enough.
  • Tried to lookup token in request-response headers, but didn't find it, so authorization server doesn't send it in headers.

Here are 2 files which can help you to understand some part of my context.

application.yml

server:
  port: 8080
  context-path: /
  session:
    cookie:
      name:FIRSTSESSION
security:
  basic:
    enabled: false
  oauth2:
    client:
      clientId: test_id
      clientSecret: f3M5m9a2Dn0v15l
      accessTokenUri: http://server:9000/blitz/oauth/te
      userAuthorizationUri: http://server:9000/blitz/oauth/ae?scope=test_scope
    resource:
      userInfoUri: http://server:9000/blitz/oauth/me
logging:
  level:
    org.springframework.security: DEBUG

SsoController.java

@EnableOAuth2Sso
@Controller
public class SsoController {

    @RequestMapping("/secondService")
    public String getContent(HttpServletRequest request, Model model) {

        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        model.addAttribute("submittedValue", authentication.getDetails());
        return "secondService";
    } 
}

So, what you can suggest? How can I extract authorization token in this case?


Solution

If you have configured oauth2 authorization/resource server you can try below code:

@Autowired
private TokenStore tokenStore;

@RequestMapping(method = { RequestMethod.POST, RequestMethod.GET },
                value = "/oauth/me")
public Map<String, Object> userInfo (OAuth2Authentication auth)
{
    final OAuth2AuthenticationDetails details = 
        (OAuth2AuthenticationDetails) auth.getDetails();

    //token
    String accessToken = details.getTokenValue();

    //reference
    final OAuth2AccessToken accessToken = 
        tokenStore.readAccessToken(details.getTokenValue());

   // clientid
    String clientId = auth.getOAuth2Request().getClientId();
}

Hope it helps!



Answered By - Samir
Answer Checked By - David Marino (PHPFixing Volunteer)
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg

[FIXED] How to fix MojoFailureException while using spring to build web project

 August 05, 2022     eclipse, exception, maven, spring, testing     No comments   

Issue

Recently I use spring STS with roo 1.2.0.M1 to build a web project. I set up the jpa and create a entity with some field and create a repository and a service layer for the entity, and then when I perform tests, it gives me the following error:

roo> perform tests 
[INFO] Scanning for projects...
[INFO]                                                                         
[INFO] ------------------------------------------------------------------------
[INFO] Building WebApplication 0.1.0.BUILD-SNAPSHOT
[INFO] ------------------------------------------------------------------------
[INFO] 
[INFO] --- aspectj-maven-plugin:1.2:compile (default) @ WebApplication ---
[INFO] 
[INFO] --- maven-resources-plugin:2.5:resources (default-resources) @ WebApplication ---
[debug] execute contextualize
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] Copying 5 resources
[INFO] 
[INFO] --- maven-compiler-plugin:2.3.2:compile (default-compile) @ WebApplication ---
[INFO] Nothing to compile - all classes are up to date
[INFO] 
[INFO] --- aspectj-maven-plugin:1.2:test-compile (default) @ WebApplication ---
[INFO] 
[INFO] --- maven-resources-plugin:2.5:testResources (default-testResources) @ WebApplication ---
[debug] execute contextualize
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] Copying 0 resource
[INFO] 
[INFO] --- maven-compiler-plugin:2.3.2:testCompile (default-testCompile) @ WebApplication ---
[INFO] Nothing to compile - all classes are up to date
[INFO] 
[INFO] --- maven-surefire-plugin:2.8:test (default-test) @ WebApplication ---
[INFO] Surefire report directory: /Users/charlesli/Documents/workspace-spring/WebApplication/target/surefire-reports
[INFO] ------------------------------------------------------------------------
[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 15.936s
[INFO] Finished at: Fri Oct 28 20:59:59 EST 2011
[INFO] Final Memory: 6M/81M
[INFO] ------------------------------------------------------------------------
[ERROR] Failed to execute goal org.apache.maven.plugins:maven-surefire-plugin:2.8:test (default-test) on project WebApplication: There are test failures.
[ERROR] 
[ERROR] Please refer to /Users/charlesli/Documents/workspace-spring/WebApplication/target/surefire-reports for the individual test results.
[ERROR] -> [Help 1]
[ERROR] 
[ERROR] To see the full stack trace of the errors, re-run Maven with the -e switch.
[ERROR] Re-run Maven using the -X switch to enable full debug logging.
[ERROR] 
[ERROR] For more information about the errors and possible solutions, please read the following articles:
[ERROR] [Help 1] http://cwiki.apache.org/confluence/display/MAVEN/MojoFailureException

And I run the mvn test in the terminal, and I get the following errors:

[INFO] ------------------------------------------------------------------------
[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 13.614s
[INFO] Finished at: Fri Oct 28 21:06:50 EST 2011
[INFO] Final Memory: 6M/81M
[INFO] ------------------------------------------------------------------------
[ERROR] Failed to execute goal org.apache.maven.plugins:maven-surefire-plugin:2.8:test (default-test) on project WebApplication: There are test failures.
[ERROR] 
[ERROR] Please refer to /Users/charlesli/Documents/workspace-spring/WebApplication/target/surefire-reports for the individual test results.
[ERROR] -> [Help 1]
org.apache.maven.lifecycle.LifecycleExecutionException: Failed to execute goal org.apache.maven.plugins:maven-surefire-plugin:2.8:test (default-test) on project WebApplication: There are test failures.

Please refer to /Users/charlesli/Documents/workspace-spring/WebApplication/target/surefire-reports for the individual test results.
    at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:213)
    at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:153)
    at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:145)
    at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject(LifecycleModuleBuilder.java:84)
    at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject(LifecycleModuleBuilder.java:59)
    at org.apache.maven.lifecycle.internal.LifecycleStarter.singleThreadedBuild(LifecycleStarter.java:183)
    at org.apache.maven.lifecycle.internal.LifecycleStarter.execute(LifecycleStarter.java:161)
    at org.apache.maven.DefaultMaven.doExecute(DefaultMaven.java:319)
    at org.apache.maven.DefaultMaven.execute(DefaultMaven.java:156)
    at org.apache.maven.cli.MavenCli.execute(MavenCli.java:537)
    at org.apache.maven.cli.MavenCli.doMain(MavenCli.java:196)
    at org.apache.maven.cli.MavenCli.main(MavenCli.java:141)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at org.codehaus.plexus.classworlds.launcher.Launcher.launchEnhanced(Launcher.java:290)
    at org.codehaus.plexus.classworlds.launcher.Launcher.launch(Launcher.java:230)
    at org.codehaus.plexus.classworlds.launcher.Launcher.mainWithExitCode(Launcher.java:409)
    at org.codehaus.plexus.classworlds.launcher.Launcher.main(Launcher.java:352)
Caused by: org.apache.maven.plugin.MojoFailureException: There are test failures.

Please refer to /Users/charlesli/Documents/workspace-spring/WebApplication/target/surefire-reports for the individual test results.
    at org.apache.maven.plugin.surefire.SurefireHelper.reportExecution(SurefireHelper.java:74)
    at org.apache.maven.plugin.surefire.SurefirePlugin.writeSummary(SurefirePlugin.java:644)
    at org.apache.maven.plugin.surefire.SurefirePlugin.executeAfterPreconditionsChecked(SurefirePlugin.java:640)
    at org.apache.maven.plugin.surefire.AbstractSurefireMojo.execute(AbstractSurefireMojo.java:103)
    at org.apache.maven.plugin.DefaultBuildPluginManager.executeMojo(DefaultBuildPluginManager.java:101)
    at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:209)
    ... 19 more
[ERROR] 
[ERROR] 
[ERROR] For more information about the errors and possible solutions, please read the following articles:
[ERROR] [Help 1] http://cwiki.apache.org/confluence/display/MAVEN/MojoFailureException

I use the following commands to build the project:

jpa setup --database MYSQL --provider HIBERNATE --databaseName App --hostName localhost --password root --persistenceUnit app --transactionManager appTransactionManager --userName root
entity --class ~.app.domain.DomainObjBaseModel --mappedSuperclass --persistenceUnit app --transactionManager appTransactionManager

// After running the above command, I manually add the following stuff in DomainObjBaseModel, because I don't know how to customise the roo auto generate stuff
    @Id @GeneratedValue(generator="system-uuid")
    @GenericGenerator(name="system-uuid", strategy = "uuid")
    @Column(unique = true, name = "id", nullable = false, length=32)
    private String id;
// After this action, I continue run the following commands.

entity --class ~.app.domain.Application --extends com.crazysoft.web.app.domain.DomainObjBaseModel --persistenceUnit app --transactionManager appTransactionManager --serializable --testAutomatically
repository jpa --interface ~.app.repository.ApplicationRepository --entity ~.app.domain.Application
service --interface ~.app.service.ApplicationService --entity ~.app.domain.Application

This is the configuration of the maven plugin:

<plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>2.3.2</version>
            <configuration>
                <source>1.6</source>
                <target>1.6</target>
                <encoding>UTF-8</encoding>
            </configuration>
        </plugin>

After I finish the above job, and run perform tests through STS roo shell, and I get the above error.

Is there anyone know that why this exception occurs? Do I do something wrong? And how to fix it?

Please help me!

Thank you in advance!


Solution

One or more tests are not working.

Have a look at the files located at: /Users/charlesli/Documents/workspace-spring/WebApplication/target/surefire-reports (usually the bigger files contain a problem)

There you will find the test results, and the test that is broken. The Stacktrace containing in this file will guide you to the problem.

(BTW: you can run the tests in eclipse via JUnit plugin (Package explorer, right click, run as JUnit) too, then you will see the stack trace in the IDE and do not need to search in the files.)


I guess, that the DB connection is not correct. But this is only a guess.



Answered By - Ralph
Answer Checked By - Gilberto Lyons (PHPFixing Admin)
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg
Older Posts Home

Total Pageviews

Featured Post

Why Learn PHP Programming

Why Learn PHP Programming A widely-used open source scripting language PHP is one of the most popular programming languages in the world. It...

Subscribe To

Posts
Atom
Posts
All Comments
Atom
All Comments

Copyright © PHPFixing