Adds collection of vim status metric

Current support is only OpenStack. It tries to do a simple project list query
to check if VIM is up or not.

Change-Id: Ifec844d9514b6c676b065fee7cf785bdf2a2ea3d
Signed-off-by: Benjamin Diaz <bdiaz@whitestack.com>
diff --git a/osm_mon/cmd/mon_collector.py b/osm_mon/cmd/mon_collector.py
index 6389d49..c4e2969 100644
--- a/osm_mon/cmd/mon_collector.py
+++ b/osm_mon/cmd/mon_collector.py
@@ -25,6 +25,7 @@
 import sys
 
 from osm_mon.collector.collector import Collector
+from osm_mon.core.database import DatabaseManager
 from osm_mon.core.settings import Config
 
 
@@ -45,6 +46,10 @@
     log = logging.getLogger(__name__)
     log.info("Starting MON Collector...")
     log.debug("Config: %s", vars(cfg))
+    log.info("Initializing database...")
+    db_manager = DatabaseManager()
+    db_manager.create_tables()
+    log.info("Database initialized correctly.")
     collector = Collector()
     collector.collect_forever()
 
diff --git a/osm_mon/cmd/mon_evaluator.py b/osm_mon/cmd/mon_evaluator.py
index 3343b9c..79adabd 100644
--- a/osm_mon/cmd/mon_evaluator.py
+++ b/osm_mon/cmd/mon_evaluator.py
@@ -24,6 +24,7 @@
 import logging
 import sys
 
+from osm_mon.core.database import DatabaseManager
 from osm_mon.core.settings import Config
 from osm_mon.evaluator.evaluator import Evaluator
 
@@ -45,6 +46,10 @@
     log = logging.getLogger(__name__)
     log.info("Starting MON Evaluator...")
     log.debug("Config: %s", vars(cfg))
+    log.info("Initializing database...")
+    db_manager = DatabaseManager()
+    db_manager.create_tables()
+    log.info("Database initialized correctly.")
     evaluator = Evaluator()
     evaluator.evaluate_forever()
 
diff --git a/osm_mon/cmd/mon_server.py b/osm_mon/cmd/mon_server.py
index a100c20..34fe0b1 100644
--- a/osm_mon/cmd/mon_server.py
+++ b/osm_mon/cmd/mon_server.py
@@ -24,6 +24,7 @@
 import logging
 import sys
 
+from osm_mon.core.database import DatabaseManager
 from osm_mon.core.settings import Config
 from osm_mon.server.server import Server
 
@@ -45,6 +46,10 @@
     log = logging.getLogger(__name__)
     log.info("Starting MON Server...")
     log.debug("Config: %s", vars(cfg))
+    log.info("Initializing database...")
+    db_manager = DatabaseManager()
+    db_manager.create_tables()
+    log.info("Database initialized correctly.")
     server = Server()
     server.run()
 
diff --git a/osm_mon/collector/backends/prometheus.py b/osm_mon/collector/backends/prometheus.py
index 31f3122..fbe6d36 100644
--- a/osm_mon/collector/backends/prometheus.py
+++ b/osm_mon/collector/backends/prometheus.py
@@ -49,10 +49,9 @@
                 prometheus_metrics[metric.name] = GaugeMetricFamily(
                     OSM_METRIC_PREFIX + metric.name,
                     'OSM metric',
-                    labels=['ns_id', 'vnf_member_index', 'vdu_name']
+                    labels=list(metric.tags.keys())
                 )
-            prometheus_metrics[metric.name].add_metric([metric.nsr_id, metric.vnf_member_index, metric.vdur_name],
-                                                       metric.value)
+            prometheus_metrics[metric.name].add_metric(list(metric.tags.values()), metric.value)
         self.custom_collector.metrics = prometheus_metrics.values()
 
     def _start_exporter(self, port):
diff --git a/osm_mon/collector/collector.py b/osm_mon/collector/collector.py
index 3143882..36ce1b0 100644
--- a/osm_mon/collector/collector.py
+++ b/osm_mon/collector/collector.py
@@ -27,9 +27,11 @@
 import peewee
 
 from osm_mon.collector.backends.prometheus import PrometheusBackend
-from osm_mon.collector.collectors.juju import VCACollector
-from osm_mon.collector.collectors.openstack import OpenstackCollector
-from osm_mon.collector.collectors.vmware import VMwareCollector
+from osm_mon.collector.vnf_collectors.vmware import VMwareCollector
+from osm_mon.collector.infra_collectors.openstack import OpenstackInfraCollector
+from osm_mon.collector.metric import Metric
+from osm_mon.collector.vnf_collectors.juju import VCACollector
+from osm_mon.collector.vnf_collectors.openstack import OpenstackCollector
 from osm_mon.core.common_db import CommonDbClient
 from osm_mon.core.database import DatabaseManager
 from osm_mon.core.settings import Config
@@ -40,6 +42,9 @@
     "openstack": OpenstackCollector,
     "vmware": VMwareCollector
 }
+VIM_INFRA_COLLECTORS = {
+    "openstack": OpenstackInfraCollector
+}
 METRIC_BACKENDS = [
     PrometheusBackend
 ]
@@ -69,7 +74,8 @@
 
     def _collect_vim_metrics(self, vnfr: dict, vim_account_id: str):
         # TODO(diazb) Add support for vrops and aws
-        vim_type = self.database_manager.get_vim_type(vim_account_id)
+        database_manager = DatabaseManager()
+        vim_type = database_manager.get_vim_type(vim_account_id)
         if vim_type in VIM_COLLECTORS:
             collector = VIM_COLLECTORS[vim_type](vim_account_id)
             metrics = collector.collect(vnfr)
@@ -78,6 +84,17 @@
         else:
             log.debug("vimtype %s is not supported.", vim_type)
 
+    def _collect_vim_infra_metrics(self, vim_account_id: str):
+        database_manager = DatabaseManager()
+        vim_type = database_manager.get_vim_type(vim_account_id)
+        if vim_type in VIM_INFRA_COLLECTORS:
+            collector = VIM_INFRA_COLLECTORS[vim_type](vim_account_id)
+            status = collector.is_vim_ok()
+            status_metric = Metric({'vim_id': vim_account_id}, 'vim_status', status)
+            self.queue.put(status_metric)
+        else:
+            log.debug("vimtype %s is not supported.", vim_type)
+
     def _collect_vca_metrics(self, vnfr: dict):
         log.debug('_collect_vca_metrics')
         log.debug('vnfr: %s', vnfr)
@@ -101,6 +118,12 @@
                                         args=(vnfr,))
             processes.append(p)
             p.start()
+        vims = self.common_db.get_vim_accounts()
+        for vim in vims:
+            p = multiprocessing.Process(target=self._collect_vim_infra_metrics,
+                                        args=(vim['_id'],))
+            processes.append(p)
+            p.start()
         for process in processes:
             process.join()
         metrics = []
diff --git a/osm_mon/collector/collectors/__init__.py b/osm_mon/collector/infra_collectors/__init__.py
similarity index 100%
copy from osm_mon/collector/collectors/__init__.py
copy to osm_mon/collector/infra_collectors/__init__.py
diff --git a/osm_mon/collector/collectors/base_vim.py b/osm_mon/collector/infra_collectors/base.py
similarity index 84%
copy from osm_mon/collector/collectors/base_vim.py
copy to osm_mon/collector/infra_collectors/base.py
index 2ae0617..6f137d0 100644
--- a/osm_mon/collector/collectors/base_vim.py
+++ b/osm_mon/collector/infra_collectors/base.py
@@ -20,9 +20,6 @@
 # contact: bdiaz@whitestack.com or glavado@whitestack.com
 ##
 
-from osm_mon.collector.collectors.base import BaseCollector
 
-
-class BaseVimCollector(BaseCollector):
-    def __init__(self, vim_account_id: str):
-        pass
+class BaseInfraCollector:
+    pass
diff --git a/osm_mon/collector/collectors/base_vim.py b/osm_mon/collector/infra_collectors/base_vim.py
similarity index 84%
copy from osm_mon/collector/collectors/base_vim.py
copy to osm_mon/collector/infra_collectors/base_vim.py
index 2ae0617..0a075a1 100644
--- a/osm_mon/collector/collectors/base_vim.py
+++ b/osm_mon/collector/infra_collectors/base_vim.py
@@ -19,10 +19,12 @@
 # For those usages not covered by the Apache License, Version 2.0 please
 # contact: bdiaz@whitestack.com or glavado@whitestack.com
 ##
-
-from osm_mon.collector.collectors.base import BaseCollector
+from osm_mon.collector.infra_collectors.base import BaseInfraCollector
 
 
-class BaseVimCollector(BaseCollector):
+class BaseVimInfraCollector(BaseInfraCollector):
     def __init__(self, vim_account_id: str):
         pass
+
+    def is_vim_ok(self) -> bool:
+        pass
diff --git a/osm_mon/collector/infra_collectors/openstack.py b/osm_mon/collector/infra_collectors/openstack.py
new file mode 100644
index 0000000..4237e4f
--- /dev/null
+++ b/osm_mon/collector/infra_collectors/openstack.py
@@ -0,0 +1,58 @@
+# Copyright 2018 Whitestack, LLC
+# *************************************************************
+
+# This file is part of OSM Monitoring module
+# All Rights Reserved to Whitestack, LLC
+
+# 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.
+
+# For those usages not covered by the Apache License, Version 2.0 please
+# contact: bdiaz@whitestack.com or glavado@whitestack.com
+##
+import logging
+
+from keystoneauth1 import session
+from keystoneauth1.identity import v3
+from keystoneclient.v3 import client
+
+from osm_mon.collector.infra_collectors.base_vim import BaseVimInfraCollector
+from osm_mon.core.auth import AuthManager
+
+log = logging.getLogger(__name__)
+
+
+class OpenstackInfraCollector(BaseVimInfraCollector):
+    def __init__(self, vim_account_id: str):
+        super().__init__(vim_account_id)
+        self.auth_manager = AuthManager()
+        self.keystone_client = self._build_keystone_client(vim_account_id)
+
+    def is_vim_ok(self) -> bool:
+        try:
+            self.keystone_client.projects.list()
+            return True
+        except Exception:
+            log.exception("VIM status is not OK!")
+            return False
+
+    def _build_keystone_client(self, vim_account_id):
+        creds = self.auth_manager.get_credentials(vim_account_id)
+        verify_ssl = self.auth_manager.is_verify_ssl(vim_account_id)
+        auth = v3.Password(auth_url=creds.url,
+                           username=creds.user,
+                           password=creds.password,
+                           project_name=creds.tenant_name,
+                           project_domain_id='default',
+                           user_domain_id='default')
+        sess = session.Session(auth=auth, verify=verify_ssl)
+        return client.Client(session=sess)
diff --git a/osm_mon/collector/metric.py b/osm_mon/collector/metric.py
index e8da11b..741096f 100644
--- a/osm_mon/collector/metric.py
+++ b/osm_mon/collector/metric.py
@@ -22,9 +22,7 @@
 
 
 class Metric:
-    def __init__(self, nsr_id, vnf_member_index, vdur_name, name, value):
-        self.nsr_id = nsr_id
-        self.vnf_member_index = vnf_member_index
-        self.vdur_name = vdur_name
+    def __init__(self, tags: dict, name: str, value):
+        self.tags = tags
         self.name = name
         self.value = value
diff --git a/osm_mon/collector/collectors/__init__.py b/osm_mon/collector/vnf_collectors/__init__.py
similarity index 100%
rename from osm_mon/collector/collectors/__init__.py
rename to osm_mon/collector/vnf_collectors/__init__.py
diff --git a/osm_mon/collector/collectors/base.py b/osm_mon/collector/vnf_collectors/base.py
similarity index 100%
rename from osm_mon/collector/collectors/base.py
rename to osm_mon/collector/vnf_collectors/base.py
diff --git a/osm_mon/collector/collectors/base_vim.py b/osm_mon/collector/vnf_collectors/base_vim.py
similarity index 93%
rename from osm_mon/collector/collectors/base_vim.py
rename to osm_mon/collector/vnf_collectors/base_vim.py
index 2ae0617..29a348f 100644
--- a/osm_mon/collector/collectors/base_vim.py
+++ b/osm_mon/collector/vnf_collectors/base_vim.py
@@ -20,7 +20,7 @@
 # contact: bdiaz@whitestack.com or glavado@whitestack.com
 ##
 
-from osm_mon.collector.collectors.base import BaseCollector
+from osm_mon.collector.vnf_collectors.base import BaseCollector
 
 
 class BaseVimCollector(BaseCollector):
diff --git a/osm_mon/collector/collectors/juju.py b/osm_mon/collector/vnf_collectors/juju.py
similarity index 91%
rename from osm_mon/collector/collectors/juju.py
rename to osm_mon/collector/vnf_collectors/juju.py
index 638086a..928b35a 100644
--- a/osm_mon/collector/collectors/juju.py
+++ b/osm_mon/collector/vnf_collectors/juju.py
@@ -25,8 +25,9 @@
 
 from n2vc.vnf import N2VC
 
-from osm_mon.collector.collectors.base import BaseCollector
 from osm_mon.collector.metric import Metric
+from osm_mon.collector.vnf_collectors.base import BaseCollector
+from osm_mon.collector.vnf_metric import VnfMetric
 from osm_mon.core.common_db import CommonDbClient
 from osm_mon.core.exceptions import VcaDeploymentInfoNotFound
 from osm_mon.core.settings import Config
@@ -64,7 +65,8 @@
                 for measure_list in measures.values():
                     for measure in measure_list:
                         log.debug("Measure: %s", measure)
-                        metric = Metric(nsr_id, vnf_member_index, vdur['name'], measure['key'], float(measure['value']))
+                        metric = VnfMetric(nsr_id, vnf_member_index, vdur['name'], measure['key'],
+                                           float(measure['value']))
                         metrics.append(metric)
         if 'vnf-configuration' in vnfd and 'metrics' in vnfd['vnf-configuration']:
             try:
@@ -77,7 +79,7 @@
             for measure_list in measures.values():
                 for measure in measure_list:
                     log.debug("Measure: %s", measure)
-                    metric = Metric(nsr_id, vnf_member_index, '', measure['key'], float(measure['value']))
+                    metric = VnfMetric(nsr_id, vnf_member_index, '', measure['key'], float(measure['value']))
                     metrics.append(metric)
         return metrics
 
diff --git a/osm_mon/collector/collectors/openstack.py b/osm_mon/collector/vnf_collectors/openstack.py
similarity index 95%
rename from osm_mon/collector/collectors/openstack.py
rename to osm_mon/collector/vnf_collectors/openstack.py
index 30bab0c..8dbab5c 100644
--- a/osm_mon/collector/collectors/openstack.py
+++ b/osm_mon/collector/vnf_collectors/openstack.py
@@ -29,8 +29,9 @@
 from keystoneauth1 import session
 from keystoneauth1.identity import v3
 
-from osm_mon.collector.collectors.base_vim import BaseVimCollector
 from osm_mon.collector.metric import Metric
+from osm_mon.collector.vnf_collectors.base_vim import BaseVimCollector
+from osm_mon.collector.vnf_metric import VnfMetric
 from osm_mon.core.auth import AuthManager
 from osm_mon.core.common_db import CommonDbClient
 from osm_mon.core.settings import Config
@@ -108,7 +109,7 @@
                                                                            resource_id=resource_id,
                                                                            granularity=self.granularity)
                         if len(measures):
-                            metric = Metric(nsr_id, vnf_member_index, vdur['name'], metric_name, measures[-1][2])
+                            metric = VnfMetric(nsr_id, vnf_member_index, vdur['name'], metric_name, measures[-1][2])
                             metrics.append(metric)
                     except gnocchiclient.exceptions.NotFound as e:
                         log.debug("No metric found: %s", e)
diff --git a/osm_mon/collector/collectors/vmware.py b/osm_mon/collector/vnf_collectors/vmware.py
similarity index 95%
rename from osm_mon/collector/collectors/vmware.py
rename to osm_mon/collector/vnf_collectors/vmware.py
index f347446..7402afb 100644
--- a/osm_mon/collector/collectors/vmware.py
+++ b/osm_mon/collector/vnf_collectors/vmware.py
@@ -23,17 +23,17 @@
 
 import json
 import logging
+import time
+import traceback
+from xml.etree import ElementTree as XmlElementTree
 
+import requests
+import six
 from pyvcloud.vcd.client import BasicLoginCredentials
 from pyvcloud.vcd.client import Client
-import requests
-import time
-from xml.etree import ElementTree as XmlElementTree
-import traceback
-import six
 
-from osm_mon.collector.collectors.base_vim import BaseVimCollector
-from osm_mon.collector.metric import Metric
+from osm_mon.collector.vnf_collectors.base_vim import BaseVimCollector
+from osm_mon.collector.vnf_metric import VnfMetric
 from osm_mon.core.auth import AuthManager
 from osm_mon.core.common_db import CommonDbClient
 from osm_mon.core.settings import Config
@@ -270,7 +270,7 @@
                             for resource_identifier in resource_identifiers:
                                 if resource_identifier['identifierType']['name'] == 'VMEntityObjectID':
                                     if resource_identifier.get('value') is not None and \
-                                        resource_identifier['value'] == vm_moref_id:
+                                            resource_identifier['value'] == vm_moref_id:
                                         vm_resource_id = resource['identifier']
                                         log.info("Found VM resource ID: {} for vm_moref_id: {}".format(vm_resource_id,
                                                                                                        vm_moref_id))
@@ -316,7 +316,7 @@
                         begin_time = end_time - time_diff
 
                         api_url = "/suite-api/api/resources/{}/stats?statKey={}&begin={}&end={}".format(
-                                  resource_id, vrops_metric_name, str(begin_time), str(end_time))
+                            resource_id, vrops_metric_name, str(begin_time), str(end_time))
 
                         headers = {'Accept': 'application/json'}
 
@@ -347,11 +347,11 @@
                                                     metrics_data['metrics_series'] = stat_list_v[0]['data']
 
                         if metrics_data:
-                            metric = Metric(nsr_id,
-                                            vnf_member_index,
-                                            vdur['name'],
-                                            metric_name,
-                                            metrics_data['metrics_series'][-1])
+                            metric = VnfMetric(nsr_id,
+                                               vnf_member_index,
+                                               vdur['name'],
+                                               metric_name,
+                                               metrics_data['metrics_series'][-1])
 
                             metrics.append(metric)
 
diff --git a/osm_mon/collector/collectors/base_vim.py b/osm_mon/collector/vnf_metric.py
similarity index 72%
copy from osm_mon/collector/collectors/base_vim.py
copy to osm_mon/collector/vnf_metric.py
index 2ae0617..d0f39c3 100644
--- a/osm_mon/collector/collectors/base_vim.py
+++ b/osm_mon/collector/vnf_metric.py
@@ -19,10 +19,14 @@
 # For those usages not covered by the Apache License, Version 2.0 please
 # contact: bdiaz@whitestack.com or glavado@whitestack.com
 ##
-
-from osm_mon.collector.collectors.base import BaseCollector
+from osm_mon.collector.metric import Metric
 
 
-class BaseVimCollector(BaseCollector):
-    def __init__(self, vim_account_id: str):
-        pass
+class VnfMetric(Metric):
+    def __init__(self, nsr_id, vnf_member_index, vdur_name, name, value):
+        tags = {
+            'ns_id': nsr_id,
+            'vnf_member_index': vnf_member_index,
+            'vdu_name': vdur_name
+        }
+        super().__init__(tags, name, value)
diff --git a/osm_mon/core/common_db.py b/osm_mon/core/common_db.py
index beaac3d..9cc9c06 100644
--- a/osm_mon/core/common_db.py
+++ b/osm_mon/core/common_db.py
@@ -75,3 +75,6 @@
     def get_vim_account_id(self, nsr_id: str, vnf_member_index: int) -> str:
         vnfr = self.get_vnfr(nsr_id, vnf_member_index)
         return vnfr['vim-account-id']
+
+    def get_vim_accounts(self):
+        return self.common_db.get_list('vim_accounts')
diff --git a/osm_mon/core/database.py b/osm_mon/core/database.py
index a41c0fd..4cbd75f 100644
--- a/osm_mon/core/database.py
+++ b/osm_mon/core/database.py
@@ -25,16 +25,14 @@
 import logging
 import uuid
 
-from peewee import CharField, TextField, FloatField, Model, AutoField
+from peewee import CharField, TextField, FloatField, Model, AutoField, Proxy
 from playhouse.db_url import connect
 
 from osm_mon.core.settings import Config
 
 log = logging.getLogger(__name__)
-cfg = Config.instance()
-cfg.read_environ()
 
-db = connect(cfg.DATABASE)
+db = Proxy()
 
 
 class BaseModel(Model):
@@ -69,54 +67,60 @@
 
 
 class DatabaseManager:
-    def create_tables(self) -> None:
-        try:
-            db.connect()
-            db.create_tables([VimCredentials, Alarm])
-            db.close()
-        except Exception:
-            log.exception("Error creating tables: ")
+    def __init__(self):
+        cfg = Config.instance()
+        cfg.read_environ()
+        db.initialize(connect(cfg.DATABASE))
 
-    def get_credentials(self, vim_uuid) -> VimCredentials:
-        return VimCredentials.get_or_none(VimCredentials.uuid == vim_uuid)
+    def create_tables(self) -> None:
+        with db.atomic():
+            db.create_tables([VimCredentials, Alarm])
+
+    def get_credentials(self, vim_uuid: str = None) -> VimCredentials:
+        with db.atomic():
+            return VimCredentials.get_or_none(VimCredentials.uuid == vim_uuid)
 
     def save_credentials(self, vim_credentials) -> VimCredentials:
         """Saves vim credentials. If a record with same uuid exists, overwrite it."""
-        exists = VimCredentials.get_or_none(VimCredentials.uuid == vim_credentials.uuid)
-        if exists:
-            vim_credentials.id = exists.id
-        vim_credentials.save()
-        return vim_credentials
+        with db.atomic():
+            exists = VimCredentials.get_or_none(VimCredentials.uuid == vim_credentials.uuid)
+            if exists:
+                vim_credentials.id = exists.id
+            vim_credentials.save()
+            return vim_credentials
 
     def get_alarm(self, alarm_id) -> Alarm:
-        alarm = (Alarm.select()
-                 .where(Alarm.alarm_id == alarm_id)
-                 .get())
-        return alarm
+        with db.atomic():
+            alarm = (Alarm.select()
+                     .where(Alarm.alarm_id == alarm_id)
+                     .get())
+            return alarm
 
     def save_alarm(self, name, threshold, operation, severity, statistic, metric_name, vdur_name,
                    vnf_member_index, nsr_id) -> Alarm:
         """Saves alarm."""
         # TODO: Add uuid optional param and check if exists to handle updates (see self.save_credentials)
-        alarm = Alarm()
-        alarm.uuid = str(uuid.uuid4())
-        alarm.name = name
-        alarm.threshold = threshold
-        alarm.operation = operation
-        alarm.severity = severity
-        alarm.statistic = statistic
-        alarm.monitoring_param = metric_name
-        alarm.vdur_name = vdur_name
-        alarm.vnf_member_index = vnf_member_index
-        alarm.nsr_id = nsr_id
-        alarm.save()
-        return alarm
+        with db.atomic():
+            alarm = Alarm()
+            alarm.uuid = str(uuid.uuid4())
+            alarm.name = name
+            alarm.threshold = threshold
+            alarm.operation = operation
+            alarm.severity = severity
+            alarm.statistic = statistic
+            alarm.monitoring_param = metric_name
+            alarm.vdur_name = vdur_name
+            alarm.vnf_member_index = vnf_member_index
+            alarm.nsr_id = nsr_id
+            alarm.save()
+            return alarm
 
     def delete_alarm(self, alarm_uuid) -> None:
-        alarm = (Alarm.select()
-                 .where(Alarm.uuid == alarm_uuid)
-                 .get())
-        alarm.delete_instance()
+        with db.atomic():
+            alarm = (Alarm.select()
+                     .where(Alarm.uuid == alarm_uuid)
+                     .get())
+            alarm.delete_instance()
 
     def get_vim_type(self, vim_account_id) -> str:
         """Get the vim type that is required by the message."""
diff --git a/osm_mon/tests/collector/test_collector.py b/osm_mon/tests/collector/test_collector.py
index 9159f35..c386ed2 100644
--- a/osm_mon/tests/collector/test_collector.py
+++ b/osm_mon/tests/collector/test_collector.py
@@ -25,7 +25,7 @@
 from unittest import mock
 
 from osm_mon.collector.collector import Collector
-from osm_mon.collector.collectors.openstack import OpenstackCollector
+from osm_mon.collector.vnf_collectors.openstack import OpenstackCollector
 from osm_mon.core.database import DatabaseManager, db