StarlingX open source release updates

Signed-off-by: Dean Troyer <dtroyer@gmail.com>
This commit is contained in:
Dean Troyer 2018-05-30 16:16:06 -07:00
parent 17d46f6ab8
commit 6cd8940170
90 changed files with 15576 additions and 0 deletions

7
CONTRIBUTORS.wrs Normal file
View File

@ -0,0 +1,7 @@
The following contributors from Wind River have developed the seed code in this
repository. We look forward to community collaboration and contributions for
additional features, enhancements and refactoring.
Contributors:
=============
Tao Liu <Tao.Liu@windriver.com>

202
LICENSE Normal file
View File

@ -0,0 +1,202 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
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.

5
README.rst Normal file
View File

@ -0,0 +1,5 @@
=========
stx-fault
=========
StarlingX Fault Management

6
fm-api/.gitignore vendored Normal file
View File

@ -0,0 +1,6 @@
!.distro
.distro/centos7/rpmbuild/RPMS
.distro/centos7/rpmbuild/SRPMS
.distro/centos7/rpmbuild/BUILD
.distro/centos7/rpmbuild/BUILDROOT
.distro/centos7/rpmbuild/SOURCES/fm-api*tar.gz

202
fm-api/LICENSE Normal file
View File

@ -0,0 +1,202 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
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.

14
fm-api/PKG-INFO Normal file
View File

@ -0,0 +1,14 @@
Metadata-Version: 1.1
Name: fm-api
Version: 1.0
Summary: CGTS Platform Fault Management Python API Package
Home-page:
Author: Windriver
Author-email: info@windriver.com
License: Apache-2.0
Description: CGTS platform Fault Management Client Library that provides APIs \
for applications to raise/clear/update active alarms.
Platform: UNKNOWN

5
fm-api/centos/build_srpm.data Executable file
View File

@ -0,0 +1,5 @@
SRC_DIR="."
COPY_LIST="$PKG_BASE/LICENSE"
EXCLUDE_FILES_FROM_TAR="centos"
TIS_PATCH_VER=13

66
fm-api/centos/fm-api.spec Normal file
View File

@ -0,0 +1,66 @@
Summary: CGTS Platform Fault Management Python API Package
Name: fm-api
Version: 1.0
Release: %{tis_patch_ver}%{?_tis_dist}
License: Apache-2.0
Group: base
Packager: Wind River <info@windriver.com>
URL: unknown
Source0: %{name}-%{version}.tar.gz
Source1: LICENSE
%define debug_package %{nil}
BuildRequires: python-setuptools
%description
CGTS platform Fault Management Client Library that provides APIs
for applications to raise/clear/update active alarms.
%package -n fm-api-doc
Summary: fm-api deploy doc
Group: doc
Provides: fm-api-doc
%description -n fm-api-doc
Contains contansts which is to be used by fm-doc package to validate
the Alarms & Logs Doc Yaml file
%define pythonroot /usr/lib64/python2.7/site-packages
%define cgcs_doc_deploy_dir /opt/deploy/cgcs_doc
%prep
%setup
%build
%{__python} setup.py build
%install
%{__python} setup.py install --root=$RPM_BUILD_ROOT \
--install-lib=%{pythonroot} \
--prefix=/usr \
--install-data=/usr/share \
--single-version-externally-managed
CGCS_DOC_DEPLOY=$RPM_BUILD_ROOT/%{cgcs_doc_deploy_dir}
install -d $CGCS_DOC_DEPLOY
# install constants.py in CGCS_DOC_DEPLOY_DIR
# used by fm-doc package to validate the Alarms & Logs Doc Yaml file
install -m 644 fm_api/constants.py $CGCS_DOC_DEPLOY
%clean
rm -rf $RPM_BUILD_ROOT
# Note: RPM package name is fm-api but import package name is fm_api so can't
# use '%{name}'.
%files
%license LICENSE
%defattr(-,root,root,-)
%dir %{pythonroot}/fm_api
%{pythonroot}/fm_api/*
%dir %{pythonroot}/fm_api-%{version}.0-py2.7.egg-info
%{pythonroot}/fm_api-%{version}.0-py2.7.egg-info/*
%files -n fm-api-doc
%defattr(-,root,root,-)
%{cgcs_doc_deploy_dir}/*

11
fm-api/fm_api/__init__.py Normal file
View File

@ -0,0 +1,11 @@
#
# Copyright (c) 2013-2014 Wind River Systems, Inc.
#
# SPDX-License-Identifier: Apache-2.0
#
# vim: tabstop=4 shiftwidth=4 softtabstop=4
# Copyright 2014 Wind River Inc.
# All Rights Reserved.
#

498
fm-api/fm_api/constants.py Executable file
View File

@ -0,0 +1,498 @@
#
# Copyright (c) 2013-2017 Wind River Systems, Inc.
#
# SPDX-License-Identifier: Apache-2.0
#
# -*- encoding: utf-8 -*-
#
#
# Author: Tao Liu
#
# This file contains CGTS alarm definitions. The alarm ids that used by Python
# applications are defined here. For a completed alarm id list see the alarm ids
# that used by the C/C++ applications defined in
# fm-common/sources/fmAlarm.h
################################################################################
#
# Please make sure that all FM_ALARM_ID_xxx entries in this file
# have a corresponding Alarm record entry in file events.yaml
#
################################################################################
# alarm sub entity types
FM_ENTITY_TYPE_SYSTEM = 'system'
FM_ENTITY_TYPE_HOST = 'host'
FM_ENTITY_TYPE_PORT = 'port'
FM_ENTITY_TYPE_INTERFACE = 'interface'
FM_ENTITY_TYPE_SERVICE = 'service'
FM_ENTITY_TYPE_AGENT = 'agent'
FM_ENTITY_TYPE_PROVIDERNET = 'providernet'
FM_ENTITY_TYPE_INSTANCE = 'instance'
FM_ENTITY_TYPE_CLUSTER = 'cluster'
FM_ENTITY_TYPE_NTP = 'ntp'
FM_ENTITY_TYPE_ML2DRIVER = 'ml2driver'
FM_ENTITY_TYPE_PV = 'pv'
FM_ENTITY_TYPE_BGP_PEER = "bgp-peer"
FM_ENTITY_TYPE_STORAGE_BACKEND = 'storage_backend'
FM_ENTITY_TYPE_SUBCLOUD = 'subcloud'
# alarm service sub entity values
FM_SERVICE_NETWORKING = 'networking'
# alarm_id = <Alarm Group ID>.<Alarm Event ID>
# <Alarm Group ID> = 000 - 999
# <Alarm Event ID> = 000 999
ALARM_GROUP_GENERAL = "100"
ALARM_GROUP_MAINTENANCE = "200"
ALARM_GROUP_BACKUP_RESTORE = "210"
ALARM_GROUP_SYSCONFIG = "250"
ALARM_GROUP_HOST_SERVICES = "270"
ALARM_GROUP_HYPERVISOR = "275"
ALARM_GROUP_DISTRIBUTED_CLOUD = "280"
ALARM_GROUP_NETWORK = "300"
ALARM_GROUP_HA = "400"
ALARM_GROUP_SECURITY = "500"
ALARM_GROUP_LICENSING = "600"
ALARM_GROUP_VM = "700"
ALARM_GROUP_STORAGE = "800"
ALARM_GROUP_SW_MGMT = "900"
# Maintenance Log id
FM_LOG_ID_HOST_DISCOVERED = ALARM_GROUP_MAINTENANCE + ".020"
# System Config Alarm id
FM_ALARM_ID_SYSCONFIG_OUT_OF_DATE = ALARM_GROUP_SYSCONFIG + ".001"
# This CONFIG_REQD alarm ID is deprecated and commented out to avoid its
# alarm id .010 from being unintentinally reused for some unrelated purpose.
# Deprecation followed the removal of the compute-config-complete command.
# FM_ALARM_ID_CONFIG_REQD = ALARM_GROUP_SYSCONFIG + ".010"
FM_ALARM_ID_CEPH_CACHE_TIER_CONFIG_OUT_OF_DATE = ALARM_GROUP_SYSCONFIG + ".002"
# Backup/Restore Alarm id
FM_ALARM_ID_BACKUP_IN_PROGRESS = ALARM_GROUP_BACKUP_RESTORE + ".001"
# Backup/Restore Log id
FM_LOG_ID_RESTORE_COMPLETE = ALARM_GROUP_BACKUP_RESTORE + ".101"
# Network alarm id
FM_ALARM_ID_NETWORK_PORT = ALARM_GROUP_NETWORK + ".001"
FM_ALARM_ID_NETWORK_INTERFACE = ALARM_GROUP_NETWORK + ".002"
FM_ALARM_ID_NETWORK_AGENT = ALARM_GROUP_NETWORK + ".003"
FM_ALARM_ID_NETWORK_PROVIDERNET = ALARM_GROUP_NETWORK + ".004"
FM_ALARM_ID_NETWORK_PROVIDERNET_CONNECTIVITY = ALARM_GROUP_NETWORK + ".005"
FM_ALARM_ID_NETWORK_ML2_DRIVER = ALARM_GROUP_NETWORK + ".010"
FM_ALARM_ID_NETWORK_OPENFLOW_CONTROLLER = ALARM_GROUP_NETWORK + ".012"
FM_ALARM_ID_NETWORK_OVSDB_MANAGER = ALARM_GROUP_NETWORK + ".014"
FM_ALARM_ID_NETWORK_BGP_PEER = ALARM_GROUP_NETWORK + ".016"
# Storage alarm id
FM_ALARM_ID_STORAGE_CEPH_CRITICAL = ALARM_GROUP_STORAGE + ".010"
FM_ALARM_ID_STORAGE_CEPH_MAJOR = ALARM_GROUP_STORAGE + ".011"
FM_ALARM_ID_STORAGE_CEPH = ALARM_GROUP_STORAGE + ".001"
FM_ALARM_ID_STORAGE_IMAGE = ALARM_GROUP_STORAGE + ".002"
FM_ALARM_ID_STORAGE_CEPH_FREE_SPACE = ALARM_GROUP_STORAGE + ".003"
FM_ALARM_ID_STORAGE_CINDER_IO_BUILDING = ALARM_GROUP_STORAGE + ".100"
FM_ALARM_ID_STORAGE_CINDER_IO_LIMITING = ALARM_GROUP_STORAGE + ".101"
FM_ALARM_ID_STORAGE_PV_FAILED = ALARM_GROUP_STORAGE + ".102"
# Alarm .103 is reserved for LVM thin pool metadata alarm
FM_ALARM_ID_STORAGE_BACKEND_FAILED = ALARM_GROUP_STORAGE + ".104"
# Host-Services alarm id
FM_ALARM_ID_HOST_SERVICES_FAILED = ALARM_GROUP_HOST_SERVICES + ".001"
# Host-Services log id
FM_LOG_ID_HOST_SERVICES_FAILED = ALARM_GROUP_HOST_SERVICES + ".101"
FM_LOG_ID_HOST_SERVICES_ENABLED = ALARM_GROUP_HOST_SERVICES + ".102"
FM_LOG_ID_HOST_SERVICES_DISABLED = ALARM_GROUP_HOST_SERVICES + ".103"
# Hypervisor log id
FM_LOG_ID_HYPERVISOR_STATE_CHANGE = ALARM_GROUP_HYPERVISOR + ".001"
# Distributed Cloud alarm id
FM_ALARM_ID_DC_SUBCLOUD_OFFLINE = ALARM_GROUP_DISTRIBUTED_CLOUD + ".001"
FM_ALARM_ID_DC_SUBCLOUD_RESOURCE_OUT_OF_SYNC = ALARM_GROUP_DISTRIBUTED_CLOUD + ".002"
# VM alarm id
FM_ALARM_ID_VM_FAILED = ALARM_GROUP_VM + ".001"
FM_ALARM_ID_VM_PAUSED = ALARM_GROUP_VM + ".002"
FM_ALARM_ID_VM_SUSPENDED = ALARM_GROUP_VM + ".003"
FM_ALARM_ID_VM_STOPPED = ALARM_GROUP_VM + ".004"
FM_ALARM_ID_VM_REBOOTING = ALARM_GROUP_VM + ".005"
FM_ALARM_ID_VM_REBUILDING = ALARM_GROUP_VM + ".006"
FM_ALARM_ID_VM_EVACUATING = ALARM_GROUP_VM + ".007"
FM_ALARM_ID_VM_LIVE_MIGRATING = ALARM_GROUP_VM + ".008"
FM_ALARM_ID_VM_COLD_MIGRATING = ALARM_GROUP_VM + ".009"
FM_ALARM_ID_VM_COLD_MIGRATED = ALARM_GROUP_VM + ".010"
FM_ALARM_ID_VM_COLD_MIGRATE_REVERTING = ALARM_GROUP_VM + ".011"
FM_ALARM_ID_VM_RESIZING = ALARM_GROUP_VM + ".012"
FM_ALARM_ID_VM_RESIZED = ALARM_GROUP_VM + ".013"
FM_ALARM_ID_VM_RESIZE_REVERTING = ALARM_GROUP_VM + ".014"
FM_ALARM_ID_VM_GUEST_HEARTBEAT = ALARM_GROUP_VM + ".015"
FM_ALARM_ID_VM_MULTI_NODE_RECOVERY_MODE = ALARM_GROUP_VM + ".016"
FM_ALARM_ID_VM_GROUP_POLICY_CONFLICT = ALARM_GROUP_VM + ".017"
# VM log id
FM_LOG_ID_VM_ENABLED = ALARM_GROUP_VM + ".101"
FM_LOG_ID_VM_FAILED = ALARM_GROUP_VM + ".102"
FM_LOG_ID_VM_CREATE = ALARM_GROUP_VM + ".103"
FM_LOG_ID_VM_CREATING = ALARM_GROUP_VM + ".104"
FM_LOG_ID_VM_CREATE_REJECTED = ALARM_GROUP_VM + ".105"
FM_LOG_ID_VM_CREATE_CANCELLED = ALARM_GROUP_VM + ".106"
FM_LOG_ID_VM_CREATE_FAILED = ALARM_GROUP_VM + ".107"
FM_LOG_ID_VM_CREATED = ALARM_GROUP_VM + ".108"
FM_LOG_ID_VM_DELETE = ALARM_GROUP_VM + ".109"
FM_LOG_ID_VM_DELETING = ALARM_GROUP_VM + ".110"
FM_LOG_ID_VM_DELETE_REJECTED = ALARM_GROUP_VM + ".111"
FM_LOG_ID_VM_DELETE_CANCELLED = ALARM_GROUP_VM + ".112"
FM_LOG_ID_VM_DELETE_FAILED = ALARM_GROUP_VM + ".113"
FM_LOG_ID_VM_DELETED = ALARM_GROUP_VM + ".114"
FM_LOG_ID_VM_PAUSE = ALARM_GROUP_VM + ".115"
FM_LOG_ID_VM_PAUSING = ALARM_GROUP_VM + ".116"
FM_LOG_ID_VM_PAUSE_REJECTED = ALARM_GROUP_VM + ".117"
FM_LOG_ID_VM_PAUSE_CANCELLED = ALARM_GROUP_VM + ".118"
FM_LOG_ID_VM_PAUSE_FAILED = ALARM_GROUP_VM + ".119"
FM_LOG_ID_VM_PAUSED = ALARM_GROUP_VM + ".120"
FM_LOG_ID_VM_UNPAUSE = ALARM_GROUP_VM + ".121"
FM_LOG_ID_VM_UNPAUSING = ALARM_GROUP_VM + ".122"
FM_LOG_ID_VM_UNPAUSE_REJECTED = ALARM_GROUP_VM + ".123"
FM_LOG_ID_VM_UNPAUSE_CANCELLED = ALARM_GROUP_VM + ".124"
FM_LOG_ID_VM_UNPAUSE_FAILED = ALARM_GROUP_VM + ".125"
FM_LOG_ID_VM_UNPAUSED = ALARM_GROUP_VM + ".126"
FM_LOG_ID_VM_SUSPEND = ALARM_GROUP_VM + ".127"
FM_LOG_ID_VM_SUSPENDING = ALARM_GROUP_VM + ".128"
FM_LOG_ID_VM_SUSPEND_REJECTED = ALARM_GROUP_VM + ".129"
FM_LOG_ID_VM_SUSPEND_CANCELLED = ALARM_GROUP_VM + ".130"
FM_LOG_ID_VM_SUSPEND_FAILED = ALARM_GROUP_VM + ".131"
FM_LOG_ID_VM_SUSPENDED = ALARM_GROUP_VM + ".132"
FM_LOG_ID_VM_RESUME = ALARM_GROUP_VM + ".133"
FM_LOG_ID_VM_RESUMING = ALARM_GROUP_VM + ".134"
FM_LOG_ID_VM_RESUME_REJECTED = ALARM_GROUP_VM + ".135"
FM_LOG_ID_VM_RESUME_CANCELLED = ALARM_GROUP_VM + ".136"
FM_LOG_ID_VM_RESUME_FAILED = ALARM_GROUP_VM + ".137"
FM_LOG_ID_VM_RESUMED = ALARM_GROUP_VM + ".138"
FM_LOG_ID_VM_START = ALARM_GROUP_VM + ".139"
FM_LOG_ID_VM_STARTING = ALARM_GROUP_VM + ".140"
FM_LOG_ID_VM_START_REJECTED = ALARM_GROUP_VM + ".141"
FM_LOG_ID_VM_START_CANCELLED = ALARM_GROUP_VM + ".142"
FM_LOG_ID_VM_START_FAILED = ALARM_GROUP_VM + ".143"
FM_LOG_ID_VM_STARTED = ALARM_GROUP_VM + ".144"
FM_LOG_ID_VM_STOP = ALARM_GROUP_VM + ".145"
FM_LOG_ID_VM_STOPPING = ALARM_GROUP_VM + ".146"
FM_LOG_ID_VM_STOP_REJECTED = ALARM_GROUP_VM + ".147"
FM_LOG_ID_VM_STOP_CANCELLED = ALARM_GROUP_VM + ".148"
FM_LOG_ID_VM_STOP_FAILED = ALARM_GROUP_VM + ".149"
FM_LOG_ID_VM_STOPPED = ALARM_GROUP_VM + ".150"
FM_LOG_ID_VM_LIVE_MIGRATE = ALARM_GROUP_VM + ".151"
FM_LOG_ID_VM_LIVE_MIGRATING = ALARM_GROUP_VM + ".152"
FM_LOG_ID_VM_LIVE_MIGRATE_REJECTED = ALARM_GROUP_VM + ".153"
FM_LOG_ID_VM_LIVE_MIGRATE_CANCELLED = ALARM_GROUP_VM + ".154"
FM_LOG_ID_VM_LIVE_MIGRATE_FAILED = ALARM_GROUP_VM + ".155"
FM_LOG_ID_VM_LIVE_MIGRATED = ALARM_GROUP_VM + ".156"
FM_LOG_ID_VM_COLD_MIGRATE = ALARM_GROUP_VM + ".157"
FM_LOG_ID_VM_COLD_MIGRATING = ALARM_GROUP_VM + ".158"
FM_LOG_ID_VM_COLD_MIGRATE_REJECTED = ALARM_GROUP_VM + ".159"
FM_LOG_ID_VM_COLD_MIGRATE_CANCELLED = ALARM_GROUP_VM + ".160"
FM_LOG_ID_VM_COLD_MIGRATE_FAILED = ALARM_GROUP_VM + ".161"
FM_LOG_ID_VM_COLD_MIGRATED = ALARM_GROUP_VM + ".162"
FM_LOG_ID_VM_COLD_MIGRATE_CONFIRM = ALARM_GROUP_VM + ".163"
FM_LOG_ID_VM_COLD_MIGRATE_CONFIRMING = ALARM_GROUP_VM + ".164"
FM_LOG_ID_VM_COLD_MIGRATE_CONFIRM_REJECTED = ALARM_GROUP_VM + ".165"
FM_LOG_ID_VM_COLD_MIGRATE_CONFIRM_CANCELLED = ALARM_GROUP_VM + ".166"
FM_LOG_ID_VM_COLD_MIGRATE_CONFIRM_FAILED = ALARM_GROUP_VM + ".167"
FM_LOG_ID_VM_COLD_MIGRATE_CONFIRMED = ALARM_GROUP_VM + ".168"
FM_LOG_ID_VM_COLD_MIGRATE_REVERT = ALARM_GROUP_VM + ".169"
FM_LOG_ID_VM_COLD_MIGRATE_REVERTING = ALARM_GROUP_VM + ".170"
FM_LOG_ID_VM_COLD_MIGRATE_REVERT_REJECTED = ALARM_GROUP_VM + ".171"
FM_LOG_ID_VM_COLD_MIGRATE_REVERT_CANCELLED = ALARM_GROUP_VM + ".172"
FM_LOG_ID_VM_COLD_MIGRATE_REVERT_FAILED = ALARM_GROUP_VM + ".173"
FM_LOG_ID_VM_COLD_MIGRATE_REVERTED = ALARM_GROUP_VM + ".174"
FM_LOG_ID_VM_EVACUATE = ALARM_GROUP_VM + ".175"
FM_LOG_ID_VM_EVACUATING = ALARM_GROUP_VM + ".176"
FM_LOG_ID_VM_EVACUATE_REJECTED = ALARM_GROUP_VM + ".177"
FM_LOG_ID_VM_EVACUATE_CANCELLED = ALARM_GROUP_VM + ".178"
FM_LOG_ID_VM_EVACUATE_FAILED = ALARM_GROUP_VM + ".179"
FM_LOG_ID_VM_EVACUATED = ALARM_GROUP_VM + ".180"
FM_LOG_ID_VM_REBOOT = ALARM_GROUP_VM + ".181"
FM_LOG_ID_VM_REBOOTING = ALARM_GROUP_VM + ".182"
FM_LOG_ID_VM_REBOOT_REJECTED = ALARM_GROUP_VM + ".183"
FM_LOG_ID_VM_REBOOT_CANCELLED = ALARM_GROUP_VM + ".184"
FM_LOG_ID_VM_REBOOT_FAILED = ALARM_GROUP_VM + ".185"
FM_LOG_ID_VM_REBOOTED = ALARM_GROUP_VM + ".186"
FM_LOG_ID_VM_REBUILD = ALARM_GROUP_VM + ".187"
FM_LOG_ID_VM_REBUILDING = ALARM_GROUP_VM + ".188"
FM_LOG_ID_VM_REBUILD_REJECTED = ALARM_GROUP_VM + ".189"
FM_LOG_ID_VM_REBUILD_CANCELLED = ALARM_GROUP_VM + ".190"
FM_LOG_ID_VM_REBUILD_FAILED = ALARM_GROUP_VM + ".191"
FM_LOG_ID_VM_REBUILT = ALARM_GROUP_VM + ".192"
FM_LOG_ID_VM_RESIZE = ALARM_GROUP_VM + ".193"
FM_LOG_ID_VM_RESIZING = ALARM_GROUP_VM + ".194"
FM_LOG_ID_VM_RESIZE_REJECTED = ALARM_GROUP_VM + ".195"
FM_LOG_ID_VM_RESIZE_CANCELLED = ALARM_GROUP_VM + ".196"
FM_LOG_ID_VM_RESIZE_FAILED = ALARM_GROUP_VM + ".197"
FM_LOG_ID_VM_RESIZED = ALARM_GROUP_VM + ".198"
FM_LOG_ID_VM_RESIZE_CONFIRM = ALARM_GROUP_VM + ".199"
FM_LOG_ID_VM_RESIZE_CONFIRMING = ALARM_GROUP_VM + ".200"
FM_LOG_ID_VM_RESIZE_CONFIRM_REJECTED = ALARM_GROUP_VM + ".201"
FM_LOG_ID_VM_RESIZE_CONFIRM_CANCELLED = ALARM_GROUP_VM + ".202"
FM_LOG_ID_VM_RESIZE_CONFIRM_FAILED = ALARM_GROUP_VM + ".203"
FM_LOG_ID_VM_RESIZE_CONFIRMED = ALARM_GROUP_VM + ".204"
FM_LOG_ID_VM_RESIZE_REVERT = ALARM_GROUP_VM + ".205"
FM_LOG_ID_VM_RESIZE_REVERTING = ALARM_GROUP_VM + ".206"
FM_LOG_ID_VM_RESIZE_REVERT_REJECTED = ALARM_GROUP_VM + ".207"
FM_LOG_ID_VM_RESIZE_REVERT_CANCELLED = ALARM_GROUP_VM + ".208"
FM_LOG_ID_VM_RESIZE_REVERT_FAILED = ALARM_GROUP_VM + ".209"
FM_LOG_ID_VM_RESIZE_REVERTED = ALARM_GROUP_VM + ".210"
FM_LOG_ID_VM_GUEST_HEARTBEAT_ESTABLISHED = ALARM_GROUP_VM + ".211"
FM_LOG_ID_VM_GUEST_HEARTBEAT_DISCONNECTED = ALARM_GROUP_VM + ".212"
FM_LOG_ID_VM_GUEST_HEARTBEAT_FAILED = ALARM_GROUP_VM + ".213"
FM_LOG_ID_VM_RENAMED = ALARM_GROUP_VM + ".214"
FM_LOG_ID_VM_GUEST_HEALTH_CHECK_FAILED = ALARM_GROUP_VM + ".215"
FM_LOG_ID_VM_MULTI_NODE_RECOVERY_MODE_ENTER = ALARM_GROUP_VM + ".216"
FM_LOG_ID_VM_MULTI_NODE_RECOVERY_MODE_EXIT = ALARM_GROUP_VM + ".217"
# Patching alarm id
FM_ALARM_ID_PATCH_IN_PROGRESS = ALARM_GROUP_SW_MGMT + ".001"
FM_ALARM_ID_PATCH_HOST_INSTALL_FAILED = ALARM_GROUP_SW_MGMT + ".002"
FM_ALARM_ID_PATCH_OBS_IN_SYSTEM = ALARM_GROUP_SW_MGMT + ".003"
# Upgrades alarm id
FM_ALARM_ID_HOST_VERSION_MISMATCH = ALARM_GROUP_SW_MGMT + ".004"
FM_ALARM_ID_UPGRADE_IN_PROGRESS = ALARM_GROUP_SW_MGMT + ".005"
# Security log id
FM_LOG_ID_INVALID_PASSWORD = ALARM_GROUP_SECURITY + ".001"
FM_LOG_ID_USER_LOCKOUT = ALARM_GROUP_SECURITY + ".002"
# Security alarm id
FM_ALARM_ID_TPM_INIT = ALARM_GROUP_SECURITY + ".100"
# Security nonstandard certificate in use for patching alarm id
FM_ALARM_ID_NONSTANDARD_CERT_PATCH = ALARM_GROUP_SECURITY + ".101"
# Software Update Orchestration
FM_ALARM_ID_SW_PATCH_AUTO_APPLY_INPROGRESS = ALARM_GROUP_SW_MGMT + ".101"
FM_ALARM_ID_SW_PATCH_AUTO_APPLY_ABORTING = ALARM_GROUP_SW_MGMT + ".102"
FM_ALARM_ID_SW_PATCH_AUTO_APPLY_FAILED = ALARM_GROUP_SW_MGMT + ".103"
FM_LOG_ID_SW_PATCH_AUTO_APPLY_START = ALARM_GROUP_SW_MGMT + ".111"
FM_LOG_ID_SW_PATCH_AUTO_APPLY_INPROGRESS = ALARM_GROUP_SW_MGMT + ".112"
FM_LOG_ID_SW_PATCH_AUTO_APPLY_REJECTED = ALARM_GROUP_SW_MGMT + ".113"
FM_LOG_ID_SW_PATCH_AUTO_APPLY_CANCELLED = ALARM_GROUP_SW_MGMT + ".114"
FM_LOG_ID_SW_PATCH_AUTO_APPLY_FAILED = ALARM_GROUP_SW_MGMT + ".115"
FM_LOG_ID_SW_PATCH_AUTO_APPLY_COMPLETED = ALARM_GROUP_SW_MGMT + ".116"
FM_LOG_ID_SW_PATCH_AUTO_APPLY_ABORT = ALARM_GROUP_SW_MGMT + ".117"
FM_LOG_ID_SW_PATCH_AUTO_APPLY_ABORTING = ALARM_GROUP_SW_MGMT + ".118"
FM_LOG_ID_SW_PATCH_AUTO_APPLY_ABORT_REJECTED = ALARM_GROUP_SW_MGMT + ".119"
FM_LOG_ID_SW_PATCH_AUTO_APPLY_ABORT_FAILED = ALARM_GROUP_SW_MGMT + ".120"
FM_LOG_ID_SW_PATCH_AUTO_APPLY_ABORTED = ALARM_GROUP_SW_MGMT + ".121"
FM_ALARM_ID_SW_UPGRADE_AUTO_APPLY_INPROGRESS = ALARM_GROUP_SW_MGMT + ".201"
FM_ALARM_ID_SW_UPGRADE_AUTO_APPLY_ABORTING = ALARM_GROUP_SW_MGMT + ".202"
FM_ALARM_ID_SW_UPGRADE_AUTO_APPLY_FAILED = ALARM_GROUP_SW_MGMT + ".203"
FM_LOG_ID_SW_UPGRADE_AUTO_APPLY_START = ALARM_GROUP_SW_MGMT + ".211"
FM_LOG_ID_SW_UPGRADE_AUTO_APPLY_INPROGRESS = ALARM_GROUP_SW_MGMT + ".212"
FM_LOG_ID_SW_UPGRADE_AUTO_APPLY_REJECTED = ALARM_GROUP_SW_MGMT + ".213"
FM_LOG_ID_SW_UPGRADE_AUTO_APPLY_CANCELLED = ALARM_GROUP_SW_MGMT + ".214"
FM_LOG_ID_SW_UPGRADE_AUTO_APPLY_FAILED = ALARM_GROUP_SW_MGMT + ".215"
FM_LOG_ID_SW_UPGRADE_AUTO_APPLY_COMPLETED = ALARM_GROUP_SW_MGMT + ".216"
FM_LOG_ID_SW_UPGRADE_AUTO_APPLY_ABORT = ALARM_GROUP_SW_MGMT + ".217"
FM_LOG_ID_SW_UPGRADE_AUTO_APPLY_ABORTING = ALARM_GROUP_SW_MGMT + ".218"
FM_LOG_ID_SW_UPGRADE_AUTO_APPLY_ABORT_REJECTED = ALARM_GROUP_SW_MGMT + ".219"
FM_LOG_ID_SW_UPGRADE_AUTO_APPLY_ABORT_FAILED = ALARM_GROUP_SW_MGMT + ".220"
FM_LOG_ID_SW_UPGRADE_AUTO_APPLY_ABORTED = ALARM_GROUP_SW_MGMT + ".221"
FM_ALARM_STATE_SET = 'set'
FM_ALARM_STATE_CLEAR = 'clear'
FM_ALARM_STATE_MSG = 'msg'
FM_ALARM_TYPE_0 = 'other'
FM_ALARM_TYPE_1 = 'communication'
FM_ALARM_TYPE_2 = 'qos'
FM_ALARM_TYPE_3 = 'processing-error'
FM_ALARM_TYPE_4 = 'equipment'
FM_ALARM_TYPE_5 = 'environmental'
FM_ALARM_TYPE_6 = 'integrity-violation'
FM_ALARM_TYPE_7 = 'operational-violation'
FM_ALARM_TYPE_8 = 'physical-violation'
FM_ALARM_TYPE_9 = 'security-service-or-mechanism-violation'
FM_ALARM_TYPE_10 = 'time-domain-violation'
FM_ALARM_SEVERITY_CLEAR = 'clear'
FM_ALARM_SEVERITY_WARNING = 'warning'
FM_ALARM_SEVERITY_MINOR = 'minor'
FM_ALARM_SEVERITY_MAJOR = 'major'
FM_ALARM_SEVERITY_CRITICAL = 'critical'
FM_ALARM_OK_STATUS = "OK"
FM_ALARM_DEGRADED_STATUS = "degraded"
FM_ALARM_CRITICAL_STATUS = "critical"
ALARM_CRITICAL_REPLICATION = 'Potential data loss. No available OSDs in storage replication group '
ALARM_MAJOR_REPLICATION = 'Loss of replication in replication group '
ALARM_PROBABLE_CAUSE_1 = 'adaptor-error'
ALARM_PROBABLE_CAUSE_2 = 'application-subsystem-failure'
ALARM_PROBABLE_CAUSE_3 = 'bandwidth-reduced'
ALARM_PROBABLE_CAUSE_4 = 'call-establishment-error'
ALARM_PROBABLE_CAUSE_5 = 'communication-protocol-error'
ALARM_PROBABLE_CAUSE_6 = 'communication-subsystem-failure'
ALARM_PROBABLE_CAUSE_7 = 'configuration-or-customization-error'
ALARM_PROBABLE_CAUSE_8 = 'congestion'
ALARM_PROBABLE_CAUSE_9 = 'corrupt-data'
ALARM_PROBABLE_CAUSE_10 = 'cpu-cycles-limit-exceeded'
ALARM_PROBABLE_CAUSE_11 = 'dataset-or-modem-error'
ALARM_PROBABLE_CAUSE_12 = 'degraded-signal'
ALARM_PROBABLE_CAUSE_13 = 'dte-dce-interface-error'
ALARM_PROBABLE_CAUSE_14 = 'enclosure-door-open'
ALARM_PROBABLE_CAUSE_15 = 'equipment-malfunction'
ALARM_PROBABLE_CAUSE_16 = 'excessive-vibration'
ALARM_PROBABLE_CAUSE_17 = 'file-error'
ALARM_PROBABLE_CAUSE_18 = 'fire-detected'
ALARM_PROBABLE_CAUSE_19 = 'flood-detected'
ALARM_PROBABLE_CAUSE_20 = 'framing-error'
ALARM_PROBABLE_CAUSE_21 = 'heating-ventilation-cooling-system-problem'
ALARM_PROBABLE_CAUSE_22 = 'humidity-unacceptable'
ALARM_PROBABLE_CAUSE_23 = 'io-device-error'
ALARM_PROBABLE_CAUSE_24 = 'input-device-error'
ALARM_PROBABLE_CAUSE_25 = 'lan-error'
ALARM_PROBABLE_CAUSE_26 = 'leak-detected'
ALARM_PROBABLE_CAUSE_27 = 'local-node-transmission-error'
ALARM_PROBABLE_CAUSE_28 = 'loss-of-frame'
ALARM_PROBABLE_CAUSE_29 = 'loss-of-signal'
ALARM_PROBABLE_CAUSE_30 = 'material-supply-exhausted'
ALARM_PROBABLE_CAUSE_31 = 'multiplexer-problem'
ALARM_PROBABLE_CAUSE_32 = 'out-of-memory'
ALARM_PROBABLE_CAUSE_33 = 'output-device-error'
ALARM_PROBABLE_CAUSE_34 = 'performance-degraded'
ALARM_PROBABLE_CAUSE_35 = 'power-problem'
ALARM_PROBABLE_CAUSE_36 = 'processor-problem'
ALARM_PROBABLE_CAUSE_37 = 'pump-failure'
ALARM_PROBABLE_CAUSE_38 = 'queue-size-exceeded'
ALARM_PROBABLE_CAUSE_39 = 'receive-failure'
ALARM_PROBABLE_CAUSE_40 = 'receiver-failure'
ALARM_PROBABLE_CAUSE_41 = 'remote-node-transmission-error'
ALARM_PROBABLE_CAUSE_42 = 'resource-at-or-nearing-capacity'
ALARM_PROBABLE_CAUSE_43 = 'response-time-excessive'
ALARM_PROBABLE_CAUSE_44 = 'retransmission-rate-excessive'
ALARM_PROBABLE_CAUSE_45 = 'software-error'
ALARM_PROBABLE_CAUSE_46 = 'software-program-abnormally-terminated'
ALARM_PROBABLE_CAUSE_47 = 'software-program-error'
ALARM_PROBABLE_CAUSE_48 = 'storage-capacity-problem'
ALARM_PROBABLE_CAUSE_49 = 'temperature-unacceptable'
ALARM_PROBABLE_CAUSE_50 = 'threshold-crossed'
ALARM_PROBABLE_CAUSE_51 = 'timing-problem'
ALARM_PROBABLE_CAUSE_52 = 'toxic-leak-detected'
ALARM_PROBABLE_CAUSE_53 = 'transmit-failure'
ALARM_PROBABLE_CAUSE_54 = 'transmitter-failure'
ALARM_PROBABLE_CAUSE_55 = 'underlying-resource-unavailable'
ALARM_PROBABLE_CAUSE_56 = 'version-mismatch'
ALARM_PROBABLE_CAUSE_57 = 'duplicate-information'
ALARM_PROBABLE_CAUSE_58 = 'information-missing'
ALARM_PROBABLE_CAUSE_59 = 'information-modification-detected'
ALARM_PROBABLE_CAUSE_60 = 'information-out-of-sequence'
ALARM_PROBABLE_CAUSE_61 = 'unexpected-information'
ALARM_PROBABLE_CAUSE_62 = 'denial-of-service'
ALARM_PROBABLE_CAUSE_63 = 'out-of-service'
ALARM_PROBABLE_CAUSE_64 = 'procedural-error'
ALARM_PROBABLE_CAUSE_65 = 'unspecified-reason'
ALARM_PROBABLE_CAUSE_66 = 'cable-tamper'
ALARM_PROBABLE_CAUSE_67 = 'intrusion-detection'
ALARM_PROBABLE_CAUSE_68 = 'authentication-failure'
ALARM_PROBABLE_CAUSE_69 = 'breach-of-confidentiality'
ALARM_PROBABLE_CAUSE_70 = 'non-repudiation-failure'
ALARM_PROBABLE_CAUSE_71 = 'unauthorized-access-attempt'
ALARM_PROBABLE_CAUSE_72 = 'delayed-information'
ALARM_PROBABLE_CAUSE_73 = 'key-expired'
ALARM_PROBABLE_CAUSE_74 = 'out-of-hours-activity'
ALARM_PROBABLE_CAUSE_75 = 'configuration-out-of-date'
ALARM_PROBABLE_CAUSE_76 = 'configuration-provisioning-required'
ALARM_PROBABLE_CAUSE_UNKNOWN = 'unknown'
ALARM_STATE = [FM_ALARM_STATE_SET, FM_ALARM_STATE_CLEAR, FM_ALARM_STATE_MSG]
ALARM_TYPE = [FM_ALARM_TYPE_0, FM_ALARM_TYPE_1, FM_ALARM_TYPE_2,
FM_ALARM_TYPE_3, FM_ALARM_TYPE_4, FM_ALARM_TYPE_5,
FM_ALARM_TYPE_6, FM_ALARM_TYPE_7, FM_ALARM_TYPE_8,
FM_ALARM_TYPE_9, FM_ALARM_TYPE_10]
ALARM_SEVERITY = [FM_ALARM_SEVERITY_CLEAR, FM_ALARM_SEVERITY_WARNING,
FM_ALARM_SEVERITY_MINOR, FM_ALARM_SEVERITY_MAJOR,
FM_ALARM_SEVERITY_CRITICAL]
ALARM_STATUS = [FM_ALARM_OK_STATUS, FM_ALARM_DEGRADED_STATUS,
FM_ALARM_CRITICAL_STATUS]
ALARM_PROBABLE_CAUSE = [ALARM_PROBABLE_CAUSE_1, ALARM_PROBABLE_CAUSE_2,
ALARM_PROBABLE_CAUSE_3, ALARM_PROBABLE_CAUSE_4,
ALARM_PROBABLE_CAUSE_5, ALARM_PROBABLE_CAUSE_6,
ALARM_PROBABLE_CAUSE_7, ALARM_PROBABLE_CAUSE_8,
ALARM_PROBABLE_CAUSE_9, ALARM_PROBABLE_CAUSE_10,
ALARM_PROBABLE_CAUSE_11, ALARM_PROBABLE_CAUSE_12,
ALARM_PROBABLE_CAUSE_13, ALARM_PROBABLE_CAUSE_14,
ALARM_PROBABLE_CAUSE_15, ALARM_PROBABLE_CAUSE_16,
ALARM_PROBABLE_CAUSE_17, ALARM_PROBABLE_CAUSE_18,
ALARM_PROBABLE_CAUSE_19, ALARM_PROBABLE_CAUSE_20,
ALARM_PROBABLE_CAUSE_21, ALARM_PROBABLE_CAUSE_22,
ALARM_PROBABLE_CAUSE_23, ALARM_PROBABLE_CAUSE_24,
ALARM_PROBABLE_CAUSE_25, ALARM_PROBABLE_CAUSE_26,
ALARM_PROBABLE_CAUSE_27, ALARM_PROBABLE_CAUSE_28,
ALARM_PROBABLE_CAUSE_29, ALARM_PROBABLE_CAUSE_30,
ALARM_PROBABLE_CAUSE_31, ALARM_PROBABLE_CAUSE_32,
ALARM_PROBABLE_CAUSE_33, ALARM_PROBABLE_CAUSE_34,
ALARM_PROBABLE_CAUSE_35, ALARM_PROBABLE_CAUSE_36,
ALARM_PROBABLE_CAUSE_37, ALARM_PROBABLE_CAUSE_38,
ALARM_PROBABLE_CAUSE_39, ALARM_PROBABLE_CAUSE_40,
ALARM_PROBABLE_CAUSE_41, ALARM_PROBABLE_CAUSE_42,
ALARM_PROBABLE_CAUSE_43, ALARM_PROBABLE_CAUSE_44,
ALARM_PROBABLE_CAUSE_45, ALARM_PROBABLE_CAUSE_46,
ALARM_PROBABLE_CAUSE_47, ALARM_PROBABLE_CAUSE_48,
ALARM_PROBABLE_CAUSE_49, ALARM_PROBABLE_CAUSE_50,
ALARM_PROBABLE_CAUSE_51, ALARM_PROBABLE_CAUSE_52,
ALARM_PROBABLE_CAUSE_53, ALARM_PROBABLE_CAUSE_54,
ALARM_PROBABLE_CAUSE_55, ALARM_PROBABLE_CAUSE_56,
ALARM_PROBABLE_CAUSE_57, ALARM_PROBABLE_CAUSE_58,
ALARM_PROBABLE_CAUSE_59, ALARM_PROBABLE_CAUSE_60,
ALARM_PROBABLE_CAUSE_61, ALARM_PROBABLE_CAUSE_62,
ALARM_PROBABLE_CAUSE_63, ALARM_PROBABLE_CAUSE_64,
ALARM_PROBABLE_CAUSE_65, ALARM_PROBABLE_CAUSE_66,
ALARM_PROBABLE_CAUSE_67, ALARM_PROBABLE_CAUSE_68,
ALARM_PROBABLE_CAUSE_69, ALARM_PROBABLE_CAUSE_70,
ALARM_PROBABLE_CAUSE_71, ALARM_PROBABLE_CAUSE_72,
ALARM_PROBABLE_CAUSE_73, ALARM_PROBABLE_CAUSE_74,
ALARM_PROBABLE_CAUSE_75, ALARM_PROBABLE_CAUSE_76,
ALARM_PROBABLE_CAUSE_UNKNOWN]
FM_CLIENT_SET_FAULT = "/usr/local/bin/fmClientCli -c "
FM_CLIENT_CLEAR_FAULT = "/usr/local/bin/fmClientCli -d "
FM_CLIENT_GET_FAULT = "/usr/local/bin/fmClientCli -g "
FM_CLIENT_GET_FAULTS = "/usr/local/bin/fmClientCli -G "
FM_CLIENT_GET_FAULTS_BY_ID = "/usr/local/bin/fmClientCli -A "
FM_CLIENT_CLEAR_ALL = "/usr/local/bin/fmClientCli -D "
FM_CLIENT_STR_SEP = "###"
FM_UUID_INDEX = 0
FM_ALARM_ID_INDEX = 1
FM_ALARM_STATE_INDEX = 2
FM_ENT_TYPE_ID_INDEX = 3
FM_ENT_INST_ID_INDEX = 4
FM_TIMESTAMP_INDEX = 5
FM_SEVERITY_INDEX = 6
FM_REASON_TEXT_INDEX = 7
FM_ALARM_TYPE_INDEX = 8
FM_CAUSE_INDEX = 9
FM_REPAIR_ACTION_INDEX = 10
FM_SERVICE_AFFECTING_INDEX = 11
FM_SUPPRESSION_INDEX = 12
FM_INHIBIT_ALARMS_INDEX = 13
MAX_ALARM_ATTRIBUTES = 14

247
fm-api/fm_api/fm_api.py Executable file
View File

@ -0,0 +1,247 @@
#
# Copyright (c) 2013-2014 Wind River Systems, Inc.
#
# SPDX-License-Identifier: Apache-2.0
#
# -*- encoding: utf-8 -*-
#
#
# Author:
#
import copy
import subprocess
import constants
import six
class ClientException(Exception):
pass
# Fields explanation:
#
# alarm_id: a text string of the alarm identifier
# alarm_state: see ALARM_STATE
# entity_type_id: type of the object raising alarm.
# entity_instance_id: instance information of the object raising alarm.
# severity: see ALARM_SEVERITY
# reason_text: free-format string providing description and additional details
# on the alarm. Optional.
# alarm_type: see ALARM_TYPE
# probable_cause: see ALARM_PROBABLE_CAUSE
# proposed_repair_action:free-format string providing additional details on how to
# clear the alarm. Optional.
# service_affecting: true/false, default to false
# suppression: true/false (allowed/not-allowed), default to false
# uuid: unique identifier of an active alarm instance, filled by FM system
# Timestamp: when the alarm has been raised/updated, filled by FM system
# See CGCS FM Guide for the alarm model specification
class Fault(object):
def __init__(self, alarm_id, alarm_state, entity_type_id,
entity_instance_id, severity, reason_text,
alarm_type, probable_cause, proposed_repair_action,
service_affecting=False, suppression=False,
uuid=None, timestamp=None):
self.alarm_id = alarm_id
self.alarm_state = alarm_state
self.entity_type_id = self._unicode(entity_type_id)
self.entity_instance_id = self._unicode(entity_instance_id)
self.severity = severity
self.reason_text = self._unicode(reason_text)
self.alarm_type = alarm_type
self.probable_cause = probable_cause
self.proposed_repair_action = self._unicode(proposed_repair_action)
self.service_affecting = service_affecting
self.suppression = suppression
self.uuid = uuid
self.timestamp = timestamp
def as_dict(self):
return copy.copy(self.__dict__)
@staticmethod
def _unicode(value):
if isinstance(value, str):
return six.text_type(value.decode('utf-8'))
else:
return value
class FaultAPIs(object):
def set_fault(self, data):
self._check_required_attributes(data)
self._validate_attributes(data)
buff = self._alarm_to_str(data)
cmd = constants.FM_CLIENT_SET_FAULT + '"' + buff + '"'
resp = self._run_cmd_and_get_resp(cmd)
if (resp[0] == "Ok") and (len(resp) > 1):
return resp[1]
else:
return None
def clear_fault(self, alarm_id, entity_instance_id):
sep = constants.FM_CLIENT_STR_SEP
buff = (sep + self._check_val(alarm_id) + sep +
self._check_val(entity_instance_id) + sep)
cmd = constants.FM_CLIENT_CLEAR_FAULT + '"' + buff + '"'
resp = self._run_cmd_and_get_resp(cmd)
if resp[0] == "Ok":
return True
else:
return False
def get_fault(self, alarm_id, entity_instance_id):
sep = constants.FM_CLIENT_STR_SEP
buff = (sep + self._check_val(alarm_id) + sep +
self._check_val(entity_instance_id) + sep)
cmd = constants.FM_CLIENT_GET_FAULT + '"' + buff + '"'
resp = self._run_cmd_and_get_resp(cmd)
if (resp[0] == "Ok") and (len(resp) > 1):
return self._str_to_alarm(resp[1])
else:
return None
def clear_all(self, entity_instance_id):
cmd = constants.FM_CLIENT_CLEAR_ALL + '"' + entity_instance_id + '"'
resp = self._run_cmd_and_get_resp(cmd)
if resp[0] == "Ok":
return True
else:
return False
def get_faults(self, entity_instance_id):
cmd = constants.FM_CLIENT_GET_FAULTS + '"' + entity_instance_id + '"'
resp = self._run_cmd_and_get_resp(cmd)
data = []
if resp[0] == "Ok":
for i in range(1, len(resp)):
alarm = self._str_to_alarm(resp[i])
data.append(alarm)
return data
else:
return None
def get_faults_by_id(self, alarm_id):
cmd = constants.FM_CLIENT_GET_FAULTS_BY_ID + '"' + alarm_id + '"'
resp = self._run_cmd_and_get_resp(cmd)
data = []
if resp[0] == "Ok":
for i in range(1, len(resp)):
alarm = self._str_to_alarm(resp[i])
data.append(alarm)
return data
else:
return None
@staticmethod
def _check_val(data):
if data is None:
return " "
else:
return data
def _alarm_to_str(self, data):
sep = constants.FM_CLIENT_STR_SEP
return (sep + self._check_val(data.uuid) + sep + data.alarm_id + sep +
data.alarm_state + sep + data.entity_type_id + sep +
data.entity_instance_id + sep + self._check_val(data.timestamp)
+ sep + data.severity + sep + self._check_val(data.reason_text)
+ sep + data.alarm_type + sep + data.probable_cause + sep +
self._check_val(data.proposed_repair_action) + sep +
str(data.service_affecting) + sep + str(data.suppression) + sep)
@staticmethod
def _str_to_alarm(alarm_str):
l = alarm_str.split(constants.FM_CLIENT_STR_SEP)
if len(l) < constants.MAX_ALARM_ATTRIBUTES:
return None
else:
data = Fault(l[constants.FM_ALARM_ID_INDEX],
l[constants.FM_ALARM_STATE_INDEX],
l[constants.FM_ENT_TYPE_ID_INDEX],
l[constants.FM_ENT_INST_ID_INDEX],
l[constants.FM_SEVERITY_INDEX],
l[constants.FM_REASON_TEXT_INDEX],
l[constants.FM_ALARM_TYPE_INDEX],
l[constants.FM_CAUSE_INDEX],
l[constants.FM_REPAIR_ACTION_INDEX],
l[constants.FM_SERVICE_AFFECTING_INDEX],
l[constants.FM_SUPPRESSION_INDEX],
l[constants.FM_UUID_INDEX],
l[constants.FM_TIMESTAMP_INDEX])
return data
@staticmethod
def _run_cmd_and_get_resp(cmd):
resp = []
cmd = cmd.encode('utf-8')
pro = subprocess.Popen(cmd,shell=True,stdout=subprocess.PIPE)
output = pro.communicate()[0]
lines = output.split('\n')
for line in lines:
if line != '':
resp.append(line)
if len(resp) == 0:
resp.append("Unknown")
return resp
@staticmethod
def _check_required_attributes(data):
if data.alarm_id is None:
raise ClientException("Alarm id is is required.")
if data.alarm_state is None:
raise ClientException("Alarm state is required.")
if data.severity is None:
raise ClientException("Severity is required.")
if data.alarm_type is None:
raise ClientException("Alarm type is required.")
if data.probable_cause is None:
raise ClientException("Probable Cause is required.")
if data.entity_type_id is None:
raise ClientException("Entity type id is required.")
if data.entity_instance_id is None:
raise ClientException("Entity instance id is required.")
@staticmethod
def _validate_attributes(data):
""" Validate the attributes
only applies to Telco specific attributes"""
if data.alarm_state not in constants.ALARM_STATE:
raise ClientException("Invalid Fault State: %s" %
data.alarm_state)
if data.severity not in constants.ALARM_SEVERITY:
raise ClientException("Invalid Fault Severity: %s" %
data.severity)
if data.alarm_type not in constants.ALARM_TYPE:
raise ClientException("Invalid Fault Type: %s" %
data.alarm_type)
if data.probable_cause not in constants.ALARM_PROBABLE_CAUSE:
raise ClientException("Invalid Fault Probable Cause: %s" %
data.probable_cause)
@staticmethod
def alarm_allowed(alarm_severity, threshold):
def severity_to_int(severity):
if severity == 'none':
return 5
elif severity == constants.FM_ALARM_SEVERITY_CRITICAL:
return 4
elif severity == constants.FM_ALARM_SEVERITY_MAJOR:
return 3
elif severity == constants.FM_ALARM_SEVERITY_MINOR:
return 2
elif severity == constants.FM_ALARM_SEVERITY_WARNING:
return 1
given = severity_to_int(alarm_severity)
threshold = severity_to_int(threshold)
if given < threshold:
return True
return False

105
fm-api/fm_api_test.py Normal file
View File

@ -0,0 +1,105 @@
# -*- encoding: utf-8 -*-
#
# Copyright (c) 2014 Wind River Systems, Inc.
#
# Author:
#
# 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
from fm_api import *
from fm_api import constants
def print_alarm(alarm):
alarm_str = "alarm_id: " + alarm.alarm_id + ", " + "uuid: " + alarm.uuid + ", "
alarm_str += "alarm_type: " + alarm.alarm_type + "\n"
alarm_str += "state: " + alarm.alarm_state + ", ""severity: " + alarm.severity + ", " \
+ "entity_type_id: " + alarm.entity_type_id + ", timestamp: "+ alarm.timestamp + "\n"
alarm_str += "entity_instance_id: " + alarm.entity_instance_id + ", "
alarm_str += "probable cause:" + alarm.probable_cause + "\n"
print alarm_str
def create():
ser = FaultAPIs()
fault = Fault(alarm_id=constants.FM_ALARM_ID_VM_RESCUED,
alarm_state=constants.FM_ALARM_STATE_SET,
entity_type_id=constants.FM_ENTITY_TYPE_INSTANCE,
entity_instance_id=constants.FM_ENTITY_TYPE_INSTANCE + '=' + 'a4e4cdb7-2ee6-4818-84c8-5310fcd67b5d',
severity = constants.FM_ALARM_SEVERITY_CRITICAL,
reason_text = "Unknown",
alarm_type = constants.FM_ALARM_TYPE_5,
probable_cause = constants.ALARM_PROBABLE_CAUSE_8,
proposed_repair_action = None,
service_affecting = False,
suppression = False)
uuid =ser.set_fault(fault)
print uuid
def delete(alarm_id, instance_id):
ser=FaultAPIs()
ret = ser.clear_fault(alarm_id,instance_id)
print "Delete fault return %s" % str(ret)
def del_all(instance_id):
ser=FaultAPIs()
ret= ser.clear_all(instance_id)
print "Delete faults return: %s" % str(ret)
def get(alarm_id, instance_id):
ser=FaultAPIs()
a = ser.get_fault(alarm_id, instance_id)
if a is not None:
print_alarm(a)
else:
print "Alarm not found"
def get_all(instance_id):
ser=FaultAPIs()
ll= ser.get_faults(instance_id)
if ll is not None:
print "Total alarm returned: %d\n" % len(ll)
for i in ll:
print_alarm(i)
else:
print "No alarm returned"
def get_list(alarm_id):
ser=FaultAPIs()
ll= ser.get_faults_by_id(alarm_id)
if ll is not None:
print "Total alarm returned: %d\n" % len(ll)
for i in ll:
print_alarm(i)
else:
print "No alarm returned"
if __name__ == "__main__":
if sys.argv[1] == "create":
sys.exit(create())
elif sys.argv[1] == "del":
sys.exit(delete(sys.argv[2],sys.argv[3]))
elif sys.argv[1] == "get":
sys.exit(get(sys.argv[2],sys.argv[3]))
elif sys.argv[1] == "get_all":
sys.exit(get_all(sys.argv[2]))
elif sys.argv[1] == "del_all":
sys.exit(del_all(sys.argv[2]))
elif sys.argv[1] == "get_list":
sys.exit(get_list(sys.argv[2]))

17
fm-api/setup.py Normal file
View File

@ -0,0 +1,17 @@
#
# Copyright (c) 2013-2014 Wind River Systems, Inc.
#
# SPDX-License-Identifier: Apache-2.0
#
import setuptools
setuptools.setup(
name='fm_api',
description='CGCS FM Python API',
version='1.0.0',
license='Apache-2.0',
packages=['fm_api'],
entry_points={
}
)

6
fm-common/.gitignore vendored Normal file
View File

@ -0,0 +1,6 @@
!.distro
.distro/centos7/rpmbuild/RPMS
.distro/centos7/rpmbuild/SRPMS
.distro/centos7/rpmbuild/BUILD
.distro/centos7/rpmbuild/BUILDROOT
.distro/centos7/rpmbuild/SOURCES/fm-common*tar.gz

14
fm-common/PKG-INFO Normal file
View File

@ -0,0 +1,14 @@
Metadata-Version: 1.1
Name: fm-common
Version: 1.0
Summary: Titanium Cloud Platform Fault Management Common Package
Home-page:
Author: Windriver
Author-email: info@windriver.com
License: Apache-2.0
Description: CGTS platform Fault Management Client Library that provides APIs
for applications to raise/clear/update active alarms."
Platform: UNKNOWN

View File

@ -0,0 +1,2 @@
SRC_DIR="sources"
TIS_PATCH_VER=8

View File

@ -0,0 +1,85 @@
%define local_dir /usr/local
%define local_bindir %{local_dir}/bin
%define cgcs_doc_deploy_dir /opt/deploy/cgcs_doc
Summary: CGTS Platform Fault Management Common Package
Name: fm-common
Version: 1.0
Release: %{tis_patch_ver}%{?_tis_dist}
License: Apache-2.0
Group: base
Packager: Wind River <info@windriver.com>
URL: unknown
Source0: %{name}-%{version}.tar.gz
BuildRequires: util-linux
BuildRequires: postgresql-devel
BuildRequires: libuuid-devel
BuildRequires: python-devel
%package -n fm-common-dev
Summary: CGTS Platform Fault Management Common Package - Development files
Group: devel
Requires: fm-common = %{version}-%{release}
%description
Titanium Cloud platform Fault Management Client Library that provides APIs for
applications to raise/clear/update active alarms.
%description -n fm-common-dev
Titanium Cloud platform Fault Management Client Library that provides APIs for
applications to raise/clear/update active alarms. This package contains
symbolic links, header files, and related items necessary for software
development.
%package -n fm-common-doc
Summary: fm-common deploy doc
Group: doc
%description -n fm-common-doc
Contains fmAlarm.h which is to be used by fm-doc package to validate
the Alarms & Logs Doc Yaml file
%prep
%setup
%build
VER=%{version}
MAJOR=`echo $VER | awk -F . '{print $1}'`
MINOR=`echo $VER | awk -F . '{print $2}'`
make MAJOR=$MAJOR MINOR=$MINOR %{?_smp_mflags}
%install
rm -rf $RPM_BUILD_ROOT
VER=%{version}
MAJOR=`echo $VER | awk -F . '{print $1}'`
MINOR=`echo $VER | awk -F . '{print $2}'`
make DEST_DIR=$RPM_BUILD_ROOT BIN_DIR=%{local_bindir} LIB_DIR=%{_libdir} INC_DIR=%{_includedir} MAJOR=$MAJOR MINOR=$MINOR install_non_bb
install -d $RPM_BUILD_ROOT/usr/bin
install -m 755 fm_db_sync_event_suppression.py $RPM_BUILD_ROOT/usr/bin/fm_db_sync_event_suppression.py
CGCS_DOC_DEPLOY=$RPM_BUILD_ROOT/%{cgcs_doc_deploy_dir}
install -d $CGCS_DOC_DEPLOY
# install fmAlarm.h in CGCS_DOC_DEPLOY_DIR
# used by fm-doc package to validate the Alarms & Logs Doc Yaml file
install -m 644 fmAlarm.h $CGCS_DOC_DEPLOY
%clean
rm -rf $RPM_BUILD_ROOT
%files
%defattr(-,root,root,-)
%doc LICENSE
%{local_bindir}/*
%{_libdir}/*.so.*
/usr/bin/fm_db_sync_event_suppression.py
%files -n fm-common-dev
%defattr(-,root,root,-)
%{_includedir}/*
%{_libdir}/*.so
%files -n fm-common-doc
%defattr(-,root,root,-)
%{cgcs_doc_deploy_dir}/*

202
fm-common/sources/LICENSE Normal file
View File

@ -0,0 +1,202 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
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.

40
fm-common/sources/Makefile Executable file
View File

@ -0,0 +1,40 @@
SRCS = fmAPI.cpp fmFile.cpp fmLog.cpp fmMsgServer.cpp fmMutex.cpp fmSocket.cpp fmThread.cpp fmTime.cpp \
fmAlarmUtils.cpp fmDb.cpp fmDbUtils.cpp fmDbAlarm.cpp fmSnmpUtils.cpp \
fmDbEventLog.cpp fmEventSuppression.cpp
CLI_SRCS = fm_cli.cpp
OBJS = $(SRCS:.cpp=.o)
CLI_OBJS = fm_cli.o
LDLIBS = -lstdc++ -lrt -luuid -lpq -lpthread -lpython2.7
INCLUDES = -I./
CCFLAGS = -g -O2 -Wall -Werror -fPIC
LIBFMCOMMON_SO := libfmcommon.so
build: lib fmClientCli
.cpp.o:
$(CXX) $(CCFLAGS) $(INCLUDES) $(EXTRACCFLAGS) -c $< -o $@
lib: $(OBJS)
$(CXX) -Wl,-soname,$(LIBFMCOMMON_SO).$(MAJOR) -o $(LIBFMCOMMON_SO).$(MAJOR).$(MINOR) -shared $(OBJS) $(EXTRAARFLAGS) ${LDLIBS}
ln -sf $(LIBFMCOMMON_SO).$(MAJOR).$(MINOR) $(LIBFMCOMMON_SO).$(MAJOR)
ln -sf $(LIBFMCOMMON_SO).$(MAJOR).$(MINOR) $(LIBFMCOMMON_SO)
fmClientCli: $(CLI_OBJS) lib
$(CXX) -o $@ $(CLI_OBJS) -L./ -lfmcommon
clean:
@rm -f $(OBJ) *.o *.so fmClientCli
install_non_bb:
install -m 755 -d $(DEST_DIR)$(BIN_DIR)
install -m 755 -d $(DEST_DIR)$(LIB_DIR)
install -m 755 -d $(DEST_DIR)$(INC_DIR)
install -m 755 fmClientCli $(DEST_DIR)$(BIN_DIR)
install -m 644 fmDbAPI.h $(DEST_DIR)$(INC_DIR)
install -m 644 fmAPI.h $(DEST_DIR)$(INC_DIR)
install -m 644 fmThread.h $(DEST_DIR)$(INC_DIR)
install -m 644 fmAlarm.h $(DEST_DIR)$(INC_DIR)
install -m 755 $(LIBFMCOMMON_SO).$(MAJOR).$(MINOR) $(DEST_DIR)$(LIB_DIR)
ln -s $(LIBFMCOMMON_SO).$(MAJOR).$(MINOR) $(DEST_DIR)$(LIB_DIR)/$(LIBFMCOMMON_SO).$(MAJOR)
ln -s $(LIBFMCOMMON_SO).$(MAJOR).$(MINOR) $(DEST_DIR)$(LIB_DIR)/$(LIBFMCOMMON_SO)

514
fm-common/sources/fmAPI.cpp Normal file
View File

@ -0,0 +1,514 @@
//
// Copyright (c) 2017 Wind River Systems, Inc.
//
// SPDX-License-Identifier: Apache-2.0
//
#include <string.h>
#include <stdio.h>
#include <errno.h>
#include <list>
#include <new>
#include <vector>
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <pthread.h>
#include <signal.h>
#include "fmAPI.h"
#include "fmMsg.h"
#include "fmLog.h"
#include "fmSocket.h"
#include "fmMutex.h"
#include "fmThread.h"
#include "fmAlarmUtils.h"
#define FM_MGR_HOST_NAME "controller"
#define MAX_PENDING_REQUEST 1000
#define HANDLE_SERVER_RC(hdr) \
if ((hdr)->msg_rc!=FM_ERR_OK) return (EFmErrorT) (hdr)->msg_rc
#define CHECK_RESPONSE(hdr,neededstruct) \
if (!fm_valid_srv_msg(hdr,sizeof(neededstruct))) \
return FM_ERR_COMMUNICATIONS
#define CHECK_LIST_FULL(l) \
if (l.size() == MAX_PENDING_REQUEST) \
return FM_ERR_NOT_ENOUGH_SPACE
#define CHECK_LIST_NOT_EMPTY(l) \
if (l.size() != 0) \
return FM_ERR_REQUEST_PENDING
static CFmSocket m_client;
static bool m_connected = false;
static bool m_thread = false;
typedef std::list<fm_buff_t> FmRequestListT;
static FmRequestListT & GetListOfFmRequests(){
static FmRequestListT reqs;
return reqs;
}
static CFmMutex & getListMutex(){
static CFmMutex *m = new CFmMutex;
return *m;
}
static CFmMutex & getThreadMutex(){
static CFmMutex *m = new CFmMutex;
return *m;
}
CFmMutex & getAPIMutex(){
static pthread_mutex_t ml = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;
static CFmMutex *m = NULL;
if (m == NULL){
pthread_mutex_lock(&ml);
m = new CFmMutex;
pthread_mutex_unlock(&ml);
}
return *m;
}
static void enqueue(fm_buff_t &req){
CFmMutexGuard m(getListMutex());
GetListOfFmRequests().push_back(req);
}
static bool dequeue(fm_buff_t &req){
CFmMutexGuard m(getListMutex());
if (GetListOfFmRequests().size() == 0){
return false;
}
FmRequestListT::iterator it = GetListOfFmRequests().begin();
req.clear();
req = (*it);
GetListOfFmRequests().pop_front();
return true;
}
static bool fm_lib_reconnect() {
char addr[INET6_ADDRSTRLEN];
while (!m_connected) {
struct addrinfo hints;
struct addrinfo *result=NULL, *rp;
memset(&hints,0,sizeof(hints));
hints.ai_family = AF_UNSPEC; /* Allow IPv4 or IPv6 */
hints.ai_socktype = SOCK_STREAM; /* Datagram socket */
hints.ai_flags = 0; /* For wildcard IP address */
hints.ai_protocol = 0; /* Any protocol */
hints.ai_canonname = NULL;
hints.ai_addr = NULL;
hints.ai_next = NULL;
int rc = getaddrinfo(FM_MGR_HOST_NAME,NULL,
&hints,
&result);
if (rc!=0) {
FM_ERROR_LOG("controller lookup failed... errno:%d",errno);
break;
} else {
for (rp = result; rp != NULL; rp = rp->ai_next) {
if (rp->ai_family==AF_INET||rp->ai_family==AF_INET6) {
if(rp->ai_family==AF_INET) {
inet_ntop(AF_INET, &(((sockaddr_in*)rp->ai_addr)->sin_addr), addr, sizeof(addr));
} else if (rp->ai_family==AF_INET6) {
inet_ntop(AF_INET6, &(((sockaddr_in6*)rp->ai_addr)->sin6_addr), addr, sizeof(addr));
}
m_connected=m_client.connect(addr,8001,rp->ai_family);
if (m_connected==true) {
FM_INFO_LOG("Connected to FM Manager.");
break;
} else {
FM_WARNING_LOG("Failed to connect to FM Manager.");
}
}
}
freeaddrinfo(result);
}
break;
}
return (m_connected);
}
EFmErrorT fm_msg_utils_prep_requet_msg(fm_buff_t &buff,
EFmMsgActionsT act,
const void * data,
uint32_t len) {
try {
buff.resize(sizeof(SFmMsgHdrT) + len);
} catch (...) {
FM_ERROR_LOG("Buff resize failed: errno:%d",errno);
return FM_ERR_NOMEM;
}
SFmMsgHdrT *hdr = ptr_to_hdr(buff);
hdr->action = act;
hdr->msg_size = len;
hdr->version = EFmMsgV1;
hdr->msg_rc = 0;
memcpy(ptr_to_data(buff),data,len);
return FM_ERR_OK;
}
static void fmApiJobHandlerThread(void *context){
while (true){
fm_buff_t buff;
buff.clear();
while (dequeue(buff)){
while (true) {
while (!fm_lib_reconnect()){
fmThreadSleep(200);
}
fm_log_request(buff);
// protect from other sync APIs to access the same socket
CFmMutexGuard m(getAPIMutex());
if(m_client.write_packet(buff)) {
fm_buff_t in_buff;
in_buff.clear();
if(!m_client.read_packet(in_buff)) {
// retry after read failure
fm_log_response(buff, in_buff, true);
m_connected = false;
continue;
}
else {
fm_log_response(buff, in_buff);
break;
}
}else{
//retry after write failure
fm_log_request(buff, true);
m_connected = false;
continue;
}
}
}
fmThreadSleep(50);
}
}
static bool fm_lib_thread(){
CFmMutexGuard m(getThreadMutex());
if (!m_thread){
FM_INFO_LOG("Creating thread");
if (!fmCreateThread(fmApiJobHandlerThread,NULL)) {
FM_ERROR_LOG("Fail to create API job thread");
}
else {
m_thread = true;
}
}
return m_thread;
}
static EFmErrorT fm_check_thread_pending_request(){
CFmMutexGuard m(getThreadMutex());
if (m_thread){
CHECK_LIST_NOT_EMPTY(GetListOfFmRequests());
}
return FM_ERR_OK;
}
extern "C" {
EFmErrorT fm_init_lib() {
signal(SIGINT,SIG_IGN);
CFmMutexGuard m(getAPIMutex());
if (!fm_lib_reconnect()) {
FM_ERROR_LOG("Socket connection failed\n");
return FM_ERR_NOCONNECT;
}
return FM_ERR_OK;
}
EFmErrorT fm_set_fault(const SFmAlarmDataT *alarm,
fm_uuid_t *uuid){
CFmMutexGuard m(getAPIMutex());
if (!fm_lib_reconnect()) return FM_ERR_NOCONNECT;
fm_buff_t buff;
buff.clear();
EFmErrorT erc = fm_msg_utils_prep_requet_msg(buff,EFmCreateFault,
alarm,sizeof(*alarm));
if (erc!=FM_ERR_OK) return erc;
if(m_client.write_packet(buff)) {
if(!m_client.read_packet(buff)) {
m_connected = false;
return FM_ERR_NOCONNECT;
}
HANDLE_SERVER_RC(ptr_to_hdr(buff));
CHECK_RESPONSE(ptr_to_hdr(buff),fm_uuid_t);
if (uuid != NULL)
memcpy(*uuid,ptr_to_data(buff),sizeof(*uuid)-1);
} else {
m_connected = false;
return FM_ERR_NOCONNECT;
}
return FM_ERR_OK;
}
EFmErrorT fm_clear_fault(AlarmFilter *filter){
CFmMutexGuard m(getAPIMutex());
if (!fm_lib_reconnect()) return FM_ERR_NOCONNECT;
fm_buff_t buff;
buff.clear();
EFmErrorT erc = fm_msg_utils_prep_requet_msg(buff,EFmDeleteFault,
filter,sizeof(*filter));
if (erc!=FM_ERR_OK) return erc;
if(m_client.write_packet(buff)) {
if(!m_client.read_packet(buff)) {
m_connected = false;
return FM_ERR_NOCONNECT;
}
HANDLE_SERVER_RC(ptr_to_hdr(buff));
} else {
m_connected = false;
return FM_ERR_NOCONNECT;
}
return FM_ERR_OK;
}
EFmErrorT fm_clear_all(fm_ent_inst_t *inst_id){
CFmMutexGuard m(getAPIMutex());
if (!fm_lib_reconnect()) return FM_ERR_NOCONNECT;
fm_buff_t buff;
buff.clear();
EFmErrorT erc = fm_msg_utils_prep_requet_msg(buff,EFmDeleteFaults,
(*inst_id), sizeof(*inst_id));
if (erc!=FM_ERR_OK) return erc;
if(m_client.write_packet(buff)) {
if(!m_client.read_packet(buff)) {
m_connected = false;
FM_ERROR_LOG("Read ERR: return FM_ERR_NOCONNECT");
return FM_ERR_NOCONNECT;
}
HANDLE_SERVER_RC(ptr_to_hdr(buff));
} else {
m_connected = false;
FM_ERROR_LOG("Write ERR: return FM_ERR_NOCONNECT");
return FM_ERR_NOCONNECT;
}
return FM_ERR_OK;
}
EFmErrorT fm_get_fault(AlarmFilter *filter, SFmAlarmDataT *alarm ){
CFmMutexGuard m(getAPIMutex());
if (!fm_lib_reconnect()) return FM_ERR_NOCONNECT;
fm_check_thread_pending_request();
fm_buff_t buff;
buff.clear();
EFmErrorT erc = fm_msg_utils_prep_requet_msg(buff,EFmGetFault,
filter,sizeof(*filter));
if (erc!=FM_ERR_OK) return erc;
if(m_client.write_packet(buff)) {
if(!m_client.read_packet(buff)) {
m_connected = false;
return FM_ERR_NOCONNECT;
}
HANDLE_SERVER_RC(ptr_to_hdr(buff));
CHECK_RESPONSE(ptr_to_hdr(buff),SFmAlarmDataT);
SFmAlarmDataT * data = (SFmAlarmDataT * ) ptr_to_data(buff);
*alarm = *data;
} else {
m_connected = false;
return FM_ERR_NOCONNECT;
}
return FM_ERR_OK;
}
EFmErrorT fm_get_faults(fm_ent_inst_t *inst_id,
SFmAlarmDataT *alarm, unsigned int *max_alarms_to_get) {
CFmMutexGuard m(getAPIMutex());
if (!fm_lib_reconnect()) return FM_ERR_NOCONNECT;
fm_check_thread_pending_request();
fm_buff_t buff;
buff.clear();
EFmErrorT erc = fm_msg_utils_prep_requet_msg(buff,EFmGetFaults,
(*inst_id),sizeof(*inst_id));
if (erc!=FM_ERR_OK) return erc;
if(m_client.write_packet(buff)) {
if(!m_client.read_packet(buff)) {
m_connected = false;
return FM_ERR_NOCONNECT;
}
if (ptr_to_hdr(buff)->msg_rc != FM_ERR_OK){
*max_alarms_to_get = 0;
EFmErrorT rc = (EFmErrorT)ptr_to_hdr(buff)->msg_rc;
return rc;
}
uint32_t pkt_size = ptr_to_hdr(buff)->msg_size;
if (pkt_size < sizeof(uint32_t)) {
FM_ERROR_LOG("Received invalid pkt size: %u\n",pkt_size );
m_connected = false;
return FM_ERR_COMMUNICATIONS;
}
pkt_size-=sizeof(uint32_t);
char *dptr = (char*)ptr_to_data(buff);
uint32_t *len = (uint32_t*)dptr;
dptr+=sizeof(uint32_t);
if (*max_alarms_to_get < *len) {
return FM_ERR_NOT_ENOUGH_SPACE;
}
if (pkt_size < (*len*sizeof(SFmAlarmDataT)) ) {
return FM_ERR_COMMUNICATIONS;
}
*max_alarms_to_get = *len;
memcpy(alarm,dptr,pkt_size);
} else {
m_connected = false;
return FM_ERR_NOCONNECT;
}
return FM_ERR_OK;
}
EFmErrorT fm_get_faults_by_id(fm_alarm_id *alarm_id, SFmAlarmDataT *alarm,
unsigned int *max_alarms_to_get){
CFmMutexGuard m(getAPIMutex());
if (!fm_lib_reconnect()) return FM_ERR_NOCONNECT;
fm_check_thread_pending_request();
fm_buff_t buff;
buff.clear();
EFmErrorT erc = fm_msg_utils_prep_requet_msg(buff,EFmGetFaultsById,
(*alarm_id),sizeof(*alarm_id));
if (erc!=FM_ERR_OK) return erc;
if(m_client.write_packet(buff)) {
if(!m_client.read_packet(buff)) {
m_connected = false;
return FM_ERR_NOCONNECT;
}
if (ptr_to_hdr(buff)->msg_rc != FM_ERR_OK){
*max_alarms_to_get = 0;
EFmErrorT rc = (EFmErrorT)ptr_to_hdr(buff)->msg_rc;
return rc;
}
uint32_t pkt_size = ptr_to_hdr(buff)->msg_size;
if (pkt_size < sizeof(uint32_t)) {
FM_ERROR_LOG("Received invalid pkt size: %u\n",pkt_size );
m_connected = false;
return FM_ERR_COMMUNICATIONS;
}
pkt_size-=sizeof(uint32_t);
char *dptr = (char*)ptr_to_data(buff);
uint32_t *len = (uint32_t*)dptr;
dptr+=sizeof(uint32_t);
if (*max_alarms_to_get < *len) {
return FM_ERR_NOT_ENOUGH_SPACE;
}
if (pkt_size < (*len*sizeof(SFmAlarmDataT)) ) {
return FM_ERR_COMMUNICATIONS;
}
*max_alarms_to_get = *len;
memcpy(alarm,dptr,pkt_size);
} else {
m_connected = false;
return FM_ERR_NOCONNECT;
}
return FM_ERR_OK;
}
/*
* APIs that enqueue the request and return ok for acknowledgment.
* A backgroup thread will pick up the request and send it to the FM Manager
*/
EFmErrorT fm_set_fault_async(const SFmAlarmDataT *alarm, fm_uuid_t *uuid){
if ( !fm_lib_thread()) return FM_ERR_RESOURCE_UNAVAILABLE;
CHECK_LIST_FULL(GetListOfFmRequests());
fm_uuid_t id;
fm_buff_t buff;
buff.clear();
fm_uuid_create(id);
EFmErrorT erc = fm_msg_utils_prep_requet_msg(buff,EFmCreateFault,
alarm,sizeof(*alarm));
if (erc!=FM_ERR_OK) return erc;
memcpy(ptr_to_data(buff), id, sizeof(fm_uuid_t)-1);
FM_INFO_LOG("Enqueue raise alarm request: UUID (%s) alarm id (%s) instant id (%s)",
id, alarm->alarm_id, alarm->entity_instance_id);
enqueue(buff);
if (uuid != NULL){
memcpy(*uuid,id,sizeof(*uuid)-1);
}
return FM_ERR_OK;
}
EFmErrorT fm_clear_fault_async(AlarmFilter *filter){
if ( !fm_lib_thread()) return FM_ERR_RESOURCE_UNAVAILABLE;
CHECK_LIST_FULL(GetListOfFmRequests());
fm_buff_t buff;
buff.clear();
EFmErrorT erc = fm_msg_utils_prep_requet_msg(buff,EFmDeleteFault,
filter,sizeof(*filter));
if (erc!=FM_ERR_OK) return erc;
FM_INFO_LOG("Enqueue clear alarm request: alarm id (%s), instant id (%s)",
filter->alarm_id, filter->entity_instance_id);
enqueue(buff);
return FM_ERR_OK;
}
EFmErrorT fm_clear_all_async(fm_ent_inst_t *inst_id){
if ( !fm_lib_thread()) return FM_ERR_RESOURCE_UNAVAILABLE;
CHECK_LIST_FULL(GetListOfFmRequests());
fm_buff_t buff;
buff.clear();
EFmErrorT erc = fm_msg_utils_prep_requet_msg(buff,EFmDeleteFaults,
(*inst_id), sizeof(*inst_id));
if (erc!=FM_ERR_OK) return erc;
FM_INFO_LOG("Enqueue clear all alarm request: instant id (%s)", *inst_id);
enqueue(buff);
return FM_ERR_OK;
}
}

224
fm-common/sources/fmAPI.h Normal file
View File

@ -0,0 +1,224 @@
//
// Copyright (c) 2017 Wind River Systems, Inc.
//
// SPDX-License-Identifier: Apache-2.0
//
#ifndef _FM_API_H
#define _FM_API_H
#include <string.h>
#include <stdio.h>
#include <errno.h>
#ifdef __cplusplus
extern "C" {
#endif
#define FM_MAX_BUFFER_LENGTH 255
/* unsigned 64-bit data, 8-byte alignment, Time in microsecond */
typedef unsigned long long int FMTimeT __attribute__((__aligned__(8)));
typedef unsigned char FMBoolTypeT;
#define FM_TRUE 1 //any non-zero value is also considered to be True
#define FM_FALSE 0
typedef enum{
FM_ALARM_STATE_CLEAR = 0,
FM_ALARM_STATE_SET = 1,
FM_ALARM_STATE_MSG = 2,
FM_ALARM_STATE_LOG = 3, // Use only for SNMP Agent
FM_ALARM_STATE_MAX = 4
}EFmAlarmStateT;
typedef enum{
FM_ALARM_SEVERITY_CLEAR = 0,
FM_ALARM_SEVERITY_WARNING = 1,
FM_ALARM_SEVERITY_MINOR = 2,
FM_ALARM_SEVERITY_MAJOR = 3,
FM_ALARM_SEVERITY_CRITICAL = 4,
FM_ALARM_SEVERITY_MAX = 5
}EFmAlarmSeverityT;
typedef enum{
FM_ALARM_TYPE_UNKNOWN = 0,
FM_ALARM_COMM = 1, //communication
FM_ALARM_QOS = 2, //qos
FM_ALARM_PROCESSING_ERROR = 3, //processing-error
FM_ALARM_EQUIPMENT = 4 , //equipment
FM_ALARM_ENVIRONMENTAL = 5, //environmental
FM_ALARM_INTERGRITY = 6, //integrity-violation
FM_ALARM_OPERATIONAL = 7, //operational-violation
FM_ALARM_PHYSICAL = 8, //physical-violation
FM_ALARM_SECURITY = 9, //security-service-or-mechanism-violation
FM_ALARM_TIME = 10, //time-domain-violation
FM_ALARM_TYPE_MAX = 11
}EFmAlarmTypeT;
typedef enum{
FM_ALARM_CAUSE_UNKNOWN = 0,
FM_ALARM_ADAPTOR_ERROR = 1, //adaptor-error
FM_ALARM_APP_SUBSYS_FAILURE = 2, //application-subsystem-failure
FM_ALARM_BANDWIDTH_REDUCED = 3, //bandwidth-reduced
FM_ALARM_CALL_ERROR = 4 , //call-establishment-error
FM_ALARM_COMM_PROTOCOL_ERROR = 5, //communication-protocol-error
FM_ALARM_COMM_SUBSYS_FAILURE = 6, //communication-subsystem-failure
FM_ALARM_CONFIG_ERROR = 7, //configuration-or-customization-error
FM_ALARM_CONGESTION = 8, //congestion
FM_ALARM_CORRUPT_DATA = 9, //corrupt-data
FM_ALARM_CPU_LIMITED_EXCEEDED = 10, //cpu-cycles-limit-exceeded
FM_ALARM_DATASET_ERROR = 11, //dataset-or-modem-error
FM_ALARM_DEGRADED_SIGNAL = 12, //degraded-signal
FM_ALARM_DTE_DCE_INTERFACE_ERROR = 13, //dte-dce-interface-error
FM_ALARM_DOOR_OPEN = 14, //enclosure-door-open',
FM_ALARM_EQUIPMENT_MALFUNCTION = 15, //equipment-malfunction
FM_ALARM_EXCESSIVE_VIBRATION = 16, //excessive-vibration'
FM_ALARM_FILE_ERROR = 17, //file-error
FM_ALARM_FIRE_DETECTED = 18, //fire-detected
FM_ALARM_FLOOD_DETECTED = 19, //flood-detected
FM_ALARM_FRAMING_ERROR = 20, //framing-error
FM_ALARM_COOLING_PROBLEM = 21, //heating-ventilation-cooling-system-problem
FM_ALARM_HUMIDITY_UNACCEPTABLE = 22, //humidity-unacceptable
FM_ALARM_IO_DEVICE_ERROR = 23, //io-device-error
FM_ALARM_INPUT_DEVICE_ERROR = 24, //input-device-error
FM_ALARM_LAN_ERROR = 25, //lan-error
FM_ALARM_LEAK_DETECTED = 26, //leak-detected
FM_ALARM_LOCAL_TX_ERROR = 27, //local-node-transmission-error
FM_ALARM_LOSS_OF_FRAME = 28, //loss-of-frame
FM_ALARM_LOSS_OF_SIGNAL = 29, //loss-of-signal
FM_ALARM_MATERIAL_SUPPlY_EXHAUSTED = 30, //material-supply-exhausted
FM_ALARM_MULTIPLEXER_PROBLEM = 31, //multiplexer-problem
FM_ALARM_OUT_OF_MEMORY = 32, //out-of-memory',
FM_ALARM_OUTPUT_DEVICE_ERROR = 33, //output-device-error
FM_ALARM_PERMFORMANCE_DEGRADED = 34, //performance-degraded
FM_ALARM_POWER_PROBLEM = 35, //power-problem
FM_ALARM_PROCESSOR_PROBLEM = 36, //processor-problem
FM_ALARM_PUMP_FAILURE = 37, //pump-failure
FM_ALARM_Q_SIZE_EXCEEDED = 38, //queue-size-exceeded
FM_ALARM_RX_FAILURE = 39, //receive-failure
FM_ALARM_RXER_FAILURE = 40, //receiver-failure
FM_ALARM_REMOTE_TX_ERROR = 41, //remote-node-transmission-error
FM_ALARM_RESOURCE_NEAR_CAPACITY = 42, //resource-at-or-nearing-capacity
FM_ALARM_RESPONSE_TIME_EXCESSIVE = 43, //response-time-excessive
FM_ALARM_RETX_RATE_EXCESSIVE = 44, //retransmission-rate-excessive
FM_ALARM_SOFTWARE_ERROR = 45, //software-error
FM_ALARM_PROGRAM_TERMINATED = 46, //software-program-abnormally-terminated
FM_ALARM_PROGRAM_ERROR = 47, //software-program-error
FM_ALARM_STORAGE_PROBLEM = 48, //storage-capacity-problem
FM_ALARM_TEMP_UNACCEPTABLE = 49, //temperature-unacceptable
FM_ALARM_THRESHOLD_CROSSED = 50, //threshold-crossed
FM_ALARM_TIMING_PROBLEM = 51, //timing-problem
FM_ALARM_TOXIC_LEAK_DETECTED = 52, //toxic-leak-detected
FM_ALARM_TRANSMIT_FAILURE = 53, //transmit-failure
FM_ALARM_TRANSMITTER_FAILURE = 54, //transmitter-failure
FM_ALARM_UNDERLYING_RESOURCE_UNAVAILABLE = 55,//underlying-resource-unavailable
FM_ALARM_VERSION_MISMATCH = 56, //version-mismatch
FM_ALARM_DUPLICATE_INFO = 57, //duplicate-information
FM_ALARM_INFO_MISSING = 58, //information-missing
FM_ALARM_INFO_MODIFICATION = 59, //information-modification-detected
FM_ALARM_INFO_OUT_OF_SEQ = 60, //information-out-of-sequence
FM_ALARM_UNEXPECTED_INFO = 61, //unexpected-information
FM_ALARM_DENIAL_OF_SERVICE = 62, //denial-of-service
FM_ALARM_OUT_OF_SERVICE = 63, //out-of-service
FM_ALARM_PROCEDURAL_ERROR = 64, //procedural-error
FM_ALARM_UNSPECIFIED_REASON = 65, //unspecified-reason
FM_ALARM_CABLE_TAMPER = 66, //cable-tamper
FM_ALARM_INTRUSION_DETECTION = 67, //intrusion-detection
FM_ALARM_AUTH_FAILURE = 68, //authentication-failure
FM_ALARM_BREACH_CONFIDENT = 69, //breach-of-confidentiality
FM_ALARM_NON_REPUD_FAILURE = 70, //non-repudiation-failure
FM_ALARM_UNAUTH_ACCESS_ATTEMP = 71, //unauthorized-access-attempt
FM_ALARM_DELAYED_INFO = 72, //delayed-information
FM_ALARM_KEY_EXPIRED = 73, //key-expired
FM_ALARM_OUT_OF_HR_ACTIVITY = 74, //out-of-hours-activity
FM_ALARM_CAUSE_MAX = 75
}EFmAlarmProbableCauseT;
typedef char fm_uuid_t[FM_MAX_BUFFER_LENGTH];
typedef char fm_ent_inst_t[FM_MAX_BUFFER_LENGTH];
typedef char fm_alarm_id[FM_MAX_BUFFER_LENGTH];
typedef struct{
fm_uuid_t uuid; //generated by FM system
char alarm_id[FM_MAX_BUFFER_LENGTH]; //structured id for the fault
EFmAlarmStateT alarm_state; //state of the fault
char entity_type_id[FM_MAX_BUFFER_LENGTH];//type of the object raising fault
char entity_instance_id[FM_MAX_BUFFER_LENGTH];//instance information of the object raising fault
FMTimeT timestamp; //time in UTC at which the fault state is last updated
EFmAlarmSeverityT severity; //severity of the fault
char reason_text[FM_MAX_BUFFER_LENGTH];
EFmAlarmTypeT alarm_type;
EFmAlarmProbableCauseT probable_cause;
char proposed_repair_action[FM_MAX_BUFFER_LENGTH];
FMBoolTypeT service_affecting;
FMBoolTypeT suppression; //'allowed' or 'not-allowed'
FMBoolTypeT inhibit_alarms; //hierarchical suppression of alarms if it is set to true
}SFmAlarmDataT;
typedef enum{
FM_ERR_OK = 0,
FM_ERR_ALARM_EXISTS = 1,
FM_ERR_INVALID_ATTRIBUTE = 2,
FM_ERR_NOCONNECT=3,
FM_ERR_NOMEM=4,
FM_ERR_COMMUNICATIONS=5,
FM_ERR_NOT_ENOUGH_SPACE=6,
FM_ERR_INVALID_REQ=7,
FM_ERR_SERVER_NO_MEM=8,
FM_ERR_SCRIPT_FAILURE=9,
FM_ERR_ENTITY_NOT_FOUND = 10,
FM_ERR_DB_OPERATION_FAILURE = 11,
FM_ERR_DB_CONNECT_FAILURE = 12,
FM_ERR_INVALID_PARAMETER = 13,
FM_ERR_RESOURCE_UNAVAILABLE = 14,
FM_ERR_REQUEST_PENDING = 15,
FM_ERR_MAX
}EFmErrorT;
typedef struct {
char alarm_id[FM_MAX_BUFFER_LENGTH];
fm_ent_inst_t entity_instance_id;
}AlarmFilter ;
EFmErrorT fm_set_fault(const SFmAlarmDataT *alarm, fm_uuid_t *uuid);
EFmErrorT fm_clear_fault(AlarmFilter *filter);
EFmErrorT fm_clear_all(fm_ent_inst_t *inst_id);
EFmErrorT fm_get_fault(AlarmFilter *filter, SFmAlarmDataT *alarm);
EFmErrorT fm_get_faults(fm_ent_inst_t *inst_id, SFmAlarmDataT *alarm,
unsigned int *max_alarms_to_get);
EFmErrorT fm_get_faults_by_id(fm_alarm_id *alarm_id, SFmAlarmDataT *alarm,
unsigned int *max_alarms_to_get);
/*
* APIs that enqueue the request and return ok for acknowledgment.
* It is up to the client to query and find out whether
* the alarm is raised or cleared successfully
*/
EFmErrorT fm_set_fault_async(const SFmAlarmDataT *alarm, fm_uuid_t *uuid);
EFmErrorT fm_clear_fault_async(AlarmFilter *filter);
EFmErrorT fm_clear_all_async(fm_ent_inst_t *inst_id);
//used by fmManager
EFmErrorT fm_server_create(const char *fn) ;
#ifdef __cplusplus
}
#endif
#endif /* _FM_API_H */

View File

@ -0,0 +1,58 @@
//
// Copyright (c) 2014 Wind River Systems, Inc.
//
// SPDX-License-Identifier: Apache-2.0
//
/* This file contains CGTS alarm definitions. The alarm ids that used by
* C/C++ applications are defined here. For a completed alarm id list see
* the alarm ids that used by the Python applications defined in
* fm-api/fm_api/constants.py
*/
#ifndef _FM_ALARM_H
#define _FM_ALARM_H
/* alarm sub entity types*/
#define FM_ENTITY_TYPE_SYSTEM "system"
#define FM_ENTITY_TYPE_HOST "host"
#define FM_ENTITY_TYPE_PORT "port"
#define FM_ENTITY_TYPE_INTERFACE "interface"
#define FM_ENTITY_TYPE_DISK "disk"
#define FM_ENTITY_TYPE_SERVICE "service"
#define FM_ENTITY_TYPE_AGENT "agent"
#define FM_ENTITY_TYPE_PROVIDERNET "providernet"
#define FM_ENTITY_TYPE_INSTANCE "instance"
/* alarm_id = <Alarm Group ID>.<Alarm Event ID> */
/* <Alarm Group ID> = 000 - 999 */
/* <Alarm Event ID> = 000 999 */
#define ALARM_GROUP_GENERAL "100"
#define ALARM_GROUP_MAINTENANCE "200"
#define ALARM_GROUP_NETWORK "300"
#define ALARM_GROUP_HA "400"
#define ALARM_GROUP_SECURITY "500"
#define ALARM_GROUP_LICENSING "600"
#define ALARM_GROUP_VM "700"
#define ALARM_GROUP_STORAGE "800"
#define ALARM_GROUP_SW_MGMT "900"
/* Maintenance group alarm id */
#define FM_ALARM_ID_MTC_LOCK (ALARM_GROUP_MAINTENANCE ".001")
#define FM_ALARM_ID_MTC_CONFIG (ALARM_GROUP_MAINTENANCE ".004")
#define FM_ALARM_ID_MTC_HB (ALARM_GROUP_MAINTENANCE ".005")
#define FM_ALARM_ID_MTC_PMOND (ALARM_GROUP_MAINTENANCE ".006")
#define FM_ALARM_ID_MTC_RESMON (ALARM_GROUP_MAINTENANCE ".007")
/* HA alarm id */
#define FM_ALARM_ID_SERVICE_GROUP_STATE (ALARM_GROUP_HA ".001")
#define FM_ALARM_ID_SERVICE_GROUP_REDUNDANCY (ALARM_GROUP_HA ".002")
/* Patching alarm id */
#define FM_ALARM_ID_PATCH_IN_PROGRESS (ALARM_GROUP_SW_MGMT ".001")
#define FM_ALARM_ID_PATCH_HOST_INSTALL_FAILED (ALARM_GROUP_SW_MGMT ".002")
#define FM_ALARM_ID_PATCH_OBS_IN_SYSTEM (ALARM_GROUP_SW_MGMT ".003")
#endif /* _FM_ALARM_H */

View File

@ -0,0 +1,580 @@
//
// Copyright (c) 2014 Wind River Systems, Inc.
//
// SPDX-License-Identifier: Apache-2.0
//
#include <stdlib.h>
#include <pthread.h>
#include <map>
#include <vector>
#include <uuid/uuid.h>
#include "fmAlarmUtils.h"
#include "fmDbUtils.h"
#include "fmLog.h"
typedef std::map<int,std::string> itos_t;
typedef std::map<std::string,int> stoi_t;
typedef std::vector<std::string> strvect_t;
static pthread_mutex_t mutex = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;
static itos_t state_to_str;
static itos_t severity_to_str;
static itos_t type_to_str;
static itos_t cause_to_str;
static itos_t bool_to_str;
static itos_t err_to_str;
static stoi_t state_to_int;
static stoi_t severity_to_int;
static stoi_t type_to_int;
static stoi_t cause_to_int;
static stoi_t bool_to_int;
static stoi_t err_to_int;
#define STRCP_TO(charb,str)\
if (((str).length()==0) || \
((str).length()==1 && ((str).c_str())[0]==' ')) { \
memset(charb,0,sizeof(charb)); \
} else { \
strncpy((charb),str.c_str(),sizeof(charb)); \
}
void add_both_tables(int id, const char *str, itos_t &t1,stoi_t &t2 ) {
t1[id]=str;
t2[str]=id;
}
static void init_tables() {
pthread_mutex_lock(&mutex);
static bool has_inited=false;
while (!has_inited) {
add_both_tables(FM_ALARM_STATE_CLEAR,"clear",state_to_str,state_to_int);
add_both_tables(FM_ALARM_STATE_SET,"set",state_to_str,state_to_int);
add_both_tables(FM_ALARM_STATE_MSG,"msg",state_to_str,state_to_int);
add_both_tables(FM_ALARM_STATE_LOG,"log",state_to_str,state_to_int);
add_both_tables(FM_ALARM_SEVERITY_CLEAR,"not-applicable",severity_to_str,severity_to_int);
add_both_tables(FM_ALARM_SEVERITY_WARNING,"warning",severity_to_str,severity_to_int);
add_both_tables(FM_ALARM_SEVERITY_MINOR,"minor",severity_to_str,severity_to_int);
add_both_tables(FM_ALARM_SEVERITY_MAJOR,"major",severity_to_str,severity_to_int);
add_both_tables(FM_ALARM_SEVERITY_CRITICAL,"critical",severity_to_str,severity_to_int);
add_both_tables(FM_ALARM_TYPE_UNKNOWN,"other",type_to_str,type_to_int);
add_both_tables(FM_ALARM_COMM,"communication",type_to_str,type_to_int);
add_both_tables(FM_ALARM_QOS,"qos",type_to_str,type_to_int);
add_both_tables(FM_ALARM_PROCESSING_ERROR,"processing-error",type_to_str,type_to_int);
add_both_tables(FM_ALARM_EQUIPMENT,"equipment",type_to_str,type_to_int);
add_both_tables(FM_ALARM_ENVIRONMENTAL,"environmental",type_to_str,type_to_int);
add_both_tables(FM_ALARM_INTERGRITY,"integrity-violation",type_to_str,type_to_int);
add_both_tables(FM_ALARM_OPERATIONAL,"operational-violation",type_to_str,type_to_int);
add_both_tables(FM_ALARM_PHYSICAL,"physical-violation",type_to_str,type_to_int);
add_both_tables(FM_ALARM_SECURITY,"security-service-or-mechanism-violation",type_to_str,type_to_int);
add_both_tables(FM_ALARM_TIME,"time-domain-violation",type_to_str,type_to_int);
add_both_tables( FM_ALARM_CAUSE_UNKNOWN ,"not-applicable",cause_to_str,cause_to_int);
add_both_tables( FM_ALARM_ADAPTOR_ERROR ,"adaptor-error",cause_to_str,cause_to_int);
add_both_tables( FM_ALARM_APP_SUBSYS_FAILURE ,"application-subsystem-failure",cause_to_str,cause_to_int);
add_both_tables( FM_ALARM_BANDWIDTH_REDUCED ,"bandwidth-reduced",cause_to_str,cause_to_int);
add_both_tables( FM_ALARM_CALL_ERROR ,"call-establishment-error",cause_to_str,cause_to_int);
add_both_tables( FM_ALARM_COMM_PROTOCOL_ERROR ,"communication-protocol-error",cause_to_str,cause_to_int);
add_both_tables( FM_ALARM_COMM_SUBSYS_FAILURE ,"communication-subsystem-failure",cause_to_str,cause_to_int);
add_both_tables( FM_ALARM_CONFIG_ERROR ,"configuration-or-customization-error",cause_to_str,cause_to_int);
add_both_tables( FM_ALARM_CONGESTION ,"congestion",cause_to_str,cause_to_int);
add_both_tables( FM_ALARM_CORRUPT_DATA ,"corrupt-data",cause_to_str,cause_to_int);
add_both_tables( FM_ALARM_CPU_LIMITED_EXCEEDED ,"cpu-cycles-limit-exceeded",cause_to_str,cause_to_int);
add_both_tables( FM_ALARM_DATASET_ERROR ,"dataset-or-modem-error",cause_to_str,cause_to_int);
add_both_tables( FM_ALARM_DEGRADED_SIGNAL ,"degraded-signal",cause_to_str,cause_to_int);
add_both_tables( FM_ALARM_DTE_DCE_INTERFACE_ERROR ,"dte-dce-interface-error",cause_to_str,cause_to_int);
add_both_tables( FM_ALARM_DOOR_OPEN ,"enclosure-door-open",cause_to_str,cause_to_int);
add_both_tables( FM_ALARM_EQUIPMENT_MALFUNCTION ,"equipment-malfunction",cause_to_str,cause_to_int);
add_both_tables( FM_ALARM_EXCESSIVE_VIBRATION ,"excessive-vibration'",cause_to_str,cause_to_int);
add_both_tables( FM_ALARM_FILE_ERROR ,"file-error",cause_to_str,cause_to_int);
add_both_tables( FM_ALARM_FIRE_DETECTED ,"fire-detected",cause_to_str,cause_to_int);
add_both_tables( FM_ALARM_FLOOD_DETECTED ,"flood-detected",cause_to_str,cause_to_int);
add_both_tables( FM_ALARM_FRAMING_ERROR ,"framing-error",cause_to_str,cause_to_int);
add_both_tables( FM_ALARM_COOLING_PROBLEM ,"heating-ventilation-cooling-system-problem",cause_to_str,cause_to_int);
add_both_tables( FM_ALARM_HUMIDITY_UNACCEPTABLE ,"humidity-unacceptable",cause_to_str,cause_to_int);
add_both_tables( FM_ALARM_IO_DEVICE_ERROR ,"io-device-error",cause_to_str,cause_to_int);
add_both_tables( FM_ALARM_INPUT_DEVICE_ERROR ,"input-device-error",cause_to_str,cause_to_int);
add_both_tables( FM_ALARM_LAN_ERROR ,"lan-error",cause_to_str,cause_to_int);
add_both_tables( FM_ALARM_LEAK_DETECTED ,"leak-detected",cause_to_str,cause_to_int);
add_both_tables( FM_ALARM_LOCAL_TX_ERROR ,"local-node-transmission-error",cause_to_str,cause_to_int);
add_both_tables( FM_ALARM_LOSS_OF_FRAME ,"loss-of-frame",cause_to_str,cause_to_int);
add_both_tables( FM_ALARM_LOSS_OF_SIGNAL ,"loss-of-signal",cause_to_str,cause_to_int);
add_both_tables( FM_ALARM_MATERIAL_SUPPlY_EXHAUSTED ,"material-supply-exhausted",cause_to_str,cause_to_int);
add_both_tables( FM_ALARM_MULTIPLEXER_PROBLEM ,"multiplexer-problem",cause_to_str,cause_to_int);
add_both_tables( FM_ALARM_OUT_OF_MEMORY ,"out-of-memory",cause_to_str,cause_to_int);
add_both_tables( FM_ALARM_OUTPUT_DEVICE_ERROR ,"output-device-error",cause_to_str,cause_to_int);
add_both_tables( FM_ALARM_PERMFORMANCE_DEGRADED ,"performance-degraded",cause_to_str,cause_to_int);
add_both_tables( FM_ALARM_POWER_PROBLEM ,"power-problem",cause_to_str,cause_to_int);
add_both_tables( FM_ALARM_PROCESSOR_PROBLEM ,"processor-problem",cause_to_str,cause_to_int);
add_both_tables( FM_ALARM_PUMP_FAILURE ,"pump-failure",cause_to_str,cause_to_int);
add_both_tables( FM_ALARM_Q_SIZE_EXCEEDED ,"queue-size-exceeded",cause_to_str,cause_to_int);
add_both_tables( FM_ALARM_RX_FAILURE ,"receive-failure",cause_to_str,cause_to_int);
add_both_tables( FM_ALARM_RXER_FAILURE ,"receiver-failure",cause_to_str,cause_to_int);
add_both_tables( FM_ALARM_REMOTE_TX_ERROR ,"remote-node-transmission-error",cause_to_str,cause_to_int);
add_both_tables( FM_ALARM_RESOURCE_NEAR_CAPACITY ,"resource-at-or-nearing-capacity",cause_to_str,cause_to_int);
add_both_tables( FM_ALARM_RESPONSE_TIME_EXCESSIVE ,"response-time-excessive",cause_to_str,cause_to_int);
add_both_tables( FM_ALARM_RETX_RATE_EXCESSIVE ,"retransmission-rate-excessive",cause_to_str,cause_to_int);
add_both_tables( FM_ALARM_SOFTWARE_ERROR ,"software-error",cause_to_str,cause_to_int);
add_both_tables( FM_ALARM_PROGRAM_TERMINATED ,"software-program-abnormally-terminated",cause_to_str,cause_to_int);
add_both_tables( FM_ALARM_PROGRAM_ERROR ,"software-program-error",cause_to_str,cause_to_int);
add_both_tables( FM_ALARM_STORAGE_PROBLEM ,"storage-capacity-problem",cause_to_str,cause_to_int);
add_both_tables( FM_ALARM_TEMP_UNACCEPTABLE ,"temperature-unacceptable",cause_to_str,cause_to_int);
add_both_tables( FM_ALARM_THRESHOLD_CROSSED ,"threshold-crossed",cause_to_str,cause_to_int);
add_both_tables( FM_ALARM_TIMING_PROBLEM ,"timing-problem",cause_to_str,cause_to_int);
add_both_tables( FM_ALARM_TOXIC_LEAK_DETECTED ,"toxic-leak-detected",cause_to_str,cause_to_int);
add_both_tables( FM_ALARM_TRANSMIT_FAILURE ,"transmit-failure",cause_to_str,cause_to_int);
add_both_tables( FM_ALARM_TRANSMITTER_FAILURE ,"transmitter-failure",cause_to_str,cause_to_int);
add_both_tables( FM_ALARM_UNDERLYING_RESOURCE_UNAVAILABLE ,"underlying-resource-unavailable",cause_to_str,cause_to_int);
add_both_tables( FM_ALARM_VERSION_MISMATCH ,"version-mismatch",cause_to_str,cause_to_int);
add_both_tables( FM_ALARM_DUPLICATE_INFO ,"duplicate-information",cause_to_str,cause_to_int);
add_both_tables( FM_ALARM_INFO_MISSING ,"information-missing",cause_to_str,cause_to_int);
add_both_tables( FM_ALARM_INFO_MODIFICATION ,"information-modification-detected",cause_to_str,cause_to_int);
add_both_tables( FM_ALARM_INFO_OUT_OF_SEQ ,"information-out-of-sequence",cause_to_str,cause_to_int);
add_both_tables( FM_ALARM_UNEXPECTED_INFO ,"unexpected-information",cause_to_str,cause_to_int);
add_both_tables( FM_ALARM_DENIAL_OF_SERVICE ,"denial-of-service",cause_to_str,cause_to_int);
add_both_tables( FM_ALARM_OUT_OF_SERVICE ,"out-of-service",cause_to_str,cause_to_int);
add_both_tables( FM_ALARM_PROCEDURAL_ERROR ,"procedural-error",cause_to_str,cause_to_int);
add_both_tables( FM_ALARM_UNSPECIFIED_REASON ,"unspecified-reason",cause_to_str,cause_to_int);
add_both_tables( FM_ALARM_CABLE_TAMPER ,"cable-tamper",cause_to_str,cause_to_int);
add_both_tables( FM_ALARM_INTRUSION_DETECTION ,"intrusion-detection",cause_to_str,cause_to_int);
add_both_tables( FM_ALARM_AUTH_FAILURE ,"authentication-failure",cause_to_str,cause_to_int);
add_both_tables( FM_ALARM_BREACH_CONFIDENT ,"breach-of-confidentiality",cause_to_str,cause_to_int);
add_both_tables( FM_ALARM_NON_REPUD_FAILURE ,"non-repudiation-failure",cause_to_str,cause_to_int);
add_both_tables( FM_ALARM_UNAUTH_ACCESS_ATTEMP ,"unauthorized-access-attempt",cause_to_str,cause_to_int);
add_both_tables( FM_ALARM_DELAYED_INFO ,"delayed-information",cause_to_str,cause_to_int);
add_both_tables( FM_ALARM_KEY_EXPIRED ,"key-expired",cause_to_str,cause_to_int);
add_both_tables( FM_ALARM_OUT_OF_HR_ACTIVITY ,"out-of-hours-activity",cause_to_str,cause_to_int);
add_both_tables( FM_ERR_OK, "Ok", err_to_str, err_to_int);
add_both_tables( FM_ERR_ALARM_EXISTS, "FM_ERR_ALARM_EXISTS", err_to_str, err_to_int);
add_both_tables( FM_ERR_INVALID_ATTRIBUTE, "FM_ERR_INVALID_ATTRIBUTE", err_to_str, err_to_int);
add_both_tables( FM_ERR_ENTITY_NOT_FOUND, "FM_ERR_ENTITY_NOT_FOUND", err_to_str, err_to_int);
add_both_tables( FM_ERR_DB_OPERATION_FAILURE, "FM_ERR_DB_OPERATION_FAILURE", err_to_str, err_to_int);
add_both_tables( FM_ERR_SCRIPT_FAILURE, "FM_ERR_SCRIPT_FAILURE",err_to_str, err_to_int);
add_both_tables( FM_ERR_NOCONNECT, "FM_ERR_NOCONNECT", err_to_str, err_to_int);
add_both_tables( FM_ERR_NOMEM, "FM_ERR_NOMEM", err_to_str, err_to_int);
add_both_tables( FM_ERR_COMMUNICATIONS, "FM_ERR_COMMUNICATIONS", err_to_str, err_to_int);
add_both_tables( FM_ERR_NOT_ENOUGH_SPACE, "FM_ERR_NOT_ENOUGH_SPACE", err_to_str, err_to_int);
add_both_tables( FM_ERR_INVALID_REQ, "FM_ERR_INVALID_REQ", err_to_str, err_to_int);
add_both_tables( FM_ERR_SERVER_NO_MEM, "FM_ERR_SERVER_NO_MEM", err_to_str, err_to_int);
add_both_tables( FM_ERR_INVALID_PARAMETER, "FM_ERR_INVALID_PARAMETER",err_to_str, err_to_int);
add_both_tables( FM_ERR_RESOURCE_UNAVAILABLE, "FM_ERR_RESOURCE_UNAVAILABLE",err_to_str, err_to_int);
add_both_tables( 0 ,"False",bool_to_str,bool_to_int);
add_both_tables( 1 ,"True",bool_to_str,bool_to_int);
has_inited=true;
}
pthread_mutex_unlock(&mutex);
}
static void add_s(std::string &s) { s+="###"; };
static std::string tostr(int id, const itos_t &t ){
itos_t::const_iterator it = t.find(id);
if (it!=t.end()) return it->second;
return "unknown";
}
static int toint(const std::string &s, const stoi_t &t) {
stoi_t::const_iterator it = t.find(s);
if (it!=t.end()) return it->second ;
return 0;
}
static std::string chkstr(const std::string &s) {
if (s.length()==0) return " ";
return s;
}
static void str_to_vector(const std::string &s, std::vector<std::string> &alarm) {
size_t offset = 0;
alarm.clear();
while (true) {
size_t beg = (offset==0) ? 0 : s.find("###",offset);
if (beg==std::string::npos) break;
size_t e = s.find("###",beg+3);
std::string cont = s.substr(beg+3,e-(beg+3));
alarm.push_back(cont);
offset=e;
}
}
static void fm_set_uuid(SFmAlarmDataT *a, std::string &s, bool is_get) {
if(is_get) s = chkstr(a->uuid);
else STRCP_TO(a->uuid,s);
}
static void fm_tr_alarm_id(SFmAlarmDataT *a, std::string &s, bool is_get) {
if(is_get) s = chkstr(a->alarm_id);
else STRCP_TO(a->alarm_id,s);
}
static void fm_alarm_state(SFmAlarmDataT *a, std::string &s, bool is_get) {
if(is_get) s = tostr(a->alarm_state,state_to_str);
else a->alarm_state = (EFmAlarmStateT)toint(s,state_to_int);
}
static void fm_entity_id(SFmAlarmDataT *a, std::string &s, bool is_get) {
if(is_get) s = chkstr(a->entity_type_id);
else STRCP_TO(a->entity_type_id,s);
}
static void fm_instance_id(SFmAlarmDataT *a, std::string &s, bool is_get) {
if(is_get) s = chkstr(a->entity_instance_id);
else STRCP_TO(a->entity_instance_id,s);
}
static void fm_timestamp(SFmAlarmDataT *a, std::string &s, bool is_get) {
if(is_get) {
fm_db_util_make_timestamp_string(s, a->timestamp);
} else {
fm_db_util_get_timestamp(s.c_str(), a->timestamp);
}
}
static void fm_alarm_severity(SFmAlarmDataT *a, std::string &s, bool is_get) {
if(is_get) s = tostr(a->severity,severity_to_str);
else a->severity = (EFmAlarmSeverityT)toint(s,severity_to_int);
}
static void fm_reason_text(SFmAlarmDataT *a, std::string &s, bool is_get) {
if(is_get) s = chkstr(a->reason_text);
else STRCP_TO(a->reason_text,s);
}
static void fm_alarm_type(SFmAlarmDataT *a, std::string &s, bool is_get) {
if(is_get) s =tostr(a->alarm_type,type_to_str);
else a->alarm_type = (EFmAlarmTypeT)toint(s,type_to_int);
}
static void fm_prop_cause(SFmAlarmDataT *a, std::string &s, bool is_get) {
if(is_get) s = tostr(a->probable_cause,cause_to_str);
else a->probable_cause = (EFmAlarmProbableCauseT)toint(s,cause_to_int);
}
static void fm_repair(SFmAlarmDataT *a, std::string &s, bool is_get) {
if(is_get) s = chkstr(a->proposed_repair_action);
else STRCP_TO(a->proposed_repair_action,s);
}
static void fm_service_affect(SFmAlarmDataT *a, std::string &s, bool is_get) {
if(is_get) s = tostr(a->service_affecting,bool_to_str);
else a->service_affecting = (((s == "t") || (s == "True"))? 1 :0);
}
static void fm_suppression(SFmAlarmDataT *a, std::string &s, bool is_get) {
if(is_get) s = tostr(a->suppression,bool_to_str);
else a->suppression = (((s == "t") || (s == "True"))? 1 :0);
}
static void fm_inhibit_alarm(SFmAlarmDataT *a, std::string &s, bool is_get) {
if(is_get) s = tostr(a->inhibit_alarms,bool_to_str);
else a->inhibit_alarms = (((s == "t") || (s == "True"))? 1 :0);
}
typedef void (*set_get_field_type)(SFmAlarmDataT *a, std::string &s, bool is_get);
struct alarm_struct_update_t{
EFmAlarmIndexMap id;
set_get_field_type func;
} fm_alarm_convert_func [] = {
{ FM_ALM_IX_UUID, fm_set_uuid },
{ FM_ALM_IX_ALARM_ID, fm_tr_alarm_id },
{ FM_ALM_IX_ALARM_STATE, fm_alarm_state },
{ FM_ALM_IX_ENTITY_ID, fm_entity_id },
{ FM_ALM_IX_INSTANCE_ID, fm_instance_id },
{ FM_ALM_IX_TIMESTAMP, fm_timestamp },
{ FM_ALM_IX_SEVERITY, fm_alarm_severity },
{ FM_ALM_IX_REASON, fm_reason_text },
{ FM_ALM_IX_ALARM_TYPE, fm_alarm_type },
{ FM_ALM_IX_PROBABLE_CAUSE, fm_prop_cause },
{ FM_ALM_IX_REPAIR_ACTION, fm_repair },
{ FM_ALM_IX_SERVICE_AFFECT, fm_service_affect },
{ FM_ALM_IX_SUPPRESSION, fm_suppression },
{ FM_ALM_IX_INHIBIT_ALARM, fm_inhibit_alarm }
};
static set_get_field_type find_func_set_get(EFmAlarmIndexMap id) {
size_t ix = 0;
size_t mx = sizeof (fm_alarm_convert_func)/sizeof(*fm_alarm_convert_func);
for ( ; ix < mx ; ++ix ) {
if (fm_alarm_convert_func[ix].id==id)
return fm_alarm_convert_func[ix].func;
}
return NULL;
}
bool fm_alarm_set_field(EFmAlarmIndexMap field, SFmAlarmDataT *a, std::string &val) {
init_tables();
set_get_field_type p = find_func_set_get(field);
if (p==NULL) return false;
p(a,val,false);
return true;
}
struct log_struct_update_t{
EFmLogIndexMap id;
set_get_field_type func;
} fm_log_convert_func [] = {
{ FM_LOG_IX_UUID, fm_set_uuid },
{ FM_LOG_IX_LOG_ID, fm_tr_alarm_id },
{ FM_LOG_IX_ENTITY_ID, fm_entity_id },
{ FM_LOG_IX_INSTANCE_ID, fm_instance_id },
{ FM_LOG_IX_TIMESTAMP, fm_timestamp },
{ FM_LOG_IX_SEVERITY, fm_alarm_severity },
{ FM_LOG_IX_REASON, fm_reason_text },
{ FM_LOG_IX_LOG_TYPE, fm_alarm_type },
{ FM_LOG_IX_PROBABLE_CAUSE, fm_prop_cause },
{ FM_LOG_IX_SERVICE_AFFECT, fm_service_affect }
};
static set_get_field_type fm_log_find_func_set_get(EFmLogIndexMap id) {
size_t ix = 0;
size_t mx = sizeof (fm_log_convert_func)/sizeof(*fm_log_convert_func);
for ( ; ix < mx ; ++ix ) {
if (fm_log_convert_func[ix].id==id)
return fm_log_convert_func[ix].func;
}
return NULL;
}
bool fm_log_set_field(EFmLogIndexMap field, SFmAlarmDataT *a, std::string &val) {
init_tables();
set_get_field_type p = fm_log_find_func_set_get(field);
if (p==NULL) return false;
p(a,val,false);
return true;
}
struct event_log_struct_update_t{
EFmEventLogIndexMap id;
set_get_field_type func;
} fm_event_log_convert_func [] = {
{ FM_EVENT_LOG_IX_UUID, fm_set_uuid },
{ FM_EVENT_LOG_IX_EVENT_ID, fm_tr_alarm_id },
{ FM_EVENT_LOG_IX_STATE, fm_alarm_state },
{ FM_EVENT_LOG_IX_ENTITY_ID, fm_entity_id },
{ FM_EVENT_LOG_IX_INSTANCE_ID, fm_instance_id },
{ FM_EVENT_LOG_IX_TIMESTAMP, fm_timestamp },
{ FM_EVENT_LOG_IX_SEVERITY, fm_alarm_severity },
{ FM_EVENT_LOG_IX_REASON, fm_reason_text },
{ FM_EVENT_LOG_IX_EVENT_TYPE, fm_alarm_type },
{ FM_EVENT_LOG_IX_PROBABLE_CAUSE, fm_prop_cause },
{ FM_EVENT_LOG_IX_REPAIR_ACTION, fm_repair },
{ FM_EVENT_LOG_IX_SERVICE_AFFECT, fm_service_affect },
{ FM_EVENT_LOG_IX_SUPPRESSION, fm_suppression }
};
static set_get_field_type fm_event_log_find_func_set_get(EFmEventLogIndexMap id) {
size_t ix = 0;
size_t mx = sizeof (fm_event_log_convert_func)/sizeof(*fm_event_log_convert_func);
for ( ; ix < mx ; ++ix ) {
if (fm_event_log_convert_func[ix].id==id)
return fm_event_log_convert_func[ix].func;
}
return NULL;
}
bool fm_event_log_set_field(EFmEventLogIndexMap field, SFmAlarmDataT *a, std::string &val) {
init_tables();
set_get_field_type p = fm_event_log_find_func_set_get(field);
if (p==NULL) return false;
p(a,val,false);
return true;
}
bool fm_alarm_get_field(EFmAlarmIndexMap field, const SFmAlarmDataT *a, std::string &val) {
init_tables();
set_get_field_type p = find_func_set_get(field);
if (p==NULL) return false;
p((SFmAlarmDataT*)a,val,true);
return true;
}
static std::string fm_alarm_to_string(const SFmAlarmDataT *a) {
std::string s;
size_t ix = 0;
size_t mx = FM_ALM_IX_INHIBIT_ALARM ;
std::string field;
for ( ; ix <= mx ; ++ix ) {
fm_alarm_get_field(((EFmAlarmIndexMap)ix),a,field);
s+=field;
add_s(s);
}
return s;
}
void fm_alarm_to_list(const SFmAlarmDataT *a, std::vector<std::string> &list) {
size_t ix = 0;
size_t mx = FM_ALM_IX_INHIBIT_ALARM ;
std::string field;
for ( ; ix <= mx ; ++ix ) {
fm_alarm_get_field(((EFmAlarmIndexMap)ix),a,field);
list.push_back(field);
}
}
void fm_formatted_str_to_vector(const std::string &s, std::vector<std::string> &alarm) {
str_to_vector(s,alarm);
}
/**
* public APIs
*/
EFmErrorT fm_error_from_string(const std::string &str){
return (EFmErrorT)toint(str,err_to_int);
}
std::string fm_error_from_int(EFmErrorT id){
return tostr((int)id,err_to_str);
}
bool fm_alarm_filter_to_string(const AlarmFilter *filter, std::string &str) {
init_tables();
str+= chkstr(filter->alarm_id);
add_s(str);
str+= chkstr(filter->entity_instance_id);
add_s(str);
return true;
}
bool fm_alarm_filter_from_string(const std::string &str, AlarmFilter *filter) {
strvect_t s;
str_to_vector(str,s);
if (s.size()<2) {
FM_ERROR_LOG("Alarm filter wrong format: %s",str.c_str());
return false;
}
init_tables();
STRCP_TO(filter->alarm_id,s[0]);
STRCP_TO(filter->entity_instance_id,s[1]);
return true;
}
bool fm_alarm_to_string(const SFmAlarmDataT *alarm, std::string &str) {
init_tables();
str+= fm_alarm_to_string(alarm);
return str.size()>0;
}
bool fm_alarm_from_string(const std::string &alstr,SFmAlarmDataT *a) {
strvect_t s;
str_to_vector(alstr, s);
if (s.size()<(FM_ALM_IX_MAX)) { //includes adjustment for last entry + 1 (for starting at 0)
return false;
}
init_tables();
size_t ix = 0;
size_t mx = s.size();
for ( ; ix < mx ; ++ix ) {
fm_alarm_set_field((EFmAlarmIndexMap)ix,a,s[ix]);
}
return true;
}
void fm_uuid_create(fm_uuid_t &uuid){
uuid_t uu;
memset(uuid, 0, sizeof(uuid));
uuid_generate(uu);
uuid_unparse_lower(uu, uuid);
}
void fm_log_request(fm_buff_t &req, bool failed){
SFmMsgHdrT *hdr = ptr_to_hdr(req);
std::string description;
if (failed) {
description.assign("Failed to send FM");
} else {
description.assign("Sending FM");
}
switch(hdr->action) {
case EFmCreateFault: {
SFmAlarmDataT *data = (SFmAlarmDataT * )ptr_to_data(req);
FM_INFO_LOG("%s raise alarm request: alarm_id (%s), entity_id (%s)",
description.c_str(), data->alarm_id, data->entity_instance_id);
}
break;
case EFmDeleteFault: {
AlarmFilter *filter = (AlarmFilter * )ptr_to_data(req);
FM_INFO_LOG("%s clear alarm request: alarm_id (%s), entity_id (%s)",
description.c_str(), filter->alarm_id, filter->entity_instance_id);
}
break;
case EFmDeleteFaults: {
fm_ent_inst_t *entity_id = (fm_ent_inst_t*)ptr_to_data(req);
fm_ent_inst_t &eid = *entity_id;
FM_INFO_LOG("%s clear all request: entity_id (%s)", description.c_str(), eid);
}
break;
default:
FM_ERROR_LOG("Unexpected API action:%u\n", hdr->action);
break;
}
}
void fm_log_response(fm_buff_t &req, fm_buff_t &resp, bool failed){
SFmMsgHdrT *hdr = ptr_to_hdr(req);
SFmMsgHdrT *resp_hdr = ptr_to_hdr(resp);
switch(hdr->action) {
case EFmCreateFault: {
SFmAlarmDataT *data = (SFmAlarmDataT * )ptr_to_data(req);
if (failed) {
FM_WARNING_LOG("Failed to get response for FM raise alarm: alarm_id (%s), entity_id (%s)",
data->alarm_id, data->entity_instance_id);
} else {
FM_INFO_LOG("FM Response for raise alarm: (%d), alarm_id (%s), entity_id (%s)",
resp_hdr->msg_rc, data->alarm_id, data->entity_instance_id);
}
}
break;
case EFmDeleteFault: {
AlarmFilter *filter = (AlarmFilter * )ptr_to_data(req);
if (failed) {
FM_WARNING_LOG("Failed to get response for FM clear alarm: alarm_id (%s), entity_id (%s)",
filter->alarm_id, filter->entity_instance_id);
} else {
FM_INFO_LOG("FM Response for clear alarm: (%d), alarm_id (%s), entity_id (%s)",
resp_hdr->msg_rc, filter->alarm_id, filter->entity_instance_id);
}
}
break;
case EFmDeleteFaults: {
fm_ent_inst_t *entity_id = (fm_ent_inst_t*)ptr_to_data(req);
fm_ent_inst_t &eid = *entity_id;
if (failed) {
FM_WARNING_LOG("Failed to get response for FM clear all: entity_id (%s)", eid);
} else {
FM_INFO_LOG("FM Response for clear all: (%d), entity_id (%s)",
resp_hdr->msg_rc, eid);
}
}
break;
default:
FM_ERROR_LOG("Unexpected API action:%u\n", hdr->action);
break;
}
}

View File

@ -0,0 +1,99 @@
//
// Copyright (c) 2014 Wind River Systems, Inc.
//
// SPDX-License-Identifier: Apache-2.0
//
#ifndef FMALARMUTILS_H_
#define FMALARMUTILS_H_
#include "fmAPI.h"
#include "fmMsg.h"
#include <string>
#include <vector>
enum EFmAlarmIndexMap {
FM_ALM_IX_UUID=0,
FM_ALM_IX_ALARM_ID,
FM_ALM_IX_ALARM_STATE,
FM_ALM_IX_ENTITY_ID,
FM_ALM_IX_INSTANCE_ID,
FM_ALM_IX_TIMESTAMP,
FM_ALM_IX_SEVERITY,
FM_ALM_IX_REASON,
FM_ALM_IX_ALARM_TYPE,
FM_ALM_IX_PROBABLE_CAUSE,
FM_ALM_IX_REPAIR_ACTION,
FM_ALM_IX_SERVICE_AFFECT,
FM_ALM_IX_SUPPRESSION,
FM_ALM_IX_INHIBIT_ALARM,
FM_ALM_IX_MAX
};
enum EFmLogIndexMap {
FM_LOG_IX_UUID=0,
FM_LOG_IX_LOG_ID,
FM_LOG_IX_ENTITY_ID,
FM_LOG_IX_INSTANCE_ID,
FM_LOG_IX_TIMESTAMP,
FM_LOG_IX_SEVERITY,
FM_LOG_IX_REASON,
FM_LOG_IX_LOG_TYPE,
FM_LOG_IX_PROBABLE_CAUSE,
FM_LOG_IX_SERVICE_AFFECT,
FM_LOG_IX_MAX
};
enum EFmEventLogIndexMap {
FM_EVENT_LOG_IX_UUID=0,
FM_EVENT_LOG_IX_EVENT_ID,
FM_EVENT_LOG_IX_STATE,
FM_EVENT_LOG_IX_ENTITY_ID,
FM_EVENT_LOG_IX_INSTANCE_ID,
FM_EVENT_LOG_IX_TIMESTAMP,
FM_EVENT_LOG_IX_SEVERITY,
FM_EVENT_LOG_IX_REASON,
FM_EVENT_LOG_IX_EVENT_TYPE,
FM_EVENT_LOG_IX_PROBABLE_CAUSE,
FM_EVENT_LOG_IX_REPAIR_ACTION,
FM_EVENT_LOG_IX_SERVICE_AFFECT,
FM_EVENT_LOG_IX_SUPPRESSION,
FM_EVENT_LOG_IX_MAX
};
bool fm_alarm_set_field(EFmAlarmIndexMap field, SFmAlarmDataT *a, std::string &val);
bool fm_alarm_get_field(EFmAlarmIndexMap field, const SFmAlarmDataT *a, std::string &val);
bool fm_log_set_field(EFmLogIndexMap field, SFmAlarmDataT *a, std::string &val);
bool fm_event_log_set_field(EFmEventLogIndexMap field, SFmAlarmDataT *a, std::string &val);
void fm_formatted_str_to_vector(const std::string &s, std::vector<std::string> &alarm);
bool fm_alarm_to_string(const SFmAlarmDataT *alarm, std::string &str);
bool fm_alarm_from_string(const std::string &str,SFmAlarmDataT *alarm);
/**
* This will create an alarm list from an alarm - will translate to string.
* The indexes of this API are based on EFmAlarmIndexMap
*/
void fm_alarm_to_list(const SFmAlarmDataT *a, std::vector<std::string> &list);
bool fm_alarm_filter_to_string(const AlarmFilter *alarm, std::string &str);
bool fm_alarm_filter_from_string(const std::string &str, AlarmFilter *alarm);
/**
* Generate a FM UUID
*/
void fm_uuid_create(fm_uuid_t &uuid);
/**
* General utilities to conver alarm fields to and from strings
*/
EFmErrorT fm_error_from_string(const std::string &str);
std::string fm_error_from_int(EFmErrorT id);
void fm_log_request(fm_buff_t &req, bool failed=false);
void fm_log_response(fm_buff_t &req, fm_buff_t &resp, bool failed=false);
#endif /* FMALARMUTILS_H_ */

199
fm-common/sources/fmDb.cpp Normal file
View File

@ -0,0 +1,199 @@
//
// Copyright (c) 2016 Wind River Systems, Inc.
//
// SPDX-License-Identifier: Apache-2.0
//
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <time.h>
#include <unistd.h>
#include "fmLog.h"
#include "fmAPI.h"
#include "fmTime.h"
#include "fmAlarmUtils.h"
#include "fmDbUtils.h"
#include "fmDb.h"
#include "fmDbConstants.h"
#include "fmThread.h"
CFmDBSession::CFmDBSession() {
m_conn.uri = NULL;
m_conn.pgconn = NULL;
m_conn.status = DB_DISCONNECTED;
}
CFmDBSession::~CFmDBSession() {
if (m_conn.pgconn != NULL){
PQfinish(m_conn.pgconn);
}
}
bool CFmDBSession::connect(const char *uri){
const char *val = NULL;
PGconn *pgconn = NULL;
size_t retries = 30, count = 0, my_sleep = 2; //2 seconds
while (count < retries){
/* Make a connection to the database */
pgconn = PQconnectdb(uri);
/* Check to see that the backend connection was successfully made */
if ((pgconn == NULL) || (PQstatus(pgconn) != CONNECTION_OK)){
FM_INFO_LOG("failed to connected to DB: (%s), retry (%d of %d) ",
uri, count+1, retries);
if (pgconn != NULL) {
FM_INFO_LOG("Postgress error message: (%s).", PQerrorMessage(pgconn));
PQfinish(pgconn);
}
sleep(my_sleep);
count++;
}else {
break;
}
}
if (count == retries) return false;
m_conn.status = DB_CONNECTED;
m_conn.pgconn = pgconn;
m_conn.uri = uri;
val = get_parameter_status("standard_conforming_strings");
//FM_INFO_LOG("connect: server standard_conforming_strings parameter: %s",
// val ? val : "unavailable");
m_conn.equote = (val && (0 == strcmp("off", val)));
//FM_INFO_LOG("connect: server requires E'' quotes: %s", m_conn.equote ? "YES" : "NO");
m_conn.server_version = PQserverVersion(m_conn.pgconn);
m_conn.protocol = PQprotocolVersion(m_conn.pgconn);
m_conn.encoding = get_parameter_status("client_encoding");
return true;
}
bool CFmDBSession::check_conn(){
if (PQstatus(m_conn.pgconn) != CONNECTION_OK) {
FM_ERROR_LOG("DB connection NOT OK\n");
disconnect();
return connect(m_conn.uri);
}
return true;
}
void CFmDBSession::disconnect(){
if (m_conn.pgconn != NULL){
PQfinish(m_conn.pgconn);
}
if (m_conn.status == DB_CONNECTED){
m_conn.status = DB_DISCONNECTED;
}
}
const char * CFmDBSession::get_parameter_status(const char *param){
return PQparameterStatus(m_conn.pgconn, param);
}
bool CFmDBSession::query(const char *db_cmd,fm_db_result_t & result) {
PGresult *res;
int nfields, ntuples, i, j;
if (check_conn() == false){
FM_ERROR_LOG("Failed to reconnect: %s", PQerrorMessage(m_conn.pgconn));
return false;
}
res = PQexec(m_conn.pgconn, db_cmd);
if (PQresultStatus(res) != PGRES_TUPLES_OK){
FM_ERROR_LOG("Status:(%s)\n", PQresStatus(PQresultStatus(res)));
FM_ERROR_LOG("Failed to execute (%s) (%s)", db_cmd, PQresultErrorMessage(res));
PQclear(res);
return false;
}
nfields = PQnfields(res);
ntuples = PQntuples(res);
FM_DEBUG_LOG("Execute cmd:(%s) OK, entries found: (%u)\n", db_cmd, ntuples);
for (i = 0; i < ntuples; ++i){
fm_db_single_result_t single_result;
for (j =0; j < nfields; ++j){
char * key = PQfname(res, j);
char * value = PQgetvalue(res, i, j);
single_result[key] = value;
}
result.push_back(single_result);
}
PQclear(res);
return true;
}
bool CFmDBSession::cmd(const char *db_cmd){
PGresult *res;
bool rc = true;
if (check_conn() == false){
FM_ERROR_LOG("Failed to reconnect: %s", PQerrorMessage(m_conn.pgconn));
return false;
}
res = PQexec(m_conn.pgconn, db_cmd);
if (PQresultStatus(res) != PGRES_COMMAND_OK) {
FM_ERROR_LOG("Status:(%s)\n", PQresStatus(PQresultStatus(res)));
FM_ERROR_LOG("Failed to execute (%s) (%s)", db_cmd, PQresultErrorMessage(res));
rc = false;
}
if (rc){
int row = atoi(PQcmdTuples(res));
FM_DEBUG_LOG("SQL command returned successful: %d rows affected.\n", row);
if (row < 1) rc = false;
}
PQclear(res);
return rc;
}
bool CFmDBSession::params_cmd(fm_db_util_sql_params & sql_params){
PGresult *res, *last_res;
bool rc = true;
if (check_conn() == false){
FM_ERROR_LOG("Failed to reconnect: %s", PQerrorMessage(m_conn.pgconn));
return false;
}
res = PQexecParams(m_conn.pgconn, sql_params.db_cmd.c_str(), sql_params.n_params,
NULL,(const char* const*)&(sql_params.param_values[0]),
(const int*)&(sql_params.param_lengths[0]), (const int*)&(sql_params.param_format[0]), 1);
if (PQresultStatus(res) != PGRES_COMMAND_OK) {
FM_ERROR_LOG("Status:(%s)\n", PQresStatus(PQresultStatus(res)));
FM_ERROR_LOG("Failed to execute (%s) (%s)", sql_params.db_cmd.c_str(),
PQresultErrorMessage(res));
rc = false;
}
if (rc){
while ((last_res=PQgetResult(m_conn.pgconn)) != NULL){
if (PQstatus(m_conn.pgconn) == CONNECTION_BAD){
FM_INFO_LOG("POSTGRES DB connection is bad.");
PQclear(last_res);
break;
}
FM_INFO_LOG("Waiting for POSTGRES command to finish: (%d)", PQresultStatus(last_res));
PQclear(last_res);
fmThreadSleep(10);
}
int row = atoi(PQcmdTuples(res));
FM_DEBUG_LOG("SQL command returned successful: %d rows affected.", row);
if (row < 1) {
rc = false;
FM_ERROR_LOG("SQL command returned successful, but no row affected.");
}
}
PQclear(res);
return rc;
}

67
fm-common/sources/fmDb.h Normal file
View File

@ -0,0 +1,67 @@
//
// Copyright (c) 2014 Wind River Systems, Inc.
//
// SPDX-License-Identifier: Apache-2.0
//
#ifndef FMDB_H_
#define FMDB_H_
#include "fmAPI.h"
#include <libpq-fe.h>
#include <string>
#include <vector>
#include <map>
struct fm_db_util_sql_params {
int id;
int n_params;
std::string db_cmd;
std::vector<const char*> param_values;
std::vector<int> param_lengths;
std::vector<int> param_format;
std::map<std::string,bool> scratch;
};
typedef std::map<std::string,std::string> fm_db_single_result_t;
typedef std::vector<fm_db_single_result_t> fm_db_result_t;
typedef struct{
const char *uri; /* Connection URI */
int status; /* status of the connection */
int equote; /* use E''-style quotes for escaped strings */
int protocol; /* protocol version */
int server_version; /* server version */
const char *encoding; /* client encoding */
PGconn *pgconn; /* the postgresql connection */
}SFmDBConn;
class CFmDBSession {
protected:
SFmDBConn m_conn;
const char *get_parameter_status(const char *param);
public:
CFmDBSession();
~CFmDBSession();
bool connect(const char *uri);
void disconnect();
bool check_conn();
bool reconnect();
bool query(const char *db_cmd,fm_db_result_t & result);
bool cmd(const char *db_cmd);
bool params_cmd(fm_db_util_sql_params & sql_params);
PGconn* get_pgconn(){
return m_conn.pgconn;
}
};
#endif /* FMDB_H_ */

View File

@ -0,0 +1,49 @@
//
// Copyright (c) 2014 Wind River Systems, Inc.
//
// SPDX-License-Identifier: Apache-2.0
//
#ifndef FMDBAPI_H_
#define FMDBAPI_H_
#include <stdbool.h>
#include "fmAPI.h"
#ifdef __cplusplus
extern "C" {
#endif
#define FM_SNMP_TRAP_UTIL_SESSION_NULL NULL
typedef void * TFmAlarmSessionT;
typedef struct {
SFmAlarmDataT *alarm;
size_t num;
} SFmAlarmQueryT;
bool fm_snmp_util_create_session(TFmAlarmSessionT *handle, const char *db_conn);
void fm_snmp_util_destroy_session(TFmAlarmSessionT handle);
/*
* Used for applications running on the controller only. Pass in an struct
* and the API will allocate some alarms and return the number of alarms
*
* It is up to the caller to free the SFmAlamarQueryT->alarms entry when done
*/
bool fm_snmp_util_get_all_alarms(TFmAlarmSessionT handle,
SFmAlarmQueryT *query);
bool fm_snmp_util_get_all_event_logs(TFmAlarmSessionT handle,
SFmAlarmQueryT *query);
#ifdef __cplusplus
}
#endif
#endif /* FMDBAPI_H_ */

View File

@ -0,0 +1,532 @@
//
// Copyright (c) 2014 Wind River Systems, Inc.
//
// SPDX-License-Identifier: Apache-2.0
//
#include <stdlib.h>
#include <string>
#include <map>
#include "fmLog.h"
#include "fmDbAlarm.h"
#include "fmAlarmUtils.h"
#include "fmDbConstants.h"
#include "fmDbUtils.h"
typedef std::map<int,std::string> itos_t;
typedef std::map<std::string,int> stoi_t;
static pthread_mutex_t mutex = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;
static itos_t db_alarm_field_ix_to_str;
static stoi_t db_alarm_field_str_to_ix;
static const char * field_map[] = {
FM_ALARM_COLUMN_CREATED_AT, //0
FM_ALARM_COLUMN_UPDATED_AT,
FM_ALARM_COLUMN_DELETED_AT,
FM_ALARM_COLUMN_ID,
FM_ALARM_COLUMN_UUID,
FM_ALARM_COLUMN_ALARM_ID,
FM_ALARM_COLUMN_ALARM_STATE,
FM_ALARM_COLUMN_ENTITY_TYPE_ID,
FM_ALARM_COLUMN_ENTITY_INSTANCE_ID,
FM_ALARM_COLUMN_TIMESTAMP,
FM_ALARM_COLUMN_SEVERITY,
FM_ALARM_COLUMN_REASON_TEXT,
FM_ALARM_COLUMN_ALARM_TYPE,
FM_ALARM_COLUMN_PROBABLE_CAUSE,
FM_ALARM_COLUMN_PROPOSED_REPAIR_ACTION,
FM_ALARM_COLUMN_SERVICE_AFFECTING,
FM_ALARM_COLUMN_SUPPRESSION,
FM_ALARM_COLUMN_INHIBIT_ALARMS,
FM_ALARM_COLUMN_MASKED //18
};
void add_both_tables(const char *str, int id, itos_t &t1,stoi_t &t2 ) {
t1[id]=str;
t2[str]=id;
}
static std::string tostr(int id, const itos_t &t ){
itos_t::const_iterator it = t.find(id);
if (it!=t.end()) return it->second;
return "unknown";
}
/*
static int toint(const std::string &s, const stoi_t &t) {
stoi_t::const_iterator it = t.find(s);
if (it!=t.end()) return it->second ;
return 0;
}
*/
static void init_tables() {
pthread_mutex_lock(&mutex);
static bool has_inited=false;
while (!has_inited) {
add_both_tables(FM_ALARM_COLUMN_UUID,FM_ALM_IX_UUID,db_alarm_field_ix_to_str,db_alarm_field_str_to_ix);
add_both_tables(FM_ALARM_COLUMN_ALARM_ID,FM_ALM_IX_ALARM_ID,db_alarm_field_ix_to_str,db_alarm_field_str_to_ix);
add_both_tables(FM_ALARM_COLUMN_ALARM_STATE,FM_ALM_IX_ALARM_STATE,db_alarm_field_ix_to_str,db_alarm_field_str_to_ix);
add_both_tables(FM_ALARM_COLUMN_ENTITY_TYPE_ID,FM_ALM_IX_ENTITY_ID,db_alarm_field_ix_to_str,db_alarm_field_str_to_ix);
add_both_tables(FM_ALARM_COLUMN_ENTITY_INSTANCE_ID,FM_ALM_IX_INSTANCE_ID,db_alarm_field_ix_to_str,db_alarm_field_str_to_ix);
add_both_tables(FM_ALARM_COLUMN_TIMESTAMP,FM_ALM_IX_TIMESTAMP,db_alarm_field_ix_to_str,db_alarm_field_str_to_ix);
add_both_tables(FM_ALARM_COLUMN_SEVERITY,FM_ALM_IX_SEVERITY,db_alarm_field_ix_to_str,db_alarm_field_str_to_ix);
add_both_tables(FM_ALARM_COLUMN_REASON_TEXT,FM_ALM_IX_REASON,db_alarm_field_ix_to_str,db_alarm_field_str_to_ix);
add_both_tables(FM_ALARM_COLUMN_ALARM_TYPE,FM_ALM_IX_ALARM_TYPE,db_alarm_field_ix_to_str,db_alarm_field_str_to_ix);
add_both_tables(FM_ALARM_COLUMN_PROBABLE_CAUSE,FM_ALM_IX_PROBABLE_CAUSE,db_alarm_field_ix_to_str,db_alarm_field_str_to_ix);
add_both_tables(FM_ALARM_COLUMN_PROPOSED_REPAIR_ACTION,FM_ALM_IX_REPAIR_ACTION,db_alarm_field_ix_to_str,db_alarm_field_str_to_ix);
add_both_tables(FM_ALARM_COLUMN_SERVICE_AFFECTING,FM_ALM_IX_SERVICE_AFFECT,db_alarm_field_ix_to_str,db_alarm_field_str_to_ix);
add_both_tables(FM_ALARM_COLUMN_SUPPRESSION,FM_ALM_IX_SUPPRESSION,db_alarm_field_ix_to_str,db_alarm_field_str_to_ix);
add_both_tables(FM_ALARM_COLUMN_INHIBIT_ALARMS,FM_ALM_IX_INHIBIT_ALARM,db_alarm_field_ix_to_str,db_alarm_field_str_to_ix);
has_inited = true;
}
pthread_mutex_unlock(&mutex);
}
void append(std::string &str, const std::string &what) {
str+=what;
str+="###";
}
bool CFmDbAlarm::import_data(data_type &m ) {
m_alarm_data = m;
return true;
}
bool CFmDbAlarm::create_data(SFmAlarmDataT *alarm) {
init_tables();
m_alarm_data.clear();
size_t ix = FM_ALM_IX_UUID;
size_t mx = FM_ALM_IX_MAX;
std::string field;
for ( ; ix < mx ; ++ix ) {
std::string field_n = tostr(ix,db_alarm_field_ix_to_str);
fm_alarm_get_field((EFmAlarmIndexMap)ix,alarm,field);
m_alarm_data[field_n] = field;
}
return true;
}
bool CFmDbAlarm::export_data(CFmDbAlarm::data_type &m) {
m = m_alarm_data;
return true;
}
bool CFmDbAlarm::export_data(SFmAlarmDataT *alarm) {
init_tables();
memset(alarm,0,sizeof(*alarm));
size_t ix = FM_ALM_IX_UUID;
size_t mx =FM_ALM_IX_MAX;
std::string field;
for ( ; ix < mx ; ++ix ) {
std::string field_n = tostr(ix,db_alarm_field_ix_to_str);
if (m_alarm_data.find(field_n)==m_alarm_data.end()) return false;
fm_alarm_set_field((EFmAlarmIndexMap)ix,alarm,m_alarm_data[field_n]);
}
return true;
}
std::string CFmDbAlarm::find_field(const char *field) {
if (field==NULL) return "";
if (m_alarm_data.find(field)==m_alarm_data.end()) return "";
return m_alarm_data[field];
}
std::string CFmDbAlarm::to_formatted_db_string(const char ** list, size_t len) {
std::string details;
if (list == NULL) {
list = &field_map[0];
len = sizeof(field_map)/sizeof(*field_map);
}
size_t ix = 0;
for ( ; ix < len ; ++ix ) {
FM_DB_UT_NAME_VAL(details,
list[ix],
m_alarm_data[list[ix]]);
if (ix < (len-1))
details += "', ";
}
return details;
}
void CFmDbAlarm::print() {
std::string str = to_formatted_db_string();
FM_INFO_LOG("%s\n",str.c_str());
}
bool CFmDbAlarmOperation::create_alarm(CFmDBSession &sess,CFmDbAlarm &a) {
CFmDbAlarm::data_type data;
if (!a.export_data(data)) return false;
CFmDbAlarm::data_type::iterator it =
data.find(FM_ALARM_COLUMN_DELETED_AT);
if (it != data.end()){
data.erase(it);
}
it = data.find(FM_ALARM_COLUMN_ID);
if (it != data.end()){
data.erase(it);
}
std::string query;
FM_DB_UT_NAME_VAL(query,FM_ALARM_COLUMN_ALARM_ID,
data[FM_ALARM_COLUMN_ALARM_ID]);
query += " AND ";
FM_DB_UT_NAME_VAL(query,FM_ALARM_COLUMN_ENTITY_INSTANCE_ID,
data[FM_ALARM_COLUMN_ENTITY_INSTANCE_ID]);
std::string sql;
fm_db_util_build_sql_query((const char*)FM_ALARM_TABLE_NAME, query.c_str(), sql);
fm_db_result_t result;
if ((sess.query(sql.c_str(), result)) != true){
return false;
}
data[FM_ALARM_COLUMN_UUID] = a.find_field(FM_ALARM_COLUMN_UUID);
data[FM_ALARM_COLUMN_MASKED] = "False";
fm_db_util_sql_params sql_params;
if (result.size() == 0){
fm_db_util_build_sql_insert((const char*)FM_ALARM_TABLE_NAME, data, sql_params);
}else{
fm_db_single_result_t alm = result[0];
fm_db_util_build_sql_update((const char*)FM_ALARM_TABLE_NAME,
alm[FM_ALARM_COLUMN_ID],data, sql_params);
}
sql_params.n_params = data.size();
FM_DEBUG_LOG("execute CMD (%s)\n", sql_params.db_cmd.c_str());
return sess.params_cmd(sql_params);
}
bool CFmDbAlarmOperation::delete_alarms(CFmDBSession &sess, const char *id) {
std::string sql;
fm_db_util_build_sql_delete_all((const char*)FM_ALARM_TABLE_NAME, id, sql);
FM_DEBUG_LOG("CMD:(%s)\n", sql.c_str());
return sess.cmd(sql.c_str());
}
bool CFmDbAlarmOperation::delete_alarm(CFmDBSession &sess, AlarmFilter &af) {
std::string sql;
fm_db_util_build_sql_delete((const char*)FM_ALARM_TABLE_NAME, &af, sql);
FM_DEBUG_LOG("CMD:(%s)\n", sql.c_str());
return sess.cmd(sql.c_str());
}
bool CFmDbAlarmOperation::get_alarm(CFmDBSession &sess, AlarmFilter &af, fm_db_result_t & alarms) {
std::string sql;
char query[FM_MAX_SQL_STATEMENT_MAX];
if (strlen(af.entity_instance_id) == 0){
snprintf(query, sizeof(query),"%s = '%s' AND %s = ' '", FM_ALARM_COLUMN_ALARM_ID, af.alarm_id,
FM_ALARM_COLUMN_ENTITY_INSTANCE_ID);
}
else{
snprintf(query, sizeof(query),"%s = '%s' AND %s = '%s'", FM_ALARM_COLUMN_ALARM_ID, af.alarm_id,
FM_ALARM_COLUMN_ENTITY_INSTANCE_ID, af.entity_instance_id);
}
fm_db_util_build_sql_query((const char*)FM_ALARM_TABLE_NAME, query, sql);
FM_DEBUG_LOG("get_alarm:(%s)\n", sql.c_str());
if ((sess.query(sql.c_str(), alarms)) != true){
return false;
}
return true;
}
bool CFmDbAlarmOperation::get_alarms(CFmDBSession &sess,const char *id, fm_db_result_t & alarms) {
std::string sql;
char query[FM_MAX_SQL_STATEMENT_MAX];
fm_db_result_t res;
res.clear();
sql = FM_DB_SELECT_FROM_TABLE(FM_ALARM_TABLE_NAME);
sql += " ";
sql += " INNER JOIN ";
sql += FM_EVENT_SUPPRESSION_TABLE_NAME;
sql += " ON ";
sql += FM_ALARM_TABLE_NAME;
sql += ".";
sql += FM_ALARM_COLUMN_ALARM_ID;
sql += " = ";
sql += FM_EVENT_SUPPRESSION_TABLE_NAME;
sql += ".";
sql += FM_EVENT_SUPPRESSION_COLUMN_ALARM_ID;
sql += " WHERE ";
sql += FM_EVENT_SUPPRESSION_TABLE_NAME;
sql += ".";
sql += FM_EVENT_SUPPRESSION_COLUMN_SUPPRESSION_STATUS;
sql += " = '";
sql += FM_EVENT_SUPPRESSION_UNSUPPRESSED;
sql += "'";
if (id != NULL){
snprintf(query, sizeof(query),"%s like '%s%s'", FM_ALARM_COLUMN_ENTITY_INSTANCE_ID, id,"%");
if (NULL!=query) {
sql += " AND ";
sql += query;
}
}
FM_DEBUG_LOG("CMD:(%s)\n", sql.c_str());
if ((sess.query(sql.c_str(), alarms)) != true)
return false;
return true;
}
bool CFmDbAlarmOperation::get_alarms_by_id(CFmDBSession &sess,const char *id, fm_db_result_t & alarms) {
fm_alarm_id alm_id;
char query[FM_MAX_SQL_STATEMENT_MAX];
std::string sql;
memset(alm_id, 0 , sizeof(alm_id));
strncpy(alm_id, id ,sizeof(alm_id)-1);
snprintf(query, sizeof(query),"%s = '%s'", FM_ALARM_COLUMN_ALARM_ID, id);
fm_db_util_build_sql_query((const char*)FM_ALARM_TABLE_NAME, query, sql);
FM_DEBUG_LOG("CMD:(%s)\n", sql.c_str());
if ((sess.query(sql.c_str(), alarms)) != true){
return false;
}
return true;
}
bool CFmDbAlarmOperation::get_all_alarms(CFmDBSession &sess, SFmAlarmDataT **alarms, size_t *len ) {
fm_db_result_t res;
*len = 0;
*alarms = NULL;
if (!get_alarms(sess, NULL, res))
return false;
std::string sname = fm_db_util_get_system_name(sess);
unsigned int found_num_alarms = res.size();
if (found_num_alarms < 1)
return false;
SFmAlarmDataT *p =
(SFmAlarmDataT*)malloc(found_num_alarms*sizeof(SFmAlarmDataT));
if (p==NULL)
return false;
size_t ix = 0;
for ( ; ix < found_num_alarms; ++ix ){
CFmDbAlarm dbAlm;
CFmDbAlarm::convert_to(res[ix],p+ix);
std::string eid = (p+ix)->entity_instance_id;
eid = sname + "." + eid;
strncpy((p+ix)->entity_instance_id, eid.c_str(),
sizeof((p+ix)->entity_instance_id));
}
(*alarms) = p;
*len = found_num_alarms;
return true;
}
bool CFmDbAlarmOperation::get_history(CFmDBSession &sess,fm_db_result_t & alarms) {
std::string sql;
std::string separator = ", ";
std::string alias = " as ";
sql = "SELECT * FROM ";
sql += FM_EVENT_LOG_TABLE_NAME;
sql += " INNER JOIN ";
sql += FM_EVENT_SUPPRESSION_TABLE_NAME;
sql += " ON ";
sql += FM_EVENT_LOG_TABLE_NAME;
sql += ".";
sql += FM_EVENT_LOG_COLUMN_EVENT_ID;
sql += " = ";
sql += FM_EVENT_SUPPRESSION_TABLE_NAME;
sql += ".";
sql += FM_EVENT_SUPPRESSION_COLUMN_ALARM_ID;
sql += " WHERE ";
sql += FM_EVENT_SUPPRESSION_TABLE_NAME;
sql += ".";
sql += FM_EVENT_SUPPRESSION_COLUMN_SUPPRESSION_STATUS;
sql += " = '";
sql += FM_EVENT_SUPPRESSION_UNSUPPRESSED;
sql += "' AND (";
sql += FM_EVENT_LOG_COLUMN_STATE;
sql += " = 'set' OR ";
sql += FM_EVENT_LOG_COLUMN_STATE;
sql += " = 'clear' ) ";
sql += std::string(FM_DB_ORDERBY_TIME());
FM_DEBUG_LOG("CMD:(%s)\n", sql.c_str());
if ((sess.query(sql.c_str(), alarms)) != true){
return false;
}
return true;
}
bool CFmDbAlarmOperation::mask_unmask_alarms(CFmDBSession &sess,
SFmAlarmDataT &a, bool mask){
std::string sql;
char query[FM_MAX_SQL_STATEMENT_MAX];
fm_db_result_t res;
res.clear();
snprintf(query, sizeof(query),"%s like '%s%s' and suppression=True",
FM_ALARM_COLUMN_ENTITY_INSTANCE_ID, a.entity_instance_id,"%");
fm_db_util_build_sql_query((const char*)FM_ALARM_TABLE_NAME, query, sql);
FM_DEBUG_LOG("CMD:(%s)\n", sql.c_str());
if ((sess.query(sql.c_str(), res)) != true){
return false;
}
fm_db_result_t::iterator it = res.begin();
fm_db_result_t::iterator end = res.end();
for (; it != end; ++it){
if (((*it)[FM_ALARM_COLUMN_ALARM_ID]==std::string(a.alarm_id)) &&
((*it)[FM_ALARM_COLUMN_ENTITY_INSTANCE_ID]==std::string(a.entity_instance_id))){
FM_INFO_LOG("Skip the alarm that inhibits others (%s), (%s)\n",
a.alarm_id, a.entity_instance_id);
continue;
}
std::map<std::string,std::string> data;
data.clear();
fm_db_util_sql_params sql_params;
fm_db_util_build_sql_update((const char*)FM_ALARM_TABLE_NAME,
(*it)[FM_ALARM_COLUMN_ID],data, sql_params, mask);
sql_params.n_params = data.size();
FM_DEBUG_LOG("execute CMD (%s)\n", sql_params.db_cmd.c_str());
sess.params_cmd(sql_params);
}
return true;
}
bool CFmDbAlarmOperation::get_all_history_alarms(CFmDBSession &sess, SFmAlarmDataT **alarms, size_t *len ) {
fm_db_result_t res;
*len = 0;
*alarms = NULL;
if (!get_history(sess,res)) return false;
std::string sname = fm_db_util_get_system_name(sess);
unsigned int found_num_alarms = res.size();
if (found_num_alarms < 1) return false;
SFmAlarmDataT *p =
(SFmAlarmDataT*)malloc(found_num_alarms*sizeof(SFmAlarmDataT));
if (p==NULL){
return false;
}
size_t ix = 0;
for ( ; ix < found_num_alarms; ++ix ){
CFmDbAlarm dbAlm;
CFmDbAlarm::convert_to(res[ix],p+ix);
std::string eid = (p+ix)->entity_instance_id;
eid = sname + "." + eid;
strncpy((p+ix)->entity_instance_id, eid.c_str(),
sizeof((p+ix)->entity_instance_id));
}
(*alarms) = p;
*len = found_num_alarms;
return true;
}
bool CFmDbAlarmOperation::add_alarm_history(CFmDBSession &sess,
SFmAlarmDataT &a, bool set){
if (set){
a.alarm_state = (a.alarm_state == FM_ALARM_STATE_CLEAR) ?
FM_ALARM_STATE_SET : a.alarm_state;
}else{
a.alarm_state = FM_ALARM_STATE_CLEAR;
}
CFmDbAlarm alm;
if (!alm.create_data(&a)) return false;
CFmDbAlarm::data_type data;
if (!alm.export_data(data)) return false;
CFmDbAlarm::data_type::iterator it =
data.find(FM_ALARM_COLUMN_DELETED_AT);
if (it != data.end()){
data.erase(it);
}
it = data.find(FM_ALARM_COLUMN_UPDATED_AT);
if (it != data.end()){
data.erase(it);
}
it = data.find(FM_ALARM_COLUMN_MASKED);
if (it != data.end()){
data.erase(it);
}
it = data.find(FM_ALARM_COLUMN_INHIBIT_ALARMS);
if (it != data.end()){
data.erase(it);
}
it = data.find(FM_ALARM_COLUMN_ID);
if (it != data.end()){
data.erase(it);
}
int id =0;
std::string sql;
if (false == fm_db_util_get_next_log_id(sess, id)) {
return false;
}
if (0 != id) {
data[FM_ALARM_COLUMN_ID] = fm_db_util_int_to_string(id);
}
// get the current time for clear event
if (!set){
std::string time_str;
fm_db_util_make_timestamp_string(time_str);
data[FM_ALARM_COLUMN_TIMESTAMP] = time_str;
//set the same time in the alarm data that will be used for logging
fm_db_util_get_timestamp(time_str.c_str(), a.timestamp);
}
sql.clear();
fm_db_util_sql_params sql_params;
fm_db_util_event_log_build_sql_insert(data, sql_params);
FM_DEBUG_LOG("Add row (%s)\n", sql_params.db_cmd.c_str());
return sess.params_cmd(sql_params);
}

View File

@ -0,0 +1,74 @@
//
// Copyright (c) 2014 Wind River Systems, Inc.
//
// SPDX-License-Identifier: Apache-2.0
//
#ifndef FMDBALARM_H_
#define FMDBALARM_H_
#include <string>
#include <vector>
#include <stddef.h>
#include <map>
#include "fmAPI.h"
#include "fmDbConstants.h"
#include "fmDb.h"
class CFmDbAlarm {
public:
typedef std::map<std::string,std::string> data_type;
bool import_data(CFmDbAlarm::data_type &m);
bool create_data(SFmAlarmDataT *alarm);
bool export_data(SFmAlarmDataT *alarm);
bool export_data(CFmDbAlarm::data_type &m);
std::string find_field(const char *field);
void set_field(const std::string &lhs, const std::string &rhs) {
m_alarm_data[lhs] = rhs;
}
std::string to_formatted_db_string(const char ** list=NULL, size_t len=0);
void print();
static inline bool convert_to(CFmDbAlarm::data_type &m, SFmAlarmDataT *alarm ) {
CFmDbAlarm a;
if (!a.import_data(m)) return false;
return a.export_data(alarm);
}
protected:
data_type m_alarm_data;
};
class CFmDbAlarmOperation {
public:
bool create_alarm(CFmDBSession &sess, CFmDbAlarm &a);
bool delete_alarms(CFmDBSession &sess, const char *id);
bool delete_alarm(CFmDBSession &sess, AlarmFilter &af);
bool delete_row(CFmDBSession &sess, const char* db_table);
bool get_alarm(CFmDBSession &sess, AlarmFilter &af, fm_db_result_t & alarms);
bool get_alarms(CFmDBSession &sess, const char *id, fm_db_result_t & alarms) ;
bool get_history(CFmDBSession &sess, fm_db_result_t & alarms) ;
bool get_all_alarms(CFmDBSession &sess, SFmAlarmDataT **alarms, size_t *len );
bool get_all_history_alarms(CFmDBSession &sess, SFmAlarmDataT **alarms, size_t *len );
bool get_alarms_by_id(CFmDBSession &sess, const char *id, fm_db_result_t & alarms);
bool mask_unmask_alarms(CFmDBSession &sess, SFmAlarmDataT &a, bool mask = true);
bool add_alarm_history(CFmDBSession &sess, SFmAlarmDataT &a, bool set);
};
#endif /* FMDBALARM_H_ */

View File

@ -0,0 +1,99 @@
//
// Copyright (c) 2014 Wind River Systems, Inc.
//
// SPDX-License-Identifier: Apache-2.0
//
#ifndef FMDBCONSTANTS_H_
#define FMDBCONSTANTS_H_
/* DB connection status */
#define DB_DISCONNECTED 0
#define DB_CONNECTED 1
#define FM_MAX_SQL_STATEMENT_MAX 4096
#define FM_DB_TABLE_COUNT_COLUMN "count"
/* Alarm table name */
#define FM_ALARM_TABLE_NAME "i_alarm"
/* Event log table name */
#define FM_EVENT_LOG_TABLE_NAME "i_event_log"
/* Event suppression table name */
#define FM_EVENT_SUPPRESSION_TABLE_NAME "event_suppression"
/* Event suppression table sync script */
#define FM_DB_SYNC_EVENT_SUPPRESSION "/usr/bin/fm_db_sync_event_suppression.py"
/* Alarm Table Columns */
#define FM_ALARM_COLUMN_CREATED_AT "created_at"
#define FM_ALARM_COLUMN_UPDATED_AT "updated_at"
#define FM_ALARM_COLUMN_DELETED_AT "deleted_at"
#define FM_ALARM_COLUMN_ID "id"
#define FM_ALARM_COLUMN_UUID "uuid"
#define FM_ALARM_COLUMN_ALARM_ID "alarm_id"
#define FM_ALARM_COLUMN_ALARM_STATE "alarm_state"
#define FM_ALARM_COLUMN_ENTITY_TYPE_ID "entity_type_id"
#define FM_ALARM_COLUMN_ENTITY_INSTANCE_ID "entity_instance_id"
#define FM_ALARM_COLUMN_TIMESTAMP "timestamp"
#define FM_ALARM_COLUMN_SEVERITY "severity"
#define FM_ALARM_COLUMN_REASON_TEXT "reason_text"
#define FM_ALARM_COLUMN_ALARM_TYPE "alarm_type"
#define FM_ALARM_COLUMN_PROBABLE_CAUSE "probable_cause"
#define FM_ALARM_COLUMN_PROPOSED_REPAIR_ACTION "proposed_repair_action"
#define FM_ALARM_COLUMN_SERVICE_AFFECTING "service_affecting"
#define FM_ALARM_COLUMN_SUPPRESSION "suppression"
#define FM_ALARM_COLUMN_INHIBIT_ALARMS "inhibit_alarms"
#define FM_ALARM_COLUMN_MASKED "masked"
/* Event Log Table Columns */
#define FM_EVENT_LOG_COLUMN_CREATED_AT "created_at"
#define FM_EVENT_LOG_COLUMN_UPDATED_AT "updated_at"
#define FM_EVENT_LOG_COLUMN_DELETED_AT "deleted_at"
#define FM_EVENT_LOG_COLUMN_ID "id"
#define FM_EVENT_LOG_COLUMN_UUID "uuid"
#define FM_EVENT_LOG_COLUMN_EVENT_ID "event_log_id"
#define FM_EVENT_LOG_COLUMN_STATE "state"
#define FM_EVENT_LOG_COLUMN_ENTITY_TYPE_ID "entity_type_id"
#define FM_EVENT_LOG_COLUMN_ENTITY_INSTANCE_ID "entity_instance_id"
#define FM_EVENT_LOG_COLUMN_TIMESTAMP "timestamp"
#define FM_EVENT_LOG_COLUMN_SEVERITY "severity"
#define FM_EVENT_LOG_COLUMN_REASON_TEXT "reason_text"
#define FM_EVENT_LOG_COLUMN_EVENT_TYPE "event_log_type"
#define FM_EVENT_LOG_COLUMN_PROBABLE_CAUSE "probable_cause"
#define FM_EVENT_LOG_COLUMN_PROPOSED_REPAIR_ACTION "proposed_repair_action"
#define FM_EVENT_LOG_COLUMN_SERVICE_AFFECTING "service_affecting"
#define FM_EVENT_LOG_COLUMN_SUPPRESSION "suppression"
/* Event Suppression Table Columns */
#define FM_EVENT_SUPPRESSION_COLUMN_CREATED_AT "created_at"
#define FM_EVENT_SUPPRESSION_COLUMN_UPDATED_AT "updated_at"
#define FM_EVENT_SUPPRESSION_COLUMN_DELETED_AT "deleted_at"
#define FM_EVENT_SUPPRESSION_COLUMN_ID "id"
#define FM_EVENT_SUPPRESSION_COLUMN_UUID "uuid"
#define FM_EVENT_SUPPRESSION_COLUMN_ALARM_ID "alarm_id"
#define FM_EVENT_SUPPRESSION_COLUMN_DESCRIPTION "description"
#define FM_EVENT_SUPPRESSION_COLUMN_SUPPRESSION_STATUS "suppression_status"
#define FM_EVENT_SUPPRESSION_SUPPRESSED "suppressed"
#define FM_EVENT_SUPPRESSION_UNSUPPRESSED "unsuppressed"
#define FM_EVENT_SUPPRESSION_NONE "None"
/* System table name */
#define FM_SYSTEM_TABLE_NAME "i_system"
#define FM_SYSTEM_NAME_COLUMN "name"
#define FM_SYSTEM_REGION_COLUMN "region_name"
#define FM_ENTITY_ROOT_KEY "system="
#define FM_ENTITY_REGION_KEY "region="
/* config keys */
#define FM_SQL_CONNECTION "sql_connection"
#define FM_EVENT_LOG_MAX_SIZE "event_log_max_size"
#define CLEAR_ALL_REASON_TEXT "System initiated hierarchical alarm clear"
#endif /* FMDBCONSTANTS_H_ */

View File

@ -0,0 +1,318 @@
//
// Copyright (c) 2014 Wind River Systems, Inc.
//
// SPDX-License-Identifier: Apache-2.0
//
#include <stdlib.h>
#include <string>
#include <map>
#include "fmLog.h"
#include "fmDbAlarm.h"
#include "fmDbEventLog.h"
#include "fmAlarmUtils.h"
#include "fmDbConstants.h"
#include "fmDbUtils.h"
typedef std::map<int,std::string> itos_t;
typedef std::map<std::string,int> stoi_t;
static pthread_mutex_t mutex = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;
static itos_t db_event_log_field_ix_to_str;
static stoi_t db_event_log_field_str_to_ix;
static const char * field_map[] = {
FM_EVENT_LOG_COLUMN_CREATED_AT, //0
FM_EVENT_LOG_COLUMN_UPDATED_AT,
FM_EVENT_LOG_COLUMN_DELETED_AT,
FM_EVENT_LOG_COLUMN_ID,
FM_EVENT_LOG_COLUMN_UUID,
FM_EVENT_LOG_COLUMN_EVENT_ID,
FM_EVENT_LOG_COLUMN_STATE,
FM_EVENT_LOG_COLUMN_ENTITY_TYPE_ID,
FM_EVENT_LOG_COLUMN_ENTITY_INSTANCE_ID,
FM_EVENT_LOG_COLUMN_TIMESTAMP,
FM_EVENT_LOG_COLUMN_SEVERITY,
FM_EVENT_LOG_COLUMN_REASON_TEXT,
FM_EVENT_LOG_COLUMN_EVENT_TYPE,
FM_EVENT_LOG_COLUMN_PROBABLE_CAUSE,
FM_EVENT_LOG_COLUMN_PROPOSED_REPAIR_ACTION,
FM_EVENT_LOG_COLUMN_SERVICE_AFFECTING,
FM_EVENT_LOG_COLUMN_SUPPRESSION,
};
static const int alarm_to_event_log_index[] = {
FM_EVENT_LOG_IX_UUID,
FM_EVENT_LOG_IX_EVENT_ID,
FM_EVENT_LOG_IX_STATE,
FM_EVENT_LOG_IX_ENTITY_ID,
FM_EVENT_LOG_IX_INSTANCE_ID,
FM_EVENT_LOG_IX_TIMESTAMP,
FM_EVENT_LOG_IX_SEVERITY,
FM_EVENT_LOG_IX_REASON,
FM_EVENT_LOG_IX_EVENT_TYPE,
FM_EVENT_LOG_IX_PROBABLE_CAUSE,
FM_EVENT_LOG_IX_REPAIR_ACTION,
FM_EVENT_LOG_IX_SERVICE_AFFECT,
FM_EVENT_LOG_IX_SUPPRESSION,
-1,
FM_EVENT_LOG_IX_MAX
};
void CFmDbEventLog::add_both_tables(const char *str, int id, itos_t &t1,stoi_t &t2 ) {
t1[id]=str;
t2[str]=id;
}
static std::string tostr(int id, const itos_t &t ){
itos_t::const_iterator it = t.find(id);
if (it!=t.end()) return it->second;
return "unknown";
}
void CFmDbEventLog::init_tables() {
pthread_mutex_lock(&mutex);
static bool has_inited=false;
while (!has_inited) {
add_both_tables(FM_EVENT_LOG_COLUMN_UUID,FM_EVENT_LOG_IX_UUID,db_event_log_field_ix_to_str,db_event_log_field_str_to_ix);
add_both_tables(FM_EVENT_LOG_COLUMN_EVENT_ID,FM_EVENT_LOG_IX_EVENT_ID,db_event_log_field_ix_to_str,db_event_log_field_str_to_ix);
add_both_tables(FM_EVENT_LOG_COLUMN_STATE,FM_EVENT_LOG_IX_STATE,db_event_log_field_ix_to_str,db_event_log_field_str_to_ix);
add_both_tables(FM_EVENT_LOG_COLUMN_ENTITY_TYPE_ID,FM_EVENT_LOG_IX_ENTITY_ID,db_event_log_field_ix_to_str,db_event_log_field_str_to_ix);
add_both_tables(FM_EVENT_LOG_COLUMN_ENTITY_INSTANCE_ID,FM_EVENT_LOG_IX_INSTANCE_ID,db_event_log_field_ix_to_str,db_event_log_field_str_to_ix);
add_both_tables(FM_EVENT_LOG_COLUMN_TIMESTAMP,FM_EVENT_LOG_IX_TIMESTAMP,db_event_log_field_ix_to_str,db_event_log_field_str_to_ix);
add_both_tables(FM_EVENT_LOG_COLUMN_SEVERITY,FM_EVENT_LOG_IX_SEVERITY,db_event_log_field_ix_to_str,db_event_log_field_str_to_ix);
add_both_tables(FM_EVENT_LOG_COLUMN_REASON_TEXT,FM_EVENT_LOG_IX_REASON,db_event_log_field_ix_to_str,db_event_log_field_str_to_ix);
add_both_tables(FM_EVENT_LOG_COLUMN_EVENT_TYPE,FM_EVENT_LOG_IX_EVENT_TYPE,db_event_log_field_ix_to_str,db_event_log_field_str_to_ix);
add_both_tables(FM_EVENT_LOG_COLUMN_PROBABLE_CAUSE,FM_EVENT_LOG_IX_PROBABLE_CAUSE,db_event_log_field_ix_to_str,db_event_log_field_str_to_ix);
add_both_tables(FM_EVENT_LOG_COLUMN_PROPOSED_REPAIR_ACTION, FM_EVENT_LOG_IX_REPAIR_ACTION, db_event_log_field_ix_to_str,db_event_log_field_str_to_ix);
add_both_tables(FM_EVENT_LOG_COLUMN_SERVICE_AFFECTING,FM_EVENT_LOG_IX_SERVICE_AFFECT,db_event_log_field_ix_to_str,db_event_log_field_str_to_ix);
add_both_tables(FM_EVENT_LOG_COLUMN_SUPPRESSION,FM_EVENT_LOG_IX_SUPPRESSION,db_event_log_field_ix_to_str,db_event_log_field_str_to_ix);
has_inited = true;
}
pthread_mutex_unlock(&mutex);
}
void CFmDbEventLog::append(std::string &str, const std::string &what) {
str+=what;
str+="###";
}
bool CFmDbEventLog::import_data(data_type &m ) {
m_event_log_data = m;
return true;
}
bool CFmDbEventLog::create_data(SFmAlarmDataT *alarm) {
init_tables();
m_event_log_data.clear();
size_t ix = FM_ALM_IX_UUID;
size_t mx = FM_ALM_IX_MAX;
std::string field;
int log_idx;
for ( ; ix < mx ; ++ix ) {
log_idx = alarm_to_event_log_index[ix];
if (log_idx == -1)
continue;
std::string field_n = tostr(log_idx,db_event_log_field_ix_to_str);
if (field_n == "unknown")
continue; // ignore these fields
fm_alarm_get_field((EFmAlarmIndexMap)ix,alarm,field);
m_event_log_data[field_n] = field;
}
return true;
}
bool CFmDbEventLog::export_data(CFmDbEventLog::data_type &m) {
m = m_event_log_data;
return true;
}
bool CFmDbEventLog::export_data(SFmAlarmDataT *data) {
init_tables();
memset(data,0,sizeof(*data));
size_t ix = FM_EVENT_LOG_IX_UUID;
size_t mx = FM_EVENT_LOG_IX_MAX;
std::string field;
for ( ; ix < mx ; ++ix ) {
std::string field_n = tostr(ix,db_event_log_field_ix_to_str);
if (m_event_log_data.find(field_n)==m_event_log_data.end()) return false;
fm_event_log_set_field((EFmEventLogIndexMap)ix,data,m_event_log_data[field_n]);
}
return true;
}
std::string CFmDbEventLog::find_field(const char *field) {
if (field==NULL) return "";
if (m_event_log_data.find(field)==m_event_log_data.end()) return "";
return m_event_log_data[field];
}
std::string CFmDbEventLog::to_formatted_db_string(const char ** list, size_t len) {
std::string details;
if (list == NULL) {
list = &field_map[0];
len = sizeof(field_map)/sizeof(*field_map);
}
size_t ix = 0;
for ( ; ix < len ; ++ix ) {
FM_DB_UT_NAME_VAL(details,
list[ix],
m_event_log_data[list[ix]]);
if (ix < (len-1))
details += "', ";
}
return details;
}
void CFmDbEventLog::print() {
std::string str = to_formatted_db_string();
FM_INFO_LOG("%s\n",str.c_str());
}
bool CFmDbEventLogOperation::create_event_log(CFmDBSession &sess,CFmDbEventLog &a) {
CFmDbEventLog::data_type data;
if (!a.export_data(data)) return false;
CFmDbEventLog::data_type::iterator it =
data.find(FM_EVENT_LOG_COLUMN_DELETED_AT);
if (it != data.end()){
data.erase(it);
}
it = data.find(FM_EVENT_LOG_COLUMN_UPDATED_AT);
if (it != data.end()){
data.erase(it);
}
it = data.find(FM_EVENT_LOG_COLUMN_ID);
if (it != data.end()){
data.erase(it);
}
int id =0;
std::string sql;
if ( false == fm_db_util_get_next_log_id(sess, id)) {
return false;
}
if (0 != id) {
data[FM_EVENT_LOG_COLUMN_ID] = fm_db_util_int_to_string(id);
}
fm_db_util_sql_params sql_params;
fm_db_util_build_sql_insert((const char*)FM_EVENT_LOG_TABLE_NAME, data, sql_params);
sql_params.n_params = data.size();
FM_DEBUG_LOG("Add row (%s)\n", sql_params.db_cmd.c_str());
return sess.params_cmd(sql_params);
}
bool CFmDbEventLogOperation::get_event_log(CFmDBSession &sess, AlarmFilter &af, fm_db_result_t & logs) {
std::string sql;
char query[FM_MAX_SQL_STATEMENT_MAX];
if (strlen(af.entity_instance_id) == 0){
snprintf(query, sizeof(query),"%s = '%s' AND %s = ' '", FM_EVENT_LOG_COLUMN_EVENT_ID, af.alarm_id,
FM_EVENT_LOG_COLUMN_ENTITY_INSTANCE_ID);
}
else{
snprintf(query, sizeof(query),"%s = '%s' AND %s = '%s'", FM_EVENT_LOG_COLUMN_EVENT_ID, af.alarm_id,
FM_EVENT_LOG_COLUMN_ENTITY_INSTANCE_ID, af.entity_instance_id);
}
fm_db_util_build_sql_query((const char*)FM_EVENT_LOG_TABLE_NAME, query, sql);
FM_DEBUG_LOG("get_log:(%s)\n", sql.c_str());
if ((sess.query(sql.c_str(), logs)) != true){
return false;
}
return true;
}
bool CFmDbEventLogOperation::get_event_logs(CFmDBSession &sess, fm_db_result_t & logs) {
std::string sql;
sql = FM_DB_SELECT_FROM_TABLE(FM_EVENT_LOG_TABLE_NAME);
sql += " LEFT OUTER JOIN ";
sql += FM_EVENT_SUPPRESSION_TABLE_NAME;
sql += " ON ";
sql += FM_EVENT_LOG_TABLE_NAME;
sql += ".";
sql += FM_EVENT_LOG_COLUMN_EVENT_ID;
sql += " = ";
sql += FM_EVENT_SUPPRESSION_TABLE_NAME;
sql += ".";
sql += FM_EVENT_SUPPRESSION_COLUMN_ALARM_ID;
sql += " WHERE ";
sql += FM_EVENT_SUPPRESSION_TABLE_NAME;
sql += ".";
sql += FM_EVENT_SUPPRESSION_COLUMN_SUPPRESSION_STATUS;
sql += " = '";
sql += FM_EVENT_SUPPRESSION_UNSUPPRESSED;
sql += "' OR ";
sql += FM_EVENT_LOG_COLUMN_STATE;
sql += " = 'log' ";
// select statement built
FM_DEBUG_LOG("CMD:(%s)\n", sql.c_str());
if ((sess.query(sql.c_str(), logs)) != true){
return false;
}
return true;
}
bool CFmDbEventLogOperation::get_event_logs_by_id(CFmDBSession &sess,const char *id, fm_db_result_t & logs) {
char query[FM_MAX_SQL_STATEMENT_MAX];
std::string sql;
snprintf(query, sizeof(query),"%s = '%s'", FM_EVENT_LOG_COLUMN_EVENT_ID, id);
fm_db_util_build_sql_query((const char*)FM_EVENT_LOG_TABLE_NAME, query, sql);
FM_DEBUG_LOG("CMD:(%s)\n", sql.c_str());
if ((sess.query(sql.c_str(), logs)) != true){
return false;
}
return true;
}
bool CFmDbEventLogOperation::get_all_event_logs(CFmDBSession &sess, SFmAlarmDataT **logs, size_t *len ) {
fm_db_result_t res;
*len = 0;
*logs = NULL;
if (!get_event_logs(sess, res)) return false;
std::string sname = fm_db_util_get_system_name(sess);
unsigned int found_num_logs = res.size();
if (found_num_logs < 1) return false;
SFmAlarmDataT *p =
(SFmAlarmDataT*)malloc(found_num_logs*sizeof(SFmAlarmDataT));
if (p==NULL){
return false;
}
size_t ix = 0;
for ( ; ix < found_num_logs; ++ix ){
CFmDbEventLog dbEventLog;
CFmDbEventLog::convert_to(res[ix],p+ix);
std::string eid = (p+ix)->entity_instance_id;
eid = sname + "." + eid;
strncpy((p+ix)->entity_instance_id, eid.c_str(),
sizeof((p+ix)->entity_instance_id));
}
(*logs) = p;
*len = found_num_logs;
return true;
}

View File

@ -0,0 +1,69 @@
//
// Copyright (c) 2016 Wind River Systems, Inc.
//
// SPDX-License-Identifier: Apache-2.0
//
#ifndef FMDBEVENTLOG_H_
#define FMDBEVENTLOG_H_
#include <string>
#include <vector>
#include <stddef.h>
#include <map>
#include "fmAPI.h"
#include "fmDbConstants.h"
#include "fmDb.h"
typedef std::map<int,std::string> itos_t;
typedef std::map<std::string,int> stoi_t;
class CFmDbEventLog {
public:
typedef std::map<std::string,std::string> data_type;
bool create_data(SFmAlarmDataT *alarm);
bool import_data(CFmDbEventLog::data_type &m);
bool export_data(SFmAlarmDataT *alarm);
bool export_data(CFmDbEventLog::data_type &m);
void append(std::string &str, const std::string &what);
void add_both_tables(const char *str, int id, itos_t &t1,stoi_t &t2 );
void init_tables();
std::string find_field(const char *field);
void set_field(const std::string &lhs, const std::string &rhs) {
m_event_log_data[lhs] = rhs;
}
std::string to_formatted_db_string(const char ** list=NULL, size_t len=0);
void print();
static inline bool convert_to(CFmDbEventLog::data_type &m, SFmAlarmDataT *alarm ) {
CFmDbEventLog a;
if (!a.import_data(m)) return false;
return a.export_data(alarm);
}
protected:
data_type m_event_log_data;
};
class CFmDbEventLogOperation {
public:
bool create_event_log(CFmDBSession &sess, CFmDbEventLog &a);
bool get_event_log(CFmDBSession &sess, AlarmFilter &af, fm_db_result_t & alarms);
bool get_event_logs(CFmDBSession &sess, fm_db_result_t & alarms) ;
bool get_all_event_logs(CFmDBSession &sess, SFmAlarmDataT **alarms, size_t *len );
bool get_event_logs_by_id(CFmDBSession &sess, const char *id, fm_db_result_t & alarms);
};
#endif /* FMDBEVENTLOG_H_ */

View File

@ -0,0 +1,715 @@
//
// Copyright (c) 2014 Wind River Systems, Inc.
//
// SPDX-License-Identifier: Apache-2.0
//
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <assert.h>
#include <sstream>
#include <map>
#include <iostream>
#include <assert.h>
#include <arpa/inet.h>
#include <python2.7/Python.h>
#include "fmMutex.h"
#include "fmAPI.h"
#include "fmLog.h"
#include "fmFile.h"
#include "fmDb.h"
#include "fmDbUtils.h"
#include "fmDbAPI.h"
#include "fmDbConstants.h"
#include "fmAlarmUtils.h"
typedef std::map<std::string,std::string> configParams;
static const char *conf = NULL;
static pthread_mutex_t mutex = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;
CFmMutex & getConfMutex(){
static CFmMutex *m = new CFmMutex;
return *m;
}
configParams &getConfigMap(){
static configParams conf;
return conf;
}
void FM_DB_UT_NAME_VAL(
std::string &result,
const std::string &lhs, const std::string &rhs) {
result+= lhs;
result+= " = '";
result+=rhs;
result+="'";
}
void FM_DB_UT_NAME_PARAM(
std::string &result,
const std::string &lhs, const std::string &rhs) {
result+= lhs;
result+= "=";
result+=rhs;
}
static inline void append_str(std::string &s, const std::string &app) {
if (s.size()!=0) s+= ", ";
s+=app;
}
static inline std::string add_quote(const std::string &s) {
return std::string("'")+s+"'";
}
static int get_oldest_id(CFmDBSession &sess, const char* db_table){
fm_db_result_t res;
int id = 0;
char sql[FM_MAX_SQL_STATEMENT_MAX];
memset(sql, 0, sizeof(sql));
snprintf(sql, sizeof(sql), "SELECT %s FROM %s order by %s limit 1",
FM_ALARM_COLUMN_ID, db_table,
FM_ALARM_COLUMN_CREATED_AT);
if (sess.query(sql, res)){
if (res.size() > 0){
std::map<std::string,std::string> entry = res[0];
id = fm_db_util_string_to_int(entry[FM_ALARM_COLUMN_ID]);
}
}
return id;
}
static void get_config_parameters(){
CfmFile f;
std::string delimiter = "=";
std::string line, key, value;
size_t pos = 0;
if (conf == NULL){
FM_ERROR_LOG("The config file is not set\n");
exit(-1);
}
if (!f.open(conf, CfmFile::READ, false)){
FM_ERROR_LOG("Failed to open config file: %s\n", conf);
exit(-1);
}
while (true){
if (!f.read_line(line)) break;
if (line.size() == 0) continue;
if (line[0] == '#') continue;
pos = line.find(delimiter);
key = line.substr(0, pos);
value = line.erase(0, pos + delimiter.length());
getConfigMap()[key] = value;
if (key.compare("sql_connection") != 0){
// Don't log sql_connection, as it has a password
FM_INFO_LOG("Config key (%s), value (%s)",
key.c_str(), value.c_str());
}
}
}
static inline CFmDBSession & FmDbSessionFromHandle(TFmAlarmSessionT *p){
return *((CFmDBSession*)p);
}
static void format_time_string(std::string &tstr, struct timespec *ts,
bool snmp){
char buff[200];
struct tm t;
int ret = 0;
//tzset();
memset(&t, 0, sizeof(t));
memset(buff, 0, sizeof(buff));
if (gmtime_r(&(ts->tv_sec), &t) == NULL)
return ;
if (snmp){
ret = strftime(buff, sizeof(buff), "%Y-%m-%d,%H:%M:%S.0,+0:0", &t);
}else{
ret = strftime(buff,sizeof(buff), "%F %T", &t);
}
if (ret == 0) return ;
tstr+=buff;
if (!snmp){
//append the microseconds
snprintf(buff,sizeof(buff), ".%06ld", ts->tv_nsec/1000);
tstr+=buff;
}
}
std::string fm_db_util_replace_single_quote(std::string const& original){
std::string result;
std::string::const_iterator it = original.begin();
for (; it != original.end(); ++it){
if (*it == '\''){
result.push_back('\'');
}
result.push_back(*it);
}
return result;
}
std::string fm_db_util_int_to_string(int val){
std::string result;
std::stringstream ss;
ss << val;
ss >> result;
return result;
}
int fm_db_util_string_to_int(std::string val){
int result;
std::stringstream ss;
ss << val;
ss >> result;
return result;
}
void fm_db_util_make_timestamp_string(std::string &tstr, FMTimeT tm,
bool snmp){
struct timespec ts;
if (tm != 0){
ts.tv_sec = tm / 1000000;
ts.tv_nsec = (tm % 1000000) * 1000;
}else{
clock_gettime(CLOCK_REALTIME, &ts);
}
tstr.clear();
format_time_string(tstr,&ts, snmp);
}
bool fm_db_util_get_timestamp(const char *str, FMTimeT &ft){
struct timespec ts;
memset(&ts, 0, sizeof(ts));
// only check if the year is present
if (strlen(str) < 10){
//get the current time
clock_gettime(CLOCK_REALTIME, &ts);
}else{
struct tm t;
memset(&t, 0, sizeof(t));
strptime(str, "%F %T", &t);
ts.tv_sec = mktime(&t);
//now get the nanoseconds
char *tstr = strdup(str);
strsep(&tstr, ".");
if (tstr != NULL){
ts.tv_nsec = atol(tstr)*1000;
}
}
ft = ts.tv_sec*1000000 + ts.tv_nsec/1000;
return true;
}
bool fm_db_util_build_sql_query(const char* db_table,
const char* db_query, std::string &db_cmd){
db_cmd = FM_DB_SELECT_FROM_TABLE(db_table);
if (NULL!=db_query) {
db_cmd += " ";
db_cmd += FM_DB_WHERE();
db_cmd += " ";
db_cmd += db_query;
}
return true;
}
bool fm_db_util_build_sql_insert(const char* db_table,
std::map<std::string,std::string> &map,
fm_db_util_sql_params &params) {
std::string keys;
std::string values;
std::string time_str;
fm_db_util_make_timestamp_string(time_str);
map[FM_ALARM_COLUMN_CREATED_AT] = time_str;
std::map<std::string,std::string>::iterator at =
map.find(FM_ALARM_COLUMN_UPDATED_AT);
if (at != map.end()){
map.erase(at);
}
std::map<std::string,std::string>::iterator it = map.begin();
std::map<std::string,std::string>::iterator end = map.end();
size_t i = 0;
std::string cmd_params;
char str[80];
std::string param;
for ( ; it != end ; ++it ) {
param.clear();
memset(str, 0, sizeof(str));
append_str(keys,it->first);
if (it->first == FM_ALARM_COLUMN_ID){
params.id = htonl(atoi(it->second.c_str()));
params.param_values.push_back((char*)&params.id);
params.param_lengths.push_back(sizeof(int));
params.param_format.push_back(1);
sprintf(str,"$%lu::int,", ++i);
} else if ((it->first == FM_ALARM_COLUMN_CREATED_AT) ||
(it->first == FM_ALARM_COLUMN_TIMESTAMP)){
params.param_values.push_back(it->second.c_str());
params.param_lengths.push_back(strlen(it->second.c_str()));
params.param_format.push_back(0);
sprintf(str, "$%lu::timestamp,", ++i);
} else if ((it->first == FM_ALARM_COLUMN_SERVICE_AFFECTING) ||
(it->first == FM_ALARM_COLUMN_SUPPRESSION) ||
(it->first == FM_ALARM_COLUMN_INHIBIT_ALARMS) ||
(it->first == FM_ALARM_COLUMN_MASKED)){
params.scratch[it->first] = (it->second == "True") ? 1 : 0;
params.param_values.push_back((char *)&(params.scratch[it->first]));
params.param_lengths.push_back(sizeof(bool));
params.param_format.push_back(1);
sprintf(str,"$%lu::boolean,", ++i);
} else {
params.param_values.push_back(it->second.c_str());
params.param_lengths.push_back(strlen(it->second.c_str()));
params.param_format.push_back(0);
sprintf(str,"$%lu::varchar,", ++i);
}
param.assign(str);
cmd_params += param;
}
cmd_params.resize(cmd_params.size()-1);
params.db_cmd = "INSERT INTO ";
params.db_cmd += db_table;
params.db_cmd += " ( ";
params.db_cmd += keys;
params.db_cmd += ") VALUES (";
params.db_cmd += cmd_params;
params.db_cmd += ");";
return true;
}
bool fm_db_util_event_log_build_sql_insert(std::map<std::string,std::string> &map,
fm_db_util_sql_params &params) {
std::string keys;
std::string values;
std::string time_str;
fm_db_util_make_timestamp_string(time_str);
map[FM_ALARM_COLUMN_CREATED_AT] = time_str;
std::map<std::string,std::string>::iterator at =
map.find(FM_ALARM_COLUMN_UPDATED_AT);
if (at != map.end()){
map.erase(at);
}
std::map<std::string,std::string>::iterator it = map.begin();
std::map<std::string,std::string>::iterator end = map.end();
size_t i = 0;
std::string cmd_params;
char str[80];
std::string param;
params.n_params = 0;
for ( ; it != end ; ++it ) {
param.clear();
memset(str, 0, sizeof(str));
if (it->first == FM_ALARM_COLUMN_ID){
append_str(keys,it->first);
params.id = htonl(atoi(it->second.c_str()));
params.param_values.push_back((char*)&params.id);
params.param_lengths.push_back(sizeof(int));
params.param_format.push_back(1);
sprintf(str,"$%lu::int,", ++i);
} else if ((it->first == FM_ALARM_COLUMN_CREATED_AT) ||
(it->first == FM_ALARM_COLUMN_TIMESTAMP)){
append_str(keys,it->first);
params.param_values.push_back(it->second.c_str());
params.param_lengths.push_back(strlen(it->second.c_str()));
params.param_format.push_back(0);
sprintf(str, "$%lu::timestamp,", ++i);
} else if ((it->first == FM_ALARM_COLUMN_SERVICE_AFFECTING) ||
(it->first == FM_ALARM_COLUMN_SUPPRESSION) ||
(it->first == FM_ALARM_COLUMN_INHIBIT_ALARMS) ||
(it->first == FM_ALARM_COLUMN_MASKED)){
append_str(keys,it->first);
params.scratch[it->first] = (it->second == "True") ? 1 : 0;
params.param_values.push_back((char *)&(params.scratch[it->first]));
params.param_lengths.push_back(sizeof(bool));
params.param_format.push_back(1);
sprintf(str,"$%lu::boolean,", ++i);
} else if ((it->first == FM_ALARM_COLUMN_ALARM_ID) ||
(it->first == FM_EVENT_LOG_COLUMN_ID)){
std::string event_log_id = FM_EVENT_LOG_COLUMN_EVENT_ID;
append_str(keys,event_log_id);
params.param_values.push_back(it->second.c_str());
params.param_lengths.push_back(strlen(it->second.c_str()));
params.param_format.push_back(0);
sprintf(str,"$%lu::varchar,", ++i);
} else if ((it->first == FM_ALARM_COLUMN_ALARM_TYPE) ||
(it->first == FM_EVENT_LOG_COLUMN_EVENT_TYPE)){
std::string event_log_type = FM_EVENT_LOG_COLUMN_EVENT_TYPE;
append_str(keys,event_log_type);
params.param_values.push_back(it->second.c_str());
params.param_lengths.push_back(strlen(it->second.c_str()));
params.param_format.push_back(0);
sprintf(str,"$%lu::varchar,", ++i);
}else if (it->first == FM_ALARM_COLUMN_ALARM_STATE) {
std::string event_state = FM_EVENT_LOG_COLUMN_STATE;
append_str(keys,event_state);
params.param_values.push_back(it->second.c_str());
params.param_lengths.push_back(strlen(it->second.c_str()));
params.param_format.push_back(0);
sprintf(str,"$%lu::varchar,", ++i);
}
else {
append_str(keys,it->first);
params.param_values.push_back(it->second.c_str());
params.param_lengths.push_back(strlen(it->second.c_str()));
params.param_format.push_back(0);
sprintf(str,"$%lu::varchar,", ++i);
}
params.n_params++;
param.assign(str);
cmd_params += param;
}
cmd_params.resize(cmd_params.size()-1);
params.db_cmd = "INSERT INTO ";
params.db_cmd += FM_EVENT_LOG_TABLE_NAME;
params.db_cmd += " ( ";
params.db_cmd += keys;
params.db_cmd += ") VALUES (";
params.db_cmd += cmd_params;
params.db_cmd += ");";
return true;
}
bool fm_db_util_build_sql_update(const char* db_table,
const std::string & id, std::map<std::string,std::string> &map,
fm_db_util_sql_params &params, FMBoolTypeT masked){
std::string time_str;
params.db_cmd = "UPDATE ";
params.db_cmd += db_table;
params.db_cmd += " SET ";
fm_db_util_make_timestamp_string(time_str);
map[FM_ALARM_COLUMN_UPDATED_AT] = time_str;
map[FM_ALARM_COLUMN_MASKED] = masked ? "True" : "False";
std::map<std::string,std::string>::iterator at =
map.find(FM_ALARM_COLUMN_CREATED_AT);
if (at != map.end()){
map.erase(at);
}
std::map<std::string,std::string>::iterator it = map.begin();
std::map<std::string,std::string>::iterator end = map.end();
size_t i = 0;
char str[80];
std::string param;
for ( ; it != end ; ++it ) {
param.clear();
memset(str, 0, sizeof(str));
if (it != map.begin())
params.db_cmd.append(", ");
if ((it->first == FM_ALARM_COLUMN_UPDATED_AT) ||
(it->first == FM_ALARM_COLUMN_TIMESTAMP)){
params.param_values.push_back(it->second.c_str());
params.param_lengths.push_back(strlen(it->second.c_str()));
params.param_format.push_back(0);
sprintf(str, "$%lu::timestamp", ++i);
} else if ((it->first == FM_ALARM_COLUMN_SERVICE_AFFECTING) ||
(it->first == FM_ALARM_COLUMN_SUPPRESSION) ||
(it->first == FM_ALARM_COLUMN_INHIBIT_ALARMS) ||
(it->first == FM_ALARM_COLUMN_MASKED)){
params.scratch[it->first] = (it->second == "True") ? 1 : 0;
params.param_values.push_back((char *)&(params.scratch[it->first]));
params.param_lengths.push_back(sizeof(bool));
params.param_format.push_back(1);
sprintf(str,"$%lu::boolean", ++i);
} else {
params.param_values.push_back(it->second.c_str());
params.param_lengths.push_back(strlen(it->second.c_str()));
params.param_format.push_back(0);
sprintf(str,"$%lu::varchar", ++i);
}
param.assign(str);
FM_DB_UT_NAME_PARAM(params.db_cmd, it->first, param);
}
params.db_cmd += " WHERE ";
FM_DB_UT_NAME_VAL(params.db_cmd, FM_ALARM_COLUMN_ID, id);
return true;
}
bool fm_db_util_build_sql_delete(const char* db_table, AlarmFilter *db_data,
std::string &db_cmd){
if (db_data==NULL) return false;
char sql[FM_MAX_SQL_STATEMENT_MAX];
if (strlen(db_data->entity_instance_id) == 0){
snprintf(sql, sizeof(sql), "DElETE FROM %s WHERE %s = '%s' AND %s = ' '",
db_table, FM_ALARM_COLUMN_ALARM_ID, db_data->alarm_id,
FM_ALARM_COLUMN_ENTITY_INSTANCE_ID);
}
else{
snprintf(sql, sizeof(sql), "DElETE FROM %s WHERE %s = '%s' AND %s = '%s'",
db_table, FM_ALARM_COLUMN_ALARM_ID, db_data->alarm_id,
FM_ALARM_COLUMN_ENTITY_INSTANCE_ID, db_data->entity_instance_id);
}
db_cmd.assign(sql);
return true;
}
bool fm_db_util_build_sql_delete_row(const char* db_table, int id,
std::string &db_cmd){
if (id == 0) return false;
char sql[FM_MAX_SQL_STATEMENT_MAX];
snprintf(sql, sizeof(sql), "DElETE FROM %s WHERE %s = %d",
db_table, FM_ALARM_COLUMN_ID, id);
db_cmd.assign(sql);
return true;
}
bool fm_db_util_build_sql_delete_all(const char* db_table, const char *id,
std::string &db_cmd){
char sql[FM_MAX_SQL_STATEMENT_MAX];
snprintf(sql, sizeof(sql), "DElETE FROM %s WHERE %s like '%s%s'", db_table,
FM_ALARM_COLUMN_ENTITY_INSTANCE_ID, id,"%");
db_cmd.assign(sql);
return true;
}
void fm_db_util_set_conf_file(const char *fn){
conf = fn;
}
bool fm_db_util_get_config(std::string &key, std::string &val){
configParams::iterator it;
static int loaded = false;
CFmMutexGuard m(getConfMutex());
if (!loaded){
get_config_parameters();
loaded = true;
}
it = getConfigMap().find(key);
if (it != getConfigMap().end()){
val = it->second;
return true;
}
return false;
}
int & fm_get_alarm_history_max_size(){
static int max_size = 0;
if (max_size == 0){
std::string val;
std::string key = FM_EVENT_LOG_MAX_SIZE;
if (fm_db_util_get_config(key, val)){
max_size = fm_db_util_string_to_int(val);
}else{
FM_ERROR_LOG("Fail to get config value for (%s)\n", key.c_str());
}
}
return max_size;
}
int & fm_get_log_max_size(){
static int max_size = 0;
if (max_size == 0){
std::string val;
std::string key = FM_EVENT_LOG_MAX_SIZE;
if (fm_db_util_get_config(key, val)){
max_size = fm_db_util_string_to_int(val);
}else{
FM_ERROR_LOG("Fail to get config value for (%s)\n", key.c_str());
}
}
return max_size;
}
std::string fm_db_util_get_system_name(CFmDBSession &sess){
fm_db_result_t res;
std::string cmd;
std::string name = "";
fm_db_util_build_sql_query(FM_SYSTEM_TABLE_NAME, NULL, cmd);
if (sess.query(cmd.c_str(), res)){
if (res.size() > 0){
std::map<std::string,std::string> entry = res[0];
name = FM_ENTITY_ROOT_KEY + entry[FM_SYSTEM_NAME_COLUMN];
}
}
return name;
}
std::string fm_db_util_get_region_name(CFmDBSession &sess){
fm_db_result_t res;
std::string cmd;
std::string name = "";
fm_db_util_build_sql_query(FM_SYSTEM_TABLE_NAME, NULL, cmd);
if (sess.query(cmd.c_str(), res)){
if (res.size() > 0){
std::map<std::string,std::string> entry = res[0];
name = FM_ENTITY_REGION_KEY + entry[FM_SYSTEM_REGION_COLUMN];
}
}
return name;
}
bool fm_db_util_get_row_counts(CFmDBSession &sess,
const char* db_table, int &counts){
fm_db_result_t res;
std::string cmd =
FM_DB_SELECT_ROW_COUNTS_FROM_TABLE(std::string(db_table));
res.clear();
if (sess.query(cmd.c_str(), res)){
if (res.size() > 0){
std::map<std::string,std::string> entry = res[0];
counts = fm_db_util_string_to_int(entry[FM_DB_TABLE_COUNT_COLUMN]);
FM_DEBUG_LOG("Table (%s) row counts: (%llu)",
db_table, counts);
return true;
}
}
return false;
}
bool fm_db_util_get_next_log_id(CFmDBSession &sess, int &id){
pthread_mutex_lock(&mutex);
static bool has_max_rows = false;
static int max = 0;
int active = 0;
if (max == 0){
max = fm_get_log_max_size();
}
if (!has_max_rows){
fm_db_util_get_row_counts(sess, FM_EVENT_LOG_TABLE_NAME, active);
FM_INFO_LOG("Active row accounts:(%d), max:(%d)\n", active, max);
if (active >= max) {
has_max_rows = true;
}
}
if (has_max_rows){
std::string sql;
id = get_oldest_id(sess, FM_EVENT_LOG_TABLE_NAME);
fm_db_util_build_sql_delete_row(FM_EVENT_LOG_TABLE_NAME, id, sql);
FM_DEBUG_LOG("Delete row (%s)\n", sql.c_str());
if (false == sess.cmd(sql.c_str())){
FM_INFO_LOG("Fail to delete the old event log: (%d)", id);
pthread_mutex_unlock(&mutex);
return false;
}
}
FM_DEBUG_LOG("Return next log id: (%d)\n", id);
pthread_mutex_unlock(&mutex);
return true;
}
bool fm_db_util_create_session(CFmDBSession **sess){
TFmAlarmSessionT handle;
const char *db_conn = NULL;
std::string val;
std::string key = FM_SQL_CONNECTION;
if (fm_db_util_get_config(key, val) != true){
FM_ERROR_LOG("Failed to get config for key: (%s)\n", key.c_str());
return false;
}
db_conn = val.c_str();
if (fm_snmp_util_create_session(&handle, db_conn)){
*sess = (CFmDBSession*)handle;
return true;
}
return false;
}
bool fm_db_util_sync_event_suppression(void){
bool return_value = true;
const char *db_conn = NULL;
std::string val;
std::string key = FM_SQL_CONNECTION;
if (fm_db_util_get_config(key, val) != true){
FM_ERROR_LOG("Failed to get config for key: (%s)\n", key.c_str());
return false;
}
db_conn = val.c_str();
FILE* file;
int argc;
char * argv[2];
FM_INFO_LOG("Starting event suppression synchronization...\n");
argc = 2;
argv[0] = (char*)FM_DB_SYNC_EVENT_SUPPRESSION;
argv[1] = (char*)db_conn;
Py_SetProgramName(argv[0]);
Py_Initialize();
PySys_SetArgv(argc, argv);
file = fopen(FM_DB_SYNC_EVENT_SUPPRESSION,"r");
PyRun_SimpleFile(file, FM_DB_SYNC_EVENT_SUPPRESSION);
fclose(file);
Py_Finalize();
FM_INFO_LOG("Completed event suppression synchronization.\n");
return return_value;
}

View File

@ -0,0 +1,94 @@
//
// Copyright (c) 2014 Wind River Systems, Inc.
//
// SPDX-License-Identifier: Apache-2.0
//
#ifndef FMDBUTILS_H_
#define FMDBUTILS_H_
#include "fmAPI.h"
#include "fmDbAlarm.h"
#include "fmDbEventLog.h"
#include "fmDb.h"
#include <string>
#include <memory>
#include <vector>
static inline const char *FM_DB_AND() { return "AND"; }
static inline const char *FM_DB_WHERE() { return "WHERE"; }
static inline const char *FM_DB_SELECT_FROM() { return "SELECT * FROM"; }
static inline const char *FM_DB_SELECT_COUNTS() {
return "SELECT COUNT(*) FROM";
}
static inline const char *FM_DB_ORDERBY_TIME() { return "order by timestamp desc"; }
static inline std::string FM_DB_SELECT_FROM_TABLE(const std::string &table){
return std::string(FM_DB_SELECT_FROM()) + " " +table;
}
static inline std::string FM_DB_SELECT_ROW_COUNTS_FROM_TABLE(
const std::string &table){
return std::string(FM_DB_SELECT_COUNTS()) + " " +table;
}
void FM_DB_UT_NAME_VAL( std::string &result,
const std::string &lhs, const std::string &rhs);
void FM_DB_UT_NAME_PARAM( std::string &result,
const std::string &lhs, const std::string &rhs);
std::string fm_db_util_replace_single_quote(std::string const& original);
void fm_db_util_make_timestamp_string(std::string &tstr,
FMTimeT tm=0, bool snmp=false);
bool fm_db_util_get_timestamp(const char *str, FMTimeT &ft);
bool fm_db_util_build_sql_query(const char* db_table,
const char* db_query, std::string &db_cmd);
bool fm_db_util_build_sql_insert(const char* db_table,
std::map<std::string,std::string> &map,
fm_db_util_sql_params &parms);
bool fm_db_util_event_log_build_sql_insert(std::map<std::string,std::string> &map,
fm_db_util_sql_params &params);
bool fm_db_util_build_sql_update(const char* db_table,
const std::string & id, std::map<std::string,std::string> &map,
fm_db_util_sql_params &parms, FMBoolTypeT masked=0);
bool fm_db_util_build_sql_delete(const char* db_table,
AlarmFilter *db_data, std::string &db_cmd);
bool fm_db_util_build_sql_delete_row(const char* db_table, int id,
std::string &db_cmd);
bool fm_db_util_build_sql_delete_all(const char* db_table,
const char *id, std::string &db_cmd);
bool fm_db_util_get_row_counts(CFmDBSession &sess, const char* db_table,
int &counts);
bool fm_db_util_create_session(CFmDBSession **sess);
std::string fm_db_util_get_system_name(CFmDBSession &sess);
std::string fm_db_util_get_region_name(CFmDBSession &sess);
void fm_db_util_set_conf_file(const char *fn);
bool fm_db_util_get_config(std::string &key, std::string &val);
bool fm_db_util_get_next_log_id(CFmDBSession &sess, int &id);
std::string fm_db_util_int_to_string(int val);
int fm_db_util_string_to_int(std::string val);
bool fm_db_util_sync_event_suppression(void);
#endif /* FMDBUTILS_H_ */

View File

@ -0,0 +1,104 @@
//
// Copyright (c) 2016 Wind River Systems, Inc.
//
// SPDX-License-Identifier: Apache-2.0
//
#include <stdlib.h>
#include <string>
#include "fmDbConstants.h"
#include "fmLog.h"
#include "fmDbAlarm.h"
#include "fmEventSuppression.h"
bool CFmEventSuppressionOperation::get_event_suppressed(CFmDBSession &sess, SFmAlarmDataT &data, bool &is_event_suppressed) {
fm_db_result_t result;
if (get_single_event_suppression(sess, data.alarm_id, result)) {
if (result.size() > 0){
fm_db_single_result_t event_suppression = result[0];
std::string db_suppression_status = event_suppression[FM_EVENT_SUPPRESSION_COLUMN_SUPPRESSION_STATUS];
if (db_suppression_status.compare(FM_EVENT_SUPPRESSION_SUPPRESSED) == 0) {
is_event_suppressed = true;
} else {
is_event_suppressed = false;
}
} else
return false;
} else
return false;
return true;
}
bool CFmEventSuppressionOperation::get_single_event_suppression(CFmDBSession &sess, const char *alarm_id, fm_db_result_t & event_suppression) {
std::string sql;
std::string separator = ", ";
sql = "SELECT ";
sql += FM_EVENT_SUPPRESSION_COLUMN_CREATED_AT + separator;
sql += FM_EVENT_SUPPRESSION_COLUMN_UPDATED_AT + separator;
sql += FM_EVENT_SUPPRESSION_COLUMN_DELETED_AT + separator;
sql += FM_EVENT_SUPPRESSION_COLUMN_ID + separator;
sql += FM_EVENT_SUPPRESSION_COLUMN_UUID + separator;
sql += FM_EVENT_SUPPRESSION_COLUMN_ALARM_ID + separator;
sql += FM_EVENT_SUPPRESSION_COLUMN_DESCRIPTION + separator;
sql += FM_EVENT_SUPPRESSION_COLUMN_SUPPRESSION_STATUS;
sql += " FROM ";
sql += FM_EVENT_SUPPRESSION_TABLE_NAME;
sql += " WHERE ";
sql += FM_EVENT_SUPPRESSION_COLUMN_ALARM_ID;
sql += " = '";
sql += std::string(alarm_id);
sql += "'";
FM_DEBUG_LOG("CMD:(%s)\n", sql.c_str());
if ((sess.query(sql.c_str(), event_suppression)) != true){
return false;
}
return true;
}
bool CFmEventSuppressionOperation::set_table_notify_listen(CFmDBSession &sess){
std::string sql;
fm_db_result_t rule_name;
// Verify if rule already in table:
sql = "SELECT rulename FROM pg_rules WHERE rulename='watch_event_supression'";
if ((sess.query(sql.c_str(), rule_name)) != true){
return false;
}
if (rule_name.size() == 0 ) {
sql.clear();
sql = "CREATE RULE watch_event_supression AS ON UPDATE TO ";
sql += FM_EVENT_SUPPRESSION_TABLE_NAME;
sql += " DO (NOTIFY ";
sql += FM_EVENT_SUPPRESSION_TABLE_NAME;
sql += ")";
if (sess.cmd(sql.c_str()) != true){
return false;
}
}
sql.clear();
sql = "LISTEN ";
sql += FM_EVENT_SUPPRESSION_TABLE_NAME;
FM_DEBUG_LOG("CMD:(%s)\n", sql.c_str());
sess.cmd(sql.c_str()); // TODO: sess.cmd() returns false since no row affected by LISTEN command
/* if (sess.cmd(sql.c_str()) != true){
return false;
} */
return true;
}

View File

@ -0,0 +1,35 @@
//
// Copyright (c) 2016 Wind River Systems, Inc.
//
// SPDX-License-Identifier: Apache-2.0
//
#ifndef FMEVENTSUPPRESSION_H_
#define FMEVENTSUPPRESSION_H_
/*
#include <string>
#include <vector>
#include <stddef.h>
#include <map>
#include "fmAPI.h"
#include "fmDbConstants.h"
*/
#include "fmDb.h"
class CFmEventSuppressionOperation {
public:
bool get_event_suppressed(CFmDBSession &sess, SFmAlarmDataT &data, bool &is_event_suppressed);
bool get_single_event_suppression(CFmDBSession &sess, const char *alarm_id, fm_db_result_t & event_suppression);
bool set_table_notify_listen(CFmDBSession &sess);
};
#endif

View File

@ -0,0 +1,57 @@
//
// Copyright (c) 2014 Wind River Systems, Inc.
//
// SPDX-License-Identifier: Apache-2.0
//
#include <unistd.h>
#include <algorithm>
#include <string.h>
#include "fmFile.h"
#include "fmLog.h"
#define FM_FILE_MODE_MAX 10
#define FM_FILE_SIZE_MAX 2056
bool CfmFile::open(const char *path,eFileAccess a, bool binary) {
char attr[FM_FILE_MODE_MAX];
switch(a) {
case READ: strcpy(attr,"r");
break;
case READ_WRITE: strcpy(attr,"r+");
break;
case WRITE: strcpy(attr,"w");
break;
case APPEND: strcpy(attr,"a");
break;
}
if (binary) {
strcat(attr,"b");
}
fp = fopen(path,attr);
return fp!=NULL;
}
int is_return_char(int c) {
return (((char)c)=='\n' || ((char)c)=='\r') ? 1 : 0;
}
bool CfmFile::read_line(std::string &s) {
char st[MAX_LINE_LEN];
bool b = fgets(st,sizeof(st)-1,fp)!=NULL;
if (b) {
s = st;
s.erase(std::find_if(s.begin(), s.end(), std::ptr_fun<int, int>(is_return_char)),s.end());
} else s = "";
return b;
}
void CfmFile::close(){
fclose(fp);
}

View File

@ -0,0 +1,36 @@
//
// Copyright (c) 2014 Wind River Systems, Inc.
//
// SPDX-License-Identifier: Apache-2.0
//
#ifndef fmFILE_H_
#define fmFILE_H_
#include <stdio.h>
#include <string>
#include <vector>
class CfmFile {
enum {MAX_LINE_LEN = 4096 };
FILE * fp;
public:
enum eFileAccess {READ, READ_WRITE, WRITE, APPEND};
CfmFile() : fp(NULL) {}
virtual ~CfmFile() { if (fp!=NULL) fclose(fp); }
bool valid() { return fp!=NULL; }
bool open(const char *fn,eFileAccess a, bool binary=false);
void close();
virtual bool read_line(std::string &line);
};
#endif

169
fm-common/sources/fmLog.cpp Normal file
View File

@ -0,0 +1,169 @@
//
// Copyright (c) 2014 Wind River Systems, Inc.
//
// SPDX-License-Identifier: Apache-2.0
//
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include "fmLog.h"
#include "fmDbAlarm.h"
#include "fmDbEventLog.h"
#include <stdarg.h>
#include <syslog.h>
static pthread_mutex_t mutex = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;
static char * escape_json(const char * s, char * buffer, const int bufLen);
void fmLoggingInit() {
static bool has_inited=false;
if (!has_inited){
openlog(NULL,LOG_CONS | LOG_NDELAY,LOG_LOCAL1);
setlogmask(LOG_UPTO (LOG_INFO));
}
has_inited=true;
}
void fmLogMsg(int level, const char *data,...){
va_list ap;
va_start(ap, data);
vsyslog(level,data,ap);
va_end(ap);
}
bool fmLogFileInit(){
fmLoggingInit();
return true;
}
// formats event into json form for logging
static char * formattedEvent(CFmDbEventLog::data_type event_map, char * output, int outputSize) {
int bufLen = 1024;
char * buffer = (char *) malloc(bufLen);
int outputLen = 0;
snprintf(output + outputLen, outputSize - outputLen, "{ \"%s\" : \"%s\", ", "event_log_id", escape_json(event_map["event_log_id"].c_str(), buffer, bufLen));
outputLen = strlen(output);
snprintf(output + outputLen, outputSize - outputLen, "\"%s\" : \"%s\", ", "reason_text", escape_json(event_map["reason_text"].c_str(), buffer, bufLen));
outputLen = strlen(output);
snprintf(output + outputLen, outputSize - outputLen, "\"%s\" : \"%s\", ", "entity_instance_id", escape_json(event_map["entity_instance_id"].c_str(), buffer, bufLen));
outputLen = strlen(output);
snprintf(output + outputLen, outputSize - outputLen, "\"%s\" : \"%s\", ", "severity", escape_json(event_map["severity"].c_str(), buffer, bufLen));
outputLen = strlen(output);
snprintf(output + outputLen, outputSize - outputLen, "\"%s\" : \"%s\", ", "state", escape_json(event_map["state"].c_str(), buffer, bufLen));
outputLen = strlen(output);
snprintf(output + outputLen, outputSize - outputLen, "\"%s\" : \"%s\" }", "timestamp", escape_json(event_map["timestamp"].c_str(), buffer, bufLen));
free(buffer);
return output;
}
// logs event to syslog
void fmLogEVT(int level, CFmDbEventLog::data_type event_map) {
char * output = (char*) malloc(2048);
char * msg = formattedEvent(event_map, output, 2048);
fmLogMsg(level,msg);
free(output);
}
void fmLogAddEventLog(SFmAlarmDataT * data, bool is_event_suppressed){
pthread_mutex_lock(&mutex);
CFmDbEventLog event;
CFmDbEventLog::data_type event_map;
event.create_data(data);
event.export_data(event_map);
fmLogEVT(fmLogLevelInfo | LOG_LOCAL5, event_map);
pthread_mutex_unlock(&mutex);
}
// Converts a string (s) to be json safe. Special characters are escaped and written to buffer.
static char * escape_json(const char * s, char * buffer, const int bufLen) {
int sLen = -1;
int bufLeft = bufLen;
int s_i = 0;
int buf_i = 0;
int ch;
char tmp_buf[16];
char * escapedChrs = NULL;
int escapedChrsLen = -1;
if (s==NULL || buffer==NULL || bufLen<1) {
return buffer;
}
sLen = strlen(s);
buffer[0] = 0;
if (s == 0) {
return buffer;
}
while (s_i < sLen && bufLeft > 0) {
ch = s[s_i];
switch (ch) {
case '\"':
escapedChrs = (char *) "\\\"";
break;
case '\\':
escapedChrs = (char *) "\\\\";
break;
case '\b':
escapedChrs = (char *) "\\b";
break;
case '\f':
escapedChrs = (char *) "\\f";
break;
case '\n':
escapedChrs = (char *) "\\n";
break;
case '\r':
escapedChrs = (char *) "\\r";
break;
case '\t':
escapedChrs = (char *) "\\t";
break;
default:
if (ch < 0) {
ch = 0xFFFD; /* replacement character */
}
if (ch > 0xFFFF) {
/* beyond BMP (Basic Multilingual Plane); need a surrogate pair
* for reference, see: https://en.wikipedia.org/wiki/Plane_%28Unicode%29
*/
snprintf(tmp_buf, sizeof(tmp_buf), "\\u%04X\\u%04X",
0xD800 + ((ch - 0x10000) >> 10),
0xDC00 + ((ch - 0x10000) & 0x3FF));
} else if (ch < 0x20 || ch >= 0x7F) {
snprintf(tmp_buf, sizeof(tmp_buf), "\\u%04X", ch);
} else {
tmp_buf[0] = ch;
tmp_buf[1] = 0;
}
escapedChrs = tmp_buf;
}
escapedChrsLen = strlen(escapedChrs);
if (bufLeft <= escapedChrsLen) {
break;
}
strncpy(&buffer[buf_i], escapedChrs, bufLeft );
bufLeft -= escapedChrsLen;
buf_i += escapedChrsLen;
s_i++;
}
return buffer;
}

76
fm-common/sources/fmLog.h Normal file
View File

@ -0,0 +1,76 @@
//
// Copyright (c) 2014 Wind River Systems, Inc.
//
// SPDX-License-Identifier: Apache-2.0
//
#ifndef FMLOG_H_
#define FMLOG_H_
#include <stdio.h>
#include <syslog.h>
#include "fmAPI.h"
extern "C" {
}
enum {
fmLogLevelCritical=LOG_CRIT,
fmLogLevelError=LOG_ERR,
fmLogLevelWarning=LOG_WARNING,
fmLogLevelNotice=LOG_NOTICE,
fmLogLevelInfo = LOG_INFO,
fmLogLevelDebug=LOG_DEBUG,
};
#define FM_LOG_LINE_TO_STRING_impl(x) #x
#define FM_LOG_LINE_TO_STRING(x) FM_LOG_LINE_TO_STRING_impl(x)
#define PRINTF(data,...) printf(data,## __VA_ARGS__)
#define FM_TRACE_LOG(data,...) \
PRINTF(data,## __VA_ARGS__)
#define FM_LOG_MSG(level,data,...) \
fmLogMsg(level, __FILE__ "(" \
FM_LOG_LINE_TO_STRING(__LINE__) "): " \
data, ## __VA_ARGS__ )
#define FM_INFO_LOG(data,...) \
FM_LOG_MSG(fmLogLevelInfo,data,## __VA_ARGS__)
#define FM_DEBUG_LOG(data,...) \
FM_LOG_MSG(fmLogLevelDebug,data,## __VA_ARGS__)
#define FM_NOTICE_LOG(data,...) \
FM_LOG_MSG(fmLogLevelNotice,data,## __VA_ARGS__)
#define FM_WARNING_LOG(data,...) \
FM_LOG_MSG(fmLogLevelWarning,data,## __VA_ARGS__)
#define FM_ERROR_LOG(data,...) \
FM_LOG_MSG(fmLogLevelError,data,## __VA_ARGS__)
#define FM_CRITICAL_LOG(data,...) \
FM_LOG_MSG(fmLogLevelCritical,data,## __VA_ARGS__)
#define FM_MAX_LOG_LENGTH 992
void fmLoggingInit();
void fmLogMsg(int level, const char *data, ...);
bool fmLogFileInit();
void fmLogAddEventLog(SFmAlarmDataT * data, bool is_event_suppressed);
//void fmLogAddEventLog(SFmAlarmDataT * data);
#endif

69
fm-common/sources/fmMsg.h Normal file
View File

@ -0,0 +1,69 @@
//
// Copyright (c) 2014 Wind River Systems, Inc.
//
// SPDX-License-Identifier: Apache-2.0
//
#ifndef _FM_MSG_H
#define _FM_MSG_H
#include <vector>
#include "fmAPI.h"
#include <stdint.h>
#define FM_MSG_VAL_KEY (0x1a0ff11d)
#define FM_MSG_WAIT_FAIL (5)
#define FM_MSG_MAX_RET (2)
#define FM_MSG_INF_WAIT (0)
typedef enum {
EFmMsgV1= 1,
EFmMaxVersion
}EFmMsgVersionT;
typedef enum {
EFmMsgRx=0,
EFmMsgTx=1,
EFmMsgMax
}EFmMsgTypesT;
typedef enum {
EFmCreateFault = 0,
EFmUpdateFault,
EFmDeleteFault,
EFmDeleteFaults,
EFmGetFault,
EFmGetFaults,
EFmReturnUUID,
EFmGetFaultsById,
EFmActMax
}EFmMsgActionsT;
typedef struct {
EFmMsgVersionT version;
EFmMsgActionsT action;
uint32_t msg_size;
uint32_t msg_rc; //filled in by server
} SFmMsgHdrT;
typedef std::vector<char> fm_buff_t;
EFmErrorT fm_msg_utils_prep_requet_msg(fm_buff_t &buff,
EFmMsgActionsT act, const void * data, uint32_t len) ;
static inline void * ptr_to_data(fm_buff_t &buff) {
return &(buff[sizeof(SFmMsgHdrT)]);
}
static inline SFmMsgHdrT * ptr_to_hdr(fm_buff_t &buff) {
return (SFmMsgHdrT *)&(buff[0]);
}
static inline bool fm_valid_srv_msg(SFmMsgHdrT *msg, uint32_t exp_size) {
return (msg->msg_size==exp_size);
}
#endif /* _FM_MSG_H */

View File

@ -0,0 +1,735 @@
//
// Copyright (c) 2017 Wind River Systems, Inc.
//
// SPDX-License-Identifier: Apache-2.0
//
#include <stdio.h>
#include <errno.h>
#include <list>
#include <new>
#include <vector>
#include <map>
#include <string>
#include <string.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <inttypes.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <algorithm>
#include <functional>
#include <cctype>
#include <locale>
#include <signal.h>
#include <pthread.h>
#include <libpq-fe.h>
#include "fmMsgServer.h"
#include "fmThread.h"
#include "fmSocket.h"
#include "fmAPI.h"
#include "fmMsg.h"
#include "fmAlarmUtils.h"
#include "fmLog.h"
#include "fmMutex.h"
#include "fmDbAlarm.h"
#include "fmSnmpConstants.h"
#include "fmSnmpUtils.h"
#include "fmDbUtils.h"
#include "fmDbEventLog.h"
#include "fmDbConstants.h"
#include "fmEventSuppression.h"
#define FM_UUID_LENGTH 36
typedef struct{
int fd;
fm_buff_t data;
}sFmGetReq;
typedef struct{
int type;
bool set;
SFmAlarmDataT data;
}sFmJobReq;
typedef std::list<sFmGetReq> fmGetList;
typedef std::list<sFmJobReq> fmJobList;
CFmMutex & getJobMutex(){
static CFmMutex *m = new CFmMutex;
return *m;
}
CFmMutex & getListMutex(){
static CFmMutex *m = new CFmMutex;
return *m;
}
CFmMutex & getSockMutex(){
static CFmMutex *m = new CFmMutex;
return *m;
}
// trim from end
static inline std::string &rtrim(std::string &s) {
s.erase(std::find_if(s.rbegin(), s.rend(),
std::not1(std::ptr_fun<int, int>(std::isspace))).base(), s.end());
return s;
}
fmJobList & getJobList(){
static fmJobList lst;
return lst;
}
fmGetList& getList(){
static fmGetList lst;
return lst;
}
static void enqueue_job(sFmJobReq &req){
CFmMutexGuard m(getJobMutex());
getJobList().push_back(req);
}
static bool dequeue_job(sFmJobReq &req){
if (getJobList().size() == 0){
//FM_DEBUG_LOG("Job queue is empty\n");
return false;
}
CFmMutexGuard m(getJobMutex());
fmJobList::iterator it = getJobList().begin();
req = (*it);
getJobList().pop_front();
return true;
}
static void enqueue_get(sFmGetReq &req){
CFmMutexGuard m(getListMutex());
getList().push_back(req);
}
static bool dequeue_get(sFmGetReq &req){
if (getList().size() == 0){
//FM_DEBUG_LOG("Job queue is empty\n");
return false;
}
CFmMutexGuard m(getListMutex());
fmGetList::iterator it = getList().begin();
req = (*it);
getList().pop_front();
return true;
}
void create_db_log(CFmDBSession &sess, sFmJobReq &req){
SFmAlarmDataT alarm = req.data;
if (alarm.alarm_state != FM_ALARM_STATE_MSG){
FM_ERROR_LOG("Unexpected request :(%d) (%s) (%s)", alarm.alarm_state,
alarm.alarm_id, alarm.entity_instance_id);
return;
}
fmLogAddEventLog(&alarm, false);
fm_snmp_util_gen_trap(sess, FM_ALARM_MESSAGE, alarm);
}
void get_db_alarm(CFmDBSession &sess, sFmGetReq &req, void *context){
fm_buff_t buff = req.data;
SFmMsgHdrT *hdr = (SFmMsgHdrT *)&buff[0];
void * data = &buff[sizeof(SFmMsgHdrT)];
AlarmFilter *filter = (AlarmFilter *)data;
FmSocketServerProcessor *srv = (FmSocketServerProcessor *)context;
CFmDbAlarmOperation op;
fm_db_result_t res;
SFmAlarmDataT alarm;
memset(&alarm, 0, sizeof(alarm));
hdr->msg_rc = FM_ERR_OK;
res.clear();
if ((op.get_alarm(sess, *filter, res)) != true){
hdr->msg_rc = FM_ERR_DB_OPERATION_FAILURE;
}else if (res.size() > 0){
FM_INFO_LOG("Get alarm: (%s) (%s)\n", filter->alarm_id,
filter->entity_instance_id);
CFmDbAlarm::convert_to(res[0],&alarm);
}else{
hdr->msg_rc = FM_ERR_ENTITY_NOT_FOUND;
}
if (hdr->msg_rc == FM_ERR_OK) {
FM_DEBUG_LOG("Send resp: uuid (%s), alarm_id (%s)\n",
alarm.uuid, alarm.alarm_id);
srv->send_response(req.fd,hdr,&alarm,sizeof(alarm));
}else{
std::string err = fm_error_from_int((EFmErrorT)hdr->msg_rc);
FM_DEBUG_LOG("Get alarm (%s) (%s) failed,send resp:(%s)\n",
filter->alarm_id, filter->entity_instance_id, err.c_str());
srv->send_response(req.fd,hdr,NULL,0);
}
}
void get_db_alarms(CFmDBSession &sess, sFmGetReq &req, void *context){
fm_buff_t buff = req.data;
SFmMsgHdrT *hdr = (SFmMsgHdrT *)&buff[0];
void * data = &buff[sizeof(SFmMsgHdrT)];
fm_ent_inst_t *pid = (fm_ent_inst_t *)(data);
fm_ent_inst_t &id = *pid;
FmSocketServerProcessor *srv = (FmSocketServerProcessor *)context;
CFmDbAlarmOperation op;
fm_db_result_t res;
std::vector<SFmAlarmDataT> alarmv;
FM_DEBUG_LOG("handle get_db_alarms:%s\n", id);
hdr->msg_rc = FM_ERR_OK;
res.clear();
if (op.get_alarms(sess, id, res) != true){
hdr->msg_rc = FM_ERR_DB_OPERATION_FAILURE;
}else if (res.size() > 0){
int ix = 0;
int resp_len = res.size();
SFmAlarmDataT alarm;
alarmv.clear();
for ( ; ix < resp_len ; ++ix ) {
CFmDbAlarm::convert_to(res[ix],&alarm);
alarmv.push_back(alarm);
}
}else{
FM_DEBUG_LOG("No alarms found for entity_instance_id (%s)\n", id);
hdr->msg_rc = FM_ERR_ENTITY_NOT_FOUND;
}
if ((hdr->msg_rc==FM_ERR_OK) && (alarmv.size() > 0)){
int found_num_alarms=alarmv.size();
int total_len =(found_num_alarms * sizeof(SFmAlarmDataT)) + sizeof(uint32_t);
void * buffer = malloc(total_len);
if (buffer==NULL) {
hdr->msg_rc =FM_ERR_SERVER_NO_MEM;
srv->send_response(req.fd,hdr,NULL,0);
return;
}
uint32_t *alen = (uint32_t*) buffer;
*alen =found_num_alarms;
SFmAlarmDataT * alarms = (SFmAlarmDataT*) ( ((char*)buffer)+sizeof(uint32_t));
memcpy(alarms,&(alarmv[0]),alarmv.size() * sizeof(SFmAlarmDataT));
srv->send_response(req.fd,hdr,buffer,total_len);
free(buffer);
} else {
srv->send_response(req.fd,hdr,NULL,0);
}
}
void get_db_alarms_by_id(CFmDBSession &sess, sFmGetReq &req, void *context){
fm_buff_t buff = req.data;
SFmMsgHdrT *hdr = (SFmMsgHdrT *)&buff[0];
void * data = &buff[sizeof(SFmMsgHdrT)];
fm_alarm_id *aid = (fm_alarm_id *)(data);
fm_alarm_id &id = *aid;
FmSocketServerProcessor *srv = (FmSocketServerProcessor *)context;
CFmDbAlarmOperation op;
fm_db_result_t res;
std::vector<SFmAlarmDataT> alarmv;
FM_DEBUG_LOG("handle get_db_alarms_by_id:%s\n", id);
hdr->msg_rc = FM_ERR_OK;
res.clear();
if (op.get_alarms_by_id(sess, id, res) != true){
hdr->msg_rc = FM_ERR_DB_OPERATION_FAILURE;
}else if (res.size() > 0){
int ix = 0;
int resp_len = res.size();
CFmDbAlarm dbAlm;
SFmAlarmDataT alarm;
alarmv.clear();
for ( ; ix < resp_len ; ++ix ) {
CFmDbAlarm::convert_to(res[ix],&alarm);
alarmv.push_back(alarm);
}
}else{
FM_DEBUG_LOG("No alarms found for alarm_id (%s)\n", id);
hdr->msg_rc = FM_ERR_ENTITY_NOT_FOUND;
}
if ((hdr->msg_rc==FM_ERR_OK) && (alarmv.size() > 0)){
int found_num_alarms=alarmv.size();
int total_len =(found_num_alarms * sizeof(SFmAlarmDataT)) + sizeof(uint32_t);
void * buffer = malloc(total_len);
if (buffer==NULL) {
hdr->msg_rc =FM_ERR_SERVER_NO_MEM;
srv->send_response(req.fd,hdr,NULL,0);
return;
}
uint32_t *alen = (uint32_t*) buffer;
*alen =found_num_alarms;
SFmAlarmDataT * alarms = (SFmAlarmDataT*) ( ((char*)buffer)+sizeof(uint32_t));
memcpy(alarms,&(alarmv[0]),alarmv.size() * sizeof(SFmAlarmDataT));
srv->send_response(req.fd,hdr,buffer,total_len);
free(buffer);
} else {
srv->send_response(req.fd,hdr,NULL,0);
}
}
void fm_handle_job_request(CFmDBSession &sess, sFmJobReq &req){
CFmDbAlarmOperation op;
CFmEventSuppressionOperation event_suppression_op;
//check if it is a customer log request
if (req.type == FM_CUSTOMER_LOG) {
return create_db_log(sess,req);
}
// check to see if there are any alarms need to be masked/unmasked
if (req.type != FM_ALARM_HIERARCHICAL_CLEAR){
if (req.data.inhibit_alarms){
FM_INFO_LOG("%s alarms: (%s)\n", req.set ? "Mask" : "Unmask",
req.data.entity_instance_id);
op.mask_unmask_alarms(sess, req.data, req.set);
}
}
if (!op.add_alarm_history(sess, req.data, req.set)){
FM_ERROR_LOG("Failed to add historical alarm to DB (%s) (%s",
req.data.alarm_id, req.data.entity_instance_id);
}
bool is_event_suppressed = false;
if ((req.type != FM_ALARM_HIERARCHICAL_CLEAR) &&
(!event_suppression_op.get_event_suppressed(sess, req.data, is_event_suppressed))) {
FM_ERROR_LOG("Failed to retrieve event suppression status in DB for (%s)",
req.data.alarm_id);
} else {
if (!is_event_suppressed)
fm_snmp_util_gen_trap(sess, req.type, req.data);
}
fmLogAddEventLog(&req.data, is_event_suppressed);
}
void fm_handle_get_request(CFmDBSession &sess, sFmGetReq &req,
void *context){
fm_buff_t buff = req.data;
SFmMsgHdrT *hdr = (SFmMsgHdrT *)&buff[0];
switch(hdr->action) {
case EFmGetFault:get_db_alarm(sess,req,context); break;
case EFmGetFaults:get_db_alarms(sess,req,context); break;
case EFmGetFaultsById:get_db_alarms_by_id(sess,req,context); break;
default:
FM_ERROR_LOG("Unexpected job request, action:%u\n",hdr->action);
break;
}
}
inline void * prep_msg_buffer(std::vector<char> &buff, int reserved_size,
SFmMsgHdrT *&hdr) {
buff.resize(sizeof(SFmMsgHdrT) + reserved_size);
hdr = (SFmMsgHdrT*)&(buff[0]);
hdr->msg_size = reserved_size;
hdr->version = EFmMsgV1;
hdr->msg_rc = 0;
return &(buff[sizeof(SFmMsgHdrT)]);
}
#define is_request_valid(len,structdata) \
if (len != sizeof(structdata)) { \
hdr->msg_rc = FM_ERR_INVALID_REQ; \
send_response(fd,hdr,NULL,0); \
return; \
}
void FmSocketServerProcessor::send_response(int fd, SFmMsgHdrT *hdr, void *data, size_t len) {
fm_buff_t resp;
CFmMutexGuard m(getSockMutex());
if (fm_msg_utils_prep_requet_msg(resp,hdr->action,data,len)!=FM_ERR_OK) {
rm_socket(fd);
FM_INFO_LOG("Failed to prepare response, close fd:(%d)", fd);
::close(fd);
return;
}
ptr_to_hdr(resp)->msg_rc = hdr->msg_rc;
if (!write_packet(fd,resp)){
FM_INFO_LOG("Failed to send response, close fd:(%d)", fd);
rm_socket(fd);
::close(fd);
return;
}
}
void FmSocketServerProcessor::handle_create_fault(int fd,
SFmMsgHdrT *hdr, std::vector<char> &rdata, CFmDBSession &sess) {
is_request_valid(hdr->msg_size,SFmAlarmDataT);
void * data = &(rdata[sizeof(SFmMsgHdrT)]);
CFmDbAlarmOperation op;
CFmDbEventLogOperation log_op;
CFmDbEventLog dbLog;
CFmDbAlarm a;
sFmJobReq req;
SFmAlarmDataT *alarm = (SFmAlarmDataT *)(data);
FM_DEBUG_LOG("Time stamp in the alarm message: (%lld)", alarm->timestamp);
if ((strlen(alarm->uuid)) != FM_UUID_LENGTH) {
fm_uuid_create(alarm->uuid);
}
hdr->msg_rc = FM_ERR_OK;
req.data = *alarm;
req.set = true;
FM_INFO_LOG("Raising Alarm/Log, (%s) (%s)", alarm->alarm_id, alarm->entity_instance_id);
//enqueue the customer log request after writing it the DB
if (alarm->alarm_state == FM_ALARM_STATE_MSG) {
alarm->alarm_state = FM_ALARM_STATE_LOG;
dbLog.create_data(alarm);
if (log_op.create_event_log(sess, dbLog)) {
FM_INFO_LOG("Log generated in DB: (%s) (%s) (%d)\n",
alarm->alarm_id, alarm->entity_instance_id, alarm->severity);
req.type = FM_CUSTOMER_LOG;
enqueue_job(req);
}else{
FM_ERROR_LOG("Fail to create customer log: (%s) (%s)\n",
alarm->alarm_id, alarm->entity_instance_id);
hdr->msg_rc = FM_ERR_DB_OPERATION_FAILURE;
}
FM_INFO_LOG("Send response for create log, uuid:(%s) (%u)\n",
alarm->uuid, hdr->msg_rc);
send_response(fd,hdr,alarm->uuid,sizeof(alarm->uuid));
} else {
a.create_data(alarm);
//a.print();
if (op.create_alarm(sess,a)){
FM_INFO_LOG("Alarm created/updated: (%s) (%s) (%d) (%s)\n",
alarm->alarm_id, alarm->entity_instance_id, alarm->severity, alarm->uuid);
req.type = alarm->severity;
enqueue_job(req);
}else{
FM_ERROR_LOG("Fail to created/updated alarm: (%s) (%s)\n",
alarm->alarm_id, alarm->entity_instance_id);
hdr->msg_rc = FM_ERR_DB_OPERATION_FAILURE;
}
FM_INFO_LOG("Send response for create fault, uuid:(%s) (%u)\n",
alarm->uuid, hdr->msg_rc);
send_response(fd,hdr,alarm->uuid,sizeof(alarm->uuid));
}
}
void FmSocketServerProcessor::handle_delete_faults(int fd,
SFmMsgHdrT *hdr, std::vector<char> &rdata, CFmDBSession &sess) {
CFmDbAlarmOperation op;
sFmJobReq req;
is_request_valid(hdr->msg_size,fm_ent_inst_t);
void * data = &(rdata[sizeof(SFmMsgHdrT)]);
fm_ent_inst_t *pid = (fm_ent_inst_t *)(data);
fm_ent_inst_t &id = *pid;
hdr->msg_rc = FM_ERR_OK;
if (op.delete_alarms(sess,id)){
FM_DEBUG_LOG("Deleted alarms (%s)\n", id);
SFmAlarmDataT alarm;
memset(&alarm, 0, sizeof(alarm));
//only cares about entity_instance_id in hierarchical alarm clear trap
strncpy(alarm.entity_instance_id, id, sizeof(alarm.entity_instance_id)-1);
strncpy(alarm.reason_text,CLEAR_ALL_REASON_TEXT,
sizeof(alarm.reason_text)-1);
fm_uuid_create(alarm.uuid);
req.type = FM_ALARM_HIERARCHICAL_CLEAR;
req.set = false;
req.data = alarm;
enqueue_job(req);
}else{
FM_INFO_LOG("Fail to Delete alarms (%s)\n", id);
hdr->msg_rc = FM_ERR_DB_OPERATION_FAILURE;
}
send_response(fd,hdr,NULL,0);
}
void FmSocketServerProcessor::handle_delete_fault(int fd,
SFmMsgHdrT *hdr, std::vector<char> &rdata, CFmDBSession &sess) {
CFmDbAlarmOperation op;
sFmJobReq req;
CFmDbAlarm dbAlm;
SFmAlarmDataT alarm;
fm_db_result_t res;
is_request_valid(hdr->msg_size,AlarmFilter);
void * data = &(rdata[sizeof(SFmMsgHdrT)]);
AlarmFilter *filter = (AlarmFilter *)(data);
hdr->msg_rc = FM_ERR_OK;
res.clear();
if ((op.get_alarm(sess, *filter, res)) != true){
hdr->msg_rc = FM_ERR_DB_OPERATION_FAILURE;
}else{
if (res.size() > 0){
if(op.delete_alarm(sess, *filter)){
FM_INFO_LOG("Deleted alarm: (%s) (%s)\n",
filter->alarm_id, filter->entity_instance_id);
CFmDbAlarm::convert_to(res[0],&alarm);
fm_uuid_create(alarm.uuid);
req.type = FM_ALARM_CLEAR;
req.set = false;
req.data = alarm;
enqueue_job(req);
}else{
hdr->msg_rc = FM_ERR_DB_OPERATION_FAILURE;
}
}else{
hdr->msg_rc = FM_ERR_ENTITY_NOT_FOUND;
FM_INFO_LOG("Deleted alarm failed: (%s) (%s) (%s)\n",
filter->alarm_id, filter->entity_instance_id,
fm_error_from_int((EFmErrorT)hdr->msg_rc).c_str());
}
}
FM_INFO_LOG("Response to delete fault: %u\n", hdr->msg_rc);
send_response(fd,hdr,NULL,0);
}
void FmSocketServerProcessor::handle_get_faults_by_id(int fd,
SFmMsgHdrT *hdr, std::vector<char> &rdata) {
is_request_valid(hdr->msg_size,fm_alarm_id);
sFmGetReq req;
req.fd = fd;
req.data = rdata;
enqueue_get(req);
}
void FmSocketServerProcessor::handle_get_faults(int fd,
SFmMsgHdrT *hdr, std::vector<char> &rdata) {
is_request_valid(hdr->msg_size,fm_ent_inst_t);
sFmGetReq req;
req.fd = fd;
req.data = rdata;
enqueue_get(req);
}
void FmSocketServerProcessor::handle_get_fault(int fd,
SFmMsgHdrT *hdr, std::vector<char> &rdata) {
is_request_valid(hdr->msg_size,AlarmFilter);
sFmGetReq req;
req.fd = fd;
req.data = rdata;
enqueue_get(req);
}
void FmSocketServerProcessor::handle_socket_data(int fd,
std::vector<char> &rdata, CFmDBSession &sess) {
SFmMsgHdrT *hdr = (SFmMsgHdrT *)&(rdata[0]);
FM_DEBUG_LOG("Processor: handler socket data, action:%u\n",hdr->action);
switch(hdr->action) {
case EFmCreateFault:handle_create_fault(fd,hdr,rdata, sess); break;
case EFmDeleteFault:handle_delete_fault(fd, hdr,rdata, sess); break;
case EFmDeleteFaults:handle_delete_faults(fd,hdr,rdata,sess); break;
case EFmGetFault:handle_get_fault(fd,hdr,rdata); break;
case EFmGetFaults:handle_get_faults(fd,hdr,rdata); break;
case EFmGetFaultsById:handle_get_faults_by_id(fd,hdr,rdata); break;
default:
FM_ERROR_LOG("Unexpected client request, action:%u\n",hdr->action);
break;
}
}
extern "C" {
EFmErrorT fm_server_create(const char *fn) {
signal(SIGPIPE,SIG_IGN);
FmSocketServerProcessor srv;
size_t retries = 5, count = 0, my_sleep = 2000;//2 seconds
const std::string host = "controller";
int rc = 0;
bool rt = false;
struct addrinfo hints;
struct addrinfo *result=NULL, *rp;
char addr[INET6_ADDRSTRLEN];
memset(&hints,0,sizeof(hints));
hints.ai_family = AF_UNSPEC; /* Allow IPv4 or IPv6 */
hints.ai_socktype = SOCK_STREAM; /* Datagram socket */
hints.ai_flags = 0; /* For wildcard IP address */
hints.ai_protocol = 0; /* Any protocol */
hints.ai_canonname = NULL;
hints.ai_addr = NULL;
hints.ai_next = NULL;
fmLoggingInit();
if (!fmLogFileInit()){
exit(-1);
}
fm_db_util_set_conf_file(fn);
if (!fm_db_util_sync_event_suppression()){
exit(-1);
}
if (!fmCreateThread(fmJobHandlerThread,NULL)) {
exit(-1);
}
if (!fmCreateThread(fmRegHandlerThread,&srv)) {
exit(-1);
}
if (!fmCreateThread(fmEventSuppressionMonitorThread,NULL)) {
exit(-1);
}
FM_INFO_LOG("Starting fmManager...\n");
while (true) {
rc = getaddrinfo(host.c_str(),NULL, &hints,&result);
if (rc == 0){
for (rp = result; rp != NULL; rp = rp->ai_next) {
if (rp->ai_family==AF_INET||rp->ai_family==AF_INET6) {
if(rp->ai_family==AF_INET) {
inet_ntop(AF_INET, &(((sockaddr_in*)rp->ai_addr)->sin_addr), addr, sizeof(addr));
} else if (rp->ai_family==AF_INET6) {
inet_ntop(AF_INET6, &(((sockaddr_in6*)rp->ai_addr)->sin6_addr), addr, sizeof(addr));
}
rt = srv.server_sock(addr,8001,rp->ai_family);
if (rt == true) break;
if (count < retries){
FM_INFO_LOG("Bind (%s) (%s) address failed, error: (%d) (%s)",
host.c_str(), addr, errno, strerror(errno));
}
}
}
freeaddrinfo(result);
}else{
FM_INFO_LOG("(%s) address lookup failed, error: (%d) (%s)",
host.c_str(),errno, strerror(errno));
}
if (rt ==true) break;
if (count > retries){
FM_ERROR_LOG("Failed to bind to controller IP, exit...");
exit(-1);
}
fmThreadSleep(my_sleep);
count++;
}
if ( rt == false)
return (EFmErrorT)-1;
srv.run();
return FM_ERR_OK;
}
void fmJobHandlerThread(void *context){
CFmDBSession *sess;
if (fm_db_util_create_session(&sess) != true){
FM_ERROR_LOG("Fail to create DB session, exit ...\n");
exit (-1);
}
while (true){
sFmJobReq req;
while (dequeue_job(req)){
fm_handle_job_request(*sess,req);
}
fmThreadSleep(200);
}
}
void fmRegHandlerThread(void *context){
CFmDBSession *sess;
if (fm_db_util_create_session(&sess) != true){
FM_ERROR_LOG("Fail to create DB session, exit ...\n");
exit (-1);
}
while (true){
sFmGetReq req;
while (dequeue_get(req)){
fm_handle_get_request(*sess, req, context);
}
fmThreadSleep(100);
}
}
bool fm_handle_event_suppress_changes(CFmDBSession &sess){
int sock_fd;
fd_set readset;
PGconn *pgconn = NULL;
PGnotify *notify;
pgconn = sess.get_pgconn();
sock_fd = PQsocket(pgconn);
FD_ZERO(&readset);
FD_SET(sock_fd, &readset);
// Wait for event_suppression update to occur
if (select(sock_fd + 1, &readset, NULL, NULL, NULL) < 0)
{
FM_ERROR_LOG("select() failed: %s\n", strerror(errno));
if (errno!=EINTR)
return false;
}
// Now check for input. This will clear the queue
PQconsumeInput(pgconn);
while ((notify = PQnotifies(pgconn)) != NULL)
{
PQfreemem(notify);
}
SFmAlarmDataT *alarm = NULL;
fm_snmp_util_gen_trap(sess, FM_WARM_START, *alarm);
return true;
}
void fmEventSuppressionMonitorThread(void *context){
CFmDBSession *sess;
CFmEventSuppressionOperation event_suppression_op;
if (fm_db_util_create_session(&sess) != true){
FM_ERROR_LOG("Fail to create DB session, exit ...\n");
exit (-1);
}
if (event_suppression_op.set_table_notify_listen(*sess) != true){
FM_ERROR_LOG("Fail to set DB table notify and listen, exit ...\n");
exit (-1);
}
while (true){
fm_handle_event_suppress_changes(*sess);
fmThreadSleep(30000); // 30 second wait allows some time to buffer in multiple notify events
// and send only 1 Warm Start trap as a result
}
}
}

View File

@ -0,0 +1,38 @@
//
// Copyright (c) 2014 Wind River Systems, Inc.
//
// SPDX-License-Identifier: Apache-2.0
//
#ifndef FMMSGSERVER_H_
#define FMMSGSERVER_H_
#include <vector>
#include "fmSocket.h"
#include "fmMsg.h"
#include "fmDb.h"
class FmSocketServerProcessor : public FmSocketServer {
protected:
virtual void handle_socket_data(int fd,std::vector<char> &data,
CFmDBSession &sess);
virtual void handle_create_fault(int fd, SFmMsgHdrT *hdr,
std::vector<char> &rdata, CFmDBSession &sess);
virtual void handle_delete_fault(int fd, SFmMsgHdrT *hdr,
std::vector<char> &rdata, CFmDBSession &sess);
virtual void handle_delete_faults(int fd, SFmMsgHdrT *hdr,
std::vector<char> &rdata,CFmDBSession &sess);
virtual void handle_get_fault(int fd, SFmMsgHdrT *hdr,
std::vector<char> &rdata);
virtual void handle_get_faults(int fd, SFmMsgHdrT *hdr,
std::vector<char> &rdata);
virtual void handle_get_faults_by_id(int fd, SFmMsgHdrT *hdr,
std::vector<char> &rdata);
public:
void send_response(int fd, SFmMsgHdrT *hdr, void *data, size_t len);
};
#endif /* FMMSGSERVER_H_ */

View File

@ -0,0 +1,48 @@
//
// Copyright (c) 2014 Wind River Systems, Inc.
//
// SPDX-License-Identifier: Apache-2.0
//
#include <pthread.h>
#include <stdio.h>
#include "fmLog.h"
#include "fmMutex.h"
bool CFmMutex::lock() {
//FM_DEBUG_LOG("lock %X",cntx);
return pthread_mutex_lock((pthread_mutex_t*)cntx)==0;
}
bool CFmMutex::unlock() {
//FM_DEBUG_LOG("unlock %X",cntx);
return pthread_mutex_unlock((pthread_mutex_t*)cntx)==0;
}
CFmMutex::CFmMutex() {
cntx = NULL;
//use recursive Mutex to allow one thread to lock it multiple times
pthread_mutex_t tmutex = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;
pthread_mutex_t * pMutex = new pthread_mutex_t;
if (pMutex!=NULL) {
*pMutex = tmutex;
cntx = pMutex;
}
}
CFmMutex::~CFmMutex() {
pthread_mutex_destroy((pthread_mutex_t*)cntx);
delete ((pthread_mutex_t*)cntx); //safe if cntx is null
cntx = NULL;
}

View File

@ -0,0 +1,45 @@
//
// Copyright (c) 2014 Wind River Systems, Inc.
//
// SPDX-License-Identifier: Apache-2.0
//
#ifndef FM_MUTEX_H_
#define FM_MUTEX_H_
class CFmMutex {
void * cntx;
public:
CFmMutex();
~CFmMutex();
bool lock();
bool unlock();
};
class CFmMutexGuard {
CFmMutex & m;
bool rc;
public:
CFmMutexGuard(CFmMutex & mu) : m(mu) {
rc = m.lock();
}
~CFmMutexGuard() {
m.unlock();
}
bool getRc() {
return rc;
}
};
#endif

View File

@ -0,0 +1,69 @@
//
// Copyright (c) 2014 Wind River Systems, Inc.
//
// SPDX-License-Identifier: Apache-2.0
//
#include <string>
#define FM_ALARM_CLEAR 6
#define FM_ALARM_HIERARCHICAL_CLEAR 7
#define FM_ALARM_MESSAGE 8
#define FM_WARM_START 9
#define FM_CUSTOMER_LOG 10
/* Trap Destination table name */
#define FM_TRAPDEST_TABLE_NAME "i_trap_destination"
#define FM_TRAPDEST_IP_COLUMN "ip_address"
#define FM_TRAPDEST_COMM_COLUMN "community"
/* MIB Trap definitions */
const std::string WRS_ALARM_MIB = "WRS-ALARM-MIB";
const std::string ALARM_CRITICAL = "wrsAlarmCritical";
const std::string ALARM_MAJOR = "wrsAlarmMajor";
const std::string ALARM_MINOR = "wrsAlarmMinor";
const std::string ALARM_WARNING = "wrsAlarmWarning";
const std::string ALARM_MSG = "wrsAlarmMessage";
const std::string ALARM_CLEAR = "wrsAlarmClear";
const std::string ALARM_HIERARCHICAL_CLEAR = "wrsAlarmHierarchicalClear";
const std::string ALARM_ID = "wrsAlarmActiveAlarmId";
const std::string ALARM_INSTANCE_ID = "wrsAlarmActiveEntityInstanceId";
const std::string ALARM_DATE_TIME = "wrsAlarmActiveDateAndTime";
const std::string ALARM_SEVERITY = "wrsAlarmActiveAlarmSeverity";
const std::string ALARM_REASON_TEXT = "wrsAlarmActiveReasonText";
const std::string ALARM_EVENT_TYPE = "wrsAlarmActiveEventType";
const std::string ALARM_CAUSE = "wrsAlarmActiveProbableCause";
const std::string ALARM_REPAIR_ACTION = "wrsAlarmActiveProposedRepairAction";
const std::string ALARM_SERVICE_AFFECTING = "wrsAlarmActiveServiceAffecting";
const std::string ALARM_SUPPRESSION = "wrsAlarmActiveSuppressionAllowed";
const std::string CUSTOMER_LOG_ID = "wrsCustomerLogId";
const std::string CUSTOMER_LOG_INSTANCE_ID = "wrsCustomerLogEntityInstanceId";
const std::string CUSTOMER_LOG_DATE_TIME = "wrsCustomerLogDateAndTime";
const std::string CUSTOMER_LOG_SEVERITY = "wrsCustomerLogSeverity";
const std::string CUSTOMER_LOG_REASON_TEXT = "wrsCustomerLogReasonText";
const std::string CUSTOMER_LOG_EVENT_TYPE = "wrsCustomerLogEventType";
const std::string CUSTOMER_LOG_CAUSE = "wrsCustomerLogProbableCause";
const std::string CUSTOMER_LOG_SERVICE_AFFECTING = "wrsCustomerLogServiceAffecting";
const std::string SNMPv2_MIB = "SNMPv2-MIB";
const std::string WARM_START = "warmStart";
const std::string TRAP_CMD = "/usr/bin/snmptrap -v 2c";
const std::string CLEAR_REASON_TEXT = "System initiated hierarchical alarm clear";
const std::string SEP = " ";
const std::string SCOPE = "::";
const std::string STR_TYPE = " s ";
const std::string INT_TYPE = " i ";
const std::string OPTION_COMM = " -c ";
const std::string DC_COMM_STR = "dcorchAlarmAggregator";
const std::string CONF_PATH_ENV = "SNMPCONFPATH=";
const std::string CONF_DIR = "/etc/snmp";

View File

@ -0,0 +1,290 @@
//
// Copyright (c) 2014 Wind River Systems, Inc.
//
// SPDX-License-Identifier: Apache-2.0
//
#include <stdlib.h>
#include <iostream>
#include <sstream>
#include <string>
#include <map>
#include <assert.h>
#include <sstream>
#include "fmDbAPI.h"
#include "fmFile.h"
#include "fmAPI.h"
#include "fmMsg.h"
#include "fmLog.h"
#include "fmDb.h"
#include "fmDbUtils.h"
#include "fmSnmpConstants.h"
#include "fmSnmpUtils.h"
typedef std::map<int,std::string> int_to_objtype;
static int_to_objtype objtype_map;
static pthread_mutex_t mutex = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;
static void add_to_table(int t, std::string objtype, int_to_objtype &tbl) {
tbl[t]=objtype;
}
static void init_objtype_table() {
pthread_mutex_lock(&mutex);
static bool has_inited=false;
while (!has_inited){
add_to_table(FM_ALARM_SEVERITY_CLEAR, ALARM_MSG, objtype_map);
add_to_table(FM_ALARM_SEVERITY_WARNING, ALARM_WARNING, objtype_map);
add_to_table(FM_ALARM_SEVERITY_MINOR, ALARM_MINOR, objtype_map);
add_to_table(FM_ALARM_SEVERITY_MAJOR, ALARM_MAJOR, objtype_map);
add_to_table(FM_ALARM_SEVERITY_CRITICAL, ALARM_CRITICAL, objtype_map);
add_to_table(FM_ALARM_CLEAR, ALARM_CLEAR, objtype_map);
add_to_table(FM_ALARM_HIERARCHICAL_CLEAR, ALARM_HIERARCHICAL_CLEAR, objtype_map);
add_to_table(FM_ALARM_MESSAGE, ALARM_MSG, objtype_map);
add_to_table(FM_WARM_START, WARM_START, objtype_map);
has_inited=true;
}
pthread_mutex_unlock(&mutex);
}
static std::string add_time_val(std::string &str,
const std::string &objtype, FMTimeT time){
std::string time_str;
fm_db_util_make_timestamp_string(time_str, time, true);
return str + objtype + STR_TYPE + time_str + SEP;
}
static std::string add_str_val(std::string &str,
const std::string &objtype, const char *value){
std::string val(value);
return str + objtype + STR_TYPE + '"' + val + '"' + SEP;
}
static std::string add_int_val(std::string &str,
const std::string &objtype, int value){
return str + objtype + INT_TYPE + fm_db_util_int_to_string(value) + SEP;
}
static std::string get_trap_objtype(int type){
init_objtype_table();
return objtype_map[type];
}
static bool get_trap_dest_list(CFmDBSession &sess,fm_db_result_t & res){
std::string cmd;
fm_db_util_build_sql_query(FM_TRAPDEST_TABLE_NAME, NULL, cmd);
return sess.query(cmd.c_str(), res);
}
static std::string format_trap_cmd(CFmDBSession &sess, int type, SFmAlarmDataT &data,
std::string &ip, std::string &comm){
std::string cmd;
std::string objtype;
std::string mib;
std::string s = "\"\" ";
std::string env;
if (get_trap_objtype(type) == WARM_START)
mib = SNMPv2_MIB;
else
mib = WRS_ALARM_MIB;
objtype = mib + SCOPE + get_trap_objtype(type);
if (comm.compare(DC_COMM_STR) == 0){
env = CONF_PATH_ENV + CONF_DIR + SEP;
}
else {
env = "";
}
cmd = env + TRAP_CMD + OPTION_COMM + comm + SEP + ip + SEP + s + objtype + SEP;
std::string operation_type =get_trap_objtype(type);
if (operation_type == ALARM_CLEAR){
cmd = add_str_val(cmd,ALARM_ID, data.alarm_id);
cmd = add_str_val(cmd, ALARM_INSTANCE_ID, data.entity_instance_id);
cmd = add_time_val(cmd, ALARM_DATE_TIME, data.timestamp);
cmd = add_str_val(cmd, ALARM_REASON_TEXT, data.reason_text);
} else if (operation_type == ALARM_HIERARCHICAL_CLEAR){
cmd = add_str_val(cmd, ALARM_INSTANCE_ID, data.entity_instance_id);
cmd = add_time_val(cmd, ALARM_DATE_TIME, 0);
cmd = add_str_val(cmd, ALARM_REASON_TEXT, CLEAR_REASON_TEXT.c_str());
} else if (operation_type == ALARM_MSG){
cmd = add_str_val(cmd, CUSTOMER_LOG_ID, data.alarm_id);
cmd = add_str_val(cmd, CUSTOMER_LOG_INSTANCE_ID, data.entity_instance_id);
cmd = add_time_val(cmd, CUSTOMER_LOG_DATE_TIME, data.timestamp);
cmd = add_int_val(cmd, CUSTOMER_LOG_SEVERITY, data.severity);
cmd = add_str_val(cmd, CUSTOMER_LOG_REASON_TEXT, data.reason_text);
cmd = add_int_val(cmd, CUSTOMER_LOG_EVENT_TYPE, data.alarm_type);
cmd = add_int_val(cmd, CUSTOMER_LOG_CAUSE, data.probable_cause);
cmd = add_int_val(cmd, CUSTOMER_LOG_SERVICE_AFFECTING, data.service_affecting);
} else if (operation_type == WARM_START){
// nothing to add to cmd
} else {
cmd = add_str_val(cmd, ALARM_ID, data.alarm_id);
cmd = add_str_val(cmd, ALARM_INSTANCE_ID, data.entity_instance_id);
cmd = add_time_val(cmd, ALARM_DATE_TIME, data.timestamp);
cmd = add_int_val(cmd, ALARM_SEVERITY, data.severity);
cmd = add_str_val(cmd, ALARM_REASON_TEXT, data.reason_text);
cmd = add_int_val(cmd, ALARM_EVENT_TYPE, data.alarm_type);
cmd = add_int_val(cmd, ALARM_CAUSE, data.probable_cause);
cmd = add_str_val(cmd, ALARM_REPAIR_ACTION, data.proposed_repair_action);
cmd = add_int_val(cmd, ALARM_SERVICE_AFFECTING, data.service_affecting);
cmd = add_int_val(cmd, ALARM_SUPPRESSION, data.suppression);
}
return cmd;
}
bool fm_snmp_util_gen_trap(CFmDBSession &sess, int type, SFmAlarmDataT &data) {
bool rc = true;
fm_buff_t cmdbuff;
fm_db_result_t res;
std::string cmd, eid;
if (!get_trap_dest_list(sess,res)) return false;
if (&data != NULL) {
eid.assign(data.entity_instance_id);
std::string region_name = fm_db_util_get_region_name(sess);
std::string sys_name = fm_db_util_get_system_name(sess);
if (sys_name.length() != 0){
eid = sys_name + "."+ eid;
}
if (region_name.length() != 0){
eid = region_name + "."+ eid;
}
strncpy(data.entity_instance_id, eid.c_str(),
sizeof(data.entity_instance_id)-1);
}
fm_db_result_t::iterator it = res.begin();
fm_db_result_t::iterator end = res.end();
for (; it != end; ++it){
memset(&(cmdbuff[0]), 0, cmdbuff.size());
cmd.clear();
std::string ip = (*it)[FM_TRAPDEST_IP_COLUMN];
std::string comm = (*it)[FM_TRAPDEST_COMM_COLUMN];
cmd = format_trap_cmd(sess,type, data, ip, comm);
//FM_INFO_LOG("run cmd: %s\n", cmd.c_str());
char *pline = &(cmdbuff[0]);
FILE *op = popen(cmd.c_str(),"r");
if (op==NULL) {
FM_ERROR_LOG("popen() failed, errno: (%d) (%s)\n",
errno, strerror(errno));
rc = false;
}
while (fgets(pline,cmdbuff.size(),op)!=NULL) {
FM_ERROR_LOG("Trap error message: (%s)\n", pline);
}
fclose(op);
}
return rc;
}
static bool fm_snmp_get_db_connection(std::string &connection){
CfmFile f;
const char *fn = "/etc/fm.conf";
std::string sql_key = FM_SQL_CONNECTION;
std::string delimiter = "=";
std::string line, key, value;
size_t pos = 0;
if (!f.open(fn, CfmFile::READ, false)){
FM_ERROR_LOG("Failed to open config file: %s\n", fn);
exit (-1);
}
while (true){
if (!f.read_line(line)) break;
if (line.size() == 0) continue;
pos = line.find(delimiter);
key = line.substr(0, pos);
if (key == sql_key){
value = line.erase(0, pos + delimiter.length());
// Don't log sql_connection, as it has a password
//FM_DEBUG_LOG("Found it: (%s)\n", value.c_str());
connection = value;
return true;
}
}
return false;;
}
extern "C" {
bool fm_snmp_util_create_session(TFmAlarmSessionT *handle, const char* db_conn){
std::string key = FM_SQL_CONNECTION;
std::string conn;
CFmDBSession *sess = new CFmDBSession;
if (sess==NULL) return false;;
if (db_conn == NULL){
if (fm_snmp_get_db_connection(conn) != true){
FM_ERROR_LOG("Fail to get db connection uri\n");
delete sess;
return false;
}
db_conn = conn.c_str();
}
if (sess->connect(db_conn) != true){
FM_ERROR_LOG("Fail to connect to (%s)\n", db_conn);
delete sess;
return false;
}
*handle = sess;
return true;
}
void fm_snmp_util_destroy_session(TFmAlarmSessionT handle) {
CFmDBSession *sess = (CFmDBSession *)handle;
if (sess != NULL){
delete sess;
}
}
bool fm_snmp_util_get_all_alarms(TFmAlarmSessionT handle,
SFmAlarmQueryT *query) {
assert(handle!=NULL);
CFmDbAlarmOperation op;
fm_db_result_t res;
CFmDBSession &sess = *((CFmDBSession*)handle);
if (!op.get_all_alarms(sess, &(query->alarm), &(query->num))) return false;
return true;
}
bool fm_snmp_util_get_all_event_logs(TFmAlarmSessionT handle,
SFmAlarmQueryT *query) {
assert(handle!=NULL);
CFmDbEventLogOperation op;
fm_db_result_t res;
CFmDBSession &sess = *((CFmDBSession*)handle);
if (!op.get_all_event_logs(sess, &(query->alarm), &(query->num))) return false;
return true;
}
}

View File

@ -0,0 +1,17 @@
//
// Copyright (c) 2014 Wind River Systems, Inc.
//
// SPDX-License-Identifier: Apache-2.0
//
#ifndef __FM_SNMP_UTILS_H
#define __FM_SNMP_UTILS_H
#include <string>
#include "fmAPI.h"
#include "fmDb.h"
bool fm_snmp_util_gen_trap(CFmDBSession &sess, int type, SFmAlarmDataT &data);
#endif

View File

@ -0,0 +1,462 @@
//
// Copyright (c) 2017 Wind River Systems, Inc.
//
// SPDX-License-Identifier: Apache-2.0
//
#include <sys/socket.h>
#include <sys/types.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <stdlib.h>
#include <sys/select.h>
#include <errno.h>
#include <unistd.h>
#include <stdint.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include "fmSocket.h"
#include "fmThread.h"
#include "fmMutex.h"
#include "fmLog.h"
#include "fmDbUtils.h"
CFmMutex & getConnectionMutex(){
static CFmMutex *m = new CFmMutex;
return *m;
}
void CFmSockAddr::set_type(socklen_t addr_len) {
if (addr_len==sizeof(address.ipv4)) {
type = AF_INET;
} else if (addr_len==sizeof(address.ipv6)) {
type = AF_INET6;
} else {
type = AF_UNIX;
}
}
CFmSocket::CFmSocket() {
m_fd = -1;
}
CFmSocket::~CFmSocket() {
close();
}
void CFmSocket::close() {
if (m_fd!=-1) {
//FM_INFO_LOG("close fd:(%d)", m_fd);
::close(m_fd);
}
m_fd = -1;
}
bool CFmSocket::create_socket() {
int optval = 1;
socklen_t optlen = sizeof(optval);
close();
m_fd = ::socket(address_family,SOCK_STREAM,0);
if (m_fd == -1){
FM_ERROR_LOG("Failed to create socket, error: (%d) (%s)", errno, strerror(errno));
return false;
}
/* Set the KEEPALIVE option active */
if(setsockopt(m_fd, SOL_SOCKET, SO_KEEPALIVE, &optval, optlen) < 0) {
FM_ERROR_LOG("Failed to setsockopt, error: (%d) (%s)", errno, strerror(errno));
close();
return false;
}
//FM_DEBUG_LOG("SO_KEEPALIVE set on socket\n");
return true;
}
bool CFmSocket::connect(const char *host, int port, int address_family) {
this->address_family = address_family;
if (!create_socket()) {
return false;
}
switch (address_family) {
//When address is IPv4
case AF_INET:
{
struct sockaddr_in addr;
if (inet_aton(host,&(addr.sin_addr))==0) {
FM_INFO_LOG("inet_aton() failed\n");
return false;
}
addr.sin_port = htons(port);
addr.sin_family = AF_INET;
fd_set wset;
FD_ZERO(&wset);
FD_SET(m_fd,&wset);
return (::connect(m_fd,(const struct sockaddr *)&addr,sizeof(addr))==0);
}
//When address is IPv6
case AF_INET6:
{
struct sockaddr_in6 addr;
if (inet_pton(AF_INET6,host,&(addr.sin6_addr))<=0) {
FM_INFO_LOG("inet_aton() failed\n");
return false;
}
addr.sin6_port = htons(port);
addr.sin6_family = AF_INET6;
fd_set wset;
FD_ZERO(&wset);
FD_SET(m_fd,&wset);
return (::connect(m_fd,(const struct sockaddr *)&addr,sizeof(addr))==0);
}
//Should never get here, needed for completeness
default:
{
return false;
}
}
}
bool CFmSocket::write(int fd, const void *data, long len) {
int offset = 0;
while (offset!=len) {
int rc = ::write(fd, ((char*)data)+offset,len-offset);
if (rc==0 || (rc==-1 && errno!=EINTR)) {
FM_ERROR_LOG("Socket Error: Failed to write to fd:(%d), len:(%d), rc:(%d), error:(%s)",
fd, len, rc, strerror(errno));
return false;
}
if (rc==-1 && errno==EINTR) continue;
offset+=rc;
}
return true;
}
bool CFmSocket::write_packet(int fd, const void *data, long plen) {
uint32_t len = htonl(plen);
bool rc = write(fd,&len,sizeof(len));
if (!rc) return false;
return write(fd,data,plen);
}
bool CFmSocket::write_packet(int fd, const std::vector<char> &data) {
return write_packet(fd,&(data[0]),data.size());
}
bool CFmSocket::read_packet(int fd, std::vector<char> &data) {
int32_t len = 0;
long tlen = sizeof(len);
int i = 10;
for ( ; i > 0 ; --i) {
if (!read(fd,&len,tlen)) {
return false;
}
break;
}
if (tlen!=sizeof(len))
{
FM_ERROR_LOG("Socket Error: Length does not match the data size: (%ld), (%ld)", tlen, sizeof(len));
return false;
}
len=ntohl(len);
data.resize(len);
tlen = len;
if (!read(fd,&(data[0]),tlen)) return false;
return true;
}
bool CFmSocket::read(int fd,void *data, long &len) {
int offset = 0;
while (offset!=len) {
int rc = ::read(fd, ((char*)data)+offset,len-offset);
if (rc==0 || (rc==-1 && errno!=EINTR)) {
// return code 0 means graceful close of TCP socket
if (rc !=0 ){
FM_ERROR_LOG("Failed to read from fd:(%d), rc:(%d), error:(%s), len:(%d)",
fd, rc, strerror(errno), len);
}
len = offset;
return false;
}
if (rc==-1 && errno==EINTR) continue;
offset+=rc;
}
return true;
}
bool CFmSocket::read_packet(std::vector<char> &data) {
return read_packet(m_fd,data);
}
bool CFmSocket::read(void *data, long &len) {
return read(m_fd,data,len);
}
int CFmSocket::select(int *rfd, int rlen, int *wfds, int wlen,int timeout, int timeoutusec, bool &timedout) {
fd_set rset,wset;
FD_ZERO(&rset);
wset=rset;
int max_fd = -1;
int ix = 0;
for ( ; ix < rlen ; ++ix ) {
if (max_fd < rfd[ix]) max_fd = rfd[ix];
FD_SET(rfd[ix],&rset);
}
ix = 0;
for ( ; ix < wlen ; ++ix ) {
if (max_fd < wfds[ix]) max_fd = wfds[ix];
FD_SET(wfds[ix],&wset);
}
struct timeval to;
to.tv_sec = timeout;
to.tv_usec = timeoutusec;
timedout=false;
int rc = 0;
while (true) {
rc = ::select(max_fd+1,&rset,&wset,NULL,&to);
if (rc==-1 && errno!=EINTR) {
break;
}
if (rc==-1) continue;
if (rc==0) timedout = true;
break;
}
if (rc>0) {
ix = 0;
for ( ; ix < rlen ; ++ix ) {
if (!FD_ISSET(rfd[ix],&rset)) {
rfd[ix]=-1;
}
}
ix = 0;
for ( ; ix < wlen ; ++ix ) {
if (!FD_ISSET(wfds[ix],&wset)) {
wfds[ix] = -1;
}
}
}
return rc;
}
int CFmSocket::select_read(int fd,int timeout, bool &timedout){
return select(&fd,1,NULL,0,timeout,0,timedout);
}
bool CFmSocket::recvfrom(void *data, long &len, CFmSockAddr &addr) {
socklen_t addr_len = sizeof(addr.address);
int l = ::recvfrom(m_fd,data,len,0,addr.get_sockaddr(),&addr_len);
if (l==-1) { len = errno; return false; }
len = l;
addr.set_type(addr_len);
return true;
}
bool CFmSocket::write(const void *data, long len) {
return write(m_fd,data,len);
}
void FmSocketServer::rm_socket(int sock) {
CFmMutexGuard m(getConnectionMutex());
conn_map_t::iterator it = connections.find(sock);
if (it!=connections.end()) {
connections.erase(it);
}
}
void FmSocketServer::handle_socket_data(int fd, std::vector<char> &data,
CFmDBSession &sess) {
FM_INFO_LOG("Received data from sock:%d len %lu\n",fd,data.size());
}
bool FmSocketServer::good_socket(int sock) {
bool timedout=false;
int rc = select(&sock,1,NULL,0,0,0,timedout);
return (rc!=-1);
}
void FmSocketServer::find_bad_fd() {
if (!good_socket(m_fd)) {
server_reset();
}
std::vector<int> lsock;
to_sock_array(lsock);
int ix = 0;
int mx =lsock.size();
for ( ; ix < mx ; ++ix) {
if (!good_socket(lsock[ix])) {
FM_INFO_LOG("Found bad fd, close it:(%d)", lsock[ix]);
::close(lsock[ix]);
rm_socket(lsock[ix]);
}
}
}
bool FmSocketServer::run() {
CFmDBSession *sess;
if (fm_db_util_create_session(&sess) != true){
FM_ERROR_LOG("Fail to create DB session, exit ...\n");
exit (-1);
}
while (true) {
std::vector<int> lsock;
to_sock_array(lsock);
lsock.push_back(m_fd);
bool timedout =false;
int rc = select(&(lsock[0]),lsock.size(),NULL,0,1,0,timedout);
if (timedout) continue;
if (rc==-1) {
find_bad_fd();
continue;
}
//listening socket and close all current sockets..
int ix = 0;
int mx = lsock.size();
for ( ; ix < mx ; ++ix ) {
if (lsock[ix]==-1) continue;
if (lsock[ix]==m_fd) {
accept();
continue;
}
std::vector<char>buff;
buff.clear();