RIFT OSM R1 Initial Submission
[osm/SO.git] / rwlaunchpad / plugins / rwlaunchpadtasklet / rift / tasklets / rwlaunchpad / message.py
diff --git a/rwlaunchpad/plugins/rwlaunchpadtasklet/rift/tasklets/rwlaunchpad/message.py b/rwlaunchpad/plugins/rwlaunchpadtasklet/rift/tasklets/rwlaunchpad/message.py
new file mode 100644 (file)
index 0000000..a1827eb
--- /dev/null
@@ -0,0 +1,360 @@
+
+# 
+#   Copyright 2016 RIFT.IO Inc
+#
+#   Licensed under the Apache License, Version 2.0 (the "License");
+#   you may not use this file except in compliance with the License.
+#   You may obtain a copy of the License at
+#
+#       http://www.apache.org/licenses/LICENSE-2.0
+#
+#   Unless required by applicable law or agreed to in writing, software
+#   distributed under the License is distributed on an "AS IS" BASIS,
+#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#   See the License for the specific language governing permissions and
+#   limitations under the License.
+#
+
+import logging
+import time
+
+
+class MessageException(Exception):
+    def __init__(self, msg):
+        if not isinstance(msg, Message):
+            raise ValueError("{} is not a message".format(msg.__class__.__name__))
+
+        self.msg = msg
+
+
+class Message(object):
+    """
+    Messages are events that describe stages of the onboarding process, and
+    any event that may occur during the onboarding process.
+    """
+
+    def __init__(self, level, name, text):
+        self._level = level
+        self._name = name
+        self._text = text
+        self._timestamp = time.time()
+
+    def __repr__(self):
+        return "{} {}:{}:{}".format(
+                self.timestamp,
+                logging._levelNames.get(self.level, self.level),
+                self.name,
+                self.text,
+                )
+
+    @property
+    def level(self):
+        return self._level
+
+    @property
+    def name(self):
+        return self._name
+
+    @property
+    def text(self):
+        return self._text
+
+    @property
+    def timestamp(self):
+        return self._timestamp
+
+    def log(self, logger):
+        logger.log(self.level, self.text)
+
+
+class WarningMessage(Message):
+    """
+    A warning is a message that does not prevent the onboarding process for
+    continuing, but may not be the intention of the user when they initiated
+    the process.
+    """
+
+    def __init__(self, name, text):
+        super().__init__(logging.WARNING, name, text)
+
+
+class ErrorMessage(Message):
+    """
+    An error message alerts the user to an event that prevent the continuation
+    of the onboarding process.
+    """
+
+    def __init__(self, name, text):
+        super().__init__(logging.ERROR, name, text)
+
+
+class StatusMessage(Message):
+    """
+    A status message informs the user of an expected stage in the onboarding
+    process.
+    """
+
+    def __init__(self, name, text):
+        super().__init__(logging.INFO, name, text)
+
+
+class FilenameMessage(Message):
+    """
+    A status message informs the user of a download file.
+    """
+
+    def __init__(self, filename):
+        super().__init__(logging.INFO, 'filename', filename)
+
+
+class Logger(object):
+    """
+    This class is used to augment a python logger class so that messages can be
+    passed to it. Messages are recorded so that the uploader application can
+    provide this information to the client, and the messages are also recorded
+    on the server via the standard logging facilities.
+    """
+
+    def __init__(self, logger, messages):
+        self._rift_logger = logger
+        self._messages = messages
+
+    @property
+    def messages(self):
+        return self._messages
+
+    def message(self, msg):
+        msg.log(self._rift_logger)
+        self._messages.append(msg)
+
+    def __getattr__(self, name):
+        """ Return the rift logger attribute
+
+        By returning the rift logger attribute back to the client,
+        the line logged by rwlogger corresponds to the actual file/line
+        logged by the application instead of one in this class.  This makes
+        debugging easier and prevents rwlogd from inadvertantly triggering
+        dup detection (which uses event & line information).
+        """
+        return getattr(self._rift_logger, name)
+
+
+
+class OnboardError(ErrorMessage):
+    def __init__(self, msg):
+        super().__init__("onboard-error", msg)
+
+
+class OnboardWarning(ErrorMessage):
+    def __init__(self, msg):
+        super().__init__("onboard-warning", msg)
+
+
+class OnboardDescriptorValidation(StatusMessage):
+    def __init__(self):
+        super().__init__("onboard-dsc-validation", "descriptor validation")
+
+
+class OnboardDescriptorTimeout(OnboardError):
+    def __init__(self):
+        super().__init__("descriptor timeout")
+
+
+class OnboardDescriptorError(OnboardError):
+    def __init__(self, filename):
+        super().__init__("unable to onboard {}".format(filename))
+
+
+class OnboardDescriptorFormatError(OnboardError):
+    def __init__(self, filename):
+        super().__init__("{} has unrecognized format".format(filename))
+
+
+class OnboardMissingContentType(OnboardError):
+    def __init__(self):
+        super().__init__("missing content-type header")
+
+
+class OnboardUnsupportedMediaType(OnboardError):
+    def __init__(self):
+        super().__init__("multipart/form-data required")
+
+
+class OnboardMissingContentBoundary(OnboardError):
+    def __init__(self):
+        super().__init__("missing content boundary")
+
+
+class OnboardMissingTerminalBoundary(OnboardError):
+    def __init__(self):
+        super().__init__("Unable to find terminal content boundary")
+
+
+class OnboardUnreadableHeaders(OnboardError):
+    def __init__(self):
+        super().__init__("Unable to read message headers")
+
+
+class OnboardUnreadablePackage(OnboardError):
+    def __init__(self):
+        super().__init__("Unable to read package")
+
+
+class OnboardExtractionError(OnboardError):
+    def __init__(self):
+        super().__init__("Unable to extract package contents")
+
+
+class OnboardImageUploadError(OnboardError):
+    def __init__(self, message=""):
+        super().__init__("Unable to upload images: %s" % message)
+
+
+class OnboardMissingChecksumsFile(OnboardError):
+    def __init__(self):
+        super().__init__("Package does not contain checksums.txt")
+
+
+class OnboardChecksumMismatch(OnboardError):
+    def __init__(self, filename):
+        super().__init__("checksum mismatch for {}".format(filename))
+
+
+class OnboardDescriptorExistsError(OnboardError):
+    def __init__(self, descriptor_id):
+        super().__init__("descriptor id {} already onboarded".format(descriptor_id))
+
+
+
+class OnboardStart(StatusMessage):
+    def __init__(self):
+        super().__init__("onboard-started", "onboarding process started")
+
+
+class OnboardDescriptorOnboard(StatusMessage):
+    def __init__(self):
+        super().__init__("onboard-dsc-onboard", "onboarding descriptors")
+
+
+class OnboardSuccess(StatusMessage):
+    def __init__(self):
+        super().__init__("onboard-success", "onboarding process successfully completed")
+
+
+class OnboardFailure(StatusMessage):
+    def __init__(self):
+        super().__init__("onboard-failure", "onboarding process failed")
+
+
+class OnboardPackageUpload(StatusMessage):
+    def __init__(self):
+        super().__init__("onboard-pkg-upload", "uploading package")
+
+
+class OnboardImageUpload(StatusMessage):
+    def __init__(self):
+        super().__init__("onboard-img-upload", "uploading image")
+
+
+class OnboardPackageValidation(StatusMessage):
+    def __init__(self):
+        super().__init__("onboard-pkg-validation", "package contents validation")
+
+
+
+class UpdateError(ErrorMessage):
+    def __init__(self, msg):
+        super().__init__("update-error", msg)
+
+
+class UpdateMissingContentType(UpdateError):
+    def __init__(self):
+        super().__init__("missing content-type header")
+
+
+class UpdateUnsupportedMediaType(UpdateError):
+    def __init__(self):
+        super().__init__("multipart/form-data required")
+
+
+class UpdateMissingContentBoundary(UpdateError):
+    def __init__(self):
+        super().__init__("missing content boundary")
+
+
+class UpdateDescriptorError(UpdateError):
+    def __init__(self, filename):
+        super().__init__("unable to update {}".format(filename))
+
+
+class UpdatePackageNotFoundError(UpdateError):
+    def __init__(self, descriptor_id):
+        super().__init__("package {} not found".format(descriptor_id))
+
+
+class UpdateDescriptorFormatError(UpdateError):
+    def __init__(self, filename):
+        super().__init__("{} has unrecognized format".format(filename))
+
+
+class UpdateExtractionError(UpdateError):
+    def __init__(self):
+        super().__init__("Unable to extract package contents")
+
+
+class UpdateDescriptorTimeout(UpdateError):
+    def __init__(self):
+        super().__init__("descriptor timeout")
+
+
+class UpdateUnreadableHeaders(UpdateError):
+    def __init__(self):
+        super().__init__("Unable to read message headers")
+
+
+class UpdateUnreadablePackage(UpdateError):
+    def __init__(self):
+        super().__init__("Unable to read package")
+
+
+class UpdateChecksumMismatch(UpdateError):
+    def __init__(self, filename):
+        super().__init__("checksum mismatch for {}".format(filename))
+
+
+class UpdateImageUploadError(UpdateError):
+    def __init__(self):
+        super().__init__("Unable to upload images")
+
+
+class UpdateStart(StatusMessage):
+    def __init__(self):
+        super().__init__("update-started", "update process started")
+
+
+class UpdateSuccess(StatusMessage):
+    def __init__(self):
+        super().__init__("update-success", "updating process successfully completed")
+
+
+class UpdateFailure(StatusMessage):
+    def __init__(self):
+        super().__init__("update-failure", "updating process failed")
+
+
+class UpdatePackageUpload(StatusMessage):
+    def __init__(self):
+        super().__init__("update-pkg-upload", "uploading package")
+
+
+class UpdateDescriptorUpdate(StatusMessage):
+    def __init__(self):
+        super().__init__("update-dsc-onboard", "updating descriptors")
+
+
+class UpdateDescriptorUpdated(StatusMessage):
+    def __init__(self):
+        super().__init__("update-dsc-updated", "updated descriptors")
+
+
+