Exemple #1
0
        public void Can_roundtrip_base_generic_instance()
        {
            // Arrange
            var resourceEvent = new ResourceEvent <MyResource>(
                ResourceEventChangeType.Created,
                "createdInTest",
                new MyResource("test-1234", "My named resource"))
            {
                Metadata = new Dictionary <string, object>
                {
                    ["stringKey"]  = "value1",
                    ["numberKey"]  = 1,
                    ["booleanKey"] = true,
                },

                SecureData = new Dictionary <string, object>
                {
                    ["key1"] = "value1",
                },

                ChangedValues = new Dictionary <string, object>
                {
                    ["key1"] = "changed-value1",
                },

                CorrelationId = "my-correlation-id",
            };

            // Act
            var asJson     = JsonSerializer.Serialize(resourceEvent, JsonSerializerOptions);
            var rehydrated = JsonSerializer.Deserialize <ResourceEvent <MyResource> >(asJson, JsonSerializerOptions);

            // Assert
            rehydrated.Should().BeEquivalentTo(resourceEvent, o => o.Excluding(e => e.ResourceType));
        }
        private static async Task PopulateResourceEventData(
            IResourceEventRepository resourceEventRepository,
            ApiOperationContext context,
            ResourceEvent resourceEvent)
        {
            // Get the latest after creation or update (cannot, obviously, get for a deleted record)
            if (resourceEvent.ChangeType != ResourceEventChangeType.Deleted)
            {
                resourceEvent.Data = await GetByIdAsync(context, resourceEvent.SelfQuery);
            }

            if (resourceEvent.ChangeType == ResourceEventChangeType.Updated)
            {
                var previousResource =
                    await resourceEventRepository.GetCurrentDataAsync(resourceEvent.Href, resourceEvent.ResourceType);

                // There are cases where the old resource will not exist because resources being saved was a new
                // introduction after being in prod for over a year
                if (previousResource != null)
                {
                    resourceEvent.ChangedValues = ObjectComparer.GetPreviousValues(
                        previousResource,
                        resourceEvent.Data);
                }
            }
        }
            public override void Transition(LocalizedResource rsrc, ResourceEvent @event)
            {
                // Note: assumes that localizing container must succeed or fail
                ResourceReleaseEvent relEvent = (ResourceReleaseEvent)@event;

                rsrc.Release(relEvent.GetContainer());
            }
            public override void Transition(LocalizedResource rsrc, ResourceEvent @event)
            {
                ResourceRecoveredEvent recoveredEvent = (ResourceRecoveredEvent)@event;

                rsrc.localPath = recoveredEvent.GetLocalPath();
                rsrc.size      = recoveredEvent.GetSize();
            }
        public static ResourceEvent <TestResource>[] ToBasicExpected(this IEnumerable <ScheduledEvent <TestResource> > events)
        {
            var lastKnown = new Dictionary <int, TestResource>();
            var retval    = new List <ResourceEvent <TestResource> >();

            foreach (var e in events.Select(x => x.Event))
            {
                var item = e;
                if (e.EventFlags.HasFlag(EventTypeFlags.Modify) && lastKnown.TryGetValue(e.Value.Key, out var oldValue))
                {
                    item = new ResourceEvent <TestResource>(e.EventFlags, e.Value, oldValue);
                }

                if (e.EventFlags.HasFlag(EventTypeFlags.Delete))
                {
                    lastKnown.Remove(e.Value.Key);
                }
                else
                {
                    if (e.Value != null)
                    {
                        lastKnown[e.Value.Key] = e.Value;
                    }
                }

                retval.Add(item);
            }

            return(retval.ToArray());
        }
Exemple #6
0
        public async Task <IActionResult> Edit(int id, [Bind("Id,ResourceId,PersonId,EventDate")] ResourceEvent resourceEvent)
        {
            if (id != resourceEvent.Id)
            {
                return(NotFound());
            }

            if (ModelState.IsValid)
            {
                try
                {
                    _resourceContext.Update(resourceEvent);
                    await _resourceContext.SaveChangesAsync();
                }
                catch (DbUpdateConcurrencyException)
                {
                    if (!ResourceEventExists(resourceEvent.Id))
                    {
                        return(NotFound());
                    }
                    else
                    {
                        throw;
                    }
                }
                return(RedirectToAction(nameof(Index)));
            }
            return(View(resourceEvent));
        }
Exemple #7
0
 private static async Task TryPopulateResourceEventDataAsync(
     ApiOperationContext context,
     ResourceEvent resourceEvent)
 {
     // Get the latest after creation or update (cannot, obviously, get for a deleted record)
     if (resourceEvent.ChangeType != ResourceEventChangeType.Deleted)
     {
         resourceEvent.Data = await GetByIdAsync(context, resourceEvent.SelfQuery);
     }
 }
            // dispatcher not typed
            public override void Transition(LocalizedResource rsrc, ResourceEvent @event)
            {
                // notify waiting containers
                ResourceRequestEvent reqEvent  = (ResourceRequestEvent)@event;
                ContainerId          container = reqEvent.GetContext().GetContainerId();

                [email protected](container);
                rsrc.dispatcher.GetEventHandler().Handle(new ContainerResourceLocalizedEvent(container
                                                                                             , rsrc.rsrc, rsrc.localPath));
            }
            // dispatcher not typed
            public override void Transition(LocalizedResource rsrc, ResourceEvent @event)
            {
                ResourceRequestEvent req       = (ResourceRequestEvent)@event;
                LocalizerContext     ctxt      = req.GetContext();
                ContainerId          container = ctxt.GetContainerId();

                [email protected](container);
                rsrc.dispatcher.GetEventHandler().Handle(new LocalizerResourceRequestEvent(rsrc,
                                                                                           req.GetVisibility(), ctxt, req.GetLocalResourceRequest().GetPattern()));
            }
            public override void Transition(LocalizedResource rsrc, ResourceEvent @event)
            {
                ResourceFailedLocalizationEvent failedEvent = (ResourceFailedLocalizationEvent)@event;
                Queue <ContainerId>             containers  = rsrc.@ref;

                foreach (ContainerId container in containers)
                {
                    rsrc.dispatcher.GetEventHandler().Handle(new ContainerResourceFailedEvent(container
                                                                                              , failedEvent.GetLocalResourceRequest(), failedEvent.GetDiagnosticMessage()));
                }
            }
Exemple #11
0
        public async Task <IActionResult> Create([Bind("ResourceId,PersonId,EventDate")] ResourceEvent resourceEvent)
        {
            if (ModelState.IsValid)
            {
                _resourceContext.Add(resourceEvent);
                await _resourceContext.SaveChangesAsync();

                return(RedirectToAction(nameof(Index)));
            }
            return(View(resourceEvent));
        }
            // dispatcher not typed
            public override void Transition(LocalizedResource rsrc, ResourceEvent @event)
            {
                ResourceLocalizedEvent locEvent = (ResourceLocalizedEvent)@event;

                rsrc.localPath = Path.GetPathWithoutSchemeAndAuthority(locEvent.GetLocation());
                rsrc.size      = locEvent.GetSize();
                foreach (ContainerId container in rsrc.@ref)
                {
                    rsrc.dispatcher.GetEventHandler().Handle(new ContainerResourceLocalizedEvent(container
                                                                                                 , rsrc.rsrc, rsrc.localPath));
                }
            }
Exemple #13
0
        public async Task Can_serialise_to_JSON()
        {
            // Arrange
            using var t = SystemTime.PauseForThread();
            t.SetUtcNow(new DateTime(2021, 07, 07, 0, 0, 0, DateTimeKind.Utc));

            var resourceEvent = new ResourceEvent <MyResource>(
                ResourceEventChangeType.Created,
                "createdInTest",
                new MyResource("test-1234", "My named resource"))
            {
                Metadata = new Dictionary <string, object>
                {
                    ["stringKey"]  = "value1",
                    ["numberKey"]  = 1,
                    ["booleanKey"] = true,
                },

                SecureData = new Dictionary <string, object>
                {
                    ["key1"] = "value1",
                },

                ChangedValues = new Dictionary <string, object>
                {
                    ["key1"] = "changed-value1",
                },

                CorrelationId = "my-correlation-id",

                Href = "https://www.my-api.com/my-resource/test-1234"
            };

            var prettyPrintOptions = new JsonSerializerOptions(JsonSerializerOptions)
            {
                WriteIndented = true
            };

            // Act
            var asJson = JsonSerializer.Serialize(resourceEvent, prettyPrintOptions);

            // Assert
            await Verifier.Verify(asJson);
        }
        public static void EventHandler(string script)
        {
            var e = new ResourceEvent(script);

            switch (script)
            {
            case RESOURCE_ADDED:
                ResourceAdded(e);
                break;

            case RESOURCE_REMOVED:
                ResourceRemoved(e);
                break;

            case RESOURCE_MODIFIED:
                ResourceModified(e);
                break;
            }
        }
Exemple #15
0
        private static async Task TryPopulateChangedValuesAsync(
            IResourceEventRepository resourceEventRepository,
            ResourceEvent resourceEvent)
        {
            if (resourceEvent.ChangeType == ResourceEventChangeType.Updated && resourceEvent.Data != null)
            {
                var previousResource =
                    await resourceEventRepository.GetCurrentDataAsync(resourceEvent.Href, resourceEvent.Data.GetType());

                // There are cases where the old resource will not exist because resources being saved was a new
                // introduction after being in prod for over a year
                if (previousResource != null)
                {
                    resourceEvent.ChangedValues = ObjectComparer.GetPreviousValues(
                        previousResource,
                        resourceEvent.Data);
                }
            }
        }
Exemple #16
0
        private void QueueActionLocked(ResourceEvent <TResource> obj)
        {
            var id = KeyOf(obj);

            var exists = _items.TryGetValue(id, out var deltas);

            if (!exists)
            {
                deltas     = new List <ResourceEvent <TResource> >();
                _items[id] = deltas;
                _queue.Enqueue(deltas);
            }

            deltas.Add(obj);
            CombineDeltas(deltas);
            if (_queue.Count == 1)             // we've just added to empty queue, kick off processing
            {
                OfferMessagesToLinks();
            }
        }
Exemple #17
0
        /*
         * Synchronizing this method for avoiding races due to multiple ResourceEvent's
         * coming to LocalResourcesTracker from Public/Private localizer and
         * Resource Localization Service.
         */
        public virtual void Handle(ResourceEvent @event)
        {
            lock (this)
            {
                LocalResourceRequest req  = @event.GetLocalResourceRequest();
                LocalizedResource    rsrc = localrsrc[req];
                switch (@event.GetType())
                {
                case ResourceEventType.Localized:
                {
                    if (useLocalCacheDirectoryManager)
                    {
                        Sharpen.Collections.Remove(inProgressLocalResourcesMap, req);
                    }
                    break;
                }

                case ResourceEventType.Request:
                {
                    if (rsrc != null && (!IsResourcePresent(rsrc)))
                    {
                        Log.Info("Resource " + rsrc.GetLocalPath() + " is missing, localizing it again");
                        RemoveResource(req);
                        rsrc = null;
                    }
                    if (null == rsrc)
                    {
                        rsrc           = new LocalizedResource(req, dispatcher);
                        localrsrc[req] = rsrc;
                    }
                    break;
                }

                case ResourceEventType.Release:
                {
                    if (null == rsrc)
                    {
                        // The container sent a release event on a resource which
                        // 1) Failed
                        // 2) Removed for some reason (ex. disk is no longer accessible)
                        ResourceReleaseEvent relEvent = (ResourceReleaseEvent)@event;
                        Log.Info("Container " + relEvent.GetContainer() + " sent RELEASE event on a resource request "
                                 + req + " not present in cache.");
                        return;
                    }
                    break;
                }

                case ResourceEventType.LocalizationFailed:
                {
                    /*
                     * If resource localization fails then Localized resource will be
                     * removed from local cache.
                     */
                    RemoveResource(req);
                    break;
                }

                case ResourceEventType.Recovered:
                {
                    if (rsrc != null)
                    {
                        Log.Warn("Ignoring attempt to recover existing resource " + rsrc);
                        return;
                    }
                    rsrc           = RecoverResource(req, (ResourceRecoveredEvent)@event);
                    localrsrc[req] = rsrc;
                    break;
                }
                }
                if (rsrc == null)
                {
                    Log.Warn("Received " + @event.GetType() + " event for request " + req + " but localized resource is missing"
                             );
                    return;
                }
                rsrc.Handle(@event);
                // Remove the resource if its downloading and its reference count has
                // become 0 after RELEASE. This maybe because a container was killed while
                // localizing and no other container is referring to the resource.
                // NOTE: This should NOT be done for public resources since the
                //       download is not associated with a container-specific localizer.
                if (@event.GetType() == ResourceEventType.Release)
                {
                    if (rsrc.GetState() == ResourceState.Downloading && rsrc.GetRefCount() <= 0 && rsrc
                        .GetRequest().GetVisibility() != LocalResourceVisibility.Public)
                    {
                        RemoveResource(req);
                    }
                }
                if (@event.GetType() == ResourceEventType.Localized)
                {
                    if (rsrc.GetLocalPath() != null)
                    {
                        try
                        {
                            stateStore.FinishResourceLocalization(user, appId, BuildLocalizedResourceProto(rsrc
                                                                                                           ));
                        }
                        catch (IOException ioe)
                        {
                            Log.Error("Error storing resource state for " + rsrc, ioe);
                        }
                    }
                    else
                    {
                        Log.Warn("Resource " + rsrc + " localized without a location");
                    }
                }
            }
        }
Exemple #18
0
        /// <summary>
        /// Synchronizes the specified cache with resource event stream such that cache is maintained up to date.
        /// </summary>
        /// <param name="source">The source sequence</param>
        /// <param name="cache">The cache to synchronize</param>
        /// <param name="keySelector">The key selector function</param>
        /// <typeparam name="TKey">The type of key</typeparam>
        /// <typeparam name="TResource">The type of resource</typeparam>
        /// <returns>Source sequence wrapped into <see cref="CacheSynchronized{T}"/>, which allows downstream consumers to synchronize themselves with cache version</returns>
        public static IObservable <CacheSynchronized <ResourceEvent <TResource> > > SynchronizeCache <TKey, TResource>(
            this IObservable <ResourceEvent <TResource> > source,
            ICache <TKey, TResource> cache,
            Func <TResource, TKey> keySelector)
        {
            // long cacheVersion = 0;
            var resetSubject = new Subject <List <ResourceEvent <TResource> > >();


            List <CacheSynchronized <ResourceEvent <TResource> > > UpdateBlock(List <ResourceEvent <TResource> > events)
            {
                // cacheVersion += events.Count;
                var reset = events
                            .Select(x => x.Value)
                            .Where(x => x != null)
                            .ToDictionary(keySelector, x => x);

                cache.Reset(reset);
                var acc = cache.Version + 1;

                cache.Version += events.Count;
                return(events
                       .Select(x => new CacheSynchronized <ResourceEvent <TResource> >(acc++, cache.Version, x))
                       .ToList());
            }

            CacheSynchronized <ResourceEvent <TResource> > UpdateSingle(ResourceEvent <TResource> notification)
            {
                cache.Version++;
                if (!notification.EventFlags.HasFlag(EventTypeFlags.Delete))
                {
                    if (notification.EventFlags.HasFlag(EventTypeFlags.Modify) && cache.TryGetValue(keySelector(notification.Value), out var oldValue))
                    {
                        notification = new ResourceEvent <TResource>(notification.EventFlags, notification.Value, oldValue);
                    }

                    if (notification.Value != null)
                    {
                        cache[keySelector(notification.Value)] = notification.Value;
                    }
                }
                else
                {
                    cache.Remove(keySelector(notification.OldValue));
                }

                return(new CacheSynchronized <ResourceEvent <TResource> >(cache.Version, cache.Version, notification));
            }

            return(Observable.Create <CacheSynchronized <ResourceEvent <TResource> > >(obs =>
            {
                var a = resetSubject
                        .SelectMany(UpdateBlock)
                        .ObserveOn(Scheduler.Immediate)
                        .Subscribe(obs);
                var b = source
                        .DetectResets(resetSubject)
                        .Where(x => !x.EventFlags.HasFlag(EventTypeFlags.Reset)) // hold back resets, they'll be reinjected as batches via resetSubject after cache sync
                        .Select(UpdateSingle)
                        .ObserveOn(Scheduler.Immediate)
                        .Subscribe(obs);
                return new CompositeDisposable(a, b);
            })
                   .ObserveOn(Scheduler.Immediate));
        }
Exemple #19
0
        public DataflowMessageStatus OfferMessage(DataflowMessageHeader messageHeader, ResourceEvent <TResource> resourceEvent, ISourceBlock <ResourceEvent <TResource> > source,
                                                  bool consumeToAccept)
        {
            if (_isCompleting)
            {
                return(DataflowMessageStatus.DecliningPermanently);
            }
            if (consumeToAccept)
            {
                resourceEvent = source.ConsumeMessage(messageHeader, this, out var consumed);
                if (!consumed)
                {
                    return(DataflowMessageStatus.NotAvailable);
                }
            }

            if (resourceEvent.EventFlags.HasFlag(EventTypeFlags.ResetEmpty) ||
                resourceEvent.Value == null)
            {
                return(DataflowMessageStatus.Declined);
            }


            lock (_lock)
            {
                // decline any syncs if we're already queued up to process this resource
                if (resourceEvent.EventFlags.HasFlag(EventTypeFlags.Sync) && _items.ContainsKey(_keyFunc(resourceEvent.Value)))
                {
                    return(DataflowMessageStatus.Declined);
                }
                QueueActionLocked(resourceEvent);
            }

            return(DataflowMessageStatus.Accepted);
        }
Exemple #20
0
 private TKey KeyOf(ResourceEvent <TResource> obj) => KeyOf(obj.Value);
Exemple #21
0
 internal static void RaiseEvent(ProtocolDiagnosticResourceEvent pdrEvent)
 {
     ResourceEvent?.Invoke(pdrEvent);
 }
Exemple #22
0
        private void MonitorProcess(object state)
        {
            try
            {
                string executionString = ExecutionString;
                Log.Logger.Information("Launching {0}", executionString);
                while (!_disposed)
                {
                    Process p = new Process();
                    p.StartInfo = new ProcessStartInfo(executionString);
                    p.Start();
                    Thread.Sleep(5000);  //Wait at least 5 seconds before doing anything else to prevent spiraling out of control

                    //Look for process
                    foreach (Process proc in Process.GetProcesses())
                    {
                        if (proc.ProcessName.StartsWith(ProcessName))
                        {
                            Log.Logger.Information("Found Monitor Process: {0}", proc.ProcessName);
                            lock (_monitoringProcessLock)
                            {
                                _monitoringProcess = proc;
                            }

                            ClearSnapshotHistory();
                            DateTime unresponsiveTime = DateTime.Now;
                            bool     exited           = proc.WaitForExit((int)(ResourceSnapshotInterval.TotalMilliseconds));
                            while (!exited)
                            {
                                //The process is still running.  This is good, just take a snapshot of it
                                lock (_monitoringProcessLock)
                                {
                                    ResourceSnapshot snapshot = LogResourceSnapshot(_monitoringProcess);
                                    try
                                    {
                                        ResourceEvent?.Invoke(this, snapshot);
                                    }
                                    catch (Exception e)
                                    {
                                        Log.Logger.Information("No Event Handler for the snap {e}", e);
                                    }

                                    if (snapshot.IsNotResponding)
                                    {
                                        if (DateTime.Now >= unresponsiveTime + UnresponsiveTimeout)
                                        {
                                            Log.Logger.Warning("Application is not responding.  Will kill.");
                                            Kill();
                                        }
                                    }
                                    else
                                    {
                                        unresponsiveTime = DateTime.Now;
                                    }
                                }
                                exited = proc.WaitForExit((int)(ResourceSnapshotInterval.TotalMilliseconds));
                            }

                            //Once the process exits, then dump some stats and restart it
                            lock (_monitoringProcessLock)
                            {
                                RaiseProcessExited();
                                _monitoringProcess = null;
                            }
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                RaiseProcessEvent(string.Format("Error with program: {0}", ex.Message));
            }
        }
Exemple #23
0
        internal void syncAction(ResourceEvent evt)
        {
            if (_synced)
            {
                evt();
                return;
            }

            lock (_events)
            {
                _events.Enqueue(evt);
            }

            _eventTrigger.Set();
        }
        public void CreateComplexXMPTypes()
        {
            //ExStart:CreateColorant
            // create RGB colorant with R, G, B components
            ColorantRGB rgbColorant = new ColorantRGB(254, 254, 1);

            // create CMYK colorant with Black, Cyan, Magenta, Yellow components
            ColorantCMYK cmykColorant = new ColorantCMYK(10, 10, 1, 50);
            //ExEnd:CreateColorant


            //ExStart:CreateDimensions
            int width  = 100;
            int height = 50;

            // create dimensions
            Dimensions dimensions = new Dimensions(width, height);

            dimensions.Units = "inch";

            // create dimensions using object initializer
            Dimensions dimensions2 = new Dimensions();

            dimensions2.Width  = width;
            dimensions2.Height = height;
            dimensions2.Units  = "inch";
            //ExEnd:CreateDimensions


            //ExStart:CreateFont
            string fontFamily = "Arial";

            // create Arial font
            GroupDocs.Metadata.Xmp.Types.Complex.Font.Font font = new GroupDocs.Metadata.Xmp.Types.Complex.Font.Font(fontFamily);
            //ExEnd:CreateFont


            //ExStart:CreateResourceEvent
            // create ResourceEvent type
            ResourceEvent resourceEvent = new ResourceEvent();

            // set the action that occurred
            resourceEvent.Action = "edited";

            // Additional description of the action
            resourceEvent.Parameters = "secon version";
            //ExEnd:CreateResourceEvent


            //ExStart:CreateResourceRef
            ResourceRef expectedValue = new ResourceRef
            {
                DocumentUri = "074255bf-78bc-4002-89dc-cd7538b40fe0",
                InstanceId  = "42a841b7-48d4-4988-8988-53d2c6e7525d"
            };

            // create XmpMediaManagementPackage
            XmpMediaManagementPackage package = new XmpMediaManagementPackage();

            // update DerivedFrom property
            package.SetDerivedFrom(expectedValue);

            // check value
            ResourceRef value = (ResourceRef)package["xmpMM:DerivedFrom"];
            //ExEnd:CreateResourceRef


            //ExStart:CreateThumbnail
            // path to the image
            string imagePath = @"C:\\image.jpg";
            string base64String;

            // use System.Drawing to get image base64 string
            using (Image image = Image.FromFile(imagePath))
            {
                using (MemoryStream m = new MemoryStream())
                {
                    image.Save(m, image.RawFormat);
                    byte[] imageBytes = m.ToArray();

                    // Convert byte[] to Base64 String
                    base64String = Convert.ToBase64String(imageBytes);
                }
            }

            // xmp thumbnail width
            int thumbnailWidth = 100;

            // xmp thumbnail height
            int thumbnailHeight = 50;

            // create xmp thumbnail
            Thumbnail thumbnail = new Thumbnail(thumbnailWidth, thumbnailHeight);

            // add provide image base64 string
            thumbnail.ImageBase64 = base64String;
            //ExEnd:CreateThumbnail


            //ExStart:CreateVersion
            // create new instance of Version
            GroupDocs.Metadata.Xmp.Types.Complex.Version.Version version = new GroupDocs.Metadata.Xmp.Types.Complex.Version.Version();

            // set version number
            version.VersionText = "1.0";

            // set version date
            version.ModifiedDate = DateTime.UtcNow;

            // set person who modified this version
            version.Modifier = "Joe Doe";

            // set version additional comments
            version.Comments = "First version, created by: Joe Doe";
            //ExEnd:CreateVersion
        }
 public static ScheduledEvent <T> ScheduleFiring <T>(this ResourceEvent <T> obj, long fireAt)
 {
     return(new ScheduledEvent <T> {
         Event = obj, ScheduledAt = fireAt
     });
 }
        public void CreateComplexXMPTypes()
        {
            //ExStart:CreateColorant
            // create RGB colorant with R, G, B components
            ColorantRGB rgbColorant = new ColorantRGB(254, 254, 1);

            // create CMYK colorant with Black, Cyan, Magenta, Yellow components
            ColorantCMYK cmykColorant = new ColorantCMYK(10, 10, 1, 50);
            //ExEnd:CreateColorant


            //ExStart:CreateDimensions
            int width = 100;
            int height = 50;

            // create dimensions
            Dimensions dimensions = new Dimensions(width, height);
            dimensions.Units = "inch";

            // create dimensions using object initializer
            Dimensions dimensions2 = new Dimensions();
            dimensions2.Width = width;
            dimensions2.Height = height;
            dimensions2.Units = "inch";
            //ExEnd:CreateDimensions


            //ExStart:CreateFont
            string fontFamily = "Arial";

            // create Arial font
            GroupDocs.Metadata.Xmp.Types.Complex.Font.Font font = new GroupDocs.Metadata.Xmp.Types.Complex.Font.Font(fontFamily);
            //ExEnd:CreateFont


            //ExStart:CreateResourceEvent
            // create ResourceEvent type
            ResourceEvent resourceEvent = new ResourceEvent();

            // set the action that occurred
            resourceEvent.Action = "edited";

            // Additional description of the action
            resourceEvent.Parameters = "secon version";
            //ExEnd:CreateResourceEvent


            //ExStart:CreateResourceRef
            ResourceRef expectedValue = new ResourceRef
            {
                DocumentUri = "074255bf-78bc-4002-89dc-cd7538b40fe0",
                InstanceId = "42a841b7-48d4-4988-8988-53d2c6e7525d"
            };

            // create XmpMediaManagementPackage
            XmpMediaManagementPackage package = new XmpMediaManagementPackage();

            // update DerivedFrom property
            package.SetDerivedFrom(expectedValue);

            // check value
            ResourceRef value = (ResourceRef)package["xmpMM:DerivedFrom"];
            //ExEnd:CreateResourceRef


            //ExStart:CreateThumbnail
            // path to the image
            string imagePath = @"C:\\image.jpg";
            string base64String;

            // use System.Drawing to get image base64 string
            using ( Image image = Image.FromFile(imagePath))
            {
                using (MemoryStream m = new MemoryStream())
                {
                    image.Save(m, image.RawFormat);
                    byte[] imageBytes = m.ToArray();

                    // Convert byte[] to Base64 String
                    base64String = Convert.ToBase64String(imageBytes);
                }
            }

            // xmp thumbnail width
            int thumbnailWidth = 100;

            // xmp thumbnail height
            int thumbnailHeight = 50;

            // create xmp thumbnail 
            Thumbnail thumbnail = new Thumbnail(thumbnailWidth, thumbnailHeight);

            // add provide image base64 string
            thumbnail.ImageBase64 = base64String;
            //ExEnd:CreateThumbnail


            //ExStart:CreateVersion
            // create new instance of Version
            GroupDocs.Metadata.Xmp.Types.Complex.Version.Version version = new GroupDocs.Metadata.Xmp.Types.Complex.Version.Version();

            // set version number
            version.VersionText = "1.0";

            // set version date
            version.ModifiedDate = DateTime.UtcNow;

            // set person who modified this version
            version.Modifier = "Joe Doe";

            // set version additional comments
            version.Comments = "First version, created by: Joe Doe";
            //ExEnd:CreateVersion
        }