Пример #1
0
 public BuiltInClassV1StitchAdaptor(PackageFile packageFile, StitchInstance instance, IStitchEventObserver observer, IModuleLog log)
 {
     Observer    = observer;
     _instance   = instance;
     _log        = log;
     _parameters = new BuiltInClassV1Parameters(packageFile.Adaptor.Parameters);
 }
Пример #2
0
 public void StitchStopped(StitchInstance instance)
 {
     _messageBus.Publish(StitchInstanceEvent.ChannelStopped, new StitchInstanceEvent
     {
         InstanceId = instance.Id,
         GroupName  = instance.GroupName
     });
 }
Пример #3
0
        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();
            }
        }
Пример #4
0
 public static InstanceActionResult Result(string instanceId, bool ok, StitchInstance instance = null)
 {
     return(new InstanceActionResult
     {
         Found = true,
         InstanceId = instanceId,
         Success = ok,
         StitchInstance = instance
     });
 }
Пример #5
0
        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();
            }
        }
Пример #6
0
 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
     });
 }
Пример #7
0
        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);
        }
Пример #8
0
        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");
        }
Пример #9
0
        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();
            }
        }
Пример #10
0
        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);
        }
Пример #11
0
        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);
        }
Пример #12
0
        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);
        }
Пример #13
0
        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);
        }
Пример #14
0
        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");
        }
Пример #15
0
        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);
        }
Пример #16
0
        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());
        }
Пример #17
0
        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");
        }
Пример #18
0
        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");
        }
Пример #19
0
        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;
        }
Пример #21
0
        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));
            }
        }
Пример #22
0
        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));
            }
        }
Пример #23
0
        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));
        }
Пример #24
0
        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);
        }
Пример #26
0
        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));
        }
Пример #27
0
 public BuiltInClassV1StitchAdaptor(PackageFile packageFile, StitchInstance stitchInstance, CoreStitchContext stitchContext)
 {
     StitchContext   = stitchContext;
     _stitchInstance = stitchInstance;
     _parameters     = new BuiltInClassV1Parameters(packageFile.Adaptor.Parameters);
 }
Пример #28
0
        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);
        }
Пример #29
0
        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;
        }
Пример #30
0
 public static InstanceResponse Success(InstanceRequest request, StitchInstance instance = null, string data = null)
 {
     return(Create(request, true, instance, data));
 }