# Integration and Testing
source: https://developer.mastercard.com/digital-redemptions/documentation/tutorials-and-guides/api-testing-tutorial/index.md

This tutorial walks through the steps required to test the Digital Redemptions Service by building an end-to-end application.

## Introduction {#introduction}

This tutorial helps you to create a simple Java application that makes an API call to the Digital Redemptions Service in the Sandbox environment.

### What you will learn {#what-you-will-learn}

* How to set up the environment to develop a simple Java application
* How to generate an API client using the [OpenAPI Generator](https://openapi-generator.tech/)
* How to make an API call

### Authentication Options {#authentication-options}

The Digital Redemptions Service supports both OAuth 1.0a and OAuth 2.0 authentication methods. This tutorial demonstrates OAuth 1.0a integration using Java. For OAuth 2.0 implementation, refer to:

* [API Basics - Client Authentication](https://developer.mastercard.com/digital-redemptions/documentation/api-basics/index.md#client-authentication) for an overview of both methods
* [Official Mastercard OAuth 2.0 documentation](https://developer.mastercard.com/platform/documentation/authentication/using-oauth-2-to-access-mastercard-apis/#overview)

Note: The code examples in this tutorial use OAuth 1.0a. If you are using OAuth 2.0, you will need to adapt the authentication configuration to use Bearer token authentication instead of request signing.

### Prerequisites {#prerequisites}

To complete this tutorial, you will need:

* [JDK 11](https://www.java.com/en/) or later
* An IDE of your choice
* Mastercard Developers account with access to the Digital Redemptions API
* Digital Redemptions Open API specification (Refer to the [Open Specification](https://developer.mastercard.com/digital-redemptions/documentation/api-reference/index.md) for details.)

## Environment Set up {#environment-set-up}

### 1. Create a Maven Project {#1-create-a-maven-project}

* In the IDE, create a new Maven project which sets your directory structure automatically. ![Create maven project](https://static.developer.mastercard.com/content/digital-redemptions/img/merchandise/tutorial/createmavenproject.png)
* Provide an ArtifactId and a project name as per your choice. ![Add project name](https://static.developer.mastercard.com/content/digital-redemptions/img/merchandise/tutorial/mvnprojectdetails.png)

### 2. Add Resources {#2-add-resources}

* Add the Digital Redemptions specification to your Maven project resources folder.
* Add the generated Sandbox key (**.p12 file** ) and encryption cert (**.pem file**) to your Maven project resources folder. (This is generated while creating the project on Mastercard Developers).
* Your Maven project directory structure should appear as: ![Maven structure](https://static.developer.mastercard.com/content/digital-redemptions/img/merchandise/tutorial/addresources.png)

### 3. Update pom.xml file {#3-update-pomxml-file}

* In your IDE, add the [OpenAPI Generator maven plugin](https://github.com/OpenAPITools/openapi-generator/tree/master/modules/openapi-generator-maven-plugin) to your project **pom.xml** file. Use the Plugin config as shown below: Note: [OpenAPI Generator](https://openapi-generator.tech/) generates API client libraries using OpenAPI Specification. It provides multiple generators and library templates to support multiple languages and frameworks. We will be using the Java generator for this project.

```XML
<plugin>
    <groupId>org.openapitools</groupId>
    <artifactId>openapi-generator-maven-plugin</artifactId>
    <version>6.2.1</version>
    <executions>
        <execution>
            <goals>
                <goal>generate</goal>
            </goals>
            <configuration>
                <inputSpec>${project.basedir}/src/main/resources/merchandise-digital-redemptions.yaml</inputSpec>
                <generatorName>java</generatorName>
                <configOptions>
                    <sourceFolder>src/gen/java/main</sourceFolder>
                    <java11>true</java11>
                    <dateLibrary>custom</dateLibrary>
                </configOptions>
                <typeMappings>
                    <typeMapping>Date=String</typeMapping>
                </typeMappings>
            </configuration>
        </execution>
    </executions>
</plugin>
```

* Add the following dependencies to your pom.xml file to add dependencies for the API client library generation and the Mastercard OAuth1 Signer library.

```XML
<properties>
       <!-- Dependencies used by the generated sources -->
       <gson-fire-version>1.8.5</gson-fire-version>
       <swagger-core-version>1.6.9</swagger-core-version>
       <okhttp-version>4.10.0</okhttp-version>
       <gson-version>2.10.1</gson-version>
       <threetenbp-version>1.6.5</threetenbp-version>
       <javax-annotation-version>1.0</javax-annotation-version>
       <junit-version>4.13.2</junit-version>
   </properties>
 
   <dependencies>
       <dependency>
           <groupId>io.swagger</groupId>
           <artifactId>swagger-annotations</artifactId>
           <version>${swagger-core-version}</version>
       </dependency>
       <dependency>
           <groupId>com.squareup.okhttp3</groupId>
           <artifactId>okhttp</artifactId>
           <version>${okhttp-version}</version>
       </dependency>
       <dependency>
           <groupId>com.squareup.okhttp3</groupId>
           <artifactId>logging-interceptor</artifactId>
           <version>${okhttp-version}</version>
       </dependency>
       <dependency>
           <groupId>com.google.code.gson</groupId>
           <artifactId>gson</artifactId>
           <version>${gson-version}</version>
       </dependency>
       <dependency>
           <groupId>io.gsonfire</groupId>
           <artifactId>gson-fire</artifactId>
           <version>${gson-fire-version}</version>
       </dependency>
       <dependency>
           <groupId>org.threeten</groupId>
           <artifactId>threetenbp</artifactId>
           <version>${threetenbp-version}</version>
       </dependency>
       <dependency>
           <groupId>javax.annotation</groupId>
           <artifactId>jsr250-api</artifactId>
           <version>${javax-annotation-version}</version>
       </dependency>
       <dependency>
           <groupId>junit</groupId>
           <artifactId>junit</artifactId>
           <version>${junit-version}</version>
       </dependency>
       <dependency>
           <groupId>com.mastercard.developer</groupId>
           <artifactId>oauth1-signer</artifactId>
           <version>1.5.2</version>
       </dependency>
 
   </dependencies>
```

* Add the following dependencies to your pom.xml file to encrypt and decrypt the requests using the using Mastercard Client Encryption library.

```XML
<properties>
    <client-encryption-version>1.7.7</client-encryption-version>
</properties>

<dependency>
    <groupId>com.mastercard.developer</groupId>
    <artifactId>client-encryption</artifactId>
    <version>${client-encryption-version}</version>
</dependency>
```

When using OpenAPI Generator to generate the API client library, you have two options:

* Generate and use the source files on the fly
* Generate and deploy the source files to a Maven repository

<br />

<br />


In this tutorial, you will be generating the API client library on the fly, so you include the dependencies that are needed to generate the library. (If you were deploying the source files to a Maven repository, you would only need to include the dependency for that repository.)

In addition, you include the dependency for one of the Mastercard OAuth1 Signer libraries. Mastercard offers OAuth1 Signer Libraries that are developed and maintained by Mastercard's API team, which offer code helpers targeting the HTTP clients used by the different OpenAPI Generator Library templates. The libraries are hosted on [Github](https://github.com/Mastercard?utf8=%E2%9C%93&q=oauth1-signer&type=&language=).

Refer to the following page for more information on [Generating and Configuring a Mastercard API Client](https://developer.mastercard.com/platform/documentation/getting-started-with-mastercard-apis/generating-and-configuring-a-mastercard-api-client/#overview).

## Generating the API Client {#generating-the-api-client}

1. Now that you have all the dependencies you need, you can generate the source code. You can navigate to the project root directory within a terminal window and run `mvn clean install `. ![clean](https://static.developer.mastercard.com/content/digital-redemptions/img/merchandise/tutorial/clean.png) ![install](https://static.developer.mastercard.com/content/digital-redemptions/img/merchandise/tutorial/install.png)
2. Alternatively, you can navigate to the root directory of the project within a terminal window and run mvn clean install. ![compile](https://static.developer.mastercard.com/content/digital-redemptions/img/merchandise/tutorial/compile.png)
3. A folder named **target** is created within your root directory which contains classes generated for the schemas and API calls defined within the OpenAPI Specification. The generated classes can be found in the target folder as shown below: ![classes](https://static.developer.mastercard.com/content/digital-redemptions/img/merchandise/tutorial/targetfiles.png)

## Making an API Call {#making-an-api-call}

Note: The example below demonstrates authentication using **OAuth 1.0a** . The Digital Redemptions API also supports **OAuth 2.0** . For details on configuring OAuth 2.0 authentication, refer to the [Using OAuth 2.0 to Access Mastercard APIs](https://developer.mastercard.com/platform/documentation/authentication/using-oauth-2-to-access-mastercard-apis/#step-by-step-implementation) and [API Basics - Client Authentication](https://developer.mastercard.com/digital-redemptions/documentation/api-basics/index.md#client-authentication).

1. Under the `src/main/java/` folder path, create a Java file named **ApiClientConfiguration.java**.
2. To make the API call, you need to make your OAuth credentials available to the program for use.

* A PrivateKey is created with the provided credentials for later use.
* AuthenticationUtils is provided by the Mastercard OAuth signing library.

```java
 // Read these values from application.properties file.
   @Value("${mastercard.api.key.alias}")
   private String signingKeyAlias;
 
   @Value("${mastercard.api.keystore.password}")
   private String signingKeyPassword;
 
   @Value("${mastercard.api.p12.path}")
   private String signingKeyPkcs12FileName;
            
```

You can include the encryption \& signing information in the application's application.properties file as shown below

```java
# path to keystore (.p12). This .p12 file will be downloaded during project creation in Mastercard Developers.
mastercard.api.p12.path=src/main/resources/merchandise-digital-redemptions.p12

# Consumer key. Copy this from "Sandbox/Production Keys" on your project page in https://developer.mastercard.com/dashboard.
mastercard.api.consumer.key=XYzbhDCSeNYvJpLL5l028sWL9it739PYh6LUd4Zja15xcRpY!fd209e6c579dc9d7be52da93d35ae6b6c167c174690bDsfa

# key alias. Default key alias for sandbox is "keyalias" (without quotes).
mastercard.api.key.alias=keyalias

# keystore password. Default keystore password for sandbox is "keystorepassword" (without quotes)
mastercard.api.keystore.password=keystorepassword

# basepath.
basePath=https://sandbox.api.mastercard.com/loyalty/mrs

# path to certificate (PEM) file whose public key will be used for encryption. Download this from "Client Encryption Keys" under Actions dropdown on your project page in https://developer.mastercard.com
mastercard.api.encryption.pem.path=src/main/resources/merchandise-digital-redemptions-encrypt.pem

# The SHA-256 hex-encoded digest of the key used for encryption. Copy this from "Client Encryption Keys" under FINGERPRINT section on your project page in https://developer.mastercard.com
mastercard.api.encryption.key.fingerprint=a36a78ddb31a3bb01e6e2887097a53ee85e51755a0db6e9ea56c4b5780182598

springdoc.paths-to-exclude=/swagger-resources/**
```

Tip: Please refer to the following [tutorial](https://developer.mastercard.com/digital-redemptions/documentation/tutorials-and-guides/sandbox-access-tutorial/index.md) to generate the keys that are used in the application.properties file.

* A certificate object can be created from a file by calling EncryptionUtils.loadEncryptionCertificate. Supported certificate formats are PEM, DER.

       Certificate encryptionCertificate = EncryptionUtils.loadEncryptionCertificate("<insert certificate file path>");

* Entire payloads can be encrypted using the "$" operator as encryption path

```java
   jweConfig = JweConfigBuilder.aJweEncryptionConfig()
             .withEncryptionCertificate(encryptionCertificate)
             .withEncryptionPath("$", "$")
             .withEncryptionKeyFingerprint(encryptionKeyFingerprint)
             .withEncryptedValueFieldName("encryptedPayload")
             .build();
```

<br />

* Instantiate a client with your authentication credentials and configuration object as interceptors before you can send it.

```java
  PrivateKey signingKey = AuthenticationUtils.loadSigningKey(signingKeyPkcs12FileName, signingKeyAlias, signingKeyPassword);
  apiClient = new ApiClient();
  apiClient.setBasePath("https://sandbox.api.mastercard.com");
  apiClient.setDebugging(true);

  OkHttpClient.Builder okHttpClientBuilder = apiClient.getHttpClient().newBuilder();
  okHttpClientBuilder.addInterceptor(new OkHttpOAuth1Interceptor(consumerKey, signingKey));

  return apiClient.setHttpClient(okHttpClientBuilder.build());
```

Note: For conciseness, only the barebones of what is needed to make the API call is shown above. The full contents of ApiClientConfiguration.java is shown below.

### Contents of ApiClientConfiguration.java {#contents-of-apiclientconfigurationjava}

```java
package com.mastercard.developer.config;
 
import com.mastercard.developer.interceptors.OkHttpOAuth1Interceptor;
import com.mastercard.developer.utils.AuthenticationUtils;
import lombok.extern.slf4j.Slf4j;
import okhttp3.OkHttpClient;
import org.openapitools.client.ApiClient;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import com.mastercard.developer.encryption.JweConfig;
import com.mastercard.developer.encryption.JweConfigBuilder;
import com.mastercard.developer.interceptors.OkHttpJweInterceptor;
import com.mastercard.developer.utils.EncryptionUtils;
import java.security.cert.Certificate;
import javax.servlet.http.HttpServletRequest;
import org.springframework.beans.factory.annotation.Autowired;
 
import java.security.PrivateKey;
 
@Service
@Slf4j
public class ApiClientConfiguration {
 
 
    @Value("${basePath}")
    private String basePath;
 
    @Value("${mastercard.api.consumer.key}")
    public String consumerKey;
 
    @Value("${mastercard.api.key.alias}")
    private String signingKeyAlias;
 
    @Value("${mastercard.api.keystore.password}")
    private String signingKeyPassword;
 
    @Value("${mastercard.api.p12.path}")
    private String signingKeyPkcs12FileName;
 
    @Value("${mastercard.api.encryption.pem.path}")
    private String encryptionKeyPemFileName;
 
    @Value("${mastercard.api.encryption.key.fingerprint}")
    private String encryptionKeyFingerprint;
 
    private ApiClient apiClient = null;
 
    @Autowired
    private HttpServletRequest httpRequest;
 
    public ApiClient getApiClient() {
        if (httpRequest.getMethod().equals("POST")) {
            createNewApiClient(true);
        } else {
            createNewApiClient(false);
        }
        return apiClient;
    }
 
    public ApiClient createNewApiClient(boolean encryptRequest) {
        apiClient = new ApiClient();
        JweConfig jweConfig = null;
        try {
 
        /* The following code will encrypt the payload if the payload has sensitive information */

            if (encryptRequest) {
                Certificate encryptionCertificate = EncryptionUtils.loadEncryptionCertificate(encryptionKeyPemFileName);
 
                jweConfig = JweConfigBuilder.aJweEncryptionConfig()
                        .withEncryptionCertificate(encryptionCertificate)
                        .withEncryptionPath("$", "$")
                        .withEncryptionKeyFingerprint(encryptionKeyFingerprint)
                        .withEncryptedValueFieldName("encryptedPayload")
                        .build();
            }
            PrivateKey signingKey = AuthenticationUtils.loadSigningKey(signingKeyPkcs12FileName, signingKeyAlias, signingKeyPassword);
            apiClient.setBasePath(basePath);
            apiClient.setDebugging(true);
            OkHttpClient.Builder okHttpClientBuilder = apiClient.getHttpClient().newBuilder();
 
            if (encryptRequest) {
                okHttpClientBuilder.addInterceptor(new OkHttpJweInterceptor(jweConfig));
            }

            okHttpClientBuilder.addInterceptor(new OkHttpOAuth1Interceptor(consumerKey, signingKey));
 
            return apiClient.setHttpClient(okHttpClientBuilder.build());
        } catch (Exception e) {
            log.error(e.getMessage());
        }
        return apiClient;
    }
 
}
```

In the above block of code, the request is signed using the parameters from the application.properties file. The request is also encrypted if it's a POST call. Refer [API Basics](https://developer.mastercard.com/digital-redemptions/documentation/api-basics/index.md) for signing and encryption details.

* Now put everything together and you can start using the APIs by making use of the generated classes.

```java
   @ApiOperation(value = "Search User Profile Call", notes = "Search User Profile", tags = { "redeemers" })
   	@PostMapping("/redeemers/search")
   	public RedeemerProfile searchUserProfile(@RequestBody SearchProfileRequest request) {
   
   		RedeemerProfile response;
   		try {
   			log.info("Method : searchUserProfile, Message : Searching user profile with the user id :"
   					+ request.getUserId());
   			ApiClient apiClient = apiClientConfiguration.createNewApiClient(true);
   			RedeemersProfileApi redeemersProfileApi = getRedeemersProfileApi(apiClient);
   			response = redeemersProfileApi.searchRedeemersProfile(request);
   			if (response != null) {
   				log.info("Method : searchUserProfile, Message :Successfully found the user profile from using search "
   						+ response);
   				return response;
   			}
   		} catch (ApiException e) {
   			log.error("Method : searchUserProfile, Message : Failed to search the user profile with user id :"
   					+ request.getUserId());
   			throw new InvalidRequest(e.getMessage(), e.getResponseBody());
   		}
   
   		throw new InvalidRequest(HttpStatus.BAD_REQUEST);
   	}
 
    public RedeemersProfileApi getRedeemersProfileApi(ApiClient apiClient) {
    		return new RedeemersProfileApi(apiClient);
    }
 
}
```

Tip: Refer to the following [reference app](https://developer.mastercard.com/digital-redemptions/documentation/reference-app/index.md) for more details.
