Minio
Step1 Add config file.
package org.demo.conf.cxbox.customization.file;
import io.minio.MinioClient;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class MinioFileConfig {
@Bean
public MinioClient minioClient(
@Value("${minio.access.name}") String accessKey,
@Value("${minio.access.secret}") String accessSecret,
@Value("${minio.url}") String minioUrl) {
return MinioClient.builder()
.endpoint(minioUrl)
.credentials(accessKey, accessSecret)
.build();
}
}
Step2 Add Controller for file storage.
package org.demo.conf.cxbox.customization.file;
import org.cxbox.core.file.controller.AbstractCxboxFileController;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import static org.cxbox.core.config.properties.APIProperties.CXBOX_API_PATH_SPEL;
@RestController
@RequestMapping(CXBOX_API_PATH_SPEL + "/file")
public class FileController extends AbstractCxboxFileController {
}
package org.demo.conf.cxbox.customization.file;
import io.minio.*;
import lombok.NonNull;
import lombok.RequiredArgsConstructor;
import lombok.SneakyThrows;
import org.cxbox.core.file.dto.FileDownloadDto;
import org.cxbox.core.file.service.CxboxFileService;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import java.util.Collections;
import java.util.UUID;
@Service
@RequiredArgsConstructor
public class FileService implements CxboxFileService {
public static final String FILENAME_FIELD = "filename";
public static final int FIVE_MIB = 5242880;
private final MinioClient minioClient;
@Value("${minio.bucket.name}")
private final String defaultBucketName;
@SneakyThrows
@Override
public <D extends FileDownloadDto> String upload(@NonNull D file, @Nullable String source) {
var contentType = file.getType();
var name = file.getName();
ObjectWriteResponse objectWriteResponse = minioClient.putObject(PutObjectArgs
.builder()
.bucket(defaultBucketName)
.object(UUID.randomUUID().toString())
.contentType(contentType)
.userMetadata(Collections.singletonMap(FILENAME_FIELD, name))
.stream(file.getContent().get(), -1, FIVE_MIB)
.build()
);
return objectWriteResponse.object();
}
@SneakyThrows
@Override
public FileDownloadDto download(@NonNull String id, @Nullable String source) {
StatObjectResponse statObjectResponse = minioClient.statObject(StatObjectArgs
.builder()
.bucket(defaultBucketName)
.object(id)
.build()
);
return new FileDownloadDto(
() -> getObject(id), statObjectResponse.size(),
statObjectResponse.userMetadata().get(FILENAME_FIELD),
statObjectResponse.contentType()
);
}
@SneakyThrows
private GetObjectResponse getObject(@NotNull String id) {
return minioClient.getObject(GetObjectArgs
.builder()
.bucket(defaultBucketName)
.object(id)
.build()
);
}
@SneakyThrows
@Override
public void remove(@NonNull String id, @Nullable String source) {
minioClient.removeObject(RemoveObjectArgs
.builder()
.bucket(defaultBucketName)
.object(id)
.build()
);
}
}
Step1 Add config file.
@Configuration
public class PlatformFileMinioConfig {
@Bean
public MinioClient minioClient(
@Value("${minio.access.name}") String accessKey,
@Value("${minio.access.secret}") String accessSecret,
@Value("${minio.url}") String minioUrl) {
return MinioClient.builder()
.endpoint(minioUrl)
.credentials(accessKey, accessSecret)
.build();
}
}
Step2 Add Controller for file storage.
public class PlatformMinioFileController {
public static final String FILENAME_FIELD = "filename";
public static final int FIVE_MIB = 5242880;
private final MinioClient minioClient;
private final String defaultBucketName;
public PlatformDemoMinioFileController(
MinioClient minioClient,
@Value("${minio.bucket.name}") String defaultBucketName
) {
this.minioClient = minioClient;
this.defaultBucketName = defaultBucketName;
}
@SneakyThrows
@PostMapping(consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
public PlatformResponseDTO<FileUploadDto> upload(MultipartFile file, String source) {
String contentType = file.getContentType();
String name = file.getOriginalFilename();
ObjectWriteResponse objectWriteResponse = minioClient.putObject(PutObjectArgs
.builder()
.bucket(defaultBucketName)
.object(UUID.randomUUID().toString())
.contentType(contentType)
.userMetadata(Collections.singletonMap(FILENAME_FIELD, name))
.stream(file.getInputStream(), -1, FIVE_MIB)
.build()
);
String id = objectWriteResponse.object();
return new PlatformResponseDTO<FileUploadDto>()
.setData(new FileUploadDto(id, name, contentType));
}
@SneakyThrows
@GetMapping
public ResponseEntity<StreamingResponseBody> download(String id, String source, boolean preview) {
GetObjectResponse getObjectResponse = minioClient.getObject(GetObjectArgs
.builder()
.bucket(defaultBucketName)
.object(id)
.build()
);
StatObjectResponse statObjectResponse = minioClient.statObject(StatObjectArgs
.builder()
.bucket(defaultBucketName)
.object(id)
.build()
);
return ResponseEntity.ok()
.header(HttpHeaders.CONTENT_DISPOSITION, "attachment;filename=\"" + statObjectResponse.userMetadata().get(FILENAME_FIELD) + "\"")
.contentLength(statObjectResponse.size()) //
.body(outputStream -> IOUtils.copy(getObjectResponse, outputStream, FIVE_MIB));
}
@SneakyThrows
@DeleteMapping
public PlatformResponseDTO<Void> remove(String id, String source) {
minioClient.removeObject(RemoveObjectArgs
.builder()
.bucket(defaultBucketName)
.object(id)
.build()
);
return new PlatformResponseDTO<>();
}
}
public class DisableControllerBFPP implements BeanFactoryPostProcessor {
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
BeanDefinitionRegistry beanDefinitionRegistry = (BeanDefinitionRegistry) beanFactory;
beanDefinitionRegistry.removeBeanDefinition("platformFileController");
}
}