From: Jackie Huang Date: Sun, 8 May 2022 13:15:19 +0000 (+0800) Subject: Convert file endlines to Unix (LF) X-Git-Tag: 2.0.0-rc1~50 X-Git-Url: https://gerrit.o-ran-sc.org/r/gitweb?a=commitdiff_plain;h=defe8209b3628593c186487857fe02586d7e1503;p=pti%2Fo2.git Convert file endlines to Unix (LF) Convert file endlines to Unix (LF) by: $ endlines linux -kr * endlines : converting files to Unix (LF) endlines : 194 files converted from : - 90 Unix (LF) - 104 Windows (CR-LF) 98 binaries skipped 2 hidden files skipped Issue-ID: INF-272 Signed-off-by: Jackie Huang Change-Id: I9e894b9b290d8d3d9f3a0b789d1cc150250c7ead --- diff --git a/Dockerfile b/Dockerfile index 1ac328a..dc0adcb 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,52 +1,52 @@ -FROM python:3.10-slim-buster - -RUN apt-get update; apt-get install -y git gcc - -# in case git repo is not accessable -# RUN mkdir -p /cgtsclient -# COPY temp/config /cgtsclient/ -RUN git clone --depth 1 --branch master https://opendev.org/starlingx/config.git /cgtsclient -RUN pip install -e /cgtsclient/sysinv/cgts-client/cgts-client/ - -# RUN mkdir -p /distcloud-client -# COPY temp/distcloud-client /distcloud-client/ -RUN git clone --depth 1 --branch master https://opendev.org/starlingx/distcloud-client.git /distcloud-client/ -RUN pip install -e /distcloud-client/distributedcloud-client -# in case git repo is not accessable - -# RUN git clone --depth 1 --branch master https://github.com/cloudify-incubator/cloudify-helm-plugin.git /helmsdk - - -COPY requirements.txt /tmp/ -COPY requirements-stx.txt /tmp/ -COPY constraints.txt /tmp/ - -RUN pip install -r /tmp/requirements.txt -c /tmp/constraints.txt - -# RUN pip install -r /tmp/requirements-stx.txt - -COPY requirements-test.txt /tmp/ -RUN pip install -r /tmp/requirements-test.txt - - -RUN mkdir -p /src -COPY o2ims/ /src/o2ims/ -COPY o2dms/ /src/o2dms/ -COPY o2common/ /src/o2common/ - -RUN mkdir -p /src/o2app/ -COPY o2app/ /src/o2app/ -COPY setup.py /src/ - -RUN pip install -e /src - -COPY configs/ /etc/o2/ - -COPY tests/ /tests/ - -RUN apt-get install -y procps vim curl - -RUN curl -O https://get.helm.sh/helm-v3.3.1-linux-amd64.tar.gz; -RUN tar -zxvf helm-v3.3.1-linux-amd64.tar.gz; cp linux-amd64/helm /usr/local/bin - -WORKDIR /src +FROM python:3.10-slim-buster + +RUN apt-get update; apt-get install -y git gcc + +# in case git repo is not accessable +# RUN mkdir -p /cgtsclient +# COPY temp/config /cgtsclient/ +RUN git clone --depth 1 --branch master https://opendev.org/starlingx/config.git /cgtsclient +RUN pip install -e /cgtsclient/sysinv/cgts-client/cgts-client/ + +# RUN mkdir -p /distcloud-client +# COPY temp/distcloud-client /distcloud-client/ +RUN git clone --depth 1 --branch master https://opendev.org/starlingx/distcloud-client.git /distcloud-client/ +RUN pip install -e /distcloud-client/distributedcloud-client +# in case git repo is not accessable + +# RUN git clone --depth 1 --branch master https://github.com/cloudify-incubator/cloudify-helm-plugin.git /helmsdk + + +COPY requirements.txt /tmp/ +COPY requirements-stx.txt /tmp/ +COPY constraints.txt /tmp/ + +RUN pip install -r /tmp/requirements.txt -c /tmp/constraints.txt + +# RUN pip install -r /tmp/requirements-stx.txt + +COPY requirements-test.txt /tmp/ +RUN pip install -r /tmp/requirements-test.txt + + +RUN mkdir -p /src +COPY o2ims/ /src/o2ims/ +COPY o2dms/ /src/o2dms/ +COPY o2common/ /src/o2common/ + +RUN mkdir -p /src/o2app/ +COPY o2app/ /src/o2app/ +COPY setup.py /src/ + +RUN pip install -e /src + +COPY configs/ /etc/o2/ + +COPY tests/ /tests/ + +RUN apt-get install -y procps vim curl + +RUN curl -O https://get.helm.sh/helm-v3.3.1-linux-amd64.tar.gz; +RUN tar -zxvf helm-v3.3.1-linux-amd64.tar.gz; cp linux-amd64/helm /usr/local/bin + +WORKDIR /src diff --git a/Dockerfile.localtest b/Dockerfile.localtest index 0324e33..b047113 100644 --- a/Dockerfile.localtest +++ b/Dockerfile.localtest @@ -1,57 +1,57 @@ -FROM python:3.10-slim-buster - -RUN apt-get update; apt-get install -y git gcc - -# in case git repo is not accessable -RUN mkdir -p /cgtsclient -COPY temp/config /cgtsclient/ -RUN pip install -e cgtsclient/sysinv/cgts-client/cgts-client/ - -RUN mkdir -p /distcloud-client -COPY temp/distcloud-client /distcloud-client/ -RUN pip install -e /distcloud-client/distributedcloud-client -# in case git repo is not accessable - - -COPY requirements.txt /tmp/ -COPY constraints.txt /tmp/ - -RUN pip install -r /tmp/requirements.txt -c /tmp/constraints.txt - -COPY requirements-test.txt /tmp/ -RUN pip install -r /tmp/requirements-test.txt - - -RUN mkdir -p /src -COPY o2ims/ /src/o2ims/ -COPY o2dms/ /src/o2dms/ -COPY o2common/ /src/o2common/ - -RUN mkdir -p /src/o2app/ -COPY o2app/ /src/o2app/ - -RUN mkdir -p /src/helm_sdk/ -COPY helm_sdk/ /src/helm_sdk/ - -COPY setup.py /src/ - -COPY configs/ /etc/o2/ - -# RUN mkdir -p /helmsdk -# COPY temp/helmsdk /helmsdk/ -# # RUN git clone --depth 1 --branch master https://github.com/cloudify-incubator/cloudify-helm-plugin.git helmsdk -# COPY /helmsdk/helm_sdk /src/helm_sdk - -# RUN pip install -e /src -COPY tests/ /tests/ - -RUN apt-get install -y procps vim - -RUN apt-get install -y curl -RUN curl -O https://get.helm.sh/helm-v3.3.1-linux-amd64.tar.gz; -RUN tar -zxvf helm-v3.3.1-linux-amd64.tar.gz; cp linux-amd64/helm /usr/local/bin - -RUN mkdir -p /etc/kubeconfig/ -# COPY temp/kubeconfig/config /etc/kubeconfig/ - -WORKDIR /src +FROM python:3.10-slim-buster + +RUN apt-get update; apt-get install -y git gcc + +# in case git repo is not accessable +RUN mkdir -p /cgtsclient +COPY temp/config /cgtsclient/ +RUN pip install -e cgtsclient/sysinv/cgts-client/cgts-client/ + +RUN mkdir -p /distcloud-client +COPY temp/distcloud-client /distcloud-client/ +RUN pip install -e /distcloud-client/distributedcloud-client +# in case git repo is not accessable + + +COPY requirements.txt /tmp/ +COPY constraints.txt /tmp/ + +RUN pip install -r /tmp/requirements.txt -c /tmp/constraints.txt + +COPY requirements-test.txt /tmp/ +RUN pip install -r /tmp/requirements-test.txt + + +RUN mkdir -p /src +COPY o2ims/ /src/o2ims/ +COPY o2dms/ /src/o2dms/ +COPY o2common/ /src/o2common/ + +RUN mkdir -p /src/o2app/ +COPY o2app/ /src/o2app/ + +RUN mkdir -p /src/helm_sdk/ +COPY helm_sdk/ /src/helm_sdk/ + +COPY setup.py /src/ + +COPY configs/ /etc/o2/ + +# RUN mkdir -p /helmsdk +# COPY temp/helmsdk /helmsdk/ +# # RUN git clone --depth 1 --branch master https://github.com/cloudify-incubator/cloudify-helm-plugin.git helmsdk +# COPY /helmsdk/helm_sdk /src/helm_sdk + +# RUN pip install -e /src +COPY tests/ /tests/ + +RUN apt-get install -y procps vim + +RUN apt-get install -y curl +RUN curl -O https://get.helm.sh/helm-v3.3.1-linux-amd64.tar.gz; +RUN tar -zxvf helm-v3.3.1-linux-amd64.tar.gz; cp linux-amd64/helm /usr/local/bin + +RUN mkdir -p /etc/kubeconfig/ +# COPY temp/kubeconfig/config /etc/kubeconfig/ + +WORKDIR /src diff --git a/README-o2imsbuilder.md b/README-o2imsbuilder.md index 6e00564..aeab693 100644 --- a/README-o2imsbuilder.md +++ b/README-o2imsbuilder.md @@ -1,130 +1,130 @@ - -## Build and deploy O2 services over O-Cloud (INF) - - -## Bring up builder container from O-Cloud controller node - - -```sh -mkdir -p /home/sysadmin/share -sudo docker run -dt --privileged -v /home/sysadmin/share/:/home/sysadmin/share/ -v /var/run:/var/run --name o2imsbuilder centos:7 -``` - -## Build O2 service images inside the builder container - - -```sh -sudo docker exec -it o2imsbuilder bash -``` - - -```sh -curl -L https://get.daocloud.io/docker/compose/releases/download/1.25.4/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose -chmod +x /usr/local/bin/docker-compose -docker-compose -v - -yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo -yum makecache fast -yum install -y docker-ce -docker ps - -yum install -y git - -cd /home/sysadmin/share/ -git clone "https://gerrit.o-ran-sc.org/r/pti/o2" -cd o2 - -mkdir -p temp -cd temp -git clone --depth 1 --branch master https://opendev.org/starlingx/config.git -git clone --depth 1 --branch master https://opendev.org/starlingx/distcloud-client.git -cd - - -docker-compose build - -exit - -``` - -### Push O2 service images to local registry (with auth user admin) - -```sh -sudo docker tag o2imsdms:latest registry.local:9001/admin/o2imsdms:0.1.4 -sudo docker image push registry.local:9001/admin/o2imsdms:0.1.4 - -``` - -## Deploy O2 services with helm chart over O-Cloud controller node (with auth user admin) - -```sh -export NAMESPACE=orano2 -kubectl create ns ${NAMESPACE} - -cd /home/sysadmin/ -source /etc/platform/openrc -cat <ocloud-override.yaml -o2ims: - imagePullSecrets: admin-orano2-registry-secret - image: - repository: registry.local:9001/admin/o2imsdms - tag: 0.1.4 - pullPolicy: IfNotPresent - logginglevel: "DEBUG" - -ocloud: - OS_AUTH_URL: "${OS_AUTH_URL}" - OS_USERNAME: "${OS_USERNAME}" - OS_PASSWORD: "${OS_PASSWORD}" -EOF - -sudo docker login registry.local:9001 -u ${OS_PROJECT_NAME} -p ${OS_PASSWORD} - -kubectl -n ${NAMESPACE} create secret docker-registry ${OS_PROJECT_NAME}-${NAMESPACE}-registry-secret \ ---docker-server=registry.local:9001 --docker-username=${OS_PROJECT_NAME} \ ---docker-password=${OS_PASSWORD} --docker-email=noreply@windriver.com - -cd /home/sysadmin/share/o2 - -helm install o2imstest charts/ -f /home/sysadmin/ocloud-override.yaml - -kubectl -n ${NAMESPACE} get pods - -``` - -### test api endpoint - -```sh -curl -k http(s)://:30205 -curl -k http(s)://:30205/o2ims_infrastructureInventory/v1 -``` - - -### Debug tips - -```sh -kubectl -n ${NAMESPACE} logs -f o2api- -c o2api -kubectl -n ${NAMESPACE} logs -f o2api- -c postgres -kubectl -n ${NAMESPACE} logs -f o2api- -c o2pubsub -kubectl -n ${NAMESPACE} logs -f o2api- -c watcher - - -kubectl -n ${NAMESPACE} logs -f o2api- -c o2api - -kubectl -n ${NAMESPACE} exec -it o2api- -c postgres -- bash - psql -U o2ims - - \c o2ims - - \d - - select * from ocloud; - - \q - - exit - -``` - -## Issues: - -1, there is chance the containers crash due to random bootstrap order of containers + +## Build and deploy O2 services over O-Cloud (INF) + + +## Bring up builder container from O-Cloud controller node + + +```sh +mkdir -p /home/sysadmin/share +sudo docker run -dt --privileged -v /home/sysadmin/share/:/home/sysadmin/share/ -v /var/run:/var/run --name o2imsbuilder centos:7 +``` + +## Build O2 service images inside the builder container + + +```sh +sudo docker exec -it o2imsbuilder bash +``` + + +```sh +curl -L https://get.daocloud.io/docker/compose/releases/download/1.25.4/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose +chmod +x /usr/local/bin/docker-compose +docker-compose -v + +yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo +yum makecache fast +yum install -y docker-ce +docker ps + +yum install -y git + +cd /home/sysadmin/share/ +git clone "https://gerrit.o-ran-sc.org/r/pti/o2" +cd o2 + +mkdir -p temp +cd temp +git clone --depth 1 --branch master https://opendev.org/starlingx/config.git +git clone --depth 1 --branch master https://opendev.org/starlingx/distcloud-client.git +cd - + +docker-compose build + +exit + +``` + +### Push O2 service images to local registry (with auth user admin) + +```sh +sudo docker tag o2imsdms:latest registry.local:9001/admin/o2imsdms:0.1.4 +sudo docker image push registry.local:9001/admin/o2imsdms:0.1.4 + +``` + +## Deploy O2 services with helm chart over O-Cloud controller node (with auth user admin) + +```sh +export NAMESPACE=orano2 +kubectl create ns ${NAMESPACE} + +cd /home/sysadmin/ +source /etc/platform/openrc +cat <ocloud-override.yaml +o2ims: + imagePullSecrets: admin-orano2-registry-secret + image: + repository: registry.local:9001/admin/o2imsdms + tag: 0.1.4 + pullPolicy: IfNotPresent + logginglevel: "DEBUG" + +ocloud: + OS_AUTH_URL: "${OS_AUTH_URL}" + OS_USERNAME: "${OS_USERNAME}" + OS_PASSWORD: "${OS_PASSWORD}" +EOF + +sudo docker login registry.local:9001 -u ${OS_PROJECT_NAME} -p ${OS_PASSWORD} + +kubectl -n ${NAMESPACE} create secret docker-registry ${OS_PROJECT_NAME}-${NAMESPACE}-registry-secret \ +--docker-server=registry.local:9001 --docker-username=${OS_PROJECT_NAME} \ +--docker-password=${OS_PASSWORD} --docker-email=noreply@windriver.com + +cd /home/sysadmin/share/o2 + +helm install o2imstest charts/ -f /home/sysadmin/ocloud-override.yaml + +kubectl -n ${NAMESPACE} get pods + +``` + +### test api endpoint + +```sh +curl -k http(s)://:30205 +curl -k http(s)://:30205/o2ims_infrastructureInventory/v1 +``` + + +### Debug tips + +```sh +kubectl -n ${NAMESPACE} logs -f o2api- -c o2api +kubectl -n ${NAMESPACE} logs -f o2api- -c postgres +kubectl -n ${NAMESPACE} logs -f o2api- -c o2pubsub +kubectl -n ${NAMESPACE} logs -f o2api- -c watcher + + +kubectl -n ${NAMESPACE} logs -f o2api- -c o2api + +kubectl -n ${NAMESPACE} exec -it o2api- -c postgres -- bash + psql -U o2ims + + \c o2ims + + \d + + select * from ocloud; + + \q + + exit + +``` + +## Issues: + +1, there is chance the containers crash due to random bootstrap order of containers diff --git a/README.md b/README.md index 01d9710..d3ab23e 100644 --- a/README.md +++ b/README.md @@ -1,313 +1,313 @@ -## Building containers - -To accommodate the git repo access issue, the cgts-client and distributed client are -cloned into temp before docker building - -```sh -mkdir -p temp -cd temp -git clone --depth 1 --branch master https://opendev.org/starlingx/config.git -git clone --depth 1 --branch master https://opendev.org/starlingx/distcloud-client.git -cd - -``` - -```sh -docker-compose build -``` - -## Running the tests - - -```sh -source ./admin_openrc.sh -export |grep OS_AUTH_URL -export |grep OS_USERNAME -export |grep OS_PASSWORD -docker-compose up -d -docker-compose run --rm --no-deps --entrypoint=pytest api /tests/unit /tests/integration -``` - -## Running the tests with a O-Cloud - -Prerequisite: in case of testing against real ocloud, download openrc file from ocloud dashboard, e.g. - -```sh -admin_openrc.sh -docker-compose run --rm --no-deps --entrypoint=pytest api /tests/unit /tests/integration-ocloud - -docker-compose run --rm --no-deps --entrypoint=pytest api /tests/integration-ocloud --log-level=DEBUG --log-file=/test -s/debug.log -``` - -## Tear down containers - -```sh -docker-compose down --remove-orphans -``` - -## Test with local virtualenv - -```sh -python3.8 -m venv .venv && source .venv/bin/activate -pip install -r requirements.txt -c constraints.txt -pip install -r requirements-test.txt -pip install -e o2ims -# pip install -e o2dms -e o2common -pytest tests/unit -pytest tests/integration -pytest tests/e2e -``` - - -Test O2DMS with docker-compose -============================== - -## setup account over INF and get token - -```sh -USER="admin-user" -NAMESPACE="kube-system" - -cat < admin-login.yaml -apiVersion: v1 -kind: ServiceAccount -metadata: - name: ${USER} - namespace: kube-system ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRoleBinding -metadata: - name: ${USER} -roleRef: - apiGroup: rbac.authorization.k8s.io - kind: ClusterRole - name: cluster-admin -subjects: -- kind: ServiceAccount - name: ${USER} - namespace: kube-system -EOF -kubectl apply -f admin-login.yaml -TOKEN_DATA=$(kubectl -n kube-system describe secret $(kubectl -n kube-system get secret | grep ${USER} | awk '{print $1}') | grep "token:" | awk '{print $2}') - -``` - -## setup remote cli to access kubenetes cluster over INF - -```sh -sudo apt-get install -y apt-transport-https -echo "deb http://mirrors.ustc.edu.cn/kubernetes/apt kubernetes-xenial main" | \ -sudo tee -a /etc/apt/sources.list.d/kubernetes.list -sudo apt-get update -sudo apt-get install -y kubectl - -source <(kubectl completion bash) # setup autocomplete in bash into the current shell, bash-completion package should be installed first. -echo "source <(kubectl completion bash)" >> ~/.bashrc # add autocomplete permanently to your bash shell. - -https://get.helm.sh/helm-v3.5.3-linux-amd64.tar.gz -tar xvf helm-v3.5.3-linux-amd64.tar.gz -sudo cp linux-amd64/helm /usr/local/bin - -source <(helm completion bash) -echo "source <(helm completion bash)" >> ~/.bashrc - -OAM_IP= -NAMESPACE=default -TOKEN_DATA= - -USER="admin-user" - -kubectl config set-cluster inf-cluster --server=https://${OAM_IP}:6443 --insecure-skip-tls-verify -kubectl config set-credentials ${USER} --token=$TOKEN_DATA -kubectl config set-context ${USER}@inf-cluster --cluster=inf-cluster --user ${USER} --namespace=${NAMESPACE} -kubectl config use-context ${USER}@inf-cluster - -kubectl get pods -A - -``` - - -## setup local repo: o2imsrepo - -```sh -helm repo add chartmuseum https://chartmuseum.github.io/charts -helm repo update -helm pull chartmuseum/chartmuseum # download chartmuseum-3.4.0.tgz to local -tar zxvf chartmuseum-3.4.0.tgz - -export NODE_IP= - -cat <chartmuseum-override.yaml -env: - open: - DISABLE_API: false -service: - type: NodePort - nodePort: 30330 -EOF - -helm install chartmuseumrepo chartmuseum/chartmuseum -f chartmuseum-override.yaml -kubectl get pods -Kubectl get services - -helm repo add o2imsrepo http://${NODE_IP}:30330 -helm repo update - -helm repo add bitnami https://charts.bitnami.com/bitnami -helm repo update - -helm pull bitnami/mysql -helm push mysql-8.8.16.tgz o2imsrepo -helm repo update - -helm install my-release o2imsrepo/mysql -kubectl get pods -helm del my-release - -``` - - - -## Verify CFW over INF: Test with cnf firewall-host-netdevice - -## Setup host netdevice over INF - -```sh -ssh sysadmin@ -sudo ip link add name veth11 type veth peer name veth12 -sudo ip link add name veth21 type veth peer name veth22 -sudo ip link |grep veth -exit -``` - - -## verify CNF over INF -```sh -git clone https://github.com/biny993/firewall-host-netdevice.git - -cat < cfw-hostdev-override.yaml - -image: - repository: ubuntu - tag: 18.04 - pullPolicy: IfNotPresent - -resources: - cpu: 2 - memory: 2Gi - hugepage: 256Mi - -#global vars for parent and subcharts. - - - unprotectedNetPortVpg: veth11 - unprotectedNetPortVfw: veth12 - unprotectedNetCidr: 10.10.1.0/24 - unprotectedNetGwIp: 10.10.1.1 - - protectedNetPortVfw: veth21 - protectedNetPortVsn: veth22 - protectedNetCidr: 10.10.2.0/24 - protectedNetGwIp: 10.10.2.1 - - vfwPrivateIp0: 10.10.1.1 - vfwPrivateIp1: 10.10.2.1 - - vpgPrivateIp0: 10.10.1.2 - - vsnPrivateIp0: 10.10.2.2 - -EOF - -helm install cfw1 firewall-host-netdevice -f cfw-hostdev-override.yaml -kubectl get pods -helm del cfw1 -``` - -## push repo to o2imsrepo - -```sh -tar -zcvf firewall-host-netdevice-1.0.0.tgz firewall-host-netdevice/ -helm push firewall-host-netdevice-1.0.0.tgz o2imsrepo -helm repo update -helm search repo firewall - -helm install cfw1 o2imsrepo/firewall-host-netdevice -f cfw-hostdev-override.yaml -kubectl get pods -helm del cfw1 -``` - -## build docker image for o2 services -```sh -cd o2 -docker-compose build - -``` - -## bootstrap o2 service with docker-compose -```sh - -mkdir -p temp/kubeconfig/ -cp temp/kubeconfig/ - -source ./admin_openrc.sh -export K8S_KUBECONFIG=/etc/kubeconfig/config -docker-compose up -d -docker logs -f o2_redis_pubsub_1 - -``` - -## simiulate SMO to deploy CFW - -```sh - -curl --location --request GET 'http://localhost:5005/o2ims_infrastructureInventory/v1/deploymentManagers' -export dmsId= -curl --location --request POST 'http://localhost:5005/o2dms/v1/${dmsId}/O2dms_DeploymentLifecycle/NfDeploymentDescriptor' \ ---header 'Content-Type: application/json' \ ---data-raw '{ - "name": "cfwdesc1", - "description": "demo nf deployment descriptor", - "artifactRepoUrl": "http://128.224.115.15:30330", - "artifactName": "firewall-host-netdevice", - "inputParams": - "{\n \"image\": {\n \"repository\": \"ubuntu\",\n \"tag\": 18.04,\n \"pullPolicy\": \"IfNotPresent\"\n },\n \"resources\": {\n \"cpu\": 2,\n \"memory\": \"2Gi\",\n \"hugepage\": \"256Mi\",\n \"unprotectedNetPortVpg\": \"veth11\",\n \"unprotectedNetPortVfw\": \"veth12\",\n \"unprotectedNetCidr\": \"10.10.1.0/24\",\n \"unprotectedNetGwIp\": \"10.10.1.1\",\n \"protectedNetPortVfw\": \"veth21\",\n \"protectedNetPortVsn\": \"veth22\",\n \"protectedNetCidr\": \"10.10.2.0/24\",\n \"protectedNetGwIp\": \"10.10.2.1\",\n \"vfwPrivateIp0\": \"10.10.1.1\",\n \"vfwPrivateIp1\": \"10.10.2.1\",\n \"vpgPrivateIp0\": \"10.10.1.2\",\n \"vsnPrivateIp0\": \"10.10.2.2\"\n }\n}", - "outputParams": "{\"output1\": 100}" -}' - -curl --location --request GET 'http://localhost:5005/o2dms/v1/${dmsId}/O2dms_DeploymentLifecycle/NfDeploymentDescriptor' - -curl --location --request POST 'http://localhost:5005/o2dms/v1/${dmsId}/O2dms_DeploymentLifecycle/NfDeployment' \ ---header 'Content-Type: application/json' \ ---data-raw '{ - "name": "cfw100", - "description": "demo nf deployment", - "descriptorId": "", - "parentDeploymentId": "" -}' - -curl --location --request GET 'http://localhost:5005/o2dms/v1/${dmsId}/O2dms_DeploymentLifecycle/NfDeployment' - -export NfDeploymentId= - -``` - -## check logs - -```sh -docker logs -f o2_redis_pubsub_1 -kubectl get pods -kubectl logs -f cfw100-sink-host-netdevice-59bf6fbd4b-845p4 -``` - -## watch traffic stats - -open browswer with url: http://:30667 - - -## bring down CFW - -```sh -curl --location --request DELETE 'http://localhost:5005/o2dms/v1/${dmsId}/O2dms_DeploymentLifecycle/NfDeployment/${NfDeploymentId}' -``` +## Building containers + +To accommodate the git repo access issue, the cgts-client and distributed client are +cloned into temp before docker building + +```sh +mkdir -p temp +cd temp +git clone --depth 1 --branch master https://opendev.org/starlingx/config.git +git clone --depth 1 --branch master https://opendev.org/starlingx/distcloud-client.git +cd - +``` + +```sh +docker-compose build +``` + +## Running the tests + + +```sh +source ./admin_openrc.sh +export |grep OS_AUTH_URL +export |grep OS_USERNAME +export |grep OS_PASSWORD +docker-compose up -d +docker-compose run --rm --no-deps --entrypoint=pytest api /tests/unit /tests/integration +``` + +## Running the tests with a O-Cloud + +Prerequisite: in case of testing against real ocloud, download openrc file from ocloud dashboard, e.g. + +```sh +admin_openrc.sh +docker-compose run --rm --no-deps --entrypoint=pytest api /tests/unit /tests/integration-ocloud + +docker-compose run --rm --no-deps --entrypoint=pytest api /tests/integration-ocloud --log-level=DEBUG --log-file=/test +s/debug.log +``` + +## Tear down containers + +```sh +docker-compose down --remove-orphans +``` + +## Test with local virtualenv + +```sh +python3.8 -m venv .venv && source .venv/bin/activate +pip install -r requirements.txt -c constraints.txt +pip install -r requirements-test.txt +pip install -e o2ims +# pip install -e o2dms -e o2common +pytest tests/unit +pytest tests/integration +pytest tests/e2e +``` + + +Test O2DMS with docker-compose +============================== + +## setup account over INF and get token + +```sh +USER="admin-user" +NAMESPACE="kube-system" + +cat < admin-login.yaml +apiVersion: v1 +kind: ServiceAccount +metadata: + name: ${USER} + namespace: kube-system +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: ${USER} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: cluster-admin +subjects: +- kind: ServiceAccount + name: ${USER} + namespace: kube-system +EOF +kubectl apply -f admin-login.yaml +TOKEN_DATA=$(kubectl -n kube-system describe secret $(kubectl -n kube-system get secret | grep ${USER} | awk '{print $1}') | grep "token:" | awk '{print $2}') + +``` + +## setup remote cli to access kubenetes cluster over INF + +```sh +sudo apt-get install -y apt-transport-https +echo "deb http://mirrors.ustc.edu.cn/kubernetes/apt kubernetes-xenial main" | \ +sudo tee -a /etc/apt/sources.list.d/kubernetes.list +sudo apt-get update +sudo apt-get install -y kubectl + +source <(kubectl completion bash) # setup autocomplete in bash into the current shell, bash-completion package should be installed first. +echo "source <(kubectl completion bash)" >> ~/.bashrc # add autocomplete permanently to your bash shell. + +https://get.helm.sh/helm-v3.5.3-linux-amd64.tar.gz +tar xvf helm-v3.5.3-linux-amd64.tar.gz +sudo cp linux-amd64/helm /usr/local/bin + +source <(helm completion bash) +echo "source <(helm completion bash)" >> ~/.bashrc + +OAM_IP= +NAMESPACE=default +TOKEN_DATA= + +USER="admin-user" + +kubectl config set-cluster inf-cluster --server=https://${OAM_IP}:6443 --insecure-skip-tls-verify +kubectl config set-credentials ${USER} --token=$TOKEN_DATA +kubectl config set-context ${USER}@inf-cluster --cluster=inf-cluster --user ${USER} --namespace=${NAMESPACE} +kubectl config use-context ${USER}@inf-cluster + +kubectl get pods -A + +``` + + +## setup local repo: o2imsrepo + +```sh +helm repo add chartmuseum https://chartmuseum.github.io/charts +helm repo update +helm pull chartmuseum/chartmuseum # download chartmuseum-3.4.0.tgz to local +tar zxvf chartmuseum-3.4.0.tgz + +export NODE_IP= + +cat <chartmuseum-override.yaml +env: + open: + DISABLE_API: false +service: + type: NodePort + nodePort: 30330 +EOF + +helm install chartmuseumrepo chartmuseum/chartmuseum -f chartmuseum-override.yaml +kubectl get pods +Kubectl get services + +helm repo add o2imsrepo http://${NODE_IP}:30330 +helm repo update + +helm repo add bitnami https://charts.bitnami.com/bitnami +helm repo update + +helm pull bitnami/mysql +helm push mysql-8.8.16.tgz o2imsrepo +helm repo update + +helm install my-release o2imsrepo/mysql +kubectl get pods +helm del my-release + +``` + + + +## Verify CFW over INF: Test with cnf firewall-host-netdevice + +## Setup host netdevice over INF + +```sh +ssh sysadmin@ +sudo ip link add name veth11 type veth peer name veth12 +sudo ip link add name veth21 type veth peer name veth22 +sudo ip link |grep veth +exit +``` + + +## verify CNF over INF +```sh +git clone https://github.com/biny993/firewall-host-netdevice.git + +cat < cfw-hostdev-override.yaml + +image: + repository: ubuntu + tag: 18.04 + pullPolicy: IfNotPresent + +resources: + cpu: 2 + memory: 2Gi + hugepage: 256Mi + +#global vars for parent and subcharts. + + + unprotectedNetPortVpg: veth11 + unprotectedNetPortVfw: veth12 + unprotectedNetCidr: 10.10.1.0/24 + unprotectedNetGwIp: 10.10.1.1 + + protectedNetPortVfw: veth21 + protectedNetPortVsn: veth22 + protectedNetCidr: 10.10.2.0/24 + protectedNetGwIp: 10.10.2.1 + + vfwPrivateIp0: 10.10.1.1 + vfwPrivateIp1: 10.10.2.1 + + vpgPrivateIp0: 10.10.1.2 + + vsnPrivateIp0: 10.10.2.2 + +EOF + +helm install cfw1 firewall-host-netdevice -f cfw-hostdev-override.yaml +kubectl get pods +helm del cfw1 +``` + +## push repo to o2imsrepo + +```sh +tar -zcvf firewall-host-netdevice-1.0.0.tgz firewall-host-netdevice/ +helm push firewall-host-netdevice-1.0.0.tgz o2imsrepo +helm repo update +helm search repo firewall + +helm install cfw1 o2imsrepo/firewall-host-netdevice -f cfw-hostdev-override.yaml +kubectl get pods +helm del cfw1 +``` + +## build docker image for o2 services +```sh +cd o2 +docker-compose build + +``` + +## bootstrap o2 service with docker-compose +```sh + +mkdir -p temp/kubeconfig/ +cp temp/kubeconfig/ + +source ./admin_openrc.sh +export K8S_KUBECONFIG=/etc/kubeconfig/config +docker-compose up -d +docker logs -f o2_redis_pubsub_1 + +``` + +## simiulate SMO to deploy CFW + +```sh + +curl --location --request GET 'http://localhost:5005/o2ims_infrastructureInventory/v1/deploymentManagers' +export dmsId= +curl --location --request POST 'http://localhost:5005/o2dms/v1/${dmsId}/O2dms_DeploymentLifecycle/NfDeploymentDescriptor' \ +--header 'Content-Type: application/json' \ +--data-raw '{ + "name": "cfwdesc1", + "description": "demo nf deployment descriptor", + "artifactRepoUrl": "http://128.224.115.15:30330", + "artifactName": "firewall-host-netdevice", + "inputParams": + "{\n \"image\": {\n \"repository\": \"ubuntu\",\n \"tag\": 18.04,\n \"pullPolicy\": \"IfNotPresent\"\n },\n \"resources\": {\n \"cpu\": 2,\n \"memory\": \"2Gi\",\n \"hugepage\": \"256Mi\",\n \"unprotectedNetPortVpg\": \"veth11\",\n \"unprotectedNetPortVfw\": \"veth12\",\n \"unprotectedNetCidr\": \"10.10.1.0/24\",\n \"unprotectedNetGwIp\": \"10.10.1.1\",\n \"protectedNetPortVfw\": \"veth21\",\n \"protectedNetPortVsn\": \"veth22\",\n \"protectedNetCidr\": \"10.10.2.0/24\",\n \"protectedNetGwIp\": \"10.10.2.1\",\n \"vfwPrivateIp0\": \"10.10.1.1\",\n \"vfwPrivateIp1\": \"10.10.2.1\",\n \"vpgPrivateIp0\": \"10.10.1.2\",\n \"vsnPrivateIp0\": \"10.10.2.2\"\n }\n}", + "outputParams": "{\"output1\": 100}" +}' + +curl --location --request GET 'http://localhost:5005/o2dms/v1/${dmsId}/O2dms_DeploymentLifecycle/NfDeploymentDescriptor' + +curl --location --request POST 'http://localhost:5005/o2dms/v1/${dmsId}/O2dms_DeploymentLifecycle/NfDeployment' \ +--header 'Content-Type: application/json' \ +--data-raw '{ + "name": "cfw100", + "description": "demo nf deployment", + "descriptorId": "", + "parentDeploymentId": "" +}' + +curl --location --request GET 'http://localhost:5005/o2dms/v1/${dmsId}/O2dms_DeploymentLifecycle/NfDeployment' + +export NfDeploymentId= + +``` + +## check logs + +```sh +docker logs -f o2_redis_pubsub_1 +kubectl get pods +kubectl logs -f cfw100-sink-host-netdevice-59bf6fbd4b-845p4 +``` + +## watch traffic stats + +open browswer with url: http://:30667 + + +## bring down CFW + +```sh +curl --location --request DELETE 'http://localhost:5005/o2dms/v1/${dmsId}/O2dms_DeploymentLifecycle/NfDeployment/${NfDeploymentId}' +``` diff --git a/charts/templates/deployment.yaml b/charts/templates/deployment.yaml index 7497d9f..a25f326 100644 --- a/charts/templates/deployment.yaml +++ b/charts/templates/deployment.yaml @@ -1,141 +1,141 @@ -# Copyright (C) 2021 Wind River Systems, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - ---- -apiVersion: apps/v1 -kind: Deployment -metadata: - name: o2api - namespace: {{ .Values.global.namespace }} - labels: - app: o2api -spec: - replicas: 1 - selector: - matchLabels: - app: o2api - template: - metadata: - labels: - app: o2api - spec: - imagePullSecrets: - - name: {{ .Values.o2ims.imagePullSecrets }} -{{- if .Values.o2ims.affinity }} - affinity: -{{ toYaml .Values.o2ims.affinity | indent 8 }} -{{- end }} - containers: - - name: postgres - image: postgres:9.6 - ports: - - containerPort: 5432 - env: - - name: POSTGRES_PASSWORD - value: o2ims123 - - name: POSTGRES_USER - value: o2ims - command: ["/bin/bash", "/opt/postgres_start.sh"] - volumeMounts: - - name: scripts - mountPath: /opt - - name: redis - image: redis:alpine - ports: - - containerPort: 6379 - - name: o2pubsub - image: "{{ .Values.o2ims.image.repository }}:{{ .Values.o2ims.image.tag }}" - command: ["/bin/bash", "/opt/o2pubsub_start.sh"] - env: - - name: DB_HOST - value: postgres - - name: DB_PASSWORD - value: o2ims123 - - name: LOGGING_CONFIG_LEVEL - value: {{ .Values.o2ims.logginglevel }} - - name: OS_AUTH_URL - value: {{ .Values.ocloud.OS_AUTH_URL }} - - name: OS_PASSWORD - value: {{ .Values.ocloud.OS_PASSWORD }} - - name: OS_USERNAME - value: {{ .Values.ocloud.OS_USERNAME }} - - name: PYTHONDONTWRITEBYTECODE - value: "1" - - name: REDIS_HOST - value: redis - - name: K8S_KUBECONFIG - value: {{ .Values.ocloud.K8S_KUBECONFIG }} - volumeMounts: - - name: scripts - mountPath: /opt - - name: watcher - image: "{{ .Values.o2ims.image.repository }}:{{ .Values.o2ims.image.tag }}" - command: ["/bin/bash", "/opt/o2watcher_start.sh"] - env: - - name: API_HOST_EXTERNAL_FLOATING - value: {{ .Values.ocloud.API_HOST_EXTERNAL_FLOATING }} - - name: DB_HOST - value: postgres - - name: DB_PASSWORD - value: o2ims123 - - name: LOGGING_CONFIG_LEVEL - value: {{ .Values.o2ims.logginglevel }} - - name: OS_AUTH_URL - value: {{ .Values.ocloud.OS_AUTH_URL }} - - name: OS_PASSWORD - value: {{ .Values.ocloud.OS_PASSWORD }} - - name: OS_USERNAME - value: {{ .Values.ocloud.OS_USERNAME }} - - name: PYTHONDONTWRITEBYTECODE - value: "1" - - name: REDIS_HOST - value: redis - volumeMounts: - - name: scripts - mountPath: /opt - - name: o2api - image: "{{ .Values.o2ims.image.repository }}:{{ .Values.o2ims.image.tag }}" - ports: - - containerPort: 80 - env: - - name: API_HOST - value: api - - name: DB_HOST - value: postgres - - name: DB_PASSWORD - value: o2ims123 - - name: FLASK_APP - value: /root/o2/o2app/entrypoints/flask_application.py - - name: FLASK_DEBUG - value: {{ .Values.o2ims.logginglevel }} - - name: LOGGING_CONFIG_LEVEL - value: {{ .Values.o2ims.logginglevel }} - - name: OS_AUTH_URL - - name: OS_PASSWORD - - name: OS_USERNAME - - name: PYTHONDONTWRITEBYTECODE - value: "1" - - name: PYTHONUNBUFFERED - value: "1" - - name: REDIS_HOST - value: redis - command: ["/bin/bash", "/opt/o2api_start.sh"] - volumeMounts: - - name: scripts - mountPath: /opt - volumes: - - name: scripts - configMap: - name: {{ .Chart.Name }}-scripts-configmap ---- +# Copyright (C) 2021 Wind River Systems, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: o2api + namespace: {{ .Values.global.namespace }} + labels: + app: o2api +spec: + replicas: 1 + selector: + matchLabels: + app: o2api + template: + metadata: + labels: + app: o2api + spec: + imagePullSecrets: + - name: {{ .Values.o2ims.imagePullSecrets }} +{{- if .Values.o2ims.affinity }} + affinity: +{{ toYaml .Values.o2ims.affinity | indent 8 }} +{{- end }} + containers: + - name: postgres + image: postgres:9.6 + ports: + - containerPort: 5432 + env: + - name: POSTGRES_PASSWORD + value: o2ims123 + - name: POSTGRES_USER + value: o2ims + command: ["/bin/bash", "/opt/postgres_start.sh"] + volumeMounts: + - name: scripts + mountPath: /opt + - name: redis + image: redis:alpine + ports: + - containerPort: 6379 + - name: o2pubsub + image: "{{ .Values.o2ims.image.repository }}:{{ .Values.o2ims.image.tag }}" + command: ["/bin/bash", "/opt/o2pubsub_start.sh"] + env: + - name: DB_HOST + value: postgres + - name: DB_PASSWORD + value: o2ims123 + - name: LOGGING_CONFIG_LEVEL + value: {{ .Values.o2ims.logginglevel }} + - name: OS_AUTH_URL + value: {{ .Values.ocloud.OS_AUTH_URL }} + - name: OS_PASSWORD + value: {{ .Values.ocloud.OS_PASSWORD }} + - name: OS_USERNAME + value: {{ .Values.ocloud.OS_USERNAME }} + - name: PYTHONDONTWRITEBYTECODE + value: "1" + - name: REDIS_HOST + value: redis + - name: K8S_KUBECONFIG + value: {{ .Values.ocloud.K8S_KUBECONFIG }} + volumeMounts: + - name: scripts + mountPath: /opt + - name: watcher + image: "{{ .Values.o2ims.image.repository }}:{{ .Values.o2ims.image.tag }}" + command: ["/bin/bash", "/opt/o2watcher_start.sh"] + env: + - name: API_HOST_EXTERNAL_FLOATING + value: {{ .Values.ocloud.API_HOST_EXTERNAL_FLOATING }} + - name: DB_HOST + value: postgres + - name: DB_PASSWORD + value: o2ims123 + - name: LOGGING_CONFIG_LEVEL + value: {{ .Values.o2ims.logginglevel }} + - name: OS_AUTH_URL + value: {{ .Values.ocloud.OS_AUTH_URL }} + - name: OS_PASSWORD + value: {{ .Values.ocloud.OS_PASSWORD }} + - name: OS_USERNAME + value: {{ .Values.ocloud.OS_USERNAME }} + - name: PYTHONDONTWRITEBYTECODE + value: "1" + - name: REDIS_HOST + value: redis + volumeMounts: + - name: scripts + mountPath: /opt + - name: o2api + image: "{{ .Values.o2ims.image.repository }}:{{ .Values.o2ims.image.tag }}" + ports: + - containerPort: 80 + env: + - name: API_HOST + value: api + - name: DB_HOST + value: postgres + - name: DB_PASSWORD + value: o2ims123 + - name: FLASK_APP + value: /root/o2/o2app/entrypoints/flask_application.py + - name: FLASK_DEBUG + value: {{ .Values.o2ims.logginglevel }} + - name: LOGGING_CONFIG_LEVEL + value: {{ .Values.o2ims.logginglevel }} + - name: OS_AUTH_URL + - name: OS_PASSWORD + - name: OS_USERNAME + - name: PYTHONDONTWRITEBYTECODE + value: "1" + - name: PYTHONUNBUFFERED + value: "1" + - name: REDIS_HOST + value: redis + command: ["/bin/bash", "/opt/o2api_start.sh"] + volumeMounts: + - name: scripts + mountPath: /opt + volumes: + - name: scripts + configMap: + name: {{ .Chart.Name }}-scripts-configmap +--- diff --git a/charts/templates/service.yaml b/charts/templates/service.yaml index fba16e3..990f78b 100644 --- a/charts/templates/service.yaml +++ b/charts/templates/service.yaml @@ -1,31 +1,31 @@ -# Copyright (C) 2021 Wind River Systems, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# ---- -apiVersion: v1 -kind: Service -metadata: - name: o2api - namespace: {{ .Values.global.namespace }} -spec: - type: NodePort - ports: - - name: o2api - port: 5005 - targetPort: 80 - nodePort: 30205 - protocol: TCP - selector: - app: o2api ---- +# Copyright (C) 2021 Wind River Systems, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +--- +apiVersion: v1 +kind: Service +metadata: + name: o2api + namespace: {{ .Values.global.namespace }} +spec: + type: NodePort + ports: + - name: o2api + port: 5005 + targetPort: 80 + nodePort: 30205 + protocol: TCP + selector: + app: o2api +--- diff --git a/configs/log.yaml b/configs/log.yaml index 62d1a92..39b923d 100644 --- a/configs/log.yaml +++ b/configs/log.yaml @@ -1,49 +1,49 @@ -# Copyright (C) 2021 Wind River Systems, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -version: 1 -disable_existing_loggers: False - -loggers: - root: - handlers: [console_handler, file_handler] - level: "WARNING" - propagate: False - o2common: - handlers: [console_handler, file_handler] - level: "WARNING" - propagate: False - o2ims: - handlers: [console_handler, file_handler] - level: "DEBUG" - propagate: False - o2dms: - handlers: [console_handler, file_handler] - level: "DEBUG" - propagate: False -handlers: - console_handler: - level: "DEBUG" - class: "logging.StreamHandler" - formatter: "standard" - file_handler: - level: "DEBUG" - class: "logging.handlers.RotatingFileHandler" - filename: "/var/log/o2.log" - formatter: "standard" - maxBytes: 52428800 - backupCount: 10 -formatters: - standard: - format: "%(asctime)s:[%(name)s]:[%(filename)s]-[%(lineno)d] [%(levelname)s]:%(message)s" +# Copyright (C) 2021 Wind River Systems, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +version: 1 +disable_existing_loggers: False + +loggers: + root: + handlers: [console_handler, file_handler] + level: "WARNING" + propagate: False + o2common: + handlers: [console_handler, file_handler] + level: "WARNING" + propagate: False + o2ims: + handlers: [console_handler, file_handler] + level: "DEBUG" + propagate: False + o2dms: + handlers: [console_handler, file_handler] + level: "DEBUG" + propagate: False +handlers: + console_handler: + level: "DEBUG" + class: "logging.StreamHandler" + formatter: "standard" + file_handler: + level: "DEBUG" + class: "logging.handlers.RotatingFileHandler" + filename: "/var/log/o2.log" + formatter: "standard" + maxBytes: 52428800 + backupCount: 10 +formatters: + standard: + format: "%(asctime)s:[%(name)s]:[%(filename)s]-[%(lineno)d] [%(levelname)s]:%(message)s" diff --git a/mock_smo/Dockerfile b/mock_smo/Dockerfile index 74d6b61..f0f01ab 100644 --- a/mock_smo/Dockerfile +++ b/mock_smo/Dockerfile @@ -1,23 +1,23 @@ -FROM python:3.10-slim-buster - -RUN apt-get update; apt-get install -y git gcc - -COPY requirements.txt /tmp/ -RUN pip install -r /tmp/requirements.txt - -# COPY requirements-test.txt /tmp/ -# RUN pip install -r /tmp/requirements-test.txt - -RUN mkdir -p /src -COPY mock_smo/ /src/mock_smo/ - -COPY setup.py o2app-mock-smo.sh /src/ -RUN pip install -e /src - -COPY etc/ /etc/mock_smo/ - -# COPY tests/ /tests/ - -# RUN apt-get install -y procps vim - -WORKDIR /src +FROM python:3.10-slim-buster + +RUN apt-get update; apt-get install -y git gcc + +COPY requirements.txt /tmp/ +RUN pip install -r /tmp/requirements.txt + +# COPY requirements-test.txt /tmp/ +# RUN pip install -r /tmp/requirements-test.txt + +RUN mkdir -p /src +COPY mock_smo/ /src/mock_smo/ + +COPY setup.py o2app-mock-smo.sh /src/ +RUN pip install -e /src + +COPY etc/ /etc/mock_smo/ + +# COPY tests/ /tests/ + +# RUN apt-get install -y procps vim + +WORKDIR /src diff --git a/mock_smo/etc/log.yaml b/mock_smo/etc/log.yaml index 59ab8eb..ff79bc1 100644 --- a/mock_smo/etc/log.yaml +++ b/mock_smo/etc/log.yaml @@ -1,49 +1,49 @@ -# Copyright (C) 2021 Wind River Systems, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -version: 1 -disable_existing_loggers: False - -loggers: - root: - handlers: [console_handler, file_handler] - level: "WARNING" - propagate: False - o2common: - handlers: [console_handler, file_handler] - level: "WARNING" - propagate: False - o2ims: - handlers: [console_handler, file_handler] - level: "DEBUG" - propagate: False - o2dms: - handlers: [console_handler, file_handler] - level: "DEBUG" - propagate: False -handlers: - console_handler: - level: "DEBUG" - class: "logging.StreamHandler" - formatter: "standard" - file_handler: - level: "DEBUG" - class: "logging.handlers.RotatingFileHandler" - filename: "/var/log/mock_smo.log" - formatter: "standard" - maxBytes: 52428800 - backupCount: 10 -formatters: - standard: - format: "%(asctime)s:[%(name)s]:[%(filename)s]-[%(lineno)d] [%(levelname)s]:%(message)s" +# Copyright (C) 2021 Wind River Systems, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +version: 1 +disable_existing_loggers: False + +loggers: + root: + handlers: [console_handler, file_handler] + level: "WARNING" + propagate: False + o2common: + handlers: [console_handler, file_handler] + level: "WARNING" + propagate: False + o2ims: + handlers: [console_handler, file_handler] + level: "DEBUG" + propagate: False + o2dms: + handlers: [console_handler, file_handler] + level: "DEBUG" + propagate: False +handlers: + console_handler: + level: "DEBUG" + class: "logging.StreamHandler" + formatter: "standard" + file_handler: + level: "DEBUG" + class: "logging.handlers.RotatingFileHandler" + filename: "/var/log/mock_smo.log" + formatter: "standard" + maxBytes: 52428800 + backupCount: 10 +formatters: + standard: + format: "%(asctime)s:[%(name)s]:[%(filename)s]-[%(lineno)d] [%(levelname)s]:%(message)s" diff --git a/mock_smo/mock_smo/__init__.py b/mock_smo/mock_smo/__init__.py index b514342..813897e 100644 --- a/mock_smo/mock_smo/__init__.py +++ b/mock_smo/mock_smo/__init__.py @@ -1,13 +1,13 @@ -# Copyright (C) 2021 Wind River Systems, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. +# Copyright (C) 2021 Wind River Systems, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. diff --git a/mock_smo/mock_smo/entrypoints/__init__.py b/mock_smo/mock_smo/entrypoints/__init__.py index b514342..813897e 100644 --- a/mock_smo/mock_smo/entrypoints/__init__.py +++ b/mock_smo/mock_smo/entrypoints/__init__.py @@ -1,13 +1,13 @@ -# Copyright (C) 2021 Wind River Systems, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. +# Copyright (C) 2021 Wind River Systems, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. diff --git a/mock_smo/mock_smo/entrypoints/mock_smo.py b/mock_smo/mock_smo/entrypoints/mock_smo.py index aea0840..67aadf3 100644 --- a/mock_smo/mock_smo/entrypoints/mock_smo.py +++ b/mock_smo/mock_smo/entrypoints/mock_smo.py @@ -1,122 +1,122 @@ -# Copyright (C) 2021 Wind River Systems, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -import json -import redis -import http.client -from flask import Flask, request -from flask.helpers import url_for - -import mock_smo.config as config -import mock_smo.logging as logging -logger = logging.get_logger(__name__) - -apibase = config.get_o2ims_api_base() -app = Flask(__name__) - -r = redis.Redis(**config.get_redis_host_and_port()) -REDIS_SUB_KEY = 'mock_smo_sub_key' -REDIS_O2IMS_URL = 'mock_smo_o2ims_url' - - -@app.route('/', methods=['GET', 'POST']) -def index(): - if request.method == 'POST': - url = request.form['url'] - consumerSubscriptionId = request.form['consumerSubId'] - sub_id = subscription_ims(url, consumerSubscriptionId) - return """ -

Subscribed O2IMS

-

Subscription ID: %s

-

Subscribed O2IMS URL: %s

- - - -""" % (sub_id, url, url_for('unsubscription')) - return """ -

Subscribe O2IMS

-
- -

- -

- -
-""" - - -@app.route('/unsubscription') -def unsubscription(): - sub_key = r.get(REDIS_SUB_KEY) - logger.info('Subscription key is {}'.format(sub_key)) - if sub_key is None: - return '

Already unsubscribed

' - url = r.get(REDIS_O2IMS_URL).decode('utf-8') - logger.info('O2 IMS API is: {}'.format(url)) - unsubscription_ims(url, sub_key.decode('utf-8')) - r.delete(REDIS_O2IMS_URL) - r.delete(REDIS_SUB_KEY) - return """ -

Unsubscribed O2IMS

- - - -""" - - -@app.route('/callback', methods=['POST']) -def callback(): - logger.info('Callback data: {}'.format(request.get_data())) - return '', 202 - - -@app.route('/registration', methods=['POST']) -def registration(): - logger.info('Registration data: {}'.format(request.get_data())) - return '', 200 - - -def subscription_ims(url, consumerSubscriptionId): - sub_key = r.get(REDIS_SUB_KEY) - logger.info('Subscription key is {}'.format(sub_key)) - if sub_key is not None: - return sub_key.decode('utf-8') - - logger.info(request.host_url) - conn = http.client.HTTPConnection(url) - headers = {'Content-type': 'application/json'} - post_val = { - 'callback': 'http://mock_smo:80' + url_for('callback'), - 'consumerSubscriptionId': consumerSubscriptionId, - 'filter': '["pserver"]' # '["pserver","pserver_mem"]' - } - json_val = json.dumps(post_val) - conn.request('POST', apibase+'/subscriptions', json_val, headers) - resp = conn.getresponse() - data = resp.read().decode('utf-8') - logger.info('Subscription response: {} {}, data: {}'.format( - resp.status, resp.reason, data)) - json_data = json.loads(data) - - r.set(REDIS_SUB_KEY, json_data['subscriptionId']) - r.set(REDIS_O2IMS_URL, url) - return json_data['subscriptionId'] - - -def unsubscription_ims(url, subId): - conn = http.client.HTTPConnection(url) - conn.request('DELETE', apibase + '/subscriptions/' + subId) - resp = conn.getresponse() - logger.info('Unsubscription response: {} {}'.format( - resp.status, resp.reason)) +# Copyright (C) 2021 Wind River Systems, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import json +import redis +import http.client +from flask import Flask, request +from flask.helpers import url_for + +import mock_smo.config as config +import mock_smo.logging as logging +logger = logging.get_logger(__name__) + +apibase = config.get_o2ims_api_base() +app = Flask(__name__) + +r = redis.Redis(**config.get_redis_host_and_port()) +REDIS_SUB_KEY = 'mock_smo_sub_key' +REDIS_O2IMS_URL = 'mock_smo_o2ims_url' + + +@app.route('/', methods=['GET', 'POST']) +def index(): + if request.method == 'POST': + url = request.form['url'] + consumerSubscriptionId = request.form['consumerSubId'] + sub_id = subscription_ims(url, consumerSubscriptionId) + return """ +

Subscribed O2IMS

+

Subscription ID: %s

+

Subscribed O2IMS URL: %s

+ + + +""" % (sub_id, url, url_for('unsubscription')) + return """ +

Subscribe O2IMS

+
+ +

+ +

+ +
+""" + + +@app.route('/unsubscription') +def unsubscription(): + sub_key = r.get(REDIS_SUB_KEY) + logger.info('Subscription key is {}'.format(sub_key)) + if sub_key is None: + return '

Already unsubscribed

' + url = r.get(REDIS_O2IMS_URL).decode('utf-8') + logger.info('O2 IMS API is: {}'.format(url)) + unsubscription_ims(url, sub_key.decode('utf-8')) + r.delete(REDIS_O2IMS_URL) + r.delete(REDIS_SUB_KEY) + return """ +

Unsubscribed O2IMS

+ + + +""" + + +@app.route('/callback', methods=['POST']) +def callback(): + logger.info('Callback data: {}'.format(request.get_data())) + return '', 202 + + +@app.route('/registration', methods=['POST']) +def registration(): + logger.info('Registration data: {}'.format(request.get_data())) + return '', 200 + + +def subscription_ims(url, consumerSubscriptionId): + sub_key = r.get(REDIS_SUB_KEY) + logger.info('Subscription key is {}'.format(sub_key)) + if sub_key is not None: + return sub_key.decode('utf-8') + + logger.info(request.host_url) + conn = http.client.HTTPConnection(url) + headers = {'Content-type': 'application/json'} + post_val = { + 'callback': 'http://mock_smo:80' + url_for('callback'), + 'consumerSubscriptionId': consumerSubscriptionId, + 'filter': '["pserver"]' # '["pserver","pserver_mem"]' + } + json_val = json.dumps(post_val) + conn.request('POST', apibase+'/subscriptions', json_val, headers) + resp = conn.getresponse() + data = resp.read().decode('utf-8') + logger.info('Subscription response: {} {}, data: {}'.format( + resp.status, resp.reason, data)) + json_data = json.loads(data) + + r.set(REDIS_SUB_KEY, json_data['subscriptionId']) + r.set(REDIS_O2IMS_URL, url) + return json_data['subscriptionId'] + + +def unsubscription_ims(url, subId): + conn = http.client.HTTPConnection(url) + conn.request('DELETE', apibase + '/subscriptions/' + subId) + resp = conn.getresponse() + logger.info('Unsubscription response: {} {}'.format( + resp.status, resp.reason)) diff --git a/mock_smo/mock_smo/logging.py b/mock_smo/mock_smo/logging.py index cb3b504..39f1f64 100644 --- a/mock_smo/mock_smo/logging.py +++ b/mock_smo/mock_smo/logging.py @@ -1,36 +1,36 @@ -# Copyright (C) 2021 Wind River Systems, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -import logging -import logging.config -import logging.handlers -import os -import yaml - - -def get_logger(name=None): - CONFIG_FILE = os.environ.get( - "LOGGING_CONFIG_FILE", "/etc/mock_smo/log.yaml") - if os.path.exists(CONFIG_FILE): - with open(file=CONFIG_FILE, mode='r', encoding="utf-8") as file: - config_yaml = yaml.load(stream=file, Loader=yaml.FullLoader) - logging.config.dictConfig(config=config_yaml) - - logger = logging.getLogger(name) - - # override logging level - LOGGING_CONFIG_LEVEL = os.environ.get("LOGGING_CONFIG_LEVEL", None) - if LOGGING_CONFIG_LEVEL: - logger.setLevel(LOGGING_CONFIG_LEVEL) - return logger +# Copyright (C) 2021 Wind River Systems, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import logging +import logging.config +import logging.handlers +import os +import yaml + + +def get_logger(name=None): + CONFIG_FILE = os.environ.get( + "LOGGING_CONFIG_FILE", "/etc/mock_smo/log.yaml") + if os.path.exists(CONFIG_FILE): + with open(file=CONFIG_FILE, mode='r', encoding="utf-8") as file: + config_yaml = yaml.load(stream=file, Loader=yaml.FullLoader) + logging.config.dictConfig(config=config_yaml) + + logger = logging.getLogger(name) + + # override logging level + LOGGING_CONFIG_LEVEL = os.environ.get("LOGGING_CONFIG_LEVEL", None) + if LOGGING_CONFIG_LEVEL: + logger.setLevel(LOGGING_CONFIG_LEVEL) + return logger diff --git a/mock_smo/requirements.txt b/mock_smo/requirements.txt index 0b2acc6..9e5ff27 100644 --- a/mock_smo/requirements.txt +++ b/mock_smo/requirements.txt @@ -1,5 +1,5 @@ -flask -flask-restx -redis -PyYAML>=5.4.1 - +flask +flask-restx +redis +PyYAML>=5.4.1 + diff --git a/mock_smo/setup.py b/mock_smo/setup.py index 3afc7fc..ccfe341 100644 --- a/mock_smo/setup.py +++ b/mock_smo/setup.py @@ -1,13 +1,13 @@ -from setuptools import setup -from setuptools import find_packages - -setup( - name="mock_smo", - version="1.0", - packages=find_packages(), - license="LICENSE", - description="Mock SMO server for O2 IMS and DMS", - install_requires=[ - 'httplib2', - ] -) +from setuptools import setup +from setuptools import find_packages + +setup( + name="mock_smo", + version="1.0", + packages=find_packages(), + license="LICENSE", + description="Mock SMO server for O2 IMS and DMS", + install_requires=[ + 'httplib2', + ] +) diff --git a/mypy.ini b/mypy.ini index 31ee9f6..601283d 100644 --- a/mypy.ini +++ b/mypy.ini @@ -1,7 +1,7 @@ -[mypy] -ignore_missing_imports = False -mypy_path = ./src -check_untyped_defs = True - -[mypy-pytest.*,sqlalchemy.*,redis.*] -ignore_missing_imports = True +[mypy] +ignore_missing_imports = False +mypy_path = ./src +check_untyped_defs = True + +[mypy-pytest.*,sqlalchemy.*,redis.*] +ignore_missing_imports = True diff --git a/o2app/__init__.py b/o2app/__init__.py index b514342..813897e 100644 --- a/o2app/__init__.py +++ b/o2app/__init__.py @@ -1,13 +1,13 @@ -# Copyright (C) 2021 Wind River Systems, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. +# Copyright (C) 2021 Wind River Systems, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. diff --git a/o2app/adapter/__init__.py b/o2app/adapter/__init__.py index b514342..813897e 100644 --- a/o2app/adapter/__init__.py +++ b/o2app/adapter/__init__.py @@ -1,13 +1,13 @@ -# Copyright (C) 2021 Wind River Systems, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. +# Copyright (C) 2021 Wind River Systems, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. diff --git a/o2app/adapter/unit_of_work.py b/o2app/adapter/unit_of_work.py index 732216e..37b30d3 100644 --- a/o2app/adapter/unit_of_work.py +++ b/o2app/adapter/unit_of_work.py @@ -1,113 +1,113 @@ -# Copyright (C) 2021 Wind River Systems, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# pylint: disable=attribute-defined-outside-init -from __future__ import annotations -from sqlalchemy import create_engine -from sqlalchemy.orm import sessionmaker -from sqlalchemy.orm.session import Session - -from o2common.config import config -from o2common.service.unit_of_work import AbstractUnitOfWork - -from o2ims.adapter import ocloud_repository -from o2dms.adapter import dms_repository - -from o2common.helper import o2logging -logger = o2logging.get_logger(__name__) - - -engine = create_engine( - config.get_postgres_uri(), - isolation_level="REPEATABLE READ", - pool_size=200, max_overflow=0, - pool_recycle=3600 -) - -DEFAULT_SESSION_FACTORY = sessionmaker( - autocommit=False, autoflush=False, bind=engine -) - - -class SqlAlchemyUnitOfWork(AbstractUnitOfWork): - - def __init__(self, session_factory=DEFAULT_SESSION_FACTORY): - self.session_factory = session_factory - - def __enter__(self): - self.session = self.session_factory() # type: Session - self.oclouds = ocloud_repository\ - .OcloudSqlAlchemyRepository(self.session) - self.resource_types = ocloud_repository\ - .ResouceTypeSqlAlchemyRepository(self.session) - self.resource_pools = ocloud_repository\ - .ResourcePoolSqlAlchemyRepository(self.session) - self.resources = ocloud_repository\ - .ResourceSqlAlchemyRepository(self.session) - self.subscriptions = ocloud_repository\ - .SubscriptionSqlAlchemyRepository(self.session) - self.configurations = ocloud_repository\ - .ConfigurationSqlAlchemyRepository(self.session) - self.deployment_managers = ocloud_repository\ - .DeploymentManagerSqlAlchemyRepository(self.session) - self.nfdeployment_descs = dms_repository\ - .NfDeploymentDescSqlAlchemyRepository(self.session) - self.nfdeployments = dms_repository\ - .NfDeploymentSqlAlchemyRepository(self.session) - self.ocloudvresources = dms_repository\ - .NfOCloudVResourceSqlAlchemyRepository(self.session) - return super().__enter__() - - def __exit__(self, *args): - super().__exit__(*args) - self.session.close() - - def _commit(self): - self.session.commit() - - def rollback(self): - self.session.rollback() - - def _collect_new_events(self): - for entry in self.oclouds.seen: - # while hasattr(entry, 'events') and len(entry.events) > 0: - while entry.events is not None and len(entry.events) > 0: - yield entry.events.pop(0) - for entry in self.resource_pools.seen: - while entry.events is not None and len(entry.events) > 0: - yield entry.events.pop(0) - for entry in self.resources.seen: - while entry.events is not None and len(entry.events) > 0: - yield entry.events.pop(0) - for entry in self.resource_types.seen: - while hasattr(entry, 'events') and len(entry.events) > 0: - yield entry.events.pop(0) - for entry in self.deployment_managers.seen: - while hasattr(entry, 'events') and len(entry.events) > 0: - yield entry.events.pop(0) - for entry in self.subscriptions.seen: - while hasattr(entry, 'events') and len(entry.events) > 0: - yield entry.events.pop(0) - for entry in self.configurations.seen: - while hasattr(entry, 'events') and len(entry.events) > 0: - yield entry.events.pop(0) - for entry in self.nfdeployment_descs.seen: - while hasattr(entry, 'events') and len(entry.events) > 0: - yield entry.events.pop(0) - for entry in self.nfdeployments.seen: - while hasattr(entry, 'events') and len(entry.events) > 0: - yield entry.events.pop(0) - for entry in self.ocloudvresources.seen: - while hasattr(entry, 'events') and len(entry.events) > 0: - yield entry.events.pop(0) +# Copyright (C) 2021 Wind River Systems, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# pylint: disable=attribute-defined-outside-init +from __future__ import annotations +from sqlalchemy import create_engine +from sqlalchemy.orm import sessionmaker +from sqlalchemy.orm.session import Session + +from o2common.config import config +from o2common.service.unit_of_work import AbstractUnitOfWork + +from o2ims.adapter import ocloud_repository +from o2dms.adapter import dms_repository + +from o2common.helper import o2logging +logger = o2logging.get_logger(__name__) + + +engine = create_engine( + config.get_postgres_uri(), + isolation_level="REPEATABLE READ", + pool_size=200, max_overflow=0, + pool_recycle=3600 +) + +DEFAULT_SESSION_FACTORY = sessionmaker( + autocommit=False, autoflush=False, bind=engine +) + + +class SqlAlchemyUnitOfWork(AbstractUnitOfWork): + + def __init__(self, session_factory=DEFAULT_SESSION_FACTORY): + self.session_factory = session_factory + + def __enter__(self): + self.session = self.session_factory() # type: Session + self.oclouds = ocloud_repository\ + .OcloudSqlAlchemyRepository(self.session) + self.resource_types = ocloud_repository\ + .ResouceTypeSqlAlchemyRepository(self.session) + self.resource_pools = ocloud_repository\ + .ResourcePoolSqlAlchemyRepository(self.session) + self.resources = ocloud_repository\ + .ResourceSqlAlchemyRepository(self.session) + self.subscriptions = ocloud_repository\ + .SubscriptionSqlAlchemyRepository(self.session) + self.configurations = ocloud_repository\ + .ConfigurationSqlAlchemyRepository(self.session) + self.deployment_managers = ocloud_repository\ + .DeploymentManagerSqlAlchemyRepository(self.session) + self.nfdeployment_descs = dms_repository\ + .NfDeploymentDescSqlAlchemyRepository(self.session) + self.nfdeployments = dms_repository\ + .NfDeploymentSqlAlchemyRepository(self.session) + self.ocloudvresources = dms_repository\ + .NfOCloudVResourceSqlAlchemyRepository(self.session) + return super().__enter__() + + def __exit__(self, *args): + super().__exit__(*args) + self.session.close() + + def _commit(self): + self.session.commit() + + def rollback(self): + self.session.rollback() + + def _collect_new_events(self): + for entry in self.oclouds.seen: + # while hasattr(entry, 'events') and len(entry.events) > 0: + while entry.events is not None and len(entry.events) > 0: + yield entry.events.pop(0) + for entry in self.resource_pools.seen: + while entry.events is not None and len(entry.events) > 0: + yield entry.events.pop(0) + for entry in self.resources.seen: + while entry.events is not None and len(entry.events) > 0: + yield entry.events.pop(0) + for entry in self.resource_types.seen: + while hasattr(entry, 'events') and len(entry.events) > 0: + yield entry.events.pop(0) + for entry in self.deployment_managers.seen: + while hasattr(entry, 'events') and len(entry.events) > 0: + yield entry.events.pop(0) + for entry in self.subscriptions.seen: + while hasattr(entry, 'events') and len(entry.events) > 0: + yield entry.events.pop(0) + for entry in self.configurations.seen: + while hasattr(entry, 'events') and len(entry.events) > 0: + yield entry.events.pop(0) + for entry in self.nfdeployment_descs.seen: + while hasattr(entry, 'events') and len(entry.events) > 0: + yield entry.events.pop(0) + for entry in self.nfdeployments.seen: + while hasattr(entry, 'events') and len(entry.events) > 0: + yield entry.events.pop(0) + for entry in self.ocloudvresources.seen: + while hasattr(entry, 'events') and len(entry.events) > 0: + yield entry.events.pop(0) diff --git a/o2app/entrypoints/__init__.py b/o2app/entrypoints/__init__.py index b514342..813897e 100644 --- a/o2app/entrypoints/__init__.py +++ b/o2app/entrypoints/__init__.py @@ -1,13 +1,13 @@ -# Copyright (C) 2021 Wind River Systems, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. +# Copyright (C) 2021 Wind River Systems, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. diff --git a/o2app/entrypoints/flask_application.py b/o2app/entrypoints/flask_application.py index cde0715..55385c2 100644 --- a/o2app/entrypoints/flask_application.py +++ b/o2app/entrypoints/flask_application.py @@ -1,33 +1,33 @@ -# Copyright (C) 2021 Wind River Systems, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from flask import Flask -from flask_restx import Api - -from o2app import bootstrap -from o2ims.views import configure_namespace as ims_route_configure_namespace -from o2dms.api import configure_namespace as dms_route_configure_namespace - - -# apibase = config.get_o2ims_api_base() -app = Flask(__name__) -app.config.SWAGGER_UI_DOC_EXPANSION = 'list' -api = Api(app, version='1.0.0', - title='INF O2 Services API', - description='Swagger OpenAPI document for the INF O2 Services', - ) -bus = bootstrap.bootstrap() - -ims_route_configure_namespace(api) -dms_route_configure_namespace(api) +# Copyright (C) 2021 Wind River Systems, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from flask import Flask +from flask_restx import Api + +from o2app import bootstrap +from o2ims.views import configure_namespace as ims_route_configure_namespace +from o2dms.api import configure_namespace as dms_route_configure_namespace + + +# apibase = config.get_o2ims_api_base() +app = Flask(__name__) +app.config.SWAGGER_UI_DOC_EXPANSION = 'list' +api = Api(app, version='1.0.0', + title='INF O2 Services API', + description='Swagger OpenAPI document for the INF O2 Services', + ) +bus = bootstrap.bootstrap() + +ims_route_configure_namespace(api) +dms_route_configure_namespace(api) diff --git a/o2app/entrypoints/resource_watcher.py b/o2app/entrypoints/resource_watcher.py index 38308eb..3f54758 100644 --- a/o2app/entrypoints/resource_watcher.py +++ b/o2app/entrypoints/resource_watcher.py @@ -1,103 +1,103 @@ -# Copyright (C) 2021 Wind River Systems, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -import cotyledon - -from o2app import bootstrap -from o2common.service.watcher.base import WatcherTree -from o2common.service.watcher.worker import PollWorker - -from o2ims.service.watcher.ocloud_watcher import OcloudWatcher -from o2ims.service.watcher.ocloud_watcher import DmsWatcher -from o2ims.service.watcher.resourcepool_watcher import ResourcePoolWatcher -from o2ims.adapter.clients.ocloud_sa_client import StxSaDmsClient -from o2ims.adapter.clients.ocloud_sa_client import StxSaOcloudClient -from o2ims.adapter.clients.ocloud_sa_client import StxSaResourcePoolClient - -from o2ims.service.watcher.pserver_watcher import PServerWatcher -from o2ims.adapter.clients.ocloud_sa_client import StxPserverClient - -from o2ims.service.watcher.pserver_cpu_watcher import PServerCpuWatcher -from o2ims.adapter.clients.ocloud_sa_client import StxCpuClient - -from o2ims.service.watcher.pserver_mem_watcher import PServerMemWatcher -from o2ims.adapter.clients.ocloud_sa_client import StxMemClient - -from o2ims.service.watcher.pserver_if_watcher import PServerIfWatcher -from o2ims.adapter.clients.ocloud_sa_client import StxIfClient - -from o2ims.service.watcher.pserver_port_watcher import PServerIfPortWatcher -from o2ims.adapter.clients.ocloud_sa_client import StxIfPortClient - -from o2ims.service.watcher.pserver_eth_watcher import PServerEthWatcher -from o2ims.adapter.clients.ocloud_sa_client import StxEthClient - -from o2common.helper import o2logging -logger = o2logging.get_logger(__name__) - -# r = redis.Redis(**config.get_redis_host_and_port()) - - -class WatcherService(cotyledon.Service): - def __init__(self, worker_id, args=None) -> None: - super().__init__(worker_id) - self.args = args - self.bus = bootstrap.bootstrap() - self.worker = PollWorker(bus=self.bus) - - def run(self): - try: - root = WatcherTree(OcloudWatcher( - StxSaOcloudClient(), self.bus)) - root.addchild( - DmsWatcher(StxSaDmsClient(), self.bus)) - - child_respool = root.addchild( - ResourcePoolWatcher(StxSaResourcePoolClient(), - self.bus)) - child_pserver = child_respool.addchild( - PServerWatcher(StxPserverClient(), self.bus)) - child_pserver.addchild( - PServerCpuWatcher(StxCpuClient(), self.bus)) - child_pserver.addchild( - PServerMemWatcher(StxMemClient(), self.bus)) - child_pserver.addchild( - PServerEthWatcher(StxEthClient(), self.bus)) - child_if = child_pserver.addchild( - PServerIfWatcher(StxIfClient(), self.bus)) - # child_if.addchild( - # PServerIfPortWatcher(StxIfPortClient(), self.bus)) - - self.worker.add_watcher(root) - - self.worker.start() - except Exception as ex: - logger.warning("WorkerService Exception:" + str(ex)) - finally: - self.worker.stop() - - -def start_watchers(sm: cotyledon.ServiceManager = None): - watchersm = sm if sm else cotyledon.ServiceManager() - watchersm.add(WatcherService, workers=1, args=()) - watchersm.run() - - -def main(): - logger.info("Resource watcher starting") - start_watchers() - - -if __name__ == "__main__": - main() +# Copyright (C) 2021 Wind River Systems, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import cotyledon + +from o2app import bootstrap +from o2common.service.watcher.base import WatcherTree +from o2common.service.watcher.worker import PollWorker + +from o2ims.service.watcher.ocloud_watcher import OcloudWatcher +from o2ims.service.watcher.ocloud_watcher import DmsWatcher +from o2ims.service.watcher.resourcepool_watcher import ResourcePoolWatcher +from o2ims.adapter.clients.ocloud_sa_client import StxSaDmsClient +from o2ims.adapter.clients.ocloud_sa_client import StxSaOcloudClient +from o2ims.adapter.clients.ocloud_sa_client import StxSaResourcePoolClient + +from o2ims.service.watcher.pserver_watcher import PServerWatcher +from o2ims.adapter.clients.ocloud_sa_client import StxPserverClient + +from o2ims.service.watcher.pserver_cpu_watcher import PServerCpuWatcher +from o2ims.adapter.clients.ocloud_sa_client import StxCpuClient + +from o2ims.service.watcher.pserver_mem_watcher import PServerMemWatcher +from o2ims.adapter.clients.ocloud_sa_client import StxMemClient + +from o2ims.service.watcher.pserver_if_watcher import PServerIfWatcher +from o2ims.adapter.clients.ocloud_sa_client import StxIfClient + +from o2ims.service.watcher.pserver_port_watcher import PServerIfPortWatcher +from o2ims.adapter.clients.ocloud_sa_client import StxIfPortClient + +from o2ims.service.watcher.pserver_eth_watcher import PServerEthWatcher +from o2ims.adapter.clients.ocloud_sa_client import StxEthClient + +from o2common.helper import o2logging +logger = o2logging.get_logger(__name__) + +# r = redis.Redis(**config.get_redis_host_and_port()) + + +class WatcherService(cotyledon.Service): + def __init__(self, worker_id, args=None) -> None: + super().__init__(worker_id) + self.args = args + self.bus = bootstrap.bootstrap() + self.worker = PollWorker(bus=self.bus) + + def run(self): + try: + root = WatcherTree(OcloudWatcher( + StxSaOcloudClient(), self.bus)) + root.addchild( + DmsWatcher(StxSaDmsClient(), self.bus)) + + child_respool = root.addchild( + ResourcePoolWatcher(StxSaResourcePoolClient(), + self.bus)) + child_pserver = child_respool.addchild( + PServerWatcher(StxPserverClient(), self.bus)) + child_pserver.addchild( + PServerCpuWatcher(StxCpuClient(), self.bus)) + child_pserver.addchild( + PServerMemWatcher(StxMemClient(), self.bus)) + child_pserver.addchild( + PServerEthWatcher(StxEthClient(), self.bus)) + child_if = child_pserver.addchild( + PServerIfWatcher(StxIfClient(), self.bus)) + # child_if.addchild( + # PServerIfPortWatcher(StxIfPortClient(), self.bus)) + + self.worker.add_watcher(root) + + self.worker.start() + except Exception as ex: + logger.warning("WorkerService Exception:" + str(ex)) + finally: + self.worker.stop() + + +def start_watchers(sm: cotyledon.ServiceManager = None): + watchersm = sm if sm else cotyledon.ServiceManager() + watchersm.add(WatcherService, workers=1, args=()) + watchersm.run() + + +def main(): + logger.info("Resource watcher starting") + start_watchers() + + +if __name__ == "__main__": + main() diff --git a/o2app/service/__init__.py b/o2app/service/__init__.py index b514342..813897e 100644 --- a/o2app/service/__init__.py +++ b/o2app/service/__init__.py @@ -1,13 +1,13 @@ -# Copyright (C) 2021 Wind River Systems, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. +# Copyright (C) 2021 Wind River Systems, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. diff --git a/o2common/__init__.py b/o2common/__init__.py index b514342..813897e 100644 --- a/o2common/__init__.py +++ b/o2common/__init__.py @@ -1,13 +1,13 @@ -# Copyright (C) 2021 Wind River Systems, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. +# Copyright (C) 2021 Wind River Systems, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. diff --git a/o2common/adapter/__init__.py b/o2common/adapter/__init__.py index b514342..813897e 100644 --- a/o2common/adapter/__init__.py +++ b/o2common/adapter/__init__.py @@ -1,13 +1,13 @@ -# Copyright (C) 2021 Wind River Systems, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. +# Copyright (C) 2021 Wind River Systems, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. diff --git a/o2common/config/__init__.py b/o2common/config/__init__.py index b514342..813897e 100644 --- a/o2common/config/__init__.py +++ b/o2common/config/__init__.py @@ -1,13 +1,13 @@ -# Copyright (C) 2021 Wind River Systems, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. +# Copyright (C) 2021 Wind River Systems, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. diff --git a/o2common/domain/__init__.py b/o2common/domain/__init__.py index b514342..813897e 100644 --- a/o2common/domain/__init__.py +++ b/o2common/domain/__init__.py @@ -1,13 +1,13 @@ -# Copyright (C) 2021 Wind River Systems, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. +# Copyright (C) 2021 Wind River Systems, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. diff --git a/o2common/domain/base.py b/o2common/domain/base.py index d7c94cd..e56672b 100644 --- a/o2common/domain/base.py +++ b/o2common/domain/base.py @@ -1,54 +1,54 @@ -# Copyright (C) 2021 Wind River Systems, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from datetime import datetime -from typing import List -from sqlalchemy.inspection import inspect -from sqlalchemy.exc import NoInspectionAvailable -# from sqlalchemy.orm.exc import DetachedInstanceError -from .events import Event - - -class AgRoot: - - events = [] - - def __init__(self) -> None: - self.hash = "" - self.updatetime = datetime.now() - self.createtime = datetime.now() - self.events = [] # type: List[Event] - # self.id = "" - - # def append_event(self, event: Event): - # self.events = self.events.append(event) - - -class Serializer(object): - - def serialize(self): - try: - # d = {c: getattr(self, c) for c in inspect(self).attrs.keys()} - # if 'createtime' in d: - # d['createtime'] = d['createtime'].isoformat() - # if 'updatetime' in d: - # d['updatetime'] = d['updatetime'].isoformat() - # return d - return {c: getattr(self, c) for c in inspect(self).attrs.keys()} - except NoInspectionAvailable: - return self.__dict__ - - @staticmethod - def serialize_list(li): - return [m.serialize() for m in li] +# Copyright (C) 2021 Wind River Systems, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from datetime import datetime +from typing import List +from sqlalchemy.inspection import inspect +from sqlalchemy.exc import NoInspectionAvailable +# from sqlalchemy.orm.exc import DetachedInstanceError +from .events import Event + + +class AgRoot: + + events = [] + + def __init__(self) -> None: + self.hash = "" + self.updatetime = datetime.now() + self.createtime = datetime.now() + self.events = [] # type: List[Event] + # self.id = "" + + # def append_event(self, event: Event): + # self.events = self.events.append(event) + + +class Serializer(object): + + def serialize(self): + try: + # d = {c: getattr(self, c) for c in inspect(self).attrs.keys()} + # if 'createtime' in d: + # d['createtime'] = d['createtime'].isoformat() + # if 'updatetime' in d: + # d['updatetime'] = d['updatetime'].isoformat() + # return d + return {c: getattr(self, c) for c in inspect(self).attrs.keys()} + except NoInspectionAvailable: + return self.__dict__ + + @staticmethod + def serialize_list(li): + return [m.serialize() for m in li] diff --git a/o2common/domain/exceptions.py b/o2common/domain/exceptions.py index dac86f3..c6e4a10 100644 --- a/o2common/domain/exceptions.py +++ b/o2common/domain/exceptions.py @@ -1,18 +1,18 @@ -# Copyright (C) 2022 Wind River Systems, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# pylint: disable=too-few-public-methods - -class Orano2Exception(Exception): - pass +# Copyright (C) 2022 Wind River Systems, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# pylint: disable=too-few-public-methods + +class Orano2Exception(Exception): + pass diff --git a/o2common/helper/__init__.py b/o2common/helper/__init__.py index b514342..813897e 100644 --- a/o2common/helper/__init__.py +++ b/o2common/helper/__init__.py @@ -1,13 +1,13 @@ -# Copyright (C) 2021 Wind River Systems, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. +# Copyright (C) 2021 Wind River Systems, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. diff --git a/o2common/helper/o2logging.py b/o2common/helper/o2logging.py index 5290f70..31584f5 100644 --- a/o2common/helper/o2logging.py +++ b/o2common/helper/o2logging.py @@ -1,36 +1,36 @@ -# Copyright (C) 2021 Wind River Systems, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -import logging -import logging.config -import logging.handlers -import os -import yaml - - -def get_logger(name=None): - CONFIG_FILE = os.environ.get( - "LOGGING_CONFIG_FILE", "/etc/o2/log.yaml") - if os.path.exists(CONFIG_FILE): - with open(file=CONFIG_FILE, mode='r', encoding="utf-8") as file: - config_yaml = yaml.load(stream=file, Loader=yaml.FullLoader) - logging.config.dictConfig(config=config_yaml) - - logger = logging.getLogger(name) - - # override logging level - LOGGING_CONFIG_LEVEL = os.environ.get("LOGGING_CONFIG_LEVEL", None) - if LOGGING_CONFIG_LEVEL: - logger.setLevel(LOGGING_CONFIG_LEVEL) - return logger +# Copyright (C) 2021 Wind River Systems, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import logging +import logging.config +import logging.handlers +import os +import yaml + + +def get_logger(name=None): + CONFIG_FILE = os.environ.get( + "LOGGING_CONFIG_FILE", "/etc/o2/log.yaml") + if os.path.exists(CONFIG_FILE): + with open(file=CONFIG_FILE, mode='r', encoding="utf-8") as file: + config_yaml = yaml.load(stream=file, Loader=yaml.FullLoader) + logging.config.dictConfig(config=config_yaml) + + logger = logging.getLogger(name) + + # override logging level + LOGGING_CONFIG_LEVEL = os.environ.get("LOGGING_CONFIG_LEVEL", None) + if LOGGING_CONFIG_LEVEL: + logger.setLevel(LOGGING_CONFIG_LEVEL) + return logger diff --git a/o2common/service/__init__.py b/o2common/service/__init__.py index b514342..813897e 100644 --- a/o2common/service/__init__.py +++ b/o2common/service/__init__.py @@ -1,13 +1,13 @@ -# Copyright (C) 2021 Wind River Systems, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. +# Copyright (C) 2021 Wind River Systems, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. diff --git a/o2common/service/client/__init__.py b/o2common/service/client/__init__.py index b514342..813897e 100644 --- a/o2common/service/client/__init__.py +++ b/o2common/service/client/__init__.py @@ -1,13 +1,13 @@ -# Copyright (C) 2021 Wind River Systems, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. +# Copyright (C) 2021 Wind River Systems, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. diff --git a/o2common/service/client/base_client.py b/o2common/service/client/base_client.py index d346e1c..96ff988 100644 --- a/o2common/service/client/base_client.py +++ b/o2common/service/client/base_client.py @@ -1,36 +1,36 @@ -# Copyright (C) 2021 Wind River Systems, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -import abc -# from typing import Optional, List, Set -# from typing import List - - -class BaseClient(abc.ABC): - def __init__(self): - pass - - def list(self, **filters): - return self._list(**filters) - - def get(self, id): - return self._get(id) - - @abc.abstractmethod - def _get(self, id): - raise NotImplementedError - - @abc.abstractmethod - def _list(self, **filters): - raise NotImplementedError +# Copyright (C) 2021 Wind River Systems, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import abc +# from typing import Optional, List, Set +# from typing import List + + +class BaseClient(abc.ABC): + def __init__(self): + pass + + def list(self, **filters): + return self._list(**filters) + + def get(self, id): + return self._get(id) + + @abc.abstractmethod + def _get(self, id): + raise NotImplementedError + + @abc.abstractmethod + def _list(self, **filters): + raise NotImplementedError diff --git a/o2common/service/watcher/__init__.py b/o2common/service/watcher/__init__.py index b514342..813897e 100644 --- a/o2common/service/watcher/__init__.py +++ b/o2common/service/watcher/__init__.py @@ -1,13 +1,13 @@ -# Copyright (C) 2021 Wind River Systems, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. +# Copyright (C) 2021 Wind River Systems, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. diff --git a/o2common/service/watcher/base.py b/o2common/service/watcher/base.py index 6e1eb9e..0807eec 100644 --- a/o2common/service/watcher/base.py +++ b/o2common/service/watcher/base.py @@ -1,96 +1,96 @@ -# Copyright (C) 2021 Wind River Systems, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# from logging import exception -# from cgtsclient import exc -from o2common.service.client.base_client import BaseClient -from o2common.domain import commands -from o2common.service.messagebus import MessageBus -from o2common.helper import o2logging -logger = o2logging.get_logger(__name__) - - -class BaseWatcher(object): - def __init__(self, client: BaseClient, - bus: MessageBus) -> None: - super().__init__() - self._client = client - self._bus = bus - # self._uow = bus.uow - - def targetname(self) -> str: - return self._targetname() - - def probe(self, parent: commands.Command = None): - try: - cmds = self._probe(parent.data if parent else None) - for cmd in cmds: - self._bus.handle(cmd) - - # return self._probe(parent) - return cmds - except Exception as ex: - logger.warning("Failed to probe resource due to: " + str(ex)) - return [] - - def _probe(self, parent: object = None) -> commands.Command: - raise NotImplementedError - - def _targetname(self): - raise NotImplementedError - - # def _compare_and_update(self, newmodel: StxGenericModel) -> bool: - # with self._uow: - # # localmodel = self._uow.stxobjects.get(ocloudmodel.id) - # localmodel = self._uow.stxobjects.get(str(newmodel.id)) - # if not localmodel: - # logger.info("add entry:" + newmodel.name) - # self._uow.stxobjects.add(newmodel) - # elif localmodel.is_outdated(newmodel): - # logger.info("update entry:" + newmodel.name) - # localmodel.update_by(newmodel) - # self._uow.stxobjects.update(localmodel) - # self._uow.commit() - - -# node to organize watchers in tree hierachy -class WatcherTree(object): - def __init__(self, watcher: BaseWatcher) -> None: - super().__init__() - self.watcher = watcher - self.children = {} - - def addchild(self, watcher: BaseWatcher) -> object: - child = WatcherTree(watcher) - self.children[watcher.targetname()] = child - return child - - def removechild(self, targetname: str) -> object: - return self.children.pop(targetname) - - # probe all resources by parent, depth = 0 for indefinite recursive - def probe(self, parentresource=None, depth: int = 0): - logger.debug("probe resources with watcher: " - + self.watcher.targetname()) - childdepth = depth - 1 if depth > 0 else 0 - resources = self.watcher.probe(parentresource) - logger.debug("probe returns " + str(len(resources)) + " resources") - - if depth == 1: - # stop recursive - return - - for res in resources: - for targetname in self.children.keys(): - self.children[targetname].probe(res, childdepth) +# Copyright (C) 2021 Wind River Systems, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# from logging import exception +# from cgtsclient import exc +from o2common.service.client.base_client import BaseClient +from o2common.domain import commands +from o2common.service.messagebus import MessageBus +from o2common.helper import o2logging +logger = o2logging.get_logger(__name__) + + +class BaseWatcher(object): + def __init__(self, client: BaseClient, + bus: MessageBus) -> None: + super().__init__() + self._client = client + self._bus = bus + # self._uow = bus.uow + + def targetname(self) -> str: + return self._targetname() + + def probe(self, parent: commands.Command = None): + try: + cmds = self._probe(parent.data if parent else None) + for cmd in cmds: + self._bus.handle(cmd) + + # return self._probe(parent) + return cmds + except Exception as ex: + logger.warning("Failed to probe resource due to: " + str(ex)) + return [] + + def _probe(self, parent: object = None) -> commands.Command: + raise NotImplementedError + + def _targetname(self): + raise NotImplementedError + + # def _compare_and_update(self, newmodel: StxGenericModel) -> bool: + # with self._uow: + # # localmodel = self._uow.stxobjects.get(ocloudmodel.id) + # localmodel = self._uow.stxobjects.get(str(newmodel.id)) + # if not localmodel: + # logger.info("add entry:" + newmodel.name) + # self._uow.stxobjects.add(newmodel) + # elif localmodel.is_outdated(newmodel): + # logger.info("update entry:" + newmodel.name) + # localmodel.update_by(newmodel) + # self._uow.stxobjects.update(localmodel) + # self._uow.commit() + + +# node to organize watchers in tree hierachy +class WatcherTree(object): + def __init__(self, watcher: BaseWatcher) -> None: + super().__init__() + self.watcher = watcher + self.children = {} + + def addchild(self, watcher: BaseWatcher) -> object: + child = WatcherTree(watcher) + self.children[watcher.targetname()] = child + return child + + def removechild(self, targetname: str) -> object: + return self.children.pop(targetname) + + # probe all resources by parent, depth = 0 for indefinite recursive + def probe(self, parentresource=None, depth: int = 0): + logger.debug("probe resources with watcher: " + + self.watcher.targetname()) + childdepth = depth - 1 if depth > 0 else 0 + resources = self.watcher.probe(parentresource) + logger.debug("probe returns " + str(len(resources)) + " resources") + + if depth == 1: + # stop recursive + return + + for res in resources: + for targetname in self.children.keys(): + self.children[targetname].probe(res, childdepth) diff --git a/o2common/service/watcher/worker.py b/o2common/service/watcher/worker.py index dbc67b7..3eef230 100644 --- a/o2common/service/watcher/worker.py +++ b/o2common/service/watcher/worker.py @@ -1,70 +1,70 @@ -# Copyright (C) 2021 Wind River Systems, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -import time -import sched -# from o2common.service.unit_of_work import AbstractUnitOfWork -from o2common.service.watcher.base import WatcherTree - -from o2common.helper import o2logging -logger = o2logging.get_logger(__name__) - - -class PollWorker(object): - def __init__(self, interval=10, bus=None) -> None: - super().__init__() - self.watchers = [] - self.schedinstance = sched.scheduler(time.time, time.sleep) - self.schedinterval = interval - self._stopped = True - self._bus = bus - - def set_interval(self, interval): - if interval > 0: - self.schedinterval = interval - else: - raise Exception("Invalid interval:" + interval) - - def add_watcher(self, watcher: WatcherTree): - self.watchers.append(watcher) - - def _repeat(self): - logger.debug("_repeat started") - if self._stopped: - return - for w in self.watchers: - try: - # logger.debug("about to probe:"+w) - w.probe(None) - except Exception as ex: - logger.warning("Worker raises exception:" + str(ex)) - continue - - # handle events - if self._bus is not None: - events = self._bus.uow.collect_new_events() - for event in events: - self._bus.handle(event) - - self.schedinstance.enter(self.schedinterval, 1, self._repeat) - - # note the sched run will block current thread - def start(self): - self._stopped = False - logger.debug('about to start sched task') - self.schedinstance.enter(self.schedinterval, 1, self._repeat) - self.schedinstance.run() - - def stop(self): - self._stopped = True +# Copyright (C) 2021 Wind River Systems, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import time +import sched +# from o2common.service.unit_of_work import AbstractUnitOfWork +from o2common.service.watcher.base import WatcherTree + +from o2common.helper import o2logging +logger = o2logging.get_logger(__name__) + + +class PollWorker(object): + def __init__(self, interval=10, bus=None) -> None: + super().__init__() + self.watchers = [] + self.schedinstance = sched.scheduler(time.time, time.sleep) + self.schedinterval = interval + self._stopped = True + self._bus = bus + + def set_interval(self, interval): + if interval > 0: + self.schedinterval = interval + else: + raise Exception("Invalid interval:" + interval) + + def add_watcher(self, watcher: WatcherTree): + self.watchers.append(watcher) + + def _repeat(self): + logger.debug("_repeat started") + if self._stopped: + return + for w in self.watchers: + try: + # logger.debug("about to probe:"+w) + w.probe(None) + except Exception as ex: + logger.warning("Worker raises exception:" + str(ex)) + continue + + # handle events + if self._bus is not None: + events = self._bus.uow.collect_new_events() + for event in events: + self._bus.handle(event) + + self.schedinstance.enter(self.schedinterval, 1, self._repeat) + + # note the sched run will block current thread + def start(self): + self._stopped = False + logger.debug('about to start sched task') + self.schedinstance.enter(self.schedinterval, 1, self._repeat) + self.schedinstance.run() + + def stop(self): + self._stopped = True diff --git a/o2dms/__init__.py b/o2dms/__init__.py index b514342..813897e 100644 --- a/o2dms/__init__.py +++ b/o2dms/__init__.py @@ -1,13 +1,13 @@ -# Copyright (C) 2021 Wind River Systems, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. +# Copyright (C) 2021 Wind River Systems, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. diff --git a/o2dms/adapter/__init__.py b/o2dms/adapter/__init__.py index b514342..813897e 100644 --- a/o2dms/adapter/__init__.py +++ b/o2dms/adapter/__init__.py @@ -1,13 +1,13 @@ -# Copyright (C) 2021 Wind River Systems, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. +# Copyright (C) 2021 Wind River Systems, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. diff --git a/o2dms/adapter/orm.py b/o2dms/adapter/orm.py index 3c1709c..a5b02d0 100644 --- a/o2dms/adapter/orm.py +++ b/o2dms/adapter/orm.py @@ -1,110 +1,110 @@ -# Copyright (C) 2021 Wind River Systems, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from retry import retry -from sqlalchemy import ( - Table, - MetaData, - Column, - Integer, - String, - Text, - # Date, - DateTime, - # ForeignKey, - # engine, - # event, - exc -) - -from sqlalchemy.orm import mapper -from o2dms.domain import dms as dmsModel - -from o2common.helper import o2logging -logger = o2logging.get_logger(__name__) - -metadata = MetaData() - -nfDeploymentDesc = Table( - "nfDeploymentDesc", - metadata, - Column("updatetime", DateTime), - Column("createtime", DateTime), - Column("hash", String(255)), - Column("version_number", Integer), - - Column("id", String(255), primary_key=True), - Column("deploymentManagerId", String(255)), - Column("name", String(255)), - Column("description", String(255)), - Column("inputParams", Text()), - Column("outputParams", String(255)), - Column("artifactRepoUrl", String(255)), - Column("artifactName", String(255)), - # Column("extensions", String(1024)) -) - -nfDeployment = Table( - "nfDeployment", - metadata, - Column("updatetime", DateTime), - Column("createtime", DateTime), - Column("hash", String(255)), - Column("version_number", Integer), - - Column("id", String(255), primary_key=True), - Column("deploymentManagerId", String(255)), - Column("name", String(255)), - Column("description", String(255)), - Column("descriptorId", String(255)), - Column("parentDeploymentId", String(255)), - Column("status", Integer) -) - -nfOCloudVResource = Table( - "nfOcloudVRes", - metadata, - Column("updatetime", DateTime), - Column("createtime", DateTime), - Column("hash", String(255)), - Column("version_number", Integer), - - Column("id", String(255), primary_key=True), - Column("deploymentManagerId", String(255)), - Column("name", String(255)), - Column("description", String(255)), - Column("descriptorId", String(255)), - Column("vresourceType", String(255)), - Column("status", Integer), - Column("metadata", String(2048)), - Column("nfDeploymentId", String(255)) -) - - -@retry((exc.IntegrityError), tries=3, delay=2) -def wait_for_metadata_ready(engine): - # wait for mapper ready - metadata.create_all(engine, checkfirst=True) - logger.info("metadata is ready") - - -def start_o2dms_mappers(engine=None): - logger.info("Starting O2 DMS mappers") - - mapper(dmsModel.NfDeploymentDesc, nfDeploymentDesc) - mapper(dmsModel.NfDeployment, nfDeployment) - mapper(dmsModel.NfOCloudVResource, nfOCloudVResource) - - if engine is not None: - wait_for_metadata_ready(engine) +# Copyright (C) 2021 Wind River Systems, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from retry import retry +from sqlalchemy import ( + Table, + MetaData, + Column, + Integer, + String, + Text, + # Date, + DateTime, + # ForeignKey, + # engine, + # event, + exc +) + +from sqlalchemy.orm import mapper +from o2dms.domain import dms as dmsModel + +from o2common.helper import o2logging +logger = o2logging.get_logger(__name__) + +metadata = MetaData() + +nfDeploymentDesc = Table( + "nfDeploymentDesc", + metadata, + Column("updatetime", DateTime), + Column("createtime", DateTime), + Column("hash", String(255)), + Column("version_number", Integer), + + Column("id", String(255), primary_key=True), + Column("deploymentManagerId", String(255)), + Column("name", String(255)), + Column("description", String(255)), + Column("inputParams", Text()), + Column("outputParams", String(255)), + Column("artifactRepoUrl", String(255)), + Column("artifactName", String(255)), + # Column("extensions", String(1024)) +) + +nfDeployment = Table( + "nfDeployment", + metadata, + Column("updatetime", DateTime), + Column("createtime", DateTime), + Column("hash", String(255)), + Column("version_number", Integer), + + Column("id", String(255), primary_key=True), + Column("deploymentManagerId", String(255)), + Column("name", String(255)), + Column("description", String(255)), + Column("descriptorId", String(255)), + Column("parentDeploymentId", String(255)), + Column("status", Integer) +) + +nfOCloudVResource = Table( + "nfOcloudVRes", + metadata, + Column("updatetime", DateTime), + Column("createtime", DateTime), + Column("hash", String(255)), + Column("version_number", Integer), + + Column("id", String(255), primary_key=True), + Column("deploymentManagerId", String(255)), + Column("name", String(255)), + Column("description", String(255)), + Column("descriptorId", String(255)), + Column("vresourceType", String(255)), + Column("status", Integer), + Column("metadata", String(2048)), + Column("nfDeploymentId", String(255)) +) + + +@retry((exc.IntegrityError), tries=3, delay=2) +def wait_for_metadata_ready(engine): + # wait for mapper ready + metadata.create_all(engine, checkfirst=True) + logger.info("metadata is ready") + + +def start_o2dms_mappers(engine=None): + logger.info("Starting O2 DMS mappers") + + mapper(dmsModel.NfDeploymentDesc, nfDeploymentDesc) + mapper(dmsModel.NfDeployment, nfDeployment) + mapper(dmsModel.NfOCloudVResource, nfOCloudVResource) + + if engine is not None: + wait_for_metadata_ready(engine) diff --git a/o2dms/api/__init__.py b/o2dms/api/__init__.py index 10d5562..83b7d44 100644 --- a/o2dms/api/__init__.py +++ b/o2dms/api/__init__.py @@ -1,33 +1,33 @@ -# Copyright (C) 2021 Wind River Systems, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from o2dms.api.dms_api_ns import api_dms_lcm_v1 -from . import dms_route -from . import nfdeployment_desc_route -from . import nfdeployment_route -from o2common.config import config - -from o2common.helper import o2logging -logger = o2logging.get_logger(__name__) - - -def configure_namespace(app): - apibase = config.get_o2dms_api_base() - logger.info( - "Expose O2DMS API:{}".format(apibase)) - - dms_route.configure_api_route() - nfdeployment_desc_route.configure_api_route() - nfdeployment_route.configure_api_route() - app.add_namespace(api_dms_lcm_v1, path=apibase) +# Copyright (C) 2021 Wind River Systems, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from o2dms.api.dms_api_ns import api_dms_lcm_v1 +from . import dms_route +from . import nfdeployment_desc_route +from . import nfdeployment_route +from o2common.config import config + +from o2common.helper import o2logging +logger = o2logging.get_logger(__name__) + + +def configure_namespace(app): + apibase = config.get_o2dms_api_base() + logger.info( + "Expose O2DMS API:{}".format(apibase)) + + dms_route.configure_api_route() + nfdeployment_desc_route.configure_api_route() + nfdeployment_route.configure_api_route() + app.add_namespace(api_dms_lcm_v1, path=apibase) diff --git a/o2dms/api/dms_api_ns.py b/o2dms/api/dms_api_ns.py index 4c8235f..f8e6159 100644 --- a/o2dms/api/dms_api_ns.py +++ b/o2dms/api/dms_api_ns.py @@ -1,5 +1,5 @@ -from flask_restx import Namespace - - -api_dms_lcm_v1 = Namespace( - "O2DMS_LCM", description='DMS LCM related operations.') +from flask_restx import Namespace + + +api_dms_lcm_v1 = Namespace( + "O2DMS_LCM", description='DMS LCM related operations.') diff --git a/o2dms/api/dms_lcm_nfdeployment.py b/o2dms/api/dms_lcm_nfdeployment.py index ef6cb8c..3b117da 100644 --- a/o2dms/api/dms_lcm_nfdeployment.py +++ b/o2dms/api/dms_lcm_nfdeployment.py @@ -1,162 +1,162 @@ -# Copyright (C) 2021 Wind River Systems, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from sqlalchemy import select -import uuid -from o2dms.domain.states import NfDeploymentState -from o2common.service import messagebus -from o2common.service import unit_of_work -from o2dms.adapter.orm import nfDeployment -from o2dms.api.dms_dto import DmsLcmNfDeploymentDTO -from o2dms.domain.dms import NfDeployment -from o2common.helper import o2logging -logger = o2logging.get_logger(__name__) - - -def lcm_nfdeployment_list( - deploymentManagerID: str, uow: unit_of_work.AbstractUnitOfWork): - with uow: - res = uow.session.execute(select(nfDeployment).where( - nfDeployment.c.deploymentManagerId == deploymentManagerID)) - return [dict(r) for r in res] - - -def lcm_nfdeployment_one( - nfdeploymentid: str, uow: unit_of_work.AbstractUnitOfWork): - with uow: - res = uow.session.execute(select(nfDeployment).where( - nfDeployment.c.id == nfdeploymentid)) - first = res.first() - return None if first is None else dict(first) - - -def lcm_nfdeployment_create( - deploymentManagerId: str, - input: DmsLcmNfDeploymentDTO. - NfDeployment_create, - bus: messagebus.MessageBus): - - uow = bus.uow - id = str(uuid.uuid4()) - with uow: - _check_duplication(input, uow) - _check_dependencies(input, uow) - entity = NfDeployment( - id, input['name'], deploymentManagerId, input['description'], - input['descriptorId'], input['parentDeploymentId']) - uow.nfdeployments.add(entity) - # entity.transit_state(NfDeploymentState.NotInstalled) - - # to be refactor later according to O2 DMS API design - entity.transit_state(NfDeploymentState.Installing) - uow.commit() - _handle_events(bus) - - return id - - -def lcm_nfdeployment_update( - nfdeploymentid: str, - input: DmsLcmNfDeploymentDTO.NfDeployment_update, - bus: messagebus.MessageBus): - - uow = bus.uow - with uow: - entity: NfDeployment = uow.nfdeployments.get(nfdeploymentid) - entity.name = input['name'] - entity.description = input['description'] - entity.outputParams = input['parentDeploymentId'] - entity.transit_state(NfDeploymentState.Updating) - uow.commit() - _handle_events(bus) - return True - - -def _handle_events(bus: messagebus.MessageBus): - # handle events - events = bus.uow.collect_new_events() - for event in events: - bus.handle(event) - return True - - -def lcm_nfdeployment_uninstall( - nfdeploymentid: str, - bus: messagebus.MessageBus): - - uow = bus.uow - with uow: - entity: NfDeployment = uow.nfdeployments.get(nfdeploymentid) - if not entity: - pass - elif entity.status == NfDeploymentState.Initial: - bus.uow.nfdeployments.delete(nfdeploymentid) - # elif entity.status == NfDeploymentState.NotInstalled: - # bus.uow.nfdeployments.delete(nfdeploymentid) - elif entity.status == NfDeploymentState.Installing: - entity.transit_state(NfDeploymentState.Uninstalling) - elif entity.status == NfDeploymentState.Installed: - entity.transit_state(NfDeploymentState.Uninstalling) - elif entity.status == NfDeploymentState.Updating: - entity.transit_state(NfDeploymentState.Uninstalling) - elif entity.status == NfDeploymentState.Uninstalling: - pass - elif entity.status == NfDeploymentState.Abnormal: - bus.uow.nfdeployments.delete(nfdeploymentid) - else: - entity.transit_state(NfDeploymentState.Abnormal) - uow.commit() - _handle_events(bus) - return True - - -# def lcm_nfdeployment_delete( -# nfdeploymentid: str, -# bus: messagebus.MessageBus): - -# uow = bus.uow -# with uow: -# entity = uow.nfdeployments.get(nfdeploymentid) -# if entity.status != NfDeploymentState.Initial: -# raise Exception( -# "NfDeployment {} is not in status to delete".format( -# nfdeploymentid)) -# uow.nfdeployments.delete(nfdeploymentid) -# entity.transit_state(NfDeploymentState.Deleting) -# uow.commit() -# return True - - -def _check_duplication( - input: DmsLcmNfDeploymentDTO, - uow: unit_of_work.AbstractUnitOfWork): - name = input['name'] - descriptorId = input['descriptorId'] - if uow.nfdeployments.count(name=name) > 0: - raise Exception( - "NfDeployment with name {} exists already".format(name)) - if uow.nfdeployments.count(descriptorId=descriptorId) > 0: - raise Exception( - "NfDeployment with descriptorId {} exists already".format( - descriptorId)) - - -def _check_dependencies( - input: DmsLcmNfDeploymentDTO, - uow: unit_of_work.AbstractUnitOfWork): - descriptorId = input['descriptorId'] - if uow.nfdeployment_descs.count(id=descriptorId) == 0: - raise Exception( - "NfDeploymentDescriptor with id {} does not exist".format( - descriptorId)) +# Copyright (C) 2021 Wind River Systems, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from sqlalchemy import select +import uuid +from o2dms.domain.states import NfDeploymentState +from o2common.service import messagebus +from o2common.service import unit_of_work +from o2dms.adapter.orm import nfDeployment +from o2dms.api.dms_dto import DmsLcmNfDeploymentDTO +from o2dms.domain.dms import NfDeployment +from o2common.helper import o2logging +logger = o2logging.get_logger(__name__) + + +def lcm_nfdeployment_list( + deploymentManagerID: str, uow: unit_of_work.AbstractUnitOfWork): + with uow: + res = uow.session.execute(select(nfDeployment).where( + nfDeployment.c.deploymentManagerId == deploymentManagerID)) + return [dict(r) for r in res] + + +def lcm_nfdeployment_one( + nfdeploymentid: str, uow: unit_of_work.AbstractUnitOfWork): + with uow: + res = uow.session.execute(select(nfDeployment).where( + nfDeployment.c.id == nfdeploymentid)) + first = res.first() + return None if first is None else dict(first) + + +def lcm_nfdeployment_create( + deploymentManagerId: str, + input: DmsLcmNfDeploymentDTO. + NfDeployment_create, + bus: messagebus.MessageBus): + + uow = bus.uow + id = str(uuid.uuid4()) + with uow: + _check_duplication(input, uow) + _check_dependencies(input, uow) + entity = NfDeployment( + id, input['name'], deploymentManagerId, input['description'], + input['descriptorId'], input['parentDeploymentId']) + uow.nfdeployments.add(entity) + # entity.transit_state(NfDeploymentState.NotInstalled) + + # to be refactor later according to O2 DMS API design + entity.transit_state(NfDeploymentState.Installing) + uow.commit() + _handle_events(bus) + + return id + + +def lcm_nfdeployment_update( + nfdeploymentid: str, + input: DmsLcmNfDeploymentDTO.NfDeployment_update, + bus: messagebus.MessageBus): + + uow = bus.uow + with uow: + entity: NfDeployment = uow.nfdeployments.get(nfdeploymentid) + entity.name = input['name'] + entity.description = input['description'] + entity.outputParams = input['parentDeploymentId'] + entity.transit_state(NfDeploymentState.Updating) + uow.commit() + _handle_events(bus) + return True + + +def _handle_events(bus: messagebus.MessageBus): + # handle events + events = bus.uow.collect_new_events() + for event in events: + bus.handle(event) + return True + + +def lcm_nfdeployment_uninstall( + nfdeploymentid: str, + bus: messagebus.MessageBus): + + uow = bus.uow + with uow: + entity: NfDeployment = uow.nfdeployments.get(nfdeploymentid) + if not entity: + pass + elif entity.status == NfDeploymentState.Initial: + bus.uow.nfdeployments.delete(nfdeploymentid) + # elif entity.status == NfDeploymentState.NotInstalled: + # bus.uow.nfdeployments.delete(nfdeploymentid) + elif entity.status == NfDeploymentState.Installing: + entity.transit_state(NfDeploymentState.Uninstalling) + elif entity.status == NfDeploymentState.Installed: + entity.transit_state(NfDeploymentState.Uninstalling) + elif entity.status == NfDeploymentState.Updating: + entity.transit_state(NfDeploymentState.Uninstalling) + elif entity.status == NfDeploymentState.Uninstalling: + pass + elif entity.status == NfDeploymentState.Abnormal: + bus.uow.nfdeployments.delete(nfdeploymentid) + else: + entity.transit_state(NfDeploymentState.Abnormal) + uow.commit() + _handle_events(bus) + return True + + +# def lcm_nfdeployment_delete( +# nfdeploymentid: str, +# bus: messagebus.MessageBus): + +# uow = bus.uow +# with uow: +# entity = uow.nfdeployments.get(nfdeploymentid) +# if entity.status != NfDeploymentState.Initial: +# raise Exception( +# "NfDeployment {} is not in status to delete".format( +# nfdeploymentid)) +# uow.nfdeployments.delete(nfdeploymentid) +# entity.transit_state(NfDeploymentState.Deleting) +# uow.commit() +# return True + + +def _check_duplication( + input: DmsLcmNfDeploymentDTO, + uow: unit_of_work.AbstractUnitOfWork): + name = input['name'] + descriptorId = input['descriptorId'] + if uow.nfdeployments.count(name=name) > 0: + raise Exception( + "NfDeployment with name {} exists already".format(name)) + if uow.nfdeployments.count(descriptorId=descriptorId) > 0: + raise Exception( + "NfDeployment with descriptorId {} exists already".format( + descriptorId)) + + +def _check_dependencies( + input: DmsLcmNfDeploymentDTO, + uow: unit_of_work.AbstractUnitOfWork): + descriptorId = input['descriptorId'] + if uow.nfdeployment_descs.count(id=descriptorId) == 0: + raise Exception( + "NfDeploymentDescriptor with id {} does not exist".format( + descriptorId)) diff --git a/o2dms/api/dms_lcm_nfdeployment_vres.py b/o2dms/api/dms_lcm_nfdeployment_vres.py index edd989a..5bdf0f4 100644 --- a/o2dms/api/dms_lcm_nfdeployment_vres.py +++ b/o2dms/api/dms_lcm_nfdeployment_vres.py @@ -1,36 +1,36 @@ -# Copyright (C) 2021 Wind River Systems, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from sqlalchemy import select -from o2common.service import unit_of_work -from o2dms.adapter.orm import nfOCloudVResource -from o2common.helper import o2logging -logger = o2logging.get_logger(__name__) - - -def lcm_nfocloudvresource_list( - nfDeploymentId: str, uow: unit_of_work.AbstractUnitOfWork): - with uow: - res = uow.session.execute(select(nfOCloudVResource).where( - nfOCloudVResource.c.nfDeploymentId == nfDeploymentId)) - return [dict(r) for r in res] - - -def lcm_nfocloudvresource_one( - ocloudvresourceId: str, uow: unit_of_work.AbstractUnitOfWork): - with uow: - res = uow.session.execute(select(nfOCloudVResource).where( - nfOCloudVResource.c.id == ocloudvresourceId)) - first = res.first() - return None if first is None else dict(first) +# Copyright (C) 2021 Wind River Systems, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from sqlalchemy import select +from o2common.service import unit_of_work +from o2dms.adapter.orm import nfOCloudVResource +from o2common.helper import o2logging +logger = o2logging.get_logger(__name__) + + +def lcm_nfocloudvresource_list( + nfDeploymentId: str, uow: unit_of_work.AbstractUnitOfWork): + with uow: + res = uow.session.execute(select(nfOCloudVResource).where( + nfOCloudVResource.c.nfDeploymentId == nfDeploymentId)) + return [dict(r) for r in res] + + +def lcm_nfocloudvresource_one( + ocloudvresourceId: str, uow: unit_of_work.AbstractUnitOfWork): + with uow: + res = uow.session.execute(select(nfOCloudVResource).where( + nfOCloudVResource.c.id == ocloudvresourceId)) + first = res.first() + return None if first is None else dict(first) diff --git a/o2dms/api/dms_lcm_nfdeploymentdesc.py b/o2dms/api/dms_lcm_nfdeploymentdesc.py index 8024574..20aa41b 100644 --- a/o2dms/api/dms_lcm_nfdeploymentdesc.py +++ b/o2dms/api/dms_lcm_nfdeploymentdesc.py @@ -1,124 +1,124 @@ -# Copyright (C) 2021 Wind River Systems, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -import json -from sqlalchemy import select -import uuid -from o2common.service import unit_of_work -from o2dms.adapter.orm import nfDeploymentDesc -from o2dms.api.dms_dto import DmsLcmNfDeploymentDescriptorDTO -from o2dms.domain.dms import NfDeploymentDesc -from o2common.helper import o2logging -logger = o2logging.get_logger(__name__) - - -def lcm_nfdeploymentdesc_list(deploymentManagerID: str, - uow: unit_of_work.AbstractUnitOfWork): - with uow: - res = uow.session.execute(select(nfDeploymentDesc).where( - nfDeploymentDesc.c.deploymentManagerId == deploymentManagerID)) - return [dict(r) for r in res] - - -def lcm_nfdeploymentdesc_one(nfdeploymentdescriptorid: str, - uow: unit_of_work.AbstractUnitOfWork): - with uow: - res = uow.session.execute(select(nfDeploymentDesc).where( - nfDeploymentDesc.c.id == nfdeploymentdescriptorid)) - first = res.first() - return None if first is None else dict(first) - - -def _check_duplication(name: str, uow: unit_of_work.AbstractUnitOfWork): - if uow.nfdeployment_descs.count(name=name) > 0: - raise Exception( - "NfDeploymentDescriptor with name {} exists already".format(name)) - - -def lcm_nfdeploymentdesc_create( - deploymentManagerId: str, - input: DmsLcmNfDeploymentDescriptorDTO. - NfDeploymentDescriptor_create, - uow: unit_of_work.AbstractUnitOfWork): - - with uow: - _check_duplication(input['name'], uow) - id = str(uuid.uuid4()) - entity = NfDeploymentDesc( - id, input['name'], deploymentManagerId, input['description'], - input['inputParams'], input['outputParams'], - input['artifactRepoUrl'], input['artifactName']) - _nfdeploymentdesc_validate(entity) - uow.nfdeployment_descs.add(entity) - uow.commit() - return id - - -def _nfdeploymentdesc_validate(desc: NfDeploymentDesc): - try: - if desc.inputParams: - json.loads(desc.inputParams) - if desc.outputParams: - json.loads(desc.outputParams) - if not desc.deploymentManagerId: - raise Exception("Invalid deploymentManager Id") - if not desc.artifactRepoUrl: - raise Exception("Invalid artifactRepoUrl") - if not desc.artifactName: - raise Exception("Invalid artifactName") - return - except json.decoder.JSONDecodeError as e: - logger.debug("NfDeploymentDesc json error with: %s" % (str(e))) - raise e - except Exception as e: - logger.debug("NfDeploymentDesc validate error with: %s" % (str(e))) - raise e - - -def lcm_nfdeploymentdesc_update( - nfdeploymentdescriptorid: str, - input: DmsLcmNfDeploymentDescriptorDTO.NfDeploymentDescriptor_update, - uow: unit_of_work.AbstractUnitOfWork): - - with uow: - entity = uow.nfdeployment_descs.get(nfdeploymentdescriptorid) - entity.name = input['name'] - entity.description = input['description'] - entity.inputParams = input['inputParams'] - entity.outputParams = input['outputParams'] - entity.artifactRepoUrl = input['artifactRepoUrl'] - entity.artifactName = input['artifactName'] - uow.commit() - return True - - -def lcm_nfdeploymentdesc_delete( - nfdeploymentdescriptorid: str, uow: unit_of_work.AbstractUnitOfWork): - - with uow: - # check dependency - _check_dependencies(nfdeploymentdescriptorid, uow) - uow.nfdeployment_descs.delete(nfdeploymentdescriptorid) - uow.commit() - return True - - -def _check_dependencies( - descriptorId: str, uow: unit_of_work.AbstractUnitOfWork -): - # check if nfdeployment depends on it - if uow.nfdeployments.count(descriptorId=descriptorId) > 0: - raise Exception( - "NfDeployment with descriptorId {} exists".format( - descriptorId)) +# Copyright (C) 2021 Wind River Systems, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import json +from sqlalchemy import select +import uuid +from o2common.service import unit_of_work +from o2dms.adapter.orm import nfDeploymentDesc +from o2dms.api.dms_dto import DmsLcmNfDeploymentDescriptorDTO +from o2dms.domain.dms import NfDeploymentDesc +from o2common.helper import o2logging +logger = o2logging.get_logger(__name__) + + +def lcm_nfdeploymentdesc_list(deploymentManagerID: str, + uow: unit_of_work.AbstractUnitOfWork): + with uow: + res = uow.session.execute(select(nfDeploymentDesc).where( + nfDeploymentDesc.c.deploymentManagerId == deploymentManagerID)) + return [dict(r) for r in res] + + +def lcm_nfdeploymentdesc_one(nfdeploymentdescriptorid: str, + uow: unit_of_work.AbstractUnitOfWork): + with uow: + res = uow.session.execute(select(nfDeploymentDesc).where( + nfDeploymentDesc.c.id == nfdeploymentdescriptorid)) + first = res.first() + return None if first is None else dict(first) + + +def _check_duplication(name: str, uow: unit_of_work.AbstractUnitOfWork): + if uow.nfdeployment_descs.count(name=name) > 0: + raise Exception( + "NfDeploymentDescriptor with name {} exists already".format(name)) + + +def lcm_nfdeploymentdesc_create( + deploymentManagerId: str, + input: DmsLcmNfDeploymentDescriptorDTO. + NfDeploymentDescriptor_create, + uow: unit_of_work.AbstractUnitOfWork): + + with uow: + _check_duplication(input['name'], uow) + id = str(uuid.uuid4()) + entity = NfDeploymentDesc( + id, input['name'], deploymentManagerId, input['description'], + input['inputParams'], input['outputParams'], + input['artifactRepoUrl'], input['artifactName']) + _nfdeploymentdesc_validate(entity) + uow.nfdeployment_descs.add(entity) + uow.commit() + return id + + +def _nfdeploymentdesc_validate(desc: NfDeploymentDesc): + try: + if desc.inputParams: + json.loads(desc.inputParams) + if desc.outputParams: + json.loads(desc.outputParams) + if not desc.deploymentManagerId: + raise Exception("Invalid deploymentManager Id") + if not desc.artifactRepoUrl: + raise Exception("Invalid artifactRepoUrl") + if not desc.artifactName: + raise Exception("Invalid artifactName") + return + except json.decoder.JSONDecodeError as e: + logger.debug("NfDeploymentDesc json error with: %s" % (str(e))) + raise e + except Exception as e: + logger.debug("NfDeploymentDesc validate error with: %s" % (str(e))) + raise e + + +def lcm_nfdeploymentdesc_update( + nfdeploymentdescriptorid: str, + input: DmsLcmNfDeploymentDescriptorDTO.NfDeploymentDescriptor_update, + uow: unit_of_work.AbstractUnitOfWork): + + with uow: + entity = uow.nfdeployment_descs.get(nfdeploymentdescriptorid) + entity.name = input['name'] + entity.description = input['description'] + entity.inputParams = input['inputParams'] + entity.outputParams = input['outputParams'] + entity.artifactRepoUrl = input['artifactRepoUrl'] + entity.artifactName = input['artifactName'] + uow.commit() + return True + + +def lcm_nfdeploymentdesc_delete( + nfdeploymentdescriptorid: str, uow: unit_of_work.AbstractUnitOfWork): + + with uow: + # check dependency + _check_dependencies(nfdeploymentdescriptorid, uow) + uow.nfdeployment_descs.delete(nfdeploymentdescriptorid) + uow.commit() + return True + + +def _check_dependencies( + descriptorId: str, uow: unit_of_work.AbstractUnitOfWork +): + # check if nfdeployment depends on it + if uow.nfdeployments.count(descriptorId=descriptorId) > 0: + raise Exception( + "NfDeployment with descriptorId {} exists".format( + descriptorId)) diff --git a/o2dms/api/dms_lcm_view.py b/o2dms/api/dms_lcm_view.py index 9995e8e..3a634e4 100644 --- a/o2dms/api/dms_lcm_view.py +++ b/o2dms/api/dms_lcm_view.py @@ -1,34 +1,34 @@ -# Copyright (C) 2021 Wind River Systems, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from sqlalchemy import select -from o2common.service import unit_of_work -from o2ims.adapter.orm import deploymentmanager -from o2common.helper import o2logging -logger = o2logging.get_logger(__name__) - - -def deployment_managers(uow: unit_of_work.AbstractUnitOfWork): - with uow: - res = uow.session.execute(select(deploymentmanager)) - return [dict(r) for r in res] - - -def deployment_manager_one(deploymentManagerId: str, - uow: unit_of_work.AbstractUnitOfWork): - with uow: - res = uow.session.execute(select(deploymentmanager).where( - deploymentmanager.c.deploymentManagerId == deploymentManagerId)) - first = res.first() - return None if first is None else dict(first) +# Copyright (C) 2021 Wind River Systems, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from sqlalchemy import select +from o2common.service import unit_of_work +from o2ims.adapter.orm import deploymentmanager +from o2common.helper import o2logging +logger = o2logging.get_logger(__name__) + + +def deployment_managers(uow: unit_of_work.AbstractUnitOfWork): + with uow: + res = uow.session.execute(select(deploymentmanager)) + return [dict(r) for r in res] + + +def deployment_manager_one(deploymentManagerId: str, + uow: unit_of_work.AbstractUnitOfWork): + with uow: + res = uow.session.execute(select(deploymentmanager).where( + deploymentmanager.c.deploymentManagerId == deploymentManagerId)) + first = res.first() + return None if first is None else dict(first) diff --git a/o2dms/domain/__init__.py b/o2dms/domain/__init__.py index b514342..813897e 100644 --- a/o2dms/domain/__init__.py +++ b/o2dms/domain/__init__.py @@ -1,13 +1,13 @@ -# Copyright (C) 2021 Wind River Systems, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. +# Copyright (C) 2021 Wind River Systems, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. diff --git a/o2dms/domain/dms.py b/o2dms/domain/dms.py index 2a8c144..d3d908e 100644 --- a/o2dms/domain/dms.py +++ b/o2dms/domain/dms.py @@ -1,93 +1,93 @@ -# Copyright (C) 2021 Wind River Systems, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from __future__ import annotations -# from os import stat -import json -from o2dms.domain import events -from o2dms.domain.states import NfDeploymentState - -from o2common.domain.base import AgRoot, Serializer - - -class NfDeploymentDesc(AgRoot, Serializer): - def __init__(self, id: str, name: str, dmsId: str, description: str = '', - inputParams: str = '', outputParams: str = '', - artifactRepoUrl: str = '', artifactName: str = '') -> None: - super().__init__() - self.id = id - self.version_number = 0 - self.deploymentManagerId = dmsId - self.name = name - self.description = description - self.artifactRepoUrl = artifactRepoUrl - self.artifactName = artifactName - self.status = 0 - - if type(inputParams) is str: - inputParams = json.loads(inputParams) - self.inputParams = json.dumps(inputParams) - - if type(outputParams) is str: - outputParams = json.loads(outputParams) - self.outputParams = json.dumps(outputParams) - - # self.extensions = [] - - -class NfDeployment(AgRoot, Serializer): - def __init__(self, id: str, name: str, dmsId: str, description: str = '', - descriptorId: str = '', parentId: str = '',) -> None: - super().__init__() - self.id = id - self.version_number = 0 - self.deploymentManagerId = dmsId - self.name = name - self.description = description - self.descriptorId = descriptorId - self.parentDeploymentId = parentId - self.status = NfDeploymentState.Initial - - def transit_state(self, state: NfDeploymentState): - if (self.status != state): - self._append_event(self.status, state) - # self.status = state - - def set_state(self, state: NfDeploymentState): - if (self.status != state): - self.status = state - - def _append_event(self, fromState, toState): - if not hasattr(self, "events"): - self.events = [] - self.events.append( - events.NfDeploymentStateChanged( - NfDeploymentId=self.id, FromState=fromState, ToState=toState)) - - -class NfOCloudVResource(AgRoot, Serializer): - def __init__(self, id: str, name: str, dmsId: str, description: str = '', - descriptorId: str = '', nfDeploymentId: str = '', - vresourceType: int = 0,) -> None: - super().__init__() - self.id = id - self.version_number = 0 - self.deploymentManagerId = dmsId - self.name = name - self.description = description - self.descriptorId = descriptorId - self.nfDeploymentId = nfDeploymentId - self.vresourceType = vresourceType - self.status = 0 - self.metadata = [] +# Copyright (C) 2021 Wind River Systems, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from __future__ import annotations +# from os import stat +import json +from o2dms.domain import events +from o2dms.domain.states import NfDeploymentState + +from o2common.domain.base import AgRoot, Serializer + + +class NfDeploymentDesc(AgRoot, Serializer): + def __init__(self, id: str, name: str, dmsId: str, description: str = '', + inputParams: str = '', outputParams: str = '', + artifactRepoUrl: str = '', artifactName: str = '') -> None: + super().__init__() + self.id = id + self.version_number = 0 + self.deploymentManagerId = dmsId + self.name = name + self.description = description + self.artifactRepoUrl = artifactRepoUrl + self.artifactName = artifactName + self.status = 0 + + if type(inputParams) is str: + inputParams = json.loads(inputParams) + self.inputParams = json.dumps(inputParams) + + if type(outputParams) is str: + outputParams = json.loads(outputParams) + self.outputParams = json.dumps(outputParams) + + # self.extensions = [] + + +class NfDeployment(AgRoot, Serializer): + def __init__(self, id: str, name: str, dmsId: str, description: str = '', + descriptorId: str = '', parentId: str = '',) -> None: + super().__init__() + self.id = id + self.version_number = 0 + self.deploymentManagerId = dmsId + self.name = name + self.description = description + self.descriptorId = descriptorId + self.parentDeploymentId = parentId + self.status = NfDeploymentState.Initial + + def transit_state(self, state: NfDeploymentState): + if (self.status != state): + self._append_event(self.status, state) + # self.status = state + + def set_state(self, state: NfDeploymentState): + if (self.status != state): + self.status = state + + def _append_event(self, fromState, toState): + if not hasattr(self, "events"): + self.events = [] + self.events.append( + events.NfDeploymentStateChanged( + NfDeploymentId=self.id, FromState=fromState, ToState=toState)) + + +class NfOCloudVResource(AgRoot, Serializer): + def __init__(self, id: str, name: str, dmsId: str, description: str = '', + descriptorId: str = '', nfDeploymentId: str = '', + vresourceType: int = 0,) -> None: + super().__init__() + self.id = id + self.version_number = 0 + self.deploymentManagerId = dmsId + self.name = name + self.description = description + self.descriptorId = descriptorId + self.nfDeploymentId = nfDeploymentId + self.vresourceType = vresourceType + self.status = 0 + self.metadata = [] diff --git a/o2dms/domain/dms_repo.py b/o2dms/domain/dms_repo.py index 4a63a85..151eb9b 100644 --- a/o2dms/domain/dms_repo.py +++ b/o2dms/domain/dms_repo.py @@ -1,151 +1,151 @@ -# Copyright (C) 2021 Wind River Systems, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -import abc -from typing import List, Set -from o2dms.domain import dms - - -class NfDeploymentRepository(abc.ABC): - def __init__(self): - self.seen = set() # type: Set[dms.NfDeployment] - - def add(self, nfdeployment: dms.NfDeployment): - self._add(nfdeployment) - self.seen.add(nfdeployment) - - def get(self, nfdeployment_id) -> dms.NfDeployment: - nfdeployment = self._get(nfdeployment_id) - if nfdeployment: - self.seen.add(nfdeployment) - return nfdeployment - - def list(self) -> List[dms.NfDeployment]: - return self._list() - - def update(self, id, **kwargs): - self._update(id, **kwargs) - - def delete(self, nfdeployment_id): - self._delete(nfdeployment_id) - - def count(self, **kwargs): - return self._count(**kwargs) - - @abc.abstractmethod - def _add(self, nfdeployment: dms.NfDeployment): - raise NotImplementedError - - @abc.abstractmethod - def _get(self, nfdeployment_id) -> dms.NfDeployment: - raise NotImplementedError - - @abc.abstractmethod - def _update(self, id, **kwargs): - raise NotImplementedError - - @abc.abstractmethod - def _delete(self, nfdeployment_id): - raise NotImplementedError - - @abc.abstractmethod - def _count(self, **kwargs): - raise NotImplementedError - - -class NfDeploymentDescRepository(abc.ABC): - def __init__(self): - self.seen = set() # type: Set[dms.NfDeploymentDesc] - - def add(self, nfdeployment_descriptor: dms.NfDeploymentDesc): - self._add(nfdeployment_descriptor) - self.seen.add(nfdeployment_descriptor) - - def get(self, nfdeployment_descriptor_id) -> dms.NfDeploymentDesc: - nfdeployment_descriptor = self._get(nfdeployment_descriptor_id) - if nfdeployment_descriptor: - self.seen.add(nfdeployment_descriptor) - return nfdeployment_descriptor - - def list(self) -> List[dms.NfDeploymentDesc]: - return self._list() - - def update(self, id, **kwargs): - self._update(id, **kwargs) - - def delete(self, nfdeployment_descriptor_id): - self._delete(nfdeployment_descriptor_id) - - def count(self, **kwargs): - return self._count(**kwargs) - - @abc.abstractmethod - def _add(self, nfdeployment_descriptor: dms.NfDeploymentDesc): - raise NotImplementedError - - @abc.abstractmethod - def _get(self, nfdeployment_descriptor_id) -> dms.NfDeploymentDesc: - raise NotImplementedError - - @abc.abstractmethod - def _update(self, id, **kwargs): - raise NotImplementedError - - @abc.abstractmethod - def _delete(self, nfdeployment_descriptor_id): - raise NotImplementedError - - @abc.abstractmethod - def _count(self, **kwargs): - raise NotImplementedError - - -class NfOCloudVResourceRepository(abc.ABC): - def __init__(self): - self.seen = set() # type: Set[dms.NfOCloudVResource] - - def add(self, nfocloudvres: dms.NfOCloudVResource): - self._add(nfocloudvres) - self.seen.add(nfocloudvres) - - def get(self, nfocloudvres_id) -> dms.NfOCloudVResource: - nfocloudvres = self._get(nfocloudvres_id) - if nfocloudvres: - self.seen.add(nfocloudvres) - return nfocloudvres - - def list(self) -> List[dms.NfOCloudVResource]: - return self._list() - - def update(self, nfocloudvres_id, **kwargs): - self._update(nfocloudvres_id, **kwargs) - - def delete(self, nfocloudvres_id): - self._delete(nfocloudvres_id) - - @abc.abstractmethod - def _add(self, nfocloudvres: dms.NfOCloudVResource): - raise NotImplementedError - - @abc.abstractmethod - def _get(self, nfocloudvres_id) -> dms.NfOCloudVResource: - raise NotImplementedError - - @abc.abstractmethod - def _update(self, nfocloudvres_id, **kwargs): - raise NotImplementedError - - @abc.abstractmethod - def _delete(self, nfocloudvres_id): - raise NotImplementedError +# Copyright (C) 2021 Wind River Systems, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import abc +from typing import List, Set +from o2dms.domain import dms + + +class NfDeploymentRepository(abc.ABC): + def __init__(self): + self.seen = set() # type: Set[dms.NfDeployment] + + def add(self, nfdeployment: dms.NfDeployment): + self._add(nfdeployment) + self.seen.add(nfdeployment) + + def get(self, nfdeployment_id) -> dms.NfDeployment: + nfdeployment = self._get(nfdeployment_id) + if nfdeployment: + self.seen.add(nfdeployment) + return nfdeployment + + def list(self) -> List[dms.NfDeployment]: + return self._list() + + def update(self, id, **kwargs): + self._update(id, **kwargs) + + def delete(self, nfdeployment_id): + self._delete(nfdeployment_id) + + def count(self, **kwargs): + return self._count(**kwargs) + + @abc.abstractmethod + def _add(self, nfdeployment: dms.NfDeployment): + raise NotImplementedError + + @abc.abstractmethod + def _get(self, nfdeployment_id) -> dms.NfDeployment: + raise NotImplementedError + + @abc.abstractmethod + def _update(self, id, **kwargs): + raise NotImplementedError + + @abc.abstractmethod + def _delete(self, nfdeployment_id): + raise NotImplementedError + + @abc.abstractmethod + def _count(self, **kwargs): + raise NotImplementedError + + +class NfDeploymentDescRepository(abc.ABC): + def __init__(self): + self.seen = set() # type: Set[dms.NfDeploymentDesc] + + def add(self, nfdeployment_descriptor: dms.NfDeploymentDesc): + self._add(nfdeployment_descriptor) + self.seen.add(nfdeployment_descriptor) + + def get(self, nfdeployment_descriptor_id) -> dms.NfDeploymentDesc: + nfdeployment_descriptor = self._get(nfdeployment_descriptor_id) + if nfdeployment_descriptor: + self.seen.add(nfdeployment_descriptor) + return nfdeployment_descriptor + + def list(self) -> List[dms.NfDeploymentDesc]: + return self._list() + + def update(self, id, **kwargs): + self._update(id, **kwargs) + + def delete(self, nfdeployment_descriptor_id): + self._delete(nfdeployment_descriptor_id) + + def count(self, **kwargs): + return self._count(**kwargs) + + @abc.abstractmethod + def _add(self, nfdeployment_descriptor: dms.NfDeploymentDesc): + raise NotImplementedError + + @abc.abstractmethod + def _get(self, nfdeployment_descriptor_id) -> dms.NfDeploymentDesc: + raise NotImplementedError + + @abc.abstractmethod + def _update(self, id, **kwargs): + raise NotImplementedError + + @abc.abstractmethod + def _delete(self, nfdeployment_descriptor_id): + raise NotImplementedError + + @abc.abstractmethod + def _count(self, **kwargs): + raise NotImplementedError + + +class NfOCloudVResourceRepository(abc.ABC): + def __init__(self): + self.seen = set() # type: Set[dms.NfOCloudVResource] + + def add(self, nfocloudvres: dms.NfOCloudVResource): + self._add(nfocloudvres) + self.seen.add(nfocloudvres) + + def get(self, nfocloudvres_id) -> dms.NfOCloudVResource: + nfocloudvres = self._get(nfocloudvres_id) + if nfocloudvres: + self.seen.add(nfocloudvres) + return nfocloudvres + + def list(self) -> List[dms.NfOCloudVResource]: + return self._list() + + def update(self, nfocloudvres_id, **kwargs): + self._update(nfocloudvres_id, **kwargs) + + def delete(self, nfocloudvres_id): + self._delete(nfocloudvres_id) + + @abc.abstractmethod + def _add(self, nfocloudvres: dms.NfOCloudVResource): + raise NotImplementedError + + @abc.abstractmethod + def _get(self, nfocloudvres_id) -> dms.NfOCloudVResource: + raise NotImplementedError + + @abc.abstractmethod + def _update(self, nfocloudvres_id, **kwargs): + raise NotImplementedError + + @abc.abstractmethod + def _delete(self, nfocloudvres_id): + raise NotImplementedError diff --git a/o2dms/domain/exceptions.py b/o2dms/domain/exceptions.py index 688392e..5a9c151 100644 --- a/o2dms/domain/exceptions.py +++ b/o2dms/domain/exceptions.py @@ -1,22 +1,22 @@ - -# Copyright (C) 2022 Wind River Systems, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# pylint: disable=too-few-public-methods - -from o2common.domain.exceptions import Orano2Exception - - -class NfdeploymentNotFoundError(Orano2Exception): - pass + +# Copyright (C) 2022 Wind River Systems, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# pylint: disable=too-few-public-methods + +from o2common.domain.exceptions import Orano2Exception + + +class NfdeploymentNotFoundError(Orano2Exception): + pass diff --git a/o2dms/domain/states.py b/o2dms/domain/states.py index 1f1b434..31f5c4d 100644 --- a/o2dms/domain/states.py +++ b/o2dms/domain/states.py @@ -1,30 +1,30 @@ - -# Copyright (C) 2021 Wind River Systems, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from __future__ import annotations -from dataclasses import dataclass - - -@dataclass -class NfDeploymentState(): - Initial = 0 - # NotInstalled = 1 - Installing = 2 - Installed = 3 - Updating = 4 - Uninstalling = 5 - Abnormal = 6 - Deleting = 7 - # Aborting = 8 + +# Copyright (C) 2021 Wind River Systems, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from __future__ import annotations +from dataclasses import dataclass + + +@dataclass +class NfDeploymentState(): + Initial = 0 + # NotInstalled = 1 + Installing = 2 + Installed = 3 + Updating = 4 + Uninstalling = 5 + Abnormal = 6 + Deleting = 7 + # Aborting = 8 diff --git a/o2dms/service/__init__.py b/o2dms/service/__init__.py index b514342..813897e 100644 --- a/o2dms/service/__init__.py +++ b/o2dms/service/__init__.py @@ -1,13 +1,13 @@ -# Copyright (C) 2021 Wind River Systems, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. +# Copyright (C) 2021 Wind River Systems, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. diff --git a/o2ims/__init__.py b/o2ims/__init__.py index b514342..813897e 100644 --- a/o2ims/__init__.py +++ b/o2ims/__init__.py @@ -1,13 +1,13 @@ -# Copyright (C) 2021 Wind River Systems, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. +# Copyright (C) 2021 Wind River Systems, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. diff --git a/o2ims/adapter/__init__.py b/o2ims/adapter/__init__.py index b514342..813897e 100644 --- a/o2ims/adapter/__init__.py +++ b/o2ims/adapter/__init__.py @@ -1,13 +1,13 @@ -# Copyright (C) 2021 Wind River Systems, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. +# Copyright (C) 2021 Wind River Systems, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. diff --git a/o2ims/adapter/clients/__init__.py b/o2ims/adapter/clients/__init__.py index b514342..813897e 100644 --- a/o2ims/adapter/clients/__init__.py +++ b/o2ims/adapter/clients/__init__.py @@ -1,13 +1,13 @@ -# Copyright (C) 2021 Wind River Systems, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. +# Copyright (C) 2021 Wind River Systems, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. diff --git a/o2ims/adapter/clients/ocloud_sa_client.py b/o2ims/adapter/clients/ocloud_sa_client.py index d0e12de..81ba817 100644 --- a/o2ims/adapter/clients/ocloud_sa_client.py +++ b/o2ims/adapter/clients/ocloud_sa_client.py @@ -1,319 +1,319 @@ -# Copyright (C) 2021 Wind River Systems, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# client talking to Stx standalone - -import uuid -from o2common.service.client.base_client import BaseClient -from typing import List -# Optional, Set -from o2ims.domain import stx_object as ocloudModel -from o2common.config import config -from o2ims.domain.resource_type import ResourceTypeEnum - -# from dcmanagerclient.api import client -from cgtsclient.client import get_client - -from o2common.helper import o2logging -logger = o2logging.get_logger(__name__) - - -class StxSaOcloudClient(BaseClient): - def __init__(self, driver=None): - super().__init__() - self.driver = driver if driver else StxSaClientImp() - - def _get(self, id) -> ocloudModel.StxGenericModel: - return self.driver.getInstanceInfo() - - def _list(self, **filters): - return [self.driver.getInstanceInfo()] - - -class StxSaResourcePoolClient(BaseClient): - def __init__(self): - super().__init__() - self.driver = StxSaClientImp() - - def _get(self, id) -> ocloudModel.StxGenericModel: - return self.driver.getInstanceInfo() - - def _list(self, **filters): - return [self.driver.getInstanceInfo()] - - -class StxSaDmsClient(BaseClient): - def __init__(self): - super().__init__() - self.driver = StxSaClientImp() - - def _get(self, name) -> ocloudModel.StxGenericModel: - return self.driver.getK8sDetail(name) - - def _list(self, **filters): - return self.driver.getK8sList(**filters) - - -class StxPserverClient(BaseClient): - def __init__(self): - super().__init__() - self.driver = StxSaClientImp() - - def _get(self, id) -> ocloudModel.StxGenericModel: - return self.driver.getPserver(id) - - def _list(self, **filters) -> List[ocloudModel.StxGenericModel]: - return self.driver.getPserverList(**filters) - - -class StxCpuClient(BaseClient): - def __init__(self): - super().__init__() - # self._pserver_id = pserver_id - self.driver = StxSaClientImp() - - def _get(self, id) -> ocloudModel.StxGenericModel: - return self.driver.getCpu(id) - - def _list(self, **filters) -> List[ocloudModel.StxGenericModel]: - return self.driver.getCpuList(**filters) - - -class StxMemClient(BaseClient): - def __init__(self): - super().__init__() - self.driver = StxSaClientImp() - - def _get(self, id) -> ocloudModel.StxGenericModel: - return self.driver.getMem(id) - - def _list(self, **filters) -> List[ocloudModel.StxGenericModel]: - return self.driver.getMemList(**filters) - - -class StxEthClient(BaseClient): - def __init__(self): - super().__init__() - self.driver = StxSaClientImp() - - def _get(self, id) -> ocloudModel.StxGenericModel: - return self.driver.getEthernet(id) - - def _list(self, **filters) -> List[ocloudModel.StxGenericModel]: - return self.driver.getEthernetList(**filters) - - -class StxIfClient(BaseClient): - def __init__(self): - super().__init__() - self.driver = StxSaClientImp() - - def _get(self, id) -> ocloudModel.StxGenericModel: - return self.driver.getIf(id) - - def _list(self, **filters) -> List[ocloudModel.StxGenericModel]: - return self.driver.getIfList(**filters) - - -class StxIfPortClient(BaseClient): - def __init__(self): - super().__init__() - self.driver = StxSaClientImp() - - def _get(self, id) -> ocloudModel.StxGenericModel: - return self.driver.getPort(id) - - def _list(self, **filters) -> List[ocloudModel.StxGenericModel]: - return self.driver.getPortList(**filters) - - -# internal driver which implement client call to Stx Standalone instance -class StxSaClientImp(object): - def __init__(self, stx_client=None): - super().__init__() - self.stxclient = stx_client if stx_client else self.getStxClient() - - def getStxClient(self): - os_client_args = config.get_stx_access_info() - config_client = get_client(**os_client_args) - return config_client - - def getInstanceInfo(self) -> ocloudModel.StxGenericModel: - systems = self.stxclient.isystem.list() - logger.debug('systems:' + str(systems[0].to_dict())) - return ocloudModel.StxGenericModel( - ResourceTypeEnum.OCLOUD, systems[0]) if systems else None - - def getPserverList(self, **filters) -> List[ocloudModel.StxGenericModel]: - # resourcepoolid = filters.get("resourcepoolid", None) - hosts = self.stxclient.ihost.list() - logger.debug('host 1:' + str(hosts[0].to_dict())) - return [ocloudModel.StxGenericModel( - ResourceTypeEnum.PSERVER, self._hostconverter(host)) - for host in hosts if host and host.availability == 'available'] - - def getPserver(self, id) -> ocloudModel.StxGenericModel: - host = self.stxclient.ihost.get(id) - logger.debug('host:' + str(host.to_dict())) - return ocloudModel.StxGenericModel( - ResourceTypeEnum.PSERVER, self._hostconverter(host)) - - def getK8sList(self, **filters) -> List[ocloudModel.StxGenericModel]: - k8sclusters = self.stxclient.kube_cluster.list() - logger.debug('k8sresources[0]:' + str(k8sclusters[0].to_dict())) - return [ocloudModel.StxGenericModel( - ResourceTypeEnum.DMS, - self._k8sconverter(k8sres), self._k8shasher(k8sres)) - for k8sres in k8sclusters if k8sres] - - def getK8sDetail(self, name) -> ocloudModel.StxGenericModel: - if not name: - k8sclusters = self.stxclient.kube_cluster.list() - # logger.debug("k8sresources[0]:" + str(k8sclusters[0].to_dict())) - k8scluster = k8sclusters.pop() - else: - k8scluster = self.stxclient.kube_cluster.get(name) - - if not k8scluster: - return None - logger.debug('k8sresource:' + str(k8scluster.to_dict())) - return ocloudModel.StxGenericModel( - ResourceTypeEnum.DMS, - self._k8sconverter(k8scluster), self._k8shasher(k8scluster)) - - def getCpuList(self, **filters) -> List[ocloudModel.StxGenericModel]: - hostid = filters.get('hostid', None) - assert (hostid is not None), 'missing hostid to query icpu list' - cpulist = self.stxclient.icpu.list(hostid) - return [ocloudModel.StxGenericModel( - ResourceTypeEnum.PSERVER_CPU, - self._cpuconverter(cpures)) for cpures in cpulist if cpures] - - def getCpu(self, id) -> ocloudModel.StxGenericModel: - cpuinfo = self.stxclient.icpu.get(id) - return ocloudModel.StxGenericModel( - ResourceTypeEnum.PSERVER_CPU, self._cpuconverter(cpuinfo)) - - def getMemList(self, **filters) -> List[ocloudModel.StxGenericModel]: - hostid = filters.get('hostid', None) - assert (hostid is not None), 'missing hostid to query imem list' - memlist = self.stxclient.imemory.list(hostid) - return [ocloudModel.StxGenericModel( - ResourceTypeEnum.PSERVER_RAM, - self._memconverter(memories)) for memories in memlist if memories] - - def getMem(self, id) -> ocloudModel.StxGenericModel: - meminfo = self.stxclient.imemory.get(id) - return ocloudModel.StxGenericModel( - ResourceTypeEnum.PSERVER_RAM, self._memconverter(meminfo)) - - def getEthernetList(self, **filters) -> List[ocloudModel.StxGenericModel]: - hostid = filters.get('hostid', None) - assert (hostid is not None), 'missing hostid to query port list' - ethlist = self.stxclient.ethernet_port.list(hostid) - return [ocloudModel.StxGenericModel( - ResourceTypeEnum.PSERVER_ETH, - self._ethconverter(eth)) for eth in ethlist if eth] - - def getEthernet(self, id) -> ocloudModel.StxGenericModel: - ethinfo = self.stxclient.ethernet_port.get(id) - return ocloudModel.StxGenericModel( - ResourceTypeEnum.PSERVER_ETH, self._ethconverter(ethinfo)) - - def getIfList(self, **filters) -> List[ocloudModel.StxGenericModel]: - hostid = filters.get('hostid', None) - assert (hostid is not None), 'missing hostid to query iinterface list' - iflist = self.stxclient.iinterface.list(hostid) - return [ocloudModel.StxGenericModel( - ResourceTypeEnum.PSERVER_IF, - self._ifconverter(ifs)) for ifs in iflist if ifs] - - def getIf(self, id) -> ocloudModel.StxGenericModel: - ifinfo = self.stxclient.iinterface.get(id) - return ocloudModel.StxGenericModel( - ResourceTypeEnum.PSERVER_IF, self._ifconverter(ifinfo)) - - def getPortList(self, **filters) -> List[ocloudModel.StxGenericModel]: - ifid = filters.get('interfaceid', None) - assert (ifid is not None), 'missing interface id to query port list' - portlist = self.stxclient.iinterface.list_ports(ifid) - return [ocloudModel.StxGenericModel( - ResourceTypeEnum.PSERVER_IF_PORT, - port) for port in portlist if port] - - def getPort(self, id) -> ocloudModel.StxGenericModel: - portinfo = self.stxclient.port.get(id) - return ocloudModel.StxGenericModel( - ResourceTypeEnum.PSERVER_IF_PORT, portinfo) - - def _getIsystems(self): - return self.stxclient.isystem.list() - - def _getIsystem(self, id=None): - if id: - return self.stxclient.isystem.get(id) - else: - isystems = self.stxclient.isystem.list() - if len(isystems) != 1 and not id: - raise Exception('No system uuid was provided and ' - 'more than one system exists in the account.') - return isystems[0] - - @ staticmethod - def _hostconverter(host): - setattr(host, 'name', host.hostname) - return host - - @ staticmethod - def _cpuconverter(cpu): - setattr(cpu, 'name', cpu.ihost_uuid.split( - '-', 1)[0] + '-cpu-'+str(cpu.cpu)) - return cpu - - @ staticmethod - def _memconverter(mem): - setattr(mem, 'name', mem.ihost_uuid.split('-', 1)[0] + - '-mem-node-'+str(mem.numa_node)) - return mem - - @ staticmethod - def _ethconverter(eth): - setattr(eth, 'name', eth.host_uuid.split('-', 1)[0] + '-'+eth.name) - setattr(eth, 'updated_at', None) - setattr(eth, 'created_at', None) - return eth - - @ staticmethod - def _ifconverter(ifs): - setattr(ifs, 'name', ifs.ihost_uuid.split('-', 1)[0] + '-'+ifs.ifname) - setattr(ifs, 'updated_at', None) - setattr(ifs, 'created_at', None) - return ifs - - @ staticmethod - def _k8sconverter(cluster): - setattr(cluster, 'name', cluster.cluster_name) - setattr(cluster, 'uuid', - uuid.uuid3(uuid.NAMESPACE_URL, cluster.cluster_name)) - setattr(cluster, 'updated_at', None) - setattr(cluster, 'created_at', None) - setattr(cluster, 'events', []) - logger.debug('k8s cluster name/uuid:' + - cluster.name + '/' + str(cluster.uuid)) - return cluster - - @ staticmethod - def _k8shasher(cluster): - return str(hash((cluster.cluster_name, - cluster.cluster_api_endpoint, cluster.admin_user))) +# Copyright (C) 2021 Wind River Systems, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# client talking to Stx standalone + +import uuid +from o2common.service.client.base_client import BaseClient +from typing import List +# Optional, Set +from o2ims.domain import stx_object as ocloudModel +from o2common.config import config +from o2ims.domain.resource_type import ResourceTypeEnum + +# from dcmanagerclient.api import client +from cgtsclient.client import get_client + +from o2common.helper import o2logging +logger = o2logging.get_logger(__name__) + + +class StxSaOcloudClient(BaseClient): + def __init__(self, driver=None): + super().__init__() + self.driver = driver if driver else StxSaClientImp() + + def _get(self, id) -> ocloudModel.StxGenericModel: + return self.driver.getInstanceInfo() + + def _list(self, **filters): + return [self.driver.getInstanceInfo()] + + +class StxSaResourcePoolClient(BaseClient): + def __init__(self): + super().__init__() + self.driver = StxSaClientImp() + + def _get(self, id) -> ocloudModel.StxGenericModel: + return self.driver.getInstanceInfo() + + def _list(self, **filters): + return [self.driver.getInstanceInfo()] + + +class StxSaDmsClient(BaseClient): + def __init__(self): + super().__init__() + self.driver = StxSaClientImp() + + def _get(self, name) -> ocloudModel.StxGenericModel: + return self.driver.getK8sDetail(name) + + def _list(self, **filters): + return self.driver.getK8sList(**filters) + + +class StxPserverClient(BaseClient): + def __init__(self): + super().__init__() + self.driver = StxSaClientImp() + + def _get(self, id) -> ocloudModel.StxGenericModel: + return self.driver.getPserver(id) + + def _list(self, **filters) -> List[ocloudModel.StxGenericModel]: + return self.driver.getPserverList(**filters) + + +class StxCpuClient(BaseClient): + def __init__(self): + super().__init__() + # self._pserver_id = pserver_id + self.driver = StxSaClientImp() + + def _get(self, id) -> ocloudModel.StxGenericModel: + return self.driver.getCpu(id) + + def _list(self, **filters) -> List[ocloudModel.StxGenericModel]: + return self.driver.getCpuList(**filters) + + +class StxMemClient(BaseClient): + def __init__(self): + super().__init__() + self.driver = StxSaClientImp() + + def _get(self, id) -> ocloudModel.StxGenericModel: + return self.driver.getMem(id) + + def _list(self, **filters) -> List[ocloudModel.StxGenericModel]: + return self.driver.getMemList(**filters) + + +class StxEthClient(BaseClient): + def __init__(self): + super().__init__() + self.driver = StxSaClientImp() + + def _get(self, id) -> ocloudModel.StxGenericModel: + return self.driver.getEthernet(id) + + def _list(self, **filters) -> List[ocloudModel.StxGenericModel]: + return self.driver.getEthernetList(**filters) + + +class StxIfClient(BaseClient): + def __init__(self): + super().__init__() + self.driver = StxSaClientImp() + + def _get(self, id) -> ocloudModel.StxGenericModel: + return self.driver.getIf(id) + + def _list(self, **filters) -> List[ocloudModel.StxGenericModel]: + return self.driver.getIfList(**filters) + + +class StxIfPortClient(BaseClient): + def __init__(self): + super().__init__() + self.driver = StxSaClientImp() + + def _get(self, id) -> ocloudModel.StxGenericModel: + return self.driver.getPort(id) + + def _list(self, **filters) -> List[ocloudModel.StxGenericModel]: + return self.driver.getPortList(**filters) + + +# internal driver which implement client call to Stx Standalone instance +class StxSaClientImp(object): + def __init__(self, stx_client=None): + super().__init__() + self.stxclient = stx_client if stx_client else self.getStxClient() + + def getStxClient(self): + os_client_args = config.get_stx_access_info() + config_client = get_client(**os_client_args) + return config_client + + def getInstanceInfo(self) -> ocloudModel.StxGenericModel: + systems = self.stxclient.isystem.list() + logger.debug('systems:' + str(systems[0].to_dict())) + return ocloudModel.StxGenericModel( + ResourceTypeEnum.OCLOUD, systems[0]) if systems else None + + def getPserverList(self, **filters) -> List[ocloudModel.StxGenericModel]: + # resourcepoolid = filters.get("resourcepoolid", None) + hosts = self.stxclient.ihost.list() + logger.debug('host 1:' + str(hosts[0].to_dict())) + return [ocloudModel.StxGenericModel( + ResourceTypeEnum.PSERVER, self._hostconverter(host)) + for host in hosts if host and host.availability == 'available'] + + def getPserver(self, id) -> ocloudModel.StxGenericModel: + host = self.stxclient.ihost.get(id) + logger.debug('host:' + str(host.to_dict())) + return ocloudModel.StxGenericModel( + ResourceTypeEnum.PSERVER, self._hostconverter(host)) + + def getK8sList(self, **filters) -> List[ocloudModel.StxGenericModel]: + k8sclusters = self.stxclient.kube_cluster.list() + logger.debug('k8sresources[0]:' + str(k8sclusters[0].to_dict())) + return [ocloudModel.StxGenericModel( + ResourceTypeEnum.DMS, + self._k8sconverter(k8sres), self._k8shasher(k8sres)) + for k8sres in k8sclusters if k8sres] + + def getK8sDetail(self, name) -> ocloudModel.StxGenericModel: + if not name: + k8sclusters = self.stxclient.kube_cluster.list() + # logger.debug("k8sresources[0]:" + str(k8sclusters[0].to_dict())) + k8scluster = k8sclusters.pop() + else: + k8scluster = self.stxclient.kube_cluster.get(name) + + if not k8scluster: + return None + logger.debug('k8sresource:' + str(k8scluster.to_dict())) + return ocloudModel.StxGenericModel( + ResourceTypeEnum.DMS, + self._k8sconverter(k8scluster), self._k8shasher(k8scluster)) + + def getCpuList(self, **filters) -> List[ocloudModel.StxGenericModel]: + hostid = filters.get('hostid', None) + assert (hostid is not None), 'missing hostid to query icpu list' + cpulist = self.stxclient.icpu.list(hostid) + return [ocloudModel.StxGenericModel( + ResourceTypeEnum.PSERVER_CPU, + self._cpuconverter(cpures)) for cpures in cpulist if cpures] + + def getCpu(self, id) -> ocloudModel.StxGenericModel: + cpuinfo = self.stxclient.icpu.get(id) + return ocloudModel.StxGenericModel( + ResourceTypeEnum.PSERVER_CPU, self._cpuconverter(cpuinfo)) + + def getMemList(self, **filters) -> List[ocloudModel.StxGenericModel]: + hostid = filters.get('hostid', None) + assert (hostid is not None), 'missing hostid to query imem list' + memlist = self.stxclient.imemory.list(hostid) + return [ocloudModel.StxGenericModel( + ResourceTypeEnum.PSERVER_RAM, + self._memconverter(memories)) for memories in memlist if memories] + + def getMem(self, id) -> ocloudModel.StxGenericModel: + meminfo = self.stxclient.imemory.get(id) + return ocloudModel.StxGenericModel( + ResourceTypeEnum.PSERVER_RAM, self._memconverter(meminfo)) + + def getEthernetList(self, **filters) -> List[ocloudModel.StxGenericModel]: + hostid = filters.get('hostid', None) + assert (hostid is not None), 'missing hostid to query port list' + ethlist = self.stxclient.ethernet_port.list(hostid) + return [ocloudModel.StxGenericModel( + ResourceTypeEnum.PSERVER_ETH, + self._ethconverter(eth)) for eth in ethlist if eth] + + def getEthernet(self, id) -> ocloudModel.StxGenericModel: + ethinfo = self.stxclient.ethernet_port.get(id) + return ocloudModel.StxGenericModel( + ResourceTypeEnum.PSERVER_ETH, self._ethconverter(ethinfo)) + + def getIfList(self, **filters) -> List[ocloudModel.StxGenericModel]: + hostid = filters.get('hostid', None) + assert (hostid is not None), 'missing hostid to query iinterface list' + iflist = self.stxclient.iinterface.list(hostid) + return [ocloudModel.StxGenericModel( + ResourceTypeEnum.PSERVER_IF, + self._ifconverter(ifs)) for ifs in iflist if ifs] + + def getIf(self, id) -> ocloudModel.StxGenericModel: + ifinfo = self.stxclient.iinterface.get(id) + return ocloudModel.StxGenericModel( + ResourceTypeEnum.PSERVER_IF, self._ifconverter(ifinfo)) + + def getPortList(self, **filters) -> List[ocloudModel.StxGenericModel]: + ifid = filters.get('interfaceid', None) + assert (ifid is not None), 'missing interface id to query port list' + portlist = self.stxclient.iinterface.list_ports(ifid) + return [ocloudModel.StxGenericModel( + ResourceTypeEnum.PSERVER_IF_PORT, + port) for port in portlist if port] + + def getPort(self, id) -> ocloudModel.StxGenericModel: + portinfo = self.stxclient.port.get(id) + return ocloudModel.StxGenericModel( + ResourceTypeEnum.PSERVER_IF_PORT, portinfo) + + def _getIsystems(self): + return self.stxclient.isystem.list() + + def _getIsystem(self, id=None): + if id: + return self.stxclient.isystem.get(id) + else: + isystems = self.stxclient.isystem.list() + if len(isystems) != 1 and not id: + raise Exception('No system uuid was provided and ' + 'more than one system exists in the account.') + return isystems[0] + + @ staticmethod + def _hostconverter(host): + setattr(host, 'name', host.hostname) + return host + + @ staticmethod + def _cpuconverter(cpu): + setattr(cpu, 'name', cpu.ihost_uuid.split( + '-', 1)[0] + '-cpu-'+str(cpu.cpu)) + return cpu + + @ staticmethod + def _memconverter(mem): + setattr(mem, 'name', mem.ihost_uuid.split('-', 1)[0] + + '-mem-node-'+str(mem.numa_node)) + return mem + + @ staticmethod + def _ethconverter(eth): + setattr(eth, 'name', eth.host_uuid.split('-', 1)[0] + '-'+eth.name) + setattr(eth, 'updated_at', None) + setattr(eth, 'created_at', None) + return eth + + @ staticmethod + def _ifconverter(ifs): + setattr(ifs, 'name', ifs.ihost_uuid.split('-', 1)[0] + '-'+ifs.ifname) + setattr(ifs, 'updated_at', None) + setattr(ifs, 'created_at', None) + return ifs + + @ staticmethod + def _k8sconverter(cluster): + setattr(cluster, 'name', cluster.cluster_name) + setattr(cluster, 'uuid', + uuid.uuid3(uuid.NAMESPACE_URL, cluster.cluster_name)) + setattr(cluster, 'updated_at', None) + setattr(cluster, 'created_at', None) + setattr(cluster, 'events', []) + logger.debug('k8s cluster name/uuid:' + + cluster.name + '/' + str(cluster.uuid)) + return cluster + + @ staticmethod + def _k8shasher(cluster): + return str(hash((cluster.cluster_name, + cluster.cluster_api_endpoint, cluster.admin_user))) diff --git a/o2ims/adapter/clients/orm_stx.py b/o2ims/adapter/clients/orm_stx.py index 2d58b8b..d29b954 100644 --- a/o2ims/adapter/clients/orm_stx.py +++ b/o2ims/adapter/clients/orm_stx.py @@ -1,64 +1,64 @@ -# Copyright (C) 2021 Wind River Systems, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# from datetime import datetime -from sqlalchemy import ( - Table, - MetaData, - Column, - # Integer, - String, - # Date, - DateTime, - # engine, - # ForeignKey, - # event, - Enum -) - -# from sqlalchemy.orm import mapper - -# from o2ims.domain import stx_object as ocloudModel - -from o2common.service.unit_of_work import AbstractUnitOfWork -# from o2ims.adapter.unit_of_work import SqlAlchemyUnitOfWork -from o2ims.domain.resource_type import ResourceTypeEnum - -from o2common.helper import o2logging -logger = o2logging.get_logger(__name__) - -metadata = MetaData() - -stxobject = Table( - "stxcache", - metadata, - Column("id", String(255), primary_key=True), - Column("type", Enum(ResourceTypeEnum, native_enum=False)), - Column("name", String(255)), - Column("updatetime", DateTime), - Column("createtime", DateTime), - Column("hash", String(255)), - Column("content", String) -) - - -def start_o2ims_stx_mappers(uow: AbstractUnitOfWork): - return - # logger.info("Starting O2 IMS Stx mappers") - # mapper(ocloudModel.StxGenericModel, stxobject) - - # with uow: - # engine1 = uow.session.get_bind() - # metadata.create_all(engine1) - # uow.commit() +# Copyright (C) 2021 Wind River Systems, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# from datetime import datetime +from sqlalchemy import ( + Table, + MetaData, + Column, + # Integer, + String, + # Date, + DateTime, + # engine, + # ForeignKey, + # event, + Enum +) + +# from sqlalchemy.orm import mapper + +# from o2ims.domain import stx_object as ocloudModel + +from o2common.service.unit_of_work import AbstractUnitOfWork +# from o2ims.adapter.unit_of_work import SqlAlchemyUnitOfWork +from o2ims.domain.resource_type import ResourceTypeEnum + +from o2common.helper import o2logging +logger = o2logging.get_logger(__name__) + +metadata = MetaData() + +stxobject = Table( + "stxcache", + metadata, + Column("id", String(255), primary_key=True), + Column("type", Enum(ResourceTypeEnum, native_enum=False)), + Column("name", String(255)), + Column("updatetime", DateTime), + Column("createtime", DateTime), + Column("hash", String(255)), + Column("content", String) +) + + +def start_o2ims_stx_mappers(uow: AbstractUnitOfWork): + return + # logger.info("Starting O2 IMS Stx mappers") + # mapper(ocloudModel.StxGenericModel, stxobject) + + # with uow: + # engine1 = uow.session.get_bind() + # metadata.create_all(engine1) + # uow.commit() diff --git a/o2ims/adapter/orm.py b/o2ims/adapter/orm.py index 43b48b0..45ec4d8 100644 --- a/o2ims/adapter/orm.py +++ b/o2ims/adapter/orm.py @@ -1,199 +1,199 @@ -# Copyright (C) 2021 Wind River Systems, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# from typing_extensions import Required -from retry import retry -from sqlalchemy import ( - Table, - MetaData, - Column, - Integer, - String, - Text, - Enum, - # Date, - DateTime, - ForeignKey, - # Boolean, - # engine, - # event, - exc, -) - -from sqlalchemy.orm import mapper, relationship -# from sqlalchemy.sql.sqltypes import Integer - -from o2ims.domain import ocloud as ocloudModel -from o2ims.domain import subscription_obj as subModel -from o2ims.domain import configuration_obj as confModel -from o2ims.domain.resource_type import ResourceTypeEnum - -from o2common.helper import o2logging -logger = o2logging.get_logger(__name__) - -metadata = MetaData() - -ocloud = Table( - "ocloud", - metadata, - Column("updatetime", DateTime), - Column("createtime", DateTime), - Column("hash", String(255)), - Column("version_number", Integer), - - Column("oCloudId", String(255), primary_key=True), - Column("globalcloudId", String(255)), - Column("name", String(255)), - Column("description", String(255)), - Column("infrastructureManagementServiceEndpoint", String(255)) - # Column("extensions", String(1024)) -) - -resourcetype = Table( - "resourcetype", - metadata, - Column("updatetime", DateTime), - Column("createtime", DateTime), - Column("hash", String(255)), - - Column("resourceTypeId", String(255), primary_key=True), - Column("resourceTypeEnum", Enum( - ResourceTypeEnum, native_enum=False), nullable=False), - Column("oCloudId", ForeignKey("ocloud.oCloudId")), - Column("name", String(255)), - Column("vendor", String(255)), - Column("model", String(255)), - Column("version", String(255)), - Column("description", String(255)), - # Column("extensions", String(1024)) -) - -resourcepool = Table( - "resourcepool", - metadata, - Column("updatetime", DateTime), - Column("createtime", DateTime), - Column("hash", String(255)), - Column("version_number", Integer), - - Column("resourcePoolId", String(255), primary_key=True), - Column("oCloudId", ForeignKey("ocloud.oCloudId")), - Column("globalLocationId", String(255)), - Column("name", String(255)), - Column("location", String(255)), - Column("description", String(255)), - # Column("resources", String(1024)) - # Column("extensions", String(1024)) -) - -resource = Table( - "resource", - metadata, - Column("updatetime", DateTime), - Column("createtime", DateTime), - Column("hash", String(255)), - Column("version_number", Integer), - - Column("resourceId", String(255), primary_key=True), - Column("resourceTypeId", ForeignKey("resourcetype.resourceTypeId")), - Column("resourcePoolId", ForeignKey("resourcepool.resourcePoolId")), - Column("name", String(255)), - # Column("globalAssetId", String(255)), - Column("parentId", String(255)), - Column("description", String(255)), - Column("elements", Text()) - # Column("extensions", String(1024)) -) - -deploymentmanager = Table( - "deploymentmanager", - metadata, - Column("updatetime", DateTime), - Column("createtime", DateTime), - Column("hash", String(255)), - Column("version_number", Integer), - - Column("deploymentManagerId", String(255), primary_key=True), - Column("oCloudId", ForeignKey("ocloud.oCloudId")), - Column("name", String(255)), - Column("description", String(255)), - Column("deploymentManagementServiceEndpoint", String(255)), - Column("supportedLocations", String(255)), - Column("capabilities", String(255)), - Column("capacity", String(255)), - # Column("extensions", String(1024)) -) - -subscription = Table( - "subscription", - metadata, - Column("updatetime", DateTime), - Column("createtime", DateTime), - Column("hash", String(255)), - Column("version_number", Integer), - - Column("subscriptionId", String(255), primary_key=True), - Column("callback", String(255)), - Column("consumerSubscriptionId", String(255)), - Column("filter", String(255)), -) - -configuration = Table( - "configuration", - metadata, - Column("updatetime", DateTime), - Column("createtime", DateTime), - - Column("configurationId", String(255), primary_key=True), - Column("conftype", String(255)), - Column("callback", String(255)), - Column("status", String(255)), - Column("comments", String(255)), -) - - -@retry((exc.IntegrityError), tries=3, delay=2) -def wait_for_metadata_ready(engine): - # wait for mapper ready - metadata.create_all(engine, checkfirst=True) - logger.info("metadata is ready") - - -def start_o2ims_mappers(engine=None): - logger.info("Starting O2 IMS mappers") - - dm_mapper = mapper(ocloudModel.DeploymentManager, deploymentmanager) - resourcepool_mapper = mapper(ocloudModel.ResourcePool, resourcepool) - resourcetype_mapper = mapper(ocloudModel.ResourceType, resourcetype) - mapper( - ocloudModel.Ocloud, - ocloud, - properties={ - "deploymentManagers": relationship(dm_mapper), - "resourceTypes": relationship(resourcetype_mapper), - "resourcePools": relationship(resourcepool_mapper) - }) - mapper( - ocloudModel.Resource, - resource, - properties={ - "resourceTypes": relationship(resourcetype_mapper), - "resourcePools": relationship(resourcepool_mapper) - } - ) - mapper(subModel.Subscription, subscription) - mapper(confModel.Configuration, configuration) - - if engine is not None: - wait_for_metadata_ready(engine) +# Copyright (C) 2021 Wind River Systems, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# from typing_extensions import Required +from retry import retry +from sqlalchemy import ( + Table, + MetaData, + Column, + Integer, + String, + Text, + Enum, + # Date, + DateTime, + ForeignKey, + # Boolean, + # engine, + # event, + exc, +) + +from sqlalchemy.orm import mapper, relationship +# from sqlalchemy.sql.sqltypes import Integer + +from o2ims.domain import ocloud as ocloudModel +from o2ims.domain import subscription_obj as subModel +from o2ims.domain import configuration_obj as confModel +from o2ims.domain.resource_type import ResourceTypeEnum + +from o2common.helper import o2logging +logger = o2logging.get_logger(__name__) + +metadata = MetaData() + +ocloud = Table( + "ocloud", + metadata, + Column("updatetime", DateTime), + Column("createtime", DateTime), + Column("hash", String(255)), + Column("version_number", Integer), + + Column("oCloudId", String(255), primary_key=True), + Column("globalcloudId", String(255)), + Column("name", String(255)), + Column("description", String(255)), + Column("infrastructureManagementServiceEndpoint", String(255)) + # Column("extensions", String(1024)) +) + +resourcetype = Table( + "resourcetype", + metadata, + Column("updatetime", DateTime), + Column("createtime", DateTime), + Column("hash", String(255)), + + Column("resourceTypeId", String(255), primary_key=True), + Column("resourceTypeEnum", Enum( + ResourceTypeEnum, native_enum=False), nullable=False), + Column("oCloudId", ForeignKey("ocloud.oCloudId")), + Column("name", String(255)), + Column("vendor", String(255)), + Column("model", String(255)), + Column("version", String(255)), + Column("description", String(255)), + # Column("extensions", String(1024)) +) + +resourcepool = Table( + "resourcepool", + metadata, + Column("updatetime", DateTime), + Column("createtime", DateTime), + Column("hash", String(255)), + Column("version_number", Integer), + + Column("resourcePoolId", String(255), primary_key=True), + Column("oCloudId", ForeignKey("ocloud.oCloudId")), + Column("globalLocationId", String(255)), + Column("name", String(255)), + Column("location", String(255)), + Column("description", String(255)), + # Column("resources", String(1024)) + # Column("extensions", String(1024)) +) + +resource = Table( + "resource", + metadata, + Column("updatetime", DateTime), + Column("createtime", DateTime), + Column("hash", String(255)), + Column("version_number", Integer), + + Column("resourceId", String(255), primary_key=True), + Column("resourceTypeId", ForeignKey("resourcetype.resourceTypeId")), + Column("resourcePoolId", ForeignKey("resourcepool.resourcePoolId")), + Column("name", String(255)), + # Column("globalAssetId", String(255)), + Column("parentId", String(255)), + Column("description", String(255)), + Column("elements", Text()) + # Column("extensions", String(1024)) +) + +deploymentmanager = Table( + "deploymentmanager", + metadata, + Column("updatetime", DateTime), + Column("createtime", DateTime), + Column("hash", String(255)), + Column("version_number", Integer), + + Column("deploymentManagerId", String(255), primary_key=True), + Column("oCloudId", ForeignKey("ocloud.oCloudId")), + Column("name", String(255)), + Column("description", String(255)), + Column("deploymentManagementServiceEndpoint", String(255)), + Column("supportedLocations", String(255)), + Column("capabilities", String(255)), + Column("capacity", String(255)), + # Column("extensions", String(1024)) +) + +subscription = Table( + "subscription", + metadata, + Column("updatetime", DateTime), + Column("createtime", DateTime), + Column("hash", String(255)), + Column("version_number", Integer), + + Column("subscriptionId", String(255), primary_key=True), + Column("callback", String(255)), + Column("consumerSubscriptionId", String(255)), + Column("filter", String(255)), +) + +configuration = Table( + "configuration", + metadata, + Column("updatetime", DateTime), + Column("createtime", DateTime), + + Column("configurationId", String(255), primary_key=True), + Column("conftype", String(255)), + Column("callback", String(255)), + Column("status", String(255)), + Column("comments", String(255)), +) + + +@retry((exc.IntegrityError), tries=3, delay=2) +def wait_for_metadata_ready(engine): + # wait for mapper ready + metadata.create_all(engine, checkfirst=True) + logger.info("metadata is ready") + + +def start_o2ims_mappers(engine=None): + logger.info("Starting O2 IMS mappers") + + dm_mapper = mapper(ocloudModel.DeploymentManager, deploymentmanager) + resourcepool_mapper = mapper(ocloudModel.ResourcePool, resourcepool) + resourcetype_mapper = mapper(ocloudModel.ResourceType, resourcetype) + mapper( + ocloudModel.Ocloud, + ocloud, + properties={ + "deploymentManagers": relationship(dm_mapper), + "resourceTypes": relationship(resourcetype_mapper), + "resourcePools": relationship(resourcepool_mapper) + }) + mapper( + ocloudModel.Resource, + resource, + properties={ + "resourceTypes": relationship(resourcetype_mapper), + "resourcePools": relationship(resourcepool_mapper) + } + ) + mapper(subModel.Subscription, subscription) + mapper(confModel.Configuration, configuration) + + if engine is not None: + wait_for_metadata_ready(engine) diff --git a/o2ims/domain/__init__.py b/o2ims/domain/__init__.py index b514342..813897e 100644 --- a/o2ims/domain/__init__.py +++ b/o2ims/domain/__init__.py @@ -1,13 +1,13 @@ -# Copyright (C) 2021 Wind River Systems, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. +# Copyright (C) 2021 Wind River Systems, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. diff --git a/o2ims/domain/ocloud.py b/o2ims/domain/ocloud.py index d60b08e..1775aa2 100644 --- a/o2ims/domain/ocloud.py +++ b/o2ims/domain/ocloud.py @@ -1,143 +1,143 @@ -# Copyright (C) 2021 Wind River Systems, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from __future__ import annotations -import json - -from o2common.domain.base import AgRoot, Serializer -# from dataclasses import dataclass -# from datetime import date -# from typing import Optional, List, Set -from .resource_type import ResourceTypeEnum -# from uuid import UUID - - -class DeploymentManager(AgRoot, Serializer): - def __init__(self, id: str, name: str, ocloudid: str, - dmsendpoint: str, description: str = '', - supportedLocations: str = '', capabilities: str = '', - capacity: str = '') -> None: - super().__init__() - self.deploymentManagerId = id - self.version_number = 0 - self.oCloudId = ocloudid - self.name = name - self.description = description - self.deploymentManagementServiceEndpoint = dmsendpoint - self.supportedLocations = supportedLocations - self.capabilities = capabilities - self.capacity = capacity - self.extensions = [] - - -class ResourcePool(AgRoot, Serializer): - def __init__(self, id: str, name: str, location: str, - ocloudid: str, gLocationId: str = '', - description: str = '') -> None: - super().__init__() - self.resourcePoolId = id - self.version_number = 0 - self.oCloudId = ocloudid - self.globalLocationId = gLocationId - self.name = name - self.location = location - self.description = description - self.extensions = [] - - -class ResourceType(AgRoot, Serializer): - def __init__(self, typeid: str, name: str, typeEnum: ResourceTypeEnum, - ocloudid: str, vender: str = '', model: str = '', - version: str = '', - description: str = '') -> None: - super().__init__() - self.resourceTypeId = typeid - self.version_number = 0 - self.oCloudId = ocloudid - self.resourceTypeEnum = typeEnum - self.name = name - self.vender = vender - self.model = model - self.version = version - self.description = description - self.extensions = [] - - -class Resource(AgRoot, Serializer): - def __init__(self, resourceId: str, resourceTypeId: str, - resourcePoolId: str, name: str, parentId: str = '', - gAssetId: str = '', elements: str = '', - description: str = '') -> None: - super().__init__() - self.resourceId = resourceId - self.version_number = 0 - self.resourceTypeId = resourceTypeId - self.resourcePoolId = resourcePoolId - self.name = name - self.globalAssetId = gAssetId - self.parentId = parentId - self.elements = elements - self.description = description - self.children = [] - self.extensions = [] - - def set_children(self, children: list): - self.children = children - - def set_resource_type_name(self, resource_type_name: str): - self.resourceTypeName = resource_type_name - - def serialize(self): - d = Serializer.serialize(self) - - if 'elements' in d and d['elements'] != '': - d['elements'] = json.loads(d['elements']) - - if not hasattr(self, 'children') or len(self.children) == 0: - return d - else: - d['children'] = [] - - for child in self.children: - d['children'].append(child.serialize()) - return d - - -class Ocloud(AgRoot, Serializer): - def __init__(self, ocloudid: str, name: str, imsendpoint: str, - globalcloudId: str = '', - description: str = '', version_number: int = 0) -> None: - super().__init__() - self.oCloudId = ocloudid - self.globalcloudId = globalcloudId - self.version_number = version_number - self.name = name - self.description = description - self.infrastructureManagementServiceEndpoint = imsendpoint - self.resourcePools = [] - self.deploymentManagers = [] - self.resourceTypes = [] - self.extensions = [] - - # def addDeploymentManager(self, - # deploymentManager: DeploymentManager): - - # deploymentManager.oCloudId = self.oCloudId - # old = filter( - # lambda x: x.deploymentManagerId == - # deploymentManager.deploymentManagerId, - # self.deploymentManagers) - # for o in old or []: - # self.deploymentManagers.remove(o) - # self.deploymentManagers.append(deploymentManager) +# Copyright (C) 2021 Wind River Systems, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from __future__ import annotations +import json + +from o2common.domain.base import AgRoot, Serializer +# from dataclasses import dataclass +# from datetime import date +# from typing import Optional, List, Set +from .resource_type import ResourceTypeEnum +# from uuid import UUID + + +class DeploymentManager(AgRoot, Serializer): + def __init__(self, id: str, name: str, ocloudid: str, + dmsendpoint: str, description: str = '', + supportedLocations: str = '', capabilities: str = '', + capacity: str = '') -> None: + super().__init__() + self.deploymentManagerId = id + self.version_number = 0 + self.oCloudId = ocloudid + self.name = name + self.description = description + self.deploymentManagementServiceEndpoint = dmsendpoint + self.supportedLocations = supportedLocations + self.capabilities = capabilities + self.capacity = capacity + self.extensions = [] + + +class ResourcePool(AgRoot, Serializer): + def __init__(self, id: str, name: str, location: str, + ocloudid: str, gLocationId: str = '', + description: str = '') -> None: + super().__init__() + self.resourcePoolId = id + self.version_number = 0 + self.oCloudId = ocloudid + self.globalLocationId = gLocationId + self.name = name + self.location = location + self.description = description + self.extensions = [] + + +class ResourceType(AgRoot, Serializer): + def __init__(self, typeid: str, name: str, typeEnum: ResourceTypeEnum, + ocloudid: str, vender: str = '', model: str = '', + version: str = '', + description: str = '') -> None: + super().__init__() + self.resourceTypeId = typeid + self.version_number = 0 + self.oCloudId = ocloudid + self.resourceTypeEnum = typeEnum + self.name = name + self.vender = vender + self.model = model + self.version = version + self.description = description + self.extensions = [] + + +class Resource(AgRoot, Serializer): + def __init__(self, resourceId: str, resourceTypeId: str, + resourcePoolId: str, name: str, parentId: str = '', + gAssetId: str = '', elements: str = '', + description: str = '') -> None: + super().__init__() + self.resourceId = resourceId + self.version_number = 0 + self.resourceTypeId = resourceTypeId + self.resourcePoolId = resourcePoolId + self.name = name + self.globalAssetId = gAssetId + self.parentId = parentId + self.elements = elements + self.description = description + self.children = [] + self.extensions = [] + + def set_children(self, children: list): + self.children = children + + def set_resource_type_name(self, resource_type_name: str): + self.resourceTypeName = resource_type_name + + def serialize(self): + d = Serializer.serialize(self) + + if 'elements' in d and d['elements'] != '': + d['elements'] = json.loads(d['elements']) + + if not hasattr(self, 'children') or len(self.children) == 0: + return d + else: + d['children'] = [] + + for child in self.children: + d['children'].append(child.serialize()) + return d + + +class Ocloud(AgRoot, Serializer): + def __init__(self, ocloudid: str, name: str, imsendpoint: str, + globalcloudId: str = '', + description: str = '', version_number: int = 0) -> None: + super().__init__() + self.oCloudId = ocloudid + self.globalcloudId = globalcloudId + self.version_number = version_number + self.name = name + self.description = description + self.infrastructureManagementServiceEndpoint = imsendpoint + self.resourcePools = [] + self.deploymentManagers = [] + self.resourceTypes = [] + self.extensions = [] + + # def addDeploymentManager(self, + # deploymentManager: DeploymentManager): + + # deploymentManager.oCloudId = self.oCloudId + # old = filter( + # lambda x: x.deploymentManagerId == + # deploymentManager.deploymentManagerId, + # self.deploymentManagers) + # for o in old or []: + # self.deploymentManagers.remove(o) + # self.deploymentManagers.append(deploymentManager) diff --git a/o2ims/domain/ocloud_repo.py b/o2ims/domain/ocloud_repo.py index 1c63de8..811e85c 100644 --- a/o2ims/domain/ocloud_repo.py +++ b/o2ims/domain/ocloud_repo.py @@ -1,203 +1,203 @@ -# Copyright (C) 2021 Wind River Systems, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -import abc -from typing import List, Set -from o2ims.domain import ocloud - - -class OcloudRepository(abc.ABC): - def __init__(self): - self.seen = set() # type: Set[ocloud.Ocloud] - - def add(self, ocloud: ocloud.Ocloud): - self._add(ocloud) - self.seen.add(ocloud) - - def get(self, ocloud_id) -> ocloud.Ocloud: - ocloud = self._get(ocloud_id) - if ocloud: - self.seen.add(ocloud) - return ocloud - - def list(self) -> List[ocloud.Ocloud]: - return self._list() - - def update(self, ocloud: ocloud.Ocloud): - self._update(ocloud) - self.seen.add(ocloud) - - # def update_fields(self, ocloudid: str, updatefields: dict): - # self._update(ocloudid, updatefields) - - @abc.abstractmethod - def _add(self, ocloud: ocloud.Ocloud): - raise NotImplementedError - - @abc.abstractmethod - def _get(self, ocloud_id) -> ocloud.Ocloud: - raise NotImplementedError - - @abc.abstractmethod - def _update(self, ocloud: ocloud.Ocloud): - raise NotImplementedError - - -class ResourceTypeRepository(abc.ABC): - def __init__(self): - self.seen = set() # type: Set[ocloud.ResourceType] - - def add(self, resource_type: ocloud.ResourceType): - self._add(resource_type) - self.seen.add(resource_type) - - def get(self, resource_type_id) -> ocloud.ResourceType: - resource_type = self._get(resource_type_id) - if resource_type: - self.seen.add(resource_type) - return resource_type - - def get_by_name(self, resource_type_name) -> ocloud.ResourceType: - resource_type = self._get_by_name(resource_type_name) - if resource_type: - self.seen.add(resource_type) - return resource_type - - def list(self) -> List[ocloud.ResourceType]: - return self._list() - - def update(self, resource_type: ocloud.ResourceType): - self._update(resource_type) - self.seen.add(resource_type) - - @abc.abstractmethod - def _add(self, resource_type: ocloud.ResourceType): - raise NotImplementedError - - @abc.abstractmethod - def _get(self, resource_type_id) -> ocloud.ResourceType: - raise NotImplementedError - - @abc.abstractmethod - def _get_by_name(self, resource_type_name) -> ocloud.ResourceType: - raise NotImplementedError - - @abc.abstractmethod - def _update(self, resource_type: ocloud.ResourceType): - raise NotImplementedError - - -class ResourcePoolRepository(abc.ABC): - def __init__(self): - self.seen = set() # type: Set[ocloud.ResourcePool] - - def add(self, resource_pool: ocloud.ResourcePool): - self._add(resource_pool) - self.seen.add(resource_pool) - - def get(self, resource_pool_id) -> ocloud.ResourcePool: - resource_pool = self._get(resource_pool_id) - if resource_pool: - self.seen.add(resource_pool) - return resource_pool - - def list(self) -> List[ocloud.ResourcePool]: - return self._list() - - def update(self, resource_pool: ocloud.ResourcePool): - self._update(resource_pool) - self.seen.add(resource_pool) - - @abc.abstractmethod - def _add(self, resource_pool: ocloud.ResourcePool): - raise NotImplementedError - - @abc.abstractmethod - def _get(self, resource_pool_id) -> ocloud.ResourcePool: - raise NotImplementedError - - @abc.abstractmethod - def _update(self, resource_pool: ocloud.ResourcePool): - raise NotImplementedError - - -class ResourceRepository(abc.ABC): - def __init__(self): - self.seen = set() # type: Set[ocloud.Resource] - - def add(self, resource: ocloud.Resource): - self._add(resource) - self.seen.add(resource) - - def get(self, resource_id) -> ocloud.Resource: - resource = self._get(resource_id) - if resource: - self.seen.add(resource) - return resource - - def list(self, resourcepool_id, **kwargs) -> List[ocloud.Resource]: - return self._list(resourcepool_id, **kwargs) - - def update(self, resource: ocloud.Resource): - self._update(resource) - self.seen.add(resource) - - @abc.abstractmethod - def _add(self, resource: ocloud.Resource): - raise NotImplementedError - - @abc.abstractmethod - def _get(self, resource_id) -> ocloud.Resource: - raise NotImplementedError - - @abc.abstractmethod - def _list(self, resourcepool_id, **kwargs) -> ocloud.Resource: - raise NotImplementedError - - @abc.abstractmethod - def _update(self, resource: ocloud.Resource): - raise NotImplementedError - - -class DeploymentManagerRepository(abc.ABC): - def __init__(self): - self.seen = set() # type: Set[ocloud.DeploymentManager] - - def add(self, deployment_manager: ocloud.DeploymentManager): - self._add(deployment_manager) - self.seen.add(deployment_manager) - - def get(self, deployment_manager_id) -> ocloud.DeploymentManager: - deployment_manager = self._get(deployment_manager_id) - if deployment_manager: - self.seen.add(deployment_manager) - return deployment_manager - - def list(self) -> List[ocloud.DeploymentManager]: - return self._list() - - def update(self, deployment_manager: ocloud.DeploymentManager): - self._update(deployment_manager) - - @abc.abstractmethod - def _add(self, deployment_manager: ocloud.DeploymentManager): - raise NotImplementedError - - @abc.abstractmethod - def _get(self, deployment_manager_id) -> ocloud.DeploymentManager: - raise NotImplementedError - - @abc.abstractmethod - def _update(self, deployment_manager: ocloud.DeploymentManager): - raise NotImplementedError +# Copyright (C) 2021 Wind River Systems, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import abc +from typing import List, Set +from o2ims.domain import ocloud + + +class OcloudRepository(abc.ABC): + def __init__(self): + self.seen = set() # type: Set[ocloud.Ocloud] + + def add(self, ocloud: ocloud.Ocloud): + self._add(ocloud) + self.seen.add(ocloud) + + def get(self, ocloud_id) -> ocloud.Ocloud: + ocloud = self._get(ocloud_id) + if ocloud: + self.seen.add(ocloud) + return ocloud + + def list(self) -> List[ocloud.Ocloud]: + return self._list() + + def update(self, ocloud: ocloud.Ocloud): + self._update(ocloud) + self.seen.add(ocloud) + + # def update_fields(self, ocloudid: str, updatefields: dict): + # self._update(ocloudid, updatefields) + + @abc.abstractmethod + def _add(self, ocloud: ocloud.Ocloud): + raise NotImplementedError + + @abc.abstractmethod + def _get(self, ocloud_id) -> ocloud.Ocloud: + raise NotImplementedError + + @abc.abstractmethod + def _update(self, ocloud: ocloud.Ocloud): + raise NotImplementedError + + +class ResourceTypeRepository(abc.ABC): + def __init__(self): + self.seen = set() # type: Set[ocloud.ResourceType] + + def add(self, resource_type: ocloud.ResourceType): + self._add(resource_type) + self.seen.add(resource_type) + + def get(self, resource_type_id) -> ocloud.ResourceType: + resource_type = self._get(resource_type_id) + if resource_type: + self.seen.add(resource_type) + return resource_type + + def get_by_name(self, resource_type_name) -> ocloud.ResourceType: + resource_type = self._get_by_name(resource_type_name) + if resource_type: + self.seen.add(resource_type) + return resource_type + + def list(self) -> List[ocloud.ResourceType]: + return self._list() + + def update(self, resource_type: ocloud.ResourceType): + self._update(resource_type) + self.seen.add(resource_type) + + @abc.abstractmethod + def _add(self, resource_type: ocloud.ResourceType): + raise NotImplementedError + + @abc.abstractmethod + def _get(self, resource_type_id) -> ocloud.ResourceType: + raise NotImplementedError + + @abc.abstractmethod + def _get_by_name(self, resource_type_name) -> ocloud.ResourceType: + raise NotImplementedError + + @abc.abstractmethod + def _update(self, resource_type: ocloud.ResourceType): + raise NotImplementedError + + +class ResourcePoolRepository(abc.ABC): + def __init__(self): + self.seen = set() # type: Set[ocloud.ResourcePool] + + def add(self, resource_pool: ocloud.ResourcePool): + self._add(resource_pool) + self.seen.add(resource_pool) + + def get(self, resource_pool_id) -> ocloud.ResourcePool: + resource_pool = self._get(resource_pool_id) + if resource_pool: + self.seen.add(resource_pool) + return resource_pool + + def list(self) -> List[ocloud.ResourcePool]: + return self._list() + + def update(self, resource_pool: ocloud.ResourcePool): + self._update(resource_pool) + self.seen.add(resource_pool) + + @abc.abstractmethod + def _add(self, resource_pool: ocloud.ResourcePool): + raise NotImplementedError + + @abc.abstractmethod + def _get(self, resource_pool_id) -> ocloud.ResourcePool: + raise NotImplementedError + + @abc.abstractmethod + def _update(self, resource_pool: ocloud.ResourcePool): + raise NotImplementedError + + +class ResourceRepository(abc.ABC): + def __init__(self): + self.seen = set() # type: Set[ocloud.Resource] + + def add(self, resource: ocloud.Resource): + self._add(resource) + self.seen.add(resource) + + def get(self, resource_id) -> ocloud.Resource: + resource = self._get(resource_id) + if resource: + self.seen.add(resource) + return resource + + def list(self, resourcepool_id, **kwargs) -> List[ocloud.Resource]: + return self._list(resourcepool_id, **kwargs) + + def update(self, resource: ocloud.Resource): + self._update(resource) + self.seen.add(resource) + + @abc.abstractmethod + def _add(self, resource: ocloud.Resource): + raise NotImplementedError + + @abc.abstractmethod + def _get(self, resource_id) -> ocloud.Resource: + raise NotImplementedError + + @abc.abstractmethod + def _list(self, resourcepool_id, **kwargs) -> ocloud.Resource: + raise NotImplementedError + + @abc.abstractmethod + def _update(self, resource: ocloud.Resource): + raise NotImplementedError + + +class DeploymentManagerRepository(abc.ABC): + def __init__(self): + self.seen = set() # type: Set[ocloud.DeploymentManager] + + def add(self, deployment_manager: ocloud.DeploymentManager): + self._add(deployment_manager) + self.seen.add(deployment_manager) + + def get(self, deployment_manager_id) -> ocloud.DeploymentManager: + deployment_manager = self._get(deployment_manager_id) + if deployment_manager: + self.seen.add(deployment_manager) + return deployment_manager + + def list(self) -> List[ocloud.DeploymentManager]: + return self._list() + + def update(self, deployment_manager: ocloud.DeploymentManager): + self._update(deployment_manager) + + @abc.abstractmethod + def _add(self, deployment_manager: ocloud.DeploymentManager): + raise NotImplementedError + + @abc.abstractmethod + def _get(self, deployment_manager_id) -> ocloud.DeploymentManager: + raise NotImplementedError + + @abc.abstractmethod + def _update(self, deployment_manager: ocloud.DeploymentManager): + raise NotImplementedError diff --git a/o2ims/domain/resource_type.py b/o2ims/domain/resource_type.py index eaddb87..8267d9e 100644 --- a/o2ims/domain/resource_type.py +++ b/o2ims/domain/resource_type.py @@ -1,21 +1,21 @@ -from enum import Enum - - -class ResourceTypeEnum(Enum): - OCLOUD = 1 - RESOURCE_POOL = 2 - DMS = 3 - PSERVER = 11 - PSERVER_CPU = 12 - PSERVER_RAM = 13 - PSERVER_IF = 14 - PSERVER_IF_PORT = 15 - PSERVER_ETH = 16 - - -class InvalidOcloudState(Exception): - pass - - -class MismatchedModel(Exception): - pass +from enum import Enum + + +class ResourceTypeEnum(Enum): + OCLOUD = 1 + RESOURCE_POOL = 2 + DMS = 3 + PSERVER = 11 + PSERVER_CPU = 12 + PSERVER_RAM = 13 + PSERVER_IF = 14 + PSERVER_IF_PORT = 15 + PSERVER_ETH = 16 + + +class InvalidOcloudState(Exception): + pass + + +class MismatchedModel(Exception): + pass diff --git a/o2ims/domain/stx_object.py b/o2ims/domain/stx_object.py index be668b6..ea0fc3d 100644 --- a/o2ims/domain/stx_object.py +++ b/o2ims/domain/stx_object.py @@ -1,54 +1,54 @@ -# Copyright (C) 2021 Wind River Systems, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# from dataclasses import dataclass -import datetime -import json -from o2common.domain.base import AgRoot - -from o2ims.domain.resource_type import ResourceTypeEnum, MismatchedModel -from o2common.helper import o2logging -logger = o2logging.get_logger(__name__) - - -class StxGenericModel(AgRoot): - def __init__(self, type: ResourceTypeEnum, - api_response: dict = None, content_hash=None) -> None: - super().__init__() - if api_response: - self.id = str(api_response.uuid) - self.type = type - self.updatetime = datetime.datetime.strptime( - api_response.updated_at.split('.')[0], "%Y-%m-%dT%H:%M:%S") \ - if api_response.updated_at else None - self.createtime = datetime.datetime.strptime( - api_response.created_at.split('.')[0], "%Y-%m-%dT%H:%M:%S") \ - if api_response.created_at else None - self.name = api_response.name - self.hash = content_hash if content_hash \ - else str(hash((self.id, self.updatetime))) - self.content = json.dumps(api_response.to_dict()) - - def is_outdated(self, newmodel) -> bool: - # return self.updatetime < newmodel.updatetime - # logger.warning("hash1: " + self.hash + " vs hash2: " + newmodel.hash) - return self.hash != newmodel.hash - - def update_by(self, newmodel) -> None: - if self.id != newmodel.id: - raise MismatchedModel("Mismatched model") - self.name = newmodel.name - self.createtime = newmodel.createtime - self.updatetime = newmodel.updatetime - self.content = newmodel.content +# Copyright (C) 2021 Wind River Systems, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# from dataclasses import dataclass +import datetime +import json +from o2common.domain.base import AgRoot + +from o2ims.domain.resource_type import ResourceTypeEnum, MismatchedModel +from o2common.helper import o2logging +logger = o2logging.get_logger(__name__) + + +class StxGenericModel(AgRoot): + def __init__(self, type: ResourceTypeEnum, + api_response: dict = None, content_hash=None) -> None: + super().__init__() + if api_response: + self.id = str(api_response.uuid) + self.type = type + self.updatetime = datetime.datetime.strptime( + api_response.updated_at.split('.')[0], "%Y-%m-%dT%H:%M:%S") \ + if api_response.updated_at else None + self.createtime = datetime.datetime.strptime( + api_response.created_at.split('.')[0], "%Y-%m-%dT%H:%M:%S") \ + if api_response.created_at else None + self.name = api_response.name + self.hash = content_hash if content_hash \ + else str(hash((self.id, self.updatetime))) + self.content = json.dumps(api_response.to_dict()) + + def is_outdated(self, newmodel) -> bool: + # return self.updatetime < newmodel.updatetime + # logger.warning("hash1: " + self.hash + " vs hash2: " + newmodel.hash) + return self.hash != newmodel.hash + + def update_by(self, newmodel) -> None: + if self.id != newmodel.id: + raise MismatchedModel("Mismatched model") + self.name = newmodel.name + self.createtime = newmodel.createtime + self.updatetime = newmodel.updatetime + self.content = newmodel.content diff --git a/o2ims/domain/stx_repo.py b/o2ims/domain/stx_repo.py index c9ef6c2..e1d47b2 100644 --- a/o2ims/domain/stx_repo.py +++ b/o2ims/domain/stx_repo.py @@ -1,59 +1,59 @@ -# Copyright (C) 2021 Wind River Systems, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -import abc -from typing import List, Set -from o2ims.domain.stx_object import StxGenericModel -from o2ims.domain.resource_type import ResourceTypeEnum - - -class StxObjectRepository(abc.ABC): - def __init__(self): - self.seen = set() # type: Set[StxGenericModel] - - def add(self, stx_obj: StxGenericModel): - self._add(stx_obj) - self.seen.add(stx_obj) - - def get(self, stx_obj_id) -> StxGenericModel: - stx_obj = self._get(stx_obj_id) - if stx_obj: - self.seen.add(stx_obj) - return stx_obj - - def list(self, type: ResourceTypeEnum) -> List[StxGenericModel]: - return self._list(type) - - def update(self, stx_obj: StxGenericModel): - self._update(stx_obj) - self.seen.add(stx_obj) - - # def update_fields(self, stx_obj_id: str, updatefields: dict): - # self._update(stx_obj_id, updatefields) - - @abc.abstractmethod - def _add(self, stx_obj: StxGenericModel): - raise NotImplementedError - - @abc.abstractmethod - def _get(self, stx_obj_id) -> StxGenericModel: - raise NotImplementedError - - @abc.abstractmethod - def _update(self, stx_obj: StxGenericModel): - raise NotImplementedError - - @abc.abstractmethod - def _list(self, type: ResourceTypeEnum): - raise NotImplementedError +# Copyright (C) 2021 Wind River Systems, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import abc +from typing import List, Set +from o2ims.domain.stx_object import StxGenericModel +from o2ims.domain.resource_type import ResourceTypeEnum + + +class StxObjectRepository(abc.ABC): + def __init__(self): + self.seen = set() # type: Set[StxGenericModel] + + def add(self, stx_obj: StxGenericModel): + self._add(stx_obj) + self.seen.add(stx_obj) + + def get(self, stx_obj_id) -> StxGenericModel: + stx_obj = self._get(stx_obj_id) + if stx_obj: + self.seen.add(stx_obj) + return stx_obj + + def list(self, type: ResourceTypeEnum) -> List[StxGenericModel]: + return self._list(type) + + def update(self, stx_obj: StxGenericModel): + self._update(stx_obj) + self.seen.add(stx_obj) + + # def update_fields(self, stx_obj_id: str, updatefields: dict): + # self._update(stx_obj_id, updatefields) + + @abc.abstractmethod + def _add(self, stx_obj: StxGenericModel): + raise NotImplementedError + + @abc.abstractmethod + def _get(self, stx_obj_id) -> StxGenericModel: + raise NotImplementedError + + @abc.abstractmethod + def _update(self, stx_obj: StxGenericModel): + raise NotImplementedError + + @abc.abstractmethod + def _list(self, type: ResourceTypeEnum): + raise NotImplementedError diff --git a/o2ims/service/__init__.py b/o2ims/service/__init__.py index b514342..813897e 100644 --- a/o2ims/service/__init__.py +++ b/o2ims/service/__init__.py @@ -1,13 +1,13 @@ -# Copyright (C) 2021 Wind River Systems, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. +# Copyright (C) 2021 Wind River Systems, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. diff --git a/o2ims/service/auditor/__init__.py b/o2ims/service/auditor/__init__.py index b514342..813897e 100644 --- a/o2ims/service/auditor/__init__.py +++ b/o2ims/service/auditor/__init__.py @@ -1,13 +1,13 @@ -# Copyright (C) 2021 Wind River Systems, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. +# Copyright (C) 2021 Wind River Systems, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. diff --git a/o2ims/service/command/__init__.py b/o2ims/service/command/__init__.py index b514342..813897e 100644 --- a/o2ims/service/command/__init__.py +++ b/o2ims/service/command/__init__.py @@ -1,13 +1,13 @@ -# Copyright (C) 2021 Wind River Systems, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. +# Copyright (C) 2021 Wind River Systems, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. diff --git a/o2ims/service/command/notify_handler.py b/o2ims/service/command/notify_handler.py index 9555623..793f9d2 100644 --- a/o2ims/service/command/notify_handler.py +++ b/o2ims/service/command/notify_handler.py @@ -1,99 +1,99 @@ -# Copyright (C) 2021 Wind River Systems, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -import json -# import redis -# import requests -import http.client -from urllib.parse import urlparse - -# from o2common.config import config -from o2common.service.unit_of_work import AbstractUnitOfWork -from o2ims.domain import commands -from o2ims.domain.subscription_obj import Subscription, Message2SMO - -from o2common.helper import o2logging -logger = o2logging.get_logger(__name__) - -# # Maybe another MQ server -# r = redis.Redis(**config.get_redis_host_and_port()) - - -def notify_change_to_smo( - cmd: commands.PubMessage2SMO, - uow: AbstractUnitOfWork, -): - logger.info('In notify_change_to_smo') - data = cmd.data - with uow: - subs = uow.subscriptions.list() - for sub in subs: - sub_data = sub.serialize() - logger.debug('Subscription: {}'.format(sub_data['subscriptionId'])) - - try: - resource_filter = json.loads(sub_data['filter']) - if len(resource_filter) > 0: - resource = uow.resources.get(data.id) - logger.debug(type(resource)) - if resource: # TODO deal with resource is empty - res_type_id = resource.serialize()['resourceTypeId'] - resourcetype = uow.resource_types.get(res_type_id) - logger.debug(resourcetype.name) - if resourcetype.name not in resource_filter: - continue - except json.decoder.JSONDecodeError as err: - logger.warning( - 'subscription filter decode json failed: {}'.format(err)) - - callback_smo(sub, data) - - -def callback_smo(sub: Subscription, msg: Message2SMO): - sub_data = sub.serialize() - callback_data = json.dumps({ - 'consumerSubscriptionId': sub_data['consumerSubscriptionId'], - 'notificationEventType': msg.notificationEventType, - 'objectRef': msg.objectRef, - 'updateTime': msg.updatetime - }) - logger.info('URL: {}, data: {}'.format( - sub_data['callback'], callback_data)) - # r.publish(sub_data['subscriptionId'], json.dumps({ - # 'consumerSubscriptionId': sub_data['consumerSubscriptionId'], - # 'notificationEventType': msg.notificationEventType, - # 'objectRef': msg.objectRef - # })) - # try: - # headers = {'User-Agent': 'Mozilla/5.0'} - # resp = requests.post(sub_data['callback'], data=callback_data, - # headers=headers) - # if resp.status_code == 202 or resp.status_code == 200: - # logger.info('Notify to SMO successed') - # return - # logger.error('Response code is: {}'.format(resp.status_code)) - # except requests.exceptions.HTTPError as err: - # logger.error('request smo error: {}'.format(err)) - o = urlparse(sub_data['callback']) - conn = http.client.HTTPConnection(o.netloc) - headers = {'Content-type': 'application/json'} - conn.request('POST', o.path, callback_data, headers) - resp = conn.getresponse() - data = resp.read().decode('utf-8') - # json_data = json.loads(data) - if resp.status == 202 or resp.status == 200: - logger.info('Notify to SMO successed, response code {} {}, data {}'. - format(resp.status, resp.reason, data)) - return - logger.error('Response code is: {}'.format(resp.status)) +# Copyright (C) 2021 Wind River Systems, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import json +# import redis +# import requests +import http.client +from urllib.parse import urlparse + +# from o2common.config import config +from o2common.service.unit_of_work import AbstractUnitOfWork +from o2ims.domain import commands +from o2ims.domain.subscription_obj import Subscription, Message2SMO + +from o2common.helper import o2logging +logger = o2logging.get_logger(__name__) + +# # Maybe another MQ server +# r = redis.Redis(**config.get_redis_host_and_port()) + + +def notify_change_to_smo( + cmd: commands.PubMessage2SMO, + uow: AbstractUnitOfWork, +): + logger.info('In notify_change_to_smo') + data = cmd.data + with uow: + subs = uow.subscriptions.list() + for sub in subs: + sub_data = sub.serialize() + logger.debug('Subscription: {}'.format(sub_data['subscriptionId'])) + + try: + resource_filter = json.loads(sub_data['filter']) + if len(resource_filter) > 0: + resource = uow.resources.get(data.id) + logger.debug(type(resource)) + if resource: # TODO deal with resource is empty + res_type_id = resource.serialize()['resourceTypeId'] + resourcetype = uow.resource_types.get(res_type_id) + logger.debug(resourcetype.name) + if resourcetype.name not in resource_filter: + continue + except json.decoder.JSONDecodeError as err: + logger.warning( + 'subscription filter decode json failed: {}'.format(err)) + + callback_smo(sub, data) + + +def callback_smo(sub: Subscription, msg: Message2SMO): + sub_data = sub.serialize() + callback_data = json.dumps({ + 'consumerSubscriptionId': sub_data['consumerSubscriptionId'], + 'notificationEventType': msg.notificationEventType, + 'objectRef': msg.objectRef, + 'updateTime': msg.updatetime + }) + logger.info('URL: {}, data: {}'.format( + sub_data['callback'], callback_data)) + # r.publish(sub_data['subscriptionId'], json.dumps({ + # 'consumerSubscriptionId': sub_data['consumerSubscriptionId'], + # 'notificationEventType': msg.notificationEventType, + # 'objectRef': msg.objectRef + # })) + # try: + # headers = {'User-Agent': 'Mozilla/5.0'} + # resp = requests.post(sub_data['callback'], data=callback_data, + # headers=headers) + # if resp.status_code == 202 or resp.status_code == 200: + # logger.info('Notify to SMO successed') + # return + # logger.error('Response code is: {}'.format(resp.status_code)) + # except requests.exceptions.HTTPError as err: + # logger.error('request smo error: {}'.format(err)) + o = urlparse(sub_data['callback']) + conn = http.client.HTTPConnection(o.netloc) + headers = {'Content-type': 'application/json'} + conn.request('POST', o.path, callback_data, headers) + resp = conn.getresponse() + data = resp.read().decode('utf-8') + # json_data = json.loads(data) + if resp.status == 202 or resp.status == 200: + logger.info('Notify to SMO successed, response code {} {}, data {}'. + format(resp.status, resp.reason, data)) + return + logger.error('Response code is: {}'.format(resp.status)) diff --git a/o2ims/service/command/registration_handler.py b/o2ims/service/command/registration_handler.py index d363149..d08bf73 100644 --- a/o2ims/service/command/registration_handler.py +++ b/o2ims/service/command/registration_handler.py @@ -1,107 +1,107 @@ -# Copyright (C) 2021 Wind River Systems, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# import time -import json -# import asyncio -# import requests -import http.client -from urllib.parse import urlparse -from retry import retry - -from o2common.service.unit_of_work import AbstractUnitOfWork -from o2common.config import config -from o2ims.domain import commands -from o2ims.domain.configuration_obj import ConfigurationTypeEnum, \ - RegistrationStatusEnum - -from o2common.helper import o2logging -logger = o2logging.get_logger(__name__) - - -def registry_to_smo( - cmd: commands.Register2SMO, - uow: AbstractUnitOfWork, -): - logger.info('In registry_to_smo') - data = cmd.data - logger.info('The Register2SMO all is {}'.format(data.all)) - if data.all: - confs = uow.configrations.list() - for conf in confs: - if conf.conftype != ConfigurationTypeEnum.SMO: - continue - reg_data = conf.serialize() - logger.debug('Configuration: {}'.format( - reg_data['configurationId'])) - - register_smo(uow, reg_data) - else: - with uow: - conf = uow.configurations.get(data.id) - if conf is None: - return - logger.debug('Configuration: {}'.format(conf.configurationId)) - conf_data = conf.serialize() - register_smo(uow, conf_data) - - -def register_smo(uow, reg_data): - call_res = call_smo(reg_data) - logger.debug('Call SMO response is {}'.format(call_res)) - if call_res: - reg = uow.configurations.get(reg_data['configurationId']) - if reg is None: - return - reg.status = RegistrationStatusEnum.NOTIFIED - logger.debug('Updating Configurations: {}'.format( - reg.configurationId)) - uow.configurations.update(reg) - uow.commit() - - -# def retry(fun, max_tries=2): -# for i in range(max_tries): -# try: -# time.sleep(5*i) -# # await asyncio.sleep(5*i) -# res = fun() -# logger.debug('retry function result: {}'.format(res)) -# return res -# except Exception: -# continue - - -@retry((ConnectionRefusedError), tries=2, delay=2) -def call_smo(reg_data: dict): - callback_data = json.dumps({ - 'consumerSubscriptionId': reg_data['configurationId'], - 'imsUrl': config.get_api_url() - }) - logger.info('URL: {}, data: {}'.format( - reg_data['callback'], callback_data)) - - o = urlparse(reg_data['callback']) - conn = http.client.HTTPConnection(o.netloc) - headers = {'Content-type': 'application/json'} - conn.request('POST', o.path, callback_data, headers) - resp = conn.getresponse() - data = resp.read().decode('utf-8') - # json_data = json.loads(data) - if resp.status == 202 or resp.status == 200: - logger.info('Registrer to SMO successed, response code {} {}, data {}'. - format(resp.status, resp.reason, data)) - return True - logger.error('Response code is: {}'.format(resp.status)) - return False +# Copyright (C) 2021 Wind River Systems, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# import time +import json +# import asyncio +# import requests +import http.client +from urllib.parse import urlparse +from retry import retry + +from o2common.service.unit_of_work import AbstractUnitOfWork +from o2common.config import config +from o2ims.domain import commands +from o2ims.domain.configuration_obj import ConfigurationTypeEnum, \ + RegistrationStatusEnum + +from o2common.helper import o2logging +logger = o2logging.get_logger(__name__) + + +def registry_to_smo( + cmd: commands.Register2SMO, + uow: AbstractUnitOfWork, +): + logger.info('In registry_to_smo') + data = cmd.data + logger.info('The Register2SMO all is {}'.format(data.all)) + if data.all: + confs = uow.configrations.list() + for conf in confs: + if conf.conftype != ConfigurationTypeEnum.SMO: + continue + reg_data = conf.serialize() + logger.debug('Configuration: {}'.format( + reg_data['configurationId'])) + + register_smo(uow, reg_data) + else: + with uow: + conf = uow.configurations.get(data.id) + if conf is None: + return + logger.debug('Configuration: {}'.format(conf.configurationId)) + conf_data = conf.serialize() + register_smo(uow, conf_data) + + +def register_smo(uow, reg_data): + call_res = call_smo(reg_data) + logger.debug('Call SMO response is {}'.format(call_res)) + if call_res: + reg = uow.configurations.get(reg_data['configurationId']) + if reg is None: + return + reg.status = RegistrationStatusEnum.NOTIFIED + logger.debug('Updating Configurations: {}'.format( + reg.configurationId)) + uow.configurations.update(reg) + uow.commit() + + +# def retry(fun, max_tries=2): +# for i in range(max_tries): +# try: +# time.sleep(5*i) +# # await asyncio.sleep(5*i) +# res = fun() +# logger.debug('retry function result: {}'.format(res)) +# return res +# except Exception: +# continue + + +@retry((ConnectionRefusedError), tries=2, delay=2) +def call_smo(reg_data: dict): + callback_data = json.dumps({ + 'consumerSubscriptionId': reg_data['configurationId'], + 'imsUrl': config.get_api_url() + }) + logger.info('URL: {}, data: {}'.format( + reg_data['callback'], callback_data)) + + o = urlparse(reg_data['callback']) + conn = http.client.HTTPConnection(o.netloc) + headers = {'Content-type': 'application/json'} + conn.request('POST', o.path, callback_data, headers) + resp = conn.getresponse() + data = resp.read().decode('utf-8') + # json_data = json.loads(data) + if resp.status == 202 or resp.status == 200: + logger.info('Registrer to SMO successed, response code {} {}, data {}'. + format(resp.status, resp.reason, data)) + return True + logger.error('Response code is: {}'.format(resp.status)) + return False diff --git a/o2ims/service/event/__init__.py b/o2ims/service/event/__init__.py index b514342..813897e 100644 --- a/o2ims/service/event/__init__.py +++ b/o2ims/service/event/__init__.py @@ -1,13 +1,13 @@ -# Copyright (C) 2021 Wind River Systems, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. +# Copyright (C) 2021 Wind River Systems, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. diff --git a/o2ims/service/event/configuration_event.py b/o2ims/service/event/configuration_event.py index ddaeb35..c1e8c1c 100644 --- a/o2ims/service/event/configuration_event.py +++ b/o2ims/service/event/configuration_event.py @@ -1,30 +1,30 @@ -# Copyright (C) 2021 Wind River Systems, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from typing import Callable - -from o2ims.domain import events - -from o2common.helper import o2logging -logger = o2logging.get_logger(__name__) - - -def notify_configuration_change( - event: events.ConfigurationChanged, - publish: Callable, -): - logger.info('In notify_registration_change') - publish("ConfigurationChanged", event) - logger.debug("published Registration Changed: {}".format( - event.id)) +# Copyright (C) 2021 Wind River Systems, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from typing import Callable + +from o2ims.domain import events + +from o2common.helper import o2logging +logger = o2logging.get_logger(__name__) + + +def notify_configuration_change( + event: events.ConfigurationChanged, + publish: Callable, +): + logger.info('In notify_registration_change') + publish("ConfigurationChanged", event) + logger.debug("published Registration Changed: {}".format( + event.id)) diff --git a/o2ims/service/event/ocloud_event.py b/o2ims/service/event/ocloud_event.py index dbeb448..6fb4563 100644 --- a/o2ims/service/event/ocloud_event.py +++ b/o2ims/service/event/ocloud_event.py @@ -1,30 +1,30 @@ -# Copyright (C) 2021 Wind River Systems, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from typing import Callable - -from o2ims.domain import events - -from o2common.helper import o2logging -logger = o2logging.get_logger(__name__) - - -def notify_ocloud_update( - event: events.OcloudChanged, - publish: Callable, -): - logger.info('In notify_ocloud_update') - publish("OcloudChanged", event) - logger.debug("published Ocloud Changed: {}".format( - event.id)) +# Copyright (C) 2021 Wind River Systems, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from typing import Callable + +from o2ims.domain import events + +from o2common.helper import o2logging +logger = o2logging.get_logger(__name__) + + +def notify_ocloud_update( + event: events.OcloudChanged, + publish: Callable, +): + logger.info('In notify_ocloud_update') + publish("OcloudChanged", event) + logger.debug("published Ocloud Changed: {}".format( + event.id)) diff --git a/o2ims/service/event/resource_event.py b/o2ims/service/event/resource_event.py index 2a749b7..09241ca 100644 --- a/o2ims/service/event/resource_event.py +++ b/o2ims/service/event/resource_event.py @@ -1,30 +1,30 @@ -# Copyright (C) 2021 Wind River Systems, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from typing import Callable - -from o2ims.domain import events - -from o2common.helper import o2logging -logger = o2logging.get_logger(__name__) - - -def notify_resource_change( - event: events.ResourceChanged, - publish: Callable, -): - logger.info('In notify_resource_change') - publish("ResourceChanged", event) - logger.debug("published Resource Changed: {}".format( - event.id)) +# Copyright (C) 2021 Wind River Systems, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from typing import Callable + +from o2ims.domain import events + +from o2common.helper import o2logging +logger = o2logging.get_logger(__name__) + + +def notify_resource_change( + event: events.ResourceChanged, + publish: Callable, +): + logger.info('In notify_resource_change') + publish("ResourceChanged", event) + logger.debug("published Resource Changed: {}".format( + event.id)) diff --git a/o2ims/service/event/resource_pool_event.py b/o2ims/service/event/resource_pool_event.py index 9c78d5b..07e6827 100644 --- a/o2ims/service/event/resource_pool_event.py +++ b/o2ims/service/event/resource_pool_event.py @@ -1,30 +1,30 @@ -# Copyright (C) 2021 Wind River Systems, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from typing import Callable - -from o2ims.domain import events - -from o2common.helper import o2logging -logger = o2logging.get_logger(__name__) - - -def notify_resourcepool_change( - event: events.ResourcePoolChanged, - publish: Callable, -): - logger.info('In notify_resourcepool_change') - publish("ResourcePoolChanged", event) - logger.debug("published Resource Pool Changed: {}".format( - event.id)) +# Copyright (C) 2021 Wind River Systems, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from typing import Callable + +from o2ims.domain import events + +from o2common.helper import o2logging +logger = o2logging.get_logger(__name__) + + +def notify_resourcepool_change( + event: events.ResourcePoolChanged, + publish: Callable, +): + logger.info('In notify_resourcepool_change') + publish("ResourcePoolChanged", event) + logger.debug("published Resource Pool Changed: {}".format( + event.id)) diff --git a/o2ims/service/watcher/__init__.py b/o2ims/service/watcher/__init__.py index b514342..813897e 100644 --- a/o2ims/service/watcher/__init__.py +++ b/o2ims/service/watcher/__init__.py @@ -1,13 +1,13 @@ -# Copyright (C) 2021 Wind River Systems, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. +# Copyright (C) 2021 Wind River Systems, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. diff --git a/o2ims/service/watcher/ocloud_watcher.py b/o2ims/service/watcher/ocloud_watcher.py index 1d0c0ae..194a10b 100644 --- a/o2ims/service/watcher/ocloud_watcher.py +++ b/o2ims/service/watcher/ocloud_watcher.py @@ -1,83 +1,83 @@ -# Copyright (C) 2021 Wind River Systems, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# from o2ims.domain.resource_type import ResourceTypeEnum -from o2common.service.client.base_client import BaseClient -from o2ims.domain.stx_object import StxGenericModel -# from o2common.service.unit_of_work import AbstractUnitOfWork -from o2common.service.watcher.base import BaseWatcher -from o2ims.domain import commands -from o2common.service.messagebus import MessageBus - -from o2common.helper import o2logging -logger = o2logging.get_logger(__name__) - - -class OcloudWatcher(BaseWatcher): - def __init__(self, ocloud_client: BaseClient, - bus: MessageBus) -> None: - super().__init__(ocloud_client, bus) - - def _targetname(self): - return "ocloud" - - def _probe(self, parent: object = None): - newmodel = self._client.get(None) - if newmodel: - logger.debug("found ocloud: " + newmodel.name) - else: - logger.warning("Failed to find out any ocloud") - # self._compare_and_update(ocloudmodel) - return [commands.UpdateOCloud(newmodel)] if newmodel else [] - -# def _compare_and_update(self, ocloudmodel: StxGenericModel) -> bool: -# with self._uow: -# # localmodel = self._uow.stxobjects.get(str(ocloudmodel.id)) -# oclouds = self._uow.stxobjects.list(ResourceTypeEnum.OCLOUD) -# if len(oclouds) > 1: -# raise InvalidOcloudState("More than 1 ocloud is found") -# if len(oclouds) == 0: -# logger.info("add ocloud:" + ocloudmodel.name -# + " update_at: " + str(ocloudmodel.updatetime) -# + " id: " + str(ocloudmodel.id) -# + " hash: " + str(ocloudmodel.hash)) -# self._uow.stxobjects.add(ocloudmodel) -# else: -# localmodel = oclouds.pop() -# if localmodel.is_outdated(ocloudmodel): -# logger.info("update ocloud:" + ocloudmodel.name -# + " update_at: " + str(ocloudmodel.updatetime) -# + " id: " + str(ocloudmodel.id) -# + " hash: " + str(ocloudmodel.hash)) -# localmodel.update_by(ocloudmodel) -# self._uow.stxobjects.update(localmodel) -# self._uow.commit() - - -class DmsWatcher(BaseWatcher): - def __init__(self, client: BaseClient, - bus: MessageBus) -> None: - super().__init__(client, bus) - - def _targetname(self): - return "dms" - - def _probe(self, parent: StxGenericModel): - ocloudid = parent.id - newmodels = self._client.list(ocloudid=ocloudid) - # for newmodel in newmodels: - # super()._compare_and_update(newmodel) - # return newmodels - return [commands.UpdateDms(data=m, parentid=ocloudid) - for m in newmodels] +# Copyright (C) 2021 Wind River Systems, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# from o2ims.domain.resource_type import ResourceTypeEnum +from o2common.service.client.base_client import BaseClient +from o2ims.domain.stx_object import StxGenericModel +# from o2common.service.unit_of_work import AbstractUnitOfWork +from o2common.service.watcher.base import BaseWatcher +from o2ims.domain import commands +from o2common.service.messagebus import MessageBus + +from o2common.helper import o2logging +logger = o2logging.get_logger(__name__) + + +class OcloudWatcher(BaseWatcher): + def __init__(self, ocloud_client: BaseClient, + bus: MessageBus) -> None: + super().__init__(ocloud_client, bus) + + def _targetname(self): + return "ocloud" + + def _probe(self, parent: object = None): + newmodel = self._client.get(None) + if newmodel: + logger.debug("found ocloud: " + newmodel.name) + else: + logger.warning("Failed to find out any ocloud") + # self._compare_and_update(ocloudmodel) + return [commands.UpdateOCloud(newmodel)] if newmodel else [] + +# def _compare_and_update(self, ocloudmodel: StxGenericModel) -> bool: +# with self._uow: +# # localmodel = self._uow.stxobjects.get(str(ocloudmodel.id)) +# oclouds = self._uow.stxobjects.list(ResourceTypeEnum.OCLOUD) +# if len(oclouds) > 1: +# raise InvalidOcloudState("More than 1 ocloud is found") +# if len(oclouds) == 0: +# logger.info("add ocloud:" + ocloudmodel.name +# + " update_at: " + str(ocloudmodel.updatetime) +# + " id: " + str(ocloudmodel.id) +# + " hash: " + str(ocloudmodel.hash)) +# self._uow.stxobjects.add(ocloudmodel) +# else: +# localmodel = oclouds.pop() +# if localmodel.is_outdated(ocloudmodel): +# logger.info("update ocloud:" + ocloudmodel.name +# + " update_at: " + str(ocloudmodel.updatetime) +# + " id: " + str(ocloudmodel.id) +# + " hash: " + str(ocloudmodel.hash)) +# localmodel.update_by(ocloudmodel) +# self._uow.stxobjects.update(localmodel) +# self._uow.commit() + + +class DmsWatcher(BaseWatcher): + def __init__(self, client: BaseClient, + bus: MessageBus) -> None: + super().__init__(client, bus) + + def _targetname(self): + return "dms" + + def _probe(self, parent: StxGenericModel): + ocloudid = parent.id + newmodels = self._client.list(ocloudid=ocloudid) + # for newmodel in newmodels: + # super()._compare_and_update(newmodel) + # return newmodels + return [commands.UpdateDms(data=m, parentid=ocloudid) + for m in newmodels] diff --git a/o2ims/service/watcher/pserver_cpu_watcher.py b/o2ims/service/watcher/pserver_cpu_watcher.py index 51a5a76..016993b 100644 --- a/o2ims/service/watcher/pserver_cpu_watcher.py +++ b/o2ims/service/watcher/pserver_cpu_watcher.py @@ -1,38 +1,38 @@ -# Copyright (C) 2021 Wind River Systems, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from o2ims.domain.stx_object import StxGenericModel -from o2common.service.client.base_client import BaseClient -# from o2common.service.unit_of_work import AbstractUnitOfWork -from o2ims.service.watcher.resource_watcher import ResourceWatcher -from o2ims.domain import commands -from o2common.service.messagebus import MessageBus - -from o2common.helper import o2logging -logger = o2logging.get_logger(__name__) - - -class PServerCpuWatcher(ResourceWatcher): - def __init__(self, client: BaseClient, - bus: MessageBus) -> None: - super().__init__(client, bus) - - def _targetname(self): - return "pserver_cpu" - - def _probe(self, parent: StxGenericModel): - hostid = parent.id - newmodels = self._client.list(hostid=hostid) - return [commands.UpdatePserverCpu(data=m, parentid=hostid) - for m in newmodels] +# Copyright (C) 2021 Wind River Systems, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from o2ims.domain.stx_object import StxGenericModel +from o2common.service.client.base_client import BaseClient +# from o2common.service.unit_of_work import AbstractUnitOfWork +from o2ims.service.watcher.resource_watcher import ResourceWatcher +from o2ims.domain import commands +from o2common.service.messagebus import MessageBus + +from o2common.helper import o2logging +logger = o2logging.get_logger(__name__) + + +class PServerCpuWatcher(ResourceWatcher): + def __init__(self, client: BaseClient, + bus: MessageBus) -> None: + super().__init__(client, bus) + + def _targetname(self): + return "pserver_cpu" + + def _probe(self, parent: StxGenericModel): + hostid = parent.id + newmodels = self._client.list(hostid=hostid) + return [commands.UpdatePserverCpu(data=m, parentid=hostid) + for m in newmodels] diff --git a/o2ims/service/watcher/pserver_eth_watcher.py b/o2ims/service/watcher/pserver_eth_watcher.py index 6aa6a13..20accaa 100644 --- a/o2ims/service/watcher/pserver_eth_watcher.py +++ b/o2ims/service/watcher/pserver_eth_watcher.py @@ -1,38 +1,38 @@ -# Copyright (C) 2021 Wind River Systems, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from o2ims.domain.stx_object import StxGenericModel -from o2common.service.client.base_client import BaseClient -# from o2common.service.unit_of_work import AbstractUnitOfWork -from o2ims.service.watcher.resource_watcher import ResourceWatcher -from o2ims.domain import commands -from o2common.service.messagebus import MessageBus - -from o2common.helper import o2logging -logger = o2logging.get_logger(__name__) - - -class PServerEthWatcher(ResourceWatcher): - def __init__(self, client: BaseClient, - bus: MessageBus) -> None: - super().__init__(client, bus) - - def _targetname(self): - return "pserver_ethernet" - - def _probe(self, parent: StxGenericModel): - hostid = parent.id - newmodels = self._client.list(hostid=hostid) - return [commands.UpdatePserverEth(data=m, parentid=hostid) - for m in newmodels] +# Copyright (C) 2021 Wind River Systems, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from o2ims.domain.stx_object import StxGenericModel +from o2common.service.client.base_client import BaseClient +# from o2common.service.unit_of_work import AbstractUnitOfWork +from o2ims.service.watcher.resource_watcher import ResourceWatcher +from o2ims.domain import commands +from o2common.service.messagebus import MessageBus + +from o2common.helper import o2logging +logger = o2logging.get_logger(__name__) + + +class PServerEthWatcher(ResourceWatcher): + def __init__(self, client: BaseClient, + bus: MessageBus) -> None: + super().__init__(client, bus) + + def _targetname(self): + return "pserver_ethernet" + + def _probe(self, parent: StxGenericModel): + hostid = parent.id + newmodels = self._client.list(hostid=hostid) + return [commands.UpdatePserverEth(data=m, parentid=hostid) + for m in newmodels] diff --git a/o2ims/service/watcher/pserver_if_watcher.py b/o2ims/service/watcher/pserver_if_watcher.py index 8bdde89..f4cea0c 100644 --- a/o2ims/service/watcher/pserver_if_watcher.py +++ b/o2ims/service/watcher/pserver_if_watcher.py @@ -1,38 +1,38 @@ -# Copyright (C) 2021 Wind River Systems, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from o2ims.domain.stx_object import StxGenericModel -from o2common.service.client.base_client import BaseClient -# from o2common.service.unit_of_work import AbstractUnitOfWork -from o2ims.service.watcher.resource_watcher import ResourceWatcher -from o2ims.domain import commands -from o2common.service.messagebus import MessageBus - -from o2common.helper import o2logging -logger = o2logging.get_logger(__name__) - - -class PServerIfWatcher(ResourceWatcher): - def __init__(self, client: BaseClient, - bus: MessageBus) -> None: - super().__init__(client, bus) - - def _targetname(self): - return "pserver_if" - - def _probe(self, parent: StxGenericModel): - hostid = parent.id - newmodels = self._client.list(hostid=hostid) - return [commands.UpdatePserverIf(data=m, parentid=hostid) - for m in newmodels] +# Copyright (C) 2021 Wind River Systems, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from o2ims.domain.stx_object import StxGenericModel +from o2common.service.client.base_client import BaseClient +# from o2common.service.unit_of_work import AbstractUnitOfWork +from o2ims.service.watcher.resource_watcher import ResourceWatcher +from o2ims.domain import commands +from o2common.service.messagebus import MessageBus + +from o2common.helper import o2logging +logger = o2logging.get_logger(__name__) + + +class PServerIfWatcher(ResourceWatcher): + def __init__(self, client: BaseClient, + bus: MessageBus) -> None: + super().__init__(client, bus) + + def _targetname(self): + return "pserver_if" + + def _probe(self, parent: StxGenericModel): + hostid = parent.id + newmodels = self._client.list(hostid=hostid) + return [commands.UpdatePserverIf(data=m, parentid=hostid) + for m in newmodels] diff --git a/o2ims/service/watcher/pserver_mem_watcher.py b/o2ims/service/watcher/pserver_mem_watcher.py index ddeb3ef..635961d 100644 --- a/o2ims/service/watcher/pserver_mem_watcher.py +++ b/o2ims/service/watcher/pserver_mem_watcher.py @@ -1,38 +1,38 @@ -# Copyright (C) 2021 Wind River Systems, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from o2ims.domain.stx_object import StxGenericModel -from o2common.service.client.base_client import BaseClient -# from o2common.service.unit_of_work import AbstractUnitOfWork -from o2ims.service.watcher.resource_watcher import ResourceWatcher -from o2ims.domain import commands -from o2common.service.messagebus import MessageBus - -from o2common.helper import o2logging -logger = o2logging.get_logger(__name__) - - -class PServerMemWatcher(ResourceWatcher): - def __init__(self, client: BaseClient, - bus: MessageBus) -> None: - super().__init__(client, bus) - - def _targetname(self): - return "pserver_mem" - - def _probe(self, parent: StxGenericModel): - hostid = parent.id - newmodels = self._client.list(hostid=hostid) - return [commands.UpdatePserverMem(data=m, parentid=hostid) - for m in newmodels] +# Copyright (C) 2021 Wind River Systems, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from o2ims.domain.stx_object import StxGenericModel +from o2common.service.client.base_client import BaseClient +# from o2common.service.unit_of_work import AbstractUnitOfWork +from o2ims.service.watcher.resource_watcher import ResourceWatcher +from o2ims.domain import commands +from o2common.service.messagebus import MessageBus + +from o2common.helper import o2logging +logger = o2logging.get_logger(__name__) + + +class PServerMemWatcher(ResourceWatcher): + def __init__(self, client: BaseClient, + bus: MessageBus) -> None: + super().__init__(client, bus) + + def _targetname(self): + return "pserver_mem" + + def _probe(self, parent: StxGenericModel): + hostid = parent.id + newmodels = self._client.list(hostid=hostid) + return [commands.UpdatePserverMem(data=m, parentid=hostid) + for m in newmodels] diff --git a/o2ims/service/watcher/pserver_port_watcher.py b/o2ims/service/watcher/pserver_port_watcher.py index f8d29c9..d96d89a 100644 --- a/o2ims/service/watcher/pserver_port_watcher.py +++ b/o2ims/service/watcher/pserver_port_watcher.py @@ -1,38 +1,38 @@ -# Copyright (C) 2021 Wind River Systems, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from o2ims.domain.stx_object import StxGenericModel -from o2common.service.client.base_client import BaseClient -# from o2common.service.unit_of_work import AbstractUnitOfWork -from o2ims.service.watcher.resource_watcher import ResourceWatcher -from o2ims.domain import commands -from o2common.service.messagebus import MessageBus - -from o2common.helper import o2logging -logger = o2logging.get_logger(__name__) - - -class PServerIfPortWatcher(ResourceWatcher): - def __init__(self, client: BaseClient, - bus: MessageBus) -> None: - super().__init__(client, bus) - - def _targetname(self): - return "pserver_if_port" - - def _probe(self, parent: StxGenericModel): - interfaceid = parent.id - newmodels = self._client.list(interfaceid=interfaceid) - return [commands.UpdatePserverIfPort(data=m, parentid=interfaceid) - for m in newmodels] +# Copyright (C) 2021 Wind River Systems, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from o2ims.domain.stx_object import StxGenericModel +from o2common.service.client.base_client import BaseClient +# from o2common.service.unit_of_work import AbstractUnitOfWork +from o2ims.service.watcher.resource_watcher import ResourceWatcher +from o2ims.domain import commands +from o2common.service.messagebus import MessageBus + +from o2common.helper import o2logging +logger = o2logging.get_logger(__name__) + + +class PServerIfPortWatcher(ResourceWatcher): + def __init__(self, client: BaseClient, + bus: MessageBus) -> None: + super().__init__(client, bus) + + def _targetname(self): + return "pserver_if_port" + + def _probe(self, parent: StxGenericModel): + interfaceid = parent.id + newmodels = self._client.list(interfaceid=interfaceid) + return [commands.UpdatePserverIfPort(data=m, parentid=interfaceid) + for m in newmodels] diff --git a/o2ims/service/watcher/pserver_watcher.py b/o2ims/service/watcher/pserver_watcher.py index 8222cc3..b239a66 100644 --- a/o2ims/service/watcher/pserver_watcher.py +++ b/o2ims/service/watcher/pserver_watcher.py @@ -1,38 +1,38 @@ -# Copyright (C) 2021 Wind River Systems, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from o2ims.domain.stx_object import StxGenericModel -from o2common.service.client.base_client import BaseClient -# from o2common.service.unit_of_work import AbstractUnitOfWork -from o2ims.service.watcher.resource_watcher import ResourceWatcher -from o2ims.domain import commands -from o2common.service.messagebus import MessageBus - -from o2common.helper import o2logging -logger = o2logging.get_logger(__name__) - - -class PServerWatcher(ResourceWatcher): - def __init__(self, client: BaseClient, - bus: MessageBus) -> None: - super().__init__(client, bus) - - def _targetname(self): - return "pserver" - - def _probe(self, parent: StxGenericModel): - resourcepoolid = parent.id - newmodels = self._client.list(resourcepoolid=resourcepoolid) - return [commands.UpdatePserver(data=m, parentid=resourcepoolid) - for m in newmodels] +# Copyright (C) 2021 Wind River Systems, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from o2ims.domain.stx_object import StxGenericModel +from o2common.service.client.base_client import BaseClient +# from o2common.service.unit_of_work import AbstractUnitOfWork +from o2ims.service.watcher.resource_watcher import ResourceWatcher +from o2ims.domain import commands +from o2common.service.messagebus import MessageBus + +from o2common.helper import o2logging +logger = o2logging.get_logger(__name__) + + +class PServerWatcher(ResourceWatcher): + def __init__(self, client: BaseClient, + bus: MessageBus) -> None: + super().__init__(client, bus) + + def _targetname(self): + return "pserver" + + def _probe(self, parent: StxGenericModel): + resourcepoolid = parent.id + newmodels = self._client.list(resourcepoolid=resourcepoolid) + return [commands.UpdatePserver(data=m, parentid=resourcepoolid) + for m in newmodels] diff --git a/o2ims/service/watcher/resource_watcher.py b/o2ims/service/watcher/resource_watcher.py index 86416e3..d25cdc6 100644 --- a/o2ims/service/watcher/resource_watcher.py +++ b/o2ims/service/watcher/resource_watcher.py @@ -1,38 +1,38 @@ -# Copyright (C) 2021 Wind River Systems, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from o2ims.domain.stx_object import StxGenericModel -from o2common.service.client.base_client import BaseClient -# from o2common.service.unit_of_work import AbstractUnitOfWork -from o2common.service.watcher.base import BaseWatcher -from o2ims.domain import commands -from o2common.service.messagebus import MessageBus - -from o2common.helper import o2logging -logger = o2logging.get_logger(__name__) - - -class ResourceWatcher(BaseWatcher): - def __init__(self, client: BaseClient, - bus: MessageBus) -> None: - super().__init__(client, bus) - - def _targetname(self): - return "resource" - - def _probe(self, parent: StxGenericModel): - parentid = parent.id - newmodels = self._client.get(parentid=parentid) - return [commands.UpdateResource(data=m, parentid=parentid) - for m in newmodels] +# Copyright (C) 2021 Wind River Systems, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from o2ims.domain.stx_object import StxGenericModel +from o2common.service.client.base_client import BaseClient +# from o2common.service.unit_of_work import AbstractUnitOfWork +from o2common.service.watcher.base import BaseWatcher +from o2ims.domain import commands +from o2common.service.messagebus import MessageBus + +from o2common.helper import o2logging +logger = o2logging.get_logger(__name__) + + +class ResourceWatcher(BaseWatcher): + def __init__(self, client: BaseClient, + bus: MessageBus) -> None: + super().__init__(client, bus) + + def _targetname(self): + return "resource" + + def _probe(self, parent: StxGenericModel): + parentid = parent.id + newmodels = self._client.get(parentid=parentid) + return [commands.UpdateResource(data=m, parentid=parentid) + for m in newmodels] diff --git a/o2ims/service/watcher/resourcepool_watcher.py b/o2ims/service/watcher/resourcepool_watcher.py index 214041f..9f1f0e2 100644 --- a/o2ims/service/watcher/resourcepool_watcher.py +++ b/o2ims/service/watcher/resourcepool_watcher.py @@ -1,42 +1,42 @@ -# Copyright (C) 2021 Wind River Systems, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from o2ims.domain.stx_object import StxGenericModel -from o2common.service.client.base_client import BaseClient -# from o2common.service.unit_of_work import AbstractUnitOfWork -from o2common.service.watcher.base import BaseWatcher -from o2ims.domain import commands -from o2common.service.messagebus import MessageBus - -from o2common.helper import o2logging -logger = o2logging.get_logger(__name__) - - -class ResourcePoolWatcher(BaseWatcher): - def __init__(self, client: BaseClient, - bus: MessageBus) -> None: - super().__init__(client, bus) - - def _targetname(self): - return "resourcepool" - - def _probe(self, parent: StxGenericModel): - ocloudid = parent.id - newmodels = self._client.list(ocloudid=ocloudid) - # for newmodel in newmodels: - # logger.info("detect ocloudmodel:" + newmodel.name) - # super()._compare_and_update(newmodel) - # return newmodels - return [commands.UpdateResourcePool(data=m, parentid=ocloudid) - for m in newmodels] +# Copyright (C) 2021 Wind River Systems, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from o2ims.domain.stx_object import StxGenericModel +from o2common.service.client.base_client import BaseClient +# from o2common.service.unit_of_work import AbstractUnitOfWork +from o2common.service.watcher.base import BaseWatcher +from o2ims.domain import commands +from o2common.service.messagebus import MessageBus + +from o2common.helper import o2logging +logger = o2logging.get_logger(__name__) + + +class ResourcePoolWatcher(BaseWatcher): + def __init__(self, client: BaseClient, + bus: MessageBus) -> None: + super().__init__(client, bus) + + def _targetname(self): + return "resourcepool" + + def _probe(self, parent: StxGenericModel): + ocloudid = parent.id + newmodels = self._client.list(ocloudid=ocloudid) + # for newmodel in newmodels: + # logger.info("detect ocloudmodel:" + newmodel.name) + # super()._compare_and_update(newmodel) + # return newmodels + return [commands.UpdateResourcePool(data=m, parentid=ocloudid) + for m in newmodels] diff --git a/o2ims/views/api_ns.py b/o2ims/views/api_ns.py index 955a598..a633a94 100644 --- a/o2ims/views/api_ns.py +++ b/o2ims/views/api_ns.py @@ -1,10 +1,10 @@ -from flask_restx import Namespace - - -api_ims_inventory_v1 = Namespace( - "O2IMS_Inventory", - description='IMS Inventory related operations.') - -api_provision_v1 = Namespace( - "PROVISION", - description='Provision related operations.') +from flask_restx import Namespace + + +api_ims_inventory_v1 = Namespace( + "O2IMS_Inventory", + description='IMS Inventory related operations.') + +api_provision_v1 = Namespace( + "PROVISION", + description='Provision related operations.') diff --git a/o2ims/views/ocloud_view.py b/o2ims/views/ocloud_view.py index 0436f3a..7355f71 100644 --- a/o2ims/views/ocloud_view.py +++ b/o2ims/views/ocloud_view.py @@ -1,140 +1,140 @@ -# Copyright (C) 2021 Wind River Systems, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -import uuid - -from o2common.service import unit_of_work -from o2ims.views.ocloud_dto import SubscriptionDTO -from o2ims.domain.subscription_obj import Subscription - -from o2common.helper import o2logging -logger = o2logging.get_logger(__name__) - - -def oclouds(uow: unit_of_work.AbstractUnitOfWork): - with uow: - li = uow.oclouds.list() - return [r.serialize() for r in li] - - -def ocloud_one(ocloudid: str, uow: unit_of_work.AbstractUnitOfWork): - with uow: - first = uow.oclouds.get(ocloudid) - return first.serialize() if first is not None else None - - -def resource_types(uow: unit_of_work.AbstractUnitOfWork): - with uow: - li = uow.resource_types.list() - return [r.serialize() for r in li] - - -def resource_type_one(resourceTypeId: str, - uow: unit_of_work.AbstractUnitOfWork): - with uow: - first = uow.resource_types.get(resourceTypeId) - return first.serialize() if first is not None else None - - -def resource_pools(uow: unit_of_work.AbstractUnitOfWork): - with uow: - li = uow.resource_pools.list() - return [r.serialize() for r in li] - - -def resource_pool_one(resourcePoolId: str, - uow: unit_of_work.AbstractUnitOfWork): - with uow: - first = uow.resource_pools.get(resourcePoolId) - return first.serialize() if first is not None else None - - -def resources(resourcePoolId: str, uow: unit_of_work.AbstractUnitOfWork, - **kwargs): - - filter_kwargs = {} # filter key should be the same with database name - if 'resourceTypeName' in kwargs: - resource_type_name = kwargs['resourceTypeName'] - with uow: - # res_types = uow.resource_types.list() - # restype_ids = [ - # restype.resourceTypeId for restype in res_types - # if resourceTypeName == restype.name] - # restype_id = '' if len(restype_ids) == 0 else restype_ids[0] - res_type = uow.resource_types.get_by_name(resource_type_name) - restype_id = '' if res_type is None else res_type.resourceTypeId - filter_kwargs['resourceTypeId'] = restype_id - - # li = uow.resources.list(resourcePoolId) - # return [r.serialize() for r in li if r.resourceTypeId == restype_id] - if 'parentId' in kwargs: - filter_kwargs['parentId'] = kwargs['parentId'] - - with uow: - li = uow.resources.list(resourcePoolId, **filter_kwargs) - return [r.serialize() for r in li] - - -def resource_one(resourceId: str, uow: unit_of_work.AbstractUnitOfWork): - with uow: - first = uow.resources.get(resourceId) - return first.serialize() if first is not None else None - - -def deployment_managers(uow: unit_of_work.AbstractUnitOfWork): - with uow: - li = uow.deployment_managers.list() - return [r.serialize() for r in li] - - -def deployment_manager_one(deploymentManagerId: str, - uow: unit_of_work.AbstractUnitOfWork): - with uow: - first = uow.deployment_managers.get(deploymentManagerId) - return first.serialize() if first is not None else None - - -def subscriptions(uow: unit_of_work.AbstractUnitOfWork): - with uow: - li = uow.subscriptions.list() - return [r.serialize() for r in li] - - -def subscription_one(subscriptionId: str, - uow: unit_of_work.AbstractUnitOfWork): - with uow: - first = uow.subscriptions.get(subscriptionId) - return first.serialize() if first is not None else None - - -def subscription_create(subscriptionDto: SubscriptionDTO.subscription, - uow: unit_of_work.AbstractUnitOfWork): - - sub_uuid = str(uuid.uuid4()) - subscription = Subscription( - sub_uuid, subscriptionDto['callback'], - subscriptionDto['consumerSubscriptionId'], - subscriptionDto['filter']) - with uow: - uow.subscriptions.add(subscription) - uow.commit() - return {"subscriptionId": sub_uuid} - - -def subscription_delete(subscriptionId: str, - uow: unit_of_work.AbstractUnitOfWork): - with uow: - uow.subscriptions.delete(subscriptionId) - uow.commit() - return True +# Copyright (C) 2021 Wind River Systems, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import uuid + +from o2common.service import unit_of_work +from o2ims.views.ocloud_dto import SubscriptionDTO +from o2ims.domain.subscription_obj import Subscription + +from o2common.helper import o2logging +logger = o2logging.get_logger(__name__) + + +def oclouds(uow: unit_of_work.AbstractUnitOfWork): + with uow: + li = uow.oclouds.list() + return [r.serialize() for r in li] + + +def ocloud_one(ocloudid: str, uow: unit_of_work.AbstractUnitOfWork): + with uow: + first = uow.oclouds.get(ocloudid) + return first.serialize() if first is not None else None + + +def resource_types(uow: unit_of_work.AbstractUnitOfWork): + with uow: + li = uow.resource_types.list() + return [r.serialize() for r in li] + + +def resource_type_one(resourceTypeId: str, + uow: unit_of_work.AbstractUnitOfWork): + with uow: + first = uow.resource_types.get(resourceTypeId) + return first.serialize() if first is not None else None + + +def resource_pools(uow: unit_of_work.AbstractUnitOfWork): + with uow: + li = uow.resource_pools.list() + return [r.serialize() for r in li] + + +def resource_pool_one(resourcePoolId: str, + uow: unit_of_work.AbstractUnitOfWork): + with uow: + first = uow.resource_pools.get(resourcePoolId) + return first.serialize() if first is not None else None + + +def resources(resourcePoolId: str, uow: unit_of_work.AbstractUnitOfWork, + **kwargs): + + filter_kwargs = {} # filter key should be the same with database name + if 'resourceTypeName' in kwargs: + resource_type_name = kwargs['resourceTypeName'] + with uow: + # res_types = uow.resource_types.list() + # restype_ids = [ + # restype.resourceTypeId for restype in res_types + # if resourceTypeName == restype.name] + # restype_id = '' if len(restype_ids) == 0 else restype_ids[0] + res_type = uow.resource_types.get_by_name(resource_type_name) + restype_id = '' if res_type is None else res_type.resourceTypeId + filter_kwargs['resourceTypeId'] = restype_id + + # li = uow.resources.list(resourcePoolId) + # return [r.serialize() for r in li if r.resourceTypeId == restype_id] + if 'parentId' in kwargs: + filter_kwargs['parentId'] = kwargs['parentId'] + + with uow: + li = uow.resources.list(resourcePoolId, **filter_kwargs) + return [r.serialize() for r in li] + + +def resource_one(resourceId: str, uow: unit_of_work.AbstractUnitOfWork): + with uow: + first = uow.resources.get(resourceId) + return first.serialize() if first is not None else None + + +def deployment_managers(uow: unit_of_work.AbstractUnitOfWork): + with uow: + li = uow.deployment_managers.list() + return [r.serialize() for r in li] + + +def deployment_manager_one(deploymentManagerId: str, + uow: unit_of_work.AbstractUnitOfWork): + with uow: + first = uow.deployment_managers.get(deploymentManagerId) + return first.serialize() if first is not None else None + + +def subscriptions(uow: unit_of_work.AbstractUnitOfWork): + with uow: + li = uow.subscriptions.list() + return [r.serialize() for r in li] + + +def subscription_one(subscriptionId: str, + uow: unit_of_work.AbstractUnitOfWork): + with uow: + first = uow.subscriptions.get(subscriptionId) + return first.serialize() if first is not None else None + + +def subscription_create(subscriptionDto: SubscriptionDTO.subscription, + uow: unit_of_work.AbstractUnitOfWork): + + sub_uuid = str(uuid.uuid4()) + subscription = Subscription( + sub_uuid, subscriptionDto['callback'], + subscriptionDto['consumerSubscriptionId'], + subscriptionDto['filter']) + with uow: + uow.subscriptions.add(subscription) + uow.commit() + return {"subscriptionId": sub_uuid} + + +def subscription_delete(subscriptionId: str, + uow: unit_of_work.AbstractUnitOfWork): + with uow: + uow.subscriptions.delete(subscriptionId) + uow.commit() + return True diff --git a/o2ims/views/provision_view.py b/o2ims/views/provision_view.py index 2a389a7..903a4bb 100644 --- a/o2ims/views/provision_view.py +++ b/o2ims/views/provision_view.py @@ -1,71 +1,71 @@ -# Copyright (C) 2021 Wind River Systems, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -import logging -import uuid -from datetime import datetime - -from o2common.service import unit_of_work, messagebus -from o2ims.domain import events -from o2ims.views.provision_dto import SmoEndpointDTO -from o2ims.domain.configuration_obj import Configuration, ConfigurationTypeEnum - - -def configurations(uow: unit_of_work.AbstractUnitOfWork): - with uow: - li = uow.configurations.list() - return [r.serialize_smo() for r in li] - - -def configuration_one(configurationId: str, - uow: unit_of_work.AbstractUnitOfWork): - with uow: - first = uow.configurations.get(configurationId) - return first.serialize_smo() if first is not None else None - - -def configuration_create(configurationDto: SmoEndpointDTO.endpoint, - bus: messagebus.MessageBus): - - conf_uuid = str(uuid.uuid4()) - configuration = Configuration( - conf_uuid, configurationDto['endpoint'], ConfigurationTypeEnum.SMO) - with bus.uow as uow: - uow.configurations.add(configuration) - logging.debug('before event length {}'.format( - len(configuration.events))) - configuration.events.append(events.ConfigurationChanged( - conf_uuid, - datetime.now())) - logging.debug('after event length {}'.format( - len(configuration.events))) - uow.commit() - _handle_events(bus) - return {"id": conf_uuid} - - -def configuration_delete(configurationId: str, - uow: unit_of_work.AbstractUnitOfWork): - with uow: - uow.configurations.delete(configurationId) - uow.commit() - return True - - -def _handle_events(bus: messagebus.MessageBus): - # handle events - events = bus.uow.collect_new_events() - for event in events: - bus.handle(event) - return True +# Copyright (C) 2021 Wind River Systems, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import logging +import uuid +from datetime import datetime + +from o2common.service import unit_of_work, messagebus +from o2ims.domain import events +from o2ims.views.provision_dto import SmoEndpointDTO +from o2ims.domain.configuration_obj import Configuration, ConfigurationTypeEnum + + +def configurations(uow: unit_of_work.AbstractUnitOfWork): + with uow: + li = uow.configurations.list() + return [r.serialize_smo() for r in li] + + +def configuration_one(configurationId: str, + uow: unit_of_work.AbstractUnitOfWork): + with uow: + first = uow.configurations.get(configurationId) + return first.serialize_smo() if first is not None else None + + +def configuration_create(configurationDto: SmoEndpointDTO.endpoint, + bus: messagebus.MessageBus): + + conf_uuid = str(uuid.uuid4()) + configuration = Configuration( + conf_uuid, configurationDto['endpoint'], ConfigurationTypeEnum.SMO) + with bus.uow as uow: + uow.configurations.add(configuration) + logging.debug('before event length {}'.format( + len(configuration.events))) + configuration.events.append(events.ConfigurationChanged( + conf_uuid, + datetime.now())) + logging.debug('after event length {}'.format( + len(configuration.events))) + uow.commit() + _handle_events(bus) + return {"id": conf_uuid} + + +def configuration_delete(configurationId: str, + uow: unit_of_work.AbstractUnitOfWork): + with uow: + uow.configurations.delete(configurationId) + uow.commit() + return True + + +def _handle_events(bus: messagebus.MessageBus): + # handle events + events = bus.uow.collect_new_events() + for event in events: + bus.handle(event) + return True diff --git a/releases/release-1.0.0.yaml b/releases/release-1.0.0.yaml index 7d2da86..26c4fa3 100644 --- a/releases/release-1.0.0.yaml +++ b/releases/release-1.0.0.yaml @@ -1,11 +1,11 @@ ---- - -distribution_type: container -container_release_tag: 1.0.0 -container_pull_registry: nexus3.o-ran-sc.org:10004 -container_push_registry: nexus3.o-ran-sc.org:10002 -project: pti-o2 -ref: f3ce354b2e6c538b50ed990ba359d3af2283c901 -containers: - - name: pti-o2imsdms - version: 1.0.0 +--- + +distribution_type: container +container_release_tag: 1.0.0 +container_pull_registry: nexus3.o-ran-sc.org:10004 +container_push_registry: nexus3.o-ran-sc.org:10002 +project: pti-o2 +ref: f3ce354b2e6c538b50ed990ba359d3af2283c901 +containers: + - name: pti-o2imsdms + version: 1.0.0 diff --git a/requirements-stx.txt b/requirements-stx.txt index d97f489..4f5ef1a 100644 --- a/requirements-stx.txt +++ b/requirements-stx.txt @@ -1,3 +1,3 @@ --e git+https://opendev.org/starlingx/distcloud-client.git@master#egg=distributedcloud-client&subdirectory=distributedcloud-client --e git+https://opendev.org/starlingx/config.git@master#egg=cgtsclient&subdirectory=sysinv/cgts-client/cgts-client# -# -e git+https://github.com/cloudify-incubator/cloudify-helm-plugin.git@master#egg=helmsdk&subdirectory=helm_sdk +-e git+https://opendev.org/starlingx/distcloud-client.git@master#egg=distributedcloud-client&subdirectory=distributedcloud-client +-e git+https://opendev.org/starlingx/config.git@master#egg=cgtsclient&subdirectory=sysinv/cgts-client/cgts-client# +# -e git+https://github.com/cloudify-incubator/cloudify-helm-plugin.git@master#egg=helmsdk&subdirectory=helm_sdk diff --git a/requirements-test.txt b/requirements-test.txt index 9b6cbe9..da66309 100644 --- a/requirements-test.txt +++ b/requirements-test.txt @@ -1,15 +1,15 @@ -flake8 -pylint -mypy -requests -tox - -pytest -pytest-cov -pytest-icdiff -mock - -tenacity - -# -e git+https://opendev.org/starlingx/distcloud-client.git@master#egg=distributedcloud-client&subdirectory=distributedcloud-client -# -e git+https://opendev.org/starlingx/config.git@master#egg=cgtsclient&subdirectory=sysinv/cgts-client/cgts-client +flake8 +pylint +mypy +requests +tox + +pytest +pytest-cov +pytest-icdiff +mock + +tenacity + +# -e git+https://opendev.org/starlingx/distcloud-client.git@master#egg=distributedcloud-client&subdirectory=distributedcloud-client +# -e git+https://opendev.org/starlingx/config.git@master#egg=cgtsclient&subdirectory=sysinv/cgts-client/cgts-client diff --git a/requirements.txt b/requirements.txt index 8fa5839..f1fc633 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,17 +1,17 @@ -flask -flask-restx -sqlalchemy -redis -psycopg2-binary -cotyledon -PyYAML>=5.4.1 - -Cython>=3.0a1 - - -httplib2 -babel -PrettyTable<0.8,>=0.7.2 - -retry +flask +flask-restx +sqlalchemy +redis +psycopg2-binary +cotyledon +PyYAML>=5.4.1 + +Cython>=3.0a1 + + +httplib2 +babel +PrettyTable<0.8,>=0.7.2 + +retry ruamel.yaml==0.17.17 \ No newline at end of file diff --git a/setup.py b/setup.py index 553dd19..15d0e9e 100644 --- a/setup.py +++ b/setup.py @@ -1,17 +1,17 @@ -from setuptools import setup -from setuptools import find_packages - -setup( - name="o2imsdms", - version="1.0", - packages=find_packages(), - license="LICENSE", - description="Represent O2 IMS and O2 DMS", - install_requires=[ - 'httplib2', - # 'distributedcloud-client', - # 'cgtsclient', - 'babel', # Required by distributedcloud-client - 'PrettyTable<0.8,>=0.7.2', # Required by distributedcloud-client - ] -) +from setuptools import setup +from setuptools import find_packages + +setup( + name="o2imsdms", + version="1.0", + packages=find_packages(), + license="LICENSE", + description="Represent O2 IMS and O2 DMS", + install_requires=[ + 'httplib2', + # 'distributedcloud-client', + # 'cgtsclient', + 'babel', # Required by distributedcloud-client + 'PrettyTable<0.8,>=0.7.2', # Required by distributedcloud-client + ] +) diff --git a/stages/container-tag.yaml b/stages/container-tag.yaml index ae42d95..73a715b 100644 --- a/stages/container-tag.yaml +++ b/stages/container-tag.yaml @@ -1,5 +1,5 @@ -# The Jenkins job requires a tag to build the Docker image. -# By default this file is in the docker build directory, -# but the location can configured in the JJB template. ---- -tag: "1.0.0" +# The Jenkins job requires a tag to build the Docker image. +# By default this file is in the docker build directory, +# but the location can configured in the JJB template. +--- +tag: "1.0.0" diff --git a/tests/__init__.py b/tests/__init__.py index b514342..813897e 100644 --- a/tests/__init__.py +++ b/tests/__init__.py @@ -1,13 +1,13 @@ -# Copyright (C) 2021 Wind River Systems, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. +# Copyright (C) 2021 Wind River Systems, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. diff --git a/tests/conftest.py b/tests/conftest.py index a1655b4..09667d5 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -1,160 +1,160 @@ -# pylint: disable=redefined-outer-name -import shutil -import subprocess -import time -from pathlib import Path - -import pytest -import redis -import requests -from flask import Flask -from flask_restx import Api -from sqlalchemy import create_engine -from sqlalchemy.orm import sessionmaker, clear_mappers -from tenacity import retry, stop_after_delay -from unittest.mock import MagicMock - -from o2common.config import config - -from o2ims.adapter.orm import metadata, start_o2ims_mappers -# from o2ims.adapter.clients.orm_stx import start_o2ims_stx_mappers - -from o2app.adapter import unit_of_work -from o2ims.views import configure_namespace - -from o2app.bootstrap import bootstrap - - -@pytest.fixture -def mock_uow(): - session = MagicMock() - uow = unit_of_work.SqlAlchemyUnitOfWork(session_factory=session) - return session, uow - - -@pytest.fixture -def mock_flask_uow(mock_uow): - session, uow = mock_uow - app = Flask(__name__) - app.config["TESTING"] = True - api = Api(app) - bootstrap(False, uow) - configure_namespace(api) - return session, app - - -@pytest.fixture -def in_memory_sqlite_db(): - engine = create_engine("sqlite:///:memory:") - # engine = create_engine("sqlite:///:memory:", echo=True) - metadata.create_all(engine) - return engine - - -@pytest.fixture -def sqlite_session_factory(in_memory_sqlite_db): - yield sessionmaker(bind=in_memory_sqlite_db) - - -@pytest.fixture -def sqlite_uow(sqlite_session_factory): - uow = unit_of_work.SqlAlchemyUnitOfWork( - session_factory=sqlite_session_factory) - # with uow: - # start_o2ims_mappers(uow.session.get_bind()) - # uow.commit() - yield uow - # clear_mappers() - with uow: - engine = uow.session.get_bind() - metadata.drop_all(engine) - - -@pytest.fixture -def sqlite_flask_uow(sqlite_uow): - app = Flask(__name__) - app.config["TESTING"] = True - api = Api(app) - bootstrap(False, sqlite_uow) - configure_namespace(api) - yield sqlite_uow, app - - -@pytest.fixture -def mappers(): - start_o2ims_mappers() - # start_o2ims_stx_mappers() - yield - clear_mappers() - - -@retry(stop=stop_after_delay(10)) -def wait_for_postgres_to_come_up(engine): - return engine.connect() - - -@retry(stop=stop_after_delay(10)) -def wait_for_webapp_to_come_up(): - return requests.get(config.get_api_url()) - - -@retry(stop=stop_after_delay(10)) -def wait_for_redis_to_come_up(): - r = redis.Redis(**config.get_redis_host_and_port()) - return r.ping() - - -@pytest.fixture(scope="session") -def postgres_db(): - engine = create_engine(config.get_postgres_uri(), - isolation_level="SERIALIZABLE") - wait_for_postgres_to_come_up(engine) - metadata.create_all(engine) - return engine - - -@pytest.fixture -def postgres_session_factory(postgres_db): - yield sessionmaker(bind=postgres_db) - - -@pytest.fixture -def postgres_session(postgres_session_factory): - return postgres_session_factory() - - -@pytest.fixture -def postgres_uow(postgres_session_factory): - uow = unit_of_work.SqlAlchemyUnitOfWork( - session_factory=postgres_session_factory) - yield uow - - -@pytest.fixture -def postgres_flask_uow(postgres_uow): - app = Flask(__name__) - app.config["TESTING"] = True - api = Api(app) - bootstrap(False, postgres_uow) - configure_namespace(api) - yield postgres_uow, app - - -@pytest.fixture -def restart_api(): - (Path(__file__).parent / "../src/o2ims/entrypoints/flask_application.py")\ - .touch() - time.sleep(0.5) - wait_for_webapp_to_come_up() - - -@pytest.fixture -def restart_redis_pubsub(): - wait_for_redis_to_come_up() - if not shutil.which("docker-compose"): - print("skipping restart, assumes running in container") - return - subprocess.run( - ["docker-compose", "restart", "-t", "0", "redis_pubsub"], - check=True, - ) +# pylint: disable=redefined-outer-name +import shutil +import subprocess +import time +from pathlib import Path + +import pytest +import redis +import requests +from flask import Flask +from flask_restx import Api +from sqlalchemy import create_engine +from sqlalchemy.orm import sessionmaker, clear_mappers +from tenacity import retry, stop_after_delay +from unittest.mock import MagicMock + +from o2common.config import config + +from o2ims.adapter.orm import metadata, start_o2ims_mappers +# from o2ims.adapter.clients.orm_stx import start_o2ims_stx_mappers + +from o2app.adapter import unit_of_work +from o2ims.views import configure_namespace + +from o2app.bootstrap import bootstrap + + +@pytest.fixture +def mock_uow(): + session = MagicMock() + uow = unit_of_work.SqlAlchemyUnitOfWork(session_factory=session) + return session, uow + + +@pytest.fixture +def mock_flask_uow(mock_uow): + session, uow = mock_uow + app = Flask(__name__) + app.config["TESTING"] = True + api = Api(app) + bootstrap(False, uow) + configure_namespace(api) + return session, app + + +@pytest.fixture +def in_memory_sqlite_db(): + engine = create_engine("sqlite:///:memory:") + # engine = create_engine("sqlite:///:memory:", echo=True) + metadata.create_all(engine) + return engine + + +@pytest.fixture +def sqlite_session_factory(in_memory_sqlite_db): + yield sessionmaker(bind=in_memory_sqlite_db) + + +@pytest.fixture +def sqlite_uow(sqlite_session_factory): + uow = unit_of_work.SqlAlchemyUnitOfWork( + session_factory=sqlite_session_factory) + # with uow: + # start_o2ims_mappers(uow.session.get_bind()) + # uow.commit() + yield uow + # clear_mappers() + with uow: + engine = uow.session.get_bind() + metadata.drop_all(engine) + + +@pytest.fixture +def sqlite_flask_uow(sqlite_uow): + app = Flask(__name__) + app.config["TESTING"] = True + api = Api(app) + bootstrap(False, sqlite_uow) + configure_namespace(api) + yield sqlite_uow, app + + +@pytest.fixture +def mappers(): + start_o2ims_mappers() + # start_o2ims_stx_mappers() + yield + clear_mappers() + + +@retry(stop=stop_after_delay(10)) +def wait_for_postgres_to_come_up(engine): + return engine.connect() + + +@retry(stop=stop_after_delay(10)) +def wait_for_webapp_to_come_up(): + return requests.get(config.get_api_url()) + + +@retry(stop=stop_after_delay(10)) +def wait_for_redis_to_come_up(): + r = redis.Redis(**config.get_redis_host_and_port()) + return r.ping() + + +@pytest.fixture(scope="session") +def postgres_db(): + engine = create_engine(config.get_postgres_uri(), + isolation_level="SERIALIZABLE") + wait_for_postgres_to_come_up(engine) + metadata.create_all(engine) + return engine + + +@pytest.fixture +def postgres_session_factory(postgres_db): + yield sessionmaker(bind=postgres_db) + + +@pytest.fixture +def postgres_session(postgres_session_factory): + return postgres_session_factory() + + +@pytest.fixture +def postgres_uow(postgres_session_factory): + uow = unit_of_work.SqlAlchemyUnitOfWork( + session_factory=postgres_session_factory) + yield uow + + +@pytest.fixture +def postgres_flask_uow(postgres_uow): + app = Flask(__name__) + app.config["TESTING"] = True + api = Api(app) + bootstrap(False, postgres_uow) + configure_namespace(api) + yield postgres_uow, app + + +@pytest.fixture +def restart_api(): + (Path(__file__).parent / "../src/o2ims/entrypoints/flask_application.py")\ + .touch() + time.sleep(0.5) + wait_for_webapp_to_come_up() + + +@pytest.fixture +def restart_redis_pubsub(): + wait_for_redis_to_come_up() + if not shutil.which("docker-compose"): + print("skipping restart, assumes running in container") + return + subprocess.run( + ["docker-compose", "restart", "-t", "0", "redis_pubsub"], + check=True, + ) diff --git a/tests/e2e/__init__.py b/tests/e2e/__init__.py index b514342..813897e 100644 --- a/tests/e2e/__init__.py +++ b/tests/e2e/__init__.py @@ -1,13 +1,13 @@ -# Copyright (C) 2021 Wind River Systems, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. +# Copyright (C) 2021 Wind River Systems, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. diff --git a/tests/integration-ocloud/__init__.py b/tests/integration-ocloud/__init__.py index b514342..813897e 100644 --- a/tests/integration-ocloud/__init__.py +++ b/tests/integration-ocloud/__init__.py @@ -1,13 +1,13 @@ -# Copyright (C) 2021 Wind River Systems, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. +# Copyright (C) 2021 Wind River Systems, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. diff --git a/tests/integration-ocloud/test_clientdriver_stx_sa.py b/tests/integration-ocloud/test_clientdriver_stx_sa.py index b2bd8c8..57598a9 100644 --- a/tests/integration-ocloud/test_clientdriver_stx_sa.py +++ b/tests/integration-ocloud/test_clientdriver_stx_sa.py @@ -1,147 +1,147 @@ -# Copyright (C) 2021 Wind River Systems, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# import sys -# import logging -import pytest - -from o2common.config import config -from o2ims.adapter.clients.ocloud_sa_client import StxSaClientImp -from cgtsclient.client import get_client - - -@pytest.fixture -def real_stx_aio_client(): - os_client_args = config.get_stx_access_info() - config_client = get_client(**os_client_args) - yield config_client - -# pytestmark = pytest.mark.usefixtures("mappers") - - -def test_get_instanceinfo(real_stx_aio_client): - # logger = logging.getLogger(__name__) - stxclientimp = StxSaClientImp(real_stx_aio_client) - assert stxclientimp is not None - systeminfo = stxclientimp.getInstanceInfo() - assert systeminfo is not None - assert systeminfo.id is not None - assert systeminfo.name is not None - assert systeminfo.content is not None - - -def test_get_pserverlist(real_stx_aio_client): - stxSaClientImp = StxSaClientImp(real_stx_aio_client) - assert stxSaClientImp is not None - hosts = stxSaClientImp.getPserverList() - assert hosts is not None - assert len(hosts) > 0 - - -def test_get_pserver(real_stx_aio_client): - stxSaClientImp = StxSaClientImp(real_stx_aio_client) - assert stxSaClientImp is not None - hosts = stxSaClientImp.getPserverList() - assert hosts is not None - assert len(hosts) > 0 - host1 = hosts[0] - host2 = stxSaClientImp.getPserver(host1.id) - assert host1 != host2 - assert host1.id == host2.id - - -def test_get_k8s_list(real_stx_aio_client): - stxSaClientImp = StxSaClientImp(real_stx_aio_client) - assert stxSaClientImp is not None - k8slist = stxSaClientImp.getK8sList() - assert k8slist is not None - assert len(k8slist) > 0 - k8s1 = k8slist[0] - k8s2 = stxSaClientImp.getK8sDetail(k8s1.name) - assert k8s1 != k8s2 - assert k8s1.name == k8s2.name - assert k8s1.id == k8s2.id - - -def test_get_cpu_list(real_stx_aio_client): - stxSaClientImp = StxSaClientImp(real_stx_aio_client) - assert stxSaClientImp is not None - hostlist = stxSaClientImp.getPserverList() - assert len(hostlist) > 0 - - cpulist = stxSaClientImp.getCpuList(hostid=hostlist[0].id) - assert len(cpulist) > 0 - cpu1 = cpulist[0] - cpu2 = stxSaClientImp.getCpu(cpu1.id) - assert cpu1 != cpu2 - assert cpu1.id == cpu2.id - - -def test_get_mem_list(real_stx_aio_client): - stxSaClientImp = StxSaClientImp(real_stx_aio_client) - assert stxSaClientImp is not None - hostlist = stxSaClientImp.getPserverList() - assert len(hostlist) > 0 - - memlist = stxSaClientImp.getMemList(hostid=hostlist[0].id) - assert len(memlist) > 0 - mem1 = memlist[0] - mem2 = stxSaClientImp.getMem(mem1.id) - assert mem1 != mem2 - assert mem1.id == mem2.id - - -def test_get_eth_list(real_stx_aio_client): - stxSaClientImp = StxSaClientImp(real_stx_aio_client) - assert stxSaClientImp is not None - hostlist = stxSaClientImp.getPserverList() - assert len(hostlist) > 0 - - ethlist = stxSaClientImp.getEthernetList(hostid=hostlist[0].id) - assert len(ethlist) > 0 - eth1 = ethlist[0] - eth2 = stxSaClientImp.getEthernet(eth1.id) - assert eth1 != eth2 - assert eth1.id == eth2.id - - -def test_get_if_list(real_stx_aio_client): - stxSaClientImp = StxSaClientImp(real_stx_aio_client) - assert stxSaClientImp is not None - hostlist = stxSaClientImp.getPserverList() - assert len(hostlist) > 0 - - iflist = stxSaClientImp.getIfList(hostid=hostlist[0].id) - assert len(iflist) > 0 - if1 = iflist[0] - if2 = stxSaClientImp.getIf(if1.id) - assert if1 != if2 - assert if1.id == if2.id - - -def test_get_if_port_list(real_stx_aio_client): - stxSaClientImp = StxSaClientImp(real_stx_aio_client) - assert stxSaClientImp is not None - hostlist = stxSaClientImp.getPserverList() - assert len(hostlist) > 0 - - iflist = stxSaClientImp.getIfList(hostid=hostlist[0].id) - assert len(iflist) > 0 - - portlist = stxSaClientImp.getPortList(interfaceid=iflist[0].id) - assert len(portlist) > 0 - port1 = portlist[0] - port2 = stxSaClientImp.getPort(port1.id) - assert port1 != port2 - assert port1.id == port2.id +# Copyright (C) 2021 Wind River Systems, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# import sys +# import logging +import pytest + +from o2common.config import config +from o2ims.adapter.clients.ocloud_sa_client import StxSaClientImp +from cgtsclient.client import get_client + + +@pytest.fixture +def real_stx_aio_client(): + os_client_args = config.get_stx_access_info() + config_client = get_client(**os_client_args) + yield config_client + +# pytestmark = pytest.mark.usefixtures("mappers") + + +def test_get_instanceinfo(real_stx_aio_client): + # logger = logging.getLogger(__name__) + stxclientimp = StxSaClientImp(real_stx_aio_client) + assert stxclientimp is not None + systeminfo = stxclientimp.getInstanceInfo() + assert systeminfo is not None + assert systeminfo.id is not None + assert systeminfo.name is not None + assert systeminfo.content is not None + + +def test_get_pserverlist(real_stx_aio_client): + stxSaClientImp = StxSaClientImp(real_stx_aio_client) + assert stxSaClientImp is not None + hosts = stxSaClientImp.getPserverList() + assert hosts is not None + assert len(hosts) > 0 + + +def test_get_pserver(real_stx_aio_client): + stxSaClientImp = StxSaClientImp(real_stx_aio_client) + assert stxSaClientImp is not None + hosts = stxSaClientImp.getPserverList() + assert hosts is not None + assert len(hosts) > 0 + host1 = hosts[0] + host2 = stxSaClientImp.getPserver(host1.id) + assert host1 != host2 + assert host1.id == host2.id + + +def test_get_k8s_list(real_stx_aio_client): + stxSaClientImp = StxSaClientImp(real_stx_aio_client) + assert stxSaClientImp is not None + k8slist = stxSaClientImp.getK8sList() + assert k8slist is not None + assert len(k8slist) > 0 + k8s1 = k8slist[0] + k8s2 = stxSaClientImp.getK8sDetail(k8s1.name) + assert k8s1 != k8s2 + assert k8s1.name == k8s2.name + assert k8s1.id == k8s2.id + + +def test_get_cpu_list(real_stx_aio_client): + stxSaClientImp = StxSaClientImp(real_stx_aio_client) + assert stxSaClientImp is not None + hostlist = stxSaClientImp.getPserverList() + assert len(hostlist) > 0 + + cpulist = stxSaClientImp.getCpuList(hostid=hostlist[0].id) + assert len(cpulist) > 0 + cpu1 = cpulist[0] + cpu2 = stxSaClientImp.getCpu(cpu1.id) + assert cpu1 != cpu2 + assert cpu1.id == cpu2.id + + +def test_get_mem_list(real_stx_aio_client): + stxSaClientImp = StxSaClientImp(real_stx_aio_client) + assert stxSaClientImp is not None + hostlist = stxSaClientImp.getPserverList() + assert len(hostlist) > 0 + + memlist = stxSaClientImp.getMemList(hostid=hostlist[0].id) + assert len(memlist) > 0 + mem1 = memlist[0] + mem2 = stxSaClientImp.getMem(mem1.id) + assert mem1 != mem2 + assert mem1.id == mem2.id + + +def test_get_eth_list(real_stx_aio_client): + stxSaClientImp = StxSaClientImp(real_stx_aio_client) + assert stxSaClientImp is not None + hostlist = stxSaClientImp.getPserverList() + assert len(hostlist) > 0 + + ethlist = stxSaClientImp.getEthernetList(hostid=hostlist[0].id) + assert len(ethlist) > 0 + eth1 = ethlist[0] + eth2 = stxSaClientImp.getEthernet(eth1.id) + assert eth1 != eth2 + assert eth1.id == eth2.id + + +def test_get_if_list(real_stx_aio_client): + stxSaClientImp = StxSaClientImp(real_stx_aio_client) + assert stxSaClientImp is not None + hostlist = stxSaClientImp.getPserverList() + assert len(hostlist) > 0 + + iflist = stxSaClientImp.getIfList(hostid=hostlist[0].id) + assert len(iflist) > 0 + if1 = iflist[0] + if2 = stxSaClientImp.getIf(if1.id) + assert if1 != if2 + assert if1.id == if2.id + + +def test_get_if_port_list(real_stx_aio_client): + stxSaClientImp = StxSaClientImp(real_stx_aio_client) + assert stxSaClientImp is not None + hostlist = stxSaClientImp.getPserverList() + assert len(hostlist) > 0 + + iflist = stxSaClientImp.getIfList(hostid=hostlist[0].id) + assert len(iflist) > 0 + + portlist = stxSaClientImp.getPortList(interfaceid=iflist[0].id) + assert len(portlist) > 0 + port1 = portlist[0] + port2 = stxSaClientImp.getPort(port1.id) + assert port1 != port2 + assert port1.id == port2.id diff --git a/tests/integration-ocloud/test_watcher_w_stx_sa.py b/tests/integration-ocloud/test_watcher_w_stx_sa.py index 1525ab1..2841606 100644 --- a/tests/integration-ocloud/test_watcher_w_stx_sa.py +++ b/tests/integration-ocloud/test_watcher_w_stx_sa.py @@ -1,30 +1,30 @@ -# Copyright (C) 2021 Wind River Systems, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from multiprocessing.queues import Queue -import pytest -from o2app.entrypoints.resource_watcher import start_watchers -from multiprocessing import Process -from multiprocessing import Pipe -# pipe = Pipe() -# q = Queue() -import time -# pytestmark = pytest.mark.usefixtures("mappers") - - -def test_watcher_service(): - testedprocess = Process(target=start_watchers, args=()) - testedprocess.start() - time.sleep(10) - testedprocess.terminate() +# Copyright (C) 2021 Wind River Systems, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from multiprocessing.queues import Queue +import pytest +from o2app.entrypoints.resource_watcher import start_watchers +from multiprocessing import Process +from multiprocessing import Pipe +# pipe = Pipe() +# q = Queue() +import time +# pytestmark = pytest.mark.usefixtures("mappers") + + +def test_watcher_service(): + testedprocess = Process(target=start_watchers, args=()) + testedprocess.start() + time.sleep(10) + testedprocess.terminate() diff --git a/tests/integration/__init__.py b/tests/integration/__init__.py index b514342..813897e 100644 --- a/tests/integration/__init__.py +++ b/tests/integration/__init__.py @@ -1,13 +1,13 @@ -# Copyright (C) 2021 Wind River Systems, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. +# Copyright (C) 2021 Wind River Systems, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. diff --git a/tests/integration/test_clientdriver_fake_stx_sa.py b/tests/integration/test_clientdriver_fake_stx_sa.py index 8dc84d9..56c92d3 100644 --- a/tests/integration/test_clientdriver_fake_stx_sa.py +++ b/tests/integration/test_clientdriver_fake_stx_sa.py @@ -1,59 +1,59 @@ -# Copyright (C) 2021 Wind River Systems, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from datetime import date, datetime -import sys -import pytest -from o2ims.adapter import ocloud_repository as repository -from o2ims.domain import ocloud -from o2common.config import config -import logging -import uuid -import json -from o2ims.adapter.clients.ocloud_sa_client import StxSaOcloudClient -from o2ims.domain import stx_object as ocloudModel -from o2ims.domain.resource_type import ResourceTypeEnum - -# pytestmark = pytest.mark.usefixtures("mappers") - - -class FakeStxSaClientImp(object): - def __init__(self): - super().__init__() - - def getInstanceInfo(self) -> ocloudModel.StxGenericModel: - model = ocloudModel.StxGenericModel(ResourceTypeEnum.OCLOUD) - model.id = uuid.uuid4() - model.name = "stx1" - model.updatetime = datetime.now - model.createtime = datetime.now - model.content = json.dumps({}) - return model - - -@pytest.fixture -def fake_driver_imp(): - fakedriver = FakeStxSaClientImp() - yield fakedriver - - -def test_get_instanceinfo(fake_driver_imp): - logger = logging.getLogger(__name__) - stxclientimp = StxSaOcloudClient(fake_driver_imp) - assert stxclientimp is not None - systeminfo = stxclientimp.get(None) - assert systeminfo is not None - assert systeminfo.id is not None - assert systeminfo.name == "stx1" - assert systeminfo.content == json.dumps({}) +# Copyright (C) 2021 Wind River Systems, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from datetime import date, datetime +import sys +import pytest +from o2ims.adapter import ocloud_repository as repository +from o2ims.domain import ocloud +from o2common.config import config +import logging +import uuid +import json +from o2ims.adapter.clients.ocloud_sa_client import StxSaOcloudClient +from o2ims.domain import stx_object as ocloudModel +from o2ims.domain.resource_type import ResourceTypeEnum + +# pytestmark = pytest.mark.usefixtures("mappers") + + +class FakeStxSaClientImp(object): + def __init__(self): + super().__init__() + + def getInstanceInfo(self) -> ocloudModel.StxGenericModel: + model = ocloudModel.StxGenericModel(ResourceTypeEnum.OCLOUD) + model.id = uuid.uuid4() + model.name = "stx1" + model.updatetime = datetime.now + model.createtime = datetime.now + model.content = json.dumps({}) + return model + + +@pytest.fixture +def fake_driver_imp(): + fakedriver = FakeStxSaClientImp() + yield fakedriver + + +def test_get_instanceinfo(fake_driver_imp): + logger = logging.getLogger(__name__) + stxclientimp = StxSaOcloudClient(fake_driver_imp) + assert stxclientimp is not None + systeminfo = stxclientimp.get(None) + assert systeminfo is not None + assert systeminfo.id is not None + assert systeminfo.name == "stx1" + assert systeminfo.content == json.dumps({}) diff --git a/tests/unit/__init__.py b/tests/unit/__init__.py index b514342..813897e 100644 --- a/tests/unit/__init__.py +++ b/tests/unit/__init__.py @@ -1,13 +1,13 @@ -# Copyright (C) 2021 Wind River Systems, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. +# Copyright (C) 2021 Wind River Systems, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. diff --git a/tests/unit/test_watcher.py b/tests/unit/test_watcher.py index 806d20f..2fe82ab 100644 --- a/tests/unit/test_watcher.py +++ b/tests/unit/test_watcher.py @@ -1,201 +1,201 @@ -# Copyright (C) 2021 Wind River Systems, Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -import time -from datetime import datetime -import json -from typing import Callable, List -# from o2common.config import config -import uuid -from o2common.service.watcher.base import BaseWatcher, WatcherTree -from o2common.service.watcher import worker -from o2common.service.unit_of_work import AbstractUnitOfWork -from o2common.service import messagebus - -from o2ims.domain.resource_type import ResourceTypeEnum -from o2ims.domain import stx_object as ocloudModel -from o2ims.adapter.ocloud_repository import OcloudRepository -from o2ims.domain.stx_repo import StxObjectRepository -from o2ims.service.watcher.ocloud_watcher import OcloudWatcher -from o2ims.domain import commands -from o2common.service.client.base_client import BaseClient -from o2ims.domain import ocloud - -from o2app.service import handlers -from o2app import bootstrap - - -class FakeOcloudClient(BaseClient): - def __init__(self): - super().__init__() - fakeCloud = ocloudModel.StxGenericModel(ResourceTypeEnum.OCLOUD) - fakeCloud.id = uuid.uuid4() - fakeCloud.name = 'stx1' - fakeCloud.content = json.dumps({}) - fakeCloud.createtime = datetime.now() - fakeCloud.updatetime = datetime.now() - fakeCloud.hash = str(hash((fakeCloud.id, fakeCloud.updatetime))) - self.fakeCloud = fakeCloud - - def _get(self, id) -> ocloudModel.StxGenericModel: - return self.fakeCloud - - def _list(self): - return [self.fakeCloud] - - -class FakeOcloudRepo(OcloudRepository): - def __init__(self): - super().__init__() - self.oclouds = [] - - def _add(self, ocloud: ocloud.Ocloud): - self.oclouds.append(ocloud) - - def _get(self, ocloudid) -> ocloud.Ocloud: - filtered = [o for o in self.oclouds if o.id == ocloudid] - return filtered.pop() - - def _list(self) -> List[ocloud.Ocloud]: - return [x for x in self.oclouds] - - def _update(self, ocloud: ocloud.Ocloud): - filtered = [o for o in self.oclouds if o.id == ocloud.id] - assert len(filtered) == 1 - ocloud1 = filtered.pop() - ocloud1.update_by(ocloud) - - -class FakeStxObjRepo(StxObjectRepository): - def __init__(self): - super().__init__() - self.oclouds = [] - - def _add(self, ocloud: ocloud.Ocloud): - self.oclouds.append(ocloud) - - def _get(self, ocloudid) -> ocloud.Ocloud: - filtered = [o for o in self.oclouds if o.id == ocloudid] - return filtered.pop() - - def _list(self, type: ResourceTypeEnum) -> List[ocloud.Ocloud]: - return [x for x in self.oclouds] - - def _update(self, ocloud: ocloud.Ocloud): - filtered = [o for o in self.oclouds if o.id == ocloud.id] - assert len(filtered) == 1 - ocloud1 = filtered.pop() - ocloud1.update_by(ocloud) - - -class FakeUnitOfWork(AbstractUnitOfWork): - def __init__(self): - pass - - def __enter__(self): - # self.session = self.session_factory() # type: Session - # self.oclouds = OcloudSqlAlchemyRepository(self.session) - self.stxobjects = FakeStxObjRepo() - return super().__enter__() - - def __exit__(self, *args): - super().__exit__(*args) - # self.session.close() - - def _commit(self): - pass - # self.session.commit() - - def rollback(self): - pass - # self.session.rollback() - - def collect_new_events(self): - yield - # return super().collect_new_events() - - -def create_fake_bus(uow): - def update_ocloud( - cmd: commands.UpdateOCloud, - uow: AbstractUnitOfWork, - publish: Callable): - return - - fakeuow = FakeUnitOfWork() - handlers.EVENT_HANDLERS = {} - handlers.COMMAND_HANDLERS = { - commands.UpdateOCloud: update_ocloud, - } - bus = bootstrap.bootstrap(False, fakeuow) - return bus - - -def test_probe_new_ocloud(): - fakeuow = FakeUnitOfWork() - bus = create_fake_bus(fakeuow) - fakeClient = FakeOcloudClient() - ocloudwatcher = OcloudWatcher(fakeClient, bus) - cmds = ocloudwatcher.probe() - assert cmds is not None - assert len(cmds) == 1 - assert cmds[0].data.name == "stx1" - # assert len(fakeuow.stxobjects.oclouds) == 1 - # assert fakeuow.stxobjects.oclouds[0].name == "stx1" - - -def test_watchers_worker(): - testedworker = worker.PollWorker() - - class FakeOCloudWatcher(BaseWatcher): - def __init__(self, client: BaseClient, - bus: messagebus) -> None: - super().__init__(client, None) - self.fakeOcloudWatcherCounter = 0 - self._client = client - self._bus = bus - - def _targetname(self): - return "fakeocloudwatcher" - - def _probe(self, parent: object = None): - # import pdb; pdb.set_trace() - self.fakeOcloudWatcherCounter += 1 - # hacking to stop the blocking sched task - if self.fakeOcloudWatcherCounter > 2: - testedworker.stop() - return [] - - # fakeRepo = FakeOcloudRepo() - fakeuow = FakeUnitOfWork() - bus = create_fake_bus(fakeuow) - - fakeClient = FakeOcloudClient() - fakewatcher = FakeOCloudWatcher(fakeClient, bus) - - root = WatcherTree(fakewatcher) - - testedworker.set_interval(1) - testedworker.add_watcher(root) - assert fakewatcher.fakeOcloudWatcherCounter == 0 - - count1 = fakewatcher.fakeOcloudWatcherCounter - testedworker.start() - time.sleep(20) - assert fakewatcher.fakeOcloudWatcherCounter > count1 - - # assumed hacking: probe has stopped the sched task - count3 = fakewatcher.fakeOcloudWatcherCounter - time.sleep(3) - assert fakewatcher.fakeOcloudWatcherCounter == count3 +# Copyright (C) 2021 Wind River Systems, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import time +from datetime import datetime +import json +from typing import Callable, List +# from o2common.config import config +import uuid +from o2common.service.watcher.base import BaseWatcher, WatcherTree +from o2common.service.watcher import worker +from o2common.service.unit_of_work import AbstractUnitOfWork +from o2common.service import messagebus + +from o2ims.domain.resource_type import ResourceTypeEnum +from o2ims.domain import stx_object as ocloudModel +from o2ims.adapter.ocloud_repository import OcloudRepository +from o2ims.domain.stx_repo import StxObjectRepository +from o2ims.service.watcher.ocloud_watcher import OcloudWatcher +from o2ims.domain import commands +from o2common.service.client.base_client import BaseClient +from o2ims.domain import ocloud + +from o2app.service import handlers +from o2app import bootstrap + + +class FakeOcloudClient(BaseClient): + def __init__(self): + super().__init__() + fakeCloud = ocloudModel.StxGenericModel(ResourceTypeEnum.OCLOUD) + fakeCloud.id = uuid.uuid4() + fakeCloud.name = 'stx1' + fakeCloud.content = json.dumps({}) + fakeCloud.createtime = datetime.now() + fakeCloud.updatetime = datetime.now() + fakeCloud.hash = str(hash((fakeCloud.id, fakeCloud.updatetime))) + self.fakeCloud = fakeCloud + + def _get(self, id) -> ocloudModel.StxGenericModel: + return self.fakeCloud + + def _list(self): + return [self.fakeCloud] + + +class FakeOcloudRepo(OcloudRepository): + def __init__(self): + super().__init__() + self.oclouds = [] + + def _add(self, ocloud: ocloud.Ocloud): + self.oclouds.append(ocloud) + + def _get(self, ocloudid) -> ocloud.Ocloud: + filtered = [o for o in self.oclouds if o.id == ocloudid] + return filtered.pop() + + def _list(self) -> List[ocloud.Ocloud]: + return [x for x in self.oclouds] + + def _update(self, ocloud: ocloud.Ocloud): + filtered = [o for o in self.oclouds if o.id == ocloud.id] + assert len(filtered) == 1 + ocloud1 = filtered.pop() + ocloud1.update_by(ocloud) + + +class FakeStxObjRepo(StxObjectRepository): + def __init__(self): + super().__init__() + self.oclouds = [] + + def _add(self, ocloud: ocloud.Ocloud): + self.oclouds.append(ocloud) + + def _get(self, ocloudid) -> ocloud.Ocloud: + filtered = [o for o in self.oclouds if o.id == ocloudid] + return filtered.pop() + + def _list(self, type: ResourceTypeEnum) -> List[ocloud.Ocloud]: + return [x for x in self.oclouds] + + def _update(self, ocloud: ocloud.Ocloud): + filtered = [o for o in self.oclouds if o.id == ocloud.id] + assert len(filtered) == 1 + ocloud1 = filtered.pop() + ocloud1.update_by(ocloud) + + +class FakeUnitOfWork(AbstractUnitOfWork): + def __init__(self): + pass + + def __enter__(self): + # self.session = self.session_factory() # type: Session + # self.oclouds = OcloudSqlAlchemyRepository(self.session) + self.stxobjects = FakeStxObjRepo() + return super().__enter__() + + def __exit__(self, *args): + super().__exit__(*args) + # self.session.close() + + def _commit(self): + pass + # self.session.commit() + + def rollback(self): + pass + # self.session.rollback() + + def collect_new_events(self): + yield + # return super().collect_new_events() + + +def create_fake_bus(uow): + def update_ocloud( + cmd: commands.UpdateOCloud, + uow: AbstractUnitOfWork, + publish: Callable): + return + + fakeuow = FakeUnitOfWork() + handlers.EVENT_HANDLERS = {} + handlers.COMMAND_HANDLERS = { + commands.UpdateOCloud: update_ocloud, + } + bus = bootstrap.bootstrap(False, fakeuow) + return bus + + +def test_probe_new_ocloud(): + fakeuow = FakeUnitOfWork() + bus = create_fake_bus(fakeuow) + fakeClient = FakeOcloudClient() + ocloudwatcher = OcloudWatcher(fakeClient, bus) + cmds = ocloudwatcher.probe() + assert cmds is not None + assert len(cmds) == 1 + assert cmds[0].data.name == "stx1" + # assert len(fakeuow.stxobjects.oclouds) == 1 + # assert fakeuow.stxobjects.oclouds[0].name == "stx1" + + +def test_watchers_worker(): + testedworker = worker.PollWorker() + + class FakeOCloudWatcher(BaseWatcher): + def __init__(self, client: BaseClient, + bus: messagebus) -> None: + super().__init__(client, None) + self.fakeOcloudWatcherCounter = 0 + self._client = client + self._bus = bus + + def _targetname(self): + return "fakeocloudwatcher" + + def _probe(self, parent: object = None): + # import pdb; pdb.set_trace() + self.fakeOcloudWatcherCounter += 1 + # hacking to stop the blocking sched task + if self.fakeOcloudWatcherCounter > 2: + testedworker.stop() + return [] + + # fakeRepo = FakeOcloudRepo() + fakeuow = FakeUnitOfWork() + bus = create_fake_bus(fakeuow) + + fakeClient = FakeOcloudClient() + fakewatcher = FakeOCloudWatcher(fakeClient, bus) + + root = WatcherTree(fakewatcher) + + testedworker.set_interval(1) + testedworker.add_watcher(root) + assert fakewatcher.fakeOcloudWatcherCounter == 0 + + count1 = fakewatcher.fakeOcloudWatcherCounter + testedworker.start() + time.sleep(20) + assert fakewatcher.fakeOcloudWatcherCounter > count1 + + # assumed hacking: probe has stopped the sched task + count3 = fakewatcher.fakeOcloudWatcherCounter + time.sleep(3) + assert fakewatcher.fakeOcloudWatcherCounter == count3 diff --git a/tox.ini b/tox.ini index d316240..d635278 100644 --- a/tox.ini +++ b/tox.ini @@ -1,65 +1,65 @@ -# content of: tox.ini , put in same dir as setup.py -[tox] -envlist= - flake8, - code, - docs, - docs-linkcheck, - -minversion = 2.0 -skipsdist = True - -[testenv] -basepython = - code: python3.8 - flake8: python3.8 -setenv = - VIRTUAL_ENV={envdir} - -# NOTE: relative paths were used due to '-w' flag for nosetests util - -usedevelop = True -install_command = pip install -U {opts} {packages} -deps = -r{toxinidir}/requirements.txt - -r{toxinidir}/requirements-test.txt -whitelist_externals = bash, flake8, pytest - -[testenv:flake8] -commands = - flake8 o2ims - flake8 o2dms - flake8 o2common - -[testenv:code] -commands = - pytest tests/unit - -[testenv:nosetests] -commands = - pytest tests/unit - - -[testenv:docs] -basepython = python3 -deps = - sphinx - sphinx-rtd-theme - sphinxcontrib-httpdomain - recommonmark - lfdocs-conf - -commands = - sphinx-build -W -b html -n -d {envtmpdir}/doctrees ./docs/ {toxinidir}/docs/_build/html - - echo "Generated docs available in {toxinidir}/docs/_build/html" - -whitelist_externals = echo - -[testenv:docs-linkcheck] -basepython = python3 -deps = sphinx - sphinx-rtd-theme - sphinxcontrib-httpdomain - recommonmark - lfdocs-conf -commands = sphinx-build -W -b linkcheck -d {envtmpdir}/doctrees ./docs/ {toxinidir}/docs/_build/linkcheck +# content of: tox.ini , put in same dir as setup.py +[tox] +envlist= + flake8, + code, + docs, + docs-linkcheck, + +minversion = 2.0 +skipsdist = True + +[testenv] +basepython = + code: python3.8 + flake8: python3.8 +setenv = + VIRTUAL_ENV={envdir} + +# NOTE: relative paths were used due to '-w' flag for nosetests util + +usedevelop = True +install_command = pip install -U {opts} {packages} +deps = -r{toxinidir}/requirements.txt + -r{toxinidir}/requirements-test.txt +whitelist_externals = bash, flake8, pytest + +[testenv:flake8] +commands = + flake8 o2ims + flake8 o2dms + flake8 o2common + +[testenv:code] +commands = + pytest tests/unit + +[testenv:nosetests] +commands = + pytest tests/unit + + +[testenv:docs] +basepython = python3 +deps = + sphinx + sphinx-rtd-theme + sphinxcontrib-httpdomain + recommonmark + lfdocs-conf + +commands = + sphinx-build -W -b html -n -d {envtmpdir}/doctrees ./docs/ {toxinidir}/docs/_build/html + + echo "Generated docs available in {toxinidir}/docs/_build/html" + +whitelist_externals = echo + +[testenv:docs-linkcheck] +basepython = python3 +deps = sphinx + sphinx-rtd-theme + sphinxcontrib-httpdomain + recommonmark + lfdocs-conf +commands = sphinx-build -W -b linkcheck -d {envtmpdir}/doctrees ./docs/ {toxinidir}/docs/_build/linkcheck