MetricsMapI::MetricsMapI(const std::string& mapPrefix, const PropertiesPtr& properties) : _properties(properties->getPropertiesForPrefix(mapPrefix)), _retain(properties->getPropertyAsIntWithDefault(mapPrefix + "RetainDetached", 10)), _accept(parseRule(properties, mapPrefix + "Accept")), _reject(parseRule(properties, mapPrefix + "Reject")) { validateProperties(mapPrefix, properties); string groupBy = properties->getPropertyWithDefault(mapPrefix + "GroupBy", "id"); vector<string>& groupByAttributes = const_cast<vector<string>&>(_groupByAttributes); vector<string>& groupBySeparators = const_cast<vector<string>&>(_groupBySeparators); if(!groupBy.empty()) { string v; bool attribute = IceUtilInternal::isAlpha(groupBy[0]) || IceUtilInternal::isDigit(groupBy[0]); if(!attribute) { groupByAttributes.push_back(""); } for(string::const_iterator p = groupBy.begin(); p != groupBy.end(); ++p) { bool isAlphaNum = IceUtilInternal::isAlpha(*p) || IceUtilInternal::isDigit(*p) || *p == '.'; if(attribute && !isAlphaNum) { groupByAttributes.push_back(v); v = *p; attribute = false; } else if(!attribute && isAlphaNum) { groupBySeparators.push_back(v); v = *p; attribute = true; } else { v += *p; } } if(attribute) { groupByAttributes.push_back(v); } else { groupBySeparators.push_back(v); } } }
void Analyzer::reload(const PropertiesPtr& properties) { MCE_INFO("Analyzer::reload type: " << type_); int defaultmin = properties->getPropertyAsIntWithDefault("Analyzer."+type_+".Default.Min", INT_MIN); int defaultmax = properties->getPropertyAsIntWithDefault("Analyzer."+type_+".Default.Max", INT_MAX); int defaultmoremin = properties->getPropertyAsIntWithDefault("Analyzer."+type_+".Default.MoreMin", INT_MIN); int defaultmoremax = properties->getPropertyAsIntWithDefault("Analyzer."+type_+".Default.MoreMax", INT_MAX); LimiterPtr defaulter = new Limiter(defaultmoremin, defaultmin, defaultmax, defaultmoremax); map<string, LimiterPtr> limits; PropertyDict patterns = properties->getPropertiesForPrefix("Analyzer."+type_+".Patterns"); for (PropertyDict::iterator pattern = patterns.begin(); pattern != patterns.end(); ++pattern) { vector<string> strings; boost::algorithm::split(strings, pattern->second, boost::algorithm::is_any_of(" ")); limits[strings.at(0)]=new Limiter(lexical_cast<int>(strings.at(1)),lexical_cast<int>(strings.at(2)),lexical_cast<int>(strings.at(3)),lexical_cast<int>(strings.at(4))); } { RWRecMutex::WLock lock(mutex_); limits_ = limits; default_ = defaulter; } MCE_DEBUG("Analyzer::reload done"); }
bool IceBox::ServiceManagerI::start() { try { ServiceManagerPtr obj = this; PropertiesPtr properties = _communicator->getProperties(); // // Create an object adapter. Services probably should NOT share // this object adapter, as the endpoint(s) for this object adapter // will most likely need to be firewalled for security reasons. // ObjectAdapterPtr adapter; if(properties->getProperty("IceBox.ServiceManager.Endpoints") != "") { adapter = _communicator->createObjectAdapter("IceBox.ServiceManager"); Identity identity; identity.category = properties->getPropertyWithDefault("IceBox.InstanceName", "IceBox"); identity.name = "ServiceManager"; adapter->add(obj, identity); } // // Parse the property set with the prefix "IceBox.Service.". These // properties should have the following format: // // IceBox.Service.Foo=entry_point [args] // // We parse the service properties specified in IceBox.LoadOrder // first, then the ones from remaining services. // const string prefix = "IceBox.Service."; PropertyDict services = properties->getPropertiesForPrefix(prefix); PropertyDict::iterator p; StringSeq loadOrder = properties->getPropertyAsList("IceBox.LoadOrder"); vector<StartServiceInfo> servicesInfo; for(StringSeq::const_iterator q = loadOrder.begin(); q != loadOrder.end(); ++q) { p = services.find(prefix + *q); if(p == services.end()) { FailureException ex(__FILE__, __LINE__); ex.reason = "ServiceManager: no service definition for `" + *q + "'"; throw ex; } servicesInfo.push_back(StartServiceInfo(*q, p->second, _argv)); services.erase(p); } for(p = services.begin(); p != services.end(); ++p) { servicesInfo.push_back(StartServiceInfo(p->first.substr(prefix.size()), p->second, _argv)); } // // Check if some services are using the shared communicator in which // case we create the shared communicator now with a property set which // is the union of all the service properties (services which are using // the shared communicator). // PropertyDict sharedCommunicatorServices = properties->getPropertiesForPrefix("IceBox.UseSharedCommunicator."); if(!sharedCommunicatorServices.empty()) { InitializationData initData; initData.properties = createServiceProperties("SharedCommunicator"); for(vector<StartServiceInfo>::iterator q = servicesInfo.begin(); q != servicesInfo.end(); ++q) { if(properties->getPropertyAsInt("IceBox.UseSharedCommunicator." + q->name) <= 0) { continue; } // // Load the service properties using the shared communicator properties as // the default properties. // PropertiesPtr svcProperties = createProperties(q->args, initData.properties); // // Erase properties from the shared communicator which don't exist in the // service properties (which include the shared communicator properties // overriden by the service properties). // PropertyDict allProps = initData.properties->getPropertiesForPrefix(""); for(PropertyDict::iterator p = allProps.begin(); p != allProps.end(); ++p) { if(svcProperties->getProperty(p->first) == "") { initData.properties->setProperty(p->first, ""); } } // // Add the service properties to the shared communicator properties. // PropertyDict props = svcProperties->getPropertiesForPrefix(""); for(PropertyDict::const_iterator r = props.begin(); r != props.end(); ++r) { initData.properties->setProperty(r->first, r->second); } // // Parse <service>.* command line options (the Ice command line options // were parsed by the createProperties above) // q->args = initData.properties->parseCommandLineOptions(q->name, q->args); } _sharedCommunicator = initialize(initData); } // // Start the services. // for(vector<StartServiceInfo>::const_iterator r = servicesInfo.begin(); r != servicesInfo.end(); ++r) { start(r->name, r->entryPoint, r->args); } // // We may want to notify external scripts that the services // have started. This is done by defining the property: // // IceBox.PrintServicesReady=bundleName // // Where bundleName is whatever you choose to call this set of // services. It will be echoed back as "bundleName ready". // // This must be done after start() has been invoked on the // services. // string bundleName = properties->getProperty("IceBox.PrintServicesReady"); if(!bundleName.empty()) { cout << bundleName << " ready" << endl; } // // Register "this" as a facet to the Admin object, and then create // Admin object // try { _communicator->addAdminFacet(this, "IceBox.ServiceManager"); // // Add a Properties facet for each service // for(vector<ServiceInfo>::iterator r = _services.begin(); r != _services.end(); ++r) { const ServiceInfo& info = *r; CommunicatorPtr communicator = info.communicator != 0 ? info.communicator : _sharedCommunicator; _communicator->addAdminFacet(new PropertiesAdminI(communicator->getProperties()), "IceBox.Service." + info.name + ".Properties"); } _communicator->getAdmin(); } catch(const ObjectAdapterDeactivatedException&) { // // Expected if the communicator has been shutdown. // } if(adapter) { try { adapter->activate(); } catch(const ObjectAdapterDeactivatedException&) { // // Expected if the communicator has been shutdown. // } } } catch(const FailureException& ex) { Error out(_logger); out << ex.reason; stopAll(); return false; } catch(const Exception& ex) { Error out(_logger); out << "ServiceManager: " << ex; stopAll(); return false; } return true; }
bool IceBox::IceBoxService::start(int argc, char* argv[], int& status) { // Run through the command line arguments removing all the service // properties. vector<string> args = Ice::argsToStringSeq(argc, argv); PropertiesPtr properties = communicator()->getProperties(); const string prefix = "IceBox.Service."; PropertyDict services = properties->getPropertiesForPrefix(prefix); for(PropertyDict::const_iterator p = services.begin(); p != services.end(); ++p) { string name = p->first.substr(prefix.size()); StringSeq::iterator q = args.begin(); while(q != args.end()) { if(q->find("--" + name + ".") == 0) { q = args.erase(q); continue; } ++q; } } IceUtilInternal::Options opts; opts.addOpt("h", "help"); opts.addOpt("v", "version"); try { args = opts.parse(args); } catch(const IceUtilInternal::BadOptException& e) { error(e.reason); usage(argv[0]); return false; } if(opts.isSet("help")) { usage(argv[0]); status = EXIT_SUCCESS; return false; } if(opts.isSet("version")) { print(ICE_STRING_VERSION); status = EXIT_SUCCESS; return false; } if(!args.empty()) { usage(argv[0]); return false; } _serviceManager = new ServiceManagerI(communicator(), argc, argv); return _serviceManager->start(); }
void ServiceI::validateProperties(const string& name, const PropertiesPtr& properties, const LoggerPtr& logger) { static const string suffixes[] = { "ReplicatedTopicManagerEndpoints", "ReplicatedPublishEndpoints", "Nodes.*", "Transient", "NodeId", "Flush.Timeout", "InstanceName", "Election.MasterTimeout", "Election.ElectionTimeout", "Election.ResponseTimeout", "Publish.AdapterId", "Publish.Endpoints", "Publish.Locator", "Publish.PublishedEndpoints", "Publish.RegisterProcess", "Publish.ReplicaGroupId", "Publish.Router", "Publish.ThreadPool.Size", "Publish.ThreadPool.SizeMax", "Publish.ThreadPool.SizeWarn", "Publish.ThreadPool.StackSize", "Node.AdapterId", "Node.Endpoints", "Node.Locator", "Node.PublishedEndpoints", "Node.RegisterProcess", "Node.ReplicaGroupId", "Node.Router", "Node.ThreadPool.Size", "Node.ThreadPool.SizeMax", "Node.ThreadPool.SizeWarn", "Node.ThreadPool.StackSize", "TopicManager.AdapterId", "TopicManager.Endpoints", "TopicManager.Locator", "TopicManager.Proxy", "TopicManager.Proxy.EndpointSelection", "TopicManager.Proxy.ConnectionCached", "TopicManager.Proxy.PreferSecure", "TopicManager.Proxy.LocatorCacheTimeout", "TopicManager.Proxy.Locator", "TopicManager.Proxy.Router", "TopicManager.Proxy.CollocationOptimization", "TopicManager.PublishedEndpoints", "TopicManager.RegisterProcess", "TopicManager.ReplicaGroupId", "TopicManager.Router", "TopicManager.ThreadPool.Size", "TopicManager.ThreadPool.SizeMax", "TopicManager.ThreadPool.SizeWarn", "TopicManager.ThreadPool.StackSize", "Trace.Election", "Trace.Replication", "Trace.Subscriber", "Trace.Topic", "Trace.TopicManager", "Send.Timeout", "Discard.Interval", "SQL.DatabaseType", "SQL.EncodingVersion", "SQL.HostName", "SQL.Port", "SQL.DatabaseName", "SQL.UserName", "SQL.Password" }; vector<string> unknownProps; string prefix = name + "."; PropertyDict props = properties->getPropertiesForPrefix(prefix); for(PropertyDict::const_iterator p = props.begin(); p != props.end(); ++p) { bool valid = false; for(unsigned int i = 0; i < sizeof(suffixes)/sizeof(*suffixes); ++i) { string prop = prefix + suffixes[i]; if(IceUtilInternal::match(p->first, prop)) { valid = true; break; } } if(!valid) { unknownProps.push_back(p->first); } } if(!unknownProps.empty()) { Warning out(logger); out << "found unknown properties for IceStorm service '" << name << "':"; for(vector<string>::const_iterator p = unknownProps.begin(); p != unknownProps.end(); ++p) { out << "\n " << *p; } } }
void ServiceI::start( const string& name, const CommunicatorPtr& communicator, const StringSeq& /*args*/) { PropertiesPtr properties = communicator->getProperties(); validateProperties(name, properties, communicator->getLogger()); int id = properties->getPropertyAsIntWithDefault(name + ".NodeId", -1); // If we are using a replicated deployment and if the topic // manager thread pool max size is not set then ensure it is set // to some suitably high number. This ensures no deadlocks in the // replicated case due to call forwarding from replicas to // coordinators. if(id != -1 && properties->getProperty(name + ".TopicManager.ThreadPool.SizeMax").empty()) { properties->setProperty(name + ".TopicManager.ThreadPool.SizeMax", "100"); } Ice::ObjectAdapterPtr topicAdapter = communicator->createObjectAdapter(name + ".TopicManager"); Ice::ObjectAdapterPtr publishAdapter = communicator->createObjectAdapter(name + ".Publish"); // // We use the name of the service for the name of the database environment. // string instanceName = properties->getPropertyWithDefault(name + ".InstanceName", "IceStorm"); Identity topicManagerId; topicManagerId.category = instanceName; topicManagerId.name = "TopicManager"; if(properties->getPropertyAsIntWithDefault(name+ ".Transient", 0) > 0) { _instance = new Instance(instanceName, name, communicator, publishAdapter, topicAdapter, 0); try { TransientTopicManagerImplPtr manager = new TransientTopicManagerImpl(_instance); _managerProxy = TopicManagerPrx::uncheckedCast(topicAdapter->add(manager, topicManagerId)); } catch(const Ice::Exception& ex) { _instance = 0; LoggerOutputBase s; s << "exception while starting IceStorm service " << name << ":\n"; s << ex; IceBox::FailureException e(__FILE__, __LINE__); e.reason = s.str(); throw e; } topicAdapter->activate(); publishAdapter->activate(); return; } if(id == -1) // No replication. { _instance = new Instance(instanceName, name, communicator, publishAdapter, topicAdapter); try { _manager = new TopicManagerImpl(_instance); _managerProxy = TopicManagerPrx::uncheckedCast(topicAdapter->add(_manager->getServant(), topicManagerId)); } catch(const Ice::Exception& ex) { _instance = 0; LoggerOutputBase s; s << "exception while starting IceStorm service " << name << ":\n"; s << ex; IceBox::FailureException e(__FILE__, __LINE__); e.reason = s.str(); throw e; } } else { // Here we want to create a map of id -> election node // proxies. map<int, NodePrx> nodes; string topicManagerAdapterId = properties->getProperty(name + ".TopicManager.AdapterId"); // We support two possible deployments. The first is a manual // deployment, the second is IceGrid. // // Here we check for the manual deployment const string prefix = name + ".Nodes."; Ice::PropertyDict props = properties->getPropertiesForPrefix(prefix); if(!props.empty()) { for(Ice::PropertyDict::const_iterator p = props.begin(); p != props.end(); ++p) { int nodeid = atoi(p->first.substr(prefix.size()).c_str()); nodes[nodeid] = NodePrx::uncheckedCast(communicator->propertyToProxy(p->first)); } } else { // If adapter id's are defined for the topic manager or // node adapters then we consider this an IceGrid based // deployment. string nodeAdapterId = properties->getProperty(name + ".Node.AdapterId"); // Validate first that the adapter ids match for the node // and the topic manager otherwise some other deployment // is being used. const string suffix = ".TopicManager"; if(topicManagerAdapterId.empty() || nodeAdapterId.empty() || topicManagerAdapterId.replace( topicManagerAdapterId.find(suffix), suffix.size(), ".Node") != nodeAdapterId) { Ice::Error error(communicator->getLogger()); error << "deployment error: `" << topicManagerAdapterId << "' prefix does not match `" << nodeAdapterId << "'"; throw IceBox::FailureException(__FILE__, __LINE__, "IceGrid deployment is incorrect"); } // Determine the set of node id and node proxies. // // This is determined by locating all topic manager // replicas, and then working out the node for that // replica. // // We work out the node id by removing the instance // name. The node id must follow. // IceGrid::LocatorPrx locator = IceGrid::LocatorPrx::checkedCast(communicator->getDefaultLocator()); assert(locator); IceGrid::QueryPrx query = locator->getLocalQuery(); Ice::ObjectProxySeq replicas = query->findAllReplicas( communicator->stringToProxy(instanceName + "/TopicManager")); for(Ice::ObjectProxySeq::const_iterator p = replicas.begin(); p != replicas.end(); ++p) { string adapterid = (*p)->ice_getAdapterId(); // Replace TopicManager with the node endpoint. adapterid = adapterid.replace(adapterid.find(suffix), suffix.size(), ".Node"); // The adapter id must start with the instance name. if(adapterid.find(instanceName) != 0) { Ice::Error error(communicator->getLogger()); error << "deployment error: `" << adapterid << "' does not start with `" << instanceName << "'"; throw IceBox::FailureException(__FILE__, __LINE__, "IceGrid deployment is incorrect"); } // The node id follows. We find the first digit (the // start of the node id, and then the end of the // digits). string::size_type start = instanceName.size(); while(start < adapterid.size() && !IceUtilInternal::isDigit(adapterid[start])) { ++start; } string::size_type end = start; while(end < adapterid.size() && IceUtilInternal::isDigit(adapterid[end])) { ++end; } if(start == end) { // We must have at least one digit, otherwise there is // some sort of deployment error. Ice::Error error(communicator->getLogger()); error << "deployment error: node id does not follow instance name. instance name:" << instanceName << " adapter id: " << adapterid; throw IceBox::FailureException(__FILE__, __LINE__, "IceGrid deployment is incorrect"); } int nodeid = atoi(adapterid.substr(start, end-start).c_str()); ostringstream os; os << "node" << nodeid; Ice::Identity id; id.category = instanceName; id.name = os.str(); nodes[nodeid] = NodePrx::uncheckedCast((*p)->ice_adapterId(adapterid)->ice_identity(id)); } } if(nodes.size() < 3) { Ice::Error error(communicator->getLogger()); error << "Replication requires at least 3 Nodes"; throw IceBox::FailureException(__FILE__, __LINE__, "Replication requires at least 3 Nodes"); } try { // If the node thread pool size is not set then initialize // to the number of nodes + 1 and disable thread pool size // warnings. if(properties->getProperty(name + ".Node.ThreadPool.Size").empty()) { ostringstream os; os << nodes.size() + 1; properties->setProperty(name + ".Node.ThreadPool.Size", os.str()); properties->setProperty(name + ".Node.ThreadPool.SizeWarn", "0"); } if(properties->getProperty(name + ".Node.MessageSizeMax").empty()) { properties->setProperty(name + ".Node.MessageSizeMax", "0"); // No limit on data exchanged internally } Ice::ObjectAdapterPtr nodeAdapter = communicator->createObjectAdapter(name + ".Node"); _instance = new Instance(instanceName, name, communicator, publishAdapter, topicAdapter, nodeAdapter, nodes[id]); _instance->observers()->setMajority(static_cast<unsigned int>(nodes.size())/2); // Trace replication information. TraceLevelsPtr traceLevels = _instance->traceLevels(); if(traceLevels->election > 0) { Ice::Trace out(traceLevels->logger, traceLevels->electionCat); out << "I am node " << id << "\n"; for(map<int, NodePrx>::const_iterator p = nodes.begin(); p != nodes.end(); ++p) { out << "\tnode: " << p->first << " proxy: " << p->second->ice_toString() << "\n"; } } if(topicManagerAdapterId.empty()) { // We're not using an IceGrid deployment. Here we need // a proxy which is used to create proxies to the // replicas later. _managerProxy = TopicManagerPrx::uncheckedCast(topicAdapter->createProxy(topicManagerId)); } else { // If we're using IceGrid deployment we need to create // indirect proxies. _managerProxy = TopicManagerPrx::uncheckedCast(topicAdapter->createIndirectProxy(topicManagerId)); } _manager = new TopicManagerImpl(_instance); topicAdapter->add(_manager->getServant(), topicManagerId); ostringstream os; // The node object identity. os << "node" << id; Ice::Identity nodeid; nodeid.category = instanceName; nodeid.name = os.str(); NodeIPtr node = new NodeI(_instance, _manager, _managerProxy, id, nodes); _instance->setNode(node); nodeAdapter->add(node, nodeid); nodeAdapter->activate(); node->start(); } catch(const Ice::Exception& ex) { _instance = 0; LoggerOutputBase s; s << "exception while starting IceStorm service " << name << ":\n"; s << ex; IceBox::FailureException e(__FILE__, __LINE__); e.reason = s.str(); throw e; } } topicAdapter->add(new FinderI(TopicManagerPrx::uncheckedCast(topicAdapter->createProxy(topicManagerId))), communicator->stringToIdentity("IceStorm/Finder")); topicAdapter->activate(); publishAdapter->activate(); }
RoutableReferencePtr IceInternal::ReferenceFactory::create(const Identity& ident, const string& facet, Reference::Mode mode, bool secure, const Ice::ProtocolVersion& protocol, const Ice::EncodingVersion& encoding, const vector<EndpointIPtr>& endpoints, const string& adapterId, const string& propertyPrefix) { DefaultsAndOverridesPtr defaultsAndOverrides = _instance->defaultsAndOverrides(); // // Default local proxy options. // LocatorInfoPtr locatorInfo; if(_defaultLocator) { if(_defaultLocator->ice_getEncodingVersion() != encoding) { locatorInfo = _instance->locatorManager()->get(_defaultLocator->ice_encodingVersion(encoding)); } else { locatorInfo = _instance->locatorManager()->get(_defaultLocator); } } RouterInfoPtr routerInfo = _instance->routerManager()->get(_defaultRouter); bool collocationOptimized = defaultsAndOverrides->defaultCollocationOptimization; bool cacheConnection = true; bool preferSecure = defaultsAndOverrides->defaultPreferSecure; Ice::EndpointSelectionType endpointSelection = defaultsAndOverrides->defaultEndpointSelection; int locatorCacheTimeout = defaultsAndOverrides->defaultLocatorCacheTimeout; int invocationTimeout = defaultsAndOverrides->defaultInvocationTimeout; Ice::Context ctx; // // Override the defaults with the proxy properties if a property prefix is defined. // if(!propertyPrefix.empty()) { PropertiesPtr properties = _instance->initializationData().properties; if(properties->getPropertyAsIntWithDefault("Ice.Warn.UnknownProperties", 1) > 0) { checkForUnknownProperties(propertyPrefix); } string property; property = propertyPrefix + ".Locator"; LocatorPrx locator = LocatorPrx::uncheckedCast(_communicator->propertyToProxy(property)); if(locator) { if(locator->ice_getEncodingVersion() != encoding) { locatorInfo = _instance->locatorManager()->get(locator->ice_encodingVersion(encoding)); } else { locatorInfo = _instance->locatorManager()->get(locator); } } property = propertyPrefix + ".Router"; RouterPrx router = RouterPrx::uncheckedCast(_communicator->propertyToProxy(property)); if(router) { if(propertyPrefix.size() > 7 && propertyPrefix.substr(propertyPrefix.size() - 7, 7) == ".Router") { Warning out(_instance->initializationData().logger); out << "`" << property << "=" << properties->getProperty(property) << "': cannot set a router on a router; setting ignored"; } else { routerInfo = _instance->routerManager()->get(router); } } property = propertyPrefix + ".CollocationOptimized"; collocationOptimized = properties->getPropertyAsIntWithDefault(property, collocationOptimized) > 0; property = propertyPrefix + ".ConnectionCached"; cacheConnection = properties->getPropertyAsIntWithDefault(property, cacheConnection) > 0; property = propertyPrefix + ".PreferSecure"; preferSecure = properties->getPropertyAsIntWithDefault(property, preferSecure) > 0; property = propertyPrefix + ".EndpointSelection"; if(!properties->getProperty(property).empty()) { string type = properties->getProperty(property); if(type == "Random") { endpointSelection = Random; } else if(type == "Ordered") { endpointSelection = Ordered; } else { EndpointSelectionTypeParseException ex(__FILE__, __LINE__); ex.str = "illegal value `" + type + "'; expected `Random' or `Ordered'"; throw ex; } } property = propertyPrefix + ".LocatorCacheTimeout"; string value = properties->getProperty(property); if(!value.empty()) { locatorCacheTimeout = properties->getPropertyAsIntWithDefault(property, locatorCacheTimeout); if(locatorCacheTimeout < -1) { locatorCacheTimeout = -1; Warning out(_instance->initializationData().logger); out << "invalid value for " << property << "`" << properties->getProperty(property) << "'" << ": defaulting to -1"; } } property = propertyPrefix + ".InvocationTimeout"; value = properties->getProperty(property); if(!value.empty()) { invocationTimeout = properties->getPropertyAsIntWithDefault(property, invocationTimeout); if(invocationTimeout < 1 && invocationTimeout != -1) { invocationTimeout = -1; Warning out(_instance->initializationData().logger); out << "invalid value for " << property << "`" << properties->getProperty(property) << "'" << ": defaulting to -1"; } } property = propertyPrefix + ".Context."; PropertyDict contexts = properties->getPropertiesForPrefix(property); for(PropertyDict::const_iterator p = contexts.begin(); p != contexts.end(); ++p) { ctx.insert(make_pair(p->first.substr(property.length()), p->second)); } } // // Create new reference // return new RoutableReference(_instance, _communicator, ident, facet, mode, secure, protocol, encoding, endpoints, adapterId, locatorInfo, routerInfo, collocationOptimized, cacheConnection, preferSecure, endpointSelection, locatorCacheTimeout, invocationTimeout, ctx); }
void Ice::PluginManagerI::loadPlugins(int& argc, const char* argv[]) { assert(_communicator); StringSeq cmdArgs = argsToStringSeq(argc, argv); const string prefix = "Ice.Plugin."; PropertiesPtr properties = _communicator->getProperties(); PropertyDict plugins = properties->getPropertiesForPrefix(prefix); // // First, load static plugin factories which were setup to load on // communicator initialization. If a matching plugin property is // set, we load the plugin with the plugin specification. The // entryPoint will be ignored but the rest of the plugin // specification might be used. // if(loadOnInitialization) { for(vector<string>::const_iterator p = loadOnInitialization->begin(); p != loadOnInitialization->end(); ++p) { string property = prefix + *p; PropertyDict::iterator r = plugins.find(property + ".cpp"); if(r == plugins.end()) { r = plugins.find(property); } else { plugins.erase(property); } if(r != plugins.end()) { loadPlugin(*p, r->second, cmdArgs); plugins.erase(r); } else { loadPlugin(*p, "", cmdArgs); } } } // // Next, load and initialize the plug-ins defined in the property // set with the prefix "Ice.Plugin.". These properties should have // the following format: // // Ice.Plugin.name[.<language>]=entry_point [args] // // If the Ice.PluginLoadOrder property is defined, load the // specified plug-ins in the specified order, then load any // remaining plug-ins. // StringSeq loadOrder = properties->getPropertyAsList("Ice.PluginLoadOrder"); for(StringSeq::const_iterator p = loadOrder.begin(); p != loadOrder.end(); ++p) { string name = *p; if(findPlugin(name)) { PluginInitializationException ex(__FILE__, __LINE__); ex.reason = "plug-in `" + name + "' already loaded"; throw ex; } string property = prefix + name; PropertyDict::iterator r = plugins.find(property + ".cpp"); if(r == plugins.end()) { r = plugins.find(property); } else { plugins.erase(property); } if(r != plugins.end()) { loadPlugin(name, r->second, cmdArgs); plugins.erase(r); } else { PluginInitializationException ex(__FILE__, __LINE__); ex.reason = "plug-in `" + name + "' not defined"; throw ex; } } // // Load any remaining plug-ins that weren't specified in PluginLoadOrder. // while(!plugins.empty()) { PropertyDict::iterator p = plugins.begin(); string name = p->first.substr(prefix.size()); size_t dotPos = name.find_last_of('.'); if(dotPos != string::npos) { string suffix = name.substr(dotPos + 1); if(suffix == "java" || suffix == "clr") { // // Ignored // plugins.erase(p); } else if(suffix == "cpp") { name = name.substr(0, dotPos); loadPlugin(name, p->second, cmdArgs); plugins.erase(p); plugins.erase(prefix + name); } else { // // Name is just a regular name that happens to contain a dot // dotPos = string::npos; } } if(dotPos == string::npos) { // // Is there a .cpp entry? // PropertyDict::iterator q = plugins.find(prefix + name + ".cpp"); if(q != plugins.end()) { plugins.erase(p); p = q; } loadPlugin(name, p->second, cmdArgs); plugins.erase(p); } } stringSeqToArgs(cmdArgs, argc, argv); }
bool MetricsViewI::addOrUpdateMap(const PropertiesPtr& properties, const string& mapName, const MetricsMapFactoryPtr& factory, const ::Ice::LoggerPtr& logger) { const string viewPrefix = "IceMX.Metrics." + _name + "."; const string mapsPrefix = viewPrefix + "Map."; PropertyDict mapsProps = properties->getPropertiesForPrefix(mapsPrefix); string mapPrefix; PropertyDict mapProps; if(!mapsProps.empty()) { mapPrefix = mapsPrefix + mapName + "."; mapProps = properties->getPropertiesForPrefix(mapPrefix); if(mapProps.empty()) { // This map isn't configured for this view. map<string, MetricsMapIPtr>::iterator q = _maps.find(mapName); if(q != _maps.end()) { q->second->destroy(); _maps.erase(q); return true; } return false; } } else { mapPrefix = viewPrefix; mapProps = properties->getPropertiesForPrefix(mapPrefix); } if(properties->getPropertyAsInt(mapPrefix + "Disabled") > 0) { // This map is disabled for this view. map<string, MetricsMapIPtr>::iterator q = _maps.find(mapName); if(q != _maps.end()) { q->second->destroy(); _maps.erase(q); return true; } return false; } map<string, MetricsMapIPtr>::iterator q = _maps.find(mapName); if(q != _maps.end() && q->second->getProperties() == mapProps) { return false; // The map configuration didn't change, no need to re-create. } if(q != _maps.end()) { // Destroy the previous map q->second->destroy(); _maps.erase(q); } try { _maps.insert(make_pair(mapName, factory->create(mapPrefix, properties))); } catch(const std::exception& ex) { ::Ice::Warning warn(logger); warn << "unexpected exception while creating metrics map:\n" << ex; } catch(const string& msg) { ::Ice::Warning warn(logger); warn << msg; } return true; }
void SChannelEngine::initialize() { Mutex::Lock lock(_mutex); if(_initialized) { return; } SSLEngine::initialize(); const string prefix = "IceSSL."; const PropertiesPtr properties = communicator()->getProperties(); // // Protocols selects which protocols to enable, by default we only enable TLS1.0 // TLS1.1 and TLS1.2 to avoid security issues with SSLv3 // vector<string> defaultProtocols; defaultProtocols.push_back("tls1_0"); defaultProtocols.push_back("tls1_1"); defaultProtocols.push_back("tls1_2"); const_cast<DWORD&>(_protocols) = parseProtocols(properties->getPropertyAsListWithDefault(prefix + "Protocols", defaultProtocols)); // // Check for a default directory. We look in this directory for // files mentioned in the configuration. // string defaultDir = properties->getProperty(prefix + "DefaultDir"); int passwordRetryMax = properties->getPropertyAsIntWithDefault(prefix + "PasswordRetryMax", 3); PasswordPromptPtr passwordPrompt = getPasswordPrompt(); setPassword(properties->getProperty(prefix + "Password")); string ciphers = properties->getProperty(prefix + "Ciphers"); if(!ciphers.empty()) { parseCiphers(ciphers); } if(securityTraceLevel() >= 1) { ostringstream os; os << "enabling SSL ciphersuites:"; if(_ciphers.empty()) { for(int i = 0; i < supportedCiphersSize; ++i) { os << "\n " << getCipherName(supportedCiphers[i]); } } else { for(vector<ALG_ID>::const_iterator i = _ciphers.begin(); i != _ciphers.end(); ++i) { os << "\n " << getCipherName(*i); } } getLogger()->trace(securityTraceCategory(), os.str()); } string certStore = properties->getPropertyWithDefault(prefix + "CertStore", "CurrentUser"); if(certStore != "CurrentUser" && certStore != "LocalMachine") { getLogger()->warning("Invalid IceSSL.CertStore value `" + certStore + "' adjusted to `CurrentUser'"); certStore = "CurrentUser"; } // // Create trusted CA store with contents of CertAuthFile // string caFile = properties->getProperty(prefix + "CertAuthFile"); if(!caFile.empty()) { _rootStore = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0, 0, 0); if(!_rootStore) { throw PluginInitializationException(__FILE__, __LINE__, "IceSSL: error creating in memory certificate store:\n" + lastErrorToString()); } if(!checkPath(caFile, defaultDir, false)) { throw PluginInitializationException(__FILE__, __LINE__, "IceSSL: CA certificate file not found:\n" + caFile); } addCertificateToStore(caFile, _rootStore); // // Create a chain engine that uses our Trusted Root Store // #ifdef __MINGW32__ CertChainEngineConfig config; memset(&config, 0, sizeof(CertChainEngineConfig)); config.cbSize = sizeof(CertChainEngineConfig); #else CERT_CHAIN_ENGINE_CONFIG config; memset(&config, 0, sizeof(CERT_CHAIN_ENGINE_CONFIG)); config.cbSize = sizeof(CERT_CHAIN_ENGINE_CONFIG); #endif config.hExclusiveRoot = _rootStore; // // Build the chain using the LocalMachine registry location as opposed // to the CurrentUser location. // if(certStore == "LocalMachine") { config.dwFlags = CERT_CHAIN_USE_LOCAL_MACHINE_STORE; } #ifdef __MINGW32__ if(!CertCreateCertificateChainEngine(reinterpret_cast<CERT_CHAIN_ENGINE_CONFIG*>(&config), &_chainEngine)) #else if(!CertCreateCertificateChainEngine(&config, &_chainEngine)) #endif { throw PluginInitializationException(__FILE__, __LINE__, "IceSSL: error creating certificate chain engine:\n" + lastErrorToString()); } } else { _chainEngine = (certStore == "LocalMachine") ? HCCE_LOCAL_MACHINE : HCCE_CURRENT_USER; } // // Import the application certificate and private keys. // string keySet = properties->getPropertyWithDefault(prefix + "KeySet", "DefaultKeySet"); if(keySet != "DefaultKeySet" && keySet != "UserKeySet" && keySet != "MachineKeySet") { getLogger()->warning("Invalid IceSSL.KeySet value `" + keySet + "' adjusted to `DefaultKeySet'"); keySet = "DefaultKeySet"; } DWORD importFlags = (keySet == "MachineKeySet") ? CRYPT_MACHINE_KEYSET : CRYPT_USER_KEYSET; string certFile = properties->getProperty(prefix + "CertFile"); string keyFile = properties->getPropertyWithDefault(prefix + "KeyFile", certFile); if(!certFile.empty()) { vector<string> certFiles; if(!splitString(certFile, IceUtilInternal::pathsep, certFiles) || certFiles.size() > 2) { throw PluginInitializationException(__FILE__, __LINE__, "IceSSL: invalid value for " + prefix + "CertFile:\n" + certFile); } vector<string> keyFiles; if(!splitString(keyFile, IceUtilInternal::pathsep, keyFiles) || keyFiles.size() > 2) { throw PluginInitializationException(__FILE__, __LINE__, "IceSSL: invalid value for " + prefix + "KeyFile:\n" + keyFile); } if(certFiles.size() != keyFiles.size()) { throw PluginInitializationException(__FILE__, __LINE__, "IceSSL: " + prefix + "KeyFile does not agree with " + prefix + "CertFile"); } for(size_t i = 0; i < certFiles.size(); ++i) { string certFile = certFiles[i]; if(!checkPath(certFile, defaultDir, false)) { throw PluginInitializationException(__FILE__, __LINE__, "IceSSL: certificate file not found:\n" + certFile); } vector<char> buffer; readFile(certFile, buffer); CRYPT_DATA_BLOB pfxBlob; pfxBlob.cbData = static_cast<DWORD>(buffer.size()); pfxBlob.pbData = reinterpret_cast<BYTE*>(&buffer[0]); HCERTSTORE store = 0; PCCERT_CONTEXT cert = 0; int err = 0; int count = 0; do { string s = password(false); store = PFXImportCertStore(&pfxBlob, stringToWstring(s).c_str(), importFlags); err = store ? 0 : GetLastError(); } while(err == ERROR_INVALID_PASSWORD && passwordPrompt && ++count < passwordRetryMax); if(store) { _stores.push_back(store); cert = CertFindCertificateInStore(store, X509_ASN_ENCODING, 0, CERT_FIND_ANY, 0, cert); if(!cert) { throw PluginInitializationException(__FILE__, __LINE__, "IceSSL: certificate error:\n" + lastErrorToString()); } _certs.push_back(cert); continue; } assert(err); if(err != CRYPT_E_BAD_ENCODE) { throw PluginInitializationException(__FILE__, __LINE__, "IceSSL: error decoding certificate:\n" + lastErrorToString()); } // // Try to load certificate & key as PEM files. // err = 0; keyFile = keyFiles[i]; if(!checkPath(keyFile, defaultDir, false)) { throw PluginInitializationException(__FILE__, __LINE__, "IceSSL: key file not found:\n" + keyFile); } readFile(keyFile, buffer); vector<BYTE> outBuffer; outBuffer.resize(buffer.size()); DWORD outLength = static_cast<DWORD>(buffer.size()); // // Convert the PEM encoded buffer to DER binary format. // if(!CryptStringToBinary(&buffer[0], static_cast<DWORD>(buffer.size()), CRYPT_STRING_BASE64HEADER, &outBuffer[0], &outLength, 0, 0)) { throw PluginInitializationException(__FILE__, __LINE__, "IceSSL: error decoding key:\n" + lastErrorToString()); } PCRYPT_PRIVATE_KEY_INFO keyInfo = 0; BYTE* key = 0; HCRYPTKEY hKey = 0; try { DWORD decodedLength = 0; if(!CryptDecodeObjectEx(X509_ASN_ENCODING, PKCS_PRIVATE_KEY_INFO, &outBuffer[0], outLength, CRYPT_DECODE_ALLOC_FLAG, 0, &keyInfo, &decodedLength)) { throw PluginInitializationException(__FILE__, __LINE__, "IceSSL: error decoding key:\n" + lastErrorToString()); } // // Check that we are using a RSA Key // if(strcmp(keyInfo->Algorithm.pszObjId, szOID_RSA_RSA)) { throw PluginInitializationException(__FILE__, __LINE__, string("IceSSL: error unknow key algorithm: `") + keyInfo->Algorithm.pszObjId + "'"); } // // Create a new RSA key set to store our key // const wstring keySetName = stringToWstring(generateUUID()); HCRYPTPROV cryptProv = 0; DWORD contextFlags = (keySet == "MachineKeySet") ? CRYPT_MACHINE_KEYSET | CRYPT_NEWKEYSET : CRYPT_NEWKEYSET; if(!CryptAcquireContextW(&cryptProv, keySetName.c_str(), MS_DEF_PROV_W, PROV_RSA_FULL, contextFlags)) { throw PluginInitializationException(__FILE__, __LINE__, "IceSSL: error acquiring cryptographic context:\n" + lastErrorToString()); } // // Decode the private key BLOB // if(!CryptDecodeObjectEx(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, PKCS_RSA_PRIVATE_KEY, keyInfo->PrivateKey.pbData, keyInfo->PrivateKey.cbData, CRYPT_DECODE_ALLOC_FLAG, 0, &key, &outLength)) { throw PluginInitializationException(__FILE__, __LINE__, "IceSSL: error decoding key:\n" + lastErrorToString()); } LocalFree(keyInfo); keyInfo = 0; // // Import the private key // if(!CryptImportKey(cryptProv, key, outLength, 0, 0, &hKey)) { throw PluginInitializationException(__FILE__, __LINE__, "IceSSL: error importing key:\n" + lastErrorToString()); } LocalFree(key); key = 0; CryptDestroyKey(hKey); hKey = 0; // // Create a new memory store to place the certificate // store = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0, 0, 0); if(!store) { throw PluginInitializationException(__FILE__, __LINE__, "IceSSL: error creating certificate store:\n" + lastErrorToString()); } addCertificateToStore(certFile, store, &cert); // // Associate key & certificate // CRYPT_KEY_PROV_INFO keyProvInfo; memset(&keyProvInfo, 0, sizeof(keyProvInfo)); keyProvInfo.pwszContainerName = const_cast<wchar_t*>(keySetName.c_str()); keyProvInfo.pwszProvName = const_cast<wchar_t*>(MS_DEF_PROV_W); keyProvInfo.dwProvType = PROV_RSA_FULL; keyProvInfo.dwKeySpec = AT_KEYEXCHANGE; if(!CertSetCertificateContextProperty(cert, CERT_KEY_PROV_INFO_PROP_ID, 0, &keyProvInfo)) { throw PluginInitializationException(__FILE__, __LINE__, "IceSSL: error seting certificate property:\n" + lastErrorToString()); } _certs.push_back(cert); _stores.push_back(store); } catch(...) { if(keyInfo) { LocalFree(keyInfo); } if(key) { LocalFree(key); } if(hKey) { CryptDestroyKey(hKey); } if(cert) { CertFreeCertificateContext(cert); } if(store) { CertCloseStore(store, 0); } throw; } } _allCerts.insert(_allCerts.end(), _certs.begin(), _certs.end()); } const string findPrefix = prefix + "FindCert."; map<string, string> certProps = properties->getPropertiesForPrefix(findPrefix); if(!certProps.empty()) { for(map<string, string>::const_iterator i = certProps.begin(); i != certProps.end(); ++i) { const string name = i->first; const string val = i->second; if(!val.empty()) { string storeSpec = name.substr(findPrefix.size()); vector<PCCERT_CONTEXT> certs = findCertificates(name, storeSpec, val, _stores); _allCerts.insert(_allCerts.end(), certs.begin(), certs.end()); } } if(_allCerts.empty()) { throw PluginInitializationException(__FILE__, __LINE__, "IceSSL: no certificates found"); } } _initialized = true; }