Showing posts with label ReST. Show all posts
Showing posts with label ReST. Show all posts

Friday, 17 August 2018

PACTs

PACT testing is a Consumer Driven Contract implementation.

Here is a quick example for a Consumer test and a Provider test.

Consumer

This is some sample code for the consumer.  This will create a 'pact' json file in the target folder after a maven build.  This json is what will get sent to the Pact Broker or can be used to validate the pacts locally instead.
 
public class MyPactConsumerTest {  

  @Rule
  public PactProviderRuleMk2 pactProviderRule = new PactProviderRuleMk2("<NAME_OF_PROVIDER>", "localhost", PACT_SERVER_PORT, PactSpecVersion.V2, this);

  @Pact(consumer = "<NAME_OF_CONSUMER>", provider = "<NAME_OF_PROVIDER")
  public RequestResponsePact doSomething(final PactDslWithProvider pactDslWithProvider) {

    return pactDslWithProvider.given("<STATE>")
      .uponReceiving("<DESCRIPTION")
      .path("<URL>")
      .method("POST")
      .body(getExpectedRequestBody())
      .headers("Content-Type", "<TYPE>")
      .willRespondWith()
      .status(HttpStatus.NO_CONTENT.value())
      .toPact();
  }

  @Test
  @PactVerification(fragment = "doSomething") <THIS IS THE METHOD NAME ABOVE>
  public void testDoSomething() {
    someJavaClassToCall.someMethod();
  }

  private DslPart getExpectedResponseBody() {
    return new PactDslJsonBody().stringMatcher("dataAttribute", ".*", "");
  }
}

Provider

The provider can then validate the pact json created by the consumer above.  If the Pacts are published then it is necessary to validate against the Broker with the @PactBroker annotation.  If you want to just validate against a pact json file then copy the file into a folder in /src/test/resources/pact (or something) and just add the @PactFolder("pact") annotation instead.


@Provider("<NAME_OF_PROVIDER>")
@PactBroker
@IgnoreNoPactsToVerify
//@PactFolder("pact") <A FOLDER CAN BE USED INSTEAD OF THE BROKER>
public class MyPactProviderTest {

  @State("<STATE>")
  public void methodName() {
    when(mockService.mockMethod(any())).thenReturn(new Data()); <THIS RETURNS DATA THAT MATCHES THE RESPONSE BODY ABOVE>
  }

}

Tuesday, 6 June 2017

Spring Sleuth

Sleuth is used to trace calls in a microservices environment. It creates a trace-id over the whole interactions and a span-id between each call.  For example, there is a call from a client to a microservice to load information for a customer id.  First is the call to the customer service, then the recent orders and accounts services.  All these calls would share the same trace-id but between each one is a different span-id.  To turn on sleuth just add the following dependencies into the pom.  You'll also need to add an application name.

spring.application.name=My Server

Maven


<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-sleuth</artifactId>
    <version>1.2.0.RELEASE</version>
</dependency>

The trace and span ids will now be created and can be seen in the headers.

To log this and make it useful though is one thing but there is a graphical tool which makes this very easy.

Zipkin

Zipkin can be configured so that all Sleuth output is sent there and it allows a view of the interactions so that the times and services called can be seen.  To configure and use zipkin just add another dependency,

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-sleuth-zipkin</artifactId>
    <version>1.2.0.RELEASE</version>
</dependency>

By default everything is logged to localhost:9411 but this can be changed by adding a property

spring.zipkin.baseurl=http://zipkin:9411/

Docker

If you are running with docker you'll need to add a zipkin image into the compose file,

      
  zipkin:
    image: openzipkin/zipkin
    networks:
      - my-network
    hostname: zipkin
    ports:
      - "9411:9411"




Friday, 7 April 2017

Swagger UI ReST Documentation

Where SOAP gives a clear contract between the client and service, ReST services do not.  This means that the documentation is even more important to allow correct use of the service for the client.  Swagger allows the ReST endpoints to be documented as annotations within the code so that it is easier to write and maintain.

Maven Dependencies

Add the two dependencies below to use swagger and enable the swagger ui.

    <dependency>
        <groupId>io.springfox</groupId>
        <artifactId>springfox-swagger2</artifactId>
        <version>2.6.1</version>
    </dependency>
    <dependency>
        <groupId>io.springfox</groupId>
        <artifactId>springfox-swagger-ui</artifactId>
        <version>2.6.1</version>
    </dependency>


Spring Integration

With Spring annotation driven configuration this process is easy.  Create a class and annotate it with @Configuration so that spring uses it.  Additionally use @EnableSwagger2 to make sure that swagger is enabled.


@Configuration
@EnableSwagger2
public class SwaggerConfiguration
{
    /**
     * Add to the swagger documentation
     *
     * @return The {@link Docket} class with api information and config
     */
    @Bean
    public Docket getApiDocumentation()
    {
        return new Docket(DocumentationType.SWAGGER_2)
                .groupName("Project ReST Service")
                .apiInfo(new ApiInfoBuilder()
                        .title("My Service")
                        .description("My service which does lots of interesting things.")
                        .build())
                .select()
                .apis(RequestHandlerSelectors.any())
                .paths(PathSelectors.any())
                .build();
    }
}


With spring boot the situation isn't really any different to that above accept that the @EnableSwagger2 can be put on the same class as a the @SpringBootApplication annotation or left exactly as it is above.

Swagger Annotations

In addition to the annotation to enable swagger (@EnableSwagger2) the other main annotations to use are,

@Api - this can be used on a controller to describe the overall behaviour
@ApiOperation - put this on the methods in the controller to describe what they do
@ApiParam - used to describe the particular parameter that is passed to a controller method

A full list of annotations can be found here https://github.com/swagger-api/swagger-core/wiki/Annotations-1.5.X