diff --git a/.gitignore b/.gitignore
index 66e4e335e7817b3622c0e3d74ea3ad807702da9a..651e1692f9c36007ca84ddbef9050d047a091be3 100644
--- a/.gitignore
+++ b/.gitignore
@@ -12,6 +12,7 @@ __pycache__/
 *.crt
 *.zip
 *.srl
+*.log
 services/nginx/certs/sign_req_body.json
 services/easy_rsa/certs/pki
 services/easy_rsa/certs/*EasyRSA*
@@ -35,4 +36,5 @@ docs/testing_with_postman/package-lock.json
 results
 
 helm/capif/*.lock
-helm/capif/charts
\ No newline at end of file
+helm/capif/charts
+helm/capif/charts/tempo*
diff --git a/helm/DELETE.txt b/helm/DELETE.txt
new file mode 100644
index 0000000000000000000000000000000000000000..2d030d7bc1bbfbdee332aaf691447b30cdea375b
--- /dev/null
+++ b/helm/DELETE.txt
@@ -0,0 +1 @@
+delete me
diff --git a/helm/capif/Chart.yaml b/helm/capif/Chart.yaml
index 0c8eb5f8848a25968679ee8be65691b6a6ae386c..fc0c9676150d16f0579ba61b5e98097d01e26768 100644
--- a/helm/capif/Chart.yaml
+++ b/helm/capif/Chart.yaml
@@ -20,6 +20,8 @@ version: v3.1.6
 # It is recommended to use it with quotes.
 appVersion: "v3.1.6"
 dependencies:
+  - name: helper
+    version: "*"
   - name: "tempo"
     condition: tempo.enabled
     repository: "https://grafana.github.io/helm-charts"
diff --git a/helm/capif/charts/helper/.helmignore b/helm/capif/charts/helper/.helmignore
new file mode 100644
index 0000000000000000000000000000000000000000..0e8a0eb36f4ca2c939201c0d54b5d82a1ea34778
--- /dev/null
+++ b/helm/capif/charts/helper/.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/helm/capif/charts/helper/Chart.yaml b/helm/capif/charts/helper/Chart.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..4ddfbf3967718e22006b5b754b7ec2d751d0e635
--- /dev/null
+++ b/helm/capif/charts/helper/Chart.yaml
@@ -0,0 +1,24 @@
+apiVersion: v2
+name: helper
+description: A 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: "1.16.0"
diff --git a/helm/capif/charts/helper/templates/NOTES.txt b/helm/capif/charts/helper/templates/NOTES.txt
new file mode 100644
index 0000000000000000000000000000000000000000..f8f6f774769a0eb1872df2436de39fd4b89dffc5
--- /dev/null
+++ b/helm/capif/charts/helper/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 "helper.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 "helper.fullname" . }}'
+  export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ include "helper.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 "helper.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/helm/capif/charts/helper/templates/_helpers.tpl b/helm/capif/charts/helper/templates/_helpers.tpl
new file mode 100644
index 0000000000000000000000000000000000000000..f4a197b20c55e50ad4c5bab1462dcdae183dd3db
--- /dev/null
+++ b/helm/capif/charts/helper/templates/_helpers.tpl
@@ -0,0 +1,62 @@
+{{/*
+Expand the name of the chart.
+*/}}
+{{- define "helper.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 "helper.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 "helper.chart" -}}
+{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }}
+{{- end }}
+
+{{/*
+Common labels
+*/}}
+{{- define "helper.labels" -}}
+helm.sh/chart: {{ include "helper.chart" . }}
+{{ include "helper.selectorLabels" . }}
+{{- if .Chart.AppVersion }}
+app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
+{{- end }}
+app.kubernetes.io/managed-by: {{ .Release.Service }}
+{{- end }}
+
+{{/*
+Selector labels
+*/}}
+{{- define "helper.selectorLabels" -}}
+app.kubernetes.io/name: {{ include "helper.name" . }}
+app.kubernetes.io/instance: {{ .Release.Name }}
+{{- end }}
+
+{{/*
+Create the name of the service account to use
+*/}}
+{{- define "helper.serviceAccountName" -}}
+{{- if .Values.serviceAccount.create }}
+{{- default (include "helper.fullname" .) .Values.serviceAccount.name }}
+{{- else }}
+{{- default "default" .Values.serviceAccount.name }}
+{{- end }}
+{{- end }}
diff --git a/helm/capif/charts/helper/templates/deployment.yaml b/helm/capif/charts/helper/templates/deployment.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..a3f43d3ed01828f6e2c086d5649b6d9c5f4aa055
--- /dev/null
+++ b/helm/capif/charts/helper/templates/deployment.yaml
@@ -0,0 +1,76 @@
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+  name: {{ include "helper.fullname" . }}
+  labels:
+    {{- include "helper.labels" . | nindent 4 }}
+spec:
+  {{- if not .Values.autoscaling.enabled }}
+  replicas: {{ .Values.replicaCount }}
+  {{- end }}
+  selector:
+    matchLabels:
+      {{- include "helper.selectorLabels" . | nindent 6 }}
+  template:
+    metadata:
+      annotations:
+        date: "{{  now | unixEpoch }}"
+        checksum/config: {{ include (print $.Template.BasePath "/ocf-helper-configmap.yaml") . | sha256sum }}
+      labels:
+        {{- include "helper.labels" . | nindent 8 }}
+        {{- with .Values.podLabels }}
+        {{- toYaml . | nindent 8 }}
+        {{- end }}
+    spec:
+      {{- with .Values.imagePullSecrets }}
+      imagePullSecrets:
+        {{- toYaml . | nindent 8 }}
+      {{- end }}
+      serviceAccountName: {{ include "helper.serviceAccountName" . }}
+      securityContext:
+        {{- toYaml .Values.podSecurityContext | nindent 8 }}
+      containers:
+        - name: {{ .Chart.Name }}
+          securityContext:
+            {{- toYaml .Values.securityContext | nindent 12 }}
+          image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}"
+          imagePullPolicy: {{ .Values.image.pullPolicy }}
+          ports:
+            - name: http
+              containerPort: {{ .Values.service.port }}
+              protocol: TCP
+          livenessProbe:
+            {{- toYaml .Values.livenessProbe | nindent 12 }}
+          readinessProbe:
+            {{- toYaml .Values.readinessProbe | nindent 12 }}
+          resources:
+            {{- toYaml .Values.resources | nindent 12 }}
+          {{- with .Values.volumeMounts }}
+          volumeMounts:
+            {{- toYaml . | nindent 12 }}
+          {{- end }}
+          env:
+            - name: CAPIF_HOSTNAME
+              value: {{ quote .Values.env.capifHostname }}
+            - name: VAULT_HOSTNAME
+              value: {{ quote .Values.env.vaultHostname }}
+            - name: VAULT_PORT
+              value: {{ quote .Values.env.vaultPort }}
+            - name: VAULT_ACCESS_TOKEN
+              value: {{ quote .Values.env.vaultAccessToken }}
+      {{- with .Values.volumes }}
+      volumes:
+        {{- toYaml . | nindent 8 }}
+      {{- end }}
+      {{- with .Values.nodeSelector }}
+      nodeSelector:
+        {{- toYaml . | nindent 8 }}
+      {{- end }}
+      {{- with .Values.affinity }}
+      affinity:
+        {{- toYaml . | nindent 8 }}
+      {{- end }}
+      {{- with .Values.tolerations }}
+      tolerations:
+        {{- toYaml . | nindent 8 }}
+      {{- end }}
diff --git a/helm/capif/charts/helper/templates/hpa.yaml b/helm/capif/charts/helper/templates/hpa.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..046148d39279bc420739dfd71c5ef35e1498c513
--- /dev/null
+++ b/helm/capif/charts/helper/templates/hpa.yaml
@@ -0,0 +1,32 @@
+{{- if .Values.autoscaling.enabled }}
+apiVersion: autoscaling/v2
+kind: HorizontalPodAutoscaler
+metadata:
+  name: {{ include "helper.fullname" . }}
+  labels:
+    {{- include "helper.labels" . | nindent 4 }}
+spec:
+  scaleTargetRef:
+    apiVersion: apps/v1
+    kind: Deployment
+    name: {{ include "helper.fullname" . }}
+  minReplicas: {{ .Values.autoscaling.minReplicas }}
+  maxReplicas: {{ .Values.autoscaling.maxReplicas }}
+  metrics:
+    {{- if .Values.autoscaling.targetCPUUtilizationPercentage }}
+    - type: Resource
+      resource:
+        name: cpu
+        target:
+          type: Utilization
+          averageUtilization: {{ .Values.autoscaling.targetCPUUtilizationPercentage }}
+    {{- end }}
+    {{- if .Values.autoscaling.targetMemoryUtilizationPercentage }}
+    - type: Resource
+      resource:
+        name: memory
+        target:
+          type: Utilization
+          averageUtilization: {{ .Values.autoscaling.targetMemoryUtilizationPercentage }}
+    {{- end }}
+{{- end }}
diff --git a/helm/capif/charts/helper/templates/ingress.yaml b/helm/capif/charts/helper/templates/ingress.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..b3817bf910c95f374b285b6ca8db0c3a5d079c16
--- /dev/null
+++ b/helm/capif/charts/helper/templates/ingress.yaml
@@ -0,0 +1,61 @@
+{{- if .Values.ingress.enabled -}}
+{{- $fullName := include "helper.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 "helper.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/helm/capif/charts/helper/templates/ocf-helper-configmap.yaml b/helm/capif/charts/helper/templates/ocf-helper-configmap.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..796a55cf7e451343b05c793a4bb1eb40486029f2
--- /dev/null
+++ b/helm/capif/charts/helper/templates/ocf-helper-configmap.yaml
@@ -0,0 +1,24 @@
+apiVersion: v1
+kind: ConfigMap
+metadata:
+  name: ocf-helper-configmap
+data:
+  config.yaml: |
+    mongo: {
+      'user': '{{ .Values.env.mongoInitdbRootUsername }}',
+      'password': '{{ .Values.env.mongoInitdbRootPassword }}',
+      'db': 'capif',
+      'invoker_col': 'invokerdetails',
+      'provider_col': 'providerenrolmentdetails',
+      'col_services': "serviceapidescriptions",
+      'col_security': "security",
+      'col_event': "eventsdetails",
+      'host': '{{ .Values.env.mongoHost }}',
+      'port': "{{ .Values.env.mongoPort }}"
+    }
+
+    ca_factory: {
+      "url": {{ quote .Values.env.vaultHostname }},
+      "port": {{ quote .Values.env.vaultPort }},
+      "token": {{ quote .Values.env.vaultAccessToken }}
+    }
\ No newline at end of file
diff --git a/helm/capif/charts/helper/templates/service.yaml b/helm/capif/charts/helper/templates/service.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..4a743709cbb1d317b323484402247bffacee3aaa
--- /dev/null
+++ b/helm/capif/charts/helper/templates/service.yaml
@@ -0,0 +1,15 @@
+apiVersion: v1
+kind: Service
+metadata:
+  name: helper
+  labels:
+    {{- include "helper.labels" . | nindent 4 }}
+spec:
+  type: {{ .Values.service.type }}
+  ports:
+    - port: {{ .Values.service.port }}
+      targetPort: http
+      protocol: TCP
+      name: http
+  selector:
+    {{- include "helper.selectorLabels" . | nindent 4 }}
diff --git a/helm/capif/charts/helper/templates/serviceaccount.yaml b/helm/capif/charts/helper/templates/serviceaccount.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..e0e6d79313e967d9ae9bedc817a49b6e82aa7642
--- /dev/null
+++ b/helm/capif/charts/helper/templates/serviceaccount.yaml
@@ -0,0 +1,13 @@
+{{- if .Values.serviceAccount.create -}}
+apiVersion: v1
+kind: ServiceAccount
+metadata:
+  name: {{ include "helper.serviceAccountName" . }}
+  labels:
+    {{- include "helper.labels" . | nindent 4 }}
+  {{- with .Values.serviceAccount.annotations }}
+  annotations:
+    {{- toYaml . | nindent 4 }}
+  {{- end }}
+automountServiceAccountToken: {{ .Values.serviceAccount.automount }}
+{{- end }}
diff --git a/helm/capif/charts/helper/templates/tests/test-connection.yaml b/helm/capif/charts/helper/templates/tests/test-connection.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..f3959cc03d5bb449a71b2b24a09fdf5f6bf3702c
--- /dev/null
+++ b/helm/capif/charts/helper/templates/tests/test-connection.yaml
@@ -0,0 +1,15 @@
+apiVersion: v1
+kind: Pod
+metadata:
+  name: "{{ include "helper.fullname" . }}-test-connection"
+  labels:
+    {{- include "helper.labels" . | nindent 4 }}
+  annotations:
+    "helm.sh/hook": test
+spec:
+  containers:
+    - name: wget
+      image: busybox
+      command: ['wget']
+      args: ['{{ include "helper.fullname" . }}:{{ .Values.service.port }}']
+  restartPolicy: Never
diff --git a/helm/capif/charts/helper/values.yaml b/helm/capif/charts/helper/values.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..147c003af380d92300cac7baa0c486ba71753fce
--- /dev/null
+++ b/helm/capif/charts/helper/values.yaml
@@ -0,0 +1,119 @@
+# Default values for helper.
+# This is a YAML-formatted file.
+# Declare variables to be passed into your templates.
+
+replicaCount: 1
+
+image:
+  repository: "helper"
+  pullPolicy: Always
+  # Overrides the image tag whose default is the chart appVersion.
+  tag: ""
+
+imagePullSecrets: []
+nameOverride: ""
+fullnameOverride: ""
+
+env:
+  vaultHostname: vault-internal.mon.svc.cluster.local
+  vaultPort: 8200
+  vaultAccessToken: dev-only-token
+  mongoHost: mongo
+  mongoPort: 27017
+  capifHostname: capif
+  mongoInitdbRootUsername: root
+  mongoInitdbRootPassword: example 
+
+serviceAccount:
+  # Specifies whether a service account should be created
+  create: true
+  # Automatically mount a ServiceAccount's API credentials?
+  automount: 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: ""
+
+podAnnotations:
+  app: ocf-helper
+
+podLabels: {}
+
+podSecurityContext: {}
+  # fsGroup: 2000
+
+securityContext: {}
+  # capabilities:
+  #   drop:
+  #   - ALL
+  # readOnlyRootFilesystem: true
+  # runAsNonRoot: true
+  # runAsUser: 1000
+
+service:
+  type: ClusterIP
+  port: 8080
+
+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
+
+livenessProbe:
+  tcpSocket:
+    port: 8080
+readinessProbe:
+  tcpSocket:
+    port: 8080
+
+autoscaling:
+  enabled: false
+  minReplicas: 1
+  maxReplicas: 100
+  targetCPUUtilizationPercentage: 80
+  # targetMemoryUtilizationPercentage: 80
+
+# Additional volumes on the output Deployment definition.
+volumes:
+ - name: ocf-helper-configmap
+   configMap:
+    name: ocf-helper-configmap
+    items:
+    - key: "config.yaml"
+      path: "config.yaml"
+
+# Additional volumeMounts on the output Deployment definition.
+volumeMounts:
+ - name: ocf-helper-configmap
+   mountPath: /usr/src/app/config.yaml
+   subPath: config.yaml
+
+nodeSelector: {}
+
+tolerations: []
+
+affinity: {}
diff --git a/helm/capif/templates/mongo-register-pvc.yaml b/helm/capif/templates/mongo-register-pvc.yaml
index 4d1a259bb9fe43636afb4bf19aa0f3a706e4d04f..b5a11d663ee0d10949768b4f1073908154b5d0c2 100644
--- a/helm/capif/templates/mongo-register-pvc.yaml
+++ b/helm/capif/templates/mongo-register-pvc.yaml
@@ -9,7 +9,7 @@ metadata:
 spec:
   storageClassName: {{ .Values.mongoRegister.mongo.persistence.storageClass }}
   accessModes:
-    - ReadWriteOnce
+    - ReadWriteMany
   resources:
     requests:
       storage: {{ .Values.mongoRegister.mongo.persistence.storage }}
diff --git a/helm/capif/templates/register-configmap.yaml b/helm/capif/templates/register-configmap.yaml
index 51293a5b7824d6688d9545d600c5571f9db4d55d..7dcc300663333ac8276f068571b6a8380df4458e 100644
--- a/helm/capif/templates/register-configmap.yaml
+++ b/helm/capif/templates/register-configmap.yaml
@@ -18,4 +18,10 @@ data:
       "url": "{{ .Values.parametersVault.env.vaultHostname }}",
       "port": "{{ .Values.parametersVault.env.vaultPort }}",
       "token": "{{ .Values.parametersVault.env.vaultAccessToken }}"
+    }
+    register: {
+      register_uuid: '6ba7b810-9dad-11d1-80b4-00c04fd430c8',
+      refresh_expiration: 30, #days
+      token_expiration: 10, #mins
+      admin_users: {admin: "password123"}
     }
\ No newline at end of file
diff --git a/helm/capif/values.yaml b/helm/capif/values.yaml
index 43083490092bc0e0656336ab460db9d3feaa5d45..f017ac0f0add5d0c6f03325104c3b5a3dbd2a365 100644
--- a/helm/capif/values.yaml
+++ b/helm/capif/values.yaml
@@ -36,7 +36,7 @@ accessControlPolicy:
 
 CapifClient:
   # -- If enable capif client.
-  enable: "true"
+  enable: ""
   image:
       # -- The docker image repository to use
       repository: "public.ecr.aws/o2v4a8t6/opencapif/client"
@@ -523,6 +523,18 @@ parametersVault:
     vaultHostname: vault-internal.mon.svc.cluster.local
     vaultPort: 8200
     vaultAccessToken: dev-only-token
+
+helper:
+  env:
+    vaultHostname: vault-internal.mon.svc.cluster.local
+    vaultPort: 8200
+    vaultAccessToken: dev-only-token
+    mongoHost: mongo
+    mongoPort: 27017
+    capifHostname: my-capif.apps.ocp-epg.hi.inet
+    mongoInitdbRootUsername: root
+    mongoInitdbRootPassword: example 
+    
 # -- With tempo.enabled: false. It won't be deployed
 # -- If monitoring.enable: "true". Also enable tempo.enabled: true
 tempo:
@@ -607,7 +619,7 @@ monitoring:
   prometheus:
       # -- With prometheus.enabled: "". It won't be deployed. prometheus.enable: "true"
       # -- It will deploy prometheus
-      enable: "true"
+      enable: ""
       image: 
         # -- The docker image repository to use
         repository: "prom/prometheus"
@@ -636,7 +648,7 @@ monitoring:
           # kubernetes.io/ingress.class: nginx
           # kubernetes.io/tls-acme: "true"
         hosts:
-          - host: prometheus.5gnacar.int
+          - host: prometheus.test.int
             paths:
               - path: /
                 pathType: Prefix
@@ -647,7 +659,7 @@ monitoring:
       # -- If ingressRoute enable=true, use monitoring.prometheus.ingress.enabled=""
       ingressRoute:
         enable: ""
-        host:  prometheus.5gnacar.int
+        host:  prometheus.test.int
   grafana:
       image: 
         # -- The docker image repository to use
@@ -686,7 +698,7 @@ monitoring:
           # kubernetes.io/ingress.class: nginx
           # kubernetes.io/tls-acme: "true"
         hosts:
-          - host: grafana.5gnacar.int
+          - host: grafana.test.int
             paths:
               - path: /
                 pathType: Prefix
diff --git a/services/TS29222_CAPIF_API_Invoker_Management_API/api_invoker_management/controllers/default_controller.py b/services/TS29222_CAPIF_API_Invoker_Management_API/api_invoker_management/controllers/default_controller.py
index 9f94b19ee0222992649bf903fc19a7ea3e8577e9..9ea3c42833a20adcf5d6ef598fc17de3efdfd644 100644
--- a/services/TS29222_CAPIF_API_Invoker_Management_API/api_invoker_management/controllers/default_controller.py
+++ b/services/TS29222_CAPIF_API_Invoker_Management_API/api_invoker_management/controllers/default_controller.py
@@ -12,7 +12,6 @@ from ..core.publisher import Publisher
 from functools import wraps
 
 invoker_operations = InvokerManagementOperations()
-publisher_ops = Publisher()
 valid_user = ControlAccess()
 
 
@@ -56,11 +55,6 @@ def onboarded_invokers_onboarding_id_delete(onboarding_id):  # noqa: E501
     current_app.logger.info("Removing invoker")
     res = invoker_operations.remove_apiinvokerenrolmentdetail(onboarding_id)
 
-    if res.status_code == 204:
-        current_app.logger.info("Invoker Removed")
-        publisher_ops.publish_message("events", "API_INVOKER_OFFBOARDED")
-        publisher_ops.publish_message("internal-messages", f"invoker-removed:{onboarding_id}")
-
     return res
 
 @cert_validation()
@@ -81,10 +75,6 @@ def onboarded_invokers_onboarding_id_put(onboarding_id, body):  # noqa: E501
         body = APIInvokerEnrolmentDetails.from_dict(connexion.request.get_json())  # noqa: E501
     res = invoker_operations.update_apiinvokerenrolmentdetail(onboarding_id,body)
 
-    if res.status_code == 200:
-        current_app.logger.info("Invoker Updated")
-        publisher_ops.publish_message("events", "API_INVOKER_UPDATED")
-
     return res
 
 
@@ -108,8 +98,5 @@ def onboarded_invokers_post(body):  # noqa: E501
 
     current_app.logger.info("Creating Invoker")
     res = invoker_operations.add_apiinvokerenrolmentdetail(body, username, uuid)
-    if res.status_code == 201:
-        current_app.logger.info("Invoker Created")
-        publisher_ops.publish_message("events", "API_INVOKER_ONBOARDED")
 
     return res
diff --git a/services/TS29222_CAPIF_API_Invoker_Management_API/api_invoker_management/core/apiinvokerenrolmentdetails.py b/services/TS29222_CAPIF_API_Invoker_Management_API/api_invoker_management/core/apiinvokerenrolmentdetails.py
index 7becdca29a7dbca35a1dbc89cf1c966da288cc75..3c3c38bdcc8f19bcf05deb7573e2a1f40110ccee 100644
--- a/services/TS29222_CAPIF_API_Invoker_Management_API/api_invoker_management/core/apiinvokerenrolmentdetails.py
+++ b/services/TS29222_CAPIF_API_Invoker_Management_API/api_invoker_management/core/apiinvokerenrolmentdetails.py
@@ -11,9 +11,10 @@ from .auth_manager import AuthManager
 from .resources import Resource
 from ..config import Config
 from api_invoker_management.models.api_invoker_enrolment_details import APIInvokerEnrolmentDetails
+from .redis_event import RedisEvent
+from .publisher import Publisher
 
-
-
+publisher_ops = Publisher()
 class InvokerManagementOperations(Resource):
 
     def __check_api_invoker_id(self, api_invoker_id):
@@ -83,7 +84,7 @@ class InvokerManagementOperations(Resource):
         invoker_dict["username"]=username
         invoker_dict["uuid"]=uuid
 
-        mycol.insert_one(apiinvokerenrolmentdetail.to_dict())
+        mycol.insert_one(invoker_dict)
 
         current_app.logger.debug("Invoker inserted in database")
         current_app.logger.debug("Netapp onboarded sucessfuly")
@@ -92,6 +93,10 @@ class InvokerManagementOperations(Resource):
 
         res = make_response(object=dict_to_camel_case(clean_empty(apiinvokerenrolmentdetail.to_dict())), status=201)
         res.headers['Location'] = "/api-invoker-management/v1/onboardedInvokers/" + str(api_invoker_id)
+
+        if res.status_code == 201:
+            current_app.logger.info("Invoker Created")
+            RedisEvent("API_INVOKER_ONBOARDED", "apiInvokerIds", [str(api_invoker_id)]).send_event()
         return res
 
         # except Exception as e:
@@ -131,6 +136,9 @@ class InvokerManagementOperations(Resource):
             invoker_updated = APIInvokerEnrolmentDetails().from_dict(dict_to_camel_case(result))
 
             res = make_response(object=dict_to_camel_case(clean_empty(invoker_updated.to_dict())), status=200)
+            if res.status_code == 200:
+                current_app.logger.info("Invoker Updated")
+                RedisEvent("API_INVOKER_UPDATED", "apiInvokerIds", [onboard_id]).send_event()
             return res
 
         except Exception as e:
@@ -154,7 +162,12 @@ class InvokerManagementOperations(Resource):
             current_app.logger.debug("Invoker resource removed from database")
             current_app.logger.debug("Netapp offboarded sucessfuly")
             out =  "The Netapp matching onboardingId  " + onboard_id + " was offboarded."
-            return make_response(out, status=204)
+            res = make_response(out, status=204)
+            if res.status_code == 204:
+                current_app.logger.info("Invoker Removed")
+                RedisEvent("API_INVOKER_OFFBOARDED", "apiInvokerIds", [onboard_id]).send_event()
+                publisher_ops.publish_message("internal-messages", f"invoker-removed:{onboard_id}")
+            return res
 
         except Exception as e:
             exception = "An exception occurred in remove invoker"
diff --git a/services/TS29222_CAPIF_API_Invoker_Management_API/api_invoker_management/core/redis_event.py b/services/TS29222_CAPIF_API_Invoker_Management_API/api_invoker_management/core/redis_event.py
new file mode 100644
index 0000000000000000000000000000000000000000..aadbdbb6b3116cf288648de41effdb12b9ca9143
--- /dev/null
+++ b/services/TS29222_CAPIF_API_Invoker_Management_API/api_invoker_management/core/redis_event.py
@@ -0,0 +1,41 @@
+from ..encoder import JSONEncoder
+from .publisher import Publisher
+import json
+
+publisher_ops = Publisher()
+
+
+class RedisEvent():
+    def __init__(self, event, event_detail_key=None, information=None) -> None:
+        self.EVENTS_ENUM = [
+            'SERVICE_API_AVAILABLE',
+            'SERVICE_API_UNAVAILABLE',
+            'SERVICE_API_UPDATE',
+            'API_INVOKER_ONBOARDED',
+            'API_INVOKER_OFFBOARDED',
+            'SERVICE_API_INVOCATION_SUCCESS',
+            'SERVICE_API_INVOCATION_FAILURE',
+            'ACCESS_CONTROL_POLICY_UPDATE',
+            'ACCESS_CONTROL_POLICY_UNAVAILABLE',
+            'API_INVOKER_AUTHORIZATION_REVOKED',
+            'API_INVOKER_UPDATED',
+            'API_TOPOLOGY_HIDING_CREATED',
+            'API_TOPOLOGY_HIDING_REVOKED']
+        if event not in self.EVENTS_ENUM:
+            raise Exception(
+                "Event (" + event + ") is not on event enum (" + ','.join(self.EVENTS_ENUM) + ")")
+        self.redis_event = {
+            "event": event
+        }
+        if event_detail_key != None and information != None:
+            self.redis_event['key'] = event_detail_key
+            self.redis_event['information'] = information
+
+    def to_string(self):
+        return json.dumps(self.redis_event, cls=JSONEncoder)
+
+    def send_event(self):
+        publisher_ops.publish_message("events", self.to_string())
+
+    def __call__(self):
+        return self.redis_event
diff --git a/services/TS29222_CAPIF_API_Invoker_Management_API/api_invoker_management/db/db.py b/services/TS29222_CAPIF_API_Invoker_Management_API/api_invoker_management/db/db.py
index bb933931c94cabeb427afe476c2afc6882ebdacc..6cb5a93bca3e130f884139e55951259ee7cb412a 100644
--- a/services/TS29222_CAPIF_API_Invoker_Management_API/api_invoker_management/db/db.py
+++ b/services/TS29222_CAPIF_API_Invoker_Management_API/api_invoker_management/db/db.py
@@ -15,7 +15,6 @@ class MongoDatabse():
         self.config = Config().get_config()
         self.db = self.__connect()
         self.invoker_enrolment_details = self.config['mongo']['col']
-        self.capif_users = self.config['mongo']['capif_users_col']
         self.service_col = self.config['mongo']["service_col"]
         self.certs_col = self.config['mongo']['certs_col']
 
diff --git a/services/TS29222_CAPIF_API_Invoker_Management_API/config.yaml b/services/TS29222_CAPIF_API_Invoker_Management_API/config.yaml
index e208a78ccfe2a48d16071e149b36575ba865e4d7..2a14561d485ebb8a81779e988a54b31f9c894fbb 100644
--- a/services/TS29222_CAPIF_API_Invoker_Management_API/config.yaml
+++ b/services/TS29222_CAPIF_API_Invoker_Management_API/config.yaml
@@ -3,20 +3,12 @@ mongo: {
   'password': 'example',
   'db': 'capif',
   'col': 'invokerdetails',
-  'capif_users_col': "user",
   'certs_col': "certs",
   'service_col': 'serviceapidescriptions',
   'host': 'mongo',
   'port': "27017"
 }
-mongo_register: {
-  'user': 'root',
-  'password': 'example',
-  'db': 'capif_users',
-  'col': 'user',
-  'host': 'mongo_register',
-  'port': '27017'
-}
+
 ca_factory: {
   "url": "vault",
   "port": "8200",
diff --git a/services/TS29222_CAPIF_API_Provider_Management_API/api_provider_management/core/provider_enrolment_details_api.py b/services/TS29222_CAPIF_API_Provider_Management_API/api_provider_management/core/provider_enrolment_details_api.py
index 61ab74d5c4720a1a6439ea16c4a3ec18339fec5b..0b54ee8152e85552bd99c5d64560498e67e69721 100644
--- a/services/TS29222_CAPIF_API_Provider_Management_API/api_provider_management/core/provider_enrolment_details_api.py
+++ b/services/TS29222_CAPIF_API_Provider_Management_API/api_provider_management/core/provider_enrolment_details_api.py
@@ -94,7 +94,7 @@ class ProviderManagementOperations(Resource):
 
             self.auth_manager.remove_auth_provider([apf_id[0], aef_id[0], amf_id[0]])
 
-            self.publish_ops.publish_message("internal-messages", f"provider-removed:{aef_id[0]}:{apf_id[0]}")
+            self.publish_ops.publish_message("internal-messages", f"provider-removed:{aef_id[0]}:{apf_id[0]}:{amf_id[0]}")
             return make_response(object=out, status=204)
 
         except Exception as e:
diff --git a/services/TS29222_CAPIF_API_Provider_Management_API/api_provider_management/db/db.py b/services/TS29222_CAPIF_API_Provider_Management_API/api_provider_management/db/db.py
index e2aba93033999abd5e5de371296534cf4f54761c..fcc6169db2432423538a7ea2dbf07ca0b3f3824c 100644
--- a/services/TS29222_CAPIF_API_Provider_Management_API/api_provider_management/db/db.py
+++ b/services/TS29222_CAPIF_API_Provider_Management_API/api_provider_management/db/db.py
@@ -16,7 +16,6 @@ class MongoDatabse():
         self.config = Config().get_config()
         self.db = self.__connect()
         self.provider_enrolment_details = self.config['mongo']['col']
-        self.capif_users = self.config['mongo']['capif_users']
         self.certs_col = self.config['mongo']['certs_col']
 
     def get_col_by_name(self, name):
diff --git a/services/TS29222_CAPIF_API_Provider_Management_API/config.yaml b/services/TS29222_CAPIF_API_Provider_Management_API/config.yaml
index 8de29a4385fffc05236cae4a9e72f9490969e47f..7d1899ab7a860fa1a6a0390f5fa4cf85271dc434 100644
--- a/services/TS29222_CAPIF_API_Provider_Management_API/config.yaml
+++ b/services/TS29222_CAPIF_API_Provider_Management_API/config.yaml
@@ -4,19 +4,10 @@ mongo: {
   'db': 'capif',
   'col': 'providerenrolmentdetails',
   'certs_col': "certs",
-  'capif_users': 'user',
   'host': 'mongo',
   'port': "27017"
 }
 
-mongo_register: {
-  'user': 'root',
-  'password': 'example',
-  'db': 'capif_users',
-  'col': 'user',
-  'host': 'mongo_register',
-  'port': '27017'
-}
 
 ca_factory: {
   "url": "vault",
diff --git a/services/TS29222_CAPIF_Access_Control_Policy_API/capif_acl/core/accesscontrolpolicyapi.py b/services/TS29222_CAPIF_Access_Control_Policy_API/capif_acl/core/accesscontrolpolicyapi.py
index 4a7280d2dcc40319f21b65d00bda4229fee0148d..d82ac984b04e746ad372a3e0574a67e50a77d88f 100644
--- a/services/TS29222_CAPIF_Access_Control_Policy_API/capif_acl/core/accesscontrolpolicyapi.py
+++ b/services/TS29222_CAPIF_Access_Control_Policy_API/capif_acl/core/accesscontrolpolicyapi.py
@@ -21,8 +21,8 @@ class accessControlPolicyApi(Resource):
             projection = {"_id":0}
 
             if api_invoker_id is not None:
-                query['apiInvokerPolicies.api_invoker_id'] = api_invoker_id
-                projection['apiInvokerPolicies.$'] = 1
+                query['api_invoker_policies.api_invoker_id'] = api_invoker_id
+                projection['api_invoker_policies.$'] = 1
             if supported_features is not None:
                 current_app.logger.debug(f"SupportedFeatures present on query with value {supported_features}, but currently not used")
             
@@ -38,8 +38,8 @@ class accessControlPolicyApi(Resource):
 
             current_app.logger.debug(policies)
 
-            api_invoker_policies = policies[0]['apiInvokerPolicies']
-            current_app.logger.debug(f"apiinvokerPolicies: {api_invoker_policies}")
+            api_invoker_policies = policies[0]['api_invoker_policies']
+            current_app.logger.debug(f"api_invoker_policies: {api_invoker_policies}")
             if not api_invoker_policies:
                 current_app.logger.info(f"ACLs list is present but empty, then no ACLs found for the requested service: {service_api_id}, aef_id: {aef_id}, invoker: {api_invoker_id} and supportedFeatures: {supported_features}")
                 #Not found error
diff --git a/services/TS29222_CAPIF_Access_Control_Policy_API/capif_acl/core/internal_service_ops.py b/services/TS29222_CAPIF_Access_Control_Policy_API/capif_acl/core/internal_service_ops.py
index 82d1f43d8060457f741795d1590d2842df203dd2..68c7ef57e1b9777022dbdb78bd40cddfee8d69c6 100644
--- a/services/TS29222_CAPIF_Access_Control_Policy_API/capif_acl/core/internal_service_ops.py
+++ b/services/TS29222_CAPIF_Access_Control_Policy_API/capif_acl/core/internal_service_ops.py
@@ -4,84 +4,109 @@ from .resources import Resource
 from models.api_invoker_policy import ApiInvokerPolicy
 from models.time_range_list import TimeRangeList
 from datetime import datetime, timedelta
+
 from core.publisher import Publisher
+from .redis_event import RedisEvent
+from util import dict_to_camel_case, clean_empty
 
 publisher_ops = Publisher()
 
 
 class InternalServiceOps(Resource):
-        
+
     def create_acl(self, invoker_id, service_id, aef_id):
 
         current_app.logger.info(f"Creating ACL for invoker: {invoker_id}")
 
         if "acls" not in self.db.db.list_collection_names():
             self.db.db.create_collection("acls")
-        
+
         mycol = self.db.get_col_by_name(self.db.acls)
 
-        res = mycol.find_one({"service_id": service_id, "aef_id":aef_id}, {"_id":0})
-        
+        res = mycol.find_one(
+            {"service_id": service_id, "aef_id": aef_id}, {"_id": 0})
+
         if res:
-            current_app.logger.info(f"Adding invoker ACL for invoker {invoker_id}")
-            range_list = [TimeRangeList(datetime.utcnow(), datetime.utcnow()+timedelta(days=365))]
-            invoker_acl = ApiInvokerPolicy(invoker_id, current_app.config["invocations"]["total"], current_app.config["invocations"]["perSecond"], range_list)
-            r = mycol.find_one({"service_id": service_id, "aef_id":aef_id, "apiInvokerPolicies.api_invoker_id": invoker_id}, {"_id":0})
+            current_app.logger.info(
+                f"Adding invoker ACL for invoker {invoker_id}")
+            range_list = [TimeRangeList(
+                datetime.utcnow(), datetime.utcnow()+timedelta(days=365))]
+            invoker_acl = ApiInvokerPolicy(
+                invoker_id, current_app.config["invocations"]["total"], current_app.config["invocations"]["perSecond"], range_list)
+            r = mycol.find_one({"service_id": service_id, "aef_id": aef_id,
+                               "api_invoker_policies.api_invoker_id": invoker_id}, {"_id": 0})
             if r is None:
-                mycol.update_one({"service_id": service_id, "aef_id":aef_id }, {"$push":{"apiInvokerPolicies":invoker_acl.to_dict()}})
+                mycol.update_one({"service_id": service_id, "aef_id": aef_id}, {
+                                 "$push": {"api_invoker_policies": invoker_acl.to_dict()}})
         else:
-            current_app.logger.info(f"Creating service ACLs for service: {service_id}")
-            range_list = [TimeRangeList(datetime.utcnow(), datetime.utcnow()+timedelta(days=365))]
-            invoker_acl = ApiInvokerPolicy(invoker_id, current_app.config["invocations"]["total"], current_app.config["invocations"]["perSecond"], range_list)
-            
-            
+            current_app.logger.info(
+                f"Creating service ACLs for service: {service_id}")
+            range_list = [TimeRangeList(
+                datetime.utcnow(), datetime.utcnow()+timedelta(days=365))]
+            invoker_acl = ApiInvokerPolicy(
+                invoker_id, current_app.config["invocations"]["total"], current_app.config["invocations"]["perSecond"], range_list)
 
             service_acls = {
                 "service_id": service_id,
                 "aef_id": aef_id,
-                "apiInvokerPolicies": [invoker_acl.to_dict()]
+                "api_invoker_policies": [invoker_acl.to_dict()]
             }
-            mycol.insert_one(service_acls)
-            publisher_ops.publish_message("events", "ACCESS_CONTROL_POLICY_UPDATE")
-        
-        current_app.logger.info(f"Invoker ACL added for invoker: {invoker_id} for service: {service_id}")
-    
+            result = mycol.insert_one(service_acls)
+
+            inserted_service_acls=mycol.find_one({"_id": result.inserted_id}, {"_id": 0})
+            current_app.logger.info(inserted_service_acls)
+            inserted_service_acls_camel=dict_to_camel_case(inserted_service_acls)
+            current_app.logger.info(inserted_service_acls_camel)
+            accCtrlPolListExt = {
+                "apiId": service_id,
+                "apiInvokerPolicies": inserted_service_acls_camel['apiInvokerPolicies']
+            }
+            RedisEvent("ACCESS_CONTROL_POLICY_UPDATE",
+                       "accCtrlPolList", accCtrlPolListExt).send_event()
+
+        current_app.logger.info(
+            f"Invoker ACL added for invoker: {invoker_id} for service: {service_id}")
+
     def remove_acl(self, invoker_id, service_id, aef_id):
 
         current_app.logger.info(f"Removing ACL for invoker: {invoker_id}")
-        
+
         mycol = self.db.get_col_by_name(self.db.acls)
 
-        res = mycol.find_one({"service_id": service_id, "aef_id":aef_id}, {"_id":0})
-        
+        res = mycol.find_one(
+            {"service_id": service_id, "aef_id": aef_id}, {"_id": 0})
+
         if res:
-           mycol.update_many({"service_id": service_id, "aef_id":aef_id},
-                           {"$pull":{ "apiInvokerPolicies": { "api_invoker_id": invoker_id }}}
-                           )
+            mycol.update_many({"service_id": service_id, "aef_id": aef_id},
+                              {"$pull": {"api_invoker_policies": {
+                                  "api_invoker_id": invoker_id}}}
+                              )
         else:
-            current_app.logger.info(f"Not found: {service_id} for api : {service_id}")
-        
-        publisher_ops.publish_message("events", "ACCESS_CONTROL_POLICY_UNAVAILABLE")
-            
-        current_app.logger.info(f"Invoker ACL removed for invoker: {invoker_id} for service: {service_id}")
-    
+            current_app.logger.info(
+                f"Not found: {service_id} for api : {service_id}")
+
+        RedisEvent("ACCESS_CONTROL_POLICY_UNAVAILABLE").send_event()
+
+        current_app.logger.info(
+            f"Invoker ACL removed for invoker: {invoker_id} for service: {service_id}")
+
     def remove_invoker_acl(self, invoker_id):
 
         current_app.logger.info(f"Removing ACLs for invoker: {invoker_id}")
         mycol = self.db.get_col_by_name(self.db.acls)
-        
-        mycol.update_many({"apiInvokerPolicies.api_invoker_id": invoker_id},
-                           {"$pull":{ "apiInvokerPolicies": { "api_invoker_id": invoker_id }}}
-                           )
-        publisher_ops.publish_message("events", "ACCESS_CONTROL_POLICY_UNAVAILABLE")
+
+        mycol.update_many({"api_invoker_policies.api_invoker_id": invoker_id},
+                          {"$pull": {"api_invoker_policies": {
+                              "api_invoker_id": invoker_id}}}
+                          )
+        RedisEvent("ACCESS_CONTROL_POLICY_UNAVAILABLE").send_event()
         current_app.logger.info(f"ACLs for invoker: {invoker_id} removed")
-    
+
     def remove_provider_acls(self, id):
 
         current_app.logger.info(f"Removing ACLs for provider/service: {id}")
         mycol = self.db.get_col_by_name(self.db.acls)
-        
-        mycol.delete_many({"$or":[{"service_id":id}, {"aef_id":id}]}
-                           )
-        publisher_ops.publish_message("events", "ACCESS_CONTROL_POLICY_UNAVAILABLE")
-        current_app.logger.info(f"ACLs for provider/service: {id} removed")
\ No newline at end of file
+
+        mycol.delete_many({"$or": [{"service_id": id}, {"aef_id": id}]})
+        RedisEvent("ACCESS_CONTROL_POLICY_UNAVAILABLE").send_event()
+        current_app.logger.info(f"ACLs for provider/service: {id} removed")
diff --git a/services/TS29222_CAPIF_Access_Control_Policy_API/capif_acl/core/redis_event.py b/services/TS29222_CAPIF_Access_Control_Policy_API/capif_acl/core/redis_event.py
new file mode 100644
index 0000000000000000000000000000000000000000..40e3e406830e58a72359e4283d8ff6e0d66bb893
--- /dev/null
+++ b/services/TS29222_CAPIF_Access_Control_Policy_API/capif_acl/core/redis_event.py
@@ -0,0 +1,41 @@
+from encoder import JSONEncoder
+from .publisher import Publisher
+import json
+
+publisher_ops = Publisher()
+
+
+class RedisEvent():
+    def __init__(self, event, event_detail_key=None, information=None) -> None:
+        self.EVENTS_ENUM = [
+            'SERVICE_API_AVAILABLE',
+            'SERVICE_API_UNAVAILABLE',
+            'SERVICE_API_UPDATE',
+            'API_INVOKER_ONBOARDED',
+            'API_INVOKER_OFFBOARDED',
+            'SERVICE_API_INVOCATION_SUCCESS',
+            'SERVICE_API_INVOCATION_FAILURE',
+            'ACCESS_CONTROL_POLICY_UPDATE',
+            'ACCESS_CONTROL_POLICY_UNAVAILABLE',
+            'API_INVOKER_AUTHORIZATION_REVOKED',
+            'API_INVOKER_UPDATED',
+            'API_TOPOLOGY_HIDING_CREATED',
+            'API_TOPOLOGY_HIDING_REVOKED']
+        if event not in self.EVENTS_ENUM:
+            raise Exception(
+                "Event (" + event + ") is not on event enum (" + ','.join(self.EVENTS_ENUM) + ")")
+        self.redis_event = {
+            "event": event
+        }
+        if event_detail_key != None and information != None:
+            self.redis_event['key'] = event_detail_key
+            self.redis_event['information'] = information
+
+    def to_string(self):
+        return json.dumps(self.redis_event, cls=JSONEncoder)
+
+    def send_event(self):
+        publisher_ops.publish_message("events", self.to_string())
+
+    def __call__(self):
+        return self.redis_event
diff --git a/services/TS29222_CAPIF_Events_API/Dockerfile b/services/TS29222_CAPIF_Events_API/Dockerfile
index ddcf2da935752d7eb90aa1dd59c2eb5811eaf5e0..1fef3f2ede15e1de5674980d38a35fbbeebb6c7b 100644
--- a/services/TS29222_CAPIF_Events_API/Dockerfile
+++ b/services/TS29222_CAPIF_Events_API/Dockerfile
@@ -13,6 +13,6 @@ COPY . /usr/src/app
 
 EXPOSE 8080
 
-ENTRYPOINT ["python3"]
+ENTRYPOINT ["gunicorn"]
 
-CMD ["-m", "capif_events"]
\ No newline at end of file
+CMD ["--bind", "0.0.0.0:8080", "--chdir", "/usr/src/app/capif_events", "wsgi:app"]
\ No newline at end of file
diff --git a/services/TS29222_CAPIF_Events_API/capif_events/__main__.py b/services/TS29222_CAPIF_Events_API/capif_events/app.py
similarity index 95%
rename from services/TS29222_CAPIF_Events_API/capif_events/__main__.py
rename to services/TS29222_CAPIF_Events_API/capif_events/app.py
index 1e602ef80d3468f980ce3c9b19d455cfeee1f285..d72ecc640eac6ca7c816323eb3c34988534b403e 100644
--- a/services/TS29222_CAPIF_Events_API/capif_events/__main__.py
+++ b/services/TS29222_CAPIF_Events_API/capif_events/app.py
@@ -4,21 +4,21 @@ import connexion
 import sys
 import logging
 
-from capif_events import encoder
+import encoder
 
 
 from flask import Flask, jsonify, request
 from flask_jwt_extended import JWTManager, jwt_required, create_access_token
 from pymongo import MongoClient
-from .config import Config
-from .core.notifications import Notifications
-from .core.consumer_messager import Subscriber
+
+from core.notifications import Notifications
+from core.consumer_messager import Subscriber
 from multiprocessing import Process
 from threading import Thread
 from flask_executor import Executor
 from flask_apscheduler import APScheduler
 from logging.handlers import RotatingFileHandler
-from .config import Config
+from config import Config
 import os
 from fluent import sender
 from flask_executor import Executor
@@ -32,7 +32,6 @@ from opentelemetry.sdk.trace.export import BatchSpanProcessor
 from opentelemetry.instrumentation.redis import RedisInstrumentor
 
 
-
 NAME = "Events-Service"
 
 def configure_monitoring(app, config):
@@ -147,5 +146,5 @@ subscriber = Subscriber()
 def create_listener_message():
     executor.submit(subscriber.listen)
 
-if __name__ == '__main__':
-    app.run(debug=True, port=8080)
+# if __name__ == '__main__':
+#     app.run(debug=True, port=8080)
diff --git a/services/TS29222_CAPIF_Events_API/capif_events/config.py b/services/TS29222_CAPIF_Events_API/capif_events/config.py
index 377b14f8c368cebf98409223d089fc31326d1987..bed212ac136607ee7459f333b0f50bf7f3481b6b 100644
--- a/services/TS29222_CAPIF_Events_API/capif_events/config.py
+++ b/services/TS29222_CAPIF_Events_API/capif_events/config.py
@@ -5,7 +5,7 @@ import os
 class Config:
 	def __init__(self):
 		self.cached = 0
-		self.file="./config.yaml"
+		self.file="../config.yaml"
 		self.my_config = {}
 		stamp = os.stat(self.file).st_mtime
 		if stamp != self.cached:
diff --git a/services/TS29222_CAPIF_Events_API/capif_events/core/consumer_messager.py b/services/TS29222_CAPIF_Events_API/capif_events/core/consumer_messager.py
index 0f9fa6ab3653ba97701c3f0e034809c69d6b5a08..ce6479afb5c3537246cb1b2192709c6e4ed83d8c 100644
--- a/services/TS29222_CAPIF_Events_API/capif_events/core/consumer_messager.py
+++ b/services/TS29222_CAPIF_Events_API/capif_events/core/consumer_messager.py
@@ -20,14 +20,18 @@ class Subscriber():
 
     def listen(self):
         for raw_message in self.p.listen():
+            current_app.logger.info(raw_message)
             if raw_message["type"] == "message" and raw_message["channel"].decode('utf-8') == "events":
                 current_app.logger.info("Event received")
-                self.notification.send_notifications(raw_message["data"].decode('utf-8'))
-
+                redis_event=json.loads(raw_message["data"].decode('utf-8'))
+                current_app.logger.info(json.dumps(redis_event, indent=4))
+                self.notification.send_notifications(redis_event)
             elif raw_message["type"] == "message" and raw_message["channel"].decode('utf-8') == "internal-messages":
-                message, *invoker_id = raw_message["data"].decode('utf-8').split(":")
-                if message == "invoker-removed" and len(invoker_id)>0:
-                    self.event_ops.delete_all_events(invoker_id[0])
+                message, *subscriber_ids = raw_message["data"].decode('utf-8').split(":")
+                if message == "invoker-removed" and len(subscriber_ids)>0:
+                    self.event_ops.delete_all_events(subscriber_ids)
+                if message == "provider-removed" and len(subscriber_ids)>0:
+                    self.event_ops.delete_all_events(subscriber_ids)
 
 
 
diff --git a/services/TS29222_CAPIF_Events_API/capif_events/core/events_apis.py b/services/TS29222_CAPIF_Events_API/capif_events/core/events_apis.py
index 1ece644c124fcf17b47f8aaea59ab4c67c1b0e86..d6b5bdff29dcec3161150bd42b8c24b62636633b 100644
--- a/services/TS29222_CAPIF_Events_API/capif_events/core/events_apis.py
+++ b/services/TS29222_CAPIF_Events_API/capif_events/core/events_apis.py
@@ -12,7 +12,7 @@ from .resources import Resource
 from bson import json_util
 from .responses import internal_server_error, not_found_error, make_response, bad_request_error
 from ..db.db import MongoDatabse
-from ..util import dict_to_camel_case
+from ..util import dict_to_camel_case, clean_empty
 from .auth_manager import AuthManager
 
 class EventSubscriptionsOperations(Resource):
@@ -73,7 +73,7 @@ class EventSubscriptionsOperations(Resource):
 
             self.auth_manager.add_auth_event(subscription_id, subscriber_id)
 
-            res = make_response(object=event_subscription, status=201)
+            res = make_response(object=dict_to_camel_case(clean_empty(event_subscription.to_dict())), status=201)
             res.headers['Location'] = "http://localhost:8080/capif-events/v1/" + \
                 str(subscriber_id) + "/subscriptions/" + str(subscription_id)
 
diff --git a/services/TS29222_CAPIF_Events_API/capif_events/core/internal_event_ops.py b/services/TS29222_CAPIF_Events_API/capif_events/core/internal_event_ops.py
index 3f4fc6a7274e9eddbfa51cf630f779d31bf18bfb..e49089a3756b4b3946bafa93b4138721e8a1be7b 100644
--- a/services/TS29222_CAPIF_Events_API/capif_events/core/internal_event_ops.py
+++ b/services/TS29222_CAPIF_Events_API/capif_events/core/internal_event_ops.py
@@ -8,22 +8,23 @@ class InternalEventOperations(Resource):
         Resource.__init__(self)
         self.auth_manager = AuthManager()
 
-    def delete_all_events(self, subscriber_id):
+    def delete_all_events(self, subscriber_ids):
 
-        mycol = self.db.get_col_by_name(self.db.event_collection)
-        my_query = {'subscriber_id': subscriber_id}
-        mycol.delete_many(my_query)
+        for subscriber_id in subscriber_ids:
+            mycol = self.db.get_col_by_name(self.db.event_collection)
+            my_query = {'subscriber_id': subscriber_id}
+            mycol.delete_many(my_query)
 
-        current_app.logger.info(f"Removed events for this subscriber: {subscriber_id}")
+            current_app.logger.info(f"Removed events for this subscriber: {subscriber_id}")
 
         #We dont need remove all auth events, becase when invoker is removed, remove auth entry
         #self.auth_manager.remove_auth_all_event(subscriber_id)
 
     def get_event_subscriptions(self, event):
+        current_app.logger.info("get subscription from db")
         try:
             mycol = self.db.get_col_by_name(self.db.event_collection)
-
-            query= {'events':event}
+            query={'events':{'$in':[event]}}
             subscriptions = mycol.find(query)
 
             if  subscriptions is None:
@@ -39,21 +40,3 @@ class InternalEventOperations(Resource):
         except Exception as e:
             current_app.logger.error("An exception occurred ::" + str(e))
             return False
-    
-    # def get_acls(self, service_id):
-    #     try:
-    #         mycol = self.db.get_col_by_name(self.db.acls_col)
-
-    #         query= {'api_id': service_id}
-    #         acls = mycol.find(query)
-
-    #         if  acls is None:
-    #             current_app.logger.error("Not found event subscriptions")
-
-    #         else:
-
-    #             return acls
-
-    #     except Exception as e:
-    #         current_app.logger.error("An exception occurred ::" + str(e))
-    #         return False
\ No newline at end of file
diff --git a/services/TS29222_CAPIF_Events_API/capif_events/core/notifications.py b/services/TS29222_CAPIF_Events_API/capif_events/core/notifications.py
index a02f0abee8a4fa60a8405ea5175e20f3a33236c8..1ca9f2fe5fb17c91b31b845cb1716fc8c4a12df2 100644
--- a/services/TS29222_CAPIF_Events_API/capif_events/core/notifications.py
+++ b/services/TS29222_CAPIF_Events_API/capif_events/core/notifications.py
@@ -1,37 +1,41 @@
 #import concurrent
 import requests
 from .internal_event_ops import InternalEventOperations
-from ..models.event_notification import EventNotification
-from ..models.access_control_policy_list_ext import AccessControlPolicyListExt
-from ..models.capif_event_detail import CAPIFEventDetail
-from ..encoder import JSONEncoder
+from models.event_notification import EventNotification
+from models.access_control_policy_list_ext import AccessControlPolicyListExt
+from models.capif_event_detail import CAPIFEventDetail
+from encoder import JSONEncoder
 import sys
 import json
 from flask import current_app
+import asyncio
+import aiohttp
 
 class Notifications():
 
     def __init__(self):
         self.events_ops = InternalEventOperations()
 
-    def send_notifications(self, event):
-        current_app.logger.info("Received event, sending notifications")
-        subscriptions = self.events_ops.get_event_subscriptions(event)
-        # message, *ids = event.split(":")
-
+    def send_notifications(self, redis_event):
         try:
+            if redis_event.get('event', None) == None:
+                raise("Event value is not present on received event from REDIS")
+            
+            current_app.logger.info("Received event " + redis_event.get('event') + ", sending notifications")
+            subscriptions = self.events_ops.get_event_subscriptions(redis_event.get('event'))
+            current_app.logger.info(subscriptions)
+
             for sub in subscriptions:
                 url = sub["notification_destination"]
-                data = EventNotification(sub["subscription_id"], events=event)
-                # details = CAPIFEventDetail()
-                # if message == "ACCESS_CONTROL_POLICY_UPDATE":
-                #     current_app.logger.info("event: ACCESS_CONTROL_POLICY_UPDATE")
-                #     acls = self.events_ops.get_acls(ids[0])
-                #     details.acc_ctrl_pol_list = AccessControlPolicyListExt(api_id=acls['service_id'], api_invoker_policies=acls['apiInvokerPolicies'])
+                current_app.logger.debug(url)
+                event_detail=None
+                if redis_event.get('key', None) != None and redis_event.get('information', None) != None:
+                    event_detail={redis_event.get('key'):redis_event.get('information')}
+                current_app.logger.debug(event_detail)
+                data = EventNotification(sub["subscription_id"], events=redis_event.get('event'), event_detail=event_detail)
+                current_app.logger.debug(json.dumps(data,cls=JSONEncoder))
 
-                # data.event_detail=details
-                self.request_post(url, data)
-                #current_app.logger.info("notification sended")
+                asyncio.run(self.send(url, json.loads(json.dumps(data,cls=JSONEncoder))))
 
         except Exception as e:
             current_app.logger.error("An exception occurred ::" + str(e))
@@ -40,4 +44,20 @@ class Notifications():
     def request_post(self, url, data):
         headers = {'content-type': 'application/json'}
         return requests.post(url, json={'text': str(data.to_str())}, headers=headers)
-
+    
+    async def send_request(self, url, data):
+        async with aiohttp.ClientSession() as session:
+            timeout = aiohttp.ClientTimeout(total=10)  # Establecer timeout a 10 segundos
+            headers = {'content-type': 'application/json'}
+            async with session.post(url, json=data, timeout=timeout, headers=headers) as response:
+                return await response.text()
+    
+    async def send(self, url, data):
+        try:
+            response = await self.send_request(url, data)
+            current_app.logger.debug(response)
+        except asyncio.TimeoutError:
+            current_app.logger.error("Timeout: Request timeout")
+        except Exception as e:
+            current_app.logger.error("An exception occurred sending notification::" + str(e))
+            return False
diff --git a/services/TS29222_CAPIF_Events_API/capif_events/core/resources.py b/services/TS29222_CAPIF_Events_API/capif_events/core/resources.py
index 94e29ec07359c93a78d520f24fa91c88971d65c4..efbe3c2d4cf28cec298ef17b394011dcd6aa66cb 100644
--- a/services/TS29222_CAPIF_Events_API/capif_events/core/resources.py
+++ b/services/TS29222_CAPIF_Events_API/capif_events/core/resources.py
@@ -1,5 +1,5 @@
 from abc import ABC, abstractmethod
-from ..db.db import MongoDatabse
+from db.db import MongoDatabse
 
 class Resource(ABC):
 
diff --git a/services/TS29222_CAPIF_Events_API/capif_events/core/responses.py b/services/TS29222_CAPIF_Events_API/capif_events/core/responses.py
index 962c4b6dd6ae07bce79dc8e810f10a507d526663..7862390ddb6ad27d60a0e9a1d2e4f358111f2270 100644
--- a/services/TS29222_CAPIF_Events_API/capif_events/core/responses.py
+++ b/services/TS29222_CAPIF_Events_API/capif_events/core/responses.py
@@ -1,6 +1,7 @@
 from ..models.problem_details import ProblemDetails
 from ..encoder import JSONEncoder
 from flask import Response
+from ..util import dict_to_camel_case, clean_empty
 import json
 
 mimetype = "application/json"
@@ -13,19 +14,35 @@ def make_response(object, status):
 def internal_server_error(detail, cause):
     prob = ProblemDetails(title="Internal Server Error", status=500, detail=detail, cause=cause)
 
+    prob = prob.to_dict()
+    prob = clean_empty(prob)
+    prob = dict_to_camel_case(prob)
+
     return Response(json.dumps(prob, cls=JSONEncoder), status=500, mimetype=mimetype)
 
 def forbidden_error(detail, cause):
     prob = ProblemDetails(title="Forbidden", status=403, detail=detail, cause=cause)
 
+    prob = prob.to_dict()
+    prob = clean_empty(prob)
+    prob = dict_to_camel_case(prob)
+
     return Response(json.dumps(prob, cls=JSONEncoder), status=403, mimetype=mimetype)
 
 def bad_request_error(detail, cause, invalid_params):
     prob = ProblemDetails(title="Bad Request", status=400, detail=detail, cause=cause, invalid_params=invalid_params)
 
+    prob = prob.to_dict()
+    prob = clean_empty(prob)
+    prob = dict_to_camel_case(prob)
+
     return Response(json.dumps(prob, cls=JSONEncoder), status=400, mimetype=cause)
 
 def not_found_error(detail, cause):
     prob = ProblemDetails(title="Not Found", status=404, detail=detail, cause=cause)
 
+    prob = prob.to_dict()
+    prob = clean_empty(prob)
+    prob = dict_to_camel_case(prob)
+
     return Response(json.dumps(prob, cls=JSONEncoder), status=404, mimetype=mimetype)
\ No newline at end of file
diff --git a/services/TS29222_CAPIF_Events_API/capif_events/db/db.py b/services/TS29222_CAPIF_Events_API/capif_events/db/db.py
index 2f4d1190297508fd9b49946fc193ba92b6e2d99e..c68c8098fdb1a0139c1053fad19f2584c60bd856 100644
--- a/services/TS29222_CAPIF_Events_API/capif_events/db/db.py
+++ b/services/TS29222_CAPIF_Events_API/capif_events/db/db.py
@@ -2,7 +2,7 @@ import atexit
 import time
 from pymongo import MongoClient
 from pymongo.errors import AutoReconnect
-from ..config import Config
+from config import Config
 from bson.codec_options import CodecOptions
 import os
 from opentelemetry.instrumentation.pymongo import PymongoInstrumentor
diff --git a/services/TS29222_CAPIF_Events_API/capif_events/encoder.py b/services/TS29222_CAPIF_Events_API/capif_events/encoder.py
index f6b018f22f8e92eb3c919f4cb4546d61a550fcd0..80bad8fa9220ab873e044b7adc0a849746088ad5 100644
--- a/services/TS29222_CAPIF_Events_API/capif_events/encoder.py
+++ b/services/TS29222_CAPIF_Events_API/capif_events/encoder.py
@@ -1,7 +1,7 @@
 from connexion.apps.flask_app import FlaskJSONEncoder
 import six
 
-from capif_events.models.base_model_ import Model
+from models.base_model_ import Model
 
 
 class JSONEncoder(FlaskJSONEncoder):
diff --git a/services/TS29222_CAPIF_Events_API/capif_events/util.py b/services/TS29222_CAPIF_Events_API/capif_events/util.py
index 396c6a5b258c051cf1c86b93d2bf79e998463ace..5a99e6772e3f91d6704a4e803819e32ff6da7d91 100644
--- a/services/TS29222_CAPIF_Events_API/capif_events/util.py
+++ b/services/TS29222_CAPIF_Events_API/capif_events/util.py
@@ -2,7 +2,19 @@ import datetime
 
 import six
 import typing
-from capif_events import typing_utils
+import typing_utils
+
+
+def clean_empty(d):
+    if isinstance(d, dict):
+        return {
+            k: v
+            for k, v in ((k, clean_empty(v)) for k, v in d.items())
+            if v
+        }
+    if isinstance(d, list):
+        return [v for v in map(clean_empty, d) if v]
+    return d
 
 
 def dict_to_camel_case(my_dict):
diff --git a/services/TS29222_CAPIF_Events_API/capif_events/wsgi.py b/services/TS29222_CAPIF_Events_API/capif_events/wsgi.py
new file mode 100644
index 0000000000000000000000000000000000000000..6026b0fa96078634d3455ab93d71dcdc78774276
--- /dev/null
+++ b/services/TS29222_CAPIF_Events_API/capif_events/wsgi.py
@@ -0,0 +1,4 @@
+from app import app
+
+if __name__ == "__main__":
+    app.run()
diff --git a/services/TS29222_CAPIF_Events_API/requirements.txt b/services/TS29222_CAPIF_Events_API/requirements.txt
index bbef950cda414a17f3ebb70ca8689ae35c121ca0..8cc1fc1c02bd25ce5c4782ce9ca3a284f4c55ee8 100644
--- a/services/TS29222_CAPIF_Events_API/requirements.txt
+++ b/services/TS29222_CAPIF_Events_API/requirements.txt
@@ -21,3 +21,7 @@ rfc3987
 redis
 flask_executor
 Flask-APScheduler
+aiohttp==3.9.5
+async-timeout==4.0.3
+gunicorn==22.0.0
+packaging==24.0
\ No newline at end of file
diff --git a/services/TS29222_CAPIF_Logging_API_Invocation_API/api_invocation_logs/core/invocationlogs.py b/services/TS29222_CAPIF_Logging_API_Invocation_API/api_invocation_logs/core/invocationlogs.py
index fe4fc9f262167775dc38de1a77ac260fd6e733ff..752b214056aea69d4410dc92a75b7f4cc3bc4858 100644
--- a/services/TS29222_CAPIF_Logging_API_Invocation_API/api_invocation_logs/core/invocationlogs.py
+++ b/services/TS29222_CAPIF_Logging_API_Invocation_API/api_invocation_logs/core/invocationlogs.py
@@ -6,8 +6,13 @@ from flask import current_app, Flask, Response
 
 from pymongo import ReturnDocument
 from ..util import dict_to_camel_case, clean_empty
+from ..encoder import JSONEncoder
 from .resources import Resource
+
 from .responses import internal_server_error, not_found_error, unauthorized_error, make_response
+from .redis_event import RedisEvent
+import json
+
 
 
 class LoggingInvocationOperations(Resource):
@@ -56,7 +61,7 @@ class LoggingInvocationOperations(Resource):
         return None
 
     def add_invocationlog(self, aef_id, invocationlog):
-
+        
         mycol = self.db.get_col_by_name(self.db.invocation_logs)
 
         try:
@@ -74,11 +79,29 @@ class LoggingInvocationOperations(Resource):
                 return result
 
             current_app.logger.debug("Check service apis")
+            event=None
+            invocation_log_base=json.loads(json.dumps(invocationlog, cls=JSONEncoder))
+
             for log in invocationlog.logs:
                 result = self.__check_service_apis(log.api_id, log.api_name)
 
+                current_app.logger.debug("Inside for loop.")
                 if result is not None:
                     return result
+                
+                if log.result:
+                    current_app.logger.debug(log)
+                    if int(log.result) >= 200 and int(log.result) < 300:
+                        event="SERVICE_API_INVOCATION_SUCCESS"
+                    else:
+                        event="SERVICE_API_INVOCATION_FAILURE"
+
+                    current_app.logger.info(event)
+                    invocation_log_base['logs']=[log]
+                    invocationLogs=[invocation_log_base]
+                    RedisEvent(event,"invocationLogs",invocationLogs).send_event()
+
+            current_app.logger.debug("After log check")
 
             current_app.logger.debug("Check existing logs")
             my_query = {'aef_id': aef_id, 'api_invoker_id': invocationlog.api_invoker_id}
diff --git a/services/TS29222_CAPIF_Logging_API_Invocation_API/api_invocation_logs/core/publisher.py b/services/TS29222_CAPIF_Logging_API_Invocation_API/api_invocation_logs/core/publisher.py
new file mode 100644
index 0000000000000000000000000000000000000000..a15c0d90e8d00233317a6c1ab748b8ff150be80e
--- /dev/null
+++ b/services/TS29222_CAPIF_Logging_API_Invocation_API/api_invocation_logs/core/publisher.py
@@ -0,0 +1,11 @@
+import redis
+import sys
+from flask import current_app
+
+class Publisher():
+
+    def __init__(self):
+        self.r = redis.Redis(host='redis', port=6379, db=0)
+
+    def publish_message(self, channel, message):
+        self.r.publish(channel, message)
diff --git a/services/TS29222_CAPIF_Logging_API_Invocation_API/api_invocation_logs/core/redis_event.py b/services/TS29222_CAPIF_Logging_API_Invocation_API/api_invocation_logs/core/redis_event.py
new file mode 100644
index 0000000000000000000000000000000000000000..aadbdbb6b3116cf288648de41effdb12b9ca9143
--- /dev/null
+++ b/services/TS29222_CAPIF_Logging_API_Invocation_API/api_invocation_logs/core/redis_event.py
@@ -0,0 +1,41 @@
+from ..encoder import JSONEncoder
+from .publisher import Publisher
+import json
+
+publisher_ops = Publisher()
+
+
+class RedisEvent():
+    def __init__(self, event, event_detail_key=None, information=None) -> None:
+        self.EVENTS_ENUM = [
+            'SERVICE_API_AVAILABLE',
+            'SERVICE_API_UNAVAILABLE',
+            'SERVICE_API_UPDATE',
+            'API_INVOKER_ONBOARDED',
+            'API_INVOKER_OFFBOARDED',
+            'SERVICE_API_INVOCATION_SUCCESS',
+            'SERVICE_API_INVOCATION_FAILURE',
+            'ACCESS_CONTROL_POLICY_UPDATE',
+            'ACCESS_CONTROL_POLICY_UNAVAILABLE',
+            'API_INVOKER_AUTHORIZATION_REVOKED',
+            'API_INVOKER_UPDATED',
+            'API_TOPOLOGY_HIDING_CREATED',
+            'API_TOPOLOGY_HIDING_REVOKED']
+        if event not in self.EVENTS_ENUM:
+            raise Exception(
+                "Event (" + event + ") is not on event enum (" + ','.join(self.EVENTS_ENUM) + ")")
+        self.redis_event = {
+            "event": event
+        }
+        if event_detail_key != None and information != None:
+            self.redis_event['key'] = event_detail_key
+            self.redis_event['information'] = information
+
+    def to_string(self):
+        return json.dumps(self.redis_event, cls=JSONEncoder)
+
+    def send_event(self):
+        publisher_ops.publish_message("events", self.to_string())
+
+    def __call__(self):
+        return self.redis_event
diff --git a/services/TS29222_CAPIF_Logging_API_Invocation_API/requirements.txt b/services/TS29222_CAPIF_Logging_API_Invocation_API/requirements.txt
index cb1e43905a79b1fdcbe01282175cd884eb958efa..b08bd828f28be3597ba68c0748cbc4ac7ca6c1ce 100644
--- a/services/TS29222_CAPIF_Logging_API_Invocation_API/requirements.txt
+++ b/services/TS29222_CAPIF_Logging_API_Invocation_API/requirements.txt
@@ -6,6 +6,7 @@ Flask == 2.0.3
 pymongo == 4.0.1
 elasticsearch == 8.4.3
 flask_jwt_extended == 4.4.4
+redis ==  4.5.4
 opentelemetry-instrumentation == 0.38b0
 opentelemetry-instrumentation-flask == 0.38b0
 opentelemetry-instrumentation-redis == 0.38b0
diff --git a/services/TS29222_CAPIF_Publish_Service_API/published_apis/controllers/default_controller.py b/services/TS29222_CAPIF_Publish_Service_API/published_apis/controllers/default_controller.py
index ab80164959e10a8339bfa8395f80e7c1e534d8e7..62e506a6be747d94efa513917913f03a75f20ca3 100644
--- a/services/TS29222_CAPIF_Publish_Service_API/published_apis/controllers/default_controller.py
+++ b/services/TS29222_CAPIF_Publish_Service_API/published_apis/controllers/default_controller.py
@@ -1,7 +1,6 @@
 import connexion
 from ..models.service_api_description import ServiceAPIDescription  # noqa: E501
 from ..core.serviceapidescriptions import PublishServiceOperations
-from ..core.publisher import Publisher
 
 from flask import Response, request, current_app
 
@@ -12,10 +11,10 @@ from functools import wraps
 
 
 service_operations = PublishServiceOperations()
-publisher_ops = Publisher()
 
 valid_user = ControlAccess()
 
+
 def cert_validation():
     def _cert_validation(f):
         @wraps(f)
@@ -25,13 +24,16 @@ def cert_validation():
             cert_tmp = request.headers['X-Ssl-Client-Cert']
             cert_raw = cert_tmp.replace('\t', '')
 
-            cert = x509.load_pem_x509_certificate(str.encode(cert_raw), default_backend())
+            cert = x509.load_pem_x509_certificate(
+                str.encode(cert_raw), default_backend())
 
-            cn = cert.subject.get_attributes_for_oid(x509.OID_COMMON_NAME)[0].value.strip()
+            cn = cert.subject.get_attributes_for_oid(
+                x509.OID_COMMON_NAME)[0].value.strip()
 
             if cn != "superadmin":
                 cert_signature = cert.signature.hex()
-                result = valid_user.validate_user_cert(args["apfId"], args["serviceApiId"], cert_signature)
+                result = valid_user.validate_user_cert(
+                    args["apfId"], args["serviceApiId"], cert_signature)
 
                 if result is not None:
                     return result
@@ -41,6 +43,7 @@ def cert_validation():
         return __cert_validation
     return _cert_validation
 
+
 def apf_id_service_apis_get(apf_id):  # noqa: E501
     """apf_id_service_apis_get
 
@@ -76,12 +79,9 @@ def apf_id_service_apis_post(apf_id, body):  # noqa: E501
 
     res = service_operations.add_serviceapidescription(apf_id, body)
 
-    if res.status_code == 201:
-        current_app.logger.info("Service published")
-        publisher_ops.publish_message("events", "SERVICE_API_AVAILABLE")
-
     return res
 
+
 @cert_validation()
 def apf_id_service_apis_service_api_id_delete(service_api_id, apf_id):  # noqa: E501
     """apf_id_service_apis_service_api_id_delete
@@ -97,15 +97,12 @@ def apf_id_service_apis_service_api_id_delete(service_api_id, apf_id):  # noqa:
     """
 
     current_app.logger.info("Removing service published")
-    res = service_operations.delete_serviceapidescription(service_api_id, apf_id)
-
-    if res.status_code == 204:
-        current_app.logger.info("Removed service published")
-        publisher_ops.publish_message("events", "SERVICE_API_UNAVAILABLE")
-        publisher_ops.publish_message("internal-messages", f"service-removed:{service_api_id}")
+    res = service_operations.delete_serviceapidescription(
+        service_api_id, apf_id)
 
     return res
 
+
 @cert_validation()
 def apf_id_service_apis_service_api_id_get(service_api_id, apf_id):  # noqa: E501
     """apf_id_service_apis_service_api_id_get
@@ -125,6 +122,7 @@ def apf_id_service_apis_service_api_id_get(service_api_id, apf_id):  # noqa: E50
 
     return res
 
+
 @cert_validation()
 def apf_id_service_apis_service_api_id_put(service_api_id, apf_id, body):  # noqa: E501
     """apf_id_service_apis_service_api_id_put
@@ -141,14 +139,13 @@ def apf_id_service_apis_service_api_id_put(service_api_id, apf_id, body):  # noq
     :rtype: ServiceAPIDescription
     """
 
-    current_app.logger.info("Updating service api id with id: " + service_api_id)
+    current_app.logger.info(
+        "Updating service api id with id: " + service_api_id)
 
     if connexion.request.is_json:
         body = ServiceAPIDescription.from_dict(connexion.request.get_json())  # noqa: E501
 
-    response = service_operations.update_serviceapidescription(service_api_id, apf_id, body)
-
-    if response.status_code == 200:
-        publisher_ops.publish_message("events", "SERVICE_API_UPDATE")
+    response = service_operations.update_serviceapidescription(
+        service_api_id, apf_id, body)
 
     return response
diff --git a/services/TS29222_CAPIF_Publish_Service_API/published_apis/core/consumer_messager.py b/services/TS29222_CAPIF_Publish_Service_API/published_apis/core/consumer_messager.py
index f0b31598fcbc8c4f9b08fc38ca7d0dd8f4b623eb..f781ead9e3beb684bf6face38ef9c0e4fd5cc5bc 100644
--- a/services/TS29222_CAPIF_Publish_Service_API/published_apis/core/consumer_messager.py
+++ b/services/TS29222_CAPIF_Publish_Service_API/published_apis/core/consumer_messager.py
@@ -16,7 +16,7 @@ class Subscriber():
         for raw_message in self.p.listen():
             if raw_message["type"] == "message" and raw_message["channel"].decode('utf-8') == "internal-messages":
                 message, *ids = raw_message["data"].decode('utf-8').split(":")
-                if message == "provider-removed" and len(ids)==2:
+                if message == "provider-removed" and len(ids) > 0:
                     self.security_ops.delete_intern_service(ids[1])
 
 
diff --git a/services/TS29222_CAPIF_Publish_Service_API/published_apis/core/redis_event.py b/services/TS29222_CAPIF_Publish_Service_API/published_apis/core/redis_event.py
new file mode 100644
index 0000000000000000000000000000000000000000..aadbdbb6b3116cf288648de41effdb12b9ca9143
--- /dev/null
+++ b/services/TS29222_CAPIF_Publish_Service_API/published_apis/core/redis_event.py
@@ -0,0 +1,41 @@
+from ..encoder import JSONEncoder
+from .publisher import Publisher
+import json
+
+publisher_ops = Publisher()
+
+
+class RedisEvent():
+    def __init__(self, event, event_detail_key=None, information=None) -> None:
+        self.EVENTS_ENUM = [
+            'SERVICE_API_AVAILABLE',
+            'SERVICE_API_UNAVAILABLE',
+            'SERVICE_API_UPDATE',
+            'API_INVOKER_ONBOARDED',
+            'API_INVOKER_OFFBOARDED',
+            'SERVICE_API_INVOCATION_SUCCESS',
+            'SERVICE_API_INVOCATION_FAILURE',
+            'ACCESS_CONTROL_POLICY_UPDATE',
+            'ACCESS_CONTROL_POLICY_UNAVAILABLE',
+            'API_INVOKER_AUTHORIZATION_REVOKED',
+            'API_INVOKER_UPDATED',
+            'API_TOPOLOGY_HIDING_CREATED',
+            'API_TOPOLOGY_HIDING_REVOKED']
+        if event not in self.EVENTS_ENUM:
+            raise Exception(
+                "Event (" + event + ") is not on event enum (" + ','.join(self.EVENTS_ENUM) + ")")
+        self.redis_event = {
+            "event": event
+        }
+        if event_detail_key != None and information != None:
+            self.redis_event['key'] = event_detail_key
+            self.redis_event['information'] = information
+
+    def to_string(self):
+        return json.dumps(self.redis_event, cls=JSONEncoder)
+
+    def send_event(self):
+        publisher_ops.publish_message("events", self.to_string())
+
+    def __call__(self):
+        return self.redis_event
diff --git a/services/TS29222_CAPIF_Publish_Service_API/published_apis/core/serviceapidescriptions.py b/services/TS29222_CAPIF_Publish_Service_API/published_apis/core/serviceapidescriptions.py
index 9dd9beb1b5af8dbbbec9b675356f9ed3a03ea13c..41ce03de2243a40442ec3cddd04b11eebf5018bf 100644
--- a/services/TS29222_CAPIF_Publish_Service_API/published_apis/core/serviceapidescriptions.py
+++ b/services/TS29222_CAPIF_Publish_Service_API/published_apis/core/serviceapidescriptions.py
@@ -7,26 +7,33 @@ from datetime import datetime
 from ..util import dict_to_camel_case, clean_empty
 from .responses import internal_server_error, forbidden_error, not_found_error, unauthorized_error, make_response
 from .auth_manager import AuthManager
+from .redis_event import RedisEvent
+from .publisher import Publisher
+
+publisher_ops = Publisher()
 
 
 service_api_not_found_message = "Service API not found"
 
+
 class PublishServiceOperations(Resource):
 
     def __check_apf(self, apf_id):
         providers_col = self.db.get_col_by_name(self.db.capif_provider_col)
 
         current_app.logger.debug("Checking apf id")
-        provider = providers_col.find_one({"api_prov_funcs.api_prov_func_id": apf_id})
+        provider = providers_col.find_one(
+            {"api_prov_funcs.api_prov_func_id": apf_id})
 
         if provider is None:
             current_app.logger.error("Publisher not exist")
-            return unauthorized_error(detail = "Publisher not existing", cause = "Publisher id not found")
+            return unauthorized_error(detail="Publisher not existing", cause="Publisher id not found")
 
-        list_apf_ids =  [func["api_prov_func_id"] for func in provider["api_prov_funcs"] if func["api_prov_func_role"] == "APF"]
+        list_apf_ids = [func["api_prov_func_id"]
+                        for func in provider["api_prov_funcs"] if func["api_prov_func_role"] == "APF"]
         if apf_id not in list_apf_ids:
             current_app.logger.debug("This id not belongs to APF")
-            return unauthorized_error(detail ="You are not a publisher", cause ="This API is only available for publishers")
+            return unauthorized_error(detail="You are not a publisher", cause="This API is only available for publishers")
 
         return None
 
@@ -47,7 +54,8 @@ class PublishServiceOperations(Resource):
             if result != None:
                 return result
 
-            service = mycol.find({"apf_id": apf_id}, {"_id":0, "api_name":1, "api_id":1, "aef_profiles":1, "description":1, "supported_features":1, "shareable_info":1, "service_api_category":1, "api_supp_feats":1, "pub_api_path":1, "ccf_id":1})
+            service = mycol.find({"apf_id": apf_id}, {"_id": 0, "api_name": 1, "api_id": 1, "aef_profiles": 1, "description": 1,
+                                 "supported_features": 1, "shareable_info": 1, "service_api_category": 1, "api_supp_feats": 1, "pub_api_path": 1, "ccf_id": 1})
             current_app.logger.debug(service)
             if service is None:
                 current_app.logger.error("Not found services for this apf id")
@@ -82,9 +90,11 @@ class PublishServiceOperations(Resource):
             if result != None:
                 return result
 
-            service = mycol.find_one({"api_name": serviceapidescription.api_name})
+            service = mycol.find_one(
+                {"api_name": serviceapidescription.api_name})
             if service is not None:
-                current_app.logger.error("Service already registered with same api name")
+                current_app.logger.error(
+                    "Service already registered with same api name")
                 return forbidden_error(detail="Already registered service with same api name", cause="Found service with same api name")
 
             api_id = secrets.token_hex(15)
@@ -99,9 +109,15 @@ class PublishServiceOperations(Resource):
             self.auth_manager.add_auth_service(api_id, apf_id)
 
             current_app.logger.debug("Service inserted in database")
+
             res = make_response(object=dict_to_camel_case(clean_empty(serviceapidescription.to_dict())), status=201)
-            res.headers['Location'] = "http://localhost:8080/published-apis/v1/" + str(apf_id) + "/service-apis/" + str(api_id)
+            res.headers['Location'] = "http://localhost:8080/published-apis/v1/" + \
+                          str(apf_id) + "/service-apis/" + str(api_id)
 
+            if res.status_code == 201:
+                current_app.logger.info("Service published")
+                RedisEvent("SERVICE_API_AVAILABLE", "apiIds",
+                           [str(api_id)]).send_event()
             return res
 
         except Exception as e:
@@ -109,26 +125,25 @@ class PublishServiceOperations(Resource):
             current_app.logger.error(exception + "::" + str(e))
             return internal_server_error(detail=exception, cause=str(e))
 
-
-
     def get_one_serviceapi(self, service_api_id, apf_id):
 
         mycol = self.db.get_col_by_name(self.db.service_api_descriptions)
 
         try:
-            current_app.logger.debug("Geting service api with id: " + service_api_id)
+            current_app.logger.debug(
+                "Geting service api with id: " + service_api_id)
             result = self.__check_apf(apf_id)
 
             if result != None:
                 return result
 
             my_query = {'apf_id': apf_id, 'api_id': service_api_id}
-            service_api = mycol.find_one(my_query, {"_id":0, "api_name":1, "api_id":1, "aef_profiles":1, "description":1, "supported_features":1, "shareable_info":1, "service_api_category":1, "api_supp_feats":1, "pub_api_path":1, "ccf_id":1})
+            service_api = mycol.find_one(my_query, {"_id": 0, "api_name": 1, "api_id": 1, "aef_profiles": 1, "description": 1,
+                                         "supported_features": 1, "shareable_info": 1, "service_api_category": 1, "api_supp_feats": 1, "pub_api_path": 1, "ccf_id": 1})
             if service_api is None:
                 current_app.logger.error(service_api_not_found_message)
                 return not_found_error(detail=service_api_not_found_message, cause="No Service with specific credentials exists")
 
-
             my_service_api = dict_to_camel_case(service_api)
             my_service_api = clean_empty(my_service_api)
 
@@ -147,7 +162,8 @@ class PublishServiceOperations(Resource):
 
         try:
 
-            current_app.logger.debug("Removing api service with id: " + service_api_id)
+            current_app.logger.debug(
+                "Removing api service with id: " + service_api_id)
             result = self.__check_apf(apf_id)
 
             if result != None:
@@ -165,22 +181,29 @@ class PublishServiceOperations(Resource):
             self.auth_manager.remove_auth_service(service_api_id, apf_id)
 
             current_app.logger.debug("Removed service from database")
-            out =  "The service matching api_id " + service_api_id + " was deleted."
-            return make_response(out, status=204)
+            out = "The service matching api_id " + service_api_id + " was deleted."
+            res = make_response(out, status=204)
+            if res.status_code == 204:
+                current_app.logger.info("Removed service published")
+                RedisEvent("SERVICE_API_UNAVAILABLE", "apiIds",
+                           [service_api_id]).send_event()
+                publisher_ops.publish_message(
+                    "internal-messages", f"service-removed:{service_api_id}")
+            return res
 
         except Exception as e:
             exception = "An exception occurred in delete service"
             current_app.logger.error(exception + "::" + str(e))
             return internal_server_error(detail=exception, cause=str(e))
 
-
     def update_serviceapidescription(self, service_api_id, apf_id, service_api_description):
 
         mycol = self.db.get_col_by_name(self.db.service_api_descriptions)
 
         try:
 
-            current_app.logger.debug("Updating service api with id: " + service_api_id)
+            current_app.logger.debug(
+                "Updating service api with id: " + service_api_id)
 
             result = self.__check_apf(apf_id)
 
@@ -197,18 +220,22 @@ class PublishServiceOperations(Resource):
             service_api_description = service_api_description.to_dict()
             service_api_description = clean_empty(service_api_description)
 
-            result = mycol.find_one_and_update(serviceapidescription, {"$set":service_api_description}, projection={"_id":0, "api_name":1, "api_id":1, "aef_profiles":1, "description":1, "supported_features":1, "shareable_info":1, "service_api_category":1, "api_supp_feats":1, "pub_api_path":1, "ccf_id":1},return_document=ReturnDocument.AFTER ,upsert=False)
+            result = mycol.find_one_and_update(serviceapidescription, {"$set": service_api_description}, projection={"_id": 0, "api_name": 1, "api_id": 1, "aef_profiles": 1, "description": 1,
+                                               "supported_features": 1, "shareable_info": 1, "service_api_category": 1, "api_supp_feats": 1, "pub_api_path": 1, "ccf_id": 1}, return_document=ReturnDocument.AFTER, upsert=False)
 
             result = clean_empty(result)
 
             current_app.logger.debug("Updated service api")
-    
-            response = make_response(object=dict_to_camel_case(result), status=200)
+            service_api_description_updated = dict_to_camel_case(result)
 
+            response = make_response(
+                object=service_api_description_updated, status=200)
+            if response.status_code == 200:
+                RedisEvent("SERVICE_API_UPDATE", "serviceAPIDescriptions", [
+                           service_api_description_updated]).send_event()
             return response
 
         except Exception as e:
             exception = "An exception occurred in update service"
             current_app.logger.error(exception + "::" + str(e))
             return internal_server_error(detail=exception, cause=str(e))
-
diff --git a/services/TS29222_CAPIF_Routing_Info_API/Dockerfile b/services/TS29222_CAPIF_Routing_Info_API/Dockerfile
index 9911d06b662dc1890945b8ec73c862a5ae5a2fab..cfa4b5dfe4888a1efa8fb9551f707f21c93dd73c 100644
--- a/services/TS29222_CAPIF_Routing_Info_API/Dockerfile
+++ b/services/TS29222_CAPIF_Routing_Info_API/Dockerfile
@@ -11,6 +11,6 @@ COPY . /usr/src/app
 
 EXPOSE 8080
 
-ENTRYPOINT ["python3"]
+ENTRYPOINT ["gunicorn"]
 
-CMD ["-m", "capif_routing_info"]
\ No newline at end of file
+CMD ["--bind", "0.0.0.0:8080", "--chdir", "/usr/src/app/capif_routing_info", "wsgi:app"]
\ No newline at end of file
diff --git a/services/TS29222_CAPIF_Routing_Info_API/capif_routing_info/__main__.py b/services/TS29222_CAPIF_Routing_Info_API/capif_routing_info/__main__.py
deleted file mode 100644
index e595fa02106ed80d620b8eb00f1d2a421bb1ee5f..0000000000000000000000000000000000000000
--- a/services/TS29222_CAPIF_Routing_Info_API/capif_routing_info/__main__.py
+++ /dev/null
@@ -1,19 +0,0 @@
-#!/usr/bin/env python3
-
-import connexion
-
-from capif_routing_info import encoder
-
-
-def main():
-    app = connexion.App(__name__, specification_dir='./openapi/')
-    app.app.json_encoder = encoder.JSONEncoder
-    app.add_api('openapi.yaml',
-                arguments={'title': 'CAPIF_Routing_Info_API'},
-                pythonic_params=True)
-
-    app.run(port=8080)
-
-
-if __name__ == '__main__':
-    main()
diff --git a/services/TS29222_CAPIF_Routing_Info_API/capif_routing_info/app.py b/services/TS29222_CAPIF_Routing_Info_API/capif_routing_info/app.py
new file mode 100644
index 0000000000000000000000000000000000000000..e669f46a4ab85ec541d4e0a6d2586c362468090d
--- /dev/null
+++ b/services/TS29222_CAPIF_Routing_Info_API/capif_routing_info/app.py
@@ -0,0 +1,18 @@
+#!/usr/bin/env python3
+
+import connexion
+import encoder
+
+
+# def main():
+app = connexion.App(__name__, specification_dir='./openapi/')
+app.app.json_encoder = encoder.JSONEncoder
+app.add_api('openapi.yaml',
+            arguments={'title': 'CAPIF_Routing_Info_API'},
+            pythonic_params=True)
+
+# app.run(port=8080)
+
+
+# if __name__ == '__main__':
+#     main()
diff --git a/services/TS29222_CAPIF_Routing_Info_API/capif_routing_info/controllers/default_controller.py b/services/TS29222_CAPIF_Routing_Info_API/capif_routing_info/controllers/default_controller.py
index 7cd07dd74ff2634a9487083283cad4ef354c61ae..442fa809298424c273d7ec228855e9b3fa8adcf5 100644
--- a/services/TS29222_CAPIF_Routing_Info_API/capif_routing_info/controllers/default_controller.py
+++ b/services/TS29222_CAPIF_Routing_Info_API/capif_routing_info/controllers/default_controller.py
@@ -1,9 +1,9 @@
 import connexion
 import six
 
-from capif_routing_info.models.problem_details import ProblemDetails  # noqa: E501
-from capif_routing_info.models.routing_info import RoutingInfo  # noqa: E501
-from capif_routing_info import util
+from ..models.problem_details import ProblemDetails  # noqa: E501
+from ..models.routing_info import RoutingInfo  # noqa: E501
+# from capif_routing_info import util
 
 
 def service_apis_service_api_id_get(service_api_id, aef_id, supp_feat=None):  # noqa: E501
diff --git a/services/TS29222_CAPIF_Routing_Info_API/capif_routing_info/encoder.py b/services/TS29222_CAPIF_Routing_Info_API/capif_routing_info/encoder.py
index b53647004a14457d83693f5909b69425d927d3c8..80bad8fa9220ab873e044b7adc0a849746088ad5 100644
--- a/services/TS29222_CAPIF_Routing_Info_API/capif_routing_info/encoder.py
+++ b/services/TS29222_CAPIF_Routing_Info_API/capif_routing_info/encoder.py
@@ -1,7 +1,7 @@
 from connexion.apps.flask_app import FlaskJSONEncoder
 import six
 
-from capif_routing_info.models.base_model_ import Model
+from models.base_model_ import Model
 
 
 class JSONEncoder(FlaskJSONEncoder):
diff --git a/services/TS29222_CAPIF_Routing_Info_API/capif_routing_info/util.py b/services/TS29222_CAPIF_Routing_Info_API/capif_routing_info/util.py
index 227076550fea5acb4f1f167a777f366215563261..910388bab6fa518b467b13476102000d2b0a0321 100644
--- a/services/TS29222_CAPIF_Routing_Info_API/capif_routing_info/util.py
+++ b/services/TS29222_CAPIF_Routing_Info_API/capif_routing_info/util.py
@@ -2,7 +2,7 @@ import datetime
 
 import six
 import typing
-from capif_routing_info import typing_utils
+import typing_utils
 
 
 def _deserialize(data, klass):
diff --git a/services/TS29222_CAPIF_Routing_Info_API/capif_routing_info/wsgi.py b/services/TS29222_CAPIF_Routing_Info_API/capif_routing_info/wsgi.py
new file mode 100644
index 0000000000000000000000000000000000000000..6026b0fa96078634d3455ab93d71dcdc78774276
--- /dev/null
+++ b/services/TS29222_CAPIF_Routing_Info_API/capif_routing_info/wsgi.py
@@ -0,0 +1,4 @@
+from app import app
+
+if __name__ == "__main__":
+    app.run()
diff --git a/services/TS29222_CAPIF_Routing_Info_API/requirements.txt b/services/TS29222_CAPIF_Routing_Info_API/requirements.txt
index 1be0346f149043abdcafbd540c98c73eca75275e..e4be1ef6b91acd656f04127c542692abdb9b7b6b 100644
--- a/services/TS29222_CAPIF_Routing_Info_API/requirements.txt
+++ b/services/TS29222_CAPIF_Routing_Info_API/requirements.txt
@@ -3,3 +3,5 @@ swagger-ui-bundle >= 0.0.2
 python_dateutil >= 2.6.0
 setuptools >= 21.0.0
 Flask == 2.0.3
+gunicorn==22.0.0
+packaging==24.0
\ No newline at end of file
diff --git a/services/TS29222_CAPIF_Security_API/capif_security/controllers/default_controller.py b/services/TS29222_CAPIF_Security_API/capif_security/controllers/default_controller.py
index 6713db133306fd689b329c380467f4f926bf8b08..7e04d4df353bd4227d5b7bda72e3cb7236cf1dab 100644
--- a/services/TS29222_CAPIF_Security_API/capif_security/controllers/default_controller.py
+++ b/services/TS29222_CAPIF_Security_API/capif_security/controllers/default_controller.py
@@ -111,10 +111,7 @@ def trusted_invokers_api_invoker_id_delete_post(api_invoker_id, body):  # noqa:
 
     current_app.logger.info("Revoking permissions")
     res = service_security_ops.revoke_api_authorization(api_invoker_id, body)
-    if res.status_code == 204:
-        current_app.logger.info("Permissions revoked")
-        publish_ops.publish_message("events", "API_INVOKER_AUTHORIZATION_REVOKED")
-
+    
     return res
 
 @cert_validation()
diff --git a/services/TS29222_CAPIF_Security_API/capif_security/core/consumer_messager.py b/services/TS29222_CAPIF_Security_API/capif_security/core/consumer_messager.py
index 749f57ed7914b5cb1954b9ee8ef259ee930a0a93..43445583236a5743ea1475079a3c329bb0788787 100644
--- a/services/TS29222_CAPIF_Security_API/capif_security/core/consumer_messager.py
+++ b/services/TS29222_CAPIF_Security_API/capif_security/core/consumer_messager.py
@@ -3,6 +3,7 @@ import redis
 from .internal_security_ops import InternalSecurityOps
 from flask import current_app
 
+
 class Subscriber():
 
     def __init__(self):
@@ -16,12 +17,7 @@ class Subscriber():
         for raw_message in self.p.listen():
             if raw_message["type"] == "message" and raw_message["channel"].decode('utf-8') == "internal-messages":
                 message, *ids = raw_message["data"].decode('utf-8').split(":")
-                if message == "invoker-removed" and len(ids)>0:
+                if message == "invoker-removed" and len(ids) > 0:
                     self.security_ops.delete_intern_servicesecurity(ids[0])
                 if message == "provider-removed" or message == "service-removed" and len(ids) > 0:
                     self.security_ops.update_intern_servicesecurity(ids[0])
-                
-
-
-
-
diff --git a/services/TS29222_CAPIF_Security_API/capif_security/core/redis_event.py b/services/TS29222_CAPIF_Security_API/capif_security/core/redis_event.py
new file mode 100644
index 0000000000000000000000000000000000000000..aadbdbb6b3116cf288648de41effdb12b9ca9143
--- /dev/null
+++ b/services/TS29222_CAPIF_Security_API/capif_security/core/redis_event.py
@@ -0,0 +1,41 @@
+from ..encoder import JSONEncoder
+from .publisher import Publisher
+import json
+
+publisher_ops = Publisher()
+
+
+class RedisEvent():
+    def __init__(self, event, event_detail_key=None, information=None) -> None:
+        self.EVENTS_ENUM = [
+            'SERVICE_API_AVAILABLE',
+            'SERVICE_API_UNAVAILABLE',
+            'SERVICE_API_UPDATE',
+            'API_INVOKER_ONBOARDED',
+            'API_INVOKER_OFFBOARDED',
+            'SERVICE_API_INVOCATION_SUCCESS',
+            'SERVICE_API_INVOCATION_FAILURE',
+            'ACCESS_CONTROL_POLICY_UPDATE',
+            'ACCESS_CONTROL_POLICY_UNAVAILABLE',
+            'API_INVOKER_AUTHORIZATION_REVOKED',
+            'API_INVOKER_UPDATED',
+            'API_TOPOLOGY_HIDING_CREATED',
+            'API_TOPOLOGY_HIDING_REVOKED']
+        if event not in self.EVENTS_ENUM:
+            raise Exception(
+                "Event (" + event + ") is not on event enum (" + ','.join(self.EVENTS_ENUM) + ")")
+        self.redis_event = {
+            "event": event
+        }
+        if event_detail_key != None and information != None:
+            self.redis_event['key'] = event_detail_key
+            self.redis_event['information'] = information
+
+    def to_string(self):
+        return json.dumps(self.redis_event, cls=JSONEncoder)
+
+    def send_event(self):
+        publisher_ops.publish_message("events", self.to_string())
+
+    def __call__(self):
+        return self.redis_event
diff --git a/services/TS29222_CAPIF_Security_API/capif_security/core/servicesecurity.py b/services/TS29222_CAPIF_Security_API/capif_security/core/servicesecurity.py
index f553b4d6112aa50af7563edf79018ed87b270664..9fe7838a47479a17b0233dd7698c3bb08958c670 100644
--- a/services/TS29222_CAPIF_Security_API/capif_security/core/servicesecurity.py
+++ b/services/TS29222_CAPIF_Security_API/capif_security/core/servicesecurity.py
@@ -7,14 +7,15 @@ from flask_jwt_extended import create_access_token
 from datetime import datetime, timedelta
 import json
 
-from ..models.access_token_rsp import AccessTokenRsp
-from ..models.access_token_claims import AccessTokenClaims
 from bson import json_util
 from ..core.publisher import Publisher
 from ..models.access_token_err import AccessTokenErr
+from ..models.access_token_rsp import AccessTokenRsp
+from ..models.access_token_claims import AccessTokenClaims
 from ..util import dict_to_camel_case, clean_empty
 from .responses import not_found_error, make_response, bad_request_error, internal_server_error, forbidden_error
 from .resources import Resource
+from .redis_event import RedisEvent
 import os
 
 publish_ops = Publisher()
@@ -22,13 +23,15 @@ publish_ops = Publisher()
 security_context_not_found_detail = "Security context not found"
 api_invoker_no_context_cause = "API Invoker has no security context"
 
+
 class SecurityOperations(Resource):
 
     def __check_invoker(self, api_invoker_id):
         invokers_col = self.db.get_col_by_name(self.db.capif_invokers)
 
-        current_app.logger.debug("Checking api invoker with id: " + api_invoker_id)
-        invoker =  invokers_col.find_one({"api_invoker_id": api_invoker_id})
+        current_app.logger.debug(
+            "Checking api invoker with id: " + api_invoker_id)
+        invoker = invokers_col.find_one({"api_invoker_id": api_invoker_id})
         if invoker is None:
             current_app.logger.error("Invoker not found")
             return not_found_error(detail="Invoker not found", cause="API Invoker not exists or invalid ID")
@@ -44,12 +47,12 @@ class SecurityOperations(Resource):
             if header != "3gpp":
                 current_app.logger.error("Bad format scope")
                 token_error = AccessTokenErr(error="invalid_scope", error_description="The first characters must be '3gpp'")
-                # return make_response(object=dict_to_camel_case(clean_empty(token_error.to_dict())), status=400)
                 return make_response(object=clean_empty(token_error.to_dict()), status=400)
 
             _, body = scope.split("#")
 
-            capif_service_col = self.db.get_col_by_name(self.db.capif_service_col)
+            capif_service_col = self.db.get_col_by_name(
+                self.db.capif_service_col)
             security_info = security_context["security_info"]
             aef_security_context = [info["aef_id"] for info in security_info]
 
@@ -59,15 +62,17 @@ class SecurityOperations(Resource):
                 if aef_id not in aef_security_context:
                     current_app.logger.error("Bad format Scope, not valid aef id ")
                     token_error = AccessTokenErr(error="invalid_scope", error_description="One of aef_id not belongs of your security context")
-                    # return make_response(object=dict_to_camel_case(clean_empty(token_error.to_dict())), status=400)
                     return make_response(object=clean_empty(token_error.to_dict()), status=400)
+
                 api_names = api_names.split(",")
                 for api_name in api_names:
-                    service = capif_service_col.find_one({"$and": [{"api_name":api_name},{self.filter_aef_id:aef_id}]})
+                    service = capif_service_col.find_one(
+                        {"$and": [{"api_name": api_name}, {self.filter_aef_id: aef_id}]})
                     if service is None:
                         current_app.logger.error("Bad format Scope, not valid api name")
-                        token_error = AccessTokenErr(error="invalid_scope", error_description="One of the api names does not exist or is not associated with the aef id provided")
-                        # return make_response(object=dict_to_camel_case(clean_empty(token_error.to_dict())), status=400)
+                        token_error = AccessTokenErr(
+                            error="invalid_scope",
+                            error_description="One of the api names does not exist or is not associated with the aef id provided")
                         return make_response(object=clean_empty(token_error.to_dict()), status=400)
 
             return None
@@ -75,7 +80,6 @@ class SecurityOperations(Resource):
         except Exception as e:
             current_app.logger.error("Bad format Scope: " + e)
             token_error = AccessTokenErr(error="invalid_scope", error_description="malformed scope")
-            # return make_response(object=dict_to_camel_case(clean_empty(token_error.to_dict())), status=400)
             return make_response(object=clean_empty(token_error.to_dict()), status=400)
 
     def __init__(self):
@@ -88,16 +92,18 @@ class SecurityOperations(Resource):
 
         try:
 
-            current_app.logger.debug("Obtainig security context with id: " + api_invoker_id)
+            current_app.logger.debug(
+                "Obtainig security context with id: " + api_invoker_id)
             result = self.__check_invoker(api_invoker_id)
             if result != None:
                 return result
             else:
-                services_security_object = mycol.find_one({"api_invoker_id": api_invoker_id}, {"_id":0, "api_invoker_id":0})
+                services_security_object = mycol.find_one({"api_invoker_id": api_invoker_id}, {
+                                                          "_id": 0, "api_invoker_id": 0})
 
                 if services_security_object is None:
                     current_app.logger.error("Not found security context")
-                    return not_found_error(detail= security_context_not_found_detail, cause=api_invoker_no_context_cause)
+                    return not_found_error(detail=security_context_not_found_detail, cause=api_invoker_no_context_cause)
 
                 if not authentication_info:
                     for security_info_obj in services_security_object['security_info']:
@@ -106,12 +112,15 @@ class SecurityOperations(Resource):
                     for security_info_obj in services_security_object['security_info']:
                         del security_info_obj['authorization_info']
 
-                properyly_json= json.dumps(services_security_object, default=json_util.default)
-                my_service_security = dict_to_camel_case(json.loads(properyly_json))
+                properyly_json = json.dumps(
+                    services_security_object, default=json_util.default)
+                my_service_security = dict_to_camel_case(
+                    json.loads(properyly_json))
                 my_service_security = clean_empty(my_service_security)
 
-                current_app.logger.debug("Obtained security context from database")
-        
+                current_app.logger.debug(
+                    "Obtained security context from database")
+
                 res = make_response(object=my_service_security, status=200)
 
                 return res
@@ -120,7 +129,6 @@ class SecurityOperations(Resource):
             current_app.logger.error(exception + "::" + str(e))
             return internal_server_error(detail=exception, cause=str(e))
 
-
     def create_servicesecurity(self, api_invoker_id, service_security):
 
         mycol = self.db.get_col_by_name(self.db.security_info)
@@ -134,43 +142,54 @@ class SecurityOperations(Resource):
 
             if rfc3987.match(service_security.notification_destination, rule="URI") is None:
                 current_app.logger.error("Bad url format")
-                return bad_request_error(detail="Bad Param", cause = "Detected Bad format of param", invalid_params=[{"param": "notificationDestination", "reason": "Not valid URL format"}])
+                return bad_request_error(detail="Bad Param", cause="Detected Bad format of param", invalid_params=[{"param": "notificationDestination", "reason": "Not valid URL format"}])
 
-            services_security_object = mycol.find_one({"api_invoker_id": api_invoker_id})
+            services_security_object = mycol.find_one(
+                {"api_invoker_id": api_invoker_id})
 
             if services_security_object is not None:
 
-                current_app.logger.error("Already security context defined with same api invoker id")
+                current_app.logger.error(
+                    "Already security context defined with same api invoker id")
                 return forbidden_error(detail="Security method already defined", cause="Identical AEF Profile IDs")
 
-
             for service_instance in service_security.security_info:
                 if service_instance.interface_details is not None:
                     security_methods = service_instance.interface_details.security_methods
                     pref_security_methods = service_instance.pref_security_methods
-                    valid_security_method = set(security_methods) & set(pref_security_methods)
+                    valid_security_method = set(
+                        security_methods) & set(pref_security_methods)
 
                 else:
-                    capif_service_col = self.db.get_col_by_name(self.db.capif_service_col)
-                    services_security_object = capif_service_col.find_one({"api_id":service_instance.api_id, self.filter_aef_id: service_instance.aef_id}, {"aef_profiles.security_methods.$":1})
+                    capif_service_col = self.db.get_col_by_name(
+                        self.db.capif_service_col)
+                    services_security_object = capif_service_col.find_one(
+                        {"api_id": service_instance.api_id, self.filter_aef_id: service_instance.aef_id}, {"aef_profiles.security_methods.$": 1})
 
                     if services_security_object is None:
-                        current_app.logger.error("Not found service with this aef id: " + service_instance.aef_id)
+                        current_app.logger.error(
+                            "Not found service with this aef id: " + service_instance.aef_id)
                         return not_found_error(detail="Service with this aefId not found", cause="Not found Service")
 
                     pref_security_methods = service_instance.pref_security_methods
-                    valid_security_methods = [security_method for array_methods in services_security_object["aef_profiles"] for security_method in array_methods["security_methods"]]
-                    valid_security_method = set(valid_security_methods) & set(pref_security_methods)
+                    valid_security_methods = [security_method for array_methods in services_security_object["aef_profiles"]
+                                              for security_method in array_methods["security_methods"]]
+                    valid_security_method = set(
+                        valid_security_methods) & set(pref_security_methods)
 
                 if len(list(valid_security_method)) == 0:
-                    current_app.logger.error("Not found comptaible security method with pref security method")
+                    current_app.logger.error(
+                        "Not found comptaible security method with pref security method")
                     return bad_request_error(detail="Not found compatible security method with pref security method", cause="Error pref security method", invalid_params=[{"param": "prefSecurityMethods", "reason": "pref security method not compatible with security method available"}])
 
-                service_instance.sel_security_method = list(valid_security_method)[0]
+                service_instance.sel_security_method = list(
+                    valid_security_method)[0]
                 # Send service instance to ACL
                 current_app.logger.debug("Sending message to create ACL")
-                publish_ops.publish_message("acls-messages", "create-acl:"+str(api_invoker_id)+":"+str(service_instance.api_id)+":"+str(service_instance.aef_id))
-                current_app.logger.debug("Inserted security context in database")
+                publish_ops.publish_message("acls-messages", "create-acl:"+str(
+                    api_invoker_id)+":"+str(service_instance.api_id)+":"+str(service_instance.aef_id))
+                current_app.logger.debug(
+                    "Inserted security context in database")
 
             rec = dict()
             rec['api_invoker_id'] = api_invoker_id
@@ -178,7 +197,9 @@ class SecurityOperations(Resource):
             mycol.insert_one(rec)
 
             res = make_response(object=dict_to_camel_case(clean_empty(service_security.to_dict())), status=201)
-            res.headers['Location'] = "https://{}/capif-security/v1/trustedInvokers/{}".format(os.getenv('CAPIF_HOSTNAME'),str(api_invoker_id))
+            res.headers['Location'] = "https://{}/capif-security/v1/trustedInvokers/{}".format(
+                os.getenv('CAPIF_HOSTNAME'), str(api_invoker_id))
+
             return res
 
         except Exception as e:
@@ -186,7 +207,6 @@ class SecurityOperations(Resource):
             current_app.logger.error(exception + "::" + str(e))
             return internal_server_error(detail=exception, cause=str(e))
 
-
     def delete_servicesecurity(self, api_invoker_id):
 
         mycol = self.db.get_col_by_name(self.db.security_info)
@@ -205,19 +225,22 @@ class SecurityOperations(Resource):
                 if services_security_count == 0:
                     current_app.logger.error(security_context_not_found_detail)
                     return not_found_error(detail=security_context_not_found_detail, cause=api_invoker_no_context_cause)
-                
+
                 mycol.delete_many(my_query)
 
-                publish_ops.publish_message("acls-messages", "remove-acl:"+api_invoker_id)
+                publish_ops.publish_message(
+                    "acls-messages", "remove-acl:"+api_invoker_id)
 
-                current_app.logger.debug("Removed security context from database")
-                out= "The security info of Netapp with Netapp ID " + api_invoker_id + " were deleted.", 204
+                current_app.logger.debug(
+                    "Removed security context from database")
+                out = "The security info of Netapp with Netapp ID " + \
+                    api_invoker_id + " were deleted.", 204
                 return make_response(out, status=204)
 
         except Exception as e:
             exception = "An exception occurred in create security info"
             current_app.logger.error(exception + "::" + str(e))
-            return internal_server_error(detail=exception, cause = str(e))
+            return internal_server_error(detail=exception, cause=str(e))
 
     def delete_intern_servicesecurity(self, api_invoker_id):
 
@@ -235,18 +258,19 @@ class SecurityOperations(Resource):
 
             invokers_col = self.db.get_col_by_name(self.db.capif_invokers)
 
-            current_app.logger.debug("Checking api invoker with id: " + access_token_req["client_id"])
-            invoker =  invokers_col.find_one({"api_invoker_id": access_token_req["client_id"]})
+            current_app.logger.debug(
+                "Checking api invoker with id: " + access_token_req["client_id"])
+            invoker = invokers_col.find_one(
+                {"api_invoker_id": access_token_req["client_id"]})
             if invoker is None:
                 client_id_error =  AccessTokenErr(error="invalid_client", error_description="Client Id not found")
-                # return make_response(object=dict_to_camel_case(clean_empty(client_id_error.to_dict())), status=400)
                 return make_response(object=clean_empty(client_id_error.to_dict()), status=400)
 
 
             if access_token_req["grant_type"] != "client_credentials":
-                client_id_error =  AccessTokenErr(error="unsupported_grant_type", error_description="Invalid value for `grant_type` ({0}), must be one of ['client_credentials'] - 'grant_type'"
-                .format(access_token_req["grant_type"]))
-                # return make_response(object=dict_to_camel_case(clean_empty(client_id_error.to_dict())), status=400)
+                client_id_error = AccessTokenErr(error="unsupported_grant_type",
+                                                 error_description="Invalid value for `grant_type` ({0}), must be one of ['client_credentials'] - 'grant_type'"
+                                                 .format(access_token_req["grant_type"]))
                 return make_response(object=clean_empty(client_id_error.to_dict()), status=400)
 
             service_security = mycol.find_one({"api_invoker_id": security_id})
@@ -254,17 +278,21 @@ class SecurityOperations(Resource):
                 current_app.logger.error("Not found security context with id: " + security_id)
                 return not_found_error(detail= security_context_not_found_detail, cause=api_invoker_no_context_cause)
 
-            result = self.__check_scope(access_token_req["scope"], service_security)
+            result = self.__check_scope(
+                access_token_req["scope"], service_security)
 
             if result != None:
                 return result
 
             expire_time = timedelta(minutes=10)
-            now=datetime.now()
+            now = datetime.now()
 
-            claims = AccessTokenClaims(iss = access_token_req["client_id"], scope=access_token_req["scope"], exp=int((now+expire_time).timestamp()))
-            access_token = create_access_token(identity = access_token_req["client_id"] , additional_claims=claims.to_dict())
-            access_token_resp = AccessTokenRsp(access_token=access_token, token_type="Bearer", expires_in=int(expire_time.total_seconds()), scope=access_token_req["scope"])
+            claims = AccessTokenClaims(iss=access_token_req["client_id"], scope=access_token_req["scope"], exp=int(
+                (now+expire_time).timestamp()))
+            access_token = create_access_token(
+                identity=access_token_req["client_id"], additional_claims=claims.to_dict())
+            access_token_resp = AccessTokenRsp(access_token=access_token, token_type="Bearer", expires_in=int(
+                expire_time.total_seconds()), scope=access_token_req["scope"])
 
             current_app.logger.debug("Created access token")
 
@@ -276,7 +304,6 @@ class SecurityOperations(Resource):
             current_app.logger.error(exception + "::" + str(e))
             return internal_server_error(detail=exception, cause=str(e))
 
-
     def update_servicesecurity(self, api_invoker_id, service_security):
         mycol = self.db.get_col_by_name(self.db.security_info)
         try:
@@ -289,32 +316,42 @@ class SecurityOperations(Resource):
             old_object = mycol.find_one({"api_invoker_id": api_invoker_id})
 
             if old_object is None:
-                current_app.logger.error("Service api not found with id: " + api_invoker_id)
+                current_app.logger.error(
+                    "Service api not found with id: " + api_invoker_id)
                 return not_found_error(detail="Service API not existing", cause="Not exist securiy information for this invoker")
 
             for service_instance in service_security.security_info:
                 if service_instance.interface_details is not None:
                     security_methods = service_instance.interface_details.security_methods
                     pref_security_methods = service_instance.pref_security_methods
-                    valid_security_method = set(security_methods) & set(pref_security_methods)
-                    service_instance.sel_security_method = list(valid_security_method)[0]
+                    valid_security_method = set(
+                        security_methods) & set(pref_security_methods)
+                    service_instance.sel_security_method = list(
+                        valid_security_method)[0]
                 else:
-                    capif_service_col = self.db.get_col_by_name(self.db.capif_service_col)
-                    services_security_object = capif_service_col.find_one({self.filter_aef_id: service_instance.aef_id}, {"aef_profiles.security_methods.$":1})
+                    capif_service_col = self.db.get_col_by_name(
+                        self.db.capif_service_col)
+                    services_security_object = capif_service_col.find_one(
+                        {self.filter_aef_id: service_instance.aef_id}, {"aef_profiles.security_methods.$": 1})
 
                     if services_security_object is None:
-                        current_app.logger.error("Service api with this aefId not found: " + service_instance.aef_id)
+                        current_app.logger.error(
+                            "Service api with this aefId not found: " + service_instance.aef_id)
                         return not_found_error(detail="Service with this aefId not found", cause="Not found Service")
 
                     pref_security_methods = service_instance.pref_security_methods
-                    valid_security_methods = [security_method for array_methods in services_security_object["aef_profiles"] for security_method in array_methods["security_methods"]]
-                    valid_security_method = set(valid_security_methods) & set(pref_security_methods)
-                    service_instance.sel_security_method = list(valid_security_method)[0]
+                    valid_security_methods = [security_method for array_methods in services_security_object["aef_profiles"]
+                                              for security_method in array_methods["security_methods"]]
+                    valid_security_method = set(
+                        valid_security_methods) & set(pref_security_methods)
+                    service_instance.sel_security_method = list(
+                        valid_security_method)[0]
 
             service_security = service_security.to_dict()
             service_security = clean_empty(service_security)
 
-            result = mycol.find_one_and_update(old_object, {"$set":service_security}, projection={'_id': 0, "api_invoker_id":0},return_document=ReturnDocument.AFTER ,upsert=False)
+            result = mycol.find_one_and_update(old_object, {"$set": service_security}, projection={
+                                               '_id': 0, "api_invoker_id": 0}, return_document=ReturnDocument.AFTER, upsert=False)
 
             # result = clean_empty(result)
 
@@ -329,7 +366,6 @@ class SecurityOperations(Resource):
             current_app.logger.error(exception + "::" + str(e))
             return internal_server_error(detail=exception, cause=str(e))
 
-
     def revoke_api_authorization(self, api_invoker_id, security_notification):
 
         mycol = self.db.get_col_by_name(self.db.security_info)
@@ -350,10 +386,12 @@ class SecurityOperations(Resource):
 
             updated_security_context = services_security_context.copy()
             for context in services_security_context["security_info"]:
-                index = services_security_context["security_info"].index(context)
+                index = services_security_context["security_info"].index(
+                    context)
                 if security_notification.aef_id == context["aef_id"] or context["api_id"] in security_notification.api_ids:
                     current_app.logger.debug("Sending message.")
-                    publish_ops.publish_message("acls-messages", "remove-acl:"+str(api_invoker_id)+":"+str(context["api_id"])+":"+str(security_notification.aef_id))
+                    publish_ops.publish_message("acls-messages", "remove-acl:"+str(
+                        api_invoker_id)+":"+str(context["api_id"])+":"+str(security_notification.aef_id))
                     current_app.logger.debug("message sended.")
                     updated_security_context["security_info"].pop(index)
 
@@ -362,13 +400,16 @@ class SecurityOperations(Resource):
             if len(updated_security_context["security_info"]) == 0:
                 mycol.delete_many(my_query)
 
-            #self.notification.send_notification(services_security_context["notification_destination"], security_notification)
-
             current_app.logger.debug("Revoked security context")
-            out= "Netapp with ID " + api_invoker_id + " was revoked by some APIs.", 204
-            return make_response(out, status=204)
+            out = "Netapp with ID " + api_invoker_id + " was revoked by some APIs.", 204
+            res = make_response(out, status=204)
+            if res.status_code == 204:
+                current_app.logger.info("Permissions revoked")
+                RedisEvent("API_INVOKER_AUTHORIZATION_REVOKED").send_event()
+
+            return res
 
         except Exception as e:
             exception = "An exception occurred in revoke security auth"
             current_app.logger.error(exception + "::" + str(e))
-            return internal_server_error(detail=exception, cause=str(e))
\ No newline at end of file
+            return internal_server_error(detail=exception, cause=str(e))
diff --git a/services/capif-client/CAPIFInvokerGUI/invoker_gui/Dockerfile b/services/capif-client/CAPIFInvokerGUI/invoker_gui/Dockerfile
deleted file mode 100644
index 8357bf96b3ffb21ac8b942395a6df5b54b708ccb..0000000000000000000000000000000000000000
--- a/services/capif-client/CAPIFInvokerGUI/invoker_gui/Dockerfile
+++ /dev/null
@@ -1,13 +0,0 @@
-FROM python:3.8
-ENV PYTHONUNBUFFERED 1
-
-RUN apt-get update && apt-get install -y jq && apt-get clean
-RUN apt-get install -y iputils-ping
-
-RUN mkdir -p /usr/src/app
-WORKDIR /usr/src/app
-ADD requirements.txt /usr/src/app/
-RUN pip install -r requirements.txt
-ADD . /usr/src/app/
-
-CMD ["sh", "prepare.sh"]
\ No newline at end of file
diff --git a/services/capif-client/CAPIFInvokerGUI/invoker_gui/capif_ops/config_files/capif_registration.json b/services/capif-client/CAPIFInvokerGUI/invoker_gui/capif_ops/config_files/capif_registration.json
deleted file mode 100644
index 498f2844f3b1090f489960a6469bdf6d5fa6064f..0000000000000000000000000000000000000000
--- a/services/capif-client/CAPIFInvokerGUI/invoker_gui/capif_ops/config_files/capif_registration.json
+++ /dev/null
@@ -1,17 +0,0 @@
-{
-  "folder_to_store_certificates": "/usr/src/app/capif_onboarding",
-  "capif_host": "capifcore",
-  "capif_http_port": "8080",
-  "capif_https_port": "443",
-  "capif_netapp_username": "test_netapp_23",
-  "capif_netapp_password": "test_netapp_password",
-  "capif_callback_url": "http://192.168.1.11:5000",
-  "description": ",test_app_description",
-  "csr_common_name": "test_app_common_name",
-  "csr_organizational_unit": "test_app_ou",
-  "csr_organization": "test_app_o",
-  "crs_locality": "Madrid",
-  "csr_state_or_province_name": "Madrid",
-  "csr_country_name": "ES",
-  "csr_email_address": "test@example.com"
-}
\ No newline at end of file
diff --git a/services/capif-client/CAPIFInvokerGUI/invoker_gui/capif_ops/config_files/credentials.properties b/services/capif-client/CAPIFInvokerGUI/invoker_gui/capif_ops/config_files/credentials.properties
deleted file mode 100755
index 0c39e2c313412f75ba0a252e17da79ef884cf5be..0000000000000000000000000000000000000000
--- a/services/capif-client/CAPIFInvokerGUI/invoker_gui/capif_ops/config_files/credentials.properties
+++ /dev/null
@@ -1,14 +0,0 @@
-[credentials]
-invoker_username = customnetapp
-invoker_password = pass123
-invoker_role = invoker
-invoker_description = Dummy NetApp
-invoker_cn = invoker
-#capif_ip = capicore
-#capif_port = 8080
-capif_callback_ip = host.docker.internal
-capif_callback_port = 8086
-nef_ip = host.docker.internal
-nef_port = 8888
-nef_callback_ip = host.docker.internal
-nef_callback_port = 8085
\ No newline at end of file
diff --git a/services/capif-client/CAPIFInvokerGUI/invoker_gui/capif_ops/config_files/demo_values.json b/services/capif-client/CAPIFInvokerGUI/invoker_gui/capif_ops/config_files/demo_values.json
deleted file mode 100644
index 3a8a2ab4fa101b15b95b45565765dbd00a8a5aab..0000000000000000000000000000000000000000
--- a/services/capif-client/CAPIFInvokerGUI/invoker_gui/capif_ops/config_files/demo_values.json
+++ /dev/null
@@ -1 +0,0 @@
-{"netappID": "93caff2e486955", "ccf_onboarding_url": "api-invoker-management/v1/onboardedInvokers", "ccf_discover_url": "service-apis/v1/allServiceAPIs?api-invoker-id=", "capif_access_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJmcmVzaCI6ZmFsc2UsImlhdCI6MTY4OTU4NzA1OCwianRpIjoiMDViOGMwYWMtYmU4OC00OWViLWFhNWItZTA0ZDM4NWJlYWFkIiwidHlwZSI6ImFjY2VzcyIsInN1YiI6ImN1c3RvbW5ldGFwcCBpbnZva2VyIiwibmJmIjoxNjg5NTg3MDU4LCJleHAiOjE2ODk1ODc5NTh9.k8ZXlgS0CJS-aDJCHgUv0oA4B6CLBjYpp5z3qIrzsvgr20wflpKXiO03c6U3G87T33ocEPR6BWG-ZhpQ1bfml2CKU16gef4nIDIgOKh17yBF0M1eW-gULBZL9exJQIpDWJXQK9oZOrkyHjgN89ieXlVYW9hKaGQfRl_B_HZL0hllWq6E9uE7kHG-VJTEmLJTEyP6uqmfIPLz2znHeTk8eP7IB_vxeIh-7Fr6LcyziDoxMskPDqxzg_6oLyd7biH9qZyWQYvtrEPsh_kJdK5Yc7vK1Kuh01uY9JRk9E97sXU8x0yBjejHgDn9K7_kH1gugPo7eP6nEPvm3BROWHFUmw", "api_id_0": "1d3c0c7803e650264ba30963b96549", "api_name_0": "/nef/api/v1/3gpp-as-session-with-qos/", "aef_id_0": "8cadd2bf35c6adf24bda897b4e8e99", "demo_ipv4_addr_0": "3gppnef", "demo_port_0": 8090, "demo_url_0": "/nef/api/v1/3gpp-as-session-with-qos/v1/{scsAsId}/subscriptions", "netapp_service_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJmcmVzaCI6ZmFsc2UsImlhdCI6MTY4OTU4ODEwOCwianRpIjoiY2NiNDNkNzktNTRjYS00NDI4LTg1OGMtN2MyNDI1MzhiZjU5IiwidHlwZSI6ImFjY2VzcyIsInN1YiI6IjIwZjAxMTY0OTRkNTA0MjhmZTI2ZDdhNjNkYjNlNSIsIm5iZiI6MTY4OTU4ODEwOCwiZXhwIjoxNjg5NTg4NzA4LCJpc3MiOiIyMGYwMTE2NDk0ZDUwNDI4ZmUyNmQ3YTYzZGIzZTUiLCJzY29wZSI6IjNncHAjOGNhZGQyYmYzNWM2YWRmMjRiZGE4OTdiNGU4ZTk5Oi9uZWYvYXBpL3YxLzNncHAtYXMtc2Vzc2lvbi13aXRoLXFvcy8ifQ.PTdAWSGCqEdxroxd1qF_cNA_JRohvNlgw_A49CyaUVqEKrky2_LnVtRll_KOHPGgGcIa8g_vqdM6We71CGx7w_KQPuSccb_wUkPQ5U2kfDT2-dkBZX8le_M1aQ9346tl3iQHqPsoMv3KdiD6mNSbO8f7vlRbQ1o7HQLtLaULB_0xbFr1iJAWdwO6Dm0KOKP_rM6kC5gKyVaLzUPUQBHGQwncQWlKp1Cey3G2cW5Aw_O6kF8mt1R1wgNCedU77JUmW3-ptc1kWmWlSo3UypYNm-XRAMWh44yYnGok5gE1tf451cRc5s9Hfl6Ya2fYYBI1by9x1S_zGlxi6f_OV9z4zg", "api_id_1": "cbc42102826d69a35de147c790a983", "api_name_1": "/nef/api/v1/3gpp-as-session-with-qos/", "aef_id_1": "1f1883a784c43f47aa4fae1dc4821f", "demo_ipv4_addr_1": "127.0.0.1", "demo_port_1": 8090, "demo_url_1": "/{scsAsId}/subscriptions", "demo_resource_id": ""}
\ No newline at end of file
diff --git a/services/capif-client/CAPIFInvokerGUI/invoker_gui/capif_ops/config_files/events.json b/services/capif-client/CAPIFInvokerGUI/invoker_gui/capif_ops/config_files/events.json
deleted file mode 100644
index 3d109204f59cee2b45773ea6d6844a15762a86d8..0000000000000000000000000000000000000000
--- a/services/capif-client/CAPIFInvokerGUI/invoker_gui/capif_ops/config_files/events.json
+++ /dev/null
@@ -1,6 +0,0 @@
-{
-    "events": [
-      "SERVICE_API_AVAILABLE"
-    ],
-    "notificationDestination": "http://192.168.1.11:8080/capifcallbacks"
-  }
\ No newline at end of file
diff --git a/services/capif-client/CAPIFInvokerGUI/invoker_gui/capif_ops/config_files/invoker_details.json b/services/capif-client/CAPIFInvokerGUI/invoker_gui/capif_ops/config_files/invoker_details.json
deleted file mode 100755
index d94aa7fe5ac73c53d7b55664f0b9e36a4a1c8c24..0000000000000000000000000000000000000000
--- a/services/capif-client/CAPIFInvokerGUI/invoker_gui/capif_ops/config_files/invoker_details.json
+++ /dev/null
@@ -1,13 +0,0 @@
-{
-  "notificationDestination" : "http://X:Y/netapp_callback",
-  "supportedFeatures" : "fffffff",
-  "apiInvokerInformation" : "dummy",
-  "websockNotifConfig" : {
-    "requestWebsocketUri" : true,
-    "websocketUri" : "websocketUri"
-  },
-  "onboardingInformation" : {
-    "apiInvokerPublicKey" : ""
-  },
-  "requestTestNotification" : true
-}
\ No newline at end of file
diff --git a/services/capif-client/CAPIFInvokerGUI/invoker_gui/capif_ops/config_files/security_info.json b/services/capif-client/CAPIFInvokerGUI/invoker_gui/capif_ops/config_files/security_info.json
deleted file mode 100755
index c1b08672b8c08e0c8775b6c8a689fbba48fb51c1..0000000000000000000000000000000000000000
--- a/services/capif-client/CAPIFInvokerGUI/invoker_gui/capif_ops/config_files/security_info.json
+++ /dev/null
@@ -1,18 +0,0 @@
-{
-    "securityInfo": [
-      {
-        "prefSecurityMethods": [
-          "OAUTH"
-        ],
-        "authenticationInfo": "string",
-        "authorizationInfo": "string"
-      }
-    ],
-    "notificationDestination": "https://mynotificationdest.com",
-    "requestTestNotification": true,
-    "websockNotifConfig": {
-      "websocketUri": "string",
-      "requestWebsocketUri": true
-    },
-    "supportedFeatures": "fff"
-  }
\ No newline at end of file
diff --git a/services/capif-client/CAPIFInvokerGUI/invoker_gui/capif_ops/config_files/service_request_body.json b/services/capif-client/CAPIFInvokerGUI/invoker_gui/capif_ops/config_files/service_request_body.json
deleted file mode 100644
index 189c49e4d67d9bd1bab5790f7bc6fa50c78d4169..0000000000000000000000000000000000000000
--- a/services/capif-client/CAPIFInvokerGUI/invoker_gui/capif_ops/config_files/service_request_body.json
+++ /dev/null
@@ -1,32 +0,0 @@
-{
-  "ipv4Addr": "10.0.0.3",
-  "notificationDestination": "http://invoker_gui:9091/nefcallbacks",
-  "snssai": {
- "sst": 1,
- "sd": "000001"
- },
-"dnn": "province1.mnc01.mcc202.gprs",
-"qosReference": 82,
-  "altQoSReferences": [
-0
- ],
-"usageThreshold": {
-"duration": 0,
- "totalVolume": 0,
-"downlinkVolume": 0,
- "uplinkVolume": 0
- },
-"qosMonInfo": {
-"reqQosMonParams": [
-"DOWNLINK"
-],
-"repFreqs": [
-"EVENT_TRIGGERED"
-],
- "latThreshDl": 0,
-"latThreshUl": 0,
- "latThreshRp": 0,
-"waitTime": 0,
- "repPeriod": 0
-}
-}
\ No newline at end of file
diff --git a/services/capif-client/CAPIFInvokerGUI/invoker_gui/capif_ops/config_files/token_request.json b/services/capif-client/CAPIFInvokerGUI/invoker_gui/capif_ops/config_files/token_request.json
deleted file mode 100755
index 5408b745186bf0d0bd3f92a43229eef846c989c1..0000000000000000000000000000000000000000
--- a/services/capif-client/CAPIFInvokerGUI/invoker_gui/capif_ops/config_files/token_request.json
+++ /dev/null
@@ -1,6 +0,0 @@
-{
-    "grant_type": "client_credentials",
-    "client_id": "",
-    "client_secret": "string",
-    "scope": ""
-}
\ No newline at end of file
diff --git a/services/capif-client/CAPIFInvokerGUI/invoker_gui/capif_ops/invoker_delete.py b/services/capif-client/CAPIFInvokerGUI/invoker_gui/capif_ops/invoker_delete.py
deleted file mode 100644
index 297f88e559f8724a4a77ac5aa370bdb567e9c5ad..0000000000000000000000000000000000000000
--- a/services/capif-client/CAPIFInvokerGUI/invoker_gui/capif_ops/invoker_delete.py
+++ /dev/null
@@ -1,71 +0,0 @@
-from dis import dis
-import requests
-import json
-import configparser
-import os
-from termcolor import colored
-
-
-class RemoveInvoker():
-
-
-    def __offboard_netapp_to_capif(self, capif_ip,  invoker_id, log_level):
-
-        print(colored("Removing netapp from CAPIF","yellow"))
-        url = 'https://{}/api-invoker-management/v1/onboardedInvokers/{}'.format(capif_ip, invoker_id)
-
-        headers = {
-            'Content-Type': 'application/json'
-        }
-
-        try:
-
-            if log_level == "debug":
-                print(colored("''''''''''REQUEST'''''''''''''''''","blue"))
-                print(colored(f"Request: to {url}","blue"))
-                print(colored(f"Request Headers: {headers}", "blue"))
-                print(colored(f"''''''''''REQUEST'''''''''''''''''", "blue"))
-
-            response = requests.request("DELETE", url, headers=headers, cert=(
-                'capif_ops/certs/dummy.crt', 'capif_ops/certs/invoker_private_key.key'), verify='capif_ops/certs/ca.crt')
-            response.raise_for_status()
-
-            if log_level == "debug":
-                print(colored("''''''''''RESPONSE'''''''''''''''''","green"))
-                print(colored(f"Response to: {response.url}","green"))
-                print(colored(f"Response Headers: {response.headers}","green"))
-                print(colored(f"Response: {response.json()}","green"))
-                print(colored(f"Response Status code: {response.status_code}","green"))
-                print(colored("Success onboard invoker","green"))
-                print(colored("''''''''''RESPONSE'''''''''''''''''","green"))
-
-        except requests.exceptions.HTTPError as err:
-            raise Exception(err.response.text, err.response.status_code)
-
-
-
-    def execute_remove_invoker(self, log_level):
-
-
-        capif_ip = os.getenv('CAPIF_HOSTNAME')
-
-        with open('capif_ops/config_files/demo_values.json', 'r') as demo_file:
-            demo_values = json.load(demo_file)
-
-        try:
-
-            self.__offboard_netapp_to_capif(capif_ip, demo_values["invokerID"], log_level)
-
-            print("ApiInvokerID: {}\n".format(demo_values["invokerID"]))
-            demo_values.pop("invokerID")
-            demo_values.pop("pub_key")
-            with open('capif_ops/config_files/demo_values.json', 'w') as outfile:
-                json.dump(demo_values, outfile)
-
-        except Exception as e:
-            status_code = e.args[0]
-            if status_code == 403:
-                print("Invoker already registered.")
-                print("Chanage invoker public key in invoker_details.json\n")
-            else:
-                print(e)
diff --git a/services/capif-client/CAPIFInvokerGUI/invoker_gui/capif_ops/invoker_discover_service.py b/services/capif-client/CAPIFInvokerGUI/invoker_gui/capif_ops/invoker_discover_service.py
deleted file mode 100644
index 7b608ac6fd23ba097dd4b7ae73661f4ab0e300dd..0000000000000000000000000000000000000000
--- a/services/capif-client/CAPIFInvokerGUI/invoker_gui/capif_ops/invoker_discover_service.py
+++ /dev/null
@@ -1,96 +0,0 @@
-from dis import dis
-import requests
-import json
-import configparser
-import redis
-import os
-from termcolor import colored
-
-
-class DiscoverService():
-
-    def __discover_service_apis(self, capif_ip, api_invoker_id, jwt_token, ccf_url, log_level):
-
-        print(colored("Discover Service", "yellow"))
-        url = "https://{}/{}{}".format(capif_ip, ccf_url, api_invoker_id)
-
-        payload = {}
-        files = {}
-        headers = {
-            'Content-Type': 'application/json'
-        }
-
-        try:
-
-            if log_level == "debug":
-                print(colored("''''''''''REQUEST'''''''''''''''''", "blue"))
-                print(colored(f"Request: to {url}", "blue"))
-                print(colored(f"Request Headers: {headers}", "blue"))
-                print(colored(f"''''''''''REQUEST'''''''''''''''''", "blue"))
-
-            response = requests.request("GET", url, headers=headers, data=payload, files=files, cert=(
-                'capif_ops/certs/dummy.crt', 'capif_ops/certs/invoker_private_key.key'), verify='capif_ops/certs/ca.crt')
-            response.raise_for_status()
-            response_payload = json.loads(response.text)
-
-            if log_level == "debug":
-                print(colored("''''''''''RESPONSE'''''''''''''''''", "green"))
-                print(colored(f"Response to: {response.url}", "green"))
-                print(colored(f"Response Headers: {response.headers}", "green"))
-                print(colored(f"Response: {response.json()}", "green"))
-                print(
-                    colored(f"Response Status code: {response.status_code}", "green"))
-                print(colored("''''''''''RESPONSE'''''''''''''''''", "green"))
-
-            return response_payload
-        except requests.exceptions.HTTPError as err:
-            print(err.response.text)
-            message = json.loads(err.response.text)
-            status = err.response.status_code
-            raise Exception(message, status)
-
-    def execute_discover_service(self, log_level):
-
-
-        with open('capif_ops/config_files/demo_values.json', 'r') as demo_file:
-            demo_values = json.load(demo_file)
-
-        capif_ip = os.getenv('CAPIF_HOSTNAME')
-
-        try:
-            if 'invokerID' in demo_values:
-                invokerID = demo_values['invokerID']
-                capif_access_token = demo_values['capif_access_token']
-                ccf_discover_url = demo_values['ccf_discover_url']
-                discovered_apis = self.__discover_service_apis(
-                    capif_ip, invokerID, capif_access_token, ccf_discover_url, log_level)
-                print(colored(json.dumps(discovered_apis, indent=2), "yellow"))
-
-                count = 0
-                api_list = discovered_apis["serviceAPIDescriptions"]
-                for api in api_list:
-                    getAEF_profiles = api["aefProfiles"][0]
-                    getAEF_interfaces = getAEF_profiles["interfaceDescriptions"][0]
-                    getAEF_versions = getAEF_profiles["versions"][0]
-                    getAEF_resources = getAEF_versions["resources"][0]
-                    demo_values[f'api_id_{count}'] = api["apiId"]
-                    demo_values[f'api_name_{count}'] = api["apiName"]
-                    demo_values[f'aef_id_{count}'] = getAEF_profiles["aefId"]
-                    demo_values[f'demo_ipv4_addr_{count}'] = getAEF_interfaces["ipv4Addr"]
-                    demo_values[f'demo_port_{count}'] = getAEF_interfaces["port"]
-                    demo_values[f'demo_url_{count}'] = api["apiName"] + getAEF_versions["apiVersion"]+ getAEF_resources['uri']
-                    count += 1
-
-                print(colored("Discovered APIs", "yellow"))
-                with open('capif_ops/config_files/demo_values.json', 'w') as outfile:
-                    json.dump(demo_values, outfile)
-
-        except Exception as e:
-            status_code = e.args[0]
-            if status_code == 401:
-                print("API Invoker is not authorized")
-            elif status_code == 403:
-                print("API Invoker does not exist. API Invoker id not found")
-            else:
-                print(e)
-
diff --git a/services/capif-client/CAPIFInvokerGUI/invoker_gui/capif_ops/invoker_get_auth.py b/services/capif-client/CAPIFInvokerGUI/invoker_gui/capif_ops/invoker_get_auth.py
deleted file mode 100644
index dde36942bb6b493791a3142ccae1e6a891d8d1c4..0000000000000000000000000000000000000000
--- a/services/capif-client/CAPIFInvokerGUI/invoker_gui/capif_ops/invoker_get_auth.py
+++ /dev/null
@@ -1,71 +0,0 @@
-import requests
-import json
-import configparser
-import os
-from termcolor import colored
-
-class PreviousAuth():
-
-    def __get_capif_auth(self, capif_ip, capif_port, username, password):
-
-            #print("Geting Auth to exposer")
-            #url = "http://{}:{}/getauth".format(capif_ip, capif_port)
-            url = "https://register:8084/getauth".format(capif_port)
-            #url = "http://{}:{}/getauth".format(capif_ip, capif_port)
-
-            payload = dict()
-            payload['username'] = username
-            payload['password'] = password
-
-            headers = {
-                'Content-Type': 'application/json'
-            }
-
-            try:
-                response = requests.request("POST", url, headers=headers, data=json.dumps(payload), verify=False)
-
-                response.raise_for_status()
-                response_payload = json.loads(response.text)
-
-                return response_payload['access_token']
-
-            except requests.exceptions.HTTPError as err:
-                raise Exception(err.response.text, err.response.status_code)
-
-
-    def execute_get_auth(self, log_level):
-
-        config = configparser.ConfigParser()
-        config.read('capif_ops/config_files/credentials.properties')
-
-        username = config.get("credentials", "invoker_username")
-        password = config.get("credentials", "invoker_password")
-
-        capif_ip = os.getenv('CAPIF_HOSTNAME')
-        capif_port = os.getenv('CAPIF_PORT')
-
-        if os.path.exists("capif_ops/config_files/demo_values.json"):
-            #os.remove("capif_ops/config_files/demo_values.json")
-            with open('capif_ops/config_files/demo_values.json', 'r') as demo_file:
-                demo_values = json.load(demo_file)
-        else:
-            demo_values = {}
-
-        #First we need register exposer in CAPIF
-        try:
-            if 'netappID' in demo_values:
-                access_token = self.__get_capif_auth(capif_ip, capif_port, username, password)
-                demo_values['capif_access_token'] = access_token
-
-            with open('capif_ops/config_files/demo_values.json', 'w') as outfile:
-                json.dump(demo_values, outfile)
-
-            print("Invoker auth Success!")
-        except Exception as e:
-            status_code = e.args[0]
-            if status_code == 409:
-                print("User already registed. Continue with token request\n")
-            else:
-                print(e)
-
-        return True
diff --git a/services/capif-client/CAPIFInvokerGUI/invoker_gui/capif_ops/invoker_get_security_auth.py b/services/capif-client/CAPIFInvokerGUI/invoker_gui/capif_ops/invoker_get_security_auth.py
deleted file mode 100644
index 74b026fa9e4e5859b4143ec21e91169d2619dad7..0000000000000000000000000000000000000000
--- a/services/capif-client/CAPIFInvokerGUI/invoker_gui/capif_ops/invoker_get_security_auth.py
+++ /dev/null
@@ -1,90 +0,0 @@
-from dis import dis
-from email import charset
-import requests
-import json
-import configparser
-import redis
-import os
-from termcolor import colored
-
-
-class InvokerGetSecurityAuth():
-
-    def __get_security_token(self, capif_ip, api_invoker_id, jwt_token, ccf_url, aef_id, api_name, log_level):
-
-    
-        url = "https://{}/capif-security/v1/securities/{}/token".format(capif_ip, api_invoker_id)
-
-        with open('capif_ops/config_files/token_request.json', "rb") as f:
-            payload = json.load(f)
-
-        payload["client_id"] = api_invoker_id
-        payload["scope"] = "3gpp#"+aef_id+":"+api_name
-
-        headers = {
-            'Content-Type': 'application/x-www-form-urlencoded',
-        }
-
-        
-        payload_dict = json.dumps(payload, indent=2)
-
-        print(colored(f"Request Body: {payload_dict}", "yellow"))
-
-        try:
-
-            if log_level == "debug":
-                print(colored("''''''''''REQUEST'''''''''''''''''","blue"))
-                print(colored(f"Request: to {url}","blue"))
-                print(colored(f"Request Headers: {headers}", "blue"))
-                print(colored(f"''''''''''REQUEST'''''''''''''''''", "blue"))
-
-            response = requests.post(url, headers=headers, data=payload, cert=('capif_ops/certs/dummy.crt', 'capif_ops/certs/invoker_private_key.key'), verify='capif_ops/certs/ca.crt')
-            print(response.request.body)
-            response.raise_for_status()
-            response_payload = json.loads(response.text)
-
-            if log_level == "debug":
-                print(colored("''''''''''RESPONSE'''''''''''''''''","green"))
-                print(colored(f"Response to: {response.url}","green"))
-                print(colored(f"Response Headers: {response.headers}","green"))
-                print(colored(f"Response: {response.json()}","green"))
-                print(colored(f"Response Status code: {response.status_code}","green"))
-                print(colored("''''''''''RESPONSE'''''''''''''''''","green"))
-
-            return response_payload
-        except requests.exceptions.HTTPError as err:
-            print(err.response.text)
-            message = json.loads(err.response.text)
-            status = err.response.status_code
-            raise Exception(message, status)
-
-    def execute_get_security_auth(self, log_level):
-
-        with open('capif_ops/config_files/demo_values.json', 'r') as demo_file:
-            demo_values = json.load(demo_file)
-
-        config = configparser.ConfigParser()
-        config.read('credentials.properties')
-
-        capif_ip = os.getenv('CAPIF_HOSTNAME')
-        invokerID = demo_values['invokerID']
-        capif_access_token = demo_values['capif_access_token']
-        ccf_discover_url = demo_values['ccf_discover_url']
-
-        try:
-            if 'aef_id_0' in demo_values and 'api_name_0' in demo_values:
-                token = self.__get_security_token(capif_ip, invokerID, capif_access_token, ccf_discover_url, demo_values['aef_id_0'], demo_values['api_name_0'],log_level)
-                print(colored(json.dumps(token, indent=2),"yellow"))
-                demo_values["netapp_service_token"] = token["access_token"]
-                print(colored("Obtained Security Token","yellow"))
-
-                with open('capif_ops/config_files/demo_values.json', 'w') as outfile:
-                    json.dump(demo_values, outfile)
-        except Exception as e:
-            status_code = e.args[0]
-            if status_code == 401:
-                print("API Invoker is not authorized")
-            elif status_code == 403:
-                print("API Invoker does not exist. API Invoker id not found")
-            else:
-                print(e)
diff --git a/services/capif-client/CAPIFInvokerGUI/invoker_gui/capif_ops/invoker_previous_register.py b/services/capif-client/CAPIFInvokerGUI/invoker_gui/capif_ops/invoker_previous_register.py
deleted file mode 100644
index 6a772648c1c862e6a3401941138bc91299d7ae41..0000000000000000000000000000000000000000
--- a/services/capif-client/CAPIFInvokerGUI/invoker_gui/capif_ops/invoker_previous_register.py
+++ /dev/null
@@ -1,134 +0,0 @@
-import requests
-import json
-import configparser
-import os
-from termcolor import colored
-
-class PreviousRegister():
-
-    def __register_invoker_to_capif(self, capif_ip, capif_port, username, password, role, description, cn):
-
-            #print(colored("Registering exposer to CAPIF","yellow"))
-            url = "https://register:8084/register".format(capif_port)
-            #url = "http://{}:{}/register".format(capif_ip, capif_port)
-
-            payload = dict()
-            payload['username'] = username
-            payload['password'] = password
-            payload['role'] = role
-            payload['description'] = description
-            payload['cn'] = cn
-
-            headers = {
-                'Content-Type': 'application/json'
-            }
-
-            try:
-                # print(colored("''''''''''REQUEST'''''''''''''''''","blue"))
-                # print(colored(f"Request: to {url}","blue"))
-                # print(colored(f"Request Headers: {headers}", "blue"))
-                # print(colored(f"Request Body: {json.dumps(payload)}", "blue"))
-                # print(colored(f"''''''''''REQUEST'''''''''''''''''", "blue"))
-
-                response = requests.request("POST", url, headers=headers, data=json.dumps(payload), verify=False)
-                response.raise_for_status()
-                response_payload = json.loads(response.text)
-
-                # print(colored("''''''''''RESPONSE'''''''''''''''''","green"))
-                # print(colored(f"Response to: {response.url}","green"))
-                # print(colored(f"Response Headers: {response.headers}","green"))
-                # print(colored(f"Response: {response.json()}","green"))
-                # print(colored(f"Response Status code: {response.status_code}","green"))
-                # print(colored("Success to register new exposer","green"))
-                # print(colored("''''''''''RESPONSE'''''''''''''''''","green"))
-                return response_payload['id'], response_payload['ccf_onboarding_url'], response_payload['ccf_discover_url'],
-            except requests.exceptions.HTTPError as err:
-                raise Exception(err.response.status_code)
-
-
-    def __get_capif_auth(self, capif_ip, capif_port, username, password):
-
-            #print("Geting Auth to exposer")
-            url = "https://register:8084/getauth".format(capif_port)
-            #url = "http://{}:{}/getauth".format(capif_ip, capif_port)
-
-            payload = dict()
-            payload['username'] = username
-            payload['password'] = password
-
-            headers = {
-                'Content-Type': 'application/json'
-            }
-
-            try:
-                # print("''''''''''REQUEST'''''''''''''''''")
-                # print("Request: to ",url) 
-                # print("Request Headers: ",  headers) 
-                # print("Request Body: ", json.dumps(payload))
-                # print("''''''''''REQUEST'''''''''''''''''")
-
-                response = requests.request("POST", url, headers=headers, data=json.dumps(payload), verify = False)
-
-                response.raise_for_status()
-                response_payload = json.loads(response.text)
-
-                # print(colored("''''''''''RESPONSE'''''''''''''''''","green"))
-                # print(colored(f"Response to: {response.url}","green"))
-                # print(colored(f"Response Headers: {response.headers}","green"))
-                # print(colored(f"Response: {response.json()}","green"))
-                # print(colored(f"Response Status code: {response.status_code}","green"))
-                # print(colored("Get AUTH Success. Received access token", "green"))
-                # print(colored("''''''''''RESPONSE'''''''''''''''''","green"))
-                return response_payload['access_token']
-
-            except requests.exceptions.HTTPError as err:
-                raise Exception(err.response.text, err.response.status_code)
-
-
-    def execute_previous_register_invoker(self):
-
-        config = configparser.ConfigParser()
-        config.read('capif_ops/config_files/credentials.properties')
-
-        username = config.get("credentials", "invoker_username")
-        password = config.get("credentials", "invoker_password")
-        role = config.get("credentials", "invoker_role")
-        description = config.get("credentials", "invoker_description")
-        cn = config.get("credentials", "invoker_cn")
-
-        capif_ip = os.getenv('CAPIF_HOSTNAME')
-        capif_port = os.getenv('CAPIF_PORT')
-
-        if os.path.exists("capif_ops/config_files/demo_values.json"):
-            #os.remove("capif_ops/config_files/demo_values.json")
-            with open('capif_ops/config_files/demo_values.json', 'r') as demo_file:
-                demo_values = json.load(demo_file)
-        else:
-            demo_values = {}
-
-        #First we need register exposer in CAPIF
-        try:
-            netappID, ccf_onboarding_url, ccf_discover_url = self.__register_invoker_to_capif(capif_ip, capif_port, username, password, role, description, cn)
-            demo_values['netappID'] = netappID
-            demo_values['ccf_onboarding_url'] = ccf_onboarding_url
-            demo_values['ccf_discover_url'] = ccf_discover_url
-            #print(colored(f"NetAppID: {netappID}\n","yellow"))
-            #print("provider ID: {}".format(providerID))
-
-            with open('capif_ops/config_files/demo_values.json', 'w') as outfile:
-                json.dump(demo_values, outfile)
-
-            if 'netappID' in demo_values:
-                access_token = self.__get_capif_auth(capif_ip, capif_port, username, password)
-                demo_values['capif_access_token'] = access_token
-
-            with open('capif_ops/config_files/demo_values.json', 'w') as outfile:
-                json.dump(demo_values, outfile)
-        except Exception as e:
-            status_code = e.args[0]
-            if status_code == 409:
-                print()
-            else:
-                print(e)
-
-        return True
diff --git a/services/capif-client/CAPIFInvokerGUI/invoker_gui/capif_ops/invoker_register_to_capif.py b/services/capif-client/CAPIFInvokerGUI/invoker_gui/capif_ops/invoker_register_to_capif.py
deleted file mode 100644
index 49be7316a33fdc85a6150fe2bbc00471cfe87f77..0000000000000000000000000000000000000000
--- a/services/capif-client/CAPIFInvokerGUI/invoker_gui/capif_ops/invoker_register_to_capif.py
+++ /dev/null
@@ -1,134 +0,0 @@
-from dis import dis
-import requests
-import json
-import configparser
-import redis
-import os
-from termcolor import colored
-
-
-from OpenSSL.SSL import FILETYPE_PEM
-from OpenSSL.crypto import (dump_certificate_request, dump_privatekey, load_publickey, PKey, TYPE_RSA, X509Req, dump_publickey)
-
-
-class RegisterInvoker():
-    def __create_csr(self,  name):
-
-        # create public/private key
-        key = PKey()
-        key.generate_key(TYPE_RSA, 2048)
-
-        # Generate CSR
-        req = X509Req()
-        req.get_subject().CN = name
-        req.get_subject().O = 'Telefonica I+D'
-        req.get_subject().OU = 'Innovation'
-        req.get_subject().L = 'Madrid'
-        req.get_subject().ST = 'Madrid'
-        req.get_subject().C = 'ES'
-        req.get_subject().emailAddress = 'inno@tid.es'
-        req.set_pubkey(key)
-        req.sign(key, 'sha256')
-
-        csr_request = dump_certificate_request(FILETYPE_PEM, req)
-
-        private_key = dump_privatekey(FILETYPE_PEM, key)
-
-        return csr_request, private_key
-
-
-
-
-    def __onboard_netapp_to_capif(self, capif_ip, capif_callback_ip, capif_callback_port, jwt_token, ccf_url, log_level):
-
-        print(colored("Onboarding netapp to CAPIF","yellow"))
-        url = 'https://{}/{}'.format(capif_ip, ccf_url)
-
-        with open('capif_ops/config_files/demo_values.json', 'r') as demo_file:
-            demo_values = json.load(demo_file)
-
-        csr_request, private_key = self.__create_csr("invoker")
-
-        if 'pub_key' not in demo_values:
-            private_key_file = open("capif_ops/certs/invoker_private_key.key", 'wb+')
-            private_key_file.write(bytes(private_key))
-
-        json_file = open('capif_ops/config_files/invoker_details.json', 'rb')
-        payload_dict = json.load(json_file)
-        if 'pub_key' not in demo_values:
-            payload_dict['onboardingInformation']['apiInvokerPublicKey'] = csr_request.decode("utf-8")
-        else:
-            payload_dict['onboardingInformation']['apiInvokerPublicKey'] = demo_values['pub_key']
-        payload_dict['notificationDestination'] = payload_dict['notificationDestination'].replace("X", capif_callback_ip)
-        payload_dict['notificationDestination'] = payload_dict['notificationDestination'].replace("Y", capif_callback_port)
-        payload = json.dumps(payload_dict, indent=2)
-
-        print(colored(f"Request Body: {payload}", "yellow"))
-
-        headers = {
-            'Authorization': 'Bearer {}'.format(jwt_token),
-            'Content-Type': 'application/json'
-        }
-
-        try:
-
-            if log_level == "debug":
-                print(colored("''''''''''REQUEST'''''''''''''''''","blue"))
-                print(colored(f"Request: to {url}","blue"))
-                print(colored(f"Request Headers: {headers}", "blue"))
-                print(colored(f"Request Body: {json.dumps(payload)}", "blue"))
-                print(colored(f"''''''''''REQUEST'''''''''''''''''", "blue"))
-
-            response = requests.request("POST", url, headers=headers, data=payload, verify='capif_ops/certs/ca.crt')
-            response.raise_for_status()
-            response_payload = json.loads(response.text)
-            certification_file = open('capif_ops/certs/dummy.crt', 'wb')
-            certification_file.write(bytes(response_payload['onboardingInformation']['apiInvokerCertificate'], 'utf-8'))
-            certification_file.close()
-
-            if log_level == "debug":
-                print(colored("''''''''''RESPONSE'''''''''''''''''","green"))
-                print(colored(f"Response to: {response.url}","green"))
-                print(colored(f"Response Headers: {response.headers}","green"))
-                print(colored(f"Response: {response.json()}","green"))
-                print(colored(f"Response Status code: {response.status_code}","green"))
-                print(colored("Success onboard invoker","green"))
-                print(colored("''''''''''RESPONSE'''''''''''''''''","green"))
-            return response_payload['apiInvokerId'],  payload_dict['onboardingInformation']['apiInvokerPublicKey']
-        except requests.exceptions.HTTPError as err:
-            raise Exception(err.response.text, err.response.status_code)
-
-
-
-
-
-    def execute_register_invoker(self, log_level):
-
-        config = configparser.ConfigParser()
-        config.read('capif_ops/config_files/credentials.properties')
-
-        capif_ip = os.getenv('CAPIF_HOSTNAME')
-
-        capif_callback_ip = config.get("credentials", "capif_callback_ip")
-        capif_callback_port = config.get("credentials", "capif_callback_port")
-
-        with open('capif_ops/config_files/demo_values.json', 'r') as demo_file:
-            demo_values = json.load(demo_file)
-
-        try:
-            capif_access_token = demo_values['capif_access_token']
-            ccf_onboarding_url = demo_values['ccf_onboarding_url']
-            invokerID, pub_key = self.__onboard_netapp_to_capif(capif_ip, capif_callback_ip, capif_callback_port, capif_access_token, ccf_onboarding_url, log_level)
-            demo_values['invokerID'] = invokerID
-            demo_values['pub_key'] = pub_key
-            print("ApiInvokerID: {}\n".format(invokerID))
-            with open('capif_ops/config_files/demo_values.json', 'w') as outfile:
-                json.dump(demo_values, outfile)
-
-        except Exception as e:
-            status_code = e.args[0]
-            if status_code == 403:
-                print("Invoker already registered.")
-                print("Chanage invoker public key in invoker_details.json\n")
-            else:
-                print(e)
diff --git a/services/capif-client/CAPIFInvokerGUI/invoker_gui/capif_ops/invoker_remove_security_context.py b/services/capif-client/CAPIFInvokerGUI/invoker_gui/capif_ops/invoker_remove_security_context.py
deleted file mode 100644
index 18bb3f35966b07492cbe71f2f6cfb1120689d59e..0000000000000000000000000000000000000000
--- a/services/capif-client/CAPIFInvokerGUI/invoker_gui/capif_ops/invoker_remove_security_context.py
+++ /dev/null
@@ -1,82 +0,0 @@
-from dis import dis
-from email import charset
-import requests
-import json
-import configparser
-import redis
-import os
-from termcolor import colored
-
-
-class InvokerRemoveSecurityContext():
-
-    def __remove_security_service(self, capif_ip, api_invoker_id, jwt_token, ccf_url, demo_values, log_level):
-
-
-        url = "https://{}/capif-security/v1/trustedInvokers/{}".format(capif_ip, api_invoker_id)
-
-        headers = {
-            'Content-Type': 'application/json'
-        }
-
-        try:
-
-            if log_level == "debug":
-                print(colored("''''''''''REQUEST'''''''''''''''''","blue"))
-                print(colored(f"Request: to {url}","blue"))
-                print(colored(f"Request Headers: {headers}", "blue"))
-                print(colored(f"''''''''''REQUEST'''''''''''''''''", "blue"))
-
-            response = requests.delete(url, cert=('capif_ops/certs/dummy.crt', 'capif_ops/certs/invoker_private_key.key'), verify='capif_ops/certs/ca.crt')
-            response.raise_for_status()
-
-            if log_level == "debug":
-                print(colored("''''''''''RESPONSE'''''''''''''''''","green"))
-                print(colored(f"Response to: {response.url}","green"))
-                print(colored(f"Response Headers: {response.headers}","green"))
-                print(colored(f"Response: {response.json()}","green"))
-                print(colored(f"Response Status code: {response.status_code}","green"))
-                print(colored("''''''''''RESPONSE'''''''''''''''''","green"))
-
-            return 
-        except requests.exceptions.HTTPError as err:
-            print(err.response.text)
-            message = json.loads(err.response.text)
-            status = err.response.status_code
-            raise Exception(message, status)
-
-    def execute_remove_security_context(self, log_level):
-
-        with open('capif_ops/config_files/demo_values.json', 'r') as demo_file:
-            demo_values = json.load(demo_file)
-
-        config = configparser.ConfigParser()
-        config.read('credentials.properties')
-
-        capif_ip = os.getenv('CAPIF_HOSTNAME')
-        invokerID = ""
-        capif_access_token = ""
-        ccf_discover_url = ""
-
-        try:
-
-            invokerID = demo_values['invokerID']
-            capif_access_token = demo_values['capif_access_token']
-            ccf_discover_url = demo_values['ccf_discover_url']
-            security_information = self.__remove_security_service(capif_ip, invokerID, capif_access_token, ccf_discover_url, demo_values,log_level)
-            print(colored(json.dumps(security_information, indent=2),"yellow"))
-            print(colored("Register Security context","yellow"))
-
-            with open('capif_ops/config_files/demo_values.json', 'w') as outfile:
-                json.dump(demo_values, outfile)
-
-
-        except Exception as e:
-            status_code = e.args[0]
-            if status_code == 401:
-                print("API Invoker is not authorized")
-            elif status_code == 403:
-                print("API Invoker does not exist. API Invoker id not found")
-            else:
-                print(e)
-
diff --git a/services/capif-client/CAPIFInvokerGUI/invoker_gui/capif_ops/invoker_secutiry_context.py b/services/capif-client/CAPIFInvokerGUI/invoker_gui/capif_ops/invoker_secutiry_context.py
deleted file mode 100644
index a26988f1c499697d219876e7ee16c2c95b8eef3b..0000000000000000000000000000000000000000
--- a/services/capif-client/CAPIFInvokerGUI/invoker_gui/capif_ops/invoker_secutiry_context.py
+++ /dev/null
@@ -1,96 +0,0 @@
-from dis import dis
-from email import charset
-import requests
-import json
-import configparser
-import redis
-import os
-from termcolor import colored
-
-
-class InvokerSecurityContext():
-
-    def __register_security_service(self, capif_ip, api_invoker_id, jwt_token, ccf_url, demo_values, log_level):
-
-
-        url = "https://{}/capif-security/v1/trustedInvokers/{}".format(capif_ip, api_invoker_id)
-
-        with open('capif_ops/config_files/security_info.json', "rb") as f:
-            payload = json.load(f)
-
-        count = 0
-        for profile in payload["securityInfo"]:
-            profile["aefId"] = demo_values[f"aef_id_{count}"]
-            profile["apiId"] = demo_values[f"api_id_{count}"]
-            count += 1
-
-        headers = {
-            'Content-Type': 'application/json'
-        }
-
-        # payload_dict = json.dumps(payload, indent=2)
-
-        # print(colored(f"Request Body: {payload_dict}", "yellow"))
-
-        try:
-
-            if log_level == "debug":
-                print(colored("''''''''''REQUEST'''''''''''''''''","blue"))
-                print(colored(f"Request: to {url}","blue"))
-                print(colored(f"Request Headers: {headers}", "blue"))
-                print(colored(f"''''''''''REQUEST'''''''''''''''''", "blue"))
-
-            response = requests.put(url, json=payload, cert=('capif_ops/certs/dummy.crt', 'capif_ops/certs/invoker_private_key.key'), verify='capif_ops/certs/ca.crt')
-            response.raise_for_status()
-            response_payload = response.json()
-
-            if log_level == "debug":
-                print(colored("''''''''''RESPONSE'''''''''''''''''","green"))
-                print(colored(f"Response to: {response.url}","green"))
-                print(colored(f"Response Headers: {response.headers}","green"))
-                print(colored(f"Response: {response.json()}","green"))
-                print(colored(f"Response Status code: {response.status_code}","green"))
-                print(colored("''''''''''RESPONSE'''''''''''''''''","green"))
-
-            return response_payload
-        except requests.exceptions.HTTPError as err:
-            print(err.response.text)
-            message = json.loads(err.response.text)
-            status = err.response.status_code
-            raise Exception(message, status)
-
-    def execute_register_security_context(self, log_level):
-
-        with open('capif_ops/config_files/demo_values.json', 'r') as demo_file:
-            demo_values = json.load(demo_file)
-
-        config = configparser.ConfigParser()
-        config.read('credentials.properties')
-
-        capif_ip = os.getenv('CAPIF_HOSTNAME')
-        invokerID = ""
-        capif_access_token = ""
-        ccf_discover_url = ""
-
-        try:
-
-            invokerID = demo_values['invokerID']
-            capif_access_token = demo_values['capif_access_token']
-            ccf_discover_url = demo_values['ccf_discover_url']
-            security_information = self.__register_security_service(capif_ip, invokerID, capif_access_token, ccf_discover_url, demo_values,log_level)
-            print(colored(json.dumps(security_information, indent=2),"yellow"))
-            print(colored("Register Security context","yellow"))
-
-            with open('capif_ops/config_files/demo_values.json', 'w') as outfile:
-                json.dump(demo_values, outfile)
-
-
-        except Exception as e:
-            status_code = e.args[0]
-            if status_code == 401:
-                print("API Invoker is not authorized")
-            elif status_code == 403:
-                print("API Invoker does not exist. API Invoker id not found")
-            else:
-                print(e)
-
diff --git a/services/capif-client/CAPIFInvokerGUI/invoker_gui/capif_ops/invoker_to_service.py b/services/capif-client/CAPIFInvokerGUI/invoker_gui/capif_ops/invoker_to_service.py
deleted file mode 100644
index bc54ad7077759696396525433075b004416b97d9..0000000000000000000000000000000000000000
--- a/services/capif-client/CAPIFInvokerGUI/invoker_gui/capif_ops/invoker_to_service.py
+++ /dev/null
@@ -1,168 +0,0 @@
-from dis import dis
-import requests
-import json
-import configparser
-import redis
-import os
-import argparse
-import re
-from termcolor import colored
-
-# Get environment variables
-
-
-class InvokerToService():
-    def __demo_to_aef(self, operation, demo_ip, demo_port, demo_url, jwt_token, name, log_level):
-
-        #def register_netapp_to_nef(nef_ip, nef_port):
-        access_token_url = "https://{}:{}/api/v1/login/access-token".format(demo_ip, demo_port)
-
-        access_payload = {
-        "username": "admin@my-email.com",
-        "password": "pass"
-        }
-
-        response = requests.request('POST', access_token_url, data=access_payload, verify=False)
-        parsed = json.loads(response.text)
-
-        access_token = parsed['access_token']
-
-        print(colored("Using AEF Service API","yellow"))
-        url = "https://{}:{}{}".format(demo_ip, demo_port, demo_url)
-        #url = "http://python_aef:8086/hello"
-
-
-      
-        json_file = open('capif_ops/config_files/service_request_body.json', 'rb')
-        payload_dict = json.load(json_file)
-        payload = json.dumps(payload_dict, indent=2)
-
-        files = {}
-        headers = {
-            'Content-Type': 'application/json',
-            'Authorization': 'Bearer '+ access_token + "," +jwt_token
-        }
-
-        if operation == "create":
-            print(colored(f"Request Body: {payload}", "yellow"))
-            try:
-                if log_level == "debug":
-                    print(colored("''''''''''REQUEST'''''''''''''''''","blue"))
-                    print(colored(f"Request: to {url}","blue"))
-                    print(colored(f"Request Headers: {headers}", "blue"))
-                    print(colored(f"Request Body: {json.dumps(payload, indent=2)}", "blue"))
-                    print(colored(f"''''''''''REQUEST'''''''''''''''''", "blue"))
-                response = requests.request("POST", url, headers=headers, data=payload, files=files, verify=False)
-                response.raise_for_status()
-                response_payload = json.loads(response.text)
-
-                if log_level == "debug":
-                    print(colored("''''''''''RESPONSE'''''''''''''''''","green"))
-                    print(colored(f"Response to: {response.url}","green"))
-                    print(colored(f"Response Headers: {response.headers}","green"))
-                    print(colored(f"Response: {response.json()}","green"))
-                    print(colored(f"Response Status code: {response.status_code}","green"))
-                    print(colored("Success to invoke service","green"))
-                    print(colored(response_payload,"green"))
-                    print(colored("''''''''''RESPONSE'''''''''''''''''","green"))
-
-                link_created_resource = response_payload["link"]
-                resource_id = link_created_resource.rsplit('/', 1)[-1]
-                if resource_id:
-                    with open('capif_ops/config_files/demo_values.json', 'r') as demo_file:
-                        demo_values = json.load(demo_file)
-                    demo_values["demo_resource_id"] = resource_id
-                    with open('capif_ops/config_files/demo_values.json', 'w') as outfile:
-                        json.dump(demo_values, outfile)
-
-                return response_payload
-            except requests.exceptions.HTTPError as err:
-                print(err.response.text)
-                message = json.loads(err.response.text)
-                status = err.response.status_code
-                raise Exception(message, status)
-            
-        elif operation == "delete":
-            with open('capif_ops/config_files/demo_values.json', 'r') as demo_file:
-                        demo_values = json.load(demo_file)
-            resource_id = demo_values["demo_resource_id"]
-            if resource_id == "":
-                print("Not found resource to delete")
-                return 
-
-            url = url + "/" + resource_id
-            try:
-                if log_level == "debug":
-                    print(colored("''''''''''REQUEST'''''''''''''''''","blue"))
-                    print(colored(f"Request: to {url}","blue"))
-                    print(colored(f"Request Headers: {headers}", "blue"))
-                    print(colored(f"''''''''''REQUEST'''''''''''''''''", "blue"))
-                response = requests.request("DELETE", url, headers=headers, verify=False)
-                response.raise_for_status()
-                response_payload = json.loads(response.text)
-
-                if log_level == "debug":
-                    print(colored("''''''''''RESPONSE'''''''''''''''''","green"))
-                    print(colored(f"Response to: {response.url}","green"))
-                    print(colored(f"Response Headers: {response.headers}","green"))
-                    print(colored(f"Response: {response.json()}","green"))
-                    print(colored(f"Response Status code: {response.status_code}","green"))
-                    print(colored("Success to invoke service","green"))
-                    print(colored(response_payload,"green"))
-                    print(colored("''''''''''RESPONSE'''''''''''''''''","green"))
-
-                demo_values["demo_resource_id"] = ""
-                with open('capif_ops/config_files/demo_values.json', 'w') as outfile:
-                    json.dump(demo_values, outfile)
-
-                return response_payload
-            except requests.exceptions.HTTPError as err:
-                print(err.response.text)
-                message = json.loads(err.response.text)
-                status = err.response.status_code
-                raise Exception(message, status)
-
-        else:
-            print("You must spicify if you want create or delete resource")
-
-
-    def execute_invoker_to_service(self, input):
-
-        # parser = argparse.ArgumentParser()
-        # parser.add_argument('--name', metavar= "name", type=str, default="Evolve5G", help="Name to send to the aef service")
-        # args = parser.parse_args()
-        input_name = "prueba"
-        operation = ""
-        log_level = ""
-        params = input.split()
-        if len(params) > 0:
-            operation = params[0]
-            if len(params) > 1:
-                log_level = params[1]
-
-        with open('capif_ops/config_files/demo_values.json', 'r') as demo_file:
-            demo_values = json.load(demo_file)
-
-        try:
-            if 'netapp_service_token' in demo_values:
-
-                print(colored("Doing test","yellow"))
-                jwt_token = demo_values['netapp_service_token']
-                invokerID = demo_values['invokerID']
-                demo_ip = demo_values['demo_ipv4_addr_0']
-                #demo_port = demo_values['demo_port_0']
-                demo_port = 4443
-                demo_url = demo_values['demo_url_0']
-                demo_url = re.sub(r'\{scsAsId\}', 'myNetapp', demo_url)
-
-                result = self.__demo_to_aef(operation, demo_ip, demo_port, demo_url, jwt_token, input_name, log_level)
-                print(colored(f"Response: {json.dumps(result, indent=2)}", "yellow"))
-                print(colored("Success","yellow"))
-        except Exception as e:
-            status_code = e.args[0]
-            if status_code == 401:
-                print("API Invoker is not authorized")
-            elif status_code == 403:
-                print("API Invoker does not exist. API Invoker id not found")
-            else:
-                print(e)
\ No newline at end of file
diff --git a/services/capif-client/CAPIFInvokerGUI/invoker_gui/capif_ops/nef_calback_server/callback.py b/services/capif-client/CAPIFInvokerGUI/invoker_gui/capif_ops/nef_calback_server/callback.py
deleted file mode 100644
index 682d35893dd8b8798fea225098779e0f65b07044..0000000000000000000000000000000000000000
--- a/services/capif-client/CAPIFInvokerGUI/invoker_gui/capif_ops/nef_calback_server/callback.py
+++ /dev/null
@@ -1,26 +0,0 @@
-#!/usr/bin/env python3
-
-from flask import Flask, jsonify, request
-# import redis
-# from redis.commands.json.path import Path
-import secrets
-from werkzeug import serving
-import os
-
-
-
-app = Flask(__name__)
-
-COUNTER = 0
-
-@app.route("/nefcallbacks", methods=["POST"])
-def nefcallback():
-    global COUNTER 
-    COUNTER += 1
-    print(f"Notification received from NEF: {COUNTER}")
-
-    return jsonify(message="Receive message"), 200
-
-
-if __name__ == '__main__':
-    serving.run_simple('0.0.0.0', 8080, app)
\ No newline at end of file
diff --git a/services/capif-client/CAPIFInvokerGUI/invoker_gui/main.py b/services/capif-client/CAPIFInvokerGUI/invoker_gui/main.py
deleted file mode 100644
index bed7c8bcd6b02ac4ba0ffda5d42552040f7b505d..0000000000000000000000000000000000000000
--- a/services/capif-client/CAPIFInvokerGUI/invoker_gui/main.py
+++ /dev/null
@@ -1,98 +0,0 @@
-
-from cmd import Cmd
-from capif_ops.invoker_previous_register import PreviousRegister
-from capif_ops.invoker_register_to_capif import RegisterInvoker
-from capif_ops.invoker_discover_service import  DiscoverService
-from capif_ops.invoker_secutiry_context import InvokerSecurityContext
-from capif_ops.invoker_get_security_auth import InvokerGetSecurityAuth
-from capif_ops.invoker_delete import RemoveInvoker
-from capif_ops.invoker_get_auth import PreviousAuth
-from capif_ops.invoker_remove_security_context import InvokerRemoveSecurityContext
-from capif_ops.invoker_to_service import InvokerToService
-import shlex
-import subprocess
-from art import *
-
-prev_register = PreviousRegister()
-regiter_capif = RegisterInvoker()
-discover_service = DiscoverService()
-register_security_context = InvokerSecurityContext()
-security_context_auth = InvokerGetSecurityAuth()
-remove_invoker = RemoveInvoker()
-invoker_auth = PreviousAuth()
-remove_security_service = InvokerRemoveSecurityContext()
-invoker_service = InvokerToService()
-
-
-
-class CAPIFProvider(Cmd):
-
-  def __init__(self):
-        Cmd.__init__(self)
-        self.prompt = "> "
-        self.intro = tprint("Welcome  to  Invoker  Console")
-
-  def emptyline(self):
-        """Do nothing on empty input line"""
-        pass
-
-  def preloop(self):
-    state = prev_register.execute_previous_register_invoker()
-    self.previous_register_state = state
-
-  def precmd(self, line):
-
-    line = line.lower()
-    args = shlex.split(line)
-
-    if len(args) >= 1 and args[0] in ["goodbye"]:
-        print("The first argument is username")
-        return ""
-
-    elif len(args) >= 1 and args[0] not in ["->", "wall", "follows", "exit", "help"]:
-        pass
-
-    return line
-
-  def do_register_invoker(self, input):
-    'Register invoker to CAPIF'
-    regiter_capif.execute_register_invoker(input)
-
-  def do_discover_service(self, input):
-    'Discover all services published in CAPIF'
-    discover_service.execute_discover_service(input)
-
-  def do_register_security_context(self, input):
-    'Create security context to use services'
-    register_security_context.execute_register_security_context(input)
-
-  def do_get_security_auth(self, input):
-    "If you select Oauth as security method use this command to obtain jwt token to access service"
-    security_context_auth.execute_get_security_auth(input)
-
-  def do_get_auth(self, input):
-    'Get jwt token to register invoker in CAPIF (Optional, only if token expires)'
-    invoker_auth.execute_get_auth(input)
-
-  def do_remove_security_context(self, input):
-    print("Not implemented yet")
-    #remove_security_service.execute_remove_security_context(input)
-
-  def do_remove_invoker(self, input):
-    "Remove invoker from CAPIF"
-    remove_invoker.execute_remove_invoker(input)
-
-  def do_call_service(self, input):
-    "Test invocation os service API"
-    invoker_service.execute_invoker_to_service(input)
-
-  def do_exit(self, input):
-    print('\nExiting...')
-    return True
-
-
-if __name__ == '__main__':
-    try:
-        CAPIFProvider().cmdloop()
-    except KeyboardInterrupt:
-        print('\nExiting...')
\ No newline at end of file
diff --git a/services/capif-client/CAPIFInvokerGUI/invoker_gui/prepare.sh b/services/capif-client/CAPIFInvokerGUI/invoker_gui/prepare.sh
deleted file mode 100755
index ca0305a044b9c7aa9f6d60a88bac3c4f13707fc0..0000000000000000000000000000000000000000
--- a/services/capif-client/CAPIFInvokerGUI/invoker_gui/prepare.sh
+++ /dev/null
@@ -1,11 +0,0 @@
-VAULT_ADDR="http://$VAULT_HOSTNAME:$VAULT_PORT"
-VAULT_TOKEN=$VAULT_ACCESS_TOKEN
-
-curl  -k -retry 30 \
-    --retry-all-errors \
-    --connect-timeout 5 \
-    --max-time 10 \
-    --retry-delay 10 \
-    --retry-max-time 300 \
-    --header "X-Vault-Token: $VAULT_TOKEN" \
-    --request GET "$VAULT_ADDR/v1/secret/data/ca" 2>/dev/null | jq -r '.data.data.ca' -j > ./capif_ops/certs/ca.crt
\ No newline at end of file
diff --git a/services/capif-client/CAPIFInvokerGUI/invoker_gui/requirements.txt b/services/capif-client/CAPIFInvokerGUI/invoker_gui/requirements.txt
deleted file mode 100755
index a9e6ededb6f821c6f5a8c6b991c68a4032dc5fad..0000000000000000000000000000000000000000
--- a/services/capif-client/CAPIFInvokerGUI/invoker_gui/requirements.txt
+++ /dev/null
@@ -1,13 +0,0 @@
-requests == 2.26.0
-evolved5g >= 0.8.9
-python_dateutil >= 2.6.0
-setuptools >= 21.0.0
-Flask
-watchdog
-redis
-configparser
-redis
-pyopenssl
-pyjwt
-art
-termcolor
\ No newline at end of file
diff --git a/services/capif-client/Dockerfile b/services/capif-client/Dockerfile
deleted file mode 100644
index ad7e50339036e5012ef65b99bf89c66a747be050..0000000000000000000000000000000000000000
--- a/services/capif-client/Dockerfile
+++ /dev/null
@@ -1,5 +0,0 @@
-FROM public.ecr.aws/o2v4a8t6/opencapif/client:3.1.3
-
-COPY ./CAPIFInvokerGUI .
-RUN pip3 install -r ./invoker_gui/requirements.txt
-CMD ["sleep", "infinity"]
\ No newline at end of file
diff --git a/services/check_services_are_running.sh b/services/check_services_are_running.sh
index 3bad399d33d55e04256e6faf58cd00293ecbbc4e..16de7046452f3faa4ab94b04e340def03d89d9d4 100755
--- a/services/check_services_are_running.sh
+++ b/services/check_services_are_running.sh
@@ -1,12 +1,39 @@
 #!/bin/bash
+export CAPIF_PRIV_KEY=
+export CAPIF_PRIV_KEY_BASE_64=
+export MONITORING=
+
+running="$(docker compose -f docker-compose-vault.yml ps --services --all --filter "status=running")"
+services="$(docker compose -f docker-compose-vault.yml ps --services --all)"
+if [ "$running" != "$services" ]; then
+    echo "Following Vault services are not running:"
+    # Bash specific
+    comm -13 <(sort <<<"$running") <(sort <<<"$services")
+    exit 1
+else
+    echo "All Vault services are running"
+fi
+
 running="$(docker compose -f docker-compose-capif.yml ps --services --all --filter "status=running")"
 services="$(docker compose -f docker-compose-capif.yml ps --services --all)"
 if [ "$running" != "$services" ]; then
-    echo "Following services are not running:"
+    echo "Following CCF services are not running:"
+    # Bash specific
+    comm -13 <(sort <<<"$running") <(sort <<<"$services")
+    exit 1
+else
+    echo "All CCF services are running"
+fi
+
+running="$(docker compose -f docker-compose-register.yml ps --services --all --filter "status=running")"
+services="$(docker compose -f docker-compose-register.yml ps --services --all)"
+if [ "$running" != "$services" ]; then
+    echo "Following Register services are not running:"
     # Bash specific
     comm -13 <(sort <<<"$running") <(sort <<<"$services")
     exit 1
 else
-    echo "All services are running"
-    exit 0
+    echo "All Register services are running"
 fi
+
+exit 0
diff --git a/services/clean_capif_docker_services.sh b/services/clean_capif_docker_services.sh
index fb8949784d4eb81d5a0b958c197765f82118d60d..cfc5b716dacf2f058c8e868b2fdef97efb96b3ce 100755
--- a/services/clean_capif_docker_services.sh
+++ b/services/clean_capif_docker_services.sh
@@ -6,6 +6,7 @@ help() {
   echo "       -v : Clean vault service"
   echo "       -r : Clean register service"
   echo "       -m : Clean monitoring service"
+  echo "       -s : Clean Robot Mock service"
   echo "       -a : Clean all services"
   echo "       -h : show this help"
   exit 1
@@ -21,7 +22,7 @@ FILES=()
 echo "${FILES[@]}"
 
 # Read params
-while getopts "cvrahm" opt; do
+while getopts "cvrahms" opt; do
   case $opt in
     c)
       echo "Remove Capif services"
@@ -39,9 +40,13 @@ while getopts "cvrahm" opt; do
       echo "Remove monitoring service"
       FILES+=("../monitoring/docker-compose.yml")
       ;;
+    s)
+      echo "Robot Mock Server"
+      FILES+=("docker-compose-mock-server.yml")
+      ;;
     a)
       echo "Remove all services"
-      FILES=("docker-compose-capif.yml" "docker-compose-vault.yml" "docker-compose-register.yml" "../monitoring/docker-compose.yml")
+      FILES=("docker-compose-capif.yml" "docker-compose-vault.yml" "docker-compose-register.yml" "docker-compose-mock-server.yml" "../monitoring/docker-compose.yml")
       ;;
     h)
       help
@@ -74,4 +79,6 @@ done
 
 docker network rm capif-network
 
+docker volume prune --all --force
+
 echo "Clean complete."
diff --git a/services/clean_mock_server.sh b/services/clean_mock_server.sh
new file mode 100755
index 0000000000000000000000000000000000000000..5ea886cdee5476d39a20440d1f2a27f3e49a0857
--- /dev/null
+++ b/services/clean_mock_server.sh
@@ -0,0 +1,16 @@
+#!/bin/bash
+
+FILE="docker-compose-mock-server.yml"
+
+echo "Executing 'docker compose down' for file $FILE"
+docker compose -f "$FILE" down --rmi all
+status=$?
+  if [ $status -eq 0 ]; then
+      echo "*** Removed Service from $FILE ***"
+  else
+      echo "*** Some services of $FILE failed on clean ***"
+  fi
+
+docker volume prune --all --force
+
+echo "Clean complete."
diff --git a/services/docker-compose-capif.yml b/services/docker-compose-capif.yml
index f667d8c2999ac6ca304cafd621dc3ba2df32a074..779df2185c851ae0ef1fa2ce35fa73510f97bc2d 100644
--- a/services/docker-compose-capif.yml
+++ b/services/docker-compose-capif.yml
@@ -1,5 +1,3 @@
-version: '3.7'
-
 services:
   redis:
     image: "redis:alpine"
@@ -11,6 +9,30 @@ services:
       - $PWD/redis.conf:/usr/local/etc/redis/redis.conf
     environment:
       - REDIS_REPLICATION_MODE=master
+    
+
+  helper:
+    build: 
+      context: ./helper
+    expose:
+      - "8080"
+    container_name: helper
+    restart: unless-stopped
+    volumes:
+      - ./helper:/usr/src/app
+    extra_hosts:
+      - host.docker.internal:host-gateway
+      - fluent-bit:host-gateway
+      - otel-collector:host-gateway
+      - vault:host-gateway
+    environment:
+      - CAPIF_HOSTNAME=${CAPIF_HOSTNAME}
+      - CONTAINER_NAME=helper
+      - VAULT_HOSTNAME=vault
+      - VAULT_ACCESS_TOKEN=dev-only-token
+      - VAULT_PORT=8200
+    depends_on:
+      - nginx
 
   access-control-policy:
     build: TS29222_CAPIF_Access_Control_Policy_API
@@ -30,7 +52,6 @@ services:
     depends_on:
       - redis
       - nginx
-    
 
   api-invoker-management:
     build:
diff --git a/services/docker-compose-mock-server.yml b/services/docker-compose-mock-server.yml
new file mode 100644
index 0000000000000000000000000000000000000000..1415b439bb1eec214b6adbd5af74812432544bf1
--- /dev/null
+++ b/services/docker-compose-mock-server.yml
@@ -0,0 +1,20 @@
+services:
+  mock-server:
+    build:
+      context: ./mock_server
+    ports:
+      - 9090:9090
+    volumes:
+      - ./mock_server:/usr/src/app
+    extra_hosts:
+      - host.docker.internal:host-gateway
+    restart: unless-stopped
+    image: public.ecr.aws/o2v4a8t6/opencapif/mock_server:latest
+
+networks:
+  default:
+    name: capif-network
+    external: true
+
+
+
diff --git a/services/docker-compose-register.yml b/services/docker-compose-register.yml
index 5363e0174270c24cdc9ea383f731945c117f4489..b0e55710ca7f1bec7f229dc32d55ee823a80cec2 100644
--- a/services/docker-compose-register.yml
+++ b/services/docker-compose-register.yml
@@ -1,5 +1,3 @@
-version: '3.7'
-
 services:
   register:
     build:
diff --git a/services/docker-compose-vault.yml b/services/docker-compose-vault.yml
index e0bb7bce196fde18748da2967cb1b94485b2ef59..82a38d0a8dd9d728c74a44ffe131ae272c34f211 100644
--- a/services/docker-compose-vault.yml
+++ b/services/docker-compose-vault.yml
@@ -1,4 +1,3 @@
-version: '3.7'
 services:
   vault:
     build:
diff --git a/services/helper/Dockerfile b/services/helper/Dockerfile
new file mode 100644
index 0000000000000000000000000000000000000000..2c521b77a2f232b87dd82c95f7f8fba652d083a7
--- /dev/null
+++ b/services/helper/Dockerfile
@@ -0,0 +1,18 @@
+FROM public.ecr.aws/o2v4a8t6/opencapif/python:3-alpine
+
+RUN mkdir -p /usr/src/app
+WORKDIR /usr/src/app
+
+COPY requirements.txt /usr/src/app/requirements.txt
+
+RUN apk add -U --no-cache gcc build-base linux-headers ca-certificates libffi-dev libressl-dev libxslt-dev
+RUN pip3 install --no-cache-dir -r requirements.txt
+RUN apk add openssl curl redis
+
+COPY . /usr/src/app
+
+EXPOSE 8080
+
+ENTRYPOINT ["gunicorn"]
+
+CMD ["--bind", "0.0.0.0:8080", "--chdir", "/usr/src/app/helper_service", "wsgi:app"]
diff --git a/services/helper/config.yaml b/services/helper/config.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..46e5801bef78265a4d572d2a59f9628814dfafb5
--- /dev/null
+++ b/services/helper/config.yaml
@@ -0,0 +1,18 @@
+mongo: {
+  'user': 'root',
+  'password': 'example',
+  'db': 'capif',
+  'invoker_col': 'invokerdetails',
+  'provider_col': 'providerenrolmentdetails',
+  'col_services': "serviceapidescriptions",
+  'col_security': "security",
+  'col_event': "eventsdetails",
+  'host': 'mongo',
+  'port': "27017"
+}
+
+ca_factory: {
+  "url": "vault",
+  "port": "8200",
+  "token": "dev-only-token"
+}
diff --git a/services/capif-client/CAPIFInvokerGUI/invoker_gui/capif_ops/__init__.py b/services/helper/helper_service/__init__.py
similarity index 100%
rename from services/capif-client/CAPIFInvokerGUI/invoker_gui/capif_ops/__init__.py
rename to services/helper/helper_service/__init__.py
diff --git a/services/helper/helper_service/app.py b/services/helper/helper_service/app.py
new file mode 100644
index 0000000000000000000000000000000000000000..2534195ec8b2bea31ea627474360a97814488905
--- /dev/null
+++ b/services/helper/helper_service/app.py
@@ -0,0 +1,67 @@
+from flask import Flask
+import logging
+from controllers.helper_controller import helper_routes
+from OpenSSL.crypto import PKey, TYPE_RSA, X509Req, dump_certificate_request, FILETYPE_PEM, dump_privatekey
+from config import Config
+import json
+import requests
+
+app = Flask(__name__)
+config = Config().get_config()
+
+# Create a superadmin CSR and keys
+key = PKey()
+key.generate_key(TYPE_RSA, 2048)
+req = X509Req()
+req.get_subject().O = 'OCF helper'
+req.get_subject().OU = 'helper'
+req.get_subject().L = 'Madrid'
+req.get_subject().ST = 'Madrid'
+req.get_subject().C = 'ES'
+req.get_subject().emailAddress = 'helper@tid.es'
+req.set_pubkey(key)
+req.sign(key, 'sha256')
+
+csr_request = dump_certificate_request(FILETYPE_PEM, req)
+private_key = dump_privatekey(FILETYPE_PEM, key)
+
+# Save superadmin private key
+key_file = open("certs/superadmin.key", 'wb+')
+key_file.write(bytes(private_key))
+key_file.close()
+
+# Request superadmin certificate
+url = 'http://{}:{}/v1/pki_int/sign/my-ca'.format(config["ca_factory"]["url"], config["ca_factory"]["port"])  
+headers = {'X-Vault-Token': f"{config["ca_factory"]["token"]}"}  
+data = {
+    'format':'pem_bundle',
+    'ttl': '43000h',
+    'csr': csr_request,
+    'common_name': "superadmin"
+}
+
+response = requests.request("POST", url, headers=headers, data=data, verify = False)
+superadmin_cert = json.loads(response.text)['data']['certificate']
+
+# Save the superadmin certificate
+cert_file = open("certs/superadmin.crt", 'wb')
+cert_file.write(bytes(superadmin_cert, 'utf-8'))
+cert_file.close()
+
+url = f"http://{config['ca_factory']['url']}:{config['ca_factory']['port']}/v1/secret/data/ca"
+headers = {
+
+        'X-Vault-Token': config['ca_factory']['token']
+}
+response = requests.request("GET", url, headers=headers, verify = False)
+
+ca_root = json.loads(response.text)['data']['data']['ca']
+cert_file = open("certs/ca_root.crt", 'wb')
+cert_file.write(bytes(ca_root, 'utf-8'))
+cert_file.close()
+
+app.register_blueprint(helper_routes)
+app.logger.setLevel(logging.DEBUG)
+
+# if __name__ == '__main__':
+#     app.run(host='0.0.0.0', port=8080, debug=True)
\ No newline at end of file
diff --git a/services/capif-client/CAPIFInvokerGUI/invoker_gui/capif_ops/nef_calback_server/__init__.py b/services/helper/helper_service/certs/.gitkeep
similarity index 100%
rename from services/capif-client/CAPIFInvokerGUI/invoker_gui/capif_ops/nef_calback_server/__init__.py
rename to services/helper/helper_service/certs/.gitkeep
diff --git a/services/helper/helper_service/config.py b/services/helper/helper_service/config.py
new file mode 100644
index 0000000000000000000000000000000000000000..f9574a678498483f4e138d4890fc1fa079cebce4
--- /dev/null
+++ b/services/helper/helper_service/config.py
@@ -0,0 +1,20 @@
+import yaml
+import os
+
+#Config class to get config
+class Config:
+    def __init__(self):
+        self.cached = 0
+        self.file="../config.yaml"
+        self.my_config = {}
+
+        stamp = os.stat(self.file).st_mtime
+        if stamp != self.cached:
+            self.cached = stamp
+            f = open(self.file)
+            self.my_config = yaml.safe_load(f)
+            f.close()
+
+    def get_config(self):
+        return self.my_config
+
diff --git a/services/helper/helper_service/controllers/helper_controller.py b/services/helper/helper_service/controllers/helper_controller.py
new file mode 100644
index 0000000000000000000000000000000000000000..f645a564ca88eb238ced5784cdc5ff2450910075
--- /dev/null
+++ b/services/helper/helper_service/controllers/helper_controller.py
@@ -0,0 +1,115 @@
+#!/usr/bin/env python3
+
+from flask import Blueprint, request, current_app, jsonify
+from core.helper_operations import HelperOperations
+from config import Config
+
+config = Config().get_config()
+
+helper_routes = Blueprint("helper_routes", __name__)
+helper_operation = HelperOperations()
+
+@helper_routes.route("/helper/getInvokers", methods=["GET"])
+def getInvokers():
+    uuid = request.args.get('uuid')
+    invoker_id = request.args.get('api_invoker_id')
+    page_size = request.args.get('page_size')
+    page = request.args.get('page')
+    sort_order = request.args.get('sort_order')
+    if page_size:
+        page_size = int(page_size)
+        if page_size < 0:
+            return jsonify(message="The value of the page_size parameter must be greater than 0"), 400
+    if page:
+        page = int(page)
+        if page < 0:
+            return jsonify(message="The value of the page parameter must be greater than 0"), 400
+    
+    current_app.logger.debug(f"uuid: {uuid}, invoker_id: {invoker_id}, page: {page}, page_size: {page_size}, sort_order: {sort_order}")
+
+    return helper_operation.get_invokers(uuid, invoker_id, page, page_size, sort_order)
+
+@helper_routes.route("/helper/getProviders", methods=["GET"])
+def getProviders():
+    uuid = request.args.get('uuid')
+    provider_id = request.args.get('api_prov_dom_id')
+    page_size = request.args.get('page_size')
+    page = request.args.get('page')
+    sort_order = request.args.get('sort_order')
+
+    if page_size:
+        page_size = int(page_size)
+        if page_size < 0:
+            return jsonify(message="The value of the page_size parameter must be greater than 0"), 400
+    if page:
+        page = int(page)
+        if page < 0:
+            return jsonify(message="The value of the page parameter must be greater than 0"), 400
+    
+    current_app.logger.debug(f"uuid: {uuid}, provider_id: {provider_id}, page: {page}, page_size: {page_size}, sort_order: {sort_order}")
+
+    return helper_operation.get_providers(uuid, provider_id, page, page_size, sort_order)
+
+
+@helper_routes.route("/helper/getServices", methods=["GET"])
+def getServices():
+    service_id = request.args.get('service_id')
+    apf_id = request.args.get('apf_id')
+    api_name = request.args.get('api_name')
+    page_size = request.args.get('page_size')
+    page = request.args.get('page')
+    sort_order = request.args.get('sort_order')
+    if page_size:
+        page_size = int(page_size)
+        if page_size < 0:
+            return jsonify(message="The value of the page_size parameter must be greater than 0"), 400
+    if page:
+        page = int(page)
+        if page < 0:
+            return jsonify(message="The value of the page parameter must be greater than 0"), 400
+    
+    current_app.logger.debug(f"service_id: {service_id}, apf_id: {apf_id}, api_name: {api_name}, page: {page}, page_size: {page_size}, sort_order: {sort_order}")
+
+    return helper_operation.get_services(service_id, apf_id, api_name, page, page_size, sort_order)
+
+@helper_routes.route("/helper/getSecurity", methods=["GET"])
+def getSecurity():
+    invoker_id = request.args.get('invoker_id')
+    page_size = request.args.get('page_size')
+    page = request.args.get('page')
+    if page_size:
+        page_size = int(page_size)
+        if page_size < 0:
+            return jsonify(message="The value of the page_size parameter must be greater than 0"), 400
+    if page:
+        page = int(page)
+        if page < 0:
+            return jsonify(message="The value of the page parameter must be greater than 0"), 400
+    
+    current_app.logger.debug(f"invoker_id: {invoker_id}, page: {page}, page_size: {page_size} ")
+
+    return helper_operation.get_security(invoker_id, page, page_size)
+
+@helper_routes.route("/helper/getEvents", methods=["GET"])
+def getEvents():
+    subscriber_id = request.args.get('subscriber_id')
+    subscription_id = request.args.get('subscription_id')
+    page_size = request.args.get('page_size')
+    page = request.args.get('page')
+    if page_size:
+        page_size = int(page_size)
+        if page_size < 0:
+            return jsonify(message="The value of the page_size parameter must be greater than 0"), 400
+    if page:
+        page = int(page)
+        if page < 0:
+            return jsonify(message="The value of the page parameter must be greater than 0"), 400
+    
+    current_app.logger.debug(f"subscriber_id: {subscriber_id}, subscription_id: {subscription_id}, page: {page}, page_size: {page_size} ")
+
+    return helper_operation.get_events(subscriber_id, subscription_id, page, page_size)
+
+
+@helper_routes.route("/helper/deleteEntities/<uuid>", methods=["DELETE"])
+def deleteUserEntities(uuid):
+    return helper_operation.remove_entities(uuid)
diff --git a/services/helper/helper_service/core/helper_operations.py b/services/helper/helper_service/core/helper_operations.py
new file mode 100644
index 0000000000000000000000000000000000000000..9e6354675ae348efbd5b9f47c940f6145f371103
--- /dev/null
+++ b/services/helper/helper_service/core/helper_operations.py
@@ -0,0 +1,204 @@
+from flask import jsonify, current_app
+import pymongo
+from db.db import MongoDatabse
+from config import Config
+import requests
+import os
+
+class HelperOperations:
+
+    def __init__(self):
+        self.db = MongoDatabse()
+        self.mimetype = 'application/json'
+        self.config = Config().get_config()
+
+    def get_invokers(self, uuid, invoker_id, page, page_size, sort_order):
+        current_app.logger.debug(f"Getting the invokers")
+        invoker_col = self.db.get_col_by_name(self.db.invoker_col)
+
+        total_invokers = invoker_col.count_documents({})
+
+        filter = {}
+        if uuid:
+            filter["uuid"]=uuid
+        if invoker_id:
+            filter["api_invoker_id"]=invoker_id
+        
+        sort_direction = pymongo.DESCENDING if sort_order == "desc" else pymongo.ASCENDING
+
+        if page_size and page:
+            index = (page - 1) * page_size
+            documents = invoker_col.find(filter,{"_id":0}).sort("onboarding_date", sort_direction).skip(index).limit(page_size)
+            pages = (total_invokers + page_size - 1) // page_size
+        else:
+            documents = invoker_col.find(filter,{"_id":0}).sort("onboarding_date", sort_direction)
+            pages = 1
+
+        list_invokers= list(documents)
+        long = len(list_invokers)
+        
+        return jsonify(message="Invokers returned successfully", 
+                        invokers=list_invokers,
+                        total = total_invokers,
+                        long = long,
+                        totalPages = pages,
+                        sortOrder = sort_order), 200
+    
+
+    def get_providers(self, uuid, provider_id, page, page_size, sort_order):
+        current_app.logger.debug(f"Getting the providers")
+        provider_col = self.db.get_col_by_name(self.db.provider_col)
+
+        total_providers = provider_col.count_documents({})
+
+        filter = {}
+        if uuid:
+            filter["uuid"]=uuid
+        if provider_id:
+            filter["api_prov_dom_id"]=provider_id
+        
+        sort_direction = pymongo.DESCENDING if sort_order == "desc" else pymongo.ASCENDING
+
+        if page_size and page:
+            index = (page - 1) * page_size
+            documents = provider_col.find(filter,{"_id":0}).sort("onboarding_date", sort_direction).skip(index).limit(page_size)
+            pages = (total_providers + page_size - 1) // page_size
+        else:
+            documents = provider_col.find(filter,{"_id":0}).sort("onboarding_date", sort_direction)
+            pages = 1
+
+        list_providers = list(documents)
+        long = len(list_providers)
+        
+        return jsonify(message="Providers returned successfully", 
+                        providers=list_providers,
+                        total = total_providers,
+                        long = long,
+                        totalPages = pages,
+                        sortOrder = sort_order), 200
+    
+    def get_services(self, service_id, apf_id, api_name, page, page_size, sort_order):
+        current_app.logger.debug(f"Getting the services")
+        service_col = self.db.get_col_by_name(self.db.services_col)
+
+        total_services = service_col.count_documents({})
+
+        filter = {}
+        if service_id:
+            filter["api_id"]=service_id
+        if apf_id:
+            filter["apf_id"]=apf_id
+        if api_name:
+            filter["api_name"]=api_name
+        
+        sort_direction = pymongo.DESCENDING if sort_order == "desc" else pymongo.ASCENDING
+
+        if page_size and page:
+            index = (page - 1) * page_size
+            documents = service_col.find(filter,{"_id":0}).sort("onboarding_date", sort_direction).skip(index).limit(page_size)
+            pages = (total_services + page_size - 1) // page_size
+        else:
+            documents = service_col.find(filter,{"_id":0}).sort("onboarding_date", sort_direction)
+            pages = 1
+
+        list_services= list(documents)
+        long = len(list_services)
+        
+        return jsonify(message="Services returned successfully", 
+                        services=list_services,
+                        total = total_services,
+                        long = long,
+                        totalPages = pages,
+                        sortOrder = sort_order), 200
+    
+    def get_security(self, invoker_id,  page, page_size):
+        current_app.logger.debug(f"Getting the security context")
+        security_col = self.db.get_col_by_name(self.db.security_context_col)
+
+        total_security = security_col.count_documents({})
+
+        filter = {}
+
+        if invoker_id:
+            filter["api_invoker_id"]=invoker_id
+
+        if page_size and page:
+            index = (page - 1) * page_size
+            documents = security_col.find(filter,{"_id":0}).skip(index).limit(page_size)
+            pages = (total_security + page_size - 1) // page_size
+        else:
+            documents = security_col.find(filter,{"_id":0})
+            pages = 1
+
+        list_security= list(documents)
+        long = len(list_security)
+        
+        return jsonify(message="Security context returned successfully", 
+                        security=list_security,
+                        total = total_security,
+                        long = long,
+                        totalPages = pages), 200
+    
+    def get_events(self, subscriber_id, subscription_id,  page, page_size):
+        current_app.logger.debug(f"Getting the events")
+        events_col = self.db.get_col_by_name(self.db.events)
+
+        total_events = events_col.count_documents({})
+
+        filter = {}
+
+        if subscriber_id:
+            filter["subscriber_id"]=subscriber_id
+        if subscription_id:
+            filter["subscription_id"]=subscription_id
+
+        if page_size and page:
+            index = (page - 1) * page_size
+            documents = events_col.find(filter,{"_id":0}).skip(index).limit(page_size)
+            pages = (total_events + page_size - 1) // page_size
+        else:
+            documents = events_col.find(filter,{"_id":0})
+            pages = 1
+
+        list_events= list(documents)
+        long = len(list_events)
+        
+        return jsonify(message="Events returned successfully", 
+                        events=list_events,
+                        total = total_events,
+                        long = long,
+                        totalPages = pages), 200
+    
+    def remove_entities(self, uuid):
+
+        current_app.logger.debug(f"Removing entities for uuid: {uuid}")
+        invoker_col = self.db.get_col_by_name(self.db.invoker_col)
+        provider_col = self.db.get_col_by_name(self.db.provider_col)
+
+        try:
+            if invoker_col.count_documents({'uuid':uuid}) == 0 and provider_col.count_documents({'uuid':uuid}) == 0:
+                current_app.logger.debug(f"No entities found for uuid: {uuid}")
+                return jsonify(message=f"No entities found for uuid: {uuid}"), 204
+            
+            for invoker in invoker_col.find({'uuid':uuid}, {"_id":0}):
+                current_app.logger.debug(f"Removing Invoker: {invoker["api_invoker_id"]}")
+                url = 'https://{}/api-invoker-management/v1/onboardedInvokers/{}'.format(os.getenv('CAPIF_HOSTNAME'), invoker["api_invoker_id"])
+                requests.request("DELETE", url, cert=(
+                            '/usr/src/app/helper_service/certs/superadmin.crt', '/usr/src/app/helper_service/certs/superadmin.key'), verify='/usr/src/app/helper_service/certs/ca_root.crt')
+
+            for provider in provider_col.find({'uuid':uuid}, {"_id":0}):
+                current_app.logger.debug(f"Removing Provider: {provider["api_prov_dom_id"]}")
+                url = 'https://{}/api-provider-management/v1/registrations/{}'.format(os.getenv('CAPIF_HOSTNAME'), provider["api_prov_dom_id"])
+
+                requests.request("DELETE", url, cert=(
+                                '/usr/src/app/helper_service/certs/superadmin.crt', '/usr/src/app/helper_service/certs/superadmin.key'), verify='/usr/src/app/helper_service/certs/ca_root.crt')
+        except Exception as e:
+            current_app.logger.debug(f"Error deleting user entities: {e}")
+            jsonify(message=f"Error deleting user entities: {e}"), 500
+        
+        current_app.logger.debug(f"User entities removed successfully")
+        return jsonify(message="User entities removed successfully"), 200
+
+    
+
+
diff --git a/services/helper/helper_service/db/db.py b/services/helper/helper_service/db/db.py
new file mode 100644
index 0000000000000000000000000000000000000000..bb2853ef6638b8d2294edbd8d7d1c2c225c8a061
--- /dev/null
+++ b/services/helper/helper_service/db/db.py
@@ -0,0 +1,45 @@
+import time
+from pymongo import MongoClient
+from pymongo.errors import AutoReconnect
+from config import Config
+from bson.codec_options import CodecOptions
+
+class MongoDatabse():
+
+    def __init__(self):
+        self.config = Config().get_config()
+        self.db = self.__connect()
+        self.invoker_col = self.config['mongo']['invoker_col']
+        self.provider_col = self.config['mongo']['provider_col']
+        self.services_col = self.config['mongo']['col_services']
+        self.security_context_col = self.config['mongo']['col_security']
+        self.events = self.config['mongo']['col_event']
+
+
+    def get_col_by_name(self, name):
+        return self.db[name].with_options(codec_options=CodecOptions(tz_aware=True))
+    
+    def __connect(self, max_retries=3, retry_delay=1):
+
+        retries = 0
+
+        while retries < max_retries:
+            try:
+                uri = f"mongodb://{self.config['mongo']['user']}:{self.config['mongo']['password']}@" \
+                      f"{self.config['mongo']['host']}:{self.config['mongo']['port']}"
+
+                
+                client = MongoClient(uri)
+                mydb = client[self.config['mongo']['db']]
+                mydb.command("ping")
+                return mydb
+            except AutoReconnect:
+                retries += 1
+                print(f"Reconnecting... Retry {retries} of {max_retries}")
+                time.sleep(retry_delay)
+        return None
+
+    def close_connection(self):
+        if self.db.client:
+            self.db.client.close()
+
diff --git a/services/helper/helper_service/wsgi.py b/services/helper/helper_service/wsgi.py
new file mode 100644
index 0000000000000000000000000000000000000000..6026b0fa96078634d3455ab93d71dcdc78774276
--- /dev/null
+++ b/services/helper/helper_service/wsgi.py
@@ -0,0 +1,4 @@
+from app import app
+
+if __name__ == "__main__":
+    app.run()
diff --git a/services/helper/requirements.txt b/services/helper/requirements.txt
new file mode 100644
index 0000000000000000000000000000000000000000..0e444da92643ea1dacd4f451aef1ccd8c1a7beb4
--- /dev/null
+++ b/services/helper/requirements.txt
@@ -0,0 +1,10 @@
+python_dateutil == 2.9.0.post0
+setuptools == 68.2.2
+Flask == 3.0.3
+pymongo == 4.0.1
+flask_jwt_extended == 4.6.0
+pyopenssl == 24.1.0
+pyyaml == 6.0.1
+requests == 2.32.2
+gunicorn==22.0.0
+packaging==24.0
diff --git a/services/mock_server/Dockerfile b/services/mock_server/Dockerfile
new file mode 100644
index 0000000000000000000000000000000000000000..6d72bf569899e6512254be59539231c0fb49b338
--- /dev/null
+++ b/services/mock_server/Dockerfile
@@ -0,0 +1,21 @@
+# start by pulling the python image
+FROM python:3.10.0-alpine
+
+# copy the requirements file into the image
+COPY ./requirements.txt /app/requirements.txt
+
+# switch working directory
+WORKDIR /app
+
+# install the dependencies and packages in the requirements file
+RUN pip install -r requirements.txt
+
+# copy every content from the local file to the image
+COPY . /app
+
+EXPOSE 9090
+
+# configure the container to run in an executed manner
+ENTRYPOINT [ "python" ]
+
+CMD ["mock_server.py" ]
\ No newline at end of file
diff --git a/services/mock_server/mock_server.py b/services/mock_server/mock_server.py
new file mode 100644
index 0000000000000000000000000000000000000000..e45fae0f241f1801e7ddc9749399f4fa0bc5d796
--- /dev/null
+++ b/services/mock_server/mock_server.py
@@ -0,0 +1,56 @@
+from flask import Flask, request
+import logging
+from logging.handlers import RotatingFileHandler
+import os
+
+app = Flask(__name__)
+
+# Lista para almacenar las solicitudes recibidas
+requests_received = []
+
+def verbose_formatter():
+    return logging.Formatter(
+        '{"timestamp": "%(asctime)s", "level": "%(levelname)s", "logger": "%(name)s", "function": "%(funcName)s", "line": %(lineno)d, "message": %(message)s}',
+        datefmt='%d/%m/%Y %H:%M:%S'
+    )
+
+
+def configure_logging(app):
+    del app.logger.handlers[:]
+    loggers = [app.logger, ]
+    handlers = []
+    console_handler = logging.StreamHandler()
+    console_handler.setLevel(logging.DEBUG)
+    console_handler.setFormatter(verbose_formatter())
+    file_handler = RotatingFileHandler(filename="mock_server.log", maxBytes=1024 * 1024 * 100, backupCount=20)
+    file_handler.setLevel(logging.DEBUG)
+    file_handler.setFormatter(verbose_formatter())
+    handlers.append(console_handler)
+    handlers.append(file_handler)
+  
+
+    for l in loggers:
+        for handler in handlers:
+            l.addHandler(handler)
+        l.propagate = False
+        l.setLevel(logging.DEBUG)
+
+@app.route('/testing', methods=['POST', 'GET'])
+def index():
+    if request.method == 'POST':
+        app.logger.debug(request.json)
+        app.logger.debug(request.headers)
+        requests_received.append(request.json)
+    return 'Mock Server is running'
+
+@app.route('/requests_list', methods=['GET','DELETE'])
+def requests_list():
+    if request.method == 'DELETE':
+        requests_received.clear()
+    return requests_received
+
+
+configure_logging(app)
+
+if __name__ == '__main__':
+    app.run(host=os.environ.get("IP",'0.0.0.0'),port=os.environ.get("PORT",9090),debug=True)
diff --git a/services/mock_server/requirements.txt b/services/mock_server/requirements.txt
new file mode 100644
index 0000000000000000000000000000000000000000..abf28620ee482efbabd6ccf8a2b8d8b554563b03
--- /dev/null
+++ b/services/mock_server/requirements.txt
@@ -0,0 +1 @@
+flask==3.0.3
\ No newline at end of file
diff --git a/services/nginx/nginx.conf b/services/nginx/nginx.conf
index d30ded7b2eb1863cc072284e1f6c5727bf849ef1..ec70d576977be2d61f633f8888ff392d60f1b322 100644
--- a/services/nginx/nginx.conf
+++ b/services/nginx/nginx.conf
@@ -12,6 +12,10 @@ http {
           default "";
           ~(^|,)CN=(?<CN>[^,]+) $CN;
         }
+        map "$request_method:$uri:$ssl_client_s_dn_cn" $helper_error_message {
+          default 'SUCCESS';
+          "~*(GET|DELETE):.*:(?!(superadmin))(.*)"   '{"status":401, "title":"Unauthorized" ,"detail":"Role not authorized for this API route", "cause":"User role must be superadmin"}';
+        }
         map "$request_method:$uri:$ssl_client_s_dn_cn" $invoker_error_message {
           default 'SUCCESS';
           "~*(PUT|DELETE):.*:(?!(INV|superadmin))(.*)"   '{"status":401, "title":"Unauthorized" ,"detail":"Role not authorized for this API route", "cause":"User role must be invoker"}';
@@ -163,6 +167,15 @@ http {
                 proxy_pass http://access-control-policy:8080;
               }
 
+              location /helper {
+                if ( $helper_error_message != SUCCESS ) {
+                  add_header Content-Type 'application/problem+json';
+                  return 401 $helper_error_message;
+                }
+                proxy_set_header X-SSL-Client-Cert $ssl_client_cert;
+                proxy_pass http://helper:8080;
+              }
+
         }
 }
 
diff --git a/services/register/config.yaml b/services/register/config.yaml
index bc1370fd86805cf64bba5f7063b502ce2aa0432c..f63df9fe95452c0443dce72e8934dc2d4998d8fc 100644
--- a/services/register/config.yaml
+++ b/services/register/config.yaml
@@ -3,6 +3,7 @@ mongo: {
   'password': 'example',
   'db': 'capif_users',
   'col': 'user',
+  'admins': 'admins',
   'host': 'mongo_register',
   'port': '27017'
 }
@@ -16,5 +17,6 @@ register: {
   register_uuid: '6ba7b810-9dad-11d1-80b4-00c04fd430c8',
   refresh_expiration: 30, #days
   token_expiration: 10, #mins
-  admin_users: {admin: "password123"}
+  admin_users: {admin_user: "admin",
+                admin_pass: "password123"}
 }
\ No newline at end of file
diff --git a/services/register/pytest.ini b/services/register/pytest.ini
new file mode 100644
index 0000000000000000000000000000000000000000..62fc4e2aa1169ef0638ebceab8d77e0cabe9d67a
--- /dev/null
+++ b/services/register/pytest.ini
@@ -0,0 +1,4 @@
+# content of pytest.ini
+[pytest]
+python_files = register_services/config.py
+
diff --git a/services/register/register_service/app.py b/services/register/register_service/app.py
index cca3cfb3c61614a3b2ac66d4c8edef66f3e0f793..a4b0a50014609efc85addf328b8f685dfb885c99 100644
--- a/services/register/register_service/app.py
+++ b/services/register/register_service/app.py
@@ -6,6 +6,8 @@ from OpenSSL.crypto import PKey, TYPE_RSA, X509Req, dump_certificate_request, FI
 import requests
 import json
 from config import Config
+from db.db import MongoDatabse
+
 
 app = Flask(__name__)
 
@@ -71,6 +73,11 @@ response = requests.request("GET", url, headers=headers, verify = False)
 
 key_data = json.loads(response.text)["data"]["data"]["key"]
 
+# Create an Admin in the Admin Collection
+client = MongoDatabse()
+if not client.get_col_by_name(client.capif_admins).find_one({"admin_name": config["register"]["admin_users"]["admin_user"], "admin_pass": config["register"]["admin_users"]["admin_pass"]}):
+    client.get_col_by_name(client.capif_admins).insert_one({"admin_name": config["register"]["admin_users"]["admin_user"], "admin_pass": config["register"]["admin_users"]["admin_pass"]})
+
 
 app.config['JWT_ALGORITHM'] = 'RS256'
 app.config['JWT_PRIVATE_KEY'] = key_data
diff --git a/services/register/register_service/controllers/register_controller.py b/services/register/register_service/controllers/register_controller.py
index 58620baf6950f0ff245c58e6b863dfe431e03d7a..da354690d65706959068276a7e6b81f0cffc3a9d 100644
--- a/services/register/register_service/controllers/register_controller.py
+++ b/services/register/register_service/controllers/register_controller.py
@@ -7,6 +7,7 @@ from config import Config
 
 from functools import wraps
 from datetime import datetime, timedelta
+from db.db import MongoDatabse
 
 from flask_httpauth import HTTPBasicAuth
 import jwt
@@ -36,7 +37,9 @@ def generate_tokens(username):
 @auth.verify_password
 def verify_password(username, password):
     users = register_operation.get_users()[0].json["users"]
-    if username in config["register"]["admin_users"] and password == config["register"]["admin_users"][username]:
+    client = MongoDatabse()
+    admin = client.get_col_by_name(client.capif_admins).find_one({"admin_name": username, "admin_pass": password})
+    if admin:
         return username, "admin"
     for user in users:
         if user["username"] == username and user["password"]==password:
@@ -86,12 +89,40 @@ def refresh_token(username):
 @register_routes.route("/createUser", methods=["POST"])
 @admin_required()
 def register(username):
-    username = request.json["username"]
-    password = request.json["password"]
-    description = request.json["description"]
-    email = request.json["email"]
+    required_fields = {
+        "username": str,
+        "password": str,
+        "enterprise": str,
+        "country": str,
+        "email": str,
+        "purpose": str
+    }
+
+    optional_fields = {
+        "phone_number": str,
+        "company_web": str,
+        "description": str
+    }
+
+    user_info = request.get_json()
+
+    missing_fields = []
+    for field, field_type in required_fields.items():
+        if field not in user_info:
+            missing_fields.append(field)
+        elif not isinstance(user_info[field], field_type):
+            return jsonify({"error": f"Field '{field}' must be of type {field_type.__name__}"}), 400
+
+    for field, field_type in optional_fields.items():
+        if field in user_info and not isinstance(user_info[field], field_type):
+            return jsonify({"error": f"Optional field '{field}' must be of type {field_type.__name__}"}), 400
+        if field not in user_info:
+            user_info[field] = None
+
+    if missing_fields:
+        return jsonify({"error": "Missing required fields", "fields": missing_fields}), 400
 
-    return register_operation.register_user(username, password, description, email)
+    return register_operation.register_user(user_info)
 
 @register_routes.route("/getauth", methods=["GET"])
 @auth.login_required
diff --git a/services/register/register_service/core/register_operations.py b/services/register/register_service/core/register_operations.py
index cf5219d759e955551fcd260899a2c65be7a497cc..a420fb88f45ddfc0e377c8dc59bf56b696dc51f9 100644
--- a/services/register/register_service/core/register_operations.py
+++ b/services/register/register_service/core/register_operations.py
@@ -3,8 +3,10 @@ from flask_jwt_extended import create_access_token
 from db.db import MongoDatabse
 from datetime import datetime
 from config import Config
+import requests
 import uuid
 
+
 class RegisterOperations:
 
     def __init__(self):
@@ -12,17 +14,18 @@ class RegisterOperations:
         self.mimetype = 'application/json'
         self.config = Config().get_config()
 
-    def register_user(self, username, password, description, email):
+    def register_user(self, user_info):
 
         mycol = self.db.get_col_by_name(self.db.capif_users)
-        exist_user = mycol.find_one({"username": username})
+        exist_user = mycol.find_one({"username": user_info["username"]})
         if exist_user:
             return jsonify("user already exists"), 409
         
         name_space = uuid.UUID(self.config["register"]["register_uuid"])
-        user_uuid = str(uuid.uuid5(name_space, username))
+        user_uuid = str(uuid.uuid5(name_space,user_info["username"]))
 
-        user_info = dict(uuid=user_uuid, username=username, password=password, description=description, email=email, onboarding_date=datetime.now())
+        user_info["uuid"] = user_uuid
+        user_info["onboarding_date"]=datetime.now()
         obj = mycol.insert_one(user_info)
 
         return jsonify(message="User registered successfully", uuid=user_uuid), 201
@@ -60,11 +63,11 @@ class RegisterOperations:
         mycol = self.db.get_col_by_name(self.db.capif_users)
 
         try:
-            mycol.delete_one({"uuid": uuid})
             
-
-            # Request to the helper to delete invokers and providers
-
+            url = f"https://capifcore/helper/deleteEntities/{uuid}" 
+            requests.delete(url, cert=("register_service/certs/superadmin.crt", "register_service/certs/superadmin.key"), verify="register_service/certs/ca_root.crt")
+            
+            mycol.delete_one({"uuid": uuid})
 
             return jsonify(message="User removed successfully"), 204
         except Exception as e:
diff --git a/services/register/register_service/db/db.py b/services/register/register_service/db/db.py
index 9e64103b191e766c5ddcbd5fd474ca1e233ed3c0..fdf448e5be3b675d585bccf141b8e2a6ffe67754 100644
--- a/services/register/register_service/db/db.py
+++ b/services/register/register_service/db/db.py
@@ -10,6 +10,7 @@ class MongoDatabse():
         self.config = Config().get_config()
         self.db = self.__connect()
         self.capif_users = self.config['mongo']['col']
+        self.capif_admins = self.config['mongo']['admins']
 
 
     def get_col_by_name(self, name):
diff --git a/services/run.sh b/services/run.sh
index 83011c34414af3725c56b86640b6e50591298276..4465aaa49909052f767c9d0bd1e6aeacfe3dfad2 100755
--- a/services/run.sh
+++ b/services/run.sh
@@ -3,6 +3,7 @@
 help() {
   echo "Usage: $1 <options>"
   echo "       -c : Setup different hostname for capif"
+  echo "       -s : Run Mock server"
   echo "       -m : Clean monitoring service"
   echo "       -h : show this help"
   exit 1
@@ -12,10 +13,14 @@ HOSTNAME=capifcore
 MONITORING_STATE=false
 DEPLOY=all
 
-#Needed to avoid write permissions on bind volumes with prometheus and grafana
+# Needed to avoid write permissions on bind volumes with prometheus and grafana
 DUID=$(id -u)
 DGID=$(id -g)
 
+# Mock Server configuration
+IP=0.0.0.0
+PORT=9090
+
 # Get docker compose version
 docker_version=$(docker compose version --short | cut -d',' -f1)
 IFS='.' read -ra version_components <<< "$docker_version"
@@ -28,7 +33,7 @@ else
 fi
 
 # Read params
-while getopts ":c:mh" opt; do
+while getopts ":c:msh" opt; do
   case $opt in
     c)
       HOSTNAME="$OPTARG"
@@ -36,6 +41,9 @@ while getopts ":c:mh" opt; do
     m)
       MONITORING_STATE=true
       ;;
+    s)
+      ROBOT_MOCK_SERVER=true
+      ;;
     h)
       help
       ;;  
@@ -97,6 +105,21 @@ if [ $status -eq 0 ]; then
     echo "*** Register Service are running ***"
 else
     echo "*** Register Service failed to start ***"
+    exit $status
+fi
+
+if [ "$ROBOT_MOCK_SERVER" == "true" ] ; then
+    echo '***Robot Mock Server set as true***'
+    echo '***Creating Robot Mock Server stack***'
+
+    IP=$IP PORT=$PORT docker compose -f "docker-compose-mock-server.yml" up --detach
+    status=$?
+    if [ $status -eq 0 ]; then
+        echo "*** Monitoring Stack Runing ***"
+    else
+        echo "*** Monitoring Stack failed to start ***"
+        exit $status
+    fi
 fi
 
 exit $status
diff --git a/services/run_capif_tests.sh b/services/run_capif_tests.sh
index b73893a45ca40cacecb4dca088999461a9de55de..7762fcd8f016a5ca227599b310cef5523ce577e5 100755
--- a/services/run_capif_tests.sh
+++ b/services/run_capif_tests.sh
@@ -9,13 +9,34 @@ RESULT_FOLDER=$REPOSITORY_BASE_FOLDER/results
 ROBOT_DOCKER_FILE_FOLDER=$REPOSITORY_BASE_FOLDER/tools/robot
 
 # nginx Hostname and http port (80 by default) to reach for tests
+# CAPIF_REGISTER=registercapif.mobilesandbox.cloud
+CAPIF_REGISTER=capifcore
+# CAPIF_REGISTER_PORT=37211
+CAPIF_REGISTER_PORT=8084
+# CAPIF_HOSTNAME=capif.mobilesandbox.cloud
 CAPIF_HOSTNAME=capifcore
 CAPIF_HTTP_PORT=8080
 CAPIF_HTTPS_PORT=443
 
-echo "HOSTNAME = $CAPIF_HOSTNAME"
+# VAULT access configuration
+# CAPIF_VAULT=vault.5gnacar.int
+CAPIF_VAULT=vault
+CAPIF_VAULT_PORT=8200
+# CAPIF_VAULT_TOKEN=dev-only-token
+CAPIF_VAULT_TOKEN=read-ca-token
+
+
+MOCK_SERVER_URL=http://mock-server:9090
+
+
+echo "CAPIF_HOSTNAME = $CAPIF_HOSTNAME"
+echo "CAPIF_REGISTER = $CAPIF_REGISTER"
 echo "CAPIF_HTTP_PORT = $CAPIF_HTTP_PORT"
 echo "CAPIF_HTTPS_PORT = $CAPIF_HTTPS_PORT"
+echo "CAPIF_VAULT = $CAPIF_VAULT"
+echo "CAPIF_VAULT_PORT = $CAPIF_VAULT_PORT"
+echo "CAPIF_VAULT_TOKEN = $CAPIF_VAULT_TOKEN"
+echo "MOCK_SERVER_URL = $MOCK_SERVER_URL"
 
 docker >/dev/null 2>/dev/null
 if [[ $? -ne 0 ]]
@@ -45,8 +66,15 @@ docker run -ti --rm --network="host" \
     --add-host host.docker.internal:host-gateway \
     --add-host vault:host-gateway \
     --add-host register:host-gateway \
+    --add-host mock-server:host-gateway \
     -v $TEST_FOLDER:/opt/robot-tests/tests \
     -v $RESULT_FOLDER:/opt/robot-tests/results ${DOCKER_ROBOT_IMAGE}:${DOCKER_ROBOT_IMAGE_VERSION}  \
     --variable CAPIF_HOSTNAME:$CAPIF_HOSTNAME \
     --variable CAPIF_HTTP_PORT:$CAPIF_HTTP_PORT \
-    --variable CAPIF_HTTPS_PORT:$CAPIF_HTTPS_PORT $@
+    --variable CAPIF_HTTPS_PORT:$CAPIF_HTTPS_PORT \
+    --variable CAPIF_REGISTER:$CAPIF_REGISTER \
+    --variable CAPIF_REGISTER_PORT:$CAPIF_REGISTER_PORT \
+    --variable CAPIF_VAULT:$CAPIF_VAULT \
+    --variable CAPIF_VAULT_PORT:$CAPIF_VAULT_PORT \
+    --variable CAPIF_VAULT_TOKEN:$CAPIF_VAULT_TOKEN \
+    --variable MOCK_SERVER_URL:$MOCK_SERVER_URL $@
diff --git a/services/run_mock_server.sh b/services/run_mock_server.sh
new file mode 100755
index 0000000000000000000000000000000000000000..5a194c469371de592d4f63ec5e8bbfc59598489c
--- /dev/null
+++ b/services/run_mock_server.sh
@@ -0,0 +1,47 @@
+#!/bin/bash
+
+help() {
+  echo "Usage: $1 <options>"
+  echo "       -i : Setup different host ip for mock server (default 0.0.0.0)"
+  echo "       -p : Setup different port for mock server (default 9090)"
+  echo "       -h : show this help"
+  exit 1
+}
+
+IP=0.0.0.0
+PORT=9090
+
+# Read params
+while getopts ":i:p:h" opt; do
+  case $opt in
+    i)
+      IP="$OPTARG"
+      ;;
+    p)
+      PORT=$OPTARG
+      ;;
+    h)
+      help
+      ;;  
+    \?)
+      echo "Not valid option: -$OPTARG" >&2
+      help
+      ;;
+    :)
+      echo "The -$OPTARG option requires an argument." >&2
+      help
+      ;;
+  esac
+done
+
+echo Robot Framework Mock Server will listen on $IP:$PORT
+
+IP=$IP PORT=$PORT docker compose -f "docker-compose-mock-server.yml" up --detach --build
+
+status=$?
+if [ $status -eq 0 ]; then
+    echo "*** All Capif services are running ***"
+else
+    echo "*** Some Capif services failed to start ***"
+    exit $status
+fi
diff --git a/services/show_logs.sh b/services/show_logs.sh
index b53641dd216e3cb43d9cd4ca0eaca85567ca60e4..c2bcf52d90607d3da9364c11c44c99d4bf209071 100755
--- a/services/show_logs.sh
+++ b/services/show_logs.sh
@@ -5,6 +5,7 @@ help() {
   echo "       -c : Show capif services"
   echo "       -v : Show vault service"
   echo "       -r : Show register service"
+  echo "       -s : Show Robot Mock Server service"
   echo "       -m : Show monitoring service"
   echo "       -a : Show all services"
   echo "       -f : Follow log output"
@@ -23,7 +24,7 @@ echo "${FILES[@]}"
 FOLLOW=""
 
 # Read params
-while getopts "cvrahmf" opt; do
+while getopts "cvrahmfs" opt; do
   case $opt in
     c)
       echo "Show Capif services"
@@ -37,13 +38,17 @@ while getopts "cvrahmf" opt; do
       echo "Show register service"
       FILES+=("-f docker-compose-register.yml")
       ;;
+    s)
+      echo "Show Mock Server service"
+      FILES+=("-f docker-compose-mock-server.yml")
+      ;;
     m)
       echo "Show monitoring service"
       FILES+=("-f ../monitoring/docker-compose.yml")
       ;;
     a)
       echo "Show all services"
-      FILES=("-f docker-compose-capif.yml" -f "docker-compose-vault.yml" -f "docker-compose-register.yml" -f "../monitoring/docker-compose.yml")
+      FILES=("-f docker-compose-capif.yml" -f "docker-compose-vault.yml" -f "docker-compose-register.yml" -f "docker-compose-mock-server.yml" -f "../monitoring/docker-compose.yml")
       ;;
     f)
       echo "Setup follow logs"
diff --git a/tests/features/CAPIF Api Access Control Policy/capif_api_access_control_policy.robot b/tests/features/CAPIF Api Access Control Policy/capif_api_access_control_policy.robot
index 04d789839c2fb6ed6212ede4fd1abf5228b09a55..ec0f0821b4ae9eff2896b2e6dcd18dc9874137eb 100644
--- a/tests/features/CAPIF Api Access Control Policy/capif_api_access_control_policy.robot	
+++ b/tests/features/CAPIF Api Access Control Policy/capif_api_access_control_policy.robot	
@@ -238,7 +238,6 @@ Retrieve ACL with security context created by two different Invokers
     ...    username=${AEF_PROVIDER_USERNAME}
 
     Check Response Variable Type And Values    ${resp}    200    AccessControlPolicyList
-
     # Check returned values
     Should Not Be Empty    ${resp.json()['apiInvokerPolicies']}
     Length Should Be    ${resp.json()['apiInvokerPolicies']}    2
diff --git a/tests/features/CAPIF Api Events/capif_events_api.robot b/tests/features/CAPIF Api Events/capif_events_api.robot
index f2a596689598ea7761ca25304e4e8f0e469f6c8e..d5e02d26d1b9d7592d5cc84e489bfecf2bc1dd0e 100644
--- a/tests/features/CAPIF Api Events/capif_events_api.robot	
+++ b/tests/features/CAPIF Api Events/capif_events_api.robot	
@@ -2,6 +2,7 @@
 Resource            /opt/robot-tests/tests/resources/common.resource
 Library             /opt/robot-tests/tests/libraries/bodyRequests.py
 Library             XML
+Library             String
 Resource            /opt/robot-tests/tests/resources/common/basicRequests.robot
 Resource            ../../resources/common.resource
 
@@ -137,3 +138,665 @@ Deletes an individual CAPIF Event Subscription with invalid SubscriptionId
     ...    title=Unauthorized
     ...    detail=User not authorized
     ...    cause=You are not the owner of this resource
+
+Invoker receives Service API Invocation events
+    [Tags]    capif_api_events-6    mockserver
+
+    # Initialize Mock server
+    Init Mock Server
+
+    # Register APF
+    ${register_user_info}=    Provider Default Registration
+
+    # Publish one api
+    Publish Service Api    ${register_user_info}
+
+    # Register INVOKER
+    ${register_user_info_invoker}    ${url}    ${request_body}=    Invoker Default Onboarding
+
+    ${discover_response}=    Get Request Capif
+    ...    ${DISCOVER_URL}${register_user_info_invoker['api_invoker_id']}
+    ...    server=${CAPIF_HTTPS_URL}
+    ...    verify=ca.crt
+    ...    username=${INVOKER_USERNAME}
+
+    ${api_ids}    ${api_names}=    Get Api Ids And Names From Discover Response    ${discover_response}
+
+    # Subscribe to events
+    ${events_list}=    Create List    SERVICE_API_INVOCATION_SUCCESS    SERVICE_API_INVOCATION_FAILURE
+    ${aef_ids}=    Create List    ${register_user_info['aef_id']}
+    ${event_filter}=    Create Capif Event Filter    aefIds=${aef_ids}
+    ${event_filters}=    Create List    ${event_filter}
+
+    ${request_body}=    Create Events Subscription
+    ...    events=@{events_list}
+    ...    notificationDestination=${MOCK_SERVER_URL}/testing
+    ...    eventFilters=${event_filters}
+    ${resp}=    Post Request Capif
+    ...    /capif-events/v1/${register_user_info_invoker['api_invoker_id']}/subscriptions
+    ...    json=${request_body}
+    ...    server=${CAPIF_HTTPS_URL}
+    ...    verify=ca.crt
+    ...    username=${INVOKER_USERNAME}
+
+    # Check Results
+    Check Response Variable Type And Values    ${resp}    201    EventSubscription
+    ${subscriber_id}    ${subscription_id}=    Check Event Location Header    ${resp}
+
+    # Create Log Entry, emulate success and failure api invocation
+    ${results}=    Create List    200    400
+    ${request_body}=    Create Log Entry
+    ...    ${register_user_info['aef_id']}
+    ...    ${register_user_info_invoker['api_invoker_id']}
+    ...    ${api_ids}
+    ...    ${api_names}
+    ...    results=${results}
+    ${resp}=    Post Request Capif
+    ...    /api-invocation-logs/v1/${register_user_info['aef_id']}/logs
+    ...    json=${request_body}
+    ...    server=${CAPIF_HTTPS_URL}
+    ...    verify=ca.crt
+    ...    username=${AEF_PROVIDER_USERNAME}
+
+    # Check Results
+    Check Response Variable Type And Values    ${resp}    201    InvocationLog
+    ${resource_url}=    Check Location Header    ${resp}    ${LOCATION_LOGGING_RESOURCE_REGEX}
+
+    # Check Event Notifications
+    ## Create check Events to ensure all notifications were received
+    ${events_expected}=    Create Events From InvocationLogs
+    ...    ${subscription_id}
+    ...    ${request_body}
+    ## Check Events Expected towards received notifications at mock server
+    Check Mock Server Notification Events    ${events_expected}
+
+Invoker subscribe to Service API Available and Unavailable events
+    [Tags]    capif_api_events-7    mockserver
+
+    # Initialize Mock server
+    Init Mock Server
+
+    # Register APF
+    ${register_user_info_provider}=    Provider Default Registration
+
+    # Publish one api
+    ${service_api_description_published_1}    ${resource_url_1}    ${request_body}=    Publish Service Api
+    ...    ${register_user_info_provider}
+
+    # Register INVOKER
+    ${register_user_info_invoker}    ${url}    ${request_body}=    Invoker Default Onboarding
+
+    ${discover_response}=    Get Request Capif
+    ...    ${DISCOVER_URL}${register_user_info_invoker['api_invoker_id']}
+    ...    server=${CAPIF_HTTPS_URL}
+    ...    verify=ca.crt
+    ...    username=${INVOKER_USERNAME}
+
+    ${api_ids}    ${api_names}=    Get Api Ids And Names From Discover Response    ${discover_response}
+
+    # Subscribe to events
+    ${events_list}=    Create List    SERVICE_API_AVAILABLE    SERVICE_API_UNAVAILABLE
+    ${aef_ids}=    Create List    ${register_user_info_provider['aef_id']}
+    ${event_filter}=    Create Capif Event Filter    aefIds=${aef_ids}
+    ${event_filters}=    Create List    ${event_filter}
+
+    ${request_body}=    Create Events Subscription
+    ...    events=@{events_list}
+    ...    notificationDestination=${MOCK_SERVER_URL}/testing
+    ...    eventFilters=${event_filters}
+    ${resp}=    Post Request Capif
+    ...    /capif-events/v1/${register_user_info_invoker['api_invoker_id']}/subscriptions
+    ...    json=${request_body}
+    ...    server=${CAPIF_HTTPS_URL}
+    ...    verify=ca.crt
+    ...    username=${INVOKER_USERNAME}
+
+    # Check Results
+    Check Response Variable Type And Values    ${resp}    201    EventSubscription
+    ${subscriber_id}    ${subscription_id}=    Check Event Location Header    ${resp}
+
+    # Provider publish new API
+    ${service_api_description_published_2}    ${resource_url_2}    ${request_body}=    Publish Service Api
+    ...    ${register_user_info_provider}
+    ...    service_2
+
+    # Provider Remove service_1 published API
+    ${resp}=    Delete Request Capif
+    ...    ${resource_url_1.path}
+    ...    server=${CAPIF_HTTPS_URL}
+    ...    verify=ca.crt
+    ...    username=${APF_PROVIDER_USERNAME}
+
+    Status Should Be    204    ${resp}
+
+    # Check Event Notifications
+    ## Create check Events to ensure all notifications were received
+    ${service_api_available_resources}=    Create List    ${resource_url_2}
+    ${service_api_unavailable_resources}=    Create List    ${resource_url_1}
+    ${events_expected}=    Create Expected Events For Service API Notifications
+    ...    subscription_id=${subscription_id}
+    ...    service_api_available_resources=${service_api_available_resources}
+    ...    service_api_unavailable_resources=${service_api_unavailable_resources}
+    ## Check Events Expected towards received notifications at mock server
+    Check Mock Server Notification Events    ${events_expected}
+
+Invoker subscribe to Service API Update
+    [Tags]    capif_api_events-8    mockserver
+
+    # Initialize Mock server
+    Init Mock Server
+
+    # Register APF
+    ${register_user_info_provider}=    Provider Default Registration
+
+    # Publish one api
+    ${service_api_description_published}    ${resource_url}    ${request_body}=    Publish Service Api
+    ...    ${register_user_info_provider}
+
+    # Register INVOKER
+    ${register_user_info_invoker}    ${url}    ${request_body}=    Invoker Default Onboarding
+
+    ${discover_response}=    Get Request Capif
+    ...    ${DISCOVER_URL}${register_user_info_invoker['api_invoker_id']}
+    ...    server=${CAPIF_HTTPS_URL}
+    ...    verify=ca.crt
+    ...    username=${INVOKER_USERNAME}
+
+    ${api_ids}    ${api_names}=    Get Api Ids And Names From Discover Response    ${discover_response}
+
+    # Subscribe to events
+    ${events_list}=    Create List    SERVICE_API_UPDATE
+    ${aef_ids}=    Create List    ${register_user_info_provider['aef_id']}
+    ${event_filter}=    Create Capif Event Filter    aefIds=${aef_ids}
+    ${event_filters}=    Create List    ${event_filter}
+
+    ${request_body}=    Create Events Subscription
+    ...    events=@{events_list}
+    ...    notificationDestination=${MOCK_SERVER_URL}/testing
+    ...    eventFilters=${event_filters}
+    ${resp}=    Post Request Capif
+    ...    /capif-events/v1/${register_user_info_invoker['api_invoker_id']}/subscriptions
+    ...    json=${request_body}
+    ...    server=${CAPIF_HTTPS_URL}
+    ...    verify=ca.crt
+    ...    username=${INVOKER_USERNAME}
+
+    # Check Results
+    Check Response Variable Type And Values    ${resp}    201    EventSubscription
+    ${subscriber_id}    ${subscription_id}=    Check Event Location Header    ${resp}
+
+    # Update Service API
+    ${service_api_description_modified}=    Create Service Api Description    service_1_modified
+    ${resp}=    Put Request Capif
+    ...    ${resource_url.path}
+    ...    json=${service_api_description_modified}
+    ...    server=${CAPIF_HTTPS_URL}
+    ...    verify=ca.crt
+    ...    username=${APF_PROVIDER_USERNAME}
+
+    Check Response Variable Type And Values    ${resp}    200    ServiceAPIDescription
+    ...    apiName=service_1_modified
+
+    # Check Event Notifications
+    ## Create check Events to ensure all notifications were received
+    ${events_expected}=   Create Expected Service Update Event   ${subscription_id}   ${resource_url}  ${service_api_description_modified}
+    ## Check Events Expected towards received notifications at mock server
+    Check Mock Server Notification Events    ${events_expected}
+
+Provider subscribe to API Invoker events
+    [Tags]    capif_api_events-9    mockserver
+
+    # Initialize Mock server
+    Init Mock Server
+
+    # Register APF
+    ${register_user_info_provider}=    Provider Default Registration
+
+    # Subscribe to events
+    ${events_list}=    Create List    API_INVOKER_ONBOARDED    API_INVOKER_UPDATED    API_INVOKER_OFFBOARDED
+    ${request_body}=    Create Events Subscription
+    ...    events=@{events_list}
+    ...    notificationDestination=${MOCK_SERVER_URL}/testing
+    ${resp}=    Post Request Capif
+    ...    /capif-events/v1/${register_user_info_provider['amf_id']}/subscriptions
+    ...    json=${request_body}
+    ...    server=${CAPIF_HTTPS_URL}
+    ...    verify=ca.crt
+    ...    username=${AMF_PROVIDER_USERNAME}
+
+    # Check Results
+    Check Response Variable Type And Values    ${resp}    201    EventSubscription
+    ${subscriber_id}    ${subscription_id}=    Check Event Location Header    ${resp}
+
+    # Register INVOKER
+    ${register_user_info_invoker}    ${url}    ${request_body}=    Invoker Default Onboarding
+
+    # Update Invoker onboarded information
+    ${new_notification_destination}=    Set Variable
+    ...    http://${CAPIF_CALLBACK_IP}:${CAPIF_CALLBACK_PORT}/netapp_new_callback
+    Set To Dictionary
+    ...    ${request_body}
+    ...    notificationDestination=${new_notification_destination}
+    ${resp}=    Put Request Capif
+    ...    ${url.path}
+    ...    ${request_body}
+    ...    server=${CAPIF_HTTPS_URL}
+    ...    verify=ca.crt
+    ...    username=${INVOKER_USERNAME}
+
+    # Check Update
+    Check Response Variable Type And Values    ${resp}    200    APIInvokerEnrolmentDetails
+    ...    notificationDestination=${new_notification_destination}
+
+    # Remove Invoker from CCF
+    ${resp}=    Delete Request Capif
+    ...    ${url.path}
+    ...    server=${CAPIF_HTTPS_URL}
+    ...    verify=ca.crt
+    ...    username=${INVOKER_USERNAME}
+
+    Call Method    ${CAPIF_USERS}    remove_capif_users_entry    ${url.path}
+
+    # Check Remove
+    Should Be Equal As Strings    ${resp.status_code}    204
+
+    # Check Event Notifications
+    ## Create check Events to ensure all notifications were received
+    ${events_expected}=    Create Expected Api Invoker Events
+    ...    ${subscription_id}
+    ...    ${register_user_info_invoker['api_invoker_id']}
+    ## Check Events Expected towards received notifications at mock server
+    Check Mock Server Notification Events    ${events_expected}
+
+Invoker subscribed to ACL update event
+    [Tags]    capif_api_events-10    mockserver
+
+    # Initialize Mock server
+    Init Mock Server
+
+    # Register APF
+    ${register_user_info_provider}=    Provider Default Registration
+
+    # Publish one api
+    ${service_api_description_published}    ${resource_url}    ${request_body}=    Publish Service Api
+    ...    ${register_user_info_provider}
+
+    # Store apiId1
+    ${service_api_id}=    Set Variable    ${service_api_description_published['apiId']}
+
+    # Register INVOKER
+    ${register_user_info_invoker}    ${url}    ${request_body}=    Invoker Default Onboarding
+
+    # Subscribe to events
+    ${events_list}=    Create List    ACCESS_CONTROL_POLICY_UPDATE
+    ${request_body}=    Create Events Subscription
+    ...    events=@{events_list}
+    ...    notificationDestination=${MOCK_SERVER_URL}/testing
+    ${resp}=    Post Request Capif
+    ...    /capif-events/v1/${register_user_info_provider['amf_id']}/subscriptions
+    ...    json=${request_body}
+    ...    server=${CAPIF_HTTPS_URL}
+    ...    verify=ca.crt
+    ...    username=${AMF_PROVIDER_USERNAME}
+
+    # Check Results
+    Check Response Variable Type And Values    ${resp}    201    EventSubscription
+    ${subscriber_id}    ${subscription_id}=    Check Event Location Header    ${resp}
+
+    # Test
+    ${discover_response}=    Get Request Capif
+    ...    ${DISCOVER_URL}${register_user_info_invoker['api_invoker_id']}&aef-id=${register_user_info_provider['aef_id']}
+    ...    server=${CAPIF_HTTPS_URL}
+    ...    verify=ca.crt
+    ...    username=${INVOKER_USERNAME}
+
+    Check Response Variable Type And Values    ${discover_response}    200    DiscoveredAPIs
+
+    # create Security Context
+    ${request_service_security_body}=    Create Service Security From Discover Response
+    ...    http://${CAPIF_HOSTNAME}:${CAPIF_HTTP_PORT}/test
+    ...    ${discover_response}
+    ${resp}=    Put Request Capif
+    ...    /capif-security/v1/trustedInvokers/${register_user_info_invoker['api_invoker_id']}
+    ...    json=${request_service_security_body}
+    ...    server=${CAPIF_HTTPS_URL}
+    ...    verify=ca.crt
+    ...    username=${INVOKER_USERNAME}
+
+    # Check Service Security
+    Check Response Variable Type And Values    ${resp}    201    ServiceSecurity
+    ${resource_url}=    Check Location Header    ${resp}    ${LOCATION_SECURITY_RESOURCE_REGEX}
+
+    ${resp}=    Get Request Capif
+    ...    /access-control-policy/v1/accessControlPolicyList/${service_api_id}?aef-id=${register_user_info_provider['aef_id']}
+    ...    server=${CAPIF_HTTPS_URL}
+    ...    verify=ca.crt
+    ...    username=${AEF_PROVIDER_USERNAME}
+
+    Check Response Variable Type And Values    ${resp}    200    AccessControlPolicyList
+    # Check returned values
+    Should Not Be Empty    ${resp.json()['apiInvokerPolicies']}
+    Length Should Be    ${resp.json()['apiInvokerPolicies']}    1
+    Should Be Equal As Strings
+    ...    ${resp.json()['apiInvokerPolicies'][0]['apiInvokerId']}
+    ...    ${register_user_info_invoker['api_invoker_id']}
+
+    ${api_invoker_policies}=    Set Variable    ${resp.json()['apiInvokerPolicies']}
+
+    # Check Event Notifications
+    ## Create check Events to ensure all notifications were received
+    ${events_expected}=    Create Expected Access Control Policy Update Event
+    ...    ${subscription_id}
+    ...    ${service_api_id}
+    ...    ${api_invoker_policies}
+    ## Check Events Expected towards received notifications at mock server
+    Check Mock Server Notification Events    ${events_expected}
+
+Provider receives an ACL unavailable event when invoker remove Security Context.
+    [Tags]    capif_api_events-11    mockserver
+
+    # Initialize Mock server
+    Init Mock Server
+
+    # Register APF
+    ${register_user_info_provider}=    Provider Default Registration
+
+    # Publish one api
+    ${service_api_description_published}    ${resource_url}    ${request_body}=    Publish Service Api
+    ...    ${register_user_info_provider}
+
+    # Store apiId1
+    ${serviceApiId}=    Set Variable    ${service_api_description_published['apiId']}
+
+    # Register INVOKER
+    ${register_user_info_invoker}    ${url}    ${request_body}=    Invoker Default Onboarding
+
+    # Subscribe to events
+    ${events_list}=    Create List    ACCESS_CONTROL_POLICY_UNAVAILABLE
+    ${request_body}=    Create Events Subscription
+    ...    events=@{events_list}
+    ...    notificationDestination=${MOCK_SERVER_URL}/testing
+    ${resp}=    Post Request Capif
+    ...    /capif-events/v1/${register_user_info_provider['amf_id']}/subscriptions
+    ...    json=${request_body}
+    ...    server=${CAPIF_HTTPS_URL}
+    ...    verify=ca.crt
+    ...    username=${INVOKER_USERNAME}
+
+    # Check Results
+    Check Response Variable Type And Values    ${resp}    201    EventSubscription
+    ${subscriber_id}    ${subscription_id}=    Check Event Location Header    ${resp}
+
+    # Test
+    ${discover_response}=    Get Request Capif
+    ...    ${DISCOVER_URL}${register_user_info_invoker['api_invoker_id']}&aef-id=${register_user_info_provider['aef_id']}
+    ...    server=${CAPIF_HTTPS_URL}
+    ...    verify=ca.crt
+    ...    username=${INVOKER_USERNAME}
+
+    Check Response Variable Type And Values    ${discover_response}    200    DiscoveredAPIs
+
+    # create Security Context
+    ${request_service_security_body}=    Create Service Security From Discover Response
+    ...    http://${CAPIF_HOSTNAME}:${CAPIF_HTTP_PORT}/test
+    ...    ${discover_response}
+    ${resp}=    Put Request Capif
+    ...    /capif-security/v1/trustedInvokers/${register_user_info_invoker['api_invoker_id']}
+    ...    json=${request_service_security_body}
+    ...    server=${CAPIF_HTTPS_URL}
+    ...    verify=ca.crt
+    ...    username=${INVOKER_USERNAME}
+
+    # Check Service Security
+    Check Response Variable Type And Values    ${resp}    201    ServiceSecurity
+    ${resource_url}=    Check Location Header    ${resp}    ${LOCATION_SECURITY_RESOURCE_REGEX}
+
+    # Remove Security Context by Provider
+    ${resp}=    Delete Request Capif
+    ...    /capif-security/v1/trustedInvokers/${register_user_info_invoker['api_invoker_id']}
+    ...    server=${CAPIF_HTTPS_URL}
+    ...    verify=ca.crt
+    ...    username=${AEF_PROVIDER_USERNAME}
+
+    Status Should Be    204    ${resp}
+
+    # Check Event Notifications
+    ## Create check Events to ensure all notifications were received
+    ${events_expected}=    Create Expected Access Control Policy Unavailable    ${subscription_id}
+    ## Check Events Expected towards received notifications at mock server
+    Check Mock Server Notification Events    ${events_expected}
+
+Invoker receives an Invoker Authorization Revoked and ACL unavailable event when Provider revoke Invoker Authorization.
+    [Tags]    capif_api_events-12    mockserver
+
+    # Initialize Mock server
+    Init Mock Server
+
+    # Register APF
+    ${register_user_info_provider}=    Provider Default Registration
+
+    # Publish one api
+    ${service_api_description_published}    ${resource_url}    ${request_body}=    Publish Service Api
+    ...    ${register_user_info_provider}
+
+    # Store apiId1
+    ${serviceApiId}=    Set Variable    ${service_api_description_published['apiId']}
+
+    # Register INVOKER
+    ${register_user_info_invoker}    ${url}    ${request_body}=    Invoker Default Onboarding
+
+    # Subscribe to events
+    ${events_list}=    Create List    ACCESS_CONTROL_POLICY_UNAVAILABLE    API_INVOKER_AUTHORIZATION_REVOKED
+    ${request_body}=    Create Events Subscription
+    ...    events=@{events_list}
+    ...    notificationDestination=${MOCK_SERVER_URL}/testing
+    ${resp}=    Post Request Capif
+    ...    /capif-events/v1/${register_user_info_provider['amf_id']}/subscriptions
+    ...    json=${request_body}
+    ...    server=${CAPIF_HTTPS_URL}
+    ...    verify=ca.crt
+    ...    username=${INVOKER_USERNAME}
+
+    # Check Results
+    Check Response Variable Type And Values    ${resp}    201    EventSubscription
+    ${subscriber_id}    ${subscription_id}=    Check Event Location Header    ${resp}
+
+    # Test
+    ${discover_response}=    Get Request Capif
+    ...    ${DISCOVER_URL}${register_user_info_invoker['api_invoker_id']}&aef-id=${register_user_info_provider['aef_id']}
+    ...    server=${CAPIF_HTTPS_URL}
+    ...    verify=ca.crt
+    ...    username=${INVOKER_USERNAME}
+
+    Check Response Variable Type And Values    ${discover_response}    200    DiscoveredAPIs
+
+    ${api_ids}=    Get Api Ids From Discover Response    ${discover_response}
+
+    # create Security Context
+    ${request_service_security_body}=    Create Service Security From Discover Response
+    ...    http://${CAPIF_HOSTNAME}:${CAPIF_HTTP_PORT}/test
+    ...    ${discover_response}
+    ${resp}=    Put Request Capif
+    ...    /capif-security/v1/trustedInvokers/${register_user_info_invoker['api_invoker_id']}
+    ...    json=${request_service_security_body}
+    ...    server=${CAPIF_HTTPS_URL}
+    ...    verify=ca.crt
+    ...    username=${INVOKER_USERNAME}
+
+    # Check Service Security
+    Check Response Variable Type And Values    ${resp}    201    ServiceSecurity
+    ${resource_url}=    Check Location Header    ${resp}    ${LOCATION_SECURITY_RESOURCE_REGEX}
+
+    # Revoke Security Context by Provider
+    ${request_body}=    Create Security Notification Body
+    ...    ${register_user_info_invoker['api_invoker_id']}
+    ...    ${api_ids}
+    ${resp}=    Post Request Capif
+    ...    /capif-security/v1/trustedInvokers/${register_user_info_invoker['api_invoker_id']}/delete
+    ...    json=${request_body}
+    ...    server=${CAPIF_HTTPS_URL}
+    ...    verify=ca.crt
+    ...    username=${AEF_PROVIDER_USERNAME}
+
+    # Check Results
+    Status Should Be    204    ${resp}
+
+    # Check Event Notifications
+    ## Create check Events to ensure all notifications were received
+    ${events_expected}=    Create Expected Access Control Policy Unavailable    ${subscription_id}
+    ${events_expected}=    Create Expected Api Invoker Authorization Revoked
+    ...    ${subscription_id}
+    ...    events_expected=${events_expected}
+    ## Check Events Expected towards received notifications at mock server
+    Check Mock Server Notification Events    ${events_expected}
+
+
+*** Keywords ***
+Create Events From InvocationLogs
+    [Arguments]    ${subscription_id}    ${invocation_log}  ${events_expected}=${NONE}
+    IF    ${events_expected} == ${NONE}
+        ${events_expected}=    Create List
+    END
+
+    # Now we create the expected events received at notification server according to logs sent to loggin service in order to check if all are present.
+    ${invocation_log_base}=    Copy Dictionary    ${invocation_log}    deepcopy=True
+    # Store log array because each log will be notified in one Event Notification
+    ${invocation_log_logs}=    Copy List    ${invocation_log_base['logs']}
+    # Remove logs array from invocationLog data
+    Remove From Dictionary    ${invocation_log_base}    logs
+
+    FOR    ${log}    IN    @{invocation_log_logs}
+        Log Dictionary    ${log}
+        ${invocation_logs}=    Copy Dictionary    ${invocation_log_base}    deepcopy=True
+
+        # Get Event Enum for this result
+        ${event_enum}=    Set Variable
+        IF    ${log['result']} >= 200 and ${log['result']} < 300
+            ${event_enum}=    Set Variable    SERVICE_API_INVOCATION_SUCCESS
+        ELSE
+            ${event_enum}=    Set Variable    SERVICE_API_INVOCATION_FAILURE
+        END
+        # Create a log array with only one component
+        ${log_list}=    Create List    ${log}
+        # Setup logs array with previously created list
+        Set To Dictionary    ${invocation_logs}    logs=${log_list}
+        ${event_expected}=  Create Notification Event  ${subscription_id}  ${event_enum}   invocationLogs=${invocation_logs}
+        Append To List    ${events_expected}    ${event_expected}
+    END
+
+    RETURN    ${events_expected}
+Create Expected Events For Service API Notifications
+    [Arguments]
+    ...    ${subscription_id}
+    ...    ${service_api_available_resources}=${NONE}
+    ...    ${service_api_unavailable_resources}=${NONE}
+    ...    ${events_expected}=${NONE}
+
+    IF    ${events_expected} == ${NONE}
+        ${events_expected}=    Create List
+    END
+
+    FOR    ${service_api_available_resource}    IN    @{service_api_available_resources}
+        Log    ${service_api_available_resource}
+        ${api_id}=    Fetch From Right    ${service_api_available_resource.path}    /
+        ${event_expected}=    Create Notification Event
+        ...    ${subscription_id}
+        ...    SERVICE_API_AVAILABLE
+        ...    apiIds=${api_id}
+        Append To List    ${events_expected}    ${event_expected}
+    END
+
+    FOR    ${service_api_unavailable_resource}    IN    @{service_api_unavailable_resources}
+        Log    ${service_api_unavailable_resource}
+        ${api_id}=    Fetch From Right    ${service_api_unavailable_resource.path}    /
+        ${event_expected}=    Create Notification Event
+        ...    ${subscription_id}
+        ...    SERVICE_API_UNAVAILABLE
+        ...    apiIds=${api_id}
+        Append To List    ${events_expected}    ${event_expected}
+    END
+
+    RETURN    ${events_expected}
+
+Create Expected Api Invoker Events
+    [Arguments]    ${subscription_id}    ${api_invoker_id}    ${events_expected}=${NONE}
+    IF    ${events_expected} == ${NONE}
+        ${events_expected}=    Create List
+    END
+    ## Create events expected
+    # Create Notification Events expected to be received for Onboard event
+    ${event_expected}=    Create Notification Event
+    ...    ${subscription_id}
+    ...    API_INVOKER_ONBOARDED
+    ...    apiInvokerIds=${api_invoker_id}
+    Append To List    ${events_expected}    ${event_expected}
+
+    # Create Notification Events expected to be received for Updated event
+    ${event_expected}=    Create Notification Event
+    ...    ${subscription_id}
+    ...    API_INVOKER_UPDATED
+    ...    apiInvokerIds=${api_invoker_id}
+    Append To List    ${events_expected}    ${event_expected}
+
+    # Create Notification Events expected to be received for Offboard event
+    ${event_expected}=    Create Notification Event
+    ...    ${subscription_id}
+    ...    API_INVOKER_OFFBOARDED
+    ...    apiInvokerIds=${api_invoker_id}
+    Append To List    ${events_expected}    ${event_expected}
+
+    RETURN    ${events_expected}
+
+Create Expected Access Control Policy Update Event
+    [Arguments]    ${subscription_id}    ${service_api_id}    ${api_invoker_policies}    ${events_expected}=${NONE}
+    IF    ${events_expected} == ${NONE}
+        ${events_expected}=    Create List
+    END
+    ${acc_ctrl_pol_list}=    Create Dictionary    apiId=${service_api_id}    apiInvokerPolicies=${api_invoker_policies}
+    Check Variable    ${acc_ctrl_pol_list}    AccessControlPolicyListExt
+
+    ${event_expected}=    Create Notification Event
+    ...    ${subscription_id}
+    ...    ACCESS_CONTROL_POLICY_UPDATE
+    ...    accCtrlPolList=${acc_ctrl_pol_list}
+    Append To List    ${events_expected}    ${event_expected}
+
+    RETURN    ${events_expected}
+
+Create Expected Access Control Policy Unavailable
+    [Arguments]    ${subscription_id}    ${events_expected}=${NONE}
+    IF    ${events_expected} == ${NONE}
+        ${events_expected}=    Create List
+    END
+    ${event_expected}=    Create Notification Event
+    ...    ${subscription_id}
+    ...    ACCESS_CONTROL_POLICY_UNAVAILABLE
+    Append To List    ${events_expected}    ${event_expected}
+
+    RETURN    ${events_expected}
+
+Create Expected Api Invoker Authorization Revoked
+    [Arguments]    ${subscription_id}    ${events_expected}=${NONE}
+    IF    ${events_expected} == ${NONE}
+        ${events_expected}=    Create List
+    END
+    ${event_expected}=    Create Notification Event
+    ...    ${subscription_id}
+    ...    API_INVOKER_AUTHORIZATION_REVOKED
+    Append To List    ${events_expected}    ${event_expected}
+    RETURN    ${events_expected}
+
+Create Expected Service Update Event
+    [Arguments]    ${subscription_id}  ${service_api_resource}   ${service_api_descriptions}  ${events_expected}=${NONE}
+    IF    ${events_expected} == ${NONE}
+        ${events_expected}=    Create List
+    END
+    ${api_id}=    Fetch From Right    ${service_api_resource.path}    /
+    Set To Dictionary    ${service_api_descriptions}    apiId=${api_id}
+    ${events_expected}=    Create List
+    ${event_expected}=    Create Notification Event
+    ...    ${subscription_id}
+    ...    SERVICE_API_UPDATE
+    ...    serviceAPIDescriptions=${service_api_descriptions}
+    Append To List    ${events_expected}    ${event_expected}
+    RETURN     ${events_expected}
\ No newline at end of file
diff --git a/tests/libraries/api_events/bodyRequests.py b/tests/libraries/api_events/bodyRequests.py
index ab6e4dae3d646bccbb9ac3f994c7f71112d9e2dc..17fd1b57f743adeecd6da459a8d0a3179b11af90 100644
--- a/tests/libraries/api_events/bodyRequests.py
+++ b/tests/libraries/api_events/bodyRequests.py
@@ -1,32 +1,97 @@
-def create_events_subscription():
+def create_events_subscription(events=["SERVICE_API_AVAILABLE", "API_INVOKER_ONBOARDED"], notificationDestination="http://robot.testing", eventFilters=None, eventReq=None, requestTestNotification=None, supportedFeatures=None, websockNotifConfig=None):
+    event_subscription = {
+        "events": events,
+        "notificationDestination": notificationDestination,
+    }
+    if eventFilters != None:
+        event_subscription['eventFilters'] = eventFilters
+    if eventReq != None:
+        event_subscription['eventReq'] = eventReq
+    if requestTestNotification != None:
+        event_subscription['requestTestNotification'] = requestTestNotification
+    if supportedFeatures != None:
+        event_subscription['supportedFeatures'] = supportedFeatures
+    if websockNotifConfig != None:
+        event_subscription['websockNotifConfig'] = websockNotifConfig
+
+    return event_subscription
+
+
+def create_capif_event_filter(aefIds=None, apiIds=None, apiInvokerIds=None):
+    if aefIds == None and apiIds == None and apiInvokerIds:
+        raise ("Error, no data present to create event filter")
+    capif_event_filter = dict()
+    if aefIds != None:
+        capif_event_filter['aefIds'] = aefIds
+    if apiIds != None:
+        capif_event_filter['apiIds'] = apiIds
+    if apiInvokerIds != None:
+        capif_event_filter['apiInvokerIds'] = apiInvokerIds
+    return capif_event_filter
+
+
+def create_default_event_req():
+    return {
+        "grpRepTime": 5,
+        "immRep": True,
+        "maxReportNbr": 0,
+        "monDur": "2000-01-23T04:56:07+00:00",
+        "partitionCriteria": ["TAC", "GEOAREA"],
+        "repPeriod": 6,
+        "sampRatio": 15
+    }
+
+
+def create_websock_notif_config_default():
     return {
-        "eventFilters": [
-            {
-                "aefIds": ["aefIds", "aefIds"],
-                "apiIds": ["apiIds", "apiIds"],
-                "apiInvokerIds": ["apiInvokerIds", "apiInvokerIds"]
-            },
-            {
-                "aefIds": ["aefIds", "aefIds"],
-                "apiIds": ["apiIds", "apiIds"],
-                "apiInvokerIds": ["apiInvokerIds", "apiInvokerIds"]
-            }
-        ],
-        "eventReq": {
-            "grpRepTime": 5,
-            "immRep": True,
-            "maxReportNbr": 0,
-            "monDur": "2000-01-23T04:56:07+00:00",
-            "partitionCriteria": ["TAC", "GEOAREA"],
-            "repPeriod": 6,
-            "sampRatio": 15
-        },
-        "events": ["SERVICE_API_AVAILABLE", "API_INVOKER_ONBOARDED"],
-        "notificationDestination": "http://robot.testing",
-        "requestTestNotification": True,
-        "supportedFeatures": "aaa",
-        "websockNotifConfig": {
-            "requestWebsocketUri": True,
-            "websocketUri": "websocketUri"
-        }
+        "requestWebsocketUri": True,
+        "websocketUri": "websocketUri"
+    }
+
+
+def create_notification_event(subscriptionId, event, serviceAPIDescriptions=None, apiIds=None, apiInvokerIds=None, accCtrlPolList=None, invocationLogs=None, apiTopoHide=None):
+    result = {
+        "subscriptionId": subscriptionId,
+        "events": event,
+        "eventDetail": dict()
     }
+    count = 0
+    if serviceAPIDescriptions != None:
+        if isinstance(serviceAPIDescriptions, list):
+            result['eventDetail']['serviceAPIDescriptions'] = serviceAPIDescriptions
+        else:
+            result['eventDetail']['serviceAPIDescriptions'] = [
+                serviceAPIDescriptions]
+        count = count+1
+    if apiIds != None:
+        if isinstance(apiIds, list):
+            result['eventDetail']['apiIds'] = apiIds
+        else:
+            result['eventDetail']['apiIds'] = [apiIds]
+        count = count+1
+    if apiInvokerIds != None:
+        if isinstance(apiInvokerIds, list):
+            result['eventDetail']['apiInvokerIds'] = apiInvokerIds
+        else:
+            result['eventDetail']['apiInvokerIds'] = [apiInvokerIds]
+        count = count+1
+    if accCtrlPolList != None:
+        result['eventDetail']['accCtrlPolList'] = accCtrlPolList
+        count = count+1
+    if invocationLogs != None:
+        if isinstance(invocationLogs, list):
+            result['eventDetail']['invocationLogs'] = invocationLogs
+        else:
+            result['eventDetail']['invocationLogs'] = [invocationLogs]
+        count = count+1
+    if apiTopoHide != None:
+        if isinstance(apiTopoHide, list):
+            result['eventDetail']['apiTopoHide'] = apiTopoHide
+        else:
+            result['eventDetail']['apiTopoHide'] = [apiTopoHide]
+        count = count+1
+
+    if count == 0:
+        del result['eventDetail']
+
+    return result
diff --git a/tests/libraries/api_logging_service/bodyRequests.py b/tests/libraries/api_logging_service/bodyRequests.py
index fe3faf1dd9dbc1ccd0fb96ce96e5b73d0cd805f9..a4d2a18770dca3d2d43742010bf9d336aaf728d3 100644
--- a/tests/libraries/api_logging_service/bodyRequests.py
+++ b/tests/libraries/api_logging_service/bodyRequests.py
@@ -1,84 +1,21 @@
-def create_log_entry(aefId=None, apiInvokerId=None, apiId=None, apiName=None):
+def create_log_entry(aefId, apiInvokerId, apiId, apiName, results=['200','500'],api_versions=['v1','v2']):
     data = {
     "aefId": aefId,
     "apiInvokerId": apiInvokerId,
-    "logs": [
-        {
-        "apiId": apiId[0],
-        "apiName": apiName[0],
-        "apiVersion": "v1",
-        "resourceName": "string",
-        "uri": "http://resource/endpoint",
-        "protocol": "HTTP_1_1",
-        "operation": "GET",
-        "result": "string",
-        "invocationTime": "2023-03-30T10:30:21.408Z",
-        "invocationLatency": 0,
-        "inputParameters": "string",
-        "outputParameters": "string",
-        "srcInterface": {
-            "ipv4Addr": "192.168.1.1",
-            "fqdn": "string",
-            "port": 65535,
-            "apiPrefix": "string",
-            "securityMethods": [
-            "PSK",
-            "string"
-            ]
-        },
-        "destInterface": {
-            "ipv4Addr": "192.168.1.23",
-            "fqdn": "string",
-            "port": 65535,
-            "apiPrefix": "string",
-            "securityMethods": [
-            "PSK",
-            "string"
-            ]
-        },
-        "fwdInterface": "string"
-        },
-        {
-        "apiId": apiId[0],
-        "apiName": apiName[0],
-        "apiVersion": "v2",
-        "resourceName": "string",
-        "uri": "http://resource/endpoint",
-        "protocol": "HTTP_1_1",
-        "operation": "GET",
-        "result": "string",
-        "invocationTime": "2023-03-30T10:30:21.408Z",
-        "invocationLatency": 0,
-        "inputParameters": "string",
-        "outputParameters": "string",
-        "srcInterface": {
-            "ipv4Addr": "192.168.1.1",
-            "fqdn": "string",
-            "port": 65535,
-            "apiPrefix": "string",
-            "securityMethods": [
-            "PSK",
-            "string"
-            ]
-        },
-        "destInterface": {
-            "ipv4Addr": "192.168.1.23",
-            "fqdn": "string",
-            "port": 65535,
-            "apiPrefix": "string",
-            "securityMethods": [
-            "PSK",
-            "string"
-            ]
-        },
-        "fwdInterface": "string"
-        }
-    ],
+    "logs": [],
     "supportedFeatures": "ffff"
     }
+    if len(results) > 0:
+        count=0
+        for result in results:
+            data['logs'].append(create_log(apiId,apiName,result,api_versions[count]))
+            count=count+1
+            if count == len(api_versions):
+                count=0
+
     return data 
 
-def create_log_entry_bad_service(aefId=None, apiInvokerId=None):
+def create_log_entry_bad_service(aefId, apiInvokerId, result='500'):
     data = {
     "aefId": aefId,
     "apiInvokerId": apiInvokerId,
@@ -91,29 +28,25 @@ def create_log_entry_bad_service(aefId=None, apiInvokerId=None):
         "uri": "string",
         "protocol": "HTTP_1_1",
         "operation": "GET",
-        "result": "string",
-        "invocationTime": "2023-03-30T10:30:21.408Z",
+        "result": result,
+        "invocationTime": "2023-03-30T10:30:21.408000+00:00",
         "invocationLatency": 0,
         "inputParameters": "string",
         "outputParameters": "string",
         "srcInterface": {
             "ipv4Addr": "192.168.1.1",
-            "fqdn": "string",
             "port": 65535,
-            "apiPrefix": "string",
             "securityMethods": [
             "PSK",
-            "string"
+            "PKI"
             ]
         },
         "destInterface": {
             "ipv4Addr": "192.168.1.23",
-            "fqdn": "string",
             "port": 65535,
-            "apiPrefix": "string",
             "securityMethods": [
             "PSK",
-            "string"
+            "PKI"
             ]
         },
         "fwdInterface": "string"
@@ -131,3 +64,29 @@ def get_api_ids_and_names_from_discover_response(discover_response):
         api_ids.append(service_api_description['apiId'])
         api_names.append(service_api_description['apiName'])
     return api_ids, api_names
+
+
+def create_log(apiId, apiName, result, api_version='v1'):
+    log= {
+        "apiId": apiId[0],
+        "apiName": apiName[0],
+        "apiVersion": api_version,
+        "resourceName": "string",
+        "uri": "http://resource/endpoint",
+        "protocol": "HTTP_1_1",
+        "operation": "GET",
+        "result": result,
+        "invocationTime": "2023-03-30T10:30:21.408000+00:00",
+        "invocationLatency": 0,
+        "inputParameters": "string",
+        "outputParameters": "string",
+        "srcInterface": {
+            "ipv4Addr": "192.168.1.1",
+            "port": 65535,
+            "securityMethods": [
+            "PSK",
+            "PKI"
+            ]
+        }
+    }
+    return log
\ No newline at end of file
diff --git a/tests/libraries/api_publish_service/bodyRequests.py b/tests/libraries/api_publish_service/bodyRequests.py
index 17ac4a794a5ba1a38357ee229d04b3b4590bfdc8..69e7bb117f01b4c53ee7d1db74b7da09e20bf3a1 100644
--- a/tests/libraries/api_publish_service/bodyRequests.py
+++ b/tests/libraries/api_publish_service/bodyRequests.py
@@ -7,7 +7,7 @@ def create_service_api_description(api_name="service_1",aef_id="aef_id"):
                 "versions": [
                     {
                         "apiVersion": "v1",
-                        "expiry": "2021-11-30T10:32:02.004000Z",
+                        "expiry": "2021-11-30T10:32:02.004000+00:00",
                         "resources": [
                             {
                                 "resourceName": "string",
@@ -20,27 +20,12 @@ def create_service_api_description(api_name="service_1",aef_id="aef_id"):
                                 "description": "string"
                             }
                         ],
-                        "custOperations": [
-                            {
-                                "commType": "REQUEST_RESPONSE",
-                                "custOpName": "string",
-                                "operations": [
-                                    "GET"
-                                ],
-                                "description": "string"
-                            }
-                        ]
                     }
                 ],
                 "protocol": "HTTP_1_1",
                 "dataFormat": "JSON",
                 "securityMethods": ["PSK"],
                 "interfaceDescriptions": [
-                    {
-                        "ipv4Addr": "string",
-                        "port": 65535,
-                        "securityMethods": ["PSK"]
-                    },
                     {
                         "ipv4Addr": "string",
                         "port": 65535,
diff --git a/tests/libraries/common/bodyRequests.py b/tests/libraries/common/bodyRequests.py
index 3f1e482d4717bc5d3ddfc298962afb8e42bc1a7e..1d4ec14f60759bfb221b686ba84df23b1386fa6c 100644
--- a/tests/libraries/common/bodyRequests.py
+++ b/tests/libraries/common/bodyRequests.py
@@ -15,7 +15,7 @@ def check_variable(input, data_type):
     if isinstance(input, list):
         for one in input:
             check_variable(one, data_type)
-            return True
+        return True
     if data_type == "string":
         if isinstance(input, str):
             return True
diff --git a/tests/libraries/common/types.json b/tests/libraries/common/types.json
index 4b683595c43c912f868856107d21ed84ad08032d..220dd0f5710796fd875ddda8d05dfb3e39a272cd 100644
--- a/tests/libraries/common/types.json
+++ b/tests/libraries/common/types.json
@@ -259,6 +259,67 @@
       "aefIds": "string"
     }
   },
+  "EventNotification": {
+    "mandatory_attributes": {
+      "subscriptionId": "string",
+      "events": "CAPIFEvent"
+    },
+    "optional_attributes": {
+      "eventDetail": "CAPIFEventDetail"
+    }
+  },
+  "CAPIFEventDetail": {
+    "mandatory_attributes": {},
+    "optional_attributes": {
+      "serviceAPIDescriptions": "ServiceAPIDescription",
+      "apiIds": "string",
+      "apiInvokerIds": "string",
+      "accCtrlPolList": "AccessControlPolicyListExt",
+      "invocationLogs": "InvocationLog",
+      "apiTopoHide": "TopologyHiding"
+    }
+  },
+  "AccessControlPolicyListExt":{
+    "mandatory_attributes": {
+      "apiId": "string"
+    },
+    "optional_attributes": {
+      "apiInvokerPolicies": "ApiInvokerPolicy"
+    }
+  },
+  "TopologyHiding": {
+    "mandatory_attributes":{
+      "apiId": "string",
+      "routingRules": "RoutingRule"
+    },
+    "optional_attributes": {}
+  },
+  "RoutingRule":{
+    "mandatory_attributes": {
+      "aefProfile": "AefProfile"
+    },
+    "optional_attributes": {
+      "ipv4AddrRanges": "Ipv4AddressRange",
+      "ipv6AddrRanges": "Ipv6AddressRange"
+    }
+  },
+  "Ipv4AddressRange":{
+    "mandatory_attributes": {},
+    "optional_attributes": {
+      "start": "Ipv4Addr",
+      "stop": "Ipv4Addr"
+    }
+  },
+  "Ipv4Addr": {
+    "regex": "^(([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\\.){3}([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])$"
+  },
+  "Ipv6AddressRange":{
+    "mandatory_attributes":{
+      "start": "string",
+      "end": "string"
+    },
+    "optional_attributes":{}
+  },
   "ReportingInformation": {
     "mandatory_attributes": {},
     "optional_attributes": {
diff --git a/tests/requirements.txt b/tests/requirements.txt
index c6d90325ac78628f7de12acc34a01497039f57f3..3119b5ca73095dfdc4a018dc35abaf83c5bc5ab2 100644
--- a/tests/requirements.txt
+++ b/tests/requirements.txt
@@ -1,8 +1,2 @@
 # Requirements file for tests.
-robotframework-mongodb-library==3.2
-requests==2.28.1
-configparser==5.3.0
-redis==4.3.4
-rfc3987==1.3.8
-robotframework-httpctrl
-robotframework-archivelibrary == 0.4.2
\ No newline at end of file
+
diff --git a/tests/resources/common.resource b/tests/resources/common.resource
index c46131b17388b006b9fa7f521033a3c32874c171..d4733b8ee4e12ac5477501b1e1c0ffab4a09f79d 100644
--- a/tests/resources/common.resource
+++ b/tests/resources/common.resource
@@ -1,5 +1,7 @@
 *** Settings ***
 Library         /opt/robot-tests/tests/libraries/helpers.py
+Library    Process
+Library    Collections
 Variables       /opt/robot-tests/tests/libraries/environment.py
 Resource        /opt/robot-tests/tests/resources/common/basicRequests.robot
 
@@ -30,6 +32,9 @@ ${CAPIF_CALLBACK_PORT}          8086
 ${REGISTER_ADMIN_USER}          admin
 ${REGISTER_ADMIN_PASSWORD}      password123
 
+${MOCK_SERVER_URL}
+
+
 ${DISCOVER_URL}                 /service-apis/v1/allServiceAPIs?api-invoker-id=
 
 
@@ -85,3 +90,78 @@ Remove Keys From Object
 Test ${TEST NAME} Currently Not Supported
     Log    Test "${TEST NAME}" Currently not supported    WARN
     Skip    Test "${TEST NAME}" Currently not supported
+
+Init Mock Server
+    Check Mock Server
+    Clean Mock Server
+
+Check Mock Server
+    Log  Checking mock Server for Robot Framework.
+
+    IF    "${MOCK_SERVER_URL}" == ""
+        Fail   Mock Server Url is not setup on Tests execution, check MOCK_SERVER_URL variable   mockserver-not-ready
+    END
+
+    Create Session    mockserver    ${MOCK_SERVER_URL}
+
+    ${endpoint}=    Set Variable  /requests_list
+
+    ${resp}=    GET On Session
+    ...    mockserver
+    ...    ${endpoint}
+    ...    expected_status=any
+    ...    verify=False
+
+    Status Should Be    200    ${resp}   Mock Server response is not 200 OK at ${MOCK_SERVER_URL}, check server status.
+
+Clean Mock Server
+    Log  Checking mock Server for Robot Framework.
+
+    Create Session    mockserver    ${MOCK_SERVER_URL}
+
+    ${endpoint}=    Set Variable  /requests_list
+
+    ${resp}=    DELETE On Session
+    ...    mockserver
+    ...    ${endpoint}
+    ...    expected_status=any
+    ...    verify=False
+
+    Status Should Be    200    ${resp}
+
+
+Get Mock Server Messages
+    Log  Checking mock Server for Robot Framework.
+
+    Create Session    mockserver    ${MOCK_SERVER_URL}
+
+    ${endpoint}=    Set Variable  /requests_list
+
+    ${resp}=    GET On Session
+    ...    mockserver
+    ...    ${endpoint}
+    ...    expected_status=any
+    ...    verify=False
+
+    Status Should Be    200    ${resp}
+    Log List    ${resp.json()}
+    RETURN   ${resp}
+
+Check Mock Server Notification Events
+    [Arguments]    ${events_expected}
+
+    Check Variable    ${events_expected}    EventNotification
+    # Check results
+    ${events_expected_length}=   Get Length    ${events_expected}
+
+    Sleep    3s
+    # Get from Mock server the EventNotification Messages sent to callback setup on event subscription.
+    ${resp}=    Get Mock Server Messages
+    ${notification_events_on_mock_server}=    Set Variable    ${resp.json()}
+    Check Variable    ${notification_events_on_mock_server}    EventNotification
+
+    Length Should Be    ${notification_events_on_mock_server}   ${events_expected_length}
+    FOR    ${event_expected}    IN    @{events_expected}
+        Log    ${event_expected}
+        List Should Contain Value    ${notification_events_on_mock_server}    ${event_expected}
+    END
\ No newline at end of file
diff --git a/tests/resources/common/basicRequests.robot b/tests/resources/common/basicRequests.robot
index ea3a96ffc432e86aa543ab51c796cbffb61bfc76..433a13cd74e3fb02a1333d812c9d5679a7b16b36 100644
--- a/tests/resources/common/basicRequests.robot
+++ b/tests/resources/common/basicRequests.robot
@@ -416,6 +416,11 @@ Create User At Register
     ...    password=${password}
     ...    description=${description}
     ...    email=${email}
+    ...    enterprise=enterprise
+    ...    country=Spain
+    ...    purpose=testing
+    ...    phone_number=123456789
+    ...    company_web=www.enterprise.com
     ${resp}=    Post On Session    register_session    /createUser    headers=${headers}    json=${body}
     Should Be Equal As Strings    ${resp.status_code}    201
 
@@ -457,6 +462,7 @@ Get Auth For User
     ${resp}=    GET On Session    register_session    /getauth    auth=${auth}
 
     Should Be Equal As Strings    ${resp.status_code}    200
+    Log Dictionary    ${resp.json()}
 
     RETURN    ${resp.json()}
 
@@ -744,3 +750,4 @@ Create Security Context Between invoker and provider
     ...    username=${register_user_info_invoker['management_cert']}
 
     Check Response Variable Type And Values    ${resp}    201    ServiceSecurity
+
diff --git a/tools/robot/Dockerfile b/tools/robot/Dockerfile
index 49cea1714ace28c777903b7c30f30bad1ae674cf..347f226da0bf93d5e1f8a9adaa18901c5dafc000 100644
--- a/tools/robot/Dockerfile
+++ b/tools/robot/Dockerfile
@@ -25,6 +25,7 @@ VOLUME $ROBOT_RESULTS_DIRECTORY
 WORKDIR $ROBOT_DIRECTORY
 
 ENV DEBIAN_FRONTEND=noninteractive
+RUN echo 'debconf debconf/frontend select Noninteractive' | debconf-set-selections
 
 # Install dependencies
 RUN apt-get update
@@ -49,14 +50,15 @@ RUN apt-get install -y --no-install-recommends  \
     python3-venv \
     python2.7-dev \
     libssl-dev \
-    libldap2-dev libsasl2-dev ldap-utils slapd tox lcov valgrind\
-    tshark
+    libldap2-dev libsasl2-dev ldap-utils slapd tox lcov valgrind \
+    tshark \
+    nodejs \
+    npm
 
-RUN add-apt-repository ppa:deadsnakes/ppa
+RUN add-apt-repository -y ppa:deadsnakes/ppa
 RUN apt-get update
 RUN apt-get install -y --fix-missing python3.10 python3.10-venv python3.10-dev
 
-
 RUN mkdir /opt/venv
 RUN python3.10 -m venv /opt/venv
 
diff --git a/tools/robot/basicRequirements.txt b/tools/robot/basicRequirements.txt
index 87752271253dc67c7e0c0d8e8f42d4768001b074..aa3e60e0f55ee408cb29605ef29446b3dd075d4f 100644
--- a/tools/robot/basicRequirements.txt
+++ b/tools/robot/basicRequirements.txt
@@ -13,7 +13,7 @@ certifi==2021.10.8
 cffi==1.15.1
 chardet==5.0.0
 charset-normalizer==2.0.12
-click==8.0.1
+click==8.1.7
 configparser==5.3.0
 cookiecutter==2.1.1
 coverage==4.5.4
@@ -25,8 +25,8 @@ docutils==0.19
 exceptiongroup==1.0.0rc9
 filelock==3.8.0
 flake8==3.9.2
+flask==3.0.3
 h11==0.14.0
-robotframework-httpctrl==0.3.1
 idna==3.4
 iniconfig==1.1.1
 invoke==1.6.0
@@ -69,10 +69,12 @@ redis==4.3.4
 rellu==0.7
 requests==2.28.1
 rfc3987==1.3.8
-robotframework==6.0
+robotframework==7.0
+robotframework-archivelibrary == 0.4.2
+robotframework-httpctrl==0.3.1
 robotframework-lint==1.1
 robotframework-mongodb-library==3.2
-robotframework-pythonlibcore==3.0.0
+robotframework-pythonlibcore==4.4.1
 robotframework-requests==0.9.3
 robotframework-seleniumlibrary==6.0.0
 robotframework-sshlibrary==3.8.0
@@ -91,11 +93,11 @@ tox==3.26.0
 tqdm==4.64.1
 trio==0.22.0
 trio-websocket==0.9.2
-typing-extensions==3.10.0.2
+typing-extensions==4.11.0
 urllib3==1.26.12
 virtualenv==20.16.5
-watchdog==0.9.0
+watchdog==4.0.0
 webdrivermanager==0.10.0
-wrapt==1.14.1
+wrapt==1.15.0
 wsproto==1.2.0
-xlrd==2.0.1
\ No newline at end of file
+xlrd==2.0.1
diff --git a/tools/robot/basicRobotInstall.sh b/tools/robot/basicRobotInstall.sh
index 511821fbab10d55f80dd2a13af1d60035ca0bd40..ae0bd6bd8b1bdedccc34b4d6152bffc8bb5f467b 100644
--- a/tools/robot/basicRobotInstall.sh
+++ b/tools/robot/basicRobotInstall.sh
@@ -1,7 +1,6 @@
 #!/bin/bash
 echo "Installing basic software related with robotFramework"
-source /opt/venv/bin/activate; 
+source /opt/venv/bin/activate
 pip install --upgrade pip
-pip install --upgrade robotframework;
-pip install -r $1 
+pip install -r $1
 echo "Robot framework installed"