void AddForDownload(ContentInfo ci) { Debug.WriteLine("CacheProxyPlugin::AddForDownload entered"); // update the database object[] obj = {ci.OriginUrl,"Downloading",null,null,null, null,null,null,null,null }; try { DataTable dt = DS.Tables["CachedItems"]; DataRow dr = dt.NewRow(); dr.ItemArray = obj; dt.Rows.Add(dr); } catch(Exception e) { Debug.WriteLine(e); } }
void IWMSCacheProxy.QueryCacheMissPolicy( string bstrOriginUrl , IWMSContext pUserContext , IWMSCommandContext pCommandContext , IWMSContext pPresentationContext , object pCachePluginContext , int lQueryType , IWMSCacheProxyCallback pCallback , object varContext ) { Debug.WriteLine("IWMSCacheProxy.QueryCacheMissPolicy entered"); int nOpenFlag = (int)WMS_CACHE_QUERY_TYPE_FLAGS.WMS_CACHE_QUERY_OPEN; int nGCI = lQueryType & ((int)WMS_CACHE_QUERY_TYPE_FLAGS.WMS_CACHE_QUERY_GET_CONTENT_INFO); int nReverseProxy = lQueryType & ((int)WMS_CACHE_QUERY_TYPE_FLAGS.WMS_CACHE_QUERY_REVERSE_PROXY); ContentInfo ci = new ContentInfo(bstrOriginUrl,null); if((nOpenFlag & lQueryType)!=0) // open query { if(nReverseProxy==0) //normal mode { // get content information ci.CacheProxyCallback = pCallback; ci.varContext = varContext; CacheProxyServer.GetContentInformation(bstrOriginUrl,pPresentationContext,null, null,this,ci); } else // it's a reverse proxy mode { // we simply look up our table to see if there is a mapping between the requested //Url and the RP url and return it // we distinguish the table entry if it's a reverse proxy or not by // checking the CDL data // we store a special string "ReverseProxy" there for the distinction // one can simply add another entry in the table to be safer // as there might be some CDL data written as "ReverseProxy" !! ContentInfo ciRP = null; GetContentInfo(bstrOriginUrl,out ciRP); WMS_CACHE_QUERY_MISS_RESPONSE Response = WMS_CACHE_QUERY_MISS_RESPONSE.WMS_CACHE_QUERY_MISS_PLAY_ON_DEMAND; if((ciRP.ContentType & 1 )!=0) // it's a brodcast content { Response = WMS_CACHE_QUERY_MISS_RESPONSE.WMS_CACHE_QUERY_MISS_PLAY_BROADCAST; } else { Response = WMS_CACHE_QUERY_MISS_RESPONSE.WMS_CACHE_QUERY_MISS_PLAY_ON_DEMAND; } IWMSContext ContentInfoContext = null; GetContentInfoContext(ci,out ContentInfoContext); pCallback.OnQueryCacheMissPolicy(0,Response,ciRP.CacheUrl,null,ContentInfoContext,varContext); } } if((nGCI & lQueryType)!=0) // GCI query from downstream server { WMS_CACHE_QUERY_MISS_RESPONSE Response = WMS_CACHE_QUERY_MISS_RESPONSE.WMS_CACHE_QUERY_MISS_FORWARD_REQUEST; IWMSContext ContentInfoContext = null; GetContentInfoContext(ci,out ContentInfoContext); pCallback.OnQueryCacheMissPolicy(0,Response,bstrOriginUrl,null,ContentInfoContext,varContext); } if((lQueryType & (int)WMS_CACHE_QUERY_TYPE_FLAGS.WMS_CACHE_QUERY_CACHE_EVENT)!=0) { pCallback.OnQueryCacheMissPolicy(0,WMS_CACHE_QUERY_MISS_RESPONSE.WMS_CACHE_QUERY_MISS_FORWARD_REQUEST, null,this,null,varContext); } return; }
void AddCDLToContext(IWMSContext pContentInfo,ContentInfo ci) { IWMSDataContainerVersion DCV = null; Type t = typeof(IWMSDataContainerVersion); Guid guid = t.GUID; object odcv = (object)DCV; /* pContentInfo.GetAndQueryIUnknownValue("WMS_CACHE_CONTENT_INFORMATION_DATA_CONTAINER_VERSION", 3,ref guid,out odcv, 0); */ pContentInfo.GetAndQueryIUnknownValue(WMSDefines.WMS_CACHE_CONTENT_INFORMATION_DATA_CONTAINER_VERSION, WMSDefines.WMS_CACHE_CONTENT_INFORMATION_DATA_CONTAINER_VERSION_ID,ref guid,out odcv, 0); DCV = (IWMSDataContainerVersion)odcv; if(ci.EntityTags!=null) { foreach(string str in ci.EntityTags) { DCV.SetEntityTag(str); } } }
public void GetContentInfoContext(ContentInfo ci, out IWMSContext Context) { Debug.WriteLine("CacheProxyPlugin::GetContentInfoContext entered"); System.IntPtr punk; Type t = typeof(IWMSContext); System.Guid guid = t.GUID; ClassObject.AllocIWMSContext(ref guid, WMS_CONTEXT_TYPE.WMS_CACHE_CONTENT_INFORMATION_CONTEXT_TYPE ,null, out punk); Context = (IWMSContext)Marshal.GetObjectForIUnknown(punk); t = typeof(IWMSDataContainerVersion); guid = t.GUID; ClassObject.CreateInstance(ref guid, out punk); IWMSDataContainerVersion DataContainer = (IWMSDataContainerVersion)Marshal.GetObjectForIUnknown(punk); Context.SetIUnknownValue(WMSDefines.WMS_CACHE_CONTENT_INFORMATION_DATA_CONTAINER_VERSION, WMSDefines.WMS_CACHE_CONTENT_INFORMATION_DATA_CONTAINER_VERSION_ID,DataContainer,0); Context.SetLongValue(WMSDefines.WMS_CACHE_CONTENT_INFORMATION_CONTENT_TYPE, WMSDefines.WMS_CACHE_CONTENT_INFORMATION_CONTENT_TYPE_ID,ci.ContentType,0); Context.SetLongValue(WMSDefines.WMS_CACHE_CONTENT_INFORMATION_EVENT_SUBSCRIPTIONS, WMSDefines.WMS_CACHE_CONTENT_INFORMATION_EVENT_SUBSCRIPTIONS_ID,ci.SubscriptionFlag,0); DataContainer.SetLastModifiedTime(ci.LastModified); DataContainer.SetExpirationTime(ci.ExpirationTime); DataContainer.SetCacheFlags(ci.CacheFlags); DataContainer.SetContentSize((int)ci.ContentSize,0); if(ci.EntityTags!=null) { foreach(string str in ci.EntityTags) { DataContainer.SetEntityTag(str); } } guid = typeof(IWMSContext).GUID; if((ci.ContentType & 2) == 0) // not a playlist { //create a CDL context and make it point to the INSSBuffer that we persisted ClassObject.AllocIWMSContext(ref guid, WMS_CONTEXT_TYPE.WMS_UNKNOWN_CONTEXT_TYPE ,null, out punk); IWMSContext CDLContext = (IWMSContext)Marshal.GetObjectForIUnknown(punk); INSSBufferImpl Buffer = new INSSBufferImpl(); Buffer.SetBuffer(ci.CDLData); INSSBuffer pBuffer = Buffer as INSSBuffer; CDLContext.SetIUnknownValue("CDL",0,(object)pBuffer,2); Context.SetIUnknownValue(WMSDefines.WMS_CACHE_CONTENT_INFORMATION_CONTENT_DESCRIPTION_LISTS, WMSDefines.WMS_CACHE_CONTENT_INFORMATION_CONTENT_DESCRIPTION_LISTS_ID,(object)CDLContext,0); } else { // create CDL for each file of the playlist // get the list of entries from PlaylistItem table corresponding to this Origin URL // for each of the entry // create CDL data and stuff it with the Context // query would be like select * from PlaylistEntries where OriginUrl=ci.OriginUrl DataTable dtPlaylist = DS.Tables["PlaylistEntries"]; string filter = string.Format("OriginUrl='{0}'",ci.OriginUrl); DataRow[] rows = dtPlaylist.Select(filter); ClassObject.AllocIWMSContext(ref guid, WMS_CONTEXT_TYPE.WMS_UNKNOWN_CONTEXT_TYPE ,null, out punk); IWMSContext CDLContext = (IWMSContext)Marshal.GetObjectForIUnknown(punk); foreach( DataRow row in rows) { INSSBufferImpl Buffer = new INSSBufferImpl(); Buffer.SetBuffer(Convert.ToString(row["CDLData"])); INSSBuffer pBuffer = Buffer as INSSBuffer; CDLContext.SetIUnknownValue(Convert.ToString(row["CacheID"]),0,(object)pBuffer,2); } Context.SetIUnknownValue(WMSDefines.WMS_CACHE_CONTENT_INFORMATION_CONTENT_DESCRIPTION_LISTS ,WMSDefines.WMS_CACHE_CONTENT_INFORMATION_CONTENT_DESCRIPTION_LISTS_ID ,(object)CDLContext,0); } }
void IWMSCacheProxy.AddCacheItem( string bstrOriginUrl , string bstrPrestuffUrl , int lExpiration , int lBandwidth , int lRemoteEventFlags , IWMSCacheProxyCallback pCallback , object varContext ) { Debug.WriteLine("IWMSCacheProxy.AddCacheItem entered"); //first remove the entry from database ContentInfo ci = new ContentInfo(bstrOriginUrl,bstrPrestuffUrl); ci.lExpiration = lExpiration; IWMSContext pPresentationContext=null; Type t = typeof(IWMSContext); Guid guid = t.GUID; System.IntPtr punk; ClassObject.AllocIWMSContext(ref guid,WMS_CONTEXT_TYPE.WMS_PRESENTATION_CONTEXT_TYPE,null, out punk); pPresentationContext = (IWMSContext)Marshal.GetObjectForIUnknown(punk); CacheProxyServer.GetContentInformation(bstrOriginUrl,pPresentationContext,null, null,this,ci); return; }
void SavePlaylist(ContentInfo ci) { Debug.WriteLine("CacheProxyPlugin::SavePlaylist entered"); //create a wsx file with filename same as first cache entry of the playlist file // create wsx with following format //<?wsx version="1.0"?> //<smil> // <media src="{filename1}" /> // <media src="{filename2}" /> //</smil> if(ci==null) { return; } if(ci.CDL.Count==0) { return; } string filename=string.Format("{0}.wsx",((PlaylistItem)ci.CDL[0]).CacheUrl); XmlDocument dom = new XmlDocument(); //create an empty playlist dom.LoadXml("<?wsx version=\"1.0\"?><smil/>"); //get the smil node XmlElement smilnode = dom.DocumentElement; int i=0; foreach(Object obj in ci.CDL) { ((PlaylistItem)obj).CacheID = i; string file = ((PlaylistItem)obj).CacheUrl; XmlElement elem = dom.CreateElement("media"); XmlAttribute attr = dom.CreateAttribute("src"); attr.Value = file; elem.Attributes.Append(attr); attr = dom.CreateAttribute("CacheID"); attr.Value = i.ToString(); elem.Attributes.Append(attr); smilnode.AppendChild(elem); i++; } // now save the file string filesaved = string.Format("{0}.wsx",((PlaylistItem)ci.CDL[0]).CacheUrl); dom.Save(filesaved); // set the cache URL to this file for cache hit ci.CacheUrl = filesaved; }
void UpdateTable(ContentInfo ci) { Debug.WriteLine("CacheProxyPlugin::UpdateTable entered"); string strTags=null; for(int i=0;(ci.EntityTags!=null)&&(i<ci.EntityTags.Count);i++) { strTags += ci.EntityTags[i]; strTags += "#"; } if(strTags==null) { strTags="Test"; } // update the database object[] obj = {ci.OriginUrl,ci.CacheUrl,ci.ContentSize,ci.ContentType,ci.CacheFlags, ci.ExpirationTime,ci.LastModified,ci.SubscriptionFlag ,strTags,ci.CDLData }; try { DataTable dt = DS.Tables["CachedItems"]; DataRow dr = dt.NewRow(); dr.ItemArray = obj; // we remove the previous entry which would most likely be due to the Add For Download call RemoveEntryFromDatabase(ci,false); dt.Rows.Add(dr); // if this is a playlist file, we also need to persist the CDL information for the playlist DataTable dt2 = DS.Tables["PlaylistEntries"]; foreach(PlaylistItem Item in ci.CDL) { //add a row for each CDL data DataRow dr2 = dt2.NewRow(); object[] objPlaylist = { ci.OriginUrl,Item.CacheID ,Item.CDLData,Item.CacheUrl }; dr2.ItemArray = objPlaylist; dt2.Rows.Add(dr2); } } catch(System.Exception e) { Debug.WriteLine(e); } }
void RemoveEntryFromDatabase(string OriginUrl,bool bDeleteFile) { ContentInfo ci = new ContentInfo(OriginUrl,null); RemoveEntryFromDatabase(ci,bDeleteFile); }
void RemoveEntryFromDatabase(ContentInfo ci,bool bDeleteFile) { Debug.WriteLine("CacheProxyPlugin::RemoveEntryFromDatabase entered"); try { DataTable dt = DS.Tables["CachedItems"]; string filexpr = string.Format("OriginUrl = '{0}'",ci.OriginUrl); DataRow[] drows = dt.Select(filexpr); if(drows.Length==0) { return; } // should ideally be only one row foreach(DataRow row in drows) { if(bDeleteFile) { string file = Convert.ToString(row["CacheUrl"]); File.Delete(file); } dt.Rows.Remove(row); } // now delete all playlist entries if available DataTable dtPlaylist = DS.Tables["PlaylistEntries"]; string filter = string.Format("OriginUrl='{0}'",ci.OriginUrl); DataRow[] rows = dtPlaylist.Select(filter); foreach(DataRow row in rows) { if(bDeleteFile) { string file = Convert.ToString(row["CacheUrl"]); File.Delete(file); } dt.Rows.Remove(row); } } catch(Exception e) { Debug.WriteLine(e); } }
// query the database to see if there is any row matching the OriginUrl bool IsDownloadInProgress(ContentInfo ci) { Debug.WriteLine("CacheProxyPlugin::IsDownloadInProgress entered"); try { DataTable dt = DS.Tables["CachedItems"]; string filexpr = string.Format("OriginUrl = '{0}'",ci.OriginUrl); DataRow[] drows = dt.Select(filexpr); return (drows.Length!=0); } catch(Exception e) { Debug.WriteLine(e); return false; } }
// selects the row for OriginUrl // creates a ContentInfo structure based on it public void GetContentInfo(string OriginUrl, out ContentInfo ci) { Debug.WriteLine("CacheProxyPlugin::GetContentInfo entered"); ci = new ContentInfo(OriginUrl,null); try { DataTable dt = DS.Tables["CachedItems"]; if(dt==null) { return; } string filexpr = string.Format("OriginUrl = '{0}'",OriginUrl); DataRow[] drows = dt.Select(filexpr); if(drows.Length==0) { return; } // FOR REVERSE PROXY DATA, WE HAVE TO HAVE THE TYPE OF CONTENT // STORED HERE AS WELL FOR THE APPROPRIATE RESPONSE ci.ContentType = Convert.ToInt32(drows[0]["ContentType"]); if((ci.ContentType & 1)!=0) { ci.CacheUrl = OriginUrl; } else { ci.CacheUrl = Convert.ToString(drows[0]["CacheUrl"]); } // if this string is ReverseProxy, then that means we are looking at a ReverseProxy // entry, so we should really return from here to force a cache miss ci.CDLData = Convert.ToString((drows[0]["CDLData"])); if(ci.CDLData=="ReverseProxy") { return; } // we simply assume there will be only one row returned as we enforce // primary key constraint ci.SubscriptionFlag = Convert.ToInt32((drows[0]["SubscriptionFlag"])); ci.LastModified = Convert.ToDateTime((drows[0]["LastModified"])); ci.ExpirationTime = Convert.ToDateTime(drows[0]["ExpirationTime"]); ci.ContentSize = Convert.ToInt64(drows[0]["ContentSize"]); // get the entity tags string strTags=Convert.ToString(drows[0]["EntityTags"]); int i=0, j=0; while(true) { int k = strTags.IndexOf('#',i); if(k<0) { break; } string str = strTags.Substring(i,k); ci.EntityTags.Insert(j,str); i=k+1; j++; } } catch(Exception e) { Debug.WriteLine(e); } }
void GetContentInfoFromContext(IWMSContext pContentInfo, ref ContentInfo ci) { Debug.WriteLine("CacheProxyPlugin::GetContentInfoFromContext entered"); int nFlag=0; int lCacheFlags=0; IWMSDataContainerVersion DCV = null; Type t = typeof(IWMSDataContainerVersion); Guid guid = t.GUID; object odcv = (object)DCV; pContentInfo.GetAndQueryIUnknownValue(WMSDefines.WMS_CACHE_CONTENT_INFORMATION_DATA_CONTAINER_VERSION, WMSDefines.WMS_CACHE_CONTENT_INFORMATION_DATA_CONTAINER_VERSION_ID,ref guid,out odcv, 0); DCV = (IWMSDataContainerVersion)odcv; DCV.GetCacheFlags(out lCacheFlags); nFlag = lCacheFlags & (int)WMS_DATA_CONTAINER_VERSION_CACHE_FLAGS.WMS_DATA_CONTAINER_VERSION_ALLOW_PROXY_CACHING; ci.CacheFlags = lCacheFlags; //content size int nLowVal=0, nHighVal=0; DCV.GetContentSize(out nLowVal,out nHighVal); ci.ContentSize = nLowVal; //content type int nContentType = 0; pContentInfo.GetLongValue(WMSDefines.WMS_CACHE_CONTENT_INFORMATION_CONTENT_TYPE, WMSDefines.WMS_CACHE_CONTENT_INFORMATION_CONTENT_TYPE_ID,out nContentType,0); ci.ContentType = nContentType; //expiration time DateTime time = new DateTime(0); //last modified DCV.GetLastModifiedTime(out time); ci.LastModified = time; //following call throws exception // when this is a bpp sourcing from encoder // so we don't call it based on the lastmodified time if(((ci.ContentType &1)!=0) && time.Year==1899) { } else { DCV.GetExpirationTime(out time); try { ci.ExpirationTime = time; } catch(Exception e) { //if this call fails, we just ignore Debug.WriteLine(e); } } //Subscription flags int nSubFlag=0; pContentInfo.GetLongValue(WMSDefines.WMS_CACHE_CONTENT_INFORMATION_EVENT_SUBSCRIPTIONS ,WMSDefines.WMS_CACHE_CONTENT_INFORMATION_EVENT_SUBSCRIPTIONS_ID,out nSubFlag,0); ci.SubscriptionFlag = nSubFlag; //clear previous entries ci.EntityTags.Clear(); int nTagCount = 0; DCV.GetEntityTagCount(out nTagCount); for(int i=0;i<nTagCount;i++) { string tag; DCV.GetEntityTag(i,out tag); ci.EntityTags.Insert(i,tag); } }