--- /dev/null
+
+#
+# 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")
+
+
+