/// <summary> /// Creates a cache implementation for the strategy as defined by the cache descriptor. /// </summary> /// <param name="cacheDesc">cache descriptor</param> /// <param name="epStatementAgentInstanceHandle">statement handle for timer invocations</param> /// <param name="schedulingService">scheduling service for time-based caches</param> /// <param name="scheduleBucket">for ordered timer invokation</param> /// <returns>data cache implementation</returns> public DataCache GetDataCache( ConfigurationDataCache cacheDesc, StatementContext statementContext, EPStatementAgentInstanceHandle epStatementAgentInstanceHandle, SchedulingService schedulingService, ScheduleBucket scheduleBucket, int streamNum) { if (cacheDesc == null) { return(new DataCacheNullImpl()); } if (cacheDesc is ConfigurationLRUCache) { var lruCache = (ConfigurationLRUCache)cacheDesc; return(new DataCacheLRUImpl(lruCache.Size)); } if (cacheDesc is ConfigurationExpiryTimeCache) { var expCache = (ConfigurationExpiryTimeCache)cacheDesc; return(MakeTimeCache(expCache, statementContext, epStatementAgentInstanceHandle, schedulingService, scheduleBucket, streamNum)); } throw new IllegalStateException("Cache implementation class not configured"); }
// settable for view-sharing /// <summary> /// Constructor. /// </summary> /// <param name="stmtEngineServices">is the engine services for the statement</param> /// <param name="schedulingService">implementation for schedule registration</param> /// <param name="scheduleBucket">is for ordering scheduled callbacks within the view statements</param> /// <param name="epStatementHandle">is the statements-own handle for use in registering callbacks with services</param> /// <param name="viewResultionService">is a service for resolving view namespace and name to a view factory</param> /// <param name="patternResolutionService">is the service that resolves pattern objects for the statement</param> /// <param name="statementExtensionSvcContext">provide extension points for custom statement resources</param> /// <param name="statementStopService">for registering a callback invoked when a statement is stopped</param> /// <param name="methodResolutionService">is a service for resolving static methods and aggregation functions</param> /// <param name="patternContextFactory">is the pattern-level services and context information factory</param> /// <param name="filterService">is the filtering service</param> /// <param name="statementResultService">handles awareness of listeners/subscriptions for a statement customizing output produced</param> /// <param name="internalEventEngineRouteDest">routing destination</param> /// <param name="annotations">The annotations.</param> /// <param name="statementAgentInstanceRegistry">The statement agent instance registry.</param> /// <param name="defaultAgentInstanceLock">The default agent instance lock.</param> /// <param name="contextDescriptor">The context descriptor.</param> /// <param name="patternSubexpressionPoolSvc">The pattern subexpression pool SVC.</param> /// <param name="matchRecognizeStatePoolStmtSvc">The match recognize state pool statement SVC.</param> /// <param name="statelessSelect">if set to <c>true</c> [stateless select].</param> /// <param name="contextControllerFactoryService">The context controller factory service.</param> /// <param name="defaultAgentInstanceScriptContext">The default agent instance script context.</param> /// <param name="aggregationServiceFactoryService">The aggregation service factory service.</param> /// <param name="scriptingService">The scripting service.</param> /// <param name="writesToTables">if set to <c>true</c> [writes to tables].</param> /// <param name="statementUserObject">The statement user object.</param> /// <param name="statementSemiAnonymousTypeRegistry">The statement semi anonymous type registry.</param> /// <param name="priority">The priority.</param> public StatementContext( StatementContextEngineServices stmtEngineServices, SchedulingService schedulingService, ScheduleBucket scheduleBucket, EPStatementHandle epStatementHandle, ViewResolutionService viewResultionService, PatternObjectResolutionService patternResolutionService, StatementExtensionSvcContext statementExtensionSvcContext, StatementStopService statementStopService, MethodResolutionService methodResolutionService, PatternContextFactory patternContextFactory, FilterService filterService, StatementResultService statementResultService, InternalEventRouteDest internalEventEngineRouteDest, Attribute[] annotations, StatementAIResourceRegistry statementAgentInstanceRegistry, IReaderWriterLock defaultAgentInstanceLock, ContextDescriptor contextDescriptor, PatternSubexpressionPoolStmtSvc patternSubexpressionPoolSvc, MatchRecognizeStatePoolStmtSvc matchRecognizeStatePoolStmtSvc, bool statelessSelect, ContextControllerFactoryService contextControllerFactoryService, AgentInstanceScriptContext defaultAgentInstanceScriptContext, AggregationServiceFactoryService aggregationServiceFactoryService, ScriptingService scriptingService, bool writesToTables, object statementUserObject, StatementSemiAnonymousTypeRegistry statementSemiAnonymousTypeRegistry, int priority) { _stmtEngineServices = stmtEngineServices; SchedulingService = schedulingService; ScheduleBucket = scheduleBucket; EpStatementHandle = epStatementHandle; ViewResolutionService = viewResultionService; PatternResolutionService = patternResolutionService; StatementExtensionServicesContext = statementExtensionSvcContext; StatementStopService = statementStopService; MethodResolutionService = methodResolutionService; PatternContextFactory = patternContextFactory; FilterService = filterService; _statementResultService = statementResultService; InternalEventEngineRouteDest = internalEventEngineRouteDest; ScheduleAdjustmentService = stmtEngineServices.ConfigSnapshot.EngineDefaults.ExecutionConfig.IsAllowIsolatedService ? new ScheduleAdjustmentService() : null; Annotations = annotations; StatementAgentInstanceRegistry = statementAgentInstanceRegistry; DefaultAgentInstanceLock = defaultAgentInstanceLock; ContextDescriptor = contextDescriptor; PatternSubexpressionPoolSvc = patternSubexpressionPoolSvc; MatchRecognizeStatePoolStmtSvc = matchRecognizeStatePoolStmtSvc; IsStatelessSelect = statelessSelect; ContextControllerFactoryService = contextControllerFactoryService; DefaultAgentInstanceScriptContext = defaultAgentInstanceScriptContext; AggregationServiceFactoryService = aggregationServiceFactoryService; ScriptingService = scriptingService; IsWritesToTables = writesToTables; StatementUserObject = statementUserObject; StatementSemiAnonymousTypeRegistry = statementSemiAnonymousTypeRegistry; Priority = priority; }
/// <summary> Ctor.</summary> /// <param name="mapDatabaseRef">is a map of database name and database configuration entries /// </param> /// <param name="schedulingService">is for scheduling callbacks for a cache /// </param> /// <param name="scheduleBucket">is a system bucket for all scheduling callbacks for caches /// </param> public DatabaseConfigServiceImpl(IDictionary <String, ConfigurationDBRef> mapDatabaseRef, SchedulingService schedulingService, ScheduleBucket scheduleBucket) { _mapDatabaseRef = mapDatabaseRef; _connectionFactories = new Dictionary <String, DatabaseConnectionFactory>(); _schedulingService = schedulingService; _scheduleBucket = scheduleBucket; }
public void SetUp() { service = new SchedulingServiceImpl(-1, new TimeSourceServiceImpl()); // 2-by-2 table of buckets and slots var buckets = new ScheduleBucket[3]; slots = new long[buckets.Length][]; slots.Fill(() => new long[2]); for (var i = 0; i < buckets.Length; i++) { buckets[i] = new ScheduleBucket(i); slots[i] = new long[2]; for (var j = 0; j < slots[i].Length; j++) { slots[i][j] = buckets[i].AllocateSlot(); } } callbacks = new SupportScheduleCallback[5]; for (var i = 0; i < callbacks.Length; i++) { callbacks[i] = new SupportScheduleCallback(); } }
/// <summary>Creates a cache implementation for the strategy as defined by the cache descriptor. </summary> /// <param name="cacheDesc">cache descriptor</param> /// <param name="epStatementAgentInstanceHandle">statement handle for timer invocations</param> /// <param name="schedulingService">scheduling service for time-based caches</param> /// <param name="scheduleBucket">for ordered timer invokation</param> /// <returns>data cache implementation</returns> public static DataCache GetDataCache(ConfigurationDataCache cacheDesc, EPStatementAgentInstanceHandle epStatementAgentInstanceHandle, SchedulingService schedulingService, ScheduleBucket scheduleBucket) { if (cacheDesc == null) { return(new DataCacheNullImpl()); } if (cacheDesc is ConfigurationLRUCache) { ConfigurationLRUCache lruCache = (ConfigurationLRUCache)cacheDesc; return(new DataCacheLRUImpl(lruCache.Size)); } if (cacheDesc is ConfigurationExpiryTimeCache) { ConfigurationExpiryTimeCache expCache = (ConfigurationExpiryTimeCache)cacheDesc; return(new DataCacheExpiringImpl(expCache.MaxAgeSeconds, expCache.PurgeIntervalSeconds, expCache.CacheReferenceType, schedulingService, scheduleBucket.AllocateSlot(), epStatementAgentInstanceHandle)); } throw new IllegalStateException("Cache implementation class not configured"); }
protected internal DataCache MakeTimeCache( ConfigurationExpiryTimeCache expCache, StatementContext statementContext, EPStatementAgentInstanceHandle epStatementAgentInstanceHandle, SchedulingService schedulingService, ScheduleBucket scheduleBucket, int streamNum) { return(new DataCacheExpiringImpl( expCache.MaxAgeSeconds, expCache.PurgeIntervalSeconds, expCache.CacheReferenceType, schedulingService, scheduleBucket.AllocateSlot(), epStatementAgentInstanceHandle)); }
public StatementContext( IContainer container, ContextRuntimeDescriptor contextRuntimeDescriptor, string deploymentId, int statementId, string statementName, string moduleName, StatementInformationalsRuntime statementInformationals, object userObjectRuntime, StatementContextRuntimeServices statementContextRuntimeServices, EPStatementHandle epStatementHandle, IDictionary<int, FilterSpecActivatable> filterSpecActivatables, PatternSubexpressionPoolStmtSvc patternSubexpressionPoolSvc, RowRecogStatePoolStmtSvc rowRecogStatePoolStmtSvc, ScheduleBucket scheduleBucket, StatementAIResourceRegistry statementAIResourceRegistry, StatementCPCacheService statementCPCacheService, StatementAIFactoryProvider statementAIFactoryProvider, StatementResultService statementResultService, UpdateDispatchView updateDispatchView, FilterService filterService, SchedulingService schedulingService, InternalEventRouteDest internalEventRouteDest) { Container = container; ContextRuntimeDescriptor = contextRuntimeDescriptor; DeploymentId = deploymentId; StatementId = statementId; StatementName = statementName; ModuleName = moduleName; StatementInformationals = statementInformationals; UserObjectRuntime = userObjectRuntime; StatementContextRuntimeServices = statementContextRuntimeServices; EpStatementHandle = epStatementHandle; FilterSpecActivatables = filterSpecActivatables; PatternSubexpressionPoolSvc = patternSubexpressionPoolSvc; RowRecogStatePoolStmtSvc = rowRecogStatePoolStmtSvc; ScheduleBucket = scheduleBucket; StatementAIResourceRegistry = statementAIResourceRegistry; StatementCPCacheService = statementCPCacheService; StatementAIFactoryProvider = statementAIFactoryProvider; StatementResultService = statementResultService; UpdateDispatchView = updateDispatchView; StatementContextFilterEvalEnv = new StatementContextFilterEvalEnv( statementContextRuntimeServices.ImportServiceRuntime, statementInformationals.Annotations, statementContextRuntimeServices.VariableManagementService, statementContextRuntimeServices.TableExprEvaluatorContext); this.FilterService = filterService; this.SchedulingService = schedulingService; this.InternalEventRouteDest = internalEventRouteDest; }
/// <summary> /// Ctor. /// </summary> /// <param name="runtime">the EPRuntime for services and runtime</param> /// <param name="usingEngineThread">true if the coordinator should set time by the scheduling service in the engine, false if it should set time externally through the calling thread</param> /// <param name="usingExternalTimer">true to use esper's external timer mechanism instead of internal timing</param> /// <param name="usingTimeSpanEvents"></param> /// <exception cref="System.ArgumentNullException">epService;epService cannot be null</exception> /// <exception cref="System.ArgumentException">Illegal type of EPServiceProvider</exception> public AdapterCoordinatorImpl(EPRuntime runtime, bool usingEngineThread, bool usingExternalTimer, bool usingTimeSpanEvents) : base(runtime, usingEngineThread, usingExternalTimer, usingTimeSpanEvents) { if (runtime == null) { throw new ArgumentNullException("runtime", "runtime cannot be null"); } if (!(runtime is EPRuntimeSPI)) { throw new ArgumentException("Illegal type of EPServiceProvider"); } this._runtime = runtime; this._scheduleBucket = new ScheduleBucket(-1); this._usingEngineThread = usingEngineThread; this._usingExternalTimer = usingExternalTimer; }
/// <summary> /// Ctor. /// </summary> /// <param name="epService">the EPServiceProvider for the engine services and runtime</param> /// <param name="usingEngineThread">true if the coordinator should set time by the scheduling service in the engine, false if it should set time externally through the calling thread</param> /// <param name="usingExternalTimer">true to use esper's external timer mechanism instead of internal timing</param> /// <param name="usingTimeSpanEvents"></param> /// <exception cref="System.ArgumentNullException">epService;epService cannot be null</exception> /// <exception cref="System.ArgumentException">Illegal type of EPServiceProvider</exception> public AdapterCoordinatorImpl(EPServiceProvider epService, bool usingEngineThread, bool usingExternalTimer, bool usingTimeSpanEvents) : base(epService, usingEngineThread, usingExternalTimer, usingTimeSpanEvents) { if (epService == null) { throw new ArgumentNullException("epService", "epService cannot be null"); } if (!(epService is EPServiceProviderSPI)) { throw new ArgumentException("Illegal type of EPServiceProvider"); } this._epService = epService; this._scheduleBucket = ((EPServiceProviderSPI)epService).SchedulingMgmtService.AllocateBucket(); this._usingEngineThread = usingEngineThread; this._usingExternalTimer = usingExternalTimer; }
/// <summary>Creates the database config service. </summary> /// <param name="configSnapshot">is the config snapshot</param> /// <param name="schedulingService">is the timer stuff</param> /// <param name="schedulingMgmtService">for statement schedule management</param> /// <returns>database config svc</returns> internal static DatabaseConfigService MakeDatabaseRefService(ConfigurationInformation configSnapshot, SchedulingService schedulingService, SchedulingMgmtService schedulingMgmtService) { DatabaseConfigService databaseConfigService; // Add auto-imports try { ScheduleBucket allStatementsBucket = schedulingMgmtService.AllocateBucket(); databaseConfigService = new DatabaseConfigServiceImpl(configSnapshot.DatabaseReferences, schedulingService, allStatementsBucket); } catch (ArgumentException ex) { throw new ConfigurationException("Error configuring engine: " + ex.Message, ex); } return(databaseConfigService); }
private void FinishInitialization(EPRuntime runtime, CSVInputAdapterSpec spec) { AssertValidParameters(runtime, spec); var spi = (EPRuntimeSPI)runtime; ScheduleSlot = new ScheduleBucket(-1).AllocateSlot(); _reader = new CSVReader(spec.AdapterInputSource); _reader.Looping = spec.IsLooping; var firstRow = FirstRow; var givenPropertyTypes = ConstructPropertyTypes( spec.EventTypeName, spec.PropertyTypes, spi.ServicesContext.EventTypeRepositoryBus); _propertyOrder = spec.PropertyOrder ?? CSVPropertyOrderHelper.ResolvePropertyOrder(firstRow, givenPropertyTypes); _reader.IsUsingTitleRow = IsUsingTitleRow(firstRow, _propertyOrder); if (!IsUsingTitleRow(firstRow, _propertyOrder)) { this._firstRow = firstRow; } _propertyTypes = ResolvePropertyTypes(givenPropertyTypes); if (givenPropertyTypes == null) { throw new EPException("CSV adapter requires a predefined event type name, the event type named '" + spec.EventTypeName + "' could not be found"); } Coercer.SetPropertyTypes(_propertyTypes); }
/// <summary> /// Creates a method-invocation polling view for use as a stream that calls a method, or pulls results from cache. /// </summary> /// <param name="streamNumber">the stream number</param> /// <param name="methodStreamSpec">defines the class and method to call</param> /// <param name="eventAdapterService">for creating event types and events</param> /// <param name="epStatementAgentInstanceHandle">for time-based callbacks</param> /// <param name="methodResolutionService">for resolving classes and imports</param> /// <param name="engineImportService">for resolving configurations</param> /// <param name="schedulingService">for scheduling callbacks in expiry-time based caches</param> /// <param name="scheduleBucket">for schedules within the statement</param> /// <param name="exprEvaluatorContext">expression evaluation context</param> /// <returns>pollable view</returns> /// <throws>ExprValidationException if the expressions cannot be validated or the method descriptorhas incorrect class and method names, or parameter number and types don't match /// </throws> public static HistoricalEventViewable CreatePollMethodView( int streamNumber, MethodStreamSpec methodStreamSpec, EventAdapterService eventAdapterService, EPStatementAgentInstanceHandle epStatementAgentInstanceHandle, MethodResolutionService methodResolutionService, EngineImportService engineImportService, SchedulingService schedulingService, ScheduleBucket scheduleBucket, ExprEvaluatorContext exprEvaluatorContext, VariableService variableService, String contextName) { VariableMetaData variableMetaData = variableService.GetVariableMetaData(methodStreamSpec.ClassName); MethodPollingExecStrategyEnum strategy; VariableReader variableReader; String variableName; // Try to resolve the method MethodInfo methodReflection; FastMethod methodFastClass; Type declaringClass; Object invocationTarget; try { if (variableMetaData != null) { variableName = variableMetaData.VariableName; if (variableMetaData.ContextPartitionName != null) { if (contextName == null || !contextName.Equals(variableMetaData.ContextPartitionName)) { throw new ExprValidationException("Variable by name '" + variableMetaData.VariableName + "' has been declared for context '" + variableMetaData.ContextPartitionName + "' and can only be used within the same context"); } strategy = MethodPollingExecStrategyEnum.TARGET_VAR_CONTEXT; variableReader = null; invocationTarget = null; } else { variableReader = variableService.GetReader(methodStreamSpec.ClassName, VariableServiceConstants.NOCONTEXT_AGENTINSTANCEID); if (variableMetaData.IsConstant) { invocationTarget = variableReader.Value; if (invocationTarget is EventBean) { invocationTarget = ((EventBean)invocationTarget).Underlying; } strategy = MethodPollingExecStrategyEnum.TARGET_CONST; } else { invocationTarget = null; strategy = MethodPollingExecStrategyEnum.TARGET_VAR; } } methodReflection = methodResolutionService.ResolveNonStaticMethod(variableMetaData.VariableType, methodStreamSpec.MethodName); } else { methodReflection = methodResolutionService.ResolveMethod(methodStreamSpec.ClassName, methodStreamSpec.MethodName); invocationTarget = null; variableReader = null; variableName = null; strategy = MethodPollingExecStrategyEnum.TARGET_CONST; } declaringClass = methodReflection.DeclaringType; methodFastClass = FastClass.CreateMethod(methodReflection); } catch (ExprValidationException e) { throw; } catch (Exception e) { throw new ExprValidationException(e.Message, e); } // Determine object type returned by method var beanClass = methodFastClass.ReturnType; if ((beanClass == typeof(void)) || (beanClass.IsBuiltinDataType())) { throw new ExprValidationException("Invalid return type for static method '" + methodFastClass.Name + "' of class '" + methodStreamSpec.ClassName + "', expecting a class"); } bool isCollection = false; bool isIterator = false; Type collectionClass = null; Type iteratorClass = null; if (methodFastClass.ReturnType.IsArray) { beanClass = methodFastClass.ReturnType.GetElementType(); } else if (!methodFastClass.ReturnType.IsGenericStringDictionary()) { isCollection = methodFastClass.ReturnType.IsGenericCollection(); if (isCollection) { collectionClass = beanClass.GetGenericType(0); beanClass = collectionClass; } var beanEnumerable = methodFastClass.ReturnType.FindGenericInterface(typeof(IEnumerable <>)); if (beanEnumerable != null) { isIterator = true; iteratorClass = beanEnumerable.GetGenericType(0); beanClass = iteratorClass; } else { var beanEnumerator = methodFastClass.ReturnType.FindGenericInterface(typeof(IEnumerator <>)); if (beanEnumerator != null) { isIterator = true; iteratorClass = beanEnumerator.GetGenericType(0); beanClass = iteratorClass; } } } // If the method returns a Map, look up the map type IDictionary <string, object> mapType = null; String mapTypeName = null; if ((methodFastClass.ReturnType.IsGenericStringDictionary()) || (methodFastClass.ReturnType.IsArray && methodFastClass.ReturnType.GetElementType().IsGenericStringDictionary()) || (methodFastClass.ReturnType.IsGenericCollection() && methodFastClass.ReturnType.GetGenericType(0).IsGenericStringDictionary()) || (methodFastClass.ReturnType.IsGenericEnumerator() && methodFastClass.ReturnType.GetGenericType(0).IsGenericStringDictionary()) || (methodFastClass.ReturnType.IsGenericEnumerable() && methodFastClass.ReturnType.GetGenericType(0).IsGenericStringDictionary())) { var metadata = GetCheckMetadata(methodStreamSpec.MethodName, methodStreamSpec.ClassName, methodResolutionService, typeof(IDictionary <string, object>)); mapTypeName = metadata.TypeName; mapType = (IDictionary <string, object>)metadata.TypeMetadata; } // If the method returns an Object[] or Object[][], look up the type information IDictionary <string, object> oaType = null; String oaTypeName = null; if ((methodFastClass.ReturnType == typeof(object[])) || (methodFastClass.ReturnType == typeof(object[][])) || (methodFastClass.ReturnType.IsGenericCollection() && methodFastClass.ReturnType.GetGenericType(0) == typeof(object[])) || (methodFastClass.ReturnType.IsGenericEnumerator() && methodFastClass.ReturnType.GetGenericType(0) == typeof(object[])) || (methodFastClass.ReturnType.IsGenericEnumerable() && methodFastClass.ReturnType.GetGenericType(0) == typeof(object[]))) { var metadata = GetCheckMetadata(methodStreamSpec.MethodName, methodStreamSpec.ClassName, methodResolutionService, typeof(IDictionary <string, object>)); oaTypeName = metadata.TypeName; oaType = (IDictionary <String, Object>)metadata.TypeMetadata; } // Determine event type from class and method name EventType eventType; if (mapType != null) { eventType = eventAdapterService.AddNestableMapType(mapTypeName, mapType, null, false, true, true, false, false); } else if (oaType != null) { eventType = eventAdapterService.AddNestableObjectArrayType(oaTypeName, oaType, null, false, true, true, false, false, false, null); } else { eventType = eventAdapterService.AddBeanType(beanClass.FullName, beanClass, false, true, true); } // Construct polling strategy as a method invocation var configCache = engineImportService.GetConfigurationMethodRef(declaringClass.FullName); if (configCache == null) { configCache = engineImportService.GetConfigurationMethodRef(declaringClass.FullName); } var dataCacheDesc = configCache != null ? configCache.DataCacheDesc : null; var dataCache = DataCacheFactory.GetDataCache(dataCacheDesc, epStatementAgentInstanceHandle, schedulingService, scheduleBucket); PollExecStrategy methodPollStrategy; if (mapType != null) { if (methodFastClass.ReturnType.IsArray) { methodPollStrategy = new MethodPollingExecStrategyMapArray(eventAdapterService, methodFastClass, eventType, invocationTarget, strategy, variableReader, variableName, variableService); } else if (isCollection) { methodPollStrategy = new MethodPollingExecStrategyMapCollection(eventAdapterService, methodFastClass, eventType, invocationTarget, strategy, variableReader, variableName, variableService); } else if (isIterator) { methodPollStrategy = new MethodPollingExecStrategyMapIterator(eventAdapterService, methodFastClass, eventType, invocationTarget, strategy, variableReader, variableName, variableService); } else { methodPollStrategy = new MethodPollingExecStrategyMapPlain(eventAdapterService, methodFastClass, eventType, invocationTarget, strategy, variableReader, variableName, variableService); } } else if (oaType != null) { if (methodFastClass.ReturnType == typeof(object[][])) { methodPollStrategy = new MethodPollingExecStrategyOAArray(eventAdapterService, methodFastClass, eventType, invocationTarget, strategy, variableReader, variableName, variableService); } else if (isCollection) { methodPollStrategy = new MethodPollingExecStrategyOACollection(eventAdapterService, methodFastClass, eventType, invocationTarget, strategy, variableReader, variableName, variableService); } else if (isIterator) { methodPollStrategy = new MethodPollingExecStrategyOAIterator(eventAdapterService, methodFastClass, eventType, invocationTarget, strategy, variableReader, variableName, variableService); } else { methodPollStrategy = new MethodPollingExecStrategyOAPlain(eventAdapterService, methodFastClass, eventType, invocationTarget, strategy, variableReader, variableName, variableService); } } else { if (methodFastClass.ReturnType.IsArray) { methodPollStrategy = new MethodPollingExecStrategyPOCOArray(eventAdapterService, methodFastClass, eventType, invocationTarget, strategy, variableReader, variableName, variableService); } else if (isCollection) { methodPollStrategy = new MethodPollingExecStrategyPOCOCollection(eventAdapterService, methodFastClass, eventType, invocationTarget, strategy, variableReader, variableName, variableService); } else if (isIterator) { methodPollStrategy = new MethodPollingExecStrategyPOCOIterator(eventAdapterService, methodFastClass, eventType, invocationTarget, strategy, variableReader, variableName, variableService); } else { methodPollStrategy = new MethodPollingExecStrategyPOCOPlain(eventAdapterService, methodFastClass, eventType, invocationTarget, strategy, variableReader, variableName, variableService); } } return(new MethodPollingViewable(variableMetaData == null, methodReflection.DeclaringType, methodStreamSpec, streamNumber, methodStreamSpec.Expressions, methodPollStrategy, dataCache, eventType, exprEvaluatorContext)); }
/// <summary> /// Creates a method-invocation polling view for use as a stream that calls a method, or pulls results from cache. /// </summary> /// <param name="streamNumber">the stream number</param> /// <param name="methodStreamSpec">defines the class and method to call</param> /// <param name="eventAdapterService">for creating event types and events</param> /// <param name="epStatementAgentInstanceHandle">for time-based callbacks</param> /// <param name="engineImportService">for resolving configurations</param> /// <param name="schedulingService">for scheduling callbacks in expiry-time based caches</param> /// <param name="scheduleBucket">for schedules within the statement</param> /// <param name="exprEvaluatorContext">expression evaluation context</param> /// <param name="variableService">variable service</param> /// <param name="statementContext">statement context</param> /// <param name="contextName">context name</param> /// <param name="dataCacheFactory">factory for cache</param> /// <exception cref="ExprValidationException"> /// if the expressions cannot be validated or the method descriptor /// has incorrect class and method names, or parameter number and types don't match /// </exception> /// <returns>pollable view</returns> public static HistoricalEventViewable CreatePollMethodView( int streamNumber, MethodStreamSpec methodStreamSpec, EventAdapterService eventAdapterService, EPStatementAgentInstanceHandle epStatementAgentInstanceHandle, EngineImportService engineImportService, SchedulingService schedulingService, ScheduleBucket scheduleBucket, ExprEvaluatorContext exprEvaluatorContext, VariableService variableService, string contextName, DataCacheFactory dataCacheFactory, StatementContext statementContext) { VariableMetaData variableMetaData = variableService.GetVariableMetaData(methodStreamSpec.ClassName); MethodPollingExecStrategyEnum strategy; VariableReader variableReader = null; string variableName = null; MethodInfo methodReflection = null; object invocationTarget = null; string eventTypeNameProvidedUDFOrScript = null; // see if this is a script in the from-clause ExprNodeScript scriptExpression = null; if (methodStreamSpec.ClassName == null && methodStreamSpec.MethodName != null) { var scriptsByName = statementContext.ExprDeclaredService.GetScriptsByName(methodStreamSpec.MethodName); if (scriptsByName != null) { scriptExpression = ExprDeclaredHelper.GetExistsScript( statementContext.ConfigSnapshot.EngineDefaults.Scripts.DefaultDialect, methodStreamSpec.MethodName, methodStreamSpec.Expressions, scriptsByName, statementContext.ExprDeclaredService); } } try { if (scriptExpression != null) { eventTypeNameProvidedUDFOrScript = scriptExpression.EventTypeNameAnnotation; strategy = MethodPollingExecStrategyEnum.TARGET_SCRIPT; ExprNodeUtility.ValidateSimpleGetSubtree( ExprNodeOrigin.METHODINVJOIN, scriptExpression, statementContext, null, false); } else if (variableMetaData != null) { variableName = variableMetaData.VariableName; if (variableMetaData.ContextPartitionName != null) { if (contextName == null || !contextName.Equals(variableMetaData.ContextPartitionName)) { throw new ExprValidationException( "Variable by name '" + variableMetaData.VariableName + "' has been declared for context '" + variableMetaData.ContextPartitionName + "' and can only be used within the same context"); } strategy = MethodPollingExecStrategyEnum.TARGET_VAR_CONTEXT; variableReader = null; invocationTarget = null; } else { variableReader = variableService.GetReader( methodStreamSpec.ClassName, EPStatementStartMethodConst.DEFAULT_AGENT_INSTANCE_ID); if (variableMetaData.IsConstant) { invocationTarget = variableReader.Value; if (invocationTarget is EventBean) { invocationTarget = ((EventBean)invocationTarget).Underlying; } strategy = MethodPollingExecStrategyEnum.TARGET_CONST; } else { invocationTarget = null; strategy = MethodPollingExecStrategyEnum.TARGET_VAR; } } methodReflection = engineImportService.ResolveNonStaticMethodOverloadChecked( variableMetaData.VariableType, methodStreamSpec.MethodName); } else if (methodStreamSpec.ClassName == null) { // must be either UDF or script Pair <Type, EngineImportSingleRowDesc> udf = null; try { udf = engineImportService.ResolveSingleRow(methodStreamSpec.MethodName); } catch (EngineImportException ex) { throw new ExprValidationException( "Failed to find user-defined function '" + methodStreamSpec.MethodName + "': " + ex.Message, ex); } methodReflection = engineImportService.ResolveMethodOverloadChecked(udf.First, methodStreamSpec.MethodName); invocationTarget = null; variableReader = null; variableName = null; strategy = MethodPollingExecStrategyEnum.TARGET_CONST; eventTypeNameProvidedUDFOrScript = udf.Second.OptionalEventTypeName; } else { methodReflection = engineImportService.ResolveMethodOverloadChecked(methodStreamSpec.ClassName, methodStreamSpec.MethodName); invocationTarget = null; variableReader = null; variableName = null; strategy = MethodPollingExecStrategyEnum.TARGET_CONST; } } catch (ExprValidationException) { throw; } catch (Exception e) { throw new ExprValidationException(e.Message, e); } Type methodProviderClass = null; Type beanClass; IDictionary <string, object> oaType = null; IDictionary <string, object> mapType = null; bool isCollection = false; bool isIterator = false; EventType eventType; EventType eventTypeWhenMethodReturnsEventBeans = null; bool isStaticMethod = false; if (methodReflection != null) { methodProviderClass = methodReflection.DeclaringType; isStaticMethod = variableMetaData == null; // Determine object type returned by method beanClass = methodReflection.ReturnType; if ((beanClass == typeof(void)) || (beanClass.IsBuiltinDataType())) { throw new ExprValidationException( "Invalid return type for static method '" + methodReflection.Name + "' of class '" + methodStreamSpec.ClassName + "', expecting a class"); } if (methodReflection.ReturnType.IsArray && methodReflection.ReturnType.GetElementType() != typeof(EventBean)) { beanClass = methodReflection.ReturnType.GetElementType(); } Type collectionClass = null; Type iteratorClass = null; if (!beanClass.IsGenericDictionary()) { isCollection = beanClass.IsGenericCollection(); if (isCollection) { collectionClass = TypeHelper.GetGenericReturnType(methodReflection, true); beanClass = collectionClass; } isIterator = beanClass.IsGenericEnumerator() && !beanClass.IsGenericDictionary(); if (isIterator) { iteratorClass = TypeHelper.GetGenericReturnType(methodReflection, true); beanClass = iteratorClass; } } // If the method returns a Map, look up the map type string mapTypeName = null; if ((methodReflection.ReturnType.IsGenericStringDictionary()) || (methodReflection.ReturnType.IsArray && methodReflection.ReturnType.GetElementType().IsGenericStringDictionary()) || (isCollection && collectionClass.IsImplementsInterface(typeof(Map))) || (isIterator && iteratorClass.IsImplementsInterface(typeof(Map)))) { MethodMetadataDesc metadata; if (variableMetaData != null) { metadata = GetCheckMetadataVariable( methodStreamSpec.MethodName, variableMetaData, variableReader, engineImportService, typeof(Map)); } else { metadata = GetCheckMetadataNonVariable( methodStreamSpec.MethodName, methodStreamSpec.ClassName, engineImportService, typeof(Map)); } mapTypeName = metadata.TypeName; mapType = (IDictionary <string, object>)metadata.TypeMetadata; } // If the method returns an object[] or object[][], look up the type information string oaTypeName = null; if (methodReflection.ReturnType == typeof(object[]) || methodReflection.ReturnType == typeof(object[][]) || (isCollection && collectionClass == typeof(object[])) || (isIterator && iteratorClass == typeof(object[]))) { MethodMetadataDesc metadata; if (variableMetaData != null) { metadata = GetCheckMetadataVariable( methodStreamSpec.MethodName, variableMetaData, variableReader, engineImportService, typeof(IDictionary <string, object>)); } else { metadata = GetCheckMetadataNonVariable( methodStreamSpec.MethodName, methodStreamSpec.ClassName, engineImportService, typeof(IDictionary <string, object>)); } oaTypeName = metadata.TypeName; oaType = (IDictionary <string, object>)metadata.TypeMetadata; } // Determine event type from class and method name // If the method returns EventBean[], require the event type if ((methodReflection.ReturnType.IsArray && methodReflection.ReturnType.GetElementType() == typeof(EventBean)) || (isCollection && collectionClass == typeof(EventBean)) || (isIterator && iteratorClass == typeof(EventBean))) { string typeName = methodStreamSpec.EventTypeName == null ? eventTypeNameProvidedUDFOrScript : methodStreamSpec.EventTypeName; eventType = EventTypeUtility.RequireEventType( "Method", methodReflection.Name, eventAdapterService, typeName); eventTypeWhenMethodReturnsEventBeans = eventType; } else if (mapType != null) { eventType = eventAdapterService.AddNestableMapType( mapTypeName, mapType, null, false, true, true, false, false); } else if (oaType != null) { eventType = eventAdapterService.AddNestableObjectArrayType( oaTypeName, oaType, null, false, true, true, false, false, false, null); } else { eventType = eventAdapterService.AddBeanType(beanClass.GetDefaultTypeName(), beanClass, false, true, true); } // the @type is only allowed in conjunction with EventBean return types if (methodStreamSpec.EventTypeName != null && eventTypeWhenMethodReturnsEventBeans == null) { throw new ExprValidationException(EventTypeUtility.DisallowedAtTypeMessage()); } } else { string eventTypeName = methodStreamSpec.EventTypeName == null ? scriptExpression.EventTypeNameAnnotation : methodStreamSpec.EventTypeName; eventType = EventTypeUtility.RequireEventType( "Script", scriptExpression.Script.Name, eventAdapterService, eventTypeName); } // get configuration for cache string configName = methodProviderClass != null ? methodProviderClass.FullName : methodStreamSpec.MethodName; ConfigurationMethodRef configCache = engineImportService.GetConfigurationMethodRef(configName); if (configCache == null) { configCache = engineImportService.GetConfigurationMethodRef(configName); } ConfigurationDataCache dataCacheDesc = (configCache != null) ? configCache.DataCacheDesc : null; DataCache dataCache = dataCacheFactory.GetDataCache( dataCacheDesc, statementContext, epStatementAgentInstanceHandle, schedulingService, scheduleBucket, streamNumber); // metadata var meta = new MethodPollingViewableMeta( methodProviderClass, isStaticMethod, mapType, oaType, invocationTarget, strategy, isCollection, isIterator, variableReader, variableName, eventTypeWhenMethodReturnsEventBeans, scriptExpression); return(new MethodPollingViewable(methodStreamSpec, dataCache, eventType, exprEvaluatorContext, meta, statementContext.ThreadLocalManager)); }