public BuiltInClassV1StitchAdaptor(PackageFile packageFile, StitchInstance instance, IStitchEventObserver observer, IModuleLog log) { Observer = observer; _instance = instance; _log = log; _parameters = new BuiltInClassV1Parameters(packageFile.Adaptor.Parameters); }
public void StitchStopped(StitchInstance instance) { _messageBus.Publish(StitchInstanceEvent.ChannelStopped, new StitchInstanceEvent { InstanceId = instance.Id, GroupName = instance.GroupName }); }
static void Main(string[] args) { var nodeConfig = NodeConfiguration.GetDefault(); using (var core = new CrossStitchCore(nodeConfig)) { // Setup an in-memory data store var store = new InMemoryDataStorage(); core.AddModule(new DataModule(core.MessageBus, store)); // Backplane so we can cluster core.AddModule(new BackplaneModule(core)); // Stitches so we can host the stitch instances var stitchesConfig = StitchesConfiguration.GetDefault(); core.AddModule(new StitchesModule(core, stitchesConfig)); // Setup logging. var logger = new LoggerFactory().AddConsole(LogLevel.Debug).CreateLogger <Program>(); core.AddModule(new LoggingModule(core, logger)); // Create a stitch instance to run on startup var groupName = new StitchGroupName("PenPal.StitchA.1"); var packageFile = new PackageFile { Id = groupName.ToString(), GroupName = groupName, Adaptor = new InstanceAdaptorDetails { Type = AdaptorType.ProcessV1, Parameters = new Dictionary <string, string> { { Parameters.RunningDirectory, "." }, { Parameters.ExecutableArguments, "" }, { Parameters.ExecutableName, "PenPal.StitchA.exe" } } }, }; store.Save(packageFile, true); var stitch = new StitchInstance { Name = "StitchA", GroupName = groupName, OwnerNodeName = core.Name, OwnerNodeId = core.NodeId, State = InstanceStateType.Running }; store.Save(stitch, true); core.Start(); Console.ReadKey(); core.Stop(); } }
public static InstanceActionResult Result(string instanceId, bool ok, StitchInstance instance = null) { return(new InstanceActionResult { Found = true, InstanceId = instanceId, Success = ok, StitchInstance = instance }); }
static void Main(string[] args) { var nodeConfig = NodeConfiguration.GetDefault(); using (var core = new CrossStitchCore(nodeConfig)) { var httpServer = new NancyHttpModule(core.MessageBus); core.AddModule(httpServer); var dataStorage = new InMemoryDataStorage(); var data = new DataModule(core.MessageBus, dataStorage); core.AddModule(data); var stitchesConfiguration = StitchesConfiguration.GetDefault(); var stitches = new StitchesModule(core, stitchesConfiguration); core.AddModule(stitches); var groupName = new StitchGroupName("HttpTest", "Stitch", "1"); var packageFile = new PackageFile { Id = groupName.ToString(), GroupName = groupName, Adaptor = new InstanceAdaptorDetails { Type = AdaptorType.ProcessV1, Parameters = new Dictionary <string, string> { { Parameters.RunningDirectory, "." }, { Parameters.ExecutableName, "HttpTest.Stitch.exe" }, //{ Parameters.ArgumentsFormat, "{ExecutableName} {CoreArgs} -- {CustomArgs}" }, //{ Parameters.ExecutableFormat, "dotnet" }, } }, }; dataStorage.Save(packageFile, true); var stitch = new StitchInstance { Name = "HttpTest.Stitch", GroupName = groupName, State = InstanceStateType.Running }; dataStorage.Save(stitch, true); var logger = new LoggerFactory().AddConsole(LogLevel.Debug).CreateLogger <Program>(); core.AddModule(new LoggingModule(core, logger)); core.Log.LogInformation("Started"); core.Start(); Console.ReadKey(); core.Stop(); } }
public static InstanceActionResult Failure(string instanceId, bool found, StitchInstance instance, Exception e) { return(new InstanceActionResult { Success = false, Found = found, InstanceId = instanceId, Exception = e, StitchInstance = instance }); }
public static InstanceResponse Success(CreateInstanceRequest request, StitchInstance createdInstance, string data = null) { var response = new InstanceResponse { Id = createdInstance.Id, Data = data, IsSuccess = true }; response.Instances.Add(createdInstance); return(response); }
public void HandleRequest_Save_Test() { var target = new DataService(new InMemoryDataStorage(), null); var entity = new StitchInstance() { Name = "A" }; var result = target.HandleRequest(DataRequest <StitchInstance> .Save(entity)); result.Type.Should().Be(DataResponseType.Success); result.Entity.Name.Should().Be("A"); }
static void Main(string[] args) { var nodeConfig = NodeConfiguration.GetDefault(); using (var core = new CrossStitchCore(nodeConfig)) { var httpServer = new NancyHttpModule(core.MessageBus); core.AddModule(httpServer); var dataStorage = new InMemoryDataStorage(); var data = new DataModule(core.MessageBus, dataStorage); core.AddModule(data); var stitchesConfiguration = StitchesConfiguration.GetDefault(); var stitches = new StitchesModule(core, stitchesConfiguration); core.AddModule(stitches); var groupName = new StitchGroupName("HttpTest", "Stitch", "1"); var packageFile = new PackageFile { Id = groupName.ToString(), GroupName = groupName, Adaptor = new InstanceAdaptorDetails { Type = AdaptorType.ProcessV1, Parameters = new Dictionary <string, string> { { CrossStitch.Stitch.ProcessV1.Parameters.DirectoryPath, "." }, { CrossStitch.Stitch.ProcessV1.Parameters.ExecutableName, "HttpTest.Stitch.exe" } } }, }; dataStorage.Save(packageFile, true); var stitch = new StitchInstance { Name = "HttpTest.Stitch", GroupName = groupName, State = InstanceStateType.Running, LastHeartbeatReceived = 0 }; dataStorage.Save(stitch, true); core.AddModule(new LoggingModule(core, Common.Logging.LogManager.GetLogger("CrossStitch"))); core.Start(); Console.ReadKey(); core.Stop(); } }
private IStitchAdaptor GetOrCreateStitchAdaptor(PackageFile packageFile, StitchInstance stitchInstance) { var adaptor = _adaptors.Get(stitchInstance.Id); if (adaptor != null) { return(adaptor); } adaptor = _adaptorFactory.Create(packageFile, stitchInstance); _adaptors.Add(stitchInstance.Id, adaptor); return(adaptor); }
public void HandleRequest_Save_InPlaceUpdate_NotFound_Test() { var target = new DataService(new InMemoryDataStorage(), null); var entity = new StitchInstance() { Name = "A" }; entity = target.HandleRequest(DataRequest <StitchInstance> .Save(entity)).Entity; var result = target.HandleRequest(DataRequest <StitchInstance> .Save("GARBAGE", a => a.Name = "B")); result.Type.Should().Be(DataResponseType.NotFound); }
public void HandleRequest_Save_InPlaceUpdate_null_Test() { var target = new DataService(new InMemoryDataStorage(), null); var entity = new StitchInstance() { Name = "A" }; entity = target.HandleRequest(DataRequest <StitchInstance> .Save(entity)).Entity; var result = target.HandleRequest(DataRequest <StitchInstance> .Save(entity.Id, null)); result.Type.Should().Be(DataResponseType.GeneralFailure); }
public static InstanceResponse Create(InstanceRequest request, bool success, StitchInstance instance = null, string data = null) { var response = new InstanceResponse { IsSuccess = success, Id = request.Id, Data = data, }; if (instance != null) { response.Instances.Add(instance); } return(response); }
public IStitchAdaptor Create(PackageFile packageFile, StitchInstance stitchInstance) { switch (packageFile.Adaptor.Type) { //case InstanceRunModeType.AppDomain: // return new AppDomainAppAdaptor(instance, _network); case AdaptorType.ProcessV1: var pv1args = new ProcessParameters(_configuration, _fileSystem, stitchInstance, packageFile); return(new ProcessStitchAdaptor(_core, _configuration, stitchInstance, _observer, pv1args, _log)); case AdaptorType.BuildInClassV1: return(new BuiltInClassV1StitchAdaptor(packageFile, stitchInstance, _observer, _log)); } throw new Exception("Run mode not supported"); }
public void HandleRequest_Save_Update_VersionMismatch_Test() { var target = new DataService(new InMemoryDataStorage(), null); var entity = new StitchInstance() { Name = "A" }; entity = target.HandleRequest(DataRequest <StitchInstance> .Save(entity)).Entity; entity.Name = "B"; entity.StoreVersion = 0; var result = target.HandleRequest(DataRequest <StitchInstance> .Save(entity)); result.Type.Should().Be(DataResponseType.VersionMismatch); }
public string BuildCoreArgumentsString(StitchInstance stitchInstance, CrossStitchCore core, ProcessParameters parameters) { var sb = new StringBuilder(); AddArgument(sb, Arguments.CoreId, core.NodeId); AddArgument(sb, Arguments.CorePid, core.CorePid.ToString()); AddArgument(sb, Arguments.InstanceId, stitchInstance.Id); AddArgument(sb, Arguments.Application, stitchInstance.GroupName.Application); AddArgument(sb, Arguments.Component, stitchInstance.GroupName.Component); AddArgument(sb, Arguments.Version, stitchInstance.GroupName.Version); AddArgument(sb, Arguments.GroupName, stitchInstance.GroupName.ToString()); AddArgument(sb, Arguments.DataDirectory, parameters.DataDirectory); AddArgument(sb, Arguments.ChannelType, parameters.ChannelType.ToString()); AddArgument(sb, Arguments.Serializer, parameters.SerializerType.ToString()); return(sb.ToString()); }
public void HandleRequest_Get_Test() { var storage = new InMemoryDataStorage(); var entity = new StitchInstance() { Name = "A" }; storage.Save(entity, true); var id = entity.Id; var target = new DataService(storage, null); var result = target.HandleRequest(DataRequest <StitchInstance> .Get(id)); result.Type.Should().Be(DataResponseType.Success); result.Entity.Name.Should().Be("A"); }
public IStitchAdaptor Create(PackageFile packageFile, StitchInstance stitchInstance) { var context = new CoreStitchContext(stitchInstance.Id); switch (packageFile.Adaptor.Type) { //case InstanceRunModeType.AppDomain: // return new AppDomainAppAdaptor(instance, _network); case AdaptorType.ProcessV1: var pv1args = new ProcessV1Parameters(_configuration, _fileSystem, stitchInstance, packageFile.Adaptor.Parameters); return(new ProcessV1StitchAdaptor(_configuration, stitchInstance, context, pv1args)); case AdaptorType.BuildInClassV1: return(new BuiltInClassV1StitchAdaptor(packageFile, stitchInstance, context)); } throw new Exception("Run mode not supported"); }
private IStitchAdaptor GetOrCreateStitchAdaptor(PackageFile packageFile, StitchInstance stitchInstance) { var adaptor = _adaptors.Get(stitchInstance.Id); if (adaptor != null) { return(adaptor); } adaptor = _adaptorFactory.Create(packageFile, stitchInstance); adaptor.StitchContext.DataDirectory = _fileSystem.GetInstanceDataDirectoryPath(stitchInstance.Id); adaptor.StitchContext.StitchStateChange += OnStitchStateChange; adaptor.StitchContext.HeartbeatReceived += OnStitchHeartbeatSyncReceived; adaptor.StitchContext.LogsReceived += OnStitchLogsReceived; adaptor.StitchContext.RequestResponseReceived += OnStitchResponseReceived; adaptor.StitchContext.DataMessageReceived += OnDataMessageReceived; _adaptors.Add(stitchInstance.Id, adaptor); return(adaptor); }
public ProcessStitchAdaptor(CrossStitchCore core, StitchesConfiguration configuration, StitchInstance stitchInstance, IStitchEventObserver observer, ProcessParameters parameters, IModuleLog log) { Assert.ArgNotNull(core, nameof(core)); Assert.ArgNotNull(configuration, nameof(configuration)); Assert.ArgNotNull(stitchInstance, nameof(stitchInstance)); Assert.ArgNotNull(observer, nameof(observer)); Assert.ArgNotNull(parameters, nameof(parameters)); Assert.ArgNotNull(log, nameof(log)); _core = core; _stitchInstance = stitchInstance; _observer = observer; _parameters = parameters; _log = log; _channelFactory = new CoreMessageChannelFactory(core.NodeId, stitchInstance.Id); _serializerFactory = new MessageSerializerFactory(); _processFactory = new ProcessFactory(stitchInstance, core, log); _stopRequested = false; }
public InstanceActionResult Stop(StitchInstance stitchInstance) { try { var adaptor = _adaptors.Get(stitchInstance.Id); if (adaptor == null) { return(InstanceActionResult.NotFound(stitchInstance.Id)); } adaptor.Stop(); stitchInstance.State = InstanceStateType.Stopped; return(InstanceActionResult.Result(stitchInstance.Id, true, stitchInstance)); } catch (Exception e) { return(InstanceActionResult.Failure(stitchInstance.Id, true, stitchInstance, e)); } }
public InstanceActionResult Start(PackageFile packageFile, StitchInstance stitchInstance) { if (string.IsNullOrEmpty(stitchInstance?.Id)) { return(InstanceActionResult.BadRequest()); } string instanceId = stitchInstance.Id; IStitchAdaptor adaptor = null; try { stitchInstance.State = InstanceStateType.Stopped; adaptor = GetOrCreateStitchAdaptor(packageFile, stitchInstance); if (adaptor == null) { stitchInstance.State = InstanceStateType.Missing; return(InstanceActionResult.NotFound(instanceId)); } // TODO: On Stitch start, we should send it information about the application topology // TODO: We should also send application topology change notifications to every Stitch // involved in the affected application. bool started = adaptor.Start(); if (started) { stitchInstance.State = InstanceStateType.Started; } return(InstanceActionResult.Result(instanceId, started, stitchInstance)); } catch (Exception e) { stitchInstance.State = InstanceStateType.Error; return(InstanceActionResult.Failure(stitchInstance.Id, adaptor != null, e)); } }
private InstanceResponse StopInstanceInternal(InstanceRequest request, StitchInstance instance) { if (instance == null) { _log.LogError("Could not find stitch {0}", request.Id); return(InstanceResponse.Failure(request)); } var stopResult = _stitchInstanceManager.Stop(instance); _data.Save(stopResult.StitchInstance); if (!stopResult.Success || stopResult.StitchInstance.State != InstanceStateType.Stopped) { _log.LogError("Could not stop stitch {0}", request.Id); return(InstanceResponse.Create(request, false)); } _log.LogDebug("Stitch instance {0} Id={3} stopped", instance.GroupName, instance.Id); _notifier.StitchStopped(instance); return(InstanceResponse.Create(request, true)); }
public ProcessV1StitchAdaptor(StitchesConfiguration configuration, StitchInstance stitchInstance, CoreStitchContext stitchContext, ProcessV1Parameters parameters) { if (configuration == null) { throw new ArgumentNullException(nameof(configuration)); } if (stitchInstance == null) { throw new ArgumentNullException(nameof(stitchInstance)); } if (stitchContext == null) { throw new ArgumentNullException(nameof(stitchContext)); } if (parameters == null) { throw new ArgumentNullException(nameof(parameters)); } _stitchInstance = stitchInstance; StitchContext = stitchContext; _parameters = parameters; _configuration = configuration; }
public void Build_Test() { var modules = new[] { "A", "B", "C" }; var stitches = new StitchInstance[] { new StitchInstance { Id = "1", GroupName = new StitchGroupName("A.B.C"), State = InstanceStateType.Running }, new StitchInstance { Id = "2", GroupName = new StitchGroupName("A.B.C"), State = InstanceStateType.Started }, new StitchInstance { Id = "3", GroupName = new StitchGroupName("A.B.C"), State = InstanceStateType.Stopped } }; var zones = new[] { "_all", "some", "none" }; var target = new NodeStatusBuilder("NodeId", "NodeName", "NetworkNodeId", zones, modules, stitches); var result = target.Build(); result.Id.Should().Be("NodeId"); result.Name.Should().Be("NodeName"); result.NetworkNodeId.Should().Be("NetworkNodeId"); result.RunningModules.Should().Contain(modules); // TODO: We should keep track of zones in the Master module and fill this in result.Zones.Count.Should().Be(3); result.StitchInstances.Count.Should().Be(3); }
private InstanceResponse StartInstanceInternal(InstanceRequest request, PackageFile packageFile, StitchInstance instance) { if (instance == null) { return(InstanceResponse.Failure(request)); } var result = _stitchInstanceManager.Start(packageFile, instance); _data.Save(instance); if (!result.Success) { _log.LogError(result.Exception, "Could not start stitch {0}", request.Id); return(InstanceResponse.Create(request, result.Success, instance)); } _log.LogInformation("Started stitch {0} Id={1}", result.StitchInstance.GroupName, result.StitchInstance.Id); _notifier.StitchStarted(instance); return(InstanceResponse.Create(request, result.Success, instance)); }
public BuiltInClassV1StitchAdaptor(PackageFile packageFile, StitchInstance stitchInstance, CoreStitchContext stitchContext) { StitchContext = stitchContext; _stitchInstance = stitchInstance; _parameters = new BuiltInClassV1Parameters(packageFile.Adaptor.Parameters); }
public ProcessV1Parameters(StitchesConfiguration configuration, StitchFileSystem fileSystem, StitchInstance stitch, Dictionary <string, string> parameters) { // Use the dir if specified, otherwise default to the running dir from the file system var defaultRunningDir = fileSystem.GetInstanceRunningDirectory(stitch.Id); DirectoryPath = parameters.GetOrAdd(Parameters.DirectoryPath, defaultRunningDir); // Executable name must be specified. Get it and validate ExecutableName = parameters.GetOrDefault(Parameters.ExecutableName); if (string.IsNullOrEmpty(ExecutableName)) { throw new Exception("Stitch executable name is not specified"); } // Custom args are optional ExecutableArguments = parameters.GetOrAdd(Parameters.ExecutableArguments, "") ?? ""; string executableExt = Path.GetExtension(ExecutableName).ToLower(); var extConfig = configuration.Extensions.GetOrDefault(executableExt, new StitchesExtensionConfiguration()); // Use the format from the StitchInstance if specified, otherwise the one configured // for the extension, otherwise fall back to the default. string executableFormat = "{DirectoryPath}\\{ExecutableName}"; if (!string.IsNullOrEmpty(extConfig.ExecutableFormat)) { executableFormat = extConfig.ExecutableFormat; } ExecutableFormat = parameters.GetOrAdd(Parameters.ExecutableFormat, executableFormat); // Use the format from the StitchInstance if specified, otherwise the one configured // for the extension, otherwise fall back to the default. string argsFormat = "{CoreArgs} -- {CustomArgs}"; if (!string.IsNullOrEmpty(extConfig.ArgumentsFormat)) { argsFormat = extConfig.ArgumentsFormat; } ArgumentsFormat = parameters.GetOrAdd(Parameters.ArgumentsFormat, argsFormat); }
public ProcessParameters(StitchesConfiguration configuration, StitchFileSystem fileSystem, StitchInstance stitch, PackageFile packageFile) { var parameters = packageFile.Adaptor.Parameters; // Use the dir if specified, otherwise default to the running dir from the file system var defaultRunningDir = fileSystem.GetInstanceRunningDirectory(stitch.Id); RunningDirectory = parameters.GetOrAdd(Parameters.RunningDirectory, defaultRunningDir); var defaultDataDir = fileSystem.GetInstanceDataDirectoryPath(stitch.Id); DataDirectory = parameters.GetOrAdd(Parameters.DataDirectory, defaultDataDir); // Executable name must be specified. Get it and validate ExecutableName = parameters.GetOrDefault(Parameters.ExecutableName); if (string.IsNullOrEmpty(ExecutableName)) { throw new Exception("Stitch executable name is not specified"); } // Custom args are optional ExecutableArguments = parameters.GetOrAdd(Parameters.ExecutableArguments, "") ?? ""; string executableExt = Path.GetExtension(ExecutableName).ToLower(); var extConfig = configuration.Extensions.GetOrDefault(executableExt, new StitchesExtensionConfiguration()); // Use the format from the StitchInstance if specified, otherwise the one configured // for the extension, otherwise fall back to the default. string executableFormat = "{DirectoryPath}\\{ExecutableName}"; if (!string.IsNullOrEmpty(extConfig.ExecutableFormat)) { executableFormat = extConfig.ExecutableFormat; } executableFormat = FileSystem.FixPath(executableFormat); ExecutableFormat = parameters.GetOrAdd(Parameters.ExecutableFormat, executableFormat); // Use the format from the StitchInstance if specified, otherwise the one configured // for the extension, otherwise fall back to the default. string argsFormat = "{CoreArgs} -- {CustomArgs}"; if (!string.IsNullOrEmpty(extConfig.ArgumentsFormat)) { argsFormat = extConfig.ArgumentsFormat; } argsFormat = FileSystem.FixPath(argsFormat); ArgumentsFormat = parameters.GetOrAdd(Parameters.ArgumentsFormat, argsFormat); ChannelType = packageFile.Adaptor.Channel; SerializerType = packageFile.Adaptor.Serializer; }
public static InstanceResponse Success(InstanceRequest request, StitchInstance instance = null, string data = null) { return(Create(request, true, instance, data)); }