Παρασκευή 5 Νοεμβρίου 2021

Spring Certification: Aspect-Oriented Programming (AOP)

What is the concept of AOP? Which problem does it solve? What is a cross cutting concern?

  • AOP is a programmatic technique to apply separation of concerns regarding cross-cutting concerns, like transaction management, security, logging and more. It allows to decouple these concerns from tangling with the business code. Thus, reduces duplicating same code. It uses "advices" applied on "pointcuts" upon calling.
  • Cross-cutting corcerns are basic functionalities that complement the business code, like the mentioned above.


What is a pointcut, a join point, an advice, an aspect, weaving?

  • Pointcut: predicate that matches join points with advice
  • Join Point: represents the effective execution of a method where the aspect applies
  • Advice: the action taken by Aspect at a join point
  • Aspect: modularization of a concern that cuts across multiple classes
  • Weaving: program transformation that applies the aspect to the target object, in order to create the advised object (target object). Happens in runtime for Spring AOP, and in compile-time and runtime for AspectJ.



How does Spring solve (implement) a cross cutting concern?

  • Spring makes use of  proxy objects that wrap the target bean and intercept any method invocations that are defined by the pointcuts of an advice. These proxies are created at runtime, and can be JDK Dynamic proxies (Spring default) or CGLIB proxies


Which are the limitations of the two proxy-types?
  • JDK Dynamic Proxy
    • Target class must implement an interface
    • Only public methods that reside in interface can be proxied
    • If target method is calling another method, proxy won't work for this second method
  • CGLIB proxy
    • Target class and methods must not be final
    • Protected and public visibilities are supported
    • No self-invocation as for JDK Dynamic proxy
    • Needs and extra library spring-core, while JDK Dynamic proxy is built-in


How many advice types does Spring support? Can you name each one?

  • Before advice
    Performs some action, and then proceeds to execution of JoinPoint
    If any exception occurs though, it does not proceed.



  • After (finally) advice
    Always executes after target method has run, regardless of exception or success.





  • After Returning advice
    Executes after successful completion of JoinPoint's target method
    Provides access to returned object with "returning" attribute



  • After Throwing advice
    Executes only if target method contains an exception
    Provides access to returned object with "throwing" attribute


  • Around advice
    The most useful advice, it can manipulate the target method's params, catch exceptions from it and advice itself, and handle normal execution result.
    It can catch any exception of target method execution inside it immediately



What do you have to do to enable the detection of the @Aspect annotation? What does @EnableAspectJAutoProxy do?
  • We would need to enable AspectJ support, thus add spring-aspects dependency in pom
  • Annotate a @Configuration file with @EnableAspectJAutoProxy
  • Finally, in our @Component that we'll apply advices and pointcuts, annotate it with @Aspect
    If we have @Bean for this, annotate Bean POJO class with @Aspect
  • @EnableAspectJAutoProxy annotation activates the support for components marked with AspectJ’s @Aspect annotation 


If shown pointcut expressions, would you understand them?
  • execution(public * com.code.in.packets.SomeBean.*(int, ..))
    Targets all methods of SomeBean of com.code.in.packets package, that return anything, are public and take one int and any other parameters
  • within(com.code.in.*)    
    Targets all methods of all classes in com.code.in package and all subpackages
  • within(SomeInterface+)
    Matches for all the methods of classes that implement the 
    SomeInterface
  • within(com.code.in.packets.SomeService+)
    Matches for SomeService class and for all of its subclasses


What is the JoinPoint argument used for?
  • Upon advice invocation, JoinPoint parameter holds reference to an object that holds static information about the join point. From a JoinPoint we can access:
  1. target object - getTarget()
  2. method signature - getSignature()
  3. method arguments - getArgs() methods.


What is a ProceedingJoinPoint? Which advice type is it used with?
  • ProceedingJoinPoint is a type JoinPoint, used on @Around advice.
  • It is the first parameter of the advice
  • It has a proceed() method used to call the join point, which also could alter the parameters of the target method

-----------------------------------------------------------------------------------------------------


Questions from EDU-1202 exam (2021)


What advice is used to stop the propagation of an exception up the call stack?
  • Around advice can catch any exception from the target method execution, and throw an other, or do something else. Because Around wraps the executed method, it has complete control over the flow.

Πέμπτη 4 Νοεμβρίου 2021

Spring Certification: Container, Dependency and IOC

What is dependency injection and what are the advantages of using it?
  • Dependency injection is a technique where application components don't create their dependencies on their own, but instead declare the dependencies' interfaces, and then the application context finds and applies real implementations of them
  • Advantages:
    • Reduced coupling
    • Increased cohesion
    • Reduced boilerplate code
    • Facilitates testing (use of mocks in place of dependencies)
    • Increased code maintainability, re-usability and readability

What is an interface and what are the advantages of making use of them in Java?
  • Interface is a Java reference type that holds a blueprint of the functionalities that should be implemented from a class. It provides a contract for an object's functionalities. It enforces the implementation of an API.
  • Advantages:
    • Decoupling of contract and implementation
    • Enables implementations' interchangeability
    • Allows implementation hiding, so that only the interface is public, and all implementations are protected, and thus one can only use e.g. @Qualifier("bean1") in caller class
    • In Spring, allows the use of JDK Dynamic Proxy

What is an ApplicationContext?
  • ApplicationContext is the representation of the Spring IoC container, and holds registered and initialized beans and components, ready for use in runtime. Also:
  • Provides access to the Environment abstraction and its properties
  • Pushes events to registered listeners
  • Manages beans lifecycle 
  • Resolves internationalization messages

How are you going to create a new instance of an ApplicationContext?
  • Web applications:
    • Inside a class implementing ServletContainerInitializer, use AnnotationConfigWebApplicationContext to include a Java Configuration file
    • Use a WebXmlApplicationContext, to include xml(s) holding all configuration
  • Standalone application:
    • Use AnnotationConfigApplicationContext to include a Java Configuration file
    • Use ClassXmlApplicationContext to load the xml configuration from classpath/jar
    • Use FileSystemXmlApplicationContext to load the xml configuration from the file system

What is the concept of a Container, what its lifecycle?
  • Container is an execution environment that plays a central role in assembling user-defined components, managing their lifecycle and also providing basic functionalities, like HTTP and REST.
    It usually supports the inversion-of-control (IOC) principle, so that the programmer only creates beans and declares dependencies, and finally the Container does the underlying work of linking all together.
  • Lifecycle:
    • App starts
    • Container is created and load all configuration to
    • create Bean Definitions
    • Any BeanFactoryPostProcessors now run to alter the definitions
    • Bean instances are created
    • Any bean dependencies and property injections are resolved
    • Any BeanPostProcessors run to alter bean instances
    • App now is up and ready 
    • App shutdown is initiated
    • Context is closing
    • Any destruction callbacks take place to release resources, etc


Can you describe the lifecycle of a Spring Bean in an ApplicationContext?

  • Context is created
  • Bean Definitions created (Spring Bean Configuration)
  • BeanFactoryPostProcessors 
  • Bean Instance created (constructor runs)
  • Properties and dependencies are resolved
  • BeanPostProcessor: postprocessBeforeInitialization method 
  • @PostConstruct annotated method 
  • InitializingBean::afterPropertiesSet 
  • @Bean(initMethod) 
  • BeanPostProcessor: postprocessAfterInitialization method 
  • Bean ready to use.
  • Bean destroyed:
  • @PreDestroy
  • DisposableBean::destroy
  • Bean(@DestroyMethod)


How are you going to create an ApplicationContext in an integration test?
  • Import maven dependencies of spring-test and JUnit
  • Before JUnit 5: Annotate test class with @RunWith(SpringRunner.class) and @ContextConfiguration(classes = MyAppConf.class)
  • After JUnit 5: Annotate test class with @ExtendWith(SpringExtension.class) @ContextConfiguration(classes=MyAppConf.class)
  • If @ContextConfiguration has no "classes" attribute, then xml <TestClass>-context.xml will be loaded
  • @ContextConfiguration can also accept XML config:
    • Example: @ContextConfiguration("file:src/main/webapp/WEB-INF/spring-config.xml")
  • To above, add annotation @WebAppConfiguration to load a web related test context. However on Spring Boot, @SpringBootTest already provides a WebApplicationContext.
  • Use @DirtiesContext to clean/restart context between tests


What is the preferred way to close an application context? Does Spring Boot do this for you?
  • Non-web / Standalone app: Call registerShutDownHook immediately on a AnnotationConfigApplicationContext. This will trigger a JVM shutdown informing all beans, etc
  • Don't use close() on the context, since some exception may occur before that
  • Web app: Servlet will send closing event to ContextLoaderListener, which in turn will close the application context 
  • Spring Boot: Automatically registers the shutdown hook which closes the application context. For web apps, the same logic with above ContextLoaderListener applies


Are beans lazily or eagerly instantiated by default? How do you alter this behavior?
  • By default, Beans (Singletons by default) are eagerly instantiated on startup.
  • Note that each singleton bean is used for multiple threads.
  • Beans with prototype scope are lazily instantiated (on demand)
  • To alter, below ways exist:
    • @ComponentScan(lazyInit = true) to make scanned beans lazy
    • @Lazy on Bean to change default eagerness to lazy 
    • @Lazy(false) to force eagerness 
    • @Lazy on @Component class
    • @Lazy on @Configuration class (makes all @Bean-s lazy)

What is a property source? How would you use @PropertySource?
  • Property sources are key-value pairs in yaml/xml files, and accessed using a Spring abstraction on Environment key-value pairs (JVM, JNDI, system ..)

  • @PropertySource is used on top of a component class, like:

    • @PropertySources({
      @PropertySource("file:${app-home}/app-db.properties"),
      @PropertySource("classpath:/app-defaults.properties")
      })
    • If using non-default properties file name (other than application.properties/yml), define a PropertySourcePlaceholderConfigurer bean with the @Bean annotation to activate the placeholder resolving mechanism
    • Set @Value("${propertyKey:defaultValue}") on a field, to retrieve and initialize it


Can you describe: 
Dependency injection using Java configuration?
Dependency injection using Annotations (@Component, @Autowired)?
Component Scanning, stereotypes?
Scopes for Spring beans? What is the default scope?

  • Dependency injection using Java configuration
    • SpringBean1,2,3 are plain POJO classes
    • In our central configuration class, we appoint them as @Bean-s
    • Use of @Autowired to inject SpringBean1's dependencies (SpringBean2,3)

  • Dependency injection using Annotations (@Component, @Autowired)
    • Each bean will be annotated with @Component in its own class file
    • If any bean has dependencies on other beans, we create fields of these beans annotated with @Autowired
    • The Configuration file is annotated with @ComponentScan, and placed on a directory level higher than all our @Component beans




  • Component Scanning, Stereotypes?
    •  Spring will scan project classpath for classes annotated with stereotype annotations like @Component, @Repository, @Service, @Controller and more, in order to create Bean Definitions. 
    • @ComponentScan is used for this, applied in project root usually
    • Attributes "basePackages", "includeFilters", "excludeFilters" can be added for named adjustments.
    • Stereotypes refer to annotations that define some specific role in the project, thus: 
      • @Component  (Spring component, scanning candidate)
      • @Controller   (Component to handle the web layer)
      •  @Service   (Component to handle the Service layer)
      • @Repository  (Component to create beans in DAO layer)

  • Scopes for Spring beans? What is the default scope?
    • Scopes: Singleton, Prototype, Request, Session, Application, WebSocket

    • Default scope for @Components is the Singleton scope (also eager)

    • Singleton: Never hold state in these, in a multithreaded environment. All threads access the unique shared instance, and there may be concurrency issues. More:
      https://dzone.com/articles/how-does-singleton-bean-serve-multiple-requests-at

    • Prototype: A typical use case to create a bean in request scope is for information that should only be valid on one page. For example, the confirmation of an order. The bean will be valid until the page is reloaded.

    • Prototype case: A Singleton bean might contain a prototype bean. The issue is that since the Singleton will be instatiated only once, the prototype bean instance will be also unique. To solve this issue use the Lookup Method Injection: https://docs.spring.io/spring-framework/docs/3.0.0.M4/reference/html/ch03s04.html#beans-factory-lookup-method-injection





What is a BeanFactoryPostProcessor and what is it used for? When is it invoked?

  • BeanFactoryPostProcessor is an interface holding one postProcessBeanFactory method 
  • It is used to modify(not create) Spring Bean metadata, that will be used later to create the actual Beans
  • It is invoked before Spring Bean is created and after Spring discovers all Bean Definitions


What is a BeanPostProcessor and how is it different to a BeanFactoryPostProcessor? What do they do? When are they called?
  • BeanPostProcessor holds two methods: postProcessBeforeInitialization and postProcessAfterInitialization 
  • The difference with BeanFactoryPostProcessor, is that it acts after the Spring Bean is created from the Bean definition, and its dependencies and property injections are done
  • Thus BeanFactoryPostProcessor acts on Bean Definition, while BeanPostProcessor acts on actual Spring Bean object


Why would you define a static @Bean method when creating your own?

  • The reason would be to have it run before any object instance creation is done
  • Example:





What is a PropertySourcesPlaceholderConfigurer used for?
  • Ιt is a BeanFactoryPostProcessor bean used to resolve properties' placeholders in Spring Beans, and specifically on fields with @Value("${propertyName}") annotation


What is an initialization method and how is it declared on a Spring bean?
  • Initialization method purpose is to perform alterations on Spring Bean after all properties and dependencies are resolved. Otherwise, having initialization functionality inside constructor is a bad practice, since properties and dependencies may not have been resolved yet
  • Three ways to set init method:
    • @Bean(initMethod = "initMyBean")
    • @PostConstruct
    • Implement InitializingBean and override afterPropertiesSet (not recommended)


What is a destroy method, how is it declared and when is it called?
  • Destroy method is called to release resources a Bean uses, before it reaches end of life
  • It is declared in three ways:
    • @PreDestroy annotated methods inside Beans
    • Implementing a DisposableBean in our Bean class, and overriding its destroy() method
    • Use @Bean(destroyMethod = "someDestroyMethod")
  • Singleton beans (as default @Component-s) destroy method is called when application and Spring container starts to shut down. A session-scoped bean's destroy will be invoked after session ends. Same for request-scope. But, prototype-scoped beans aren't tracked from Spring after being created, so destroy method won't be called automatically.

Consider how you enable JSR-250 annotations like @PostConstruct and @PreDestroy?
  • When using AnnotationConfigApplicationContext, support for @PostConstruct and @PreDestroy is added automatically. Specifically, these are handled by CommonAnnotationBeanPostProcessor.



What does component-scanning do?
  • Spring framework scans project classpath in search for classes annotated with Stereotype annotations (@Component, @Controller, @Service, @Repository), and creates Bean Definitions in Spring container.


What is the behavior of the annotation @Autowired with regards to field injection, constructor injection and method injection?
  • Autowired annotation is processed by AutowiredAnnotationBeanPostProcessor and enables automatic Spring Dependency Resolution based on types. If there are multiple implementations for a type, we need to specify the unique candidate, usually with @Qualifier or @Primary or Spring will automatically match bean name

  • Autowired injection takes place after Bean constructor is run, to resolve the wanted dependencies. Autowired injections finishes before any initialization method (@PostConstruct, InitializingBean, @Bean(initMethod))

  • Constructor injection: @Autowired is applied above constructor method. All dependencies must not be null. If we expect some dependency to be null, use Optional, @Nullable, or @Autowired(required=false) for that parameter. If we have many constructors, we must apply @Autowire in one only.

    Tip:
     Use constructor injection to ensure with IoC container that all required dependencies are successfully initialized, and prevent NPEs. Additionally, all dependencies are visible in one place, and any refactoring need is facilitated.

  • Method/Setter injection: Same as above, and also if some parameter(s) are expected to be null, use @Autowired(required=false) above method. Preferable for optional dependencies.

  • Method injection - Map/Collection:
    @Autowired
    public void setRecordsReaders(List<RecordsReader> recordsReaders) {}

    Spring autowires all implementations of interface RecordsReader, by @Order or @Priority annotations, or Ordered interface 

  • Field injection: Same as above

  • More: https://reflectoring.io/constructor-injection/



What do you have to do, if you would like to inject something into a private field? How does this impact testing?
  • Use @MockBean to inject a mock in a private field (Here, ReportWriter is a private field of ReportService). Spring Test framework will create an application context, where the ReportWriter Bean will be replaced with a mock.
  • Use Mockito mock. No Spring application context is loaded here, only plain mocks. @InjectMocks will recognize and inject @Mocks that are dependencies of ReportService


  • Use ReflectionTestUtils to alter a private field using Reflection. Not recommended since a name refactoring will break this


  • Use @TestPropertySource to introduce a test properties file, to be utilized by @Value annotations in the code.


    Here, the targeted private field is a String. The @Value annotation will read property from the test property file of @TestPropertySource








How does the @Qualifier annotation complement the use of @Autowired?

  • "dbRecordsProcessor" will be matched with available Bean name







  • Or define explicitly in @Component attribute the Bean name to match


  • Or define explicitly using @Qualifier


  • Include @Qualifier inside a custom meta-annotation






  • Use @Qualifier inside method parameters :

    @Autowired

    public void doStuff(@Qualifier("book") Book book)



What is a proxy object and what are the two different types of proxies Spring can create?

  • Proxies are used to add additional functionality on top of a class by intercepting caller access to this class, without altering class code. Proxies help on applying separation of concerns, e.g. logging, security, etc. Proxies hold same public method as the proxied class, to provide known access points
  • Example in Spring: There is a CGLIB proxy for each @Component singleton bean, to ensure all callers use the same and unique instance.  
  • Disadvantages:
    • Code hard to debug
    • Proxies not serializable
  • JDK Dynamic proxy
    • Proxied must implement an interface
    • Only interface methods can be proxied
    • No support for self invocation
  • CGLIB proxy
    • Proxied does not have to implement an interface
    • Proxied must not be final (CGLIB needs to extend this)


What are the advantages of Java Config? Limitations?
  • Advantages of Java Config versus XML configuration:
    • Compile-time checking vs XML's runtime checking
    • Most IDEs support refactoring adjustments for Java Config, while not for XML config
  • Advantages of Java Config versus Annotation-based configuration:
    • Beans are organized in single @Configuration file (better project organization)
    • Separation of concerns (Beans implementation resides outside the @Configuration + @Beans file)
    • Tech-agnosticism (Beans' implementations is a POJO class, not glued to Spring framework, while e.g. @Component class is Spring-specific)
    • Ability to integrate with 3rd-party libraries (Just have a @Bean method returning some modified library instance)
  • Disadvantages of Java Config:
    • @Configuration file and @Beans must not be Final, because these annotations utilize a CGLIB proxy which demands proxied object to be inheritable. 
      Note: CGLIB proxying is used to ensure that all callers access a single instance of the Bean (@Bean is by default a Singleton) 



What does the @Bean annotation do?
What is the default bean id if you only use @Bean? How can you override this?
  • @Bean is used in @Configuration files to tell Spring container to manage it as a Spring Bean. It also can define a Bean name identifier.
  • Cases of usage:
    • By default, the method name ("springBean3A") is set as bean's name. If @Bean name attribute exists, then "springBean3rd" is set as name.


    • Bean attributes "initMethod" and "destroyMethod"


    • Bean attribute "autowireCandidate" to tell if this bean should be used as dependency to other beans








Why are you not allowed to annotate a final class with @Configuration?
  • @Configuration file and @Beans must not be Final, because these annotations utilize a CGLIB proxy which demands proxied object to be inheritable.
  • Note: CGLIB proxying is used to ensure that all callers access a single instance of the Bean (@Bean is by default a Singleton)  


How do you configure profiles? What are possible use cases where they might be useful?
Can you use @Bean together with @Profile? Can you use @Component together with @Profile?
  • @Profile with @Component



  • @Profile with @Configuration
    (Also, we can have multiple configuration files per profile.
    Then, import all / some config files in main Configuration file : @Configuration @Import({Config1.class, Config2.class , ...}))









  • @Profile with @Bean (in @Configuration file)







  • @Profile included in custom annotation











To activate profiles, there are many ways:

  • Use ConfigurableEnvironment to set active profiles in Runner class










  • VM options: Dspring.profiles.active="profile1,profile2,profile3"

  • Use @ActiveProfiles in test class, to define profile(s) for Test Context to load










  • In Spring Boot, use SpringApplicationBuilder to set profiles:














  • In application.properties, define spring.profiles.active 



How many profiles can you have?
  • setActiveProfiles() accepts varargs, and that being a String array, can hold the maximum value of Integer (Integer.MAX_VALUE)


How do you inject scalar/literal values into Spring beans?
What is @Value used for?
  • Using @Value on field to inject value from properties file, in conjunction with @PropertySource

















  • Using plain primitive types




  • Using spEL language (Below example also uses property reference)



  • Can inject values from other Bean:






  • Can inject values from VM options or environment properties with "$"

  • Can inject whole Map, Sets in field





What is Spring Expression Language (SpEL for short)?
  •  SpEL is an expression language that evaluates the given expression at runtime and the results are injected in a field ready to use

  • It can be used with:

    • ExpressionParser and EvaluationContext
    • On top of constructors, fields, method parameters using @Value
  • SpEL expressions by default are interpreted dynamically at runtime, but we can choose to evaluate them in compile-time for performance reasons:
    • SpelCompilerMode has values Off (no compiler-time evaluation), Immediate (compiler enabled after first interpretation) and Mixed (in case of evaluation exception switches back to runtime, and again to compiler later)

What is the Environment abstraction in Spring?
  • Part of Spring Container that handles Profiles and Properties
  • Can use directly Environment to fetch properties
  • Decided default-activated profile, and active profile set by developer
  • Provides standard ways to resolve properties from configured property sources (property files, JVM, system environment variables, JNDI, servlet config, context params)
  • Standalone application: StandardEnvironment
  • Web application: StandardServletEnvironment (has also servlet configs and context params)


Where can properties in the environment come from – there are many sources for properties – check the documentation if not sure. Spring Boot adds even more.

  • Common sources for Spring Standalone, Spring Web, and Spring Boot apps
    • JVM properties
    • Properties files
    • Enviroment variables
  • Sources for Spring Web app:
    • JNDI
    • ServletConfig init params
    • ServletContext init params

  • Sources for Spring Boot app:
    • @TestPropertySource, @PropertySource
    • @SpringBootTest's property attribute 
    • Command line arguments
    • application.properties file (inside or outside or JAR)

What can you reference using SpEL?







What is the difference between $ and # in @Value expressions?

  • $  => reference a property in Spring Environment Abstraction
  • # => spEL expressions parsed and evalueated by SpEL




Σάββατο 23 Οκτωβρίου 2021

Spring Certification: Spring Boot Testing

When do you want to use @SpringBootTest annotation?
  • When we want to load whole ApplicationContext for our tests
  • Mostly when running a JUnit integration test
  • @SpringBootTest will search for a main configuration class or @SpringBootApplication annotated class upwards the project structure tree, and start a Spring application on a mock or running environment, with full application context - no slicing.
  • To use it:
    • JUnit 4 - Add @RunWith(SpringRunner.class) also
    • JUnit 5 - Runner is already included in the annotation

What does @SpringBootTest auto-configure?
  • @SpringBootTest  searches for  @SpringBootApplication / @SpringBootConfiguration, which contains @EnableAutoConfiguration, which triggers Spring AutoConfiguration mechanism.

  • So it uses all xxxAutoConfiguration classes in spring.factories, which autoconfigure all beans needed, according to what exists in the classpath

  • Alternatively, @SpringBootTest(classes = CustomApplication.class) sets a specific main configuration class

  • Also, @SpringBootTest(properties = "spring.main.web-application-type=reactive") takes in account specific properties file



What dependencies does spring-boot-starter-test brings to the classpath?
  • Spring Test
  • Spring Boot Test modules
  • JSONPath
  • JUnit,
  • AssertJ
  • Mockito
  • Hamcrest
  • JSONassert


How do you perform integration testing with @SpringBootTest for a web application?
  • Integration tests should be performed in a full running server environment, so we use:
    • @SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT) (or defined port)
    • And a fully configured TestRestTemplate or WebTestClient to act a REST client for our tests 
  • Integration tests could be run in a mock servlet environment, that by default @SpringBootTest bootstraps. The original application context will be loaded. For actual test methods, we will use MockMvc. Generally, note that there are no actual mocks of any classes. Also we don't need to use @MockBean or mocks like in @WebMvcTest 




  • Additionally, we might need a test-only property file, so we use @TestPropertySource. As mentioned, the @Value annotations will now be injected from our test property file.



When do you want to use @WebMvcTest? What does it auto-configure?
  • When we want to test the web slice of an application, particularly the behavior of the controllers interacting with the outer world.
  • By default, it autoconfigures all Spring beans referring to the web part, and specifically:
    • @Controller
    • @ControllerAdvice
    • @JsonComponent
    • @WebMvcConfigurer
    • and more
  • Can autoconfigure specific controller with: @WebMvcTest(SomeController.class)
  • Except for @Controllers setup, we must mock their dependencies with use of @MockBean
  • Autoconfigures MockMvc, to use in performing mock web tests



Differences between @SpringBootTest, MockMvc, @WebMvcTest





What are the differences between @MockBean and @Mock?
  • @Mock  is used to create mocks of any class, generally method-wise, while @MockBean to replace Spring bean context-wise
  • @Mock needs @RunWith(MockitoJUnitRunner.class) (Mockito library), while @MockBean needs @RunWith(SpringRunner.class) (spring-boot-test)
  • @Mock creates a Mockito mock, while @MockBean creates a Mockito mock and injects it into the Application Context
  • In order for a @Mock to be injected in its container class, need to use @InjectMocks on container class reference


When do you want @DataJpaTest for? What does it auto-configure?
  • Use for test slicing, particularly for testing of Spring beans that talk to a database (Entities, Repositories)
  • Configures in-memory database for testing
  • Loads in Application Context: @Entities, @Repositories, @TestEntityManager

Παρασκευή 22 Οκτωβρίου 2021

Spring Certification: Spring Boot Actuator

What value does Spring Boot Actuator provide?
  • Out-of-the-box production-ready features, like monitoring, metrics, health checks, audit events and more
  • Provided with spring-boot-starter-actuator dependency
  • Access through HTTP endpoints, like /actuator/health



What are the two protocols you can use to access actuator endpoints?
  • HTTP
  • JMX


What are the actuator endpoints that are provided out of the box?

  • /actuator:  provides a hypermedia-based discovery page for all the other endpoints (requires spring-boot-starter-hateoas)
  • /health: application health checks
  • /configprops:  lists all the configuration properties that are defined by the @ConfigurationProperties beans
  • /beans:  lists all Spring beans
  • /env: exposes all the properties from the Spring Environment abstraction. Displays application properties, active profiles and system environment variables
  • /httptrace: Shows most recent HTTP requests/responses
  • /info: general application info
  • /metrics: memory, performance, processor, garbage collection, and HTTP requests
  • /loggers:  view logs (also change without restarting app)



What is info endpoint for? How do you supply data?

  • Actuator's info endpoint is used to project user-customized application data, like application name, version, description, java runtime and more
  • The endpoint is exposed through HTTP (/actuator/info) or JMX (org.springframework.boot/Endpoint/Info)
  • To supply data, in application.properties define info.app.name/description/version or info.java-vendor. Alternatively, create a Component implementing InfoContributor

How do you change logging level of a package using loggers endpoint?
  • Execute a POST in /actuator/loggers endpoint and specific package, like: 
    • curl -i -X POST -H 'Content-Type: application/json' -d '{"configuredLevel": "INFO"}' http://localhost:8080/actuator/loggers/com.code.in.packets.package1.logging
  • Also, make to enable loggers endpoint:
    • management.endpoints.web.exposure.include=loggers
                management.endpoint.loggers.enabled=true

 

How do you access an endpoint using a tag?

  • Using syntax: /actuator/metrics/<metric>?tag=<key>:<value>
  • Example listing all GET requests that resulted in a server error: 
    • /actuator/metrics/http.server.requests?tag=outcome:SERVER_ERROR&tag=method:GET


What is metrics for?
  • Actuator metrics are implemented by Micrometer
  • Provide information about: memory usage, CPU usage, threads, garbage collection, application uptime, heap size, site-visited count and more
  • Need to explicitly enable in properties: management.endpoints.web.exposure.include=metrics


How do you create a custom metric?

  • Inject a MeterRegistry dependency in a Component
  • Use MeterRegistry's methods, like timer, counter, gaugeNewCollection and more to display desired info, like:
    • meterRegistry.gaugeCollectionSize("employeesList.size", Tags.empty(), this.employeesList)
    • meterRegistry.counter("<metric-name>", "<key>", <value>).increment(); 

What is Health Indicator?
  • HealthIndicator API and its endpoint "/actuator/health" is used to produce information about application status and overall health 
  • External systems can consume it in order to decide any time if we have a fault tolerant and durable application
  • The endpoint provides all Health Indicators that are set programmatically as components that implement HealthIndicator and override health method
  • Health Indicators are provided/autoconfigured by Spring Actuator, when relevant dependencies are found

What are the Health Indicators that are provided out of the box?
  • ApplicationHealthIndicator, should always be UP
  • DiskSpaceHealthIndicator, DOWN if low disk space is available
  • DataSourceHealthIndicator, UP if connection successful, otherwise DOWN.
  • JmsHealthIndicator, UP if connection with message broker successful, otherwise DOWN. 
  • Similar for Mail, Redis, Neo4J, Solr and more



    What is the Health Indicator status?
    What are the Health Indicator statuses that are provided out of the box?
    • All Health Indicators return a health status if triggered (from overwritten health method), that are aggregated and displayed in /health endpoint. These statuses are:
    • UP (200)
    • DOWN (503)
    • UNKNOWN (200)
    • OUT_OF_SERVICE (503)


    How do you change the Health Indicator status severity order?
    • Configure "management.health.status.order" property, like:
      • management.health.status.order=DOWN, OUT_OF_SERVICE, UNKNOWN, UP

    Why do you want to leverage 3rd-party external monitoring system?
    • Necessity: Decoupling code from system monitoring utilities, and having an extra system for alert, data/visitor visualizations, and more
    • Easy with Spring: Spring Actuator uses Micrometer that is a facade for multiple external monitoring systems, like Elastic, Atlas, KairosDB and more. We only need to import dependency with groupId = io.micrometer, and artifactId = micrometer-registry-${external-monitoring-system}


    -----------------------------------------------------------------------------------------------------


    Questions from EDU-1202 exam (2021)


    Actuator JMX endpoints can also be turned on for HTTP
    • True
    Actuator metrics can be leveraged by third-party providers for purposes of visualization
    • True
    Providers (Prometheus, Grafana, etc) can be adjusted easily by declaring dependency in pom.xml
    • True