Пример #1
0
 public static RESTCallHandler getHandler()
 {
     if (instance == null)
     {
         instance = new RESTCallHandler();
     }
     return(instance);
 }
        public EventNotificationStatus ProcessEvent(TeamFoundationRequestContext requestContext,
                                                    NotificationType notificationType,
                                                    object notificationEventArgs,
                                                    out int statusCode,
                                                    out string statusMessage,
                                                    out ExceptionPropertyCollection properties)
        {
            statusCode    = 0;
            properties    = null;
            statusMessage = String.Empty;

            // TODO: Make impact on performance minimal by optimize logic for understanding if we are interested
            // in this event or not. Also put longer running task in Jobs. For now - do basic checks.

            if (notificationType != NotificationType.Notification)
            {
                return(EventNotificationStatus.ActionPermitted);
            }
            var notification = notificationEventArgs as WorkItemChangedEvent;

            if (notification == null)
            {
                return(EventNotificationStatus.ActionPermitted);
            }

            // Should not thow exception - if so, the code will be disabled by TFS.
            try
            {
                // Init adapter - will only be done once per deployment of plugin
                if (!HandlerSettings.initFromFile())
                {
                    // Fatal error when trying to init - return
                    // TODO: How allow retry without server restart or re-deploy of plugin?
                    return(EventNotificationStatus.ActionPermitted);
                }

                // Handle case where event is fired because of Save we initiated.
                if (ignoreSaveEvent(notification))
                {
                    return(EventNotificationStatus.ActionPermitted);
                }

                int workItemId = notification.CoreFields.IntegerFields[0].NewValue;
                HandlerSettings.LogMessage(
                    String.Format(
                        "WorkItem with id {0} named '{1}' was saved.",
                        "" + workItemId,
                        notification.WorkItemTitle),
                    HandlerSettings.LoggingLevel.INFO);

                // TODO: In examples I have seen you get actual WI by process below, i.e. opening a new connection to TFS.
                // I would expect as we already are in the context of a TFS you somehow could use this. Note: There is a
                // WorkItem class in the namespace Microsoft.TeamFoundation.WorkItemTracking.Server - no documentation found.

                Microsoft.TeamFoundation.WorkItemTracking.Client.WorkItem workItem = getStore().GetWorkItem(workItemId);

                // If a new item is based on an existing (copied) we need to reset the connection to any existing TR.
                // Note exception if item is created by the functional user. This to allow test case where TR is set
                // by test case code.
                String user = HandlerSettings.GetSignumForChangeNotification(workItem, notification);
                if (notification.ChangeType == ChangeTypes.New)
                {
                    if (!user.Equals(HandlerSettings.TFSProviderUser, StringComparison.OrdinalIgnoreCase))
                    {
                        // Note: Will not save - done in event handling or at end.
                        ECRMapper.disconnectBug(workItem);
                    }
                }

                ProductMapper.EventType eventType =
                    ProductMapper.getInstance().GetEventType(workItem, notification, user);

                if (eventType == ProductMapper.EventType.CreateUpdate)
                {
                    // Handle the event as the release is for a maintenance product
                    RESTCallHandler.getHandler().handleEvent(workItem, user, notification);
                }
                else if (eventType == ProductMapper.EventType.Disconnect)
                {
                    // Handle the event as the release is for a maintenance product
                    RESTCallHandler.getHandler().handleDisconnectEvent(workItem, user, notification);
                }
                else
                {
                    HandlerSettings.LogMessage(
                        String.Format(
                            "WorkItem with id {0} save event was ignored by integration.",
                            "" + workItemId),
                        HandlerSettings.LoggingLevel.INFO);
                }

                // If updated but not saved, we need to explicitly call save. Very unusual case but will happen
                // e.g. if item is copied with a product value that before was in maintenance but now not. Then
                // code to disconnect bug is called, but event not handled or Bug saved, hence save here.
                if (workItem.IsDirty)
                {
                    RESTCallHandler.getHandler().saveBug(workItem);
                }
            }
            catch (Exception ex)
            {
                // Error when reading mapping file - assume fatal
                HandlerSettings.LogMessage(
                    "Error when handling the change of workitem." +
                    "\nError: " + ex.Message +
                    "\nStack: " + ex.StackTrace,
                    HandlerSettings.LoggingLevel.ERROR);
            }
            return(EventNotificationStatus.ActionPermitted);
        }
Пример #3
0
        // Define the event handlers.
        private static void OnChanged(object source, FileSystemEventArgs e)
        {
            // The file is changed or being changed - lets make sure we can read before proceeding
            while (true)
            {
                try
                {
                    using (Stream stream = System.IO.File.Open(
                               e.FullPath, FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite))
                    {
                        if (stream != null)
                        {
                            LogMessage(
                                String.Format("File {0} changed, will re-read.", e.FullPath),
                                LoggingLevel.INFO);
                            break;
                        }
                    }
                }
                catch (FileNotFoundException ex)
                {
                    LogMessage(
                        String.Format("File {0} not ready for re-read yet: {1}", e.FullPath, ex.Message),
                        LoggingLevel.INFO);
                }
                catch (IOException ex)
                {
                    LogMessage(
                        String.Format("File {0} not ready for re-read yet: {1}", e.FullPath, ex.Message),
                        LoggingLevel.INFO);
                }
                catch (UnauthorizedAccessException ex)
                {
                    LogMessage(
                        String.Format("File {0} not ready for re-read yet: {1}", e.FullPath, ex.Message),
                        LoggingLevel.INFO);
                }
                Thread.Sleep(500);
            }

            try
            {
                FileSystemWatcher watcher = (FileSystemWatcher)source;
                if (configFileChangeTimes.ContainsKey(watcher))
                {
                    DateTime lastKnownChange = configFileChangeTimes[watcher];
                    DateTime lastChange      = File.GetLastWriteTime(e.FullPath);
                    if (lastKnownChange == lastChange)
                    {
                        // Event originating because of same change - ignore
                        return;
                    }
                }

                // Set new last file write time
                configFileChangeTimes[watcher] = File.GetLastWriteTime(e.FullPath);

                // Clear cached values
                WorkItemChangedEventHandler.clearConnection();
                RESTCallHandler.clearHandler();

                // Re-initialize by re-reading all config files
                initiated = false;
                initFromFile();
            }
            catch (Exception ex)
            {
                LogMessage(
                    String.Format("Failed to re-read the property file: {1}", ex.Message),
                    LoggingLevel.ERROR);
            }
        }
Пример #4
0
 public static void clearHandler()
 {
     instance = null;
 }