Skip to content

Extra - Lab 1

1. Mapping objects

We now have two Simulation classes:

  • one created by us to use in the data generation and methods in the client and service classes as com.workshop.model package
  • another auto-generated by the Open API generator as com.eliasnogueira.credit.model package

Both are almost identical, but even if they were identical we need to map, which means telling our code that both are the same, mapping all the matching attributes. To be able to build a reliable service class for the Simulations API, we need more code.

Steps

  1. Open your pom.xml file
  2. In the <properties> section, add the following:
    <modelmapper.version>3.1.1</modelmapper.version>
    
  3. In the <dependecies> section, add the following:
    <dependency>
        <groupId>org.modelmapper</groupId>
        <artifactId>modelmapper</artifactId>
        <version>${modelmapper.version}</version>
    </dependency>
    
  4. Refresh your Maven libraries or run mvn clean package
  5. In the com.workshop package in the src/main/java folder, create a package called api.client
  6. Create a Java class named SimulationsApiClient in the com.workshop.api.client package
  7. Add the following method:
    private <T> com.eliasnogueira.credit.model.Simulation mapSimulation(Simulation simulation) {
        return new ModelMapper().map(simulation, com.eliasnogueira.credit.model.Simulation.class);
    }
    
  8. Open the Simulation class in the com.workshop.models package in the src/main/java folder
  9. Add a new attribute, id, and mark it to be ignored by the JSON conversion
    @JsonIgnore
    private int id;
    

2. Create the SimulationsApiClient class

Steps

  1. In the SimulationsApiClient class:

    • Add all the methods related to the Simulations API, associating the following requests with the methods from the generated client
    Request What it does Intermal client method
    GET /simulations Retrieve all simulations or all simulations by a given name getSimulationUsingGET()
    GET /simulations/{cpf} Retrieve a simulation given its cfp oneUsingGET1()
    POST /simulations Creates a new simulation newSimulationUsingPOST()
    PUT /simulations/{cpf} Update an existing simulation updateSimulationUsingPUT()
    DELETE /simulations/{cpf} Delete an existing simulation deleteUsingDELETE()
  2. Before the method creation, add the following code to Map the Simulation objects from the different packages

     private <T> com.eliasnogueira.credit.model.Simulation mapSimulation(Simulation simulation) {
         return new ModelMapper().map(simulation, com.eliasnogueira.credit.model.Simulation.class);
     }
    

  3. The body() method in the newSimulationUsingPOST() and updateSimulationUsingPUT() must use, as the parameter value the following:
    mapSimulation(simulation)
    

Tips

You will have:

  • two methods to retrieve the simulations:
    • one for all
    • another based on the query parameter name

Don't forget to create the method parameter matching the necessary path and body parameters.

Expected results

  • SimulationsApiClient class created

Solution

Click to see...
public class SimulationsApiClient {

    private final SimulationsApi simulationsApi = new RestApiClientBuilder().build(SimulationsApi::simulations);

    public Response retrieveSimulations() {
        return simulationsApi.getSimulationUsingGET().execute(identity());
    }

    public Response retrieveSimulations(String name) {
        return simulationsApi.getSimulationUsingGET().nameQuery(name).execute(identity());
    }

    public Response retrieveSimulation(String cpf) {
        return simulationsApi.oneUsingGET1().cpfPath(cpf).execute(identity());
    }

    public Response createSimulation(Simulation simulation) {

        return simulationsApi.newSimulationUsingPOST().body(mapSimulation(simulation)).execute(identity());
    }

    public Response updateSimulation(String cpf, Simulation simulation) {
        return simulationsApi.updateSimulationUsingPUT().cpfPath(cpf).body(mapSimulation(simulation)).execute(identity());
    }

    public Response deleteSimulation(String cpf) {
        return simulationsApi.deleteUsingDELETE().cpfPath(cpf).execute(identity());
    }

    private <T> com.eliasnogueira.credit.model.Simulation mapSimulation(Simulation simulation) {
        return new ModelMapper().map(simulation, com.eliasnogueira.credit.model.Simulation.class);
    }
}

3. Create the SimulationsApiService class

Steps

  1. In the com.workshop package in the src/main/java folder, create a package called api.service
  2. Create a Java class named SimulationsApiService in the com.workshop.api.service package
  3. Add a global instance to the SimulationApiClient
  4. Add all the necessary methods related to the SimulationsApiClient

Tips

The approach for all methods is (except for the delete)

return simulationsApiClient.methodFromClient().then().statusCode(CORRECT_STATUS_CODE).extract().as(RealClassFromClientToReturn.class);

In the case of many resulsts (retrieveSimulations()) you need to:

  • make the method return a list, for example: List<Simulation>
  • extract the class as an array, example: `extract().as(Simulation[].class)
  • return the whole command as a List, for example: List.of(content)

The createSimulation() method should return and extract the java.net.URI class

The deleteSimulation() will return a boolean, as true, after the request.

Expected results

  • SimulationsApiService class created

Solution

Click to see...
import io.restassured.http.Header;
import com.workshop.api.client.SimulationsApiClient;
import com.workshop.models.Simulation;

import java.util.List;

import static java.util.List.of;
import static org.apache.http.HttpStatus.SC_CREATED;
import static org.apache.http.HttpStatus.SC_NOT_FOUND;
import static org.apache.http.HttpStatus.SC_OK;

public class SimulationsApiService {

    private final SimulationsApiClient simulationsApiClient = new SimulationsApiClient();

    public List<Simulation> retrieveSimulations() {
        return of(simulationsApiClient.retrieveSimulations().then().statusCode(SC_OK).extract().as(Simulation[].class));
    }

    public List<Simulation> retrieveSimulations(String name) {
        return of(simulationsApiClient.retrieveSimulations(name).then().statusCode(SC_OK).extract().as(Simulation[].class));
    }

    public Simulation retrieveSimulation(String cpf) {
        return simulationsApiClient.retrieveSimulation(cpf).then().statusCode(SC_OK).extract().as(Simulation.class);
    }

    public Header createSimulation(Simulation simulation) {
        return simulationsApiClient.createSimulation(simulation).then().statusCode(SC_CREATED)
                .extract().response().getHeaders().get("Location");
    }

    public Simulation updateSimulation(String cpf, Simulation simulation) {
        return simulationsApiClient.updateSimulation(cpf, simulation).then().extract().as(Simulation.class);
    }

    public boolean deleteSimulation(String cpf) {
        simulationsApiClient.deleteSimulation(cpf).then().statusCode(SC_NO_CONTENT);
        return true;
    }
}