# Step 6: Run (Part 2)

## Run Your Local Web Server

Open a terminal window.

### Enter Your Client Credentials

{% hint style="danger" %}
Safeguard your **`Client ID`** and **`Client Secret`** values. Do not share these with any third parties as anyone with your **`Client ID`** and **`Client Secret`** values can impersonate you and act fully on your behalf.
{% endhint %}

Export your registered client credentials (see the [prerequisites](https://docs.inrupt.com/sdk/java-sdk/tutorial/prerequisites "mention")) as environment variables.

1. Identity Provider (the IDP with whom you registered your application):

```sh
read -s MY_SOLID_IDP && export MY_SOLID_IDP
```

Enter `https://login.inrupt.com`

2. Client ID:

```sh
read -s MY_SOLID_CLIENT_ID && export MY_SOLID_CLIENT_ID
```

Enter your Client ID.

3. Client Secret:

```sh
read -s MY_SOLID_CLIENT_SECRET && export MY_SOLID_CLIENT_SECRET
```

Enter your Client Secret.

4. Authentication Flow Method:

```sh
read -s MY_AUTH_FLOW && export MY_AUTH_FLOW
```

Enter `client_secret_basic`

### Run the Application

Once you have entered your client credentials, start your application. From your project ( `getting-started/` ) directory, run your Spring Boot application:

* For Java, this tutorial assumes a Spring Boot Web Maven Project.
* For Kotlin, this tutorial assumes a Spring Boot Web Gradle Project.

{% tabs %}
{% tab title="Java" %}

```sh
./mvnw spring-boot:run
```

{% endtab %}

{% tab title="Kotlin" %}

```sh
./gradlew bootRun
```

{% endtab %}
{% endtabs %}

Your Web service runs on `http://localhost:8080` .

{% hint style="info" %}
Reminder\
The application is running **as** you, the user who registered it.
{% endhint %}

## Test the Service

Open another terminal window. To test, call the new endpoints defined in the **`ExpenseController`** class:

<table><thead><tr><th width="267.5859375">Endpoint</th><th>Description</th></tr></thead><tbody><tr><td><strong><code>/api/expenses/receipts/add</code></strong></td><td>Saves a non-RDF resource, namely an image file of a receipt, to a location in the Pod and updates the <strong><code>Expense</code></strong> object with the receipt location. Returns the updated <strong><code>Expense</code></strong> object.</td></tr><tr><td><strong><code>/api/resource/nonRDF/add</code></strong></td><td>Saves a non-RDF resource to a location in the Pod. Returns the identifier (as String) for the saved resource.</td></tr></tbody></table>

### Get Pod URL

To find your Pod URL, issue the following **`curl`** command, substituting your WebID (e.g., **`https://id.inrupt.com/yourUserName`** ):

```sh
curl -X GET http://localhost:8080/api/pods\?webid\=SUBSTITUTE_YOUR_WEBID
```

Upon success, the operation should return an array with your Pod Root URL; for example:

```sh
["https://storage.inrupt.com/your-root-container/"]
```

{% hint style="info" %}
Note\
In the following operations, substitute **`your-root-container`** with the value of your root container.
{% endhint %}

### Add a Receipt to Existing Expense

To add a receipt to an existing expense created in Part 1, call the **`api/expenses/receipts/add`** endpoint with a local **`.png`** file (can be a different file type **`.jpg`** , **`.pdf`** , etc. as well), **substituting** the path to your local file and your root container in the request body:

<pre class="language-sh"><code class="lang-sh">
curl -X PUT http://localhost:8080/api/expenses/receipts/add \
          -H "Content-Type: multipart/form-data" \
<strong>          -F "destinationURL=https://storage.inrupt.com/your-root-container/expenses/20230315/receipt.png" \
</strong><strong>          -F "file=@/my/local/file/path/to/receipt.png" \
</strong><strong>          -F "expenseURL=https://storage.inrupt.com/your-root-container/expenses/20230315/expense1"
</strong>
</code></pre>

{% hint style="info" %}
Tip

* If you encounter an **`HTTP 403 Forbidden`** error, double check that you have substituted **`your-root-container`** in the command.
* If you encounter a **`PreconditionFailedException`** , check that the **`receipt.png`** does not already exist at the the specified identifier. The **`.create()`** operation errors with **`PreconditionFailedException`** if a resource already exists. See [crud-data](https://docs.inrupt.com/sdk/java-sdk/crud-data "mention") for details.
  {% endhint %}

Upon success, the operation should return the updated **`Expense`** object as JSON (as well as print out, on the server-side, the content formatted in Turtle):

{% tabs %}
{% tab title="Returned Expense Object" %}

<pre class="language-json"><code class="lang-json">
{
    "identifier": "https://storage.inrupt.com/your-root-container/expenses/20230315/expense1",
    "merchantProvider": "Example Restaurant",
    "expenseDate": "2023-03-15T00:00:00.000+00:00",
    "description": "Team Lunch",
    "amount": 100,
    "currency": "USD",
    "category": "Travel &#x26; Entertainment",
<strong>    "receipts": [
</strong><strong>        "https://storage.inrupt.com/your-root-container/expenses/20230315/receipt.png"
</strong><strong>    ],
</strong>    "rdftype": "https://schema.org/Invoice"
}
</code></pre>

{% endtab %}

{% tab title="Content Formatted as Turtle" %}

<pre class="language-turtle"><code class="lang-turtle">
&#x3C;https://storage.inrupt.com/your-root-container/expenses/20230315/expense1>
        a                              &#x3C;https://schema.org/Invoice> ;
        &#x3C;https://schema.org/purchaseDate>
                "2023-03-15T00:00:00Z"^^&#x3C;http://www.w3.org/2001/XMLSchema#dateTime> ;
        &#x3C;https://schema.org/category>  "Travel &#x26; Entertainment" ;
        &#x3C;https://schema.org/description>
                "Team Lunch" ;
<strong>        &#x3C;https://schema.org/image>     &#x3C;https://storage.inrupt.com/your-root-container/expenses/20230315/receipt.png> ;
</strong><strong>        &#x3C;https://schema.org/priceCurrency>
</strong>                "USD" ;
        &#x3C;https://schema.org/provider>  "Example Restaurant" ;
        &#x3C;https://schema.org/totalPrice>
                "100"^^&#x3C;http://www.w3.org/2001/XMLSchema#decimal> .
</code></pre>

{% endtab %}
{% endtabs %}

See also [crud-data](https://docs.inrupt.com/sdk/java-sdk/crud-data "mention").

### Save a Non-RDF File

To save a receipt (a non-RDF resource) to your Pod, issue the following **`curl`** command to the **`api/resource/nonRDF/add`** endpoint, <mark style="color:red;">**substituting**</mark> the path to your local file and your root container in the request body:

<pre class="language-sh"><code class="lang-sh">curl -X PUT http://localhost:8080/api/resource/nonRDF/add \
          -H "Content-Type: multipart/form-data" \
<strong>          -F "destinationURL=https://storage.inrupt.com/your-root-container/expenses/20230327/receipt.png" \
</strong><strong>          -F "file=@/my/local/file/path/to/newreceipt.png"
</strong></code></pre>

{% hint style="info" %}
Tip

* If you encounter an **`HTTP 403 Forbidden`** error, double check that you have substituted **`your-root-container`** in the command.
* If you encounter a **`PreconditionFailedException`** , check that the resource does not already exist at the the specified identifier. The **`.create()`** operation errors with **`PreconditionFailedException`** if a resource already exists. See [crud-data](https://docs.inrupt.com/sdk/java-sdk/crud-data "mention") for details.
  {% endhint %}

Upon success, the operation returns identifier (as string) of the resource:

```none
https://storage.inrupt.com/your-root-container/expenses/20230327/receipt.png
```

See also [crud-data](https://docs.inrupt.com/sdk/java-sdk/crud-data "mention").

### Create an Expense Record

Using the receipt saved in the Save a Non-RDF File section, create a new expense that includes the receipt info, <mark style="color:red;">**substituting**</mark> your root container in the request body:

<pre class="language-sh"><code class="lang-sh">
curl -X POST http://localhost:8080/api/expenses/create \
   -H 'Content-type:application/json'  \
   -d '{
<strong>      "identifier": "https://storage.inrupt.com/your-root-container/expenses/20230327/expense1",
</strong><strong>      "merchantProvider": "Example Supply Store",
</strong>      "description": "Chair",
      "expenseDate": "2023-03-27",
      "amount": 400,
      "currency": "USD",
      "category": "Office Equipment &#x26; Supplies",
<strong>      "receipts": [ "https://storage.inrupt.com/your-root-container/expenses/20230327/receipt.png"] }'
</strong>
</code></pre>

{% hint style="info" %}
Tip

* If you encounter an **`HTTP 403 Forbidden`** error, double check that you have substituted **`your-root-container`** in the command.
* If you encounter a **`PreconditionFailedException`** , check that the resource does not already exist at the the specified identifier. The **`.create()`** operation errors with **`PreconditionFailedException`** if a resource already exists. See [crud-data](https://docs.inrupt.com/sdk/java-sdk/crud-data "mention") for details.
  {% endhint %}

Upon success, the operation should return the updated **`Expense`** object as JSON (as well as print out, on the server-side, the content formatted in Turtle):

{% tabs %}
{% tab title="Returned Expense Object" %}

```json
{
    "identifier": "https://storage.inrupt.com/your-root-container/expenses/20230327/expense1",
    "merchantProvider": "Example Supply Store",
    "expenseDate": "2023-03-27T00:00:00.000+00:00",
    "description": "Chair",
    "amount": 400,
    "currency": "USD",
    "category": "Office Equipment & Supplies",
    "receipts": [
        "https://storage.inrupt.com/your-root-container/expenses/20230327/receipt.png"
    ],
    "rdftype": "https://schema.org/Invoice"
}
```

{% endtab %}

{% tab title="Content Formatted as Turtle" %}

```turtle
<https://storage.inrupt.com/your-root-container/expenses/20230327/expense1>
        a                              <https://schema.org/Invoice> ;
        <https://schema.org/purchaseDate>
                "2023-03-27T00:00:00Z"^^<http://www.w3.org/2001/XMLSchema#dateTime> ;
        <https://schema.org/category>  "Office Equipment & Supplies" ;
        <https://schema.org/description>
                "Chair" ;
        <https://schema.org/image>     <https://storage.inrupt.com/your-root-container/expenses/20230327/receipt.png> ;
        <https://schema.org/priceCurrency>
                "USD" ;
        <https://schema.org/provider>  "Example Supply Store" ;
        <https://schema.org/totalPrice>
                "400"^^<http://www.w3.org/2001/XMLSchema#decimal> .
```

{% endtab %}
{% endtabs %}

See also [crud-data](https://docs.inrupt.com/sdk/java-sdk/crud-data "mention").
