This repository has been archived by the owner on Jun 3, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
Developer's Guide
Nordine Bittich edited this page Mar 22, 2020
·
8 revisions
sh install-local.sh
- a new microservice should be added on the folder microservices
- if it is a rest service, you must put it in the web module. if it is a kafka service, you must put it in the kafka module
- difference between a rest and and kafka module is that in case of kafka, the services will communicate with kafka & sometimes feign (rest services) through the rest gateway (e.g upload-rest), while the rest services are "discoverable" through zookeeper (see Service discovery) and can communicate in that way (also with Feign). The rest services also expose rest endpoints.
- This setup is common for each kind of services
- In module directory, add a DockerFile:
FROM amazoncorretto:11
VOLUME /usr/app
ARG JAR_FILE
COPY ${JAR_FILE} app.jar
ENTRYPOINT ["java","-jar", "app.jar","-server"]
- Simple pom.xml file example
<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>atriangle-kafka</artifactId> <!-- change in case of web -->
<groupId>tech.artcoded</groupId>
<version>0.1.5-SNAPSHOT</version> <!-- make sure to update with the latest the version -->
</parent>
<modelVersion>4.0.0</modelVersion>
<name>A Triangle - MyService-KAFA</name>
<artifactId>atriangle-mymicroservice</artifactId>
<properties>
<docker.image.name>atriangle/mymicroservice</docker.image.name> <!-- docker image name -->
</properties>
<dependencies>
<dependency>
<groupId>tech.artcoded</groupId>
<artifactId>atriangle-core-kafka</artifactId> <!-- common to every project -->
</dependency>
<dependency>
<groupId>tech.artcoded</groupId>
<artifactId>atriangle-shared-config</artifactId> <!-- shared config -->
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
</dependencies>
<profiles>
<profile>
<id>docker</id>
<activation>
<property>
<name>docker</name>
</property>
</activation>
<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId> <!-- docker image -->
<artifactId>exec-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</profile>
</profiles>
<build>
<finalName>atriangle-mymicroservice</finalName>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
- in src/main/resources, create an application.yml file and add the following:
application:
basePath: ${PROJECT_BASE_PATH:/${user.home}/mysercice}
server:
port: 0
spring:
application:
name: MyService
profiles:
include: kafka
- create file
src/main/java/tech/artcoded/atriangle/myservice/MyServiceApplicaton.java
- import kafka config to your application:
@SpringBootApplication
@Import({KafkaConfig.class})
public class MyServiceApplicaton {
public static void main(String[] args) {
SpringApplication.run(MyServiceApplicaton.class, args);
}
}
In order to log an action to elasticsearch, follow these steps:
-
run the
tech.artcoded.atriangle.logsink.LogSinkApplication
(or run the docker image) -
run the
tech.artcoded.atriangle.rest.RestProxyGatewayApplication
(or run the docker image) -
Inject & Usage of LoggerAction
@Service
public class MyService {
private final LoggerAction loggerAction;
@Inject
public MyService(LoggerAction loggerAction) {
this.loggerAction = loggerAction;
}
public void doStuff(){
// the first argument is the correlation id supplier,
// it is mainly used when you want to correlate logs
// the following arguments are the same as if you were
// using String.format("do stuff %s", "one thing");
loggerAction.info(IdGenerators::get,"do stuff %s", "one thing");
}
}
- Verify the result at http://localhost:8088/proxy/elasticsearch/logsink/_search
- By adding atriangle-kafka-core and KafkaConfig, you are already able to communicate with kafka
- To keep a certain logic, you must create you own event and let the event dispatcher dispatches it
- add the following to your application.yml file:
out:
topic: my-event-out # topic to produce
spring:
kafka:
template:
default-topic: my-event # topic to consume
- Add the new topics to event-dispatcher:
- in
microservices/kafka/event-dispatcher/src/main/resources/application.yml
:
- in
event:
dispatcher:
# .. other
my-event-topic: my-event
my-event-topic-out: my-event-out
- Add new enums to EventType:
public enum EventType {
// other enums...
MY_EVENT,
MY_EVENT_OUT,
}
- Add routing to
microservices/kafka/event-dispatcher/src/main/java/tech/artcoded/atriangle/eventdispatcher/EventDispatcherSink.java
:
// ... others
@Value("${event.dispatcher.my-event-topic}")
private String myEventTopic;
@Value("${event.dispatcher.my-event-topic-out}")
private String myEventTopicOut;
// ...
optionalKafkaEvent.ifPresent(kafkaEvent -> {
switch (kafkaEvent.getEventType()) {
case MY_EVENT:
log.info("result of send event: {}", sendEvent.apply(myEventTopic));
break;
}
});
- Create a simple Consumer / Producer:
@Component
@Slf4j
public class MyConsumer implements ATriangleConsumer<String, String> {
private final ObjectMapperWrapper mapperWrapper;
@Value("${out.topic}")
@Getter
private String outTopic;
@Inject
public MyConsumer(ObjectMapperWrapper mapperWrapper) {
this.mapperWrapper = mapperWrapper;
}
@Override
public Map<String, String> consume(ConsumerRecord<String, String> record) throws Exception {
String kafkaEventJson = record.value();
// parse the event
Optional<KafkaEvent> optionalKafkaEvent = mapperWrapper.deserialize(kafkaEventJson, KafkaEvent.class);
KafkaEvent kafkaEvent = optionalKafkaEvent.orElseThrow(() -> new RuntimeException("event could not be parsed"));
Optional<MyEvent> optionalMyEvent = mapperWrapper.deserialize(kafkaEvent.getEvent(), MyEvent.class);
MyEvent event = optionalMyEvent.orElseThrow(() -> new RuntimeException("event could not be parsed"));
// do something useful with MyEvent
log.info("receive{} ", event.getMessage());
MyEventOut eventOut = MyEventOut.builder().message(event.getMessage()).build();
// response out
String eventOutId = IdGenerators.get();
KafkaEvent kafkaEventOut = kafkaEvent.toBuilder()
.id(eventOutId)
.eventType(EventType.MY_EVENT_OUT)
.event(mapperWrapper.serialize(eventOut))
.build();
return Map.of(eventOutId, mapperWrapper.serialize(kafkaEventOut)); // message will be send to the out topic
}
}
- Add the following dependency:
<dependency>
<groupId>tech.artcoded</groupId>
<artifactId>atriangle-core-rest</artifactId>
</dependency>
- Include the following profile:
spring:
application:
name: MyService # important for zuul
profiles:
include: kafka, zookeeper, rest
- On the main app, add the SwaggerConfig and enable discovery:
@SpringBootApplication
@Import({KafkaConfig.class, SwaggerConfig.class})
@EnableDiscoveryClient
public class MyServiceApplicaton {
public static void main(String[] args) {
SpringApplication.run(MyServiceApplicaton.class, args);
}
}
- Create a controller:
@CrossOriginRestController
@ApiOperation("Hello Rest")
@Slf4j
public class MyController implements PingControllerTrait {
@GetMapping(path = "/hello")
public ResponseEntity<String> hello() {
return ResponseEntity.ok("hello");
}
}
- add the zuul config to
common/shared-config/src/main/resources/application-zuul.yml
:
hello:
path: /api/hello/**
serviceId: MyService # spring.application.name
- run the main
- run the rest-gateway
microservices/web/rest-gateway/src/main/java/tech/artcoded/atriangle/rest/RestProxyGatewayApplication.java
- ping the new service: http://localhost:8088/api/hello/ping or http://localhost:8088/api/hello/swagger-ui.html
sh release.sh 0.1.5 0.1.6
© artcoded.tech