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