Java with MINIO file operations: upload, download, delete

If you have started working with MIN IO called as MINIO I guess you have heard enough about this. This is nothing but object storage service. Quoting from them
MinIO is a High Performance Object Storage released under Apache License v2.0. It is API compatible with Amazon S3 cloud storage service. Use MinIO to build high performance infrastructure for machine learning, analytics and application data workloads.
Today, we will see how to connect with minio, store documents as minio-object and get them from minio server with spring(java). Here, I should mention that their documentation is very good and you can achieve all these from them. But if you need live example code then you can follow here.

First of all, you need minio server running in your machine. If you are struggling with that check MinIO Quickstart Guide, pretty much straight forward. If it runs successfully, you will see a screen like this:


Check, you have got default accessKey and secretKey for starter. So, our minio server is ready to store document objects. Try localhost:minio . Create a bucket called bucket1 from right-bottom "+" option in which bucket we are going to add storage.

Let's dive into coding...
I am using java-8, in my gradle project with minio-server version 7.1.0
1. Minio configuration-properties file: application.properties file

minio.bucket.name=bucket1
minio.default.folder=/
minio.access.name=minioadmin
minio.access.secret=minioadmin
minio.url=http://127.0.0.1:9000


2. MinioConfig.java:

package com.tigerit.soa.config;

import io.minio.MinioClient;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * Created by DIPU on 7/22/20
 */
@Configuration
public class MinioConfig {

    @Value("${minio.access.name}")
    String accessKey;
    @Value("${minio.access.secret}")
    String accessSecret;
    @Value("${minio.url}")
    String minioUrl;


    @Bean
    public MinioClient generateMinioClient() {
        try {
            MinioClient client =
                    MinioClient.builder()
                            .endpoint(minioUrl)
                            .credentials(accessKey, accessSecret)
                            .build();
            return client;
        } catch (Exception e) {
            throw new RuntimeException(e.getMessage());
        }

    }
}

3. I am avoiding all the other stuffs-coding design not mandatory to  get into the core things. So providing only the relevant methods required

MinioServiceImpl.java


@Service
@Log4j2
public class MinioServiceImpl implements MinioService {

    @Autowired
    private MinioClient minioClient;

    @Value("${minio.bucket.name}")
    private String defaultBucketName;



 @Override
    public boolean uploadFile(String name, byte[] bytes) {

        try {

            ByteArrayInputStream byteArrayInputStream=new ByteArrayInputStream(bytes);
            minioClient.putObject(
                    PutObjectArgs.builder().bucket(defaultBucketName).object(name).stream(
                            byteArrayInputStream, bytes.length, -1)
                            .contentType("image/png")
                            .build());

            return true;
        }
        catch (Exception e)
        {
            log.error(e.getMessage());
        }
        return false;
    }

  @Override
    public byte[] getFile(String key) {

        try (InputStream stream = minioClient.getObject(
                GetObjectArgs.builder()
                        .bucket(defaultBucketName)
                        .object(key)
                        .build())) {
            byte[] content = IOUtils.toByteArray(stream);
            return content;
        }
        catch (Exception e) {
        e.printStackTrace();
    }
        return null;
    }

@Override
    public boolean deleteFile(String bucketName, String objectName) {

        try
        {
            minioClient.removeObject(
                    RemoveObjectArgs.builder()
                            .bucket(bucketName)
                            .object(objectName)
                            .build());

            return true;
        }
        catch (Exception e)
        {
            log.error("Err-deleteFile:"+ e.getMessage());
        }
        return false;
    }

}





4.Controller:

@PostMapping("/file/upload1")
public ResponseEntity<ServiceResponse> uploadFile(HttpServletRequest request,@RequestBody byte[] file,
               @RequestParam("fileName") String fileName)
 {
  log.info("fileName:"+ fileName);

  minioService.uploadByUpdatedAPI(fileName, file);
  return ResponseEntity.ok(new ServiceResponse());
 }

 In case, you want to upload multipart file:

@PostMapping(path = "/file/upload2", consumes = {MediaType.MULTIPART_FORM_DATA_VALUE})
public ResponseEntity<ServiceResponse> uploadFile2(HttpServletRequest request, @RequestPart(value = "file", required = false) MultipartFile files)
 {
  log.info("fileName:"+ files.getOriginalFilename());
//convert files.getInputStream() --> to byte[] and can call the same service
}


To get file in byte[]:

@GetMapping(path = "/file/download/{bucketName}/{fileName}")
public ResponseEntity<ServiceResponse> downLoadFileStream(HttpServletRequest request,
                 @PathVariable("bucketName") String bucketName, @PathVariable("fileName")String fileName)
 {
  log.info("fileName:{}, bucket: {}", fileName, bucketName);
  try
  {
   InputStream inputStream= minioService.getFileStream(bucketName, fileName);
   byte[] bytes= ByteStreams.toByteArray(inputStream);
   log.info("byteArray size:"+ bytes.length);
   ServiceResponse response=new ServiceResponse(HttpStatus.OK, StatusCode.SUCCESS, bytes, Collections.emptyList());

   return ResponseEntity.ok(response);
  }
  catch (Exception e)
  {
   log.error("minio test err:"+ e.getMessage());
  }
  return null;
 }


To delete a file:


@DeleteMapping(path = "/file/{bucketName}/{fileName}")
public ResponseEntity<ServiceResponse> deleteFile(HttpServletRequest request,
                 @PathVariable("bucketName") String bucketName, @PathVariable("fileName")String fileName)
 {
  log.info("fileName:{}, bucket: {}", fileName, bucketName);
  try
  {
   boolean bool=minioService.deleteFile(bucketName, fileName);
   ServiceResponse response=new ServiceResponse(HttpStatus.OK, StatusCode.SUCCESS, bool, Collections.emptyList());

   return ResponseEntity.ok(response);
  }
  catch (Exception e)
  {
   log.error("minio test err:"+ e.getMessage());
  }
  return null;
 }



5. Testing from Postman:


6. check from localhost:minio/bucket1


Similarly, you can test other apis for your own.

Will add the project later may be ?

---Happy Coding! ---

Comments

Popular posts from this blog

Spring Boot Scheduler for Distributed System: Using shedlock

Kafka Stream API: MySQL CDC to apache Kafka with debezium