spring-projects / spring-boot

Spring Boot
https://spring.io/projects/spring-boot
Apache License 2.0
74.57k stars 40.55k forks source link

spring boot azure storage and spring-boot-email-tools Failed to bind properties under 'azure.storage' to com.microsoft.azure.spring.autoconfigure.storage.StorageProperties: #14170

Closed peripurnama closed 6 years ago

peripurnama commented 6 years ago

I use spring boot 2.0.2. when I run the application spring boot in cmd with the mvn spring-boot: run command running smoothly, but when I export it to war and I run it on tomcat with the ROOT path I get the following error:

2018-08-22 17:21:17.312  INFO 10764 --- [ost-startStop-1] m.s.d.PriorityQueueEmailSchedulerService : Scheduled email Email{from=developerglob@gmail.com, to=[cisvapery@gmail.com], subject=Glob report buy point firetime \'2018-08-22T16:38+07:00\' and priority 1, body=, attachments=[report_buy_point pripurna bandung.csv], encoding=UTF-8} at UTC time [2018-08-22T16:38+07:00, 1] with priority {} with template
[WARN] AnnotationConfigServletWebServerApplicationContext - Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'storageAzureService': Unsatisfied dependency expressed through field 'cloudStorageAccount'; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'com.microsoft.azure.spring.autoconfigure.storage.StorageAutoConfiguration': Unsatisfied dependency expressed through constructor parameter 0; nested exception is org.springframework.boot.context.properties.ConfigurationPropertiesBindException: Error creating bean with name 'azure.storage-com.microsoft.azure.spring.autoconfigure.storage.StorageProperties': Could not bind properties to 'StorageProperties' : prefix=azure.storage, ignoreInvalidFields=false, ignoreUnknownFields=true; nested exception is org.springframework.boot.context.properties.bind.BindException: Failed to bind properties under 'azure.storage' to com.microsoft.azure.spring.autoconfigure.storage.StorageProperties
2018-08-22 17:21:18.183  INFO 10764 --- [ost-startStop-1] m.s.d.PriorityQueueEmailSchedulerService : Closing EmailScheduler
2018-08-22 17:21:18.185  INFO 10764 --- [ost-startStop-1] m.s.d.PriorityQueueEmailSchedulerService : Interrupting email scheduler consumer
Exception in thread "PriorityQueueEmailSchedulerService -- Consumer" org.springframework.mail.MailSendException: Mail server connection failed; nested exception is javax.mail.MessagingException: Could not convert socket to TLS;
  nested exception is:
        javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target. Failed messages: javax.mail.MessagingException: Could not convert socket to TLS;
  nested exception is:
        javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target; message exception details (1) are:
Failed message 1:
javax.mail.MessagingException: Could not convert socket to TLS;
  nested exception is:
        javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
        at com.sun.mail.smtp.SMTPTransport.startTLS(SMTPTransport.java:2155)
        at com.sun.mail.smtp.SMTPTransport.protocolConnect(SMTPTransport.java:752)
        at javax.mail.Service.connect(Service.java:366)
        at org.springframework.mail.javamail.JavaMailSenderImpl.connectTransport(JavaMailSenderImpl.java:515)
        at org.springframework.mail.javamail.JavaMailSenderImpl.doSend(JavaMailSenderImpl.java:435)
        at org.springframework.mail.javamail.JavaMailSenderImpl.send(JavaMailSenderImpl.java:359)
        at org.springframework.mail.javamail.JavaMailSenderImpl.send(JavaMailSenderImpl.java:354)
        at it.ozimov.springboot.mail.service.defaultimpl.DefaultEmailService.send(DefaultEmailService.java:138)
        at it.ozimov.springboot.mail.service.defaultimpl.PriorityQueueEmailSchedulerService$Consumer.run(PriorityQueueEmailSchedulerService.java:443)
Caused by: javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
        at sun.security.ssl.Alerts.getSSLException(Alerts.java:192)
        at sun.security.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1959)
        at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:328)
        at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:322)
        at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1614)
        at sun.security.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:216)
        at sun.security.ssl.Handshaker.processLoop(Handshaker.java:1052)
        at sun.security.ssl.Handshaker.process_record(Handshaker.java:987)
        at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:1072)
        at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1385)
        at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1413)
        at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1397)
        at com.sun.mail.util.SocketFetcher.configureSSLSocket(SocketFetcher.java:620)
        at com.sun.mail.util.SocketFetcher.startTLS(SocketFetcher.java:547)
        at com.sun.mail.smtp.SMTPTransport.startTLS(SMTPTransport.java:2150)
        ... 8 more
Caused by: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
        at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:397)
        at sun.security.validator.PKIXValidator.engineValidate(PKIXValidator.java:302)
        at sun.security.validator.Validator.validate(Validator.java:260)
        at sun.security.ssl.X509TrustManagerImpl.validate(X509TrustManagerImpl.java:324)
        at sun.security.ssl.X509TrustManagerImpl.checkTrusted(X509TrustManagerImpl.java:229)
        at sun.security.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:124)
        at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1596)
        ... 18 more
Caused by: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
        at sun.security.provider.certpath.SunCertPathBuilder.build(SunCertPathBuilder.java:141)
        at sun.security.provider.certpath.SunCertPathBuilder.engineBuild(SunCertPathBuilder.java:126)
        at java.security.cert.CertPathBuilder.build(CertPathBuilder.java:280)
        at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:392)
        ... 24 more
2018-08-22 17:21:39.400  INFO 10764 --- [ost-startStop-1] m.s.d.PriorityQueueEmailSchedulerService : Closed EmailScheduler
[INFO] LocalContainerEntityManagerFactoryBean - Closing JPA EntityManagerFactory for persistence unit 'default'
2018-08-22 17:21:39.431  INFO 10764 --- [ost-startStop-1] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Shutdown initiated...
2018-08-22 17:21:39.437  INFO 10764 --- [ost-startStop-1] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Shutdown completed.
[INFO] ConditionEvaluationReportLoggingListener -

Error starting ApplicationContext. To display the conditions report re-run your application with 'debug' enabled.
[ERROR] LoggingFailureAnalysisReporter -
***************************
APPLICATION FAILED TO START
***************************

Description:

Failed to bind properties under 'azure.storage' to com.microsoft.azure.spring.autoconfigure.storage.StorageProperties:

    Property: azure.storage.connection-string
    Value: DefaultEndpointsProtocol=https;EndpointSuffix=core.windows.net;AccountName=globimage;AccountKey=j98PljOhAYdToMXHxFeLd5sC6afk1DMBeF8dfYETOYJU0j8AHp0Fkh3dgikoevByrkb2zCr4IwzST4HqjkBTUQ==
    Origin: class path resource [application.properties]:60:33
    Reason: HV000030: No validator could be found for constraint 'javax.validation.constraints.NotEmpty' validating type 'java.lang.String'. Check configuration for 'connectionString'

Action:

Update your application's configuration

even though the application properties are correct application.properties:

#Server konfiguration port
server.port=8087
#spring.resources.static-locations[0]=file:src/main/resources/static/
#spring.resources.static-locations[1]=classpath:/static/

#JPA Konfiguration
spring.datasource.url=jdbc:sqlserver://52.230.65.127;databaseName=globdbreview
spring.datasource.username=sa
spring.datasource.password=Develasas
spring.datasource.driverClassName=com.microsoft.sqlserver.jdbc.SQLServerDriver
spring.jpa.show-sql=true
spring.jpa.hibernate.ddl-auto = update
spring.jpa.properties.hibernate.legacy_limit_handler=true

#SQL Server JPA konfiguration
spring.jpa.properties.hibernate.dialect=com.bridgetech.glob.model.SQLServerNativeDialect
spring.jpa.hibernate.naming.implicit-strategy=org.hibernate.boot.model.naming.ImplicitNamingStrategyLegacyJpaImpl
spring.jpa.hibernate.naming.physical-strategy=org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl

#default JSP
#spring.mvc.view.prefix=/WEB-INF/jsp/
#spring.mvc.view.suffix=.jsp

#Logging
logging.level.org.springframework.web=INFO

#Thymeleaf konfiguration
spring.thymeleaf.cache=false

# Specify the Lucene Directory
#spring.jpa.properties.hibernate.search.default.directory_provider = filesystem

# Using the filesystem DirectoryProvider you also have to specify the default
# base directory for all indexes 
#spring.jpa.properties.hibernate.search.default.indexBase = indexpath

#Smtp mail konfiguration
spring.mail.default-encoding=UTF-8
spring.mail.host=smtp.gmail.com
spring.mail.username=developerglobsa@gmail.com
spring.mail.password=@asdadsadsa
spring.mail.port=587
spring.mail.protocol=smtp
spring.mail.test-connection=false
spring.mail.properties.mail.smtp.auth=true
spring.mail.properties.mail.smtp.starttls.enable=true

#upload file
#spring.servlet.multipart.max-file-size=50mb
#spring.servlet.multipart.max-request-size=50mb

spring.mail.scheduler.enabled=true
spring.mail.scheduler.priorityLevels=5

spring.mail.scheduler.persistence.enabled=false
spring.mail.scheduler.persistence.redis.embedded=false
spring.mail.scheduler.persistence.redis.enabled=false

#azure storage
azure.storage.connection-string=DefaultEndpointsProtocol=https;EndpointSuffix=core.windows.net;AccountName=globim;AccountKey=j98PljOhAYdToMXHxFeLd5sC6afk1DMBeF8dfYETOYJU0j8AHp0Fkh3dgik

StorageAzureService:

@Service
public class StorageAzureService {

    @Autowired
    private CloudStorageAccount cloudStorageAccount;

    public static final String storageConnectionString = "DefaultEndpointsProtocol=[http|https];EndpointSuffix=core.windows.net;AccountName=globimage;AccountKey=j98PljOhAYdToMXHxFeLd5sC6afk1DMBeF8dfYETOYJU0j8AHp0Fkh3dgikoevByrkb2zCr4IwzST4HqjkBTUQ==";

    final String containerName = "image";

    public StorageAzureService() {
//      try {
//          cloudStorageAccount = CloudStorageAccount.parse(storageConnectionString);
//      } catch (InvalidKeyException e) {
//          // TODO Auto-generated catch block
//          e.printStackTrace();
//      } catch (URISyntaxException e) {
//          // TODO Auto-generated catch block
//          e.printStackTrace();
//      }
        // TODO Auto-generated constructor stub
    }

    public void createContainerIfNotExists() {
        try {
            // Create a blob client.
            final CloudBlobClient blobClient = cloudStorageAccount.createCloudBlobClient();
            // Get a reference to a container. (Name must be lower case.)
            final CloudBlobContainer container = blobClient.getContainerReference(containerName);
            // Create the container if it does not exist.
            if (container.createIfNotExists()) {
                System.out.println("True: " + containerName);
            } else {
                System.out.println("False: " + containerName);
            }
        } catch (Exception e) {
            // Output the stack trace.
            e.printStackTrace();
        }
    }

    public String uploadTextBlob(MultipartFile file, String fileName) {
        try {

            // Create a blob client.
            final CloudBlobClient blobClient = cloudStorageAccount.createCloudBlobClient();
            // Get a reference to a container. (Name must be lower case.)
            final CloudBlobContainer container = blobClient.getContainerReference(containerName);
            // Get a blob reference for a text file.
            CloudBlockBlob blob = container.getBlockBlobReference(fileName);
            // Upload some text into the blob.
            blob.upload(file.getInputStream(), file.getSize());
            System.out.println("success upload." + blob.getUri().toString());
            return blob.getUri().toString();
        } catch (Exception e) {
            // Output the stack trace.
            e.printStackTrace();
        }
        return null;
    }

    public void deleteTextBlob(String fileName) {
        try {
            if (fileName.startsWith("https://globimage.blob.core.windows.net/glob-images/")) {
                System.out.println("True: https://globimage.blob.core.windows.net/glob-images/");
                String fileNameImgGlob = fileName.substring(52);
                // Create a blob client.
                final CloudBlobClient blobClient = cloudStorageAccount.createCloudBlobClient();
                // Get a reference to a container. (Name must be lower case.)
                final CloudBlobContainer container = blobClient.getContainerReference(containerName);
                // Get a blob reference for a text file.
                CloudBlockBlob blob = container.getBlockBlobReference(fileNameImgGlob);
                // Upload some text into the blob.
                if (blob.exists()) {
                    blob.deleteIfExists();
                    System.out.println("success delete." + blob.getUri().toString());
                } else {
                    System.out.println("file not found.");
                }
            }
        } catch (Exception e) {
            // Output the stack trace.
            e.printStackTrace();
        }
    }

    public void deleteShareFile() {

        try {

            // Create the file client.
            CloudFileClient fileClient = cloudStorageAccount.createCloudFileClient();

            // Get a reference to the file share
            CloudFileShare share = fileClient.getShareReference("sampleshare");

            if (share.deleteIfExists()) {
                System.out.println("sampleshare deleted");
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    public void createDirectory() {

        try {
            // Create the file client.
            CloudFileClient fileClient = cloudStorageAccount.createCloudFileClient();

            // Get a reference to the file share
            CloudFileShare share = fileClient.getShareReference("sampleshare");

            // Get a reference to the root directory for the share.
            CloudFileDirectory rootDir = share.getRootDirectoryReference();

            // Get a reference to the sampledir directory
            CloudFileDirectory sampleDir = rootDir.getDirectoryReference("sampledir");

            if (sampleDir.createIfNotExists()) {
                System.out.println("sampledir created");
            } else {
                System.out.println("sampledir already exists");
            }
        } catch (Exception e) {
            // TODO: handle exception
        }

    }

    public void deleteDirectory() {
        try {
            // Create the file client.
            CloudFileClient fileClient = cloudStorageAccount.createCloudFileClient();

            // Get a reference to the file share
            CloudFileShare share = fileClient.getShareReference("sampleshare");

            // Get a reference to the root directory for the share.
            CloudFileDirectory rootDir = share.getRootDirectoryReference();

            // Get a reference to the directory you want to delete
            CloudFileDirectory containerDir = rootDir.getDirectoryReference("sampledir");

            // Delete the directory
            if (containerDir.deleteIfExists()) {
                System.out.println("Directory deleted");
            }
        } catch (Exception e) {
            // TODO: handle exception
        }
    }

    public void listFilesAndDirectories() {
        try {
            // Create the file client.
            CloudFileClient fileClient = cloudStorageAccount.createCloudFileClient();

            // Get a reference to the file share
            CloudFileShare share = fileClient.getShareReference(containerName);
            // Get a reference to the root directory for the share.
            CloudFileDirectory rootDir = share.getRootDirectoryReference();

            for (ListFileItem fileItem : rootDir.listFilesAndDirectories()) {
                System.out.println(fileItem.getUri());
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public void uploadFile() {
        try {
            // Create the file client.
            CloudFileClient fileClient = cloudStorageAccount.createCloudFileClient();

            // Get a reference to the file share
            CloudFileShare share = fileClient.getShareReference("share-images");

            if (share.createIfNotExists()) {
                System.out.println("New share created");
            }

            // Get a reference to the root directory for the share.
            CloudFileDirectory rootDir = share.getRootDirectoryReference();

            // Define the path to a local file.
            final String filePath = "D:\\uploads\\my.jpg";

            CloudFile cloudFile = rootDir.getFileReference("my.jpg");
            cloudFile.uploadFromFile(filePath);
        } catch (Exception e) {
            // TODO: handle exception
            System.out.println(e.getMessage());
        }
    }

    public void downloadFile() {
        try {
            // Create the file client.
            CloudFileClient fileClient = cloudStorageAccount.createCloudFileClient();

            // Get a reference to the file share
            CloudFileShare share = fileClient.getShareReference("sampleshare");

            // Get a reference to the root directory for the share.
            CloudFileDirectory rootDir = share.getRootDirectoryReference();

            // Get a reference to the directory that contains the file
            CloudFileDirectory sampleDir = rootDir.getDirectoryReference("sampledir");

            // Get a reference to the file you want to download
            CloudFile file = sampleDir.getFileReference("SampleFile.txt");

            // Write the contents of the file to the console.
            System.out.println(file.downloadText());
        } catch (Exception e) {
            // TODO: handle exception
        }
    }

    public void deleteFile2() {
        try {
            // Create the file client.
            CloudFileClient fileClient = cloudStorageAccount.createCloudFileClient();

            // Get a reference to the file share
            CloudFileShare share = fileClient.getShareReference("sampleshare");

            // Get a reference to the root directory for the share.
            CloudFileDirectory rootDir = share.getRootDirectoryReference();

            // Get a reference to the directory where the file to be deleted is in
            CloudFileDirectory containerDir = rootDir.getDirectoryReference("sampledir");

            String filename = "SampleFile.txt";
            CloudFile file;

            file = containerDir.getFileReference(filename);
            if (file.deleteIfExists()) {
                System.out.println(filename + " was deleted");
            }
        } catch (Exception e) {
            // TODO: handle exception
        }
    }

}

I use spring boot 2.0.2. when I run the application spring boot in cmd with the mvn spring-boot: run command running smoothly, but when I export it to war and I run it on tomcat with the ROOT path I get the following error:

2018-08-22 17:21:17.312  INFO 10764 --- [ost-startStop-1] m.s.d.PriorityQueueEmailSchedulerService : Scheduled email Email{from=developerglob@gmail.com, to=[cisvapery@gmail.com], subject=Glob report buy point firetime \'2018-08-22T16:38+07:00\' and priority 1, body=, attachments=[report_buy_point pripurna bandung.csv], encoding=UTF-8} at UTC time [2018-08-22T16:38+07:00, 1] with priority {} with template
[WARN] AnnotationConfigServletWebServerApplicationContext - Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'storageAzureService': Unsatisfied dependency expressed through field 'cloudStorageAccount'; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'com.microsoft.azure.spring.autoconfigure.storage.StorageAutoConfiguration': Unsatisfied dependency expressed through constructor parameter 0; nested exception is org.springframework.boot.context.properties.ConfigurationPropertiesBindException: Error creating bean with name 'azure.storage-com.microsoft.azure.spring.autoconfigure.storage.StorageProperties': Could not bind properties to 'StorageProperties' : prefix=azure.storage, ignoreInvalidFields=false, ignoreUnknownFields=true; nested exception is org.springframework.boot.context.properties.bind.BindException: Failed to bind properties under 'azure.storage' to com.microsoft.azure.spring.autoconfigure.storage.StorageProperties
2018-08-22 17:21:18.183  INFO 10764 --- [ost-startStop-1] m.s.d.PriorityQueueEmailSchedulerService : Closing EmailScheduler
2018-08-22 17:21:18.185  INFO 10764 --- [ost-startStop-1] m.s.d.PriorityQueueEmailSchedulerService : Interrupting email scheduler consumer
Exception in thread "PriorityQueueEmailSchedulerService -- Consumer" org.springframework.mail.MailSendException: Mail server connection failed; nested exception is javax.mail.MessagingException: Could not convert socket to TLS;
  nested exception is:
        javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target. Failed messages: javax.mail.MessagingException: Could not convert socket to TLS;
  nested exception is:
        javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target; message exception details (1) are:
Failed message 1:
javax.mail.MessagingException: Could not convert socket to TLS;
  nested exception is:
        javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
        at com.sun.mail.smtp.SMTPTransport.startTLS(SMTPTransport.java:2155)
        at com.sun.mail.smtp.SMTPTransport.protocolConnect(SMTPTransport.java:752)
        at javax.mail.Service.connect(Service.java:366)
        at org.springframework.mail.javamail.JavaMailSenderImpl.connectTransport(JavaMailSenderImpl.java:515)
        at org.springframework.mail.javamail.JavaMailSenderImpl.doSend(JavaMailSenderImpl.java:435)
        at org.springframework.mail.javamail.JavaMailSenderImpl.send(JavaMailSenderImpl.java:359)
        at org.springframework.mail.javamail.JavaMailSenderImpl.send(JavaMailSenderImpl.java:354)
        at it.ozimov.springboot.mail.service.defaultimpl.DefaultEmailService.send(DefaultEmailService.java:138)
        at it.ozimov.springboot.mail.service.defaultimpl.PriorityQueueEmailSchedulerService$Consumer.run(PriorityQueueEmailSchedulerService.java:443)
Caused by: javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
        at sun.security.ssl.Alerts.getSSLException(Alerts.java:192)
        at sun.security.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1959)
        at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:328)
        at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:322)
        at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1614)
        at sun.security.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:216)
        at sun.security.ssl.Handshaker.processLoop(Handshaker.java:1052)
        at sun.security.ssl.Handshaker.process_record(Handshaker.java:987)
        at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:1072)
        at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1385)
        at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1413)
        at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1397)
        at com.sun.mail.util.SocketFetcher.configureSSLSocket(SocketFetcher.java:620)
        at com.sun.mail.util.SocketFetcher.startTLS(SocketFetcher.java:547)
        at com.sun.mail.smtp.SMTPTransport.startTLS(SMTPTransport.java:2150)
        ... 8 more
Caused by: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
        at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:397)
        at sun.security.validator.PKIXValidator.engineValidate(PKIXValidator.java:302)
        at sun.security.validator.Validator.validate(Validator.java:260)
        at sun.security.ssl.X509TrustManagerImpl.validate(X509TrustManagerImpl.java:324)
        at sun.security.ssl.X509TrustManagerImpl.checkTrusted(X509TrustManagerImpl.java:229)
        at sun.security.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:124)
        at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1596)
        ... 18 more
Caused by: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
        at sun.security.provider.certpath.SunCertPathBuilder.build(SunCertPathBuilder.java:141)
        at sun.security.provider.certpath.SunCertPathBuilder.engineBuild(SunCertPathBuilder.java:126)
        at java.security.cert.CertPathBuilder.build(CertPathBuilder.java:280)
        at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:392)
        ... 24 more
2018-08-22 17:21:39.400  INFO 10764 --- [ost-startStop-1] m.s.d.PriorityQueueEmailSchedulerService : Closed EmailScheduler
[INFO] LocalContainerEntityManagerFactoryBean - Closing JPA EntityManagerFactory for persistence unit 'default'
2018-08-22 17:21:39.431  INFO 10764 --- [ost-startStop-1] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Shutdown initiated...
2018-08-22 17:21:39.437  INFO 10764 --- [ost-startStop-1] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Shutdown completed.
[INFO] ConditionEvaluationReportLoggingListener -

Error starting ApplicationContext. To display the conditions report re-run your application with 'debug' enabled.
[ERROR] LoggingFailureAnalysisReporter -
***************************
APPLICATION FAILED TO START
***************************

Description:

Failed to bind properties under 'azure.storage' to com.microsoft.azure.spring.autoconfigure.storage.StorageProperties:

    Property: azure.storage.connection-string
    Value: DefaultEndpointsProtocol=https;EndpointSuffix=core.windows.net;AccountName=globimage;AccountKey=j98PljOhAYdToMXHxFeLd5sC6afk1DMBeF8dfYETOYJU0j8AHp0Fkh3dgikoevByrkb2zCr4IwzST4HqjkBTUQ==
    Origin: class path resource [application.properties]:60:33
    Reason: HV000030: No validator could be found for constraint 'javax.validation.constraints.NotEmpty' validating type 'java.lang.String'. Check configuration for 'connectionString'

Action:

Update your application's configuration

even though the application properties are correct application.properties:

#Server konfiguration port
server.port=8087
#spring.resources.static-locations[0]=file:src/main/resources/static/
#spring.resources.static-locations[1]=classpath:/static/

#JPA Konfiguration
spring.datasource.url=jdbc:sqlserver://52.230.65.127;databaseName=globdbreview
spring.datasource.username=sa
spring.datasource.password=Develasas
spring.datasource.driverClassName=com.microsoft.sqlserver.jdbc.SQLServerDriver
spring.jpa.show-sql=true
spring.jpa.hibernate.ddl-auto = update
spring.jpa.properties.hibernate.legacy_limit_handler=true

#SQL Server JPA konfiguration
spring.jpa.properties.hibernate.dialect=com.bridgetech.glob.model.SQLServerNativeDialect
spring.jpa.hibernate.naming.implicit-strategy=org.hibernate.boot.model.naming.ImplicitNamingStrategyLegacyJpaImpl
spring.jpa.hibernate.naming.physical-strategy=org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl

#default JSP
#spring.mvc.view.prefix=/WEB-INF/jsp/
#spring.mvc.view.suffix=.jsp

#Logging
logging.level.org.springframework.web=INFO

#Thymeleaf konfiguration
spring.thymeleaf.cache=false

# Specify the Lucene Directory
#spring.jpa.properties.hibernate.search.default.directory_provider = filesystem

# Using the filesystem DirectoryProvider you also have to specify the default
# base directory for all indexes 
#spring.jpa.properties.hibernate.search.default.indexBase = indexpath

#Smtp mail konfiguration
spring.mail.default-encoding=UTF-8
spring.mail.host=smtp.gmail.com
spring.mail.username=developerglobsa@gmail.com
spring.mail.password=@asdadsadsa
spring.mail.port=587
spring.mail.protocol=smtp
spring.mail.test-connection=false
spring.mail.properties.mail.smtp.auth=true
spring.mail.properties.mail.smtp.starttls.enable=true

#upload file
#spring.servlet.multipart.max-file-size=50mb
#spring.servlet.multipart.max-request-size=50mb

spring.mail.scheduler.enabled=true
spring.mail.scheduler.priorityLevels=5

spring.mail.scheduler.persistence.enabled=false
spring.mail.scheduler.persistence.redis.embedded=false
spring.mail.scheduler.persistence.redis.enabled=false

#azure storage
azure.storage.connection-string=DefaultEndpointsProtocol=https;EndpointSuffix=core.windows.net;AccountName=globim;AccountKey=j98PljOhAYdToMXHxFeLd5sC6afk1DMBeF8dfYETOYJU0j8AHp0Fkh3dgik
StorageAzureService:
@Service
public class StorageAzureService {

    @Autowired
    private CloudStorageAccount cloudStorageAccount;

    public static final String storageConnectionString = "DefaultEndpointsProtocol=[http|https];EndpointSuffix=core.windows.net;AccountName=globimage;AccountKey=j98PljOhAYdToMXHxFeLd5sC6afk1DMBeF8dfYETOYJU0j8AHp0Fkh3dgikoevByrkb2zCr4IwzST4HqjkBTUQ==";

    final String containerName = "image";

    public StorageAzureService() {
//      try {
//          cloudStorageAccount = CloudStorageAccount.parse(storageConnectionString);
//      } catch (InvalidKeyException e) {
//          // TODO Auto-generated catch block
//          e.printStackTrace();
//      } catch (URISyntaxException e) {
//          // TODO Auto-generated catch block
//          e.printStackTrace();
//      }
        // TODO Auto-generated constructor stub
    }

    public void createContainerIfNotExists() {
        try {
            // Create a blob client.
            final CloudBlobClient blobClient = cloudStorageAccount.createCloudBlobClient();
            // Get a reference to a container. (Name must be lower case.)
            final CloudBlobContainer container = blobClient.getContainerReference(containerName);
            // Create the container if it does not exist.
            if (container.createIfNotExists()) {
                System.out.println("True: " + containerName);
            } else {
                System.out.println("False: " + containerName);
            }
        } catch (Exception e) {
            // Output the stack trace.
            e.printStackTrace();
        }
    }

    public String uploadTextBlob(MultipartFile file, String fileName) {
        try {

            // Create a blob client.
            final CloudBlobClient blobClient = cloudStorageAccount.createCloudBlobClient();
            // Get a reference to a container. (Name must be lower case.)
            final CloudBlobContainer container = blobClient.getContainerReference(containerName);
            // Get a blob reference for a text file.
            CloudBlockBlob blob = container.getBlockBlobReference(fileName);
            // Upload some text into the blob.
            blob.upload(file.getInputStream(), file.getSize());
            System.out.println("success upload." + blob.getUri().toString());
            return blob.getUri().toString();
        } catch (Exception e) {
            // Output the stack trace.
            e.printStackTrace();
        }
        return null;
    }

    public void deleteTextBlob(String fileName) {
        try {
            if (fileName.startsWith("https://globimage.blob.core.windows.net/glob-images/")) {
                System.out.println("True: https://globimage.blob.core.windows.net/glob-images/");
                String fileNameImgGlob = fileName.substring(52);
                // Create a blob client.
                final CloudBlobClient blobClient = cloudStorageAccount.createCloudBlobClient();
                // Get a reference to a container. (Name must be lower case.)
                final CloudBlobContainer container = blobClient.getContainerReference(containerName);
                // Get a blob reference for a text file.
                CloudBlockBlob blob = container.getBlockBlobReference(fileNameImgGlob);
                // Upload some text into the blob.
                if (blob.exists()) {
                    blob.deleteIfExists();
                    System.out.println("success delete." + blob.getUri().toString());
                } else {
                    System.out.println("file not found.");
                }
            }
        } catch (Exception e) {
            // Output the stack trace.
            e.printStackTrace();
        }
    }

    public void deleteShareFile() {

        try {

            // Create the file client.
            CloudFileClient fileClient = cloudStorageAccount.createCloudFileClient();

            // Get a reference to the file share
            CloudFileShare share = fileClient.getShareReference("sampleshare");

            if (share.deleteIfExists()) {
                System.out.println("sampleshare deleted");
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    public void createDirectory() {

        try {
            // Create the file client.
            CloudFileClient fileClient = cloudStorageAccount.createCloudFileClient();

            // Get a reference to the file share
            CloudFileShare share = fileClient.getShareReference("sampleshare");

            // Get a reference to the root directory for the share.
            CloudFileDirectory rootDir = share.getRootDirectoryReference();

            // Get a reference to the sampledir directory
            CloudFileDirectory sampleDir = rootDir.getDirectoryReference("sampledir");

            if (sampleDir.createIfNotExists()) {
                System.out.println("sampledir created");
            } else {
                System.out.println("sampledir already exists");
            }
        } catch (Exception e) {
            // TODO: handle exception
        }

    }

    public void deleteDirectory() {
        try {
            // Create the file client.
            CloudFileClient fileClient = cloudStorageAccount.createCloudFileClient();

            // Get a reference to the file share
            CloudFileShare share = fileClient.getShareReference("sampleshare");

            // Get a reference to the root directory for the share.
            CloudFileDirectory rootDir = share.getRootDirectoryReference();

            // Get a reference to the directory you want to delete
            CloudFileDirectory containerDir = rootDir.getDirectoryReference("sampledir");

            // Delete the directory
            if (containerDir.deleteIfExists()) {
                System.out.println("Directory deleted");
            }
        } catch (Exception e) {
            // TODO: handle exception
        }
    }

    public void listFilesAndDirectories() {
        try {
            // Create the file client.
            CloudFileClient fileClient = cloudStorageAccount.createCloudFileClient();

            // Get a reference to the file share
            CloudFileShare share = fileClient.getShareReference(containerName);
            // Get a reference to the root directory for the share.
            CloudFileDirectory rootDir = share.getRootDirectoryReference();

            for (ListFileItem fileItem : rootDir.listFilesAndDirectories()) {
                System.out.println(fileItem.getUri());
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public void uploadFile() {
        try {
            // Create the file client.
            CloudFileClient fileClient = cloudStorageAccount.createCloudFileClient();

            // Get a reference to the file share
            CloudFileShare share = fileClient.getShareReference("share-images");

            if (share.createIfNotExists()) {
                System.out.println("New share created");
            }

            // Get a reference to the root directory for the share.
            CloudFileDirectory rootDir = share.getRootDirectoryReference();

            // Define the path to a local file.
            final String filePath = "D:\\uploads\\my.jpg";

            CloudFile cloudFile = rootDir.getFileReference("my.jpg");
            cloudFile.uploadFromFile(filePath);
        } catch (Exception e) {
            // TODO: handle exception
            System.out.println(e.getMessage());
        }
    }

    public void downloadFile() {
        try {
            // Create the file client.
            CloudFileClient fileClient = cloudStorageAccount.createCloudFileClient();

            // Get a reference to the file share
            CloudFileShare share = fileClient.getShareReference("sampleshare");

            // Get a reference to the root directory for the share.
            CloudFileDirectory rootDir = share.getRootDirectoryReference();

            // Get a reference to the directory that contains the file
            CloudFileDirectory sampleDir = rootDir.getDirectoryReference("sampledir");

            // Get a reference to the file you want to download
            CloudFile file = sampleDir.getFileReference("SampleFile.txt");

            // Write the contents of the file to the console.
            System.out.println(file.downloadText());
        } catch (Exception e) {
            // TODO: handle exception
        }
    }

    public void deleteFile2() {
        try {
            // Create the file client.
            CloudFileClient fileClient = cloudStorageAccount.createCloudFileClient();

            // Get a reference to the file share
            CloudFileShare share = fileClient.getShareReference("sampleshare");

            // Get a reference to the root directory for the share.
            CloudFileDirectory rootDir = share.getRootDirectoryReference();

            // Get a reference to the directory where the file to be deleted is in
            CloudFileDirectory containerDir = rootDir.getDirectoryReference("sampledir");

            String filename = "SampleFile.txt";
            CloudFile file;

            file = containerDir.getFileReference(filename);
            if (file.deleteIfExists()) {
                System.out.println(filename + " was deleted");
            }
        } catch (Exception e) {
            // TODO: handle exception
        }
    }

}
GlobApplication:

@ComponentScan(basePackages = "com.bridgetech.glob")
@SpringBootApplication
@EnableEmailTools
public class GlobApplication
//implements ApplicationContextAware
{

    @Autowired
    EmailSenderService emailSenderService;
//  
//  private ApplicationContext applicationContext;

    @Bean
    WebMvcConfigurer configurer() {
        return new WebMvcConfigurer() {
            @Override
            public void addResourceHandlers(ResourceHandlerRegistry registry) {
                registry.addResourceHandler("/static/**").addResourceLocations("classpath:/static/");
            }
        };
    }

    public static void main(String[] args) {
        SpringApplication.run(GlobApplication.class, args);
    }

//  @Override
//  public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
//      this.applicationContext = applicationContext;
//  }
//
    @PostConstruct
    public void sendEmail() throws UnsupportedEncodingException, InterruptedException, CannotSendEmailException, URISyntaxException {
        emailSenderService.scheduleSixEmails(1);

//      close();
    }

//  private void close() {
//      TimerTask shutdownTask = new TimerTask() {
//          @Override
//          public void run() {
//              ((AbstractApplicationContext) applicationContext).close();
//          }
//      };
//      Timer shutdownTimer = new Timer();
//      shutdownTimer.schedule(shutdownTask, TimeUnit.SECONDS.toMillis(20));
//  }

}

pom.xml:

<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.bridgetech</groupId>
    <artifactId>glob</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>war</packaging>

    <name>glob</name>
    <description>Demo project for Spring Boot</description>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.0.2.RELEASE</version>
        <relativePath /> <!-- lookup parent from repository -->
    </parent>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
        <azure.version>2.0.4</azure.version>
    </properties>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>com.microsoft.azure</groupId>
                <artifactId>azure-spring-boot-bom</artifactId>
                <version>${azure.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <dependencies>
        <dependency>
            <groupId>com.microsoft.azure</groupId>
            <artifactId>azure-storage-spring-boot-starter</artifactId>
        </dependency>
        <dependency>
            <groupId>org.json</groupId>
            <artifactId>json</artifactId>
            <version>20180130</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <!-- <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> 
            <scope>runtime</scope> </dependency> -->
        <dependency>
            <groupId>com.microsoft.sqlserver</groupId>
            <artifactId>mssql-jdbc</artifactId>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-tomcat</artifactId>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>jstl</artifactId>
        </dependency>

        <dependency>
            <groupId>org.apache.tomcat.embed</groupId>
            <artifactId>tomcat-embed-jasper</artifactId>
            <scope>provided</scope>
        </dependency>

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

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

        <dependency>
            <groupId>org.hibernate.validator</groupId>
            <artifactId>hibernate-validator</artifactId>
        </dependency>

        <dependency>
            <groupId>commons-beanutils</groupId>
            <artifactId>commons-beanutils</artifactId>
            <version>1.9.3</version>
        </dependency>

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

        <dependency>
            <groupId>com.icegreen</groupId>
            <artifactId>greenmail</artifactId>
            <version>1.5.5</version>
            <scope>test</scope>
        </dependency>

        <!-- bootstrap and jquery -->
        <dependency>
            <groupId>org.webjars</groupId>
            <artifactId>bootstrap</artifactId>
            <version>3.3.7</version>
        </dependency>
        <dependency>
            <groupId>org.webjars</groupId>
            <artifactId>jquery</artifactId>
            <version>3.2.1</version>
        </dependency>

        <!-- https://mvnrepository.com/artifact/org.apache.poi/poi -->
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi</artifactId>
            <version>3.17</version>
        </dependency>

        <!-- https://mvnrepository.com/artifact/com.lowagie/itext -->
        <dependency>
            <groupId>com.lowagie</groupId>
            <artifactId>itext</artifactId>
            <version>2.1.7</version>
        </dependency>

        <dependency>
            <groupId>javax.xml.bind</groupId>
            <artifactId>jaxb-api</artifactId>
        </dependency>

        <dependency>
            <groupId>org.eclipse.persistence</groupId>
            <artifactId>eclipselink</artifactId>
            <version>2.7.0</version>
        </dependency>

        <!-- https://mvnrepository.com/artifact/org.springframework/spring-webmvc -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
        </dependency>

        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-lang3</artifactId>
        </dependency>

        <!-- https://mvnrepository.com/artifact/com.itextpdf/itextpdf -->
        <dependency>
            <groupId>com.itextpdf</groupId>
            <artifactId>itextpdf</artifactId>
            <version>5.5.13</version>
        </dependency>

        <dependency>
            <groupId>org.json</groupId>
            <artifactId>json</artifactId>
            <version>20160810</version>
        </dependency>

        <dependency>
            <groupId>com.google.firebase</groupId>
            <artifactId>firebase-admin</artifactId>
            <version>5.9.0</version>
        </dependency>

        <dependency>
            <groupId>it.ozimov</groupId>
            <artifactId>spring-boot-email-core</artifactId>
            <version>0.6.3</version>
        </dependency>

        <dependency>
            <groupId>it.ozimov</groupId>
            <artifactId>spring-boot-freemarker-email</artifactId>
            <version>0.6.3</version>
        </dependency>

        <!-- <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-configuration-processor</artifactId>
            <optional>true</optional>
        </dependency> -->
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-resources-plugin</artifactId>
                <configuration>
                    <nonFilteredFileExtensions>
                        <nonFilteredFileExtension>ttf</nonFilteredFileExtension>
                        <nonFilteredFileExtension>woff</nonFilteredFileExtension>
                        <nonFilteredFileExtension>woff2</nonFilteredFileExtension>
                    </nonFilteredFileExtensions>
                </configuration>
            </plugin>

        </plugins>
    </build>

</project>

emailservice:

@Service
public class EmailSenderService {

    @Autowired
    private EmailSchedulerService emailSchedulerService;

    @Autowired
    private ConfigPointRepository configPointRepository;

    @Autowired
    private MerchantRepository merchantRepository;

    @Autowired
    private RequestPointRepository requestPointRepository;

    public void scheduleSixEmails(int priority) throws UnsupportedEncodingException, CannotSendEmailException, URISyntaxException {
        OffsetDateTime now = OffsetDateTime.now();
        Date waktuSekarang = new Date();
        OffsetDateTime whenFirstGroup = now.plusSeconds(60*5);
        OffsetDateTime whenSecondGroup = now.plusSeconds(10);
        OffsetDateTime whenThirdGroup = now.plusSeconds(15);

        ConfigPoint cp =configPointRepository.findById("50521216-0918-42E9-A240-A593E8A6569E").get();
        Date date = cp.getSchedulerReportOfTime();
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);

        OffsetDateTime o = OffsetDateTime.of(LocalDate.now(),LocalTime.of(cal.get(Calendar.HOUR_OF_DAY), cal.get(Calendar.MINUTE), cal.get(Calendar.SECOND)), now.getOffset());

        System.out.println("===============");
        System.out.println(now.getDayOfMonth());
        System.out.println(now.getHour());
        System.out.println(now.getMinute());
        System.out.println(now.getSecond());
        System.out.println(now.plusSeconds(60));
        System.out.println("===============");
        System.out.println(o.getDayOfMonth());
        System.out.println(o.getHour());
        System.out.println(o.getMinute());
        System.out.println(o.getSecond());
        System.out.println(o.plusSeconds(60));
        System.out.println("===============");
//        schedulePlainTextEmail(o, 1);
        scheduleMimeEmail(o, priority);
//        schedulePlainTextEmail(now.plusSeconds(60), 2);
//        schedulePlainTextEmail(whenFirstGroup, 2);
//        schedulePlainTextEmail(whenFirstGroup, 1);
//        schedulePlainTextEmail(whenSecondGroup, 1);
//        schedulePlainTextEmail(whenSecondGroup, 2);
//        schedulePlainTextEmail(whenThirdGroup, 2);
//        schedulePlainTextEmail(whenThirdGroup, 1);
    }

    private void schedulePlainTextEmail(OffsetDateTime when, int priority) throws UnsupportedEncodingException {
        final Email email = DefaultEmail.builder()
                .from(new InternetAddress("developerglob@gmail.com",
                        "Glob Report"))
                .to(newArrayList(
                        new InternetAddress("cisvapery@gmail.com",
                                "Cleon I")))
                .subject(String.format("Email scheduled with firetime '%s' and priority %d", when, priority))
                .body("Hello Planet!")
                .encoding("UTF-8").build();

        emailSchedulerService.schedule(email, when, priority);
    }

    private void scheduleMimeEmail(OffsetDateTime when, int priority) throws UnsupportedEncodingException, CannotSendEmailException, URISyntaxException {
        InlinePicture inlinePicture = createGalaxyInlinePicture();

        List<EmailAttachment> emailAttachments = new ArrayList<>();
        List<InternetAddress> internetAddress = new ArrayList<>();

        OffsetDateTime now = OffsetDateTime.now();
        OffsetDateTime startDateTime = OffsetDateTime.of(LocalDate.now(),LocalTime.of(0, 0, 0), now.getOffset());
        OffsetDateTime endDateTime = OffsetDateTime.of(LocalDate.now(),LocalTime.of(23, 59, 59), now.getOffset());

        Date d1 = Date.from(startDateTime.toInstant());
        Date d2 = Date.from(endDateTime.toInstant());

        System.out.println(new SimpleDateFormat("dd/MMMM/yyyy HH:mm:ss").format(d1));

        List<MerchantDto> listMerchant = new ArrayList<>();
        merchantRepository.findAllMerchantDto().stream().forEach(listMerchant::add);

        Set<String> merchantRequestPoint = new HashSet<>();

        for (MerchantDto merchantDto : listMerchant) {
            requestPointRepository.requestPointDtoFindByBetweenDateByMerchant(d1, d2 , merchantDto.getId()).stream().forEach(merchantRequestPoint::add);;
        }

        FormatCurrencyIndonesia fci = new FormatCurrencyIndonesia();

        System.out.println("Size of merchant in request point: " + merchantRequestPoint.size());

        String data = "Here are your purchase points today:\nFullname, Point, Nominal(Rp), PricePerPoint(Rp)\n";
        Iterator<String> it = merchantRequestPoint.iterator();
        while (it.hasNext()) {
            String merchantId = (String) it.next();
            MerchantDto m = merchantRepository.findById2(merchantId);

            System.out.println("merchant: " + m.getFullName());

            List<RequestPointDto> requestPointDto = new ArrayList<>();
            requestPointRepository.listRequestPointDtoFindByBetweenDateByMerchant(d1, d2 , merchantId).stream().forEach(requestPointDto::add);

            System.out.println("size requestPointDto: " + requestPointDto.size());

            DefaultEmailAttachment attachment = null;

            Long sumPoint = 0l;

            List<BigDecimal> listNominalReqPoint = new ArrayList<>();

            for (RequestPointDto rp : requestPointDto) {
                data += rp.getMerchantFullName() + "," + rp.getPoint() + "," + rp.getNominal().intValue() + ", " + rp.getPricePerPoint().intValue() + " \n";
                sumPoint += rp.getPoint();
                listNominalReqPoint.add(rp.getNominal());
            }

            BigDecimal sumNominal = listNominalReqPoint.stream().reduce(BigDecimal.ZERO, BigDecimal::add);

            data += " Total price: " + sumNominal.intValue() + "\n Total Point: " +  sumPoint.intValue() + "\n";

            System.out.println(data);

            attachment = DefaultEmailAttachment.builder()
                    .attachmentName("report_buy_point " + m.getFullName() + ".csv")
                    .attachmentData(data.getBytes(Charset.forName("UTF-8")))
                    .mediaType(MediaType.TEXT_PLAIN).build();

            final Email email = DefaultEmail.builder()
                    .from(new InternetAddress("developerglob@gmail.com", "Glob Report"))
                    .to(newArrayList(new InternetAddress(m.getEmail(), m.getFullName())))
                    .subject(String.format("Glob report buy point firetime '%s' and priority %d", when, priority))
                    .body("")
                    .attachment(attachment)
                    .encoding("UTF-8").build();
            String template = "report_scheduler/emailTemplate.ftl";

            Map<String, Object> modelObject = ImmutableMap.of(
                    "title", "Report From Buy Point Everyday",
                    "name", m.getFullName(),
                    "requestPointDto", requestPointDto,
                    "sumNominal", fci.formatCurrency(sumNominal),
                    "sumPoint", sumPoint.intValue()
            );
            emailSchedulerService.schedule(email, when, priority, template, modelObject, inlinePicture);

            data = "Here are your purchase points today:\nFullname, Point, Nominal(Rp), PricePerPoint(Rp)\n";
        }

    }

    private EmailAttachment getCsvForecastAttachment(String filename) {
        String data = "Here are your purchase points today:\n";
        List<MerchantDto> list = new ArrayList<>();
        merchantRepository.findAllMerchantDto().stream().forEach(list::add);
        int i = 1;
        for (MerchantDto o : list) {
            data += i + ","+o.getFullName() + "," + o.getUsername() + "," + o.getPhone() + "," + o.getEmail() + "," + o.getCategory().getName() + "\n";
            i++;
        }

        DefaultEmailAttachment attachment = null;
        attachment = DefaultEmailAttachment.builder()
                .attachmentName(filename)
                .attachmentData(data.getBytes(Charset.forName("UTF-8")))
                .mediaType(MediaType.TEXT_PLAIN).build();
        return attachment;
    }

    private InlinePicture createGalaxyInlinePicture() throws URISyntaxException {
        ClassLoader classLoader = getClass().getClassLoader();
        File pictureFile = new File(classLoader.getResource("images" + File.separator + "glob.png").toURI());
        System.out.println(pictureFile.exists());
        Preconditions.checkState(pictureFile.exists(), "There is not picture %s", pictureFile.getName());

        return DefaultInlinePicture.builder()
                .file(pictureFile)
                .imageType(ImageType.PNG)
                .templateName("glob.png").build();
    }

}
snicoll commented 6 years ago

Thanks for getting in touch, but it feels like this is a question that would be better suited to Stack Overflow. As mentioned in the guidelines for contributing, we prefer to use GitHub issues only for bugs and enhancements. Feel free to update this issue with a link to the re-posted question (so that other people can find it) or add some more details if you feel this is a genuine bug.

bclozel commented 6 years ago

Also, note that your question seems to reference credentials - you should now consider those as insecure and rotate them as soon as possible.