[SEBA-742] Tech-profile-id as a mandatory field in RCORDSubscriber
Change-Id: I3f7f1e816d7cac457e1e286d809fd2728fb6f0ee
diff --git a/Makefile b/Makefile
index 82c8439..892a527 100644
--- a/Makefile
+++ b/Makefile
@@ -54,13 +54,13 @@
test: test-unit test-migration test-xproto
-test-unit:
+test-unit: venv-service
tox
venv-service:
virtualenv $@;\
source ./$@/bin/activate ; set -u ;\
- pip install -r requirements.txt xosmigrate~=3.2.6
+ pip install -r requirements.txt xosmigrate~=3.2.6 django
create-migration: venv-service
source ./venv-service/bin/activate; set -u;\
diff --git a/tox.ini b/tox.ini
index 9064a11..73c1e23 100644
--- a/tox.ini
+++ b/tox.ini
@@ -23,6 +23,7 @@
-r requirements.txt
requests_mock
nose2
+ django
; flake8
changedir = xos
diff --git a/xos/synchronizer/migrations/0011_mandatory_tech_profile_id.py b/xos/synchronizer/migrations/0011_mandatory_tech_profile_id.py
new file mode 100644
index 0000000..a1a2fbd
--- /dev/null
+++ b/xos/synchronizer/migrations/0011_mandatory_tech_profile_id.py
@@ -0,0 +1,45 @@
+# Copyright 2017-present Open Networking Foundation
+#
+# 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.
+
+# -*- coding: utf-8 -*-
+# Generated by Django 1.11.20 on 2019-06-19 01:31
+from __future__ import unicode_literals
+
+import django.core.validators
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ def forwards(apps, schema_editor):
+
+ # set a default value on tech_profile_id for existing subscribers
+ subscribers = apps.get_model('rcord', 'RCORDSubscriber')
+
+ for s in subscribers.objects.all():
+ s.tech_profile_id = "64"
+ s.save()
+
+ dependencies = [
+ ('rcord', '0010_bandwidth_profile_values'),
+ ]
+
+ operations = [
+ migrations.RunPython(forwards),
+ migrations.AlterField(
+ model_name='rcordsubscriber_decl',
+ name='tech_profile_id',
+ field=models.IntegerField(help_text=b'Technology profile id to be used along with Technology type to retreive the profile', validators=[django.core.validators.MaxValueValidator(65535), django.core.validators.MinValueValidator(0)]),
+ ),
+ ]
diff --git a/xos/synchronizer/models/models.py b/xos/synchronizer/models/models.py
index 5a42ce5..c80cb63 100755
--- a/xos/synchronizer/models/models.py
+++ b/xos/synchronizer/models/models.py
@@ -15,7 +15,7 @@
import re
import socket
import random
-
+from django.core.exceptions import ObjectDoesNotExist
from xos.exceptions import XOSValidationError, XOSProgrammingError, XOSPermissionDenied, XOSConfigurationError
from models_decl import RCORDService_decl, RCORDSubscriber_decl, RCORDIpAddress_decl, BandwidthProfile_decl
@@ -82,7 +82,6 @@
else:
return tag
-
def generate_c_tag(self):
# unused_c_tags_for_s_tag() this function will return a list of unused c_tags for the given s_tag
@@ -165,6 +164,26 @@
else:
return None
+ def validate_tech_profile_id(self):
+ if self.owner.leaf_model.access != "voltha":
+ # if we're not using VOLTHA we don't need to validate this
+ return True
+
+ volt = None
+ for ps in self.owner.provider_services:
+ provider_service = ps.leaf_model
+ if provider_service.name.lower() == "volt":
+ volt = provider_service
+
+ technology = volt.get_olt_technology_from_unu_sn(self.onu_device)
+
+ try:
+ tp = volt.get_tech_profile(technology, self.tech_profile_id)
+ return True
+ except ObjectDoesNotExist:
+ return False
+
+
def save(self, *args, **kwargs):
self.validate_unique_service_specific_id(none_okay=True)
@@ -232,6 +251,10 @@
if not volt_service.has_access_device(self.onu_device):
raise XOSValidationError("The onu_device you specified (%s) does not exists" % self.onu_device)
+ # validate that the tech_profile_id actually exists
+ if not self.validate_tech_profile_id():
+ raise XOSValidationError("The technology profile you specified [%s] does not exist" % self.tech_profile_id)
+
super(RCORDSubscriber, self).save(*args, **kwargs)
self.invalidate_related_objects()
return
diff --git a/xos/synchronizer/models/rcord.xproto b/xos/synchronizer/models/rcord.xproto
index e1ebb9a..e08cf34 100644
--- a/xos/synchronizer/models/rcord.xproto
+++ b/xos/synchronizer/models/rcord.xproto
@@ -62,6 +62,10 @@
optional string mac_address = 18 [
help_text = "Subscriber MAC Address",
max_length = 256];
+ required int32 tech_profile_id = 23 [
+ help_text = "Technology profile id to be used along with Technology type to retreive the profile",
+ min_value = 0,
+ max_value = 65535];
// operator specific fields
optional string nas_port_id = 20 [
@@ -73,10 +77,6 @@
optional string remote_id = 22 [
help_text = "Option 82 Remote ID for DHCP relay agent",
max_length = 256];
- optional int32 tech_profile_id = 23 [
- help_text = "Technology profile id to be used along with Technology type to retreive the profile",
- min_value = 0,
- max_value = 65535];
required manytoone upstream_bps->BandwidthProfile:us_subscriber = 31:1001 [
help_text = "The subscriber the IP address belongs to"];
diff --git a/xos/synchronizer/models/test_models.py b/xos/synchronizer/models/test_models.py
index a0e5a4d..16b0114 100644
--- a/xos/synchronizer/models/test_models.py
+++ b/xos/synchronizer/models/test_models.py
@@ -65,10 +65,13 @@
self.module_patcher = patch.dict('sys.modules', modules)
self.module_patcher.start()
- self.volt = Mock()
-
from models import RCORDSubscriber, RCORDIpAddress
+ self.volt = Mock(name="vOLT")
+ self.volt.leaf_model.name = "vOLT"
+ self.volt.get_olt_technology_from_unu_sn.return_value = "xgspon"
+
+
self.rcord_subscriber_class = RCORDSubscriber
self.rcord_subscriber = RCORDSubscriber()
@@ -85,9 +88,12 @@
self.rcord_subscriber.owner.provider_services = [self.volt]
self.rcord_subscriber.list_of_unused_c_tags_for_s_tag = []
+
self.rcord_ip = RCORDIpAddress()
self.rcord_ip.subscriber = 1
+ # TODO add a test for validate_tech_profile_id
+
def tearDown(self):
sys.path = self.sys_path_save