WebHookService.java
package io.featureprobe.api.service;
import io.featureprobe.api.base.enums.ResourceType;
import io.featureprobe.api.base.hook.CallbackType;
import io.featureprobe.api.dao.entity.WebHookSettings;
import io.featureprobe.api.dao.exception.ResourceConflictException;
import io.featureprobe.api.dao.exception.ResourceNotFoundException;
import io.featureprobe.api.dao.repository.WebHookSettingsRepository;
import io.featureprobe.api.dao.utils.PageRequestUtil;
import io.featureprobe.api.dto.SecretKeyResponse;
import io.featureprobe.api.dto.WebHookCreateRequest;
import io.featureprobe.api.dto.WebHookItemResponse;
import io.featureprobe.api.dto.WebHookListRequest;
import io.featureprobe.api.dto.WebHookResponse;
import io.featureprobe.api.dto.WebHookUpdateRequest;
import io.featureprobe.api.mapper.WebHookMapper;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.criteria.Predicate;
import java.net.MalformedURLException;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.UUID;
import java.util.stream.Collectors;
@Slf4j
@Service
@AllArgsConstructor
public class WebHookService {
private WebHookSettingsRepository webHookSettingsRepository;
@PersistenceContext
public EntityManager entityManager;
@Transactional(rollbackFor = Exception.class)
public WebHookResponse create(WebHookCreateRequest createRequest) {
checkName(createRequest.getName());
checkUrl(createRequest.getUrl());
WebHookSettings webHookSettings = WebHookMapper.INSTANCE.requestToEntity(createRequest);
webHookSettings.setType(CallbackType.COMMON);
return WebHookMapper.INSTANCE.entityToResponse(webHookSettingsRepository.save(webHookSettings));
}
@Transactional(rollbackFor = Exception.class)
public WebHookResponse update(Long id, WebHookUpdateRequest updateRequest) {
WebHookSettings webHookSettings = webHookSettingsRepository.findById(id).orElseThrow(() ->
new ResourceNotFoundException(ResourceType.WEBHOOK, String.valueOf(id)));
if (!webHookSettings.getName().equals(updateRequest.getName())) {
checkName(updateRequest.getName());
}
checkUrl(updateRequest.getUrl());
WebHookMapper.INSTANCE.mapEntity(updateRequest, webHookSettings);
return WebHookMapper.INSTANCE.entityToResponse(webHookSettingsRepository.save(webHookSettings));
}
public SecretKeyResponse secretKey() {
return new SecretKeyResponse(DigestUtils.sha1Hex(UUID.randomUUID().toString()
.getBytes(StandardCharsets.UTF_8)));
}
@Transactional(rollbackFor = Exception.class)
public WebHookResponse delete(Long id) {
WebHookSettings webHookSettings = webHookSettingsRepository.findById(id).orElseThrow(() ->
new ResourceNotFoundException(ResourceType.WEBHOOK, String.valueOf(id)));
webHookSettingsRepository.deleteById(id);
return WebHookMapper.INSTANCE.entityToResponse(webHookSettings);
}
public WebHookItemResponse query(Long id) {
WebHookSettings webHookSettings = webHookSettingsRepository.findById(id).orElseThrow(() ->
new ResourceNotFoundException(ResourceType.WEBHOOK, String.valueOf(id)));
return WebHookMapper.INSTANCE.entityToItemResponse(webHookSettings);
}
public List<String> queryByUrl(String url) {
List<WebHookSettings> webHookSettingsList = webHookSettingsRepository.findByUrl(url);
return webHookSettingsList.stream().map(WebHookSettings::getName).collect(Collectors.toList());
}
public Page<WebHookItemResponse> list(WebHookListRequest listRequest) {
Specification<WebHookSettings> resultSpec = (root, query, cb) -> {
List<Predicate> predicateListOr = new ArrayList<>();
if (StringUtils.isNotBlank(listRequest.getNameLike())) {
predicateListOr.add(cb.like(root.get("name"), "%" + listRequest.getNameLike() + "%"));
}
if (Objects.nonNull(listRequest.getStatus())) {
predicateListOr.add(cb.equal(root.get("status"), listRequest.getStatus()));
}
if (predicateListOr.size() > 0) {
return query.where(cb.or(predicateListOr.toArray(new Predicate[predicateListOr.size()])))
.getRestriction();
}
return query.getRestriction();
};
Pageable pageable = PageRequestUtil.toPageable(listRequest, Sort.Direction.DESC, "createdTime");
Page<WebHookSettings> all = webHookSettingsRepository.findAll(resultSpec, pageable);
return all.map(entity -> WebHookMapper.INSTANCE.entityToItemResponse(entity));
}
private void checkName(String name) {
Optional<WebHookSettings> webHookSettings = webHookSettingsRepository.findByName(name);
if (webHookSettings.isPresent()) {
throw new ResourceConflictException(ResourceType.PROJECT);
}
}
private void checkUrl(String url) {
try {
new URL(url);
} catch (MalformedURLException e) {
throw new IllegalArgumentException("WebHook URL is illegal");
}
}
}