diff options
141 files changed, 9362 insertions, 535 deletions
@@ -68,3 +68,16 @@ docs/_build/ target/ logs/ + + +# Intellij Files & Dir # +*.iml +*.ipr +*.iws +*.uml + +atlassian-ide-plugin.xml +out/ +.DS_Store +./lib/ +.idea diff --git a/LICENSE.txt b/LICENSE.txt index 69d5fc1..9536f0b 100644 --- a/LICENSE.txt +++ b/LICENSE.txt @@ -1,11 +1,11 @@ /* * ============LICENSE_START========================================== * =================================================================== -* Copyright © 2017 AT&T Intellectual Property. All rights reserved. +* Copyright (c) 2017 AT&T Intellectual Property. All rights reserved. * =================================================================== * * Unless otherwise specified, all software contained herein is licensed -* under the Apache License, Version 2.0 (the “License”); +* under the Apache License, Version 2.0 (the "License"); * you may not use this software except in compliance with the License. * You may obtain a copy of the License at * @@ -20,7 +20,7 @@ * * * Unless otherwise specified, all documentation contained herein is licensed -* under the Creative Commons License, Attribution 4.0 Intl. (the “License”); +* under the Creative Commons License, Attribution 4.0 Intl. (the "License"); * you may not use this documentation except in compliance with the License. * You may obtain a copy of the License at * diff --git a/dcaeapplib/ChangeLog.md b/dcaeapplib/ChangeLog.md new file mode 100644 index 0000000..0942537 --- /dev/null +++ b/dcaeapplib/ChangeLog.md @@ -0,0 +1,6 @@ +# Change Log + +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](http://keepachangelog.com/) +and this project adheres to [Semantic Versioning](http://semver.org/). diff --git a/dcaeapplib/LICENSE.txt b/dcaeapplib/LICENSE.txt new file mode 100644 index 0000000..8bdab89 --- /dev/null +++ b/dcaeapplib/LICENSE.txt @@ -0,0 +1,17 @@ +============LICENSE_START======================================================= +Copyright (c) 2018 AT&T Intellectual Property. All rights reserved. +================================================================================ +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. +============LICENSE_END========================================================= + +ECOMP is a trademark and service mark of AT&T Intellectual Property. diff --git a/dcaeapplib/README.md b/dcaeapplib/README.md new file mode 100644 index 0000000..81fd825 --- /dev/null +++ b/dcaeapplib/README.md @@ -0,0 +1,64 @@ +# dcaeapplib + +Library for building DCAE analytics applications + +# Example use: + +``` + +class myapp: + def __init__(self): + # get the environment, and register callbacks for health checks and + # configuration changes + self.dcaeenv = dcaeapplib.DcaeEnv(healthCB=self.isHealthy, reconfigCB=self.reconfigure) + # simulate a configuration change - we want the initial configuration + self.reconfigure() + # start the environment (to wait for health checks and config changes) + self.dcaeenv.start() + # begin processing loop + while True: + if self.configchanged: + # fetch the updated configuration + self.conig = self.dcaeenv.getconfig() + self.configchanged = False + # do any setup relevant to the configuration + data = self.dcaeenv.getdata('myinputstream') + # Data is a UTF-8 string, 'myinputstream' is this application's logical + # name for this (one of potentially several) data sources. + # Can also specify timeout_ms and limit as arguments. + # timeout_ms (default 15,000) is the maximum time getdata() will block + # limit is the maximum number of records retrieved at a time. + # If no data is retrieved (timeout) the return will be None. + if data is not None: + # do something to process the data + self.dcaeenv.senddata('myoutputstream', 'somepartitionkey', data) + # data is a string, 'myoutputstream' is the application's logical + # name for this (one of potentially several) data sinks. + # somepartitionkey is used, by Kafka, to assign the data to a partition. + + def isHealthy(self): + # return the health of the application (True/False) + return True + + def reconfigure(self): + # Do whatever needs to be done to handle a configuration change + self.configchanged = True +``` + +# Environment Variables + +This library uses the onap-dcae-cbs-docker-client library to fetch +configuration. That library relies on the HOSTNAME and CONSUL_HOST +environment variables to find the configuration. + +This library provides an HTTP interface for health checks. By default this +listens on port 80 but can be overridden to use another port by setting the +DCAEPORT environment variable. The HTTP interface supports getting 2 URLs: +/healthcheck, which will return a status of 202 (Accepted) for healthy, +and 503 (Service Unavailable) for unhealthy, and /reconfigure, which triggers +the library to check for updated configuration. + +# Console Commands + +This library provides a single console command "reconfigure.sh" which +performs an HTTP get of the /reconfigure URL diff --git a/dcaeapplib/dcaeapplib/__init__.py b/dcaeapplib/dcaeapplib/__init__.py new file mode 100644 index 0000000..18b60fe --- /dev/null +++ b/dcaeapplib/dcaeapplib/__init__.py @@ -0,0 +1,152 @@ +# org.onap.dcae +# ============LICENSE_START==================================================== +# Copyright (c) 2018 AT&T Intellectual Property. All rights reserved. +# ============================================================================= +# 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. +# ============LICENSE_END====================================================== +# +# ECOMP is a trademark and service mark of AT&T Intellectual Property. + +import base64 +import json +import os +import requests +from threading import Thread +import uuid +from onap_dcae_cbs_docker_client.client import get_config + +try: + from http.server import BaseHTTPRequestHandler, HTTPServer +except ImportError: + from BaseHTTPServer import BaseHTTPRequestHandler, HTTPServer + +_httpport = int(os.environ['DCAEPORT']) if 'DCAEPORT' in os.environ else 80 +_clientid = uuid.uuid4().hex +_groupid = uuid.uuid4().hex + +class _handler(BaseHTTPRequestHandler): + def do_GET(self): + if '/healthcheck' == self.path: + if self.server.env._health(): + self.send_response(202) + self.end_headers() + else: + self.send_error(503) + elif '/reconfigure' == self.path: + self.server.env._loadconfig() + self.server.env._reconf() + self.send_response(202) + self.end_headers() + else: + self.send_error(404) + +def _genauth(sinfo): + """ + Return authentication parameters for stream, if present. + """ + user = sinfo['aaf_username'] if 'aaf_username' in sinfo else None + password = sinfo['aaf_password'] if 'aaf_password' in sinfo else None + if user and password: + return { 'auth': (user, password) } + else: + return {} + +class DcaeEnv: + def __init__(self, healthCB = lambda:True, reconfigCB = lambda:None): + """ + Initialize environment, but don't start web server or invoke any callbacks. + """ + self._health = healthCB + self._reconf = reconfigCB + self._unread = {} + self._server = None + self._loadconfig() + + def start(self): + """ + Start web server to receive health checks and reconfigure requests + """ + if self._server is not None: + return + self._server = HTTPServer(('', _httpport), _handler) + self._server.env = self + th = Thread(target=self._server.serve_forever, name='webserver') + th.daemon = True + th.start() + + def stop(self): + """ + Stop web server + """ + if self._server is None: + return + self._server.shutdown() + self._server.env = None + self._server = None + + def _loadconfig(self): + self._config = get_config() + + def hasdata(self, stream): + """ + Return whether there is any unprocessed received data for the specified + data stream. That is, if an earlier getdata() call returned more than + one record, and the additional records have not yet been retrieved. + """ + return stream in self._unread + + def getdata(self, stream, timeout_ms = 15000, limit = 10): + """ + Try to retrieve data from Message Router for the specified data stream. + If no data is retrieved, within the specified timeout, return None. + """ + sinfo = self._config['streams_subscribes'][stream] + if stream in self._unread: + x = self._unread[stream] + ret = x.pop() + if len(x) == 0: + del self._unread[stream] + return ret + gid = sinfo['client_id'] if 'client_id' in sinfo and sinfo['client_id'] else _groupid + resp = requests.get('{0}/{1}/{2}?timeout={3}&limit={4}'.format(sinfo['dmaap_info']['topic_url'], gid, _clientid, timeout_ms, limit), **_genauth(sinfo)) + resp.raise_for_status() + x = resp.json() + if len(x) == 0: + return None + if len(x) == 1: + return x[0] + x.reverse() + ret = x.pop() + self._unread[stream] = x + return ret + + def senddata(self, stream, partition, data): + """ + Publish data to the specified stream. + """ + sinfo = self._config['streams_publishes'][stream] + body = '{0}.{1}.{2}{3}'.format(len(partition), len(data), partition, data) + resp = requests.post('{0}'.format(sinfo['dmaap_info']['topic_url']), headers={'Content-Type': 'application/cambria'}, data=body, **_genauth(sinfo)) + resp.raise_for_status() + + def getconfig(self): + """ + Get the latest version of the configuration data. + """ + return self._config + +def reconfigure(): + """ + Make the web request to reconfigure (locally) + """ + requests.get('http://localhost:{0}/reconfigure'.format(_httpport)) diff --git a/dcaeapplib/pom.xml b/dcaeapplib/pom.xml new file mode 100644 index 0000000..66e73da --- /dev/null +++ b/dcaeapplib/pom.xml @@ -0,0 +1,241 @@ +<?xml version="1.0"?> +<!-- +================================================================================ +Copyright (c) 2018 AT&T Intellectual Property. All rights reserved. +================================================================================ +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. +============LICENSE_END========================================================= + +ECOMP is a trademark and service mark of AT&T Intellectual Property. +--> +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + <parent> + <groupId>org.onap.dcaegen2.utils</groupId> + <artifactId>utils</artifactId> + <version>1.2.0-SNAPSHOT</version> + </parent> + <groupId>org.onap.dcaegen2.utils</groupId> + <artifactId>dcaeapplib</artifactId> + <name>dcaeapplib</name> + <version>0.0.3-SNAPSHOT</version> + <url>http://maven.apache.org</url> + + <properties> + <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> + + <sonar.sources>.</sonar.sources> + <sonar.junit.reportsPath>xunit-results.xml</sonar.junit.reportsPath> + <sonar.python.coverage.reportPath>coverage.xml</sonar.python.coverage.reportPath> + <sonar.language>py</sonar.language> + <sonar.pluginName>Python</sonar.pluginName> + <sonar.inclusions>**/*.py</sonar.inclusions> + <sonar.exclusions>tests/*,setup.py</sonar.exclusions> + </properties> + <build> + <finalName>${project.artifactId}-${project.version}</finalName> + <pluginManagement> + <plugins> + <!-- the following plugins are invoked from oparent, we do not need them --> + <plugin> + <groupId>org.sonatype.plugins</groupId> + <artifactId>nexus-staging-maven-plugin</artifactId> + <version>1.6.7</version> + <configuration> + <skipNexusStagingDeployMojo>true</skipNexusStagingDeployMojo> + </configuration> + </plugin> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-deploy-plugin</artifactId> + <!-- This version supports the "deployAtEnd" parameter --> + <version>2.8</version> + <configuration> + <skip>true</skip> + </configuration> + </plugin> + <!-- first disable the default Java plugins at various stages --> + <!-- maven-resources-plugin is called during "*resource" phases by default behavior. it prepares + the resources dir. we do not need it --> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-resources-plugin</artifactId> + <version>2.6</version> + <configuration> + <skip>true</skip> + </configuration> + </plugin> + <!-- maven-compiler-plugin is called during "compile" phases by default behavior. we do not need it --> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-compiler-plugin</artifactId> + <version>3.1</version> + <configuration> + <skip>true</skip> + </configuration> + </plugin> + <!-- maven-jar-plugin is called during "compile" phase by default behavior. we do not need it --> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-jar-plugin</artifactId> + <version>2.4</version> + <executions> + <execution> + <id>default-jar</id> + <phase/> + </execution> + </executions> + </plugin> + <!-- maven-install-plugin is called during "install" phase by default behavior. it tries to copy stuff under + target dir to ~/.m2. we do not need it --> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-install-plugin</artifactId> + <version>2.4</version> + <configuration> + <skip>true</skip> + </configuration> + </plugin> + <!-- maven-surefire-plugin is called during "test" phase by default behavior. it triggers junit test. + we do not need it --> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-surefire-plugin</artifactId> + <version>2.12.4</version> + <configuration> + <skipTests>true</skipTests> + </configuration> + </plugin> + </plugins> + </pluginManagement> + <plugins> + <!-- plugin> + <artifactId>maven-assembly-plugin</artifactId> + <version>2.4.1</version> + <configuration> + <descriptors> + <descriptor>assembly/dep.xml</descriptor> + </descriptors> + </configuration> + <executions> + <execution> + <id>make-assembly</id> + <phase>package</phase> + <goals> + <goal>single</goal> + </goals> + </execution> + </executions> + </plugin --> + <!-- now we configure custom action (calling a script) at various lifecycle phases --> + <plugin> + <groupId>org.codehaus.mojo</groupId> + <artifactId>exec-maven-plugin</artifactId> + <version>1.2.1</version> + <executions> + <execution> + <id>clean phase script</id> + <phase>clean</phase> + <goals> + <goal>exec</goal> + </goals> + <configuration> + <arguments> + <argument>${project.artifactId}</argument> + <argument>clean</argument> + </arguments> + </configuration> + </execution> + <execution> + <id>generate-sources script</id> + <phase>generate-sources</phase> + <goals> + <goal>exec</goal> + </goals> + <configuration> + <arguments> + <argument>${project.artifactId}</argument> + <argument>generate-sources</argument> + </arguments> + </configuration> + </execution> + <execution> + <id>compile script</id> + <phase>compile</phase> + <goals> + <goal>exec</goal> + </goals> + <configuration> + <arguments> + <argument>${project.artifactId}</argument> + <argument>compile</argument> + </arguments> + </configuration> + </execution> + <execution> + <id>package script</id> + <phase>package</phase> + <goals> + <goal>exec</goal> + </goals> + <configuration> + <arguments> + <argument>${project.artifactId}</argument> + <argument>package</argument> + </arguments> + </configuration> + </execution> + <execution> + <id>test script</id> + <phase>test</phase> + <goals> + <goal>exec</goal> + </goals> + <configuration> + <arguments> + <argument>${project.artifactId}</argument> + <argument>test</argument> + </arguments> + </configuration> + </execution> + <execution> + <id>install script</id> + <phase>install</phase> + <goals> + <goal>exec</goal> + </goals> + <configuration> + <arguments> + <argument>${project.artifactId}</argument> + <argument>install</argument> + </arguments> + </configuration> + </execution> + <execution> + <id>deploy script</id> + <phase>deploy</phase> + <goals> + <goal>exec</goal> + </goals> + <configuration> + <arguments> + <argument>${project.artifactId}</argument> + <argument>deploy</argument> + </arguments> + </configuration> + </execution> + </executions> + </plugin> + </plugins> + </build> +</project> diff --git a/dcaeapplib/setup.py b/dcaeapplib/setup.py new file mode 100644 index 0000000..b985be9 --- /dev/null +++ b/dcaeapplib/setup.py @@ -0,0 +1,39 @@ +# org.onap.dcae +# ============LICENSE_START==================================================== +# Copyright (c) 2018 AT&T Intellectual Property. All rights reserved. +# ============================================================================= +# 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. +# ============LICENSE_END====================================================== +# +# ECOMP is a trademark and service mark of AT&T Intellectual Property. + +from setuptools import setup, find_packages + +setup( + name='dcaeapplib', + version='0.0.5', + packages=find_packages(), + author = 'Andrew Gauld', + author_email = 'ag1282@att.com', + description = ('Library for building DCAE analytics applications'), + license = 'Apache 2.0', + keywords = '', + url = '', + zip_safe = True, + install_requires=[ 'onap-dcae-cbs-docker-client>=0.0.5' ], + entry_points = { + 'console_scripts': [ + 'reconfigure.sh=dcaeapplib:reconfigure' + ] + } +) diff --git a/dcaeapplib/tests/test_dcaeapplib.py b/dcaeapplib/tests/test_dcaeapplib.py new file mode 100644 index 0000000..9995264 --- /dev/null +++ b/dcaeapplib/tests/test_dcaeapplib.py @@ -0,0 +1,112 @@ +# org.onap.dcae +# ============LICENSE_START==================================================== +# Copyright (c) 2018 AT&T Intellectual Property. All rights reserved. +# ============================================================================= +# 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. +# ============LICENSE_END====================================================== +# +# ECOMP is a trademark and service mark of AT&T Intellectual Property. + +import dcaeapplib +import requests +import json + +class Stubs: + def __init__(self): + self.toreturn = [ 's1', 's2', 's3' ] + self.config = { + "anotherparameter": 1, + "streams_subscribes": { + "myinputstream": { + "aaf_username": "user1", + "aaf_password": "pass1", + "dmaap_info": { + "topic_url": "http://messagerouter.example.com:3904/events/topic1" + } + } + }, + "streams_publishes": { + "myoutputstream": { + "aaf_username": None, + "aaf_password": None, + "dmaap_info": { + "topic_url": "http://messagerouter.example.com:3904/events/topic2" + } + } + } + } + self.health = True + self.cc = False + + def raise_for_status(self): + pass + + def json(self): + return self.toreturn + +def test_todo(monkeypatch): + stuff = Stubs() + def stub_config(): + return json.loads(json.dumps(stuff.config)) + def stub_hc(): + return stuff.health + def stub_cc(): + stuff.cc = True + monkeypatch.setattr(dcaeapplib, 'get_config', stub_config) + monkeypatch.setattr(dcaeapplib, '_httpport', 0) + env = dcaeapplib.DcaeEnv(healthCB=stub_hc, reconfigCB=stub_cc) + env.stop() # exercise stop when not running + env.start() + print('Port is {0}'.format(env._server.server_port)) + monkeypatch.setattr(dcaeapplib, '_httpport', env._server.server_port) + stuff.config['anotherparameter'] = 2 + assert env.getconfig()['anotherparameter'] == 1 + dcaeapplib.reconfigure() + assert stuff.cc is True + assert env.getconfig()['anotherparameter'] == 2 + resp = requests.get('http://localhost:{0}/healthcheck'.format(dcaeapplib._httpport)) + assert resp.status_code < 300 + stuff.health = False + resp = requests.get('http://localhost:{0}/healthcheck'.format(dcaeapplib._httpport)) + assert resp.status_code >= 500 + resp = requests.get('http://localhost:{0}/invalid'.format(dcaeapplib._httpport)) + assert resp.status_code == 404 + env.start() # exercise start when already running + env.stop() + def stub_get(*args, **kwargs): + stuff.auth = 'auth' in kwargs + return stuff + def stub_post(url, data, *args, **kwargs): + assert data == '4.11.asdfhello world' + stuff.auth = 'auth' in kwargs + stuff.posted = True + return stuff + monkeypatch.setattr(requests, 'post', stub_post) + stuff.posted = False + stuff.auth = True + env.senddata('myoutputstream', 'asdf', 'hello world') + assert stuff.posted == True + assert stuff.auth == False + monkeypatch.setattr(requests, 'get', stub_get) + assert env.hasdata('myinputstream') is False + assert env.getdata('myinputstream') == 's1' + assert stuff.auth == True + stuff.toreturn = [ 'a1' ] + assert env.getdata('myinputstream') == 's2' + assert env.hasdata('myinputstream') is True + assert env.getdata('myinputstream') == 's3' + assert env.hasdata('myinputstream') is False + assert env.getdata('myinputstream') == 'a1' + stuff.toreturn = [] + assert env.hasdata('myinputstream') is False + assert env.getdata('myinputstream') is None diff --git a/dcaeapplib/tox-local.ini b/dcaeapplib/tox-local.ini new file mode 100644 index 0000000..935a5d6 --- /dev/null +++ b/dcaeapplib/tox-local.ini @@ -0,0 +1,11 @@ +[tox] +envlist = py27 +[testenv] +deps= + onap-dcae-cbs-docker-client>=0.0.2 + pytest + coverage + pytest-cov +setenv = + PYTHONPATH={toxinidir} +commands=pytest --cov dcaeapplib --cov-report html diff --git a/dcaeapplib/tox.ini b/dcaeapplib/tox.ini new file mode 100644 index 0000000..653ac3f --- /dev/null +++ b/dcaeapplib/tox.ini @@ -0,0 +1,13 @@ +[tox] +envlist = py27,py35 +[testenv] +deps= + onap-dcae-cbs-docker-client>=0.0.5 + pytest + coverage + pytest-cov +setenv = + PYTHONPATH={toxinidir} +commands= + pytest --junitxml xunit-results.xml --cov dcaeapplib --cov-report xml + coverage xml diff --git a/eelf-logger/cpd-exclude.properties b/eelf-logger/cpd-exclude.properties new file mode 100644 index 0000000..399fb30 --- /dev/null +++ b/eelf-logger/cpd-exclude.properties @@ -0,0 +1,21 @@ +#
+# ================================================================================
+# Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+# ================================================================================
+# 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.
+# ============LICENSE_END=========================================================
+#
+#
+
+# Ignored as there are different log specs
+org.onap.dcae.utils.eelf.logger.model.spec.AuditLogSpecImpl,org.onap.dcae.utils.eelf.logger.model.spec.MetricLogSpecImpl
diff --git a/eelf-logger/eelf-logger-api/pom.xml b/eelf-logger/eelf-logger-api/pom.xml new file mode 100644 index 0000000..1d7fa1b --- /dev/null +++ b/eelf-logger/eelf-logger-api/pom.xml @@ -0,0 +1,48 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ ================================================================================ + ~ Copyright (c) 2018 AT&T Intellectual Property. All rights reserved. + ~ ================================================================================ + ~ 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. + ~ ============LICENSE_END========================================================= + ~ + --> + +<project xmlns="http://maven.apache.org/POM/4.0.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + + <modelVersion>4.0.0</modelVersion> + + <parent> + <groupId>org.onap.dcaegen2.utils</groupId> + <artifactId>eelf-logger</artifactId> + <version>1.0.0-SNAPSHOT</version> + </parent> + + <artifactId>eelf-logger-api</artifactId> + <packaging>jar</packaging> + + <!-- EELF LOGGING API CONTAINS VARIOUS INTERFACES REQUIRED TO SUPPORT SUPPORT EELF LOGGING SPECIFICATIONS --> + <name>dcaegen2-utils-eelf-logger-api</name> + <description>API contracts for EELF Logging Framework</description> + + <properties> + <main.basedir>${project.parent.basedir}</main.basedir> + <!-- SONAR SETTINGS : EXCLUDE TEST COVERAGE AS API ONLY CONTAINS INTERFACES AND NO BUSINESS LOGIC--> + <sonar.coverage.exclusions>**/api/**</sonar.coverage.exclusions> + </properties> + + <!-- NOTE: THIS API MODULE MUST NOT HAVE ANY DEPENDENCIES IN COMPILE SCOPE--> + +</project> diff --git a/eelf-logger/eelf-logger-api/src/main/java/org/onap/dcae/utils/eelf/logger/api/info/AppLogInfo.java b/eelf-logger/eelf-logger-api/src/main/java/org/onap/dcae/utils/eelf/logger/api/info/AppLogInfo.java new file mode 100644 index 0000000..bdce8d1 --- /dev/null +++ b/eelf-logger/eelf-logger-api/src/main/java/org/onap/dcae/utils/eelf/logger/api/info/AppLogInfo.java @@ -0,0 +1,101 @@ +/* + * ================================================================================ + * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + * + */ + +package org.onap.dcae.utils.eelf.logger.api.info; + +/** + * Captures information about application which is doing the logging. All app log fields must remain same for + * the whole duration of the application once its instance is created. + * + * @author Rajiv Singla + */ +public interface AppLogInfo extends LogInfo { + + /** + * Required field contains UUID which identifies this service instance inside an inventory management system + * (e.g. A&AI) to reference/manage this service as a unit + * + * @return remote VM Name or service the request is acting upon. + */ + String getServiceInstanceID(); + + /** + * Required field contains a universally unique identifier used to differentiate between multiple instances of + * the same (named), log writing service/application. Its value is set at instance creation time (and read by it, + * e.g. at start/initialization time from the environment). This value should be picked up by the component + * instance from its configuration file and subsequently used to enable differentiating log records created by + * multiple, locally load balanced EELF component or sub component instances that are otherwise identically + * configured. + * + * @return instance UUID + */ + String getInstanceUUID(); + + /** + * Optional field contains VM Name where app is deployed. + * DCAE sub components should populate this field but it can be empty if + * determined that its value can be added by the log files collecting agent itself (e.g. Splunk). + * <p> + * <b> Example: host.vm.name.com</b> + * </p> + * + * @return virtual server name + */ + String getVirtualServerName(); + + /** + * Optional field contains the logging component host server’s IP address. + * <p> + * <b>Example: 127.0.0.100</b> + * </p> + * + * @return server ip address + */ + String getServerIPAddress(); + + /** + * Required field for VM's fully qualified domain name or hosting machine fully qualified domain name. + * <p> + * <b> Example: host.fqdn.com</b> + * </p> + * + * @return server host fully qualified domain name + */ + String getServerFQDN(); + + + /** + * Contains default values for {@link AppLogInfo} + */ + interface Defaults { + + String DEFAULT_SERVICE_INSTANCE_ID = "UNKNOWN_INSTANCE_ID"; + + String DEFAULT_INSTANCE_UUID = ""; + + String DEFAULT_VIRTUAL_SERVER_NAME = ""; + + String DEFAULT_SERVER_IP_ADDRESS = "UNKNOWN_IP_ADDRESS"; + + String DEFAULT_SERVER_FQDN = "UNKNOWN_SERVER_FQDN"; + + } + + +} diff --git a/eelf-logger/eelf-logger-api/src/main/java/org/onap/dcae/utils/eelf/logger/api/info/CodeLogInfo.java b/eelf-logger/eelf-logger-api/src/main/java/org/onap/dcae/utils/eelf/logger/api/info/CodeLogInfo.java new file mode 100644 index 0000000..bea195d --- /dev/null +++ b/eelf-logger/eelf-logger-api/src/main/java/org/onap/dcae/utils/eelf/logger/api/info/CodeLogInfo.java @@ -0,0 +1,55 @@ +/* + * ================================================================================ + * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + * + */ + +package org.onap.dcae.utils.eelf.logger.api.info; + +/** + * Capture field required to log details about code which is generating the log message. + * <p> + * <b>NOTE: When using a logging framework(e.g. logback) implementation these fields may be automatically deduced - so + * settings these fields is not required by the application and even if application sets these fields the logging + * framework may ignore it + * </b> + * </p> + * + * @author Rajiv Singla + */ +public interface CodeLogInfo extends LogInfo { + + + /** + * Optional field used if wanting to trace processing of a request over a number of sub-components of a single EELF + * component. It should be preceded by a log record that establishes its chaining back to the corresponding + * requestID. + * + * @return thread ID used to trace processing of request over number of sub-components of single EELF Component. + */ + String getThreadId(); + + + /** + * Optional field: If available for OO programing languages that support this concept. This is the name of the + * class that has caused the log record to be created. + * + * @return name of the class that has the caused the log record to be created + */ + String getClassName(); + + +} diff --git a/eelf-logger/eelf-logger-api/src/main/java/org/onap/dcae/utils/eelf/logger/api/info/CustomFieldsLogInfo.java b/eelf-logger/eelf-logger-api/src/main/java/org/onap/dcae/utils/eelf/logger/api/info/CustomFieldsLogInfo.java new file mode 100644 index 0000000..634afa6 --- /dev/null +++ b/eelf-logger/eelf-logger-api/src/main/java/org/onap/dcae/utils/eelf/logger/api/info/CustomFieldsLogInfo.java @@ -0,0 +1,62 @@ +/* + * ================================================================================ + * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + * + */ + +package org.onap.dcae.utils.eelf.logger.api.info; + +/** + * Captures fields required to log Custom fields + * + * @author Rajiv Singla + */ +public interface CustomFieldsLogInfo extends LogInfo { + + /** + * Optional field that can be used by developers to include additional application-specific + * information to support operations and troubleshooting of the system. + * + * @return additional application-specific information to support operations and troubleshooting of the system. + */ + String getCustomField1(); + + /** + * Optional field that can be used by developers to include additional application-specific + * information to support operations and troubleshooting of the system. + * + * @return additional application-specific information to support operations and troubleshooting of the system. + */ + String getCustomField2(); + + /** + * Optional field that can be used by developers to include additional application-specific + * information to support operations and troubleshooting of the system. + * + * @return additional application-specific information to support operations and troubleshooting of the system. + */ + String getCustomField3(); + + /** + * Optional field that can be used by developers to include additional application-specific + * information to support operations and troubleshooting of the system. + * + * @return additional application-specific information to support operations and troubleshooting of the system. + */ + String getCustomField4(); + + +} diff --git a/eelf-logger/eelf-logger-api/src/main/java/org/onap/dcae/utils/eelf/logger/api/info/ErrorLogInfo.java b/eelf-logger/eelf-logger-api/src/main/java/org/onap/dcae/utils/eelf/logger/api/info/ErrorLogInfo.java new file mode 100644 index 0000000..876037c --- /dev/null +++ b/eelf-logger/eelf-logger-api/src/main/java/org/onap/dcae/utils/eelf/logger/api/info/ErrorLogInfo.java @@ -0,0 +1,76 @@ +/* + * ================================================================================ + * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + * + */ + +package org.onap.dcae.utils.eelf.logger.api.info; + +/** + * Captures fields required to log error related information + * + * @author Rajiv Singla + */ +public interface ErrorLogInfo extends LogInfo { + + + /** + * Required field contains an error code representing the error condition. The codes can be chose by + * the logging application but they should adhere to the guidelines embodied in the table below: + * <table summary="Error Codes" cellspacing=0 border=1> + * <tr> + * <td style=min-width:50px>Error type</td> + * <td style=min-width:50px>Notes</td> + * </tr> + * <tr> + * <td style=min-width:50px>100</td> + * <td style=min-width:50px>Permission errors</td> + * </tr> + * <tr> + * <td style=min-width:50px>200</td> + * <td style=min-width:50px>Availability errors/Timeouts</td> + * </tr> + * <tr> + * <td style=min-width:50px>300</td> + * <td style=min-width:50px>Data errors</td> + * </tr> + * <tr> + * <td style=min-width:50px>400</td> + * <td style=min-width:50px>Schema errors</td> + * </tr> + * <tr> + * <td style=min-width:50px>500</td> + * <td style=min-width:50px>Business process errors</td> + * </tr> + * <tr> + * <td style=min-width:50px>900</td> + * <td style=min-width:50px>Unknown Errors</td> + * </tr> + * </table> + * + * @return error Code + */ + Integer getErrorCode(); + + + /** + * Required field contains a human readable description of the error condition. + * + * @return human readable description of the error condition + */ + String getErrorDescription(); + +} diff --git a/eelf-logger/eelf-logger-api/src/main/java/org/onap/dcae/utils/eelf/logger/api/info/LogInfo.java b/eelf-logger/eelf-logger-api/src/main/java/org/onap/dcae/utils/eelf/logger/api/info/LogInfo.java new file mode 100644 index 0000000..4a3680f --- /dev/null +++ b/eelf-logger/eelf-logger-api/src/main/java/org/onap/dcae/utils/eelf/logger/api/info/LogInfo.java @@ -0,0 +1,30 @@ +/* + * ================================================================================ + * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + * + */ + +package org.onap.dcae.utils.eelf.logger.api.info; + +import java.io.Serializable; + +/** + * Marker interface for all EELF Logging Information Components + * + * @author Rajiv Singla + */ +public interface LogInfo extends Serializable { +} diff --git a/eelf-logger/eelf-logger-api/src/main/java/org/onap/dcae/utils/eelf/logger/api/info/LogLevelCategory.java b/eelf-logger/eelf-logger-api/src/main/java/org/onap/dcae/utils/eelf/logger/api/info/LogLevelCategory.java new file mode 100644 index 0000000..665a280 --- /dev/null +++ b/eelf-logger/eelf-logger-api/src/main/java/org/onap/dcae/utils/eelf/logger/api/info/LogLevelCategory.java @@ -0,0 +1,36 @@ +/* + * ================================================================================ + * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + * + */ + +package org.onap.dcae.utils.eelf.logger.api.info; + +/** + * Captures various logging levels. + * NOTE: Enum ordered signifies low to high log level severity + * + * @author Rajiv Singla + */ +public enum LogLevelCategory implements LogInfo { + + DEBUG, + INFO, + WARN, + ERROR, + FATAL; + +} diff --git a/eelf-logger/eelf-logger-api/src/main/java/org/onap/dcae/utils/eelf/logger/api/info/MessageLogInfo.java b/eelf-logger/eelf-logger-api/src/main/java/org/onap/dcae/utils/eelf/logger/api/info/MessageLogInfo.java new file mode 100644 index 0000000..cd53ccf --- /dev/null +++ b/eelf-logger/eelf-logger-api/src/main/java/org/onap/dcae/utils/eelf/logger/api/info/MessageLogInfo.java @@ -0,0 +1,62 @@ +/* + * ================================================================================ + * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + * + */ + +package org.onap.dcae.utils.eelf.logger.api.info; + +import java.util.Date; + +/** + * Captures fields required for message level logging. These fields are mostly derived fields. For example: creation + * timestamp can be auto generated based on system time, {@link RequestStatusCode} and {@link NagiosAlertLevel} can be + * derived based on {@link LogLevelCategory} + * + * @author Rajiv Singla + */ +public interface MessageLogInfo extends LogInfo { + + + /** + * Required field to capture when the message was created + * The value should be represented in UTC and formatted according to ISO 8601. + * <p> + * <b>Example: 2015-06-03T13:21:58+00:00</b> + * </p> + * + * @return message creation creationTimestamp + */ + Date getCreationTimestamp(); + + /** + * Required field contains a value of COMPLETE or ERROR to indicate high level success or failure of the + * request related activities. + * + * @return value to indicate high level success or failure of the request related activities + */ + RequestStatusCode getStatusCode(); + + + /** + * Optional field for Nagios monitoring/alerting severity code + * + * @return nagios monitoring/alerting severity code + */ + NagiosAlertLevel getAlertSeverity(); + + +} diff --git a/eelf-logger/eelf-logger-api/src/main/java/org/onap/dcae/utils/eelf/logger/api/info/MiscLogInfo.java b/eelf-logger/eelf-logger-api/src/main/java/org/onap/dcae/utils/eelf/logger/api/info/MiscLogInfo.java new file mode 100644 index 0000000..bf1e451 --- /dev/null +++ b/eelf-logger/eelf-logger-api/src/main/java/org/onap/dcae/utils/eelf/logger/api/info/MiscLogInfo.java @@ -0,0 +1,45 @@ +/* + * ================================================================================ + * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + * + */ + +package org.onap.dcae.utils.eelf.logger.api.info; + +/** + * Captures optional / deprecated fields that can be populated as per EELF Logging Requirements + * + * @author Rajiv Singla + */ +public interface MiscLogInfo extends LogInfo { + + /** + * Optional field that can can be used to capture the flow of a transaction through the system by + * indicating the components and operations involved in processed. If present, it can be denoted by a comma + * separated list of components and applications. + * + * @return list of comma separated components and operations involved in processing + */ + String getProcessId(); + + /** + * This field is deprecated and should be left empty. + * + * @return deprecated field value - should be empty + */ + String getUnused(); + +} diff --git a/eelf-logger/eelf-logger-api/src/main/java/org/onap/dcae/utils/eelf/logger/api/info/NagiosAlertLevel.java b/eelf-logger/eelf-logger-api/src/main/java/org/onap/dcae/utils/eelf/logger/api/info/NagiosAlertLevel.java new file mode 100644 index 0000000..3da5fc3 --- /dev/null +++ b/eelf-logger/eelf-logger-api/src/main/java/org/onap/dcae/utils/eelf/logger/api/info/NagiosAlertLevel.java @@ -0,0 +1,52 @@ +/* + * ================================================================================ + * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + * + */ + +package org.onap.dcae.utils.eelf.logger.api.info; + +/** + * Enum for Nagios monitoring/alerting codes as per table below. + * <p> + * <table cellspacing=0 border=1> + * <tr><th>Return Code</th><th>Service State</th><th>Host State</th></tr> + * <tr><td>0</td><td>OK</td><td>UP</td></tr> + * <tr><td>1</td><td>WARNING</td><td>UP or DOWN/UNREACHABLE*</td></tr> + * <tr><td>2</td><td>CRITICAL</td><td>DOWN/UNREACHABLE</td></tr> + * <tr><td>3</td><td>UNKNOWN</td><td>DOWN/UNREACHABLE</td></tr> + * </table> + * + * @author Rajiv Singla + */ +public enum NagiosAlertLevel implements LogInfo { + + OK("0"), + WARNING("1"), + CRITICAL("2"), + UNKNOWN("3"); + + private String severityCode; + + NagiosAlertLevel(final String severityCode) { + this.severityCode = severityCode; + } + + public String getSeverityCode() { + return severityCode; + } + +} diff --git a/eelf-logger/eelf-logger-api/src/main/java/org/onap/dcae/utils/eelf/logger/api/info/RequestIdLogInfo.java b/eelf-logger/eelf-logger-api/src/main/java/org/onap/dcae/utils/eelf/logger/api/info/RequestIdLogInfo.java new file mode 100644 index 0000000..68d5a17 --- /dev/null +++ b/eelf-logger/eelf-logger-api/src/main/java/org/onap/dcae/utils/eelf/logger/api/info/RequestIdLogInfo.java @@ -0,0 +1,44 @@ +/* + * ================================================================================ + * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + * + */ + +package org.onap.dcae.utils.eelf.logger.api.info; + +/** + * Captures fields required for logging request information + * + * @author Rajiv Singla + */ +public interface RequestIdLogInfo extends LogInfo { + + /** + * Required field containing requestID which uniquely that identifies a single transaction request within the EELF + * platform. Its value is conforms to RFC4122 UUID. The requestID value is passed using a REST API from one + * EELF component to another via HTTP Headers named X-RequestID + * <p> + * <b>724229c0-9945-11e5-bcde-0002a5d5c51b:1234</b> + * </p> + * If receiving a composite requestID value, e.g. something of the form UUID-1:UUID-2, the receiving component + * should only use the UUID-1 portion (i.e. remove the “:” and any trailing suffix, e.g. UUID-2) as the requestID + * field value for its log files. + * + * @return requestID which uniquely that identifies a single transaction request within the EELF + */ + String getRequestId(); + +} diff --git a/eelf-logger/eelf-logger-api/src/main/java/org/onap/dcae/utils/eelf/logger/api/info/RequestStatusCode.java b/eelf-logger/eelf-logger-api/src/main/java/org/onap/dcae/utils/eelf/logger/api/info/RequestStatusCode.java new file mode 100644 index 0000000..b022b80 --- /dev/null +++ b/eelf-logger/eelf-logger-api/src/main/java/org/onap/dcae/utils/eelf/logger/api/info/RequestStatusCode.java @@ -0,0 +1,32 @@ +/* + * ================================================================================ + * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + * + */ + +package org.onap.dcae.utils.eelf.logger.api.info; + +/** + * Enum to indicate high level success or failure of the request related activities + * + * @author Rajiv Singla + */ +public enum RequestStatusCode { + + ERROR, + COMPLETE; + +} diff --git a/eelf-logger/eelf-logger-api/src/main/java/org/onap/dcae/utils/eelf/logger/api/info/RequestTimingLogInfo.java b/eelf-logger/eelf-logger-api/src/main/java/org/onap/dcae/utils/eelf/logger/api/info/RequestTimingLogInfo.java new file mode 100644 index 0000000..7448e69 --- /dev/null +++ b/eelf-logger/eelf-logger-api/src/main/java/org/onap/dcae/utils/eelf/logger/api/info/RequestTimingLogInfo.java @@ -0,0 +1,64 @@ +/* + * ================================================================================ + * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + * + */ + +package org.onap.dcae.utils.eelf.logger.api.info; + +import java.util.Date; + +/** + * Captures Logging fields required for request timing related information + * + * @author Rajiv Singla + */ +public interface RequestTimingLogInfo extends LogInfo { + + /** + * Required field containing creationTimestamp when the request processing started. + * The value should be represented in UTC and formatted according to ISO 8601. + * <p> + * <b>Example: 2015-06-03T13:21:58+00:00</b> + * </p> + * + * @return request activity begin creationTimestamp + */ + Date getBeginTimestamp(); + + + /** + * Required field containing creationTimestamp when the request processed stopped. + * The value should be represented in UTC and formatted according to ISO 8601. + * <p> + * <b>Example: 2015-06-03T13:21:58+00:00</b> + * </p> + * + * @return request activity end creationTimestamp + */ + Date getEndTimestamp(); + + + /** + * Required field contains the elapsed time to complete processing of an API call or transaction request (e.g., + * processing of a message that was received). This value should be the difference between EndTimestamp and + * BeginTimestamp fields and should be expressed in milliseconds. + * + * @return request processing elapsed time in milliseconds + */ + Long getElapsedTime(); + +} diff --git a/eelf-logger/eelf-logger-api/src/main/java/org/onap/dcae/utils/eelf/logger/api/info/ResponseLogInfo.java b/eelf-logger/eelf-logger-api/src/main/java/org/onap/dcae/utils/eelf/logger/api/info/ResponseLogInfo.java new file mode 100644 index 0000000..1929e7f --- /dev/null +++ b/eelf-logger/eelf-logger-api/src/main/java/org/onap/dcae/utils/eelf/logger/api/info/ResponseLogInfo.java @@ -0,0 +1,81 @@ +/* + * ================================================================================ + * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + * + */ + +package org.onap.dcae.utils.eelf.logger.api.info; + +/** + * Captures field required for logging Response information + * + * @author Rajiv Singla + */ +public interface ResponseLogInfo extends LogInfo { + + /** + * Required field contains application-specific response codes. While error codes are + * application-specific, they + * should conform categories mentioned in table below in order to provide consistency + * <p> + * <table cellspacing=0 border=1> + * <tr> + * <th style=min-width:50px><b>Error type</b></th> + * <th style=min-width:50px><b>Notes</b></th> + * </tr> + * <tr> + * <td style=min-width:50px>0</td> + * <td style=min-width:50px>Success</td> + * </tr> + * <tr> + * <td style=min-width:50px>100</td> + * <td style=min-width:50px>Permission errors</td> + * </tr> + * <tr> + * <td style=min-width:50px>200</td> + * <td style=min-width:50px>Availability errors/Timeouts</td> + * </tr> + * <tr> + * <td style=min-width:50px>300</td> + * <td style=min-width:50px>Data errors</td> + * </tr> + * <tr> + * <td style=min-width:50px>400</td> + * <td style=min-width:50px>Schema errors</td> + * </tr> + * <tr> + * <td style=min-width:50px>500</td> + * <td style=min-width:50px>Business process errors</td> + * </tr> + * <tr> + * <td style=min-width:50px>900</td> + * <td style=min-width:50px>Unknown Errors</td> + * </tr> + * </table> + * + * @return application-specific error code + */ + Integer getResponseCode(); + + + /** + * Required field contains a human readable description of the {@link #getResponseCode()}. + * + * @return human readable description of the response code + */ + String getResponseDescription(); + +} diff --git a/eelf-logger/eelf-logger-api/src/main/java/org/onap/dcae/utils/eelf/logger/api/info/ServiceLogInfo.java b/eelf-logger/eelf-logger-api/src/main/java/org/onap/dcae/utils/eelf/logger/api/info/ServiceLogInfo.java new file mode 100644 index 0000000..0287cef --- /dev/null +++ b/eelf-logger/eelf-logger-api/src/main/java/org/onap/dcae/utils/eelf/logger/api/info/ServiceLogInfo.java @@ -0,0 +1,61 @@ +/* + * ================================================================================ + * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + * + */ + +package org.onap.dcae.utils.eelf.logger.api.info; + +/** + * Captures information about logging fields for application acting as service and handling requests from other + * applications + * + * @author Rajiv Singla + */ +public interface ServiceLogInfo extends LogInfo { + + /** + * Required field contains the developer given name of the ecomp component's exposed api (~='method', function') + * invoked. For example if the application is exposing a REST interface and exposing runtime metrics then the + * service name can be: appName-getMetrics + * + * @return name of the API invoked by the application + */ + String getServiceName(); + + + /** + * Optional field contains the name of the client or user invoking the service. + * It may be an application, user name or mech id. + * + * @return name of the client or user invoking the API if known + */ + String getPartnerName(); + + + /** + * Optional field contains requesting remote client application’s IP address. Use UNKNOWN or an empty string if not + * available. + * + * @return remote client application’s IP address + */ + String getClientIPAddress(); + + +} + + + diff --git a/eelf-logger/eelf-logger-api/src/main/java/org/onap/dcae/utils/eelf/logger/api/info/TargetServiceLogInfo.java b/eelf-logger/eelf-logger-api/src/main/java/org/onap/dcae/utils/eelf/logger/api/info/TargetServiceLogInfo.java new file mode 100644 index 0000000..d9b1f98 --- /dev/null +++ b/eelf-logger/eelf-logger-api/src/main/java/org/onap/dcae/utils/eelf/logger/api/info/TargetServiceLogInfo.java @@ -0,0 +1,54 @@ +/* + * ================================================================================ + * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + * + */ + +package org.onap.dcae.utils.eelf.logger.api.info; + +/** + * Captures fields for logging application which is calling an external/target service + * + * @author Rajiv Singla + */ +public interface TargetServiceLogInfo extends LogInfo { + + /** + * Required field containing name of EELF component/sub component or non-EELF entity which is invoked by the + * logging application + * + * @return target entity name which is invoked by the logging application + */ + String getTargetEntity(); + + + /** + * Required field containing name of External API/operation activities invoked on {@link #getTargetEntity()} + * + * @return target service name invoked by the logging application + */ + String getTargetServiceName(); + + + /** + * Optional field containing target VNF or VM being acted upon by the logging application. This field contains the + * virtual entity that is the target of the action for example the FQDN of the target virtual entity + * + * @return target Virtual Entity + */ + String getTargetVirtualEntity(); + +} diff --git a/eelf-logger/eelf-logger-api/src/main/java/org/onap/dcae/utils/eelf/logger/api/info/package-info.java b/eelf-logger/eelf-logger-api/src/main/java/org/onap/dcae/utils/eelf/logger/api/info/package-info.java new file mode 100644 index 0000000..45bddd1 --- /dev/null +++ b/eelf-logger/eelf-logger-api/src/main/java/org/onap/dcae/utils/eelf/logger/api/info/package-info.java @@ -0,0 +1,28 @@ +/* + * ================================================================================ + * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + * + */ + +/** + * Captures EELF logging information about various types. + * <p> + * The logging information is segregated into various information different types as to their relevance in particular + * cases. + * + * @author Rajiv Singla + */ +package org.onap.dcae.utils.eelf.logger.api.info; diff --git a/eelf-logger/eelf-logger-api/src/main/java/org/onap/dcae/utils/eelf/logger/api/log/AuditLog.java b/eelf-logger/eelf-logger-api/src/main/java/org/onap/dcae/utils/eelf/logger/api/log/AuditLog.java new file mode 100644 index 0000000..952176e --- /dev/null +++ b/eelf-logger/eelf-logger-api/src/main/java/org/onap/dcae/utils/eelf/logger/api/log/AuditLog.java @@ -0,0 +1,130 @@ +/* + * ================================================================================ + * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + * + */ + +package org.onap.dcae.utils.eelf.logger.api.log; + + +import org.onap.dcae.utils.eelf.logger.api.info.LogLevelCategory; +import org.onap.dcae.utils.eelf.logger.api.spec.AuditLogSpec; +import org.onap.dcae.utils.eelf.logger.api.spec.OptionalLogSpec; + +/** + * Audit Log captures all log levels supported by audit specifications + * + * @author Rajiv Singla + */ +public interface AuditLog { + + /** + * Logs audit message with provided {@link LogLevelCategory} + * + * @param logLevelCategory log level category + * @param message log message + * @param auditLogSpec audit log spec + * @param optionalLogSpec optional log spec + * @param args argument values for log message interpolation + */ + void log(LogLevelCategory logLevelCategory, String message, AuditLogSpec auditLogSpec, + OptionalLogSpec optionalLogSpec, String... args); + + /** + * Logs audit message with provided {@link LogLevelCategory} and with default {@link OptionalLogSpec} + * + * @param logLevelCategory log level category + * @param message log message + * @param auditLogSpec audit log spec + * @param args argument values for log message interpolation + */ + void log(LogLevelCategory logLevelCategory, String message, AuditLogSpec auditLogSpec, String... args); + + + /** + * Logs audit message with provided INFO {@link LogLevelCategory} + * + * @param message log message + * @param auditLogSpec audit log spec + * @param args argument values for log message interpolation + */ + void info(String message, AuditLogSpec auditLogSpec, OptionalLogSpec optionalLogSpec, String... args); + + /** + * Logs audit message with provided INFO {@link LogLevelCategory} and with default {@link OptionalLogSpec} + * + * @param message log message + * @param auditLogSpec audit log spec + * @param args argument values for log message interpolation + */ + void info(String message, AuditLogSpec auditLogSpec, String... args); + + + /** + * Logs audit message with provided WARN {@link LogLevelCategory} + * + * @param message log message + * @param auditLogSpec audit log spec + * @param args argument values for log message interpolation + */ + void warn(String message, AuditLogSpec auditLogSpec, OptionalLogSpec optionalLogSpec, String... args); + + /** + * Logs audit message with provided WARN {@link LogLevelCategory} and with default {@link OptionalLogSpec} + * + * @param message log message + * @param auditLogSpec audit log spec + * @param args argument values for log message interpolation + */ + void warn(String message, AuditLogSpec auditLogSpec, String... args); + + /** + * Logs audit message with provided ERROR {@link LogLevelCategory} + * + * @param message log message + * @param auditLogSpec audit log spec + * @param args argument values for log message interpolation + */ + void error(String message, AuditLogSpec auditLogSpec, OptionalLogSpec optionalLogSpec, String... args); + + /** + * Logs audit message with provided ERROR {@link LogLevelCategory} and with default {@link OptionalLogSpec} + * + * @param message log message + * @param auditLogSpec audit log spec + * @param args argument values for log message interpolation + */ + void error(String message, AuditLogSpec auditLogSpec, String... args); + + /** + * Logs audit message with provided FATAL {@link LogLevelCategory} + * + * @param message log message + * @param auditLogSpec audit log spec + * @param args argument values for log message interpolation + */ + void fatal(String message, AuditLogSpec auditLogSpec, OptionalLogSpec optionalLogSpec, String... args); + + /** + * Logs audit message with provided FATAL {@link LogLevelCategory} and with default {@link OptionalLogSpec} + * + * @param message log message + * @param auditLogSpec audit log spec + * @param args argument values for log message interpolation + */ + void fatal(String message, AuditLogSpec auditLogSpec, String... args); + +} diff --git a/eelf-logger/eelf-logger-api/src/main/java/org/onap/dcae/utils/eelf/logger/api/log/DebugLog.java b/eelf-logger/eelf-logger-api/src/main/java/org/onap/dcae/utils/eelf/logger/api/log/DebugLog.java new file mode 100644 index 0000000..98a0921 --- /dev/null +++ b/eelf-logger/eelf-logger-api/src/main/java/org/onap/dcae/utils/eelf/logger/api/log/DebugLog.java @@ -0,0 +1,76 @@ +/* + * ================================================================================ + * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + * + */ + +package org.onap.dcae.utils.eelf.logger.api.log; + +import org.onap.dcae.utils.eelf.logger.api.info.LogLevelCategory; +import org.onap.dcae.utils.eelf.logger.api.spec.DebugLogSpec; +import org.onap.dcae.utils.eelf.logger.api.spec.OptionalLogSpec; + +/** + * Debug Log captures all log levels supported by debug specifications. + * <p> + * <b>NOTE: DEBUG Log is optional as per EELF Specifications</b> + * + * @author Rajiv Singla + */ +public interface DebugLog { + + /** + * Logs debug message with provided {@link LogLevelCategory} + * + * @param logLevelCategory log level category + * @param message log message + * @param debugLogSpec debug log spec + * @param optionalLogSpec optional log spec + * @param args argument values for log message interpolation + */ + void log(LogLevelCategory logLevelCategory, String message, DebugLogSpec debugLogSpec, + OptionalLogSpec optionalLogSpec, String... args); + + /** + * Logs debug message with provided {@link LogLevelCategory} and with default {@link OptionalLogSpec} + * + * @param logLevelCategory log level category + * @param message log message + * @param debugLogSpec debug log spec + * @param args argument values for log message interpolation + */ + void log(LogLevelCategory logLevelCategory, String message, DebugLogSpec debugLogSpec, String... args); + + + /** + * Logs debug message with provided DEBUG {@link LogLevelCategory} + * + * @param message log message + * @param debugLogSpec debug log spec + * @param args argument values for log message interpolation + */ + void debug(String message, DebugLogSpec debugLogSpec, OptionalLogSpec optionalLogSpec, String... args); + + /** + * Logs debug message with provided DEBUG {@link LogLevelCategory} and with default {@link OptionalLogSpec} + * + * @param message log message + * @param debugLogSpec debug log spec + * @param args argument values for log message interpolation + */ + void debug(String message, DebugLogSpec debugLogSpec, String... args); + +} diff --git a/eelf-logger/eelf-logger-api/src/main/java/org/onap/dcae/utils/eelf/logger/api/log/EELFLogFactory.java b/eelf-logger/eelf-logger-api/src/main/java/org/onap/dcae/utils/eelf/logger/api/log/EELFLogFactory.java new file mode 100644 index 0000000..2cfb2ec --- /dev/null +++ b/eelf-logger/eelf-logger-api/src/main/java/org/onap/dcae/utils/eelf/logger/api/log/EELFLogFactory.java @@ -0,0 +1,85 @@ +/* + * ================================================================================ + * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + * + */ + +package org.onap.dcae.utils.eelf.logger.api.log; + + +import org.onap.dcae.utils.eelf.logger.api.noop.NoOpEELFLogger; + +import java.lang.reflect.InvocationTargetException; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.ServiceLoader; +import java.util.WeakHashMap; + +/** + * EELF Log Factory uses {@link ServiceLoader} to load implementations of {@link EELFLogger} in application + * classpath. If no EELF Logging implementations are found - eelf logging is disabled and {@link NoOpEELFLogger} + * is used. + * + * @author Rajiv Singla + */ +public class EELFLogFactory { + + private static final ServiceLoader<EELFLogger> SERVICE_LOADER = ServiceLoader.load(EELFLogger.class); + private static final Map<Class<?>, EELFLogger> LOGGER_CACHE = new WeakHashMap<>(64); + + private static List<EELFLogger> loggerImplementations = new LinkedList<>(); + + static { + + for (EELFLogger loggerImplementation : SERVICE_LOADER) { + loggerImplementations.add(loggerImplementation); + } + + if (loggerImplementations.isEmpty()) { + System.err.println( + "EELF LOGGING ERROR: Unable to find any EELF Logger Implementations in the classpath."); + System.err.println("=============EELF LOGGING IS DISABLED================"); + loggerImplementations.add(NoOpEELFLogger.getInstance()); + } + + } + + private EELFLogFactory() { + // private constructor + } + + public static <T> EELFLogger getLogger(Class<T> clazz) { + + if (LOGGER_CACHE.get(clazz) != null) { + return LOGGER_CACHE.get(clazz); + } + + EELFLogger EELFLogger = null; + try { + EELFLogger = loggerImplementations.get(0).getClass().getConstructor(Class.class) + .newInstance(clazz); + return EELFLogger; + + } catch ( + InstantiationException | IllegalAccessException | InvocationTargetException | NoSuchMethodException e) { + throw new IllegalStateException("Error while Creating EELF Logger", e); + } + + } + + +} diff --git a/eelf-logger/eelf-logger-api/src/main/java/org/onap/dcae/utils/eelf/logger/api/log/EELFLogger.java b/eelf-logger/eelf-logger-api/src/main/java/org/onap/dcae/utils/eelf/logger/api/log/EELFLogger.java new file mode 100644 index 0000000..500d814 --- /dev/null +++ b/eelf-logger/eelf-logger-api/src/main/java/org/onap/dcae/utils/eelf/logger/api/log/EELFLogger.java @@ -0,0 +1,67 @@ +/* + * ================================================================================ + * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + * + */ + +package org.onap.dcae.utils.eelf.logger.api.log; + +/** + * EELF Logger is main abstraction which applications use to log EELF Compliant log messages + * + * @author Rajiv Singla + */ +public interface EELFLogger { + + /** + * Provides Audit Log + * + * @return Audit log + */ + AuditLog auditLog(); + + + /** + * Provides Metric Log + * + * @return metric log + */ + MetricLog metricLog(); + + /** + * Provides Error Log + * + * @return error log + */ + ErrorLog errorLog(); + + + /** + * Provides Debug Log + * + * @return debug log + */ + DebugLog debugLog(); + + /** + * Provides logging context + * + * @return logging context + */ + EELFLoggerContext loggingContext(); + + +} diff --git a/eelf-logger/eelf-logger-api/src/main/java/org/onap/dcae/utils/eelf/logger/api/log/EELFLoggerContext.java b/eelf-logger/eelf-logger-api/src/main/java/org/onap/dcae/utils/eelf/logger/api/log/EELFLoggerContext.java new file mode 100644 index 0000000..5910da5 --- /dev/null +++ b/eelf-logger/eelf-logger-api/src/main/java/org/onap/dcae/utils/eelf/logger/api/log/EELFLoggerContext.java @@ -0,0 +1,56 @@ +/* + * ================================================================================ + * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + * + */ + +package org.onap.dcae.utils.eelf.logger.api.log; + + +import org.onap.dcae.utils.eelf.logger.api.spec.AppLogSpec; + +/** + * EELF Logger Context contains fields are set during application creation time and are fixed for the entire + * duration of the application lifetime + * + * @author Rajiv Singla + */ +public interface EELFLoggerContext { + + /** + * Returns App Log Spec + * + * @return current app log spec + */ + AppLogSpec getAppLogSpec(); + + + /** + * Sets new App Log Spec + * + * @param appLogSpec new app log spec + */ + void setAppLogSpec(AppLogSpec appLogSpec); + + + /** + * Returns true if logging context is already initialized + * + * @return true if logger context is already initialized + */ + boolean isInitialized(); + +} diff --git a/eelf-logger/eelf-logger-api/src/main/java/org/onap/dcae/utils/eelf/logger/api/log/ErrorLog.java b/eelf-logger/eelf-logger-api/src/main/java/org/onap/dcae/utils/eelf/logger/api/log/ErrorLog.java new file mode 100644 index 0000000..6b27755 --- /dev/null +++ b/eelf-logger/eelf-logger-api/src/main/java/org/onap/dcae/utils/eelf/logger/api/log/ErrorLog.java @@ -0,0 +1,93 @@ +/* + * ================================================================================ + * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + * + */ + +package org.onap.dcae.utils.eelf.logger.api.log; + + +import org.onap.dcae.utils.eelf.logger.api.info.LogLevelCategory; +import org.onap.dcae.utils.eelf.logger.api.spec.ErrorLogSpec; +import org.onap.dcae.utils.eelf.logger.api.spec.OptionalLogSpec; + +/** + * @author Rajiv Singla + */ +public interface ErrorLog { + + /** + * Logs error message with provided {@link LogLevelCategory} + * + * @param logLevelCategory log level category + * @param message log message + * @param errorLogSpec error log spec + * @param optionalLogSpec optional log spec + * @param args argument values for log message interpolation + */ + void log(LogLevelCategory logLevelCategory, String message, ErrorLogSpec errorLogSpec, + OptionalLogSpec optionalLogSpec, String... args); + + /** + * Logs error message with provided {@link LogLevelCategory} and with default {@link OptionalLogSpec} + * + * @param logLevelCategory log level category + * @param message log message + * @param errorLogSpec error log spec + * @param args argument values for log message interpolation + */ + void log(LogLevelCategory logLevelCategory, String message, ErrorLogSpec errorLogSpec, String... args); + + + /** + * Logs error message with ERROR {@link LogLevelCategory} + * + * @param message log message + * @param errorLogSpec error log spec + * @param args argument values for log message interpolation + */ + void error(String message, ErrorLogSpec errorLogSpec, OptionalLogSpec optionalLogSpec, String... args); + + /** + * Logs error message with ERROR {@link LogLevelCategory} and with default {@link OptionalLogSpec} + * + * @param message log message + * @param errorLogSpec error log spec + * @param args argument values for log message interpolation + */ + void error(String message, ErrorLogSpec errorLogSpec, String... args); + + + /** + * Logs error message with WARN {@link LogLevelCategory} + * + * @param message log message + * @param errorLogSpec error log spec + * @param args argument values for log message interpolation + */ + void warn(String message, ErrorLogSpec errorLogSpec, OptionalLogSpec optionalLogSpec, String... args); + + /** + * Logs error message with WARN {@link LogLevelCategory} and with default {@link OptionalLogSpec} + * + * @param message log message + * @param errorLogSpec error log spec + * @param args argument values for log message interpolation + */ + void warn(String message, ErrorLogSpec errorLogSpec, String... args); + + +} diff --git a/eelf-logger/eelf-logger-api/src/main/java/org/onap/dcae/utils/eelf/logger/api/log/MetricLog.java b/eelf-logger/eelf-logger-api/src/main/java/org/onap/dcae/utils/eelf/logger/api/log/MetricLog.java new file mode 100644 index 0000000..ebc33ca --- /dev/null +++ b/eelf-logger/eelf-logger-api/src/main/java/org/onap/dcae/utils/eelf/logger/api/log/MetricLog.java @@ -0,0 +1,130 @@ +/* + * ================================================================================ + * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + * + */ + +package org.onap.dcae.utils.eelf.logger.api.log; + + +import org.onap.dcae.utils.eelf.logger.api.info.LogLevelCategory; +import org.onap.dcae.utils.eelf.logger.api.spec.MetricLogSpec; +import org.onap.dcae.utils.eelf.logger.api.spec.OptionalLogSpec; + +/** + * Metric Log captures all log levels supported by metric specifications + * + * @author Rajiv Singla + */ +public interface MetricLog { + + /** + * Logs metric message with provided {@link LogLevelCategory} + * + * @param logLevelCategory log level category + * @param message log message + * @param metricLogSpec metric log spec + * @param optionalLogSpec optional log spec + * @param args argument values for log message interpolation + */ + void log(LogLevelCategory logLevelCategory, String message, MetricLogSpec metricLogSpec, + OptionalLogSpec optionalLogSpec, String... args); + + /** + * Logs metric message with provided {@link LogLevelCategory} and with default {@link OptionalLogSpec} + * + * @param logLevelCategory log level category + * @param message log message + * @param metricLogSpec metric log spec + * @param args argument values for log message interpolation + */ + void log(LogLevelCategory logLevelCategory, String message, MetricLogSpec metricLogSpec, String... args); + + + /** + * Logs metric message with provided INFO {@link LogLevelCategory} + * + * @param message log message + * @param metricLogSpec metric log spec + * @param args argument values for log message interpolation + */ + void info(String message, MetricLogSpec metricLogSpec, OptionalLogSpec optionalLogSpec, String... args); + + /** + * Logs metric message with provided INFO {@link LogLevelCategory} and with default {@link OptionalLogSpec} + * + * @param message log message + * @param metricLogSpec metric log spec + * @param args argument values for log message interpolation + */ + void info(String message, MetricLogSpec metricLogSpec, String... args); + + + /** + * Logs metric message with provided WARN {@link LogLevelCategory} + * + * @param message log message + * @param metricLogSpec metric log spec + * @param args argument values for log message interpolation + */ + void warn(String message, MetricLogSpec metricLogSpec, OptionalLogSpec optionalLogSpec, String... args); + + /** + * Logs metric message with provided WARN {@link LogLevelCategory} and with default {@link OptionalLogSpec} + * + * @param message log message + * @param metricLogSpec metric log spec + * @param args argument values for log message interpolation + */ + void warn(String message, MetricLogSpec metricLogSpec, String... args); + + /** + * Logs metric message with provided ERROR {@link LogLevelCategory} + * + * @param message log message + * @param metricLogSpec metric log spec + * @param args argument values for log message interpolation + */ + void error(String message, MetricLogSpec metricLogSpec, OptionalLogSpec optionalLogSpec, String... args); + + /** + * Logs metric message with provided ERROR {@link LogLevelCategory} and with default {@link OptionalLogSpec} + * + * @param message log message + * @param metricLogSpec metric log spec + * @param args argument values for log message interpolation + */ + void error(String message, MetricLogSpec metricLogSpec, String... args); + + /** + * Logs metric message with provided FATAL {@link LogLevelCategory} + * + * @param message log message + * @param metricLogSpec metric log spec + * @param args argument values for log message interpolation + */ + void fatal(String message, MetricLogSpec metricLogSpec, OptionalLogSpec optionalLogSpec, String... args); + + /** + * Logs metric message with provided FATAL {@link LogLevelCategory} and with default {@link OptionalLogSpec} + * + * @param message log message + * @param metricLogSpec metric log spec + * @param args argument values for log message interpolation + */ + void fatal(String message, MetricLogSpec metricLogSpec, String... args); + +} diff --git a/eelf-logger/eelf-logger-api/src/main/java/org/onap/dcae/utils/eelf/logger/api/log/package-info.java b/eelf-logger/eelf-logger-api/src/main/java/org/onap/dcae/utils/eelf/logger/api/log/package-info.java new file mode 100644 index 0000000..e24ccc9 --- /dev/null +++ b/eelf-logger/eelf-logger-api/src/main/java/org/onap/dcae/utils/eelf/logger/api/log/package-info.java @@ -0,0 +1,23 @@ +/* + * ================================================================================ + * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + * + */ + +/** + * Contains Logging API contracts for various EELF Logs (e.g. Audit, Metric, Error, Debug etc) + */ +package org.onap.dcae.utils.eelf.logger.api.log; diff --git a/eelf-logger/eelf-logger-api/src/main/java/org/onap/dcae/utils/eelf/logger/api/noop/NoOpAuditLog.java b/eelf-logger/eelf-logger-api/src/main/java/org/onap/dcae/utils/eelf/logger/api/noop/NoOpAuditLog.java new file mode 100644 index 0000000..6c1c583 --- /dev/null +++ b/eelf-logger/eelf-logger-api/src/main/java/org/onap/dcae/utils/eelf/logger/api/noop/NoOpAuditLog.java @@ -0,0 +1,90 @@ +/* + * ================================================================================ + * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + * + */ + +package org.onap.dcae.utils.eelf.logger.api.noop; + + +import org.onap.dcae.utils.eelf.logger.api.info.LogLevelCategory; +import org.onap.dcae.utils.eelf.logger.api.log.AuditLog; +import org.onap.dcae.utils.eelf.logger.api.spec.AuditLogSpec; +import org.onap.dcae.utils.eelf.logger.api.spec.OptionalLogSpec; + +/** + * A no operation implementation of AuditLog + * + * @author Rajiv Singla + */ +public class NoOpAuditLog implements AuditLog { + + @Override + public void log(final LogLevelCategory logLevelCategory, final String message, final AuditLogSpec auditLogSpec, + final OptionalLogSpec optionalLogSpec, final String... args) { + // no operation + } + + @Override + public void log(final LogLevelCategory logLevelCategory, final String message, final AuditLogSpec auditLogSpec, + final String... args) { + // no operation + } + + @Override + public void info(final String message, final AuditLogSpec auditLogSpec, final OptionalLogSpec optionalLogSpec, + final String... args) { + // no operation + } + + @Override + public void info(final String message, final AuditLogSpec auditLogSpec, final String... args) { + // no operation + } + + @Override + public void warn(final String message, final AuditLogSpec auditLogSpec, final OptionalLogSpec optionalLogSpec, + final String... args) { + // no operation + } + + @Override + public void warn(final String message, final AuditLogSpec auditLogSpec, final String... args) { + // no operation + } + + @Override + public void error(final String message, final AuditLogSpec auditLogSpec, final OptionalLogSpec optionalLogSpec, + final String... args) { + // no operation + } + + @Override + public void error(final String message, final AuditLogSpec auditLogSpec, final String... args) { + // no operation + } + + @Override + public void fatal(final String message, final AuditLogSpec auditLogSpec, final OptionalLogSpec optionalLogSpec, + final String... args) { + // no operation + } + + @Override + public void fatal(final String message, final AuditLogSpec auditLogSpec, final String... args) { + // no operation + } +} diff --git a/eelf-logger/eelf-logger-api/src/main/java/org/onap/dcae/utils/eelf/logger/api/noop/NoOpDebugLog.java b/eelf-logger/eelf-logger-api/src/main/java/org/onap/dcae/utils/eelf/logger/api/noop/NoOpDebugLog.java new file mode 100644 index 0000000..dd36b52 --- /dev/null +++ b/eelf-logger/eelf-logger-api/src/main/java/org/onap/dcae/utils/eelf/logger/api/noop/NoOpDebugLog.java @@ -0,0 +1,56 @@ +/* + * ================================================================================ + * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + * + */ + +package org.onap.dcae.utils.eelf.logger.api.noop; + + +import org.onap.dcae.utils.eelf.logger.api.info.LogLevelCategory; +import org.onap.dcae.utils.eelf.logger.api.log.DebugLog; +import org.onap.dcae.utils.eelf.logger.api.spec.DebugLogSpec; +import org.onap.dcae.utils.eelf.logger.api.spec.OptionalLogSpec; + +/** + * A no operation implementation of Debug Log + * + * @author Rajiv Singla + */ +public class NoOpDebugLog implements DebugLog { + @Override + public void log(final LogLevelCategory logLevelCategory, final String message, final DebugLogSpec debugLogSpec, + final OptionalLogSpec optionalLogSpec, final String... args) { + // no operation + } + + @Override + public void log(final LogLevelCategory logLevelCategory, final String message, final DebugLogSpec debugLogSpec, + final String... args) { + // no operation + } + + @Override + public void debug(final String message, final DebugLogSpec debugLogSpec, final OptionalLogSpec optionalLogSpec, + final String... args) { + // no operation + } + + @Override + public void debug(final String message, final DebugLogSpec debugLogSpec, final String... args) { + // no operation + } +} diff --git a/eelf-logger/eelf-logger-api/src/main/java/org/onap/dcae/utils/eelf/logger/api/noop/NoOpEELFLogger.java b/eelf-logger/eelf-logger-api/src/main/java/org/onap/dcae/utils/eelf/logger/api/noop/NoOpEELFLogger.java new file mode 100644 index 0000000..c761ba1 --- /dev/null +++ b/eelf-logger/eelf-logger-api/src/main/java/org/onap/dcae/utils/eelf/logger/api/noop/NoOpEELFLogger.java @@ -0,0 +1,77 @@ +/* + * ================================================================================ + * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + * + */ + +package org.onap.dcae.utils.eelf.logger.api.noop; + + +import org.onap.dcae.utils.eelf.logger.api.log.AuditLog; +import org.onap.dcae.utils.eelf.logger.api.log.DebugLog; +import org.onap.dcae.utils.eelf.logger.api.log.EELFLogger; +import org.onap.dcae.utils.eelf.logger.api.log.EELFLoggerContext; +import org.onap.dcae.utils.eelf.logger.api.log.ErrorLog; +import org.onap.dcae.utils.eelf.logger.api.log.MetricLog; + +/** + * A no operation implementation of {@link EELFLogger} + * + * @author Rajiv Singla + */ +public class NoOpEELFLogger implements EELFLogger { + + private static final AuditLog NO_OP_AUDIT_LOG = new NoOpAuditLog(); + private static final MetricLog NO_OP_METRIC_LOG = new NoOpMetricLog(); + private static final ErrorLog NO_OP_ERROR_LOG = new NoOpErrorLog(); + private static final DebugLog NO_OP_DEBUG_LOG = new NoOpDebugLog(); + + private static final NoOpEELFLogger NO_OP_EELF_LOGGER = new NoOpEELFLogger(); + + private NoOpEELFLogger() { + // private constructor + } + + public static NoOpEELFLogger getInstance() { + return NO_OP_EELF_LOGGER; + } + + @Override + public AuditLog auditLog() { + return NO_OP_AUDIT_LOG; + } + + @Override + public MetricLog metricLog() { + return NO_OP_METRIC_LOG; + } + + @Override + public ErrorLog errorLog() { + return NO_OP_ERROR_LOG; + } + + @Override + public DebugLog debugLog() { + return NO_OP_DEBUG_LOG; + } + + @Override + public EELFLoggerContext loggingContext() { + return null; + } + +} diff --git a/eelf-logger/eelf-logger-api/src/main/java/org/onap/dcae/utils/eelf/logger/api/noop/NoOpErrorLog.java b/eelf-logger/eelf-logger-api/src/main/java/org/onap/dcae/utils/eelf/logger/api/noop/NoOpErrorLog.java new file mode 100644 index 0000000..c1b4e13 --- /dev/null +++ b/eelf-logger/eelf-logger-api/src/main/java/org/onap/dcae/utils/eelf/logger/api/noop/NoOpErrorLog.java @@ -0,0 +1,68 @@ +/* + * ================================================================================ + * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + * + */ + +package org.onap.dcae.utils.eelf.logger.api.noop; + + +import org.onap.dcae.utils.eelf.logger.api.info.LogLevelCategory; +import org.onap.dcae.utils.eelf.logger.api.log.ErrorLog; +import org.onap.dcae.utils.eelf.logger.api.spec.ErrorLogSpec; +import org.onap.dcae.utils.eelf.logger.api.spec.OptionalLogSpec; + +/** + * A no operation implementation of Error Log + * + * @author Rajiv Singla + */ +public class NoOpErrorLog implements ErrorLog { + + @Override + public void log(final LogLevelCategory logLevelCategory, final String message, final ErrorLogSpec errorLogSpec, + final OptionalLogSpec optionalLogSpec, final String... args) { + // no operation + } + + @Override + public void log(final LogLevelCategory logLevelCategory, final String message, final ErrorLogSpec errorLogSpec, + final String... args) { + // no operation + } + + @Override + public void error(final String message, final ErrorLogSpec errorLogSpec, final OptionalLogSpec optionalLogSpec, + final String... args) { + // no operation + } + + @Override + public void error(final String message, final ErrorLogSpec errorLogSpec, final String... args) { + // no operation + } + + @Override + public void warn(final String message, final ErrorLogSpec errorLogSpec, final OptionalLogSpec optionalLogSpec, + final String... args) { + // no operation + } + + @Override + public void warn(final String message, final ErrorLogSpec errorLogSpec, final String... args) { + // no operation + } +} diff --git a/eelf-logger/eelf-logger-api/src/main/java/org/onap/dcae/utils/eelf/logger/api/noop/NoOpMetricLog.java b/eelf-logger/eelf-logger-api/src/main/java/org/onap/dcae/utils/eelf/logger/api/noop/NoOpMetricLog.java new file mode 100644 index 0000000..1c67862 --- /dev/null +++ b/eelf-logger/eelf-logger-api/src/main/java/org/onap/dcae/utils/eelf/logger/api/noop/NoOpMetricLog.java @@ -0,0 +1,89 @@ +/* + * ================================================================================ + * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + * + */ + +package org.onap.dcae.utils.eelf.logger.api.noop; + + +import org.onap.dcae.utils.eelf.logger.api.info.LogLevelCategory; +import org.onap.dcae.utils.eelf.logger.api.log.MetricLog; +import org.onap.dcae.utils.eelf.logger.api.spec.MetricLogSpec; +import org.onap.dcae.utils.eelf.logger.api.spec.OptionalLogSpec; + +/** + * A no operation implementation of Metric Log + * + * @author Rajiv Singla + */ +public class NoOpMetricLog implements MetricLog { + @Override + public void log(final LogLevelCategory logLevelCategory, final String message, final MetricLogSpec metricLogSpec, + final OptionalLogSpec optionalLogSpec, final String... args) { + // no operation + } + + @Override + public void log(final LogLevelCategory logLevelCategory, final String message, final MetricLogSpec metricLogSpec, + final String... args) { + // no operation + } + + @Override + public void info(final String message, final MetricLogSpec metricLogSpec, final OptionalLogSpec optionalLogSpec, + final String... args) { + // no operation + } + + @Override + public void info(final String message, final MetricLogSpec metricLogSpec, final String... args) { + // no operation + } + + @Override + public void warn(final String message, final MetricLogSpec metricLogSpec, final OptionalLogSpec optionalLogSpec, + final String... args) { + // no operation + } + + @Override + public void warn(final String message, final MetricLogSpec metricLogSpec, final String... args) { + // no operation + } + + @Override + public void error(final String message, final MetricLogSpec metricLogSpec, final OptionalLogSpec optionalLogSpec, + final String... args) { + // no operation + } + + @Override + public void error(final String message, final MetricLogSpec metricLogSpec, final String... args) { + // no operation + } + + @Override + public void fatal(final String message, final MetricLogSpec metricLogSpec, final OptionalLogSpec optionalLogSpec, + final String... args) { + // no operation + } + + @Override + public void fatal(final String message, final MetricLogSpec metricLogSpec, final String... args) { + // no operation + } +} diff --git a/eelf-logger/eelf-logger-api/src/main/java/org/onap/dcae/utils/eelf/logger/api/noop/package-info.java b/eelf-logger/eelf-logger-api/src/main/java/org/onap/dcae/utils/eelf/logger/api/noop/package-info.java new file mode 100644 index 0000000..f7ed917 --- /dev/null +++ b/eelf-logger/eelf-logger-api/src/main/java/org/onap/dcae/utils/eelf/logger/api/noop/package-info.java @@ -0,0 +1,26 @@ +/* + * ================================================================================ + * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + * + */ + +/** + * Contains no operation implementation of EELF Logging API. Generally used as a fallback when no EELF Logging + * implementation is detected in the application classpath + * + * @author Rajiv Singla + */ +package org.onap.dcae.utils.eelf.logger.api.noop; diff --git a/eelf-logger/eelf-logger-api/src/main/java/org/onap/dcae/utils/eelf/logger/api/spec/AppLogSpec.java b/eelf-logger/eelf-logger-api/src/main/java/org/onap/dcae/utils/eelf/logger/api/spec/AppLogSpec.java new file mode 100644 index 0000000..83643fb --- /dev/null +++ b/eelf-logger/eelf-logger-api/src/main/java/org/onap/dcae/utils/eelf/logger/api/spec/AppLogSpec.java @@ -0,0 +1,32 @@ +/* + * ================================================================================ + * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + * + */ + +package org.onap.dcae.utils.eelf.logger.api.spec; + + +import org.onap.dcae.utils.eelf.logger.api.info.AppLogInfo; + +/** + * App Log spec captures fields which are fixed for the duration of application once its instance is created. They + * should be populated for all specifications regardless of if they are relevant to that specification + * + * @author Rajiv Singla + */ +public interface AppLogSpec extends AppLogInfo { +} diff --git a/eelf-logger/eelf-logger-api/src/main/java/org/onap/dcae/utils/eelf/logger/api/spec/AuditLogSpec.java b/eelf-logger/eelf-logger-api/src/main/java/org/onap/dcae/utils/eelf/logger/api/spec/AuditLogSpec.java new file mode 100644 index 0000000..46360b1 --- /dev/null +++ b/eelf-logger/eelf-logger-api/src/main/java/org/onap/dcae/utils/eelf/logger/api/spec/AuditLogSpec.java @@ -0,0 +1,42 @@ +/* + * ================================================================================ + * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + * + */ + +package org.onap.dcae.utils.eelf.logger.api.spec; + + +import org.onap.dcae.utils.eelf.logger.api.info.RequestIdLogInfo; +import org.onap.dcae.utils.eelf.logger.api.info.RequestTimingLogInfo; +import org.onap.dcae.utils.eelf.logger.api.info.ResponseLogInfo; +import org.onap.dcae.utils.eelf.logger.api.info.ServiceLogInfo; + +/** + * Captures fields required for EELF Audit Log Specification. + * + * @author Rajiv Singla + */ +public interface AuditLogSpec extends + // request id must be preset for all log specifications + RequestIdLogInfo, + // duration related fields + RequestTimingLogInfo, + // app acting as a service fields + ServiceLogInfo, ResponseLogInfo { + + +} diff --git a/eelf-logger/eelf-logger-api/src/main/java/org/onap/dcae/utils/eelf/logger/api/spec/DebugLogSpec.java b/eelf-logger/eelf-logger-api/src/main/java/org/onap/dcae/utils/eelf/logger/api/spec/DebugLogSpec.java new file mode 100644 index 0000000..ac4bd64 --- /dev/null +++ b/eelf-logger/eelf-logger-api/src/main/java/org/onap/dcae/utils/eelf/logger/api/spec/DebugLogSpec.java @@ -0,0 +1,34 @@ +/* + * ================================================================================ + * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + * + */ + +package org.onap.dcae.utils.eelf.logger.api.spec; + + +import org.onap.dcae.utils.eelf.logger.api.info.RequestIdLogInfo; + +/** + * Captures fields required for EELF Debug Log Specification. + * NOTE: As per specification debug log is optional + * + * @author Rajiv Singla + */ +public interface DebugLogSpec extends + // request id must be preset for all log specifications + RequestIdLogInfo { +} diff --git a/eelf-logger/eelf-logger-api/src/main/java/org/onap/dcae/utils/eelf/logger/api/spec/ErrorLogSpec.java b/eelf-logger/eelf-logger-api/src/main/java/org/onap/dcae/utils/eelf/logger/api/spec/ErrorLogSpec.java new file mode 100644 index 0000000..455f433 --- /dev/null +++ b/eelf-logger/eelf-logger-api/src/main/java/org/onap/dcae/utils/eelf/logger/api/spec/ErrorLogSpec.java @@ -0,0 +1,42 @@ +/* + * ================================================================================ + * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + * + */ + +package org.onap.dcae.utils.eelf.logger.api.spec; + + +import org.onap.dcae.utils.eelf.logger.api.info.ErrorLogInfo; +import org.onap.dcae.utils.eelf.logger.api.info.RequestIdLogInfo; +import org.onap.dcae.utils.eelf.logger.api.info.ServiceLogInfo; +import org.onap.dcae.utils.eelf.logger.api.info.TargetServiceLogInfo; + +/** + * Captures fields required for EELF Error Log Specification + * + * @author Rajiv Singla + */ +public interface ErrorLogSpec extends + // request id must be preset for all log specifications + RequestIdLogInfo, + // app acting as a service fields + ServiceLogInfo, + // app calling external service fields + TargetServiceLogInfo, + // error details fields + ErrorLogInfo { +} diff --git a/eelf-logger/eelf-logger-api/src/main/java/org/onap/dcae/utils/eelf/logger/api/spec/MetricLogSpec.java b/eelf-logger/eelf-logger-api/src/main/java/org/onap/dcae/utils/eelf/logger/api/spec/MetricLogSpec.java new file mode 100644 index 0000000..5b5f698 --- /dev/null +++ b/eelf-logger/eelf-logger-api/src/main/java/org/onap/dcae/utils/eelf/logger/api/spec/MetricLogSpec.java @@ -0,0 +1,36 @@ +/* + * ================================================================================ + * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + * + */ + +package org.onap.dcae.utils.eelf.logger.api.spec; + + +import org.onap.dcae.utils.eelf.logger.api.info.TargetServiceLogInfo; + +/** + * Captures fields required for EELF Metric Log Specification. + * + * @author Rajiv Singla + */ +public interface MetricLogSpec extends + // Audit log spec + AuditLogSpec, + // App calling external service fields + TargetServiceLogInfo { + +} diff --git a/eelf-logger/eelf-logger-api/src/main/java/org/onap/dcae/utils/eelf/logger/api/spec/OptionalLogSpec.java b/eelf-logger/eelf-logger-api/src/main/java/org/onap/dcae/utils/eelf/logger/api/spec/OptionalLogSpec.java new file mode 100644 index 0000000..dac08ab --- /dev/null +++ b/eelf-logger/eelf-logger-api/src/main/java/org/onap/dcae/utils/eelf/logger/api/spec/OptionalLogSpec.java @@ -0,0 +1,39 @@ +/* + * ================================================================================ + * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + * + */ + +package org.onap.dcae.utils.eelf.logger.api.spec; + +import org.onap.dcae.utils.eelf.logger.api.info.CodeLogInfo; +import org.onap.dcae.utils.eelf.logger.api.info.CustomFieldsLogInfo; +import org.onap.dcae.utils.eelf.logger.api.info.MessageLogInfo; +import org.onap.dcae.utils.eelf.logger.api.info.MiscLogInfo; + +/** + * Captures fields which are optional or derived from other fields + * + * @author Rajiv Singla + */ +public interface OptionalLogSpec extends + // message fields are mostly auto generated or can be derived from other fields + MessageLogInfo, + // Code log info can be derived by the underlying logging framework or provided optionally by the app + CodeLogInfo, + // custom and misc log info are mostly optional + CustomFieldsLogInfo, MiscLogInfo { +} diff --git a/eelf-logger/eelf-logger-api/src/main/java/org/onap/dcae/utils/eelf/logger/api/spec/package-info.java b/eelf-logger/eelf-logger-api/src/main/java/org/onap/dcae/utils/eelf/logger/api/spec/package-info.java new file mode 100644 index 0000000..b4c1df8 --- /dev/null +++ b/eelf-logger/eelf-logger-api/src/main/java/org/onap/dcae/utils/eelf/logger/api/spec/package-info.java @@ -0,0 +1,28 @@ +/* + * ================================================================================ + * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + * + */ + +/** + * Contains various EELF Logging Specifications. + * <p> + * Some specifications are fixed for the whole duration of the + * application, some specification are either optional or derived and some are required for particular EELF Logging + * specification. These logging specification are composed of various logging information in + * {@link org.onap.dcae.utils.eelf.logger.api.info} package + */ +package org.onap.dcae.utils.eelf.logger.api.spec; diff --git a/eelf-logger/eelf-logger-logback-impl/pom.xml b/eelf-logger/eelf-logger-logback-impl/pom.xml new file mode 100644 index 0000000..165d216 --- /dev/null +++ b/eelf-logger/eelf-logger-logback-impl/pom.xml @@ -0,0 +1,62 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ ================================================================================ + ~ Copyright (c) 2018 AT&T Intellectual Property. All rights reserved. + ~ ================================================================================ + ~ 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. + ~ ============LICENSE_END========================================================= + ~ + --> + +<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xmlns="http://maven.apache.org/POM/4.0.0" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + + <modelVersion>4.0.0</modelVersion> + + <parent> + <groupId>org.onap.dcaegen2.utils</groupId> + <artifactId>eelf-logger</artifactId> + <version>1.0.0-SNAPSHOT</version> + </parent> + + <artifactId>eelf-logger-logback-impl</artifactId> + <packaging>jar</packaging> + + <!-- EELF LOGGING IMPLEMENTATION BACKED BY LOGBACK LOGGING FRAMEWORK--> + <name>dcaegen2-utils-eelf-logger-logback-impl</name> + <description>Implements EEL Logging Specification using Logback</description> + + <properties> + <main.basedir>${project.parent.basedir}</main.basedir> + </properties> + + <dependencies> + + <!-- ECOMP LOGGER MODEL --> + <dependency> + <groupId>${project.groupId}</groupId> + <artifactId>eelf-logger-model</artifactId> + <version>${project.version}</version> + </dependency> + + <!-- LOGBACK --> + <dependency> + <groupId>ch.qos.logback</groupId> + <artifactId>logback-classic</artifactId> + </dependency> + + </dependencies> + + +</project> diff --git a/eelf-logger/eelf-logger-logback-impl/src/main/java/org/onap/dcae/utils/eelf/logger/logback/EELFLoggerDefaults.java b/eelf-logger/eelf-logger-logback-impl/src/main/java/org/onap/dcae/utils/eelf/logger/logback/EELFLoggerDefaults.java new file mode 100644 index 0000000..eceaf20 --- /dev/null +++ b/eelf-logger/eelf-logger-logback-impl/src/main/java/org/onap/dcae/utils/eelf/logger/logback/EELFLoggerDefaults.java @@ -0,0 +1,105 @@ +/* + * ================================================================================ + * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + * + */ + +package org.onap.dcae.utils.eelf.logger.logback; + + +import org.onap.dcae.utils.eelf.logger.api.info.LogInfo; +import org.onap.dcae.utils.eelf.logger.model.info.AppLogInfoImpl; +import org.onap.dcae.utils.eelf.logger.model.info.CustomFieldsLogInfoImpl; +import org.onap.dcae.utils.eelf.logger.model.info.ErrorLogInfoImpl; +import org.onap.dcae.utils.eelf.logger.model.info.MiscLogInfoImpl; +import org.onap.dcae.utils.eelf.logger.model.info.RequestTimingLogInfoImpl; +import org.onap.dcae.utils.eelf.logger.model.info.ResponseLogInfoImpl; +import org.onap.dcae.utils.eelf.logger.model.info.ServiceLogInfoImpl; +import org.onap.dcae.utils.eelf.logger.model.info.TargetServiceLogInfoImpl; +import org.onap.dcae.utils.eelf.logger.model.spec.OptionalLogSpecImpl; + +import java.util.Date; + +import static org.onap.dcae.utils.eelf.logger.logback.utils.LogUtils.createDefaultAppLogInfo; + + +/** + * This utility class various default implementations for EELF Logger. Users should use these default rather then + * creating their own {@link LogInfo} objects. + * + * @author Rajiv Singla + */ +public class EELFLoggerDefaults { + + private static final String UNKNOWN_FIELD_VALUE = "UNKNOWN"; + + // =============== APP LOG SPEC ======================// + /** + * Provides Default {@link AppLogInfoImpl} + */ + public static final AppLogInfoImpl DEFAULT_APP_LOG_INFO = createDefaultAppLogInfo(); + + + // =============== AUDIT LOG SPEC ===================== // + + private static final String DEFAULT_PARTNER_NAME = + System.getProperty("user.name") != null ? System.getProperty("user.name") : UNKNOWN_FIELD_VALUE; + + public static final ServiceLogInfoImpl DEFAULT_SERVICE_LOG_INFO = + new ServiceLogInfoImpl(UNKNOWN_FIELD_VALUE, DEFAULT_PARTNER_NAME, ""); + + + public static final RequestTimingLogInfoImpl DEFAULT_REQUEST_TIMING_LOG_INFO = + new RequestTimingLogInfoImpl(new Date(), new Date(), null); + + + public static final ResponseLogInfoImpl DEFAULT_RESPONSE_LOG_INFO = + new ResponseLogInfoImpl(900, "UNDEFINED"); + + + // =============== METRIC LOG SPEC ===================== // + + public static final TargetServiceLogInfoImpl DEFAULT_TARGET_SERVICE_LOG_INFO = + new TargetServiceLogInfoImpl(UNKNOWN_FIELD_VALUE, UNKNOWN_FIELD_VALUE, UNKNOWN_FIELD_VALUE); + + // =============== ERROR LOG SPEC ===================== // + + public static final ErrorLogInfoImpl DEFAULT_ERROR_LOG_INFO = + new ErrorLogInfoImpl(900, "UNDEFINED ERROR"); + + + // ============= OPTIONAL LOG SPEC =================== // + + /** + * Provides Default {@link CustomFieldsLogInfoImpl} + */ + public static final CustomFieldsLogInfoImpl DEFAULT_CUSTOM_FIELDS_LOG_INFO = + new CustomFieldsLogInfoImpl("", "", "", ""); + + /** + * Provides Default {@link MiscLogInfoImpl} + */ + public static final MiscLogInfoImpl DEFAULT_MISC_LOG_INFO = new MiscLogInfoImpl("", ""); + + + /** + * Provides Default {@link OptionalLogSpecImpl} + */ + public static final OptionalLogSpecImpl DEFAULT_OPTIONAL_LOG_SPEC = new OptionalLogSpecImpl(null, null, + DEFAULT_CUSTOM_FIELDS_LOG_INFO, DEFAULT_MISC_LOG_INFO); + + +} diff --git a/eelf-logger/eelf-logger-logback-impl/src/main/java/org/onap/dcae/utils/eelf/logger/logback/filter/MarkerFilter.java b/eelf-logger/eelf-logger-logback-impl/src/main/java/org/onap/dcae/utils/eelf/logger/logback/filter/MarkerFilter.java new file mode 100644 index 0000000..a664190 --- /dev/null +++ b/eelf-logger/eelf-logger-logback-impl/src/main/java/org/onap/dcae/utils/eelf/logger/logback/filter/MarkerFilter.java @@ -0,0 +1,71 @@ +/* + * ================================================================================ + * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + * + */ + +package org.onap.dcae.utils.eelf.logger.logback.filter; + +import ch.qos.logback.classic.spi.ILoggingEvent; +import ch.qos.logback.core.filter.AbstractMatcherFilter; +import ch.qos.logback.core.spi.FilterReply; +import org.slf4j.Marker; +import org.slf4j.MarkerFactory; + +import java.util.HashSet; +import java.util.Set; + +/** + * Logback Marker filter + * + * @author Rajiv Singla + */ +public class MarkerFilter extends AbstractMatcherFilter<ILoggingEvent> { + + private String markersString; + private Set<Marker> markersToAccept = new HashSet<>(); + + @Override + public FilterReply decide(final ILoggingEvent event) { + + if (!isStarted()) { + return FilterReply.NEUTRAL; + } + + if (markersToAccept.contains(event.getMarker())) { + return onMatch; + } else { + return onMismatch; + } + } + + public void setMarkers(String markersString) { + this.markersString = markersString; + } + + + public void start() { + + if (markersString != null && markersString.trim().split(",").length > 0) { + + final String[] markerStrings = markersString.trim().split(","); + for (String markerString : markerStrings) { + markersToAccept.add(MarkerFactory.getMarker(markerString.trim())); + } + super.start(); + } + } +} diff --git a/eelf-logger/eelf-logger-logback-impl/src/main/java/org/onap/dcae/utils/eelf/logger/logback/layout/AuditLogLayout.java b/eelf-logger/eelf-logger-logback-impl/src/main/java/org/onap/dcae/utils/eelf/logger/logback/layout/AuditLogLayout.java new file mode 100644 index 0000000..5d848ac --- /dev/null +++ b/eelf-logger/eelf-logger-logback-impl/src/main/java/org/onap/dcae/utils/eelf/logger/logback/layout/AuditLogLayout.java @@ -0,0 +1,81 @@ +/* + * ================================================================================ + * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + * + */ + +package org.onap.dcae.utils.eelf.logger.logback.layout; + +import ch.qos.logback.classic.spi.ILoggingEvent; +import ch.qos.logback.core.LayoutBase; +import org.onap.dcae.utils.eelf.logger.api.info.LogLevelCategory; +import org.onap.dcae.utils.eelf.logger.api.spec.AppLogSpec; +import org.onap.dcae.utils.eelf.logger.api.spec.AuditLogSpec; +import org.onap.dcae.utils.eelf.logger.api.spec.OptionalLogSpec; +import org.onap.dcae.utils.eelf.logger.logback.utils.LogUtils; + + +/** + * Audit log layout generates log messages as per EELF Audit Log Specifications + * + * @author Rajiv Singla + */ +public class AuditLogLayout extends LayoutBase<ILoggingEvent> { + + @Override + public String doLayout(final ILoggingEvent event) { + + final AppLogSpec appLogSpec = LogUtils.getAppLogSpec(); + final LogLevelCategory logLevelCategory = LogUtils.getLogLevelCategory(); + final Class<?> loggerClass = LogUtils.getLoggerClass(); + final OptionalLogSpec optionalLogSpec = LogUtils.getOptionalLogSpec(loggerClass, logLevelCategory); + final AuditLogSpec auditLogSpec = LogUtils.getAuditLogSpec(); + + final String beginTimestamp = LogUtils.formatDate(auditLogSpec.getBeginTimestamp()); + final String endTimestamp = LogUtils.formatDate(auditLogSpec.getEndTimestamp()); + + final String[] auditLogValues = { + beginTimestamp, + endTimestamp, + auditLogSpec.getRequestId(), + appLogSpec.getServiceInstanceID(), + event.getThreadName(), + appLogSpec.getVirtualServerName(), + auditLogSpec.getServiceName(), + auditLogSpec.getPartnerName(), + optionalLogSpec.getStatusCode().name(), + auditLogSpec.getResponseCode().toString(), + auditLogSpec.getResponseDescription(), + appLogSpec.getInstanceUUID(), + logLevelCategory != null ? logLevelCategory.name() : "", + optionalLogSpec.getAlertSeverity().getSeverityCode(), + appLogSpec.getServerIPAddress(), + auditLogSpec.getElapsedTime().toString(), + appLogSpec.getServerFQDN(), + auditLogSpec.getClientIPAddress(), + optionalLogSpec.getClassName(), + optionalLogSpec.getUnused(), + optionalLogSpec.getProcessId(), + optionalLogSpec.getCustomField1(), + optionalLogSpec.getCustomField2(), + optionalLogSpec.getCustomField3(), + optionalLogSpec.getCustomField4(), + event.getFormattedMessage() + }; + + return LogUtils.createLogMessageString(auditLogValues); + } +} diff --git a/eelf-logger/eelf-logger-logback-impl/src/main/java/org/onap/dcae/utils/eelf/logger/logback/layout/ConsoleLayout.java b/eelf-logger/eelf-logger-logback-impl/src/main/java/org/onap/dcae/utils/eelf/logger/logback/layout/ConsoleLayout.java new file mode 100644 index 0000000..589d863 --- /dev/null +++ b/eelf-logger/eelf-logger-logback-impl/src/main/java/org/onap/dcae/utils/eelf/logger/logback/layout/ConsoleLayout.java @@ -0,0 +1,56 @@ +/* + * ================================================================================ + * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + * + */ + +package org.onap.dcae.utils.eelf.logger.logback.layout; + +import ch.qos.logback.classic.spi.ILoggingEvent; +import ch.qos.logback.core.LayoutBase; +import org.onap.dcae.utils.eelf.logger.logback.utils.LogUtils; +import org.slf4j.Marker; + +/** + * Console layout is used to log messages on the console for debugging purposes. + * + * @author Rajiv Singla + */ +public class ConsoleLayout extends LayoutBase<ILoggingEvent> { + + private static final MetricLogLayout METRIC_LOG_LAYOUT = new MetricLogLayout(); + private static final AuditLogLayout AUDIT_LOG_LAYOUT = new AuditLogLayout(); + private static final ErrorLogLayout ERROR_LOG_LAYOUT = new ErrorLogLayout(); + private static final DebugLogLayout DEBUG_LOG_LAYOUT = new DebugLogLayout(); + + @Override + public String doLayout(final ILoggingEvent event) { + + final Marker eventMarker = event.getMarker(); + + if (eventMarker.equals(LogUtils.AUDIT_LOG_MARKER)) { + return AUDIT_LOG_LAYOUT.doLayout(event); + } else if (eventMarker.equals(LogUtils.METRIC_LOG_MARKER)) { + return METRIC_LOG_LAYOUT.doLayout(event); + } else if (eventMarker.equals(LogUtils.ERROR_LOG_MARKER)) { + return ERROR_LOG_LAYOUT.doLayout(event); + } else if (eventMarker.equals(LogUtils.DEBUG_LOG_MARKER)) { + return DEBUG_LOG_LAYOUT.doLayout(event); + } + + return "Console Layout not defined for Marker: " + eventMarker; + } +} diff --git a/eelf-logger/eelf-logger-logback-impl/src/main/java/org/onap/dcae/utils/eelf/logger/logback/layout/DebugLogLayout.java b/eelf-logger/eelf-logger-logback-impl/src/main/java/org/onap/dcae/utils/eelf/logger/logback/layout/DebugLogLayout.java new file mode 100644 index 0000000..e7b1cd4 --- /dev/null +++ b/eelf-logger/eelf-logger-logback-impl/src/main/java/org/onap/dcae/utils/eelf/logger/logback/layout/DebugLogLayout.java @@ -0,0 +1,54 @@ +/* + * ================================================================================ + * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + * + */ + +package org.onap.dcae.utils.eelf.logger.logback.layout; + +import ch.qos.logback.classic.spi.ILoggingEvent; +import ch.qos.logback.core.LayoutBase; +import org.onap.dcae.utils.eelf.logger.api.info.LogLevelCategory; +import org.onap.dcae.utils.eelf.logger.api.spec.DebugLogSpec; +import org.onap.dcae.utils.eelf.logger.api.spec.OptionalLogSpec; +import org.onap.dcae.utils.eelf.logger.logback.utils.LogUtils; + + +/** + * @author Rajiv Singla + */ +public class DebugLogLayout extends LayoutBase<ILoggingEvent> { + + @Override + public String doLayout(final ILoggingEvent event) { + + final LogLevelCategory logLevelCategory = LogUtils.getLogLevelCategory(); + final Class<?> loggerClass = LogUtils.getLoggerClass(); + final OptionalLogSpec optionalLogSpec = LogUtils.getOptionalLogSpec(loggerClass, logLevelCategory); + + final DebugLogSpec debugLogSpec = LogUtils.getDebugLogSpec(); + + final String creationTimestamp = LogUtils.formatDate(optionalLogSpec.getCreationTimestamp()); + + final String[] debugLogValues = { + creationTimestamp, + debugLogSpec.getRequestId(), + event.getFormattedMessage() + }; + + return LogUtils.createLogMessageString(debugLogValues); + } +} diff --git a/eelf-logger/eelf-logger-logback-impl/src/main/java/org/onap/dcae/utils/eelf/logger/logback/layout/ErrorLogLayout.java b/eelf-logger/eelf-logger-logback-impl/src/main/java/org/onap/dcae/utils/eelf/logger/logback/layout/ErrorLogLayout.java new file mode 100644 index 0000000..4eefe36 --- /dev/null +++ b/eelf-logger/eelf-logger-logback-impl/src/main/java/org/onap/dcae/utils/eelf/logger/logback/layout/ErrorLogLayout.java @@ -0,0 +1,64 @@ +/* + * ================================================================================ + * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + * + */ + +package org.onap.dcae.utils.eelf.logger.logback.layout; + +import ch.qos.logback.classic.spi.ILoggingEvent; +import ch.qos.logback.core.LayoutBase; +import org.onap.dcae.utils.eelf.logger.api.info.LogLevelCategory; +import org.onap.dcae.utils.eelf.logger.api.spec.ErrorLogSpec; +import org.onap.dcae.utils.eelf.logger.api.spec.OptionalLogSpec; +import org.onap.dcae.utils.eelf.logger.logback.utils.LogUtils; + + +/** + * Error Log Layout generates log messages as per EELF Error Log Specifications + * + * @author Rajiv Singla + */ +public class ErrorLogLayout extends LayoutBase<ILoggingEvent> { + + @Override + public String doLayout(final ILoggingEvent event) { + + final LogLevelCategory logLevelCategory = LogUtils.getLogLevelCategory(); + final Class<?> loggerClass = LogUtils.getLoggerClass(); + final OptionalLogSpec optionalLogSpec = LogUtils.getOptionalLogSpec(loggerClass, logLevelCategory); + + final ErrorLogSpec errorLogSpec = LogUtils.getErrorLogSpec(); + + final String creationTimestamp = LogUtils.formatDate(optionalLogSpec.getCreationTimestamp()); + + final String[] errorLogValues = { + creationTimestamp, + errorLogSpec.getRequestId(), + event.getThreadName(), + errorLogSpec.getServiceName(), + errorLogSpec.getPartnerName(), + errorLogSpec.getTargetEntity(), + errorLogSpec.getTargetServiceName(), + logLevelCategory != null ? logLevelCategory.name() : "", + errorLogSpec.getErrorCode() != null ? errorLogSpec.getErrorCode().toString() : "", + errorLogSpec.getErrorDescription(), + event.getFormattedMessage() + }; + + return LogUtils.createLogMessageString(errorLogValues); + } +} diff --git a/eelf-logger/eelf-logger-logback-impl/src/main/java/org/onap/dcae/utils/eelf/logger/logback/layout/MetricLogLayout.java b/eelf-logger/eelf-logger-logback-impl/src/main/java/org/onap/dcae/utils/eelf/logger/logback/layout/MetricLogLayout.java new file mode 100644 index 0000000..509ff8f --- /dev/null +++ b/eelf-logger/eelf-logger-logback-impl/src/main/java/org/onap/dcae/utils/eelf/logger/logback/layout/MetricLogLayout.java @@ -0,0 +1,83 @@ +/* + * ================================================================================ + * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + * + */ + +package org.onap.dcae.utils.eelf.logger.logback.layout; + +import ch.qos.logback.classic.spi.ILoggingEvent; +import ch.qos.logback.core.LayoutBase; +import org.onap.dcae.utils.eelf.logger.api.info.LogLevelCategory; +import org.onap.dcae.utils.eelf.logger.api.spec.AppLogSpec; +import org.onap.dcae.utils.eelf.logger.api.spec.MetricLogSpec; +import org.onap.dcae.utils.eelf.logger.api.spec.OptionalLogSpec; +import org.onap.dcae.utils.eelf.logger.logback.utils.LogUtils; + +/** + * Metric Log Layout generates log messages as per EELF Metric Log Specifications + * + * @author Rajiv Singla + */ +public class MetricLogLayout extends LayoutBase<ILoggingEvent> { + + @Override + public String doLayout(final ILoggingEvent event) { + + final AppLogSpec appLogSpec = LogUtils.getAppLogSpec(); + final LogLevelCategory logLevelCategory = LogUtils.getLogLevelCategory(); + final Class<?> loggerClass = LogUtils.getLoggerClass(); + final OptionalLogSpec optionalLogSpec = LogUtils.getOptionalLogSpec(loggerClass, logLevelCategory); + final MetricLogSpec metricLogSpec = LogUtils.getMetricLogSpec(); + + final String beginTimestamp = LogUtils.formatDate(metricLogSpec.getBeginTimestamp()); + final String endTimestamp = LogUtils.formatDate(metricLogSpec.getEndTimestamp()); + + final String[] metricLogValues = { + beginTimestamp, + endTimestamp, + metricLogSpec.getRequestId(), + appLogSpec.getServiceInstanceID(), + event.getThreadName(), + appLogSpec.getVirtualServerName(), + metricLogSpec.getServiceName(), + metricLogSpec.getPartnerName(), + metricLogSpec.getTargetEntity(), + metricLogSpec.getTargetServiceName(), + optionalLogSpec.getStatusCode().name(), + metricLogSpec.getResponseCode().toString(), + metricLogSpec.getResponseDescription(), + appLogSpec.getInstanceUUID(), + logLevelCategory != null ? logLevelCategory.name() : "", + optionalLogSpec.getAlertSeverity().getSeverityCode(), + appLogSpec.getServerIPAddress(), + metricLogSpec.getElapsedTime().toString(), + appLogSpec.getServerFQDN(), + metricLogSpec.getClientIPAddress(), + optionalLogSpec.getClassName(), + optionalLogSpec.getUnused(), + optionalLogSpec.getProcessId(), + metricLogSpec.getTargetVirtualEntity(), + optionalLogSpec.getCustomField1(), + optionalLogSpec.getCustomField2(), + optionalLogSpec.getCustomField3(), + optionalLogSpec.getCustomField4(), + event.getFormattedMessage() + }; + + return LogUtils.createLogMessageString(metricLogValues); + } +} diff --git a/eelf-logger/eelf-logger-logback-impl/src/main/java/org/onap/dcae/utils/eelf/logger/logback/listener/LogbackStartupListener.java b/eelf-logger/eelf-logger-logback-impl/src/main/java/org/onap/dcae/utils/eelf/logger/logback/listener/LogbackStartupListener.java new file mode 100644 index 0000000..b02c471 --- /dev/null +++ b/eelf-logger/eelf-logger-logback-impl/src/main/java/org/onap/dcae/utils/eelf/logger/logback/listener/LogbackStartupListener.java @@ -0,0 +1,128 @@ +/* + * ================================================================================ + * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + * + */ + +package org.onap.dcae.utils.eelf.logger.logback.listener; + +import ch.qos.logback.classic.Level; +import ch.qos.logback.classic.Logger; +import ch.qos.logback.classic.LoggerContext; +import ch.qos.logback.classic.spi.LoggerContextListener; +import ch.qos.logback.core.Context; +import ch.qos.logback.core.spi.ContextAwareBase; +import ch.qos.logback.core.spi.LifeCycle; +import ch.qos.logback.core.status.InfoStatus; +import ch.qos.logback.core.status.WarnStatus; +import org.onap.dcae.utils.eelf.logger.api.info.AppLogInfo; +import org.onap.dcae.utils.eelf.logger.model.spec.AppLogSpecImpl; + + +import java.io.File; + +import static org.onap.dcae.utils.eelf.logger.logback.EELFLoggerDefaults.DEFAULT_APP_LOG_INFO; +import static org.onap.dcae.utils.eelf.logger.logback.utils.LogUtils.APP_LOG_SPEC_KEY; +import static org.onap.dcae.utils.eelf.logger.logback.utils.LogUtils.CUSTOM_MDC_MAP; + + +/** + * Logback Startup Listener is used to inject {@link AppLogInfo} + * + * @author Rajiv Singla + */ +public class LogbackStartupListener extends ContextAwareBase implements LoggerContextListener, LifeCycle { + + private static final String APP_LOG_INFO_KEY_IN_CONTEXT = "APP_LOG_INFO"; + private static final String CONTEXT_COMPONENT_NAME_PROPERTY_KEY = "componentName"; + private static final String CONTEXT_MODIFY_WINDOWS_LOG_PATH_PROPERTY_KEY = "modifyLogPathInWindows"; + private static final String CONTEXT_LOG_DIRECTORY_PROPERTY_KEY = "logDirectory"; + private static final String CONTEXT_DEBUG_LOG_DIRECTORY_PROPERTY_KEY = "debugLogDirectory"; + private static final String CONTEXT_APPEND_DIRECTORY_PROPERTY_KEY = "appendDirectory"; + + private boolean started = false; + + @Override + public boolean isResetResistant() { + return true; + } + + @Override + public void onStart(final LoggerContext context) { + + } + + @Override + public void onReset(final LoggerContext context) { + + } + + @Override + public void onStop(final LoggerContext context) { + + } + + @Override + public void onLevelChange(final Logger logger, final Level level) { + + } + + @Override + public void start() { + if (started) { + return; + } + + Context context = getContext(); + + CUSTOM_MDC_MAP.put(APP_LOG_SPEC_KEY, new AppLogSpecImpl(DEFAULT_APP_LOG_INFO)); + context.putObject(APP_LOG_INFO_KEY_IN_CONTEXT, DEFAULT_APP_LOG_INFO); + context.getStatusManager().add(new InfoStatus("Initialized APP LOG INFO", DEFAULT_APP_LOG_INFO)); + + // if Component name is not set derive from jar file name + if (context.getProperty(CONTEXT_COMPONENT_NAME_PROPERTY_KEY) == null) { + final String appName = + new File(getClass().getProtectionDomain().getCodeSource().getLocation().getPath()).getName(); + context.putProperty(CONTEXT_COMPONENT_NAME_PROPERTY_KEY, appName); + context.getStatusManager().add(new WarnStatus( + "No componentName Property found. Deriving it from jar name", appName)); + } + + // if modify windows log path is enabled - then append target before log directories + if (context.getProperty(CONTEXT_MODIFY_WINDOWS_LOG_PATH_PROPERTY_KEY).equalsIgnoreCase("true")) { + final String os = System.getProperty("os.name"); + if (os != null && os.startsWith("Windows")) { + final String logDirectory = context.getProperty(CONTEXT_LOG_DIRECTORY_PROPERTY_KEY); + final String debugLogDirectory = context.getProperty(CONTEXT_DEBUG_LOG_DIRECTORY_PROPERTY_KEY); + final String appendDir = context.getProperty(CONTEXT_APPEND_DIRECTORY_PROPERTY_KEY); + context.putProperty(CONTEXT_LOG_DIRECTORY_PROPERTY_KEY, appendDir + "/" + logDirectory); + context.putProperty(CONTEXT_DEBUG_LOG_DIRECTORY_PROPERTY_KEY, appendDir + "/" + debugLogDirectory); + } + } + + started = true; + } + + @Override + public void stop() { + + } + + @Override + public boolean isStarted() { + return started; + } +} diff --git a/eelf-logger/eelf-logger-logback-impl/src/main/java/org/onap/dcae/utils/eelf/logger/logback/log/AuditLogImpl.java b/eelf-logger/eelf-logger-logback-impl/src/main/java/org/onap/dcae/utils/eelf/logger/logback/log/AuditLogImpl.java new file mode 100644 index 0000000..947b4c2 --- /dev/null +++ b/eelf-logger/eelf-logger-logback-impl/src/main/java/org/onap/dcae/utils/eelf/logger/logback/log/AuditLogImpl.java @@ -0,0 +1,119 @@ +/* + * ================================================================================ + * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + * + */ + +package org.onap.dcae.utils.eelf.logger.logback.log; + + +import org.onap.dcae.utils.eelf.logger.api.info.LogLevelCategory; +import org.onap.dcae.utils.eelf.logger.api.log.AuditLog; +import org.onap.dcae.utils.eelf.logger.api.spec.AuditLogSpec; +import org.onap.dcae.utils.eelf.logger.api.spec.OptionalLogSpec; +import org.onap.dcae.utils.eelf.logger.logback.utils.LogUtils; +import org.slf4j.Logger; + + +/** + * Audit Log Logback Implementation + * + * @author Rajiv Singla + */ +public class AuditLogImpl implements AuditLog { + + private final Logger logger; + private final Class<?> clazz; + + public AuditLogImpl(final Logger logger, final Class<?> clazz) { + this.logger = logger; + this.clazz = clazz; + } + + @Override + public void log(final LogLevelCategory logLevelCategory, final String message, final AuditLogSpec + auditLogSpec, final OptionalLogSpec optionalLogSpec, final String... args) { + // if audit log spec or log level category is null throw an exception + if (auditLogSpec == null || logLevelCategory == null) { + throw new IllegalArgumentException("Audit Log Spec and Log level category must not be null"); + } + // required fields + LogUtils.CUSTOM_MDC_MAP.put(LogUtils.LOG_LEVEL_CATEGORY_KEY, logLevelCategory); + LogUtils.CUSTOM_MDC_MAP.put(LogUtils.AUDIT_LOG_SPEC_KEY, auditLogSpec); + LogUtils.CUSTOM_MDC_MAP.put(LogUtils.LOGGER_CLASS_KEY, clazz); + // optional fields + LogUtils.CUSTOM_MDC_MAP.put(LogUtils.OPTIONAL_LOG_SPEC_KEY, optionalLogSpec); + + // log with normalized log level category + LogUtils.logWithLogLevel(logLevelCategory, logger, LogUtils.AUDIT_LOG_MARKER, message, args); + + // clean up + LogUtils.CUSTOM_MDC_MAP.remove(LogUtils.LOG_LEVEL_CATEGORY_KEY); + LogUtils.CUSTOM_MDC_MAP.remove(LogUtils.AUDIT_LOG_SPEC_KEY); + LogUtils.CUSTOM_MDC_MAP.remove(LogUtils.LOGGER_CLASS_KEY); + LogUtils.CUSTOM_MDC_MAP.remove(LogUtils.OPTIONAL_LOG_SPEC_KEY); + } + + @Override + public void log(final LogLevelCategory logLevelCategory, final String message, final AuditLogSpec auditLogSpec, + final String... args) { + log(logLevelCategory, message, auditLogSpec, null, args); + } + + @Override + public void info(final String message, final AuditLogSpec auditLogSpec, final OptionalLogSpec optionalLogSpec, + final String... args) { + log(LogLevelCategory.INFO, message, auditLogSpec, optionalLogSpec, args); + } + + @Override + public void info(final String message, final AuditLogSpec auditLogSpec, final String... args) { + info(message, auditLogSpec, null, args); + } + + @Override + public void warn(final String message, final AuditLogSpec auditLogSpec, final OptionalLogSpec optionalLogSpec, + final String... args) { + log(LogLevelCategory.WARN, message, auditLogSpec, optionalLogSpec, args); + } + + @Override + public void warn(final String message, final AuditLogSpec auditLogSpec, final String... args) { + warn(message, auditLogSpec, null, args); + } + + @Override + public void error(final String message, final AuditLogSpec auditLogSpec, final OptionalLogSpec optionalLogSpec, + final String... args) { + log(LogLevelCategory.ERROR, message, auditLogSpec, optionalLogSpec, args); + } + + @Override + public void error(final String message, final AuditLogSpec auditLogSpec, final String... args) { + error(message, auditLogSpec, null, args); + } + + @Override + public void fatal(final String message, final AuditLogSpec auditLogSpec, final OptionalLogSpec optionalLogSpec, + final String... args) { + log(LogLevelCategory.FATAL, message, auditLogSpec, optionalLogSpec, args); + } + + @Override + public void fatal(final String message, final AuditLogSpec auditLogSpec, final String... args) { + fatal(message, auditLogSpec, null, args); + } +} diff --git a/eelf-logger/eelf-logger-logback-impl/src/main/java/org/onap/dcae/utils/eelf/logger/logback/log/DebugLogImpl.java b/eelf-logger/eelf-logger-logback-impl/src/main/java/org/onap/dcae/utils/eelf/logger/logback/log/DebugLogImpl.java new file mode 100644 index 0000000..1e17f3b --- /dev/null +++ b/eelf-logger/eelf-logger-logback-impl/src/main/java/org/onap/dcae/utils/eelf/logger/logback/log/DebugLogImpl.java @@ -0,0 +1,88 @@ +/* + * ================================================================================ + * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + * + */ + +package org.onap.dcae.utils.eelf.logger.logback.log; + + +import org.onap.dcae.utils.eelf.logger.api.info.LogLevelCategory; +import org.onap.dcae.utils.eelf.logger.api.log.DebugLog; +import org.onap.dcae.utils.eelf.logger.api.spec.DebugLogSpec; +import org.onap.dcae.utils.eelf.logger.api.spec.OptionalLogSpec; +import org.onap.dcae.utils.eelf.logger.logback.utils.LogUtils; +import org.slf4j.Logger; + + +/** + * Debug Log Logback Implementation + * + * @author Rajiv Singla + */ +public class DebugLogImpl implements DebugLog { + + private final Logger logger; + private final Class<?> clazz; + + public DebugLogImpl(final Logger logger, final Class<?> clazz) { + this.logger = logger; + this.clazz = clazz; + } + + @Override + public void log(final LogLevelCategory logLevelCategory, final String message, final DebugLogSpec debugLogSpec, + final OptionalLogSpec optionalLogSpec, final String... args) { + + // if log level category is null throw an exception + if (logLevelCategory == null) { + throw new IllegalArgumentException("Log level category must not be null"); + } + + LogUtils.CUSTOM_MDC_MAP.put(LogUtils.LOG_LEVEL_CATEGORY_KEY, logLevelCategory); + LogUtils.CUSTOM_MDC_MAP.put(LogUtils.DEBUG_LOG_SPEC_KEY, debugLogSpec); + LogUtils.CUSTOM_MDC_MAP.put(LogUtils.LOGGER_CLASS_KEY, clazz); + // optional fields + LogUtils.CUSTOM_MDC_MAP.put(LogUtils.OPTIONAL_LOG_SPEC_KEY, optionalLogSpec); + + // log with normalized log level category + LogUtils.logWithLogLevel(logLevelCategory, logger, LogUtils.DEBUG_LOG_MARKER, message, args); + + // clean up + LogUtils.CUSTOM_MDC_MAP.remove(LogUtils.LOG_LEVEL_CATEGORY_KEY); + LogUtils.CUSTOM_MDC_MAP.remove(LogUtils.DEBUG_LOG_SPEC_KEY); + LogUtils.CUSTOM_MDC_MAP.remove(LogUtils.LOGGER_CLASS_KEY); + LogUtils.CUSTOM_MDC_MAP.remove(LogUtils.OPTIONAL_LOG_SPEC_KEY); + + } + + @Override + public void log(final LogLevelCategory logLevelCategory, final String message, final DebugLogSpec debugLogSpec, + final String... args) { + log(logLevelCategory, message, debugLogSpec, null, args); + } + + @Override + public void debug(final String message, final DebugLogSpec debugLogSpec, final OptionalLogSpec optionalLogSpec, + final String... args) { + log(LogLevelCategory.DEBUG, message, debugLogSpec, optionalLogSpec, args); + } + + @Override + public void debug(final String message, final DebugLogSpec debugLogSpec, final String... args) { + debug(message, debugLogSpec, null, args); + } +} diff --git a/eelf-logger/eelf-logger-logback-impl/src/main/java/org/onap/dcae/utils/eelf/logger/logback/log/EELFLoggerContextImpl.java b/eelf-logger/eelf-logger-logback-impl/src/main/java/org/onap/dcae/utils/eelf/logger/logback/log/EELFLoggerContextImpl.java new file mode 100644 index 0000000..e5be1d8 --- /dev/null +++ b/eelf-logger/eelf-logger-logback-impl/src/main/java/org/onap/dcae/utils/eelf/logger/logback/log/EELFLoggerContextImpl.java @@ -0,0 +1,57 @@ +/* + * ================================================================================ + * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + * + */ + +package org.onap.dcae.utils.eelf.logger.logback.log; + +import org.onap.dcae.utils.eelf.logger.api.log.EELFLoggerContext; +import org.onap.dcae.utils.eelf.logger.api.spec.AppLogSpec; +import org.onap.dcae.utils.eelf.logger.model.spec.AppLogSpecImpl; + +import static org.onap.dcae.utils.eelf.logger.logback.EELFLoggerDefaults.DEFAULT_APP_LOG_INFO; +import static org.onap.dcae.utils.eelf.logger.logback.utils.LogUtils.APP_LOG_SPEC_KEY; +import static org.onap.dcae.utils.eelf.logger.logback.utils.LogUtils.CUSTOM_MDC_MAP; + + +/** + * Default EELF Logger Context which contains EELF Specs which are usually constant for entire life cycle of the + * application + * + * @author Rajiv Singla + */ +public class EELFLoggerContextImpl implements EELFLoggerContext { + + @Override + public AppLogSpec getAppLogSpec() { + return CUSTOM_MDC_MAP.get(APP_LOG_SPEC_KEY) == null ? null : (AppLogSpec) CUSTOM_MDC_MAP.get(APP_LOG_SPEC_KEY); + } + + @Override + public void setAppLogSpec(final AppLogSpec appLogSpec) { + if (appLogSpec == null) { + CUSTOM_MDC_MAP.put(APP_LOG_SPEC_KEY, new AppLogSpecImpl(DEFAULT_APP_LOG_INFO)); + } else { + CUSTOM_MDC_MAP.put(APP_LOG_SPEC_KEY, appLogSpec); + } + } + + @Override + public boolean isInitialized() { + return CUSTOM_MDC_MAP.get(APP_LOG_SPEC_KEY) == null; + } +} diff --git a/eelf-logger/eelf-logger-logback-impl/src/main/java/org/onap/dcae/utils/eelf/logger/logback/log/EELFLoggerImpl.java b/eelf-logger/eelf-logger-logback-impl/src/main/java/org/onap/dcae/utils/eelf/logger/logback/log/EELFLoggerImpl.java new file mode 100644 index 0000000..3f1e716 --- /dev/null +++ b/eelf-logger/eelf-logger-logback-impl/src/main/java/org/onap/dcae/utils/eelf/logger/logback/log/EELFLoggerImpl.java @@ -0,0 +1,81 @@ +/* + * ================================================================================ + * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + * + */ + +package org.onap.dcae.utils.eelf.logger.logback.log; + + +import org.onap.dcae.utils.eelf.logger.api.log.AuditLog; +import org.onap.dcae.utils.eelf.logger.api.log.DebugLog; +import org.onap.dcae.utils.eelf.logger.api.log.EELFLogger; +import org.onap.dcae.utils.eelf.logger.api.log.EELFLoggerContext; +import org.onap.dcae.utils.eelf.logger.api.log.ErrorLog; +import org.onap.dcae.utils.eelf.logger.api.log.MetricLog; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * EELF Logger Logback Implementation + * + * @author Rajiv Singla + */ +public class EELFLoggerImpl implements EELFLogger { + + private Logger logger; + private Class<?> clazz; + + public EELFLoggerImpl() { + // no arg constructor required for Service Loader discovery + } + + public EELFLoggerImpl(final Class<?> clazz) { + logger = LoggerFactory.getLogger(clazz); + this.clazz = clazz; + } + + + @Override + public AuditLog auditLog() { + return new AuditLogImpl(logger, clazz); + } + + @Override + public MetricLog metricLog() { + return new MetricLogImpl(logger, clazz); + } + + @Override + public ErrorLog errorLog() { + return new ErrorLogImpl(logger, clazz); + } + + @Override + public DebugLog debugLog() { + return new DebugLogImpl(logger, clazz); + } + + @Override + public EELFLoggerContext loggingContext() { + return new EELFLoggerContextImpl(); + } + + @Override + public String toString() { + return "EELF LOGBACK IMP"; + } +} diff --git a/eelf-logger/eelf-logger-logback-impl/src/main/java/org/onap/dcae/utils/eelf/logger/logback/log/ErrorLogImpl.java b/eelf-logger/eelf-logger-logback-impl/src/main/java/org/onap/dcae/utils/eelf/logger/logback/log/ErrorLogImpl.java new file mode 100644 index 0000000..5d8f272 --- /dev/null +++ b/eelf-logger/eelf-logger-logback-impl/src/main/java/org/onap/dcae/utils/eelf/logger/logback/log/ErrorLogImpl.java @@ -0,0 +1,98 @@ +/* + * ================================================================================ + * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + * + */ + +package org.onap.dcae.utils.eelf.logger.logback.log; + +import org.onap.dcae.utils.eelf.logger.api.info.LogLevelCategory; +import org.onap.dcae.utils.eelf.logger.api.log.ErrorLog; +import org.onap.dcae.utils.eelf.logger.api.spec.ErrorLogSpec; +import org.onap.dcae.utils.eelf.logger.api.spec.OptionalLogSpec; +import org.onap.dcae.utils.eelf.logger.logback.utils.LogUtils; +import org.slf4j.Logger; + + +/** + * Error Log Logback Implementation + * + * @author Rajiv Singla + */ +public class ErrorLogImpl implements ErrorLog { + + private final Logger logger; + private final Class<?> clazz; + + public ErrorLogImpl(final Logger logger, final Class<?> clazz) { + this.logger = logger; + this.clazz = clazz; + } + + @Override + public void log(final LogLevelCategory logLevelCategory, final String message, final ErrorLogSpec errorLogSpec, + final OptionalLogSpec optionalLogSpec, final String... args) { + + // if error log spec or log level category is null throw an exception + if (errorLogSpec == null || logLevelCategory == null) { + throw new IllegalArgumentException("Error Log Spec and Log level category must not be null"); + } + + // required fields + LogUtils.CUSTOM_MDC_MAP.put(LogUtils.LOG_LEVEL_CATEGORY_KEY, logLevelCategory); + LogUtils.CUSTOM_MDC_MAP.put(LogUtils.ERROR_LOG_SPEC_KEY, errorLogSpec); + LogUtils.CUSTOM_MDC_MAP.put(LogUtils.LOGGER_CLASS_KEY, clazz); + // optional fields + LogUtils.CUSTOM_MDC_MAP.put(LogUtils.OPTIONAL_LOG_SPEC_KEY, optionalLogSpec); + + // log with normalized log level category + LogUtils.logWithLogLevel(logLevelCategory, logger, LogUtils.ERROR_LOG_MARKER, message, args); + + // clean up + LogUtils.CUSTOM_MDC_MAP.remove(LogUtils.LOG_LEVEL_CATEGORY_KEY); + LogUtils.CUSTOM_MDC_MAP.remove(LogUtils.ERROR_LOG_SPEC_KEY); + LogUtils.CUSTOM_MDC_MAP.remove(LogUtils.LOGGER_CLASS_KEY); + LogUtils.CUSTOM_MDC_MAP.remove(LogUtils.OPTIONAL_LOG_SPEC_KEY); + } + + @Override + public void log(final LogLevelCategory logLevelCategory, final String message, final ErrorLogSpec errorLogSpec, + final String... args) { + log(logLevelCategory, message, errorLogSpec, null, args); + } + + @Override + public void error(final String message, final ErrorLogSpec errorLogSpec, final OptionalLogSpec optionalLogSpec, + final String... args) { + log(LogLevelCategory.ERROR, message, errorLogSpec, null, args); + } + + @Override + public void error(final String message, final ErrorLogSpec errorLogSpec, final String... args) { + error(message, errorLogSpec, null, args); + } + + @Override + public void warn(final String message, final ErrorLogSpec errorLogSpec, final OptionalLogSpec optionalLogSpec, + final String... args) { + log(LogLevelCategory.WARN, message, errorLogSpec, null, args); + } + + @Override + public void warn(final String message, final ErrorLogSpec errorLogSpec, final String... args) { + warn(message, errorLogSpec, null, args); + } +} diff --git a/eelf-logger/eelf-logger-logback-impl/src/main/java/org/onap/dcae/utils/eelf/logger/logback/log/MetricLogImpl.java b/eelf-logger/eelf-logger-logback-impl/src/main/java/org/onap/dcae/utils/eelf/logger/logback/log/MetricLogImpl.java new file mode 100644 index 0000000..5857835 --- /dev/null +++ b/eelf-logger/eelf-logger-logback-impl/src/main/java/org/onap/dcae/utils/eelf/logger/logback/log/MetricLogImpl.java @@ -0,0 +1,120 @@ +/* + * ================================================================================ + * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + * + */ + +package org.onap.dcae.utils.eelf.logger.logback.log; + +import org.onap.dcae.utils.eelf.logger.api.info.LogLevelCategory; +import org.onap.dcae.utils.eelf.logger.api.log.MetricLog; +import org.onap.dcae.utils.eelf.logger.api.spec.MetricLogSpec; +import org.onap.dcae.utils.eelf.logger.api.spec.OptionalLogSpec; +import org.onap.dcae.utils.eelf.logger.logback.utils.LogUtils; +import org.slf4j.Logger; + +/** + * Metric Log Logback Implementation + * + * @author Rajiv Singla + */ +public class MetricLogImpl implements MetricLog { + + private final Logger logger; + private final Class<?> clazz; + + public MetricLogImpl(final Logger logger, final Class<?> clazz) { + this.logger = logger; + this.clazz = clazz; + } + + + @Override + public void log(final LogLevelCategory logLevelCategory, final String message, final MetricLogSpec metricLogSpec, + final OptionalLogSpec optionalLogSpec, final String... args) { + + // if metric log spec or log level category is null throw an exception + if (metricLogSpec == null || logLevelCategory == null) { + throw new IllegalArgumentException("Metric Log Spec and Log level category must not be null"); + } + + // required fields + LogUtils.CUSTOM_MDC_MAP.put(LogUtils.LOG_LEVEL_CATEGORY_KEY, logLevelCategory); + LogUtils.CUSTOM_MDC_MAP.put(LogUtils.METRIC_LOG_SPEC_KEY, metricLogSpec); + LogUtils.CUSTOM_MDC_MAP.put(LogUtils.LOGGER_CLASS_KEY, clazz); + // optional fields + LogUtils.CUSTOM_MDC_MAP.put(LogUtils.OPTIONAL_LOG_SPEC_KEY, optionalLogSpec); + + // log with normalized log level category + LogUtils.logWithLogLevel(logLevelCategory, logger, LogUtils.METRIC_LOG_MARKER, message, args); + + // clean up + LogUtils.CUSTOM_MDC_MAP.remove(LogUtils.LOG_LEVEL_CATEGORY_KEY); + LogUtils.CUSTOM_MDC_MAP.remove(LogUtils.METRIC_LOG_SPEC_KEY); + LogUtils.CUSTOM_MDC_MAP.remove(LogUtils.LOGGER_CLASS_KEY); + LogUtils.CUSTOM_MDC_MAP.remove(LogUtils.OPTIONAL_LOG_SPEC_KEY); + } + + @Override + public void log(final LogLevelCategory logLevelCategory, final String message, final MetricLogSpec metricLogSpec, + final String... args) { + log(logLevelCategory, message, metricLogSpec, null, args); + } + + @Override + public void info(final String message, final MetricLogSpec metricLogSpec, final OptionalLogSpec optionalLogSpec, + final String... args) { + log(LogLevelCategory.INFO, message, metricLogSpec, optionalLogSpec, args); + } + + @Override + public void info(final String message, final MetricLogSpec metricLogSpec, final String... args) { + log(LogLevelCategory.INFO, message, metricLogSpec, args); + } + + @Override + public void warn(final String message, final MetricLogSpec metricLogSpec, final OptionalLogSpec optionalLogSpec, + final String... args) { + log(LogLevelCategory.WARN, message, metricLogSpec, optionalLogSpec, args); + } + + @Override + public void warn(final String message, final MetricLogSpec metricLogSpec, final String... args) { + warn(message, metricLogSpec, null, args); + } + + @Override + public void error(final String message, final MetricLogSpec metricLogSpec, final OptionalLogSpec optionalLogSpec, + final String... args) { + log(LogLevelCategory.ERROR, message, metricLogSpec, optionalLogSpec, args); + } + + @Override + public void error(final String message, final MetricLogSpec metricLogSpec, final String... args) { + error(message, metricLogSpec, null, args); + } + + @Override + public void fatal(final String message, final MetricLogSpec metricLogSpec, final OptionalLogSpec optionalLogSpec, + final String... args) { + log(LogLevelCategory.FATAL, message, metricLogSpec, optionalLogSpec, args); + } + + @Override + public void fatal(final String message, final MetricLogSpec metricLogSpec, final String... args) { + fatal(message, metricLogSpec, null, args); + } +} diff --git a/eelf-logger/eelf-logger-logback-impl/src/main/java/org/onap/dcae/utils/eelf/logger/logback/resolver/CompositePropertyResolver.java b/eelf-logger/eelf-logger-logback-impl/src/main/java/org/onap/dcae/utils/eelf/logger/logback/resolver/CompositePropertyResolver.java new file mode 100644 index 0000000..e5f1bc1 --- /dev/null +++ b/eelf-logger/eelf-logger-logback-impl/src/main/java/org/onap/dcae/utils/eelf/logger/logback/resolver/CompositePropertyResolver.java @@ -0,0 +1,53 @@ +/* + * ================================================================================ + * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + * + */ + +package org.onap.dcae.utils.eelf.logger.logback.resolver; + +import java.util.Arrays; +import java.util.List; + +/** + * A composite property resolver can look under different resolvers in order of given property resolvers + * + * @author Rajiv Singla + */ +public class CompositePropertyResolver implements PropertyResolver { + + private static final long serialVersionUID = 1L; + + private final List<PropertyResolver> propertyResolvers; + + public CompositePropertyResolver(PropertyResolver... propertyResolvers) { + this.propertyResolvers = Arrays.asList(propertyResolvers); + } + + @Override + public String resolve(final List<String> propertyNames) { + // resolver property in given resolvers in the same order they are defined + for (PropertyResolver propertyResolver : propertyResolvers) { + final String propertyValue = propertyResolver.resolve(propertyNames); + if (propertyValue != null) { + return propertyValue; + } + } + + return null; + } + +} diff --git a/eelf-logger/eelf-logger-logback-impl/src/main/java/org/onap/dcae/utils/eelf/logger/logback/resolver/EnvironmentPropertyResolver.java b/eelf-logger/eelf-logger-logback-impl/src/main/java/org/onap/dcae/utils/eelf/logger/logback/resolver/EnvironmentPropertyResolver.java new file mode 100644 index 0000000..8f3d59f --- /dev/null +++ b/eelf-logger/eelf-logger-logback-impl/src/main/java/org/onap/dcae/utils/eelf/logger/logback/resolver/EnvironmentPropertyResolver.java @@ -0,0 +1,46 @@ +/* + * ================================================================================ + * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + * + */ + +package org.onap.dcae.utils.eelf.logger.logback.resolver; + +import java.util.List; + +/** + * Looks up Property values inside HOST environment variables + * + * @author Rajiv Singla + */ +public class EnvironmentPropertyResolver implements PropertyResolver { + + private static final long serialVersionUID = 1L; + + @Override + public String resolve(final List<String> propertyNames) { + + // check if system environment variables have property names set + for (final String propertyName : propertyNames) { + final String propertyValue = System.getenv(propertyName); + if (propertyValue != null) { + return propertyValue; + } + } + + return null; + } +} diff --git a/eelf-logger/eelf-logger-logback-impl/src/main/java/org/onap/dcae/utils/eelf/logger/logback/resolver/PropertyResolver.java b/eelf-logger/eelf-logger-logback-impl/src/main/java/org/onap/dcae/utils/eelf/logger/logback/resolver/PropertyResolver.java new file mode 100644 index 0000000..758de61 --- /dev/null +++ b/eelf-logger/eelf-logger-logback-impl/src/main/java/org/onap/dcae/utils/eelf/logger/logback/resolver/PropertyResolver.java @@ -0,0 +1,41 @@ +/* + * ================================================================================ + * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + * + */ + +package org.onap.dcae.utils.eelf.logger.logback.resolver; + +import java.io.Serializable; +import java.util.List; + +/** + * A resolver is used to resolve properties + * + * @author Rajiv Singla + */ +public interface PropertyResolver extends Serializable { + + /** + * Returns resolved property value + * + * @param propertyNames names under which property can be found + * + * @return property value + */ + String resolve(List<String> propertyNames); + +} diff --git a/eelf-logger/eelf-logger-logback-impl/src/main/java/org/onap/dcae/utils/eelf/logger/logback/resolver/SystemPropertyResolver.java b/eelf-logger/eelf-logger-logback-impl/src/main/java/org/onap/dcae/utils/eelf/logger/logback/resolver/SystemPropertyResolver.java new file mode 100644 index 0000000..674b00b --- /dev/null +++ b/eelf-logger/eelf-logger-logback-impl/src/main/java/org/onap/dcae/utils/eelf/logger/logback/resolver/SystemPropertyResolver.java @@ -0,0 +1,59 @@ +/* + * ================================================================================ + * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + * + */ + +package org.onap.dcae.utils.eelf.logger.logback.resolver; + +import java.util.List; +import java.util.Map; +import java.util.Properties; + +/** + * Resolve System Properties passed in by -DpropertyName=propertyValue when invoking + * via java command line arguments + * + * @author Rajiv Singla + */ +public class SystemPropertyResolver implements PropertyResolver { + + private static final long serialVersionUID = 1L; + + @Override + public String resolve(final List<String> propertyNames) { + + // Get all system Properties + final Properties systemProperties = System.getProperties(); + + for (Map.Entry<Object, Object> systemEntries : systemProperties.entrySet()) { + + if (systemEntries.getKey() instanceof String) { + final String systemKey = (String) systemEntries.getKey(); + + // if system properties contain any of the property names - ignoring case then return its value + for (String propertyName : propertyNames) { + if (propertyName.equalsIgnoreCase(systemKey)) { + return (String) systemEntries.getValue(); + } + } + + } + } + + return null; + } +} diff --git a/eelf-logger/eelf-logger-logback-impl/src/main/java/org/onap/dcae/utils/eelf/logger/logback/utils/LogUtils.java b/eelf-logger/eelf-logger-logback-impl/src/main/java/org/onap/dcae/utils/eelf/logger/logback/utils/LogUtils.java new file mode 100644 index 0000000..f5c558b --- /dev/null +++ b/eelf-logger/eelf-logger-logback-impl/src/main/java/org/onap/dcae/utils/eelf/logger/logback/utils/LogUtils.java @@ -0,0 +1,590 @@ +/* + * ================================================================================ + * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + * + */ + +package org.onap.dcae.utils.eelf.logger.logback.utils; + +import ch.qos.logback.core.CoreConstants; +import org.onap.dcae.utils.eelf.logger.api.info.AppLogInfo; +import org.onap.dcae.utils.eelf.logger.api.info.LogLevelCategory; +import org.onap.dcae.utils.eelf.logger.api.info.NagiosAlertLevel; +import org.onap.dcae.utils.eelf.logger.api.info.RequestIdLogInfo; +import org.onap.dcae.utils.eelf.logger.api.info.RequestStatusCode; +import org.onap.dcae.utils.eelf.logger.api.spec.AppLogSpec; +import org.onap.dcae.utils.eelf.logger.api.spec.AuditLogSpec; +import org.onap.dcae.utils.eelf.logger.api.spec.DebugLogSpec; +import org.onap.dcae.utils.eelf.logger.api.spec.ErrorLogSpec; +import org.onap.dcae.utils.eelf.logger.api.spec.MetricLogSpec; +import org.onap.dcae.utils.eelf.logger.api.spec.OptionalLogSpec; +import org.onap.dcae.utils.eelf.logger.logback.EELFLoggerDefaults; +import org.onap.dcae.utils.eelf.logger.logback.resolver.CompositePropertyResolver; +import org.onap.dcae.utils.eelf.logger.logback.resolver.EnvironmentPropertyResolver; +import org.onap.dcae.utils.eelf.logger.logback.resolver.SystemPropertyResolver; +import org.onap.dcae.utils.eelf.logger.model.info.AppLogInfoImpl; +import org.onap.dcae.utils.eelf.logger.model.info.CodeLogInfoImpl; +import org.onap.dcae.utils.eelf.logger.model.info.MessageLogInfoImpl; +import org.onap.dcae.utils.eelf.logger.model.info.RequestIdLogInfoImpl; +import org.onap.dcae.utils.eelf.logger.model.info.RequestTimingLogInfoImpl; +import org.onap.dcae.utils.eelf.logger.model.spec.AppLogSpecImpl; +import org.onap.dcae.utils.eelf.logger.model.spec.AuditLogSpecImpl; +import org.onap.dcae.utils.eelf.logger.model.spec.DebugLogSpecImpl; +import org.onap.dcae.utils.eelf.logger.model.spec.ErrorLogSpecImpl; +import org.onap.dcae.utils.eelf.logger.model.spec.MetricLogSpecImpl; +import org.onap.dcae.utils.eelf.logger.model.spec.OptionalLogSpecImpl; +import org.slf4j.Logger; +import org.slf4j.Marker; +import org.slf4j.MarkerFactory; + +import java.net.InetAddress; +import java.net.UnknownHostException; +import java.text.SimpleDateFormat; +import java.util.Arrays; +import java.util.Date; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.TimeZone; +import java.util.UUID; + + + +/** + * Contains various logging utility methods + * + * @author Rajiv Singla + */ +public abstract class LogUtils { + + private static final String LOG_MESSAGE_DELIMITER = "|"; + private static final String DATE_FORMAT = "yyyy-MM-dd'T'HH:mm:ss.SSSZ"; + private static final String DATE_TIMEZONE = "UTC"; + // property resolver which looks up system property and the environment properties + private static final CompositePropertyResolver COMPOSITE_PROPERTY_RESOLVER = + new CompositePropertyResolver(new SystemPropertyResolver(), new EnvironmentPropertyResolver()); + + // Custom MDC Map Keys + public static final String APP_LOG_SPEC_KEY = "APP_LOG_SPEC"; + public static final String AUDIT_LOG_SPEC_KEY = "AUDIT_LOG_SPEC"; + public static final String METRIC_LOG_SPEC_KEY = "METRIC_LOG_SPEC"; + public static final String ERROR_LOG_SPEC_KEY = "ERROR_LOG_SPEC"; + public static final String DEBUG_LOG_SPEC_KEY = "DEBUG_LOG_SPEC"; + public static final String OPTIONAL_LOG_SPEC_KEY = "OPTIONAL_LOG_SPEC"; + public static final String LOG_LEVEL_CATEGORY_KEY = "LOG_LEVEL_CATEGORY"; + public static final String LOGGER_CLASS_KEY = "LOGGER_CLASS_KEY"; + + // markers + public static final Marker AUDIT_LOG_MARKER = MarkerFactory.getMarker("AUDIT_LOG"); + public static final Marker METRIC_LOG_MARKER = MarkerFactory.getMarker("METRIC_LOG"); + public static final Marker ERROR_LOG_MARKER = MarkerFactory.getMarker("ERROR_LOG"); + public static final Marker DEBUG_LOG_MARKER = MarkerFactory.getMarker("DEBUG_LOG"); + + + public static final Map<String, Object> CUSTOM_MDC_MAP = new ThreadLocal<Map<String, Object>>() { + @Override + protected Map<String, Object> initialValue() { + return new HashMap<>(); + } + }.get(); + + public static final ThreadLocal<SimpleDateFormat> SIMPLE_DATE_FORMAT = new ThreadLocal<SimpleDateFormat>() { + @Override + protected SimpleDateFormat initialValue() { + final SimpleDateFormat simpleDateFormat = new SimpleDateFormat(DATE_FORMAT); + simpleDateFormat.setTimeZone(TimeZone.getTimeZone(DATE_TIMEZONE)); + return simpleDateFormat; + } + }; + + + private LogUtils() { + // private constructor + } + + + /** + * Logs eomp message with normalized log level category + * + * @param logLevelCategory ecomp log level category + * @param logger logback logger + * @param marker logback marker + * @param message log message + * @param args log message arguments for interpolation + */ + public static void logWithLogLevel(final LogLevelCategory logLevelCategory, + final Logger logger, final Marker marker, + final String message, final String... args) { + switch (logLevelCategory) { + case DEBUG: + logger.debug(marker, message, args); + break; + case INFO: + logger.info(marker, message, args); + break; + case WARN: + logger.warn(marker, message, args); + break; + default: + // fatal log level is treated as error also as logback does not have fatal level + logger.error(marker, message, args); + } + } + + + /** + * Returns value for {@link AppLogSpec}. If no {@link AppLogSpec} is defined a default app log spec is passed + * + * @return app log spec + */ + public static AppLogSpec getAppLogSpec() { + final AppLogSpec appLogSpec = getCustomMapValue(APP_LOG_SPEC_KEY, AppLogSpec.class); + return appLogSpec == null ? new AppLogSpecImpl(EELFLoggerDefaults.DEFAULT_APP_LOG_INFO) : appLogSpec; + } + + /** + * Populate default values of {@link OptionalLogSpec} if not present + * + * @param loggerClass logger class + * @param logLevelCategory log level category + * + * @return optional log spec with default values if not present + */ + public static OptionalLogSpec getOptionalLogSpec(final Class<?> loggerClass, final LogLevelCategory + logLevelCategory) { + + OptionalLogSpecImpl optionalLogSpec = + getCustomMapValue(OPTIONAL_LOG_SPEC_KEY, OptionalLogSpecImpl.class); + + if (optionalLogSpec != null) { + // if message log info is empty populate default values + if (optionalLogSpec.getMessageLogInfo() == null || + optionalLogSpec.getCreationTimestamp() == null && optionalLogSpec.getAlertSeverity() == null && + optionalLogSpec.getStatusCode() == null) { + optionalLogSpec = optionalLogSpec.withMessageLogInfo(createDefaultMessageLogInfo(logLevelCategory)); + } + // if code log info is empty populate default values + if (optionalLogSpec.getCodeLogInfo() == null || + optionalLogSpec.getClassName() == null && optionalLogSpec.getThreadId() == null) { + optionalLogSpec = optionalLogSpec.withCodeLogInfo(createDefaultCodeLogInfo(loggerClass)); + } + // if custom fields log info is empty populate default values + if (optionalLogSpec.getCustomFieldsLogInfo() == null) { + optionalLogSpec = + optionalLogSpec.withCustomFieldsLogInfo(EELFLoggerDefaults.DEFAULT_CUSTOM_FIELDS_LOG_INFO); + } + // if misc fields log info is empty populate default values + if (optionalLogSpec.getMiscLogInfo() == null) { + optionalLogSpec = optionalLogSpec.withMiscLogInfo(EELFLoggerDefaults.DEFAULT_MISC_LOG_INFO); + } + } else { + // optional log spec is null so create new optional log spec + optionalLogSpec = createDefaultOptionalLogSpec(loggerClass, logLevelCategory); + } + + return optionalLogSpec; + } + + + /** + * Formats given date in ISO 8601 format + * + * @param date Date object + * + * @return formatted date string + */ + public static String formatDate(final Date date) { + if (date == null) { + return ""; + } + return SIMPLE_DATE_FORMAT.get().format(date); + } + + /** + * Creates log message string + * + * @param logValues log message values + * + * @return log message string + */ + public static String createLogMessageString(final String[] logValues) { + final StringBuffer stringBuffer = new StringBuffer(512); + for (int i = 0; i < logValues.length; i++) { + final String logValue = logValues[i]; + stringBuffer.append(logValue != null ? logValue : ""); + if (i != logValues.length - 1) { + stringBuffer.append(LOG_MESSAGE_DELIMITER); + } + } + stringBuffer.append(CoreConstants.LINE_SEPARATOR); + return stringBuffer.toString(); + } + + /** + * Gets custom MDC value from Custom MDC Map for give key. Returns null if no value can be found + * + * @param key MDC Map key + * @param clazz expected value class type + * @param <T> class type + * + * @return value inside Custom MDC Map + */ + private static <T> T getCustomMapValue(final String key, final Class<T> clazz) { + final Object value = CUSTOM_MDC_MAP.get(key); + if (value != null) { + return clazz.cast(value); + } + return null; + } + + + /** + * Get current Metric log spec from the custom MDC map and populates default values if not present + * + * @return Metric log spec + */ + public static MetricLogSpec getMetricLogSpec() { + MetricLogSpecImpl metricLogSpec = getCustomMapValue(METRIC_LOG_SPEC_KEY, MetricLogSpecImpl.class); + + if (metricLogSpec != null) { + if (metricLogSpec.getRequestIdLogInfo() == null || metricLogSpec.getRequestId() == null) { + metricLogSpec = metricLogSpec.withRequestIdLogInfo(createNewRequestIdLogInfo()); + } + if (metricLogSpec.getServiceLogInfo() == null) { + metricLogSpec = metricLogSpec.withServiceLogInfo(EELFLoggerDefaults.DEFAULT_SERVICE_LOG_INFO); + } + if (metricLogSpec.getRequestTimingLogInfo() == null || metricLogSpec.getBeginTimestamp() == null || + metricLogSpec.getEndTimestamp() == null) { + metricLogSpec = + metricLogSpec.withRequestTimingLogInfo(EELFLoggerDefaults.DEFAULT_REQUEST_TIMING_LOG_INFO); + } + if (metricLogSpec.getResponseLogInfo() == null) { + metricLogSpec = metricLogSpec.withResponseLogInfo(EELFLoggerDefaults.DEFAULT_RESPONSE_LOG_INFO); + } + final Date beginTimestamp = metricLogSpec.getBeginTimestamp(); + final Date endTimestamp = metricLogSpec.getEndTimestamp(); + final Long elapsedTime = metricLogSpec.getElapsedTime(); + if (endTimestamp != null && beginTimestamp != null && elapsedTime == null) { + final RequestTimingLogInfoImpl requestTimingLogInfo = + new RequestTimingLogInfoImpl(beginTimestamp, endTimestamp, + endTimestamp.getTime() - beginTimestamp.getTime()); + metricLogSpec = metricLogSpec.withRequestTimingLogInfo(requestTimingLogInfo); + } + if (metricLogSpec.getTargetServiceLogInfo() == null) { + metricLogSpec = + metricLogSpec.withTargetServiceLogInfo(EELFLoggerDefaults.DEFAULT_TARGET_SERVICE_LOG_INFO); + } + } else { + throw new IllegalArgumentException("Metric Log Spec must not be null"); + } + + return metricLogSpec; + } + + /** + * Get current Debug log spec from the custom MDC map and populates default values if not present + * + * @return Debug log spec + */ + public static DebugLogSpec getDebugLogSpec() { + final DebugLogSpecImpl debugLogSpec = getCustomMapValue(DEBUG_LOG_SPEC_KEY, DebugLogSpecImpl.class); + if (debugLogSpec == null || debugLogSpec.getRequestIdLogInfo() == null || debugLogSpec.getRequestId() == null) { + return new DebugLogSpecImpl(createNewRequestIdLogInfo()); + } + return debugLogSpec; + } + + /** + * Get current Error log spec from the custom MDC map and populates default values if not present + * + * @return Error log spec + */ + public static ErrorLogSpec getErrorLogSpec() { + ErrorLogSpecImpl errorLogSpec = getCustomMapValue(ERROR_LOG_SPEC_KEY, ErrorLogSpecImpl.class); + if (errorLogSpec != null) { + + if (errorLogSpec.getRequestIdLogInfo() == null || errorLogSpec.getRequestId() == null) { + errorLogSpec = errorLogSpec.withRequestIdLogInfo(createNewRequestIdLogInfo()); + } + if (errorLogSpec.getServiceLogInfo() == null) { + errorLogSpec = errorLogSpec.withServiceLogInfo(EELFLoggerDefaults.DEFAULT_SERVICE_LOG_INFO); + } + if (errorLogSpec.getTargetServiceLogInfo() == null) { + errorLogSpec = + errorLogSpec.withTargetServiceLogInfo(EELFLoggerDefaults.DEFAULT_TARGET_SERVICE_LOG_INFO); + } + if (errorLogSpec.getErrorLogInfo() == null) { + errorLogSpec = errorLogSpec.withErrorLogInfo(EELFLoggerDefaults.DEFAULT_ERROR_LOG_INFO); + } + + } else { + throw new IllegalArgumentException("Error Log Spec cannot be null"); + } + return errorLogSpec; + } + + + /** + * Get current Audit log spec from the custom MDC map and populates default values if not present + * + * @return Audit log spec + */ + public static AuditLogSpec getAuditLogSpec() { + AuditLogSpecImpl auditLogSpec = getCustomMapValue(AUDIT_LOG_SPEC_KEY, AuditLogSpecImpl.class); + if (auditLogSpec != null) { + if (auditLogSpec.getServiceLogInfo() == null) { + auditLogSpec = auditLogSpec.withServiceLogInfo(EELFLoggerDefaults.DEFAULT_SERVICE_LOG_INFO); + } + if (auditLogSpec.getRequestIdLogInfo() == null || auditLogSpec.getRequestId() == null) { + auditLogSpec = auditLogSpec.withRequestIdLogInfo(createNewRequestIdLogInfo()); + } + if (auditLogSpec.getResponseLogInfo() == null) { + auditLogSpec = auditLogSpec.withResponseLogInfo(EELFLoggerDefaults.DEFAULT_RESPONSE_LOG_INFO); + } + + if (auditLogSpec.getRequestTimingLogInfo() == null || auditLogSpec.getBeginTimestamp() == null || + auditLogSpec.getEndTimestamp() == null) { + auditLogSpec = + auditLogSpec.withRequestTimingLogInfo(EELFLoggerDefaults.DEFAULT_REQUEST_TIMING_LOG_INFO); + } + final Date beginTimestamp = auditLogSpec.getBeginTimestamp(); + final Date endTimestamp = auditLogSpec.getEndTimestamp(); + final Long elapsedTime = auditLogSpec.getElapsedTime(); + if (endTimestamp != null && beginTimestamp != null && elapsedTime == null) { + final RequestTimingLogInfoImpl requestTimingLogInfo = + new RequestTimingLogInfoImpl(beginTimestamp, endTimestamp, + endTimestamp.getTime() - beginTimestamp.getTime()); + auditLogSpec = auditLogSpec.withRequestTimingLogInfo(requestTimingLogInfo); + } + + } else { + throw new IllegalArgumentException("Audit Log Spec cannot be null"); + } + + return auditLogSpec; + } + + + private static RequestIdLogInfo createNewRequestIdLogInfo() { + return new RequestIdLogInfoImpl(UUID.randomUUID().toString()); + } + + /** + * Return Log Level Category from MDC Map + * + * @return log level category + */ + public static Class<?> getLoggerClass() { + final Class<?> loggerClass = getCustomMapValue(LOGGER_CLASS_KEY, Class.class); + // logger class must always be non null + if (loggerClass != null) { + return loggerClass; + } + return LogUtils.class.getClass(); + } + + + /** + * Return Log Level Category from MDC Map + * + * @return log level category + */ + public static LogLevelCategory getLogLevelCategory() { + final LogLevelCategory logLevelCategory = getCustomMapValue(LOG_LEVEL_CATEGORY_KEY, LogLevelCategory.class); + if (logLevelCategory != null) { + return logLevelCategory; + } + return LogLevelCategory.ERROR; + } + + /** + * Creates Default Optional Log spec + * + * @param loggerClass logger class name + * @param logLevelCategory Log leve category + * + * @return default optional log spec + */ + private static OptionalLogSpecImpl createDefaultOptionalLogSpec(final Class<?> loggerClass, + final LogLevelCategory logLevelCategory) { + return new OptionalLogSpecImpl(createDefaultMessageLogInfo(logLevelCategory), + createDefaultCodeLogInfo(loggerClass), EELFLoggerDefaults.DEFAULT_CUSTOM_FIELDS_LOG_INFO, + EELFLoggerDefaults.DEFAULT_MISC_LOG_INFO); + } + + + /** + * Creates Default Code Log Info + * + * @param loggerClass logger class name + * + * @return default code log info + */ + private static CodeLogInfoImpl createDefaultCodeLogInfo(final Class<?> loggerClass) { + // thread id can be extracted from the framework + return new CodeLogInfoImpl(null, loggerClass != null ? loggerClass.getName() : ""); + } + + + /** + * Creates Default Message Log Info + * + * @param logLevelCategory Log leve category + * + * @return default message log info + */ + private static MessageLogInfoImpl createDefaultMessageLogInfo(final LogLevelCategory logLevelCategory) { + return new MessageLogInfoImpl(new Date(), + getStatusCode(logLevelCategory), + getNagiosAlertLevel(logLevelCategory)); + } + + + /** + * Creates Default App Log Spec + * + * @return default APP log Spec + */ + public static AppLogInfoImpl createDefaultAppLogInfo() { + final String serviceInstanceId = + resolveProperty(null, AppLogInfo.Defaults.DEFAULT_SERVICE_INSTANCE_ID, + "SERVICE_NAME", "ServiceInstanceId", "SERVICE_INSTANCE_ID"); + final String instanceUUID = + resolveProperty(null, AppLogInfo.Defaults.DEFAULT_INSTANCE_UUID, + "InstanceUUID", "INSTANCE_UUID"); + final String virtualServerName = + resolveProperty(null, AppLogInfo.Defaults.DEFAULT_VIRTUAL_SERVER_NAME, + "VirtualServerName", "VIRTUAL_SERVER_NAME"); + final String serverIPAddress = getHostIPAddress() != null ? + getHostIPAddress() : AppLogInfo.Defaults.DEFAULT_SERVER_IP_ADDRESS; + final String serverFQDN = getHostName() != null ? getHostName() : AppLogInfo.Defaults.DEFAULT_SERVER_FQDN; + return new AppLogInfoImpl(serviceInstanceId, instanceUUID, virtualServerName, serverIPAddress, serverFQDN); + } + + + /** + * Returns status code based on log level category + * + * @param logLevelCategory log level category + * + * @return request status code as string based on log level category + */ + private static RequestStatusCode getStatusCode(final LogLevelCategory logLevelCategory) { + if (logLevelCategory == LogLevelCategory.DEBUG || logLevelCategory == LogLevelCategory.INFO || + logLevelCategory == LogLevelCategory.WARN) { + return RequestStatusCode.COMPLETE; + } else { + return RequestStatusCode.ERROR; + } + } + + /** + * Returns nagios Alert level based on log level category + * + * @param logLevelCategory log level category + * + * @return nagios alert level + */ + private static NagiosAlertLevel getNagiosAlertLevel(final LogLevelCategory logLevelCategory) { + switch (logLevelCategory) { + case DEBUG: + return NagiosAlertLevel.OK; + case INFO: + return NagiosAlertLevel.OK; + case WARN: + return NagiosAlertLevel.WARNING; + case ERROR: + return NagiosAlertLevel.CRITICAL; + case FATAL: + return NagiosAlertLevel.CRITICAL; + default: + return NagiosAlertLevel.UNKNOWN; + } + } + + /** + * Resolves property value if not present + * + * @param userPassedValue user passed property value + * @param defaultValue default value if no value is found after resolving the property + * @param propertyNames property names + * + * @return resolved property value + */ + private static String resolveProperty( + final String userPassedValue, final String defaultValue, final String... propertyNames) { + // if user passed is present return that value + if (userPassedValue != null) { + return userPassedValue; + } + // resolve it using composite resolver + final String resolveProperty = resolveProperty(Arrays.asList(propertyNames)); + return resolveProperty != null ? resolveProperty : defaultValue; + } + + /** + * Resolves property values in different places + * + * @param propertyNames property Names + * + * @return property Value + */ + private static String resolveProperty(final List<String> propertyNames) { + return COMPOSITE_PROPERTY_RESOLVER.resolve(propertyNames); + } + + + /** + * Determine host IP Address + * + * @return host ip address + */ + private static String getHostIPAddress() { + final InetAddress inetAddress = getInetAddress(); + if (inetAddress != null) { + return inetAddress.getHostAddress(); + } + return null; + } + + /** + * Determines fully qualified host name + * + * @return fully qualified host name + */ + private static String getHostName() { + final InetAddress inetAddress = getInetAddress(); + if (inetAddress != null) { + return inetAddress.getCanonicalHostName(); + } + return null; + } + + /** + * Fetches Inet Address + * + * @return Inet Address + */ + private static InetAddress getInetAddress() { + try { + return InetAddress.getLocalHost(); + } catch (UnknownHostException e) { + return null; + } + } + + +} diff --git a/eelf-logger/eelf-logger-logback-impl/src/main/resources/META-INF/services/org.onap.dcae.utils.eelf.logger.api.log.EELFLogger b/eelf-logger/eelf-logger-logback-impl/src/main/resources/META-INF/services/org.onap.dcae.utils.eelf.logger.api.log.EELFLogger new file mode 100644 index 0000000..d7d5c71 --- /dev/null +++ b/eelf-logger/eelf-logger-logback-impl/src/main/resources/META-INF/services/org.onap.dcae.utils.eelf.logger.api.log.EELFLogger @@ -0,0 +1,20 @@ +# +# ================================================================================ +# Copyright (c) 2018 AT&T Intellectual Property. All rights reserved. +# ================================================================================ +# 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. +# ============LICENSE_END========================================================= +# +# + +org.onap.dcae.utils.eelf.logger.logback.log.EELFLoggerImpl diff --git a/eelf-logger/eelf-logger-logback-impl/src/main/resources/eelf-async-appenders.xml b/eelf-logger/eelf-logger-logback-impl/src/main/resources/eelf-async-appenders.xml new file mode 100644 index 0000000..e2e93e4 --- /dev/null +++ b/eelf-logger/eelf-logger-logback-impl/src/main/resources/eelf-async-appenders.xml @@ -0,0 +1,55 @@ +<!-- + ~ ================================================================================ + ~ Copyright (c) 2018 AT&T Intellectual Property. All rights reserved. + ~ ================================================================================ + ~ 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. + ~ ============LICENSE_END========================================================= + ~ + --> + +<included> + + <!-- + ASYNC APPENDERS CAN BE USED TO INCREASE THE PERFORMANCE OF ECOMP LOGGING, HOWEVER, ASYNC LOGGERS + CAN DROP MESSAGES IF QUEUE SIZE IF FULL AND DURING SHUT DOWN TIME. + + SO INCREASED PERFORMANCE AT THE COST OF LESS RELIABLE LOGGING + --> + + <appender name="asyncAuditLogAppender" class="ch.qos.logback.classic.AsyncAppender"> + <queueSize>${queueSize}</queueSize> + <maxFlushTime>${maxFlushTime}</maxFlushTime> + <appender-ref ref="auditLogAppender"/> + </appender> + + <appender name="asyncMetricLogAppender" class="ch.qos.logback.classic.AsyncAppender"> + <queueSize>${queueSize}</queueSize> + <maxFlushTime>${maxFlushTime}</maxFlushTime> + <appender-ref ref="metricLogAppender"/> + </appender> + + <appender name="asyncErrorLogAppender" class="ch.qos.logback.classic.AsyncAppender"> + <queueSize>${queueSize}</queueSize> + <maxFlushTime>${maxFlushTime}</maxFlushTime> + <appender-ref ref="errorLogAppender"/> + </appender> + + <appender name="asyncDebugLogAppender" class="ch.qos.logback.classic.AsyncAppender"> + <queueSize>${queueSize}</queueSize> + <maxFlushTime>${maxFlushTime}</maxFlushTime> + <appender-ref ref="debugLogAppender"/> + </appender> + +</included> + + diff --git a/eelf-logger/eelf-logger-logback-impl/src/main/resources/eelf-defaults.xml b/eelf-logger/eelf-logger-logback-impl/src/main/resources/eelf-defaults.xml new file mode 100644 index 0000000..f9bb078 --- /dev/null +++ b/eelf-logger/eelf-logger-logback-impl/src/main/resources/eelf-defaults.xml @@ -0,0 +1,51 @@ +<!-- + ~ ================================================================================ + ~ Copyright (c) 2018 AT&T Intellectual Property. All rights reserved. + ~ ================================================================================ + ~ 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. + ~ ============LICENSE_END========================================================= + ~ + --> + +<included> + + <!-- LOG DIRECTORIES --> + <property scope="context" name="logDir" value="logs"/> + <property scope="context" name="debugDir" value="debug-logs"/> + + <!-- SETUP LOG DIRECTORIES --> + <property scope="context" name="logDirectory" value="${logDir}/${componentName}"/> + <property scope="context" name="debugLogDirectory" value="${debugDir}/${componentName}"/> + + <!-- + MODIFY LOG DIR ON WINDOWS OS SO THAT TEST LOGS ARE UNDER TARGET DIR CAN BE CLEANED AFTER TESTS AUTOMATICALLY + --> + <property scope="context" name="modifyLogPathInWindows" value="true" /> + <property scope="context" name="appendDirectory" value="target" /> + + <!-- LOG FILE NAMES --> + <property scope="context" name="metricLogName" value="metrics"/> + <property scope="context" name="auditLogName" value="audit"/> + <property scope="context" name="errorLogName" value="error"/> + <property scope="context" name="debugLogName" value="debug"/> + + <!-- ROLLING FILE APPENDER DEFAULT SETTINGS --> + <property scope="context" name="minFileIndex" value="1"/> + <property scope="context" name="maxFileIndex" value="10"/> + <property scope="context" name="maxFileSize" value="2500KB"/> + + <!-- ASYNC APPENDER DEFAULT SETTINGS --> + <property scope="context" name="queueSize" value="1024"/> + <property scope="context" name="maxFlushTime" value="5000"/> + +</included> diff --git a/eelf-logger/eelf-logger-logback-impl/src/main/resources/eelf-logback.xml b/eelf-logger/eelf-logger-logback-impl/src/main/resources/eelf-logback.xml new file mode 100644 index 0000000..7e08eb2 --- /dev/null +++ b/eelf-logger/eelf-logger-logback-impl/src/main/resources/eelf-logback.xml @@ -0,0 +1,45 @@ +<!-- + ~ ================================================================================ + ~ Copyright (c) 2018 AT&T Intellectual Property. All rights reserved. + ~ ================================================================================ + ~ 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. + ~ ============LICENSE_END========================================================= + ~ + --> + +<included> + + <include resource="eelf-defaults.xml"/> + + <!-- CUSTOM STARTUP LISTENER REQUIRED TO SETUP DEFAULT APP LOG INFO DURING STARTUP TIME--> + <contextListener class="org.onap.dcae.utils.eelf.logger.logback.listener.LogbackStartupListener"/> + + <!-- ADD REQUIRED APPENDERS --> + <include resource="eelf-required-appenders.xml"/> + + <!-- ADD OPTIONAL APPENDERS: NOT ADDED BY DEFAULT --> + <!--<include resource="eelf-optional-appenders.xml"/>--> + + + <root level="DEBUG"> + <!-- required appenders --> + <appender-ref ref="auditLogAppender"/> + <appender-ref ref="metricLogAppender"/> + <appender-ref ref="errorLogAppender"/> + + <!-- optional appenders: not added by default --> + <!--<appender-ref ref="debugLogAppender"/>--> + <!--<appender-ref ref="STDOUT"/>--> + </root> + +</included> diff --git a/eelf-logger/eelf-logger-logback-impl/src/main/resources/eelf-optional-appenders.xml b/eelf-logger/eelf-logger-logback-impl/src/main/resources/eelf-optional-appenders.xml new file mode 100644 index 0000000..fb7ec7f --- /dev/null +++ b/eelf-logger/eelf-logger-logback-impl/src/main/resources/eelf-optional-appenders.xml @@ -0,0 +1,68 @@ +<!-- + ~ ================================================================================ + ~ Copyright (c) 2018 AT&T Intellectual Property. All rights reserved. + ~ ================================================================================ + ~ 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. + ~ ============LICENSE_END========================================================= + ~ + --> + +<included> + + <!-- + ============================= DEBUG LOG APPENDER ================================ + --> + <appender name="debugLogAppender" class="ch.qos.logback.core.rolling.RollingFileAppender"> + + <filter class="org.onap.dcae.utils.eelf.logger.logback.filter.MarkerFilter"> + <markers>DEBUG_LOG</markers> + <onMatch>ACCEPT</onMatch> + <onMismatch>DENY</onMismatch> + </filter> + + <file>${debugLogDirectory}/${debugLogName}.log</file> + + <rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy"> + <fileNamePattern>${logDirectory}/${debugLogName}.%i.log.zip</fileNamePattern> + <minIndex>${minFileIndex}</minIndex> + <maxIndex>${maxFileIndex}</maxIndex> + </rollingPolicy> + + <triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy"> + <maxFileSize>${maxFileSize}</maxFileSize> + </triggeringPolicy> + + <encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder"> + <layout class="org.onap.dcae.utils.eelf.logger.logback.layout.DebugLogLayout"/> + </encoder> + + </appender> + + + <!-- + ============================= CONSOLE APPENDER ================================ + --> + <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> + + <filter class="org.onap.dcae.utils.eelf.logger.logback.filter.MarkerFilter"> + <markers>METRIC_LOG,AUDIT_LOG,ERROR_LOG,DEBUG_LOG</markers> + <onMatch>ACCEPT</onMatch> + <onMismatch>DENY</onMismatch> + </filter> + + <encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder"> + <layout class="org.onap.dcae.utils.eelf.logger.logback.layout.ConsoleLayout"/> + </encoder> + </appender> + +</included> diff --git a/eelf-logger/eelf-logger-logback-impl/src/main/resources/eelf-required-appenders.xml b/eelf-logger/eelf-logger-logback-impl/src/main/resources/eelf-required-appenders.xml new file mode 100644 index 0000000..72f1a5d --- /dev/null +++ b/eelf-logger/eelf-logger-logback-impl/src/main/resources/eelf-required-appenders.xml @@ -0,0 +1,112 @@ +<!-- + ~ ================================================================================ + ~ Copyright (c) 2018 AT&T Intellectual Property. All rights reserved. + ~ ================================================================================ + ~ 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. + ~ ============LICENSE_END========================================================= + ~ + --> + +<included> + + <!-- + ============================= AUDIT LOG APPENDER ================================ + --> + <appender name="auditLogAppender" class="ch.qos.logback.core.rolling.RollingFileAppender"> + + <filter class="org.onap.dcae.utils.eelf.logger.logback.filter.MarkerFilter"> + <markers>AUDIT_LOG</markers> + <onMatch>ACCEPT</onMatch> + <onMismatch>DENY</onMismatch> + </filter> + + <file>${logDirectory}/${auditLogName}.log</file> + + <rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy"> + <fileNamePattern>${logDirectory}/${auditLogName}.%i.log.zip</fileNamePattern> + <minIndex>${minFileIndex}</minIndex> + <maxIndex>${maxFileIndex}</maxIndex> + </rollingPolicy> + + <triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy"> + <maxFileSize>${maxFileSize}</maxFileSize> + </triggeringPolicy> + + <encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder"> + <layout class="org.onap.dcae.utils.eelf.logger.logback.layout.AuditLogLayout"/> + </encoder> + + </appender> + + + <!-- + ============================= METRIC LOG APPENDER ================================ + --> + <appender name="metricLogAppender" class="ch.qos.logback.core.rolling.RollingFileAppender"> + + <filter class="org.onap.dcae.utils.eelf.logger.logback.filter.MarkerFilter"> + <markers>METRIC_LOG</markers> + <onMatch>ACCEPT</onMatch> + <onMismatch>DENY</onMismatch> + </filter> + + <file>${logDirectory}/${metricLogName}.log</file> + + <rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy"> + <fileNamePattern>${logDirectory}/${metricLogName}.%i.log.zip</fileNamePattern> + <minIndex>${minFileIndex}</minIndex> + <maxIndex>${maxFileIndex}</maxIndex> + </rollingPolicy> + + <triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy"> + <maxFileSize>${maxFileSize}</maxFileSize> + </triggeringPolicy> + + <encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder"> + <layout class="org.onap.dcae.utils.eelf.logger.logback.layout.MetricLogLayout"/> + </encoder> + + </appender> + + + <!-- + ============================= ERROR LOG APPENDER ================================ + --> + <appender name="errorLogAppender" class="ch.qos.logback.core.rolling.RollingFileAppender"> + + <filter class="org.onap.dcae.utils.eelf.logger.logback.filter.MarkerFilter"> + <markers>ERROR_LOG</markers> + <onMatch>ACCEPT</onMatch> + <onMismatch>DENY</onMismatch> + </filter> + + <file>${logDirectory}/${errorLogName}.log</file> + + <rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy"> + <fileNamePattern>${logDirectory}/${errorLogName}.%i.log.zip</fileNamePattern> + <minIndex>${minFileIndex}</minIndex> + <maxIndex>${maxFileIndex}</maxIndex> + </rollingPolicy> + + <triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy"> + <maxFileSize>${maxFileSize}</maxFileSize> + </triggeringPolicy> + + <encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder"> + <layout class="org.onap.dcae.utils.eelf.logger.logback.layout.ErrorLogLayout"/> + </encoder> + + </appender> + + +</included> diff --git a/eelf-logger/eelf-logger-logback-impl/src/test/java/org/onap/dcae/utils/eelf/logger/logback/BaseLogbackUnitTest.java b/eelf-logger/eelf-logger-logback-impl/src/test/java/org/onap/dcae/utils/eelf/logger/logback/BaseLogbackUnitTest.java new file mode 100644 index 0000000..fda4355 --- /dev/null +++ b/eelf-logger/eelf-logger-logback-impl/src/test/java/org/onap/dcae/utils/eelf/logger/logback/BaseLogbackUnitTest.java @@ -0,0 +1,157 @@ +/* + * ================================================================================ + * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + * + */ + +package org.onap.dcae.utils.eelf.logger.logback; + + +import org.onap.dcae.utils.eelf.logger.api.info.CodeLogInfo; +import org.onap.dcae.utils.eelf.logger.api.info.CustomFieldsLogInfo; +import org.onap.dcae.utils.eelf.logger.api.info.ErrorLogInfo; +import org.onap.dcae.utils.eelf.logger.api.info.MessageLogInfo; +import org.onap.dcae.utils.eelf.logger.api.info.MiscLogInfo; +import org.onap.dcae.utils.eelf.logger.api.info.NagiosAlertLevel; +import org.onap.dcae.utils.eelf.logger.api.info.RequestIdLogInfo; +import org.onap.dcae.utils.eelf.logger.api.info.RequestStatusCode; +import org.onap.dcae.utils.eelf.logger.api.info.RequestTimingLogInfo; +import org.onap.dcae.utils.eelf.logger.api.info.ResponseLogInfo; +import org.onap.dcae.utils.eelf.logger.api.info.ServiceLogInfo; +import org.onap.dcae.utils.eelf.logger.api.info.TargetServiceLogInfo; +import org.onap.dcae.utils.eelf.logger.api.spec.AuditLogSpec; +import org.onap.dcae.utils.eelf.logger.api.spec.DebugLogSpec; +import org.onap.dcae.utils.eelf.logger.api.spec.ErrorLogSpec; +import org.onap.dcae.utils.eelf.logger.api.spec.MetricLogSpec; +import org.onap.dcae.utils.eelf.logger.api.spec.OptionalLogSpec; +import org.onap.dcae.utils.eelf.logger.model.info.CodeLogInfoImpl; +import org.onap.dcae.utils.eelf.logger.model.info.CustomFieldsLogInfoImpl; +import org.onap.dcae.utils.eelf.logger.model.info.ErrorLogInfoImpl; +import org.onap.dcae.utils.eelf.logger.model.info.MessageLogInfoImpl; +import org.onap.dcae.utils.eelf.logger.model.info.MiscLogInfoImpl; +import org.onap.dcae.utils.eelf.logger.model.info.RequestIdLogInfoImpl; +import org.onap.dcae.utils.eelf.logger.model.info.RequestTimingLogInfoImpl; +import org.onap.dcae.utils.eelf.logger.model.info.ResponseLogInfoImpl; +import org.onap.dcae.utils.eelf.logger.model.info.ServiceLogInfoImpl; +import org.onap.dcae.utils.eelf.logger.model.info.TargetServiceLogInfoImpl; +import org.onap.dcae.utils.eelf.logger.model.spec.AuditLogSpecImpl; +import org.onap.dcae.utils.eelf.logger.model.spec.DebugLogSpecImpl; +import org.onap.dcae.utils.eelf.logger.model.spec.ErrorLogSpecImpl; +import org.onap.dcae.utils.eelf.logger.model.spec.MetricLogSpecImpl; +import org.onap.dcae.utils.eelf.logger.model.spec.OptionalLogSpecImpl; + +import java.util.Date; + +/** + * Base Logback Unit Test. + * + * @author Rajiv Singla + */ +public abstract class BaseLogbackUnitTest { + + protected static final String TEST_SERVICE_INSTANCE_ID = "testServiceInstanceID"; + protected static final String TEST_INSTANCE_UUID = ""; + + static { + System.setProperty("ServiceInstanceId", TEST_SERVICE_INSTANCE_ID); + System.setProperty("InstanceUUID", TEST_INSTANCE_UUID); + } + + protected static final String TEST_REQUEST_ID = "403cdad8-4de7-450d-b441-561001decdd6"; + protected static final String TEST_SERVICE_NAME = "testServiceName"; + protected static final String TEST_PARTNER_NAME = "testPartnerName"; + protected static final String TEST_CLIENT_IP_ADDRESS = ""; + + protected static final Date START_DATE = new Date(); + protected static final Date END_DATE = new Date(new Date().getTime() + 30_000); + protected static final Long ELAPSED_TIME = END_DATE.getTime() - START_DATE.getTime(); + + protected static final Integer RESPONSE_CODE = 200; + protected static final String RESPONSE_DESCRIPTION = "TEST RESPONSE DESCRIPTION"; + + protected static final String TEST_TARGET_ENTITY = "testTargetEntity"; + protected static final String TEST_TARGET_SERVICE_NAME = "testTargetServiceName"; + protected static final String TEST_TARGET_VIRTUAL_ENTITY = "testTargetVirtualEntity"; + + + protected static final String TEST_THREAD_ID = "testThreadId"; + protected static final String TEST_CLASS_NAME = "testClassName"; + + protected static final String TEST_CUSTOM_FIELD1 = "testCustomField1"; + protected static final String TEST_CUSTOM_FIELD2 = "testCustomField2"; + protected static final String TEST_CUSTOM_FIELD3 = "testCustomField3"; + protected static final String TEST_CUSTOM_FIELD4 = "testCustomField4"; + + protected static final String TEST_PROCESS_KEY = "testProcessId"; + + protected static final Integer TEST_ERROR_CODE = 500; + protected static final String TEST_ERROR_CODE_DESCRIPTION = "TEST ERROR CODE DESCRIPTION"; + + + protected static RequestIdLogInfo getTestRequestIdLogInfo() { + return new RequestIdLogInfoImpl(TEST_REQUEST_ID); + } + + protected static ServiceLogInfo getTestServiceLogInfo() { + return new ServiceLogInfoImpl(TEST_SERVICE_NAME, TEST_PARTNER_NAME, TEST_CLIENT_IP_ADDRESS); + } + + protected static RequestTimingLogInfo getTestRequestTimingInfo() { + return new RequestTimingLogInfoImpl(START_DATE, END_DATE, ELAPSED_TIME); + } + + protected static ResponseLogInfo getTestResponseLogInfo() { + return new ResponseLogInfoImpl(RESPONSE_CODE, RESPONSE_DESCRIPTION); + } + + protected static AuditLogSpec getTestAuditLogSpec() { + return new AuditLogSpecImpl(getTestRequestIdLogInfo(), getTestServiceLogInfo(), + getTestRequestTimingInfo(), getTestResponseLogInfo()); + } + + protected static DebugLogSpec getTestDebugLogSpec() { + return new DebugLogSpecImpl(getTestRequestIdLogInfo()); + } + + protected static TargetServiceLogInfo getTestTargetServiceLogInfo() { + return new TargetServiceLogInfoImpl(TEST_TARGET_ENTITY, TEST_TARGET_SERVICE_NAME, TEST_TARGET_VIRTUAL_ENTITY); + } + + protected static MetricLogSpec getTestMetricLogSpec() { + return new MetricLogSpecImpl(getTestRequestIdLogInfo(), getTestServiceLogInfo(), + getTestRequestTimingInfo(), getTestResponseLogInfo(), getTestTargetServiceLogInfo()); + } + + protected static ErrorLogInfo getTestErrorLogInfo() { + return new ErrorLogInfoImpl(TEST_ERROR_CODE, TEST_ERROR_CODE_DESCRIPTION); + } + + protected static ErrorLogSpec getTestErrorLogSpec() { + return new ErrorLogSpecImpl(getTestRequestIdLogInfo(), getTestServiceLogInfo(), getTestTargetServiceLogInfo() + , getTestErrorLogInfo()); + } + + protected static OptionalLogSpec getTestOptionalLogSpec() { + final MessageLogInfo messageLogInfo = new MessageLogInfoImpl(new Date(), RequestStatusCode.COMPLETE, + NagiosAlertLevel.OK); + final CodeLogInfo codeLogInfo = new CodeLogInfoImpl(TEST_THREAD_ID, TEST_CLASS_NAME); + final CustomFieldsLogInfo customFieldsLogInfo = new CustomFieldsLogInfoImpl(TEST_CUSTOM_FIELD1, + TEST_CUSTOM_FIELD2, TEST_CUSTOM_FIELD3, TEST_CUSTOM_FIELD4); + final MiscLogInfo miscLogInfo = new MiscLogInfoImpl(TEST_PROCESS_KEY, ""); + return new OptionalLogSpecImpl(messageLogInfo, codeLogInfo, customFieldsLogInfo, miscLogInfo); + } + +} diff --git a/eelf-logger/eelf-logger-logback-impl/src/test/java/org/onap/dcae/utils/eelf/logger/logback/log/AuditLogImplTest.java b/eelf-logger/eelf-logger-logback-impl/src/test/java/org/onap/dcae/utils/eelf/logger/logback/log/AuditLogImplTest.java new file mode 100644 index 0000000..02b377a --- /dev/null +++ b/eelf-logger/eelf-logger-logback-impl/src/test/java/org/onap/dcae/utils/eelf/logger/logback/log/AuditLogImplTest.java @@ -0,0 +1,66 @@ +/* + * ================================================================================ + * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + * + */ + +package org.onap.dcae.utils.eelf.logger.logback.log; + +import org.junit.Test; +import org.onap.dcae.utils.eelf.logger.api.log.EELFLogFactory; +import org.onap.dcae.utils.eelf.logger.api.log.EELFLogger; +import org.onap.dcae.utils.eelf.logger.api.spec.AuditLogSpec; +import org.onap.dcae.utils.eelf.logger.logback.BaseLogbackUnitTest; +import org.onap.dcae.utils.eelf.logger.logback.EELFLoggerDefaults; +import org.onap.dcae.utils.eelf.logger.model.spec.AuditLogSpecImpl; + +/** + * Tests for Audit log implementations. + * + * @author Rajiv Singla + */ +public class AuditLogImplTest extends BaseLogbackUnitTest { + + private static final EELFLogger LOG = EELFLogFactory.getLogger(AuditLogImplTest.class); + + @Test + public void auditLoggerTest() throws Exception { + + LOG.auditLog().info("Test Audit info message: {}", + getTestAuditLogSpec(), getTestOptionalLogSpec(), "infoArg"); + + final AuditLogSpec emptyAuditLog = new AuditLogSpecImpl(null, null, + null, null); + + LOG.auditLog().info("Test Empty Audit info message.", emptyAuditLog, + EELFLoggerDefaults.DEFAULT_OPTIONAL_LOG_SPEC); + + } + + + @Test + public void auditLoggerTestWithWarnLogLevel() throws Exception { + LOG.auditLog().warn("Test Audit warn message: {}", + getTestAuditLogSpec(), getTestOptionalLogSpec(), "warnArg"); + } + + @Test + public void auditLoggerTestWithErrorLogLevel() throws Exception { + LOG.auditLog().error("Test Audit error message: {}", + getTestAuditLogSpec(), getTestOptionalLogSpec(), "errorArg"); + + } +} diff --git a/eelf-logger/eelf-logger-logback-impl/src/test/java/org/onap/dcae/utils/eelf/logger/logback/log/DebugLogImplTest.java b/eelf-logger/eelf-logger-logback-impl/src/test/java/org/onap/dcae/utils/eelf/logger/logback/log/DebugLogImplTest.java new file mode 100644 index 0000000..76d41f9 --- /dev/null +++ b/eelf-logger/eelf-logger-logback-impl/src/test/java/org/onap/dcae/utils/eelf/logger/logback/log/DebugLogImplTest.java @@ -0,0 +1,53 @@ +/* + * ================================================================================ + * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + * + */ + +package org.onap.dcae.utils.eelf.logger.logback.log; + +import org.junit.Test; +import org.onap.dcae.utils.eelf.logger.api.log.EELFLogFactory; +import org.onap.dcae.utils.eelf.logger.api.log.EELFLogger; +import org.onap.dcae.utils.eelf.logger.api.spec.DebugLogSpec; +import org.onap.dcae.utils.eelf.logger.logback.BaseLogbackUnitTest; +import org.onap.dcae.utils.eelf.logger.logback.EELFLoggerDefaults; +import org.onap.dcae.utils.eelf.logger.model.spec.DebugLogSpecImpl; + + +/** + * Test for Debug log implementation. + * + * @author Rajiv Singla + */ +public class DebugLogImplTest extends BaseLogbackUnitTest { + + private static final EELFLogger LOG = EELFLogFactory.getLogger(DebugLogImplTest.class); + + @Test + public void debugLoggerTest() throws Exception { + + LOG.debugLog().debug("Test DebugLog debug message: {}", + getTestDebugLogSpec(), getTestOptionalLogSpec(), "debugArg"); + + final DebugLogSpec emptyDebugLog = new DebugLogSpecImpl(null); + + LOG.debugLog().debug("Test Empty DebugLog debug message.", emptyDebugLog, + EELFLoggerDefaults.DEFAULT_OPTIONAL_LOG_SPEC); + + } + +} diff --git a/eelf-logger/eelf-logger-logback-impl/src/test/java/org/onap/dcae/utils/eelf/logger/logback/log/ErrorLogImplTest.java b/eelf-logger/eelf-logger-logback-impl/src/test/java/org/onap/dcae/utils/eelf/logger/logback/log/ErrorLogImplTest.java new file mode 100644 index 0000000..0b96be5 --- /dev/null +++ b/eelf-logger/eelf-logger-logback-impl/src/test/java/org/onap/dcae/utils/eelf/logger/logback/log/ErrorLogImplTest.java @@ -0,0 +1,61 @@ +/* + * ================================================================================ + * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + * + */ + +package org.onap.dcae.utils.eelf.logger.logback.log; + +import org.junit.Test; +import org.onap.dcae.utils.eelf.logger.api.log.EELFLogFactory; +import org.onap.dcae.utils.eelf.logger.api.log.EELFLogger; +import org.onap.dcae.utils.eelf.logger.api.spec.ErrorLogSpec; +import org.onap.dcae.utils.eelf.logger.logback.BaseLogbackUnitTest; +import org.onap.dcae.utils.eelf.logger.logback.EELFLoggerDefaults; +import org.onap.dcae.utils.eelf.logger.model.spec.ErrorLogSpecImpl; + + +/** + * Tests for Error Log implementation. + * + * @author Rajiv Singla + */ +public class ErrorLogImplTest extends BaseLogbackUnitTest { + + private static final EELFLogger LOG = EELFLogFactory.getLogger(ErrorLogImplTest.class); + + @Test + public void errorLoggerTest() throws Exception { + LOG.errorLog().error("Test ErrorLog error message: {}", + getTestErrorLogSpec(), getTestOptionalLogSpec(), "errorArg"); + + final ErrorLogSpec emptyErrorLog = new ErrorLogSpecImpl(null, null, + null, null); + + LOG.errorLog().error("Test Empty ErrorLog error message", emptyErrorLog, + EELFLoggerDefaults.DEFAULT_OPTIONAL_LOG_SPEC); + + } + + @Test + public void errorLoggerTestWithWarnLogLevel() throws Exception { + LOG.errorLog().warn("Test errorLog warn message: {}", getTestErrorLogSpec(), getTestOptionalLogSpec(), + "warnArg"); + + } + + +} diff --git a/eelf-logger/eelf-logger-logback-impl/src/test/java/org/onap/dcae/utils/eelf/logger/logback/log/MetricLogImplTest.java b/eelf-logger/eelf-logger-logback-impl/src/test/java/org/onap/dcae/utils/eelf/logger/logback/log/MetricLogImplTest.java new file mode 100644 index 0000000..8df1e9c --- /dev/null +++ b/eelf-logger/eelf-logger-logback-impl/src/test/java/org/onap/dcae/utils/eelf/logger/logback/log/MetricLogImplTest.java @@ -0,0 +1,67 @@ +/* + * ================================================================================ + * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + * + */ + +package org.onap.dcae.utils.eelf.logger.logback.log; + +import org.junit.Test; +import org.onap.dcae.utils.eelf.logger.api.log.EELFLogFactory; +import org.onap.dcae.utils.eelf.logger.api.log.EELFLogger; +import org.onap.dcae.utils.eelf.logger.api.spec.MetricLogSpec; +import org.onap.dcae.utils.eelf.logger.logback.BaseLogbackUnitTest; +import org.onap.dcae.utils.eelf.logger.logback.EELFLoggerDefaults; +import org.onap.dcae.utils.eelf.logger.model.spec.MetricLogSpecImpl; + + +/** + * Tests for Metric Log implementation. + * + * @author Rajiv Singla + */ +public class MetricLogImplTest extends BaseLogbackUnitTest { + + private static final EELFLogger LOG = EELFLogFactory.getLogger(MetricLogImplTest.class); + + @Test + public void metricLoggerTest() throws Exception { + + LOG.metricLog().info("test Metric info message: {}", getTestMetricLogSpec(), getTestOptionalLogSpec(), + "infoArg"); + + final MetricLogSpec emptyMetricLog = new MetricLogSpecImpl(null, null, null, null, null); + + LOG.metricLog().info("Test Empty Metric info message", emptyMetricLog, + EELFLoggerDefaults.DEFAULT_OPTIONAL_LOG_SPEC); + } + + @Test + public void metricLoggerTestWithWarnLogLevel() throws Exception { + LOG.metricLog().warn("test Metric warn message: {}", getTestMetricLogSpec(), getTestOptionalLogSpec(), + "warnArg"); + + } + + @Test + public void metricLoggerTestWithErrorLogLevel() throws Exception { + LOG.metricLog().warn("test Metric error message: {}", getTestMetricLogSpec(), getTestOptionalLogSpec(), + "errorArg"); + + + } + +} diff --git a/eelf-logger/eelf-logger-logback-impl/src/test/resources/logback.xml b/eelf-logger/eelf-logger-logback-impl/src/test/resources/logback.xml new file mode 100644 index 0000000..b1cffd6 --- /dev/null +++ b/eelf-logger/eelf-logger-logback-impl/src/test/resources/logback.xml @@ -0,0 +1,41 @@ +<!-- + ~ ================================================================================ + ~ Copyright (c) 2018 AT&T Intellectual Property. All rights reserved. + ~ ================================================================================ + ~ 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. + ~ ============LICENSE_END========================================================= + ~ + --> +<configuration> + + <!-- SET EELF COMPONENT NAME --> + <property scope="context" name="componentName" value="test-eelf-logger"/> + <contextName>${componentName}</contextName> + + <include resource="eelf-logback.xml"/> + + <include resource="eelf-optional-appenders.xml"/> + + <root level="DEBUG"> + <!-- required appenders --> + <appender-ref ref="auditLogAppender"/> + <appender-ref ref="metricLogAppender"/> + <appender-ref ref="errorLogAppender"/> + + <!-- optional appenders --> + <appender-ref ref="debugLogAppender"/> + <appender-ref ref="STDOUT"/> + </root> + + +</configuration> diff --git a/eelf-logger/eelf-logger-model/pom.xml b/eelf-logger/eelf-logger-model/pom.xml new file mode 100644 index 0000000..86f269a --- /dev/null +++ b/eelf-logger/eelf-logger-model/pom.xml @@ -0,0 +1,77 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ ================================================================================ + ~ Copyright (c) 2018 AT&T Intellectual Property. All rights reserved. + ~ ================================================================================ + ~ 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. + ~ ============LICENSE_END========================================================= + ~ + --> + +<project xmlns="http://maven.apache.org/POM/4.0.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + + <modelVersion>4.0.0</modelVersion> + + <parent> + <groupId>org.onap.dcaegen2.utils</groupId> + <artifactId>eelf-logger</artifactId> + <version>1.0.0-SNAPSHOT</version> + </parent> + + <artifactId>eelf-logger-model</artifactId> + <packaging>jar</packaging> + + + <!-- EELF LOGGER MODELS CONTAINS IMMUTABLE MODEL OBJECTS FOR VARIOUS EELF LOGGER INTERFACES --> + <name>dcaegen2-utils-eelf-logger-model</name> + <description>Contains immutable model objects for various EELF Logger interfaces</description> + + <properties> + <main.basedir>${project.parent.basedir}</main.basedir> + <!-- SONAR SETTINGS : EXCLUDE TEST COVERAGE AS MODEL ONLY CONTAINS POJOs AND NO BUSINESS LOGIC--> + <sonar.coverage.exclusions>**/model/**</sonar.coverage.exclusions> + </properties> + + <!-- NOTE: THIS MODULE MUST NOT HAVE ANY DEPENDENCY BESIDES ECOMP LOGGER API IN COMPILE SCOPE --> + <dependencies> + + <!-- ECOMP LOGGER API --> + <dependency> + <groupId>${project.groupId}</groupId> + <artifactId>eelf-logger-api</artifactId> + <version>${project.version}</version> + </dependency> + + <!-- LOMBOK IS USED FOR CODE GENERATION IN PROVIDED SCOPE (NOT IN COMPILE SCOPE) --> + <dependency> + <groupId>org.projectlombok</groupId> + <artifactId>lombok</artifactId> + </dependency> + + </dependencies> + + <build> + <sourceDirectory>${project.build.directory}/generated-sources/delombok</sourceDirectory> + <plugins> + <plugin> + <groupId>org.projectlombok</groupId> + <artifactId>lombok-maven-plugin</artifactId> + </plugin> + </plugins> + </build> + + + +</project> diff --git a/eelf-logger/eelf-logger-model/src/main/java/org/onap/dcae/utils/eelf/logger/model/info/AppLogInfoImpl.java b/eelf-logger/eelf-logger-model/src/main/java/org/onap/dcae/utils/eelf/logger/model/info/AppLogInfoImpl.java new file mode 100644 index 0000000..689915c --- /dev/null +++ b/eelf-logger/eelf-logger-model/src/main/java/org/onap/dcae/utils/eelf/logger/model/info/AppLogInfoImpl.java @@ -0,0 +1,53 @@ +/* + * ================================================================================ + * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + * + */ + +package org.onap.dcae.utils.eelf.logger.model.info; + +import lombok.AllArgsConstructor; +import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.ToString; +import lombok.experimental.Wither; +import org.onap.dcae.utils.eelf.logger.api.info.AppLogInfo; + +/** + * Concrete model implementation for {@link AppLogInfo} + * + * @author Rajiv Singla + */ +@Getter +@AllArgsConstructor +@EqualsAndHashCode +@ToString +@Wither +public class AppLogInfoImpl implements AppLogInfo { + + private static final long serialVersionUID = 1L; + + private String serviceInstanceID; + + private String instanceUUID; + + private String virtualServerName; + + private String serverIPAddress; + + private String serverFQDN; + +} diff --git a/eelf-logger/eelf-logger-model/src/main/java/org/onap/dcae/utils/eelf/logger/model/info/CodeLogInfoImpl.java b/eelf-logger/eelf-logger-model/src/main/java/org/onap/dcae/utils/eelf/logger/model/info/CodeLogInfoImpl.java new file mode 100644 index 0000000..7f5eb2f --- /dev/null +++ b/eelf-logger/eelf-logger-model/src/main/java/org/onap/dcae/utils/eelf/logger/model/info/CodeLogInfoImpl.java @@ -0,0 +1,48 @@ +/* + * ================================================================================ + * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + * + */ + +package org.onap.dcae.utils.eelf.logger.model.info; + +import lombok.AllArgsConstructor; +import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.ToString; +import lombok.experimental.Wither; +import org.onap.dcae.utils.eelf.logger.api.info.CodeLogInfo; + +/** + * Concrete model implementation for {@link CodeLogInfo} + * + * @author Rajiv Singla + */ +@Getter +@AllArgsConstructor +@EqualsAndHashCode +@ToString +@Wither +public class CodeLogInfoImpl implements CodeLogInfo { + + private static final long serialVersionUID = 1L; + + private String threadId; + + private String className; + + +} diff --git a/eelf-logger/eelf-logger-model/src/main/java/org/onap/dcae/utils/eelf/logger/model/info/CustomFieldsLogInfoImpl.java b/eelf-logger/eelf-logger-model/src/main/java/org/onap/dcae/utils/eelf/logger/model/info/CustomFieldsLogInfoImpl.java new file mode 100644 index 0000000..151900d --- /dev/null +++ b/eelf-logger/eelf-logger-model/src/main/java/org/onap/dcae/utils/eelf/logger/model/info/CustomFieldsLogInfoImpl.java @@ -0,0 +1,51 @@ +/* + * ================================================================================ + * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + * + */ + +package org.onap.dcae.utils.eelf.logger.model.info; + +import lombok.AllArgsConstructor; +import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.ToString; +import lombok.experimental.Wither; +import org.onap.dcae.utils.eelf.logger.api.info.CustomFieldsLogInfo; + +/** + * Concrete model implementation for {@link CustomFieldsLogInfo} + * + * @author Rajiv Singla + */ +@Getter +@AllArgsConstructor +@EqualsAndHashCode +@ToString +@Wither +public class CustomFieldsLogInfoImpl implements CustomFieldsLogInfo { + + private static final long serialVersionUID = 1L; + + private String customField1; + + private String customField2; + + private String customField3; + + private String customField4; + +} diff --git a/eelf-logger/eelf-logger-model/src/main/java/org/onap/dcae/utils/eelf/logger/model/info/ErrorLogInfoImpl.java b/eelf-logger/eelf-logger-model/src/main/java/org/onap/dcae/utils/eelf/logger/model/info/ErrorLogInfoImpl.java new file mode 100644 index 0000000..18c2e95 --- /dev/null +++ b/eelf-logger/eelf-logger-model/src/main/java/org/onap/dcae/utils/eelf/logger/model/info/ErrorLogInfoImpl.java @@ -0,0 +1,47 @@ +/* + * ================================================================================ + * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + * + */ + +package org.onap.dcae.utils.eelf.logger.model.info; + +import lombok.AllArgsConstructor; +import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.ToString; +import lombok.experimental.Wither; +import org.onap.dcae.utils.eelf.logger.api.info.ErrorLogInfo; + +/** + * Concrete model implementation for {@link ErrorLogInfo} + * + * @author Rajiv Singla + */ +@Getter +@AllArgsConstructor +@EqualsAndHashCode +@ToString +@Wither +public class ErrorLogInfoImpl implements ErrorLogInfo { + + private static final long serialVersionUID = 1L; + + private Integer errorCode; + + private String errorDescription; + +} diff --git a/eelf-logger/eelf-logger-model/src/main/java/org/onap/dcae/utils/eelf/logger/model/info/MessageLogInfoImpl.java b/eelf-logger/eelf-logger-model/src/main/java/org/onap/dcae/utils/eelf/logger/model/info/MessageLogInfoImpl.java new file mode 100644 index 0000000..65e722a --- /dev/null +++ b/eelf-logger/eelf-logger-model/src/main/java/org/onap/dcae/utils/eelf/logger/model/info/MessageLogInfoImpl.java @@ -0,0 +1,54 @@ +/* + * ================================================================================ + * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + * + */ + +package org.onap.dcae.utils.eelf.logger.model.info; + +import lombok.AllArgsConstructor; +import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.ToString; +import lombok.experimental.Wither; +import org.onap.dcae.utils.eelf.logger.api.info.MessageLogInfo; +import org.onap.dcae.utils.eelf.logger.api.info.NagiosAlertLevel; +import org.onap.dcae.utils.eelf.logger.api.info.RequestStatusCode; + + +import java.util.Date; + +/** + * Concrete model implementation for {@link MessageLogInfo} + * + * @author Rajiv Singla + */ +@Getter +@AllArgsConstructor +@EqualsAndHashCode +@ToString +@Wither +public class MessageLogInfoImpl implements MessageLogInfo { + + private static final long serialVersionUID = 1L; + + private Date creationTimestamp; + + private RequestStatusCode statusCode; + + private NagiosAlertLevel alertSeverity; + +} diff --git a/eelf-logger/eelf-logger-model/src/main/java/org/onap/dcae/utils/eelf/logger/model/info/MiscLogInfoImpl.java b/eelf-logger/eelf-logger-model/src/main/java/org/onap/dcae/utils/eelf/logger/model/info/MiscLogInfoImpl.java new file mode 100644 index 0000000..f7e648b --- /dev/null +++ b/eelf-logger/eelf-logger-model/src/main/java/org/onap/dcae/utils/eelf/logger/model/info/MiscLogInfoImpl.java @@ -0,0 +1,47 @@ +/* + * ================================================================================ + * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + * + */ + +package org.onap.dcae.utils.eelf.logger.model.info; + +import lombok.AllArgsConstructor; +import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.ToString; +import lombok.experimental.Wither; +import org.onap.dcae.utils.eelf.logger.api.info.MiscLogInfo; + +/** + * Concrete model implementation for {@link MiscLogInfo} + * + * @author Rajiv Singla + */ +@Getter +@AllArgsConstructor +@EqualsAndHashCode +@ToString +@Wither +public class MiscLogInfoImpl implements MiscLogInfo { + + private static final long serialVersionUID = 1L; + + private String processId; + + private String unused; + +} diff --git a/eelf-logger/eelf-logger-model/src/main/java/org/onap/dcae/utils/eelf/logger/model/info/RequestIdLogInfoImpl.java b/eelf-logger/eelf-logger-model/src/main/java/org/onap/dcae/utils/eelf/logger/model/info/RequestIdLogInfoImpl.java new file mode 100644 index 0000000..af939c4 --- /dev/null +++ b/eelf-logger/eelf-logger-model/src/main/java/org/onap/dcae/utils/eelf/logger/model/info/RequestIdLogInfoImpl.java @@ -0,0 +1,45 @@ +/* + * ================================================================================ + * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + * + */ + +package org.onap.dcae.utils.eelf.logger.model.info; + +import lombok.AllArgsConstructor; +import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.ToString; +import lombok.experimental.Wither; +import org.onap.dcae.utils.eelf.logger.api.info.RequestIdLogInfo; + +/** + * Concrete model implementation for {@link RequestIdLogInfo} + * + * @author Rajiv Singla + */ +@Getter +@AllArgsConstructor +@EqualsAndHashCode +@ToString +@Wither +public class RequestIdLogInfoImpl implements RequestIdLogInfo { + + private static final long serialVersionUID = 1L; + + private String requestId; + +} diff --git a/eelf-logger/eelf-logger-model/src/main/java/org/onap/dcae/utils/eelf/logger/model/info/RequestTimingLogInfoImpl.java b/eelf-logger/eelf-logger-model/src/main/java/org/onap/dcae/utils/eelf/logger/model/info/RequestTimingLogInfoImpl.java new file mode 100644 index 0000000..19d860b --- /dev/null +++ b/eelf-logger/eelf-logger-model/src/main/java/org/onap/dcae/utils/eelf/logger/model/info/RequestTimingLogInfoImpl.java @@ -0,0 +1,51 @@ +/* + * ================================================================================ + * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + * + */ + +package org.onap.dcae.utils.eelf.logger.model.info; + +import lombok.AllArgsConstructor; +import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.ToString; +import lombok.experimental.Wither; +import org.onap.dcae.utils.eelf.logger.api.info.RequestTimingLogInfo; + +import java.util.Date; + +/** + * Concrete model implementation for {@link RequestTimingLogInfo} + * + * @author Rajiv Singla + */ +@Getter +@AllArgsConstructor +@EqualsAndHashCode +@ToString +@Wither +public class RequestTimingLogInfoImpl implements RequestTimingLogInfo { + + private static final long serialVersionUID = 1L; + + private Date beginTimestamp; + + private Date endTimestamp; + + private Long elapsedTime; + +} diff --git a/eelf-logger/eelf-logger-model/src/main/java/org/onap/dcae/utils/eelf/logger/model/info/ResponseLogInfoImpl.java b/eelf-logger/eelf-logger-model/src/main/java/org/onap/dcae/utils/eelf/logger/model/info/ResponseLogInfoImpl.java new file mode 100644 index 0000000..1f0bfbf --- /dev/null +++ b/eelf-logger/eelf-logger-model/src/main/java/org/onap/dcae/utils/eelf/logger/model/info/ResponseLogInfoImpl.java @@ -0,0 +1,47 @@ +/* + * ================================================================================ + * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + * + */ + +package org.onap.dcae.utils.eelf.logger.model.info; + +import lombok.AllArgsConstructor; +import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.ToString; +import lombok.experimental.Wither; +import org.onap.dcae.utils.eelf.logger.api.info.ResponseLogInfo; + +/** + * Concrete model implementation for {@link ResponseLogInfo} + * + * @author Rajiv Singla + */ +@Getter +@AllArgsConstructor +@EqualsAndHashCode +@ToString +@Wither +public class ResponseLogInfoImpl implements ResponseLogInfo { + + private static final long serialVersionUID = 1L; + + private Integer responseCode; + + private String responseDescription; + +} diff --git a/eelf-logger/eelf-logger-model/src/main/java/org/onap/dcae/utils/eelf/logger/model/info/ServiceLogInfoImpl.java b/eelf-logger/eelf-logger-model/src/main/java/org/onap/dcae/utils/eelf/logger/model/info/ServiceLogInfoImpl.java new file mode 100644 index 0000000..68d1f41 --- /dev/null +++ b/eelf-logger/eelf-logger-model/src/main/java/org/onap/dcae/utils/eelf/logger/model/info/ServiceLogInfoImpl.java @@ -0,0 +1,49 @@ +/* + * ================================================================================ + * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + * + */ + +package org.onap.dcae.utils.eelf.logger.model.info; + +import lombok.AllArgsConstructor; +import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.ToString; +import lombok.experimental.Wither; +import org.onap.dcae.utils.eelf.logger.api.info.ServiceLogInfo; + +/** + * Concrete model implementation for {@link ServiceLogInfo} + * + * @author Rajiv Singla + */ +@Getter +@AllArgsConstructor +@EqualsAndHashCode +@ToString +@Wither +public class ServiceLogInfoImpl implements ServiceLogInfo { + + private static final long serialVersionUID = 1L; + + private String serviceName; + + private String partnerName; + + private String clientIPAddress; + +} diff --git a/eelf-logger/eelf-logger-model/src/main/java/org/onap/dcae/utils/eelf/logger/model/info/TargetServiceLogInfoImpl.java b/eelf-logger/eelf-logger-model/src/main/java/org/onap/dcae/utils/eelf/logger/model/info/TargetServiceLogInfoImpl.java new file mode 100644 index 0000000..4a41e73 --- /dev/null +++ b/eelf-logger/eelf-logger-model/src/main/java/org/onap/dcae/utils/eelf/logger/model/info/TargetServiceLogInfoImpl.java @@ -0,0 +1,48 @@ +/* + * ================================================================================ + * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + * + */ + +package org.onap.dcae.utils.eelf.logger.model.info; + +import lombok.AllArgsConstructor; +import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.ToString; +import lombok.experimental.Wither; +import org.onap.dcae.utils.eelf.logger.api.info.TargetServiceLogInfo; + +/** + * Concrete model implementation for {@link TargetServiceLogInfo} + * + * @author Rajiv Singla + */ +@Getter +@AllArgsConstructor +@EqualsAndHashCode +@ToString +@Wither +public class TargetServiceLogInfoImpl implements TargetServiceLogInfo { + + private static final long serialVersionUID = 1L; + + private String targetEntity; + + private String targetServiceName; + + private String targetVirtualEntity; +} diff --git a/eelf-logger/eelf-logger-model/src/main/java/org/onap/dcae/utils/eelf/logger/model/info/package-info.java b/eelf-logger/eelf-logger-model/src/main/java/org/onap/dcae/utils/eelf/logger/model/info/package-info.java new file mode 100644 index 0000000..ce0966e --- /dev/null +++ b/eelf-logger/eelf-logger-model/src/main/java/org/onap/dcae/utils/eelf/logger/model/info/package-info.java @@ -0,0 +1,23 @@ +/* + * ================================================================================ + * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + * + */ + +/** + * Contains immutable implementations for EELF Logging Information interfaces + */ +package org.onap.dcae.utils.eelf.logger.model.info; diff --git a/eelf-logger/eelf-logger-model/src/main/java/org/onap/dcae/utils/eelf/logger/model/spec/AppLogSpecImpl.java b/eelf-logger/eelf-logger-model/src/main/java/org/onap/dcae/utils/eelf/logger/model/spec/AppLogSpecImpl.java new file mode 100644 index 0000000..d1e40ad --- /dev/null +++ b/eelf-logger/eelf-logger-model/src/main/java/org/onap/dcae/utils/eelf/logger/model/spec/AppLogSpecImpl.java @@ -0,0 +1,47 @@ +/* + * ================================================================================ + * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + * + */ + +package org.onap.dcae.utils.eelf.logger.model.spec; + +import lombok.AllArgsConstructor; +import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.ToString; +import lombok.experimental.Delegate; +import org.onap.dcae.utils.eelf.logger.api.info.AppLogInfo; +import org.onap.dcae.utils.eelf.logger.api.spec.AppLogSpec; + + +/** + * Concrete model implementation for {@link AppLogSpec} + * + * @author Rajiv Singla + */ +@Getter +@AllArgsConstructor +@EqualsAndHashCode +@ToString +public class AppLogSpecImpl implements AppLogSpec { + + private static final long serialVersionUID = 1L; + + @Delegate(types = AppLogSpec.class) + private AppLogInfo appLogInfo; + +} diff --git a/eelf-logger/eelf-logger-model/src/main/java/org/onap/dcae/utils/eelf/logger/model/spec/AuditLogSpecImpl.java b/eelf-logger/eelf-logger-model/src/main/java/org/onap/dcae/utils/eelf/logger/model/spec/AuditLogSpecImpl.java new file mode 100644 index 0000000..c217595 --- /dev/null +++ b/eelf-logger/eelf-logger-model/src/main/java/org/onap/dcae/utils/eelf/logger/model/spec/AuditLogSpecImpl.java @@ -0,0 +1,61 @@ +/* + * ================================================================================ + * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + * + */ + +package org.onap.dcae.utils.eelf.logger.model.spec; + +import lombok.AllArgsConstructor; +import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.ToString; +import lombok.experimental.Delegate; +import lombok.experimental.Wither; +import org.onap.dcae.utils.eelf.logger.api.info.RequestIdLogInfo; +import org.onap.dcae.utils.eelf.logger.api.info.RequestTimingLogInfo; +import org.onap.dcae.utils.eelf.logger.api.info.ResponseLogInfo; +import org.onap.dcae.utils.eelf.logger.api.info.ServiceLogInfo; +import org.onap.dcae.utils.eelf.logger.api.spec.AuditLogSpec; + + +/** + * Concrete model implementation for {@link AuditLogSpec} + * + * @author Rajiv Singla + */ +@Getter +@AllArgsConstructor +@EqualsAndHashCode +@ToString +@Wither +public class AuditLogSpecImpl implements AuditLogSpec { + + private static final long serialVersionUID = 1L; + + @Delegate(types = RequestIdLogInfo.class) + private RequestIdLogInfo requestIdLogInfo; + + @Delegate(types = ServiceLogInfo.class) + private ServiceLogInfo serviceLogInfo; + + @Delegate(types = RequestTimingLogInfo.class) + private RequestTimingLogInfo requestTimingLogInfo; + + @Delegate(types = ResponseLogInfo.class) + private ResponseLogInfo responseLogInfo; + +} diff --git a/eelf-logger/eelf-logger-model/src/main/java/org/onap/dcae/utils/eelf/logger/model/spec/DebugLogSpecImpl.java b/eelf-logger/eelf-logger-model/src/main/java/org/onap/dcae/utils/eelf/logger/model/spec/DebugLogSpecImpl.java new file mode 100644 index 0000000..53a1070 --- /dev/null +++ b/eelf-logger/eelf-logger-model/src/main/java/org/onap/dcae/utils/eelf/logger/model/spec/DebugLogSpecImpl.java @@ -0,0 +1,48 @@ +/* + * ================================================================================ + * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + * + */ + +package org.onap.dcae.utils.eelf.logger.model.spec; + +import lombok.AllArgsConstructor; +import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.ToString; +import lombok.experimental.Delegate; +import lombok.experimental.Wither; +import org.onap.dcae.utils.eelf.logger.api.info.RequestIdLogInfo; +import org.onap.dcae.utils.eelf.logger.api.spec.DebugLogSpec; + + +/** + * Concrete model implementation for {@link DebugLogSpec} + * + * @author Rajiv Singla + */ +@Getter +@AllArgsConstructor +@EqualsAndHashCode +@ToString +@Wither +public class DebugLogSpecImpl implements DebugLogSpec { + + private static final long serialVersionUID = 1L; + + @Delegate(types = RequestIdLogInfo.class) + private RequestIdLogInfo requestIdLogInfo; +} diff --git a/eelf-logger/eelf-logger-model/src/main/java/org/onap/dcae/utils/eelf/logger/model/spec/ErrorLogSpecImpl.java b/eelf-logger/eelf-logger-model/src/main/java/org/onap/dcae/utils/eelf/logger/model/spec/ErrorLogSpecImpl.java new file mode 100644 index 0000000..6e73fcf --- /dev/null +++ b/eelf-logger/eelf-logger-model/src/main/java/org/onap/dcae/utils/eelf/logger/model/spec/ErrorLogSpecImpl.java @@ -0,0 +1,61 @@ +/* + * ================================================================================ + * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + * + */ + +package org.onap.dcae.utils.eelf.logger.model.spec; + +import lombok.AllArgsConstructor; +import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.ToString; +import lombok.experimental.Delegate; +import lombok.experimental.Wither; +import org.onap.dcae.utils.eelf.logger.api.info.ErrorLogInfo; +import org.onap.dcae.utils.eelf.logger.api.info.RequestIdLogInfo; +import org.onap.dcae.utils.eelf.logger.api.info.ServiceLogInfo; +import org.onap.dcae.utils.eelf.logger.api.info.TargetServiceLogInfo; +import org.onap.dcae.utils.eelf.logger.api.spec.ErrorLogSpec; + + +/** + * Concrete model implementation for {@link ErrorLogSpec} + * + * @author Rajiv Singla + */ +@Getter +@AllArgsConstructor +@EqualsAndHashCode +@ToString +@Wither +public class ErrorLogSpecImpl implements ErrorLogSpec { + + private static final long serialVersionUID = 1L; + + @Delegate(types = RequestIdLogInfo.class) + private RequestIdLogInfo requestIdLogInfo; + + @Delegate(types = ServiceLogInfo.class) + private ServiceLogInfo serviceLogInfo; + + @Delegate(types = TargetServiceLogInfo.class) + private TargetServiceLogInfo targetServiceLogInfo; + + @Delegate(types = ErrorLogInfo.class) + private ErrorLogInfo errorLogInfo; + +} diff --git a/eelf-logger/eelf-logger-model/src/main/java/org/onap/dcae/utils/eelf/logger/model/spec/MetricLogSpecImpl.java b/eelf-logger/eelf-logger-model/src/main/java/org/onap/dcae/utils/eelf/logger/model/spec/MetricLogSpecImpl.java new file mode 100644 index 0000000..d910bc2 --- /dev/null +++ b/eelf-logger/eelf-logger-model/src/main/java/org/onap/dcae/utils/eelf/logger/model/spec/MetricLogSpecImpl.java @@ -0,0 +1,64 @@ +/* + * ================================================================================ + * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + * + */ + +package org.onap.dcae.utils.eelf.logger.model.spec; + +import lombok.AllArgsConstructor; +import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.ToString; +import lombok.experimental.Delegate; +import lombok.experimental.Wither; +import org.onap.dcae.utils.eelf.logger.api.info.RequestIdLogInfo; +import org.onap.dcae.utils.eelf.logger.api.info.RequestTimingLogInfo; +import org.onap.dcae.utils.eelf.logger.api.info.ResponseLogInfo; +import org.onap.dcae.utils.eelf.logger.api.info.ServiceLogInfo; +import org.onap.dcae.utils.eelf.logger.api.info.TargetServiceLogInfo; +import org.onap.dcae.utils.eelf.logger.api.spec.MetricLogSpec; + + +/** + * Concrete model implementation for {@link MetricLogSpec} + * + * @author Rajiv Singla + */ +@Getter +@AllArgsConstructor +@EqualsAndHashCode +@ToString +@Wither +public class MetricLogSpecImpl implements MetricLogSpec { + + private static final long serialVersionUID = 1L; + + @Delegate(types = RequestIdLogInfo.class) + private RequestIdLogInfo requestIdLogInfo; + + @Delegate(types = ServiceLogInfo.class) + private ServiceLogInfo serviceLogInfo; + + @Delegate(types = RequestTimingLogInfo.class) + private RequestTimingLogInfo requestTimingLogInfo; + + @Delegate(types = ResponseLogInfo.class) + private ResponseLogInfo responseLogInfo; + + @Delegate(types = TargetServiceLogInfo.class) + private TargetServiceLogInfo targetServiceLogInfo; +} diff --git a/eelf-logger/eelf-logger-model/src/main/java/org/onap/dcae/utils/eelf/logger/model/spec/OptionalLogSpecImpl.java b/eelf-logger/eelf-logger-model/src/main/java/org/onap/dcae/utils/eelf/logger/model/spec/OptionalLogSpecImpl.java new file mode 100644 index 0000000..755b4bf --- /dev/null +++ b/eelf-logger/eelf-logger-model/src/main/java/org/onap/dcae/utils/eelf/logger/model/spec/OptionalLogSpecImpl.java @@ -0,0 +1,60 @@ +/* + * ================================================================================ + * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + * + */ + +package org.onap.dcae.utils.eelf.logger.model.spec; + +import lombok.AllArgsConstructor; +import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.ToString; +import lombok.experimental.Delegate; +import lombok.experimental.Wither; +import org.onap.dcae.utils.eelf.logger.api.info.CodeLogInfo; +import org.onap.dcae.utils.eelf.logger.api.info.CustomFieldsLogInfo; +import org.onap.dcae.utils.eelf.logger.api.info.MessageLogInfo; +import org.onap.dcae.utils.eelf.logger.api.info.MiscLogInfo; +import org.onap.dcae.utils.eelf.logger.api.spec.OptionalLogSpec; + + +/** + * Concrete model implementation for {@link OptionalLogSpec} + * + * @author Rajiv Singla + */ +@Getter +@AllArgsConstructor +@EqualsAndHashCode +@ToString +@Wither +public class OptionalLogSpecImpl implements OptionalLogSpec { + + private static final long serialVersionUID = 1L; + + @Delegate(types = MessageLogInfo.class) + private MessageLogInfo messageLogInfo; + + @Delegate(types = CodeLogInfo.class) + private CodeLogInfo codeLogInfo; + + @Delegate(types = CustomFieldsLogInfo.class) + private CustomFieldsLogInfo customFieldsLogInfo; + + @Delegate(types = MiscLogInfo.class) + private MiscLogInfo miscLogInfo; +} diff --git a/eelf-logger/eelf-logger-model/src/main/java/org/onap/dcae/utils/eelf/logger/model/spec/package-info.java b/eelf-logger/eelf-logger-model/src/main/java/org/onap/dcae/utils/eelf/logger/model/spec/package-info.java new file mode 100644 index 0000000..73aec41 --- /dev/null +++ b/eelf-logger/eelf-logger-model/src/main/java/org/onap/dcae/utils/eelf/logger/model/spec/package-info.java @@ -0,0 +1,23 @@ +/* + * ================================================================================ + * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + * + */ + +/** + * Contains immutable implementations for EELF Logging specification interfaces + */ +package org.onap.dcae.utils.eelf.logger.model.spec; diff --git a/eelf-logger/findbugs-exclude.xml b/eelf-logger/findbugs-exclude.xml new file mode 100644 index 0000000..9eac36d --- /dev/null +++ b/eelf-logger/findbugs-exclude.xml @@ -0,0 +1,30 @@ +<?xml version="1.0" encoding="UTF-8"?> + +<!-- + ~ ================================================================================ + ~ Copyright (c) 2018 AT&T Intellectual Property. All rights reserved. + ~ ================================================================================ + ~ 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. + ~ ============LICENSE_END========================================================= + ~ + --> + +<FindBugsFilter> + + <Match> + <!-- MODEL OBJECTS ARE USING LOMBOK ANNOTATIONS SO SOME FINDBUGS ARE IGNORED--> + <Package name="~.*model.*"/> + <Bug pattern="ES_COMPARING_PARAMETER_STRING_WITH_EQ, RC_REF_COMPARISON, EI_EXPOSE_REP, EI_EXPOSE_REP2"/> + </Match> + +</FindBugsFilter> diff --git a/eelf-logger/pmd-exclude.properties b/eelf-logger/pmd-exclude.properties new file mode 100644 index 0000000..d325b88 --- /dev/null +++ b/eelf-logger/pmd-exclude.properties @@ -0,0 +1,22 @@ +#
+# ================================================================================
+# Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+# ================================================================================
+# 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.
+# ============LICENSE_END=========================================================
+#
+#
+
+# List fully qualified names of classes that can be excluded for PMD (PROGRAMMING-MISTAKE-DETECTOR)
+
+# IGNORE TOO MANY STATIC IMPORTS
diff --git a/eelf-logger/pom.xml b/eelf-logger/pom.xml new file mode 100644 index 0000000..acb5fda --- /dev/null +++ b/eelf-logger/pom.xml @@ -0,0 +1,476 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ ================================================================================ + ~ Copyright (c) 2018 AT&T Intellectual Property. All rights reserved. + ~ ================================================================================ + ~ 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. + ~ ============LICENSE_END========================================================= + ~ + --> +<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xmlns="http://maven.apache.org/POM/4.0.0" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + + <modelVersion>4.0.0</modelVersion> + <modules> + <module>eelf-logger-api</module> + <module>eelf-logger-model</module> + <module>eelf-logger-logback-impl</module> + </modules> + + <parent> + <artifactId>utils</artifactId> + <groupId>org.onap.dcaegen2.utils</groupId> + <version>1.2.0-SNAPSHOT</version> + </parent> + + + <artifactId>eelf-logger</artifactId> + <name>dcaegen2-utils-eelf-logger</name> + <version>1.0.0-SNAPSHOT</version> + <packaging>pom</packaging> + <url>http://maven.apache.org</url> + + + <properties> + + <!-- PROJECT SETTINGS--> + <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> + <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> + <main.basedir>${project.basedir}</main.basedir> + + <!--TEST SETTINGS --> + <surefire.redirectTestOutputToFile>true</surefire.redirectTestOutputToFile> + + <!-- PROJECT DEPENDENCIES --> + <slf4j.version>1.7.5</slf4j.version> + <logback.version>1.2.3</logback.version> + <lombok.version>1.16.10</lombok.version> + + + <!--TESTING DEPENDENCIES --> + <junit.version>4.12</junit.version> + <mockito.version>2.2.11</mockito.version> + <assertj-core.version>2.6.0</assertj-core.version> + + + <!-- PLUGINS VERSIONS --> + <compiler.plugin.version>3.3</compiler.plugin.version> + <surefire.plugin.version>2.19.1</surefire.plugin.version> + <failsafe.plugin.version>2.19.1</failsafe.plugin.version> + <findbugs.plugin.version>3.0.2</findbugs.plugin.version> + + <pmd.plugin.version>3.5</pmd.plugin.version> + <javadoc.plugin.version>2.10.4</javadoc.plugin.version> + <source.plugin.version>2.4</source.plugin.version> + <jar.plugin.version>2.4</jar.plugin.version> + <deploy.plugin.version>2.8</deploy.plugin.version> + <lombok.plugin.version>1.16.10.0</lombok.plugin.version> + <maven.site.plugin>3.5.1</maven.site.plugin> + + <!--PLUGIN SETTINGS --> + <compiler.source.version>1.7</compiler.source.version> + <compiler.target.version>1.7</compiler.target.version> + <unit.test.pattern>**/*Test.java</unit.test.pattern> + <skip.unit.tests>false</skip.unit.tests> + <integration.test.pattern>**/*IT.java</integration.test.pattern> + <skip.integration.tests>true</skip.integration.tests> + <pmd.violation.buildfail>true</pmd.violation.buildfail> + <findbugs.failOnError>true</findbugs.failOnError> + + </properties> + + + <dependencyManagement> + + <dependencies> + + <!-- LOGGING --> + <dependency> + <groupId>org.slf4j</groupId> + <artifactId>slf4j-api</artifactId> + <version>${slf4j.version}</version> + </dependency> + + <dependency> + <groupId>ch.qos.logback</groupId> + <artifactId>logback-classic</artifactId> + <version>${logback.version}</version> + </dependency> + + <!-- CODE GENERATION --> + <dependency> + <groupId>org.projectlombok</groupId> + <artifactId>lombok</artifactId> + <version>${lombok.version}</version> + <scope>provided</scope> + </dependency> + + + <!-- TEST DEPENDENCIES --> + <dependency> + <groupId>junit</groupId> + <artifactId>junit</artifactId> + <version>${junit.version}</version> + <scope>test</scope> + </dependency> + + <dependency> + <groupId>org.mockito</groupId> + <artifactId>mockito-core</artifactId> + <version>${mockito.version}</version> + <scope>test</scope> + </dependency> + + <dependency> + <groupId>org.assertj</groupId> + <artifactId>assertj-core</artifactId> + <version>${assertj-core.version}</version> + <scope>test</scope> + </dependency> + + </dependencies> + + </dependencyManagement> + + + <!-- COMMON DEPENDENCIES FOR ALL SUB-PROJECTS --> + <dependencies> + <!-- TEST DEPENDENCIES --> + <dependency> + <groupId>junit</groupId> + <artifactId>junit</artifactId> + </dependency> + <dependency> + <groupId>org.mockito</groupId> + <artifactId>mockito-core</artifactId> + </dependency> + <dependency> + <groupId>org.assertj</groupId> + <artifactId>assertj-core</artifactId> + </dependency> + </dependencies> + + + <build> + + <pluginManagement> + + <plugins> + <!-- COMPILER PLUGIN --> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-compiler-plugin</artifactId> + <version>${compiler.plugin.version}</version> + <configuration> + <source>${compiler.target.version}</source> + <target>${compiler.source.version}</target> + </configuration> + </plugin> + + <!-- MAVEN SOURCE PLUGIN --> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-source-plugin</artifactId> + <version>${source.plugin.version}</version> + <configuration> + <excludeResources>true</excludeResources> + </configuration> + <executions> + <execution> + <id>attach-sources</id> + <phase>verify</phase> + <goals> + <goal>jar-no-fork</goal> + </goals> + </execution> + </executions> + </plugin> + + + <!-- MAVEN JAVADOC PLUGIN --> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-javadoc-plugin</artifactId> + <version>${javadoc.plugin.version}</version> + <configuration> + <!-- minimize console output messages --> + <quiet>true</quiet> + <verbose>false</verbose> + <useStandardDocletOptions>false</useStandardDocletOptions> + </configuration> + <executions> + <execution> + <id>aggregate</id> + <phase>site</phase> + <goals> + <goal>aggregate</goal> + </goals> + </execution> + <execution> + <id>attach-javadoc</id> + <goals> + <goal>jar</goal> + </goals> + </execution> + </executions> + </plugin> + + + <!-- SUREFIRE TEST PLUGIN --> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-surefire-plugin</artifactId> + <version>${surefire.plugin.version}</version> + <configuration> + <skipTests>${skip.unit.tests}</skipTests> + <argLine>-Xmx2048m -Djava.awt.headless=true -XX:+UseConcMarkSweepGC + -XX:OnOutOfMemoryError="kill -9 %p" -XX:+HeapDumpOnOutOfMemoryError + </argLine> + <redirectTestOutputToFile>${surefire.redirectTestOutputToFile}</redirectTestOutputToFile> + <parallel>methods</parallel> + <threadCount>8</threadCount> + <forkCount>8</forkCount> + <reuseForks>true</reuseForks> + <reportFormat>xml</reportFormat> + <trimStackTrace>false</trimStackTrace> + <systemPropertyVariables> + <java.io.tmpdir>${project.build.directory}</java.io.tmpdir> + <logback.configurationFile> + ${basedir}/src/test/resources/logback-test.xml + </logback.configurationFile> + </systemPropertyVariables> + <includes> + <include>${unit.test.pattern}</include> + </includes> + <excludes> + <exclude>${integration.test.pattern}</exclude> + </excludes> + <!-- Sets the VM argument line used when unit tests are run. --> + <argLine>${surefireArgLine}</argLine> + </configuration> + <dependencies> + <dependency> + <groupId>org.apache.maven.surefire</groupId> + <artifactId>surefire-junit47</artifactId> + <version>${surefire.plugin.version}</version> + </dependency> + </dependencies> + </plugin> + + <!-- FAIL SAFE PLUGIN FOR INTEGRATION TEST --> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-failsafe-plugin</artifactId> + <version>${failsafe.plugin.version}</version> + <executions> + <execution> + <id>integration-tests</id> + <goals> + <goal>integration-test</goal> + <goal>verify</goal> + </goals> + <configuration> + <skipTests>${skip.integration.tests}</skipTests> + <!-- Sets the VM argument line used when integration tests are run. --> + <!--suppress MavenModelInspection --> + <argLine>${failsafeArgLine}</argLine> + </configuration> + </execution> + </executions> + </plugin> + + + <!-- FIND BUGS (STATIC CODE ANALYSIS) PLUGIN --> + <plugin> + <groupId>org.codehaus.mojo</groupId> + <artifactId>findbugs-maven-plugin</artifactId> + <version>${findbugs.plugin.version}</version> + <configuration> + <effort>Max</effort> + <threshold>Low</threshold> + <xmlOutput>true</xmlOutput> + <!-- BUILD FAIL ON FINDBUGS ERRORS --> + <failOnError>${findbugs.failOnError}</failOnError> + <excludeFilterFile>${main.basedir}/findbugs-exclude.xml</excludeFilterFile> + <outputDirectory>${project.reporting.outputDirectory}/findbugs</outputDirectory> + <findbugsXmlOutputDirectory>${project.reporting.outputDirectory}/findbugs + </findbugsXmlOutputDirectory> + </configuration> + <executions> + <execution> + <id>analyze-compile</id> + <phase>compile</phase> + <goals> + <goal>check</goal> + </goals> + </execution> + </executions> + </plugin> + + <!-- PMD PLUGIN SETUP --> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-pmd-plugin</artifactId> + <version>${pmd.plugin.version}</version> + <configuration> + <sourceEncoding>${project.build.sourceEncoding}</sourceEncoding> + <targetJdk>${compiler.target.version}</targetJdk> + <linkXRef>false</linkXRef> + <!-- BUILD FAIL ON PMD VIOLATION --> + <failOnViolation>${pmd.violation.buildfail}</failOnViolation> + <targetDirectory>${project.reporting.outputDirectory}/pmd</targetDirectory> + <minimumTokens>200</minimumTokens> + </configuration> + <executions> + <execution> + <id>pmd-check</id> + <goals> + <goal>check</goal> + </goals> + <configuration> + <printFailingErrors>true</printFailingErrors> + <excludeFromFailureFile>${main.basedir}/pmd-exclude.properties</excludeFromFailureFile> + </configuration> + </execution> + <execution> + <id>cpd-check</id> + <goals> + <goal>cpd-check</goal> + </goals> + <configuration> + <printFailingErrors>true</printFailingErrors> + <excludeFromFailureFile>${main.basedir}/cpd-exclude.properties</excludeFromFailureFile> + </configuration> + </execution> + </executions> + </plugin> + + + + + <!-- LOMBOK PLUGIN --> + <plugin> + <groupId>org.projectlombok</groupId> + <artifactId>lombok-maven-plugin</artifactId> + <version>${lombok.plugin.version}</version> + <executions> + <execution> + <id>delombok</id> + <phase>generate-sources</phase> + <goals> + <goal>delombok</goal> + </goals> + <configuration> + <addOutputDirectory>false</addOutputDirectory> + <sourceDirectory>src/main/java</sourceDirectory> + </configuration> + </execution> + </executions> + </plugin> + + <!-- JAR PLUGIN --> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-jar-plugin</artifactId> + <version>${jar.plugin.version}</version> + <configuration> + <archive> + <manifest> + <addDefaultImplementationEntries>true</addDefaultImplementationEntries> + </manifest> + <manifestEntries> + <Implementation-Build-Version>${project.version}</Implementation-Build-Version> + </manifestEntries> + </archive> + </configuration> + </plugin> + + <!-- DEPLOY PLUGIN --> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-deploy-plugin</artifactId> + <version>${deploy.plugin.version}</version> + <configuration> + <deployAtEnd>true</deployAtEnd> + </configuration> + </plugin> + + </plugins> + + </pluginManagement> + + <plugins> + + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-compiler-plugin</artifactId> + </plugin> + + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-jar-plugin</artifactId> + </plugin> + + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-surefire-plugin</artifactId> + </plugin> + + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-failsafe-plugin</artifactId> + </plugin> + + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-deploy-plugin</artifactId> + </plugin> + + + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-source-plugin</artifactId> + </plugin> + + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-javadoc-plugin</artifactId> + </plugin> + + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-pmd-plugin</artifactId> + </plugin> + + <plugin> + <groupId>org.codehaus.mojo</groupId> + <artifactId>findbugs-maven-plugin</artifactId> + </plugin> + </plugins> + + </build> + + <profiles> + <profile> + <id>disable-java8-doclint</id> + <activation> + <jdk>[1.8,)</jdk> + </activation> + <properties> + <additionalparam>-Xdoclint:none</additionalparam> + </properties> + </profile> + </profiles> + +</project> diff --git a/eelf-logger/version.properties b/eelf-logger/version.properties new file mode 100644 index 0000000..907cdc4 --- /dev/null +++ b/eelf-logger/version.properties @@ -0,0 +1,25 @@ +# +# ================================================================================ +# Copyright (c) 2018 AT&T Intellectual Property. All rights reserved. +# ================================================================================ +# 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. +# ============LICENSE_END========================================================= +# +# + +major=1 +minor=0 +patch=0 +base_version=${major}.${minor}.${patch} +release_version=${base_version} +snapshot_version=${base_version}-SNAPSHOT diff --git a/mvn-phase-script.sh b/mvn-phase-script.sh index 5fa716a..7d432af 100755 --- a/mvn-phase-script.sh +++ b/mvn-phase-script.sh @@ -33,17 +33,10 @@ if [ -z "${MVN_NEXUSPROXY}" ]; then echo "MVN_NEXUSPROXY environment variable not set. Cannot proceed" exit 1 fi -if [ -z "$SETTINGS_FILE" ]; then - echo "SETTINGS_FILE environment variable not set. Cannot proceed" - exit 2 -fi +export SETTINGS_FILE=${SETTINGS_FILE:-$HOME/.m2/settings.xml} set +e -if ! wget -O ${PROJECT_ROOT}/mvn-phase-lib.sh \ - "$MVN_RAWREPO_BASEURL_DOWNLOAD"/org.onap.dcaegen2.utils/releases/scripts/mvn-phase-lib.sh; then - cp "${PROJECT_ROOT}"/scripts/mvn-phase-lib.sh "${PROJECT_ROOT}/mvn-phase-lib.sh" -fi -source "${PROJECT_ROOT}"/mvn-phase-lib.sh +source "${PROJECT_ROOT}"/scripts/mvn-phase-lib.sh # This is the base for where "deploy" will upload @@ -86,9 +79,12 @@ test) echo "==> test phase script" case $MVN_PROJECT_MODULEID in *) - set +e - run_tox_test - set -e + if [ -f tox.ini ] + then + set -e + run_tox_test + set +e + fi ;; esac ;; diff --git a/onap-dcae-cbs-docker-client/.coveragerc b/onap-dcae-cbs-docker-client/.coveragerc index 38c506c..c60c1ee 100644 --- a/onap-dcae-cbs-docker-client/.coveragerc +++ b/onap-dcae-cbs-docker-client/.coveragerc @@ -21,8 +21,3 @@ exclude_lines = # Don't complain if non-runnable code isn't run: if 0: if __name__ == .__main__.: - -[xml] -output = coverage-reports/coverage-configbinding.xml - - diff --git a/onap-dcae-cbs-docker-client/.gitignore b/onap-dcae-cbs-docker-client/.gitignore index c86ccf6..4f07413 100644 --- a/onap-dcae-cbs-docker-client/.gitignore +++ b/onap-dcae-cbs-docker-client/.gitignore @@ -1,3 +1,4 @@ +.pytest_cache/ xunit-results.xml .DS_Store # Byte-compiled / optimized / DLL files diff --git a/onap-dcae-cbs-docker-client/Changelog.md b/onap-dcae-cbs-docker-client/Changelog.md index 5027203..1269750 100644 --- a/onap-dcae-cbs-docker-client/Changelog.md +++ b/onap-dcae-cbs-docker-client/Changelog.md @@ -1,9 +1,23 @@ # Change Log All notable changes to this project will be documented in this file. -The format is based on [Keep a Changelog](http://keepachangelog.com/) +The format is based on [Keep a Changelog](http://keepachangelog.com/) and this project adheres to [Semantic Versioning](http://semver.org/). +## [1.0.2] +* Refactor some code, PEP8 compliance +* Add flake8 to tox + +## [1.0.1] +* [Sadly, Missing] + +## [1.0.0] +* Depend on the CBS 2.0.0 API +* Add new endpoint for getting all + +## [0.0.5] +* Dont pin requests version + ## [0.0.3] * Changelog started * Unit test suite created diff --git a/onap-dcae-cbs-docker-client/README.md b/onap-dcae-cbs-docker-client/README.md index 1e622a7..81a8ef0 100644 --- a/onap-dcae-cbs-docker-client/README.md +++ b/onap-dcae-cbs-docker-client/README.md @@ -1,11 +1,11 @@ # Python CBS Docker Client -Used for DCAE Dockerized microservices written in Python. Pulls your configuration from the config_binding_service. Expects that CONSUL_HOST and HOSTNAME are set as env variables, which is true in DCAE. +Used for DCAE Dockerized microservices written in Python. Pulls your configuration from the config_binding_service. Expects that CONSUL_HOST and HOSTNAME are set as env variables, which is true in DCAE. # Client Usage ## Development outside of Docker -To test your raw code without Docker, you will need to set the env variables CONSUL_HOST and HOSTNAME (name of your key to pull from) that are set in DCAEs Docker enviornment. +To test your raw code without Docker, you will need to set the env variables CONSUL_HOST and HOSTNAME (name of your key to pull from) that are set in DCAEs Docker enviornment. 1. `CONSUL_HOST` is the hostname only of the Consul instance you are talking to 2. HOSTNAME is the name of your component in Consul @@ -13,6 +13,7 @@ To test your raw code without Docker, you will need to set the env variables CON ``` >>> from onap_dcae_cbs_docker_client import client >>> client.get_config() +>>> client.get_all() ``` # Installation @@ -24,6 +25,6 @@ pip install onap-dcae-cbs-docker-client # Testing ``` -tox -c tox-local.ini +tox ``` diff --git a/onap-dcae-cbs-docker-client/onap_dcae_cbs_docker_client/__init__.py b/onap-dcae-cbs-docker-client/onap_dcae_cbs_docker_client/__init__.py index 9e81f65..e9d0246 100644 --- a/onap-dcae-cbs-docker-client/onap_dcae_cbs_docker_client/__init__.py +++ b/onap-dcae-cbs-docker-client/onap_dcae_cbs_docker_client/__init__.py @@ -1,6 +1,5 @@ -# org.onap.dcae # ================================================================================ -# Copyright (c) 2017 AT&T Intellectual Property. All rights reserved. +# Copyright (c) 2017-2018 AT&T Intellectual Property. All rights reserved. # ================================================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -16,4 +15,3 @@ # ============LICENSE_END========================================================= # # ECOMP is a trademark and service mark of AT&T Intellectual Property. - diff --git a/onap-dcae-cbs-docker-client/onap_dcae_cbs_docker_client/client.py b/onap-dcae-cbs-docker-client/onap_dcae_cbs_docker_client/client.py index ce9ac74..adcec85 100644 --- a/onap-dcae-cbs-docker-client/onap_dcae_cbs_docker_client/client.py +++ b/onap-dcae-cbs-docker-client/onap_dcae_cbs_docker_client/client.py @@ -1,6 +1,5 @@ -# org.onap.dcae # ================================================================================ -# Copyright (c) 2017 AT&T Intellectual Property. All rights reserved. +# Copyright (c) 2017-2018 AT&T Intellectual Property. All rights reserved. # ================================================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -18,39 +17,50 @@ # ECOMP is a trademark and service mark of AT&T Intellectual Property. import json -import requests import os import logging +import requests + +LOGGER = logging.getLogger().getChild(__name__) + + +class ENVsMissing(Exception): + """ + Exception to represent critical ENVs are missing + """ + pass + + +######### +# HELPERS -root = logging.getLogger() -logger = root.getChild(__name__) def _get_uri_from_consul(consul_url, name): """ Call consul's catalog - TODO: currently assumes there is only one service with this HOSTNAME + TODO: currently assumes there is only one service with this hostname """ url = "{0}/v1/catalog/service/{1}".format(consul_url, name) - logger.debug("Trying to lookup service: {0}".format(url)) + LOGGER.debug("Trying to lookup service: {0}".format(url)) res = requests.get(url) - try: - res.raise_for_status() - services = res.json() - return "http://{0}:{1}".format(services[0]["ServiceAddress"], services[0]["ServicePort"]) - except Exception as e: - logger.error("Exception occured when querying Consul: either could not hit {0} or no service registered. Error code: {1}, Error Text: {2}".format(url, res.status_code, res.text)) - return None + res.raise_for_status() + services = res.json() + return "http://{0}:{1}".format(services[0]["ServiceAddress"], services[0]["ServicePort"]) + def _get_envs(): """ - Returns HOSTNAME, CONSUL_HOST, CONFIG_BINDING_SERVICE or crashes for caller to deal with + Returns hostname, consul_host. + If the necessary ENVs are not found, this is fatal, and raises an exception. """ - HOSTNAME = os.environ["HOSTNAME"] - CONSUL_HOST = os.environ["CONSUL_HOST"] - return HOSTNAME, CONSUL_HOST + if "HOSTNAME" not in os.environ or "CONSUL_HOST" not in os.environ: + raise ENVsMissing("HOSTNAME or CONSUL_HOST missing") + hostname = os.environ["HOSTNAME"] + consul_host = os.environ["CONSUL_HOST"] + return hostname, consul_host -#Public -def get_config(): + +def _get_path(path): """ This call does not raise an exception if Consul or the CBS cannot complete the request. It logs an error and returns {} if the config is not bindable. @@ -62,24 +72,39 @@ def get_config(): config = {} - HOSTNAME, CONSUL_HOST = _get_envs() + hostname, consul_host = _get_envs() - #not sure how I as the component developer is supposed to know consul port - consul_url = "http://{0}:8500".format(CONSUL_HOST) + # not sure how I as the component developer is supposed to know consul port + consul_url = "http://{0}:8500".format(consul_host) - #get the CBS URL. Would not need the following hoorahrah if we had DNS. - cbs_url = _get_uri_from_consul(consul_url, "config_binding_service") - if cbs_url is None: - logger.error("Cannot bind config at this time, cbs is unreachable") - else: - #get my config - my_config_endpoint = "{0}/service_component/{1}".format(cbs_url, HOSTNAME) + try: + # get my config + cbs_url = _get_uri_from_consul(consul_url, "config_binding_service") + my_config_endpoint = "{0}/{1}/{2}".format(cbs_url, path, hostname) res = requests.get(my_config_endpoint) - try: - res.raise_for_status() - config = res.json() - logger.info("get_config returned the following configuration: {0}".format(json.dumps(config))) - except: - logger.error("in get_config, the config binding service endpoint {0} blew up on me. Error code: {1}, Error text: {2}".format(my_config_endpoint, res.status_code, res.text)) + + res.raise_for_status() + config = res.json() + LOGGER.info("get_config returned the following configuration: {0}".format( + json.dumps(config))) + except requests.exceptions.HTTPError as exc: + LOGGER.error("in get_config, the config binding service endpoint %s was not reachable. Error code: %d, Error text: %s", my_config_endpoint, res.status_code, res.text) + except Exception as exc: + LOGGER.exception(exc) return config + +######### +# Public +def get_all(): + """ + Hit the CBS service_component_all endpoint + """ + return _get_path("service_component_all") + + +def get_config(): + """ + Hit the CBS service_component endpoint + """ + return _get_path("service_component") diff --git a/onap-dcae-cbs-docker-client/pom.xml b/onap-dcae-cbs-docker-client/pom.xml index d334aae..d006a29 100644 --- a/onap-dcae-cbs-docker-client/pom.xml +++ b/onap-dcae-cbs-docker-client/pom.xml @@ -34,19 +34,13 @@ ECOMP is a trademark and service mark of AT&T Intellectual Property. <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <!-- Sonar --> - <sonar.skip>false</sonar.skip> <sonar.sources>.</sonar.sources> <sonar.junit.reportsPath>xunit-results.xml</sonar.junit.reportsPath> - <!-- - <sonar.python.coverage.reportPath>coverage.xml</sonar.python.coverage.reportPath> - see https://docs.sonarqube.org/display/PLUG/Python+Coverage+Results+Import - Ant pattern describing the path to coverage reports, relative to projects root. Leave unset to use the default ("coverage-reports/coverage-*.xml"). - --> + <sonar.python.coverage.reportPath>coverage.xml</sonar.python.coverage.reportPath> <sonar.language>py</sonar.language> <sonar.pluginName>Python</sonar.pluginName> <sonar.inclusions>**/*.py</sonar.inclusions> - <sonar.exclusions>tests/*</sonar.exclusions> - <sonar.host.url>http://135.205.228.63:9000</sonar.host.url> + <sonar.exclusions>tests/*,setup.py</sonar.exclusions> </properties> <build> <finalName>${project.artifactId}-${project.version}</finalName> diff --git a/onap-dcae-cbs-docker-client/requirements.txt b/onap-dcae-cbs-docker-client/requirements.txt deleted file mode 100644 index 856c82c..0000000 --- a/onap-dcae-cbs-docker-client/requirements.txt +++ /dev/null @@ -1 +0,0 @@ -requests==2.18.3 diff --git a/onap-dcae-cbs-docker-client/setup.py b/onap-dcae-cbs-docker-client/setup.py index 9f23048..b4fdf0e 100644 --- a/onap-dcae-cbs-docker-client/setup.py +++ b/onap-dcae-cbs-docker-client/setup.py @@ -1,6 +1,5 @@ -# org.onap.dcae # ================================================================================ -# Copyright (c) 2017 AT&T Intellectual Property. All rights reserved. +# Copyright (c) 2017-2018 AT&T Intellectual Property. All rights reserved. # ================================================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -17,23 +16,19 @@ # # ECOMP is a trademark and service mark of AT&T Intellectual Property. -import os from setuptools import setup, find_packages -from pip.req import parse_requirements -from pip.download import PipSession - -install_reqs = parse_requirements("requirements.txt", session=PipSession()) -reqs = [str(ir.req) for ir in install_reqs] setup( - name = "onap_dcae_cbs_docker_client", - description = "very lightweight client for a DCAE dockerized component to get it's config from the CBS", - version = "0.0.3", + name="onap_dcae_cbs_docker_client", + description="very lightweight client for a DCAE dockerized component to get it's config from the CBS", + version="1.0.2", packages=find_packages(), - author = "Tommy Carpenter", - author_email = "tommy@research.att.com", + author="Tommy Carpenter", + author_email="tommy@research.att.com", license='Apache 2', - keywords = "", - url = "", - install_requires=reqs + keywords="", + url="", + install_requires=[ + "requests>= 2.0.0, < 3.0.0" + ] ) diff --git a/onap-dcae-cbs-docker-client/tests/test_client.py b/onap-dcae-cbs-docker-client/tests/test_client.py index 6c9062b..dd6ab10 100644 --- a/onap-dcae-cbs-docker-client/tests/test_client.py +++ b/onap-dcae-cbs-docker-client/tests/test_client.py @@ -1,36 +1,63 @@ -from onap_dcae_cbs_docker_client.client import get_config -import requests +# ================================================================================ +# Copyright (c) 2017-2018 AT&T Intellectual Property. All rights reserved. +# ================================================================================ +# 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. +# ============LICENSE_END========================================================= +# +# ECOMP is a trademark and service mark of AT&T Intellectual Property. +from onap_dcae_cbs_docker_client.client import get_config, get_all + class FakeResponse: def __init__(self, status_code, thejson): self.status_code = status_code self.thejson = thejson + def raise_for_status(self): pass + def json(self): return self.thejson -def test_client(monkeypatch): - def monkeyed_requests_get(url): - #mock all the get calls for existent and non-existent - if url == "http://consuldotcom:8500/v1/catalog/service/config_binding_service": - return FakeResponse( - status_code = 200, - thejson = [ - {"ServiceAddress" : "666.666.666.666", - "ServicePort" : 8888 - }] - ) - elif url == "http://666.666.666.666:8888/service_component/mybestfrienddotcom": - return FakeResponse( - status_code = 200, - thejson = {"key_to_your_heart" : 666}) +def monkeyed_requests_get(url): + # mock all the get calls for existent and non-existent + if url == "http://consuldotcom:8500/v1/catalog/service/config_binding_service": + return FakeResponse(status_code=200, + thejson=[{"ServiceAddress": "666.666.666.666", + "ServicePort": 8888}]) + elif url == "http://666.666.666.666:8888/service_component_all/mybestfrienddotcom": + return FakeResponse(status_code=200, + thejson={"config": {"key_to_your_heart": 666}, + "dti": {"some amazing": "dti stuff"}, + "policies": {"event": {"foo": "bar"}, + "items": [{"foo2": "bar2"}]}, + "otherkey": {"foo3": "bar3"}}) - - monkeypatch.setattr('requests.get', monkeyed_requests_get) - assert(get_config() == {"key_to_your_heart" : 666}) + elif url == "http://666.666.666.666:8888/service_component/mybestfrienddotcom": + return FakeResponse(status_code=200, + thejson={"key_to_your_heart": 666}) +def test_config(monkeypatch): + monkeypatch.setattr('requests.get', monkeyed_requests_get) + assert(get_config() == {"key_to_your_heart": 666}) +def test_all(monkeypatch): + monkeypatch.setattr('requests.get', monkeyed_requests_get) + assert(get_all() == {"config": {"key_to_your_heart": 666}, + "dti": {"some amazing": "dti stuff"}, + "policies": {"event": {"foo": "bar"}, + "items": [{"foo2": "bar2"}]}, + "otherkey": {"foo3": "bar3"}}) diff --git a/onap-dcae-cbs-docker-client/tox-local.ini b/onap-dcae-cbs-docker-client/tox-local.ini index a5991a9..8e48932 100644 --- a/onap-dcae-cbs-docker-client/tox-local.ini +++ b/onap-dcae-cbs-docker-client/tox-local.ini @@ -1,15 +1,21 @@ [tox] -envlist = py27,py36 +envlist = py27,py36,flake8 [testenv] deps= - -rrequirements.txt pytest coverage pytest-cov -setenv = +setenv = CONSUL_HOST = consuldotcom HOSTNAME = mybestfrienddotcom commands=pytest --cov {envsitepackagesdir}/onap_dcae_cbs_docker_client --cov-report html +[testenv:flake8] +basepython = python3.6 +skip_install = true +deps = flake8 +commands = flake8 setup.py onap_dcae_cbs_docker_client tests +[flake8] +ignore = E501 diff --git a/onap-dcae-cbs-docker-client/tox.ini b/onap-dcae-cbs-docker-client/tox.ini index 9e57fc0..6bbe73f 100644 --- a/onap-dcae-cbs-docker-client/tox.ini +++ b/onap-dcae-cbs-docker-client/tox.ini @@ -1,15 +1,26 @@ # content of: tox.ini , put in same dir as setup.py [tox] -envlist = py27,py35 +envlist = py27,py36,flake8 [testenv] deps= - -rrequirements.txt pytest coverage pytest-cov setenv = CONSUL_HOST = consuldotcom HOSTNAME = mybestfrienddotcom + PYTHONPATH={toxinidir} -commands=pytest --junitxml xunit-results.xml --cov {envsitepackagesdir}/onap_dcae_cbs_docker_client --cov-report=xml +commands= + pytest --junitxml xunit-results.xml --cov onap_dcae_cbs_docker_client --cov-report xml + coverage xml + +[testenv:flake8] +basepython = python3.6 +skip_install = true +deps = flake8 +commands = flake8 setup.py onap_dcae_cbs_docker_client tests + +[flake8] +ignore = E501 diff --git a/onap-dcae-dcaepolicy-lib/.coveragerc b/onap-dcae-dcaepolicy-lib/.coveragerc index 26ed8ac..43c7005 100644 --- a/onap-dcae-dcaepolicy-lib/.coveragerc +++ b/onap-dcae-dcaepolicy-lib/.coveragerc @@ -23,7 +23,3 @@ exclude_lines = if __name__ == .__main__.: ignore_errors = True - -[xml] -output = coverage-reports/coverage-onap_dcae_dcaepolicy_lib.xml - diff --git a/onap-dcae-dcaepolicy-lib/LICENSE.txt b/onap-dcae-dcaepolicy-lib/LICENSE.txt index 45ec201..0b6ac42 100644 --- a/onap-dcae-dcaepolicy-lib/LICENSE.txt +++ b/onap-dcae-dcaepolicy-lib/LICENSE.txt @@ -1,7 +1,5 @@ ============LICENSE_START======================================================= -org.onap.dcae -================================================================================ -Copyright (c) 2017 AT&T Intellectual Property. All rights reserved. +Copyright (c) 2017-2018 AT&T Intellectual Property. All rights reserved. ================================================================================ Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/onap-dcae-dcaepolicy-lib/README.md b/onap-dcae-dcaepolicy-lib/README.md index ff37256..b46f0b1 100644 --- a/onap-dcae-dcaepolicy-lib/README.md +++ b/onap-dcae-dcaepolicy-lib/README.md @@ -1,4 +1,5 @@ # onap-dcae-dcaepolicy-lib - policy in dcae controller + - python-package to be used in cloudify plugins to maintain the policies lifecycle ## upload the python package to pypi server @@ -8,23 +9,26 @@ python setup.py sdist upload ``` --- -# usage in plugins -**requirements.txt** +## usage in plugins + +### **requirements.txt** + ```python onap-dcae-dcaepolicy-lib==1.0.0 ``` -**tasks.py** -- import +### **tasks.py** + +import ```python from onap_dcae_dcaepolicy_lib import Policies ``` -# examples of **@operation** with **@Policies.<>** decorator +### examples of **@operation** with **@Policies.<>** decorator -## Usage +### Usage: import the dcaepolicy-node-type.yaml into your blueprint to use the dcae.nodes.type node @@ -46,9 +50,12 @@ node_templates: Then the dcaepolicyplugin will bring the latest policy to the dcae.nodes.policy node during the install workflow of cloudify. ------- -## cloudify.interfaces.lifecycle.**configure** +--- + +### cloudify.interfaces.lifecycle.**configure** + - gather policy data into runtime_properties of policy consumer node + ```yaml cloudify.interfaces.lifecycle: configure: @@ -64,23 +71,15 @@ APPLICATION_CONFIG = "application_config" SERVICE_COMPONENT_NAME = "service_component_name" @operation -@Policies.gather_policies_to_node +@Policies.gather_policies_to_node() def node_configure(**kwargs): - """decorate with @Policies.gather_policies_to_node on policy consumer node to + """decorate with @Policies.gather_policies_to_node() on policy consumer node to prepopulate runtime_properties[POLICIES] """ - app_config = None - if APPLICATION_CONFIG in ctx.node.properties: - # dockerized blueprint puts the app config into property application_config - app_config = ctx.node.properties.get(APPLICATION_CONFIG) - else: - # CDAP components expect that in property app_config - app_config = ctx.node.properties.get("app_config") - - app_config = Policies.shallow_merge_policies_into(app_config) + app_config = ctx.node.properties.get(APPLICATION_CONFIG) + ctx.instance.runtime_properties[APPLICATION_CONFIG] = app_config - ctx.logger.info("example: applied policy_configs to property app_config: {0}" \ - .format(json.dumps(app_config))) + ctx.logger.info("app_config: {0}".format(json.dumps(app_config))) if SERVICE_COMPONENT_NAME in ctx.instance.runtime_properties: ctx.logger.info("saving app_config({0}) to consul under key={1}" \ @@ -88,16 +87,6 @@ def node_configure(**kwargs): ctx.instance.runtime_properties[SERVICE_COMPONENT_NAME])) DiscoveryClient.put_kv(ctx.instance.runtime_properties[SERVICE_COMPONENT_NAME], app_config) - # alternative 1 - use the list of policy configs from policies in runtime_properties - policy_configs = Policies.get_policy_configs() - if policy_configs: - ctx.logger.warn("TBD: apply policy_configs: {0}".format(json.dumps(policy_configs))) - - # alternative 2 - use the policies dict by policy_id from runtime_properties - if POLICIES in ctx.instance.runtime_properties: - policies = ctx.instance.runtime_properties[POLICIES] - ctx.logger.warn("TBD: apply policies: {0}".format(json.dumps(policies))) - ctx.logger.info("deploying the demo component: {0}...".format(ctx.node.id)) demo_app = DemoApp(ctx.node.id) demo_app.start() @@ -105,8 +94,10 @@ def node_configure(**kwargs): demo_app.get_logs() ``` ------- -## execute-operation **policy-update** +--- + +### execute-operation **policy-update** + ```yaml dcae.interfaces.policy: policy_update: @@ -114,6 +105,7 @@ dcae.interfaces.policy: ``` execute-operation **policy-update** that gets a list of changed policy-configs + ```python from .discovery import DiscoveryClient @@ -123,25 +115,13 @@ APPLICATION_CONFIG = "application_config" SERVICE_COMPONENT_NAME = "service_component_name" @operation -@Policies.update_policies_on_node(configs_only=True) -def policy_update(updated_policies, **kwargs): +@Policies.update_policies_on_node() +def policy_update(updated_policies, removed_policies=None, policies=None, **kwargs): """decorate with @Policies.update_policies_on_node() to update runtime_properties[POLICIES] :updated_policies: contains the list of changed policy-configs when configs_only=True (default). Use configs_only=False to bring the full policy objects in :updated_policies:. """ - app_config = DiscoveryClient.get_value(ctx.instance.runtime_properties[SERVICE_COMPONENT_NAME]) - - # This is how to merge the policies into app_config object - app_config = Policies.shallow_merge_policies_into(app_config) - - ctx.logger.info("merged updated_policies {0} into app_config {1}" - .format(json.dumps(updated_policies), json.dumps(app_config))) - - ctx.instance.runtime_properties[APPLICATION_CONFIG] = app_config - - DiscoveryClient.put_kv(ctx.instance.runtime_properties[SERVICE_COMPONENT_NAME], app_config) - # example how to notify the dockerized component about the policy change notify_app_through_script = True if notify_app_through_script: @@ -149,24 +129,29 @@ def policy_update(updated_policies, **kwargs): .format(json.dumps(updated_policies), json.dumps(app_config))) demo_app = DemoApp(ctx.node.id) demo_app.notify_app_through_script( - POLICY_MESSAGE_TYPE, + "policies", updated_policies=updated_policies, - application_config=app_config + removed_policies=removed_policies, + policies=policies ) ``` example of the **changed\_policies** with **configs_only=True** + - list of config objects (preparsed from json string) + - manual mess produced by mock_policy_updater + ```json [{ - "policy_updated_from_ver": "2", - "policy_updated_to_ver": "3", - "updated_policy_id": "DCAE_alex.Config_db_client_policy_id_value", - "policy_hello": "world!", - "policy_updated_ts": "2017-08-17T21:49:39.279187Z" + "policy_updated_from_ver": "2", + "policy_updated_to_ver": "3", + "updated_policy_id": "DCAE_alex.Config_db_client_policy_id_value", + "policy_hello": "world!", + "policy_updated_ts": "2017-08-17T21:49:39.279187Z" }] ``` + --- example of **policies** in runtime_properties **before policy-update** diff --git a/onap-dcae-dcaepolicy-lib/onap_dcae_dcaepolicy_lib/__init__.py b/onap-dcae-dcaepolicy-lib/onap_dcae_dcaepolicy_lib/__init__.py index b3658b1..f8a2498 100644 --- a/onap-dcae-dcaepolicy-lib/onap_dcae_dcaepolicy_lib/__init__.py +++ b/onap-dcae-dcaepolicy-lib/onap_dcae_dcaepolicy_lib/__init__.py @@ -1,8 +1,5 @@ -"""expose the Policies class on the package level""" - -# org.onap.dcae # ================================================================================ -# Copyright (c) 2017 AT&T Intellectual Property. All rights reserved. +# Copyright (c) 2017-2018 AT&T Intellectual Property. All rights reserved. # ================================================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -19,4 +16,6 @@ # # ECOMP is a trademark and service mark of AT&T Intellectual Property. -from .dcae_policy import Policies, POLICIES, POLICY_MESSAGE_TYPE +"""expose the Policies class on the package level""" + +from .dcae_policy import Policies diff --git a/onap-dcae-dcaepolicy-lib/onap_dcae_dcaepolicy_lib/dcae_policy.py b/onap-dcae-dcaepolicy-lib/onap_dcae_dcaepolicy_lib/dcae_policy.py index 6a277f3..65c2614 100644 --- a/onap-dcae-dcaepolicy-lib/onap_dcae_dcaepolicy_lib/dcae_policy.py +++ b/onap-dcae-dcaepolicy-lib/onap_dcae_dcaepolicy_lib/dcae_policy.py @@ -1,8 +1,5 @@ -"""dcae_policy contains decorators for the policy lifecycle in cloudify""" - -# org.onap.dcae # ================================================================================ -# Copyright (c) 2017 AT&T Intellectual Property. All rights reserved. +# Copyright (c) 2017-2018 AT&T Intellectual Property. All rights reserved. # ================================================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -19,124 +16,293 @@ # # ECOMP is a trademark and service mark of AT&T Intellectual Property. +"""dcae_policy contains decorators for the policy lifecycle in cloudify""" + import json -import copy +import traceback +from copy import deepcopy from functools import wraps from cloudify import ctx from cloudify.context import NODE_INSTANCE from cloudify.exceptions import NonRecoverableError +from .policies_output import PoliciesOutput + POLICIES = 'policies' +POLICY_FILTERS = 'policy_filters' +POLICIES_FILTERED = 'policies_filtered' POLICY_ID = 'policy_id' POLICY_BODY = 'policy_body' POLICY_VERSION = "policyVersion" POLICY_CONFIG = 'config' + +POLICY_FILTER = 'policy_filter' +POLICY_FILTER_ID = 'policy_filter_id' + +POLICY_PERSISTENT = 'policy_persistent' DCAE_POLICY_TYPE = 'dcae.nodes.policy' -POLICY_MESSAGE_TYPE = 'policy' +DCAE_POLICIES_TYPE = 'dcae.nodes.policies' + +ACTION_GATHERED = "gathered" +ACTION_UPDATED = "updated" + +CONFIG_ATTRIBUTES = "configAttributes" class Policies(object): """static class for policy operations""" + _updated_policies = {} + _removed_policies = {} @staticmethod - def gather_policies_to_node(func): - """decorate with @Policies.gather_policies_to_node to - gather the policies from dcae.nodes.policy nodes this node depends on. + def _init(): + """init static members""" + Policies._updated_policies = {} + Policies._removed_policies = {} - Places the policies into runtime_properties["policies"]. + @staticmethod + def _set_policies(policies): + """store the :policies: in :runtime_properties[POLICIES]:""" + if not policies: + if POLICIES in ctx.instance.runtime_properties: + del ctx.instance.runtime_properties[POLICIES] + return - Call Policies.shallow_merge_policies_into(config) to merge the policies into config. - """ - def _merge_policy_with_node(target): - """get all properties of the policy node and add the actual policy""" - policy = dict(target.node.properties) - if POLICY_BODY in target.instance.runtime_properties: - policy[POLICY_BODY] = target.instance.runtime_properties[POLICY_BODY] - return policy + ctx.instance.runtime_properties[POLICIES] = policies - if not func: + @staticmethod + def _add_policy(policy_id, policy, policy_persistent, policies): + """only add the latest version of policy to policies""" + prev_policy = policies.get(policy_id) + prev_policy_persistent = (prev_policy or {}).get(POLICY_PERSISTENT) + + if not prev_policy \ + or (policy_persistent and not prev_policy_persistent) \ + or (policy_persistent == prev_policy_persistent and policy.get(POLICY_BODY)): + policy = deepcopy(policy) + policy[POLICY_PERSISTENT] = policy_persistent + policies[policy_id] = policy + + @staticmethod + def _gather_policy(target, policies): + """adds the policy from dcae.nodes.policy node to policies""" + if DCAE_POLICY_TYPE not in target.node.type_hierarchy: return + policy_id = target.node.properties.get(POLICY_ID) + if not policy_id: + return True + policy = deepcopy(dict(target.node.properties)) + policy_body = target.instance.runtime_properties.get(POLICY_BODY) + if policy_body: + policy[POLICY_BODY] = policy_body - @wraps(func) - def wrapper(*args, **kwargs): - """gather and save the policies from dcae.nodes.policy nodes this node related to""" + Policies._add_policy(policy_id, policy, True, policies) + return True + + @staticmethod + def _fix_policy_filter(policy_filter): + if CONFIG_ATTRIBUTES in policy_filter: + config_attributes = policy_filter.get(CONFIG_ATTRIBUTES) + if isinstance(config_attributes, dict): + return try: - if ctx.type == NODE_INSTANCE: - policies = dict([(rel.target.node.properties[POLICY_ID], \ - _merge_policy_with_node(rel.target)) \ - for rel in ctx.instance.relationships \ - if DCAE_POLICY_TYPE in rel.target.node.type_hierarchy \ - and POLICY_ID in rel.target.node.properties \ - and rel.target.node.properties[POLICY_ID] \ - ]) - if policies: - ctx.instance.runtime_properties[POLICIES] = policies - except Exception as ex: - error = "Failed to set the policies {0}".format(str(ex)) - ctx.logger.error(error) - raise NonRecoverableError(error) - - return func(*args, **kwargs) - return wrapper + config_attributes = json.loads(config_attributes) + if config_attributes and isinstance(config_attributes, dict): + policy_filter[CONFIG_ATTRIBUTES] = config_attributes + return + except (ValueError, TypeError): + pass + if config_attributes: + ctx.logger.warn("unexpected %s: %s", CONFIG_ATTRIBUTES, config_attributes) + del policy_filter[CONFIG_ATTRIBUTES] @staticmethod - def _update_policies_on_ctx(updated_policies): - """update policies in runtime_properties and return changed_policies""" - if POLICIES not in ctx.instance.runtime_properties: + def _gather_policies(target, policies, policy_filters): + """adds the policies and policy-filter from dcae.nodes.policies node to policies""" + if DCAE_POLICIES_TYPE not in target.node.type_hierarchy: return - if not updated_policies: - ctx.logger.error("update_policies_on_ctx - no updated_policies provided in arguments") + + property_policy_filter = target.node.properties.get(POLICY_FILTER) + if property_policy_filter: + policy_filter = deepcopy(dict( + (k, v) for (k, v) in dict(property_policy_filter).iteritems() + if v or isinstance(v, (int, float)) + )) + Policies._fix_policy_filter(policy_filter) + + if policy_filter: + policy_filters[target.instance.id] = { + POLICY_FILTER_ID : target.instance.id, + POLICY_FILTER : policy_filter + } + + filtered_policies = target.instance.runtime_properties.get(POLICIES_FILTERED) + if not filtered_policies or not isinstance(filtered_policies, dict): + return True + for (policy_id, policy) in filtered_policies.iteritems(): + Policies._add_policy(policy_id, policy, False, policies) + return True + + @staticmethod + def _get_policy_bodies_dict(policies): + """returns a dict of policy_id -> policy_body if policy_body exists""" + if not policies: + return {} + + return dict((policy_id, policy.get(POLICY_BODY)) + for policy_id, policy in policies.iteritems() if policy.get(POLICY_BODY) + ) + + @staticmethod + def gather_policies_to_node(): + """ + decorate with @Policies.gather_policies_to_node() to + gather the policies from dcae.nodes.policy nodes this node depends on. + + Places the policies into runtime_properties["policies"]. + + Stores <scn>:policies data in consul-kv + """ + def gather_policies_decorator(func): + """the decorator""" + if not func: + return + + @wraps(func) + def wrapper(*args, **kwargs): + """gather and save the policies from dcae.nodes.policy nodes this node related to""" + if ctx.type != NODE_INSTANCE: + raise NonRecoverableError("can only invoke gather_policies_to_node on node") + + policies_outputted = False + policy_bodies = [] + try: + policies = {} + policy_filters = {} + for rel in ctx.instance.relationships: + _ = Policies._gather_policy(rel.target, policies) \ + or Policies._gather_policies(rel.target, policies, policy_filters) + + Policies._set_policies(policies) + if policy_filters: + ctx.instance.runtime_properties[POLICY_FILTERS] = policy_filters + + policy_bodies = Policies._get_policy_bodies_dict(policies) + if policy_bodies: + policies_outputted = PoliciesOutput.store_policies(ACTION_GATHERED, policy_bodies) + except Exception as ex: + error = "Failed to set the policies {0}".format(str(ex)) + ctx.logger.error("{0}: {1}".format(error, traceback.format_exc())) + raise NonRecoverableError(error) + + func_result = func(*args, **kwargs) + + if not policies_outputted and policy_bodies: + PoliciesOutput.store_policies(ACTION_GATHERED, policy_bodies) + + return func_result + return wrapper + return gather_policies_decorator + + @staticmethod + def _update_policies(updated_policies, added_policies, removed_policies): + """ + filter and update policies in runtime_properties + and return the ordered filtered list of changed_policies + """ + Policies._init() + + if not updated_policies and not removed_policies and not added_policies: + ctx.logger.error("update_policies_on_ctx - no updated, added, or removed policies received") return - policies = ctx.instance.runtime_properties[POLICIES] - ctx.logger.info("update_policies_on_ctx: {0}".format(json.dumps(updated_policies))) - changed_policies = [] - ignored_policies = [] - unexpected_policies = [] - same_policies = [] + updated_policies = updated_policies or [] + added_policies = added_policies or {} + removed_policies = removed_policies or [] + + ctx.logger.info("updated_policies: {0}, added_policies: {1}, removed_policies: {2}" + .format(json.dumps(updated_policies), + json.dumps(added_policies), + json.dumps(removed_policies))) + + policies = ctx.instance.runtime_properties.get(POLICIES, {}) + policy_filters = ctx.instance.runtime_properties.get(POLICY_FILTERS, {}) + + for policy_id in removed_policies: + removed_policy = policies.get(policy_id) + if removed_policy and POLICY_BODY in removed_policy: + Policies._removed_policies[policy_id] = deepcopy(removed_policy) + if removed_policy.get(POLICY_PERSISTENT): + del policies[policy_id][POLICY_BODY] + else: + del policies[policy_id] + + new_policies = dict((policy_id, policy) + for policy_filter_id in policy_filters + for (policy_id, policy) in added_policies.get(policy_filter_id, {}) + .get(POLICIES, {}).iteritems()) + + ctx.logger.info("new_policies: {0}".format(json.dumps(new_policies))) + + for (policy_id, policy) in new_policies.iteritems(): + deployed_policy = policies.get(policy_id) + if not deployed_policy: + policies[policy_id] = policy + Policies._updated_policies[policy_id] = policy + continue + updated_policies.append(policy) + + skipped = {"ignored": [], "unexpected": [], "same": [], "duplicate": []} for policy in updated_policies: - if POLICY_ID not in policy or policy[POLICY_ID] not in policies: - ignored_policies.append(policy) + policy_id = policy.get(POLICY_ID) + if not policy_id or policy_id not in policies: + skipped["ignored"].append(policy) + continue + + if policy_id in Policies._updated_policies: + skipped["duplicate"].append(policy) + continue + + updated_policy_body = policy.get(POLICY_BODY, {}) + updated_policy_version = updated_policy_body.get(POLICY_VERSION) + if not updated_policy_version or POLICY_CONFIG not in updated_policy_body: + skipped["unexpected"].append(policy) continue - if POLICY_BODY not in policy or POLICY_VERSION not in policy[POLICY_BODY] \ - or not policy[POLICY_BODY][POLICY_VERSION]: - unexpected_policies.append(policy) + + deployed_policy = policies.get(policy_id) + deployed_policy_version = deployed_policy.get(POLICY_BODY, {}).get(POLICY_VERSION) + if updated_policy_version == deployed_policy_version: + skipped["same"].append(policy) continue - deployed_policy = policies[policy[POLICY_ID]].get(POLICY_BODY, {}) - new_policy_body = policy[POLICY_BODY] - if not deployed_policy or POLICY_VERSION not in deployed_policy \ - or not deployed_policy[POLICY_VERSION] \ - or deployed_policy[POLICY_VERSION] != new_policy_body[POLICY_VERSION]: - policies[policy[POLICY_ID]][POLICY_BODY] = new_policy_body - changed_policies.append(dict(policies[policy[POLICY_ID]])) - else: - same_policies.append(policy) - - if same_policies: - ctx.logger.info("same policies: {0}".format(json.dumps(same_policies))) - if ignored_policies: - ctx.logger.info("ignored policies: {0}".format(json.dumps(ignored_policies))) - if unexpected_policies: - ctx.logger.warn("unexpected policies: {0}".format(json.dumps(unexpected_policies))) - - if changed_policies: - ctx.instance.runtime_properties[POLICIES] = policies - return changed_policies + policies[policy_id][POLICY_BODY] = updated_policy_body + Policies._updated_policies[policy_id] = policy + + if skipped["same"] or skipped["ignored"] or skipped["unexpected"] or skipped["duplicate"]: + ctx.logger.info("skipped updates on policies: {0}".format(json.dumps(skipped))) + + if Policies._updated_policies or Policies._removed_policies: + Policies._set_policies(policies) + policy_bodies = Policies._get_policy_bodies_dict(policies) + PoliciesOutput.store_policies(ACTION_UPDATED, policy_bodies) @staticmethod - def update_policies_on_node(configs_only=True): - """decorate each policy_update operation with @Policies.update_policies_on_node to + def update_policies_on_node(): + """ + decorate each policy_update operation with @Policies.update_policies_on_node() to filter out the updated_policies to only what applies to the current node instance, update runtime_properties["policies"] - :configs_only: - set to True if expect to see only the config in updated_policies - instead of the whole policy object (False) + updates <scn>:policies data in consul-kv Passes through the filtered list of updated_policies that apply to the current node instance - :updated_policies: contains the list of changed policy-configs when configs_only=True. + :updated_policies: contains the list of changed policy_bodies + + :removed_policies: contains the list of removed policy_bodies + + :policies: contains the list of current policy_bodies """ def update_policies_decorator(func): """actual decorator""" @@ -144,56 +310,64 @@ class Policies(object): return @wraps(func) - def wrapper(updated_policies, **kwargs): - """update matching policies on context""" + def wrapper(updated_policies=None, added_policies=None, removed_policies=None, **kwargs): + """update matching policies on the node""" if ctx.type != NODE_INSTANCE: - return + raise NonRecoverableError("can only invoke update_policies_on_node on node") + + try: + Policies._update_policies(updated_policies, added_policies, removed_policies) + + updated_policies = Policies.get_policy_bodies( + selected_policies=Policies._updated_policies + ) - updated_policies = Policies._update_policies_on_ctx(updated_policies) - if updated_policies: - if configs_only: - updated_policies = [policy[POLICY_BODY][POLICY_CONFIG] \ - for policy in updated_policies \ - if POLICY_BODY in policy \ - and POLICY_CONFIG in policy[POLICY_BODY] \ - ] - return func(updated_policies, **kwargs) + removed_policies = Policies.get_policy_bodies( + selected_policies=Policies._removed_policies + ) + + except Exception as ex: + error = "Failed to update the policies {0}".format(str(ex)) + ctx.logger.error("{0}: {1}".format(error, traceback.format_exc())) + raise NonRecoverableError(error) + + if updated_policies or removed_policies: + return func(updated_policies, + removed_policies=removed_policies, + policies=Policies.get_policy_bodies(), + **kwargs) return wrapper return update_policies_decorator - @staticmethod - def get_policy_configs(): - """returns the list of policy configs from the runtime policies""" - if ctx.type != NODE_INSTANCE \ - or POLICIES not in ctx.instance.runtime_properties: - return - policies = ctx.instance.runtime_properties[POLICIES] - if not policies: + def cleanup_policies_on_node(func): + """ + decorate each delete operation with @Policies.cleanup_policies_on_node to + remove <scn>:policies data in consul-kv + """ + if not func: return - policy_configs = [policies[policy_id][POLICY_BODY][POLICY_CONFIG] \ - for policy_id in policies \ - if POLICY_BODY in policies[policy_id] \ - and POLICY_CONFIG in policies[policy_id][POLICY_BODY] \ - ] - return policy_configs - @staticmethod - def shallow_merge_policies_into(config): - """shallow merge the policy configs (dict) into config that is expected to be a dict""" - if config is None: - config = {} - policy_configs = Policies.get_policy_configs() - if not policy_configs or not isinstance(config, dict): - return config - - for policy_config in copy.deepcopy(policy_configs): - if not isinstance(policy_config, dict): - continue + @wraps(func) + def wrapper(**kwargs): + """remove policies in consul-kv""" + if ctx.type == NODE_INSTANCE: + try: + PoliciesOutput.delete_policies() + except Exception as ex: + error = "Failed to cleanup policies in consul-kv {0}".format(str(ex)) + ctx.logger.error("{0}: {1}".format(error, traceback.format_exc())) - config.update(policy_config) - for cfg_item in policy_config: - if policy_config[cfg_item] is None: - config.pop(cfg_item, None) + return func(**kwargs) + return wrapper + + @staticmethod + def get_policy_bodies(selected_policies=None): + """returns the list of policy_body objects if policy_body exists""" + if isinstance(selected_policies, dict): + return deepcopy([policy.get(POLICY_BODY) + for policy in selected_policies.values() if policy.get(POLICY_BODY)]) - return config + policies = ctx.instance.runtime_properties.get(POLICIES, {}) + return deepcopy([policy.get(POLICY_BODY) + for policy in policies.values() if policy.get(POLICY_BODY)]) diff --git a/onap-dcae-dcaepolicy-lib/onap_dcae_dcaepolicy_lib/policies_output.py b/onap-dcae-dcaepolicy-lib/onap_dcae_dcaepolicy_lib/policies_output.py new file mode 100644 index 0000000..d8125c0 --- /dev/null +++ b/onap-dcae-dcaepolicy-lib/onap_dcae_dcaepolicy_lib/policies_output.py @@ -0,0 +1,148 @@ +# ================================================================================ +# Copyright (c) 2018 AT&T Intellectual Property. All rights reserved. +# ================================================================================ +# 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. +# ============LICENSE_END========================================================= +# +# ECOMP is a trademark and service mark of AT&T Intellectual Property. + +"""client to talk to consul on standard port 8500""" + +import base64 +import json +import urllib +import uuid +from datetime import datetime + +import requests +from cloudify import ctx + + +class PoliciesOutput(object): + """static class for store-delete policies in consul kv""" + # it is safe to assume that consul agent is at consul:8500 + # define consul alis in /etc/hosts on cloudify manager vm + # $ cat /etc/hosts + # 127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4 consul + CONSUL_TRANSACTION_URL = "http://consul:8500/v1/txn" + + POLICIES_EVENT = 'policies_event' + + POLICIES_FOLDER_MASK = "{0}:policies/{1}" + MAX_OPS_PER_TXN = 64 + + OPERATION_SET = "set" + OPERATION_DELETE = "delete" + OPERATION_DELETE_FOLDER = "delete-tree" + SERVICE_COMPONENT_NAME = "service_component_name" + + + @staticmethod + def _gen_txn_operation(verb, service_component_name, key=None, value=None): + """returns the properly formatted operation to be used inside transaction""" + key = PoliciesOutput.POLICIES_FOLDER_MASK.format( + service_component_name, urllib.quote(key or "") + ) + if value: + return {"KV": {"Verb": verb, "Key": key, "Value": base64.b64encode(value)}} + return {"KV": {"Verb": verb, "Key": key}} + + + @staticmethod + def _run_transaction(operation_name, txn): + """run a single transaction of several operations at consul /txn""" + if not txn: + return None + + response = None + try: + response = requests.put(PoliciesOutput.CONSUL_TRANSACTION_URL, json=txn) + except requests.exceptions.RequestException as ex: + ctx.logger.error( + "RequestException - failed to {0} at {1}: {2} on txn={3}" + .format(operation_name, PoliciesOutput.CONSUL_TRANSACTION_URL, + str(ex), json.dumps(txn))) + return None + + if response.status_code != requests.codes.ok: + ctx.logger.error( + "failed {0} for {1} {2}: text={3} txn={4}" + .format(response.status_code, operation_name, + PoliciesOutput.CONSUL_TRANSACTION_URL, response.text, json.dumps(txn))) + return None + ctx.logger.info( + "response {0} for {1} {2}: text={3} txn={4}" + .format(response.status_code, operation_name, + PoliciesOutput.CONSUL_TRANSACTION_URL, response.text, json.dumps(txn))) + return True + + + @staticmethod + def store_policies(action, policy_bodies): + """put the policy_bodies for service_component_name into consul-kv""" + service_component_name = ctx.instance.runtime_properties.get( + PoliciesOutput.SERVICE_COMPONENT_NAME + ) + if not service_component_name: + ctx.logger.warn("failed to find service_component_name to store_policies in consul-kv") + return False + + event = { + "action": action, + "timestamp": (datetime.utcnow().isoformat()[:-3] + 'Z'), + "update_id": str(uuid.uuid4()), + "policies_count": len(policy_bodies) + } + ctx.instance.runtime_properties[PoliciesOutput.POLICIES_EVENT] = event + + store_policies = [ + PoliciesOutput._gen_txn_operation(PoliciesOutput.OPERATION_SET, service_component_name, + "items/" + policy_id, json.dumps(policy_body)) + for policy_id, policy_body in policy_bodies.iteritems() + ] + txn = [ + PoliciesOutput._gen_txn_operation( + PoliciesOutput.OPERATION_DELETE_FOLDER, service_component_name), + PoliciesOutput._gen_txn_operation( + PoliciesOutput.OPERATION_SET, service_component_name, "event", json.dumps(event)) + ] + idx_step = PoliciesOutput.MAX_OPS_PER_TXN - len(txn) + for idx in xrange(0, len(store_policies), idx_step): + txn += store_policies[idx : idx + idx_step] + if not PoliciesOutput._run_transaction("store_policies", txn): + return False + txn = [] + + PoliciesOutput._run_transaction("store_policies", txn) + return True + + + @staticmethod + def delete_policies(): + """delete policies for service_component_name in consul-kv""" + if PoliciesOutput.POLICIES_EVENT not in ctx.instance.runtime_properties: + return + + service_component_name = ctx.instance.runtime_properties.get( + PoliciesOutput.SERVICE_COMPONENT_NAME + ) + if not service_component_name: + ctx.logger.warn("failed to find service_component_name to delete_policies in consul-kv") + return + + delete_policies = [ + PoliciesOutput._gen_txn_operation( + PoliciesOutput.OPERATION_DELETE_FOLDER, service_component_name + ) + ] + PoliciesOutput._run_transaction("delete_policies", delete_policies) diff --git a/onap-dcae-dcaepolicy-lib/pom.xml b/onap-dcae-dcaepolicy-lib/pom.xml index d4a7a74..b7ae319 100644 --- a/onap-dcae-dcaepolicy-lib/pom.xml +++ b/onap-dcae-dcaepolicy-lib/pom.xml @@ -1,7 +1,7 @@ <?xml version="1.0"?> <!-- ================================================================================ -Copyright (c) 2017 AT&T Intellectual Property. All rights reserved. +Copyright (c) 2017-2018 AT&T Intellectual Property. All rights reserved. ================================================================================ Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -28,7 +28,7 @@ ECOMP is a trademark and service mark of AT&T Intellectual Property. <groupId>org.onap.dcaegen2.utils</groupId> <artifactId>onap-dcae-dcaepolicy-lib</artifactId> <name>dcaegen2-utils-onap-dcae-dcaepolicy-lib</name> - <version>1.1.0-SNAPSHOT</version> + <version>2.4.0-SNAPSHOT</version> <url>http://maven.apache.org</url> <properties> @@ -38,9 +38,12 @@ ECOMP is a trademark and service mark of AT&T Intellectual Property. <!-- sonar.host.url>http://localhost:9000</sonar.host.url --> <!-- below are language dependent --> <!-- for Python --> + <sonar.junit.reportsPath>xunit-results.xml</sonar.junit.reportsPath> + <sonar.python.coverage.reportPath>coverage.xml</sonar.python.coverage.reportPath> <sonar.language>py</sonar.language> <sonar.pluginName>Python</sonar.pluginName> <sonar.inclusions>**/*.py</sonar.inclusions> + <sonar.exclusions>tests/*,setup.py</sonar.exclusions> <!-- for JavaScaript --> <!-- <sonar.language>js</sonar.language> diff --git a/onap-dcae-dcaepolicy-lib/setup.py b/onap-dcae-dcaepolicy-lib/setup.py index 7a4e71a..a2ff93f 100644 --- a/onap-dcae-dcaepolicy-lib/setup.py +++ b/onap-dcae-dcaepolicy-lib/setup.py @@ -1,8 +1,5 @@ -"""setup.py is used for package build and distribution""" - -# org.onap.dcae # ================================================================================ -# Copyright (c) 2017 AT&T Intellectual Property. All rights reserved. +# Copyright (c) 2017-2018 AT&T Intellectual Property. All rights reserved. # ================================================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -19,12 +16,14 @@ # # ECOMP is a trademark and service mark of AT&T Intellectual Property. +"""setup.py is used for package build and distribution""" + from setuptools import setup, find_packages setup( name='onap-dcae-dcaepolicy-lib', description='lib of policy decorators to be used by cloudify plugins of dcae controller', - version="1.0.0", + version="2.4.0", author='Alex Shatov', author_email="alexs@att.com", license='Apache 2', @@ -33,7 +32,6 @@ setup( ], keywords='onap policy dcae controller cloudify plugin', classifiers=[ - 'Development Status :: 4 - Beta', 'Intended Audience :: Telecommunications Industry', 'Programming Language :: Python :: 2.7' ] diff --git a/onap-dcae-dcaepolicy-lib/tests/__init__.py b/onap-dcae-dcaepolicy-lib/tests/__init__.py new file mode 100644 index 0000000..6c84c78 --- /dev/null +++ b/onap-dcae-dcaepolicy-lib/tests/__init__.py @@ -0,0 +1,19 @@ +# ================================================================================ +# Copyright (c) 2018 AT&T Intellectual Property. All rights reserved. +# ================================================================================ +# 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. +# ============LICENSE_END========================================================= +# +# ECOMP is a trademark and service mark of AT&T Intellectual Property. + +"""unit test the onap-dcae-dcaepolicy-lib""" diff --git a/onap-dcae-dcaepolicy-lib/tests/log_ctx.py b/onap-dcae-dcaepolicy-lib/tests/log_ctx.py index 9f5464d..0d82687 100644 --- a/onap-dcae-dcaepolicy-lib/tests/log_ctx.py +++ b/onap-dcae-dcaepolicy-lib/tests/log_ctx.py @@ -1,8 +1,5 @@ -""":@CtxLogger.log_ctx: decorator for logging the cloudify ctx before and after operation""" - -# org.onap.dcae # ================================================================================ -# Copyright (c) 2017 AT&T Intellectual Property. All rights reserved. +# Copyright (c) 2017-2018 AT&T Intellectual Property. All rights reserved. # ================================================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -19,7 +16,10 @@ # # ECOMP is a trademark and service mark of AT&T Intellectual Property. +""":@CtxLogger.log_ctx: decorator for logging the cloudify ctx before and after operation""" + import json +import traceback from functools import wraps from cloudify import ctx @@ -102,7 +102,8 @@ class CtxLogger(object): ctx.logger.info("{0} context: {1}".format(\ func_name, json.dumps(CtxLogger.get_ctx_info()))) except Exception as ex: - ctx.logger.error("Failed to log the node context: {0}".format(str(ex))) + ctx.logger.error("Failed to log the node context: {0}: {1}" \ + .format(str(ex), traceback.format_exc())) @staticmethod def log_ctx(pre_log=True, after_log=False, exe_task=None): @@ -119,8 +120,8 @@ class CtxLogger(object): if ctx.type == NODE_INSTANCE and exe_task: ctx.instance.runtime_properties[exe_task] = func.__name__ except Exception as ex: - ctx.logger.error("Failed to set exe_task {0}: {1}".format(\ - exe_task, str(ex))) + ctx.logger.error("Failed to set exe_task {0}: {1}: {2}" \ + .format(exe_task, str(ex), traceback.format_exc())) if pre_log: CtxLogger.log_ctx_info('before ' + func.__name__) diff --git a/onap-dcae-dcaepolicy-lib/tests/mock_cloudify_ctx.py b/onap-dcae-dcaepolicy-lib/tests/mock_cloudify_ctx.py index 0c130c0..50aa46e 100644 --- a/onap-dcae-dcaepolicy-lib/tests/mock_cloudify_ctx.py +++ b/onap-dcae-dcaepolicy-lib/tests/mock_cloudify_ctx.py @@ -1,8 +1,5 @@ - # ============LICENSE_START======================================================= -# org.onap.dcae -# ================================================================================ -# Copyright (c) 2017 AT&T Intellectual Property. All rights reserved. +# Copyright (c) 2017-2018 AT&T Intellectual Property. All rights reserved. # ================================================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -19,6 +16,8 @@ # # ECOMP is a trademark and service mark of AT&T Intellectual Property. +"""mock of cloudify context with relationships and type_hierrarchy""" + from cloudify.mocks import MockCloudifyContext, MockNodeInstanceContext, MockNodeContext TARGET_NODE_ID = "target_node_id" diff --git a/onap-dcae-dcaepolicy-lib/tests/test_dcae_policy.py b/onap-dcae-dcaepolicy-lib/tests/test_dcae_policy.py index 29b192c..4b3e39c 100644 --- a/onap-dcae-dcaepolicy-lib/tests/test_dcae_policy.py +++ b/onap-dcae-dcaepolicy-lib/tests/test_dcae_policy.py @@ -1,7 +1,5 @@ # ============LICENSE_START======================================================= -# org.onap.dcae -# ================================================================================ -# Copyright (c) 2017 AT&T Intellectual Property. All rights reserved. +# Copyright (c) 2017-2018 AT&T Intellectual Property. All rights reserved. # ================================================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -18,31 +16,43 @@ # # ECOMP is a trademark and service mark of AT&T Intellectual Property. +"""tests of decorators around the cloudify operations to handle policy actions""" + +import copy import json import logging from datetime import datetime, timedelta +from functools import wraps import pytest - +import requests from cloudify import ctx -from cloudify.state import current_ctx from cloudify.exceptions import NonRecoverableError +from cloudify.state import current_ctx -from mock_cloudify_ctx import MockCloudifyContextFull, TARGET_NODE_ID, TARGET_NODE_NAME -from log_ctx import CtxLogger - -from onap_dcae_dcaepolicy_lib import Policies, POLICIES +from onap_dcae_dcaepolicy_lib import dcae_policy +from onap_dcae_dcaepolicy_lib.dcae_policy import Policies +from onap_dcae_dcaepolicy_lib.policies_output import PoliciesOutput +from tests.log_ctx import CtxLogger +from tests.mock_cloudify_ctx import (TARGET_NODE_ID, TARGET_NODE_NAME, + MockCloudifyContextFull) -DCAE_POLICY_TYPE = 'dcae.nodes.policy' POLICY_ID = 'policy_id' POLICY_VERSION = "policyVersion" POLICY_NAME = "policyName" POLICY_BODY = 'policy_body' POLICY_CONFIG = 'config' +CONFIG_NAME = "ConfigName" + MONKEYED_POLICY_ID = 'monkeyed.Config_peach' MONKEYED_POLICY_ID_2 = 'monkeyed.Config_peach_2' +MONKEYED_POLICY_ID_M = 'monkeyed.Config_multi' +MONKEYED_POLICY_ID_M_2 = 'monkeyed.Config_multi_2' +MONKEYED_POLICY_ID_M_3 = 'monkeyed.Config_multi_3' +MONKEYED_POLICY_ID_B = 'monkeyed.Config_both' APPLICATION_CONFIG = "application_config" -LOG_FILE = 'test_onap_dcae_dcaepolicy_lib.log' +LOG_FILE = 'logs/test_onap_dcae_dcaepolicy_lib.log' +LOREM_IPSUM = """Lorem ipsum dolor sit amet consectetur ametist""".split() RUN_TS = datetime.utcnow() @@ -66,20 +76,28 @@ class MonkeyedLogHandler(object): class MonkeyedPolicyBody(object): """policy body that policy-engine returns""" @staticmethod - def create_policy_body(policy_id, policy_version=1): + def create_policy_body(policy_id, policy_version=1, priority=None, **kwargs): """returns a fake policy-body""" prev_ver = policy_version - 1 timestamp = RUN_TS + timedelta(hours=prev_ver) - prev_ver = str(prev_ver) this_ver = str(policy_version) config = { - "policy_updated_from_ver": prev_ver, + "policy_updated_from_ver": str(prev_ver), "policy_updated_to_ver": this_ver, - "policy_hello": "world!", + "policy_hello": LOREM_IPSUM[prev_ver % len(LOREM_IPSUM)], "policy_updated_ts": timestamp.isoformat()[:-3] + 'Z', "updated_policy_id": policy_id } + config.update(copy.deepcopy(kwargs) or {}) + + matching_conditions = { + "ONAPName": "DCAE", + CONFIG_NAME: "alex_config_name" + } + if priority is not None: + matching_conditions["priority"] = priority + return { "policyConfigMessage": "Config Retrieved! ", "policyConfigStatus": "CONFIG_RETRIEVED", @@ -87,23 +105,29 @@ class MonkeyedPolicyBody(object): POLICY_NAME: "{0}.{1}.xml".format(policy_id, this_ver), POLICY_VERSION: this_ver, POLICY_CONFIG: config, - "matchingConditions": { - "ECOMPName": "DCAE", - "ConfigName": "alex_config_name" - }, + "matchingConditions": matching_conditions, "responseAttributes": {}, "property": None } @staticmethod - def create_policy(policy_id, policy_version=1): + def create_policy_bare(policy_id, policy_version=1, priority=None, **kwargs): """returns the whole policy object for policy_id and policy_version""" return { - POLICY_ID : policy_id, - POLICY_BODY : MonkeyedPolicyBody.create_policy_body(policy_id, policy_version) + POLICY_ID: policy_id, + POLICY_BODY: MonkeyedPolicyBody.create_policy_body( + policy_id, policy_version, priority, **kwargs) } @staticmethod + def create_policy(policy_id, policy_version=1, policy_persistent=True, priority=None, **kwargs): + """returns the whole policy object for policy_id and policy_version""" + policy = MonkeyedPolicyBody.create_policy_bare( + policy_id, policy_version, priority, **kwargs) + policy[dcae_policy.POLICY_PERSISTENT] = bool(policy_persistent) + return policy + + @staticmethod def is_the_same_dict(policy_body_1, policy_body_2): """check whether both policy_body objects are the same""" if not isinstance(policy_body_1, dict) or not isinstance(policy_body_2, dict): @@ -111,23 +135,25 @@ class MonkeyedPolicyBody(object): for key in policy_body_1.keys(): if key not in policy_body_2: return False - if isinstance(policy_body_1[key], dict): - return MonkeyedPolicyBody.is_the_same_dict( - policy_body_1[key], policy_body_2[key]) - if (policy_body_1[key] is None and policy_body_2[key] is not None) \ - or (policy_body_1[key] is not None and policy_body_2[key] is None) \ - or (policy_body_1[key] != policy_body_2[key]): + + val_1 = policy_body_1[key] + val_2 = policy_body_2[key] + if isinstance(val_1, dict) \ + and not MonkeyedPolicyBody.is_the_same_dict(val_1, val_2): + return False + if (val_1 is None and val_2 is not None) \ + or (val_1 is not None and val_2 is None) \ + or (val_1 != val_2): return False return True - class MonkeyedNode(object): """node in cloudify""" BLUEPRINT_ID = 'test_dcae_policy_bp_id' DEPLOYMENT_ID = 'test_dcae_policy_dpl_id' EXECUTION_ID = 'test_dcae_policy_exe_id' - def __init__(self, node_id, node_name, node_type, properties, + def __init__(self, node_id, node_name, node_type, properties=None, relationships=None, runtime_properties=None): self.node_id = node_id self.node_name = node_name @@ -142,121 +168,1119 @@ class MonkeyedNode(object): relationships=relationships, runtime_properties=runtime_properties ) - MonkeyedLogHandler.add_handler_to(self.ctx.logger) + +class MonkeyedResponse(object): + """Monkey response""" + def __init__(self, full_path, headers=None, resp_json=None): + self.full_path = full_path + self.status_code = 200 + self.headers = headers or {} + self.resp_json = resp_json + self.text = json.dumps(resp_json or {}) + + def json(self): + """returns json of response""" + return self.resp_json + + def raise_for_status(self): + """always happy""" + pass + +def get_app_config(): + """just get the config""" + config = copy.deepcopy(dict(ctx.instance.runtime_properties.get(APPLICATION_CONFIG, {}))) + if not config: + config = copy.deepcopy(dict(ctx.node.properties.get(APPLICATION_CONFIG, {}))) + return config + +def operation_node_configure(**kwargs): + """do the node-configure operation""" + ctx.logger.info("operation_node_configure kwargs: {0}".format(kwargs)) + + app_config = get_app_config() + ctx.instance.runtime_properties[APPLICATION_CONFIG] = app_config + ctx.instance.runtime_properties[PoliciesOutput.SERVICE_COMPONENT_NAME] = "unit_test_scn" + ctx.logger.info("property app_config: {0}".format(json.dumps(app_config))) @CtxLogger.log_ctx(pre_log=True, after_log=True, exe_task='exe_task') -@Policies.gather_policies_to_node +@Policies.gather_policies_to_node() def node_configure(**kwargs): """decorate with @Policies.gather_policies_to_node on policy consumer node to bring all policies to runtime_properties["policies"] """ - ctx.logger.info("node_configure kwargs: {0}".format(kwargs)) + operation_node_configure(**kwargs) - app_config = None - if APPLICATION_CONFIG in ctx.node.properties: - # dockerized blueprint puts the app config into property application_config - app_config = ctx.node.properties.get(APPLICATION_CONFIG) +@CtxLogger.log_ctx(pre_log=True, after_log=True, exe_task='execute_operation') +@Policies.update_policies_on_node() +def policy_update(updated_policies, removed_policies=None, **kwargs): + """decorate with @Policies.update_policies_on_node() to update runtime_properties["policies"] - app_config = Policies.shallow_merge_policies_into(app_config) - ctx.instance.runtime_properties[APPLICATION_CONFIG] = app_config - ctx.logger.info("example: applied policy_configs to property app_config: {0}" \ - .format(json.dumps(app_config))) + :updated_policies: contains the list of changed policy-configs when configs_only=True (default). + """ + # This is how to merge the policies into default app_config object + # (runtime_properties[APPLICATION_CONFIG] = application_config) + app_config = get_app_config() + ctx.logger.info("app_config {0}".format(json.dumps(app_config))) - policy_configs = Policies.get_policy_configs() - if policy_configs: - ctx.logger.warn("TBD: apply policy_configs: {0}".format(json.dumps(policy_configs))) + ctx.instance.runtime_properties[APPLICATION_CONFIG] = app_config @CtxLogger.log_ctx(pre_log=True, after_log=True, exe_task='execute_operation') -@Policies.update_policies_on_node(configs_only=True) -def policy_update(updated_policies, **kwargs): +@Policies.update_policies_on_node() +def policy_update_not_only_config(updated_policies, removed_policies=None, **kwargs): """decorate with @Policies.update_policies_on_node() to update runtime_properties["policies"] :updated_policies: contains the list of changed policy-configs when configs_only=True (default). - Use configs_only=False to bring the full policy objects in :updated_policies:. - - Use :Policies.shallow_merge_policies_into(): to merge the updated_policies into app_config """ - app_config = ctx.instance.runtime_properties[APPLICATION_CONFIG] + # This is how to merge the policies into default app_config object + # (runtime_properties[APPLICATION_CONFIG] = application_config) + app_config = get_app_config() + ctx.logger.info("app_config {0}".format(json.dumps(app_config))) + + ctx.instance.runtime_properties[APPLICATION_CONFIG] = app_config - # This is how to merge the policies into app_config object - app_config = Policies.shallow_merge_policies_into(app_config) +@CtxLogger.log_ctx(pre_log=True, after_log=True, exe_task='execute_operation') +@Policies.update_policies_on_node() +def policy_update_many_calcs(updated_policies, removed_policies=None, policies=None, **kwargs): + """decorate with @Policies.update_policies_on_node() to update runtime_properties["policies"] - ctx.logger.info("merged updated_policies {0} into app_config {1}" - .format(json.dumps(updated_policies), json.dumps(app_config))) + :updated_policies: contains the list of changed policy-configs when configs_only=True (default). + """ + app_config = get_app_config() + ctx.logger.info("app_config {0}".format(json.dumps(app_config))) ctx.instance.runtime_properties[APPLICATION_CONFIG] = app_config +@CtxLogger.log_ctx(pre_log=True, after_log=True, exe_task='exe_task') +@Policies.cleanup_policies_on_node +def node_delete(**kwargs): + """delete <service_component_name> records in consul-kv""" + operation_node_configure(**kwargs) + + +class CurrentCtx(object): + """cloudify context""" + _node_ms = None + + @staticmethod + def set_current_ctx(include_bad=True, include_good=True): + """set up the nodes for cloudify""" + Policies._init() + + def add_target_to_relationships(relationships, node): + """adds the node as the target of relationships""" + relationships.append({TARGET_NODE_ID: node.node_id, TARGET_NODE_NAME: node.node_name}) + + relationships = [] + if include_good: + node_policy = MonkeyedNode( + 'dcae_policy_node_id', + 'dcae_policy_node_name', + dcae_policy.DCAE_POLICY_TYPE, + {POLICY_ID: MONKEYED_POLICY_ID}, + None, + {POLICY_BODY: MonkeyedPolicyBody.create_policy_body( + MONKEYED_POLICY_ID, priority="1")} + ) + add_target_to_relationships(relationships, node_policy) + + if include_bad: + bad_policy_2 = MonkeyedNode( + 'bad_policy_2_node_id', + 'bad_policy_2_node_name', + dcae_policy.DCAE_POLICY_TYPE, + {POLICY_ID: MONKEYED_POLICY_ID_2}, + None, + None + ) + add_target_to_relationships(relationships, bad_policy_2) + + if include_good: + node_policy_2 = MonkeyedNode( + 'dcae_policy_node_id_2', + 'dcae_policy_node_name_2', + dcae_policy.DCAE_POLICY_TYPE, + {POLICY_ID: MONKEYED_POLICY_ID_2}, + None, + {POLICY_BODY: MonkeyedPolicyBody.create_policy_body( + MONKEYED_POLICY_ID_2, 4, priority="2")} + ) + add_target_to_relationships(relationships, node_policy_2) + + if include_bad: + bad_policy_3 = MonkeyedNode( + 'bad_policy_3_node_id', + 'bad_policy_3_node_name', + dcae_policy.DCAE_POLICY_TYPE, + {POLICY_ID: MONKEYED_POLICY_ID_2}, + None, + None + ) + add_target_to_relationships(relationships, bad_policy_3) + + bad_policy_4 = MonkeyedNode( + 'bad_policy_4_node_id', + 'bad_policy_4_node_name', + dcae_policy.DCAE_POLICY_TYPE, + None, + None, + None + ) + add_target_to_relationships(relationships, bad_policy_4) + + weird_policy_5 = MonkeyedNode( + 'weird_policy_5_node_id', + 'weird_policy_5_node_name', + dcae_policy.DCAE_POLICY_TYPE, + None, + None, + {POLICY_BODY: MonkeyedPolicyBody.create_policy_body( + MONKEYED_POLICY_ID, 3, priority="2")} + ) + add_target_to_relationships(relationships, weird_policy_5) + + if include_good: + node_policies = MonkeyedNode( + 'dcae_policies_node_id', + 'dcae_policies_node_name', + dcae_policy.DCAE_POLICIES_TYPE, + {dcae_policy.POLICY_FILTER: { + POLICY_NAME: MONKEYED_POLICY_ID_M + ".*", + dcae_policy.CONFIG_ATTRIBUTES: json.dumps({ + CONFIG_NAME: "alex_config_name" + }) + }}, + None, + {dcae_policy.POLICIES_FILTERED: { + MONKEYED_POLICY_ID_M: + MonkeyedPolicyBody.create_policy_bare(MONKEYED_POLICY_ID_M, 3)}} + ) + add_target_to_relationships(relationships, node_policies) + + node_policies_2 = MonkeyedNode( + 'dcae_policies_2_node_id', + 'dcae_policies_2_node_name', + dcae_policy.DCAE_POLICIES_TYPE, + {dcae_policy.POLICY_FILTER: {POLICY_NAME: MONKEYED_POLICY_ID_M + ".*"}}, + None, + {dcae_policy.POLICIES_FILTERED: { + MONKEYED_POLICY_ID_M: + MonkeyedPolicyBody.create_policy_bare(MONKEYED_POLICY_ID_M, 2)}} + ) + add_target_to_relationships(relationships, node_policies_2) + + policies_empty = MonkeyedNode( + 'dcae_policies_empty_node_id', + 'dcae_policies_empty_node_name', + dcae_policy.DCAE_POLICIES_TYPE, + {dcae_policy.POLICY_FILTER: {"empty": None}}, + None, + None + ) + add_target_to_relationships(relationships, policies_empty) + + policies_empty_2 = MonkeyedNode( + 'dcae_policies_empty_2_node_id', + 'dcae_policies_empty_2_node_name', + dcae_policy.DCAE_POLICIES_TYPE, + None, + None, + None + ) + add_target_to_relationships(relationships, policies_empty_2) + + non_policies = MonkeyedNode( + 'non_policies_node_id', + 'non_policies_node_name', + "non.policy.type" + ) + add_target_to_relationships(relationships, non_policies) + + if include_good: + node_policies_b = MonkeyedNode( + 'dcae_policies_b_node_id', + 'dcae_policies_b_node_name', + dcae_policy.DCAE_POLICIES_TYPE, + {dcae_policy.POLICY_FILTER: {POLICY_NAME: MONKEYED_POLICY_ID_M + ".*"}}, + None, + {dcae_policy.POLICIES_FILTERED: { + MONKEYED_POLICY_ID_B: + MonkeyedPolicyBody.create_policy_bare(MONKEYED_POLICY_ID_B, 1)}} + ) + add_target_to_relationships(relationships, node_policies_b) + + node_policies_b_2 = MonkeyedNode( + 'dcae_policies_b_2_node_id', + 'dcae_policies_b_2_node_name', + dcae_policy.DCAE_POLICIES_TYPE, + {dcae_policy.POLICY_FILTER: {POLICY_NAME: MONKEYED_POLICY_ID_M + ".*"}}, + None, + {dcae_policy.POLICIES_FILTERED: { + MONKEYED_POLICY_ID_B: + MonkeyedPolicyBody.create_policy_bare(MONKEYED_POLICY_ID_B, 2)}} + ) + add_target_to_relationships(relationships, node_policies_b_2) + + if include_good: + node_policy_b = MonkeyedNode( + 'dcae_policy_b_node_id', + 'dcae_policy_b_node_name', + dcae_policy.DCAE_POLICY_TYPE, + {POLICY_ID: MONKEYED_POLICY_ID_B}, + None, + {POLICY_BODY: MonkeyedPolicyBody.create_policy_body( + MONKEYED_POLICY_ID_B, 4, priority="1.5")} + ) + add_target_to_relationships(relationships, node_policy_b) + + node_policies_b_5 = MonkeyedNode( + 'dcae_policies_b_5_node_id', + 'dcae_policies_b_5_node_name', + dcae_policy.DCAE_POLICIES_TYPE, + {dcae_policy.POLICY_FILTER: {POLICY_NAME: MONKEYED_POLICY_ID_M + ".*"}}, + None, + {dcae_policy.POLICIES_FILTERED: { + MONKEYED_POLICY_ID_B: + MonkeyedPolicyBody.create_policy_bare(MONKEYED_POLICY_ID_B, 5)}} + ) + add_target_to_relationships(relationships, node_policies_b_5) + + + CurrentCtx._node_ms = MonkeyedNode( + 'test_ms_id', 'test_ms_name', "ms.nodes.type", + {APPLICATION_CONFIG: MonkeyedPolicyBody.create_policy_body( + "no_policy", db_port="123", weather="snow")[POLICY_CONFIG] + }, + relationships + ) + current_ctx.set(CurrentCtx._node_ms.ctx) + MonkeyedLogHandler.add_handler_to(CurrentCtx._node_ms.ctx.logger) + + @staticmethod + def reset(): + """reset context""" + current_ctx.set(CurrentCtx._node_ms.ctx) + + +def monkeyed_consul_boom(full_path, json): + """boom on monkeypatch for the put to consul""" + raise requests.ConnectionError("monkey-boom") + + +@pytest.fixture() +def fix_consul_boom(monkeypatch): + """monkeyed discovery request.put""" + PoliciesOutput._lazy_inited = False + monkeypatch.setattr('requests.put', monkeyed_consul_boom) + yield fix_consul_boom + PoliciesOutput._lazy_inited = False + + +def monkeyed_consul_put(full_path, json): + """monkeypatch for the put to consul""" + return MonkeyedResponse(full_path) + + +@pytest.fixture() +def fix_consul(monkeypatch): + """monkeyed discovery request.put""" + PoliciesOutput._lazy_inited = False + monkeypatch.setattr('requests.put', monkeyed_consul_put) + yield fix_consul + PoliciesOutput._lazy_inited = False + + +def cfy_ctx(include_bad=True, include_good=True): + """test and safely clean up""" + def cfy_ctx_decorator(func): + """test and safely clean up""" + if not func: + return + + @wraps(func) + def ctx_wrapper(*args, **kwargs): + """test""" + try: + CurrentCtx.set_current_ctx(include_bad, include_good) + + func(*args, **kwargs) + + finally: + ctx.logger.info("MockCloudifyContextFull.clear") + MockCloudifyContextFull.clear() + current_ctx.clear() + + return ctx_wrapper + return cfy_ctx_decorator + +@pytest.mark.usefixtures("fix_consul") +@cfy_ctx(include_bad=True) +def test_gather_policies_to_node(): + """test gather_policies_to_node""" + node_configure() + + runtime_properties = ctx.instance.runtime_properties + ctx.logger.info("runtime_properties: {0}".format(json.dumps(runtime_properties))) + + assert dcae_policy.POLICIES in runtime_properties + policies = runtime_properties[dcae_policy.POLICIES] + ctx.logger.info("policies: {0}".format(json.dumps(policies))) + +@pytest.mark.usefixtures("fix_consul") +@cfy_ctx(include_bad=True) def test_policies_to_node(): - """test gather_policies_to_node and policy_update""" - - node_policy = MonkeyedNode( - 'test_dcae_policy_node_id', - 'test_dcae_policy_node_name', - DCAE_POLICY_TYPE, - {POLICY_ID: MONKEYED_POLICY_ID}, - None, - {POLICY_BODY : MonkeyedPolicyBody.create_policy_body(MONKEYED_POLICY_ID)} - ) - node_policy_2 = MonkeyedNode( - 'test_dcae_policy_node_id_2', - 'test_dcae_policy_node_name_2', - DCAE_POLICY_TYPE, - {POLICY_ID: MONKEYED_POLICY_ID_2}, - None, - {POLICY_BODY : MonkeyedPolicyBody.create_policy_body(MONKEYED_POLICY_ID_2)} - ) - node_ms = MonkeyedNode('test_ms_id', 'test_ms_name', "ms.nodes.type", None, \ - [{TARGET_NODE_ID: node_policy.node_id, TARGET_NODE_NAME: node_policy.node_name}, - {TARGET_NODE_ID: node_policy_2.node_id, TARGET_NODE_NAME: node_policy_2.node_name} - ]) - - try: - current_ctx.set(node_ms.ctx) + """test gather_policies_to_node""" + node_configure() + + runtime_properties = ctx.instance.runtime_properties + ctx.logger.info("runtime_properties: {0}".format(json.dumps(runtime_properties))) + + assert dcae_policy.POLICIES in runtime_properties + policies = runtime_properties[dcae_policy.POLICIES] + ctx.logger.info("policies: {0}".format(json.dumps(policies))) + + assert MONKEYED_POLICY_ID in policies + expected_1 = MonkeyedPolicyBody.create_policy(MONKEYED_POLICY_ID, priority="1") + policy = policies[MONKEYED_POLICY_ID] + ctx.logger.info("expected[{0}]: {1}".format(MONKEYED_POLICY_ID, json.dumps(expected_1))) + ctx.logger.info("policy[{0}]: {1}".format(MONKEYED_POLICY_ID, json.dumps(policy))) + assert MonkeyedPolicyBody.is_the_same_dict(policy, expected_1) + assert MonkeyedPolicyBody.is_the_same_dict(expected_1, policy) + + assert MONKEYED_POLICY_ID_B in policies + expected_b = MonkeyedPolicyBody.create_policy(MONKEYED_POLICY_ID_B, 4, priority="1.5") + policy = policies[MONKEYED_POLICY_ID_B] + ctx.logger.info("expected[{0}]: {1}".format(MONKEYED_POLICY_ID_B, json.dumps(expected_b))) + ctx.logger.info("policy[{0}]: {1}".format(MONKEYED_POLICY_ID_B, json.dumps(policy))) + assert MonkeyedPolicyBody.is_the_same_dict(policy, expected_b) + assert MonkeyedPolicyBody.is_the_same_dict(expected_b, policy) + + assert MONKEYED_POLICY_ID_2 in policies + expected_2 = MonkeyedPolicyBody.create_policy(MONKEYED_POLICY_ID_2, 4, priority="2") + policy = policies[MONKEYED_POLICY_ID_2] + ctx.logger.info("expected[{0}]: {1}".format(MONKEYED_POLICY_ID_2, json.dumps(expected_2))) + ctx.logger.info("policy[{0}]: {1}".format(MONKEYED_POLICY_ID_2, json.dumps(policy))) + assert MonkeyedPolicyBody.is_the_same_dict(policy, expected_2) + assert MonkeyedPolicyBody.is_the_same_dict(expected_2, policy) + + assert MONKEYED_POLICY_ID_M in policies + expected_m = MonkeyedPolicyBody.create_policy(MONKEYED_POLICY_ID_M, 2, False) + policy = policies[MONKEYED_POLICY_ID_M] + ctx.logger.info("expected[{0}]: {1}".format(MONKEYED_POLICY_ID_M, json.dumps(expected_m))) + ctx.logger.info("policy[{0}]: {1}".format(MONKEYED_POLICY_ID_M, json.dumps(policy))) + assert MonkeyedPolicyBody.is_the_same_dict(policy, expected_m) + assert MonkeyedPolicyBody.is_the_same_dict(expected_m, policy) + +@pytest.mark.usefixtures("fix_consul") +@cfy_ctx(include_bad=True) +def test_update_policies(): + """test policy_update""" + node_configure() + + runtime_properties = ctx.instance.runtime_properties + ctx.logger.info("runtime_properties: {0}".format(json.dumps(runtime_properties))) + + assert dcae_policy.POLICIES in runtime_properties + policies = runtime_properties[dcae_policy.POLICIES] + ctx.logger.info("policies: {0}".format(json.dumps(policies))) + + updated_policy = MonkeyedPolicyBody.create_policy(MONKEYED_POLICY_ID_2, 2, priority="aa20") + added_policy = MonkeyedPolicyBody.create_policy(MONKEYED_POLICY_ID_M_2, 2, + False, priority="1") + ctx.logger.info("policy_update: [{0}]".format(json.dumps(updated_policy))) + + ctx.logger.info("policy[{0}]: not yet in policies".format(MONKEYED_POLICY_ID_M_2)) + assert MONKEYED_POLICY_ID_M_2 not in policies + + policy_filter_ids = runtime_properties.get(dcae_policy.POLICY_FILTERS, {}).keys() or ["--"] + + policy_update(updated_policies=[updated_policy], + added_policies={ + policy_filter_ids[0]: { + dcae_policy.POLICIES: {MONKEYED_POLICY_ID_M_2: added_policy}} + }, + removed_policies=[MONKEYED_POLICY_ID_M]) + + ctx.logger.info("policy[{0}]: removed".format(MONKEYED_POLICY_ID_M)) + assert MONKEYED_POLICY_ID_M not in policies + + assert MONKEYED_POLICY_ID_M_2 in policies + policy = policies[MONKEYED_POLICY_ID_M_2] + ctx.logger.info("policy[{0}]: {1}".format(MONKEYED_POLICY_ID_M_2, json.dumps(policy))) + assert MonkeyedPolicyBody.is_the_same_dict(policy, added_policy) + assert MonkeyedPolicyBody.is_the_same_dict(added_policy, policy) + + assert MONKEYED_POLICY_ID_2 in policies + policy = policies[MONKEYED_POLICY_ID_2] + ctx.logger.info("policy[{0}]: {1}".format(MONKEYED_POLICY_ID_2, json.dumps(policy))) + assert MonkeyedPolicyBody.is_the_same_dict(policy, updated_policy) + assert MonkeyedPolicyBody.is_the_same_dict(updated_policy, policy) + + assert MONKEYED_POLICY_ID in policies + policy = policies[MONKEYED_POLICY_ID] + expected_1 = MonkeyedPolicyBody.create_policy(MONKEYED_POLICY_ID, priority="1") + ctx.logger.info("expected[{0}]: {1}".format(MONKEYED_POLICY_ID, json.dumps(expected_1))) + ctx.logger.info("policy[{0}]: {1}".format(MONKEYED_POLICY_ID, json.dumps(policy))) + assert MonkeyedPolicyBody.is_the_same_dict(policy, expected_1) + assert MonkeyedPolicyBody.is_the_same_dict(expected_1, policy) + + assert MONKEYED_POLICY_ID_B in policies + policy = policies[MONKEYED_POLICY_ID_B] + expected_b = MonkeyedPolicyBody.create_policy(MONKEYED_POLICY_ID_B, 4, priority="1.5") + ctx.logger.info("expected[{0}]: {1}".format(MONKEYED_POLICY_ID_B, json.dumps(expected_1))) + ctx.logger.info("policy[{0}]: {1}".format(MONKEYED_POLICY_ID_B, json.dumps(policy))) + assert MonkeyedPolicyBody.is_the_same_dict(policy, expected_b) + assert MonkeyedPolicyBody.is_the_same_dict(expected_b, policy) + +@pytest.mark.usefixtures("fix_consul") +@cfy_ctx(include_bad=True) +def test_update_not_only_config(): + """test policy_update""" + node_configure() + + runtime_properties = ctx.instance.runtime_properties + ctx.logger.info("runtime_properties: {0}".format(json.dumps(runtime_properties))) + + assert dcae_policy.POLICIES in runtime_properties + policies = runtime_properties[dcae_policy.POLICIES] + ctx.logger.info("policies: {0}".format(json.dumps(policies))) + + updated_policy = MonkeyedPolicyBody.create_policy(MONKEYED_POLICY_ID_2, 2, priority="aa20") + added_policy = MonkeyedPolicyBody.create_policy(MONKEYED_POLICY_ID_M_2, 2, + False, priority="1") + ctx.logger.info("policy_update: [{0}]".format(json.dumps(updated_policy))) + + ctx.logger.info("policy[{0}]: not yet in policies".format(MONKEYED_POLICY_ID_M_2)) + assert MONKEYED_POLICY_ID_M_2 not in policies + + policy_filter_ids = runtime_properties.get(dcae_policy.POLICY_FILTERS, {}).keys() or ["--"] + + policy_update_not_only_config(updated_policies=[updated_policy], + added_policies={ + policy_filter_ids[0]: { + dcae_policy.POLICIES: {MONKEYED_POLICY_ID_M_2: added_policy}} + }, + removed_policies=[MONKEYED_POLICY_ID_M]) + + ctx.logger.info("policy[{0}]: removed".format(MONKEYED_POLICY_ID_M)) + assert MONKEYED_POLICY_ID_M not in policies + + assert MONKEYED_POLICY_ID_M_2 in policies + policy = policies[MONKEYED_POLICY_ID_M_2] + ctx.logger.info("policy[{0}]: {1}".format(MONKEYED_POLICY_ID_M_2, json.dumps(policy))) + assert MonkeyedPolicyBody.is_the_same_dict(policy, added_policy) + assert MonkeyedPolicyBody.is_the_same_dict(added_policy, policy) + + assert MONKEYED_POLICY_ID_2 in policies + policy = policies[MONKEYED_POLICY_ID_2] + ctx.logger.info("policy[{0}]: {1}".format(MONKEYED_POLICY_ID_2, json.dumps(policy))) + assert MonkeyedPolicyBody.is_the_same_dict(policy, updated_policy) + assert MonkeyedPolicyBody.is_the_same_dict(updated_policy, policy) + + assert MONKEYED_POLICY_ID in policies + policy = policies[MONKEYED_POLICY_ID] + expected_1 = MonkeyedPolicyBody.create_policy(MONKEYED_POLICY_ID, priority="1") + ctx.logger.info("expected[{0}]: {1}".format(MONKEYED_POLICY_ID, json.dumps(expected_1))) + ctx.logger.info("policy[{0}]: {1}".format(MONKEYED_POLICY_ID, json.dumps(policy))) + assert MonkeyedPolicyBody.is_the_same_dict(policy, expected_1) + assert MonkeyedPolicyBody.is_the_same_dict(expected_1, policy) + + assert MONKEYED_POLICY_ID_B in policies + policy = policies[MONKEYED_POLICY_ID_B] + expected_b = MonkeyedPolicyBody.create_policy(MONKEYED_POLICY_ID_B, 4, priority="1.5") + ctx.logger.info("expected[{0}]: {1}".format(MONKEYED_POLICY_ID_B, json.dumps(expected_1))) + ctx.logger.info("policy[{0}]: {1}".format(MONKEYED_POLICY_ID_B, json.dumps(policy))) + assert MonkeyedPolicyBody.is_the_same_dict(policy, expected_b) + assert MonkeyedPolicyBody.is_the_same_dict(expected_b, policy) + +@pytest.mark.usefixtures("fix_consul") +@cfy_ctx(include_bad=True) +def test_update_policies_not(): + """test policy_update - ignore all policies with junk params""" + node_configure() + + runtime_properties = ctx.instance.runtime_properties + ctx.logger.info("runtime_properties: {0}".format(json.dumps(runtime_properties))) + + assert dcae_policy.POLICIES in runtime_properties + assert APPLICATION_CONFIG in runtime_properties + policies = runtime_properties[dcae_policy.POLICIES] + app_config = runtime_properties[APPLICATION_CONFIG] + ctx.logger.info("policies: {0}".format(json.dumps(policies))) + ctx.logger.info("app_config: {0}".format(json.dumps(app_config))) + + expected_policies = copy.deepcopy(policies) + expected_app_config = copy.deepcopy(app_config) + + existing_policy = MonkeyedPolicyBody.create_policy_bare(MONKEYED_POLICY_ID, priority="1") + damaged_policy = MonkeyedPolicyBody.create_policy_bare(MONKEYED_POLICY_ID_2) + del damaged_policy[POLICY_BODY][POLICY_CONFIG] + updated_policy = MonkeyedPolicyBody.create_policy_bare(MONKEYED_POLICY_ID_M_3, 3) + added_policy = MonkeyedPolicyBody.create_policy_bare(MONKEYED_POLICY_ID_M_2, 4) + junk_policy_filter_id = "<<<junk_removed_policy_id>>>" + unexpected_removed_policy_id = "<<<junk_removed_policy_id>>>" + ctx.logger.info("policy_update: [{0}]".format(json.dumps(updated_policy))) + + assert MONKEYED_POLICY_ID in policies + assert MONKEYED_POLICY_ID_2 in policies + assert MONKEYED_POLICY_ID_M_2 not in policies + assert MONKEYED_POLICY_ID_M_3 not in policies + assert unexpected_removed_policy_id not in policies + assert junk_policy_filter_id not in runtime_properties.get(dcae_policy.POLICY_FILTERS, {}) + + policy_filter_ids = runtime_properties.get(dcae_policy.POLICY_FILTERS, {}).keys() or ["--"] + + policy_update(updated_policies=[existing_policy, damaged_policy, updated_policy], + added_policies={ + junk_policy_filter_id: { + dcae_policy.POLICIES: {MONKEYED_POLICY_ID_M_2: added_policy}}, + policy_filter_ids[0]: { + dcae_policy.POLICIES: {MONKEYED_POLICY_ID_2: damaged_policy}} + }, + removed_policies=[unexpected_removed_policy_id]) + + ctx.logger.info("runtime_properties: {0}".format(json.dumps(runtime_properties))) + + ctx.logger.info("policies not changed: {0}".format(json.dumps(policies))) + assert MonkeyedPolicyBody.is_the_same_dict(policies, expected_policies) + assert MonkeyedPolicyBody.is_the_same_dict(expected_policies, policies) + + ctx.logger.info("app_config not changed: {0}".format(json.dumps(app_config))) + assert MonkeyedPolicyBody.is_the_same_dict(app_config, expected_app_config) + assert MonkeyedPolicyBody.is_the_same_dict(expected_app_config, app_config) + +@pytest.mark.usefixtures("fix_consul") +@cfy_ctx(include_bad=True) +def test_update_many_calcs(): + """test policy_update""" + node_configure() + + runtime_properties = ctx.instance.runtime_properties + ctx.logger.info("runtime_properties: {0}".format(json.dumps(runtime_properties))) + + assert dcae_policy.POLICIES in runtime_properties + policies = runtime_properties[dcae_policy.POLICIES] + ctx.logger.info("policies: {0}".format(json.dumps(policies))) + + updated_policy = MonkeyedPolicyBody.create_policy(MONKEYED_POLICY_ID_2, 2, priority="aa20") + added_policy = MonkeyedPolicyBody.create_policy(MONKEYED_POLICY_ID_M_2, 2, + False, priority="1") + ctx.logger.info("policy_update: [{0}]".format(json.dumps(updated_policy))) + ctx.logger.info("policy[{0}]: not yet in policies".format(MONKEYED_POLICY_ID_M_2)) + assert MONKEYED_POLICY_ID_M_2 not in policies + + policy_filter_ids = runtime_properties.get(dcae_policy.POLICY_FILTERS, {}).keys() or ["--"] + + policy_update_many_calcs(updated_policies=[updated_policy], + added_policies={ + policy_filter_ids[0]: { + dcae_policy.POLICIES: {MONKEYED_POLICY_ID_M_2: added_policy}} + }, + removed_policies=[MONKEYED_POLICY_ID_M]) + + ctx.logger.info("policy[{0}]: removed".format(MONKEYED_POLICY_ID_M)) + assert MONKEYED_POLICY_ID_M not in policies + + assert MONKEYED_POLICY_ID_M_2 in policies + policy = policies[MONKEYED_POLICY_ID_M_2] + ctx.logger.info("policy[{0}]: {1}".format(MONKEYED_POLICY_ID_M_2, json.dumps(policy))) + assert MonkeyedPolicyBody.is_the_same_dict(policy, added_policy) + assert MonkeyedPolicyBody.is_the_same_dict(added_policy, policy) + + assert MONKEYED_POLICY_ID_2 in policies + policy = policies[MONKEYED_POLICY_ID_2] + ctx.logger.info("policy[{0}]: {1}".format(MONKEYED_POLICY_ID_2, json.dumps(policy))) + assert MonkeyedPolicyBody.is_the_same_dict(policy, updated_policy) + assert MonkeyedPolicyBody.is_the_same_dict(updated_policy, policy) + + assert MONKEYED_POLICY_ID in policies + policy = policies[MONKEYED_POLICY_ID] + expected_1 = MonkeyedPolicyBody.create_policy(MONKEYED_POLICY_ID, priority="1") + ctx.logger.info("expected[{0}]: {1}".format(MONKEYED_POLICY_ID, json.dumps(expected_1))) + ctx.logger.info("policy[{0}]: {1}".format(MONKEYED_POLICY_ID, json.dumps(policy))) + assert MonkeyedPolicyBody.is_the_same_dict(policy, expected_1) + assert MonkeyedPolicyBody.is_the_same_dict(expected_1, policy) + + assert MONKEYED_POLICY_ID_B in policies + policy = policies[MONKEYED_POLICY_ID_B] + expected_b = MonkeyedPolicyBody.create_policy(MONKEYED_POLICY_ID_B, 4, priority="1.5") + ctx.logger.info("expected[{0}]: {1}".format(MONKEYED_POLICY_ID_B, json.dumps(expected_1))) + ctx.logger.info("policy[{0}]: {1}".format(MONKEYED_POLICY_ID_B, json.dumps(policy))) + assert MonkeyedPolicyBody.is_the_same_dict(policy, expected_b) + assert MonkeyedPolicyBody.is_the_same_dict(expected_b, policy) + +@pytest.mark.usefixtures("fix_consul") +@cfy_ctx(include_bad=True) +def test_remove_all_policies(): + """test policy_update - remove all policies""" + node_configure() + + runtime_properties = ctx.instance.runtime_properties + ctx.logger.info("runtime_properties: {0}".format(json.dumps(runtime_properties))) + + assert dcae_policy.POLICIES in runtime_properties + policies = runtime_properties[dcae_policy.POLICIES] + ctx.logger.info("policies: {0}".format(json.dumps(policies))) + + remove_policy_ids = policies.keys() + + policy_update(updated_policies=None, added_policies=None, removed_policies=remove_policy_ids) + + ctx.logger.info("removed: {0}".format(remove_policy_ids)) + ctx.logger.info("runtime_properties: {0}".format(json.dumps(runtime_properties))) + assert dcae_policy.POLICIES in runtime_properties + assert Policies.get_policy_bodies() == [] + + assert APPLICATION_CONFIG in runtime_properties + assert APPLICATION_CONFIG in ctx.node.properties + app_config = runtime_properties[APPLICATION_CONFIG] + expected_config = dict(ctx.node.properties[APPLICATION_CONFIG]) + ctx.logger.info("expected = default application_config: {0}".format(json.dumps(app_config))) + assert MonkeyedPolicyBody.is_the_same_dict(app_config, expected_config) + assert MonkeyedPolicyBody.is_the_same_dict(expected_config, app_config) + +@pytest.mark.usefixtures("fix_consul") +@cfy_ctx(include_bad=True) +def test_remove_all_policies_twice(): + """test policy_update - remove all policies twice""" + node_configure() + + runtime_properties = ctx.instance.runtime_properties + ctx.logger.info("runtime_properties: {0}".format(json.dumps(runtime_properties))) + + assert dcae_policy.POLICIES in runtime_properties + policies = runtime_properties[dcae_policy.POLICIES] + ctx.logger.info("policies: {0}".format(json.dumps(policies))) + + remove_policy_ids = policies.keys() + + policy_update(updated_policies=None, added_policies=None, removed_policies=remove_policy_ids) + policy_update(updated_policies=None, added_policies=None, removed_policies=remove_policy_ids) + + ctx.logger.info("removed: {0}".format(remove_policy_ids)) + ctx.logger.info("runtime_properties: {0}".format(json.dumps(runtime_properties))) + assert dcae_policy.POLICIES in runtime_properties + assert Policies.get_policy_bodies() == [] + + assert APPLICATION_CONFIG in runtime_properties + assert APPLICATION_CONFIG in ctx.node.properties + app_config = runtime_properties[APPLICATION_CONFIG] + expected_config = dict(ctx.node.properties[APPLICATION_CONFIG]) + ctx.logger.info("expected = default application_config: {0}".format(json.dumps(app_config))) + assert MonkeyedPolicyBody.is_the_same_dict(app_config, expected_config) + assert MonkeyedPolicyBody.is_the_same_dict(expected_config, app_config) + +@pytest.mark.usefixtures("fix_consul") +@cfy_ctx(include_bad=True) +def test_remove_then_update(): + """test policy_update""" + node_configure() + + runtime_properties = ctx.instance.runtime_properties + ctx.logger.info("runtime_properties: {0}".format(json.dumps(runtime_properties))) + + assert dcae_policy.POLICIES in runtime_properties + policies = runtime_properties[dcae_policy.POLICIES] + ctx.logger.info("policies: {0}".format(json.dumps(policies))) + + remove_policy_ids = policies.keys() + policy_update(updated_policies=None, added_policies=None, removed_policies=remove_policy_ids) + + updated_policy = MonkeyedPolicyBody.create_policy(MONKEYED_POLICY_ID_2, 2, priority="aa20") + added_policy = MonkeyedPolicyBody.create_policy(MONKEYED_POLICY_ID_M_2, 2, + False, priority="1") + ctx.logger.info("policy_update: [{0}]".format(json.dumps(updated_policy))) + + ctx.logger.info("policy[{0}]: not yet in policies".format(MONKEYED_POLICY_ID_M_2)) + assert MONKEYED_POLICY_ID_M_2 not in policies + + policy_filter_ids = runtime_properties.get(dcae_policy.POLICY_FILTERS, {}).keys() or ["--"] + + policy_update(updated_policies=[updated_policy], + added_policies={ + policy_filter_ids[0]: { + dcae_policy.POLICIES: {MONKEYED_POLICY_ID_M_2: added_policy}} + }, + removed_policies=[MONKEYED_POLICY_ID_M]) + + ctx.logger.info("policy[{0}]: removed".format(MONKEYED_POLICY_ID_M)) + assert MONKEYED_POLICY_ID_M not in policies + + assert MONKEYED_POLICY_ID_M_2 in policies + policy = policies[MONKEYED_POLICY_ID_M_2] + ctx.logger.info("policy[{0}]: {1}".format(MONKEYED_POLICY_ID_M_2, json.dumps(policy))) + assert MonkeyedPolicyBody.is_the_same_dict(policy, added_policy) + assert MonkeyedPolicyBody.is_the_same_dict(added_policy, policy) + + assert MONKEYED_POLICY_ID_2 in policies + policy = policies[MONKEYED_POLICY_ID_2] + ctx.logger.info("policy[{0}]: {1}".format(MONKEYED_POLICY_ID_2, json.dumps(policy))) + assert MonkeyedPolicyBody.is_the_same_dict(policy, updated_policy) + assert MonkeyedPolicyBody.is_the_same_dict(updated_policy, policy) + + assert MONKEYED_POLICY_ID in policies + assert MONKEYED_POLICY_ID_B in policies + +@pytest.mark.usefixtures("fix_consul") +@cfy_ctx(include_bad=True) +def test_remove_update_many_calcs(): + """test policy_update""" + node_configure() + + runtime_properties = ctx.instance.runtime_properties + ctx.logger.info("runtime_properties: {0}".format(json.dumps(runtime_properties))) + + assert dcae_policy.POLICIES in runtime_properties + policies = runtime_properties[dcae_policy.POLICIES] + ctx.logger.info("policies: {0}".format(json.dumps(policies))) + + remove_policy_ids = policies.keys() + policy_update_many_calcs(updated_policies=None, + added_policies=None, + removed_policies=remove_policy_ids) + + assert dcae_policy.POLICIES in runtime_properties + policies = runtime_properties[dcae_policy.POLICIES] + ctx.logger.info("policies: {0}".format(json.dumps(policies))) + + updated_policy = MonkeyedPolicyBody.create_policy(MONKEYED_POLICY_ID_2, 2, priority="aa20") + added_policy = MonkeyedPolicyBody.create_policy(MONKEYED_POLICY_ID_M_2, 2, + False, priority="1") + ctx.logger.info("policy_update: [{0}]".format(json.dumps(updated_policy))) + + ctx.logger.info("policy[{0}]: not yet in policies".format(MONKEYED_POLICY_ID_M_2)) + assert MONKEYED_POLICY_ID_M_2 not in policies + + policy_filter_ids = runtime_properties.get(dcae_policy.POLICY_FILTERS, {}).keys() or ["--"] + + policy_update_many_calcs(updated_policies=[updated_policy], + added_policies={ + policy_filter_ids[0]: { + dcae_policy.POLICIES: {MONKEYED_POLICY_ID_M_2: added_policy}} + }, + removed_policies=[MONKEYED_POLICY_ID_M]) + + ctx.logger.info("policy[{0}]: removed".format(MONKEYED_POLICY_ID_M)) + assert MONKEYED_POLICY_ID_M not in policies + + assert MONKEYED_POLICY_ID_M_2 in policies + policy = policies[MONKEYED_POLICY_ID_M_2] + ctx.logger.info("policy[{0}]: {1}".format(MONKEYED_POLICY_ID_M_2, json.dumps(policy))) + assert MonkeyedPolicyBody.is_the_same_dict(policy, added_policy) + assert MonkeyedPolicyBody.is_the_same_dict(added_policy, policy) + + assert MONKEYED_POLICY_ID_2 in policies + policy = policies[MONKEYED_POLICY_ID_2] + ctx.logger.info("policy[{0}]: {1}".format(MONKEYED_POLICY_ID_2, json.dumps(policy))) + assert MonkeyedPolicyBody.is_the_same_dict(policy, updated_policy) + assert MonkeyedPolicyBody.is_the_same_dict(updated_policy, policy) + + assert MONKEYED_POLICY_ID in policies + assert MONKEYED_POLICY_ID_B in policies + +@pytest.mark.usefixtures("fix_consul") +@cfy_ctx(include_bad=True) +def test_bad_update_many_calcs(): + """test policy_update""" + node_configure() + + runtime_properties = ctx.instance.runtime_properties + ctx.logger.info("runtime_properties: {0}".format(json.dumps(runtime_properties))) + + assert dcae_policy.POLICIES in runtime_properties + policies = runtime_properties[dcae_policy.POLICIES] + ctx.logger.info("policies: {0}".format(json.dumps(policies))) + + damaged_policy = MonkeyedPolicyBody.create_policy(MONKEYED_POLICY_ID_2, 2, priority="aa20") + damaged_policy[POLICY_BODY][POLICY_CONFIG] = ["damaged config"] + + added_policy = MonkeyedPolicyBody.create_policy(MONKEYED_POLICY_ID_M_2, 2, + False, priority="1") + added_policy[POLICY_BODY][POLICY_CONFIG] = {"unexpected":"foo", "none": None} + + ctx.logger.info("policy_update: [{0}]".format(json.dumps(damaged_policy))) + + ctx.logger.info("policy[{0}]: not yet in policies".format(MONKEYED_POLICY_ID_M_2)) + assert MONKEYED_POLICY_ID_M_2 not in policies + + policy_filter_ids = runtime_properties.get(dcae_policy.POLICY_FILTERS, {}).keys() or ["--"] + + policy_update_many_calcs(updated_policies=[damaged_policy], + added_policies={ + policy_filter_ids[0]: { + dcae_policy.POLICIES: {MONKEYED_POLICY_ID_M_2: added_policy}} + }, + removed_policies=[MONKEYED_POLICY_ID_M]) + + ctx.logger.info("policy[{0}]: removed".format(MONKEYED_POLICY_ID_M)) + assert MONKEYED_POLICY_ID_M not in policies + + assert MONKEYED_POLICY_ID_M_2 in policies + policy = policies[MONKEYED_POLICY_ID_M_2] + ctx.logger.info("policy[{0}]: {1}".format(MONKEYED_POLICY_ID_M_2, json.dumps(policy))) + assert MonkeyedPolicyBody.is_the_same_dict(policy, added_policy) + assert MonkeyedPolicyBody.is_the_same_dict(added_policy, policy) + + assert MONKEYED_POLICY_ID_2 in policies + policy = policies[MONKEYED_POLICY_ID_2] + ctx.logger.info("policy[{0}]: {1}".format(MONKEYED_POLICY_ID_2, json.dumps(policy))) + assert MonkeyedPolicyBody.is_the_same_dict(policy, damaged_policy) + assert MonkeyedPolicyBody.is_the_same_dict(damaged_policy, policy) + + assert MONKEYED_POLICY_ID in policies + policy = policies[MONKEYED_POLICY_ID] + expected_1 = MonkeyedPolicyBody.create_policy(MONKEYED_POLICY_ID, priority="1") + ctx.logger.info("expected[{0}]: {1}".format(MONKEYED_POLICY_ID, json.dumps(expected_1))) + ctx.logger.info("policy[{0}]: {1}".format(MONKEYED_POLICY_ID, json.dumps(policy))) + assert MonkeyedPolicyBody.is_the_same_dict(policy, expected_1) + assert MonkeyedPolicyBody.is_the_same_dict(expected_1, policy) + + assert MONKEYED_POLICY_ID_B in policies + policy = policies[MONKEYED_POLICY_ID_B] + expected_b = MonkeyedPolicyBody.create_policy(MONKEYED_POLICY_ID_B, 4, priority="1.5") + ctx.logger.info("expected[{0}]: {1}".format(MONKEYED_POLICY_ID_B, json.dumps(expected_1))) + ctx.logger.info("policy[{0}]: {1}".format(MONKEYED_POLICY_ID_B, json.dumps(policy))) + assert MonkeyedPolicyBody.is_the_same_dict(policy, expected_b) + assert MonkeyedPolicyBody.is_the_same_dict(expected_b, policy) + +@pytest.mark.usefixtures("fix_consul") +@cfy_ctx(include_bad=True, include_good=False) +def test_bad_policies(): + """test bad policy nodes""" + node_configure() + + runtime_properties = ctx.instance.runtime_properties + ctx.logger.info("runtime_properties: {0}".format(json.dumps(runtime_properties))) + + assert dcae_policy.POLICIES in runtime_properties + policies = runtime_properties[dcae_policy.POLICIES] + ctx.logger.info("policies: {0}".format(json.dumps(policies))) + +@pytest.mark.usefixtures("fix_consul") +@cfy_ctx(include_bad=True, include_good=False) +def test_wrong_ctx_node_configure(): + """test wrong ctx""" + current_ctx.set(ctx.instance.relationships[0]) + ctx_type = ctx.type + + with pytest.raises(NonRecoverableError) as excinfo: + node_configure() + + CurrentCtx.reset() + ctx.logger.info("{0} not a node boom: {1}".format(ctx_type, str(excinfo.value))) + assert ctx_type == 'cloudify.relationships.depends_on' + assert str(excinfo.value) == "can only invoke gather_policies_to_node on node" + +@pytest.mark.usefixtures("fix_consul") +@cfy_ctx(include_bad=True, include_good=False) +def test_wrong_ctx_policy_update(): + """test wrong ctx""" + no_policies = Policies.get_policy_bodies() + current_ctx.set(ctx.instance.relationships[0]) + ctx_type = ctx.type + + with pytest.raises(NonRecoverableError) as excinfo: + policy_update(updated_policies=None, added_policies=None, removed_policies=None) + + CurrentCtx.reset() + ctx.logger.info("{0} not a node boom: {1}".format(ctx_type, str(excinfo.value))) + assert ctx_type == 'cloudify.relationships.depends_on' + assert no_policies == [] + assert str(excinfo.value) == "can only invoke update_policies_on_node on node" + +def test_defenses_on_decorators(): + """test defenses of code mainly for code coverage""" + should_be_none = Policies.gather_policies_to_node()(None) + assert should_be_none is None + + should_be_none = Policies.update_policies_on_node()(None) + assert should_be_none is None + +def monkeyed_set_policies_boom(policies): + """monkeypatch for exception""" + raise Exception("Policies._set_policies boom: {0}".format(json.dumps(policies or {}))) + +@pytest.fixture() +def fix_boom_gather(monkeypatch): + """monkeyed boom""" + monkeypatch.setattr('onap_dcae_dcaepolicy_lib.dcae_policy.Policies._set_policies', + monkeyed_set_policies_boom) + return fix_boom_gather # provide the fixture value + +@cfy_ctx(include_bad=True, include_good=False) +@pytest.mark.usefixtures("fix_boom_gather") +def test_exception_on_gather(): + """test exception on gather""" + with pytest.raises(NonRecoverableError) as excinfo: node_configure() - runtime_properties = ctx.instance.runtime_properties - ctx.logger.info("runtime_properties: {0}".format(json.dumps(runtime_properties))) - - assert POLICIES in runtime_properties - policies = runtime_properties[POLICIES] - ctx.logger.info("policies: {0}".format(json.dumps(policies))) - - assert MONKEYED_POLICY_ID in policies - expected_1 = MonkeyedPolicyBody.create_policy(MONKEYED_POLICY_ID) - policy = policies[MONKEYED_POLICY_ID] - ctx.logger.info("expected[{0}]: {1}".format(MONKEYED_POLICY_ID, json.dumps(expected_1))) - ctx.logger.info("policy[{0}]: {1}".format(MONKEYED_POLICY_ID, json.dumps(policy))) - assert MonkeyedPolicyBody.is_the_same_dict(policy, expected_1) - assert MonkeyedPolicyBody.is_the_same_dict(expected_1, policy) - - assert MONKEYED_POLICY_ID_2 in policies - expected_2 = MonkeyedPolicyBody.create_policy(MONKEYED_POLICY_ID_2) - policy = policies[MONKEYED_POLICY_ID_2] - ctx.logger.info("expected[{0}]: {1}".format(MONKEYED_POLICY_ID_2, json.dumps(expected_2))) - ctx.logger.info("policy[{0}]: {1}".format(MONKEYED_POLICY_ID_2, json.dumps(policy))) - assert MonkeyedPolicyBody.is_the_same_dict(policy, expected_2) - assert MonkeyedPolicyBody.is_the_same_dict(expected_2, policy) - - updated_policy = MonkeyedPolicyBody.create_policy(MONKEYED_POLICY_ID_2, 2) - ctx.logger.info("policy_update: [{0}]".format(json.dumps(updated_policy))) - - policy_update([updated_policy]) - - assert MONKEYED_POLICY_ID_2 in policies - policy = policies[MONKEYED_POLICY_ID_2] - ctx.logger.info("policy[{0}]: {1}".format(MONKEYED_POLICY_ID_2, json.dumps(policy))) - assert MonkeyedPolicyBody.is_the_same_dict(policy, updated_policy) - assert MonkeyedPolicyBody.is_the_same_dict(updated_policy, policy) - - assert MONKEYED_POLICY_ID in policies - policy = policies[MONKEYED_POLICY_ID] - ctx.logger.info("expected[{0}]: {1}".format(MONKEYED_POLICY_ID, json.dumps(expected_1))) - ctx.logger.info("policy[{0}]: {1}".format(MONKEYED_POLICY_ID, json.dumps(policy))) - assert MonkeyedPolicyBody.is_the_same_dict(policy, expected_1) - assert MonkeyedPolicyBody.is_the_same_dict(expected_1, policy) - - finally: - MockCloudifyContextFull.clear() - current_ctx.clear() + ctx.logger.info("monkeyed_set_policies_boom: {0}".format(str(excinfo.value))) + assert str(excinfo.value).startswith("Failed to set the policies ") + +def monkeyed_update_policies_boom(policies): + """monkeypatch for exception""" + raise Exception("Policies._update_policies boom") + +@pytest.fixture() +def fix_boom_update_policies(monkeypatch): + """monkeyed boom""" + monkeypatch.setattr('onap_dcae_dcaepolicy_lib.dcae_policy.Policies._update_policies', + monkeyed_update_policies_boom) + return fix_boom_update_policies # provide the fixture value + +@cfy_ctx(include_bad=True, include_good=False) +@pytest.mark.usefixtures("fix_boom_update_policies") +def test_exception_on_update(): + """test exception on update_policies""" + with pytest.raises(NonRecoverableError) as excinfo: + policy_update(updated_policies=None, added_policies=None, removed_policies=None) + + ctx.logger.info("monkeyed_update_policies_boom: {0}".format(str(excinfo.value))) + assert str(excinfo.value).startswith("Failed to update the policies ") + +@cfy_ctx(include_bad=True, include_good=False) +def test_defenses_on_policy_update(): + """test defenses on policy_update""" + policy_update(updated_policies=None, added_policies=None, removed_policies=None) + ctx.logger.info("policy_update() ok") + +@cfy_ctx(include_bad=True, include_good=False) +def test_defenses_on_set_policies(): + """test defenses of code mainly for code coverage""" + node_configure() + + runtime_properties = ctx.instance.runtime_properties + ctx.logger.info("runtime_properties: {0}".format(json.dumps(runtime_properties))) + + assert dcae_policy.POLICIES in runtime_properties + policies = runtime_properties[dcae_policy.POLICIES] + ctx.logger.info("policies: {0}".format(json.dumps(policies))) + + Policies._set_policies({}) + + assert dcae_policy.POLICIES not in runtime_properties + + Policies._set_policies({}) + + assert dcae_policy.POLICIES not in runtime_properties + +@pytest.mark.usefixtures("fix_consul") +@cfy_ctx(include_bad=True) +def test_delete_node(): + """test delete""" + node_configure() + + runtime_properties = ctx.instance.runtime_properties + ctx.logger.info("runtime_properties: {0}".format(json.dumps(runtime_properties))) + + assert dcae_policy.POLICIES in runtime_properties + policies = runtime_properties[dcae_policy.POLICIES] + ctx.logger.info("policies: {0}".format(json.dumps(policies))) + + node_delete() + + +@pytest.mark.usefixtures("fix_consul_boom") +@cfy_ctx(include_bad=True) +def test_delete_node_no_consul(): + """test delete without consul""" + node_configure() + + runtime_properties = ctx.instance.runtime_properties + ctx.logger.info("runtime_properties: {0}".format(json.dumps(runtime_properties))) + + assert dcae_policy.POLICIES in runtime_properties + policies = runtime_properties[dcae_policy.POLICIES] + ctx.logger.info("policies: {0}".format(json.dumps(policies))) + + node_delete() + + +@pytest.mark.usefixtures("fix_consul_boom") +@cfy_ctx(include_bad=True) +def test_delete_node_no_policies(): + """test delete without consul and setup""" + + ctx.instance.runtime_properties[PoliciesOutput.POLICIES_EVENT] = {} + ctx.instance.runtime_properties[PoliciesOutput.SERVICE_COMPONENT_NAME] = "delete_node_empty" + + runtime_properties = ctx.instance.runtime_properties + ctx.logger.info("runtime_properties: {0}".format(json.dumps(runtime_properties))) + + assert dcae_policy.POLICIES not in runtime_properties + + node_delete() + + +@pytest.mark.usefixtures("fix_consul_boom") +@cfy_ctx(include_bad=True) +def test_delete_node_empty(): + """test delete without consul and setup""" + runtime_properties = ctx.instance.runtime_properties + ctx.logger.info("runtime_properties: {0}".format(json.dumps(runtime_properties))) + + assert dcae_policy.POLICIES not in runtime_properties + + node_delete() + +@pytest.mark.usefixtures("fix_consul_boom") +@cfy_ctx(include_bad=True) +def test_delete_node_lost_scn(): + """test delete without consul and setup""" + ctx.instance.runtime_properties[PoliciesOutput.POLICIES_EVENT] = {} + + runtime_properties = ctx.instance.runtime_properties + ctx.logger.info("runtime_properties: {0}".format(json.dumps(runtime_properties))) + + assert dcae_policy.POLICIES not in runtime_properties + + node_delete() + + +@pytest.mark.usefixtures("fix_consul_boom") +@cfy_ctx(include_bad=True) +def test_delete_node_empty_config(): + """test delete without consul and setup""" + + ctx.instance.runtime_properties[PoliciesOutput.POLICIES_EVENT] = {} + ctx.instance.runtime_properties[PoliciesOutput.SERVICE_COMPONENT_NAME] = "delete_node_empty" + + runtime_properties = ctx.instance.runtime_properties + ctx.logger.info("runtime_properties: {0}".format(json.dumps(runtime_properties))) + + assert dcae_policy.POLICIES not in runtime_properties + + node_delete() + +@pytest.mark.usefixtures("fix_consul_boom") +@cfy_ctx(include_bad=True) +def test_delete_ms_no_consul_addr(): + """test delete without consul and setup""" + + ctx.instance.runtime_properties[PoliciesOutput.POLICIES_EVENT] = {} + ctx.instance.runtime_properties[PoliciesOutput.SERVICE_COMPONENT_NAME] = "delete_node_empty" + + runtime_properties = ctx.instance.runtime_properties + ctx.logger.info("runtime_properties: {0}".format(json.dumps(runtime_properties))) + + assert dcae_policy.POLICIES not in runtime_properties + + node_delete() + + +@pytest.mark.usefixtures("fix_consul_boom") +@cfy_ctx(include_bad=True) +def test_delete_bad_config(): + """test delete without consul and setup""" + + ctx.instance.runtime_properties[PoliciesOutput.POLICIES_EVENT] = {} + ctx.instance.runtime_properties[PoliciesOutput.SERVICE_COMPONENT_NAME] = "delete_node_empty" + + runtime_properties = ctx.instance.runtime_properties + ctx.logger.info("runtime_properties: {0}".format(json.dumps(runtime_properties))) + + assert dcae_policy.POLICIES not in runtime_properties + + node_delete() + diff --git a/onap-dcae-dcaepolicy-lib/tox-local.ini b/onap-dcae-dcaepolicy-lib/tox-local.ini index ed9879a..41d5708 100644 --- a/onap-dcae-dcaepolicy-lib/tox-local.ini +++ b/onap-dcae-dcaepolicy-lib/tox-local.ini @@ -1,3 +1,4 @@ +# tox -c tox-local.ini | tee -a logs/test_onap_dcae_dcaepolicy_lib.log 2>&1 [tox] envlist = py27 @@ -12,5 +13,3 @@ setenv = PYTHONPATH={toxinidir} # recreate = True commands=pytest -v --cov onap_dcae_dcaepolicy_lib --cov-report html - - diff --git a/onap-dcae-dcaepolicy-lib/tox.ini b/onap-dcae-dcaepolicy-lib/tox.ini index 78af290..9bace46 100644 --- a/onap-dcae-dcaepolicy-lib/tox.ini +++ b/onap-dcae-dcaepolicy-lib/tox.ini @@ -11,4 +11,11 @@ deps= pytest-cov setenv = PYTHONPATH={toxinidir} -commands=pytest --junitxml xunit-reports/xunit-result-onap_dcae_dcaepolicy_lib.xml --cov onap_dcae_dcaepolicy_lib --cov-report=xml +whitelist_externals= + rm + mkdir +commands= + rm -rf {toxinidir}/logs + mkdir {toxinidir}/logs + pytest --junitxml xunit-results.xml --cov onap_dcae_dcaepolicy_lib --cov-report xml + coverage xml @@ -38,28 +38,16 @@ ECOMP is a trademark and service mark of AT&T Intellectual Property. <module>onap-dcae-dcaepolicy-lib</module> <module>python-discovery-client</module> <module>python-dockering</module> + <module>dcaeapplib</module> + <module>eelf-logger</module> </modules> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> - <sonar.skip>true</sonar.skip> - <sonar.sources>*/</sonar.sources> - <sonar.junit.reportsPath>**/xunit-results.xml</sonar.junit.reportsPath> - <sonar.python.coverage.reportPath>**/coverage.xml</sonar.python.coverage.reportPath> <!-- customize the SONARQUBE URL --> <sonar.host.url>http://localhost:9000</sonar.host.url> - <sonar.exclusions>tests/*</sonar.exclusions> - <!-- below are language dependent --> - <!-- for Python --> - <sonar.language>py</sonar.language> - <sonar.pluginName>Python</sonar.pluginName> - <sonar.inclusions>**/*.py</sonar.inclusions> - <!-- for JavaScaript --> - <!-- - <sonar.language>js</sonar.language> - <sonar.pluginName>JS</sonar.pluginName> - <sonar.inclusions>**/*.js</sonar.inclusions> - --> + <!-- taken care of in the children --> + <sonar.exclusions>**/*.py</sonar.exclusions> </properties> <build> <finalName>${project.artifactId}-${project.version}</finalName> diff --git a/python-discovery-client/pom.xml b/python-discovery-client/pom.xml index b420626..0854b5a 100644 --- a/python-discovery-client/pom.xml +++ b/python-discovery-client/pom.xml @@ -40,7 +40,7 @@ ECOMP is a trademark and service mark of AT&T Intellectual Property. <sonar.language>py</sonar.language> <sonar.pluginName>Python</sonar.pluginName> <sonar.inclusions>**/*.py</sonar.inclusions> - <sonar.exclusions>tests/*</sonar.exclusions> + <sonar.exclusions>tests/*,setup.py</sonar.exclusions> </properties> <build> <finalName>${project.artifactId}-${project.version}</finalName> diff --git a/python-discovery-client/setup.py b/python-discovery-client/setup.py index 8648808..5a044ee 100644 --- a/python-discovery-client/setup.py +++ b/python-discovery-client/setup.py @@ -18,8 +18,6 @@ # ECOMP is a trademark and service mark of AT&T Intellectual Property. from setuptools import setup, find_packages -from pip.req import parse_requirements -from pip.download import PipSession setup( name = "onap-dcae-discovery-client", diff --git a/python-discovery-client/tox.ini b/python-discovery-client/tox.ini index 5b492c9..d8386d8 100644 --- a/python-discovery-client/tox.ini +++ b/python-discovery-client/tox.ini @@ -7,4 +7,8 @@ deps= pytest coverage pytest-cov -commands=pytest --junitxml xunit-results.xml --cov {envsitepackagesdir}/discovery_client --cov-report=xml +setenv= + PYTHONPATH={toxinidir} +commands= + pytest --junitxml xunit-results.xml --cov discovery_client --cov-report=xml + coverage xml diff --git a/python-dockering/pom.xml b/python-dockering/pom.xml index aa24d9c..7dd0de5 100644 --- a/python-dockering/pom.xml +++ b/python-dockering/pom.xml @@ -40,7 +40,7 @@ ECOMP is a trademark and service mark of AT&T Intellectual Property. <sonar.language>py</sonar.language> <sonar.pluginName>Python</sonar.pluginName> <sonar.inclusions>**/*.py</sonar.inclusions> - <sonar.exclusions>tests/*</sonar.exclusions> + <sonar.exclusions>tests/*,setup.py</sonar.exclusions> </properties> <build> <finalName>${project.artifactId}-${project.version}</finalName> diff --git a/python-dockering/tox.ini b/python-dockering/tox.ini index 280cf78..71de279 100644 --- a/python-dockering/tox.ini +++ b/python-dockering/tox.ini @@ -7,4 +7,8 @@ deps= pytest coverage pytest-cov -commands=pytest --junitxml xunit-results.xml --cov {envsitepackagesdir}/dockering --cov-report=xml +setenv= + PYTHONPATH={toxinidir} +commands= + pytest --junitxml xunit-results.xml --cov dockering --cov-report xml + coverage xml diff --git a/scripts/mvn-phase-lib.sh b/scripts/mvn-phase-lib.sh index 6cef83e..2bf82bd 100644 --- a/scripts/mvn-phase-lib.sh +++ b/scripts/mvn-phase-lib.sh @@ -1,7 +1,7 @@ #!/bin/bash # ================================================================================ -# Copyright (c) 2017 AT&T Intellectual Property. All rights reserved. +# Copyright (c) 2017-2018 AT&T Intellectual Property. All rights reserved. # ================================================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -15,8 +15,6 @@ # See the License for the specific language governing permissions and # limitations under the License. # ============LICENSE_END========================================================= -# -# ECOMP is a trademark and service mark of AT&T Intellectual Property. #MVN_PROJECT_MODULEID="$1" @@ -52,16 +50,18 @@ if [ -z "$WORKSPACE" ]; then WORKSPACE=$(pwd) fi -if [ -z "$SETTINGS_FILE" ]; then - echo "SETTINGS_FILE environment variable not set. Cannot proceed" - exit -fi +export SETTINGS_FILE=${SETTINGS_FILE:-$HOME/.m2/settings.xml} +RELEASE_TAG=${MVN_RELEASE_TAG:-R3} +if [ "$RELEASE_TAG" == "R1" ]; then + unset RELEASE_TAG +fi # mvn phase in life cycle MVN_PHASE="$2" +echo "MVN_RELEASE_TAG is [$MVN_RELEASE_TAG]" echo "MVN_PROJECT_MODULEID is [$MVN_PROJECT_MODULEID]" echo "MVN_PHASE is [$MVN_PHASE]" echo "MVN_PROJECT_GROUPID is [$MVN_PROJECT_GROUPID]" @@ -76,7 +76,6 @@ echo "MVN_RAWREPO_SERVERID is [$MVN_RAWREPO_SERVERID]" echo "MVN_DOCKERREGISTRY_SNAPSHOT is [$MVN_DOCKERREGISTRY_SNAPSHOT]" echo "MVN_DOCKERREGISTRY_PUBLIC is [$MVN_DOCKERREGISTRY_PUBLIC]" echo "MVN_DOCKERREGISTRY_RELEASE is [$MVN_DOCKERREGISTRY_RELEASE]" - echo "MVN_PYPISERVER_SERVERID [$MVN_PYPISERVER_SERVERID]" echo "MVN_PYPISERVER_BASEURL is [$MVN_PYPISERVER_BASEURL]" @@ -108,19 +107,30 @@ expand_templates() export ONAPTEMPLATE_RAWREPOURL_org_onap_ccsdk_platform_plugins_snapshots="$MVN_RAWREPO_BASEURL_DOWNLOAD/org.onap.ccsdk.platform.plugins" export ONAPTEMPLATE_RAWREPOURL_org_onap_ccsdk_platform_blueprints_releases="$MVN_RAWREPO_BASEURL_DOWNLOAD/org.onap.ccsdk.platform.blueprints" export ONAPTEMPLATE_RAWREPOURL_org_onap_ccsdk_platform_blueprints_snapshots="$MVN_RAWREPO_BASEURL_DOWNLOAD/org.onap.ccsdk.platform.blueprints" - - export ONAPTEMPLATE_RAWREPOURL_org_onap_dcaegen2_releases="$MVN_RAWREPO_BASEURL_DOWNLOAD/org.onap.dcaegen2/releases" - export ONAPTEMPLATE_RAWREPOURL_org_onap_dcaegen2_snapshots="$MVN_RAWREPO_BASEURL_DOWNLOAD/org.onap.dcaegen2/snapshots" - export ONAPTEMPLATE_RAWREPOURL_org_onap_dcaegen2_platform_plugins_releases="$MVN_RAWREPO_BASEURL_DOWNLOAD/org.onap.dcaegen2.platform.plugins/releases" - export ONAPTEMPLATE_RAWREPOURL_org_onap_dcaegen2_platform_plugins_snapshots="$MVN_RAWREPO_BASEURL_DOWNLOAD/org.onap.dcaegen2.platform.plugins/snapshots" - export ONAPTEMPLATE_RAWREPOURL_org_onap_dcaegen2_platform_blueprints_releases="$MVN_RAWREPO_BASEURL_DOWNLOAD/org.onap.dcaegen2.platform.blueprints/releases" - export ONAPTEMPLATE_RAWREPOURL_org_onap_dcaegen2_platform_blueprints_snapshots="$MVN_RAWREPO_BASEURL_DOWNLOAD/org.onap.dcaegen2.platform.blueprints/snapshots" + + + if [ -z "$RELEASE_TAG" ]; then + export ONAPTEMPLATE_RAWREPOURL_org_onap_dcaegen2_releases="$MVN_RAWREPO_BASEURL_DOWNLOAD/org.onap.dcaegen2/releases" + export ONAPTEMPLATE_RAWREPOURL_org_onap_dcaegen2_snapshots="$MVN_RAWREPO_BASEURL_DOWNLOAD/org.onap.dcaegen2/snapshots" + export ONAPTEMPLATE_RAWREPOURL_org_onap_dcaegen2_platform_plugins_releases="$MVN_RAWREPO_BASEURL_DOWNLOAD/org.onap.dcaegen2.platform.plugins/releases" + export ONAPTEMPLATE_RAWREPOURL_org_onap_dcaegen2_platform_plugins_snapshots="$MVN_RAWREPO_BASEURL_DOWNLOAD/org.onap.dcaegen2.platform.plugins/snapshots" + export ONAPTEMPLATE_RAWREPOURL_org_onap_dcaegen2_platform_blueprints_releases="$MVN_RAWREPO_BASEURL_DOWNLOAD/org.onap.dcaegen2.platform.blueprints/releases" + export ONAPTEMPLATE_RAWREPOURL_org_onap_dcaegen2_platform_blueprints_snapshots="$MVN_RAWREPO_BASEURL_DOWNLOAD/org.onap.dcaegen2.platform.blueprints/snapshots" + else + export ONAPTEMPLATE_RAWREPOURL_org_onap_dcaegen2_releases="$MVN_RAWREPO_BASEURL_DOWNLOAD/org.onap.dcaegen2/$RELEASE_TAG" + export ONAPTEMPLATE_RAWREPOURL_org_onap_dcaegen2_snapshots="$MVN_RAWREPO_BASEURL_DOWNLOAD/org.onap.dcaegen2/$RELEASE_TAG" + export ONAPTEMPLATE_RAWREPOURL_org_onap_dcaegen2_platform_plugins_releases="$MVN_RAWREPO_BASEURL_DOWNLOAD/org.onap.dcaegen2.platform.plugins/$RELEASE_TAG" + export ONAPTEMPLATE_RAWREPOURL_org_onap_dcaegen2_platform_plugins_snapshots="$MVN_RAWREPO_BASEURL_DOWNLOAD/org.onap.dcaegen2.platform.plugins/$RELEASE_TAG" + export ONAPTEMPLATE_RAWREPOURL_org_onap_dcaegen2_platform_blueprints_releases="$MVN_RAWREPO_BASEURL_DOWNLOAD/org.onap.dcaegen2.platform.blueprints/$RELEASE_TAG" + export ONAPTEMPLATE_RAWREPOURL_org_onap_dcaegen2_platform_blueprints_snapshots="$MVN_RAWREPO_BASEURL_DOWNLOAD/org.onap.dcaegen2.platform.blueprints/$RELEASE_TAG" + fi + export ONAPTEMPLATE_PYPIURL_org_onap_dcaegen2="${MVN_PYPISERVER_BASEURL}" # docker registry templates are for poll, so use PUBLIC registry - export ONAPTEMPLATE_DOCKERREGURL_org_onap_dcaegen2_releases="$MVN_DOCKERREGISTRY_PUBLIC" - export ONAPTEMPLATE_DOCKERREGURL_org_onap_dcaegen2_snapshots="${MVN_DOCKERREGISTRY_PUBLIC}/snapshots" + export ONAPTEMPLATE_DOCKERREGURL_org_onap_dcaegen2_releases="${MVN_DOCKERREGISTRY_PUBLIC}" + export ONAPTEMPLATE_DOCKERREGURL_org_onap_dcaegen2_snapshots="${MVN_DOCKERREGISTRY_PUBLIC}" # Mvn repo export ONAPTEMPLATE_MVN_org_onap_dcaegen2_analytics_tca_snapshots="${MVN_NEXUSPROXY}/service/local/repositories/snapshots/content/org/onap/dcaegen2/analytics/tca" @@ -171,7 +181,7 @@ expand_templates() echo "====> Resolving the following template from environment variables " echo "$TEMPLATES" for KEY in $TEMPLATES; do - VALUE1=$(eval 'echo "$"'"$KEY"'"' | sed 1q) + VALUE1=$(eval 'echo "$'"$KEY"'"' | sed 1q) VALUE2=$(eval 'echo "$'"$KEY"'"' | sed -e 's/\//\\\//g' -e 's/$/\\/' -e '$s/\\$//') echo "======> Resolving template $KEY to value $VALUE1 for file $F2" @@ -191,12 +201,12 @@ test_templates() find . -name '*-template' | sed -e 's/-template$//' | while read file do - egrep '^ - .?https?://' < $file + egrep '^ - .?https?://' < "$file" done | awk '{print $2}' | sed -e 's/"//g' | sort -u | while read url do - curl -L -w '%{http_code}' -s -o /dev/null "$url" > $TMP - case $(< $TMP) in + curl -L -w '%{http_code}' -s -o /dev/null "$url" > "$TMP" + case $(< "$TMP") in 2* ) ;; * ) echo ">>>>>>>>>>>>>>>> $url not found <<<<<<<<<<<<<<<<" ;; esac @@ -207,14 +217,14 @@ test_templates() find . -name '*-template' | sed -e 's/-template$//' | while read blueprint do - check-blueprint-vs-input -b $blueprint -i check-blueprint-vs-input/lib/sample-inputs.yaml || true + check-blueprint-vs-input -b "$blueprint" -i check-blueprint-vs-input/lib/sample-inputs.yaml || true done } run_tox_test() { - set -x + set -e -x CURDIR=$(pwd) TOXINIS=$(find . -name "tox.ini") for TOXINI in "${TOXINIS[@]}"; do @@ -223,8 +233,9 @@ run_tox_test() rm -rf ./venv-tox ./.tox virtualenv ./venv-tox source ./venv-tox/bin/activate - pip install --upgrade pip - pip install --upgrade tox argparse + pip install pip==9.0.3 + pip install --upgrade argparse + pip install tox==2.9.1 pip freeze tox deactivate @@ -250,17 +261,40 @@ build_wagons() echo "In $PLUGIN_DIR, build plugin $PLUGIN_NAME, version $PLUGIN_VERSION" - wagon create --format tar.gz "${PLUGIN_DIR}" + wagon create -r "${PLUGIN_DIR}/requirements.txt" --format tar.gz "${PLUGIN_DIR}" PKG_FILE_NAMES=( "${PLUGIN_NAME}-${PLUGIN_VERSION}"*.wgn ) echo Built package: "${PKG_FILE_NAMES[@]}" - cd $CURDIR + cd "$CURDIR" done deactivate rm -rf venv-pkg } +build_archives_for_wagons() +{ + rm -rf ./*.tgz ./*.zip venv-pkg + + SETUPFILES=$(find "$(pwd)" -name "setup.py") + CURDIR=$(pwd) + for SETUPFILE in $SETUPFILES; do + PLUGIN_FULL_DIR=$(dirname "$SETUPFILE") + PLUGIN_BASE_DIR=$(basename "$PLUGIN_FULL_DIR") + PLUGIN_NAME=$(grep 'name' "$SETUPFILE" | cut -f2 -d'=' | sed 's/[^0-9a-zA-Z\.]*//g') + PLUGIN_VERSION=$(grep 'version' "$SETUPFILE" | cut -f2 -d'=' | sed 's/[^0-9\.]*//g') + + cd "${PLUGIN_FULL_DIR}"/.. + echo "In $(pwd), build plugin zip $PLUGIN_NAME, version $PLUGIN_VERSION" + + zip -r "${PLUGIN_NAME}-${PLUGIN_VERSION}.zip" "./${PLUGIN_BASE_DIR}" + tar -czvf "${PLUGIN_NAME}-${PLUGIN_VERSION}.tgz" "./${PLUGIN_BASE_DIR}" + + echo "Built archives for package ${PLUGIN_NAME}-${PLUGIN_VERSION} at $(pwd)" + cd "$CURDIR" + done +} + upload_raw_file() { @@ -280,6 +314,10 @@ upload_raw_file() OUTPUT_FILE_TYPE='text/x-shellscript' elif [ "$EXT" == 'gz' ]; then OUTPUT_FILE_TYPE='application/gzip' + elif [ "$EXT" == 'tgz' ]; then + OUTPUT_FILE_TYPE='application/gzip' + elif [ "$EXT" == 'zip' ]; then + OUTPUT_FILE_TYPE='application/zip' elif [ "$EXT" == 'wgn' ]; then OUTPUT_FILE_TYPE='application/gzip' else @@ -294,17 +332,13 @@ upload_raw_file() else PROJECT_NAME=${FQDN} fi - if [ "$MVN_DEPLOYMENT_TYPE" == 'SNAPSHOT' ]; then - SEND_TO="${REPO}/${PROJECT_NAME}/snapshots" - elif [ "$MVN_DEPLOYMENT_TYPE" == 'STAGING' ]; then - SEND_TO="${REPO}/${PROJECT_NAME}/releases" + + if [ -z "$RELEASE_TAG" ]; then + SEND_TO="${REPO}/${PROJECT_NAME}" else - echo "Unreconfnized deployment type, quit" - exit + SEND_TO="${REPO}/${PROJECT_NAME}/${RELEASE_TAG}" fi - #if [ ! -z "$MVN_PROJECT_MODULEID" ]; then - # SEND_TO="$SEND_TO/$MVN_PROJECT_MODULEID" - #fi + if [ ! -z "$2" ]; then SEND_TO="$SEND_TO/$2" fi @@ -314,7 +348,36 @@ upload_raw_file() curl -vkn --netrc-file "${NETRC}" --upload-file "${OUTPUT_FILE}" -X PUT -H "Content-Type: $OUTPUT_FILE_TYPE" "${SEND_TO}/${OUTPUT_FILE}" } +upload_wagon_archives() +{ + SETUPFILES=$(find "$(pwd)" -name "setup.py") + CURDIR=$(pwd) + for SETUPFILE in $SETUPFILES; do + PLUGIN_FULL_DIR=$(dirname "$SETUPFILE") + PLUGIN_BASE_DIR=$(basename "$PLUGIN_FULL_DIR") + PLUGIN_NAME=$(grep 'name' "$SETUPFILE" | cut -f2 -d'=' | sed 's/[^0-9a-zA-Z\.]*//g') + PLUGIN_VERSION=$(grep 'version' "$SETUPFILE" | cut -f2 -d'=' | sed 's/[^0-9\.]*//g') + + cd "${PLUGIN_FULL_DIR}"/.. + echo "In $(pwd), upload zip archive for $PLUGIN_NAME, version $PLUGIN_VERSION" + ARCHIVE_FILE_NAME="${PLUGIN_NAME}-${PLUGIN_VERSION}.zip" + if [ -z "$ARCHIVE_FILE_NAME" ]; then + echo "!!! No zip archive file found ${ARCHIVE_FILE_NAME}" + exit -1 + fi + upload_raw_file "${ARCHIVE_FILE_NAME}" "${PLUGIN_NAME}/${PLUGIN_VERSION}" + echo "In $(pwd), upload tgz archive for $PLUGIN_NAME, version $PLUGIN_VERSION" + ARCHIVE_FILE_NAME="${PLUGIN_NAME}-${PLUGIN_VERSION}.tgz" + if [ -z "$ARCHIVE_FILE_NAME" ]; then + echo "!!! No tgz archive file found ${ARCHIVE_FILE_NAME}" + exit -1 + fi + upload_raw_file "${ARCHIVE_FILE_NAME}" "${PLUGIN_NAME}/${PLUGIN_VERSION}" + + cd "${CURDIR}" + done +} upload_wagons_and_type_yamls() { @@ -341,19 +404,18 @@ upload_wagons_and_type_yamls() cp -f "$TYPEFILE_NAME" "$NEWFILENAME" fi - TYPEFILE_PACKAGE_VERSION=$(grep -R 'package_version' $TYPEFILE_NAME |cut -f2 -d ':' |sed -r 's/\s+//g') - WAGONFILE_NAME=$(ls -1 $PLUGIN_NAME-$TYPEFILE_PACKAGE_VERSION-*.wgn) + TYPEFILE_PACKAGE_VERSION=$(grep -R 'package_version' "$TYPEFILE_NAME" |cut -f2 -d ':' |sed -r 's/\s+//g') + WAGONFILE_NAME=$(ls -1 "${PLUGIN_NAME}"-"${TYPEFILE_PACKAGE_VERSION}"-*.wgn) if [ -z "$WAGONFILE_NAME" ]; then echo "!!! No wagonfile found with matching package name and version as required in typefile: " echo " $TYPEFILE_NAME plugin $PLUGIN_NAME package version ${TYPEFILE_PACKAGE_VERSION}" exit -1 fi - upload_raw_file "$NEWFILENAME" type_files/${PLUGIN_NAME}/${PLUGIN_VERSION_MAJOR} - upload_raw_file "$NEWFILENAME" type_files/${PLUGIN_NAME}/${PLUGIN_VERSION_MAJOR_MINOR} - upload_raw_file "${WAGONFILE_NAME}" "plugins/${PLUGIN_NAME}" + upload_raw_file "${NEWFILENAME}" "${PLUGIN_NAME}/${PLUGIN_VERSION}" + upload_raw_file "${WAGONFILE_NAME}" "${PLUGIN_NAME}/${PLUGIN_VERSION}" - rm -r $WAGONFILE_NAME + rm -r "$WAGONFILE_NAME" if [ "$TYPEFILE_NAME" != "$NEWFILENAME" ]; then rm -f "$NEWFILENAME" fi @@ -367,6 +429,13 @@ upload_files_of_extension() upload_raw_file "$F" "$2" done } +upload_files_of_extension_recursively() +{ + FILES=$(find . -name "*.$1") + for F in $FILES ; do + upload_raw_file "$F" "$2" + done +} generate_pypirc_then_publish() @@ -398,9 +467,22 @@ EOL +# following the https://wiki.onap.org/display/DW/Independent+Versioning+and+Release+Process +#IndependentVersioningandReleaseProcess-StandardizedDockerTagging build_and_push_docker() { - IMAGENAME="onap/${FQDN}.${MVN_PROJECT_MODULEID}" + # Old tagging + #IMAGENAME="onap/${FQDN}.${MVN_PROJECT_MODULEID}" + # new tagging + ENDID=$(echo $FQDN | rev | cut -f1 -d '.' |rev) + if [ "$ENDID" == "${MVN_PROJECT_MODULEID}" ]; then + #IMAGENAME="onap/${FQDN/org.onap./}" + IMAGENAME="onap/${FQDN}" + else + #IMAGENAME="onap/${FQDN/org.onap./}.${MVN_PROJECT_MODULEID}" + IMAGENAME="onap/${FQDN}.${MVN_PROJECT_MODULEID}" + fi + IMAGENAME=$(echo "$IMAGENAME" | sed -e 's/_*$//g' -e 's/\.*$//g') IMAGENAME=$(echo "$IMAGENAME" | tr '[:upper:]' '[:lower:]') @@ -408,16 +490,16 @@ build_and_push_docker() VERSION="${MVN_PROJECT_VERSION//[^0-9.]/}" VERSION2=$(echo "$VERSION" | cut -f1-2 -d'.') - LFQI="${IMAGENAME}:${VERSION}-${TIMESTAMP}" + LFQI="${IMAGENAME}:${VERSION}-${TIMESTAMP}"Z # build a docker image docker build --rm -f ./Dockerfile -t "${LFQI}" ./ + # all local builds push to SNAPSHOT repo REPO="" if [ $MVN_DEPLOYMENT_TYPE == "SNAPSHOT" ]; then - REPO=$MVN_DOCKERREGISTRY_SNASHOT + REPO=$MVN_DOCKERREGISTRY_SNAPSHOT elif [ $MVN_DEPLOYMENT_TYPE == "STAGING" ]; then - # there seems to be no staging docker registry? set to use SNAPSHOT also - REPO=$MVN_DOCKERREGISTRY_RELEASE + REPO=$MVN_DOCKERREGISTRY_SNAPSHOT else echo "Fail to determine DEPLOYMENT_TYPE" REPO=$MVN_DOCKERREGISTRY_SNAPSHOT @@ -437,19 +519,14 @@ build_and_push_docker() echo docker login "$REPO" -u "$USER" -p "$PASS_PROVIDED" docker login "$REPO" -u "$USER" -p "$PASS" - if [ $MVN_DEPLOYMENT_TYPE == "SNAPSHOT" ]; then - REPO="$REPO/snapshots" - elif [ $MVN_DEPLOYMENT_TYPE == "STAGING" ]; then - # there seems to be no staging docker registry? set to use SNAPSHOT also - #REPO=$MVN_DOCKERREGISTRY_RELEASE - REPO="$REPO" - else - echo "Fail to determine DEPLOYMENT_TYPE" - REPO="$REPO/unknown" - fi - - OLDTAG="${LFQI}" - PUSHTAGS="${REPO}/${IMAGENAME}:${VERSION2}-${TIMESTAMP} ${REPO}/${IMAGENAME}:${VERSION2} ${REPO}/${IMAGENAME}:${VERSION2}-latest" + # local tag is imagename:version-timestamp + OLDTAG="${LFQI}" + # three tags are pushed: + # {imagename}:{semver}-SNAPSHOT-{timestamp}Z this is what CIMAN-132 asks + # {imagename}:{semver} latest of current version, for testing + # {imagename}:latest latest of all, used mainly by csit + # LFQI="${IMAGENAME}:${VERSION}-${TIMESTAMP}"Z + PUSHTAGS="${REPO}/${IMAGENAME}:${VERSION}-SNAPSHOT-${TIMESTAMP}Z ${REPO}/${IMAGENAME}:${VERSION} ${REPO}/${IMAGENAME}:latest" for NEWTAG in ${PUSHTAGS} do echo "tagging ${OLDTAG} to ${NEWTAG}" @@ -459,8 +536,4 @@ build_and_push_docker() OLDTAG="${NEWTAG}" done fi - } - - - diff --git a/scripts/pom.xml b/scripts/pom.xml index 12e71fb..4ff29df 100644 --- a/scripts/pom.xml +++ b/scripts/pom.xml @@ -45,7 +45,7 @@ ECOMP is a trademark and service mark of AT&T Intellectual Property. <sonar.language>py</sonar.language> <sonar.pluginName>Python</sonar.pluginName> <sonar.inclusions>**/*.py</sonar.inclusions> - <sonar.exclusions>tests/*</sonar.exclusions> + <sonar.exclusions>tests/*,setup.py</sonar.exclusions> <sonar.host.url>http://135.205.228.63:9000</sonar.host.url> </properties> <build> |