diff --git a/gdk-oci-metrics/00-introduction/introduction.md b/gdk-oci-metrics/00-introduction/introduction.md
new file mode 100644
index 000000000..58d89d2fe
--- /dev/null
+++ b/gdk-oci-metrics/00-introduction/introduction.md
@@ -0,0 +1,59 @@
+# Introduction
+
+## About this Workshop
+
+This workshop takes you step by step through the process of building a Java application to Publish standard and custom metrics to Oracle Cloud Infrastructure (OCI) Monitoring with the Graal Development Kit for Micronaut (GDK). It shows you how to query and visualize the published metrics using the OCI Metrics Explorer. You'll use GraalVM Native Image to package and run the application as a native executable.
+
+It is aimed at application developers and DevOps engineers with a basic knowledge of Java.
+
+Estimated Workshop Time: 75 minutes
+
+### What is Graal Development Kit for Micronaut?
+
+The [Graal Development Kit for Micronaut (GDK)](https://graal.cloud/gdk) is an Oracle build of the open source Micronaut® framework. The GDK provides a curated set of Micronaut framework modules that simplify cloud application development, are designed for ahead-of-time compilation with GraalVM Native Image, and are fully supported by Oracle. The GDK also provides project creation utilities, VS Code and IntelliJ extensions to simplify application development and deployment.
+
+### What is Micronaut?
+
+The [Micronaut® framework](https://micronaut.io/) is a modern, JVM-based framework to build modular, easily testable microservice and serverless applications. By avoiding runtime reflection in favor of annotation processing, Micronaut improves the Java-based development experience by detecting errors at compile time instead of runtime, and improves Java-based application startup time and memory footprint. Micronaut includes a persistence framework called Micronaut Data that precomputes your SQL queries at compilation time making it a great fit for working with databases like MySQL, Oracle Autonomous Database, etc.
+
+> Micronaut® is a registered trademark of Object Computing, Inc. Use is for referential purposes and does not imply any endorsement or affiliation with any third-party product.
+
+### What is GraalVM Native Image?
+
+[GraalVM Native Image](https://www.graalvm.org/) technology compiles Java applications ahead-of-time into self-contained native executables that are small in size, start almost instantaneously, provide peak performance with no warmup, and require less memory and CPU. Only the code that is required at run time by the application gets added into the executable file. Native Image is perfect for containerized workloads and microservices — which is why it has been embraced by Micronaut, Spring Boot, Helidon, and Quarkus.
+
+The GDK modules are designed for ahead-of-time compilation with GraalVM Native Image to produce native executables that are ideal for microservices: they have a small memory footprint, start instantly, and provide peak performance with no warmup.
+
+> Graal Development Kit for Micronaut, and Oracle GraalVM are available at no additional cost on Oracle Cloud Infrastructure (OCI).
+
+### Objectives
+
+In this workshop, you will:
+
+* Use Visual Studio Code (VS Code) from a remote desktop running in an OCI Compute Instance
+* Review the application source code developed with the Graal Development Kit for Micronaut
+* Configure the application to use OCI Monitoring
+* Build a native executable for the application using GraalVM Native Image
+* Run the application and publish standard and custom metrics to OCI Monitoring
+* View the published metrics in OCI Monitoring
+
+### Prerequisites
+
+This workshop assumes you have:
+
+* Some familiarity with Oracle Cloud Infrastructure (OCI)
+* Understanding of the Java programming language
+* Oracle GraalVM for JDK 17
+* Visual Studio Code (VS Code)
+* A browser with access to the internet
+* An Oracle Cloud Infrastructure (OCI) account with adequate permissions
+
+## Learn More
+
+* [Graal Development Kit for Micronaut](https://graal.cloud/gdk/)
+
+## Acknowledgements
+
+* **Author** - [](var:author)
+* **Contributors** - [](var:contributors)
+* **Last Updated By/Date** - [](var:last_updated)
diff --git a/gdk-oci-metrics/01-prepare-setup/prepare-setup.md b/gdk-oci-metrics/01-prepare-setup/prepare-setup.md
new file mode 100644
index 000000000..c03d06e0f
--- /dev/null
+++ b/gdk-oci-metrics/01-prepare-setup/prepare-setup.md
@@ -0,0 +1,85 @@
+# Prepare Setup
+
+## Introduction
+
+This lab will show you how to download the Oracle Resource Manager (ORM) stack zip file needed to set up the resources needed to run this workshop.
+
+*Estimated Lab Time:* 5 minutes
+
+### Objectives
+
+* Download ORM stack
+* (*Optional*) Configure an existing Virtual Cloud Network (VCN)
+* Select a Compartment for the workshop
+
+### Prerequisites
+
+This lab assumes you have:
+
+* An Oracle Cloud account
+
+## Task 1: Download Oracle Resource Manager (ORM) stack zip file
+
+1. Click on the link below to download the Resource Manager zip file you need to build your environment:
+
+ * [gdk-oci-metrics-ll-orm.zip](https://c4u04.objectstorage.us-ashburn-1.oci.customer-oci.com/p/EcTjWk2IuZPZeNnD_fYMcgUhdNDIDA6rt9gaFj_WZMiL7VvxPBNMY60837hu5hga/n/c4u04/b/livelabsfiles/o/oci-library/gdk-oci-metrics-ll-orm.zip)
+
+2. Save it in your downloads folder.
+
+3. (*Recommended*) We strongly recommend using this stack to create a new self-contained/dedicated VCN along with your instance. Skip to **Task 3** to follow the recommendation.
+
+4. Alternatively, if you would rather use an existing VCN then proceed to the next task to update your existing VCN with the required network security rules.
+
+## Task 2: Add Network Security Rules to an Existing VCN
+
+This workshop requires a certain number of ports to be available, a requirement that is automatically met by using the default ORM stack execution that creates a new dedicated VCN.
+
+However, if you would rather use an existing VCN/subnet, follow these steps to add the following rules to the network security list.
+
+1. From the Oracle Cloud Console navigation menu, go to **Networking >> Virtual Cloud Networks**.
+2. Choose your network.
+3. Under **Resources**, select **Security Lists**.
+4. Click on **Default Security Lists** under the **Create Security List** button.
+5. Click **Add Ingress Rules** button.
+6. Create a rule for each row in the *Ingress* table below:
+
+ | Stateless | Source Type | Source CIDR | IP Protocol | Source Port Range | Destination Port Range | Description |
+ | :------------- | :---------: | :---------: | :---------: | :---------------: | :--------------------: | :------------------------- |
+ | No (unchecked) | CIDR | 0.0.0.0/0 | TCP | All | 80 | Remote Desktop using noVNC |
+ | No (unchecked) | CIDR | 0.0.0.0/0 | TCP | All | 6080 | Remote Desktop using noVNC |
+ {: title="Network Ingress Security Rules"}
+
+7. Select **Egress Rule** from the left panel.
+8. Click **Add Egress Rule** button
+9. Create a rule for each row in the *Egress* table below:
+
+ | Stateless | Source Type | Destination CIDR | IP Protocol | Source Port Range | Destination Port Range | Description |
+ | :------------- | :---------: | :--------------: | :---------: | :---------------: | :--------------------: | :-------------------- |
+ | No (unchecked) | CIDR | 0.0.0.0/0 | TCP | All | 80 | Outbound HTTP access |
+ | No (unchecked) | CIDR | 0.0.0.0/0 | TCP | All | 443 | Outbound HTTPS access |
+ {: title="Network Egress Security Rules"}
+
+## Task 3: Select a Compartment for the Workshop
+
+We recommend you use a single compartment for the workshop. We will refer to this as your workshop compartment. This is the compartment where you will provision all the resources - Oracle Resource Manager (ORM) Stack, Compute Instance, VCN/Subnet - needed for the workshop.
+
+1. From the Oracle Cloud Console navigation menu, go to **Identity & Security >> Identity >> Compartments**.
+2. Go to your workshop compartment.
+3. Make a note of the compartment name and OCID. You will need this information in subsequent labs.
+
+## Task 4: Setup Compute
+
+Using the details from the above Tasks, proceed to the **Environment Setup** lab to set up your workshop environment using Oracle Resource Manager (ORM) with one of the following options:
+
+* (*Recommended*) Create Stack: **Compute + Networking**
+* Create Stack: **Compute only** with an existing VCN where security lists have been updated as per **Task 2** above
+
+The ORM stack will provision a compute instance with 4 OCPUs, 64 GB RAM and a Remote Desktop environment.
+
+You may now **proceed to the next lab**.
+
+## Acknowledgements
+
+* **Author** - [](var:author)
+* **Contributors** - [](var:contributors)
+* **Last Updated By/Date** - [](var:last_updated)
diff --git a/gdk-oci-metrics/02-git-clone/git-clone.md b/gdk-oci-metrics/02-git-clone/git-clone.md
new file mode 100644
index 000000000..f3bc9fe7f
--- /dev/null
+++ b/gdk-oci-metrics/02-git-clone/git-clone.md
@@ -0,0 +1,54 @@
+# Clone the Sample Application Source Code
+
+## Introduction
+
+This lab describes the steps to download the sample application source code used in the workshop.
+
+Estimated Lab Time: 5 minutes
+
+### Objectives
+
+In this lab, you will:
+
+* Clone the sample application source code
+
+## Task 1: Clone the Sample Application Source Code
+
+1. From the **Activities** menu, start a new **Terminal** window.
+
+2. Clone the sample application source code.
+
+ ```bash
+
+ git init lab
+ cd lab
+ git remote add origin https://github.com/sachin-pikle/gdk-oci-samples.git
+ git config core.sparsecheckout true
+ echo "gdk-oci-metrics-mvn/*">>.git/info/sparse-checkout
+ git pull --depth=1 origin main
+
+ ```
+
+3. Open the sample application source code from the _gdk-oci-metrics-mvn_ directory in **Visual Studio Code**.
+
+ ```bash
+
+ code gdk-oci-metrics-mvn
+
+ ```
+
+4. VS Code may show a dialog box with the message "Do you trust the authors of the files in this folder?". Select **Trust the authors of all files in the parent folder 'oracle'** and click **Yes, I trust the authors**.
+
+5. VS Code may ask you to choose a password for new keyring. Press **Cancel** twice to close the prompt.
+
+6. VS Code may show a dialog box with the message "A git repository was found in the parent folders of the workspace or the open file(s). Would you like to open the repository?". Click **Never**.
+
+ 
+
+You may now **proceed to the next lab**.
+
+## Acknowledgements
+
+* **Author** - [](var:author)
+* **Contributors** - [](var:contributors)
+* **Last Updated By/Date** - [](var:last_updated)
diff --git a/gdk-oci-metrics/02-git-clone/images/vs-code-question-icon.jpg b/gdk-oci-metrics/02-git-clone/images/vs-code-question-icon.jpg
new file mode 100644
index 000000000..0e7299ab5
Binary files /dev/null and b/gdk-oci-metrics/02-git-clone/images/vs-code-question-icon.jpg differ
diff --git a/gdk-oci-metrics/03-review-code/review-code.md b/gdk-oci-metrics/03-review-code/review-code.md
new file mode 100644
index 000000000..2ea0fe4ee
--- /dev/null
+++ b/gdk-oci-metrics/03-review-code/review-code.md
@@ -0,0 +1,222 @@
+# Review the Sample Application Source Code
+
+## Introduction
+
+This lab reviews the sample Micronaut application code used in the workshop. The application source code and build scripts are available for review in VS Code.
+
+You'll see how easy it is to configure a Micronaut application to publish metrics to OCI Monitoring with the GDK.
+
+Estimated Time: 10 minutes
+
+### Objectives
+
+In this lab, you will:
+
+* Review the sample application source code
+
+## Task 1: Review the Application Dependencies
+
+The build files contain the following dependencies to enable Micronaut's Micrometer integration with OCI Monitoring:
+
+- `micronaut-micrometer-core`
+- `micronaut-oraclecloud-bmc-monitoring`
+- `micronaut-oraclecloud-micrometer`
+
+_lib/pom.xml_
+
+
+ io.micronaut.micrometer
+ micronaut-micrometer-core
+ compile
+
+
+_oci/pom.xml_
+
+
+ io.micronaut.micrometer
+ micronaut-micrometer-core
+ compile
+
+
+ io.micronaut.oraclecloud
+ micronaut-oraclecloud-bmc-monitoring
+ compile
+
+ ...
+
+ io.micronaut.oraclecloud
+ micronaut-oraclecloud-micrometer
+ compile
+
+
+## Task 2: Review the Controller
+
+The controller class `BookController` exposes the `Book` resource with REST APIs for the common CRUD operations.
+
+_lib/src/main/java/com/example/BookController.java_
+
+``` java
+@Controller("/books") // <1>
+@ExecuteOn(TaskExecutors.IO)
+class BookController {
+```
+
+1. The class is defined as a controller with the [@Controller](https://docs.micronaut.io/latest/api/io/micronaut/http/annotation/Controller.html) annotation mapped to the path `/books`.
+
+``` java
+@Get // <2>
+@Timed("books.index") // <3>
+Iterable index() {
+ return bookRepository.findAll();
+}
+```
+
+2. Maps a `GET` request to `/books`, which returns a list of all books.
+
+3. Creates a `Timer` metric with the name `books.index` that contains the `total time`, `max time` and `count`. The `@Timed` annotation is used to add timing support to methods such as those serving web request endpoints.
+
+``` java
+@Get("/{isbn}") // <4>
+@Counted("books.find") // <5>
+Optional findBook(String isbn) {
+ return bookRepository.findByIsbn(isbn);
+}
+```
+
+4. Maps a `GET` request to `/books/{isbn}` to find a book by its International Standard Book Number (ISBN).
+
+5. Creates a `Counter` metric with the name `books.find` that only contains a count.
+
+## Task 3: Review the Service Class
+
+The service class `MicroserviceBooksNumberService` retrieves information from the database and publishes custom metrics based on it. In this example, the custom metrics reflect the number of books containing the word "microservices" in their title.
+
+_lib/src/main/java/com/example/MicroserviceBooksNumberService.java_
+
+``` java
+@Singleton
+public class MicroserviceBooksNumberService {
+
+ ...
+ private final Counter checks;
+ private final Timer time;
+ private final AtomicInteger microserviceBooksNumber = new AtomicInteger(0);
+ ...
+
+ MicroserviceBooksNumberService(BookRepository bookRepository,
+ MeterRegistry meterRegistry) {
+ this.bookRepository = bookRepository;
+ checks = meterRegistry.counter("microserviceBooksNumber.checks");
+ time = meterRegistry.timer("microserviceBooksNumber.time");
+ meterRegistry.gauge("microserviceBooksNumber.latest", microserviceBooksNumber);
+ }
+```
+
+The constructor registers the following custom meters:
+- `microserviceBooksNumber.checks` stores the number of times this check is performed.
+- `microserviceBooksNumber.time` stores the total time spent on each check.
+- `microserviceBooksNumber.latest` stores the total number of books containing the word "microservices" in their title.
+
+``` java
+ public void updateNumber() {
+ time.record(() -> {
+ try {
+ Iterable allBooks = bookRepository.findAll();
+ long booksNumber = StreamSupport.stream(allBooks.spliterator(), false)
+ .filter(b -> b.getName().toLowerCase().contains(SEARCH_KEY))
+ .count();
+
+ checks.increment();
+ microserviceBooksNumber.set((int) booksNumber);
+ } catch (Exception e) {
+ log.error("Problem setting the number of microservice books", e);
+ }
+ });
+ }
+```
+
+The `updateNumber()` method queries the database, counts the total number of books containing the word "microservices" in their title and updates the `microserviceBooksNumber.latest` meter with the value. It records the time taken and increments the number of times this check is performed.
+
+``` java
+ @Scheduled(fixedRate = "${customMetrics.updateFrequency:1h}",
+ initialDelay = "${customMetrics.initialDelay:0s}")
+ public void updateNumber() {
+ ...
+ ...
+ }
+```
+
+The metric update is scheduled using the `@Scheduled` annotation. The `customMetrics.updateFrequency` parameter corresponds to the update rate and has a default value of one hour. The `customMetrics.initialDelay` parameter corresponds to a delay after application startup before the metrics calculation and has a default value of zero seconds.
+
+## Task 4: Review the Books Database
+
+The application uses [Micronaut integration with Flyway](https://micronaut-projects.github.io/micronaut-flyway/latest/guide/) to create a database schema on the fly.
+
+Flyway migration is automatically triggered before your application starts. Flyway reads the migration file(s) from the _lib/src/main/resources/db/migration/_ directory. During application startup, Flyway runs the commands in the SQL file and creates the schema needed for the application.
+
+Using the SQL statements in _V1__schema.sql_, Flyway creates a table with the name `book` and populates it with four records.
+
+_lib/src/main/resources/db/migration/V1__schema.sql_
+
+``` sql
+DROP TABLE IF EXISTS book;
+
+CREATE TABLE book (
+ id BIGINT NOT NULL AUTO_INCREMENT UNIQUE PRIMARY KEY,
+ name VARCHAR(255) NOT NULL UNIQUE,
+ isbn CHAR(13) NOT NULL UNIQUE
+);
+
+INSERT INTO book (isbn, name)
+VALUES ("9781491950357", "Building Microservices"),
+ ("9781680502398", "Release It!"),
+ ("9780321601919", "Continuous Delivery"),
+ ("9781617294549", "Microservices Patterns");
+```
+
+## Task 5: Review the Metrics Collection Configuration
+
+Several groups of metrics are enabled by default: these include system metrics (such as JVM information and uptime), as well as metrics tracking web requests, data sources activity, and others.
+
+_oci/src/main/resources/application-oraclecloud.properties_
+
+``` properties
+# <1>
+micronaut.metrics.enabled=true
+# <2>
+micronaut.metrics.binders.files.enabled=true
+micronaut.metrics.binders.jdbc.enabled=true
+micronaut.metrics.binders.jvm.enabled=true
+micronaut.metrics.binders.logback.enabled=true
+micronaut.metrics.binders.processor.enabled=true
+micronaut.metrics.binders.uptime.enabled=true
+micronaut.metrics.binders.web.enabled=true
+# <3>
+micronaut.metrics.export.oraclecloud.enabled=true
+# <4>
+micronaut.metrics.export.oraclecloud.namespace=gcn_metrics_oci
+# <5>
+micronaut.metrics.export.oraclecloud.compartmentId=${COMPARTMENT_OCID}
+```
+
+1. Overall metrics can be enabled or disabled. To disable, change to false.
+
+2. Metrics groups can be individually enabled or disabled. In this case all metrics groups are enabled. To disable, change to false.
+
+3. To export metrics to OCI, enable Oracle Cloud as an export location for Micrometer. Then create queries and monitor metrics in the OCI Monitoring service’s Metrics Explorer UI.
+
+4. Set the namespace for metrics to something meaningful, for example, a name such as `gcn_metrics_oci`. The namespace groups the metrics in OCI Monitoring.
+
+5. By default, metrics are published in the root compartment of your tenancy. The `compartmentId` property specifies the compartment to which metrics should be published.
+
+**Note:** This way (`property: ${}`) of defining properties enables you to externalize the configuration easily. In this example, the value is picked up from an environment variable named `COMPARTMENT_OCID`.
+
+In the next section, you will configure the application to use OCI Monitoring.
+
+You may now **proceed to the next lab**.
+
+## Acknowledgements
+
+* **Author** - [](var:author)
+* **Contributors** - [](var:contributors)
+* **Last Updated By/Date** - [](var:last_updated)
diff --git a/gdk-oci-metrics/04-configure-app/configure-app.md b/gdk-oci-metrics/04-configure-app/configure-app.md
new file mode 100644
index 000000000..0425b0b5f
--- /dev/null
+++ b/gdk-oci-metrics/04-configure-app/configure-app.md
@@ -0,0 +1,91 @@
+# Configure the application to use OCI Monitoring
+
+## Introduction
+
+This lab provides instructions to configure the application to point to OCI Monitoring.
+
+Estimated Lab Time: 05 minutes
+
+### Objectives
+
+In this lab, you will:
+
+* Configure the application to use the OCI Monitoring
+* Configure OCI Instance Principal Authentication
+
+## Task 1: Configure the Application to use the OCI Monitoring
+
+1. From the Oracle Cloud Console, open the navigation menu, navigate to **Identity & Security >> Compartments** , find your workshop compartment in the list, open it, in the **Compartment Information** section click **Copy** to copy the value of the compartment OCID.
+
+2. Open a new terminal in VS Code using the **Terminal > New Terminal** menu.
+
+3. Set the environment variable `COMPARTMENT_OCID` using the compartment OCID you copied.
+
+ ```
+
+ export COMPARTMENT_OCID=ocid1.compartment.oc1...
+
+ ```
+
+4. Confirm the value set by running the following command:
+
+ ```
+
+ echo $COMPARTMENT_OCID
+
+ ```
+
+## Task 2: UseConfigure OCI Instance Principal Authentication
+
+1. In VS Code, open `application-oraclecloud.properties`. The application is configured to use `OCI Instance Principal Authentication` when it is running on an OCI Compute Instance.
+
+ _oci/src/main/resources/application-oraclecloud.properties_
+
+ ``` properties
+ oci.config.instance-principal.enabled=true
+ ```
+
+
+2. The workshop environment includes a preconfigured `Instance Principal` using a `Dynamic Group` and a `Policy` in OCI to allow the application to send logs to OCI Logging.
+
+
+
+2. The following steps show you how to set up an `Instance Principal` using a `Dynamic Group`-less `Policy` in OCI to allow the application to send logs to OCI Logging.
+
+3. From the Oracle Cloud Console navigation menu, go to **Identity & Security >> Identity >> Policies**.
+
+ 
+
+4. Go to your workshop compartment.
+
+5. Click **Create Policy**.
+
+6. Enter a name and description.
+
+7. Select your workshop compartment.
+
+8. In the **Policy Builder** section, click **Show manual editor**.
+
+9. Enter the following policy statement in the text area. Replace the placeholders `WORKSHOP_COMPARTMENT_NAME` with your workshop compartment name, and `WORKSHOP_COMPARTMENT_OCID` with your workshop compartment OCID.
+
+ ``` text
+
+ Allow any-user to use metrics in compartment WORKSHOP_COMPARTMENT_NAME where ALL {request.principal.type='instance', request.principal.compartment.id='WORKSHOP_COMPARTMENT_OCID'}
+
+ ```
+
+ To learn more about policies to control access to OCI Monitoring, see [Policy Reference - Details for Monitoring](https://docs.oracle.com/en-us/iaas/Content/Identity/Reference/monitoringpolicyreference.htm).
+
+
+
+ To learn more about the supported authentication options, see [Micronaut Oracle Cloud Authentication](https://micronaut-projects.github.io/micronaut-oracle-cloud/snapshot/guide/#authentication).
+
+Congratulations! In this lab, you configured the application to publish metrics to OCI Monitoring.
+
+You may now **proceed to the next lab**.
+
+## Acknowledgements
+
+* **Author** - [](var:author)
+* **Contributors** - [](var:contributors)
+* **Last Updated By/Date** - [](var:last_updated)
diff --git a/gdk-oci-metrics/05-build-run-app/build-run-app.md b/gdk-oci-metrics/05-build-run-app/build-run-app.md
new file mode 100644
index 000000000..d455e2a9a
--- /dev/null
+++ b/gdk-oci-metrics/05-build-run-app/build-run-app.md
@@ -0,0 +1,98 @@
+# Build and run the application
+
+## Introduction
+
+This section of the lab takes you through the steps to build and run the sample application.
+
+Estimated Lab Time: 10 minutes
+
+### Objectives
+
+In this lab, you will:
+
+* Build and run the application
+* Send requests to publish metrics to OCI Metrics
+
+## Task 1: Build and run the application with `mn:run`
+
+1. From the same terminal in VS Code, run the following command with `mn:run` to build and start the application on port 8080.
+
+``` bash
+
+./mvnw install -pl lib -am && MICRONAUT_ENVIRONMENTS=oraclecloud ./mvnw mn:run -pl oci
+
+```
+
+## Task 2: Send requests to publish metrics to OCI Metrics
+
+1. Open a second terminal in VS Code using the **Terminal>New Terminal** menu.
+
+2. From the second terminal, send a few test requests (2 each) with cURL, as follows:
+
+ a) Get all the books:
+
+ ``` bash
+
+ curl localhost:8080/books | jq
+
+ ```
+
+ VS Code may prompt you to open the URL in a browser as shown below. Just click the **Configure Notifications** gear icon and then click **Don't Show Again**.
+
+ 
+
+ 
+
+ b) Get a book by its ISBN:
+
+ ``` bash
+
+ curl localhost:8080/books/9781680502398 | jq
+
+ ```
+
+ c) Get a list of all the available metrics:
+
+ ``` bash
+
+ curl localhost:8080/metrics | jq
+
+ ```
+
+ d) Get a particular metric value:
+
+ ``` bash
+
+ curl localhost:8080/metrics/http.server.requests | jq
+
+ ```
+
+ e) Get the value of the metric created on the `/books` endpoint:
+
+ ``` bash
+
+ curl localhost:8080/metrics/books.index | jq
+
+ ```
+
+ f) Get the value of the custom metric that contains the total number of books containing the word "microservices" in their title:
+
+ ``` bash
+
+ curl localhost:8080/metrics/microserviceBooksNumber.latest | jq
+
+ ```
+
+## Task 3: Stop the application
+
+1. In the first terminal in VS Code, use `CTRL+C` to stop the application.
+
+Congratulations! You've successfully completed this lab. Your Java application can successfully publish metrics to OCI Monitoring.
+
+You may now **proceed to the next lab**.
+
+## Acknowledgements
+
+* **Author** - [](var:author)
+* **Contributors** - [](var:contributors)
+* **Last Updated By/Date** - [](var:last_updated)
diff --git a/gdk-oci-metrics/05-build-run-app/images/vscode-dont-show-again.png b/gdk-oci-metrics/05-build-run-app/images/vscode-dont-show-again.png
new file mode 100644
index 000000000..6d31dec1e
Binary files /dev/null and b/gdk-oci-metrics/05-build-run-app/images/vscode-dont-show-again.png differ
diff --git a/gdk-oci-metrics/05-build-run-app/images/vscode-paste-urls.png b/gdk-oci-metrics/05-build-run-app/images/vscode-paste-urls.png
new file mode 100644
index 000000000..38620b8a1
Binary files /dev/null and b/gdk-oci-metrics/05-build-run-app/images/vscode-paste-urls.png differ
diff --git a/gdk-oci-metrics/06-build-run-native/build-run-native.md b/gdk-oci-metrics/06-build-run-native/build-run-native.md
new file mode 100644
index 000000000..c6568e5db
--- /dev/null
+++ b/gdk-oci-metrics/06-build-run-native/build-run-native.md
@@ -0,0 +1,168 @@
+# Build and run a native executable
+
+## Introduction
+
+This lab describes how to build and run a native executable for the application.
+
+You will use [GraalVM Native Image](https://docs.oracle.com/en/graalvm/jdk/17/docs/overview/)’s ahead-of-time compilation to build a native executable for the application.
+
+At build time, GraalVM analyzes a Java application and its dependencies to identify just what classes, methods, and fields are absolutely necessary, and then generates a native executable with optimized machine code for just these elements.
+
+Native executables built with GraalVM require less memory, are smaller in size, and start upto 100x faster than just-in-time compiled applications running on a Java Virtual Machine.
+
+For this step you will start a local MySQL container, update the datasources default URL, username, and password in the _oci/src/main/resources/application-oraclecloud.properties_ file, build the native executable and run the native executable with the local MySQL database.
+
+Estimated Lab Time: 15 minutes
+
+### Objectives
+
+In this lab, you will:
+
+* Configure the application to use local MySQL database
+* Build and run a native executable for the application
+* Send requests to publish metrics to OCI Metrics
+
+## Task 1: Configure the application to use local MySQL database
+
+1. Open a third terminal in VS Code using the **Terminal>New Terminal** menu.
+
+2. Copy the following command to run a MySQL container:
+
+ ``` bash
+
+ docker run -it --rm \
+ --name "mysql.latest" \
+ -p 3306:3306 \
+ -e MYSQL_DATABASE=db \
+ -e MYSQL_USER=sherlock \
+ -e MYSQL_PASSWORD=elementary \
+ -e MYSQL_ALLOW_EMPTY_PASSWORD=true \
+ container-registry.oracle.com/mysql/community-server:latest
+
+ ```
+
+3. Place your cursor in the terminal in VS Code and paste (`CTRL+SHIFT+V`) the command you copied. A dialog box will ask **Are you sure you want to paste 8 lines of text in to the terminal?**. Select **Do not ask me again** and click **Paste** to proceed.
+
+ 
+
+ Press the enter (return) key. The MySQL container starts in a few seconds. When MySQL is up and running, you will see a message in the terminal window similar to:
+
+ ``` bash
+ ... [Server] /usr/sbin/mysqld: ready for connections. Version: '9.0.1' socket: '/var/lib/mysql/mysql.sock' port: 3306 MySQL Community Server - GPL.
+ ```
+
+4. Uncomment the `url`, `username` and `password` under the `datasources.default` property in _oci/src/main/resources/application-oraclecloud.properties_:
+
+ ``` properties
+ datasources.default.url=${DATASOURCES_DEFAULT_URL:`jdbc:mysql://localhost:3306/db`}
+ datasources.default.username=${DATASOURCES_DEFAULT_USERNAME:sherlock}
+ datasources.default.password=${DATASOURCES_DEFAULT_PASSWORD:elementary}
+ ```
+
+ Save the file (`CTRL+S`).
+
+## Task 2: Build and run a native executable for the application
+
+1. In the first terminal in VS Code, check the version of the GraalVM native-image utility:
+
+ ``` bash
+
+ native-image --version
+
+ ```
+
+2. To generate a native executable using Maven, run the following command:
+
+ ``` bash
+
+ ./mvnw install -pl lib -am && ./mvnw clean package -pl oci -Dpackaging=native-image
+
+ ```
+
+ It can take approximately 3-4 minutes to generate the native executable.
+
+3. The native executable is created in the _oci/target_ directory and can be run with the following command:
+
+ ``` bash
+
+ MICRONAUT_ENVIRONMENTS=oraclecloud oci/target/oci-metrics-demo-oci
+
+ ```
+
+ The native executable starts instantaneously.
+
+## Task 3: Send requests to publish metrics to OCI Metrics
+
+1. From the second terminal, send a few test requests (2 each) with cURL, as follows:
+
+ a) Get all the books:
+
+ ``` bash
+
+ curl localhost:8080/books | jq
+
+ ```
+
+ b) Get a book by its ISBN:
+
+ ``` bash
+
+ curl localhost:8080/books/9781680502398 | jq
+
+ ```
+
+ c) Get a list of all the available metrics:
+
+ ``` bash
+
+ curl localhost:8080/metrics | jq
+
+ ```
+
+ d) Get a particular metric value:
+
+ ``` bash
+
+ curl localhost:8080/metrics/http.server.requests | jq
+
+ ```
+
+ e) Get the value of the metric created on the `/books` endpoint:
+
+ ``` bash
+
+ curl localhost:8080/metrics/books.index | jq
+
+ ```
+
+ f) Get the value of the custom metric that contains the total number of books containing the word "microservices" in their title:
+
+ ``` bash
+
+ curl localhost:8080/metrics/microserviceBooksNumber.latest | jq
+
+ ```
+
+## Task 4: Stop the application
+
+1. In the first terminal in VS Code, use `CTRL+C` to stop the application.
+
+ You may see some error stack traces with messages such as `... failed to post metrics to oracle cloud infrastructure monitoring ...` and `... Client 'oci': Cannot send HTTPS request. SSL is disabled`. You can safely ignore these messages.
+
+2. From the same terminal, stop the MySQL container.
+
+ ``` bash
+
+ docker rm -f "mysql.latest"
+
+ ```
+
+Congratulations! You've successfully completed this lab. Your Java application native executable can successfully publish metrics to OCI Monitoring.
+
+You may now **proceed to the next lab**.
+
+## Acknowledgements
+
+* **Author** - [](var:author)
+* **Contributors** - [](var:contributors)
+* **Last Updated By/Date** - [](var:last_updated)
diff --git a/gdk-oci-metrics/06-build-run-native/images/paste-mysql-8-confirm.jpg b/gdk-oci-metrics/06-build-run-native/images/paste-mysql-8-confirm.jpg
new file mode 100644
index 000000000..a3f7cbad4
Binary files /dev/null and b/gdk-oci-metrics/06-build-run-native/images/paste-mysql-8-confirm.jpg differ
diff --git a/gdk-oci-metrics/07-view-metrics/images/metrics-explorer-icon.jpg b/gdk-oci-metrics/07-view-metrics/images/metrics-explorer-icon.jpg
new file mode 100644
index 000000000..9f413e8ae
Binary files /dev/null and b/gdk-oci-metrics/07-view-metrics/images/metrics-explorer-icon.jpg differ
diff --git a/gdk-oci-metrics/07-view-metrics/images/metrics-query-compartment.jpg b/gdk-oci-metrics/07-view-metrics/images/metrics-query-compartment.jpg
new file mode 100644
index 000000000..0912fb639
Binary files /dev/null and b/gdk-oci-metrics/07-view-metrics/images/metrics-query-compartment.jpg differ
diff --git a/gdk-oci-metrics/07-view-metrics/images/select-metric-name.jpg b/gdk-oci-metrics/07-view-metrics/images/select-metric-name.jpg
new file mode 100644
index 000000000..e66edf662
Binary files /dev/null and b/gdk-oci-metrics/07-view-metrics/images/select-metric-name.jpg differ
diff --git a/gdk-oci-metrics/07-view-metrics/images/select-metric-namespace.jpg b/gdk-oci-metrics/07-view-metrics/images/select-metric-namespace.jpg
new file mode 100644
index 000000000..988d661cd
Binary files /dev/null and b/gdk-oci-metrics/07-view-metrics/images/select-metric-namespace.jpg differ
diff --git a/gdk-oci-metrics/07-view-metrics/images/update-chart.jpg b/gdk-oci-metrics/07-view-metrics/images/update-chart.jpg
new file mode 100644
index 000000000..d5f3f23fb
Binary files /dev/null and b/gdk-oci-metrics/07-view-metrics/images/update-chart.jpg differ
diff --git a/gdk-oci-metrics/07-view-metrics/images/updated-metrics-chart.png b/gdk-oci-metrics/07-view-metrics/images/updated-metrics-chart.png
new file mode 100644
index 000000000..baf13ef55
Binary files /dev/null and b/gdk-oci-metrics/07-view-metrics/images/updated-metrics-chart.png differ
diff --git a/gdk-oci-metrics/07-view-metrics/view-metrics.md b/gdk-oci-metrics/07-view-metrics/view-metrics.md
new file mode 100644
index 000000000..643b46205
--- /dev/null
+++ b/gdk-oci-metrics/07-view-metrics/view-metrics.md
@@ -0,0 +1,50 @@
+# View the published metrics in OCI Monitoring
+
+## Introduction
+
+This lab shows how to visualize the published metrics in Metrics Explorer from the Oracle Cloud Console.
+
+Estimated Lab Time: 15 minutes
+
+### Objectives
+
+In this lab, you will:
+
+* View the published metrics in OCI Monitoring
+
+## Task 1: View the published metrics in OCI Monitoring
+
+1. From the Oracle Cloud Console, navigate to **OCI Console >> Observability & Management**. Under **Monitoring**, click **Metrics Explorer**.
+
+ 
+
+2. In the **Metrics Explorer**, scroll down to the **Query 1** section. Select your workshop compartment from the **Compartment** drop down list.
+
+ 
+
+5. Select the **Metric namespace** as `gcn_metrics_oci`.
+
+ 
+
+6. Select the **Metric name** as `microserviceBooksNumber.latest_value`.
+
+ 
+
+7. Click **Update Chart** to visualize the selected metric.
+
+ 
+
+8. Scroll up to visualize the selected metric.
+
+ 
+
+
+Congratulations! You've successfully completed this lab. You can visualize the metrics published by the sample application in the OCI Metrics Explorer.
+
+You may now **proceed to the next lab**.
+
+## Acknowledgements
+
+* **Author** - [](var:author)
+* **Contributors** - [](var:contributors)
+* **Last Updated By/Date** - [](var:last_updated)
diff --git a/gdk-oci-metrics/08-cleanup/cleanup.md b/gdk-oci-metrics/08-cleanup/cleanup.md
new file mode 100644
index 000000000..e9ceb2a66
--- /dev/null
+++ b/gdk-oci-metrics/08-cleanup/cleanup.md
@@ -0,0 +1,35 @@
+# Cleanup
+
+## Introduction
+
+From the Oracle Cloud Console, clean up the resources provisioned for this workshop.
+
+Estimated Workshop Time: 05 minutes
+
+### Objectives
+
+In this lab, you will:
+
+* Destroy Stack
+* Delete Stack
+* Delete the Instance Principals Policy
+
+## Task 1: Cleanup
+
+From the Oracle Cloud Console, clean up the resources provisioned for this workshop:
+
+1. From **Resource Manager >> Stacks >> Stack Details** screen, run **Destroy** to delete the VCN and the Compute instance.
+
+2. From **Resource Manager >> Stacks >> Stack Details** screen, **Delete** the **Stack**.
+
+3. From **Identity & Security >> Identity >> Policies**, delete the Instance Principals **Policy**.
+
+Congratulations! You've successfully completed this lab.
+
+You may now **proceed to the next lab**.
+
+## Acknowledgements
+
+* **Author** - [](var:author)
+* **Contributors** - [](var:contributors)
+* **Last Updated By/Date** - [](var:last_updated)
\ No newline at end of file
diff --git a/gdk-oci-metrics/09-conclusion/conclusion.md b/gdk-oci-metrics/09-conclusion/conclusion.md
new file mode 100644
index 000000000..bfc402256
--- /dev/null
+++ b/gdk-oci-metrics/09-conclusion/conclusion.md
@@ -0,0 +1,18 @@
+# Conclusion
+
+In this workshop, you've learnt how to build a Micronaut application to publish standard and custom metrics to OCI Monitoring with the GDK, and to query and visualize the published metrics using the OCI Metrics Explorer.
+
+You've seen how to use GraalVM Native Image to package and run the application as a native executable.
+
+Application developers can use the Graal Development Kit for Micronaut (GDK) to build cloud-portable Java applications on Oracle Cloud Infrastructure with Micronaut and GraalVM Native Image.
+
+## Learn More
+
+- [Create a Micronaut Database Application to Collect Metrics and Monitor Them on Oracle Cloud](https://graal.cloud/gdk/gdk-modules/metrics/micronaut-metrics-db-oci/?buildTool=maven&lang=java)
+- [GDK Metrics](https://graal.cloud/gdk/modules/#metrics)
+
+## Acknowledgements
+
+* **Author** - [](var:author)
+* **Contributors** - [](var:contributors)
+* **Last Updated By/Date** - [](var:last_updated)
diff --git a/gdk-oci-metrics/variables/variables.json b/gdk-oci-metrics/variables/variables.json
new file mode 100644
index 000000000..9482d6dea
--- /dev/null
+++ b/gdk-oci-metrics/variables/variables.json
@@ -0,0 +1,5 @@
+{
+ "author": "Graal Product Management",
+ "contributors": "Lesia Chaban, Sachin Pikle, Ewan Slater, Kris Foster, Shaun Smith",
+ "last_updated": "Lesia Chaban, October 2024"
+ }
\ No newline at end of file
diff --git a/gdk-oci-metrics/workshops/desktop/index.html b/gdk-oci-metrics/workshops/desktop/index.html
new file mode 100644
index 000000000..7ec6410f1
--- /dev/null
+++ b/gdk-oci-metrics/workshops/desktop/index.html
@@ -0,0 +1,62 @@
+
+
+
+
+
+
+
+
+ Oracle LiveLabs
+
+
+
+
+
+
+
+
+
+
+
+
+
Oracle LiveLabs
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/gdk-oci-metrics/workshops/desktop/manifest.json b/gdk-oci-metrics/workshops/desktop/manifest.json
new file mode 100644
index 000000000..a92b1e1cc
--- /dev/null
+++ b/gdk-oci-metrics/workshops/desktop/manifest.json
@@ -0,0 +1,64 @@
+{
+ "workshoptitle": "Publish standard and custom metrics to Oracle Cloud Infrastructure (OCI) Monitoring with the Graal Development Kit for Micronaut (GDK)",
+ "variables": ["../../variables/variables.json"],
+ "help": "livelabs-help-oci_us@oracle.com",
+ "tutorials": [
+ {
+ "title": "Introduction",
+ "description": "The Introduction is always second for LiveLabs. The title and contents menu title match for the Introduction.",
+ "filename": "../../00-introduction/introduction.md"
+ },
+ {
+ "title": "Get Started",
+ "description": "Prerequisites for LiveLabs (Oracle-owned tenancies). The title of the lab and the Contents Menu title (the title above) match for Prerequisite lab. This lab is always first.",
+ "filename": "https://oracle-livelabs.github.io/common/labs/cloud-login/cloud-login-livelabs2.md"
+ },
+ {
+ "title": "Get Started with noVNC Remote Desktop",
+ "description": "Using noVNC Remote Desktop",
+ "filename": "https://oracle-livelabs.github.io/common/labs/remote-desktop/using-novnc-remote-desktop.md"
+ },
+ {
+ "title": "Lab 1: Clone the Sample Application Source Code",
+ "filename": "../../02-git-clone/git-clone.md"
+ },
+ {
+ "title": "Lab 2: Review the Application Source Code",
+ "filename": "../../03-review-code/review-code.md"
+ },
+ {
+ "title": "Lab 3: Configure the application to use OCI Monitoring",
+ "filename": "../../04-configure-app/configure-app.md",
+ "type": "desktop"
+ },
+ {
+ "title": "Lab 4: Build and Run the Application",
+ "filename": "../../05-build-run-app/build-run-app.md",
+ "type" : "desktop"
+ },
+ {
+ "title": "Lab 5: Build and Run a Native Executable",
+ "filename": "../../06-build-run-native/build-run-native.md",
+ "type": "desktop"
+ },
+ {
+ "title": "Lab 6: View the published metrics in OCI Monitoring",
+ "filename": "../../07-view-metrics/view-metrics.md",
+ "type": "desktop"
+ },
+ {
+ "title": "Lab 7: Cleanup",
+ "filename": "../../08-cleanup/cleanup.md",
+ "type": "desktop"
+ },
+ {
+ "title": "Conclusion",
+ "filename": "../../09-conclusion/conclusion.md"
+ },
+ {
+ "title": "Need Help?",
+ "description": "Solutions to Common Problems and Directions for Receiving Live Help",
+ "filename": "https://oracle-livelabs.github.io/common/labs/need-help/need-help-livelabs.md"
+ }
+ ]
+}
diff --git a/gdk-oci-metrics/workshops/sandbox/index.html b/gdk-oci-metrics/workshops/sandbox/index.html
new file mode 100644
index 000000000..7ec6410f1
--- /dev/null
+++ b/gdk-oci-metrics/workshops/sandbox/index.html
@@ -0,0 +1,62 @@
+
+
+
+
+
+
+
+
+ Oracle LiveLabs
+
+
+
+
+
+
+
+
+
+
+
+
+
Oracle LiveLabs
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/gdk-oci-metrics/workshops/sandbox/manifest.json b/gdk-oci-metrics/workshops/sandbox/manifest.json
new file mode 100644
index 000000000..59705e14a
--- /dev/null
+++ b/gdk-oci-metrics/workshops/sandbox/manifest.json
@@ -0,0 +1,59 @@
+{
+ "workshoptitle": "Publish standard and custom metrics to Oracle Cloud Infrastructure (OCI) Monitoring with the Graal Development Kit for Micronaut (GDK)",
+ "variables": ["../../variables/variables.json"],
+ "help": "livelabs-help-oci_us@oracle.com",
+ "tutorials": [
+ {
+ "title": "Introduction",
+ "description": "The Introduction is always second for LiveLabs. The title and contents menu title match for the Introduction.",
+ "filename": "../../00-introduction/introduction.md"
+ },
+ {
+ "title": "Get Started",
+ "description": "Prerequisites for LiveLabs (Oracle-owned tenancies). The title of the lab and the Contents Menu title (the title above) match for Prerequisite lab. This lab is always first.",
+ "filename": "https://oracle-livelabs.github.io/common/labs/cloud-login/cloud-login-livelabs2.md"
+ },
+ {
+ "title": "Lab 1: Clone the Sample Application Source Code",
+ "filename": "../../02-git-clone/git-clone.md"
+ },
+ {
+ "title": "Lab 2: Review the Application Source Code",
+ "filename": "../../03-review-code/review-code.md"
+ },
+ {
+ "title": "Lab 3: Configure the application to use OCI Monitoring",
+ "filename": "../../04-configure-app/configure-app.md",
+ "type": "desktop"
+ },
+ {
+ "title": "Lab 4: Build and Run the Application",
+ "filename": "../../05-build-run-app/build-run-app.md",
+ "type" : "desktop"
+ },
+ {
+ "title": "Lab 5: Build and Run a Native Executable",
+ "filename": "../../06-build-run-native/build-run-native.md",
+ "type": "desktop"
+ },
+ {
+ "title": "Lab 6: View the published metrics in OCI Monitoring",
+ "filename": "../../07-view-metrics/view-metrics.md",
+ "type": "desktop"
+ },
+ {
+ "title": "Lab 7: Cleanup",
+ "filename": "../../08-cleanup/cleanup.md",
+ "type": "desktop"
+ },
+ {
+ "title": "Conclusion",
+ "filename": "../../09-conclusion/conclusion.md"
+ },
+ {
+ "title": "Need Help?",
+ "description": "Solutions to Common Problems and Directions for Receiving Live Help",
+ "filename": "https://oracle-livelabs.github.io/common/labs/need-help/need-help-livelabs.md"
+ }
+ ]
+}
diff --git a/gdk-oci-metrics/workshops/tenancy/index.html b/gdk-oci-metrics/workshops/tenancy/index.html
new file mode 100644
index 000000000..7ec6410f1
--- /dev/null
+++ b/gdk-oci-metrics/workshops/tenancy/index.html
@@ -0,0 +1,62 @@
+
+
+
+
+
+
+
+
+ Oracle LiveLabs
+
+
+
+
+
+
+
+
+
+
+
+
+
Oracle LiveLabs
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/gdk-oci-metrics/workshops/tenancy/manifest.json b/gdk-oci-metrics/workshops/tenancy/manifest.json
new file mode 100644
index 000000000..e0fc52875
--- /dev/null
+++ b/gdk-oci-metrics/workshops/tenancy/manifest.json
@@ -0,0 +1,74 @@
+{
+ "workshoptitle": "Publish standard and custom metrics to Oracle Cloud Infrastructure (OCI) Monitoring with the Graal Development Kit for Micronaut (GDK)",
+ "variables": ["../../variables/variables.json"],
+ "help": "livelabs-help-oci_us@oracle.com",
+ "tutorials": [
+ {
+ "title": "Introduction",
+ "description": "The Introduction is always first. The title and contents menu title match for the Introduction.",
+ "filename": "../../00-introduction/introduction.md"
+ },
+ {
+ "title": "Get Started",
+ "description": "This is the prerequisites for customers using Free Trial and Paid tenancies, and Always Free accounts (if applicable). The title of the lab and the Contents Menu title (the title above) match for Prerequisite lab. This lab is always first.",
+ "filename": "https://oracle-livelabs.github.io/common/labs/cloud-login/pre-register-free-tier-account.md"
+ },
+ {
+ "title": "Prepare Setup",
+ "description": "How to download your ORM stack and update security rules for an existing VCN",
+ "filename": "../../01-prepare-setup/prepare-setup.md"
+ },
+ {
+ "title": "Environment Setup",
+ "description": "How to provision the workshop environment and connect to it",
+ "filename": "https://oracle-livelabs.github.io/common/labs/setup-compute-generic/setup-compute-novnc-ssh.md"
+ },
+ {
+ "title": "Get Started with noVNC Remote Desktop",
+ "description": "Using noVNC Remote Desktop",
+ "filename": "https://oracle-livelabs.github.io/common/labs/remote-desktop/using-novnc-remote-desktop.md"
+ },
+ {
+ "title": "Lab 1: Clone the Sample Application Source Code",
+ "filename": "../../02-git-clone/git-clone.md"
+ },
+ {
+ "title": "Lab 2: Review the Application Source Code",
+ "filename": "../../03-review-code/review-code.md"
+ },
+ {
+ "title": "Lab 3: Configure the application to use OCI Monitoring",
+ "filename": "../../04-configure-app/configure-app.md",
+ "type": "tenancy"
+ },
+ {
+ "title": "Lab 4: Build and Run the Application",
+ "filename": "../../05-build-run-app/build-run-app.md",
+ "type" : "tenancy"
+ },
+ {
+ "title": "Lab 5: Build and Run a Native Executable",
+ "filename": "../../06-build-run-native/build-run-native.md",
+ "type": "tenancy"
+ },
+ {
+ "title": "Lab 6: View the published metrics in OCI Monitoring",
+ "filename": "../../07-view-metrics/view-metrics.md",
+ "type": "tenancy"
+ },
+ {
+ "title": "Lab 7: Cleanup",
+ "filename": "../../08-cleanup/cleanup.md",
+ "type": "tenancy"
+ },
+ {
+ "title": "Conclusion",
+ "filename": "../../09-conclusion/conclusion.md"
+ },
+ {
+ "title": "Need Help?",
+ "description": "Solutions to Common Problems and Directions for Receiving Live Help",
+ "filename": "https://oracle-livelabs.github.io/common/labs/need-help/need-help-freetier.md"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/gdk-oci-tracing/00-introduction/introduction.md b/gdk-oci-tracing/00-introduction/introduction.md
new file mode 100644
index 000000000..6b4ef8651
--- /dev/null
+++ b/gdk-oci-tracing/00-introduction/introduction.md
@@ -0,0 +1,59 @@
+# Introduction
+
+## About this Workshop
+
+This workshop takes you step by step through the process of configuring a Java application to send traces to Oracle Cloud Infrastructure (OCI) Application Performance Monitoring (APM) Tracing with the Graal Development Kit for Micronaut (GDK). It shows you how to visualize the traces and spans using the OCI APM Trace Explorer. You'll use GraalVM Native Image to package and run the application as a native executable.
+
+It is aimed at application developers and DevOps engineers with an intermediate knowledge of Java.
+
+Estimated Workshop Time: 75 minutes
+
+### What is Graal Development Kit for Micronaut?
+
+The [Graal Development Kit for Micronaut (GDK)](https://graal.cloud/gdk) is an Oracle build of the open source Micronaut® framework. The GDK provides a curated set of Micronaut framework modules that simplify cloud application development, are designed for ahead-of-time compilation with GraalVM Native Image, and are fully supported by Oracle. The GDK also provides project creation utilities, VS Code and IntelliJ extensions to simplify application development and deployment.
+
+### What is Micronaut?
+
+The [Micronaut® framework](https://micronaut.io/) is a modern, JVM-based framework to build modular, easily testable microservice and serverless applications. By avoiding runtime reflection in favor of annotation processing, Micronaut improves the Java-based development experience by detecting errors at compile time instead of runtime, and improves Java-based application startup time and memory footprint. Micronaut includes a persistence framework called Micronaut Data that precomputes your SQL queries at compilation time making it a great fit for working with databases like MySQL, Oracle Autonomous Database, etc.
+
+> Micronaut® is a registered trademark of Object Computing, Inc. Use is for referential purposes and does not imply any endorsement or affiliation with any third-party product.
+
+### What is GraalVM Native Image?
+
+[GraalVM Native Image](https://www.graalvm.org/) technology compiles Java applications ahead-of-time into self-contained native executables that are small in size, start almost instantaneously, provide peak performance with no warmup, and require less memory and CPU. Only the code that is required at run time by the application gets added into the executable file. Native Image is perfect for containerized workloads and microservices — which is why it has been embraced by Micronaut, Spring Boot, Helidon, and Quarkus.
+
+The GDK modules are designed for ahead-of-time compilation with GraalVM Native Image to produce native executables that are ideal for microservices: they have a small memory footprint, start instantly, and provide peak performance with no warmup.
+
+> Graal Development Kit for Micronaut, and Oracle GraalVM are available at no additional cost on Oracle Cloud Infrastructure (OCI).
+
+### Objectives
+
+In this workshop, you will:
+
+* Use Visual Studio Code (VS Code) from a remote desktop running in an OCI Compute Instance
+* Review the application source code developed with the Graal Development Kit for Micronaut
+* Create a new OCI APM Domain from the Oracle Cloud Console
+* Configure the application to use the OCI APM Domain
+* Build a native executable for the application using GraalVM Native Image
+* View the traces and spans using the OCI APM Trace Explorer.
+
+### Prerequisites
+
+This workshop assumes you have:
+
+* Some familiarity with Oracle Cloud Infrastructure (OCI)
+* Understanding of the Java programming language
+* Oracle GraalVM for JDK 17
+* Visual Studio Code (VS Code)
+* A browser with access to the internet
+* An Oracle Cloud Infrastructure (OCI) account with adequate permissions
+
+## Learn More
+
+* [Graal Development Kit for Micronaut](https://graal.cloud/gdk/)
+
+## Acknowledgements
+
+* **Author** - [](var:author)
+* **Contributors** - [](var:contributors)
+* **Last Updated By/Date** - [](var:last_updated)
diff --git a/gdk-oci-tracing/01-prepare-setup/prepare-setup.md b/gdk-oci-tracing/01-prepare-setup/prepare-setup.md
new file mode 100644
index 000000000..49a5cb3d2
--- /dev/null
+++ b/gdk-oci-tracing/01-prepare-setup/prepare-setup.md
@@ -0,0 +1,85 @@
+# Prepare Setup
+
+## Introduction
+
+This lab will show you how to download the Oracle Resource Manager (ORM) stack zip file needed to set up the resources needed to run this workshop.
+
+*Estimated Lab Time:* 05 minutes
+
+### Objectives
+
+* Download ORM stack
+* (*Optional*) Configure an existing Virtual Cloud Network (VCN)
+* Select a Compartment for the workshop
+
+### Prerequisites
+
+This lab assumes you have:
+
+* An Oracle Cloud account
+
+## Task 1: Download Oracle Resource Manager (ORM) stack zip file
+
+1. Click on the link below to download the Resource Manager zip file you need to build your environment:
+
+ * [gdk-oci-tracing-ll-orm.zip](https://c4u04.objectstorage.us-ashburn-1.oci.customer-oci.com/p/EcTjWk2IuZPZeNnD_fYMcgUhdNDIDA6rt9gaFj_WZMiL7VvxPBNMY60837hu5hga/n/c4u04/b/livelabsfiles/o/oci-library/gdk-oci-tracing-ll-orm.zip)
+
+2. Save it in your downloads folder.
+
+3. (*Recommended*) We strongly recommend using this stack to create a new self-contained/dedicated VCN along with your instance. Skip to **Task 3** to follow the recommendation.
+
+4. Alternatively, if you would rather use an existing VCN then proceed to the next task to update your existing VCN with the required network security rules.
+
+## Task 2: Add Network Security Rules to an Existing VCN
+
+This workshop requires a certain number of ports to be available, a requirement that is automatically met by using the default ORM stack execution that creates a new dedicated VCN.
+
+However, if you would rather use an existing VCN/subnet, follow these steps to add the following rules to the network security list.
+
+1. From the Oracle Cloud Console navigation menu, go to **Networking >> Virtual Cloud Networks**.
+2. Choose your network.
+3. Under **Resources**, select **Security Lists**.
+4. Click on **Default Security Lists** under the **Create Security List** button.
+5. Click **Add Ingress Rules** button.
+6. Create a rule for each row in the *Ingress* table below:
+
+ | Stateless | Source Type | Source CIDR | IP Protocol | Source Port Range | Destination Port Range | Description |
+ | :------------- | :---------: | :---------: | :---------: | :---------------: | :--------------------: | :------------------------- |
+ | No (unchecked) | CIDR | 0.0.0.0/0 | TCP | All | 80 | Remote Desktop using noVNC |
+ | No (unchecked) | CIDR | 0.0.0.0/0 | TCP | All | 6080 | Remote Desktop using noVNC |
+ {: title="Network Ingress Security Rules"}
+
+7. Select **Egress Rule** from the left panel.
+8. Click **Add Egress Rule** button
+9. Create a rule for each row in the *Egress* table below:
+
+ | Stateless | Source Type | Destination CIDR | IP Protocol | Source Port Range | Destination Port Range | Description |
+ | :------------- | :---------: | :--------------: | :---------: | :---------------: | :--------------------: | :-------------------- |
+ | No (unchecked) | CIDR | 0.0.0.0/0 | TCP | All | 80 | Outbound HTTP access |
+ | No (unchecked) | CIDR | 0.0.0.0/0 | TCP | All | 443 | Outbound HTTPS access |
+ {: title="Network Egress Security Rules"}
+
+## Task 3: Select a Compartment for the Workshop
+
+We recommend you use a single compartment for the workshop. We will refer to this as your workshop compartment. This is the compartment where you will provision all the resources - Oracle Resource Manager (ORM) Stack, Compute Instance, VCN/Subnet, APM Domain - needed for the workshop.
+
+1. From the Oracle Cloud Console navigation menu, go to **Identity & Security >> Identity >> Compartments**.
+2. Go to your workshop compartment.
+3. Make a note of the compartment name and OCID. You will need this information in subsequent labs.
+
+## Task 4: Setup Compute
+
+Using the details from the above Tasks, proceed to the **Environment Setup** lab to set up your workshop environment using Oracle Resource Manager (ORM) with one of the following options:
+
+* (*Recommended*) Create Stack: **Compute + Networking**
+* Create Stack: **Compute only** with an existing VCN where security lists have been updated as per **Task 2** above
+
+The ORM stack will provision a compute instance with 4 OCPUs, 64 GB RAM and a Remote Desktop environment.
+
+You may now **proceed to the next lab**.
+
+## Acknowledgements
+
+* **Author** - [](var:author)
+* **Contributors** - [](var:contributors)
+* **Last Updated By/Date** - [](var:last_updated)
diff --git a/gdk-oci-tracing/02-git-clone/git-clone.md b/gdk-oci-tracing/02-git-clone/git-clone.md
new file mode 100644
index 000000000..9f930ac79
--- /dev/null
+++ b/gdk-oci-tracing/02-git-clone/git-clone.md
@@ -0,0 +1,54 @@
+# Clone the Sample Application Source Code
+
+## Introduction
+
+This lab describes the steps to download the sample application source code used in the workshop.
+
+Estimated Lab Time: 05 minutes
+
+### Objectives
+
+In this lab, you will:
+
+* Clone the sample application source code
+
+## Task 1: Clone the Sample Application Source Code
+
+1. From the **Activities** menu, start a new **Terminal** window.
+
+2. Clone the sample application source code.
+
+ ```bash
+
+ git init lab
+ cd lab
+ git remote add origin https://github.com/sachin-pikle/gdk-oci-samples.git
+ git config core.sparsecheckout true
+ echo "gdk-oci-tracing-mvn/*">>.git/info/sparse-checkout
+ git pull --depth=1 origin main
+
+ ```
+
+3. Open the sample application source code from the _gdk-oci-tracing-mvn_ directory in **Visual Studio Code**.
+
+ ```bash
+
+ code gdk-oci-tracing-mvn
+
+ ```
+
+4. VS Code may show a dialog box with the message "Do you trust the authors of the files in this folder?". Select **Trust the authors of all files in the parent folder 'oracle'** and click **Yes, I trust the authors**.
+
+5. VS Code may ask you to choose a password for new keyring. Press **Cancel** twice to close the prompt.
+
+6. VS Code may show a dialog box with the message "A git repository was found in the parent folders of the workspace or the open file(s). Would you like to open the repository?". Click **Never**.
+
+ 
+
+You may now **proceed to the next lab**.
+
+## Acknowledgements
+
+* **Author** - [](var:author)
+* **Contributors** - [](var:contributors)
+* **Last Updated By/Date** - [](var:last_updated)
diff --git a/gdk-oci-tracing/02-git-clone/images/vs-code-question-icon.jpg b/gdk-oci-tracing/02-git-clone/images/vs-code-question-icon.jpg
new file mode 100644
index 000000000..0e7299ab5
Binary files /dev/null and b/gdk-oci-tracing/02-git-clone/images/vs-code-question-icon.jpg differ
diff --git a/gdk-oci-tracing/03-configure-apm-domain/configure-apm-domain.md b/gdk-oci-tracing/03-configure-apm-domain/configure-apm-domain.md
new file mode 100644
index 000000000..01088d4fe
--- /dev/null
+++ b/gdk-oci-tracing/03-configure-apm-domain/configure-apm-domain.md
@@ -0,0 +1,47 @@
+# Create the OCI APM Domain
+
+## Introduction
+
+This lab provides instructions to create a new OCI APM Domain service.
+
+Estimated Lab Time: 05 minutes
+
+### Objectives
+
+In this lab, you will:
+
+* Create the OCI APM Domain
+
+## Task 1: Create a new OCI APM Domain
+
+1. From the Oracle Cloud Console navigation menu, go to **Observability & Management**. Under **Application Performance Monitoring**, click **Administration**.
+
+ 
+
+2. Select your workshop compartment from the **Compartment** drop down list on the left.
+
+ 
+
+3. Click **Create APM Domain**.
+
+ 
+
+5. You will see the **Create APM Domain** screen. Enter the Name as "gdk-apm-domain". Click **Create** to create the APM Domain.
+
+ 
+
+ It can take about two minutes to create the domain.
+
+6. From the **APM Domains** list, click **gdk-apm-domain** to go to the **Domain Details** screen.
+
+ 
+
+Congratulations! In this lab, you created an APM Domain.
+
+You may now **proceed to the next lab**.
+
+## Acknowledgements
+
+* **Author** - [](var:author)
+* **Contributors** - [](var:contributors)
+* **Last Updated By/Date** - [](var:last_updated)
diff --git a/gdk-oci-tracing/03-configure-apm-domain/images/apm-administration-menu.png b/gdk-oci-tracing/03-configure-apm-domain/images/apm-administration-menu.png
new file mode 100644
index 000000000..74486a003
Binary files /dev/null and b/gdk-oci-tracing/03-configure-apm-domain/images/apm-administration-menu.png differ
diff --git a/gdk-oci-tracing/03-configure-apm-domain/images/apm-domain-create-button.jpg b/gdk-oci-tracing/03-configure-apm-domain/images/apm-domain-create-button.jpg
new file mode 100644
index 000000000..8ea2e5fce
Binary files /dev/null and b/gdk-oci-tracing/03-configure-apm-domain/images/apm-domain-create-button.jpg differ
diff --git a/gdk-oci-tracing/03-configure-apm-domain/images/apm-domain-create-screen.png b/gdk-oci-tracing/03-configure-apm-domain/images/apm-domain-create-screen.png
new file mode 100644
index 000000000..bf27219c4
Binary files /dev/null and b/gdk-oci-tracing/03-configure-apm-domain/images/apm-domain-create-screen.png differ
diff --git a/gdk-oci-tracing/03-configure-apm-domain/images/apm-domains-list.png b/gdk-oci-tracing/03-configure-apm-domain/images/apm-domains-list.png
new file mode 100644
index 000000000..413046a1e
Binary files /dev/null and b/gdk-oci-tracing/03-configure-apm-domain/images/apm-domains-list.png differ
diff --git a/gdk-oci-tracing/03-configure-apm-domain/images/select-compartment-button.png b/gdk-oci-tracing/03-configure-apm-domain/images/select-compartment-button.png
new file mode 100644
index 000000000..0a7d96af9
Binary files /dev/null and b/gdk-oci-tracing/03-configure-apm-domain/images/select-compartment-button.png differ
diff --git a/gdk-oci-tracing/04-review-code/review-code.md b/gdk-oci-tracing/04-review-code/review-code.md
new file mode 100644
index 000000000..c74c89bf8
--- /dev/null
+++ b/gdk-oci-tracing/04-review-code/review-code.md
@@ -0,0 +1,250 @@
+# Review the Sample Application Source Code
+
+## Introduction
+
+This lab reviews the sample Micronaut application code used in the workshop. The application source code and build scripts are available for review in VS Code.
+
+The application is a simple "RESTful" microservice that manages the inventory of items.
+
+You'll see how easy it is to configure a Micronaut application to send traces to OCI APM Tracing with the GDK.
+
+Estimated Time: 10 minutes
+
+### Objectives
+
+In this lab, you will:
+
+* Review the sample application source code
+
+## Task 1: Tracing Annotations
+
+The Micronaut framework uses the [Micronaut Tracing](https://micronaut-projects.github.io/micronaut-tracing/latest/guide/index.html) and [OpenTelemetry](https://opentelemetry.io/) to generate and export tracing data.
+
+The [`io.micronaut.tracing.annotation`](https://micronaut-projects.github.io/micronaut-tracing/latest/api/io/micronaut/tracing/annotation/package-summary.html) package provides the following annotations that can be declared on methods to create new spans or continue existing spans:
+
+- [@NewSpan](https://micronaut-projects.github.io/micronaut-tracing/latest/api/io/micronaut/tracing/annotation/NewSpan.html): Used on methods to create a new span; defaults to the method name, but a unique name may be assigned instead.
+
+- [@ContinueSpan](https://micronaut-projects.github.io/micronaut-tracing/latest/api/io/micronaut/tracing/annotation/ContinueSpan.html): Used on methods to continue an existing span; primarily used in conjunction with `@SpanTag` (below).
+
+- [@SpanTag](https://micronaut-projects.github.io/micronaut-tracing/latest/api/io/micronaut/tracing/annotation/SpanTag.html): Used on method parameters to assign a value to a span; defaults to the parameter name, but you can assign a unique name instead. To use the `@SpanTag` on a method argument, the method must be annotated with either `@NewSpan` or `@ContinueSpan`.
+
+## Task 2: Review the Application Dependencies
+
+Your build configuration files contain the `io.micronaut.tracing` dependency which means all HTTP server methods (those annotated with `@Get`, `@Post`, and so on) create spans automatically.
+
+_lib/pom.xml_
+
+
+ io.micronaut.tracing
+ micronaut-tracing-opentelemetry
+ compile
+
+
+
+ io.micronaut.tracing
+ micronaut-tracing-opentelemetry-http
+ compile
+
+
+Micronaut provides a Zipkin exporter that uses Micronaut’s HTTP client instead of OKHttp client. This reduces the dependency graph and makes your native executable smaller.
+
+_oci/pom.xml_
+
+
+ io.micronaut.tracing
+ micronaut-tracing-opentelemetry-zipkin-exporter
+ compile
+
+
+## Task 3: Review the Inventory Service
+
+The `InventoryService` class uses a WarehouseClient bean to interact with an external Warehouse service to fetch the product counts and place orders. This class demonstrates how to create and use spans using `io.micronaut.tracing.annotation` and `OpenTelemetry`.
+
+_lib/src/main/java/com/example/InventoryService.java_
+
+``` java
+InventoryService(Tracer tracer, WarehouseClient warehouse) { // <1>
+ this.tracer = tracer;
+ this.warehouse = warehouse;
+
+ inventory.put("laptop", 4);
+ inventory.put("desktop", 2);
+ inventory.put("monitor", 11);
+}
+```
+
+1. To do tracing you’ll need to acquire an `OpenTelemetry Tracer`. Inject an `OpenTelemetry Tracer` bean using Micronaut Constructor Injection.
+
+``` java
+@NewSpan("stock-counts") // <2>
+public Map getStockCounts(@SpanTag("inventory.item") String item) { // <3>
+ Map counts = new HashMap<>();
+ if (inventory.containsKey(item)) {
+ int count = inventory.get(item);
+ counts.put("store", count);
+
+ if (count < 10) {
+ counts.put("warehouse", inWarehouse(storeName, item));
+ }
+ }
+
+ return counts;
+}
+```
+
+2. Create a new `io.micronaut.tracing.annotation` span called “stock-counts”.
+
+3. Add a `io.micronaut.tracing.annotation` tag called “inventory.item” that will contain the value contained in the parameter `item`. Span tags and attributes are key-value pairs used to provide additional context on a span about the specific operation it tracks, such as results or operation properties.
+
+``` java
+private int inWarehouse(String store, String item) {
+ Span.current().setAttribute("inventory.store-name", store); // <4>
+
+ return warehouse.getItemCount(store, getUPC(item));
+}
+```
+
+4. Alternate way of adding a key called "inventory.store-name". Get the current OpenTelemetry span and set the value of its attribute named “inventory.store-name” to the `store` parameter.
+
+``` java
+private void orderFromWarehouse(String item, int count) {
+ Span span = tracer.spanBuilder("warehouse-order") // <5>
+ .setAttribute("item", item)
+ .setAttribute("count", count)
+ .startSpan();
+
+ warehouse.order(Map.of(
+ "store", storeName,
+ "product", item,
+ "amount", count,
+ "upc", getUPC(item)));
+
+ span.end(); // <6>
+}
+```
+
+5. Alternate way of creating a new span called "warehouse-order". Create an OpenTelemetry span named “warehouse-order”, set its attributes and start the span.
+
+6. End the span started in 5.
+
+## Task 4: Review the Store Controller
+
+The `StoreController` class also demonstrates the use of Micronaut Tracing annotations (`io.micronaut.tracing.annotation`).
+
+_lib/src/main/java/com/example/StoreController.java_
+
+``` java
+@Post("/order")
+@Status(CREATED)
+@NewSpan("store.order") // <1>
+void order(@SpanTag("order.item") String item, @SpanTag int count) { // <2>
+ inventory.order(item, count);
+}
+```
+
+1. Create a new span called "store.order".
+
+2. Add tags for the method parameters. Name the first parameter “order.item”, and use the default name for the second parameter.
+
+``` java
+@Get("/inventory") // <3>
+List