/**
 * Find local service matching filter.
 */
std::set<ServiceDescription> ServiceManager::findLocal(const ServiceFilter& svcFilter) {
	std::set<ServiceDescription> foundSvcs;
	std::map<intptr_t, ServiceDescription>::iterator svcDescIter = _localSvcDesc.begin();
	while(svcDescIter != _localSvcDesc.end()) {
		if (svcFilter.matches(svcDescIter->second)) {
			foundSvcs.insert(svcDescIter->second);
			UM_LOG_INFO("we have a match for %s", svcFilter.getServiceName().c_str());
		}
		svcDescIter++;
	}
	return foundSvcs;
}
void ServiceManager::stopQuery(const ServiceFilter& filter) {
	RScopeLock lock(_mutex);
	if (_localQueries.find(filter) != _localQueries.end()) {
		Message* unqueryMsg = filter.toMessage();
		unqueryMsg->putMeta("um.rpc.type", "stopDiscovery");
		unqueryMsg->putMeta("um.rpc.mgrId", _svcSub->getUUID());
		_svcPub->send(unqueryMsg);
		delete unqueryMsg;
		_localQueries.erase(filter);
	}
}
/**
 * Start a query for a service.
 *
 * Remember service filter and send query to all connected ServiceManagers.
 */
void ServiceManager::startQuery(const ServiceFilter& filter, ResultSet<ServiceDescription>* listener) {
	RScopeLock lock(_mutex);
	_localQueries[filter] = listener;
	Message* queryMsg = filter.toMessage();
	queryMsg->putMeta("um.rpc.type", "startDiscovery");
	queryMsg->putMeta("um.rpc.mgrId", _svcSub->getUUID());

	_svcPub->send(queryMsg);
	UM_LOG_INFO("Sending new query to %d ServiceManagers", _svcPub->waitForSubscribers(0));
	delete queryMsg;
}
ServiceDescription ServiceManager::find(const ServiceFilter& svcFilter, int timeout) {
	if(_svcPub->waitForSubscribers(1, timeout) < 1) {
		// there is no other ServiceManager yet
		UM_LOG_INFO("Failed to find another ServiceManager");
		return ServiceDescription();
	}

	Message* findMsg = svcFilter.toMessage();
	std::string reqId = UUID::getUUID();
	findMsg->putMeta("um.rpc.type", "discover");
	findMsg->putMeta("um.rpc.reqId", reqId.c_str());
	findMsg->putMeta("um.rpc.mgrId", _svcSub->getUUID());
//	Thread::sleepMs(1000);
	if(_findRequests.find(reqId) != _findRequests.end())
		UM_LOG_WARN("Find request %s already received", reqId.c_str());
	_findRequests[reqId] = new Monitor();

	_svcPub->send(findMsg);
	delete findMsg;

	RScopeLock lock(_mutex);
	_findRequests[reqId]->wait(_mutex, timeout);
	delete _findRequests[reqId];
	_findRequests.erase(reqId);

	if (_findResponses.find(reqId) == _findResponses.end()) {
		UM_LOG_INFO("Failed to find %s", svcFilter.getServiceName().c_str());
		return ServiceDescription();
	}

	// TODO: Remove other replies as they come in!

	Message* foundMsg = _findResponses[reqId];
	assert(foundMsg != NULL);
	ServiceDescription svcDesc(foundMsg);
	svcDesc._svcManager = this;
	_findResponses.erase(reqId);
	delete foundMsg;
	return svcDesc;

}
Beispiel #5
0
	/* @brief Do mutual connections */
bool SendHugeData::SearchAndConnectToAnotherOne()
{
	// Store pointer to the filter object
	ServiceFilter * MySearch = And(NameIs("SendHugeData"),Not(PeerIdIs(MyAssociatedService->GetPeerId())));

	// Search for a SendHugeData service that is not me
	ServiceProxy * TheOtherSendHugeData = MyAssociatedService->FindService( MySearch );

	// Free the ServiceFilter. As it is a simple one, call to Empty is not mandatory
	MySearch->Empty();
	delete MySearch;

	if ( TheOtherSendHugeData == (ServiceProxy *)NULL )
	{
		OmiscidError( "Could not find another SendHugeData service.\n" );
		return false;
	}

	MyAssociatedService->ConnectTo( "SendData", TheOtherSendHugeData, "ReceiveData" );

	return true;
}
Beispiel #6
0
void ServiceManager::receive(Message* msg) {
  ScopeLock lock(&_mutex);
	// is this a response for one of our requests?
	if (msg->getMeta().find("respId") != msg->getMeta().end()) {
		string respId = msg->getMeta("respId");
		if (_findRequests.find(respId) != _findRequests.end()) {
			_findResponses[respId] = new Message(*msg);
			_findRequests[respId].signal();
		}
	}

	// is someone asking for a service?
	if (msg->getMeta().find("type") != msg->getMeta().end() &&
	        msg->getMeta("type").compare("serviceDisc") == 0) {
		ServiceFilter* filter = new ServiceFilter(msg);
    std::set<ServiceDescription*> foundSvcs = findLocal(filter);
    delete filter;
    
    if (foundSvcs.size() > 0) {
      ServiceDescription* svcDesc = (*(foundSvcs.begin()));
      Message* foundMsg = svcDesc->toMessage();
      foundMsg->setMeta("respId", msg->getMeta("reqId"));
      foundMsg->setMeta("desc:channel", svcDesc->getChannelName());
      _svcPub->send(foundMsg);
      delete foundMsg;
		}
	}
  
  // is this the start of a continuous query?
  if (msg->getMeta().find("type") != msg->getMeta().end() &&
      msg->getMeta("type").compare("serviceDiscStart") == 0) {
		ServiceFilter* filter = new ServiceFilter(msg);
    _remoteQueries[filter->_uuid] = filter;

    // do we have such a service?
    std::set<ServiceDescription*> foundSvcs = findLocal(filter);
    std::set<ServiceDescription*>::iterator svcDescIter = foundSvcs.begin();
		while(svcDescIter != foundSvcs.end()) {
			if (filter->matches(*svcDescIter)) {
				Message* foundMsg = (*svcDescIter)->toMessage();
				foundMsg->setMeta("filterId", filter->_uuid);
				foundMsg->setMeta("type", "serviceDiscFound");
				foundMsg->setMeta("desc:channel", (*svcDescIter)->getChannelName());
				_svcPub->send(foundMsg);
				delete foundMsg;
			}
			svcDescIter++;
		}
  }
  
  // is this the end of a continuous query?
  if (msg->getMeta().find("type") != msg->getMeta().end() &&
      msg->getMeta("type").compare("serviceDiscStop") == 0) {
		ServiceFilter* filter = new ServiceFilter(msg);
    if (_remoteQueries.find(filter->_uuid) != _remoteQueries.end()) {
      delete _remoteQueries[filter->_uuid];
      _remoteQueries.erase(filter->_uuid);
    }
    delete filter;
  }
  
  // is this a reply to a continuous service query?
  if (msg->getMeta().find("type") != msg->getMeta().end() &&
      (msg->getMeta("type").compare("serviceDiscFound") == 0 || 
       msg->getMeta("type").compare("serviceDiscRemoved") == 0)) {
    // _svcQueries comparator uses filter uuid
    ServiceFilter* keyFilter = new ServiceFilter("");
    keyFilter->_uuid = msg->getMeta("filterId");
    if (_localQueries.find(keyFilter) != _localQueries.end()) {
      ResultSet<ServiceDescription>* listener = _localQueries[keyFilter];
      assert(msg->getMeta("desc:channel").size() > 0);
      if (_remoteSvcDesc.find(msg->getMeta("desc:channel")) == _remoteSvcDesc.end())
        _remoteSvcDesc[msg->getMeta("desc:channel")] = shared_ptr<ServiceDescription>(new ServiceDescription(msg));
      if (msg->getMeta("type").compare("serviceDiscFound") == 0) {
        listener->added(_remoteSvcDesc[msg->getMeta("desc:channel")]);
      } else {
        listener->removed(_remoteSvcDesc[msg->getMeta("desc:channel")]);
        _remoteSvcDesc.erase(msg->getMeta("desc:channel"));
      }
    }
    delete keyFilter;
  }
}