Hello World SME Invoker Service 86/12586/4
authorambrishest <ambrish.singh@est.tech>
Fri, 1 Mar 2024 13:05:16 +0000 (13:05 +0000)
committerambrishest <ambrish.singh@est.tech>
Thu, 7 Mar 2024 12:05:44 +0000 (12:05 +0000)
Issue-ID: NONRTRIC-965
Change-Id: Icc998cc3d456ca894eb86b44779c7798c2df1fd4
Signed-off-by: ambrishest <ambrish.singh@est.tech>
35 files changed:
sample-services/hello-world-sme-invoker/.gitignore [moved from test/servicestub/.gitignore with 100% similarity]
sample-services/hello-world-sme-invoker/Dockerfile [new file with mode: 0644]
sample-services/hello-world-sme-invoker/README.md [new file with mode: 0644]
sample-services/hello-world-sme-invoker/build.sh [new file with mode: 0644]
sample-services/hello-world-sme-invoker/container-tag.yaml [new file with mode: 0644]
sample-services/hello-world-sme-invoker/docker-compose.yml [new file with mode: 0644]
sample-services/hello-world-sme-invoker/hello-world-sme-invoker-build-start.sh [new file with mode: 0644]
sample-services/hello-world-sme-invoker/hello-world-sme-invoker/.helmignore [moved from test/servicestub/hello-world-chart/.helmignore with 100% similarity]
sample-services/hello-world-sme-invoker/hello-world-sme-invoker/Chart.yaml [new file with mode: 0644]
sample-services/hello-world-sme-invoker/hello-world-sme-invoker/templates/deployment.yaml [new file with mode: 0644]
sample-services/hello-world-sme-invoker/hello-world-sme-invoker/templates/service.yaml [moved from test/servicestub/hello-world-chart/templates/tests/test-connection.yaml with 65% similarity]
sample-services/hello-world-sme-invoker/hello-world-sme-invoker/values.yaml [new file with mode: 0644]
sample-services/hello-world-sme-invoker/pom.xml [new file with mode: 0644]
sample-services/hello-world-sme-invoker/src/main/java/org/oransc/nonrtric/sample/HelloWorldSmeInvokerApplication.java [new file with mode: 0644]
sample-services/hello-world-sme-invoker/src/main/java/org/oransc/nonrtric/sample/exception/CapifAccessException.java [new file with mode: 0644]
sample-services/hello-world-sme-invoker/src/main/java/org/oransc/nonrtric/sample/exception/GlobalExceptionHandler.java [new file with mode: 0644]
sample-services/hello-world-sme-invoker/src/main/java/org/oransc/nonrtric/sample/rest/HelloWorldSmeInvokerController.java [new file with mode: 0644]
sample-services/hello-world-sme-invoker/src/main/java/org/oransc/nonrtric/sample/rest/response/ApiResponse.java [new file with mode: 0644]
sample-services/hello-world/.gitignore [new file with mode: 0644]
sample-services/hello-world/Dockerfile [moved from test/servicestub/Dockerfile with 100% similarity]
sample-services/hello-world/README.md [moved from test/servicestub/README.md with 59% similarity]
sample-services/hello-world/build.sh [moved from test/servicestub/build.sh with 98% similarity]
sample-services/hello-world/container-tag.yaml [moved from test/servicestub/container-tag.yaml with 100% similarity]
sample-services/hello-world/docker-compose.yml [moved from test/servicestub/docker-compose.yml with 93% similarity]
sample-services/hello-world/hello-world-build-start.sh [moved from test/servicestub/service-stub-build-start.sh with 94% similarity]
sample-services/hello-world/hello-world-chart/.helmignore [new file with mode: 0644]
sample-services/hello-world/hello-world-chart/Chart.yaml [moved from test/servicestub/hello-world-chart/Chart.yaml with 100% similarity]
sample-services/hello-world/hello-world-chart/templates/deployment.yaml [moved from test/servicestub/hello-world-chart/templates/deployment.yaml with 100% similarity]
sample-services/hello-world/hello-world-chart/templates/service.yaml [moved from test/servicestub/hello-world-chart/templates/service.yaml with 98% similarity]
sample-services/hello-world/hello-world-chart/values.yaml [moved from test/servicestub/hello-world-chart/values.yaml with 91% similarity]
sample-services/hello-world/pom.xml [moved from test/servicestub/pom.xml with 95% similarity]
sample-services/hello-world/src/main/java/org/oransc/nonrtric/sample/HelloWorldApplication.java [moved from test/servicestub/src/main/java/org/oransc/nonrtric/sample/ServiceStubApplication.java with 88% similarity]
sample-services/hello-world/src/main/java/org/oransc/nonrtric/sample/rest/HelloWorldController.java [moved from test/servicestub/src/main/java/org/oransc/nonrtric/sample/rest/HelloWorldController.java with 100% similarity]
sample-services/hello-world/src/test/java/org/oransc/nonrtric/sample/rest/HelloWorldControllerTest.java [moved from test/servicestub/src/test/java/org/oransc/nonrtric/sample/rest/HelloWorldControllerTest.java with 100% similarity]
test/servicestub/hello-world-chart/templates/_helpers.tpl [deleted file]

diff --git a/sample-services/hello-world-sme-invoker/Dockerfile b/sample-services/hello-world-sme-invoker/Dockerfile
new file mode 100644 (file)
index 0000000..4885a48
--- /dev/null
@@ -0,0 +1,47 @@
+#==================================================================================
+#   Copyright (C) 2024: OpenInfra Foundation Europe
+#
+#   Licensed under the Apache License, Version 2.0 (the "License");
+#   you may not use this file except in compliance with the License.
+#   You may obtain a copy of the License at
+#
+#       http://www.apache.org/licenses/LICENSE-2.0
+#
+#   Unless required by applicable law or agreed to in writing, software
+#   distributed under the License is distributed on an "AS IS" BASIS,
+#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#   See the License for the specific language governing permissions and
+#   limitations under the License.
+#
+#   This source code is part of the near-RT RIC (RAN Intelligent Controller)
+#   platform project (RICP).
+#==================================================================================
+
+
+# Use Maven image with OpenJDK 17 for the build stage
+FROM maven:3.8.5-openjdk-17 AS maven_build
+
+# Copy Maven project files
+COPY pom.xml /tmp/
+COPY src /tmp/src/
+
+# Set working directory
+WORKDIR /tmp/
+
+# Build the Maven project
+RUN mvn package
+
+# Use a separate image with OpenJDK 17 for the runtime stage
+FROM openjdk:17-jdk-slim
+
+# Expose port 8080
+EXPOSE 8080
+
+# Set the working directory
+WORKDIR /app
+
+# Copy the JAR file from the maven_build stage to the runtime stage
+COPY --from=maven_build /tmp/target/hello-world-sme-invoker-0.1.0.jar /app/hello-world-sme-invoker-0.1.0.jar
+
+# Command to run the application
+CMD ["java", "-jar", "hello-world-sme-invoker-0.1.0.jar"]
diff --git a/sample-services/hello-world-sme-invoker/README.md b/sample-services/hello-world-sme-invoker/README.md
new file mode 100644 (file)
index 0000000..95822a7
--- /dev/null
@@ -0,0 +1,37 @@
+# Hello World Sme Invoker Service\r
+\r
+This repository contains a Spring Boot application serving few Hello World SME endpoints. \r
+The application can be built and run using the provided script - ``hello-world-sme-invoker-build-start.sh``.\r
+\r
+## Prerequisites\r
+\r
+- Docker installed on your machine.\r
+\r
+## Building and Running the Application\r
+Run the script:\r
+\r
+```bash\r
+  ./hello-world-sme-invoker-build-start.sh\r
+```\r
+\r
+The script will build a Docker image and run a container with the Hello World SME service. After the container starts,\r
+wait for a few seconds to ensure the Spring Boot application is fully initialized. Next, it will make an HTTP request to the\r
+Hello World SME endpoint and display the response:\r
+\r
+```bash\r
+  response=$(curl -s http://localhost:8080/helloworld/v1/sme)\r
+  echo "Response from the Hello World SME endpoint:"\r
+  echo "$response"\r
+```\r
+\r
+To stop and remove the Docker container:\r
+\r
+```bash\r
+  docker stop hello-world-sme-invoker\r
+  docker rm hello-world-sme-invoker\r
+```\r
+\r
+## Additional Information\r
+\r
+- The Hello World SME endpoint is available at http://localhost:8080/helloworld/v1/sme.\r
+\r
diff --git a/sample-services/hello-world-sme-invoker/build.sh b/sample-services/hello-world-sme-invoker/build.sh
new file mode 100644 (file)
index 0000000..7dc1786
--- /dev/null
@@ -0,0 +1,96 @@
+#!/bin/bash
+
+#  ============LICENSE_START===============================================
+#  Copyright (C) 2024: OpenInfra Foundation Europe.
+#  ========================================================================
+#  Licensed under the Apache License, Version 2.0 (the "License");
+#  you may not use this file except in compliance with the License.
+#  You may obtain a copy of the License at
+#
+#       http://www.apache.org/licenses/LICENSE-2.0
+#
+#  Unless required by applicable law or agreed to in writing, software
+#  distributed under the License is distributed on an "AS IS" BASIS,
+#  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#  See the License for the specific language governing permissions and
+#  limitations under the License.
+#  ============LICENSE_END=================================================
+#
+
+# Build image from Dockerfile with/without custom image tag
+# Optionally push to external image repo
+
+print_usage() {
+    echo "Usage: build.sh no-push|<docker-hub-repo-name> [<image-tag>]"
+    exit 1
+}
+
+if [ $# -ne 1 ] && [ $# -ne 2 ]; then
+    print_usage
+fi
+
+IMAGE_NAME="nonrtric-sample-helloworld-sme-invoker"
+IMAGE_TAG="latest"
+REPO=""
+if [ $1 == "no-push" ]; then
+    echo "Only local image build"
+else
+    REPO=$1
+    echo "Attempt to push built image to: "$REPO
+fi
+
+shift
+while [ $# -ne 0 ]; do
+    if [ $1 == "--tag" ]; then
+        shift
+        if [ -z "$1" ]; then
+            print_usage
+        fi
+        IMAGE_TAG=$1
+        echo "Setting image tag to: "$IMAGE_TAG
+        shift
+    else
+        echo "Unknown parameter: $1"
+        print_usage
+    fi
+done
+
+IMAGE=$IMAGE_NAME:$IMAGE_TAG
+
+export DOCKER_DEFAULT_PLATFORM=linux/amd64
+CURRENT_PLATFORM=$(docker system info --format '{{.OSType}}/{{.Architecture}}')
+if [ $CURRENT_PLATFORM != $DOCKER_DEFAULT_PLATFORM ]; then
+    echo "Image may not work on the current platform: $CURRENT_PLATFORM, only platform $DOCKER_DEFAULT_PLATFORM supported"
+fi
+
+echo "Building image $IMAGE"
+docker build -t $IMAGE_NAME:$IMAGE_TAG .
+if [ $? -ne 0 ]; then
+    echo "BUILD FAILED"
+    exit 1
+fi
+echo "BUILD OK"
+
+if [ "$REPO" != "" ]; then
+    echo "Tagging image"
+    NEW_IMAGE=$REPO/$IMAGE_NAME:$IMAGE_TAG
+    docker tag $IMAGE $NEW_IMAGE
+    if [ $? -ne 0 ]; then
+        echo "RE-TAGGING FAILED"
+        exit 1
+    fi
+    echo "RE-TAG OK"
+
+    echo "Pushing image $NEW_IMAGE"
+    docker push $NEW_IMAGE
+    if [ $? -ne 0 ]; then
+        echo "PUSHED FAILED"
+        echo " Perhaps not logged into docker-hub repo $REPO?"
+        exit 1
+    fi
+    IMAGE=$NEW_IMAGE
+    echo "PUSH OK"
+fi
+
+echo "IMAGE OK: $IMAGE"
+echo "DONE"
diff --git a/sample-services/hello-world-sme-invoker/container-tag.yaml b/sample-services/hello-world-sme-invoker/container-tag.yaml
new file mode 100644 (file)
index 0000000..77dc89e
--- /dev/null
@@ -0,0 +1,25 @@
+# -
+#   ========================LICENSE_START=================================
+#   O-RAN-SC
+#   %%
+#   Copyright (C) 2024: OpenInfra Foundation Europe.
+#   %%
+#   Licensed under the Apache License, Version 2.0 (the "License");
+#   you may not use this file except in compliance with the License.
+#   You may obtain a copy of the License at
+#
+#        http://www.apache.org/licenses/LICENSE-2.0
+#
+#   Unless required by applicable law or agreed to in writing, software
+#   distributed under the License is distributed on an "AS IS" BASIS,
+#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#   See the License for the specific language governing permissions and
+#   limitations under the License.
+#   ========================LICENSE_END===================================
+#
+
+# The Jenkins job requires a tag to build the Docker image.
+# By default this file is in the docker build directory,
+# but the location can configured in the JJB template.
+---
+tag: 0.1.0
diff --git a/sample-services/hello-world-sme-invoker/docker-compose.yml b/sample-services/hello-world-sme-invoker/docker-compose.yml
new file mode 100644 (file)
index 0000000..eaaef18
--- /dev/null
@@ -0,0 +1,29 @@
+# -
+#   ========================LICENSE_START=================================
+#   O-RAN-SC
+#   %%
+#   Copyright (C) 2024: OpenInfra Foundation Europe
+#   %%
+#   Licensed under the Apache License, Version 2.0 (the "License");
+#   you may not use this file except in compliance with the License.
+#   You may obtain a copy of the License at
+#
+#        http://www.apache.org/licenses/LICENSE-2.0
+#
+#   Unless required by applicable law or agreed to in writing, software
+#   distributed under the License is distributed on an "AS IS" BASIS,
+#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#   See the License for the specific language governing permissions and
+#   limitations under the License.
+#   ========================LICENSE_END===================================
+#
+
+version: "3.0"
+
+services:
+  hello-world-sme-invoker:
+    build:
+      context: ../../sample-services/hello-world-sme-invoker
+      dockerfile: Dockerfile
+    ports:
+      - 8080:8080
\ No newline at end of file
diff --git a/sample-services/hello-world-sme-invoker/hello-world-sme-invoker-build-start.sh b/sample-services/hello-world-sme-invoker/hello-world-sme-invoker-build-start.sh
new file mode 100644 (file)
index 0000000..e4a2ede
--- /dev/null
@@ -0,0 +1,35 @@
+#!/bin/bash
+
+# -
+#   ========================LICENSE_START=================================
+#   O-RAN-SC
+#   %%
+#   Copyright (C) 2024: OpenInfra Foundation Europe.
+#   %%
+#   Licensed under the Apache License, Version 2.0 (the "License");
+#   you may not use this file except in compliance with the License.
+#   You may obtain a copy of the License at
+#
+#        http://www.apache.org/licenses/LICENSE-2.0
+#
+#   Unless required by applicable law or agreed to in writing, software
+#   distributed under the License is distributed on an "AS IS" BASIS,
+#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#   See the License for the specific language governing permissions and
+#   limitations under the License.
+#   ========================LICENSE_END===================================
+#
+
+NAME="hello-world-sme-invoker"
+IMAGE_NAME="nonrtric-sample-helloworld-sme-invoker"
+
+docker build -t $IMAGE_NAME:latest .
+
+docker run --rm -d -p 8080:8080 --name $NAME $IMAGE_NAME
+
+sleep 10
+
+echo "Make an HTTP request to the Hello World Sme Invoker endpoint and display the response"
+response=$(curl -s http://localhost:8080/helloworld/v1/sme)
+echo "Response from the /helloworld/v1/sme endpoint: "
+echo "$response"
diff --git a/sample-services/hello-world-sme-invoker/hello-world-sme-invoker/Chart.yaml b/sample-services/hello-world-sme-invoker/hello-world-sme-invoker/Chart.yaml
new file mode 100644 (file)
index 0000000..3eee3d6
--- /dev/null
@@ -0,0 +1,44 @@
+# -\r
+#   ========================LICENSE_START=================================\r
+#   O-RAN-SC\r
+#   %%\r
+#   Copyright (C) 2024: OpenInfra Foundation Europe\r
+#   %%\r
+#   Licensed under the Apache License, Version 2.0 (the "License");\r
+#   you may not use this file except in compliance with the License.\r
+#   You may obtain a copy of the License at\r
+#\r
+#        http://www.apache.org/licenses/LICENSE-2.0\r
+#\r
+#   Unless required by applicable law or agreed to in writing, software\r
+#   distributed under the License is distributed on an "AS IS" BASIS,\r
+#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+#   See the License for the specific language governing permissions and\r
+#   limitations under the License.\r
+#   ========================LICENSE_END===================================\r
+#\r
+\r
+apiVersion: v2\r
+name: hello-world-sme-invoker\r
+description: A Helm chart for NONRTRIC Hello World SME Invoker\r
+\r
+# A chart can be either an 'application' or a 'library' chart.\r
+#\r
+# Application charts are a collection of templates that can be packaged into versioned archives\r
+# to be deployed.\r
+#\r
+# Library charts provide useful utilities or functions for the chart developer. They're included as\r
+# a dependency of application charts to inject those utilities and functions into the rendering\r
+# pipeline. Library charts do not define any templates and therefore cannot be deployed.\r
+type: application\r
+\r
+# This is the chart version. This version number should be incremented each time you make changes\r
+# to the chart and its templates, including the app version.\r
+# Versions are expected to follow Semantic Versioning (https://semver.org/)\r
+version: 0.1.0\r
+\r
+# This is the version number of the application being deployed. This version number should be\r
+# incremented each time you make changes to the application. Versions are not expected to\r
+# follow Semantic Versioning. They should reflect the version the application is using.\r
+# It is recommended to use it with quotes.\r
+appVersion: "0.1.0"\r
diff --git a/sample-services/hello-world-sme-invoker/hello-world-sme-invoker/templates/deployment.yaml b/sample-services/hello-world-sme-invoker/hello-world-sme-invoker/templates/deployment.yaml
new file mode 100644 (file)
index 0000000..9a31fba
--- /dev/null
@@ -0,0 +1,48 @@
+# -
+#   ========================LICENSE_START=================================
+#   O-RAN-SC
+#   %%
+#   Copyright (C) 2024: OpenInfra Foundation Europe
+#   %%
+#   Licensed under the Apache License, Version 2.0 (the "License");
+#   you may not use this file except in compliance with the License.
+#   You may obtain a copy of the License at
+#
+#        http://www.apache.org/licenses/LICENSE-2.0
+#
+#   Unless required by applicable law or agreed to in writing, software
+#   distributed under the License is distributed on an "AS IS" BASIS,
+#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#   See the License for the specific language governing permissions and
+#   limitations under the License.
+#   ========================LICENSE_END===================================
+#
+
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+  name: {{ include "hello-world-sme-invoker.fullname" . }}
+  labels:
+    {{- include "hello-world-sme-invoker.labels" . | nindent 4 }}
+spec:
+  replicas: {{ .Values.replicaCount }}
+  selector:
+    matchLabels:
+      {{- include "hello-world-sme-invoker.selectorLabels" . | nindent 8 }}
+  template:
+    metadata:
+      labels:
+        {{- include "hello-world-sme-invoker.selectorLabels" . | nindent 12 }}
+    spec:
+      containers:
+        - name: {{ .Chart.Name }}
+          image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
+          env:
+            - name: RAPP_INSTANCE_ID
+              value: "{{ .Values.environment.RAPP_INSTANCE_ID }}"
+            - name: SME_DISCOVERY_ENDPOINT
+              value: "{{ .Values.environment.SME_DISCOVERY_ENDPOINT }}"
+          ports:
+            - name: http
+              containerPort: {{ .Values.service.port }}
+
@@ -2,7 +2,7 @@
 #   ========================LICENSE_START=================================
 #   O-RAN-SC
 #   %%
-#   Copyright (C) 2023: OpenInfra Foundation Europe
+#   Copyright (C) 2024: OpenInfra Foundation Europe
 #   %%
 #   Licensed under the Apache License, Version 2.0 (the "License");
 #   you may not use this file except in compliance with the License.
 #
 
 apiVersion: v1
-kind: Pod
+kind: Service
 metadata:
-  name: "{{ include "hello-world-chart.fullname" . }}-test-connection"
+  name: {{ include "hello-world-sme-invoker.fullname" . }}
   labels:
-    {{- include "hello-world-chart.labels" . | nindent 4 }}
-  annotations:
-    "helm.sh/hook": test
+    {{- include "hello-world-sme-invoker.labels" . | nindent 4 }}
 spec:
-  containers:
-    - name: wget
-      image: busybox
-      command: ['wget']
-      args: ['{{ include "hello-world-chart.fullname" . }}:{{ .Values.service.port }}']
-  restartPolicy: Never
+  type: {{ .Values.service.type }}
+  ports:
+    - port: {{ .Values.service.port }}
+      targetPort: http
+      protocol: TCP
+      name: http
+  selector:
+    {{- include "hello-world-sme-invoker.selectorLabels" . | nindent 4 }}
+
diff --git a/sample-services/hello-world-sme-invoker/hello-world-sme-invoker/values.yaml b/sample-services/hello-world-sme-invoker/hello-world-sme-invoker/values.yaml
new file mode 100644 (file)
index 0000000..39aeeb5
--- /dev/null
@@ -0,0 +1,34 @@
+# -
+#   ========================LICENSE_START=================================
+#   O-RAN-SC
+#   %%
+#   Copyright (C) 2024: OpenInfra Foundation Europe
+#   %%
+#   Licensed under the Apache License, Version 2.0 (the "License");
+#   you may not use this file except in compliance with the License.
+#   You may obtain a copy of the License at
+#
+#        http://www.apache.org/licenses/LICENSE-2.0
+#
+#   Unless required by applicable law or agreed to in writing, software
+#   distributed under the License is distributed on an "AS IS" BASIS,
+#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#   See the License for the specific language governing permissions and
+#   limitations under the License.
+#   ========================LICENSE_END===================================
+#
+
+image:
+  repository: nexus3.o-ran-sc.org:10003/nonrtric-sample-helloworld-sme-invoker
+  tag: latest
+
+service:
+  name: hello-world-sme-invoker
+  type: ClusterIP
+  port: 8080
+
+environment:
+  APP_ID: Invoker_Rapp_Id
+  SME_DISCOVERY_ENDPOINT: capifcore.nonrtric.svc.cluster.local:8090/service-apis/v1/allServiceAPIs
+
+
diff --git a/sample-services/hello-world-sme-invoker/pom.xml b/sample-services/hello-world-sme-invoker/pom.xml
new file mode 100644 (file)
index 0000000..07c46c2
--- /dev/null
@@ -0,0 +1,72 @@
+<?xml version="1.0" encoding="UTF-8"?>\r
+\r
+<!--\r
+* ========================LICENSE_START=================================\r
+* O-RAN-SC\r
+* %%\r
+* Copyright (C) 2024 OpenInfra Foundation Europe.\r
+* %%\r
+* Licensed under the Apache License, Version 2.0 (the "License");\r
+* you may not use this file except in compliance with the License.\r
+* You may obtain a copy of the License at\r
+*\r
+* http://www.apache.org/licenses/LICENSE-2.0\r
+*\r
+* Unless required by applicable law or agreed to in writing, software\r
+* distributed under the License is distributed on an "AS IS" BASIS,\r
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+* See the License for the specific language governing permissions and\r
+* limitations under the License.\r
+* ========================LICENSE_END===================================\r
+-->\r
+\r
+<project xmlns="http://maven.apache.org/POM/4.0.0"\r
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"\r
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">\r
+    <modelVersion>4.0.0</modelVersion>\r
+\r
+    <parent>\r
+        <groupId>org.springframework.boot</groupId>\r
+        <artifactId>spring-boot-starter-parent</artifactId>\r
+        <version>3.2.3</version>\r
+    </parent>\r
+\r
+    <groupId>org.o-ran-sc.nonrtric.plt</groupId>\r
+    <artifactId>hello-world-sme-invoker</artifactId>\r
+    <version>0.1.0</version>\r
+\r
+    <properties>\r
+        <maven.compiler.source>17</maven.compiler.source>\r
+        <maven.compiler.target>17</maven.compiler.target>\r
+        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>\r
+    </properties>\r
+\r
+    <dependencies>\r
+        <dependency>\r
+            <groupId>org.springframework.boot</groupId>\r
+            <artifactId>spring-boot-starter-web</artifactId>\r
+        </dependency>\r
+\r
+        <dependency>\r
+            <groupId>org.springframework.boot</groupId>\r
+            <artifactId>spring-boot-starter-test</artifactId>\r
+            <scope>test</scope>\r
+        </dependency>\r
+\r
+        <dependency>\r
+            <groupId>org.mockito</groupId>\r
+            <artifactId>mockito-core</artifactId>\r
+            <scope>test</scope>\r
+        </dependency>\r
+    </dependencies>\r
+\r
+    <build>\r
+        <plugins>\r
+            <plugin>\r
+                <groupId>org.springframework.boot</groupId>\r
+                <artifactId>spring-boot-maven-plugin</artifactId>\r
+            </plugin>\r
+        </plugins>\r
+    </build>\r
+\r
+</project>
\ No newline at end of file
diff --git a/sample-services/hello-world-sme-invoker/src/main/java/org/oransc/nonrtric/sample/HelloWorldSmeInvokerApplication.java b/sample-services/hello-world-sme-invoker/src/main/java/org/oransc/nonrtric/sample/HelloWorldSmeInvokerApplication.java
new file mode 100644 (file)
index 0000000..0a384f4
--- /dev/null
@@ -0,0 +1,39 @@
+/*-\r
+ * ========================LICENSE_START=================================\r
+ * O-RAN-SC\r
+ * %%\r
+ * Copyright (C) 2024 OpenInfra Foundation Europe.\r
+ * %%\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ *      http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ * ========================LICENSE_END===================================\r
+ */\r
+\r
+package org.oransc.nonrtric.sample;\r
+\r
+import org.springframework.boot.SpringApplication;\r
+import org.springframework.boot.autoconfigure.SpringBootApplication;\r
+import org.springframework.boot.web.client.RestTemplateBuilder;\r
+import org.springframework.context.annotation.Bean;\r
+import org.springframework.web.client.RestTemplate;\r
+\r
+@SpringBootApplication(scanBasePackages = "org.oransc.nonrtric.sample")\r
+public class HelloWorldSmeInvokerApplication {\r
+    public static void main(String[] args) {\r
+        SpringApplication.run(HelloWorldSmeInvokerApplication.class, args);\r
+    }\r
+\r
+    @Bean\r
+    public RestTemplate restTemplate(RestTemplateBuilder builder) {\r
+        return builder.build();\r
+    }\r
+}\r
diff --git a/sample-services/hello-world-sme-invoker/src/main/java/org/oransc/nonrtric/sample/exception/CapifAccessException.java b/sample-services/hello-world-sme-invoker/src/main/java/org/oransc/nonrtric/sample/exception/CapifAccessException.java
new file mode 100644 (file)
index 0000000..b4c2940
--- /dev/null
@@ -0,0 +1,28 @@
+/*-\r
+ * ========================LICENSE_START=================================\r
+ * O-RAN-SC\r
+ * %%\r
+ * Copyright (C) 2024 OpenInfra Foundation Europe.\r
+ * %%\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ *      http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ * ========================LICENSE_END===================================\r
+ */\r
+\r
+package org.oransc.nonrtric.sample.exception;\r
+\r
+public class CapifAccessException extends RuntimeException {\r
+    public CapifAccessException(String message) {\r
+        super(message);\r
+    }\r
+}\r
+\r
diff --git a/sample-services/hello-world-sme-invoker/src/main/java/org/oransc/nonrtric/sample/exception/GlobalExceptionHandler.java b/sample-services/hello-world-sme-invoker/src/main/java/org/oransc/nonrtric/sample/exception/GlobalExceptionHandler.java
new file mode 100644 (file)
index 0000000..414adf0
--- /dev/null
@@ -0,0 +1,39 @@
+/*-\r
+ * ========================LICENSE_START=================================\r
+ * O-RAN-SC\r
+ * %%\r
+ * Copyright (C) 2024 OpenInfra Foundation Europe.\r
+ * %%\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ *      http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ * ========================LICENSE_END===================================\r
+ */\r
+\r
+package org.oransc.nonrtric.sample.exception;\r
+\r
+import org.springframework.http.HttpStatus;\r
+import org.springframework.http.MediaType;\r
+import org.springframework.http.ResponseEntity;\r
+import org.springframework.web.bind.annotation.ControllerAdvice;\r
+import org.springframework.web.bind.annotation.ExceptionHandler;\r
+\r
+@ControllerAdvice\r
+public class GlobalExceptionHandler {\r
+\r
+    @ExceptionHandler(CapifAccessException.class)\r
+    public ResponseEntity<String> handleCapifAccessException(CapifAccessException ex) {\r
+        return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)\r
+            .contentType(MediaType.TEXT_PLAIN)\r
+            .body(ex.getMessage());\r
+    }\r
+}\r
+\r
diff --git a/sample-services/hello-world-sme-invoker/src/main/java/org/oransc/nonrtric/sample/rest/HelloWorldSmeInvokerController.java b/sample-services/hello-world-sme-invoker/src/main/java/org/oransc/nonrtric/sample/rest/HelloWorldSmeInvokerController.java
new file mode 100644 (file)
index 0000000..5782092
--- /dev/null
@@ -0,0 +1,203 @@
+/*-\r
+ * ========================LICENSE_START=================================\r
+ * O-RAN-SC\r
+ * %%\r
+ * Copyright (C) 2024 OpenInfra Foundation Europe.\r
+ * %%\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ *      http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ * ========================LICENSE_END===================================\r
+ */\r
+\r
+package org.oransc.nonrtric.sample.rest;\r
+\r
+import jakarta.servlet.http.HttpServletRequest;\r
+import java.util.ArrayList;\r
+import java.util.List;\r
+import org.oransc.nonrtric.sample.exception.CapifAccessException;\r
+import org.oransc.nonrtric.sample.rest.response.ApiResponse;\r
+import org.slf4j.Logger;\r
+import org.slf4j.LoggerFactory;\r
+import org.springframework.http.ResponseEntity;\r
+import org.springframework.web.bind.annotation.RequestMapping;\r
+import org.springframework.web.bind.annotation.RestController;\r
+import org.springframework.web.client.RestTemplate;\r
+\r
+@RestController\r
+public class HelloWorldSmeInvokerController {\r
+\r
+    private final RestTemplate restTemplate;\r
+    private static final Logger logger = LoggerFactory.getLogger(HelloWorldSmeInvokerController.class);\r
+\r
+    public HelloWorldSmeInvokerController(RestTemplate restTemplate) {\r
+        this.restTemplate = restTemplate;\r
+    }\r
+\r
+    @RequestMapping("/helloworld/v1/sme")\r
+    public String helloWorld(HttpServletRequest request) {\r
+        String path = logRequestPath(request);\r
+        return "Hello from " + path;\r
+    }\r
+\r
+    @RequestMapping("/helloworld/sme/invoker/v1/apiset")\r
+    public ResponseEntity<ApiResponse> helloWorldSmeInvoker(HttpServletRequest request) {\r
+        String path = logRequestPath(request);\r
+        String capifUrl = createCapifUrl();\r
+        try {\r
+            ApiResponse apiResponse = restTemplate.getForObject(capifUrl, ApiResponse.class);\r
+            return ResponseEntity.ok(apiResponse);\r
+        } catch (IllegalArgumentException e) {\r
+            throw new CapifAccessException("Error accessing the URL :- "+capifUrl);\r
+        } catch (Exception e) {\r
+            throw new CapifAccessException("Unexpected error");\r
+        }\r
+    }\r
+\r
+    @RequestMapping("/helloworld/sme/invoker/v1")\r
+    public ResponseEntity<String> accessHelloWorldByInvoker(HttpServletRequest request) {\r
+        String path = logRequestPath(request);\r
+        String capifUrl = createCapifUrl();\r
+        String baseUrl = "";\r
+        ApiResponse apiResponse = new ApiResponse();\r
+        try {\r
+            apiResponse = restTemplate.getForObject(capifUrl, ApiResponse.class);\r
+            baseUrl = getBaseUrl(apiResponse);\r
+        } catch (IllegalArgumentException e) {\r
+            throw new CapifAccessException("Error accessing the URL :- "+capifUrl);\r
+        } catch (Exception e) {\r
+            throw new CapifAccessException("Unexpected error");\r
+        }\r
+\r
+        String helloWorldEndpoint = "";\r
+        List<String> apiSetEndpoints = getApiSetEndpoints(apiResponse, baseUrl);\r
+        if(apiSetEndpoints != null && !apiSetEndpoints.isEmpty()){\r
+            helloWorldEndpoint = apiSetEndpoints.get(0);\r
+        }\r
+\r
+        try {\r
+            String responseHelloWorld = restTemplate.getForObject(helloWorldEndpoint, String.class);\r
+            logger.info("Response :- ", responseHelloWorld);\r
+            return ResponseEntity.ok(responseHelloWorld);\r
+        } catch (IllegalArgumentException e) {\r
+            throw new CapifAccessException("Error accessing the URL :- "+helloWorldEndpoint);\r
+        } catch (Exception e) {\r
+            throw new CapifAccessException("Unexpected error");\r
+        }\r
+    }\r
+\r
+    private String logRequestPath(HttpServletRequest request) {\r
+        String path = request.getRequestURI();\r
+        logger.info("Received request for path: {}", path);\r
+        return path;\r
+    }\r
+\r
+    private String createCapifUrl() {\r
+        String appId = System.getenv("APP_ID");\r
+        if (appId != null) {\r
+            logger.info("APP_ID: " + appId);\r
+        } else {\r
+            logger.info("APP_ID environment variable is not set. ");\r
+            appId = "Invoker_App_1";\r
+            logger.info("APP_ID default value :- " + appId);\r
+        }\r
+\r
+        String smeDiscoveryEndpoint = System.getenv("SME_DISCOVERY_ENDPOINT");\r
+        if (smeDiscoveryEndpoint != null) {\r
+            logger.info("SME_DISCOVERY_ENDPOINT: " + smeDiscoveryEndpoint);\r
+        } else {\r
+            logger.info("SME_DISCOVERY_ENDPOINT environment variable is not set.");\r
+            smeDiscoveryEndpoint = "capifcore.nonrtric.svc.cluster.local:8090/service-apis/v1/allServiceAPIs";\r
+            logger.info("SME_DISCOVERY_ENDPOINT default value :- " + smeDiscoveryEndpoint);\r
+        }\r
+\r
+        String invokerId = "api_invoker_id_Invoker_App_1";\r
+        if (appId != null) {\r
+            invokerId = "api_invoker_id_" + appId;\r
+        }\r
+        logger.info("invokerId: " + invokerId);\r
+\r
+        String capifUrl =\r
+            "http://capifcore.nonrtric.svc.cluster.local:8090/service-apis/v1/allServiceAPIs" + "?api-invoker-id=" +\r
+                invokerId;\r
+        if (smeDiscoveryEndpoint != null) {\r
+            capifUrl = smeDiscoveryEndpoint + "?api-invoker-id=" + invokerId;\r
+        }\r
+        logger.info("capifUrl: " + capifUrl);\r
+\r
+        return capifUrl;\r
+    }\r
+\r
+    private static String getBaseUrl(ApiResponse apiResponse) {\r
+        if (apiResponse != null &&\r
+            apiResponse.getServiceAPIDescriptions() != null &&\r
+            !apiResponse.getServiceAPIDescriptions().isEmpty()) {\r
+\r
+            ApiResponse.ServiceAPIDescription serviceAPIDescription = apiResponse.getServiceAPIDescriptions().get(0);\r
+\r
+            if (serviceAPIDescription.getAefProfiles() != null &&\r
+                !serviceAPIDescription.getAefProfiles().isEmpty()) {\r
+\r
+                ApiResponse.AefProfile aefProfile = serviceAPIDescription.getAefProfiles().get(0);\r
+\r
+                if (aefProfile.getInterfaceDescriptions() != null &&\r
+                    !aefProfile.getInterfaceDescriptions().isEmpty()) {\r
+                    ApiResponse.InterfaceDescription interfaceDescription = aefProfile.getInterfaceDescriptions().get(0);\r
+                    return "http://" + interfaceDescription.getIpv4Addr() + ":" + interfaceDescription.getPort();\r
+                }\r
+            }\r
+        }\r
+        return "";\r
+    }\r
+\r
+    private static List<String> getApiSetEndpoints(ApiResponse apiResponse, String baseUrl){\r
+\r
+        String helloWorldEndpoint = "";\r
+        List<String> apiSetEndpoints = new ArrayList<>(5);\r
+\r
+        if (apiResponse != null &&\r
+            apiResponse.getServiceAPIDescriptions() != null &&\r
+            !apiResponse.getServiceAPIDescriptions().isEmpty()) {\r
+\r
+            ApiResponse.ServiceAPIDescription serviceAPIDescription = apiResponse.getServiceAPIDescriptions().get(0);\r
+\r
+            if (serviceAPIDescription.getAefProfiles() != null &&\r
+                !serviceAPIDescription.getAefProfiles().isEmpty()) {\r
+\r
+                ApiResponse.AefProfile aefProfile = serviceAPIDescription.getAefProfiles().get(0);\r
+\r
+                if (aefProfile.getInterfaceDescriptions() != null &&\r
+                    !aefProfile.getInterfaceDescriptions().isEmpty()) {\r
+\r
+                    ApiResponse.InterfaceDescription interfaceDescription = aefProfile.getInterfaceDescriptions().get(0);\r
+\r
+                    if (aefProfile.getVersions() != null &&\r
+                        !aefProfile.getVersions().isEmpty()) {\r
+\r
+                        ApiResponse.ApiVersion apiVersion = aefProfile.getVersions().get(0);\r
+\r
+                        if (apiVersion.getResources() != null &&\r
+                            !apiVersion.getResources().isEmpty()) {\r
+\r
+                            for(ApiResponse.Resource resource : apiVersion.getResources()) {\r
+                                helloWorldEndpoint = baseUrl + resource.getUri();\r
+                                logger.info("Complete URL for resource " + helloWorldEndpoint);\r
+                                apiSetEndpoints.add(helloWorldEndpoint);\r
+                            }\r
+                        }\r
+                    }\r
+                }\r
+            }\r
+        }\r
+        return apiSetEndpoints;\r
+    }\r
+\r
+}\r
diff --git a/sample-services/hello-world-sme-invoker/src/main/java/org/oransc/nonrtric/sample/rest/response/ApiResponse.java b/sample-services/hello-world-sme-invoker/src/main/java/org/oransc/nonrtric/sample/rest/response/ApiResponse.java
new file mode 100644 (file)
index 0000000..f7dbde8
--- /dev/null
@@ -0,0 +1,215 @@
+/*-\r
+ * ========================LICENSE_START=================================\r
+ * O-RAN-SC\r
+ * %%\r
+ * Copyright (C) 2024 OpenInfra Foundation Europe.\r
+ * %%\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ *      http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ * ========================LICENSE_END===================================\r
+ */\r
+\r
+package org.oransc.nonrtric.sample.rest.response;\r
+\r
+import com.fasterxml.jackson.annotation.JsonProperty;\r
+import java.util.List;\r
+\r
+public class ApiResponse {\r
+\r
+    @JsonProperty("serviceAPIDescriptions")\r
+    private List<ServiceAPIDescription> serviceAPIDescriptions;\r
+\r
+    public List<ServiceAPIDescription> getServiceAPIDescriptions() {\r
+        return serviceAPIDescriptions;\r
+    }\r
+\r
+    public void setServiceAPIDescriptions(List<ServiceAPIDescription> serviceAPIDescriptions) {\r
+        this.serviceAPIDescriptions = serviceAPIDescriptions;\r
+    }\r
+\r
+    public static class ServiceAPIDescription {\r
+        @JsonProperty("apiName")\r
+        private String apiName;\r
+\r
+        @JsonProperty("apiId")\r
+        private String apiId;\r
+\r
+        @JsonProperty("description")\r
+        private String description;\r
+\r
+        @JsonProperty("aefProfiles")\r
+        private List<AefProfile> aefProfiles;\r
+\r
+        public String getApiName() {\r
+            return apiName;\r
+        }\r
+\r
+        public void setApiName(String apiName) {\r
+            this.apiName = apiName;\r
+        }\r
+\r
+        public String getApiId() {\r
+            return apiId;\r
+        }\r
+\r
+        public void setApiId(String apiId) {\r
+            this.apiId = apiId;\r
+        }\r
+\r
+        public String getDescription() {\r
+            return description;\r
+        }\r
+\r
+        public void setDescription(String description) {\r
+            this.description = description;\r
+        }\r
+\r
+        public List<AefProfile> getAefProfiles() {\r
+            return aefProfiles;\r
+        }\r
+\r
+        public void setAefProfiles(List<AefProfile> aefProfiles) {\r
+            this.aefProfiles = aefProfiles;\r
+        }\r
+    }\r
+\r
+    public static class AefProfile {\r
+        private String aefId;\r
+        private String domainName;\r
+        private List<ApiVersion> versions;\r
+        private String protocol;\r
+        private List<InterfaceDescription> interfaceDescriptions;\r
+\r
+        public String getAefId() {\r
+            return aefId;\r
+        }\r
+\r
+        public String getDomainName() {\r
+            return domainName;\r
+        }\r
+\r
+        public void setDomainName(String domainName) {\r
+            this.domainName = domainName;\r
+        }\r
+\r
+        public void setAefId(String aefId) {\r
+            this.aefId = aefId;\r
+        }\r
+\r
+        public List<ApiVersion> getVersions() {\r
+            return versions;\r
+        }\r
+\r
+        public void setVersions(List<ApiVersion> versions) {\r
+            this.versions = versions;\r
+        }\r
+\r
+        public String getProtocol() {\r
+            return protocol;\r
+        }\r
+\r
+        public void setProtocol(String protocol) {\r
+            this.protocol = protocol;\r
+        }\r
+\r
+        public List<InterfaceDescription> getInterfaceDescriptions() {\r
+            return interfaceDescriptions;\r
+        }\r
+\r
+        public void setInterfaceDescriptions(\r
+            List<InterfaceDescription> interfaceDescriptions) {\r
+            this.interfaceDescriptions = interfaceDescriptions;\r
+        }\r
+    }\r
+\r
+    public static class ApiVersion {\r
+        private String apiVersion;\r
+        private List<Resource> resources;\r
+\r
+        public String getApiVersion() {\r
+            return apiVersion;\r
+        }\r
+\r
+        public void setApiVersion(String apiVersion) {\r
+            this.apiVersion = apiVersion;\r
+        }\r
+\r
+        public List<Resource> getResources() {\r
+            return resources;\r
+        }\r
+\r
+        public void setResources(List<Resource> resources) {\r
+            this.resources = resources;\r
+        }\r
+    }\r
+\r
+    public static class Resource {\r
+        private String resourceName;\r
+        private String commType;\r
+        private String uri;\r
+        private List<String> operations;\r
+\r
+        public String getResourceName() {\r
+            return resourceName;\r
+        }\r
+\r
+        public void setResourceName(String resourceName) {\r
+            this.resourceName = resourceName;\r
+        }\r
+\r
+        public String getCommType() {\r
+            return commType;\r
+        }\r
+\r
+        public void setCommType(String commType) {\r
+            this.commType = commType;\r
+        }\r
+\r
+        public String getUri() {\r
+            return uri;\r
+        }\r
+\r
+        public void setUri(String uri) {\r
+            this.uri = uri;\r
+        }\r
+\r
+        public List<String> getOperations() {\r
+            return operations;\r
+        }\r
+\r
+        public void setOperations(List<String> operations) {\r
+            this.operations = operations;\r
+        }\r
+    }\r
+\r
+    public static class InterfaceDescription {\r
+        private String ipv4Addr;\r
+        private int port;\r
+\r
+        public String getIpv4Addr() {\r
+            return ipv4Addr;\r
+        }\r
+\r
+        public void setIpv4Addr(String ipv4Addr) {\r
+            this.ipv4Addr = ipv4Addr;\r
+        }\r
+\r
+        public int getPort() {\r
+            return port;\r
+        }\r
+\r
+        public void setPort(int port) {\r
+            this.port = port;\r
+        }\r
+    }\r
+}\r
+\r
diff --git a/sample-services/hello-world/.gitignore b/sample-services/hello-world/.gitignore
new file mode 100644 (file)
index 0000000..5ff6309
--- /dev/null
@@ -0,0 +1,38 @@
+target/
+!.mvn/wrapper/maven-wrapper.jar
+!**/src/main/**/target/
+!**/src/test/**/target/
+
+### IntelliJ IDEA ###
+.idea/modules.xml
+.idea/jarRepositories.xml
+.idea/compiler.xml
+.idea/libraries/
+*.iws
+*.iml
+*.ipr
+
+### Eclipse ###
+.apt_generated
+.classpath
+.factorypath
+.project
+.settings
+.springBeans
+.sts4-cache
+
+### NetBeans ###
+/nbproject/private/
+/nbbuild/
+/dist/
+/nbdist/
+/.nb-gradle/
+build/
+!**/src/main/**/build/
+!**/src/test/**/build/
+
+### VS Code ###
+.vscode/
+
+### Mac OS ###
+.DS_Store
\ No newline at end of file
similarity index 59%
rename from test/servicestub/README.md
rename to sample-services/hello-world/README.md
index b4aa791..1dd8abc 100644 (file)
@@ -1,7 +1,7 @@
-# Hello World Service Stub\r
+# Hello World Service\r
 \r
 This repository contains a Spring Boot application serving a Hello World endpoint. The application can be built and \r
-run using the provided script - ``service-stub-build-start.sh``.\r
+run using the provided script - ``hello-world-build-start.sh``.\r
 \r
 ## Prerequisites\r
 \r
@@ -11,7 +11,7 @@ run using the provided script - ``service-stub-build-start.sh``.
 Run the script:\r
 \r
 ```bash\r
-  ./service-stub-build-start.sh\r
+  ./hello-world-build-start.sh\r
 ```\r
 \r
 The script will build a Docker image and run a container with the Hello World service. After the container starts, \r
@@ -19,19 +19,19 @@ wait for a few seconds to ensure the Spring Boot application is fully initialize
 Hello World endpoint and display the response:\r
 \r
 ```bash\r
-  response=$(curl -s http://localhost:8080/helloworld/v1/sme)\r
-  echo "Response from the Hello World SME endpoint:"\r
+  response=$(curl -s http://localhost:8080/helloworld/v1)\r
+  echo "Response from the Hello World endpoint:"\r
   echo "$response"\r
 ```\r
 \r
 To stop and remove the Docker container:\r
 \r
 ```bash\r
-  docker stop service-stub-hello-world-test\r
-  docker rm service-stub-hello-world-test\r
+  docker stop hello-world\r
+  docker rm hello-world\r
 ```\r
 \r
 ## Additional Information\r
 \r
-- The Hello World SME endpoint is available at http://localhost:8080/helloworld/v1/sme.\r
+- The Hello World endpoint is available at http://localhost:8080/helloworld/v1.\r
 \r
similarity index 98%
rename from test/servicestub/build.sh
rename to sample-services/hello-world/build.sh
index bb0ff80..5d1ad29 100644 (file)
@@ -29,7 +29,7 @@ if [ $# -ne 1 ] && [ $# -ne 2 ]; then
     print_usage
 fi
 
-IMAGE_NAME="nonrtric-hello-world"
+IMAGE_NAME="nonrtric-sample-helloworld"
 IMAGE_TAG="latest"
 REPO=""
 if [ $1 == "no-push" ]; then
similarity index 93%
rename from test/servicestub/docker-compose.yml
rename to sample-services/hello-world/docker-compose.yml
index b137ec1..4c2ac67 100644 (file)
@@ -23,7 +23,7 @@ version: "3.0"
 services:
   hello-world:
     build: 
-      context: ./
+      context: ../../sample-services/hello-world
       dockerfile: Dockerfile
     ports:
       - 8080:8080
\ No newline at end of file
@@ -20,8 +20,8 @@
 #   ========================LICENSE_END===================================
 #
 
-NAME="service-stub-hello-world-test"
-IMAGE_NAME="nonrtric-hello-world"
+NAME="hello-world"
+IMAGE_NAME="nonrtric-sample-helloworld"
 
 docker build -t $IMAGE_NAME:latest .
 
diff --git a/sample-services/hello-world/hello-world-chart/.helmignore b/sample-services/hello-world/hello-world-chart/.helmignore
new file mode 100644 (file)
index 0000000..0e8a0eb
--- /dev/null
@@ -0,0 +1,23 @@
+# Patterns to ignore when building packages.
+# This supports shell glob matching, relative path matching, and
+# negation (prefixed with !). Only one pattern per line.
+.DS_Store
+# Common VCS dirs
+.git/
+.gitignore
+.bzr/
+.bzrignore
+.hg/
+.hgignore
+.svn/
+# Common backup files
+*.swp
+*.bak
+*.tmp
+*.orig
+*~
+# Various IDEs
+.project
+.idea/
+*.tmproj
+.vscode/
@@ -31,7 +31,6 @@ spec:
       targetPort: http
       protocol: TCP
       name: http
-      nodePort: 30951
   selector:
     {{- include "hello-world-chart.selectorLabels" . | nindent 4 }}
 
 #
 
 image:
-  repository: nonrtric-hello-world
+  repository: nexus3.o-ran-sc.org:10003/nonrtric-sample-helloworld
   tag: latest
 
 service:
   name: hello-world
-  type: NodePort
+  type: ClusterIP
   port: 8080
 
similarity index 95%
rename from test/servicestub/pom.xml
rename to sample-services/hello-world/pom.xml
index e46ae58..35848cd 100644 (file)
@@ -28,7 +28,7 @@
     <parent>\r
         <groupId>org.springframework.boot</groupId>\r
         <artifactId>spring-boot-starter-parent</artifactId>\r
-        <version>3.2.1</version>\r
+        <version>3.2.3</version>\r
     </parent>\r
 \r
     <groupId>org.o-ran-sc.nonrtric.plt</groupId>\r
@@ -24,8 +24,8 @@ import org.springframework.boot.SpringApplication;
 import org.springframework.boot.autoconfigure.SpringBootApplication;\r
 \r
 @SpringBootApplication(scanBasePackages = "org.oransc.nonrtric.sample")\r
-public class ServiceStubApplication {\r
+public class HelloWorldApplication {\r
     public static void main(String[] args) {\r
-        SpringApplication.run(ServiceStubApplication.class, args);\r
+        SpringApplication.run(HelloWorldApplication.class, args);\r
     }\r
 }\r
diff --git a/test/servicestub/hello-world-chart/templates/_helpers.tpl b/test/servicestub/hello-world-chart/templates/_helpers.tpl
deleted file mode 100644 (file)
index 5759827..0000000
+++ /dev/null
@@ -1,62 +0,0 @@
-{{/*
-Expand the name of the chart.
-*/}}
-{{- define "hello-world-chart.name" -}}
-{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }}
-{{- end }}
-
-{{/*
-Create a default fully qualified app name.
-We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
-If release name contains chart name it will be used as a full name.
-*/}}
-{{- define "hello-world-chart.fullname" -}}
-{{- if .Values.fullnameOverride }}
-{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }}
-{{- else }}
-{{- $name := default .Chart.Name .Values.nameOverride }}
-{{- if contains $name .Release.Name }}
-{{- .Release.Name | trunc 63 | trimSuffix "-" }}
-{{- else }}
-{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }}
-{{- end }}
-{{- end }}
-{{- end }}
-
-{{/*
-Create chart name and version as used by the chart label.
-*/}}
-{{- define "hello-world-chart.chart" -}}
-{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }}
-{{- end }}
-
-{{/*
-Common labels
-*/}}
-{{- define "hello-world-chart.labels" -}}
-helm.sh/chart: {{ include "hello-world-chart.chart" . }}
-{{ include "hello-world-chart.selectorLabels" . }}
-{{- if .Chart.AppVersion }}
-app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
-{{- end }}
-app.kubernetes.io/managed-by: {{ .Release.Service }}
-{{- end }}
-
-{{/*
-Selector labels
-*/}}
-{{- define "hello-world-chart.selectorLabels" -}}
-app.kubernetes.io/name: {{ include "hello-world-chart.name" . }}
-app.kubernetes.io/instance: {{ .Release.Name }}
-{{- end }}
-
-{{/*
-Create the name of the service account to use
-*/}}
-{{- define "hello-world-chart.serviceAccountName" -}}
-{{- if .Values.serviceAccount.create }}
-{{- default (include "hello-world-chart.fullname" .) .Values.serviceAccount.name }}
-{{- else }}
-{{- default "default" .Values.serviceAccount.name }}
-{{- end }}
-{{- end }}