:virgo-homepage: https://eclipse.org/virgo
:guide-short-name: uploading-files
:recipe-name: Getting Started - Uploading Files
:recipe-short-name: recipe-{guide-short-name}

include::../../../recipe-template/src/asciidoc/00_title.adoc[]
include::../../../recipe-template/src/asciidoc/01_acknowledgements.adoc[]

== {recipe-name}

The original guide uses https://projects.spring.io/spring-boot/[Spring Boot] to bootstrap the demo application. This guide walks through the necessary
additional steps/configuration to get "{recipe-name}" up and running on Virgo.

include::../../../recipe-template/src/asciidoc/03_shopping-list.adoc[]

include::../../../recipe-template/src/asciidoc/04_ingredients.adoc[]
* Spring configuration
* Web application configuration
* OSGi manifest

== Preparations

include::../../../recipe-template/src/asciidoc/051_get-the-code.adoc[]
include::../../../recipe-template/src/asciidoc/052_create-recipe-runtime.adoc[]
include::../../../recipe-template/src/asciidoc/053_create-eclipse-project-metadata.adoc[]
include::../../../recipe-template/src/asciidoc/054_prepare-virgo-tooling.adoc[]
include::../../../recipe-template/src/asciidoc/055_import-the-code.adoc[]
include::../../../recipe-template/src/asciidoc/056_create-new-virgo-server.adoc[]

== Directions

Virgo has no support for Springs `@EnableAutoConfiguration`. Thus you have to be explicit where Spring Boot configures the embedded Tomcat with reasonable defaults on your behalf.
Last but not least Virgo is an OSGi runtime and every bundle needs to be explicit about its needs in the `META-INF/MANIFEST.MF`.

This is mostly about specifying necessary `Import-Package` and the `Web-ContextPath` the file upload application wants to be published.

.template.mf
[source,txt]
----
include::../../org.eclipse.virgo.samples.recipe.uploading/template.mf[]
----

You can mix and match the Virgo specific header `Import-Bundle` and OSGi standard header `Import-Package` within the `MANIFEST.MF`.
In the sample the fine-tuning of the `MANIFEST.MF` is done within the Bundlor `template.mf`.

NOTE: If you intend to run your bundles in different OSGi containers you have to limit yourself to the OSGi standard headers.

Next step is to confiugre the servlet container via `WEB-INF/web.xml`:

[source,xml]
.web.xml
----
include::../../org.eclipse.virgo.samples.recipe.uploading/src/main/resources/WEB-INF/web.xml[]
----
<1> Virgo specific `contextClass`

NOTE: Most important the `contextClass` which is *not* the default from the Spring Framework, but `org.eclipse.virgo.web.dm.ServerOsgiBundleXmlWebApplicationContext`.

Finally the Spring web application context. Nothing Virgo specific here:

[source,xml]
----
include::../../org.eclipse.virgo.samples.recipe.uploading/src/main/resources/WEB-INF/spring/appServlet/servlet-context.xml[]
----

== Let's taste

For easy client-side consumption of the file upload you can use the `FileUploader`.

[source,java]
----
include::../../org.eclipse.virgo.samples.recipe.uploading/src/main/java/org/eclipse/virgo/samples/recipe/uploading/internal/FileUploader.java[tags=type]
----

NOTE: Please see the original guide https://spring.io/guides/gs/{guide-short-name}/["{recipe-name}"] for more background information about this client.

There is an easy way to use the `FileUploader` with Gradle:

[source,sh]
----
$ ./gradlew run
----

Or if you are more used to `curl` and the command line simply run the following command within the project's directory.

[source,sh]
----
$ curl -F "name=sample.txt" -F "file=@org.eclipse.virgo.samples.recipe.uploading/sample.txt" http://localhost:8080/upload-guide/upload
----

Either way you should see the following output independent of your choice:

....
You successfully uploaded sample.txt into sample.txt-uploaded !
....

include::../../../recipe-template/src/asciidoc/08_dockerize_recipe.adoc[]
