예제 #1
0
        /// <summary>
        /// Get a list of Historics queries in your account.
        /// </summary>
        /// <param name="user">The user making the request.</param>
        /// <param name="page">The page number to get.</param>
        /// <param name="per_page">The number of items per page.</param>
        /// <returns>A list of Historic objects.</returns>
        public static HistoricList list(User user, int page = 1, int per_page = 20)
        {
            try
            {
                Dictionary <string, string> parameters = new Dictionary <string, string>();
                parameters.Add("page", page.ToString());
                parameters.Add("per_page", per_page.ToString());
                JSONdn res = user.callApi("historics/get", parameters);

                if (!res.has("count"))
                {
                    throw new ApiException("No count in the response");
                }
                HistoricList retval = new HistoricList(res.getIntVal("count"));

                if (!res.has("data") && retval.TotalCount > 0)
                {
                    throw new ApiException("No historics in the response");
                }
                JToken[] children = res.getChildren("data");
                for (int i = 0; i < children.Length; i++)
                {
                    retval.Add(new Historic(user, new JSONdn(children[i])));
                }
                return(retval);
            }
            catch (ApiException e)
            {
                if (e.Code == 400)
                {
                    throw new InvalidDataException(e.Message);
                }
                throw new ApiException("Unexpected API response code: " + e.Code.ToString() + " " + e.Message);
            }
        }
예제 #2
0
        /// <summary>
        /// Called by derived classes when a complete JSON string has been received.
        /// </summary>
        /// <param name="json">The JSON string.</param>
        protected void onData(string json)
        {
            JSONdn data = new JSONdn(json);
            if (data.has("status"))
            {
                if (data.has("tick"))
                {
                    // Ignore ticks
                }
                else switch (data.getStringVal("status"))
                {
                    case "failure":
                    case "error":
                        onError(data.getStringVal("message"));
                        break;

                    case "warning":
                        onWarning(data.getStringVal("message"));
                        break;

                    default:
                        onWarning("Unhandled status message: \"" + data.getStringVal("status") + "\"");
                        break;
                }
            }
            else if (data.has("hash"))
            {
                // The data contains a hash so the connection is consuming
                // multiple streams.
                if (data.has("data.deleted"))
                {
                    m_event_handler.onDeleted(this, new Interaction(data.getJVal("data")), data.getStringVal("hash"));
                }
                else
                {
                    m_event_handler.onInteraction(this, new Interaction(data.getJVal("data")), data.getStringVal("hash"));
                }
            }
            else if (data.has("interaction"))
            {
                // The data does not contain a hash so the connection is
                // consuming a single stream. Use the first element in
                // the hashes array as the hash for the callback.
                if (data.has("deleted"))
                {
                    m_event_handler.onDeleted(this, new Interaction(data.getJVal()), m_hashes[0]);
                }
                else
                {
                    m_event_handler.onInteraction(this, new Interaction(data.getJVal()), m_hashes[0]);
                }
            }
            else
            {
                // Hitting this means the data structure did not have any of
                // the expected elements.
                onError("Unhandled data received: " + json);
            }
        }
예제 #3
0
        /// <summary>
        /// Prepare this Historics query.
        /// </summary>
        public void prepare()
        {
            if (isDeleted())
            {
                throw new InvalidDataException("Cannot set the name of a deleted Historics query");
            }
            if (m_playback_id.Length > 0)
            {
                throw new InvalidDataException("This Historics query has already been prepared");
            }

            Dictionary <string, string> parameters = new Dictionary <string, string>();

            parameters.Add("hash", m_stream_hash);
            parameters.Add("start", Utils.DateTimeToUnixTimestamp(m_start_date).ToString());
            parameters.Add("end", Utils.DateTimeToUnixTimestamp(m_end_date).ToString());
            parameters.Add("name", m_name);
            parameters.Add("sources", string.Join(",", m_sources.ToArray()));
            try
            {
                JSONdn res = m_user.callApi("historics/prepare", parameters);

                if (!res.has("id"))
                {
                    throw new InvalidDataException("Prepared successfully but no playback ID in the response");
                }
                m_playback_id = res.getStringVal("id");

                if (!res.has("dpus"))
                {
                    throw new InvalidDataException("Prepared successfully but no DPU cost in the response");
                }
                m_dpus = res.getDoubleVal("dpus");

                if (!res.has("availability"))
                {
                    throw new InvalidDataException("Prepared successfully but no availability in the response");
                }
                m_availability = new HistoricDataAvailability(new JSONdn(res.getJVal("availability")));
            }
            catch (ApiException e)
            {
                // 400 = Missing or bad parameters.
                // 404 = Historics query not found.
                if (e.Code == 400 || e.Code == 404)
                {
                    throw new InvalidDataException(e.Message);
                }
                throw new ApiException("Unexpected API response code: " + e.Code.ToString() + " " + e.Message);
            }

            // Update our data.
            reloadData();
        }
        /// <summary>
        /// Page through recent Push log entries.
        /// </summary>
        /// <param name="user">The user making the request.</param>
        /// <param name="page">Which page to fetch.</param>
        /// <param name="per_page">How many entries per page.</param>
        /// <param name="order_by">Which field to sort by.</param>
        /// <param name="order_dir">In asc[ending] or desc[ending] order.</param>
        /// <param name="id">Optional subscription ID.</param>
        /// <returns>A PushLog object.</returns>
        public static PushLog getLogs(User user, int page, int per_page, string order_by = ORDERBY_REQUEST_TIME, string order_dir = ORDERDIR_DESC, string id = "")
        {
            Dictionary <string, string> parameters = new Dictionary <string, string>();

            if (page < 1)
            {
                throw new InvalidDataException("The specified page number is invalid");
            }

            if (per_page < 1)
            {
                throw new InvalidDataException("The specified per_page value is invalid");
            }

            if (order_by != ORDERBY_REQUEST_TIME)
            {
                throw new InvalidDataException("The specified order_by is not supported");
            }

            if (order_dir != ORDERDIR_ASC && order_dir != ORDERDIR_DESC)
            {
                throw new InvalidDataException("The specified order_dir is not supported");
            }

            if (id.Length > 0)
            {
                parameters.Add("id", id);
            }

            parameters.Add("page", page.ToString());
            parameters.Add("per_page", per_page.ToString());
            parameters.Add("order_by", order_by);
            parameters.Add("order_dir", order_dir);

            JSONdn res = user.callApi("push/log", parameters);

            if (!res.has("count"))
            {
                throw new ApiException("No count in the response");
            }
            PushLog retval = new PushLog(res.getIntVal("count"));

            if (!res.has("log_entries") && retval.TotalCount > 0)
            {
                throw new ApiException("No log entries in the response");
            }
            JToken[] children = res.getChildren("log_entries");
            for (int i = 0; i < children.Length; i++)
            {
                retval.Add(new PushLogEntry(new JSONdn(children[i])));
            }
            return(retval);
        }
        public void Test_Parse()
        {
            JSONdn json = new JSONdn("{\"delivery_frequency\":10,\"url\":\"http://www.example.com/push_endpoint\",\"auth\":{\"type\":\"basic\",\"username\":\"wooop\",\"password\":\"dsadsa\"}}");

            PushOutputParams pop = new PushOutputParams(json);

            Assert.AreEqual("10", pop["delivery_frequency"], "Parsed value for 'delivery_frequency' is incorrect");
            Assert.AreEqual("http://www.example.com/push_endpoint", pop["url"], "Parsed value for 'url' is incorrect");
            Assert.AreEqual("basic", pop["auth.type"], "Parsed value for 'auth.type' is incorrect");
            Assert.AreEqual("wooop", pop["auth.username"], "Parsed value for 'auth.username' is incorrect");
            Assert.AreEqual("dsadsa", pop["auth.password"], "Parsed value for 'auth.password' is incorrect");
        }
        public HistoricDataAvailability(JSONdn json)
        {
            m_start = json.getDateTimeFromLongVal("start");
            m_end   = json.getDateTimeFromLongVal("end");

            if (json.has("sources"))
            {
                foreach (string key in json.getKeys("sources"))
                {
                    m_sources.Add(key, new HistoricDataAvailabilitySource(new JSONdn(json.getJVal("sources." + key))));
                }
            }
        }
	    public HistoricDataAvailability(JSONdn json)
        {
		    m_start = json.getDateTimeFromLongVal("start");
            m_end = json.getDateTimeFromLongVal("end");
		    
            if (json.has("sources"))
            {
                foreach (string key in json.getKeys("sources"))
                {
			        m_sources.Add(key, new HistoricDataAvailabilitySource(new JSONdn(json.getJVal("sources." + key))));
                }
            }
	    }
	    public HistoricDataAvailabilitySource(JSONdn json)
        {
		    m_status = json.getIntVal("status");

            foreach (JToken version in json.getJVal("versions"))
	        {
		        m_versions.Add(Convert.ToInt32(version.ToString()));
	        }
            
            foreach (string key in json.getKeys("augmentations"))
            {
			    m_augmentations.Add(key, json.getIntVal("augmentations." + key));
		    }
	    }
        public HistoricDataAvailabilitySource(JSONdn json)
        {
            m_status = json.getIntVal("status");

            foreach (JToken version in json.getJVal("versions"))
            {
                m_versions.Add(Convert.ToInt32(version.ToString()));
            }

            foreach (string key in json.getKeys("augmentations"))
            {
                m_augmentations.Add(key, json.getIntVal("augmentations." + key));
            }
        }
예제 #10
0
 /// <summary>
 /// Recursive method to parse a tree in JSON into the flat
 /// dot-notation parameters used by the API.
 /// </summary>
 /// <param name="json">The JSON object.</param>
 /// <param name="key_prefix">The current key prefix.</param>
 protected void setOutputParams(JSONdn json, string key_prefix)
 {
     foreach (string key in json.getKeys())
     {
         string full_key = (key_prefix.Length == 0 ? "" : key_prefix + ".") + key;
         if (json.hasChildren(key))
         {
             setOutputParams(new JSONdn(json.getJVal(key)), full_key);
         }
         else
         {
             set(full_key, json.getStringVal(key));
         }
     }
 }
예제 #11
0
        /// <summary>
        /// Construct an instance from a JSONdn object.
        /// </summary>
        /// <param name="data">The source JSONdn object.</param>
        public Usage(JSONdn data)
        {
            // Validate that the object has the required data
            if (!data.has("start"))
            {
                throw new InvalidDataException("No start date in the usage data");
            }
            if (!data.has("end"))
            {
                throw new InvalidDataException("No end date in the usage data");
            }
            if (!data.has("streams"))
            {
                throw new InvalidDataException("No stream info in the usage data");
            }

            // Save it for later.
            m_data = data;
        }
예제 #12
0
        /// <summary>
        /// Construct an instance from a JSONdn object.
        /// </summary>
        /// <param name="data">The source JSONdn object.</param>
        public Usage(JSONdn data)
        {
            // Validate that the object has the required data
            if (!data.has("start"))
            {
                throw new InvalidDataException("No start date in the usage data");
            }
            if (!data.has("end"))
            {
                throw new InvalidDataException("No end date in the usage data");
            }
            if (!data.has("streams"))
            {
                throw new InvalidDataException("No stream info in the usage data");
            }

            // Save it for later.
            m_data = data;
        }
예제 #13
0
        /// <summary>
        /// Send the CSDL to DataSift for compilation.
        /// </summary>
        public void compile()
        {
            // We must have some CSDL in order to compile the CSDL!
            if (m_csdl.Length == 0)
            {
                throw new InvalidDataException("Cannot compile an empty definition");
            }

            try
            {
                Dictionary <string, string> parameters = new Dictionary <string, string>();
                parameters.Add("csdl", m_csdl);
                JSONdn res = m_user.callApi("compile", parameters);

                if (!res.has("hash"))
                {
                    throw new CompileFailedException("Compiled successfully but no hash in the response");
                }
                m_hash = res.getStringVal("hash");

                if (!res.has("created_at"))
                {
                    throw new CompileFailedException("Compiled successfully but no created_at in the response");
                }
                m_created_at = res.getDateTimeVal("created_at", "yyyy-MM-dd HH:mm:ss");

                if (!res.has("dpu"))
                {
                    throw new CompileFailedException("Compiled successfully but no DPU in the response");
                }
                m_total_dpu = res.getDoubleVal("dpu");
            }
            catch (ApiException e)
            {
                clearHash();
                if (e.Code == 400)
                {
                    throw new CompileFailedException(e.Message);
                }
                throw new CompileFailedException("Unexpected API response code: " + e.Code.ToString() + " " + e.Message);
            }
        }
예제 #14
0
 /// <summary>
 /// Constructor.
 /// </summary>
 /// <param name="status_code">The HTTP status code.</param>
 /// <param name="response_data">The content of the response - expected to be JSON.</param>
 /// <param name="rate_limit">The value of the x-rate-limit-limit header.</param>
 /// <param name="rate_limit_remaining">The value of the x-rate-limit-remaining header.</param>
 public ApiResponse(int status_code, string response_data, int rate_limit = -1, int rate_limit_remaining = -1)
 {
     try
     {
         m_response_code = status_code;
         if (response_data.Length == 0)
         {
             m_data = new JSONdn("{}");
         }
         else
         {
             m_data = new JSONdn(response_data);
         }
         m_rate_limit           = rate_limit;
         m_rate_limit_remaining = rate_limit_remaining;
     }
     catch (Exception e)
     {
         throw new ApiException("Request failed: " + e.Message, 503);
     }
 }
예제 #15
0
 /// <summary>
 /// Constructor.
 /// </summary>
 /// <param name="status_code">The HTTP status code.</param>
 /// <param name="response_data">The content of the response - expected to be JSON.</param>
 /// <param name="rate_limit">The value of the x-rate-limit-limit header.</param>
 /// <param name="rate_limit_remaining">The value of the x-rate-limit-remaining header.</param>
 public ApiResponse(int status_code, string response_data, int rate_limit = -1, int rate_limit_remaining = -1)
 {
     try
     {
         m_response_code = status_code;
         if (response_data.Length == 0)
         {
             m_data = new JSONdn("{}");
         }
         else
         {
             m_data = new JSONdn(response_data);
         }
         m_rate_limit = rate_limit;
         m_rate_limit_remaining = rate_limit_remaining;
     }
     catch (Exception e)
     {
         throw new ApiException("Request failed: " + e.Message, 503);
     }
 }
예제 #16
0
        /// <summary>
        /// Constructor.
        /// </summary>
        /// <param name="data">The JSON API response.</param>
        public Dpu(JSONdn data)
        {
            m_dpu = new Dictionary <string, DpuItem>();

            foreach (string key in data.getKeys("detail"))
            {
                DpuItem item = new DpuItem(data.getIntVal("detail." + key + ".count"), data.getDoubleVal("detail." + key + ".dpu"));

                if (data.has("detail." + key + ".targets"))
                {
                    JToken t = data.getJVal("detail." + key + ".targets");
                    foreach (string targetkey in data.getKeys("detail." + key + ".targets"))
                    {
                        JSONdn t2 = new JSONdn(t[targetkey]);
                        item.addTarget(targetkey, new DpuItem(t2.getIntVal("count"), t2.getDoubleVal("dpu")));
                    }
                }

                m_dpu.Add(key, item);
            }

            m_total = data.getDoubleVal("dpu");
        }
예제 #17
0
        /// <summary>
        /// Constructor.
        /// </summary>
        /// <param name="data">The JSON API response.</param>
        public Dpu(JSONdn data)
        {
            m_dpu = new Dictionary<string, DpuItem>();

            foreach (string key in data.getKeys("detail"))
            {
                DpuItem item = new DpuItem(data.getIntVal("detail." + key + ".count"), data.getDoubleVal("detail." + key + ".dpu"));

                if (data.has("detail." + key + ".targets"))
                {
                    JToken t = data.getJVal("detail." + key + ".targets");
                    foreach (string targetkey in data.getKeys("detail." + key + ".targets"))
                    {
                        JSONdn t2 = new JSONdn(t[targetkey]);
                        item.addTarget(targetkey, new DpuItem(t2.getIntVal("count"), t2.getDoubleVal("dpu")));
                    }
                }

                m_dpu.Add(key, item);
            }

            m_total = data.getDoubleVal("dpu");
        }
예제 #18
0
        /// <summary>
        /// Get buffered tweets.
        /// </summary>
        /// <param name="count">The number of tweets to get - see http://dev.datasift.com/ for the limit.</param>
        /// <param name="from_id">The ID of the latest interaction that you received.</param>
        /// <returns>An array of Interaction objects.</returns>
        public Interaction[] getBuffered(uint count = 0, ulong from_id = 0)
        {
            if (m_csdl.Length == 0)
            {
                throw new InvalidDataException("Cannot get buffered interactions for an empty definition");
            }

            Dictionary <string, string> parameters = new Dictionary <string, string>();

            parameters.Add("hash", getHash());
            if (count > 0)
            {
                parameters.Add("count", count.ToString());
            }
            if (from_id > 0)
            {
                parameters.Add("from_id", from_id.ToString());
            }

            JSONdn res = m_user.callApi("stream", parameters);

            if (!res.has("stream"))
            {
                throw new ApiException("No data in the response", -1);
            }

            List <Interaction> retval = new List <Interaction>();

            JToken[] children = res.getChildren("stream");
            for (int i = 0; i < children.Length; i++)
            {
                retval.Add(new Interaction(children[i]));
            }

            return(retval.ToArray());
        }
예제 #19
0
 /// <summary>
 /// Construct a PushSubscription object from a JSON object.
 /// </summary>
 /// <param name="user"></param>
 /// <param name="json"></param>
 public PushSubscription(User user, JSONdn json)
     : base(user)
 {
     init(json);
 }
예제 #20
0
        /// <summary>
        /// Initialise this object from teh data in a JSON object.
        /// </summary>
        /// <param name="data">The JSON object.</param>
        public void init(JSONdn data)
        {
            if (!data.has("id"))
            {
                throw new ApiException("No playback ID in the response");
            }
            if (m_playback_id.Length > 0 && m_playback_id.CompareTo(data.getStringVal("id")) != 0)
            {
                throw new ApiException("Incorrect playback ID in the response");
            }
            m_playback_id = data.getStringVal("id");

            if (!data.has("definition_id"))
            {
                throw new ApiException("No definition hash in the response");
            }
            m_stream_hash = data.getStringVal("definition_id");

            if (!data.has("name"))
            {
                throw new ApiException("No name in the response");
            }
            m_name = data.getStringVal("name");

            if (!data.has("start"))
            {
                throw new ApiException("No start timestamp in the response");
            }
            m_start_date = data.getDateTimeFromLongVal("start");

            if (!data.has("end"))
            {
                throw new ApiException("No end timestamp in the response");
            }
            m_end_date = data.getDateTimeFromLongVal("end");

            if (!data.has("created_at"))
            {
                throw new ApiException("No created at timestamp in the response");
            }
            m_created_at = data.getDateTimeFromLongVal("created_at");

            if (!data.has("status"))
            {
                throw new ApiException("No status in the response");
            }
            m_status = data.getStringVal("status");

            if (!data.has("progress"))
            {
                throw new ApiException("No progress in the response");
            }
            m_progress = data.getIntVal("progress");

            if (!data.has("sources"))
            {
                throw new ApiException("No sources in the response");
            }
            m_sources.Clear();
            foreach (JToken source in data.getJVal("sources"))
            {
                m_sources.Add(source.ToString());
            }

            if (!data.has("sample"))
            {
                throw new ApiException("No sample in the response");
            }
            m_sample = data.getDoubleVal("sample");

        }
예제 #21
0
 /// <summary>
 /// Constrcutor. Creates a Historic object from the data contained within a JSON object.
 /// </summary>
 /// <param name="user">The User creating the object.</param>
 /// <param name="data">The JSON data.</param>
 public Historic(User user, JSONdn data)
 {
     m_user = user;
     init(data);
 }
예제 #22
0
        /// <summary>
        /// Extract data from a JSON object.
        /// </summary>
        /// <param name="json">The JSON object.</param>
        protected void init(JSONdn json)
        {
            if (!json.has("id"))
            {
                throw new InvalidDataException("No ID found");
            }
            m_id = json.getStringVal("id");

            if (!json.has("name"))
            {
                throw new InvalidDataException("No name found");
            }
            m_name = json.getStringVal("name");

            if (!json.has("created_at"))
            {
                throw new InvalidDataException("No created at date found");
            }
            m_created_at = Utils.UnixTimestampToDateTime(json.getLongVal("created_at"));

            if (!json.has("status"))
            {
                throw new InvalidDataException("No status found");
            }
            m_status = json.getStringVal("status");

            if (!json.has("hash_type"))
            {
                throw new InvalidDataException("No hash_type found");
            }
            m_hash_type = json.getStringVal("hash_type");

            if (!json.has("hash"))
            {
                throw new InvalidDataException("No hash found");
            }
            m_hash = json.getStringVal("hash");

            if (!json.has("last_request"))
            {
                throw new InvalidDataException("No last request date found");
            }
            try
            {
                m_last_request = Utils.UnixTimestampToDateTime(json.getLongVal("last_request"));
            }
            catch (Exception)
            {
                m_last_request = DateTime.MinValue;
            }

            if (!json.has("last_success"))
            {
                throw new InvalidDataException("No last success date found");
            }
            try
            {
                m_last_success = Utils.UnixTimestampToDateTime(json.getLongVal("last_success"));
            }
            catch (Exception)
            {
                m_last_success = DateTime.MinValue;
            }

            if (!json.has("output_type"))
            {
                throw new InvalidDataException("No output type found");
            }
            m_output_type = json.getStringVal("output_type");

            if (!json.has("id"))
            {
                throw new InvalidDataException("No ID found");
            }
            m_output_params.Clear();
            m_output_params.parse(new JSONdn(json.getJVal("output_params")));
        }
예제 #23
0
        /// <summary>
        /// Called by the base class when it wants the consumer to start.
        /// </summary>
        /// <param name="auto_reconnect">True to reconnect should the connection get dropped.</param>
        protected override void onStart(bool auto_reconnect = true)
        {
            bool firstConnection = true;
            int  connectionDelay = 0;

            while ((firstConnection || auto_reconnect) && isRunning(true))
            {
                firstConnection = false;

                // Do we need to wait before trying to reconnect?
                if (connectionDelay > 0)
                {
                    Thread.Sleep(connectionDelay * 1000);
                }

                byte[]          buffer = new byte[65536];
                HttpWebResponse response;

                // TODO: check status in exception handler to treat timeouts differently if needed
                WebExceptionStatus status;

                try
                {
                    // Build the request.
                    HttpWebRequest request = (HttpWebRequest)WebRequest.Create(getUrl());
                    request.Timeout          = 65000;
                    request.ReadWriteTimeout = 65000;
                    request.Headers["Auth"]  = getAuthHeader();
                    request.UserAgent        = getUserAgent();

                    // Get the response.
                    response = (HttpWebResponse)request.GetResponse();
                }
                catch (WebException e)
                {
                    // An error occurred, but we handle the response with the same code below.
                    response = (HttpWebResponse)e.Response;
                    status   = e.Status;
                }
                catch (Exception e)
                {
                    // Have we exhausted the recommended retries?
                    if (connectionDelay < 16)
                    {
                        // No. Increment the retry delay by a second and tell the user about the problem.
                        connectionDelay += 1;
                        onWarning("Connection failed (" + e.Message + "), retrying in " + connectionDelay + " second" + (connectionDelay == 1 ? "" : "s"));
                        // Try again.
                        continue;
                    }

                    // No more retries. Tell the user and break out of the reconnect loop.
                    onWarning("Connection failed (" + e.Message + "), no more retries");
                    break;
                }

                int statusCode = (response == null ? -1 : (int)response.StatusCode);

                if (statusCode == 200)
                {
                    // Yay, connected. Reset the delay, tell the user we're connected and start reading the stream.
                    connectionDelay = 0;
                    onConnect();
                    readStream(new StreamReader(response.GetResponseStream()));
                }
                else if (statusCode == 404)
                {
                    // Unknown hash.
                    onError("Hash not found");
                    break;
                }
                else if (statusCode >= 400 && statusCode < 500 && statusCode != 420)
                {
                    // A 4xx (excluding 420) response should contain an error message in JSON.
                    StreamReader response_stream = new StreamReader(response.GetResponseStream());
                    string       json_data       = "init";
                    while (json_data.Length <= 4)
                    {
                        json_data = response_stream.ReadLine();
                    }
                    JSONdn json = new JSONdn(json_data);
                    if (json.has("message"))
                    {
                        onError(json.getStringVal("message"));
                    }
                    else
                    {
                        onError("Unhandled error code: " + statusCode.ToString() + " " + json_data);
                    }
                    // Break out of the reconnect loop.
                    break;
                }
                else
                {
                    // All other response codes follow the recommended retry pattern for server-side errors.
                    if (connectionDelay == 0)
                    {
                        connectionDelay = 10;
                    }
                    else if (connectionDelay < 320)
                    {
                        connectionDelay *= 2;
                    }
                    else
                    {
                        // We've hit the retry limit, tell the user and break out of the reconnect loop.
                        onError((statusCode == -1 ? "Connection failed" : "Received " + statusCode.ToString() + " response") + ", no more retries");
                        break;
                    }
                    // Tell the user that we're retrying.
                    onWarning((statusCode == -1 ? "Connection failed" : "Received " + statusCode.ToString() + " response") + ", retrying in " + connectionDelay + " seconds");
                }
            }

            // Tell the user we've disconnected.
            onDisconnect();
        }
        /// <summary>
        /// Called by the base class when it wants the consumer to start.
        /// </summary>
        /// <param name="auto_reconnect">True to reconnect should the connection get dropped.</param>
        protected override void onStart(bool auto_reconnect = true)
        {
            bool firstConnection = true;
            int connectionDelay = 0;
            while ((firstConnection || auto_reconnect) && isRunning(true))
            {
                firstConnection = false;

                // Do we need to wait before trying to reconnect?
                if (connectionDelay > 0)
                {
                    Thread.Sleep(connectionDelay * 1000);
                }

                byte[] buffer = new byte[65536];
                HttpWebResponse response;

                // TODO: check status in exception handler to treat timeouts differently if needed
                WebExceptionStatus status;

                try
                {
                    // Build the request.
                    HttpWebRequest request = (HttpWebRequest)WebRequest.Create(getUrl());
                    request.Timeout = 65000;
                    request.ReadWriteTimeout = 65000;
                    request.Headers["Auth"] = getAuthHeader();
                    request.UserAgent = getUserAgent();

                    // Get the response.
                    response = (HttpWebResponse)request.GetResponse();
                }
                catch (WebException e)
                {
                    // An error occurred, but we handle the response with the same code below.
                    response = (HttpWebResponse)e.Response;
                    status = e.Status;
                }
                catch (Exception e)
                {
                    // Have we exhausted the recommended retries?
                    if (connectionDelay < 16)
                    {
                        // No. Increment the retry delay by a second and tell the user about the problem.
                        connectionDelay += 1;
                        onWarning("Connection failed (" + e.Message + "), retrying in " + connectionDelay + " second" + (connectionDelay == 1 ? "" : "s"));
                        // Try again.
                        continue;
                    }

                    // No more retries. Tell the user and break out of the reconnect loop.
                    onWarning("Connection failed (" + e.Message + "), no more retries");
                    break;
                }

                int statusCode = (response == null ? -1 : (int)response.StatusCode);

                if (statusCode == 200)
                {
                    // Yay, connected. Reset the delay, tell the user we're connected and start reading the stream.
                    connectionDelay = 0;
                    onConnect();
                    readStream(new StreamReader(response.GetResponseStream()));
                }
                else if (statusCode == 404)
                {
                    // Unknown hash.
                    onError("Hash not found");
                    break;
                }
                else if (statusCode >= 400 && statusCode < 500 && statusCode != 420)
                {
                    // A 4xx (excluding 420) response should contain an error message in JSON.
                    StreamReader response_stream = new StreamReader(response.GetResponseStream());
                    string json_data = "init";
                    while (json_data.Length <= 4)
                    {
                        json_data = response_stream.ReadLine();
                    }
                    JSONdn json = new JSONdn(json_data);
                    if (json.has("message"))
                    {
                        onError(json.getStringVal("message"));
                    }
                    else
                    {
                        onError("Unhandled error code: " + statusCode.ToString() + " " + json_data);
                    }
                    // Break out of the reconnect loop.
                    break;
                }
                else
                {
                    // All other response codes follow the recommended retry pattern for server-side errors.
                    if (connectionDelay == 0)
                    {
                        connectionDelay = 10;
                    }
                    else if (connectionDelay < 320)
                    {
                        connectionDelay *= 2;
                    }
                    else
                    {
                        // We've hit the retry limit, tell the user and break out of the reconnect loop.
                        onError((statusCode == -1 ? "Connection failed" : "Received " + statusCode.ToString() + " response") + ", no more retries");
                        break;
                    }
                    // Tell the user that we're retrying.
                    onWarning((statusCode == -1 ? "Connection failed" : "Received " + statusCode.ToString() + " response") + ", retrying in " + connectionDelay + " seconds");
                }
            }

            // Tell the user we've disconnected.
            onDisconnect();
        }
예제 #25
0
 /// <summary>
 /// Parse the data in a JSON object and store it in this instance.
 /// </summary>
 /// <param name="json">The JSON object.</param>
 public void parse(JSONdn json)
 {
     setOutputParams(json, "");
 }
예제 #26
0
 /// <summary>
 /// Constructor from a JSON object.
 /// </summary>
 /// <param name="json">The JSON object.</param>
 public PushLogEntry(JSONdn json)
     : this(json.getStringVal("subscription_id"), Utils.UnixTimestampToDateTime(json.getLongVal("request_time")), json.getBoolVal("success"), json.has("message") ? json.getStringVal("message") : "")
 {
 }
예제 #27
0
 /// <summary>
 /// Constructor from a JSON object.
 /// </summary>
 /// <param name="json">The JSON object.</param>
 public PushLogEntry(JSONdn json)
     : this(json.getStringVal("subscription_id"), Utils.UnixTimestampToDateTime(json.getLongVal("request_time")), json.getBoolVal("success"), json.has("message") ? json.getStringVal("message") : "")
 {
 }
예제 #28
0
        /// <summary>
        /// Initialise this object from teh data in a JSON object.
        /// </summary>
        /// <param name="data">The JSON object.</param>
        public void init(JSONdn data)
        {
            if (!data.has("id"))
            {
                throw new ApiException("No playback ID in the response");
            }
            if (m_playback_id.Length > 0 && m_playback_id.CompareTo(data.getStringVal("id")) != 0)
            {
                throw new ApiException("Incorrect playback ID in the response");
            }
            m_playback_id = data.getStringVal("id");

            if (!data.has("definition_id"))
            {
                throw new ApiException("No definition hash in the response");
            }
            m_stream_hash = data.getStringVal("definition_id");

            if (!data.has("name"))
            {
                throw new ApiException("No name in the response");
            }
            m_name = data.getStringVal("name");

            if (!data.has("start"))
            {
                throw new ApiException("No start timestamp in the response");
            }
            m_start_date = data.getDateTimeFromLongVal("start");

            if (!data.has("end"))
            {
                throw new ApiException("No end timestamp in the response");
            }
            m_end_date = data.getDateTimeFromLongVal("end");

            if (!data.has("created_at"))
            {
                throw new ApiException("No created at timestamp in the response");
            }
            m_created_at = data.getDateTimeFromLongVal("created_at");

            if (!data.has("status"))
            {
                throw new ApiException("No status in the response");
            }
            m_status = data.getStringVal("status");

            if (!data.has("progress"))
            {
                throw new ApiException("No progress in the response");
            }
            m_progress = data.getIntVal("progress");

            if (!data.has("sources"))
            {
                throw new ApiException("No sources in the response");
            }
            m_sources.Clear();
            foreach (JToken source in data.getJVal("sources"))
            {
                m_sources.Add(source.ToString());
            }

            if (!data.has("sample"))
            {
                throw new ApiException("No sample in the response");
            }
            m_sample = data.getDoubleVal("sample");
        }
예제 #29
0
        /// <summary>
        /// Get a page of Push subscriptions in the given user's account,
        /// where each page contains up to per_page items. Results will be
        /// ordered according to the supplied ordering parameters.
        /// </summary>
        /// <param name="user">The user object making the request.</param>
        /// <param name="page">The page number to get.</param>
        /// <param name="per_page">The number of items per page.</param>
        /// <param name="order_by">The field by which to order the results.</param>
        /// <param name="order_dir">Ascending or descending.</param>
        /// <param name="include_finished">True to include subscriptions against finished Historics queries.</param>
        /// <param name="hash_type">Optional hash type to look for (hash is also required)</param>
        /// <param name="hash">Optional hash to look for (hash_type is also required)</param>
        /// <returns>A PushSubscriptionList object.</returns>
        public static PushSubscriptionList list(User user, int page, int per_page, string order_by = ORDERBY_CREATED_AT, string order_dir = ORDERDIR_ASC, bool include_finished = false, string hash_type = "", string hash = "")
        {
            Dictionary <string, string> parameters = new Dictionary <string, string>();

            if (hash_type.Length > 0)
            {
                if (hash_type != "hash" && hash_type != "playback_id")
                {
                    throw new InvalidDataException("Hash type is invalid");
                }
                if (hash.Length == 0)
                {
                    throw new InvalidDataException("Hash type given but the hash is empty");
                }
                parameters.Add(hash_type, hash);
            }

            if (page < 1)
            {
                throw new InvalidDataException("The specified page number is invalid");
            }

            if (per_page < 1)
            {
                throw new InvalidDataException("The specified per_page value is invalid");
            }

            if (order_by != ORDERBY_ID && order_by != ORDERBY_CREATED_AT)
            {
                throw new InvalidDataException("The specified order_by is not supported");
            }

            if (order_dir != ORDERDIR_ASC && order_dir != ORDERDIR_DESC)
            {
                throw new InvalidDataException("The specified order_dir is not supported");
            }

            parameters.Add("page", page.ToString());
            parameters.Add("per_page", per_page.ToString());
            parameters.Add("order_by", order_by);
            parameters.Add("order_dir", order_dir);

            if (include_finished)
            {
                parameters.Add("include_finished", "1");
            }

            JSONdn res = user.callApi("push/get", parameters);

            if (!res.has("count"))
            {
                throw new ApiException("No count in the response");
            }
            PushSubscriptionList retval = new PushSubscriptionList(res.getIntVal("count"));

            if (!res.has("subscriptions") && retval.TotalCount > 0)
            {
                throw new ApiException("No subscriptions in the response");
            }
            JToken[] children = res.getChildren("subscriptions");
            for (int i = 0; i < children.Length; i++)
            {
                retval.Add(new PushSubscription(user, new JSONdn(children[i])));
            }
            return(retval);
        }
예제 #30
0
 /// <summary>
 /// Construct a PushSubscription object from a JSON object.
 /// </summary>
 /// <param name="user"></param>
 /// <param name="json"></param>
 public PushSubscription(User user, JSONdn json)
     : base(user)
 {
     init(json);
 }
예제 #31
0
 /// <summary>
 /// Construct from data in a JSON object.
 /// </summary>
 /// <param name="json">The JSON object.</param>
 public PushOutputParams(JSONdn json)
     : base()
 {
     parse(json);
 }
예제 #32
0
 /// <summary>
 /// Constrcutor. Creates a Historic object from the data contained within a JSON object.
 /// </summary>
 /// <param name="user">The User creating the object.</param>
 /// <param name="data">The JSON data.</param>
 public Historic(User user, JSONdn data)
 {
     m_user = user;
     init(data);
 }
예제 #33
0
        /// <summary>
        /// Extract data from a JSON object.
        /// </summary>
        /// <param name="json">The JSON object.</param>
        protected void init(JSONdn json)
        {
            if (!json.has("id"))
            {
                throw new InvalidDataException("No ID found");
            }
            m_id = json.getStringVal("id");

            if (!json.has("name"))
            {
                throw new InvalidDataException("No name found");
            }
            m_name = json.getStringVal("name");

            if (!json.has("created_at"))
            {
                throw new InvalidDataException("No created at date found");
            }
            m_created_at = Utils.UnixTimestampToDateTime(json.getLongVal("created_at"));

            if (!json.has("status"))
            {
                throw new InvalidDataException("No status found");
            }
            m_status = json.getStringVal("status");

            if (!json.has("hash_type"))
            {
                throw new InvalidDataException("No hash_type found");
            }
            m_hash_type = json.getStringVal("hash_type");

            if (!json.has("hash"))
            {
                throw new InvalidDataException("No hash found");
            }
            m_hash = json.getStringVal("hash");

            if (!json.has("last_request"))
            {
                throw new InvalidDataException("No last request date found");
            }
            try
            {
                m_last_request = Utils.UnixTimestampToDateTime(json.getLongVal("last_request"));
            }
            catch (Exception)
            {
                m_last_request = DateTime.MinValue;
            }

            if (!json.has("last_success"))
            {
                throw new InvalidDataException("No last success date found");
            }
            try
            {
                m_last_success = Utils.UnixTimestampToDateTime(json.getLongVal("last_success"));
            }
            catch (Exception)
            {
                m_last_success = DateTime.MinValue;
            }

            if (!json.has("output_type"))
            {
                throw new InvalidDataException("No output type found");
            }
            m_output_type = json.getStringVal("output_type");

            if (!json.has("id"))
            {
                throw new InvalidDataException("No ID found");
            }
            m_output_params.Clear();
            m_output_params.parse(new JSONdn(json.getJVal("output_params")));
        }