diff --git a/nebulous/Dockerfile b/nebulous/Dockerfile index 4c8f7be..a1cf301 100644 --- a/nebulous/Dockerfile +++ b/nebulous/Dockerfile @@ -9,7 +9,7 @@ COPY pom.xml ${BASEDIR}/ RUN mvn -f ${BASEDIR}/pom.xml -DskipTests clean install # ----------------- Runtime image ----------------- -FROM registry.gitlab.com/nebulous-project/ems-main/ems-server:2024-jan +FROM registry.gitlab.com/nebulous-project/ems-main/ems-server:opendev COPY --from=builder /app/ems-nebulous/target/ems-nebulous-plugin-1.0.0-SNAPSHOT-jar-with-dependencies.jar /plugins/ ENV EXTRA_LOADER_PATHS=/plugins/* diff --git a/nebulous/examples/LICENSE b/nebulous/examples/LICENSE new file mode 100644 index 0000000..d0a1fa1 --- /dev/null +++ b/nebulous/examples/LICENSE @@ -0,0 +1,373 @@ +Mozilla Public License Version 2.0 +================================== + +1. Definitions +-------------- + +1.1. "Contributor" + means each individual or legal entity that creates, contributes to + the creation of, or owns Covered Software. + +1.2. "Contributor Version" + means the combination of the Contributions of others (if any) used + by a Contributor and that particular Contributor's Contribution. + +1.3. "Contribution" + means Covered Software of a particular Contributor. + +1.4. "Covered Software" + means Source Code Form to which the initial Contributor has attached + the notice in Exhibit A, the Executable Form of such Source Code + Form, and Modifications of such Source Code Form, in each case + including portions thereof. + +1.5. "Incompatible With Secondary Licenses" + means + + (a) that the initial Contributor has attached the notice described + in Exhibit B to the Covered Software; or + + (b) that the Covered Software was made available under the terms of + version 1.1 or earlier of the License, but not also under the + terms of a Secondary License. + +1.6. "Executable Form" + means any form of the work other than Source Code Form. + +1.7. "Larger Work" + means a work that combines Covered Software with other material, in + a separate file or files, that is not Covered Software. + +1.8. "License" + means this document. + +1.9. "Licensable" + means having the right to grant, to the maximum extent possible, + whether at the time of the initial grant or subsequently, any and + all of the rights conveyed by this License. + +1.10. "Modifications" + means any of the following: + + (a) any file in Source Code Form that results from an addition to, + deletion from, or modification of the contents of Covered + Software; or + + (b) any new file in Source Code Form that contains any Covered + Software. + +1.11. "Patent Claims" of a Contributor + means any patent claim(s), including without limitation, method, + process, and apparatus claims, in any patent Licensable by such + Contributor that would be infringed, but for the grant of the + License, by the making, using, selling, offering for sale, having + made, import, or transfer of either its Contributions or its + Contributor Version. + +1.12. "Secondary License" + means either the GNU General Public License, Version 2.0, the GNU + Lesser General Public License, Version 2.1, the GNU Affero General + Public License, Version 3.0, or any later versions of those + licenses. + +1.13. "Source Code Form" + means the form of the work preferred for making modifications. + +1.14. "You" (or "Your") + means an individual or a legal entity exercising rights under this + License. For legal entities, "You" includes any entity that + controls, is controlled by, or is under common control with You. For + purposes of this definition, "control" means (a) the power, direct + or indirect, to cause the direction or management of such entity, + whether by contract or otherwise, or (b) ownership of more than + fifty percent (50%) of the outstanding shares or beneficial + ownership of such entity. + +2. License Grants and Conditions +-------------------------------- + +2.1. Grants + +Each Contributor hereby grants You a world-wide, royalty-free, +non-exclusive license: + +(a) under intellectual property rights (other than patent or trademark) + Licensable by such Contributor to use, reproduce, make available, + modify, display, perform, distribute, and otherwise exploit its + Contributions, either on an unmodified basis, with Modifications, or + as part of a Larger Work; and + +(b) under Patent Claims of such Contributor to make, use, sell, offer + for sale, have made, import, and otherwise transfer either its + Contributions or its Contributor Version. + +2.2. Effective Date + +The licenses granted in Section 2.1 with respect to any Contribution +become effective for each Contribution on the date the Contributor first +distributes such Contribution. + +2.3. Limitations on Grant Scope + +The licenses granted in this Section 2 are the only rights granted under +this License. No additional rights or licenses will be implied from the +distribution or licensing of Covered Software under this License. +Notwithstanding Section 2.1(b) above, no patent license is granted by a +Contributor: + +(a) for any code that a Contributor has removed from Covered Software; + or + +(b) for infringements caused by: (i) Your and any other third party's + modifications of Covered Software, or (ii) the combination of its + Contributions with other software (except as part of its Contributor + Version); or + +(c) under Patent Claims infringed by Covered Software in the absence of + its Contributions. + +This License does not grant any rights in the trademarks, service marks, +or logos of any Contributor (except as may be necessary to comply with +the notice requirements in Section 3.4). + +2.4. Subsequent Licenses + +No Contributor makes additional grants as a result of Your choice to +distribute the Covered Software under a subsequent version of this +License (see Section 10.2) or under the terms of a Secondary License (if +permitted under the terms of Section 3.3). + +2.5. Representation + +Each Contributor represents that the Contributor believes its +Contributions are its original creation(s) or it has sufficient rights +to grant the rights to its Contributions conveyed by this License. + +2.6. Fair Use + +This License is not intended to limit any rights You have under +applicable copyright doctrines of fair use, fair dealing, or other +equivalents. + +2.7. Conditions + +Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted +in Section 2.1. + +3. Responsibilities +------------------- + +3.1. Distribution of Source Form + +All distribution of Covered Software in Source Code Form, including any +Modifications that You create or to which You contribute, must be under +the terms of this License. You must inform recipients that the Source +Code Form of the Covered Software is governed by the terms of this +License, and how they can obtain a copy of this License. You may not +attempt to alter or restrict the recipients' rights in the Source Code +Form. + +3.2. Distribution of Executable Form + +If You distribute Covered Software in Executable Form then: + +(a) such Covered Software must also be made available in Source Code + Form, as described in Section 3.1, and You must inform recipients of + the Executable Form how they can obtain a copy of such Source Code + Form by reasonable means in a timely manner, at a charge no more + than the cost of distribution to the recipient; and + +(b) You may distribute such Executable Form under the terms of this + License, or sublicense it under different terms, provided that the + license for the Executable Form does not attempt to limit or alter + the recipients' rights in the Source Code Form under this License. + +3.3. Distribution of a Larger Work + +You may create and distribute a Larger Work under terms of Your choice, +provided that You also comply with the requirements of this License for +the Covered Software. If the Larger Work is a combination of Covered +Software with a work governed by one or more Secondary Licenses, and the +Covered Software is not Incompatible With Secondary Licenses, this +License permits You to additionally distribute such Covered Software +under the terms of such Secondary License(s), so that the recipient of +the Larger Work may, at their option, further distribute the Covered +Software under the terms of either this License or such Secondary +License(s). + +3.4. Notices + +You may not remove or alter the substance of any license notices +(including copyright notices, patent notices, disclaimers of warranty, +or limitations of liability) contained within the Source Code Form of +the Covered Software, except that You may alter any license notices to +the extent required to remedy known factual inaccuracies. + +3.5. Application of Additional Terms + +You may choose to offer, and to charge a fee for, warranty, support, +indemnity or liability obligations to one or more recipients of Covered +Software. However, You may do so only on Your own behalf, and not on +behalf of any Contributor. You must make it absolutely clear that any +such warranty, support, indemnity, or liability obligation is offered by +You alone, and You hereby agree to indemnify every Contributor for any +liability incurred by such Contributor as a result of warranty, support, +indemnity or liability terms You offer. You may include additional +disclaimers of warranty and limitations of liability specific to any +jurisdiction. + +4. Inability to Comply Due to Statute or Regulation +--------------------------------------------------- + +If it is impossible for You to comply with any of the terms of this +License with respect to some or all of the Covered Software due to +statute, judicial order, or regulation then You must: (a) comply with +the terms of this License to the maximum extent possible; and (b) +describe the limitations and the code they affect. Such description must +be placed in a text file included with all distributions of the Covered +Software under this License. Except to the extent prohibited by statute +or regulation, such description must be sufficiently detailed for a +recipient of ordinary skill to be able to understand it. + +5. Termination +-------------- + +5.1. The rights granted under this License will terminate automatically +if You fail to comply with any of its terms. However, if You become +compliant, then the rights granted under this License from a particular +Contributor are reinstated (a) provisionally, unless and until such +Contributor explicitly and finally terminates Your grants, and (b) on an +ongoing basis, if such Contributor fails to notify You of the +non-compliance by some reasonable means prior to 60 days after You have +come back into compliance. Moreover, Your grants from a particular +Contributor are reinstated on an ongoing basis if such Contributor +notifies You of the non-compliance by some reasonable means, this is the +first time You have received notice of non-compliance with this License +from such Contributor, and You become compliant prior to 30 days after +Your receipt of the notice. + +5.2. If You initiate litigation against any entity by asserting a patent +infringement claim (excluding declaratory judgment actions, +counter-claims, and cross-claims) alleging that a Contributor Version +directly or indirectly infringes any patent, then the rights granted to +You by any and all Contributors for the Covered Software under Section +2.1 of this License shall terminate. + +5.3. In the event of termination under Sections 5.1 or 5.2 above, all +end user license agreements (excluding distributors and resellers) which +have been validly granted by You or Your distributors under this License +prior to termination shall survive termination. + +************************************************************************ +* * +* 6. Disclaimer of Warranty * +* ------------------------- * +* * +* Covered Software is provided under this License on an "as is" * +* basis, without warranty of any kind, either expressed, implied, or * +* statutory, including, without limitation, warranties that the * +* Covered Software is free of defects, merchantable, fit for a * +* particular purpose or non-infringing. The entire risk as to the * +* quality and performance of the Covered Software is with You. * +* Should any Covered Software prove defective in any respect, You * +* (not any Contributor) assume the cost of any necessary servicing, * +* repair, or correction. This disclaimer of warranty constitutes an * +* essential part of this License. No use of any Covered Software is * +* authorized under this License except under this disclaimer. * +* * +************************************************************************ + +************************************************************************ +* * +* 7. Limitation of Liability * +* -------------------------- * +* * +* Under no circumstances and under no legal theory, whether tort * +* (including negligence), contract, or otherwise, shall any * +* Contributor, or anyone who distributes Covered Software as * +* permitted above, be liable to You for any direct, indirect, * +* special, incidental, or consequential damages of any character * +* including, without limitation, damages for lost profits, loss of * +* goodwill, work stoppage, computer failure or malfunction, or any * +* and all other commercial damages or losses, even if such party * +* shall have been informed of the possibility of such damages. This * +* limitation of liability shall not apply to liability for death or * +* personal injury resulting from such party's negligence to the * +* extent applicable law prohibits such limitation. Some * +* jurisdictions do not allow the exclusion or limitation of * +* incidental or consequential damages, so this exclusion and * +* limitation may not apply to You. * +* * +************************************************************************ + +8. Litigation +------------- + +Any litigation relating to this License may be brought only in the +courts of a jurisdiction where the defendant maintains its principal +place of business and such litigation shall be governed by laws of that +jurisdiction, without reference to its conflict-of-law provisions. +Nothing in this Section shall prevent a party's ability to bring +cross-claims or counter-claims. + +9. Miscellaneous +---------------- + +This License represents the complete agreement concerning the subject +matter hereof. If any provision of this License is held to be +unenforceable, such provision shall be reformed only to the extent +necessary to make it enforceable. Any law or regulation which provides +that the language of a contract shall be construed against the drafter +shall not be used to construe this License against a Contributor. + +10. Versions of the License +--------------------------- + +10.1. New Versions + +Mozilla Foundation is the license steward. Except as provided in Section +10.3, no one other than the license steward has the right to modify or +publish new versions of this License. Each version will be given a +distinguishing version number. + +10.2. Effect of New Versions + +You may distribute the Covered Software under the terms of the version +of the License under which You originally received the Covered Software, +or under the terms of any subsequent version published by the license +steward. + +10.3. Modified Versions + +If you create software not governed by this License, and you want to +create a new license for such software, you may create and use a +modified version of this License if you rename the license and remove +any references to the name of the license steward (except to note that +such modified license differs from this License). + +10.4. Distributing Source Code Form that is Incompatible With Secondary +Licenses + +If You choose to distribute Source Code Form that is Incompatible With +Secondary Licenses under the terms of this version of the License, the +notice described in Exhibit B of this License must be attached. + +Exhibit A - Source Code Form License Notice +------------------------------------------- + + This Source Code Form is subject to the terms of the Mozilla Public + License, v. 2.0. If a copy of the MPL was not distributed with this + file, You can obtain one at https://mozilla.org/MPL/2.0/. + +If it is not possible or desirable to put the notice in a particular +file, then You may include the notice in a location (such as a LICENSE +file in a relevant directory) where a recipient would be likely to look +for such a notice. + +You may add additional accurate notices of copyright ownership. + +Exhibit B - "Incompatible With Secondary Licenses" Notice +--------------------------------------------------------- + + This Source Code Form is "Incompatible With Secondary Licenses", as + defined by the Mozilla Public License, v. 2.0. diff --git a/nebulous/examples/helm-charts/ems-server/.helmignore b/nebulous/examples/helm-charts/ems-server/.helmignore new file mode 100644 index 0000000..0e8a0eb --- /dev/null +++ b/nebulous/examples/helm-charts/ems-server/.helmignore @@ -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/ diff --git a/nebulous/examples/helm-charts/ems-server/Chart.yaml b/nebulous/examples/helm-charts/ems-server/Chart.yaml new file mode 100644 index 0000000..c8cc03b --- /dev/null +++ b/nebulous/examples/helm-charts/ems-server/Chart.yaml @@ -0,0 +1,33 @@ +# +# Copyright (C) 2017-2025 Institute of Communication and Computer Systems (imu.iccs.gr) +# +# This Source Code Form is subject to the terms of the Mozilla Public License, v2.0, unless +# Esper library is used, in which case it is subject to the terms of General Public License v2.0. +# If a copy of the MPL was not distributed with this file, you can obtain one at +# https://www.mozilla.org/en-US/MPL/2.0/ +# + +apiVersion: v2 +name: ems-server +description: EMS server Helm chart for Kubernetes + +# A chart can be either an 'application' or a 'library' chart. +# +# Application charts are a collection of templates that can be packaged into versioned archives +# to be deployed. +# +# Library charts provide useful utilities or functions for the chart developer. They're included as +# a dependency of application charts to inject those utilities and functions into the rendering +# pipeline. Library charts do not define any templates and therefore cannot be deployed. +type: application + +# This is the chart version. This version number should be incremented each time you make changes +# to the chart and its templates, including the app version. +# Versions are expected to follow Semantic Versioning (https://semver.org/) +version: 0.1.0 + +# This is the version number of the application being deployed. This version number should be +# incremented each time you make changes to the application. Versions are not expected to +# follow Semantic Versioning. They should reflect the version the application is using. +# It is recommended to use it with quotes. +appVersion: "7.0.0-SNAPSHOT" diff --git a/nebulous/examples/helm-charts/ems-server/templates/NOTES.txt b/nebulous/examples/helm-charts/ems-server/templates/NOTES.txt new file mode 100644 index 0000000..4f01567 --- /dev/null +++ b/nebulous/examples/helm-charts/ems-server/templates/NOTES.txt @@ -0,0 +1,22 @@ +1. Get the application URL by running these commands: +{{- if .Values.ingress.enabled }} +{{- range $host := .Values.ingress.hosts }} + {{- range .paths }} + http{{ if $.Values.ingress.tls }}s{{ end }}://{{ $host.host }}{{ .path }} + {{- end }} +{{- end }} +{{- else if contains "NodePort" .Values.service.type }} + export NODE_PORT=$(kubectl get --namespace {{ .Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ include "ems-server.fullname" . }}) + export NODE_IP=$(kubectl get nodes --namespace {{ .Release.Namespace }} -o jsonpath="{.items[0].status.addresses[0].address}") + echo http://$NODE_IP:$NODE_PORT +{{- else if contains "LoadBalancer" .Values.service.type }} + NOTE: It may take a few minutes for the LoadBalancer IP to be available. + You can watch the status of by running 'kubectl get --namespace {{ .Release.Namespace }} svc -w {{ include "ems-server.fullname" . }}' + export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ include "ems-server.fullname" . }} --template "{{"{{ range (index .status.loadBalancer.ingress 0) }}{{.}}{{ end }}"}}") + echo http://$SERVICE_IP:{{ .Values.service.port }} +{{- else if contains "ClusterIP" .Values.service.type }} + export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app.kubernetes.io/name={{ include "ems-server.name" . }},app.kubernetes.io/instance={{ .Release.Name }}" -o jsonpath="{.items[0].metadata.name}") + export CONTAINER_PORT=$(kubectl get pod --namespace {{ .Release.Namespace }} $POD_NAME -o jsonpath="{.spec.containers[0].ports[0].containerPort}") + echo "Visit http://127.0.0.1:8080 to use your application" + kubectl --namespace {{ .Release.Namespace }} port-forward $POD_NAME 8080:$CONTAINER_PORT +{{- end }} diff --git a/nebulous/examples/helm-charts/ems-server/templates/_helpers.tpl b/nebulous/examples/helm-charts/ems-server/templates/_helpers.tpl new file mode 100644 index 0000000..499b1e7 --- /dev/null +++ b/nebulous/examples/helm-charts/ems-server/templates/_helpers.tpl @@ -0,0 +1,62 @@ +{{/* +Expand the name of the chart. +*/}} +{{- define "ems-server.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 "ems-server.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 "ems-server.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Common labels +*/}} +{{- define "ems-server.labels" -}} +helm.sh/chart: {{ include "ems-server.chart" . }} +{{ include "ems-server.selectorLabels" . }} +{{- if .Chart.AppVersion }} +app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} +{{- end }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- end }} + +{{/* +Selector labels +*/}} +{{- define "ems-server.selectorLabels" -}} +app.kubernetes.io/name: {{ include "ems-server.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end }} + +{{/* +Create the name of the service account to use +*/}} +{{- define "ems-server.serviceAccountName" -}} +{{- if .Values.serviceAccount.create }} +{{- default (include "ems-server.fullname" .) .Values.serviceAccount.name }} +{{- else }} +{{- default "default" .Values.serviceAccount.name }} +{{- end }} +{{- end }} diff --git a/nebulous/examples/helm-charts/ems-server/templates/deployment.yaml b/nebulous/examples/helm-charts/ems-server/templates/deployment.yaml new file mode 100644 index 0000000..8e2f501 --- /dev/null +++ b/nebulous/examples/helm-charts/ems-server/templates/deployment.yaml @@ -0,0 +1,135 @@ +# +# Copyright (C) 2017-2025 Institute of Communication and Computer Systems (imu.iccs.gr) +# +# This Source Code Form is subject to the terms of the Mozilla Public License, v2.0, unless +# Esper library is used, in which case it is subject to the terms of General Public License v2.0. +# If a copy of the MPL was not distributed with this file, you can obtain one at +# https://www.mozilla.org/en-US/MPL/2.0/ +# +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ include "ems-server.fullname" . }} + labels: + {{- include "ems-server.labels" . | nindent 4 }} +spec: + {{- if not .Values.autoscaling.enabled }} + replicas: {{ .Values.replicaCount }} + {{- end }} + selector: + matchLabels: + {{- include "ems-server.selectorLabels" . | nindent 6 }} + template: + metadata: + {{- with .Values.podAnnotations }} + annotations: + {{- toYaml . | nindent 8 }} + {{- end }} + labels: + {{- include "ems-server.selectorLabels" . | nindent 8 }} + spec: + {{- with .Values.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + + serviceAccountName: {{ include "ems-server.serviceAccountName" . }} + securityContext: + {{- toYaml .Values.podSecurityContext | nindent 8 }} + + terminationGracePeriodSeconds: 10 + containers: + - name: {{ .Chart.Name }} + securityContext: + {{- toYaml .Values.securityContext | nindent 12 }} + image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}" + imagePullPolicy: {{ .Values.image.pullPolicy }} + env: + {{- range .Values.env }} + - name: {{ .name }} + value: {{ .value | quote }} + {{- end }} + ports: + {{- range .Values.ports }} + - name: {{ .name }} + containerPort: {{ .containerPort }} + protocol: {{ .protocol }} + {{- end }} + livenessProbe: + tcpSocket: + port: http + readinessProbe: + tcpSocket: + port: http + resources: + {{- toYaml .Values.resources | nindent 12 }} + {{- with .Values.nodeSelector }} + nodeSelector: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.affinity }} + affinity: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.tolerations }} + tolerations: + {{- toYaml . | nindent 8 }} + {{- end }} +--- +# The configmap to be updated +#apiVersion: v1 +#kind: ConfigMap +#metadata: +# name: ems-client-configmap +#--- + +kind: RoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: ems-server-role-binding +subjects: + - kind: ServiceAccount + name: {{ include "ems-server.serviceAccountName" . }} +# namespace: default +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: ems-server-role +--- +kind: Role +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: ems-server-role +# Benefit of using RBAC over giving your personal access token as a secret to your application: You can pinpoint which access you want to allow +rules: + - apiGroups: ["", "apps"] # Empty string for kubernetes system + resources: ["configmaps", "daemonsets"] + resourceNames: ["monitoring-configmap", "ems-client-configmap", "ems-client-daemonset"] + verbs: ["get", "update", "delete", "list", "watch", "patch"] + - apiGroups: ["", "apps"] # Empty string for kubernetes system + resources: ["configmaps", "daemonsets"] + verbs: ["create"] + +--- +kind: ClusterRoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: ems-server-cluster-role-binding +subjects: + - kind: ServiceAccount + name: {{ include "ems-server.serviceAccountName" . }} + namespace: default +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: ems-server-cluster-role +--- +kind: ClusterRole +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: ems-server-cluster-role +rules: + - apiGroups: ["", "apps"] + resources: ["pods", "nodes"] + verbs: ["get", "list", "watch"] diff --git a/nebulous/examples/helm-charts/ems-server/templates/hpa.yaml b/nebulous/examples/helm-charts/ems-server/templates/hpa.yaml new file mode 100644 index 0000000..47311e9 --- /dev/null +++ b/nebulous/examples/helm-charts/ems-server/templates/hpa.yaml @@ -0,0 +1,28 @@ +{{- if .Values.autoscaling.enabled }} +apiVersion: autoscaling/v2beta1 +kind: HorizontalPodAutoscaler +metadata: + name: {{ include "ems-server.fullname" . }} + labels: + {{- include "ems-server.labels" . | nindent 4 }} +spec: + scaleTargetRef: + apiVersion: apps/v1 + kind: Deployment + name: {{ include "ems-server.fullname" . }} + minReplicas: {{ .Values.autoscaling.minReplicas }} + maxReplicas: {{ .Values.autoscaling.maxReplicas }} + metrics: + {{- if .Values.autoscaling.targetCPUUtilizationPercentage }} + - type: Resource + resource: + name: cpu + targetAverageUtilization: {{ .Values.autoscaling.targetCPUUtilizationPercentage }} + {{- end }} + {{- if .Values.autoscaling.targetMemoryUtilizationPercentage }} + - type: Resource + resource: + name: memory + targetAverageUtilization: {{ .Values.autoscaling.targetMemoryUtilizationPercentage }} + {{- end }} +{{- end }} diff --git a/nebulous/examples/helm-charts/ems-server/templates/ingress.yaml b/nebulous/examples/helm-charts/ems-server/templates/ingress.yaml new file mode 100644 index 0000000..0a687a6 --- /dev/null +++ b/nebulous/examples/helm-charts/ems-server/templates/ingress.yaml @@ -0,0 +1,61 @@ +{{- if .Values.ingress.enabled -}} +{{- $fullName := include "ems-server.fullname" . -}} +{{- $svcPort := .Values.service.port -}} +{{- if and .Values.ingress.className (not (semverCompare ">=1.18-0" .Capabilities.KubeVersion.GitVersion)) }} + {{- if not (hasKey .Values.ingress.annotations "kubernetes.io/ingress.class") }} + {{- $_ := set .Values.ingress.annotations "kubernetes.io/ingress.class" .Values.ingress.className}} + {{- end }} +{{- end }} +{{- if semverCompare ">=1.19-0" .Capabilities.KubeVersion.GitVersion -}} +apiVersion: networking.k8s.io/v1 +{{- else if semverCompare ">=1.14-0" .Capabilities.KubeVersion.GitVersion -}} +apiVersion: networking.k8s.io/v1beta1 +{{- else -}} +apiVersion: extensions/v1beta1 +{{- end }} +kind: Ingress +metadata: + name: {{ $fullName }} + labels: + {{- include "ems-server.labels" . | nindent 4 }} + {{- with .Values.ingress.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + {{- if and .Values.ingress.className (semverCompare ">=1.18-0" .Capabilities.KubeVersion.GitVersion) }} + ingressClassName: {{ .Values.ingress.className }} + {{- end }} + {{- if .Values.ingress.tls }} + tls: + {{- range .Values.ingress.tls }} + - hosts: + {{- range .hosts }} + - {{ . | quote }} + {{- end }} + secretName: {{ .secretName }} + {{- end }} + {{- end }} + rules: + {{- range .Values.ingress.hosts }} + - host: {{ .host | quote }} + http: + paths: + {{- range .paths }} + - path: {{ .path }} + {{- if and .pathType (semverCompare ">=1.18-0" $.Capabilities.KubeVersion.GitVersion) }} + pathType: {{ .pathType }} + {{- end }} + backend: + {{- if semverCompare ">=1.19-0" $.Capabilities.KubeVersion.GitVersion }} + service: + name: {{ $fullName }} + port: + number: {{ $svcPort }} + {{- else }} + serviceName: {{ $fullName }} + servicePort: {{ $svcPort }} + {{- end }} + {{- end }} + {{- end }} +{{- end }} diff --git a/nebulous/examples/helm-charts/ems-server/templates/service.yaml b/nebulous/examples/helm-charts/ems-server/templates/service.yaml new file mode 100644 index 0000000..5c2eafe --- /dev/null +++ b/nebulous/examples/helm-charts/ems-server/templates/service.yaml @@ -0,0 +1,24 @@ +# +# Copyright (C) 2017-2025 Institute of Communication and Computer Systems (imu.iccs.gr) +# +# This Source Code Form is subject to the terms of the Mozilla Public License, v2.0, unless +# Esper library is used, in which case it is subject to the terms of General Public License v2.0. +# If a copy of the MPL was not distributed with this file, you can obtain one at +# https://www.mozilla.org/en-US/MPL/2.0/ +# + +apiVersion: v1 +kind: Service +metadata: + name: {{ include "ems-server.fullname" . }} + labels: + {{- include "ems-server.labels" . | nindent 4 }} +spec: + type: {{ .Values.service.type }} + ports: + - port: {{ .Values.service.port }} + targetPort: http + protocol: TCP + name: http + selector: + {{- include "ems-server.selectorLabels" . | nindent 4 }} diff --git a/nebulous/examples/helm-charts/ems-server/templates/serviceaccount.yaml b/nebulous/examples/helm-charts/ems-server/templates/serviceaccount.yaml new file mode 100644 index 0000000..e024260 --- /dev/null +++ b/nebulous/examples/helm-charts/ems-server/templates/serviceaccount.yaml @@ -0,0 +1,12 @@ +{{- if .Values.serviceAccount.create -}} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ include "ems-server.serviceAccountName" . }} + labels: + {{- include "ems-server.labels" . | nindent 4 }} + {{- with .Values.serviceAccount.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +{{- end }} diff --git a/nebulous/examples/helm-charts/ems-server/templates/tests/test-connection.yaml b/nebulous/examples/helm-charts/ems-server/templates/tests/test-connection.yaml new file mode 100644 index 0000000..0c0d0b3 --- /dev/null +++ b/nebulous/examples/helm-charts/ems-server/templates/tests/test-connection.yaml @@ -0,0 +1,15 @@ +apiVersion: v1 +kind: Pod +metadata: + name: "{{ include "ems-server.fullname" . }}-test-connection" + labels: + {{- include "ems-server.labels" . | nindent 4 }} + annotations: + "helm.sh/hook": test +spec: + containers: + - name: wget + image: busybox + command: ['wget'] + args: ['{{ include "ems-server.fullname" . }}:{{ .Values.service.port }}'] + restartPolicy: Never diff --git a/nebulous/examples/helm-charts/ems-server/values.yaml b/nebulous/examples/helm-charts/ems-server/values.yaml new file mode 100644 index 0000000..1d8c1c6 --- /dev/null +++ b/nebulous/examples/helm-charts/ems-server/values.yaml @@ -0,0 +1,179 @@ +# +# Copyright (C) 2017-2025 Institute of Communication and Computer Systems (imu.iccs.gr) +# +# This Source Code Form is subject to the terms of the Mozilla Public License, v2.0, unless +# Esper library is used, in which case it is subject to the terms of General Public License v2.0. +# If a copy of the MPL was not distributed with this file, you can obtain one at +# https://www.mozilla.org/en-US/MPL/2.0/ +# + +# Default values for ems-server. +# This is a YAML-formatted file. +# Declare variables to be passed into your templates. + +replicaCount: 1 + +image: + repository: "quay.io/nebulous/monitoring" + pullPolicy: IfNotPresent + # Overrides the image tag whose default is the chart appVersion. + tag: &image_tag "latest" + +imagePullSecrets: [] +nameOverride: "" +fullnameOverride: "" + +serviceAccount: + # Specifies whether a service account should be created + create: true + # Annotations to add to the service account + annotations: {} + # The name of the service account to use. + # If not set and create is true, a name is generated using the fullname template + name: "ems-server-service-account" + +podAnnotations: {} + +podSecurityContext: {} + # fsGroup: 2000 + +securityContext: {} + # capabilities: + # drop: + # - ALL + # readOnlyRootFilesystem: true + # runAsNonRoot: true + # runAsUser: 1000 + +service: + type: ClusterIP + port: 8111 + +ingress: + enabled: false + className: "" + annotations: {} + # kubernetes.io/ingress.class: nginx + # kubernetes.io/tls-acme: "true" + hosts: + - host: chart-example.local + paths: + - path: / + pathType: ImplementationSpecific + tls: [] + # - secretName: chart-example-tls + # hosts: + # - chart-example.local + +resources: {} + # We usually recommend not to specify default resources and to leave this as a conscious + # choice for the user. This also increases chances charts run on environments with little + # resources, such as Minikube. If you do want to specify resources, uncomment the following + # lines, adjust them as necessary, and remove the curly braces after 'resources:'. + # limits: + # cpu: 100m + # memory: 128Mi + # requests: + # cpu: 100m + # memory: 128Mi + +autoscaling: + enabled: false + minReplicas: 1 + maxReplicas: 1 + targetCPUUtilizationPercentage: 80 + # targetMemoryUtilizationPercentage: 80 + +nodeSelector: {} + +tolerations: [] + +affinity: {} + +ports: + - name: http + containerPort: 8111 + protocol: TCP + - name: openwire + containerPort: 61616 + protocol: TCP + - name: openwire-tls + containerPort: 61617 + protocol: TCP + - name: stomp + containerPort: 61610 + protocol: TCP + +env: + # + # ===== EMS server configuration ===== + # + # ===== INITIALIZATION settings ===== + - name: JASYPT_PASSWORD + value: 'password' + - name: NET_UTIL_ADDRESS_DISCOVERY_SERVICES + value: '-' + - name: EMS_IP_SETTING + value: 'DEFAULT_IP' + # ===== Authentication settings ===== + - name: JWT_SECRET + value: 'ENC(I0mRWgH2FVDDNs4OBcdh7Z+o3lOQDa3ztaEtmnXT2HN0aClkChp/lqm9zM5HyTk0stJ7v2Di75U=)' + - name: WEB_SECURITY_API_KEY_AUTHENTICATION_VALUE + value: '1234567890' + - name: WEB_SECURITY_FORM_AUTHENTICATION_PASSWORD + value: 'ems' + - name: EXTERNAL_ENABLED + value: 'true' + - name: EXTERNAL_BROKER_ADDRESS + value: '' + - name: EXTERNAL_BROKER_PORT + value: '5672' + - name: EXTERNAL_BROKER_USERNAME + value: '' + - name: EXTERNAL_BROKER_PASSWORD + value: '' + # ===== Broker settings ===== + - name: BROKERCEP_ADDITIONAL_BROKER_CREDENTIALS + value: 'aaa/111, bbb/222' +# value: 'ENC(axeJUxNHajYfBffUwvuT3kwTgLTpRliDMz/ZQ9hROZ3BNOv0Idw72NJsawzIZRuZ)' + - name: BROKERCEP_EVENT_RECORDER_ENABLED + value: 'false' + - name: BROKERCEP_EVENT_RECORDER_FILTER_MODE + value: 'ALL' + # ===== Baguette Server settings ===== + - name: BAGUETTE_SERVER_CREDENTIALS +# value: '{ "aa":"xx" }' + value: 'ENC(y46CiW6przlpXvz8ToE+T1Sn6uGfO2haP7OhATB0SXo=)' + # + # ===== EMS server K8sClientInstaller configuration ===== + # + - name: EMS_CLIENT_DEPLOYMENT_DRY_RUN + value: "false" + - name: K8S_SERVICE_ACCOUNT_SECRETS_PATH + value: "/var/run/secrets/kubernetes.io/serviceaccount" + - name: APP_CONFIG_MAP_NAME + value: "monitoring-configmap" +# - name: EMS_CLIENT_BROKER_USERNAME # It is appended to EMS_CLIENT_ADDITIONAL_BROKER_CREDENTIALS +# value: "ccc" +# - name: EMS_CLIENT_BROKER_PASSWORD +# value: "333" + - name: EMS_CLIENT_CONFIG_MAP_NAME + value: "ems-client-configmap" +# - name: EMS_CLIENT_DAEMONSET_SPECIFICATION_FILE +# value: "/ems-client-daemonset.yaml" + - name: EMS_CLIENT_DAEMONSET_NAME + value: "ems-client-daemonset" + - name: EMS_CLIENT_DAEMONSET_IMAGE_REPOSITORY + value: "registry.gitlab.com/nebulous-project/ems-main/ems-client" + - name: EMS_CLIENT_DAEMONSET_IMAGE_TAG +# value: "latest" + value: *image_tag + - name: EMS_CLIENT_DAEMONSET_IMAGE_PULL_POLICY + value: "Always" + - name: EMS_CLIENT_ADDITIONAL_BROKER_CREDENTIALS + value: 'aaa/111, bbb/222' +# value: "ENC(axeJUxNHajYfBffUwvuT3kwTgLTpRliDMz/ZQ9hROZ3BNOv0Idw72NJsawzIZRuZ)" + - name: EMS_CLIENT_KEYSTORE_SECRET + value: "" + - name: EMS_CLIENT_TRUSTSTORE_SECRET + value: "" \ No newline at end of file diff --git a/nebulous/examples/helm-charts/simple-app/Chart.yaml b/nebulous/examples/helm-charts/simple-app/Chart.yaml new file mode 100644 index 0000000..b3f9ab3 --- /dev/null +++ b/nebulous/examples/helm-charts/simple-app/Chart.yaml @@ -0,0 +1,13 @@ +# +# Copyright (C) 2017-2025 Institute of Communication and Computer Systems (imu.iccs.gr) +# +# This Source Code Form is subject to the terms of the Mozilla Public License, v2.0, unless +# Esper library is used, in which case it is subject to the terms of General Public License v2.0. +# If a copy of the MPL was not distributed with this file, you can obtain one at +# https://www.mozilla.org/en-US/MPL/2.0/ +# + +apiVersion: v2 +name: simple-app +description: Simple App Helm chart +version: 0.1.0 \ No newline at end of file diff --git a/nebulous/examples/helm-charts/simple-app/templates/_helpers.tpl b/nebulous/examples/helm-charts/simple-app/templates/_helpers.tpl new file mode 100644 index 0000000..c4b676c --- /dev/null +++ b/nebulous/examples/helm-charts/simple-app/templates/_helpers.tpl @@ -0,0 +1,17 @@ +{{/* _helpers.tpl */}} +{{- define "simple-app.fullname" -}} +{{- printf "%s-%s" .Release.Name .Chart.Name }} +{{- end -}} + +{{- define "simple-app.labels" -}} +app.kubernetes.io/name: {{ include "simple-app.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end -}} + +{{- define "simple-app.selectorLabels" -}} +app.kubernetes.io/name: {{ include "simple-app.name" . }} +{{- end -}} + +{{- define "simple-app.name" -}} +{{- default "simple-app" .Values.nameOverride | trunc 63 | trimSuffix "-" -}} +{{- end -}} diff --git a/nebulous/examples/helm-charts/simple-app/templates/deployment.yaml b/nebulous/examples/helm-charts/simple-app/templates/deployment.yaml new file mode 100644 index 0000000..59b62d2 --- /dev/null +++ b/nebulous/examples/helm-charts/simple-app/templates/deployment.yaml @@ -0,0 +1,79 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ include "simple-app.fullname" . }} +spec: + replicas: 1 + selector: + matchLabels: + app: {{ include "simple-app.fullname" . }} + template: + metadata: + labels: + app: {{ include "simple-app.fullname" . }} + spec: + containers: + - name: {{ .Chart.Name }} + image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}" + imagePullPolicy: {{ .Values.image.pullPolicy }} + ports: + - containerPort: 8080 + env: + # + # K8S cluster node info + # + - name: K8S_NODE_NAME + valueFrom: + fieldRef: + fieldPath: spec.nodeName + - name: K8S_NODE_ADDRESS + valueFrom: + fieldRef: + fieldPath: status.hostIP + # + # Pod info + # + - name: POD_NAME + valueFrom: + fieldRef: + fieldPath: metadata.name + - name: POD_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + - name: POD_ADDRESS + valueFrom: + fieldRef: + fieldPath: status.podIP + # + # EMS client broker info + # + - name: 'BROKER_SERVER' + valueFrom: + fieldRef: + fieldPath: status.hostIP + - name: 'BROKER_PORT' + value: '61610' + - name: 'BROKER_USERNAME' + valueFrom: + configMapKeyRef: + name: monitoring-configmap + key: BROKER_USERNAME + - name: 'BROKER_PASSWORD' + valueFrom: + configMapKeyRef: + name: monitoring-configmap + key: BROKER_PASSWORD + # + # Env. vars from Values.yaml + # + {{- range .Values.env }} + - name: {{ .name }} + value: {{ .value | quote }} + {{- end }} + + volumeMounts: + {{- range .Values.volumeMounts }} + - name: {{ .name }} + mountPath: {{ .mountPath | quote }} + {{- end }} diff --git a/nebulous/examples/helm-charts/simple-app/values.yaml b/nebulous/examples/helm-charts/simple-app/values.yaml new file mode 100644 index 0000000..6ebd295 --- /dev/null +++ b/nebulous/examples/helm-charts/simple-app/values.yaml @@ -0,0 +1,26 @@ +# +# Copyright (C) 2017-2025 Institute of Communication and Computer Systems (imu.iccs.gr) +# +# This Source Code Form is subject to the terms of the Mozilla Public License, v2.0, unless +# Esper library is used, in which case it is subject to the terms of General Public License v2.0. +# If a copy of the MPL was not distributed with this file, you can obtain one at +# https://www.mozilla.org/en-US/MPL/2.0/ +# + +replicaCount: 1 + +image: + repository: "simple-app" + pullPolicy: IfNotPresent + # Overrides the image tag whose default is the chart appVersion. + tag: "latest" + +env: + - name: 'TARGET_TOPIC' + value: 'a__component_cpu__util__instance__SENSOR' + - name: 'SEND_DELAY' + value: '10' + - name: 'VALUE_MIN' + value: '0' + - name: 'VALUE_MAX' + value: '100' diff --git a/nebulous/examples/simple-app-java/.gitattributes b/nebulous/examples/simple-app-java/.gitattributes new file mode 100644 index 0000000..b3b9b03 --- /dev/null +++ b/nebulous/examples/simple-app-java/.gitattributes @@ -0,0 +1,9 @@ +# +# Copyright (C) 2017-2025 Institute of Communication and Computer Systems (imu.iccs.gr) +# +# This Source Code Form is subject to the terms of the Mozilla Public License, v2.0. +# If a copy of the MPL was not distributed with this file, You can obtain one at +# https://www.mozilla.org/en-US/MPL/2.0/ +# + +* text eol=lf \ No newline at end of file diff --git a/nebulous/examples/simple-app-java/.gitignore b/nebulous/examples/simple-app-java/.gitignore new file mode 100644 index 0000000..768b37c --- /dev/null +++ b/nebulous/examples/simple-app-java/.gitignore @@ -0,0 +1,15 @@ +target/ + +### STS ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans + +### IntelliJ IDEA ### +.idea +*.iws +*.iml +*.ipr diff --git a/nebulous/examples/simple-app-java/Dockerfile b/nebulous/examples/simple-app-java/Dockerfile new file mode 100644 index 0000000..be17340 --- /dev/null +++ b/nebulous/examples/simple-app-java/Dockerfile @@ -0,0 +1,22 @@ +# +# Copyright (C) 2017-2025 Institute of Communication and Computer Systems (imu.iccs.gr) +# +# This Source Code Form is subject to the terms of the Mozilla Public License, v2.0. +# If a copy of the MPL was not distributed with this file, You can obtain one at +# https://www.mozilla.org/en-US/MPL/2.0/ +# + +FROM eclipse-temurin:21.0.2_13-jre-jammy + +WORKDIR /app +RUN apt-get update && \ + apt-get install -y vim iputils-ping curl telnet && \ + rm -rf /var/lib/apt/lists/* + +COPY target/simple-app-java-jar-with-dependencies.jar /app/ +COPY entrypoint.sh /app/ +RUN chmod + /app/*.sh + +EXPOSE 8080 + +ENTRYPOINT [ "./entrypoint.sh" ] \ No newline at end of file diff --git a/nebulous/examples/simple-app-java/docker-compose.yml b/nebulous/examples/simple-app-java/docker-compose.yml new file mode 100644 index 0000000..bdbf7ab --- /dev/null +++ b/nebulous/examples/simple-app-java/docker-compose.yml @@ -0,0 +1,23 @@ +# +# Copyright (C) 2017-2025 Institute of Communication and Computer Systems (imu.iccs.gr) +# +# This Source Code Form is subject to the terms of the Mozilla Public License, v2.0. +# If a copy of the MPL was not distributed with this file, You can obtain one at +# https://www.mozilla.org/en-US/MPL/2.0/ +# + + +services: + simple-app: + image: simple-app:latest + environment: + - BROKER_SERVER=host.docker.internal + - BROKER_PORT=61616 + - BROKER_USERNAME=aaa + - BROKER_PASSWORD=111 + - TARGET_TOPIC=some_topic + - SEND_DELAY=10 + - VALUE_MIN=0 + - VALUE_MAX=100 + ports: + - 8080:8080 \ No newline at end of file diff --git a/nebulous/examples/simple-app-java/entrypoint.sh b/nebulous/examples/simple-app-java/entrypoint.sh new file mode 100644 index 0000000..441a81b --- /dev/null +++ b/nebulous/examples/simple-app-java/entrypoint.sh @@ -0,0 +1,11 @@ +#!/usr/bin/env bash +# +# Copyright (C) 2017-2025 Institute of Communication and Computer Systems (imu.iccs.gr) +# +# This Source Code Form is subject to the terms of the Mozilla Public License, v2.0. +# If a copy of the MPL was not distributed with this file, You can obtain one at +# https://www.mozilla.org/en-US/MPL/2.0/ +# + +# Start simple-app to send messages to broker +java -jar simple-app-java-jar-with-dependencies.jar diff --git a/nebulous/examples/simple-app-java/pom.xml b/nebulous/examples/simple-app-java/pom.xml new file mode 100644 index 0000000..bb65ca3 --- /dev/null +++ b/nebulous/examples/simple-app-java/pom.xml @@ -0,0 +1,61 @@ + + + 4.0.0 + + simple-app-java + ems-examples + 1.0.0 + Simple App for sending metrics to EMS client + + + + org.apache.activemq + activemq-client + 6.0.1 + + + + + ${project.artifactId} + + + org.apache.maven.plugins + maven-assembly-plugin + 3.1.1 + + + + jar-with-dependencies + + + + gr.iccs.imu.ems.example.SimpleApp + true + true + + + + + + + make-assembly + package + + single + + + + + + + + + diff --git a/nebulous/examples/simple-app-java/src/main/java/gr/iccs/imu/ems/example/SimpleApp.java b/nebulous/examples/simple-app-java/src/main/java/gr/iccs/imu/ems/example/SimpleApp.java new file mode 100644 index 0000000..ddf9685 --- /dev/null +++ b/nebulous/examples/simple-app-java/src/main/java/gr/iccs/imu/ems/example/SimpleApp.java @@ -0,0 +1,142 @@ +/* + * Copyright (C) 2017-2025 Institute of Communication and Computer Systems (imu.iccs.gr) + * + * This Source Code Form is subject to the terms of the Mozilla Public License, v2.0, unless + * Esper library is used, in which case it is subject to the terms of General Public License v2.0. + * If a copy of the MPL was not distributed with this file, you can obtain one at + * https://www.mozilla.org/en-US/MPL/2.0/ + */ + +package gr.iccs.imu.ems.example; + +import jakarta.jms.*; +import org.apache.activemq.ActiveMQConnectionFactory; + +public class SimpleApp { + private Connection connection; + private Session session; + + public static void main(String[] args) throws InterruptedException { + // Load configuration + String brokerAddress = getOrDefault("BROKER_SERVER", "localhost"); + String brokerPort = getOrDefault("BROKER_PORT", "61616"); + String connectionString = "tcp://"+brokerAddress+":"+brokerPort; + String username = getOrDefault("BROKER_USERNAME", "aaa"); + String password = getOrDefault("BROKER_PASSWORD", "111"); + String destinationName = getOrDefault("TARGET_TOPIC", "sample_topic"); + + int retryConnect = Integer.parseInt(getOrDefault("RETRY_CONNECT", "5")); + int sendDelay = Integer.parseInt(getOrDefault("SEND_DELAY", "10")); + double valueMin = Double.parseDouble(getOrDefault("VALUE_MIN", "0")); + double valueMax = Double.parseDouble(getOrDefault("VALUE_MAX", "100")); + + // Print configuration + System.out.println("===== Configuration ====="); + System.out.println(" BROKER_SERVER: "+brokerAddress); + System.out.println(" BROKER_PORT: "+brokerPort); + System.out.println(" CONNECTION-STR: "+connectionString); + System.out.println("BROKER_USERNAME: "+username); + System.out.println("BROKER_PASSWORD: "+password); + System.out.println(" TARGET_TOPIC: "+destinationName); + + System.out.println(" RETRY_CONNECT: "+retryConnect); + System.out.println(" SEND_DELAY: "+sendDelay); + System.out.println(" VALUE_MIN: "+valueMin); + System.out.println(" VALUE_MAX: "+valueMax); + + // Run example + while (true) { + try { + SimpleApp app = new SimpleApp(); + app.runExample(connectionString, username, password, + destinationName, 1000L * sendDelay, valueMin, valueMax); + } catch (Exception e) { + System.err.println("EXCEPTION: "+e.getMessage()); + e.printStackTrace(System.err); + + System.out.println("Retrying in "+retryConnect+" seconds"); + Thread.sleep(1000L * retryConnect); + } + } + } + + protected static String getOrDefault(String name, String defaultValue) { + String value = System.getenv(name); + if (value==null || value.trim().isEmpty()) + value = defaultValue; + if (value==null) + throw new IllegalArgumentException("Property "+name+" is not provided or is empty, and default value is null"); + return value.trim(); + } + + public void runExample(String connectionString, String username, String password, + String destinationName, long sendDelay, double valueMin, double valueMax) + throws JMSException, InterruptedException + { + try { + // open connection + openConnection(connectionString, username, password); + System.out.println("Connected to broker: "+connectionString+", as user: "+username); + + // Create the destination (Topic) + Topic destination = session.createTopic(destinationName); + System.out.println("Sending to topic: "+destinationName); + + // Create a MessageProducer from the Session to the Topic + MessageProducer producer = session.createProducer(destination); + producer.setDeliveryMode(DeliveryMode.NON_PERSISTENT); + + // Publish values + double valueRange = valueMax - valueMin; + while (true) { + publishEvent(producer, valueRange * Math.random() - valueMin); + Thread.sleep(sendDelay); + } + } finally { + // close connection + closeConnection(); + } + } + + // ------------------------------------------------------------------------ + + protected void publishEvent(MessageProducer producer, double value) throws JMSException { + // Create a messages + String payloadText = String.format("{ \"metricValue\": %f, \"level\": 1, \"timestamp\": %d }", value, System.currentTimeMillis()); + Message message = session.createTextMessage(payloadText); + + // Send the message + producer.send(message); + System.out.println("Sent: " + payloadText); + } + + // ------------------------------------------------------------------------ + + public void openConnection(String connectionString, String username, String password) throws JMSException { + // Create connection factory + ActiveMQConnectionFactory connectionFactory = new ActiveMQConnectionFactory(connectionString); + connectionFactory.setBrokerURL(connectionString); + connectionFactory.setUserName(username); + connectionFactory.setPassword(password); + connectionFactory.setTrustAllPackages(true); + connectionFactory.setWatchTopicAdvisories(true); + + // Create a Connection + Connection connection = connectionFactory.createConnection(); + connection.start(); + + // Create a Session + Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); + + this.connection = connection; + this.session = session; + } + + public void closeConnection() throws JMSException { + // Clean up + session.close(); + connection.close(); + session = null; + connection = null; + } +} \ No newline at end of file diff --git a/nebulous/examples/simple-app-python/.gitattributes b/nebulous/examples/simple-app-python/.gitattributes new file mode 100644 index 0000000..b3b9b03 --- /dev/null +++ b/nebulous/examples/simple-app-python/.gitattributes @@ -0,0 +1,9 @@ +# +# Copyright (C) 2017-2025 Institute of Communication and Computer Systems (imu.iccs.gr) +# +# This Source Code Form is subject to the terms of the Mozilla Public License, v2.0. +# If a copy of the MPL was not distributed with this file, You can obtain one at +# https://www.mozilla.org/en-US/MPL/2.0/ +# + +* text eol=lf \ No newline at end of file diff --git a/nebulous/examples/simple-app-python/Dockerfile b/nebulous/examples/simple-app-python/Dockerfile new file mode 100644 index 0000000..65f23a1 --- /dev/null +++ b/nebulous/examples/simple-app-python/Dockerfile @@ -0,0 +1,27 @@ +# +# Copyright (C) 2017-2025 Institute of Communication and Computer Systems (imu.iccs.gr) +# +# This Source Code Form is subject to the terms of the Mozilla Public License, v2.0. +# If a copy of the MPL was not distributed with this file, You can obtain one at +# https://www.mozilla.org/en-US/MPL/2.0/ +# + +FROM python:3.9.18-slim + +WORKDIR /app +RUN apt-get update && \ + apt-get install -y netcat-traditional && \ + apt-get install -y vim iputils-ping curl telnet && \ + rm -rf /var/lib/apt/lists/* + +COPY requirements.txt /app/ +RUN pip install -r requirements.txt + +COPY simple-app.py /app/ +COPY simple-prometheus-exporter.sh /app/ +COPY entrypoint.sh /app/ +RUN chmod + /app/*.sh + +EXPOSE 8080 + +ENTRYPOINT [ "./entrypoint.sh" ] \ No newline at end of file diff --git a/nebulous/examples/simple-app-python/docker-compose.yml b/nebulous/examples/simple-app-python/docker-compose.yml new file mode 100644 index 0000000..a2e9b86 --- /dev/null +++ b/nebulous/examples/simple-app-python/docker-compose.yml @@ -0,0 +1,23 @@ +# +# Copyright (C) 2017-2025 Institute of Communication and Computer Systems (imu.iccs.gr) +# +# This Source Code Form is subject to the terms of the Mozilla Public License, v2.0. +# If a copy of the MPL was not distributed with this file, You can obtain one at +# https://www.mozilla.org/en-US/MPL/2.0/ +# + + +services: + simple-app: + image: simple-app:latest + environment: + - BROKER_SERVER=host.docker.internal + - BROKER_PORT=61610 + - BROKER_USERNAME=aaa + - BROKER_PASSWORD=111 + - TARGET_TOPIC=some_topic + - SEND_DELAY=10 + - VALUE_MIN=0 + - VALUE_MAX=100 + ports: + - 8080:8080 \ No newline at end of file diff --git a/nebulous/examples/simple-app-python/entrypoint.sh b/nebulous/examples/simple-app-python/entrypoint.sh new file mode 100644 index 0000000..db45ba3 --- /dev/null +++ b/nebulous/examples/simple-app-python/entrypoint.sh @@ -0,0 +1,14 @@ +#!/usr/bin/env bash +# +# Copyright (C) 2017-2025 Institute of Communication and Computer Systems (imu.iccs.gr) +# +# This Source Code Form is subject to the terms of the Mozilla Public License, v2.0. +# If a copy of the MPL was not distributed with this file, You can obtain one at +# https://www.mozilla.org/en-US/MPL/2.0/ +# + +# Start prometheus endpoint in background +./simple-prometheus-exporter.sh & + +# Start simple-app to send messages to broker +python simple-app.py diff --git a/nebulous/examples/simple-app-python/requirements.txt b/nebulous/examples/simple-app-python/requirements.txt new file mode 100644 index 0000000..065650d --- /dev/null +++ b/nebulous/examples/simple-app-python/requirements.txt @@ -0,0 +1,3 @@ +docopt==0.6.2 +stomp.py==8.1.0 +websocket-client==1.7.0 diff --git a/nebulous/examples/simple-app-python/simple-app.py b/nebulous/examples/simple-app-python/simple-app.py new file mode 100644 index 0000000..fb4ab07 --- /dev/null +++ b/nebulous/examples/simple-app-python/simple-app.py @@ -0,0 +1,72 @@ +# +# Copyright (C) 2017-2025 Institute of Communication and Computer Systems (imu.iccs.gr) +# +# This Source Code Form is subject to the terms of the Mozilla Public License, v2.0. +# If a copy of the MPL was not distributed with this file, You can obtain one at +# https://www.mozilla.org/en-US/MPL/2.0/ +# + +import stomp +import time +import calendar +import random +import json +import os +import sys + + +BROKER_SERVER=os.environ.get('BROKER_SERVER') +BROKER_PORT=int(os.environ.get('BROKER_PORT', 61610)) +BROKER_USERNAME=os.environ.get('BROKER_USERNAME') +BROKER_PASSWORD=os.environ.get('BROKER_PASSWORD') +RETRY_CONNECT=os.environ.get('RETRY_CONNECT', 5) + +TARGET_TOPIC='/topic/' + os.environ.get('TARGET_TOPIC', 'simple') +SEND_DELAY=int(os.environ.get('SEND_DELAY', 10)) +VALUE_MIN=float(os.environ.get('VALUE_MIN', 0)) +VALUE_MAX=float(os.environ.get('VALUE_MAX', 100)) + +class MyListener(stomp.ConnectionListener): + def __init__(self, conn): + self.conn = conn + def on_error(self, frame): + print("on_error %s %s", frame.headers, frame.body) + def on_message(self, frame): + print("Received ",frame.body) + def on_disconnected(self): + print('disconnected') + +def eprint(*args, **kwargs): + print(*args, file=sys.stderr, **kwargs) + +while True: + try: + print(f'Connecting to broker: {BROKER_SERVER}:{BROKER_PORT}, as user: {BROKER_USERNAME}...') + sys.stdout.flush() + conn = stomp.Connection([(BROKER_SERVER, BROKER_PORT)]) + conn.set_listener('', MyListener(conn)) + conn.connect(BROKER_USERNAME, BROKER_PASSWORD, wait=True) + print('Connected') + print(f'Sending messages to topic: {TARGET_TOPIC}, every {SEND_DELAY}s. Value range: [{VALUE_MIN}..{VALUE_MAX}]') + sys.stdout.flush() + + while True: + timestamp = calendar.timegm(time.gmtime()) +# message = '{ "metricValue": '+str(random.randint(VALUE_MIN, VALUE_MAX))+', "level": 1, "timestamp": '+str(timestamp)+' }' + payload_body = { + "metricValue": random.uniform(VALUE_MIN, VALUE_MAX), + "level": 1, + "timestamp": timestamp + } + message = json.dumps(payload_body) + print(f"Sending {message}") + sys.stdout.flush() + conn.send(TARGET_TOPIC, message, headers={'type':'textMessage', 'amq-msg-type':'text'}) + + time.sleep(SEND_DELAY) + + except: + eprint("Error:", sys.exc_info()[0]) + eprint(f"Re-connect in {RETRY_CONNECT}s") + sys.stderr.flush() + time.sleep(RETRY_CONNECT) diff --git a/nebulous/examples/simple-app-python/simple-prometheus-exporter.sh b/nebulous/examples/simple-app-python/simple-prometheus-exporter.sh new file mode 100644 index 0000000..c2f1ea1 --- /dev/null +++ b/nebulous/examples/simple-app-python/simple-prometheus-exporter.sh @@ -0,0 +1,50 @@ +#!/bin/bash +# +# Copyright (C) 2017-2025 Institute of Communication and Computer Systems (imu.iccs.gr) +# +# This Source Code Form is subject to the terms of the Mozilla Public License, v2.0. +# If a copy of the MPL was not distributed with this file, You can obtain one at +# https://www.mozilla.org/en-US/MPL/2.0/ +# + +DATE=`command -v date` +CUT=`command -v cut` +SHUF=`command -v shuf` +OD=`command -v od` +NC=`command -v nc` +GREP=`command -v grep` + +PORT=8080 +PATH="/metrics" +METRIC_NAME="random_number" +METRIC_HELP="Random number sequences, generated using various methods (check the labels)" +METRIC_TYPE="gauge" + +# Bash/Nc-based Web server +# See: https://funprojects.blog/2021/04/11/a-web-server-in-1-line-of-bash/ +echo "Starting prometheus endpoint on port ${PORT}" +while true; +#for i in {1..5} +do + REQUEST_PATH=$( { + echo "HTTP/1.1 200 OK" + echo "Content-Type: text/plain; version=0.0.4" + echo -e "" + echo "# HELP ${METRIC_NAME} ${METRIC_HELP}" + echo "# TYPE ${METRIC_NAME} ${METRIC_TYPE}" + TIMESTAMP=`$DATE +%s%N | $CUT -b1-13`; + RND1=`$SHUF -i 0-255 -n 1`; + RND2=`$OD -A n -t d -N 1 /dev/urandom`; + RND2="${RND2#"${RND2%%[![:space:]]*}"}" + RND2="${RND2%"${RND2##*[![:space:]]}"}" + echo "${METRIC_NAME}{method=\"shuf\"} ${RND1} ${TIMESTAMP}" + echo "${METRIC_NAME}{method=\"urandom\"} ${RND2} ${TIMESTAMP}" + } \ + | $NC -l -k -p ${PORT} -q 1 \ + | $GREP "GET /" ; ) + echo $REQUEST_PATH +# if [[ $REQUEST_PATH =~ ^GET\ /exit\ .* ]]; then +# break +# fi +done +echo "Prometheus exporter exited."