static void Main(string[] args)
        {
            log = LogManager.GetLogger("AI_POC");

            //metadata catalog = GetCustomerCatalog(@"C:\Users\mnholden\Documents\GitHub\AIPOC\AIPOC\bin\Debug\METADATA-XMLX-20190121T121838Z");

            //metadataAsset item = catalog.Items.First();
            //var result = GetCombinedObjectFromXMLMetadata(item.identifier, "entitled", item);


            OlsaPortTypeClient client = null;

            if (!Parser.TryParse(args, out Options options))
            {
                return;
            }
            try
            {
                client = GetOLSAClient(new Uri(options.endpoint), options.customerid, options.sharedsecret);
                Process(client, options.mode, options.interval, options.retries);
            }
            catch (Exception ex)
            {
                log.FatalFormat("Issue while Processing.", ex);
            }
        }
        /// <summary>
        /// Processes the specified client.
        /// </summary>
        /// <param name="client">The client.</param>
        /// <param name="assetMode">The asset mode.</param>
        /// <param name="interval">The interval.</param>
        /// <param name="retries">The retries.</param>
        static void Process(OlsaPortTypeClient client, assetInitiationMode assetMode = assetInitiationMode.all, int interval = 1, int retries = 10)
        {
            log.InfoFormat("Starting Process. assetInitiationMode : {0}", assetMode.ToString());


            //Best practice for OLSA AI cycle, on startup - send NULL Acknowledgement to cancel any existing pending requests
            AI_AcknowledgeAssetMetaData(client, null);

            //Call and get the XML data, send NULL acknowledgement
            var xmlResultsFile = DownloadMetadata(client, assetMetadataFormat.XMLX, assetMode, false, false, interval, retries);

            //Call and get the AICC data, send acknowledgement of the returned handled
            var aiccResultsFile = DownloadMetadata(client, assetMetadataFormat.AICC, assetMode, true, false, interval, retries);

            //Extract the downloaded ZIP metadata
            var xmlFolder  = ExtractZip(xmlResultsFile);
            var aiccFolder = ExtractZip(aiccResultsFile);

            //Now perform AI processing
            List <CombinedAssetObject> combinedObjects = new List <CombinedAssetObject>();

            //Loop thru the XML _ss_entitlements.xml from the AICC folder
            XmlTextReader  reader    = new XmlTextReader(string.Format("{0}\\{1}", aiccFolder, "_ss_entitlement_status.xml"));
            XPathDocument  document  = new XPathDocument(reader);
            XPathNavigator navigator = document.CreateNavigator();

            XPathNavigator catalogNavigator = GetXpathNavigatorForCustomerCatalogXML(xmlFolder);

            //Get the ASSET nodes
            XPathNodeIterator nodeIterator = navigator.Select("//ASSET");

            while (nodeIterator.MoveNext())
            {
                if (nodeIterator.Current.HasAttributes)
                {
                    //Extract the ID/STATUS
                    var id     = nodeIterator.Current.GetAttribute("ID", "");
                    var status = nodeIterator.Current.GetAttribute("STATUS", "");
                    //Generate a combine object using the XML and AICC data
                    var result = GetCombinedObject(id, status, catalogNavigator, aiccFolder);
                    combinedObjects.Add(result);
                }
            }
            DateTime now          = DateTime.UtcNow;
            string   jsonFilename = String.Format("JSONDATA-{0:D4}{1:D2}{2:D2}T{3:D2}{4:D2}{5:D2}Z.json",
                                                  now.Year, now.Month, now.Day,
                                                  now.Hour, now.Minute, now.Second);

            log.InfoFormat("Saving Results to JSON. File : {0}", jsonFilename);

            string jsonStr = JsonConvert.SerializeObject(combinedObjects);

            File.WriteAllText(jsonFilename, jsonStr);
        }
        /// <summary>
        /// Checks if metadata is ready, runs thru a polling cycle
        /// </summary>
        /// <param name="client">The service.</param>
        /// <param name="metadataHandle">The report handle.</param>
        /// <param name="retries">The retries.</param>
        /// <param name="interval">The interval in ms</param>
        /// <returns></returns>
        /// <exception cref="OlsaPollTimeOutException"></exception>
        private static Uri CheckIfDataReady(OlsaPortTypeClient client, string metadataHandle, int retries, int interval)
        {
            //Start Download Loop
            bool pollComplete = false;
            Uri  reportUri    = null;

            int _attempt = 1;

            //Loop until the report is ready OR we exceed our retries number
            do
            {
                //Check attempts not greater than number of retries
                if (_attempt > retries)
                {
                    pollComplete = false;
                    throw new Exceptions.OlsaPollTimeOutException(string.Format(CultureInfo.CurrentCulture, "Number of retries exceeded. retries={0} interval={1}", retries, interval));
                }

                log.InfoFormat("Waiting before checking if data ready. Attempt: {0} of {1}", _attempt, retries);
                // wait before Polling for the response
                if (!pollComplete)
                {
                    Thread.Sleep(interval);
                }


                try
                {
                    reportUri    = AI_PollForAssetMetaData(client, metadataHandle);
                    pollComplete = true;
                }
                //Catch OLSA Specific Faults
                catch (Exceptions.OlsaDataNotReadyException)
                {
                    //The report requested has not completed running
                    pollComplete = false;
                }

                //Increment attempt
                _attempt++;
            } while (!pollComplete);
            return(reportUri);
        }
        /// <summary>
        /// Gets the olsa client
        /// </summary>
        /// <param name="olsaServerEndpoint">The olsa server endpoint.</param>
        /// <param name="olsaCustomerId">The olsa customer identifier.</param>
        /// <param name="olsaSharedSecret">The olsa shared secret.</param>
        /// <returns></returns>
        private static OlsaPortTypeClient GetOLSAClient(Uri olsaServerEndpoint, string olsaCustomerId, string olsaSharedSecret)
        {
            //Set the encoding to SOAP 1.1, Disable Addressing and set encoding to UTF8
            TextMessageEncodingBindingElement messageEncoding = new TextMessageEncodingBindingElement();

            messageEncoding.MessageVersion = MessageVersion.CreateVersion(EnvelopeVersion.Soap11, AddressingVersion.None);
            messageEncoding.WriteEncoding  = Encoding.UTF8;

            //Setup Binding Elemment
            HttpTransportBindingElement transportBinding = new HttpsTransportBindingElement();

            //Set the maximum received messages sizes to 1Mb
            transportBinding.MaxReceivedMessageSize = 1024 * 1024;
            transportBinding.MaxBufferPoolSize      = 1024 * 1024;

            //Create the CustomBinding
            Binding customBinding = new CustomBinding(messageEncoding, transportBinding);

            //Create the OLSA Service
            EndpointAddress serviceAddress = new EndpointAddress(olsaServerEndpoint);

            //Set the endPoint URL YOUROLSASERVER/olsa/services/Olsa has to be HTTPS
            OlsaPortTypeClient service = new OlsaPortTypeClient(customBinding, serviceAddress);

            //Add Behaviour to support SOAP UserNameToken Password Digest
            AuthenticationBehavior behavior1 = new AuthenticationBehavior(olsaCustomerId, olsaSharedSecret);

            service.Endpoint.Behaviors.Add(behavior1);

            //Add Behaviour to support fix of Namespaces to address AXIS2 / VWCF incompatability
            NameSpaceFixUpBehavior behavior2 = new NameSpaceFixUpBehavior();

            service.Endpoint.Behaviors.Add(behavior2);

            return(service);
        }
        /// <summary>
        /// Initiates the asset meta data.
        /// </summary>
        /// <param name="client">The client.</param>
        /// <param name="metadataFormat">The metadata format.</param>
        /// <param name="initiationMode">The initiation mode.</param>
        /// <param name="onsuccessclose">if set to <c>true</c> [onsuccessclose].</param>
        /// <returns></returns>
        /// <exception cref="AIPOC.Exceptions.OlsaSecurityException"></exception>
        public static string AI_InitiateAssetMetaData(OlsaPortTypeClient client, assetMetadataFormat metadataFormat, assetInitiationMode initiationMode, bool onsuccessclose = false)
        {
            HandleResponse handleResponse = new HandleResponse();

            try
            {
                log.InfoFormat("Sending AI_InitiateAssetMetadata Request. Format: {0} Mode: {1}", metadataFormat, initiationMode);
                InitiateAssetMetaDataRequest request = new InitiateAssetMetaDataRequest();

                //Pull the OlsaAuthenticationBehviour so we can extract the customerid
                AuthenticationBehavior olsaCredentials = (AuthenticationBehavior)client.ChannelFactory.Endpoint.Behaviors.Where(p => p.GetType() == typeof(AuthenticationBehavior)).FirstOrDefault();
                request.customerId     = olsaCredentials.UserName;
                request.initiationMode = initiationMode;
                request.metadataFormat = metadataFormat;

                handleResponse = client.AI_InitiateAssetMetaData(request);
            }
            catch (WebException)
            {
                // This captures any Web Exepctions such as DNS lookup errors, HTTP status errors such as 404, proxy errors etc
                // See http://msdn.microsoft.com/en-us/library/48ww3ee9(VS.80).aspx
                throw;
            }
            catch (TimeoutException)
            {
                //This captures the WCF timeout exception
                throw;
            }
            //Olsa.GeneralFault exception will be thrown for issues like parameters invalid, user does could not be created etc
            catch (FaultException <Olsa.GeneralFault> )
            {
                throw;
            }
            //WCF fault exception will be thrown for any other issues such as Security
            catch (FaultException fe)
            {
                if (fe.Message.ToLower(CultureInfo.InvariantCulture).Contains("the security token could not be authenticated or authorized"))
                {
                    //The OLSA Credentials specified could not be authenticated
                    //Check the values in the web.config are correct for OLSA.CustomerID and OLSA.SharedSecret - these are case sensitive
                    //Check the time on the machine, the SOAP message is valid for 5 minutes. This means that if the time on the calling machine
                    //is to slow OR to fast then the SOAP message will be invalid.
                    throw new Exceptions.OlsaSecurityException();
                }
                throw;
            }
            catch (CommunicationException)
            {
                throw;
            }
            catch (Exception)
            {
                //Any other type of exception, perhaps out of memory
                throw;
            }
            finally
            {
                if (client != null)
                {
                    if (client.State == CommunicationState.Faulted)
                    {
                        client.Abort();
                    }
                    if (onsuccessclose)
                    {
                        client.Close();
                    }
                }
            }
            return(handleResponse.handle);
        }
        /// <summary>
        /// This calls the AI_InitiateAssetMetadata function, then the AI_PollForAssetMetadata, saves the results (metadata_<paramref name="metadataFormat" />.zip and extracts them.
        /// </summary>
        /// <param name="client">The OLSA client.</param>
        /// <param name="metadataFormat">The metadata format.</param>
        /// <param name="initiationMode">The initiation mode.</param>
        /// <param name="acknowledge">if set to <c>true</c> send an AI_AcknowledgeAssetMetadata</param>
        /// <param name="onsuccessclose">if set to <c>true</c> [onsuccessclose].</param>
        /// <param name="pollInterval">The poll interval.</param>
        /// <returns></returns>
        static FileInfo DownloadMetadata(OlsaPortTypeClient client, assetMetadataFormat metadataFormat, assetInitiationMode initiationMode, bool acknowledge = false, bool onsuccessclose = false, int pollInterval = 5, int pollRetries = 10)
        {
            DateTime now        = DateTime.UtcNow;
            string   _localFile = String.Format("METADATA-{0}-{1:D4}{2:D2}{3:D2}T{4:D2}{5:D2}{6:D2}Z.zip",
                                                metadataFormat, now.Year, now.Month, now.Day,
                                                now.Hour, now.Minute, now.Second);

            FileInfo localFile = null;
            Uri      metadataDownloadUri;

            string metadataHandle = null;

            try
            {
                log.InfoFormat("DownloadMetadata. Format: {0} Mode: {1}", metadataFormat, initiationMode);

                metadataHandle = AI_InitiateAssetMetaData(client, metadataFormat, initiationMode, onsuccessclose);
                log.InfoFormat("Returned Handle: {0}", metadataHandle);
            }
            catch (FaultException <Olsa.RequestAlreadyInProgressFault> )
            {
                throw;
            }
            catch (Exception ex)
            {
                log.Fatal("Issue while submitting request", ex);
                throw;
            }


            if (!string.IsNullOrEmpty(metadataHandle))
            {
                //We have a report handle so poll every x minutes until report ready or for max y attempts
                int interval = (int)(pollInterval * 60 * 1000);
                int retries  = pollRetries;

                log.InfoFormat("Starting Loop to check if data is ready. Interval: {0} minutes. Retries:{1}", pollInterval, retries);

                //Poll for the report
                try
                {
                    metadataDownloadUri = CheckIfDataReady(client, metadataHandle, retries, interval);
                    log.InfoFormat("Returned Url: {0}", metadataDownloadUri.OriginalString);
                }
                catch (Exception ex1)
                {
                    log.Fatal("Issue while checking if data ready", ex1);
                    throw;
                }


                log.InfoFormat("Starting Download of file. Saving to: {0}", _localFile);
                using (WebClient webClient = new WebClient())
                {
                    try
                    {
                        webClient.DownloadFile(metadataDownloadUri, _localFile);
                        log.Info("Download Completed");
                    }
                    catch (Exception ex2)
                    {
                        log.Fatal("Issue while downloading report", ex2);
                        throw;
                    }
                }

                if (client != null)
                {
                    if (client.State == CommunicationState.Faulted)
                    {
                        client.Abort();
                    }
                }
            }

            if (acknowledge)
            {
                log.InfoFormat("Sending Acknowledgement. Handle: {0}", metadataHandle);
                AI_AcknowledgeAssetMetaData(client, metadataHandle);
            }
            else
            {
                //Send NULL Handle Ack
                log.Info("Sending Acknowledgement. Null Handle");
                AI_AcknowledgeAssetMetaData(client, null);
            }


            localFile = new FileInfo(_localFile);
            return(localFile);
        }
Beispiel #7
0
        static void Process(Uri endpoint, string customerId, string sharedSecret)
        {
            //Create the OLSA Web Services Client using code
            OlsaPortTypeClient client = Helpers.Olsa.GetOLSAClient(endpoint, customerId, sharedSecret);

            Console.WriteLine("Issuing the UD_SubmitReport Request");
            Console.WriteLine("------------------------------------");
            HandleResponse handleResponse = new HandleResponse();

            //--------------------------------------------------------------------------------------------
            //Define report settings here to ease changes
            string       scopingUserId  = "admin";
            reportFormat reportFormat   = reportFormat.CSV;
            string       reportFilename = "report." + reportFormat.ToString();

            string reportLanguage     = "en_US"; //en_US only supported value
            int    reportRetainperiod = 3;       //1 - 1 hour, 2 - 8 hours, 3 - 24 hours.

            //For details of report names and parameters see https://documentation.skillsoft.com/en_us/skillport/8_0/ah/35465.htm
            string reportName = "summary_catalog";
            //Define report parameters
            List <MapItem> paramList = new List <MapItem>();

            paramList.Add(new MapItem()
            {
                key = "asset_category", value = "1,2,3,4,5,21"
            });
            paramList.Add(new MapItem()
            {
                key = "display_options", value = "all"
            });


            //--------------------------------------------------------------------------------------------

            //Submit Report request
            try
            {
                handleResponse = Helpers.Olsa.SubmitReport(scopingUserId, reportFormat, reportName, paramList.ToArray(), reportLanguage, reportRetainperiod, client, false);

                //Minutes between polls
                int sleepInterval = 2;
                Console.WriteLine("Handle: {0}", handleResponse.handle);

                UrlResponse url = null;

                for (int i = 0; i < 10; i++)
                {
                    Console.WriteLine("{0}: Sleeping {1} minutes", DateTime.UtcNow.ToLongTimeString(), sleepInterval);
                    //ms - so here we sleep for 10 minutes
                    System.Threading.Thread.Sleep(sleepInterval * 60 * 1000);

                    try
                    {
                        url = Helpers.Olsa.PollforReport(handleResponse.handle, client, false);
                        break;
                    }
                    catch (FaultException <Olsa.DataNotReadyYetFault> )
                    {
                        //The report has not completed generation, we are checking for a Specific OLSA Exception
                        Console.WriteLine("{0}: The specified report is not yet ready", DateTime.UtcNow.ToLongTimeString());
                    }
                    catch (Exception ex)
                    {
                        Console.WriteLine("{0}: Issue while Polling for Report.", DateTime.UtcNow.ToLongTimeString());
                        Console.WriteLine("{0}: Exception: {1}", DateTime.UtcNow.ToLongTimeString(), ex.ToString());
                        throw;
                    }
                }

                if (url != null)
                {
                    WebClient myWebClient = new WebClient();
                    Console.WriteLine("{0}: Downloading Report: {1}", DateTime.UtcNow.ToLongTimeString(), url.olsaURL);
                    myWebClient.DownloadFile(url.olsaURL, reportFilename);
                    Console.WriteLine("{0}: Successfully Downloaded: {1}", DateTime.UtcNow.ToLongTimeString(), reportFilename);
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine("{0}: Issue while Submitting Report.", DateTime.UtcNow.ToLongTimeString());
                Console.WriteLine("{0}: Exception: {1}", DateTime.UtcNow.ToLongTimeString(), ex.ToString());
            }
            //Now we can close the client
            if (client != null)
            {
                if (client.State == CommunicationState.Faulted)
                {
                    client.Abort();
                }

                client.Close();
            }
        }
Beispiel #8
0
        /// <summary>
        /// Pollfors the report.
        /// </summary>
        /// <param name="reportId">The report identifier.</param>
        /// <param name="client">The client.</param>
        /// <param name="closeclient">if set to <c>true</c> [closeclient].</param>
        /// <returns></returns>
        public static UrlResponse PollforReport(string reportId, OlsaPortTypeClient client, bool closeclient = false)
        {
            //Set up our response object
            UrlResponse response = null;

            try
            {
                //Create our request
                PollForReportRequest request = new PollForReportRequest();

                //Pull the OlsaAuthenticationBehviour so we can extract the customerid
                AuthenticationBehavior olsaCredentials = (AuthenticationBehavior)client.ChannelFactory.Endpoint.Behaviors.Where(p => p.GetType() == typeof(AuthenticationBehavior)).FirstOrDefault();
                request.customerId = olsaCredentials.UserName;

                request.reportId = reportId;

                response = client.UTIL_PollForReport(request);
            }
            catch (WebException)
            {
                // This captures any Web Exceptions such as proxy errors etc
                // See http://msdn.microsoft.com/en-us/library/48ww3ee9(VS.80).aspx
                throw;
            }
            catch (TimeoutException)
            {
                //This captures the WCF timeout exception
                throw;
            }
            //WCF fault exception will be thrown for any other issues such as Security
            catch (FaultException fe)
            {
                if (fe.Message.ToLower(CultureInfo.InvariantCulture).Contains("the security token could not be authenticated or authorized"))
                {
                    //The OLSA Credentials specified could not be authenticated
                    throw;
                }
                throw;
            }
            catch (Exception)
            {
                //Any other type of exception, perhaps out of memory
                throw;
            }
            finally
            {
                //Shutdown and dispose of the client
                if (client != null)
                {
                    if (client.State == CommunicationState.Faulted)
                    {
                        client.Abort();
                    }
                    if (closeclient)
                    {
                        //We cannot resue client if we close
                        client.Close();
                    }
                }
            }
            return(response);
        }