Assessments: Answer: The Following Functionality Is Provided by The
Assessments: Answer: The Following Functionality Is Provided by The
Chapter 2
1. What is the purpose of the @SpringBootApplication annotation?
It enables component scanning, that is, looking for Spring components and
configuration classes, in the package of the application class and all its sub-
packages.
The application class itself becomes a configuration class.
It enables auto-configuration, where Spring Boot looks for JAR files in the
classpath that it can configure automatically. If you, for example, have
Tomcat in the classpath, Spring Boot will automatically configure Tomcat as
an embedded web server.
2. What are the main differences between the older Spring component for
developing REST services, Spring Web MVC, and the new version, Spring
WebFlux?
Answer: Spring WebFlux supports the development of reactive, that is, non-
blocking, HTTP clients and services. It also supports non-Servlet-based web
servers such as Netty. Spring Web MVC only supports Servlet-based web servers.
Finally, Spring WebFlux comes with a new functional programming model
complementing the annotation-driven model introduced by Spring Web MVC
(which Spring WebFlux still supports).
4. What is the function of a repository in Spring Data and what is the simplest
possible implementation of a repository?
Chapter 3
1. What is the command to list available dependencies when you create a new
Spring Boot project using the Spring Initializr CLI tool spring init?
2. How can you set up Gradle to build multiple related projects with one
command?
Answer: Create a file named settings.gradle in the root folder with one
include statement for each sub-project or module, for example:
include ':microservices:product-service'
include ':microservices:review-service'
[2]
Assessments
Answer: They are used in Spring WebFlux to indicate that a method parameter
should be bound either to the URI part or as a request parameter in an API. For an
example usage of a @PathVariable annotation, refer to the getProduct method
in $BOOK_HOME/Chapter03/2-basic-rest-
services/api/src/main/java/se/magnus/api/core/product/ProductSe
rvice.java. For an example usage of a @RequestParam annotation, refer to the
getRecommendations method in
$BOOK_HOME/Chapter03/2-basic-rest-
services/api/src/main/java/se/magnus/api/core/recommendation/Re
commendationService.java.
4. How can you separate protocol-specific error handling from the business logic in
an API implementation class?
Chapter 4
1. What are the major differences between a virtual machine and a Docker
container?
[3]
Assessments
3. What happens with a Java application that doesn't honor the max memory
settings in a container and allocates more memory than it is allowed to?
Answer: It is killed by Docker without giving the Java application any chance to
react by, for example, logging relevant information regarding what caused it to
allocate too much memory.
5. Why will the following Docker Compose code snippet not work?
review:
build: microservices/review-service
ports:
- "8080:8080"
environment:
- SPRING_PROFILES_ACTIVE=docker
product-composite:
build: microservices/product-composite-service
ports:
- "8080:8080"
environment:
- SPRING_PROFILES_ACTIVE=docker
[4]
Assessments
Answer: Since both the review and product-composite services try to bind
their local port, 8080, to the same port in the Docker host, one of them will get an
error during startup along the lines of the following: Bind for 0.0.0.0:8080
failed: port is already allocated.
Changing the port mapping for one of the services will solve the problem, for
example, mapping to port 8081 on the Docker host:
ports:
- "8081:8080"
Chapter 5
1. How does SpringFox help us to create API documentation of RESTful services?
[5]
Assessments
value, row 2
6. How can you repeat a call to an API performed using the embedded Swagger
viewer without using the viewer again?
Answer: You can copy the prepared curl command in the response part and run
it in a terminal window.
Chapter 6
1. When using Spring Data, a common programming model based on entities and
repositories can be used for different types of database engine. From the source
code examples in this chapter, what are the most important differences in the
persistence code between MySQL and MongoDB?
Answer: The MySQL entity class uses JPA annotations, the @Entity annotation.
The MongoDB entity class uses annotations from the Spring Data MongoDB
module, for example, @Document. Since MySQL, just like any other relational
database, is transactional, custom methods added to the MySQL repository must
have annotations describing their transactional semantics, for example, using a
read-only transaction for methods that only read data from the MySQL database.
Answer: Annotate a field in the entity class with the @Version annotation.
4. What does it mean when we specify that an operation is idempotent, and why is
that useful?
Answer: It means that the operation will return the same result if called several
times with the same input parameters. The state of an underlying database, if any,
will also remain the same if the operation is called one or several times with the
same input parameters. Operations that may experience temporary errors, for
example, network-related problems, can simply be called several times, in the
case of a temporary error, until they return a successful response given that they
are idempotent.
[6]
Assessments
5. How can we access the data that is stored in MySQL and MongoDB
databases without using the API?
Chapter 7
1. Why is it important to know how to develop reactive microservices?
[7]
Assessments
This code will register a subscriber and the subscriber will apply the lambda
function specified in the call to the subscribe method on each element it gets from
the stream; in other words, it will add them to the list element.
[8]
Assessments
6. What are the challenges in writing tests with reactive code using JUnit and how
can we handle them?
Chapter 8
1. What is the purpose of Netflix Eureka?
Answer: Acting as an edge server, it can hide private APIs and secure public APIs
from external usage. It also provides a single entry point to the public APIs in a
system landscape of microservices.
Answer: Spring Cloud Config comes with built-in support for the following:
Git repositories
Local filesystem
HashiCorp Vault
JDBC databases
Circuit breaker
Rate limiter
Bulkhead
Retries
Timeout
5. What are the trace tree and span concepts used for in distributed tracing, and
[9]
Assessments
Chapter 9
1. What is required to turn a Spring Boot application created with Spring Initializr
into a fully fledged Netflix Eureka Server?
[ 10 ]
Assessments
1. That the HTTP client used is made load balancer-aware. Using the
reactive WebClient class, this can be done with the following code
@Bean:
@LoadBalanced
public WebClient.Builder loadBalancedWebClientBuilder() {
final WebClient.Builder builder = WebClient.builder();
return builder;
}
2. Using the URL hostnames that are the same as the microservice
application name as specified in its property:
spring.application.name. This is the name that the microservice
will be known by in the Eureka Server.
4. Let's assume that you have a Netflix Eureka server up and running, along with
one instance of microservice A and two instances of microservice B. All
microservice instances register themselves with the Netflix Eureka server.
Microservice A makes HTTP requests to microservice B based on the information
it gets from the Eureka server. What will happen if, in turn:
Answer: After a while, thanks to the resilience capabilities built into Netflix
Eureka, Netflix Ribbon, and Spring Cloud, the information regarding available
microservices will be in sync and the two instances of microservice A will be able
to utilize both of the instances of microservice B. The time it takes to synchronize
the discovery information depends on the configuration used.
Chapter 10
1. What elements are used to build a routing rule in Spring Cloud Gateway called?
[ 11 ]
Assessments
Answer: Replace the http and https protocol used in the URL with lb. By way
of a hostname in the URL, use the name of the microservice as registered in the
Eureka server, in other words, the name specified in the
spring.application.name property of the microservice.
4. In a Docker environment, how can we ensure that external HTTP requests to the
Docker engine can only reach the edge server?
Answer: This can be achieved by only exposing ports in the Docker host from the
edge server. This means only using ports: in the Docker Compose files for the
edge server container.
5. How do we change the routing rules so that the edge server accepts calls to the
product-composite service on the http://$HOST:$PORT/api/product URL
instead of the currently used http://$HOST:$PORT/product-composite?
Answer: Using the SetPath filter, we can replace the id: product-
composite routing rule with a new route such as the following:
- id: api-product-composite-1
uri: lb://product-composite
predicates:
- Path=/api/product/{segment}
filters:
- SetPath=/product-composite/{segment}
[ 12 ]
Assessments
for example, GET and DELETE requests. But it will not match a POST on
http://$HOST:$PORT/api/product. To also support the POST request, we can
add a second route:
- id: api-product-composite-2
uri: lb://product-composite
predicates:
- Path=/api/product
filters:
- SetPath=/product-composite
# Try read the product again, should fail with the HTTP status "404
Not Found"
curl -i http://$HOST:$PORT/api/product/123456789 -H "Authorization:
Bearer $ACCESS_TOKEN"
Expect all requests, except the last one, to return the 200 OK HTTP status the last
request should return the 404 Not Found HTTP status.
Chapter 11
1. What are the benefits and shortcomings using self-signed certificates?
[ 13 ]
Assessments
Benefits: They are convenient to use during development and tests since
you can create them yourself.
Shortcomings: Web browsers and mobile devices don't trust them, so they
can't be used in production.
Answer: JWT tokens, a.k.a a JSON Web Tokens, are an open standard (https://
tools.ietf.org/html/rfc7519) for sending information in a token.
Answer: JWT tokens can be signed by the sender, which means that the receiver
of a JWT token can trust the content in the token, given that the signature is
validated by the receiver.
6. Is it suitable to use the OAuth 2.0 authorization code grant flow with a native
mobile app?
Answer: In general, no, since a native mobile app can't protect the client secret
that needs to be used in an authorization code grant flow. This means that in
practice, it does not provide any increased security over the simpler implicit grant
flow.
[ 14 ]
Assessments
RFC8252 - OAuth 2.0 for Native Apps relies on the use of RFC 7636: Proof Key for
Code Exchange (https://tools.ietf.org/html/rfc7636).
Chapter 12
1. What API call can we expect from a review service to the config server during
startup to retrieve its configuration?
Answer: Given that we are running the microservices in Docker, we can expect
the following call:
http://${username}:${password}@config-server:8888/review/docker.
2. The review service was started up using the following command: docker
compose up -d.
What configuration information should we expect back from an API call to the
config server using the following command:
curl
https://dev-usr:dev-pwd@localhost:8443/config/application/default -
ks | jq
Answer: We can expect the configuration that applies to all microservices using
the default Spring profile: basically, the content of the application.yml file that
does not belong to a specific SPring profile.
Answer:
Git repositories
Local filesystem
HashiCorp Vault
JDBC databases
4. How can we encrypt sensitive information on disk using Spring Cloud Config?
[ 15 ]
Assessments
information when stored on disk. The config server supports the use of both
symmetric and asymmetric keys. Asymmetric keys are more secure but harder to
manage. The configuration server provides endpoints for encrypting and
decrypting information: /config/encrypt and /config/decrypt. Access to
these endpoints must be locked down before being used in production.
6. Mention some pros and cons for clients that first connect to the config server vis-
à-vis those that first connect to the discovery server.
Pros: This is the default behavior and easy to configure. It requires clients to have
a local configuration for how to connect to the configuration server. The
remainder of the configuration information will be retrieved from the
configuration server, including a configuration for how to communicate with the
discovery server. Also, the discovery server can store its configuration in the
config server.
Cons: This scenario requires a more complex local configuration of the clients.
[ 16 ]
Assessments
The clients must have both a local configurations for how to connect to the
discovery server and some configuration (except for URLs) for how to connect to
the configuration server.
Chapter 13
1. What are the states of a circuit breaker and how are they used?
Closed. This is the state for normal operation; all requests are sent through
the circuit breaker.
Open. Too many failures have been detected and no requests are allowed.
The circuit breaker will perform fast failure logic. This means that it doesn't
wait for a new fault, for example, a timeout, to happen on subsequent
requests. Instead, it redirects the call directly to a fallback method.
Half-Open. The circuit breaker allows a new request to be sent through to
see whether the issue that caused the failures has disappeared.
4. How can a retry mechanism and a circuit breaker interfere with one another?
Answer: If a circuit breaker is configured to open the circuit too soon, the retry
mechanism might not get a chance to perform all the retries it is configured to
perform before giving up.
5. Provide an example of a service that you can't apply a retry mechanism to.
Answer: A service that is not idempotent (by which we mean, calling the service
one or many times with the same request parameters) does not give the same
[ 17 ]
Assessments
result. This can, for example, be a service for creating orders. If an order creation
service doesn't have logic for detecting retry attempts, it may create multiple
orders instead of just one.
Chapter 14
1. What configuration parameter is used to control how trace information is sent to
Zipkin?
Answer: It is used to limit the number of spans that are sent to Zipkin. By default,
it is set to 0.1; in other words, 10% of all spans are sent to Zipkin. This can be
a sensible value in production environments to avoid flooding Zipkin but, for
development, we often want all spans sent to Zipkin, by setting this value to 1.0.
3. How can you identify the longest-running request after executing the test script,
test-em-all.bash?
Answer: By setting the Sort parameter to Longest First in the Zipkin UI.
4. How can we find requests interrupted by the timeout introduced in Chapter 13,
Improving Resilience Using Resilience4j?
Answer: If you set the Sort parameter to Longest First, you will find them at
the top of the list.
However, you can also be a bit more precise in your search and specify the
following:
Note that it is the second product-composite span that has the error field set
to CANCELLED, so it is important that you don't search for the gateway service
only!
[ 18 ]
Assessments
5. What does the trace look like for an API request when the circuit breaker
introduced in Chapter 13, Improving Resilience using Resilience4j, is open?
Answer: We do expect a short response time when the circuit breaker is open; in
other words, when fast fallback to the fallback method has been applied.
Therefore, perform a search with the following parameter settings:
The first two traces in the response should come from a request with the circuit
breaker open. Click on one of them. They should appear as follows:
Note that the call to the product service failed, due to the open circuit breaker, but
the request succeeded thanks to the fallback method applied by the product-
composite service!
6. How can we find APIs that failed due to the caller not being authorized to
perform the request?
Answer: Search for error=403 in the Annotation Query parameter and you will
find an HTTP DELETE request that failed due to the user not having enough
[ 19 ]
Assessments
Chapter 15
1. What happens if you run the same kubectl create command twice?
2. What happens if you run the same kubectl apply command twice?
Answer: The command succeeds and returns information to the effect that the
affected objects are unchanged.
3. In terms of questions 1 and 2, why do they act differently the second time they
are run?
Answer: The create command is imperative. This means that it tells Kubernetes
exactly what to do. The apply command is declarative, this means that it is up to
Kubernetes to find out what to do if anything at all needs to be done, as in this
case.
6. How can a container find out the IP address of another container that runs in the
same pod?
Answer: Containers in the same pod share the same network namespace,
meaning that they have the same IP address and port space. They can
communicate with each other using the localhost hostname, or the IP address
127.0.0.1. They have to ensure that they don't use the same ports.
7. What happens if you create two deployments with the same name but in
[ 20 ]
Assessments
different namespaces?
Answer: This works perfectly fine. For example, two developers can run their
own versions of a group of deployments and pods in two different namespaces in
the same Kubernetes cluster.
8. What can make the creation of two services with the same name fail if they are
created in two different namespaces?
Answer: If the services are of the NodePort type and try to allocate the same
node port, they will conflict and the creation of the second service will fail.
Chapter 16
1. Why did we remove the Eureka server from the microservice landscape when
deploying it on Kubernetes?
2. What did we replace the Eureka server with and how was the source code of the
microservices affected by this change?
Answer: The Eureka server was replaced by built-in Kubernetes service objects
and the kube-proxy runtime component.
The source code itself in the microservices was not affected by this change.
However, the build dependencies and configuration were changed on account of
the following:
[ 21 ]
Assessments
4. How can we get a running pod updated with changes in a config map or secret?
5. If we are using the latest tag on a Docker image, how can we get running pods
using a new build of the Docker image?
The following example is based on the fact that the product deployment is rolled
back to revision 2:
kubectl rollout history deployment product
kubectl rollout undo deployment product --to-revision=2
[ 22 ]
Assessments
8. What are the different ports used for in the following service definition?
apiVersion: v1
kind: Service
spec:
type: NodePort
ports:
- port: 443
nodePort: 31443
targetPort: 8443
Answer:
port: 443: specifies on which port the services will be accessible, that is,
internally in the cluster
nodePort: 31443: specifies on what port the service will be externally
accessible using any of the nodes in the cluster
targetPort: 8443, specifies the port in the pod to which the requests will
be forwarded, that is, the container port
Chapter 17
1. How was the Spring Cloud Config Server replaced by Kubernetes resources?
[ 23 ]
Assessments
4. What role do Cert Manager and Let's Encrypt play in automating the
provisioning of certificates?
Answer:
6. Why did we use ngrok and what can we do to avoid using it?
Answer: Ngrok is used to create a temporary HTTP tunnel from the internet to
the local Kubernetes cluster running in Minikube. The HTTP tunnel is used by
Let's Encrypt to verify that we own the DNS name of the endpoint we want to
issue a certificate for. To eliminate the HTTP tunnel, we must be able to expose
the endpoint to the internet, for example, by running the Kubernetes cluster on a
server with a public IP address reachable from the internet.
Chapter 18
1. What is the function of a proxy component in a service mesh?
Answer: The proxy component is injected in each pod that is part of the service
mesh and controls its incoming and outgoing traffic. The proxy component also
[ 24 ]
Assessments
2. What's the difference between a control plane and a data plane in a service mesh?
Answer: The data plane consists of proxy components together with gateway
components that handle external incoming and outgoing traffic to and from the
service mesh. The control plane manages the components in the data plane and
also collects metrics and telemetry data used for monitoring and observation.
Answer: It is used to inject Istio's proxy components into pods, in other words, to
add an Istio proxy component to a pod as a sidecar.
Answer: Both the client and server sides need to agree on using mutual
authentication. The server side is controlled by a Policy object that can be set to
be either STRICT or PERMISSIVE (in other words, allowing both plaintext and
HTTPS with mutual authentication). Clients are configured using
DestinationRule objects where TLS mode can be set to ISTIO_MUTUAL.
7. What can the abort and delay elements in a virtual service be used for?
[ 25 ]
Assessments
Chapter 19
1. A user searched for ERROR log messages in the hands-on namespace for the last
30 days using the search criteria shown in the following screenshot, but none
were found. Why?
2. A user has found a log record of interest. How can the user find related log
records from this and other microservices, for example, coming from the
processing of an external API request?:
[ 26 ]
Assessments
Answer: Use the spring.trace field in the log record, which contains the trace
ID, as a correlation ID to search for other log records that also contain the same
value in their spring.trace field.
3. A user has found a log record that seems to indicate the root cause of a problem
reported by an end user. How can the user find the stack trace that shows where
the error occurred in the source code?:
[ 27 ]
Assessments
Answer: Click on the View surrounding documents link to find log records with
stack traces reported in near time of the log record.
6. Suddenly, you lose the connection with Kibana from your web browser. What
may be the root cause of the problem?
Answer: It may be that the minikube tunnel command has stopped running.
Restart it if required.
[ 28 ]
Assessments
Chapter 20
1. What changes did we need to make to the source code in the microservices to
make them produce metrics that are consumed by Prometheus?
Annotations were added in the pod templets in the deployment objects to let
Prometheus know where to find the metrics:
annotations:
prometheus.io/scrape: "true"
prometheus.io/port: "4004"
prometheus.io/scheme: http
prometheus.io/path: "/actuator/prometheus"
Answer: It is used to tag the Prometheus metrics with the name of the
microservice. The following configuration was added to the file in the
configuration repository, config-repo/application.yml configuration
repository:
management.metrics.tags.application: ${spring.application.name}
3. If you want to analyze a support case regarding high CPU consumption, which
of the dashboards in this chapter would you start with?
Answer: The dashboard named JVM (Micrometer), and look for high CPU
consumption. The Istio Mesh Dashboard dashboard can also be of help in
determining whether any specific service currently has longer response times
than usual. It could indicate what services you should start to investigate. Also,
the Kiali graph view may be of considerable help in getting an overview of the
situation from an application view.
4. If you want to analyze a support case regarding slow API responses, which of the
dashboards in this chapter would you start with?
[ 29 ]
Assessments
Answer: Start with the Istio Mesh Dashboard to get an overview of what services
appear to be slow. Follow up with the Istio Service Dashboard and JVM
(Micrometer) dashboards to ascertain further details. Also, the Kiali graph view
can be of considerable help in obtaining an overview of the situation from an
application perspective.
Answer: Only the counter-based metric value has increased, making it hard to
identify trends in a dashboard. The rate function in Grafana can be used to
convert a counter metric to a counts per second metric, making it much easier to see
changes in how the increased rate goes up or down.
6. Why does the metric for the circuit breaker report 1 for a short while before it
reports 2?
Answer: 1 means that the circuit breaker is in its open state, while 2 means that is
is half-open. 0 means that it is closed.
[ 30 ]