Example #1
0
        /// <summary>
        /// Deletes the resource in inRiver, associated with the asset id of bynder
        /// </summary>
        /// <param name="bynderAssetId"></param>
        /// <returns></returns>
        public WorkerResult Execute(string bynderAssetId)
        {
            var result = new WorkerResult();

            // only process if we are allowed to delete entities
            if (!GetDeleteResourceOnDeletedEvents())
            {
                return(result);
            }

            // find resourceEntity based on bynderAssetId
            Entity resourceEntity =
                _inRiverContext.ExtensionManager.DataService.GetEntityByUniqueValue(FieldTypeIds.ResourceBynderId, bynderAssetId,
                                                                                    LoadLevel.DataAndLinks);

            // delete if exist
            if (resourceEntity != null)
            {
                _inRiverContext.Log(LogLevel.Verbose, $"Deleting Resource {resourceEntity.Id}, which is associated with the deleted bynder asset {bynderAssetId}");

                _inRiverContext.ExtensionManager.DataService.DeleteEntity(resourceEntity.Id);
                result.Messages.Add($"Deleted Resource {resourceEntity.Id}, which was associated with the deleted bynder asset {bynderAssetId}");
            }
            else
            {
                _inRiverContext.Log(LogLevel.Debug, $"Nothing to remove. Deleted asset {bynderAssetId} does not exist in inRiver as Resource.");
                result.Messages.Add($"Nothing to remove. Deleted asset {bynderAssetId} does not exist in inRiver as Resource.");
            }

            return(result);
        }
Example #2
0
        public static string SaveAndZipDocument(string channelIdentifier, XDocument doc, string folderDateTime, Configuration config, inRiverContext context)
        {
            string dirPath = Path.Combine(config.PublicationsRootPath, folderDateTime);

            if (!Directory.Exists(dirPath))
            {
                Directory.CreateDirectory(dirPath);
            }

            try
            {
                XDocument verified = VerifyAndCorrectDocument(doc, context);
                doc = verified;
            }
            catch (Exception exception)
            {
                context.Log(LogLevel.Error, "Fail to verify the document: ", exception);
            }

            string filePath = Path.Combine(dirPath, Configuration.ExportFileName);

            context.Log(
                LogLevel.Information,
                string.Format("Saving verified document to path {0} for channel:{1}", filePath, channelIdentifier));
            doc.Save(filePath);
            string fullZippedFileName = string.Format(
                "inRiverExport_{0}_{1}.zip",
                channelIdentifier,
                DateTime.Now.ToString("yyyyMMdd-HHmmss"));

            ZipFile(filePath, fullZippedFileName);

            return(fullZippedFileName);
        }
Example #3
0
        public IEnumerable <string> UploadResourcesAndDocumentToAzure(List <StructureEntity> channelEntities, XDocument resourceDocument, Configuration config, string folderDateTime, inRiverContext context)
        {
            try
            {
                List <int> resourceIds = new List <int>();
                foreach (StructureEntity structureEntity in channelEntities)
                {
                    if (structureEntity.Type == "Resource" && !resourceIds.Contains(structureEntity.EntityId))
                    {
                        resourceIds.Add(structureEntity.EntityId);
                    }
                }

                context.Log(LogLevel.Debug, $"channel entities count {channelEntities.Count} in UploadResources to azure");

                List <Entity> resources =
                    context.ExtensionManager.DataService.GetEntities(resourceIds, LoadLevel.DataAndLinks);

                context.Log(LogLevel.Debug, $"resources count {resources.Count} after fetching them before passing them to UploadResourceFiles to azure");

                return(UploadResourceFilesToAzureFileStorage(resources, resourceDocument, config, folderDateTime, context));
            }
            catch (Exception ex)
            {
                context.Log(LogLevel.Error, "Could not add resources", ex);
                return(null);
            }
        }
Example #4
0
        public void Execute(Entity resourceEntity)
        {
            if (!resourceEntity.EntityType.Id.Equals(EntityTypeIds.Resource))
            {
                return;
            }
            if (resourceEntity.LoadLevel < LoadLevel.DataOnly)
            {
                resourceEntity = _inRiverContext.ExtensionManager.DataService.GetEntity(resourceEntity.Id, LoadLevel.DataOnly);
            }

            string bynderDownloadState =
                (string)resourceEntity.GetField(FieldTypeIds.ResourceBynderDownloadState)?.Data;

            if (string.IsNullOrWhiteSpace(bynderDownloadState) || bynderDownloadState != BynderStates.Todo)
            {
                return;
            }

            string bynderId = (string)resourceEntity.GetField(FieldTypeIds.ResourceBynderId)?.Data;

            if (string.IsNullOrWhiteSpace(bynderId))
            {
                return;
            }

            // download asset information
            Asset asset = _bynderClient.GetAssetByAssetId(bynderId);

            if (asset == null)
            {
                _inRiverContext.Log(LogLevel.Error, "Asset information is empty");
                return;
            }

            // check for existing file
            var resourceFileId = resourceEntity.GetField(FieldTypeIds.ResourceFileId)?.Data;
            int existingFileId = resourceFileId != null ? (int)resourceFileId : 0;

            // add new asset
            string resourceFileName = (string)resourceEntity.GetField(FieldTypeIds.ResourceFilename)?.Data;
            int    newFileId        = _inRiverContext.ExtensionManager.UtilityService.AddFileFromUrl(resourceFileName, _bynderClient.GetAssetDownloadLocation(asset.Id).S3_File);

            // delete older asset file
            if (existingFileId > 0)
            {
                _inRiverContext.Log(LogLevel.Verbose, $"existing fileId found {existingFileId}");
                _inRiverContext.ExtensionManager.UtilityService.DeleteFile(existingFileId);
            }

            // set fieltypes for resource entity
            resourceEntity.GetField(FieldTypeIds.ResourceFileId).Data              = newFileId;
            resourceEntity.GetField(FieldTypeIds.ResourceMimeType).Data            = asset.GetOriginalMimeType();
            resourceEntity.GetField(FieldTypeIds.ResourceBynderDownloadState).Data = BynderStates.Done;

            _inRiverContext.ExtensionManager.DataService.UpdateEntity(resourceEntity);
            _inRiverContext.Logger.Log(LogLevel.Information, $"Updated resource entity {resourceEntity.Id}");
        }
Example #5
0
        public XDocument GenerateXml(Entity entity, SchemabasedEntityActionEnum entityAction, Dictionary <string, string> uniqueFieldTypes, int channelId = 0, Link linkToBeDeleted = null)
        {
            XDocument doc = null;

            if (entity == null)
            {
                context.Log(LogLevel.Error, "Entity argument is null in Generate Xml in SchemabasedOutput. Aborting.");
                return(doc);
            }

            try
            {
                this.currentChannelId = channelId;
                this.deletedLink      = linkToBeDeleted;
                ReGenerateSchema(entity.EntityType.Id, false);
                doc = this.GetDocumentBase(entity.EntityType.Id);
                XElement root = doc.Element(targetNamespace + entity.EntityType.Id + "s");
                if (root != null)
                {
                    string uniqueFieldType = string.Empty;
                    if (uniqueFieldTypes.ContainsKey(entity.EntityType.Id))
                    {
                        uniqueFieldType = uniqueFieldTypes[entity.EntityType.Id];
                    }

                    root.Add(this.CreateEntity(entity, entityAction, uniqueFieldType, uniqueFieldTypes));
                }
            }
            catch (Exception exception)
            {
                context.Log(LogLevel.Error, $"Error during generating xml for entity id {entity.Id}:", exception);
                doc = null;
            }
            return(doc);
        }
Example #6
0
        internal string ZipAndUploadToCloud(Configuration config, inRiverContext context, Dictionary <string, byte[]> files, CloudFileDirectory cloudDirectory, CloudFile cloudFile)
        {
            using (MemoryStream stream = new MemoryStream())
            {
                using (ZipArchive archive = new ZipArchive(stream, ZipArchiveMode.Create, true))
                {
                    foreach (KeyValuePair <string, byte[]> imageFile in files)
                    {
                        ZipArchiveEntry entry = archive.CreateEntry(imageFile.Key);
                        using (Stream entryStream = entry.Open())
                        {
                            entryStream.Write(imageFile.Value, 0, imageFile.Value.Length);
                        }
                    }
                }

                stream.Position = 0;
                cloudFile.UploadFromStream(stream);

                Uri path = cloudFile.Uri;
                config.ResourceNameInCloud = cloudFile.Name;
                context.Log(LogLevel.Debug, $"done uploading resource files to the file storage in {cloudDirectory} and this is it's uri {path}");

                return(path.ToString());
            }
        }
Example #7
0
        public static void ZipDirectoryAndSubdirectory(string zippedFileName, Configuration configuration, inRiverContext context)
        {
            context.Log(LogLevel.Debug, "Zipping resource directory");
            Stopwatch dirZipStopWatch = new Stopwatch();

            try
            {
                dirZipStopWatch.Start();
                string        directoryToZip     = Path.Combine(configuration.ResourcesRootPath, "temp");
                DirectoryInfo directoryInfo      = new DirectoryInfo(directoryToZip);
                string        fullZippedFileName = Path.Combine(configuration.ResourcesRootPath, zippedFileName);
                using (Package zip = Package.Open(fullZippedFileName, FileMode.Create))
                {
                    foreach (DirectoryInfo di in directoryInfo.GetDirectories())
                    {
                        foreach (FileInfo fi in di.GetFiles())
                        {
                            string destFilename = string.Format(".\\{0}\\{1}", di.Name, fi.Name);
                            ZipFile(zip, fi, destFilename);
                        }
                    }

                    foreach (FileInfo fi in directoryInfo.GetFiles())
                    {
                        if (fi.Name.Equals(zippedFileName))
                        {
                            continue;
                        }

                        string destFilename = string.Format(".\\{0}", fi.Name);
                        ZipFile(zip, fi, destFilename);
                    }
                }

                dirZipStopWatch.Stop();
            }
            catch (Exception ex)
            {
                context.Log(LogLevel.Error, "Exception in ZipDirectoryAndSubdirectoryAndRemoveFiles", ex);
            }
            BusinessHelper businessHelper = new BusinessHelper(context);

            context.Log(
                LogLevel.Information,
                string.Format("Resource directory zipped, took {0}!", businessHelper.GetElapsedTimeFormated(dirZipStopWatch)));
        }
Example #8
0
        internal XDocument GetChannelStructure(int channelId)
        {
            try
            {
                string channelStructure = _context.ExtensionManager.ChannelService.GetChannelStructure(channelId);
                if (!string.IsNullOrEmpty(channelStructure))
                {
                    return(XDocument.Parse(channelStructure));
                }
            }
            catch (Exception ex)
            {
                _context.Log(LogLevel.Error, "Error in GetChannelStructure", ex);
            }

            return(new XDocument());
        }
Example #9
0
        /// <summary>
        /// Creates the resource document by looping through the channel entities
        /// </summary>
        /// <param name="channelEntities">A <see cref="List{StructureEntity}"/> object</param>
        /// <param name="config">The Episerver <see cref="Configuration" /> object</param>
        /// <returns>Episerver Xml document as a <see cref="XDocument"/></returns>
        public XDocument GetResourcesDocument(List <StructureEntity> channelEntities, Configuration config)
        {
            XDocument resourceDocument = new XDocument();

            try
            {
                List <int> resourceIds = new List <int>();

                foreach (StructureEntity structureEntity in channelEntities)
                {
                    if (structureEntity.Type == "Resource" && !resourceIds.Contains(structureEntity.EntityId))
                    {
                        resourceIds.Add(structureEntity.EntityId);
                    }
                }

                List <Entity> resources = _context.ExtensionManager.DataService.GetEntities(resourceIds, LoadLevel.DataAndLinks);

                EntityType reourceType         = resources.Count > 0 ? resources[0].EntityType : _context.ExtensionManager.ModelService.GetEntityType("Resource");
                XElement   resourceMetaClasses = _epiElement.CreateResourceMetaFieldsElement(reourceType, config);
                resourceDocument = CreateResourceDocument(resourceMetaClasses, resources, resources, "added", config);
            }
            catch (Exception ex)
            {
                _context.Log(LogLevel.Error, string.Format("Could not add resources"), ex);
            }

            return(resourceDocument);
        }
Example #10
0
        public CultureInfo GetChannelDefaultLanguage(Configuration configuration, Entity channel)
        {
            Field defaultLanguageField = channel.Fields.FirstOrDefault(f => f.FieldType.Id.ToLower().Contains("channeldefaultlanguage"));

            if (defaultLanguageField == null || defaultLanguageField.IsEmpty())
            {
                if (configuration.LanguageMapping?.Any() ?? false)
                {
                    _context.Log(LogLevel.Debug, $"Using '{configuration.LanguageMapping.Values.First()}' as default language.");
                    return(configuration.LanguageMapping.Values.First());
                }

                _context.Log(LogLevel.Debug, $"Using 'en-US' as default language.");
                return(new CultureInfo("en-us"));
            }

            _context.Log(LogLevel.Debug, $"Using '{defaultLanguageField.Data}' as default language.");

            return(new CultureInfo(defaultLanguageField.Data.ToString()));
        }
Example #11
0
        private CVLDataMode StringToCVLDataMode(string str)
        {
            CVLDataMode mode;

            if (!Enum.TryParse(str, out mode))
            {
                _context.Log(LogLevel.Error, string.Format("Could not parse CVLDataMode for string {0}", str));
            }

            return(mode);
        }
Example #12
0
        internal ConnectorEvent InitiateConnectorEvent(ConnectorEventType messageType, string message, int percentage, bool error = false)
        {
            string channelId;

            _context.Settings.TryGetValue("CHANNEL_ID", out channelId);
            ConnectorEvent connectorEvent = new ConnectorEvent
            {
                ChannelId          = int.Parse(channelId ?? "0"),
                ConnectorEventType = messageType,
                ConnectorId        = _context.ExtensionId,
                EventTime          = DateTime.Now,
                SessionId          = Guid.NewGuid(),
                Percentage         = percentage,
                IsError            = error,
                Message            = message
            };

            _context.Log(LogLevel.Information, connectorEvent.Message);
            return(connectorEvent);
        }
Example #13
0
        public Configuration(inRiverContext context)
        {
            _context           = context;
            settings           = context.Settings;
            LinkTypes          = new List <LinkType>(context.ExtensionManager.ModelService.GetAllLinkTypes());
            epiFieldsIninRiver = new List <string> {
                "startdate", "enddate", "displaytemplate", "seodescription", "seokeywords", "seotitle", "seouri", "skus"
            };
            ChannelStructureEntities = new List <StructureEntity>();
            ChannelEntities          = new Dictionary <int, Entity>();

            context.Log(LogLevel.Debug, $"A new instance of {GetType().FullName} was created.");
        }
Example #14
0
        public string FieldIsUseInCompare(FieldType fieldType)
        {
            string value = "False";

            if (fieldType.Settings.ContainsKey("UseInComparing"))
            {
                value = fieldType.Settings["UseInComparing"];
                if (!(value.ToLower().Equals("false") || value.ToLower().Equals("true")))
                {
                    _context.Log(LogLevel.Error, string.Format("Fieldtype with id {0} has invalid UseInComparing setting", fieldType.Id));
                }
            }

            return(value);
        }
Example #15
0
        public static void SaveDocument(string channelIdentifier, XDocument doc, Configuration config, string folderDateTime, inRiverContext context)
        {
            string dirPath = Path.Combine(config.ResourcesRootPath, folderDateTime);

            if (!Directory.Exists(dirPath))
            {
                Directory.CreateDirectory(dirPath);
            }

            string filePath = Path.Combine(dirPath, "Resources.xml");

            context.Log(
                LogLevel.Information,
                string.Format("Saving document to path {0} for channel:{1}", filePath, channelIdentifier));
            doc.Save(filePath);
        }
Example #16
0
        private static XDocument VerifyAndCorrectDocument(XDocument doc, inRiverContext context)
        {
            List <string> unwantedEntityTypes = CreateUnwantedEntityTypeList(context);
            XDocument     result = new XDocument(doc);
            XElement      root   = result.Root;

            if (root == null)
            {
                throw new Exception("Can't verify the Catalog.cml as it's empty.");
            }

            IEnumerable <XElement> entryElements    = root.Descendants("Entry");
            List <string>          codesToBeRemoved = new List <string>();

            foreach (XElement entryElement in entryElements)
            {
                string code          = entryElement.Elements("Code").First().Value;
                string metaClassName =
                    entryElement.Elements("MetaData").Elements("MetaClass").Elements("Name").First().Value;

                if (unwantedEntityTypes.Contains(metaClassName))
                {
                    context.Log(
                        LogLevel.Debug,
                        string.Format("Code {0} will be removed as it has wrong metaclass name ({1})", code, metaClassName));
                    codesToBeRemoved.Add(code);
                }
            }

            foreach (string code in codesToBeRemoved)
            {
                string theCode = code;
                root.Descendants("Entry").Where(
                    e =>
                {
                    XElement codeElement = e.Element("Code");
                    return(codeElement != null && codeElement.Value == theCode);
                }).Remove();
            }

            return(result);
        }
Example #17
0
        internal XDocument CreateResourceDocument(XElement resourceMetaClasses, List <Entity> channelResources, List <Entity> resources, string action, Configuration config)
        {
            Dictionary <int, Entity> parentEntities = config.ChannelEntities;
            int imageCount = resources.Count(resource =>
            {
                string mainCategoryKey = resource.GetField("ResourceMainCategory")?.Data as string;

                return(mainCategoryKey == "Image");
            });

            _context?.Log(LogLevel.Debug, string.Format("Episerver imageCount {0}", imageCount.ToString()));

            return
                (new XDocument(
                     new XElement(
                         "Resources",
                         resourceMetaClasses,
                         new XElement(
                             "ResourceFiles",
                             resources.Select(res => _epiElement.CreateResourceElement(res, action, config, parentEntities, imageCount))))));
        }
        public void ImportEntities(IEnumerable <MappedEntity> mappedEntities)
        {
            int count = 0;

            foreach (MappedEntity mappedEntity in mappedEntities)
            {
                bool   newEntity = false;
                Entity entity    = _entityRepository
                                   .GetEntityByUniqueValue(
                    mappedEntity.UniqueFieldType,
                    mappedEntity.UniqueFieldValue,
                    LoadLevel.DataOnly);
                if (entity == null)
                {
                    EntityType entityType = _modelsRepository
                                            .GetEntityType(mappedEntity.EntityType);
                    entity    = Entity.CreateEntity(entityType);
                    newEntity = true;
                }

                bool entityModified = false;
                foreach (MappedField mappedField in mappedEntity.Fields)
                {
                    // This extension method is much more efficient than the built-in GetField() method.
                    Field field = entity.GetFieldOrdinal(mappedField.Name);
                    if (field == null)
                    {
                        throw new InvalidOperationException(
                                  $"The field '{mappedField.Name}' does not exist in the model.");
                    }

                    object fieldValue = mappedField.Value;

                    field.Data = fieldValue;

                    entityModified = true;
                }

                if (entity.FieldSetId != mappedEntity.FieldSet)
                {
                    entity.FieldSetId = mappedEntity.FieldSet;
                    entityModified    = true;
                }

                if (entity.Id == 0)
                {
                    entity = _entityRepository.AddEntity(entity);
                }
                else if (entityModified)
                {
                    entity = _entityRepository.UpdateEntity(entity);
                }

                foreach (MappedLink mappedLink in mappedEntity.Links)
                {
                    ImportLink(mappedLink, entity, newEntity);
                }

                count++;
            }

            _context.Log(LogLevel.Information, $"Finished importing {count} entities.");
        }
Example #19
0
        internal void Add(Entity channelEntity, ConnectorEvent connectorEvent, out bool resourceIncluded)
        {
            resourceIncluded = false;

            var channelHelper        = new ChannelHelper(_context);
            var epiApi               = new EpiApi(_context);
            var connectorEventHelper = new ConnectorEventHelper(_context);


            connectorEventHelper.UpdateConnectorEvent(connectorEvent, "Generating catalog.xml...", 11);
            Dictionary <string, List <XElement> > epiElements = _epiDocument.GetEPiElements(ConnectorConfig);

            XDocument doc = _epiDocument.CreateImportDocument(
                channelEntity,
                null,
                null,
                epiElements,
                ConnectorConfig);

            string folderDateTime = DateTime.Now.ToString("yyyyMMdd-HHmmss.fff");

            if (!DocumentFileHelper.ZipDocumentAndUploadToAzure(XmlDocumentType.Catalog, doc, ConnectorConfig, folderDateTime))
            {
                _context.Log(LogLevel.Information, "Failed to zip and upload the catalog file to azure from add utility Add() method");
            }

            _context.Log(LogLevel.Information, "Catalog saved with the following:");
            _context.Log(LogLevel.Information, string.Format("Nodes: {0}", epiElements["Nodes"].Count));
            _context.Log(LogLevel.Information, string.Format("Entries: {0}", epiElements["Entries"].Count));
            _context.Log(LogLevel.Information, string.Format("Relations: {0}", epiElements["Relations"].Count));
            _context.Log(LogLevel.Information, string.Format("Associations: {0}", epiElements["Associations"].Count));
            connectorEventHelper.UpdateConnectorEvent(connectorEvent, "Done generating catalog.xml", 25);

            connectorEventHelper.UpdateConnectorEvent(connectorEvent, "Generating Resource.xml and saving files to disk...", 26);

            Resources resourceHelper = new Resources(_context);

            XDocument resourceDocument = resourceHelper.GetResourcesDocument(ConnectorConfig.ChannelStructureEntities, ConnectorConfig);

            // Add all files included in resource document
            Dictionary <string, byte[]> files = new Dictionary <string, byte[]>();

            IEnumerable <XElement> resourceFileElements = resourceDocument.Document.Element("Resources")?.Element("ResourceFiles")?.Elements("Resource");

            if (resourceFileElements != null && resourceFileElements.Any())
            {
                _context.Log(LogLevel.Information, $"Adding {resourceFileElements.Count()} resource files to zip archive.");
                foreach (XElement resourceFileElement in resourceFileElements)
                {
                    int resourceEntityId;
                    if (int.TryParse(resourceFileElement.Attribute("id").Value, out resourceEntityId))
                    {
                        Entity targetEntity = _context.ExtensionManager.DataService.GetEntity(resourceEntityId, LoadLevel.DataOnly);

                        _context.Log(LogLevel.Debug, $"Adding image file {targetEntity.DisplayName}({targetEntity.Id})");
                        int resourceFileId = resourceHelper.GetResourceFileId(targetEntity);

                        foreach (string displayConfig in resourceHelper.GetDisplayConfigurations(targetEntity, ConnectorConfig))
                        {
                            string fileName = resourceHelper.GetResourceFileName(targetEntity, resourceFileId, displayConfig, ConnectorConfig);

                            byte[] resourceData = _context.ExtensionManager.UtilityService.GetFile(resourceFileId, displayConfig);

                            if (resourceData != null)
                            {
                                files.Add($"{displayConfig}/{fileName}", resourceData);
                            }
                        }
                    }
                }
            }
            else
            {
                string elementCount = resourceFileElements == null ? "null" : resourceFileElements.Count().ToString();
                _context.Log(LogLevel.Information, $"No files linked to resource document. Document contains {elementCount} elements");
            }


            DocumentFileHelper.ZipDocumentAndUploadToAzure(XmlDocumentType.Resources, resourceDocument, ConnectorConfig, folderDateTime, files);

            connectorEventHelper.UpdateConnectorEvent(connectorEvent, "Done generating/saving Resource.xml", 50);

            if (ConnectorConfig.ActivePublicationMode.Equals(PublicationMode.Automatic))
            {
                _context.Log(LogLevel.Debug, "Starting automatic import!");
                connectorEventHelper.UpdateConnectorEvent(connectorEvent, "Sending Catalog.xml to EPiServer...", 51);
                if (epiApi.StartImportIntoEpiServerCommerce(ConnectorConfig.CatalogPathInCloud, channelHelper.GetChannelGuid(channelEntity, ConnectorConfig), ConnectorConfig))
                {
                    connectorEventHelper.UpdateConnectorEvent(connectorEvent, "Done sending Catalog.xml to EPiServer", 75);
                }
                else
                {
                    connectorEventHelper.UpdateConnectorEvent(connectorEvent, "Error while sending Catalog.xml to EPiServer", -1, true);

                    return;
                }

                connectorEventHelper.UpdateConnectorEvent(connectorEvent, "Sending Resources to EPiServer...", 76);
                if (epiApi.StartAssetImportIntoEpiServerCommerce(ConnectorConfig.ResourceNameInCloud, Path.Combine(ConnectorConfig.ResourcesRootPath, folderDateTime), ConnectorConfig))
                {
                    connectorEventHelper.UpdateConnectorEvent(connectorEvent, "Done sending Resources to EPiServer...", 99);
                    resourceIncluded = true;
                }
                else
                {
                    connectorEventHelper.UpdateConnectorEvent(connectorEvent, "Error while sending resources to EPiServer", -1, true);
                }
            }
        }
Example #20
0
        public void Delete(Entity channelEntity, int parentEntityId, Entity targetEntity, string linkTypeId, List <int> productParentIds = null)
        {
            var    channelHelper     = new ChannelHelper(_context);
            string channelIdentifier = channelHelper.GetChannelIdentifier(channelEntity);
            string folderDateTime    = DateTime.Now.ToString("yyyyMMdd-HHmmss.fff");

            channelHelper.BuildEntityIdAndTypeDict(DeleteUtilConfig);


            if (!DeleteUtilConfig.ChannelEntities.ContainsKey(targetEntity.Id))
            {
                DeleteUtilConfig.ChannelEntities.Add(targetEntity.Id, targetEntity);
            }

            string resourceZipFile = string.Format("resource_{0}.zip", folderDateTime);

            if (_context.ExtensionManager.ChannelService.EntityExistsInChannel(channelEntity.Id, targetEntity.Id))
            {
                var existingEntities = _context.ExtensionManager.ChannelService.GetAllStructureEntitiesForEntityInChannel(
                    channelEntity.Id,
                    targetEntity.Id);

                Entity parentEnt = _context.ExtensionManager.DataService.GetEntity(parentEntityId, LoadLevel.DataOnly);

                if (parentEnt != null)
                {
                    if (!DeleteUtilConfig.ChannelEntities.ContainsKey(parentEnt.Id))
                    {
                        DeleteUtilConfig.ChannelEntities.Add(parentEnt.Id, parentEnt);
                    }
                    if (targetEntity.EntityType.Id == "Resource")
                    {
                        DeleteResource(
                            targetEntity,
                            parentEnt,
                            channelIdentifier,
                            folderDateTime,
                            resourceZipFile);
                    }
                    else
                    {
                        DeleteEntityThatStillExistInChannel(
                            channelEntity,
                            targetEntity,
                            parentEnt,
                            linkTypeId,
                            existingEntities,
                            channelIdentifier,
                            folderDateTime,
                            resourceZipFile);
                    }
                }
                else
                {
                    _context.Log(LogLevel.Information, $"Unable to find entity {parentEntityId} (already deleted?)");
                }
            }
            else
            {
                //DeleteEntity
                DeleteEntity(
                    channelEntity,
                    parentEntityId,
                    targetEntity,
                    linkTypeId,
                    channelIdentifier,
                    folderDateTime,
                    productParentIds);
            }
        }
Example #21
0
 public void DeleteCatalog(int catalogId, Configuration config)
 {
     lock (SingletonEPiLock.Instance)
     {
         try
         {
             RestEndpoint <int> endpoint = new RestEndpoint <int>(config.Settings, "DeleteCatalog", this._context);
             endpoint.Post(catalogId);
         }
         catch (Exception exception)
         {
             _context.Log(LogLevel.Error, $"Failed to delete catalog with id: {catalogId}", exception);
         }
     }
 }
Example #22
0
        public void AddCvl(string cvlId, string folderDateTime)
        {
            List <XElement>  metafields         = new List <XElement>();
            List <FieldType> affectedFieldTypes = _businessHelper.GetFieldTypesWithCVL(cvlId, CvlUtilConfig);

            foreach (FieldType fieldType in affectedFieldTypes)
            {
                if (_epiMappingHelper.SkipField(fieldType, CvlUtilConfig))
                {
                    continue;
                }

                XElement metaField = _epiElement.InRiverFieldTypeToMetaField(fieldType, CvlUtilConfig);

                if (fieldType.DataType.Equals(DataType.CVL))
                {
                    metaField.Add(_epiMappingHelper.GetDictionaryValues(fieldType, CvlUtilConfig));
                }

                if (metafields.Any(
                        mf =>
                {
                    XElement nameElement = mf.Element("Name");
                    return(nameElement != null && nameElement.Value.Equals(_epiMappingHelper.GetEPiMetaFieldNameFromField(fieldType, CvlUtilConfig)));
                }))
                {
                    XElement existingMetaField =
                        metafields.FirstOrDefault(
                            mf =>
                    {
                        XElement nameElement = mf.Element("Name");
                        return(nameElement != null && nameElement.Value.Equals(_epiMappingHelper.GetEPiMetaFieldNameFromField(fieldType, CvlUtilConfig)));
                    });

                    if (existingMetaField == null)
                    {
                        continue;
                    }

                    var movefields = metaField.Elements("OwnerMetaClass");
                    existingMetaField.Add(movefields);
                }
                else
                {
                    metafields.Add(metaField);
                }
            }

            XElement  metaData = new XElement("MetaDataPlusBackup", new XAttribute("version", "1.0"), metafields.ToArray());
            XDocument doc      = _epiDocument.CreateDocument(null, metaData, null, CvlUtilConfig);

            Entity channelEntity = _context.ExtensionManager.DataService.GetEntity(CvlUtilConfig.ChannelId, LoadLevel.DataOnly);

            if (channelEntity == null)
            {
                _context.Log(LogLevel.Error, string.Format("Could not find channel {0} for cvl add", CvlUtilConfig.ChannelId));
                return;
            }

            string channelIdentifier = _channelHelper.GetChannelIdentifier(channelEntity);

            if (!DocumentFileHelper.ZipDocumentAndUploadToAzure(XmlDocumentType.Catalog, doc, CvlUtilConfig, folderDateTime))
            {
                _context.Log(LogLevel.Information, "Failed to zip and upload the catalog file to azure from cvl utility AddCvl() method");
            }

            _context.Log(LogLevel.Debug, string.Format("catalog {0} saved", channelIdentifier));

            if (CvlUtilConfig.ActivePublicationMode.Equals(PublicationMode.Automatic))
            {
                _context.Log(LogLevel.Debug, "Starting automatic import!");

                _epiApi.StartImportIntoEpiServerCommerce(
                    Path.Combine(CvlUtilConfig.PublicationsRootPath, folderDateTime, Configuration.ExportFileName),
                    _channelHelper.GetChannelGuid(channelEntity, CvlUtilConfig), CvlUtilConfig);
            }
        }
Example #23
0
        /// <summary>
        /// Main method of the worker
        /// </summary>
        /// <param name="bynderAssetId"></param>
        /// <param name="notificationType"></param>
        /// <returns></returns>
        public WorkerResult Execute(string bynderAssetId, NotificationType notificationType)
        {
            var result = new WorkerResult();

            // get original filename, as we need to evaluate this for further processing
            var asset = _bynderClient.GetAssetByAssetId(bynderAssetId);

            // evaluate filename
            string originalFileName = asset.GetOriginalFileName();
            var    evaluatorResult  = _fileNameEvaluator.Evaluate(originalFileName);

            if (!evaluatorResult.IsMatch())
            {
                result.Messages.Add($"Not processing '{originalFileName}'; does not match regex.");
                return(result);
            }

            // evaluate conditions
            if (!AssetAppliesToConditions(asset))
            {
                _inRiverContext.Log(LogLevel.Debug, $"Asset {bynderAssetId} does not apply to the conditions");

                result.Messages.Add($"Not processing '{originalFileName}'; does not apply to import conditions.");
                return(result);
            }

            _inRiverContext.Log(LogLevel.Debug, $"Asset {asset.Id} applies to conditions.");

            // find resourceEntity based on bynderAssetId
            Entity resourceEntity =
                _inRiverContext.ExtensionManager.DataService.GetEntityByUniqueValue(FieldTypeIds.ResourceBynderId, bynderAssetId,
                                                                                    LoadLevel.DataAndLinks);

            // handle notification logic
            switch (notificationType)
            {
            case NotificationType.DataUpsert:
                return(CreateOrUpdateEntityAndRelations(result, asset, evaluatorResult, resourceEntity));

            case NotificationType.MetadataUpdated:
                if (resourceEntity != null)
                {
                    return(UpdateMetadata(result, asset, resourceEntity));
                }
                else
                {
                    return(CreateOrUpdateEntityAndRelations(result, asset, evaluatorResult, resourceEntity));
                }

            case NotificationType.IsArchived:
                if (resourceEntity != null)
                {
                    return(SetValuesOnResource(result, bynderAssetId, resourceEntity));
                }
                else
                {
                    _inRiverContext.Log(LogLevel.Debug, $"Archived asset {bynderAssetId}, does not exist in inRiver as Resource.");
                    result.Messages.Add($"Archived asset {bynderAssetId}, does not exist in inRiver as Resource.");

                    return(result);
                }

            default:
                _inRiverContext.Log(LogLevel.Warning, $"Notification type {notificationType} is not implemented yet! This notification will not be processed for asset {bynderAssetId}.");
                result.Messages.Add($"Notification type {notificationType} is not implemented yet! This notification will not be processed for asset {bynderAssetId}.");

                return(result);
            }
        }
Example #24
0
        public bool ImportResources(string fileNameInCloud, string baseResourcePath, string id)
        {
            context.Log(LogLevel.Information,
                        string.Format("Starting Resource Import. Manifest: {0} BaseResourcePath: {1}", fileNameInCloud, baseResourcePath));

            // Get custom setting
            this.settings = context.Settings;

            // Check if ENABLE_EPI_ENDPOINT is set, and set to false
            bool enableEndPoint = true;

            if (this.settings.ContainsKey("ENABLE_EPI_ENDPOINT"))
            {
                string valueEnableEPIEndpoint = settings["ENABLE_EPI_ENDPOINT"];
                if (!string.IsNullOrEmpty(valueEnableEPIEndpoint))
                {
                    enableEndPoint = bool.Parse(valueEnableEPIEndpoint);
                }
            }
            if (!enableEndPoint)
            {
                context.Log(LogLevel.Information, "EPI Endpoint Disabled under Configuration");
                return(true);
            }

            string apikey;

            if (this.settings.ContainsKey("EPI_APIKEY"))
            {
                apikey = this.settings["EPI_APIKEY"];
            }
            else
            {
                throw new ConfigurationErrorsException("Missing EPI_APIKEY setting on connector. It needs to be defined to else the calls will fail. Please see the documentation.");
            }

            int timeout;

            if (this.settings.ContainsKey("EPI_RESTTIMEOUT"))
            {
                string timeoutString = this.settings["EPI_RESTTIMEOUT"];
                if (!int.TryParse(timeoutString, out timeout))
                {
                    throw new ConfigurationErrorsException("Can't parse EPI_RESTTIMEOUT : " + timeoutString);
                }
            }
            else
            {
                throw new ConfigurationErrorsException("Missing EPI_RESTTIMEOUT setting on connector. It needs to be defined to else the calls will fail. Please see the documentation.");
            }

            if (this.settings.ContainsKey("EPI_ENDPOINT_URL") == false)
            {
                throw new ConfigurationErrorsException("Missing EPI_ENDPOINT_URL setting on connector. It should point to the import end point on the EPiServer Commerce web site. Please see the documentation.");
            }

            string endpointAddress = this.settings["EPI_ENDPOINT_URL"];

            if (string.IsNullOrEmpty(endpointAddress))
            {
                throw new ConfigurationErrorsException("Missing EPI_ENDPOINT_URL setting on connector. It should point to the import end point on the EPiServer Commerce web site. Please see the documentation.");
            }

            if (endpointAddress.EndsWith("/") == false)
            {
                endpointAddress = endpointAddress + "/";
            }

            // Name of resource import controller method
            endpointAddress = endpointAddress + "ImportResources";

            return(this.ImportResourcesToEPiServerCommerce(fileNameInCloud, baseResourcePath, endpointAddress, apikey, timeout));
        }
Example #25
0
        internal IEnumerable <string> UploadResourceFilesToAzureFileStorage(List <Entity> resources, XDocument importXml, Configuration config, string folderDateTime, inRiverContext context)
        {
            Stopwatch saveFileStopWatch = new Stopwatch();

            List <string> cloudFileNames = new List <string>();

            try
            {
                // validate configuration settings
                if (string.IsNullOrEmpty(config.StorageAccountName) ||
                    string.IsNullOrEmpty(config.StorageAccountKey) ||
                    string.IsNullOrEmpty(config.StorageAccountShareReference) ||
                    string.IsNullOrEmpty(config.StorageAccountCatalogDirectoryReference) ||
                    string.IsNullOrEmpty(config.StorageAccountResourcesDirectoryReference))
                {
                    context.Log(LogLevel.Warning, $"Azure config settings are invalid: " +
                                $"StorageAccountName: {config.StorageAccountName}, " +
                                $"StorageAccountKey: {config.StorageAccountKey}, " +
                                $"StorageAccountShareReference: {config.StorageAccountShareReference}, " +
                                $"StorageAccountCatalogDirectoryReference: {config.StorageAccountCatalogDirectoryReference}, " +
                                $"StorageAccountResourcesDirectoryReference: {config.StorageAccountResourcesDirectoryReference}");

                    return(cloudFileNames);
                }

                // validate resources argument
                if (resources == null)
                {
                    context.Log(LogLevel.Error, "Resource is null!");
                    return(cloudFileNames);
                }

                // create varible files to hold filename and binary
                Dictionary <string, byte[]> files = new Dictionary <string, byte[]>();

                // setup credentials and storage account
                StorageCredentials  credentials    = new StorageCredentials(config.StorageAccountName, config.StorageAccountKey);
                CloudStorageAccount storageAccount = new CloudStorageAccount(credentials, true);

                // setup file client and remoge share
                CloudFileClient fileClient = storageAccount.CreateCloudFileClient();
                CloudFileShare  share      = fileClient.GetShareReference(config.StorageAccountShareReference);
                share.CreateIfNotExists();

                // setup root directory and resource directory
                CloudFileDirectory root      = share.GetRootDirectoryReference();
                CloudFileDirectory directory = root.GetDirectoryReference(config.GetAzureStorageDirectoryName(XmlDocumentType.Resources));
                directory.CreateIfNotExists();

                saveFileStopWatch.Start();

                // setup resource helper object
                Resources resourcesObj = new Resources(context);

                // setup the uncompressed file size total counter
                int totalFileSize = 0;

                // setup the azure file counter
                int fileCount = 0;

                // setup the file id list
                List <int> fileIdList = new List <int>();

                foreach (Entity resource in resources)
                {
                    // get the file id of the resource
                    int resourceFileId = resourcesObj.GetResourceFileId(resource);

                    // ensure the resource id has a proper id
                    if (resourceFileId < 0)
                    {
                        context.Log(LogLevel.Information, $"Resource with id:{resource.Id} has no value for ResourceFileId");
                        continue;
                    }

                    // loop through each display configurations
                    foreach (string displayConfiguration in resourcesObj.GetDisplayConfigurations(resource, config))
                    {
                        // setup the fileName to use the output file extension from display configuration
                        string fileName = resourcesObj.GetResourceFileName(resource, resourceFileId, displayConfiguration, config);

                        // if the file for some reason already exists, continue to the next display configuration
                        if (files.ContainsKey(fileName))
                        {
                            context.Log(LogLevel.Debug, $"{fileName} already exists in the files collection and is skipped");

                            continue;
                        }

                        // get file bytes
                        byte[] resourceData = context.ExtensionManager.UtilityService.GetFile(resourceFileId, displayConfiguration);

                        // make sure we recieved the file from the utility service
                        if (resourceData == null)
                        {
                            context.Log(LogLevel.Error, $"Resource with id:{resource.Id} and ResourceFileId: {resourceFileId} could not get file");
                            continue;
                        }

                        // add the current resource file id to the list
                        fileIdList.Add(resource.Id);

                        // log the resource file name
                        context.Log(LogLevel.Debug, $"Adding resource {displayConfiguration}/{fileName}");

                        // add the file to the files collection
                        files.Add($"{displayConfiguration}/{fileName}", resourceData);

                        // add size to total file size counter
                        totalFileSize += resourceData.Length;
                    }

                    if (totalFileSize > (config.TotalResourceSizeLimitMb * 1024 * 1024))
                    {
                        try
                        {
                            // increase file counter
                            fileCount++;

                            // setup remote zip file
                            CloudFile cloudFile = directory.GetFileReference(GetZipFileName(config, XmlDocumentType.Resources, folderDateTime, fileCount));

                            // setup reader
                            using (XmlReader reader = importXml.CreateReader())
                            {
                                // create a new file that only contains the elements specified in the file id list
                                XmlDocument doc = XmlSplitUtility.GetPartialResourcesXml(reader, fileIdList);

                                // log the resource file name
                                context.Log(LogLevel.Debug, "Adding Resources.xml");

                                // setup memory a stream
                                using (MemoryStream stream = new MemoryStream())
                                {
                                    // create a xml writer to format output
                                    using (XmlWriter writer = XmlWriter.Create(stream, new XmlWriterSettings {
                                        Indent = true
                                    }))
                                    {
                                        // save partial document to the xml writer
                                        doc.Save(writer);

                                        // add the partial document to the files collection
                                        files.Add("Resources.xml", stream.ToArray());
                                    }
                                }

                                // send the zipped file to Azure and store the file name
                                cloudFileNames.Add(ZipAndUploadToCloud(config, context, files, directory, cloudFile));

                                // clear the id list
                                fileIdList.Clear();

                                // clear the file list
                                files.Clear();

                                // reset total file size
                                totalFileSize = 0;
                            }
                        }
                        catch (Exception ex)
                        {
                            context.Log(LogLevel.Error, "An error occured while sending the resources to the cloud.", ex);
                        }
                    }
                }

                // make sure to send the final files
                if (files.Any())
                {
                    try
                    {
                        // increase file counter
                        fileCount++;

                        // setup remote zip file
                        CloudFile cloudFile = directory.GetFileReference(GetZipFileName(config, XmlDocumentType.Resources, folderDateTime, fileCount));

                        // setup reader
                        using (XmlReader reader = importXml.CreateReader())
                        {
                            // create a new file that only contains the elements specified in the file id list
                            XmlDocument doc = XmlSplitUtility.GetPartialResourcesXml(reader, fileIdList);

                            // log the resource file name
                            context.Log(LogLevel.Debug, "Adding Resources.xml");

                            // setup memory a stream
                            using (MemoryStream stream = new MemoryStream())
                            {
                                // create a xml writer to format output
                                using (XmlWriter writer = XmlWriter.Create(stream, new XmlWriterSettings {
                                    Indent = true
                                }))
                                {
                                    // save partial document to the xml writer
                                    doc.Save(writer);

                                    // add the partial document to the files collection
                                    files.Add("Resources.xml", stream.ToArray());
                                }
                            }

                            // send the zipped file to Azure and store the file name
                            cloudFileNames.Add(ZipAndUploadToCloud(config, context, files, directory, cloudFile));
                        }
                    }
                    catch (Exception ex)
                    {
                        context.Log(LogLevel.Error, "An error occured while sending the resources to the cloud.", ex);
                    }
                }
            }
            catch (Exception ex)
            {
                context.Log(LogLevel.Error, "An error occured while sending the resources to the cloud.", ex);
            }

            return(cloudFileNames);
        }
Example #26
0
        public string Post(T message)
        {
            if (!enableEndPoint)
            {
                _context.Log(LogLevel.Information, "EPI Endpoint Disabled under Configuration");
                return(string.Empty);
            }

            Uri        uri     = new Uri(this.GetUrl());
            HttpClient client  = new HttpClient();
            string     baseUrl = uri.Scheme + "://" + uri.Authority;

            _context.Log(LogLevel.Information, $"Posting to {uri}");

            client.BaseAddress = new Uri(baseUrl);

            // Add an Accept header for JSON format.
            client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
            client.DefaultRequestHeaders.Add("apikey", this.apikey);

            // HttpResponseMessage response = client.GetAsync("").Result;  // Blocking call!
            client.Timeout = new TimeSpan(this.timeout, 0, 0);
            HttpResponseMessage response = client.PostAsJsonAsync(uri.PathAndQuery, message).Result;

            if (response.IsSuccessStatusCode)
            {
                // Parse the response body. Blocking!
                string resp = response.Content.ReadAsAsync <string>().Result;

                _context.Log(LogLevel.Debug, $"Post response - Message:{message} Result:{resp} URI:{uri.PathAndQuery}");

                int tries = 0;
                RestEndpoint <string> endpoint = new RestEndpoint <string>(this.settingsDictionary, "IsImporting", this._context);

                while (resp == "importing")
                {
                    tries++;
                    if (tries < 10)
                    {
                        Thread.Sleep(2000);
                    }
                    else if (tries < 30)
                    {
                        Thread.Sleep(30000);
                    }
                    else
                    {
                        Thread.Sleep(300000);
                    }

                    resp = endpoint.Get();

                    if (tries == 1 || (tries % 5 == 0))
                    {
                        _context.Log(LogLevel.Debug, $"Post - GET - Message:{message} Retries:{tries} Response:{resp} URI:{uri.PathAndQuery}");
                    }
                }

                if (resp.StartsWith("ERROR"))
                {
                    _context.Log(LogLevel.Error, resp);
                }

                return(resp);
            }

            string errorMsg = string.Format("Import failed: {0} ({1})", (int)response.StatusCode, response.ReasonPhrase);

            _context.Log(LogLevel.Error, errorMsg);
            throw new HttpRequestException(errorMsg);
        }
Example #27
0
        /// <summary>
        /// Fills skeleton with child elements (entity, nodes and relations)
        /// </summary>
        /// <param name="epiElements"></param>
        /// <param name="config"></param>
        private void FillElementList(Dictionary <string, List <XElement> > epiElements, Configuration config)
        {
            try
            {
                if (!epiElements["Nodes"].Any(e =>
                {
                    XElement element = e.Element("Code");
                    return(element != null && element.Value.Equals(config.ChannelIdPrefix + "_inRiverAssociations"));
                }))
                {
                    epiElements["Nodes"].Add(_epiElement.CreateAssociationNodeElement("inRiverAssociations", config));
                    _context.Log(LogLevel.Debug, string.Format("Added channelNode {0} to Nodes", "inRiverAssociations"));
                }

                List <string> addedEntities  = new List <string>();
                List <string> addedNodes     = new List <string>();
                List <string> addedRelations = new List <string>();

                int totalLoaded = 0;
                int batchSize   = config.BatchSize;

                do
                {
                    var batch = config.ChannelStructureEntities.Skip(totalLoaded).Take(batchSize).ToList();

                    config.ChannelEntities = GetEntitiesInStructure(batch);

                    FillElements(batch, config, addedEntities, addedNodes, addedRelations, epiElements);

                    totalLoaded += batch.Count;

                    _context.Log(LogLevel.Debug, string.Format("fetched {0} of {1} total", totalLoaded, config.ChannelStructureEntities.Count));
                }while (config.ChannelStructureEntities.Count > totalLoaded);
            }
            catch (Exception ex)
            {
                _context.Log(LogLevel.Error, ex.Message, ex);
            }
        }