--- /dev/null
+# 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/
--- /dev/null
+apiVersion: v2
+name: ics-consumer
+description: A Helm chart for Kubernetes
+type: application
+version: 0.1.0
+appVersion: "1.16.0"
--- /dev/null
+#
+# ========================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: {{ .Values.consumer.name }}
+spec:
+ replicas: {{ .Values.consumer.replicaCount }}
+ selector:
+ matchLabels:
+ app: {{ .Values.consumer.name }}
+ template:
+ metadata:
+ labels:
+ app: {{ .Values.consumer.name }}
+ spec:
+ containers:
+ - name: {{ .Values.consumer.name }}
+ image: "{{ .Values.consumer.image.repository }}:{{ .Values.consumer.image.tag }}"
+ ports:
+ - containerPort: {{ .Values.consumer.service.port }}
+ env:
+ - name: SPRING_KAFKA_SERVER
+ value: "{{ .Values.kafka.host }}:{{ .Values.kafka.port }}"
--- /dev/null
+#
+# ========================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: v1
+kind: Service
+metadata:
+ name: {{ .Values.consumer.name }}
+spec:
+ type: NodePort
+ ports:
+ - port: {{ .Values.consumer.service.port }}
+ targetPort: {{ .Values.consumer.service.port }}
+ nodePort: {{ .Values.consumer.service.nodePort }}
+ selector:
+ app: {{ .Values.consumer.name }}
--- /dev/null
+#
+# ========================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===================================
+#
+consumer:
+ name: kafka-consumer
+ replicaCount: 1
+ image:
+ repository: nexus3.o-ran-sc.org:10001/o-ran-sc/nonrtric-simple-icsconsumer
+ tag: 0.0.1
+ service:
+ port: 9090
+ nodePort: 30081
+
+kafka:
+ host: kafka-1-kafka-bootstrap.nonrtric
+ port: 9092
--- /dev/null
+# 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/
--- /dev/null
+apiVersion: v2
+name: ics-producer
+description: A Helm chart for Kubernetes
+type: application
+version: 0.1.0
+appVersion: "1.16.0"
--- /dev/null
+#
+# ========================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: {{ .Values.producer.name }}
+spec:
+ replicas: {{ .Values.producer.replicaCount }}
+ selector:
+ matchLabels:
+ app: {{ .Values.producer.name }}
+ template:
+ metadata:
+ labels:
+ app: {{ .Values.producer.name }}
+ spec:
+ containers:
+ - name: {{ .Values.producer.name }}
+ image: "{{ .Values.producer.image.repository }}:{{ .Values.producer.image.tag }}"
+ ports:
+ - containerPort: {{ .Values.producer.service.port }}
+ env:
+ - name: SPRING_KAFKA_SERVER
+ value: "{{ .Values.kafka.host }}:{{ .Values.kafka.port }}"
--- /dev/null
+#
+# ========================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: v1
+kind: Service
+metadata:
+ name: {{ .Values.producer.name }}
+spec:
+ type: NodePort
+ ports:
+ - port: {{ .Values.producer.service.port }}
+ targetPort: {{ .Values.producer.service.port }}
+ nodePort: {{ .Values.producer.service.nodePort }}
+ selector:
+ app: {{ .Values.producer.name }}
--- /dev/null
+#
+# ========================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===================================
+#
+producer:
+ name: kafka-producer
+ replicaCount: 1
+ image:
+ repository: nexus3.o-ran-sc.org:10001/o-ran-sc/nonrtric-simple-icsproducer
+ tag: 0.0.1
+ service:
+ port: 8080
+ nodePort: 30080
+
+kafka:
+ host: kafka-1-kafka-bootstrap.nonrtric
+ port: 9092
--- /dev/null
+REGISTRY=nexus3.o-ran-sc.org:10001/
\ No newline at end of file
--- /dev/null
+services:
+ informationcoordinator:
+ image: ${REGISTRY}o-ran-sc/nonrtric-plt-informationcoordinatorservice:1.6.0
+ container_name: informationcoordinatorservice
+ ports:
+ - "8083:8083"
+
+ kafka-producer:
+ image: ${REGISTRY}o-ran-sc/nonrtric-simple-icsproducer:latest
+ container_name: kafka-producer
+ environment:
+ - SPRING_KAFKA_SERVER=broker:9092
+ ports:
+ - "8080:8080"
+ depends_on:
+ - broker
+
+ kafka-consumer:
+ image: ${REGISTRY}o-ran-sc/nonrtric-simple-icsconsumer:latest
+ container_name: kafka-consumer
+ environment:
+ - SPRING_KAFKA_SERVER=broker:9092
+ ports:
+ - "9090:9090"
+ depends_on:
+ - broker
+
+ broker:
+ image: confluentinc/cp-kafka:7.7.0
+ hostname: broker
+ container_name: broker
+ ports:
+ - "9092:9092"
+ - "9101:9101"
+ environment:
+ KAFKA_NODE_ID: 1
+ KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: 'CONTROLLER:PLAINTEXT,PLAINTEXT:PLAINTEXT,PLAINTEXT_HOST:PLAINTEXT'
+ KAFKA_ADVERTISED_LISTENERS: 'PLAINTEXT://broker:29092,PLAINTEXT_HOST://broker:9092'
+ KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: 1
+ KAFKA_GROUP_INITIAL_REBALANCE_DELAY_MS: 0
+ KAFKA_TRANSACTION_STATE_LOG_MIN_ISR: 1
+ KAFKA_TRANSACTION_STATE_LOG_REPLICATION_FACTOR: 1
+ KAFKA_JMX_PORT: 9101
+ KAFKA_JMX_HOSTNAME: localhost
+ KAFKA_PROCESS_ROLES: 'broker,controller'
+ KAFKA_CONTROLLER_QUORUM_VOTERS: '1@broker:29093'
+ KAFKA_LISTENERS: 'PLAINTEXT://broker:29092,CONTROLLER://broker:29093,PLAINTEXT_HOST://broker:9092'
+ KAFKA_INTER_BROKER_LISTENER_NAME: 'PLAINTEXT'
+ KAFKA_CONTROLLER_LISTENER_NAMES: 'CONTROLLER'
+ KAFKA_LOG_DIRS: '/tmp/kraft-combined-logs'
+ # Replace CLUSTER_ID with a unique base64 UUID using "bin/kafka-storage.sh random-uuid"
+ # See https://docs.confluent.io/kafka/operations-tools/kafka-tools.html#kafka-storage-sh
+ CLUSTER_ID: 'MkU3OEVBNTcwNTJENDM2Qk'
+
+ # curl-client:
+ # image: curlimages/curl:latest
+ # container_name: curl-client
+ # command: ["tail", "-f", "/dev/null"]
+ # networks:
+ # - kafka
+
+ # redpanda-console:
+ # container_name: redpanda-console
+ # image: docker.redpanda.com/redpandadata/console:v2.4.5
+ # entrypoint: /bin/sh
+ # command: -c 'echo "$$CONSOLE_CONFIG_FILE" > /tmp/config.yml; /app/console'
+ # environment:
+ # CONFIG_FILEPATH: /tmp/config.yml
+ # CONSOLE_CONFIG_FILE: |
+ # kafka:
+ # brokers: ["broker:9092"]
+ # ports:
+ # - 8888:8080
+ # networks:
+ # - kafka
\ No newline at end of file
--- /dev/null
+# ========================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=================================================
+#!/bin/bash
+source ./utils/utils.sh
+
+docker compose up -d
+
+# Wait for the Kafka container to be running
+wait_for_container "broker" "Kafka Server started"
+wait_for_container "kafka-producer" "Started KafkaProducerApplication"
+wait_for_container "kafka-consumer" "Started KafkaConsumerApplication"
+
+# Once Kafka container is running, start the producers and consumers
+echo "Kafka container is up and running. Starting producer and consumer..."
+space
+
+curl -v -i -X POST -H 'Content-Type: application/json' -d '{"configuredLevel": "TRACE"}' http://localhost:8083/actuator/loggers/org.oransc.ics
+
+echo "Sending type1 to ICS"
+curl -X 'PUT' \
+ 'http://localhost:8083/data-producer/v1/info-types/type1' \
+ -H 'accept: application/json' \
+ -H 'Content-Type: application/json' \
+ -d '{
+ "info_job_data_schema": {
+ "$schema":"http://json-schema.org/draft-07/schema#",
+ "title":"STD_Type1_1.0.0",
+ "description":"Type 1",
+ "topic": "mytopic",
+ "bootStrapServers": "broker:9092"
+ }
+}'
+
+echo "Getting types from ICS"
+curl -X 'GET' 'http://localhost:8083/data-producer/v1/info-types/type1'
+space
+
+echo "Sending Producer infos to ICS"
+curl -X 'PUT' \
+ 'http://localhost:8083/data-producer/v1/info-producers/1' \
+ -H 'accept: application/json' \
+ -H 'Content-Type: application/json' \
+ -d '{
+ "info_producer_supervision_callback_url": "http://kafka-producer:8080/health-check",
+ "supported_info_types": [
+ "type1"
+ ],
+ "info_job_callback_url": "http://kafka-producer:8080/info-job"
+}'
+
+echo "Getting Producers Infos from ICS"
+curl -H 'Content-Type: application/json' 'http://localhost:8083/data-producer/v1/info-producers/1'
+space
+
+echo "Sending Consumer Subscription Job infos to ICS"
+curl -X 'PUT' \
+ 'http://localhost:8083/data-consumer/v1/info-type-subscription/1' \
+ -H 'accept: application/json' \
+ -H 'Content-Type: application/json' \
+ -d '{
+ "status_result_uri": "http://kafka-consumer:9090/info-type-status",
+ "owner": "demo"
+}'
+echo "Getting Consumer Subscription Job infos from ICS"
+curl -X 'GET' 'http://localhost:8083/data-consumer/v1/info-type-subscription/1' -H 'accept: application/json'
+space
+
+#start Consumer
+echo "Sending type1 to ICS to use the callback, This will start a CONSUMER"
+curl -X 'PUT' \
+ 'http://localhost:8083/data-producer/v1/info-types/type1' \
+ -H 'accept: application/json' \
+ -H 'Content-Type: application/json' \
+ -d '{
+ "info_job_data_schema": {
+ "$schema":"http://json-schema.org/draft-07/schema#",
+ "title":"STD_Type1_1.0.0",
+ "description":"Type 1",
+ "topic": "mytopic",
+ "bootStrapServers": "broker:9092"
+ }
+}'
+
+sleep 3
+
+#ICS starts a producer (healthcheck to status)
+echo "Sending Consumer Job infos to ICS, This will start a PRODUCER"
+curl -X 'PUT' \
+ 'http://localhost:8083/data-consumer/v1/info-jobs/1' \
+ -H 'accept: application/json' \
+ -H 'Content-Type: application/json' \
+ -d '{
+ "info_type_id": "type1",
+ "job_owner": "demo",
+ "job_definition": {
+ "deliveryInfo": {
+ "topic": "mytopic",
+ "bootStrapServers": "broker:9092",
+ "numberOfMessages": 100
+ }
+ },
+ "job_result_uri": "http://kafka-producer:8080/info-job",
+ "status_notification_uri": "http://kafka-consumer:9090/info-type-status"
+}'
+
+echo "Getting Consumer Job Infos from ICS"
+curl -H 'Content-Type: application/json' 'http://localhost:8083/data-consumer/v1/info-jobs/1'
+space
+
+for i in {1..10}; do
+ echo
+ curl -X GET "http://localhost:8080/publish/$i"
+ sleep 1
+done
+
+space
+echo "Deleting Producer Job infos to ICS"
+curl -X 'DELETE' \
+ 'http://localhost:8083/data-producer/v1/info-producers/1'
+
+echo "Deleting Consumer Job infos to ICS"
+curl -X 'DELETE' \
+ 'http://localhost:8083/data-consumer/v1/info-jobs/1'
+
+echo "Deleting type1 to ICS to use the callback and stop consuming"
+curl -X 'DELETE' \
+ 'http://localhost:8083/data-producer/v1/info-types/type1'
+
+
+echo "ICS Producer Docker logs "
+docker logs informationcoordinatorservice | grep -E 'o.o.i.c.r1producer.ProducerCallbacks|o.o.i.repository.InfoTypeSubscriptions'
+space
+echo "Demo Producer Docker logs "
+docker logs kafka-producer | grep c.d.k.controller.KafkaController
+space
+echo "Demo Consumer Docker logs "
+docker logs kafka-consumer | grep c.d.kafkaconsumer.service.KafkaConsumer
+space
+
+echo "Done."
+
+containers=("kafka-producer" "kafka-consumer")
+
+for container in "${containers[@]}"; do
+ if docker logs "$container" | grep -q ERROR; then
+ echo "Errors found in logs of $container"
+ docker logs "$container" | grep ERROR
+ echo "FAIL"
+ exit 1
+ else
+ echo "No errors found in logs of $container"
+ fi
+done
+echo "SUCCESS"
+docker compose down
+exit 0
--- /dev/null
+# ========================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=================================================
+
+#!/bin/bash
+
+checkJava() {
+ if ! command -v java >/dev/null 2>&1; then
+ echo "Java is not installed. Please install Java."
+ echo "Suggested fix for ubuntu:"
+ echo "sudo apt install default-jdk"
+ exit 1
+ else
+ echo "Java is installed."
+ fi
+}
+
+checkMaven() {
+ if mvn -v >/dev/null 2>&1; then
+ echo "Maven is installed."
+ else
+ echo "Maven is not installed. Please install Maven."
+ echo "Suggested fix for ubuntu:"
+ echo "sudo apt install maven"
+ exit 1
+ fi
+}
+
+checkDocker() {
+ if ! docker -v > /dev/null 2>&1; then
+ echo "Docker is not installed. Please install Docker."
+ echo "Suggested fix for ubuntu:"
+ echo "sudo apt-get update"
+ echo "sudo apt-get install -y apt-transport-https ca-certificates curl gnupg lsb-release"
+ echo "curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg"
+ echo "echo \"deb [arch=\$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu \$(lsb_release -cs) stable\" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null"
+ echo "sudo apt-get update"
+ echo "sudo apt-get install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin"
+ echo "sudo usermod -aG docker \$USER"
+ echo "newgrp docker"
+ exit 1
+ else
+ echo "Docker is installed."
+ fi
+}
+
+checkDockerCompose() {
+ if ! docker-compose -v > /dev/null 2>&1; then
+ echo "docker-compose is not installed. Please install docker-compose"
+ echo "Suggested fix for ubuntu:"
+ echo "sudo apt-get install docker-compose-plugin"
+ exit 1
+ else
+ echo "docker-compose is installed."
+ fi
+}
+
+# Function to wait for a Docker container to be running and log a specific string with a maximum timeout of 20 minutes
+wait_for_container() {
+ local container_name="$1"
+ local log_string="$2"
+ local timeout=1200 # Timeout set to 20 minutes (20 minutes * 60 seconds)
+
+ local start_time=$(date +%s)
+ local end_time=$((start_time + timeout))
+
+ while ! docker inspect "$container_name" &>/dev/null; do
+ echo "Waiting for container '$container_name' to be created..."
+ sleep 5
+ if [ "$(date +%s)" -ge "$end_time" ]; then
+ echo "Timeout: Container creation exceeded 20 minutes."
+ exit 1
+ fi
+ done
+
+ while [ "$(docker inspect -f '{{.State.Status}}' "$container_name")" != "running" ]; do
+ echo "Waiting for container '$container_name' to be running..."
+ sleep 5
+ if [ "$(date +%s)" -ge "$end_time" ]; then
+ echo "Timeout: Container start exceeded 20 minutes."
+ exit 1
+ fi
+ done
+
+ # Check container logs for the specified string
+ while ! docker logs "$container_name" 2>&1 | grep "$log_string"; do
+ echo "Waiting for '$log_string' in container logs of '$container_name'..."
+ sleep 5
+ if [ "$(date +%s)" -ge "$end_time" ]; then
+ echo "Timeout: Log string not found within 20 minutes."
+ exit 1
+ fi
+ done
+}
+
+
+space() {
+ echo ""
+ echo "++++++++++++++++++++++++++++++++++++++++++++++++++++"
+ echo ""
+}