parent
f9af2e20d3
commit
6f0857e7cb
@ -0,0 +1,123 @@ |
|||||||
|
<?xml version="1.0" encoding="UTF-8"?> |
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" |
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> |
||||||
|
<modelVersion>4.0.0</modelVersion> |
||||||
|
<parent> |
||||||
|
<groupId>org.springframework.boot</groupId> |
||||||
|
<artifactId>spring-boot-starter-parent</artifactId> |
||||||
|
<version>2.3.3.RELEASE</version> |
||||||
|
<relativePath/> <!-- lookup parent from repository --> |
||||||
|
</parent> |
||||||
|
<groupId>fr.apside</groupId> |
||||||
|
<artifactId>service-webhook</artifactId> |
||||||
|
<version>0.0.1-SNAPSHOT</version> |
||||||
|
<name>service-webhook</name> |
||||||
|
<description>Service de webhook au sein de la transition TOP</description> |
||||||
|
|
||||||
|
<properties> |
||||||
|
<java.version>11</java.version> |
||||||
|
</properties> |
||||||
|
|
||||||
|
<dependencies> |
||||||
|
<dependency> |
||||||
|
<groupId>org.springframework.boot</groupId> |
||||||
|
<artifactId>spring-boot-starter-web</artifactId> |
||||||
|
<exclusions> |
||||||
|
<exclusion> |
||||||
|
<groupId>org.springframework.boot</groupId> |
||||||
|
<artifactId>spring-boot-starter-logging</artifactId> |
||||||
|
</exclusion> |
||||||
|
</exclusions> |
||||||
|
</dependency> |
||||||
|
|
||||||
|
<dependency> |
||||||
|
<groupId>org.springframework.boot</groupId> |
||||||
|
<artifactId>spring-boot-starter-log4j2</artifactId> |
||||||
|
</dependency> |
||||||
|
|
||||||
|
<dependency> |
||||||
|
<groupId>org.springframework.boot</groupId> |
||||||
|
<artifactId>spring-boot-starter-test</artifactId> |
||||||
|
<scope>test</scope> |
||||||
|
<exclusions> |
||||||
|
<exclusion> |
||||||
|
<groupId>org.junit.vintage</groupId> |
||||||
|
<artifactId>junit-vintage-engine</artifactId> |
||||||
|
</exclusion> |
||||||
|
</exclusions> |
||||||
|
</dependency> |
||||||
|
|
||||||
|
<!-- Lombok --> |
||||||
|
<!-- https://mvnrepository.com/artifact/org.projectlombok/lombok --> |
||||||
|
<dependency> |
||||||
|
<groupId>org.projectlombok</groupId> |
||||||
|
<artifactId>lombok</artifactId> |
||||||
|
<version>1.18.12</version> |
||||||
|
<scope>provided</scope> |
||||||
|
</dependency> |
||||||
|
|
||||||
|
<!-- Feign --> |
||||||
|
<!-- https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-starter-openfeign --> |
||||||
|
<dependency> |
||||||
|
<groupId>org.springframework.cloud</groupId> |
||||||
|
<artifactId>spring-cloud-starter-openfeign</artifactId> |
||||||
|
<version>2.2.4.RELEASE</version> |
||||||
|
</dependency> |
||||||
|
<dependency> |
||||||
|
<groupId>io.github.openfeign</groupId> |
||||||
|
<artifactId>feign-okhttp</artifactId> |
||||||
|
<version>9.3.1</version> |
||||||
|
</dependency> |
||||||
|
<dependency> |
||||||
|
<groupId>io.github.openfeign</groupId> |
||||||
|
<artifactId>feign-gson</artifactId> |
||||||
|
<version>9.3.1</version> |
||||||
|
</dependency> |
||||||
|
<dependency> |
||||||
|
<groupId>io.github.openfeign</groupId> |
||||||
|
<artifactId>feign-slf4j</artifactId> |
||||||
|
<version>9.3.1</version> |
||||||
|
</dependency> |
||||||
|
<dependency> |
||||||
|
<groupId>com.fasterxml.jackson.core</groupId> |
||||||
|
<artifactId>jackson-annotations</artifactId> |
||||||
|
<version>2.11.2</version> |
||||||
|
</dependency> |
||||||
|
|
||||||
|
<!-- RabbitMQ --> |
||||||
|
<dependency> |
||||||
|
<groupId>org.springframework.amqp</groupId> |
||||||
|
<artifactId>spring-rabbit-test</artifactId> |
||||||
|
<scope>test</scope> |
||||||
|
</dependency> |
||||||
|
<dependency> |
||||||
|
<groupId>org.springframework.amqp</groupId> |
||||||
|
<artifactId>spring-amqp</artifactId> |
||||||
|
<version>2.2.7.RELEASE</version> |
||||||
|
<scope>compile</scope> |
||||||
|
</dependency> |
||||||
|
<dependency> |
||||||
|
<groupId>org.springframework.amqp</groupId> |
||||||
|
<artifactId>spring-rabbit</artifactId> |
||||||
|
<version>2.2.7.RELEASE</version> |
||||||
|
<scope>compile</scope> |
||||||
|
</dependency> |
||||||
|
|
||||||
|
<!-- Jackson --> |
||||||
|
<dependency> |
||||||
|
<groupId>com.fasterxml.jackson.core</groupId> |
||||||
|
<artifactId>jackson-databind</artifactId> |
||||||
|
<version>2.11.2</version> |
||||||
|
</dependency> |
||||||
|
</dependencies> |
||||||
|
|
||||||
|
<build> |
||||||
|
<plugins> |
||||||
|
<plugin> |
||||||
|
<groupId>org.springframework.boot</groupId> |
||||||
|
<artifactId>spring-boot-maven-plugin</artifactId> |
||||||
|
</plugin> |
||||||
|
</plugins> |
||||||
|
</build> |
||||||
|
|
||||||
|
</project> |
@ -0,0 +1,18 @@ |
|||||||
|
package fr.apside.servicewebhook; |
||||||
|
|
||||||
|
import fr.apside.servicewebhook.model.CandidateResponse; |
||||||
|
import org.springframework.cloud.openfeign.FeignClient; |
||||||
|
import org.springframework.web.bind.annotation.PathVariable; |
||||||
|
import org.springframework.web.bind.annotation.RequestMapping; |
||||||
|
import org.springframework.web.bind.annotation.RequestMethod; |
||||||
|
|
||||||
|
import java.util.List; |
||||||
|
|
||||||
|
@FeignClient(name = "candidates", url = "${feign.url}") |
||||||
|
public interface CandidateClient { |
||||||
|
@RequestMapping(method = RequestMethod.GET, value = "/candidates") |
||||||
|
List<CandidateResponse> getCandidates(); |
||||||
|
|
||||||
|
@RequestMapping(method = RequestMethod.GET, value = "/candidates/{candidateId}", headers = "Authorization=Bearer ${bearer.token}") |
||||||
|
CandidateResponse getCandidateById(@PathVariable("candidateId") Long candidateId); |
||||||
|
} |
@ -0,0 +1,40 @@ |
|||||||
|
package fr.apside.servicewebhook; |
||||||
|
|
||||||
|
import org.slf4j.Logger; |
||||||
|
import org.slf4j.LoggerFactory; |
||||||
|
import org.springframework.amqp.AmqpException; |
||||||
|
import org.springframework.amqp.AmqpRejectAndDontRequeueException; |
||||||
|
import org.springframework.amqp.rabbit.core.RabbitTemplate; |
||||||
|
import org.springframework.beans.factory.annotation.Autowired; |
||||||
|
import org.springframework.boot.SpringApplication; |
||||||
|
import org.springframework.boot.autoconfigure.SpringBootApplication; |
||||||
|
import org.springframework.cloud.openfeign.EnableFeignClients; |
||||||
|
import org.springframework.web.bind.annotation.PostMapping; |
||||||
|
import org.springframework.web.bind.annotation.RequestBody; |
||||||
|
import org.springframework.web.bind.annotation.RestController; |
||||||
|
|
||||||
|
@SpringBootApplication |
||||||
|
@EnableFeignClients |
||||||
|
@RestController |
||||||
|
public class ServiceWebhookApplication { |
||||||
|
|
||||||
|
public static Logger logger = LoggerFactory.getLogger(ServiceWebhookApplication.class); |
||||||
|
|
||||||
|
@Autowired |
||||||
|
private RabbitTemplate template; |
||||||
|
|
||||||
|
@PostMapping |
||||||
|
public void receipWebhook(@RequestBody long candidateId) { |
||||||
|
logger.trace("Reception du nouveau collaborateur : " + candidateId); |
||||||
|
try { |
||||||
|
this.template.convertAndSend("WebhookWork", candidateId); |
||||||
|
} catch (AmqpException ae) { |
||||||
|
logger.error("Erreur lors de l'envois du message dans la queue de travail : "); |
||||||
|
ae.printStackTrace(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public static void main(String[] args) { |
||||||
|
SpringApplication.run(ServiceWebhookApplication.class, args); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,63 @@ |
|||||||
|
package fr.apside.servicewebhook; |
||||||
|
|
||||||
|
import com.fasterxml.jackson.core.JsonProcessingException; |
||||||
|
import com.fasterxml.jackson.databind.ObjectMapper; |
||||||
|
import feign.FeignException; |
||||||
|
import fr.apside.servicewebhook.model.Candidate; |
||||||
|
import org.slf4j.Logger; |
||||||
|
import org.springframework.amqp.AmqpException; |
||||||
|
import org.springframework.amqp.AmqpRejectAndDontRequeueException; |
||||||
|
import org.springframework.amqp.core.Message; |
||||||
|
import org.springframework.amqp.rabbit.annotation.RabbitListener; |
||||||
|
import org.springframework.amqp.rabbit.core.RabbitTemplate; |
||||||
|
import org.springframework.amqp.utils.SerializationUtils; |
||||||
|
import org.springframework.beans.factory.annotation.Autowired; |
||||||
|
import org.springframework.stereotype.Component; |
||||||
|
|
||||||
|
import java.util.UUID; |
||||||
|
|
||||||
|
@Component |
||||||
|
public class Worker { |
||||||
|
|
||||||
|
Logger logger = ServiceWebhookApplication.logger; |
||||||
|
|
||||||
|
@Autowired |
||||||
|
private RabbitTemplate template; |
||||||
|
|
||||||
|
@Autowired |
||||||
|
private CandidateClient client; |
||||||
|
|
||||||
|
@RabbitListener(queues = "WebhookWork") |
||||||
|
public void receiveMessage(Message message) throws AmqpRejectAndDontRequeueException{ |
||||||
|
receive(message, 1); |
||||||
|
} |
||||||
|
|
||||||
|
public void receive(Message in, int receiver) throws AmqpRejectAndDontRequeueException { |
||||||
|
long idCandidate = Long.parseLong(SerializationUtils.deserialize(in.getBody()).toString()); //conversion du body de byte[] a long
|
||||||
|
ObjectMapper objectMapper = new ObjectMapper(); |
||||||
|
try{ |
||||||
|
logger.trace("Recuperation des donnees du nouveau collaborateur : "); |
||||||
|
Candidate newCandidate = client.getCandidateById(idCandidate).getCandidate(); |
||||||
|
newCandidate.setFields2(logger); // parse les fields dans les attributs de Candidate et set fields a null (pour le parsing)
|
||||||
|
|
||||||
|
newCandidate.setId(UUID.randomUUID().toString()); // Genere un UUID et le set au nouveau collaborateur
|
||||||
|
|
||||||
|
String newCandidateAsSJson = objectMapper.writeValueAsString(newCandidate); |
||||||
|
|
||||||
|
logger.trace("Envois des donnees via RabbitMQ"); |
||||||
|
this.template.convertAndSend("WebhookExchange", "collaborateur.new", newCandidateAsSJson); |
||||||
|
}catch (FeignException fe){ |
||||||
|
logger.error("Erreur lors de la recuperation des donnees : "); |
||||||
|
fe.printStackTrace(); |
||||||
|
throw new AmqpRejectAndDontRequeueException("Erreur lors de la recuperation des donnees"); |
||||||
|
}catch (AmqpException ae){ |
||||||
|
logger.error("Erreur lors de l'envois des donnees : "); |
||||||
|
ae.printStackTrace(); |
||||||
|
throw new AmqpRejectAndDontRequeueException("Erreur lors de l'envois des donnees"); |
||||||
|
}catch (JsonProcessingException je){ |
||||||
|
logger.error("Erreur lors du parsing des donnees au format Json : "); |
||||||
|
je.printStackTrace(); |
||||||
|
throw new AmqpRejectAndDontRequeueException("Erreur lors du parsing des donnees au format Json"); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,148 @@ |
|||||||
|
package fr.apside.servicewebhook.model; |
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonInclude; |
||||||
|
import com.fasterxml.jackson.annotation.JsonProperty; |
||||||
|
import lombok.Getter; |
||||||
|
import lombok.Setter; |
||||||
|
import lombok.ToString; |
||||||
|
import org.slf4j.Logger; |
||||||
|
|
||||||
|
import java.util.ArrayList; |
||||||
|
import java.util.List; |
||||||
|
|
||||||
|
@Getter |
||||||
|
@Setter |
||||||
|
@ToString |
||||||
|
@JsonInclude(JsonInclude.Include.NON_NULL) |
||||||
|
public class Candidate { |
||||||
|
@JsonProperty("id") |
||||||
|
private String id; |
||||||
|
|
||||||
|
@JsonProperty("fields") |
||||||
|
private List<Field> fields = null; |
||||||
|
|
||||||
|
@JsonProperty("posteRecherche") |
||||||
|
private List<String> posteRecherche = null; |
||||||
|
@JsonProperty("motifRecherche") |
||||||
|
private List<Object> motifRecherche = null; |
||||||
|
@JsonProperty("pistes") |
||||||
|
private List<Object> pistes = null; |
||||||
|
@JsonProperty("criteresChoix") |
||||||
|
private List<Object> criteresChoix = null; |
||||||
|
@JsonProperty("disponibilite") |
||||||
|
private String disponibilite; |
||||||
|
@JsonProperty("mobilitee") |
||||||
|
private List<Object> mobilitee = null; |
||||||
|
@JsonProperty("pretentionSalariale") |
||||||
|
private List<Object> pretentionSalariale = null; |
||||||
|
@JsonProperty("skills") |
||||||
|
private List<Object> skills = null; |
||||||
|
@JsonProperty("languageSkills") |
||||||
|
private List<Object> languageSkills = null; |
||||||
|
@JsonProperty("rqth") |
||||||
|
private boolean rqth; |
||||||
|
@JsonProperty("genre") |
||||||
|
private String genre; |
||||||
|
@JsonProperty("nationalite") |
||||||
|
private List<Object> nationalite = null; |
||||||
|
@JsonProperty("adresses") |
||||||
|
private List<String> adresses = null; |
||||||
|
@JsonProperty("references") |
||||||
|
private List<Object> references = null; |
||||||
|
@JsonProperty("education") |
||||||
|
private List<Object> education = null; |
||||||
|
@JsonProperty("experience") |
||||||
|
private List<Object> experience = null; |
||||||
|
|
||||||
|
@JsonProperty("tags") |
||||||
|
private List<Object> tags = null; |
||||||
|
@JsonProperty("phones") |
||||||
|
private List<String> phones = null; |
||||||
|
@JsonProperty("name") |
||||||
|
private String name; |
||||||
|
@JsonProperty("photo_url") |
||||||
|
private String photoUrl; |
||||||
|
@JsonProperty("emails") |
||||||
|
private List<String> emails = null; |
||||||
|
|
||||||
|
public void setFields2(Logger log){ |
||||||
|
for (Field f : this.fields){ |
||||||
|
if (f.getName() == null && f.getValues() != null){ |
||||||
|
switch (f.getKind()){ |
||||||
|
case "skills": |
||||||
|
this.skills = f.getValues(); |
||||||
|
break; |
||||||
|
case "language_skill": |
||||||
|
this.languageSkills = f.getValues(); |
||||||
|
break; |
||||||
|
case "gender": |
||||||
|
String genderString = f.getValues().toString(); |
||||||
|
this.genre = genderString.substring(genderString.indexOf("=") + 1, genderString.length() - 2); |
||||||
|
break; |
||||||
|
case "nationality": |
||||||
|
this.nationalite = f.getValues(); |
||||||
|
break; |
||||||
|
case "address": |
||||||
|
this.adresses = new ArrayList<>(); |
||||||
|
for(Object v : f.getValues()){ |
||||||
|
String adString = v.toString(); |
||||||
|
this.adresses.add(adString.substring(adString.indexOf("=") + 1, adString.length() - 2)); |
||||||
|
} |
||||||
|
break; |
||||||
|
case "education": |
||||||
|
this.education = f.getValues(); |
||||||
|
break; |
||||||
|
case "experience": |
||||||
|
this.experience = f.getValues(); |
||||||
|
break; |
||||||
|
default: |
||||||
|
log.warn("Champ inconnu dans le collaborateur : " + f.getKind()); |
||||||
|
break; |
||||||
|
} |
||||||
|
}else if(f.getValues() != null){ |
||||||
|
switch (f.getName()){ |
||||||
|
case "Poste et contrat recherché": |
||||||
|
this.posteRecherche = new ArrayList<>(); |
||||||
|
for(Object v : f.getValues()) { |
||||||
|
String posteString = v.toString(); |
||||||
|
this.posteRecherche.add(posteString.substring(posteString.indexOf("=") + 1, posteString.length() - 2)); |
||||||
|
} |
||||||
|
break; |
||||||
|
case "Motif recherche": |
||||||
|
this.motifRecherche = new ArrayList<>(); |
||||||
|
for(Object v : f.getValues()) { |
||||||
|
String motifString = v.toString(); |
||||||
|
this.motifRecherche.add(motifString.substring(motifString.indexOf("=") + 1, motifString.length() - 2)); |
||||||
|
} |
||||||
|
case "Pistes": |
||||||
|
this.pistes = f.getValues(); |
||||||
|
break; |
||||||
|
case "Critères de choix": |
||||||
|
this.criteresChoix = f.getValues(); |
||||||
|
break; |
||||||
|
case "Disponibilité": |
||||||
|
String dispoString = f.getValues().get(0).toString(); |
||||||
|
this.disponibilite = dispoString.substring(dispoString.indexOf("=") + 1, dispoString.length() - 2); |
||||||
|
break; |
||||||
|
case "Mobilité": |
||||||
|
this.mobilitee = f.getValues(); |
||||||
|
break; |
||||||
|
case "Prétentions salariales": |
||||||
|
this.pretentionSalariale = f.getValues(); |
||||||
|
break; |
||||||
|
case "RQTH": |
||||||
|
String rqthString = f.getValues().get(0).toString(); |
||||||
|
this.rqth = Boolean.parseBoolean(rqthString.substring(rqthString.indexOf("=") + 1, rqthString.length() - 2)); |
||||||
|
break; |
||||||
|
case "Références": |
||||||
|
this.references = f.getValues(); |
||||||
|
break; |
||||||
|
default: |
||||||
|
log.warn("Champ inconnu dans le collaborateur : " + f.getName()); |
||||||
|
break; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
this.fields = null; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,21 @@ |
|||||||
|
package fr.apside.servicewebhook.model; |
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonInclude; |
||||||
|
import com.fasterxml.jackson.annotation.JsonProperty; |
||||||
|
import com.fasterxml.jackson.annotation.JsonPropertyOrder; |
||||||
|
import lombok.Getter; |
||||||
|
import lombok.Setter; |
||||||
|
import lombok.ToString; |
||||||
|
|
||||||
|
@JsonInclude(JsonInclude.Include.NON_NULL) |
||||||
|
@JsonPropertyOrder({ |
||||||
|
"candidate" |
||||||
|
}) |
||||||
|
@Getter |
||||||
|
@Setter |
||||||
|
@ToString |
||||||
|
public class CandidateResponse { |
||||||
|
@JsonProperty("candidate") |
||||||
|
private Candidate candidate; |
||||||
|
|
||||||
|
} |
@ -0,0 +1,20 @@ |
|||||||
|
package fr.apside.servicewebhook.model; |
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonProperty; |
||||||
|
import lombok.Getter; |
||||||
|
import lombok.Setter; |
||||||
|
import lombok.ToString; |
||||||
|
|
||||||
|
import java.util.List; |
||||||
|
|
||||||
|
@Getter |
||||||
|
@Setter |
||||||
|
@ToString |
||||||
|
public class Field { |
||||||
|
@JsonProperty("kind") |
||||||
|
private String kind; |
||||||
|
@JsonProperty("name") |
||||||
|
private String name; |
||||||
|
@JsonProperty("values") |
||||||
|
private List<Object> values = null; |
||||||
|
} |
@ -0,0 +1,4 @@ |
|||||||
|
#API Recruitee |
||||||
|
bearer.token=QkU4LzlyTnFlektjajhrR0JHbFNQUT09 |
||||||
|
feign.url=https://api.recruitee.com/c/${id.apside} |
||||||
|
id.apside=41694 |
@ -0,0 +1,35 @@ |
|||||||
|
<?xml version="1.0" encoding="UTF-8"?> |
||||||
|
<Configuration> |
||||||
|
<Appenders> |
||||||
|
<Console name="Console" target="SYSTEM_OUT"> |
||||||
|
<PatternLayout |
||||||
|
pattern="%style{%d{ISO8601}}{black} %highlight{%-5level }[%style{%t}{bright,blue}] %style{%C{1.}}{bright,yellow}: %msg%n%throwable" /> |
||||||
|
</Console> |
||||||
|
|
||||||
|
<RollingFile name="RollingFile" |
||||||
|
fileName="./logs/spring-boot-logger-log4j2.log" |
||||||
|
filePattern="./logs/$${date:yyyy-MM}/spring-boot-logger-log4j2-%d{-dd-MMMM-yyyy}-%i.log"> |
||||||
|
<PatternLayout> |
||||||
|
<pattern>%d %p %C{1.} [%t] %m%n</pattern> |
||||||
|
</PatternLayout> |
||||||
|
<Policies> |
||||||
|
<!-- rollover on startup, daily and when the file reaches 10 MegaBytes --> |
||||||
|
<OnStartupTriggeringPolicy /> |
||||||
|
<SizeBasedTriggeringPolicy size="10 MB" /> |
||||||
|
<TimeBasedTriggeringPolicy /> |
||||||
|
</Policies> |
||||||
|
</RollingFile> |
||||||
|
</Appenders> |
||||||
|
|
||||||
|
<Loggers> |
||||||
|
<!-- LOG everything at INFO level --> |
||||||
|
<Root level="info"> |
||||||
|
<AppenderRef ref="Console" /> |
||||||
|
<AppenderRef ref="RollingFile" /> |
||||||
|
</Root> |
||||||
|
|
||||||
|
<!-- LOG "fr.apside*" at TRACE level --> |
||||||
|
<Logger name="fr.apside" level="trace"></Logger> |
||||||
|
</Loggers> |
||||||
|
|
||||||
|
</Configuration> |
@ -0,0 +1,13 @@ |
|||||||
|
package fr.apside.servicewebhook; |
||||||
|
|
||||||
|
import org.junit.jupiter.api.Test; |
||||||
|
import org.springframework.boot.test.context.SpringBootTest; |
||||||
|
|
||||||
|
@SpringBootTest |
||||||
|
class ServiceWebhookApplicationTests { |
||||||
|
|
||||||
|
@Test |
||||||
|
void contextLoads() { |
||||||
|
} |
||||||
|
|
||||||
|
} |
Loading…
Reference in new issue