class SimpleRequestProcessor(object):
    """Processes request payloads from a RequestFactory client. This implementation
    is stateless. A single instance may be reused and is thread-safe.
    """

    # Allows the creation of properly-configured AutoBeans without having to
    # create an AutoBeanFactory with the desired annotations.
    CONFIGURATION = Configuration.Builder().setCategories(EntityProxyCategory,
        ValueProxyCategory, BaseProxyCategory).setNoWrap(EntityProxyId).build()

    def __init__(self, serviceLayer):
        self._service = serviceLayer
        self._exceptionHandler = DefaultExceptionHandler()


    def processPayload(self, payload):
        """Process a payload sent by a RequestFactory client.

        @param payload the payload sent by the client
        @return a payload to return to the client
        """
        req = AutoBeanCodex.decode(FACTORY, RequestMessage, payload).as_()
        responseBean = FACTORY.response()
        # Create a new response envelope, since the state is unknown
        # Return a JSON-formatted payload
        try:
            self.process(req, responseBean.as_())
        except ReportableException, e:
            responseBean = FACTORY.response()
            responseBean.as_().setGeneralFailure(self.createFailureMessage(e).as_())
        return AutoBeanCodex.encode(responseBean).getPayload()
    def createOobMessage(self, domainValues):
        """Encode a list of objects into a self-contained message that can be used for
        out-of-band communication.
        """
        state = RequestState(self._service)

        encodedValues = list()
        for domainValue in domainValues:
            if domainValue is None:
                clientValue = None
            else:
                clientType = self._service.resolveClientType(
                        domainValue.__class__, BaseProxy, True)
                clientValue = state.getResolver().resolveClientValue(
                        domainValue, clientType, set())
            encodedValues.append(EntityCodex.encode(state, clientValue))

        map_ = IdToEntityMap()
        map_.update(state.beans)
        operations = list()
        self.createReturnOperations(operations, state, map_)

        invocation = FACTORY.invocation().as_()
        invocation.setParameters(encodedValues)

        bean = FACTORY.request()
        resp = bean.as_()
        resp.setInvocations(list(invocation))
        resp.setOperations(operations)
        return AutoBeanCodex.encode(bean)
 def decodeOobMessage(self, domainClass, payload):
     """Decode an out-of-band message."""
     proxyType = self._service.resolveClientType(domainClass, BaseProxy, True)
     state = RequestState(self._service)
     message = AutoBeanCodex.decode(FACTORY, RequestMessage, payload).as_()
     self.processOperationMessages(state, message)
     decoded = self.decodeInvocationArguments(state,
             message.getInvocations()[0].getParameters(),
             [proxyType], [domainClass])
     return decoded
Example #4
0
 def getBeanForPayload(self, id_, domainObject=None):
     """Get or create a BaseProxy AutoBean for the given id."""
     if domainObject is None:
         idMessage = AutoBeanCodex.decode(MessageFactoryHolder.FACTORY, IdMessage, id_).as_()
         toReturn = self.getBeansForPayload([idMessage]).get(0)
         return toReturn
     else:
         toReturn = self.beans.get(id_)
         if toReturn is None:
             toReturn = self.createProxyBean(id_, domainObject)
         return toReturn
Example #5
0
 def getBeanForPayload(self, id_, domainObject=None):
     """Get or create a BaseProxy AutoBean for the given id."""
     if domainObject is None:
         idMessage = AutoBeanCodex.decode(MessageFactoryHolder.FACTORY,
                                          IdMessage, id_).as_()
         toReturn = self.getBeansForPayload([idMessage]).get(0)
         return toReturn
     else:
         toReturn = self.beans.get(id_)
         if toReturn is None:
             toReturn = self.createProxyBean(id_, domainObject)
         return toReturn
    def processPayload(self, payload):
        """Process a payload sent by a RequestFactory client.

        @param payload the payload sent by the client
        @return a payload to return to the client
        """
        req = AutoBeanCodex.decode(FACTORY, RequestMessage, payload).as_()
        responseBean = FACTORY.response()
        # Create a new response envelope, since the state is unknown
        # Return a JSON-formatted payload
        try:
            self.process(req, responseBean.as_())
        except ReportableException, e:
            responseBean = FACTORY.response()
            responseBean.as_().setGeneralFailure(self.createFailureMessage(e).as_())
Example #7
0
 def getSerializedProxyId(self, stableId):
     """EntityCodex support. This method is identical to
     {@link IdFactory#getHistoryToken(SimpleProxyId)} except that it
     base64-encodes the server ids.
     <p>
     XXX: Merge this with AbstsractRequestContext's implementation
     """
     bean = MessageFactoryHolder.FACTORY.id()
     ref = bean.as_()
     ref.setTypeToken(self._service.resolveTypeToken(stableId.getProxyClass()))
     if stableId.isSynthetic():
         ref.setStrength(Strength.SYNTHETIC)
         ref.setSyntheticId(stableId.getSyntheticId())
     elif stableId.isEphemeral():
         ref.setStrength(Strength.EPHEMERAL)
         ref.setClientId(stableId.getClientId())
     else:
         ref.setServerId(toBase64(stableId.getServerId()))
     return AutoBeanCodex.encode(bean)
 def processInvocationMessages(self, state, req, results, successes, returnState):
     invocations = req.getInvocations()
     if invocations is None:
         # No method invocations which can happen via RequestContext.fire()
         return
     contextMethods = list()
     invocationResults = list()
     allPropertyRefs = dict()
     for invocation in invocations:
         # Find the Method
         try:
             operation = invocation.getOperation()
             contextMethod = self._service.resolveRequestContextMethod(operation)
             if contextMethod is None:
                 raise UnexpectedException('Cannot resolve operation '
                         + invocation.getOperation(), None)
             contextMethods.append(contextMethod)
             domainMethod = self._service.resolveDomainMethod(operation)
             if domainMethod is None:
                 raise UnexpectedException('Cannot resolve domain method '
                         + invocation.getOperation(), None)
             # Compute the arguments
             args = self.decodeInvocationArguments_(state, invocation, contextMethod)
             # Possibly use a ServiceLocator
             if self._service.requiresServiceLocator(contextMethod, domainMethod):
                 requestContext = self._service.resolveRequestContext(operation)
                 serviceInstance = self._service.createServiceInstance(requestContext)
                 args.add(0, serviceInstance)
             # Invoke it
             domainReturnValue = self._service.invoke(domainMethod, list(args))
             if invocation.getPropertyRefs() is not None:
                 paths = allPropertyRefs[domainReturnValue]
                 if paths is None:
                     paths = set()#TreeSet()
                     allPropertyRefs[domainReturnValue] = paths
                 paths.update(invocation.getPropertyRefs())
             ok = True
         except ReportableException, e:
             domainReturnValue = AutoBeanCodex.encode(self.createFailureMessage(e))
             ok = False
         invocationResults.append(domainReturnValue)
         successes.append(ok)
Example #9
0
 def getSerializedProxyId(self, stableId):
     """EntityCodex support. This method is identical to
     {@link IdFactory#getHistoryToken(SimpleProxyId)} except that it
     base64-encodes the server ids.
     <p>
     XXX: Merge this with AbstsractRequestContext's implementation
     """
     bean = MessageFactoryHolder.FACTORY.id()
     ref = bean.as_()
     ref.setTypeToken(
         self._service.resolveTypeToken(stableId.getProxyClass()))
     if stableId.isSynthetic():
         ref.setStrength(Strength.SYNTHETIC)
         ref.setSyntheticId(stableId.getSyntheticId())
     elif stableId.isEphemeral():
         ref.setStrength(Strength.EPHEMERAL)
         ref.setClientId(stableId.getClientId())
     else:
         ref.setServerId(toBase64(stableId.getServerId()))
     return AutoBeanCodex.encode(bean)