Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 31 additions & 21 deletions cadastral/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,21 +1,31 @@
#FROM openjdk:17-alpine
#MAINTAINER com.mateusbalda
#VOLUME /tmp
#EXPOSE 8081
#
#COPY CrudService/target/*.jar /crud-service.jar
#
#ENTRYPOINT ["java","-jar","-Dspring.profiles.active=docker-demo", "/crud-service.jar"]

## In this way the file, creates the image along with maven
FROM maven:3.6-openjdk-17-slim AS MAVEN_BUILD
COPY CrudService/pom.xml /build/
COPY CrudService/src /build/src/
WORKDIR /build/
RUN mvn package -DskipTests

FROM openjdk:17-alpine
MAINTAINER com.mateusbalda
EXPOSE 8081
COPY --from=MAVEN_BUILD /build/target/*.jar imobiliaria.jar
ENTRYPOINT ["java","-jar","-Dspring.profiles.active=docker-demo","/imobiliaria.jar"]
# ---------- stage 1: build ----------
FROM maven:3.9.6-eclipse-temurin-21 AS build

WORKDIR /app

# Copiar apenas o pom para aproveitar o cache do Maven
COPY pom.xml .
RUN mvn -q -DskipTests dependency:go-offline

# Copiar código restante
COPY . .

# Gerar o JAR (sem testes para agilizar)
RUN mvn -q clean package -DskipTests


# ---------- stage 2: runtime ----------
FROM eclipse-temurin:21-jre AS runtime

WORKDIR /app

# Copia o JAR final
COPY --from=build /app/target/*.jar app.jar

# Heroku usa PORT, mas exponho 8080 por consistência
EXPOSE 8080

# Importante: garantir que a aplicação leia PORT corretamente
ENV SERVER_PORT=${PORT}

CMD ["sh", "-c", "java -Dserver.port=$PORT -jar app.jar"]
15 changes: 11 additions & 4 deletions cadastral/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -102,10 +102,10 @@
<artifactId>dotenv-java</artifactId>
<version>3.0.0</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-config</artifactId>
</dependency>
<!-- <dependency>-->
<!-- <groupId>org.springframework.cloud</groupId>-->
<!-- <artifactId>spring-cloud-starter-config</artifactId>-->
<!-- </dependency>-->

<!-- https://mvnrepository.com/artifact/io.jsonwebtoken/jjwt-api -->
<dependency>
Expand All @@ -126,6 +126,13 @@
<version>1.5.5.Final</version>
</dependency>

<dependency>
<groupId>com.cloudinary</groupId>
<artifactId>cloudinary-http44</artifactId>
<version>1.29.0</version>
</dependency>



</dependencies>
<dependencyManagement>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package com.unipampa.crud.config;

import com.cloudinary.Cloudinary;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class CloudinaryConfig {

@Value("${CLOUDINARY_URL}")
private String cloudinaryUrl;

@Bean
public Cloudinary cloudinary() {
return new Cloudinary(cloudinaryUrl);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import com.unipampa.crud.enums.UserType;
import io.github.cdimascio.dotenv.Dotenv;
import org.bson.Document;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.CommandLineRunner;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
Expand All @@ -16,6 +17,8 @@ public class MongoScriptInitializer implements CommandLineRunner {

private final PasswordEncoder passwordEncoder;
private final Dotenv dotenv = Dotenv.load();
@Value("${spring.data.mongodb.uri}")
private String mongoUri;

public MongoScriptInitializer(PasswordEncoder passwordEncoder) {
this.passwordEncoder = passwordEncoder;
Expand All @@ -26,8 +29,8 @@ public MongoScriptInitializer(PasswordEncoder passwordEncoder) {
public void run(String... args) throws Exception {
System.out.println("Verificando se os dados já existem no banco...");

try (var client = MongoClients.create("mongodb://localhost:27017")) {
var database = client.getDatabase("cadastral");
try (var client = MongoClients.create(mongoUri)) {
var database = client.getDatabase("imovato");
var roleCollection = database.getCollection("role");
var userCollection = database.getCollection("user");

Expand Down Expand Up @@ -62,26 +65,27 @@ public void run(String... args) throws Exception {

userCollection.insertMany(List.of(
new Document("_id", "admin-1")
.append("userName", dotenv.get("ADMIN1_USERNAME"))
.append("password", passwordEncoder.encode(dotenv.get("ADMIN1_PASSWORD")))
.append("userName", System.getenv("ADMIN1_USERNAME"))
.append("password", passwordEncoder.encode(System.getenv("ADMIN1_PASSWORD")))
.append("roles", List.of(roleAdmin)),

new Document("_id", "admin-2")
.append("userName", dotenv.get("ADMIN2_USERNAME"))
.append("password", passwordEncoder.encode(dotenv.get("ADMIN2_PASSWORD")))
.append("userName", System.getenv("ADMIN2_USERNAME"))
.append("password", passwordEncoder.encode(System.getenv("ADMIN2_PASSWORD")))
.append("roles", List.of(roleAdmin)),

new Document("_id", "admin-3")
.append("userName", dotenv.get("ADMIN3_USERNAME"))
.append("password", passwordEncoder.encode(dotenv.get("ADMIN3_PASSWORD")))
.append("userName", System.getenv("ADMIN3_USERNAME"))
.append("password", passwordEncoder.encode(System.getenv("ADMIN3_PASSWORD")))
.append("roles", List.of(roleAdmin)),

new Document("_id", "admin-4")
.append("userName", dotenv.get("ADMIN4_USERNAME"))
.append("password", passwordEncoder.encode(dotenv.get("ADMIN4_PASSWORD")))
.append("userName", System.getenv("ADMIN4_USERNAME"))
.append("password", passwordEncoder.encode(System.getenv("ADMIN4_PASSWORD")))
.append("roles", List.of(roleAdmin))
));


System.out.println("Usuários criados com sucesso!");
} else {
System.out.println("Usuários já existem no banco. Inicialização de usuários não necessária.");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,12 +80,15 @@ public ResponseEntity<AccommodationDTO> save(
AccommodationRequestDTO accommodationDTO = mapper.readValue(dadosJson, AccommodationRequestDTO.class);

validations.forEach(e -> e.validate(accommodationDTO));

var accommodation = accommodationMapper.toEntity(accommodationDTO);
String novoId = new ObjectId().toString();
accommodation.setId(novoId);

String authenticatedUserId = SecurityUtil.getAuthenticatedUserId();
accommodation.setHostId(authenticatedUserId);
accommodation.setStats(AccommodationStats.AVAILABLE);

accommodationService.save(accommodation, images);

URI location = URI.create("/accommodations/" + accommodation.getId());
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package com.unipampa.crud.resources;

import com.unipampa.crud.service.ImageService;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import java.util.List;

@RestController
@RequestMapping("/images")
public class ImageResource {

private final ImageService imageService;

public ImageResource(ImageService imageService) {
this.imageService = imageService;
}

@PostMapping
public ResponseEntity<List<String>> upload(@RequestParam("files") List<MultipartFile> files) {
List<String> urls = imageService.uploadImages(files);
return ResponseEntity.ok(urls);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ public ResponseEntity<Object> saveUser(@RequestBody UserDTO userDto) {
}


@PreAuthorize( "hasRole('ROLE_ADMINISTRATOR')" )
@PreAuthorize( "hasRole('ADMINISTRATOR')" )
@GetMapping
@Operation(summary = "Retorna todos os usuários cadastrados")
public ResponseEntity<Page<User>> getAllUsers(
Expand All @@ -93,7 +93,7 @@ public ResponseEntity<Page<User>> getAllUsers(
return ResponseEntity.status(HttpStatus.OK).body(users);
}

@PreAuthorize( "hasAnyRole('ROLE_ADMINISTRATOR', 'ROLE_HOST', 'ROLE_GUEST')" )
@PreAuthorize( "hasAnyRole('ADMINISTRATOR', 'HOST', 'GUEST')" )
@GetMapping("email/{email}")
@Operation(summary = "Retorna um usuario pelo email")
public ResponseEntity<Object> getUserByEmail(@PathVariable("email") String email) {
Expand All @@ -105,7 +105,7 @@ public ResponseEntity<Object> getUserByEmail(@PathVariable("email") String email
return new ResponseEntity<>(user, HttpStatus.OK);
}

@PreAuthorize( "hasAnyRole('ROLE_ADMINISTRATOR', 'ROLE_HOST', 'ROLE_GUEST')" )
@PreAuthorize( "hasAnyRole('ADMINISTRATOR', 'HOST', 'GUEST')" )
@GetMapping("{id}")
@Operation(summary = "Retorna um usuario pelo id")
public ResponseEntity<Object> getUserById(@PathVariable("id") String id) {
Expand All @@ -117,7 +117,7 @@ public ResponseEntity<Object> getUserById(@PathVariable("id") String id) {
return new ResponseEntity<>(user, HttpStatus.OK);
}

@PreAuthorize( "hasAnyRole('ROLE_ADMINISTRATOR', 'ROLE_HOST', 'ROLE_GUEST')" )
@PreAuthorize( "hasAnyRole('ADMINISTRATOR', 'HOST', 'GUEST')" )
@PutMapping("{id}")
@Operation(summary = "Atualiza um usuario pelo id")
public ResponseEntity<Object> updateUser(@RequestBody UserDTO userDTO, @PathVariable("id")String id) {
Expand All @@ -132,7 +132,7 @@ public ResponseEntity<Object> updateUser(@RequestBody UserDTO userDTO, @PathVar
return new ResponseEntity<>(userModel, HttpStatus.OK);
}

@PreAuthorize( "hasAnyRole('ROLE_ADMINISTRATOR', 'ROLE_HOST', 'ROLE_GUEST')" )
@PreAuthorize( "hasAnyRole('ADMINISTRATOR', 'HOST', 'GUEST')" )
@DeleteMapping("{id}")
@Operation(summary = "Remove um usuario pelo seu id")
public ResponseEntity<Object> deleteUser(@PathVariable("id") String id) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package com.unipampa.crud.service;

import com.cloudinary.Cloudinary;
import com.cloudinary.utils.ObjectUtils;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

@Service
public class ImageService {

private final Cloudinary cloudinary;

public ImageService(Cloudinary cloudinary) {
this.cloudinary = cloudinary;
}

public List<String> uploadImages(List<MultipartFile> files) {
if (files == null || files.isEmpty()) {
throw new IllegalArgumentException("Envie ao menos uma imagem.");
}

List<String> urls = new ArrayList<>();

for (MultipartFile file : files) {
try {
Map result = cloudinary.uploader().upload(
file.getBytes(),
ObjectUtils.asMap("folder", "imovato/accommodations")
);
urls.add(result.get("secure_url").toString());

} catch (Exception e) {
throw new RuntimeException("Erro ao fazer upload para Cloudinary", e);
}
}

return urls;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import com.unipampa.crud.repository.AccommodationRepository;
import com.unipampa.crud.sender.AccommodationSender;
import com.unipampa.crud.service.AccommodationService;
import com.unipampa.crud.service.ImageService;
import jakarta.persistence.EntityNotFoundException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
Expand All @@ -19,10 +20,7 @@
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.UUID;
import java.util.*;

@Service
public class AccommodationServiceImpl implements AccommodationService {
Expand All @@ -35,22 +33,34 @@ public class AccommodationServiceImpl implements AccommodationService {
public static final String TAMANHO_MAXIMO_DA_IMAGEM = "Imagem excede o tamanho máximo permitido de 5MB.";
private AccommodationRepository propertyRepository;
private AccommodationSender accommodationSender;
private ImageService imageService;

@Value("${app.uploads-dir}")
private String uploadsDir;

@Autowired
public AccommodationServiceImpl(AccommodationRepository repository, AccommodationSender sendMessage) {
public AccommodationServiceImpl(AccommodationRepository repository, AccommodationSender sendMessage, ImageService imageService) {
this.propertyRepository = repository;
this.accommodationSender = sendMessage;
this.imageService = imageService;
}

@Override
@Transactional
public void save(Accommodation hosting, MultipartFile[] images) throws IOException {
List<String> caminhos = buildPathForImages(hosting.getId(), images);
hosting.setImagesUrls(caminhos);
Accommodation savedWithImages = propertyRepository.save(hosting);
public void save(Accommodation accommodation, MultipartFile[] images) throws IOException {

List<String> urls = new ArrayList<>();

if (images != null && images.length > 0) {
List<MultipartFile> files = Arrays.asList(images);
List<String> uploadedUrls = imageService.uploadImages(files);
urls.addAll(uploadedUrls);

}

accommodation.setImagesUrls(urls);

Accommodation savedWithImages = propertyRepository.save(accommodation);
accommodationSender.sendMessage(savedWithImages);
}

Expand Down
Loading