Skip to content
This repository has been archived by the owner on Sep 23, 2020. It is now read-only.

Commit

Permalink
base service and process, service startup
Browse files Browse the repository at this point in the history
  • Loading branch information
mmeisinger committed Apr 19, 2010
1 parent 79ff0f4 commit ab3d9bb
Show file tree
Hide file tree
Showing 9 changed files with 279 additions and 39 deletions.
65 changes: 55 additions & 10 deletions README.txt
@@ -1,18 +1,63 @@
This is the project for the OOI Release 1 LCA architecture prototype.
==================================================
LCAARCH - OOI Release 1 LCA architecture prototype
==================================================

It contains the core services and their architectural dependencies, and relies on selected
external packages, such as Magnet, etc.
April 2010

This project defines the services of the OOI release 1 system with their
architectural dependencies.

This project and relies on selected external packages, such as Magnet, etc.

Get it with
::
git clone git@amoeba.ucsd.edu:lcaarch.git

>git clone git://amoeba.ucsd.edu/lcaarch.git
Usage
=====

Start CC ("Magnet" Python Capability Container) shell in directory with:

>twistd -n magnet -h amoeba.ucsd.edu shell
::
twistd -n magnet -h amoeba.ucsd.edu shell

Start system by executing within the CC shell:

><> from ion.core import bootstrap
><> bootstrap.start()

><>
from ion.core import bootstrap
bootstrap.start()

Start a test case by executing within the CC shell:
><>
from ion import ts
ts.start()

Install the dependencies: Magnet (see Magnet's Readme)
======================================================
Recommendation:
Create a virtualenv for installing Magnet and its dependencies.

Twisted Python
--------------
::
easy_install twisted

txAMQP
------
::
easy_install txamqp

carrot (use txamqp branch)
----------------------
::
git clone git://amoeba.ucsd.edu/carrot.git
(cd carrot; git checkout -b txamqp origin/txamqp)
(cd carrot; python setup.py install)

Install the Magnet package:
---------------------------
Get the latest version of the repository, if you haven't already.
::
git clone git://amoeba.ucsd.edu/magnet.git # no ooi credential
# OR
git clone git@amoeba.ucsd.edu:magnet.git # need ooi credential
(cd magnet; git checkout -b space origin/space)
(cd magnet; python setup.py install)
2 changes: 0 additions & 2 deletions bootstrap.cmd

This file was deleted.

72 changes: 62 additions & 10 deletions ion/core/base_process.py
Expand Up @@ -4,21 +4,63 @@
@file ion/core/base_process.py
@author Michael Meisinger
@author Stephen Pasco
@brief abstract superclass for all processes
@brief base class for all processes within Magnet
"""

import logging

from twisted.python import log
from twisted.internet import defer

from magnet.spawnable import Receiver
from magnet.spawnable import send
from magnet.spawnable import spawn
from magnet.store import Store

import ion.util.procutils as pu

logging.basicConfig(level=logging.DEBUG)
logging.debug('Loaded: '+__name__)

class BaseProcess(object):
"""
This is the abstract superclass for all processes.
"""

store = Store()
receiver = None
procName = __name__
procId = None

def __init__(self, procName=__name__):
"""Constructor using a given name for the spawnable receiver.
"""
logging.debug('BaseProcess.__init__('+procName+')')

self.procName = procName
self.receiver = Receiver(procName)
logging.info('Created receiver: '+str(self.receiver)+" for "+procName)

@defer.inlineCallbacks
def plc_start(self):
"""Performs the start of the process. Creates the actual spawned
process.
@return deferred
"""
logging.info('Process '+self.procName+' plc_start()')

self.procId = yield spawn(self.receiver)
logging.info('Spawned process with id='+str(self.procId))


def op_noop_catch(self, content, headers, msg):
"""The method called if operation is not defined
"""

def receive(self, content, msg):
logging.info('Catch message')


def _dispatch_message(self, content, msg, dispatchIn):
"""
content - content can be anything (list, tuple, dictionary, string, int, etc.)
Expand All @@ -32,18 +74,28 @@ def receive(self, content, msg):
pu.log_message(__name__, content, msg)

if "op" in content:
print 'found \'op\' in content'
op = content['op']
logging.info('BaseProcess._dispatch_message OP='+op)

# TODO: Null error check 'cont'
cont = content['content']
# TODO: Null error check 'op'
op = content['op']

# dynamically invoke the operation

opdef = getattr(self, 'op_' + op)
opdef = getattr(dispatchIn, 'op_' + op)
if opdef != None:
opdef(cont, content, msg)
elif getattr(dispatchIn,'op_noop_catch') == None:
log.error("Receive() failed. Cannot dispatch to catch")
else:
op_noop_catch(cont, content, msg)
dispatchIn.op_noop_catch(cont, content, msg)
else:
log.error("Receive() failed. Bad message", content)


def receive(self, content, msg):
_dispatch_message(content, msg, self)

def send_message(to,operation,content,headers):
"""Send a message via the processes receiver to a
"""
src = procId
pu.send_message(receiver,src,to,operation,content,headers)
2 changes: 1 addition & 1 deletion ion/core/bootstrap.py
Expand Up @@ -47,7 +47,7 @@
@defer.inlineCallbacks
def start():
id = yield spawn(receiver)
store.put('bootstrap', id)
yield store.put('bootstrap', id)
yield op_bootstrap()

@defer.inlineCallbacks
Expand Down
25 changes: 14 additions & 11 deletions ion/services/base_service.py
Expand Up @@ -6,6 +6,8 @@
@package ion.services abstract base classes for all service interfaces, implementations and provider.
"""

import logging

from twisted.python import log
from twisted.internet import defer

Expand All @@ -14,6 +16,9 @@
from magnet.spawnable import spawn
from magnet.store import Store

logging.basicConfig(level=logging.DEBUG)
logging.debug('Loaded: '+__name__)

class BaseService(object):
"""
This is the abstract superclass for all service processes.
Expand All @@ -22,12 +27,9 @@ class BaseService(object):
anywhere in the network and that provides a service.
"""

svcReceiver = None
receiver = None
svcMessages = {}

def __init__(self, rec):
self.svcReceiver = rec


def slc_start(self):
pass

Expand All @@ -43,15 +45,16 @@ def _add_messages(self):
def _add_conv_type(self):
none

class ServiceClient(object):
"""This is the abstract base class for service client libraries.
"""
def op_noop_catch(self, content, headers, msg):
"""The method called if operation is not defined
"""
logging.info('Catch message')

class ServiceInterface(object):
"""This is the abstract base class for all service provider messaging interface.
class BaseServiceClient(object):
"""This is the abstract base class for service client libraries.
"""

class ServiceImplementation(object):
class BaseServiceImplementation(object):
"""This is the abstract base class for all service provider implementations
of a service provider interface.
"""
95 changes: 95 additions & 0 deletions ion/services/base_svcproc.py
@@ -0,0 +1,95 @@
#!/usr/bin/env python

"""
@file ion/services/base_svcproc.py
@author Michael Meisinger
@brief base class for all service processes within Magnet
"""

import logging

from twisted.internet import defer

from ion.core.base_process import BaseProcess

logging.basicConfig(level=logging.DEBUG)
logging.debug('Loaded: '+__name__)

class BaseServiceProcess(BaseProcess):
"""
This is the base class for all service processes.
A service process is a Capability Container process that can be spawned
anywhere in the network and that provides a service.
"""

# Name of the spawnable of the executed process
processName = None

# Fully qualified name of the service module
serviceModule = None

# Name of the service class within service module
serviceName = None

# An instance of the service class
serviceInstance = None

def __init__(self, procName, svcMod, svcName):
"""Constructor.
@param procName public name of the spawnable process
@param svcMod qualified name of the module in which the service class
is, e.g. 'ion.services.coi.resource_registry'
@param svcName name of the service class, e.g. 'ResourceRegistryService'
"""
logging.info('BaseServiceProcess.__init__('+procName+','+svcMod+','+svcName+')')
BaseProcess.__init__(self, procName)

self.processName = procName
self.serviceModule = svcMod
self.serviceName = svcName

localMod = svcMod.rpartition('.')[2]
logging.info('BaseServiceProcess.__init__: from '+self.serviceModule+' import '+localMod+', '+svcName)

svc_mod = __import__(self.serviceModule, globals(), locals(), [localMod,svcName])
#logging.debug('Module: '+str(svc_mod))

svc_class = getattr(svc_mod, svcName)
#logging.debug('Class: '+str(svc_class))

self.serviceInstance = svc_class()
self.serviceInstance.receiver = self.receiver
logging.info('BaseServiceProcess.__init__: created service instance '+str(self.serviceInstance) )


def receive(self, content, msg):
logging.info('BaseServiceProcess.receive()')
self._dispatch_message(content, msg, self.serviceInstance)

# Code below is for starting this base class directly as a process

@defer.inlineCallbacks
def start(svcMod, svcName):
"""Starts a new process and tries to instantiate the given service class
in the given module.
@param svcMod qualified name of the module in which the service class is,
e.g. 'ion.services.coi.resource_registry'
@param svcName name of the service class, e.g. 'ResourceRegistryService'
"""

logging.info('BaseServiceProcess.start: '+svcMod+':'+svcName+' in proc '+__name__)
procInst = BaseServiceProcess(__name__, svcMod, svcName)
procInst.receiver.handle(procInst.receive)

yield procInst.plc_start()
#logging.debug('procInst: '+str(procInst.__dict__))


"""
from ion.services import base_svcproc as b
b.start('ion.services.hello_service','HelloService')
send(1, {'op':'hello','content':'Hello you there!'})
"""
2 changes: 1 addition & 1 deletion ion/services/coi/service_registry.py
Expand Up @@ -3,7 +3,7 @@
"""
@file ion/services/coi/service_registry.py
@author Michael Meisinger
@brief ervice for registering service (types and instances).
@brief service for registering service (types and instances).
"""

from twisted.python import log
Expand Down

0 comments on commit ab3d9bb

Please sign in to comment.