Skip to content

Commit 81995bd

Browse files
refresh esd, restore esd file if error happens
with unit tests
1 parent 9897b92 commit 81995bd

3 files changed

Lines changed: 65 additions & 66 deletions

File tree

f5_openstack_agent/lbaasv2/drivers/bigip/esd_filehandler.py

Lines changed: 29 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
# limitations under the License.
1515
#
1616

17+
import copy
1718
import glob
1819
import json
1920
import os
@@ -31,56 +32,50 @@
3132
LOG = logging.getLogger(__name__)
3233

3334

34-
class EsdJSONValidation(object):
35-
"""Class reads the json file(s)
35+
class EsdTagProcessor(object):
36+
"""Class processes json dictionary
3637
37-
It checks and parses the content of json file(s) to a dictionary
38+
It checks compares the tags from esdjson dictionary to list of valid tags
3839
"""
39-
def __init__(self, esddir):
40-
self.esdJSONFileList = glob.glob(os.path.join(esddir, '*.json'))
41-
self.esdJSONDict = {}
42-
43-
def read_json(self):
44-
for fileList in self.esdJSONFileList:
40+
_instance = None
41+
esd_dict = {}
42+
43+
def __new__(cls, *args, **kwargs):
44+
if not isinstance(cls._instance, cls):
45+
cls._instance = object.__new__(cls, *args, **kwargs)
46+
return cls._instance
47+
48+
def read_json(self, esddir):
49+
esdJSONFileList = glob.glob(os.path.join(esddir, '*.json'))
50+
esdJSONDict = {}
51+
for fileList in esdJSONFileList:
4552
try:
4653
with open(fileList) as json_file:
4754
# Reading each file to a dictionary
4855
fileJSONDict = json.load(json_file)
4956
# Combine all dictionaries to one
50-
self.esdJSONDict.update(fileJSONDict)
57+
esdJSONDict.update(fileJSONDict)
5158

5259
except ValueError as err:
5360
LOG.error('ESD JSON File is invalid: %s', err)
5461
raise f5_ex.esdJSONFileInvalidException()
5562

56-
return self.esdJSONDict
57-
58-
59-
class EsdTagProcessor(EsdJSONValidation):
60-
"""Class processes json dictionary
61-
62-
It checks compares the tags from esdjson dictionary to list of valid tags
63-
"""
64-
def __init__(self, esddir):
65-
super(EsdTagProcessor, self).__init__(esddir)
66-
67-
# this function will return intersection of known valid esd tags
68-
# and the ones that user provided
69-
def valid_tag_key_subset(self):
70-
self.validtags = list(set(self.esdJSONDict.keys()) &
71-
set(self.valid_esd_tags.keys()))
72-
if not self.validtags:
73-
LOG.error("Intersect of valid esd tags and user esd tags is empty")
74-
75-
if set(self.validtags) != set(self.esdJSONDict.keys()):
76-
LOG.error("invalid tags in the user esd tags")
63+
return esdJSONDict
7764

78-
def process_esd(self, bigips):
65+
def process_esd(self, bigips, esddir):
66+
esd_json_backup = {}
67+
esd_json_backup = copy.deepcopy(self.esd_dict)
7968
try:
80-
dict = self.read_json()
69+
dict = self.read_json(esddir)
8170
self.esd_dict = self.verify_esd_dict(bigips, dict)
8271
except f5_ex.esdJSONFileInvalidException:
83-
self.esd_dict = {}
72+
# if error happens, we set backup esd.
73+
self.esd_dict = copy.deepcopy(esd_json_backup)
74+
LOG.warning(
75+
"ESD JSON File is invalid, "
76+
"ESD JSON Dict is restored to %s",
77+
esd_json_backup
78+
)
8479
raise
8580

8681
def get_esd(self, name):

f5_openstack_agent/lbaasv2/drivers/bigip/icontrol_driver.py

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -841,20 +841,22 @@ def init_esd(self):
841841
# init esd object in lbaas_builder
842842
# init esd object in service_adapter
843843
esd_dir = os.path.join(self.get_config_dir(), 'esd')
844-
self.esd = EsdTagProcessor(esd_dir)
844+
# EsdTagProcessor is a singleton, so nothing new
845+
self.esd = EsdTagProcessor()
845846
try:
846-
self.esd.process_esd(self.get_all_bigips())
847+
self.esd.process_esd(self.get_all_bigips(), esd_dir)
847848
self.lbaas_builder.init_esd(self.esd)
848849
self.service_adapter.init_esd(self.esd)
849850

850-
LOG.debug('esd details here after process_esd(): ')
851-
LOG.debug(self.esd)
852-
self.esd_names = self.esd.esd_dict.keys() or []
853-
LOG.debug('##### self.esd_names obtainded here:')
854-
LOG.debug(self.esd_names)
855851
except f5ex.esdJSONFileInvalidException as err:
856852
LOG.error("unable to initialize ESD. Error: %s.", err.message)
857853

854+
LOG.debug('ESD details here after process_esd(): ')
855+
LOG.debug(self.esd)
856+
self.esd_names = self.esd.esd_dict.keys() or []
857+
LOG.debug('self.esd_names obtainded here:')
858+
LOG.debug(self.esd_names)
859+
858860
def _validate_ha(self, bigip):
859861
# if there was only one address supplied and
860862
# this is not a standalone device, get the

f5_openstack_agent/lbaasv2/drivers/bigip/test/test_esd_filehandler.py

Lines changed: 27 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
import pytest
1818

1919
from f5_openstack_agent.lbaasv2.drivers.bigip.esd_filehandler import \
20-
EsdJSONValidation
20+
EsdTagProcessor
2121
from f5_openstack_agent.lbaasv2.drivers.bigip import exceptions as f5_ex
2222

2323

@@ -38,57 +38,59 @@ def assertIn(obj1, dict_obj, note=''):
3838

3939
def test_invalid_dir_name(self):
4040
# invliad directory name
41-
reader = EsdJSONValidation('/as87awoiujasdf/')
42-
assert not reader.esdJSONFileList
41+
esd = EsdTagProcessor()
42+
reader = esd.read_json('/as87awoiujasdf/')
43+
assert not reader
4344

4445
def test_no_files(self, get_relative_path):
4546
# verify no files in empty directory
46-
reader = EsdJSONValidation(
47+
esd = EsdTagProcessor()
48+
reader = esd.read_json(
4749
'{}/{}/empty_dir'.format(get_relative_path, self.remaining_path))
48-
assert not reader.esdJSONFileList
50+
assert not reader
4951

5052
def test_no_json_files(self, get_relative_path):
5153
# verify no files are read in dir that contains non-JSON files
52-
reader = EsdJSONValidation(
54+
esd = EsdTagProcessor()
55+
reader = esd.read_json(
5356
'{}/{}/no_json'.format(get_relative_path, self.remaining_path))
54-
assert not reader.esdJSONFileList
57+
assert not reader
5558

5659
def test_mix_json_files(self, get_relative_path):
5760
# verify single JSON file
58-
reader = EsdJSONValidation(
61+
esd = EsdTagProcessor()
62+
reader = esd.read_json(
5963
'{}/{}/mix_json/'.format(get_relative_path, self.remaining_path))
60-
self.assertEqual(1, len(reader.esdJSONFileList))
64+
self.assertEqual(3, len(reader.keys()))
6165

6266
def test_json_only_files(self, get_relative_path):
6367
# expect three files
64-
reader = EsdJSONValidation(
68+
esd = EsdTagProcessor()
69+
reader = esd.read_json(
6570
'{}/{}/valid'.format(get_relative_path, self.remaining_path))
66-
self.assertEqual(3, len(reader.esdJSONFileList))
71+
self.assertEqual(3, len(reader.keys()))
6772

6873
def test_invalid_json(self, get_relative_path):
69-
handler = EsdJSONValidation(
70-
'{}/{}/invalid'.format(get_relative_path, self.remaining_path))
71-
72-
# verify exception raised
74+
esd = EsdTagProcessor()
7375
with self.assertRaises(f5_ex.esdJSONFileInvalidException):
74-
handler.read_json()
76+
esd.read_json(
77+
'{}/{}/invalid'.format(get_relative_path, self.remaining_path))
7578

7679
def test_valid_json(self, get_relative_path):
77-
handler = EsdJSONValidation(
80+
esd = EsdTagProcessor()
81+
result = esd.read_json(
7882
'{}/{}/valid/'.format(get_relative_path, self.remaining_path))
79-
dict = handler.read_json()
8083

8184
# verify keys in the final dictionary
82-
self.assertIn('app_type_1', dict)
83-
self.assertIn('app_type_2', dict)
84-
self.assertIn('app_type_3', dict)
85+
self.assertIn('app_type_1', result)
86+
self.assertIn('app_type_2', result)
87+
self.assertIn('app_type_3', result)
8588

8689
def test_empty_json(self, get_relative_path):
8790
# verify empty file is read
88-
handler = EsdJSONValidation(
91+
esd = EsdTagProcessor()
92+
result = esd.read_json(
8993
'{}/{}/empty_file/'.format(get_relative_path, self.remaining_path))
90-
self.assertEqual(1, len(handler.esdJSONFileList))
9194

9295
# verify empty dict is returned
93-
dict = handler.read_json()
94-
assert not dict
96+
assert not result

0 commit comments

Comments
 (0)