예제 #1
0
        /// <summary>
        /// Initializes sender.
        /// </summary>
        /// <param name="restApi">Server address</param>
        /// <param name="apiToken">API token of account</param>
        /// <returns>Task</returns>
        public async Task <List <string> > Initialize(string restApi, string apiToken, Func <string, string, ISpeckleGSASender> gsaSenderCreator)
        {
            var statusMessages = new List <string>();

            if (IsInit)
            {
                return(statusMessages);
            }

            if (!GSA.IsInit)
            {
                Status.AddError("GSA link not found.");
                return(statusMessages);
            }

            GSA.SetAssembliesSenderDictionaries();

            var startTime = DateTime.Now;

            Status.ChangeStatus("Reading GSA data into cache");

            //Update cache
            int numRowsUpdated = 0;
            int numKeywords    = 0;
            var updatedCache   = await Task.Run(() => UpdateCache(out numRowsUpdated, out numKeywords));

            if (!updatedCache)
            {
                Status.AddError("Error in communicating GSA - please check if the GSA file has been closed down");
                return(statusMessages);
            }
            Status.AddMessage("Read " + numRowsUpdated + " GWA lines across " + numKeywords + " keywords into cache");

            // Grab all GSA related object
            Status.ChangeStatus("Preparing to read GSA Objects");

            // Run initialize sender method in interfacer
            var objTypes    = GetAssembliesTypes();
            var streamNames = GetStreamNames(objTypes);

            CreateStreamMap(objTypes);

            // Create the streams
            Status.ChangeStatus("Creating streams");

            await CreateInitialiseSenders(streamNames, gsaSenderCreator, restApi, apiToken);

            TimeSpan duration = DateTime.Now - startTime;

            Status.AddMessage("Duration of initialisation: " + duration.ToString(@"hh\:mm\:ss"));
            Status.ChangeStatus("Ready to stream");
            IsInit = true;

            return(statusMessages);
        }
예제 #2
0
        private Dictionary <string, Dictionary <string, List <SpeckleObject> > > CreateStreamBuckets()
        {
            var buckets = new Dictionary <string, Dictionary <string, List <SpeckleObject> > >();

            var currentObjects = GSA.GetAllConvertedGsaObjectsByType();

            foreach (var t in currentObjects.Keys)
            {
                //var bucketName = GSA.App.Settings.SeparateStreams ? StreamMap[kvp.Key] : "Full Model";
                var bucketName = (string)t.GetAttribute("Stream");

                foreach (IGSASpeckleContainer obj in currentObjects[t])
                {
                    if (GSA.App.LocalSettings.SendOnlyMeaningfulNodes)
                    {
                        if (obj.GetType().Name == "GSANode" && !(bool)obj.GetType().GetField("ForceSend").GetValue(obj))
                        {
                            continue;
                        }
                    }
                    var insideVal = (SpeckleObject)obj.SpeckleObject;

                    insideVal.GenerateHash();

                    if (!buckets.ContainsKey(bucketName))
                    {
                        buckets[bucketName] = new Dictionary <string, List <SpeckleObject> >();
                    }

                    if (buckets[bucketName].ContainsKey(insideVal.GetType().Name))
                    {
                        buckets[bucketName][insideVal.GetType().Name].Add(insideVal);
                    }
                    else
                    {
                        buckets[bucketName][insideVal.GetType().Name] = new List <SpeckleObject>()
                        {
                            insideVal
                        };
                    }
                }
            }
            return(buckets);
        }
예제 #3
0
        private Dictionary <string, Dictionary <string, List <object> > > CreateStreamBuckets()
        {
            var streamBuckets = new Dictionary <string, Dictionary <string, List <object> > >();

            var currentObjects = GSA.GetAllConvertedGsaObjectsByType();

            foreach (var kvp in currentObjects)
            {
                var targetStream = GSA.Settings.SeparateStreams ? StreamMap[kvp.Key] : "Full Model";

                foreach (object obj in kvp.Value)
                {
                    if (GSA.Settings.SendOnlyMeaningfulNodes)
                    {
                        if (obj.GetType().Name == "GSANode" && !(bool)obj.GetType().GetField("ForceSend").GetValue(obj))
                        {
                            continue;
                        }
                    }
                    object insideVal = obj.GetType().GetProperty("Value").GetValue(obj);

                    ((SpeckleObject)insideVal).GenerateHash();

                    if (!streamBuckets.ContainsKey(targetStream))
                    {
                        streamBuckets[targetStream] = new Dictionary <string, List <object> >();
                    }

                    if (streamBuckets[targetStream].ContainsKey(insideVal.GetType().Name))
                    {
                        streamBuckets[targetStream][insideVal.GetType().Name].Add(insideVal);
                    }
                    else
                    {
                        streamBuckets[targetStream][insideVal.GetType().Name] = new List <object>()
                        {
                            insideVal
                        };
                    }
                }
            }
            return(streamBuckets);
        }
예제 #4
0
        private async Task CreateInitialiseSenders(List <string> streamNames, Func <string, string, ISpeckleGSASender> GSASenderCreator, string restApi, string apiToken)
        {
            GSA.RemoveUnusedStreamInfo(streamNames);

            Senders = new Dictionary <string, ISpeckleGSASender>();

            foreach (string streamName in streamNames)
            {
                Senders[streamName] = GSASenderCreator(restApi, apiToken);

                if (!GSA.SenderInfo.ContainsKey(streamName))
                {
                    Status.AddMessage("Creating new sender for " + streamName);
                    await Senders[streamName].InitializeSender(null, null, streamName);
                    GSA.SenderInfo[streamName] = new Tuple <string, string>(Senders[streamName].StreamID, Senders[streamName].ClientID);
                }
                else
                {
                    await Senders[streamName].InitializeSender(GSA.SenderInfo[streamName].Item1, GSA.SenderInfo[streamName].Item2, streamName);
                }
            }
        }
예제 #5
0
        private void UpdateStreamWithIds(List <Layer> layers, List <SpeckleObject> bucketObjects, ref int numErrors)
        {
            // Update stream with payload
            var placeholders = new List <SpeckleObject>();

            foreach (string id in bucketObjects.Select(bo => bo._id))
            {
                placeholders.Add(new SpecklePlaceholder()
                {
                    _id = id
                });
            }

            SpeckleStream updateStream = new SpeckleStream
            {
                Layers         = layers,
                Objects        = placeholders,
                Name           = StreamName,
                BaseProperties = GSA.GetBaseProperties()
            };

            try
            {
                _ = apiClient.StreamUpdateAsync(StreamID, updateStream).Result;
                apiClient.Stream.Layers  = updateStream.Layers.ToList();
                apiClient.Stream.Objects = placeholders;
                GSA.GsaApp.gsaMessenger.CacheMessage(MessageIntent.Display, MessageLevel.Information, "Updated the stream's object list on the server", StreamID);
            }
            catch (Exception ex)
            {
                numErrors++;
                GSA.GsaApp.gsaMessenger.CacheMessage(MessageIntent.Display, MessageLevel.Error, "Updating the stream's object list on the server", StreamID);
                var speckleExceptionContext = ExtractSpeckleExceptionContext(ex);
                var errContext = speckleExceptionContext.Concat(new[] { "Error updating the stream's object list on the server", "StreamId=" + StreamID });
                GSA.GsaApp.gsaMessenger.CacheMessage(MessageIntent.TechnicalLog, MessageLevel.Error, ex, errContext.ToArray());
            }

            return;
        }
예제 #6
0
        /// <summary>
        /// Trigger to update stream.
        /// </summary>
        public void Trigger()
        {
            if ((IsBusy) || (!IsInit))
            {
                return;
            }

            var startTime = DateTime.Now;

            IsBusy             = true;
            GSA.Settings.Units = GSA.gsaProxy.GetUnits();

            //Clear previously-sent objects
            GSA.ClearSenderDictionaries();

            // Read objects
            var currentBatch = new List <Type>();

            bool changeDetected = false;

            do
            {
                ExecuteWithLock(ref traversedSerialisedLock, () =>
                {
                    currentBatch = FilteredReadTypePrereqs.Where(i => i.Value.Count(x => !traversedSerialisedTypes.Contains(x)) == 0).Select(i => i.Key).ToList();
                    currentBatch.RemoveAll(i => traversedSerialisedTypes.Contains(i));
                });

#if DEBUG
                foreach (var t in currentBatch)
                {
                    ProcessTypeForSending(t, ref changeDetected);
                }
#else
                Parallel.ForEach(currentBatch, t =>
                {
                    ProcessTypeForSending(t, ref changeDetected);
                }
                                 );
#endif
            } while (currentBatch.Count > 0);

            if (!changeDetected)
            {
                Status.ChangeStatus("Finished sending", 100);
                IsBusy = false;
                return;
            }

            // Separate objects into streams
            var streamBuckets = CreateStreamBuckets();

            TimeSpan duration = DateTime.Now - startTime;
            Status.AddMessage("Duration of conversion to Speckle: " + duration.ToString(@"hh\:mm\:ss"));
            startTime = DateTime.Now;

            // Send package
            Status.ChangeStatus("Sending to Server");

            foreach (var k in streamBuckets.Keys)
            {
                Status.ChangeStatus("Sending to stream: " + Senders[k].StreamID);

                var title      = GSA.gsaProxy.GetTitle();
                var streamName = GSA.Settings.SeparateStreams ? title + "." + k : title;

                Senders[k].UpdateName(streamName);
                Senders[k].SendGSAObjects(streamBuckets[k]);
            }

            duration = DateTime.Now - startTime;
            Status.AddMessage("Duration of sending to Speckle: " + duration.ToString(@"hh\:mm\:ss"));

            IsBusy = false;
            Status.ChangeStatus("Finished sending", 100);
        }
예제 #7
0
        /// <summary>
        /// Trigger to update stream.
        /// </summary>
        public async Task Trigger()
        {
            if ((IsBusy) || (!IsInit))
            {
                return;
            }

            IsBusy = true;
            //GSA.App.Settings.Units = GSA.App.Proxy.GetUnits();

            #region update_cache
            var startTime = DateTime.Now;
            statusProgress.Report("Reading GSA data into cache");

            var txTypePrereqs = GSA.TxTypeDependencies;

            //Update cache
            var updatedCache = UpdateCache();
            if (!updatedCache)
            {
                this.loggingProgress.Report(new MessageEventArgs(SpeckleGSAInterfaces.MessageIntent.Display, SpeckleGSAInterfaces.MessageLevel.Error, "Error in communicating GSA - please check if the GSA file has been closed down"));
                return;
            }

            TimeSpan duration = DateTime.Now - startTime;
            loggingProgress.Report(new MessageEventArgs(SpeckleGSAInterfaces.MessageIntent.Display, SpeckleGSAInterfaces.MessageLevel.Information, "Duration of reading GSA model into cache: " + duration.ToString(@"hh\:mm\:ss")));
            loggingProgress.Report(new MessageEventArgs(SpeckleGSAInterfaces.MessageIntent.Telemetry, SpeckleGSAInterfaces.MessageLevel.Information, "send", "update-cache", "duration", duration.ToString(@"hh\:mm\:ss")));
            #endregion

            #region GSA_model_to_SpeckleObjects
            startTime = DateTime.Now;

            //Clear previously-sent objects
            GSA.ClearSenderDictionaries();

            lock (traversedSerialisedLock)
            {
                traversedSerialisedTypes.Clear();
            }

            var changeDetected = ProcessTxObjects();

            if (!changeDetected)
            {
                statusProgress.Report("No new or changed objects to send");
                IsBusy = false;
                return;
            }

            duration = DateTime.Now - startTime;
            loggingProgress.Report(new MessageEventArgs(SpeckleGSAInterfaces.MessageIntent.Display, SpeckleGSAInterfaces.MessageLevel.Information, "Duration of conversion to Speckle: " + duration.ToString(@"hh\:mm\:ss")));
            loggingProgress.Report(new MessageEventArgs(SpeckleGSAInterfaces.MessageIntent.Telemetry, SpeckleGSAInterfaces.MessageLevel.Information, "send", "conversion", "duration", duration.ToString(@"hh\:mm\:ss")));
            #endregion

            #region create_necessary_streams
            startTime = DateTime.Now;

            // Separate objects into streams
            var allBuckets = CreateStreamBuckets();

            var bucketsToCreate = allBuckets.Keys.Except(Senders.Keys).ToList();

            //TO DO: review this, possibly move to the kit
            if (GSA.GsaApp.Settings.StreamSendConfig == StreamContentConfig.TabularResultsOnly && bucketsToCreate.Contains("results"))
            {
                bucketsToCreate = new List <string> {
                    "results"
                };
            }

            //Now check if any streams need to be created
            if (bucketsToCreate.Count() > 0)
            {
                Progress <int> incrementProgress = new Progress <int>();
                incrementProgress.ProgressChanged += IncorporateSendPayloadProgress;
                Progress <int> totalProgress = new Progress <int>();
                totalProgress.ProgressChanged += IncorporateNewNumPayloadsProgress;

                if (savedSenderSidRecords != null && savedSenderSidRecords.Count() > 0)
                {
                    var sidRecordByBucket = savedSenderSidRecords.ToDictionary(r => r.Bucket, r => r);

                    var savedBuckets       = sidRecordByBucket.Keys.ToList();
                    var reuseBuckets       = sidRecordByBucket.Keys.Where(ssn => bucketsToCreate.Any(sn => ssn.Equals(sn, StringComparison.InvariantCultureIgnoreCase))).ToList();
                    var discardStreamNames = sidRecordByBucket.Keys.Except(reuseBuckets);
                    foreach (var bucket in reuseBuckets)
                    {
                        var sender      = gsaSenderCreator(restApi, apiToken);
                        var initialised = await sender.InitializeSender(documentName, sidRecordByBucket[bucket].StreamId, sidRecordByBucket[bucket].ClientId, totalProgress, incrementProgress);

                        if (initialised)
                        {
                            Senders.Add(bucket, sender);

                            bucketsToCreate.Remove(bucket);
                        }
                    }
                    foreach (var dsn in discardStreamNames)
                    {
                        streamDeletionProgress.Report(sidRecordByBucket[dsn]);
                    }
                }

                foreach (var sn in bucketsToCreate)
                {
                    var streamName = string.IsNullOrEmpty(documentTitle) ? "GSA " + sn : documentTitle + " (" + sn + ")";

                    var sender      = gsaSenderCreator(restApi, apiToken);
                    var initialised = await sender.InitializeSender(documentName, streamName, basePropertyUnits, tolerance, angleTolerance, totalProgress, incrementProgress);

                    if (initialised)
                    {
                        Senders.Add(sn, sender);
                        streamCreationProgress.Report(new SidSpeckleRecord(Senders[sn].StreamId, sn, Senders[sn].ClientId, streamName));
                    }
                }
            }

            #endregion

            #region send_to_server
            // Send package
            statusProgress.Report("Sending to Server");

            int numErrors    = 0;
            var sendingTasks = new List <Task>();
            foreach (var k in Senders.Keys)
            {
                statusProgress.Report("Sending to stream: " + Senders[k].StreamId);
                numErrors += Senders[k].SendObjects(allBuckets[k]);
            }

            if (numErrors > 0)
            {
                loggingProgress.Report(new MessageEventArgs(SpeckleGSAInterfaces.MessageIntent.Display, SpeckleGSAInterfaces.MessageLevel.Error,
                                                            numErrors + " errors found with sending to the server. Refer to the .txt log file(s) in " + AppDomain.CurrentDomain.BaseDirectory));
            }

            duration = DateTime.Now - startTime;
            loggingProgress.Report(new MessageEventArgs(SpeckleGSAInterfaces.MessageIntent.Display, SpeckleGSAInterfaces.MessageLevel.Information, "Duration of sending to Speckle: " + duration.ToString(@"hh\:mm\:ss")));
            loggingProgress.Report(new MessageEventArgs(SpeckleGSAInterfaces.MessageIntent.Telemetry, SpeckleGSAInterfaces.MessageLevel.Information, "send", "sending", "duration", duration.ToString(@"hh\:mm\:ss")));
            #endregion
            IsBusy = false;
            statusProgress.Report("Finished sending");
        }