TeamService.java

  1. package no.nav.data.team.team;

  2. import lombok.extern.slf4j.Slf4j;
  3. import lombok.val;
  4. import no.nav.data.common.TeamCatalogProps;
  5. import no.nav.data.common.storage.StorageService;
  6. import no.nav.data.common.storage.domain.GenericStorage;
  7. import no.nav.data.common.validator.Validator;
  8. import no.nav.data.team.cluster.domain.Cluster;
  9. import no.nav.data.team.location.LocationRepository;
  10. import no.nav.data.team.location.domain.LocationType;
  11. import no.nav.data.team.naisteam.NaisConsoleClient;
  12. import no.nav.data.team.po.domain.ProductArea;
  13. import no.nav.data.team.resource.NomClient;
  14. import no.nav.data.team.shared.domain.DomainObjectStatus;
  15. import no.nav.data.team.team.domain.Team;
  16. import no.nav.data.team.team.domain.TeamMember;
  17. import no.nav.data.team.team.dto.TeamMemberRequest;
  18. import no.nav.data.team.team.dto.TeamRequest;
  19. import no.nav.data.team.team.dto.TeamRequest.Fields;
  20. import org.springframework.beans.factory.annotation.Autowired;
  21. import org.springframework.stereotype.Service;

  22. import java.time.DayOfWeek;
  23. import java.util.List;
  24. import java.util.Optional;
  25. import java.util.UUID;

  26. import static no.nav.data.common.utils.StreamUtils.convert;
  27. import static no.nav.data.common.validator.Validator.*;

  28. @Slf4j
  29. @Service
  30. public class TeamService {

  31.     private final StorageService storage;
  32.     private final NaisConsoleClient naisTeamService;
  33.     private final NomClient nomClient;
  34.     private final TeamRepository teamRepository;
  35.     private final LocationRepository locationRepository;

  36.     @Autowired
  37.     private TeamCatalogProps teamCatalogProps;

  38.     public TeamService(StorageService storage, NaisConsoleClient naisTeamService, NomClient nomClient, TeamRepository teamRepository, LocationRepository locationRepository) {
  39.         this.storage = storage;
  40.         this.naisTeamService = naisTeamService;
  41.         this.nomClient = nomClient;
  42.         this.teamRepository = teamRepository;
  43.         this.locationRepository = locationRepository;
  44.     }

  45.     public Team save(TeamRequest request) {
  46.         if (request.getProductAreaId() == null) {
  47.             request.setProductAreaId(teamCatalogProps.getDefaultProductareaUuid());
  48.         }
  49.         Validator.validate(request, storage)
  50.                 .addValidations(validator -> validator.checkExists(request.getProductAreaId(), storage, ProductArea.class))
  51.                 .addValidations(validator -> getaVoid(request, validator))
  52.                 .addValidations(TeamRequest::getMembers, this::validateMembers)
  53.                 .addValidation(TeamRequest::getContactPersonIdent, this::validateContactPerson)
  54.                 .addValidations(TeamRequest::getNaisTeams, this::validateNaisTeam)
  55.                 .addValidations(this::validateName)
  56.                 .addValidations(this::validateTeamOwner)
  57.                 .addValidations(this::validateLocationCode)
  58.                 .addValidations(this::validateStatusNotNull)
  59.                 .ifErrorsThrowValidationException();

  60.         var team = request.isUpdate() ? storage.get(request.getIdAsUUID(), Team.class) : new Team();

  61.         storage.save(team.convert(request));
  62.         return team;
  63.     }



  64.     private void getaVoid(TeamRequest request, Validator<TeamRequest> validator) {
  65.         request.getClusterIds().forEach(cId -> validator.checkExists(cId, storage, Cluster.class));
  66.     }

  67.     public Team get(UUID id) {
  68.         return storage.get(id, Team.class);
  69.     }

  70.     public Team delete(UUID id) {
  71.         Team delete = storage.delete(id, Team.class);
  72.         //graphService.deleteTeam(delete);
  73.         return delete;
  74.     }

  75.     public List<Team> getAll() {
  76.         return storage.getAll(Team.class);
  77.     }

  78.     public List<Team> getAllActive() {
  79.         return getAll().stream().filter(team -> team.getStatus() == DomainObjectStatus.ACTIVE).toList();

  80.     }

  81.     public List<Team> findByProductArea(UUID productAreaId) {
  82.         return convert(teamRepository.findByProductArea(productAreaId), GenericStorage::toTeam);
  83.     }

  84.     public List<Team> findByCluster(UUID clusterId) {
  85.         return teamRepository.findByCluster(clusterId);
  86.     }

  87.     public List<Team> search(String name) {
  88.         return convert(teamRepository.findByNameLike(name), GenericStorage::toTeam);
  89.     }

  90.     private void validateNaisTeam(Validator<TeamRequest> validator, String naisTeam) {
  91.         Team existingTeam = validator.getDomainItem();
  92.         if (!(existingTeam != null && existingTeam.getNaisTeams().contains(naisTeam)) && !naisTeamService.naisTeamExists(naisTeam)) {
  93.             validator.addError(Fields.naisTeams, DOES_NOT_EXIST, "Nais Team " + naisTeam + " does not exist");
  94.         }
  95.     }

  96.     private void validateMembers(Validator<TeamRequest> validator, TeamMemberRequest member) {
  97.         var existingMembers = validator.getDomainItem() == null ? List.<TeamMember>of() : validator.getDomainItem(Team.class).getMembers();
  98.         validateIdent(validator, member.getNavIdent(), Fields.members, convert(existingMembers, TeamMember::getNavIdent));
  99.     }

  100.     private void validateContactPerson(Validator<TeamRequest> validator, String ident) {
  101.         List<String> existingIdents = Optional.ofNullable(validator.getDomainItem(Team.class)).map(Team::getContactPersonIdent).map(List::of).orElse(List.of());
  102.         validateIdent(validator, ident, Fields.contactPersonIdent, existingIdents);
  103.     }

  104.     private void validateStatusNotNull(Validator<TeamRequest> teamRequestValidator) {
  105.     if(teamRequestValidator.getItem().getStatus() == null){
  106.         teamRequestValidator.addError("status", ILLEGAL_ARGUMENT, "Status cannot be null");
  107.     }
  108.     }


  109.     private void validateIdent(Validator<TeamRequest> validator, String ident, String fieldName, List<String> existingIdents) {
  110.         if (ident == null) {
  111.             return;
  112.         }
  113.         if (existingIdents.stream().noneMatch(m -> m.equals(ident)) && nomClient.getByNavIdent(ident).isEmpty()) {
  114.             validator.addError(fieldName, DOES_NOT_EXIST, "Resource " + ident + " does not exist");
  115.         }
  116.     }

  117.     private void validateName(Validator<TeamRequest> validator) {
  118.         String name = validator.getItem().getName();
  119.         if (name == null || name == "") {
  120.             validator.addError(Fields.name, ERROR_MESSAGE_MISSING, "Name is required");
  121.         }

  122.     }

  123.     private void validateTeamOwner(Validator<TeamRequest> validator) {
  124.         var teamRequest = validator.getItem();
  125.         var teamInDefaultProductArea = teamCatalogProps.getDefaultProductareaUuid().
  126.                 equals(teamRequest.getProductAreaId());
  127.         if(teamInDefaultProductArea){
  128.             if(teamRequest.getTeamOwnerIdent() != null){
  129.                 validateIdent(validator,teamRequest.getTeamOwnerIdent(), Fields.teamOwnerIdent, List.of());
  130.             }
  131.         }else{
  132.             if(teamRequest.getTeamOwnerIdent() != null) {
  133.                 var errMsg = "Cannot specify teamOwner for team in non-default product-area.";
  134.                 validator.addError(Fields.teamOwnerIdent, ILLEGAL_ARGUMENT, errMsg);
  135.             }
  136.         }
  137.     }

  138.     private void validateLocationCode(Validator<TeamRequest> validator){
  139.         val officeHours = validator.getItem().getOfficeHours();
  140.         if(officeHours != null){
  141.             if(officeHours.getDays().contains(DayOfWeek.SATURDAY) || officeHours.getDays().contains(DayOfWeek.SUNDAY)){
  142.                 validator.addError(Fields.officeHours, ILLEGAL_ARGUMENT, "Officehours can't be on saturdays or sundays");
  143.             }

  144.             val location = locationRepository.getLocationByCode(officeHours.getLocationCode());
  145.             if(location.isEmpty()){
  146.                 validator.addError(Fields.officeHours, DOES_NOT_EXIST, "Location for given location code does not exist.");
  147.             }
  148.             if(location.filter(l -> !l.getType().equals(LocationType.FLOOR)).isPresent()){
  149.                 validator.addError(Fields.officeHours, ILLEGAL_ARGUMENT, "Team location must be of type FLOOR");
  150.             }
  151.         }
  152.     }
  153. }