Ejemplo n.º 1
0
        /// <summary>
        /// Extracts delimeted text block from XML document format
        /// </summary>
        /// <param name="xml">XML document containing the text block</param>
        /// <returns>Block with text-serialized CRM data</returns>
        public static string XmlSerializedToTextFile(XmlDocument xml)
        {
            XmlNode root    = CintXML.FindChild(xml, "ShuffleData");
            string  sertype = CintXML.GetAttribute(root, "Type");

            if (sertype == SerializationType.Text.ToString())
            {
                XmlNode xText = CintXML.FindChild(root, "Text");
                string  text  = xText.InnerText;
                return(text);
            }
            else
            {
                throw new ArgumentOutOfRangeException("xml", sertype, "XmlSerializedToTextFile called with xml document of incompatible serialization type");
            }
        }
Ejemplo n.º 2
0
        private List <string> GetMatchAttributes(XmlNode xMatch)
        {
            var result = new List <string>();

            if (xMatch != null)
            {
                foreach (XmlNode xMatchAttr in xMatch.ChildNodes)
                {
                    var matchattr = CintXML.GetAttribute(xMatchAttr, "Name");
                    if (string.IsNullOrEmpty(matchattr))
                    {
                        throw new ArgumentOutOfRangeException("Match Attribute name not set");
                    }
                    result.Add(matchattr);
                }
            }
            return(result);
        }
        private string GetSolutionFilename(XmlNode xBlock, string name, string type)
        {
            log.StartSection("GetSolutionFilename");
            string file = CintXML.GetAttribute(xBlock, "File");

            if (string.IsNullOrWhiteSpace(file))
            {
                file = name;
            }
            string path = CintXML.GetAttribute(xBlock, "Path");

            if (string.IsNullOrWhiteSpace(path) && !string.IsNullOrWhiteSpace(definitionpath))
            {
                path = definitionpath;
            }
            path += path.EndsWith("\\") ? "" : "\\";
            string filename;

            if (type == "Managed")
            {
                filename = path + file + "_managed.zip";
            }
            else if (type == "Unmanaged")
            {
                filename = path + file + ".zip";
            }
            else
            {
                throw new ArgumentOutOfRangeException("Type", type, "Invalid Solution type");
            }

            if (filename.Contains("%"))
            {
                IDictionary envvars = Environment.GetEnvironmentVariables();
                foreach (DictionaryEntry de in envvars)
                {
                    filename = filename.Replace("%" + de.Key.ToString() + "%", de.Value.ToString());
                }
            }
            log.Log("Filename: {0}", filename);
            log.EndSection();
            return(filename);
        }
Ejemplo n.º 4
0
 private static void AddRelationFilter(ShuffleBlocks blocks, XmlNode xRelation, XmlNode xEntity, ILoggable log)
 {
     if (blocks != null && blocks.Count > 0)
     {
         var                     block       = CintXML.GetAttribute(xRelation, "Block");
         var                     attribute   = CintXML.GetAttribute(xRelation, "Attribute");
         var                     pkattribute = CintXML.GetAttribute(xRelation, "PK-Attribute");
         var                     includenull = CintXML.GetBoolAttribute(xRelation, "IncludeNull", false);
         List <string>           ids         = new List <string>();
         CintDynEntityCollection parentcoll  = blocks.ContainsKey(block) ? blocks[block] : null;
         if (parentcoll != null && parentcoll.Count > 0)
         {
             foreach (CintDynEntity parent in parentcoll)
             {
                 if (string.IsNullOrEmpty(pkattribute))
                 {
                     ids.Add(parent.Id.ToString());
                 }
                 else
                 {
                     ids.Add(parent.Property <EntityReference>(pkattribute, new EntityReference()).Id.ToString());
                 }
             }
         }
         else
         {
             // Adding temp guid to indicate "no matches", as ConditionOperator.In will fail if no values are given
             ids.Add(new Guid().ToString());
         }
         if (!includenull)
         {
             CintFetchXML.AppendFilter(xEntity, "and", attribute, "in", ids.ToArray());
         }
         else
         {
             var xFilter = CintFetchXML.AppendFilter(xEntity, "or");
             CintFetchXML.AppendCondition(xFilter, attribute, "null");
             CintFetchXML.AppendCondition(xFilter, attribute, "in", ids.ToArray());
         }
         log.Log("Adding relation condition for {0} in {1} values in {2}.{3}", attribute, ids.Count, block, pkattribute);
     }
 }
Ejemplo n.º 5
0
        private static string GetEntityDisplayString(XmlNode xMatch, CintDynEntity cdEntity)
        {
            var unique = new List <string>();

            if (xMatch != null && xMatch.ChildNodes.Count > 0)
            {
                foreach (XmlNode xMatchAttr in xMatch.ChildNodes)
                {
                    string matchdisplay = CintXML.GetAttribute(xMatchAttr, "Display");
                    if (string.IsNullOrEmpty(matchdisplay))
                    {
                        matchdisplay = CintXML.GetAttribute(xMatchAttr, "Name");
                    }
                    var matchvalue = "<null>";
                    if (cdEntity.Contains(matchdisplay, true))
                    {
                        if (cdEntity.Entity[matchdisplay] is EntityReference)
                        {   // Don't use PropertyAsString, that would perform GetRelated that we don't want due to performance
                            var entref = cdEntity.Property <EntityReference>(matchdisplay, null);
                            if (!string.IsNullOrEmpty(entref.Name))
                            {
                                matchvalue = entref.Name;
                            }
                            else
                            {
                                matchvalue = entref.LogicalName + ":" + entref.Id.ToString();
                            }
                        }
                        else
                        {
                            matchvalue = cdEntity.PropertyAsString(matchdisplay, "", false, false, true);
                        }
                    }
                    unique.Add(matchvalue);
                }
            }
            if (unique.Count == 0)
            {
                unique.Add(cdEntity.Id.ToString());
            }
            return(string.Join(", ", unique));
        }
        /// <summary>Get the current versions for all solutions defined in the definition file</summary>
        /// <remarks>Results will be placed in the public dictionary <c ref="ExistingSolutionVersions">ExistingSolutionVersions</c></remarks>
        public void GetCurrentVersions()
        {
            log.StartSection("GetCurrentVersions");
            ExistingSolutionVersions = new Dictionary <string, Version>();
            var xRoot   = CintXML.FindChild(definition, "ShuffleDefinition");
            var xBlocks = CintXML.FindChild(xRoot, "Blocks");

            if (xBlocks != null)
            {
                var solutions = GetExistingSolutions();
                foreach (XmlNode xBlock in xBlocks.ChildNodes)
                {
                    if (xBlock.NodeType == XmlNodeType.Element)
                    {
                        switch (xBlock.Name)
                        {
                        case "DataBlock":
                            break;

                        case "SolutionBlock":
                            var xmlNode = CintXML.FindChild(xBlock, "Export");
                            if (xmlNode != null)
                            {
                                var name = CintXML.GetAttribute(xBlock, "Name");
                                log.Log("Getting version for: {0}", name);
                                foreach (var solution in solutions)
                                {
                                    if (name.Equals(solution.Property("uniquename", ""), StringComparison.OrdinalIgnoreCase))
                                    {
                                        ExistingSolutionVersions.Add(name, new Version(solution.Property("version", "1.0.0.0")));
                                        log.Log("Version found: {0}", ExistingSolutionVersions[name]);
                                    }
                                }
                            }
                            break;
                        }
                    }
                }
            }
            log.EndSection();
        }
Ejemplo n.º 7
0
        /// <summary>
        /// Import entities to CRM from dictionary of blocks
        /// </summary>
        /// <param name="blocks">Blocks with entities to import</param>
        /// <returns>Tuple with counters for: Created, Updated, Skipped and Failed records</returns>
        public Tuple <int, int, int, int, int, EntityReferenceCollection> ImportToCRM(ShuffleBlocks blocks)
        {
            log.StartSection("ImportToCRM");
            if (definition == null)
            {
                throw new ArgumentNullException("Definition", "Shuffle definition must be specified to import data");
            }

            int created = 0;
            int updated = 0;
            int skipped = 0;
            int deleted = 0;
            int failed  = 0;
            EntityReferenceCollection references = new EntityReferenceCollection();

            XmlNode xRoot   = CintXML.FindChild(definition, "ShuffleDefinition");
            XmlNode xBlocks = CintXML.FindChild(xRoot, "Blocks");

            if (xBlocks != null)
            {
                guidmap     = new Dictionary <Guid, Guid>();
                stoponerror = CintXML.GetBoolAttribute(xRoot, "StopOnError", false);
                timeout     = CintXML.GetIntAttribute(xRoot, "Timeout", -1);
                double savedtimeout = -1;
                if (timeout > -1)
                {
                    try
                    {
                        SendLine("Setting timeout: {0} minutes", timeout);
                        OrganizationServiceProxy orgsvcpxy = crmsvc.GetService <OrganizationServiceProxy>();
                        savedtimeout      = orgsvcpxy.Timeout.TotalMinutes;
                        orgsvcpxy.Timeout = new TimeSpan(0, timeout, 0);
                    }
                    catch (InvalidPluginExecutionException)
                    {   // Couldn't cast to correct service type, for some reason...
                        savedtimeout = -1;
                    }
                }

                int totalBlocks  = xBlocks.ChildNodes.Count;
                int currentBlock = 0;
                foreach (XmlNode xBlock in xBlocks.ChildNodes)
                {
                    currentBlock++;
                    SendStatus(totalBlocks, currentBlock, -1, -1);
                    if (xBlock.NodeType == XmlNodeType.Element)
                    {
                        switch (xBlock.Name)
                        {
                        case "DataBlock":
                            string name = CintXML.GetAttribute(xBlock, "Name");
                            if (!blocks.ContainsKey(name))
                            {
                                blocks.Add(name, new CintDynEntityCollection());
                            }
                            Tuple <int, int, int, int, int, EntityReferenceCollection> dataresult = ImportDataBlock(xBlock, blocks[name]);
                            created += dataresult.Item1;
                            updated += dataresult.Item2;
                            skipped += dataresult.Item3;
                            deleted += dataresult.Item4;
                            failed  += dataresult.Item5;
                            references.AddRange(dataresult.Item6);
                            break;

                        case "SolutionBlock":
                            var solutionresult = ImportSolutionBlock(xBlock);
                            switch (solutionresult)
                            {
                            case ItemImportResult.Created: created++; break;

                            case ItemImportResult.Updated: updated++; break;

                            case ItemImportResult.Skipped: skipped++; break;

                            case ItemImportResult.Failed: failed++; break;
                            }
                            break;
                        }
                    }
                }
                SendStatus(0, 0, 0, 0);
                if (savedtimeout > -1)
                {
                    OrganizationServiceProxy orgsvcpxy = crmsvc.GetService <OrganizationServiceProxy>();
                    orgsvcpxy.Timeout = new TimeSpan(0, (int)savedtimeout, 0);
                }
            }
            log.EndSection();
            return(new Tuple <int, int, int, int, int, EntityReferenceCollection>(created, updated, skipped, deleted, failed, references));
        }
Ejemplo n.º 8
0
        /// <summary>
        /// Export entities from CRM to dictionary of blocks with entities
        /// </summary>
        /// <returns>Blocks with exported entities</returns>
        public ShuffleBlocks ExportFromCRM()
        {
            log.StartSection("ExportFromCRM");
            if (definition == null)
            {
                throw new ArgumentNullException("Definition", "Shuffle definition must be specified to export data");
            }
            ShuffleBlocks blocks = new ShuffleBlocks();

            ExistingSolutionVersions = null;
            XmlNode xRoot   = CintXML.FindChild(definition, "ShuffleDefinition");
            XmlNode xBlocks = CintXML.FindChild(xRoot, "Blocks");

            if (xBlocks != null)
            {
                stoponerror = CintXML.GetBoolAttribute(xRoot, "StopOnError", false);
                timeout     = CintXML.GetIntAttribute(xRoot, "Timeout", -1);
                double savedtimeout = -1;
                if (timeout > -1)
                {
                    SendLine("Setting timeout: {0} minutes", timeout);
                    OrganizationServiceProxy orgsvcpxy = crmsvc.GetService <OrganizationServiceProxy>();
                    savedtimeout      = orgsvcpxy.Timeout.TotalMinutes;
                    orgsvcpxy.Timeout = new TimeSpan(0, timeout, 0);
                }

                int totalBlocks  = xBlocks.ChildNodes.Count;
                int currentBlock = 0;
                foreach (XmlNode xBlock in xBlocks.ChildNodes)
                {
                    currentBlock++;
                    SendStatus(totalBlocks, currentBlock, -1, -1);
                    if (xBlock.NodeType == XmlNodeType.Element)
                    {
                        switch (xBlock.Name)
                        {
                        case "DataBlock":
                            CintDynEntityCollection cExported = ExportDataBlock(blocks, xBlock);
                            string name = CintXML.GetAttribute(xBlock, "Name");
                            if (cExported != null)
                            {
                                if (blocks.ContainsKey(name))
                                {
                                    SendLine("Block already added: {0}", name);
                                }
                                else
                                {
                                    blocks.Add(name, cExported);
                                }
                            }
                            break;

                        case "SolutionBlock":
                            if (ExistingSolutionVersions == null)
                            {
                                GetCurrentVersions();
                            }
                            ExportSolutionBlock(xBlock);
                            break;
                        }
                    }
                }
                SendStatus(0, 0, 0, 0);
                if (savedtimeout > -1)
                {
                    OrganizationServiceProxy orgsvcpxy = crmsvc.GetService <OrganizationServiceProxy>();
                    orgsvcpxy.Timeout = new TimeSpan(0, (int)savedtimeout, 0);
                }
            }
            log.EndSection();
            return(blocks);
        }
Ejemplo n.º 9
0
        /// <summary>
        /// Deserialize xml/string to blocks with entities
        /// </summary>
        /// <param name="serialized"></param>
        /// <returns>Optional, only required for SerializationType: Text</returns>
        public ShuffleBlocks Deserialize(XmlDocument serialized)
        {
            log.StartSection("Deserialize");
            ShuffleBlocks result = new ShuffleBlocks();

            if (serialized != null)
            {
                XmlNode root    = CintXML.FindChild(serialized, "ShuffleData");
                string  sertype = CintXML.GetAttribute(root, "Type");
                SendLine("Deserialize from {0}", sertype);
                if (sertype == SerializationType.Full.ToString() ||
                    sertype == SerializationType.Simple.ToString() ||
                    sertype == SerializationType.SimpleNoId.ToString() ||
                    sertype == SerializationType.SimpleWithValue.ToString() ||
                    sertype == SerializationType.Explicit.ToString())
                {
                    foreach (XmlNode xBlock in root.ChildNodes)
                    {
                        if (xBlock.NodeType == XmlNodeType.Element && xBlock.Name == "Block" && xBlock.ChildNodes.Count == 1)
                        {
                            string      name = CintXML.GetAttribute(xBlock, "Name");
                            XmlDocument xml  = new XmlDocument();
                            xml.AppendChild(xml.ImportNode(xBlock.ChildNodes[0], true));
                            CintDynEntityCollection cEntities = new CintDynEntityCollection(xml, crmsvc, log);
                            SendLine("Block {0}: {1} records", name, cEntities.Count);
                            result.Add(name, cEntities);
                        }
                    }
                }
                else if (sertype == SerializationType.Text.ToString())
                {
                    string        strdelimeter    = CintXML.GetAttribute(root, "Delimeter");
                    char          delimeter       = strdelimeter.Length == 1 ? strdelimeter[0] : '\t';
                    XmlNode       xText           = CintXML.FindChild(root, "Text");
                    StringReader  reader          = new StringReader(xText.InnerText);
                    int           line            = 0;
                    string        name            = "";
                    StringBuilder serializedblock = null;
                    string        current         = reader.ReadLine();
                    while (current != null)
                    {
                        log.Log("Line {0:000}: {1}", line, current);
                        if (current.StartsWith("<<<") && current.Contains(">>>"))
                        {
                            log.Log("Block start");
                            if (!string.IsNullOrWhiteSpace(name) && serializedblock != null)
                            {
                                CintDynEntityCollection cEntities = new CintDynEntityCollection(serializedblock.ToString(), delimeter, crmsvc, log);
                                result.Add(name, cEntities);
                                SendLine("Block {0}: {1} records", name, cEntities.Count);
                            }
                            name            = current.Substring(3);
                            name            = name.Substring(0, name.IndexOf(">>>", StringComparison.Ordinal));
                            serializedblock = new StringBuilder();
                        }
                        else
                        {
                            serializedblock.AppendLine(current);
                        }
                        current = reader.ReadLine();
                        line++;
                    }
                    if (!string.IsNullOrWhiteSpace(serializedblock.ToString()))
                    {
                        CintDynEntityCollection cEntities = new CintDynEntityCollection(serializedblock.ToString(), delimeter, crmsvc, log);
                        result.Add(name, cEntities);
                        SendLine("Block {0}: {1} records", name, cEntities.Count);
                    }
                }
            }
            log.EndSection();
            return(result);
        }
Ejemplo n.º 10
0
        private CintDynEntityCollection ExportDataBlock(ShuffleBlocks blocks, XmlNode xBlock)
        {
            log.StartSection("ExportDataBlock");
            string name = CintXML.GetAttribute(xBlock, "Name");

            log.Log("Block: {0}", name);
            CintDynEntityCollection cExportEntities = null;

            if (xBlock.Name != "DataBlock")
            {
                throw new ArgumentOutOfRangeException("Type", xBlock.Name, "Invalid Block type");
            }
            string  entity  = CintXML.GetAttribute(xBlock, "Entity");
            string  type    = CintXML.GetAttribute(xBlock, "Type");
            XmlNode xExport = CintXML.FindChild(xBlock, "Export");

            if (xExport != null)
            {
                if (string.IsNullOrEmpty(entity))
                {
                    entity = CintXML.GetAttribute(xExport, "Entity");
                }

                #region Define attributes

                XmlNode       xAttributes     = CintXML.FindChild(xExport, "Attributes");
                bool          allcolumns      = false;
                List <string> lAttributes     = new List <string>();
                List <string> lNullAttributes = new List <string>();
                if (xAttributes != null)
                {
                    foreach (XmlNode xAttr in xAttributes.ChildNodes)
                    {
                        if (xAttr.Name == "Attribute")
                        {
                            string attr = CintXML.GetAttribute(xAttr, "Name");
                            log.Log("Adding column: {0}", attr);
                            lAttributes.Add(attr.Replace("*", "%"));
                            if (attr.Contains("*"))
                            {
                                allcolumns = true;
                                log.Log("Found wildcard");
                            }
                            else
                            {
                                bool includenull = CintXML.GetBoolAttribute(xAttr, "IncludeNull", false);
                                if (includenull)
                                {
                                    lNullAttributes.Add(attr);
                                }
                            }
                        }
                    }
                }
                else
                {
                    allcolumns = true;
                    lAttributes.Add("*");
                    log.Log("Attributes not specified, retrieving all");
                }

                #endregion Define attributes

                if (type == "Entity" || string.IsNullOrEmpty(type))
                {
                    #region QueryExpression Entity

                    log.StartSection("Export entity " + entity);
                    QueryExpression qExport = new QueryExpression(entity);
                    if (CintXML.GetBoolAttribute(xExport, "ActiveOnly", true))
                    {
                        CintQryExp.AppendConditionActive(qExport.Criteria);
                    }

                    foreach (var xBlockChild in xBlock.ChildNodes.Cast <XmlNode>())
                    {
                        if (xBlockChild.Name == "Relation")
                        {
                            AddRelationFilter(blocks, xBlockChild, qExport.Criteria, log);
                        }
                    }
                    foreach (XmlNode xExpProp in xExport.ChildNodes)
                    {
                        if (xExport.NodeType == XmlNodeType.Element)
                        {
                            switch (xExpProp.Name)
                            {
                            case "#comment":
                            case "Attributes":
                                break;

                            case "Filter":
                                AddFilter(qExport, xExpProp);
                                break;

                            case "Sort":
                                qExport.AddOrder(
                                    CintXML.GetAttribute(xExpProp, "Attribute"),
                                    CintXML.GetAttribute(xExpProp, "Type") == "Desc" ? OrderType.Descending : OrderType.Ascending);
                                break;

                            default:
                                throw new ArgumentOutOfRangeException("Name", xExpProp.Name, "Invalid subitem to export block " + name);
                            }
                        }
                    }
                    if (allcolumns)
                    {
                        qExport.ColumnSet = new ColumnSet(true);
                    }
                    else
                    {
                        foreach (string attr in lAttributes)
                        {
                            qExport.ColumnSet.AddColumn(attr);
                        }
                    }
#if DEBUG
                    log.Log("Converting to FetchXML");
                    try
                    {
                        var fetch = CintQryExp.ConvertToFetchXml(qExport, crmsvc);
                        log.Log("Exporting {0}:\n{1}", entity, fetch);
                    }
                    catch (Exception ex)
                    {
                        log.Log("Conversion error:");
                        log.Log(ex);
                    }
#endif
                    cExportEntities = CintDynEntity.RetrieveMultiple(crmsvc, qExport, log);
                    if (allcolumns)
                    {
                        SelectAttributes(cExportEntities, lAttributes, lNullAttributes);
                    }
                    SendLine("Block {0} - {1} records", name, cExportEntities.Count);
                    log.EndSection();

                    #endregion QueryExpression Entity
                }
                else if (type == "Intersect")
                {
                    #region FetchXML Intersect

                    log.StartSection("Export intersect " + entity);
                    XmlDocument xDoc    = new XmlDocument();
                    XmlNode     xEntity = CintFetchXML.Create(xDoc, entity);
                    CintFetchXML.AddAttribute(xEntity, lAttributes.ToArray());

                    foreach (var xBlockChild in xBlock.ChildNodes.Cast <XmlNode>())
                    {
                        if (xBlockChild.Name == "Relation")
                        {
                            AddRelationFilter(blocks, xBlockChild, xEntity, log);
                        }
                    }

                    var fetch = xDoc.OuterXml;
                    fetch = fetch.Replace("<fetch ", "<fetch {0} {1} ");    // Detta för att se till att CrmServiceProxy.RetrieveMultiple kan hantera paging
#if DEBUG
                    log.Log("Exporting intersect entity {0}\n{1}", entity, fetch);
#endif
                    var qExport = new FetchExpression(fetch);
                    cExportEntities = CintDynEntity.RetrieveMultiple(crmsvc, qExport, log);
                    foreach (var cde in cExportEntities)
                    {
                        List <KeyValuePair <string, object> > newattributes = new List <KeyValuePair <string, object> >();
                        foreach (var attr in cde.Attributes)
                        {
                            if (attr.Value is Guid)
                            {
                                var    attrname      = attr.Key;
                                string relatedentity = attrname.Substring(0, attrname.Length - (attrname.EndsWith("idone") || attrname.EndsWith("idtwo") ? 5 : 2));
                                newattributes.Add(new KeyValuePair <string, object>(attrname, new EntityReference(relatedentity, (Guid)attr.Value)));
                            }
                        }
                        foreach (var newattr in newattributes)
                        {
                            if (!newattr.Key.Equals(cde.PrimaryIdAttribute))
                            {
                                cde.AddProperty(newattr.Key, newattr.Value);
                            }
                        }
                    }
                    log.EndSection();

                    #endregion FetchXML Intersect
                }

                log.Log("Returning {0} records", cExportEntities.Count);
            }
            log.EndSection();
            return(cExportEntities);
        }
Ejemplo n.º 11
0
        private void AddRelationFilter(ShuffleBlocks blocks, XmlNode xRelation, FilterExpression filter, ILoggable log)
        {
            log.StartSection(MethodBase.GetCurrentMethod().Name);
            if (blocks != null && blocks.Count > 0)
            {
                var block       = CintXML.GetAttribute(xRelation, "Block");
                var attribute   = CintXML.GetAttribute(xRelation, "Attribute");
                var pkattribute = CintXML.GetAttribute(xRelation, "PK-Attribute");
                var includenull = CintXML.GetBoolAttribute(xRelation, "IncludeNull", false);
                var entityName  = xRelation.ParentNode.Attributes["Entity"].Value;

                var type = GetAttributeType(attribute, entityName);

                ConditionExpression cond = new ConditionExpression();
                cond.AttributeName = attribute;
                cond.Operator      = Microsoft.Xrm.Sdk.Query.ConditionOperator.In;

                List <object>           ids        = new List <object>();
                CintDynEntityCollection parentcoll = blocks.ContainsKey(block) ? blocks[block] : null;
                if (parentcoll != null && parentcoll.Count > 0)
                {
                    foreach (CintDynEntity parent in parentcoll)
                    {
                        if (string.IsNullOrEmpty(pkattribute))
                        {
                            if (type == AttributeTypeCode.String)
                            {
                                ids.Add(parent.Id.ToString());
                            }
                            else
                            {
                                ids.Add(parent.Id);
                            }
                        }
                        else if (type == AttributeTypeCode.String)
                        {
                            ids.Add(parent.Property <EntityReference>(pkattribute, new EntityReference()).Id.ToString());
                        }
                        else
                        {
                            ids.Add(parent.Property <EntityReference>(pkattribute, new EntityReference()).Id);
                        }
                    }
                }
                else
                {
                    // Adding temp guid to indicate "no matches", as ConditionOperator.In will fail if no values are given
                    ids.Add(new Guid());
                }
                cond.Values.AddRange(ids);
                if (!includenull)
                {
                    filter.AddCondition(cond);
                }
                else
                {
                    var orfilter = new FilterExpression(LogicalOperator.Or);
                    orfilter.AddCondition(attribute, Microsoft.Xrm.Sdk.Query.ConditionOperator.Null);
                    orfilter.AddCondition(cond);
                    filter.AddFilter(orfilter);
                }
                log.Log("Adding relation condition for {0} in {1} values in {2}.{3}", attribute, ids.Count, block, pkattribute);
            }
            log.EndSection();
        }
Ejemplo n.º 12
0
        private void AddFilter(QueryExpression qExport, XmlNode xExpProp)
        {
            string valuestring = CintXML.GetAttribute(xExpProp, "Value");

            if (valuestring.Contains("{0}"))
            {
                throw new ArgumentOutOfRangeException("Name", "Filter", "Parameterized Filters not supported in embedded Shuffle Utils");
            }
            string operstr = CintXML.GetAttribute(xExpProp, "Operator");

            if (string.IsNullOrEmpty(operstr))
            {
                operstr = "Equal";
            }
            Microsoft.Xrm.Sdk.Query.ConditionOperator oper = (Microsoft.Xrm.Sdk.Query.ConditionOperator)Enum.Parse(typeof(Microsoft.Xrm.Sdk.Query.ConditionOperator), operstr, true);

            object value = null;

            if (oper != Microsoft.Xrm.Sdk.Query.ConditionOperator.EqualBusinessId &&
                oper != Microsoft.Xrm.Sdk.Query.ConditionOperator.EqualUserId &&
                oper != Microsoft.Xrm.Sdk.Query.ConditionOperator.EqualUserLanguage &&
                oper != Microsoft.Xrm.Sdk.Query.ConditionOperator.NotEqualBusinessId &&
                oper != Microsoft.Xrm.Sdk.Query.ConditionOperator.NotEqualUserId &&
                oper != Microsoft.Xrm.Sdk.Query.ConditionOperator.NotNull &&
                oper != Microsoft.Xrm.Sdk.Query.ConditionOperator.Null &&
                oper != Microsoft.Xrm.Sdk.Query.ConditionOperator.ThisMonth &&
                oper != Microsoft.Xrm.Sdk.Query.ConditionOperator.ThisWeek &&
                oper != Microsoft.Xrm.Sdk.Query.ConditionOperator.ThisYear &&
                oper != Microsoft.Xrm.Sdk.Query.ConditionOperator.Today &&
                oper != Microsoft.Xrm.Sdk.Query.ConditionOperator.Tomorrow &&
                oper != Microsoft.Xrm.Sdk.Query.ConditionOperator.Yesterday)
            {
                switch (CintXML.GetAttribute(xExpProp, "Type").ToUpperInvariant())
                {
                case "STRING":
                    value = valuestring;
                    break;

                case "INT":
                    value = int.Parse(valuestring);
                    break;

                case "BOOL":
                    value = bool.Parse(valuestring);
                    break;

                case "DATETIME":
                    value = DateTime.Parse(valuestring);
                    break;

                case "GUID":
                    value = new Guid(valuestring);
                    break;

                default:
                    throw new ArgumentOutOfRangeException("Type", CintXML.GetAttribute(xExpProp, "Type"), "Invalid filter attribute type");
                }
            }
            string attribute = CintXML.GetAttribute(xExpProp, "Attribute");

            log.Log("Adding filter: {0} {1} {2}", attribute, oper, value);
            CintQryExp.AppendCondition(qExport.Criteria, LogicalOperator.And, attribute, oper, value);
        }
        private void ExportSolutionBlock(XmlNode xBlock)
        {
            log.StartSection("ExportSolutionBlock");

            if (xBlock.Name != "SolutionBlock")
            {
                throw new ArgumentOutOfRangeException("Type", xBlock.Name, "Invalid Block type");
            }
            string name = CintXML.GetAttribute(xBlock, "Name");

            log.Log("Block: {0}", name);
            string path = CintXML.GetAttribute(xBlock, "Path");
            string file = CintXML.GetAttribute(xBlock, "File");

            if (string.IsNullOrWhiteSpace(path) && !string.IsNullOrWhiteSpace(definitionpath))
            {
                path  = definitionpath;
                path += path.EndsWith("\\") ? "" : "\\";
            }
            if (string.IsNullOrWhiteSpace(file))
            {
                file = name;
            }
            XmlNode xExport = CintXML.FindChild(xBlock, "Export");

            if (xExport != null)
            {
                string type          = CintXML.GetAttribute(xExport, "Type");
                string setversion    = CintXML.GetAttribute(xExport, "SetVersion");
                bool   publish       = CintXML.GetBoolAttribute(xExport, "PublishBeforeExport", false);
                string targetversion = CintXML.GetAttribute(xExport, "TargetVersion");

                CintDynEntity cdSolution     = GetAndVerifySolutionForExport(name);
                var           currentversion = new Version(cdSolution.Property("version", "1.0.0.0"));

                SendLine("Solution: {0} {1}", name, currentversion);

                if (!string.IsNullOrWhiteSpace(setversion))
                {
                    SetNewSolutionVersion(setversion, cdSolution, currentversion);
                }

                if (publish)
                {
                    SendLine("Publishing customizations");
                    crmsvc.Execute(new PublishAllXmlRequest());
                }

                ExportSolutionRequest req = new ExportSolutionRequest()
                {
                    SolutionName = name
                };
#if Crm8
                if (!string.IsNullOrWhiteSpace(targetversion))
                {
                    req.TargetVersion = targetversion;
                }
#endif
                XmlNode xSettings = CintXML.FindChild(xExport, "Settings");
                if (xSettings != null)
                {
                    req.ExportAutoNumberingSettings          = CintXML.GetBoolAttribute(xSettings, "AutoNumbering", false);
                    req.ExportCalendarSettings               = CintXML.GetBoolAttribute(xSettings, "Calendar", false);
                    req.ExportCustomizationSettings          = CintXML.GetBoolAttribute(xSettings, "Customization", false);
                    req.ExportEmailTrackingSettings          = CintXML.GetBoolAttribute(xSettings, "EmailTracking", false);
                    req.ExportGeneralSettings                = CintXML.GetBoolAttribute(xSettings, "General", false);
                    req.ExportMarketingSettings              = CintXML.GetBoolAttribute(xSettings, "Marketing", false);
                    req.ExportOutlookSynchronizationSettings = CintXML.GetBoolAttribute(xSettings, "OutlookSync", false);
                    req.ExportRelationshipRoles              = CintXML.GetBoolAttribute(xSettings, "RelationshipRoles", false);
                    req.ExportIsvConfig = CintXML.GetBoolAttribute(xSettings, "IsvConfig", false);
                }

                if (type == "Managed" || type == "Both")
                {
                    string filename = path + file + "_managed.zip";
                    SendLine("Exporting solution to: {0}", filename);
                    req.Managed = true;
                    ExportSolutionResponse exportSolutionResponse = (ExportSolutionResponse)crmsvc.Execute(req);
                    byte[] exportXml = exportSolutionResponse.ExportSolutionFile;
                    File.WriteAllBytes(filename, exportXml);
                }
                if (type == "Unmanaged" || type == "Both")
                {
                    string filename = path + file + ".zip";
                    SendLine("Exporting solution to: {0}", filename);
                    req.Managed = false;
                    ExportSolutionResponse exportSolutionResponse = (ExportSolutionResponse)crmsvc.Execute(req);
                    byte[] exportXml = exportSolutionResponse.ExportSolutionFile;
                    File.WriteAllBytes(filename, exportXml);
                }
            }
            log.EndSection();
        }
Ejemplo n.º 14
0
        private Tuple <int, int, int, int, int, EntityReferenceCollection> ImportDataBlock(XmlNode xBlock, CintDynEntityCollection cEntities)
        {
            log.StartSection("ImportDataBlock");
            int created = 0;
            int updated = 0;
            int skipped = 0;
            int deleted = 0;
            int failed  = 0;
            EntityReferenceCollection references = new EntityReferenceCollection();

            string name = CintXML.GetAttribute(xBlock, "Name");

            log.Log("Block: {0}", name);
            SendStatus(name, null);
            SendLine();

            switch (xBlock.Name)
            {
            case "DataBlock":
                string  type    = CintXML.GetAttribute(xBlock, "Type");
                XmlNode xImport = CintXML.FindChild(xBlock, "Import");
                if (xImport != null)
                {
                    var includeid           = CintXML.GetBoolAttribute(xImport, "CreateWithId", false);
                    var save                = CintXML.GetAttribute(xImport, "Save");
                    var delete              = CintXML.GetAttribute(xImport, "Delete");
                    var updateinactive      = CintXML.GetBoolAttribute(xImport, "UpdateInactive", false);
                    var updateidentical     = CintXML.GetBoolAttribute(xImport, "UpdateIdentical", false);
                    var deprecatedoverwrite = CintXML.GetAttribute(xImport, "Overwrite");
                    if (!string.IsNullOrWhiteSpace(deprecatedoverwrite))
                    {
                        SendLine("DEPRECATED use of attribute Overwrite!");
                        bool overwrite = CintXML.GetBoolAttribute(xImport, "Overwrite", true);
                        save = overwrite ? "CreateUpdate" : "CreateOnly";
                    }
                    if (string.IsNullOrWhiteSpace(save))
                    {       // Default
                        save = "CreateUpdate";
                    }
                    if (string.IsNullOrWhiteSpace(delete))
                    {       // Default
                        delete = "None";
                    }
                    XmlNode xMatch           = CintXML.FindChild(xImport, "Match");
                    var     matchattributes  = GetMatchAttributes(xMatch);
                    var     updateattributes = !updateidentical?GetUpdateAttributes(cEntities) : new List <string>();

                    var preretrieveall = xMatch != null?CintXML.GetBoolAttribute(xMatch, "PreRetrieveAll", false) : false;

                    SendLine();
                    SendLine("Importing block {0} - {1} records ", name, cEntities.Count);

                    var i = 1;

                    if (delete == "All" && (matchattributes.Count == 0))
                    {       // All records shall be deleted, no match attribute defined, so just get all and delete all
                        string entity  = CintXML.GetAttribute(xBlock, "Entity");
                        var    qDelete = new QueryExpression(entity);
                        qDelete.ColumnSet.AddColumn(crmsvc.PrimaryAttribute(entity, log));
                        var deleterecords = CintDynEntity.RetrieveMultiple(crmsvc, qDelete, log);
                        SendLine("Deleting ALL {0} - {1} records", entity, deleterecords.Count);
                        foreach (var record in deleterecords)
                        {
                            SendLine("{0:000} Deleting existing: {1}", i, record);
                            try
                            {
                                record.Delete();
                                deleted++;
                            }
                            catch (FaultException <OrganizationServiceFault> ex)
                            {
                                if (ex.Message.ToUpperInvariant().Contains("DOES NOT EXIST"))
                                {       // This may happen through delayed cascade delete in CRM
                                    SendLine("      ...already deleted");
                                }
                                else
                                {
                                    throw;
                                }
                            }
                            i++;
                        }
                    }
                    int totalRecords = cEntities.Count;
                    i = 1;
                    CintDynEntityCollection cAllRecordsToMatch = null;
                    foreach (CintDynEntity cdEntity in cEntities)
                    {
                        string unique = cdEntity.Id.ToString();
                        SendStatus(-1, -1, totalRecords, i);
                        try
                        {
                            Guid oldid = cdEntity.Id;
                            Guid newid = Guid.Empty;

                            ReplaceGuids(cdEntity, includeid);
                            ReplaceUpdateInfo(cdEntity);
                            unique = GetEntityDisplayString(xMatch, cdEntity);
                            SendStatus(null, unique);

                            if (type == "Entity" || string.IsNullOrEmpty(type))
                            {
                                #region Entity

                                if (matchattributes.Count == 0)
                                {
                                    if (save == "Never" || save == "UpdateOnly")
                                    {
                                        skipped++;
                                        SendLine("{0:000} Not saving: {1}", i, unique);
                                    }
                                    else
                                    {
                                        if (!includeid)
                                        {
                                            cdEntity.Id = Guid.Empty;
                                        }
                                        if (SaveEntity(cdEntity, null, updateinactive, updateidentical, i, unique))
                                        {
                                            created++;
                                            newid = cdEntity.Id;
                                            references.Add(cdEntity.Entity.ToEntityReference());
                                        }
                                    }
                                }
                                else
                                {
                                    var matches = GetMatchingRecords(cdEntity, matchattributes, updateattributes, preretrieveall, ref cAllRecordsToMatch);
                                    if (delete == "All" || (matches.Count == 1 && delete == "Existing"))
                                    {
                                        foreach (CintDynEntity cdMatch in matches)
                                        {
                                            SendLine("{0:000} Deleting existing: {1}", i, unique);
                                            try
                                            {
                                                cdMatch.Delete();
                                                deleted++;
                                            }
                                            catch (FaultException <OrganizationServiceFault> ex)
                                            {
                                                if (ex.Message.ToUpperInvariant().Contains("DOES NOT EXIST"))
                                                {       // This may happen through cascade delete in CRM
                                                    SendLine("      ...already deleted");
                                                }
                                                else
                                                {
                                                    throw;
                                                }
                                            }
                                        }
                                        matches.Clear();
                                    }
                                    if (matches.Count == 0)
                                    {
                                        if (save == "Never" || save == "UpdateOnly")
                                        {
                                            skipped++;
                                            SendLine("{0:000} Not creating: {1}", i, unique);
                                        }
                                        else
                                        {
                                            if (!includeid)
                                            {
                                                cdEntity.Id = Guid.Empty;
                                            }
                                            if (SaveEntity(cdEntity, null, updateinactive, updateidentical, i, unique))
                                            {
                                                created++;
                                                newid = cdEntity.Id;
                                                references.Add(cdEntity.Entity.ToEntityReference());
                                            }
                                        }
                                    }
                                    else if (matches.Count == 1)
                                    {
                                        var match = matches[0];
                                        newid = match.Id;
                                        if (save == "CreateUpdate" || save == "UpdateOnly")
                                        {
                                            if (SaveEntity(cdEntity, match, updateinactive, updateidentical, i, unique))
                                            {
                                                updated++;
                                                references.Add(cdEntity.Entity.ToEntityReference());
                                            }
                                            else
                                            {
                                                skipped++;
                                            }
                                        }
                                        else
                                        {
                                            skipped++;
                                            SendLine("{0:000} Exists: {1}", i, unique);
                                        }
                                    }
                                    else
                                    {
                                        failed++;
                                        SendLine("Import object matches {0} records in target database!", matches.Count);
                                        SendLine(unique);
                                    }
                                }
                                if (!oldid.Equals(Guid.Empty) && !newid.Equals(Guid.Empty) && !oldid.Equals(newid) && !guidmap.ContainsKey(oldid))
                                {
                                    log.Log("Mapping IDs: {0} ==> {1}", oldid, newid);
                                    guidmap.Add(oldid, newid);
                                }

                                #endregion Entity
                            }
                            else if (type == "Intersect")
                            {
                                #region Intersect

                                if (cdEntity.Attributes.Count != 2)
                                {
                                    throw new ArgumentOutOfRangeException("Attributes", cdEntity.Attributes.Count, "Invalid Attribute count for intersect object");
                                }
                                string intersect = CintXML.GetAttribute(xBlock, "IntersectName");
                                if (string.IsNullOrEmpty(intersect))
                                {
                                    intersect = cdEntity.Name;
                                }

                                EntityReference ref1   = (EntityReference)cdEntity.Attributes.ElementAt(0).Value;
                                EntityReference ref2   = (EntityReference)cdEntity.Attributes.ElementAt(1).Value;
                                CintDynEntity   party1 = CintDynEntity.InitFromNameAndId(ref1.LogicalName, ref1.Id, crmsvc, log);
                                CintDynEntity   party2 = CintDynEntity.InitFromNameAndId(ref2.LogicalName, ref2.Id, crmsvc, log);
                                try
                                {
                                    party1.Associate(party2, intersect);
                                    created++;
                                    SendLine("{0} Associated: {1}", i.ToString().PadLeft(3, '0'), name);
                                }
                                catch (Exception ex)
                                {
                                    if (ex.Message.Contains("duplicate"))
                                    {
                                        SendLine("{0} Association exists: {1}", i.ToString().PadLeft(3, '0'), name);
                                        skipped++;
                                    }
                                    else
                                    {
                                        throw;
                                    }
                                }

                                #endregion Intersect
                            }
                        }
                        catch (Exception ex)
                        {
                            failed++;
                            SendLine("\n*** Error record: {0} ***\n{1}", unique, ex.Message);
                            log.Log(ex);
                            if (stoponerror)
                            {
                                throw;
                            }
                        }
                        i++;
                    }

                    SendLine("Created: {0} Updated: {1} Skipped: {2} Deleted: {3} Failed: {4}", created, updated, skipped, deleted, failed);
                }
                break;

            default:
                throw new ArgumentOutOfRangeException("Type", xBlock.Name, "Invalid Block type");
            }
            log.EndSection();
            return(new Tuple <int, int, int, int, int, EntityReferenceCollection>(created, updated, skipped, deleted, failed, references));
        }
        private void ValidatePreReqs(XmlNode xImport, Version thisversion)
        {
            log.StartSection("ValidatePreReqs");
            XmlNode xPreReqs = CintXML.FindChild(xImport, "PreRequisites");

            if (xPreReqs != null)
            {
                CintDynEntityCollection cSolutions = GetExistingSolutions();
                foreach (XmlNode xPreReq in xPreReqs.ChildNodes)
                {
                    if (xPreReq.NodeType == XmlNodeType.Element && xPreReq.Name == "Solution")
                    {
                        bool   valid    = false;
                        string name     = CintXML.GetAttribute(xPreReq, "Name");
                        string comparer = CintXML.GetAttribute(xPreReq, "Comparer");
                        var    version  = new Version();
                        log.Log("Prereq: {0} {1} {2}", name, comparer, version);

                        if (comparer.Contains("this"))
                        {
                            version  = thisversion;
                            comparer = comparer.Replace("-this", "");
                        }
                        else if (comparer != "any")
                        {
                            version = new Version(CintXML.GetAttribute(xPreReq, "Version").Replace('*', '0'));
                        }

                        foreach (CintDynEntity cdSolution in cSolutions)
                        {
                            if (cdSolution.Property("uniquename", "") == name)
                            {
                                log.Log("Found matching solution");
                                switch (comparer)
                                {
                                case "any":
                                    valid = true;
                                    break;

                                case "eq":
                                    valid = new Version(cdSolution.Property("version", "1.0.0.0")).Equals(version);
                                    break;

                                case "ge":
                                    valid = new Version(cdSolution.Property("version", "<undefined>")) >= version;
                                    break;

                                default:
                                    throw new ArgumentOutOfRangeException("Comparer", comparer, "Invalid comparer value");
                                }
                            }
                            if (valid)
                            {
                                break;
                            }
                        }
                        if (valid)
                        {
                            SendLine("Prerequisite {0} {1} {2} is satisfied", name, comparer, version);
                        }
                        else
                        {
                            SendLine("Prerequisite {0} {1} {2} is NOT satisfied", name, comparer, version);
                            throw new Exception("Prerequisite NOT satisfied (" + name + " " + comparer + " " + version + ")");
                        }
                    }
                }
            }
            else
            {
                log.Log("No prereqs for solution import");
            }
            log.EndSection();
        }
        private ItemImportResult ImportSolutionBlock(XmlNode xBlock)
        {
            log.StartSection("ImportSolutionBlock");
            var importResult = ItemImportResult.None;

            if (xBlock.Name != "SolutionBlock")
            {
                throw new ArgumentOutOfRangeException("Type", xBlock.Name, "Invalid Block type");
            }
            XmlNode xImport = CintXML.FindChild(xBlock, "Import");

            if (xImport != null)
            {
                string name = CintXML.GetAttribute(xBlock, "Name");
                log.Log("Block: {0}", name);
                SendStatus(name, null);
                string type = CintXML.GetAttribute(xImport, "Type");
                SendLine();
                SendLine("Importing solution: {0}", name);

                string filename = GetSolutionFilename(xBlock, name, type);
                var    version  = ExtractVersionFromSolutionZip(filename);
                try
                {
                    ValidatePreReqs(xImport, version);
                    SolutionImportConditions ImportCondition = CheckIfImportRequired(xImport, name, version);
                    if (ImportCondition != SolutionImportConditions.Skip)
                    {
                        if (DoImportSolution(xImport, filename, version))
                        {
                            if (ImportCondition == SolutionImportConditions.Create)
                            {
                                importResult = ItemImportResult.Created;
                            }
                            else
                            {
                                importResult = ItemImportResult.Updated;
                            }
                        }
                        else
                        {
                            importResult = ItemImportResult.Failed;
                            log.Log("Failed during import");
                        }
                        bool publish = CintXML.GetBoolAttribute(xImport, "PublishAll", false);
                        if (publish)
                        {
                            SendLine("Publishing customizations");
                            crmsvc.Execute(new PublishAllXmlRequest());
                        }
                    }
                    else
                    {
                        importResult = ItemImportResult.Skipped;
                        log.Log("Skipped due to import condition");
                    }
                }
                catch (Exception ex)
                {
                    log.Log(ex);
                    importResult = ItemImportResult.Failed;
                    if (stoponerror)
                    {
                        throw;
                    }
                }
            }
            log.EndSection();
            return(importResult);
        }