private SlicedBlobWriter(Stream inputStream, FPTag tag, int threads) { int sliceSize = (int)(inputStream.Length / threads); int lastSlice = (int)(inputStream.Length - (sliceSize * (threads - 1))); int numBytes = sliceSize; int i; Thread[] writeThread = new Thread[threads]; //PartialBlobWriteStream[] slices = new PartialBlobWriteStream[threads]; for (i = 0; i < threads; i++) { if (i == (threads - 1)) { numBytes = lastSlice; } writeThread[i] = new PartialBlobWriteThread(tag, i, inputStream, (i * sliceSize), numBytes); writeThread[i].Start(); } for (i = 0; i < threads; i++) { writeThread[i].Join(); } FPLogger.ConsoleMessage("\nFinished"); }
private SlicedBlobReader(Stream outputStream, FPTag t, int threads) { int sliceSize = (int)(t.BlobSize / threads); int lastSlice = (int)(t.BlobSize - (sliceSize * (threads - 1))); int i, numBytes = sliceSize; Thread[] readThread = new Thread[threads]; for (i = 0; i < threads; i++) { if (i == (threads - 1)) { numBytes = lastSlice; } readThread[i] = new PartialBlobReadThread(t, outputStream, i * sliceSize, numBytes); readThread[i].Start(); } // Wait for all the threads to complete for (i = 0; i < threads; i++) { readThread[i].Join(); } FPLogger.ConsoleMessage("\n** finished"); }
static void Main(string[] args) { try { FPLogger.ConsoleMessage("\nCluster to connect to [" + clusterAddress + "]: "); String answer = Console.ReadLine(); if (answer != "") { clusterAddress = answer; } FPPool myPool = new FPPool(clusterAddress); FPLogger.ConsoleMessage("\nEnter the content address of the clip to manage: "); String clipID = Console.ReadLine(); FPClip clipRef = myPool.ClipOpen(clipID, FPMisc.OPEN_ASTREE); FPLogger.ConsoleMessage("\nThe following RetentionClasses are configured in the pool:\n"); foreach (FPRetentionClass rc in myPool.RetentionClasses) { FPLogger.ConsoleMessage(rc.ToString()); } FPLogger.ConsoleMessage("\nEnter RetentionClass or Period (in seconds) to be set: "); String newValue = Console.ReadLine(); if (myPool.RetentionClasses.ValidateClass(newValue)) { clipRef.RetentionClassName = newValue; } else { clipRef.RetentionPeriod = new TimeSpan(0, 0, int.Parse(newValue)); } clipID = clipRef.Write(); FPLogger.ConsoleMessage("\nThe new content address for the clip is " + clipID); FPLogger.ConsoleMessage("\nCluster time " + myPool.ClusterTime); FPLogger.ConsoleMessage("\nClip created " + clipRef.CreationDate); FPLogger.ConsoleMessage("\nThe retention period " + clipRef.RetentionPeriod); FPLogger.ConsoleMessage("\nThe retention will expire on " + clipRef.RetentionExpiry); clipRef.Close(); } catch (FPLibraryException e) { ErrorInfo err = e.errorInfo; FPLogger.ConsoleMessage("\nException thrown in FP Library: Error " + err.error + " " + err.message); } catch (Exception e) { FPLogger.ConsoleMessage("\nException thrown! " + e.Message); } }
// Standard ctor - Stream to be used to buffer, the Tag we read the data from public BlobReadStream(Stream s, FPTag t) : base(s, t) { myCallbacks = new Callbacks(holdingArea); fpStream = new FPGenericStream(holdingArea, FPStream.StreamDirection.OutputFromCentera, myCallbacks, IntPtr.Zero); fpStream.StreamLen = t.BlobSize; FPLogger.ConsoleMessage("\nStarting blob read thread"); blobThread = new Thread(delegate() { t.BlobRead(fpStream); }); blobThread.Name = "BlobReadThread"; blobThread.Start(); }
static void Main(string[] args) { try { FPLogger.ConsoleMessage("\nCluster to connect to [" + defaultCluster + "] : "); String clusterAddress = System.Console.ReadLine(); if ("" == clusterAddress) { clusterAddress = defaultCluster; } FPLogger.ConsoleMessage("\nEnter the name of the file containing the clip to be restored: "); String fileName = Console.ReadLine(); if (!fileName.EndsWith(".xml")) { FPLogger.ConsoleMessage("\nInvalid file name format - should be <clipID>.xml"); return; } String clipID = fileName.Substring(0, fileName.Length - 4); FPPool thePool = new FPPool(clusterAddress); FPStream fpStream = new FPStream(fileName, 16 * 1024); // Create the clip FPClip clipRef = thePool.ClipRawOpen(clipID, fpStream, FPMisc.OPTION_DEFAULT_OPTIONS); FPTag t = clipRef.NextTag; fpStream = new FPStream(clipID + ".Tag.0", 16 * 1024); t.BlobWrite(fpStream, FPMisc.OPTION_DEFAULT_OPTIONS); fpStream.Close(); t.Close(); t = clipRef.NextTag; fpStream = new FPStream(clipID + ".Tag.1", 16 * 1024); t.BlobWrite(fpStream, FPMisc.OPTION_DEFAULT_OPTIONS); fpStream.Close(); t.Close(); clipRef.Write(); clipRef.Close(); thePool.Close(); FPLogger.ConsoleMessage("\nClip and Blobs successfully restored to Cluster"); } catch (FPLibraryException e) { ErrorInfo err = e.errorInfo; FPLogger.ConsoleMessage("\nException thrown in FP Library: Error " + err.error + " " + err.message); } }
/* Remove this object from the list of open streams, wait for the content in the buffer * to finish being sent to the Cluster and then clean up. */ public override void Close() { FPLogger.ConsoleMessage("\nAll content buffered for thread " + this.GetHashCode() + " - flushing to cluster ...."); openStreams.Remove(this.GetHashCode()); if (blobThread.IsAlive) { blobThread.Join(); } holdingArea.Close(); fpStream.Close(); FPLogger.ConsoleMessage(" content flushed, thread " + this.GetHashCode() + " closed"); }
internal PartialBlobWriteThread(FPTag t, int sequenceNum, Stream s, int offset, int numBytes) : base(t, sequenceNum) { myWriteThread = new Thread(delegate() { BinaryReader myReader = new BinaryReader(new FPPartialInputStream(s, offset, numBytes)); BinaryWriter myWriter = new BinaryWriter(this); FPLogger.ConsoleMessage("\nStarted sliced write thread " + GetHashCode() + " at " + offset + " size " + numBytes); myWriter.Write(myReader.ReadBytes(numBytes)); myWriter.Flush(); Close(); }); }
// Standard ctor - Stream to be used to buffer, the Tag we write the data to public BlobWriteStream(Stream s, FPTag t) : base(s, t) { myCallbacks = new Callbacks(holdingArea); fpStream = new FPGenericStream(holdingArea, FPStream.StreamDirection.InputToCentera, myCallbacks, (IntPtr)this.GetHashCode()); blobThread = new Thread(delegate() { theTag.BlobWrite(fpStream); }); blobThread.Name = "BlobWriteThread"; FPLogger.ConsoleMessage("\nStarted stream " + this.GetHashCode() + " blob write thread " + blobThread.GetHashCode()); // We keep track of the current "open" streams being used in a hashtable // When user closes the stream we remove this to signal the callback that we are done writing openStreams.Add(this.GetHashCode(), blobThread.GetHashCode()); }
static void Main(string[] args) { try { FPLogger.ConsoleMessage("\nCluster to connect to [" + clusterAddress + "]: "); String answer = Console.ReadLine(); if (answer != "") { clusterAddress = answer; } FPPool myPool = new FPPool(clusterAddress); FPLogger.ConsoleMessage("\nEnter the content address of the clip to check for deletion eligibility: "); String clipID = Console.ReadLine(); FPClip clipRef = myPool.ClipOpen(clipID, FPMisc.OPEN_ASTREE); FPLogger.ConsoleMessage("\nCluster Time " + myPool.ClusterTime); FPLogger.ConsoleMessage("\nClip Creation Date " + clipRef.CreationDate + "\n"); FPLogger.ConsoleMessage("\nRetention information for Clip " + clipRef + "\n"); FPLogger.ConsoleMessage("\nRetention Class: " + clipRef.RetentionClassName); FPLogger.ConsoleMessage("\nRetention Period: " + clipRef.RetentionPeriod); FPLogger.ConsoleMessage("\nRetention Expiry: " + clipRef.RetentionExpiry); if (clipRef.RetentionExpiry < myPool.ClusterTime) { FPLogger.ConsoleMessage("\nThe clip is eligible for deletion."); } else { FPLogger.ConsoleMessage("\nThe clip is not eligible for deletion if Retention is enforced "); FPLogger.ConsoleMessage("\ni.e. Cluster is not a Basic Edition."); } clipRef.Close(); } catch (FPLibraryException e) { ErrorInfo err = e.errorInfo; FPLogger.ConsoleMessage("\nException thrown in FP Library: Error " + err.error + " " + err.message); } catch (Exception e) { FPLogger.ConsoleMessage("\nException thrown! " + e.Message); } }
internal PartialBlobReadThread(FPTag t, Stream s, int offset, int numBytes) : base(t, offset, numBytes) { myReadThread = new Thread(delegate() { BinaryReader myReader = new BinaryReader(this); BinaryWriter myWriter = new BinaryWriter(new FPPartialOutputStream(s, offset, numBytes)); FPLogger.ConsoleMessage("\nStarted sliced read thread " + GetHashCode() + " at " + offset + " size " + numBytes); // Wait until we have all the read content back in the buffer Join(); myWriter.Write(myReader.ReadBytes(numBytes)); Close(); }); }
// Standard ctor - as for BlobWriteStream but also specify the sequence number of the segment. public PartialBlobWriteStream(Stream s, FPTag t, int id) { // We cannot call the base constructor because we need use the additional id parameter // Even if we split out some of the functionality using a virtual init method with no // parameters, the sequenceId will not be initialized when the virtual function was called // by the base constructor. So we just have to duplicate the (small)initialization code. holdingArea = s; theTag = t; sequenceId = id; myCallbacks = new Callbacks(holdingArea); fpStream = new FPGenericStream(holdingArea, FPStream.StreamDirection.InputToCentera, myCallbacks, (IntPtr)this.GetHashCode()); FPLogger.ConsoleMessage("\n ** Partial blob write stream with sequence id = " + sequenceId); blobThread = new Thread(delegate() { theTag.BlobWritePartial(fpStream, sequenceId); }); blobThread.Name = "PartialBlobWriteThread"; }
static void Main(string[] args) { try { FPLogger.ConsoleMessage("\nCluster to connect to [" + defaultCluster + "] :"); String clusterAddress = System.Console.ReadLine(); if ("" == clusterAddress) { clusterAddress = defaultCluster; } FPLogger.ConsoleMessage("\nEnter the CA of the content (and ancestors) to delete : "); String clipID = System.Console.ReadLine(); FPPool thePool = new FPPool(clusterAddress); FPClip clipRef = thePool.ClipOpen(clipID, FPMisc.OPEN_FLAT); while (clipID.CompareTo("") != 0) { clipID = clipRef.GetAttribute("prev.clip"); FPLogger.ConsoleMessage("\n\tDeleting clip " + clipRef.ClipID); thePool.ClipAuditedDelete(clipRef.ClipID, "Cascaded Delete example", FPMisc.OPTION_DELETE_PRIVILEGED); clipRef.Close(); if (clipID.CompareTo("") != 0) { clipRef = thePool.ClipOpen(clipID, FPMisc.OPEN_FLAT); } } } catch (FPLibraryException e) { ErrorInfo err = e.errorInfo; FPLogger.ConsoleMessage("\nException thrown in FP Library: Error " + err.error + " " + err.message); } }
static void Main(string[] args) { IntPtr userData = new IntPtr(0); try { FPPool myPool = new FPPool("128.221.200.56?c:\\pea\\emea1.pea"); FPTag myTag; FPLogger log = new FPLogger(); log.LogPath = "C:\\GenStreamsLog.txt"; log.Start(); // First we'll write a test clip to the Centera string fileName = "c:\\discovery.xml"; FileInfo info = new FileInfo(fileName); FPClip myClip = myPool.ClipCreate("GenericStreamWrite_testClip"); myTag = myClip.AddTag("testTag"); FPGenericStream myStream = new FPGenericStream(File.OpenRead(fileName), userData); myStream.StreamLen = info.Length; myTag.BlobWrite(myStream); myTag.Close(); myStream.Close(); string clipID = myClip.Write(); myClip.Close(); FPLogger.ConsoleMessage("\nGenericStreamWrite test succeeded"); // Now we will test reading it back from the Centera { myClip = myPool.ClipOpen(clipID, FPMisc.OPEN_ASTREE); myTag = myClip.NextTag; myStream = new FPGenericStream(File.OpenWrite("c:\\test.out"), userData); myStream.StreamLen = myTag.BlobSize; myTag.BlobRead(myStream); myStream.Close(); FPLogger.ConsoleMessage("\nGenericStreamRead test succeeded for FileStream"); // We could use a Memory stream. As it is a bi-directional stream we // need to use a ctor that specifies the direction we want to use. // We'll set up the space first. MemoryStream s = new MemoryStream((int)myTag.BlobSize); myStream = new FPGenericStream(s, FPStream.StreamDirection.OutputFromCentera, userData); myStream.StreamLen = myTag.BlobSize; myTag.BlobRead(myStream, FPMisc.OPTION_DEFAULT_OPTIONS); myStream.Close(); FPLogger.ConsoleMessage("\nGenericStreamRead test succeeded for MemoryStream"); myTag.Close(); myClip.Close(); myPool.Close(); } catch (FPLibraryException e) { ErrorInfo err = e.errorInfo; FPLogger.ConsoleMessage("\nException thrown in FP Library: Error " + err.error + " " + err.message); } }
static FPInt myLoggingCB(String inMessage) { FPLogger.ConsoleMessage("\nThis is a test log >> " + inMessage + " ***"); return(0); }
static void Main(string[] args) { try { FPLogger.ConsoleMessage("\nCluster to connect to [" + defaultCluster + "] : "); String clusterAddress = System.Console.ReadLine(); if ("" == clusterAddress) { clusterAddress = defaultCluster; } UTF8Encoding converter2 = new UTF8Encoding(); // We are going to create a filename containing Chinese characters byte[] inputFileName = { 0xE6, 0x98, 0x8E, 0xE5, 0xA4, 0xA9, 0x2E, 0x74, 0x78, 0x74 }; string fileName = System.Text.Encoding.UTF8.GetString(inputFileName); File.WriteAllText(fileName, "Test file with wide characters in the file name\n"); FPLogger.ConsoleMessage("\nEnter the threshold to use for Embedded Blobs: "); String blobString = System.Console.ReadLine(); if (blobString == "") { blobString = "0"; } int blobThreshold = Int32.Parse(blobString); if (blobThreshold > 0) { FPLogger.ConsoleMessage("\nContent less than " + blobString + " bytes will be embedded in the CDF."); } else { FPLogger.ConsoleMessage("\nContent will never be embedded in the CDF."); } FPPool.EmbeddedBlobThreshold = blobThreshold; FPPool thePool = new FPPool(clusterAddress); // Create the clip FPClip clipRef = new FPClip(thePool, "UTF8_Example"); clipRef.SetAttribute("OriginalFilename", fileName); FPTag fileTag = clipRef.AddTag("WideFilenameTag"); fileTag.SetAttribute("filename", fileName); // Write the content of the file to the Centera FPStream streamRef = new FPWideFilenameStream(fileName); fileTag.BlobWrite(streamRef, FPMisc.OPTION_CLIENT_CALCID); streamRef.Close(); long blobSize = fileTag.BlobSize; if (blobThreshold > 0 && blobSize < blobThreshold) { FPLogger.ConsoleMessage("\nContent was embedded in the CDF as size " + blobSize + " is less than the threshold."); } fileTag.Close(); fileTag = clipRef.AddTag("TestTag"); fileTag.SetAttribute("fileCabinetGuid", "52d9cf57-7261-472a-b6d9-a8cdd30d1d27"); fileTag.SetAttribute("attr2", "a second attribute"); fileTag.SetAttribute("anotherattr", "the third attribute"); /* Or you can write from a memory buffer holding the data * The exampe uses a byte array containing a string */ UTF8Encoding converter = new UTF8Encoding(); byte[] rawBuffer = converter.GetBytes("This is a test string to illustrate how to interface to Centera using a buffer stream"); IntPtr source = Marshal.AllocHGlobal(rawBuffer.Length); Marshal.Copy(rawBuffer, 0, source, rawBuffer.Length); streamRef = new FPStream(source, rawBuffer.Length, FPStream.StreamDirection.InputToCentera); fileTag.BlobWrite(streamRef, FPMisc.OPTION_CLIENT_CALCID); streamRef.Close(); Marshal.FreeHGlobal(source); fileTag.Close(); fileTag = clipRef.AddTag("TestTag2"); fileTag.SetAttribute("filename", fileName); // We will only store a fragment of the file - "length" characters from position "offset" long offset = 5; long length = 30; streamRef = new FPWideFilenameStream(fileName, offset, length); fileTag.BlobWrite(streamRef, FPMisc.OPTION_CLIENT_CALCID); streamRef.Close(); // And this is how we read back at most "length" characters into a file at position "offset" // We can also specify that we don't want the created file to be larger than "maxFileSize" long maxFileSize = 20; streamRef = new FPWideFilenameStream(fileName + ".partial", FileMode.OpenOrCreate, offset, length, maxFileSize); fileTag.BlobRead(streamRef); streamRef.Close(); String clipID = clipRef.Write(); /* Write the Clip ID to the output file, "inputFileName.clipID" */ FPLogger.ConsoleMessage("\nThe C-Clip ID of the content is " + clipID); FileStream outFile = new FileStream(fileName + ".clipID", FileMode.Create); BinaryWriter outWriter = new BinaryWriter(outFile); outWriter.Write(clipID.ToString() + "\n"); outWriter.Close(); outFile.Close(); fileTag.Close(); clipRef.Close(); thePool.Close(); } catch (FPLibraryException e) { ErrorInfo err = e.errorInfo; FPLogger.ConsoleMessage("\nException thrown in FP Library: Error " + err.error + " " + err.message); } }
static void Main(string[] args) { try { FPLogger.ConsoleMessage("\nEnter cluster to connect to [" + clusterAddress + "]: "); String answer = Console.ReadLine(); if (answer != "") { clusterAddress = answer; } // The 3.2 SDK introduced dynamic logging features FPLogger log = new FPLogger(); log.LogPath = "c:\\mySDKLog.txt"; log.Start(); // New in 3.1 - applications can be registered FPPool.RegisterApplication("GetClusterInfo", "3.1"); using (FPPool myPool = new FPPool(clusterAddress)) { FPLogger.ConsoleMessage("\nCluster time is " + myPool.ClusterTime); // Display the pool information individually. We could just have used // // FPLogger.ConsoleMessage(myPool); // // as the pool object overrides toString() to print exactly this. FPLogger.ConsoleMessage( "\nPool Information" + "\n================" + "\nCluster ID: " + myPool.ClusterID + "\nCluster Name: " + myPool.ClusterName + "\nCentraStar software version: " + myPool.CentraStarVersion + "\nSDK version: " + FPPool.SDKVersion + "\nCluster Capacity (Bytes): " + myPool.Capacity + "\nCluster Free Space (Bytes): " + myPool.FreeSpace + "\nCluster Replica Address: " + myPool.ReplicaAddress); FPLogger.Stop(); FPLogger.RegisterCallback(myLoggingCB); log.Start(); FPLogger.Log(FPLogLevel.Error, "logged via our callback i.e. the Console"); FPLogger.Stop(); log.DisableCallback = FPBool.True; log.LogPath = "c:\\mySDKLog2.txt"; log.Start(); // Print out the information on the Governors if we have Advanced Retention if (myPool.HoldSupported) { FPLogger.ConsoleMessage( "\nVariable Retention Min " + myPool.VariableRetentionMin + "\nVariable Retention Max " + myPool.VariableRetentionMax + "\nFixed Retention Min " + myPool.FixedRetentionMin + "\nFixed Retention Max " + myPool.FixedRetentionMax + "\nDefault Retention " + myPool.RetentionDefault); } FPLogger.ConsoleMessage("\nRetention classes configured on the cluster:"); foreach (FPRetentionClass rc in myPool.RetentionClasses) { FPLogger.ConsoleMessage("\n\t" + rc); } // Check for a ProfileClip associated with the pool connection. try { String clipID = myPool.ProfileClip; FPLogger.ConsoleMessage("\nProfile Clip id " + clipID + " has metadata: "); using (FPClip clipRef = myPool.ClipOpen(clipID, FPMisc.OPEN_FLAT)) { foreach (FPAttribute attr in clipRef.Attributes) { FPLogger.ConsoleMessage("\n\t" + attr); } } } catch (FPLibraryException e) { ErrorInfo err = e.errorInfo; if (e.errorInfo.error == FPMisc.PROFILECLIPID_NOTFOUND_ERR) { FPLogger.ConsoleMessage("\nNo Profile Clip exists for this application.\n"); } else if (e.errorInfo.error == FPMisc.SERVER_ERR) { FPLogger.ConsoleMessage("\nThe Centera cluster you are attempting to access may not support profile clips.\n"); } else { throw e; } } log.Save("c:\\myLogState.out"); } } catch (FPLibraryException e) { ErrorInfo err = e.errorInfo; FPLogger.ConsoleMessage("\nException thrown in FP Library: " + e); } }
static void Main(string[] args) { try { FPLogger.ConsoleMessage("\nCluster to connect to [" + clusterAddress + "]: "); String answer = Console.ReadLine(); if (answer != "") { clusterAddress = answer; } FPPool myPool = new FPPool(clusterAddress); // Check that we can use LitigationHold // This property checks that it is supported on the cluster // and also that we have the capability granted to use it if (!myPool.HoldAllowed) { FPLogger.ConsoleMessage("\nRetention Hold is not supported"); } else { FPClip testClip = myPool.ClipCreate("testClip"); testClip.RetentionPeriod = new TimeSpan(0); string clipID = testClip.Write(); FPLogger.ConsoleMessage("\nCreated testClip " + clipID + "\n"); // We now have a test clip with no retention set, which would normally // mean that we can always delete it. // Let's place it under LitigationHold and see what happens. testClip.SetRetentionHold(true, "123456789"); clipID = testClip.Write(); testClip.Close(); // Multiple holds can be set on a clip so let's set another one just to // demonstrate how it is done. As the mutable metadata associated with // the clip is being modified you need to open it in TREE mode. testClip = myPool.ClipOpen(clipID, FPMisc.OPEN_ASTREE); testClip.SetRetentionHold(true, "ABCDEFG"); clipID = testClip.Write(); FPLogger.ConsoleMessage("\nClip " + clipID + " now under holds '123456789' and 'ABCDEFG'"); try { myPool.ClipDelete(clipID); } catch (FPLibraryException e) { FPLogger.ConsoleMessage("\nTrying to delete clip that is under Litigation Hold: "); FPLogger.ConsoleMessage("\n\t" + e.errorInfo.error + " " + e.errorInfo); } //Release one of the holds testClip.SetRetentionHold(false, "123456789"); clipID = testClip.Write(); FPLogger.ConsoleMessage("\nReleased '123456789' hold but 'ABCDEFG' still active"); try { myPool.ClipDelete(clipID); } catch (FPLibraryException e) { FPLogger.ConsoleMessage("\nTrying to delete clip that is under Litigation Hold: "); FPLogger.ConsoleMessage("\n\t" + e.errorInfo.error + " " + e.errorInfo); } // Release the other hold testClip.SetRetentionHold(false, "ABCDEFG"); clipID = testClip.Write(); FPLogger.ConsoleMessage("\nReleased 'ABCDEFG' hold"); testClip.Close(); myPool.ClipDelete(clipID); FPLogger.ConsoleMessage("\nAll holds released, delete was allowed on " + clipID); } myPool.Close(); } catch (FPLibraryException e) { ErrorInfo err = e.errorInfo; FPLogger.ConsoleMessage("\nException thrown in FP Library: " + e); } }
static void Main(string[] args) { try { string clipID; FPLogger.ConsoleMessage("\nEnter cluster to connect to [" + clusterAddress + "]: "); String answer = Console.ReadLine(); if (answer != "") { clusterAddress = answer; } using (FPPool myPool = new FPPool(clusterAddress)) { FPLogger.ConsoleMessage("\nEBR supported: " + myPool.EBRSupported); FPLogger.ConsoleMessage("\nHold Supported: " + myPool.HoldSupported); FPLogger.ConsoleMessage("\nHold allowed: " + myPool.HoldAllowed); FPLogger.ConsoleMessage("\nCluster time is " + myPool.ClusterTime); FPLogger.ConsoleMessage("\nMin retention periods: F:" + myPool.FixedRetentionMin + " V:" + myPool.VariableRetentionMin); // By utilising the "using" clause we can allow for the // dispose method to tidy the Pool connection // Create a test clip that we will use to show the way EBR works FPClip testClip = myPool.ClipCreate("testClip"); testClip.RetentionPeriod = new TimeSpan(0, 0, 1); // myPool.FixedRetentionMin; testClip.EBRPeriod = new TimeSpan(0, 0, 4); // myPool.VariableRetentionMin; clipID = testClip.Write(); FPLogger.ConsoleMessage("\nCreated test clip " + clipID); FPLogger.ConsoleMessage("\nCluster time is " + myPool.ClusterTime + "\nFixed Retention expires " + testClip.RetentionExpiry); //testClip.Close(); // Check that we cannot delete the clip because the EBR Event has not fired Thread.Sleep(1005); try { myPool.ClipDelete(clipID); } catch (FPLibraryException e) { // You cannot delete a clip with EBR enabled before the EBREventhappens! FPLogger.ConsoleMessage("\nTried to delete Clip before EBR Event occurred"); FPLogger.ConsoleMessage("\n\t" + e.errorInfo.error + " " + e.errorInfo); } // Here's how we fire the EBR Event on an existing clip that is effectively // in a "wait" state. As the mutable metadata associated with // the clip is being modified you need to open it in TREE mode. // We could equally have used TriggerEBRPeriod here to set a different // value to that which we originally used when putting the clip in the // "wait" state. //testClip = myPool.ClipOpen(clipID, FPMisc.OPEN_ASTREE); testClip.TriggerEBREvent(); testClip.Write(); FPLogger.ConsoleMessage("\nEBR event triggered: expires on " + testClip.EBRExpiry); // You cannot trigger the Event twice. If you do try and do this // then you get an nasty -10160 FP_EBR_OVERRIDE_ERR. This seems to invalidate // SDK reference objects so we can't demonstrate it! Thread.Sleep(2005); // At this point, the EBR Event has occurred but the period // has the not expired try { FPLogger.ConsoleMessage("\nCluster time is " + myPool.ClusterTime + "\nFixed Retention expires " + testClip.RetentionExpiry + "\nEBR expires " + testClip.EBRExpiry); myPool.ClipDelete(clipID); } catch (FPLibraryException e) { FPLogger.ConsoleMessage("\nTried to delete clip before EBR period expired"); FPLogger.ConsoleMessage("\n\t" + e.errorInfo.error + " " + e.errorInfo); } // Let's wait and try it again later Thread.Sleep(4005); FPLogger.ConsoleMessage("\nCluster time is " + myPool.ClusterTime + "\nFixed Retention expires " + testClip.RetentionExpiry + "\nEBR expires " + testClip.EBRExpiry); testClip.Close(); myPool.ClipDelete(clipID); FPLogger.ConsoleMessage("\nClip successfully deleted as EBR and fixed retention periods have expired"); } } catch (FPLibraryException e) { if (e.errorInfo.error.Equals(FPMisc.OUT_OF_BOUNDS_ERR)) { FPLogger.ConsoleMessage("\nThe cluster is configured with Mimumum Retention governors " + "whose values are too high to use this sample"); } ErrorInfo err = e.errorInfo; FPLogger.ConsoleMessage("\nException thrown in FP Library: " + e); } }
static void Main(string[] args) { //int exitCode = 0; try { FPLogger.ConsoleMessage("\nCluster to connect to [" + defaultCluster + "] :"); String clusterAddress = Console.ReadLine(); if ("" == clusterAddress) { clusterAddress = defaultCluster; } // New feature for 2.3 lazy pool open FPPool.OpenStrategy = FPMisc.LAZY_OPEN; // open cluster connection FPPool thePool = new FPPool(clusterAddress); // Check that query is supported on this connection; query can be // disabled by the Centera administrator if (!thePool.QueryAllowed) { FPLogger.ConsoleMessage("\nQuery is not supported for this pool connection."); return; } FPLogger.ConsoleMessage("\nQuery capability is enabled for this pool connection."); FPQuery myQuery = new FPQuery(thePool); //FPLogger.ConsoleMessage("\nEnter the start time (YYYY/MM/DD HH:MM:SS) : "); //myQuery.StartTime = FPMisc.GetDateTime(Console.ReadLine()); //FPLogger.ConsoleMessage("\nEnter the end time (YYYY/MM/DD HH:MM:SS) : "); //myQuery.EndTime = FPMisc.GetDateTime(Console.ReadLine()); myQuery.UnboundedStartTime = true; myQuery.UnboundedEndTime = true; // New for 2.3 two types to query for EXISTING or DELETED. We'll get both. myQuery.Type = FPMisc.QUERY_TYPE_EXISTING | FPMisc.QUERY_TYPE_DELETED; // We want to retrieve two fields during our query, select them beforehand. myQuery.SelectField("creation.date"); myQuery.SelectField("modification.date"); myQuery.Execute(); FPLogger.ConsoleMessage("\nCurrent Cluster Time is " + thePool.ClusterTime); // Retrieve Query results one at a time, checking for incomplete gaps. // Gaps can occur when data is temporarily unavailable on the Centera backend int count = 0; int queryStatus = 0; ArrayList resultsCollection = new ArrayList(); do { FPQueryResult queryResult = new FPQueryResult(); queryStatus = myQuery.FetchResult(ref queryResult, -1); switch (queryStatus) { case FPMisc.QUERY_RESULT_CODE_OK: FPLogger.ConsoleMessage("\n" + queryResult + " creation date: " + queryResult.GetField("creation.date") + " modification time on clip : " + queryResult.GetField("modification.date")); count++; // And store in a collection for later use resultsCollection.Add(queryResult); break; case FPMisc.QUERY_RESULT_CODE_INCOMPLETE: // One or more nodes on centera could not be queried. FPLogger.ConsoleMessage("\nReceived FP_QUERY_RESULT_CODE_INCOMPLETE error, invalid C-Clip, trying again."); break; case FPMisc.QUERY_RESULT_CODE_COMPLETE: // Indicate error should have been received after incomplete error FPLogger.ConsoleMessage("\nReceived FP_QUERY_RESULT_CODE_COMPLETE, there should have been a previous " + "FP_QUERY_RESULT_CODE_INCOMPLETE error reported."); break; case FPMisc.QUERY_RESULT_CODE_ERROR: //Server error FPLogger.ConsoleMessage("\nreceived FP_QUERY_RESULT_CODE_ERROR error, retrying again"); break; case FPMisc.QUERY_RESULT_CODE_PROGRESS: // Waiting on results coming back FPLogger.ConsoleMessage("\nreceived FP_QUERY_RESULT_CODE_PROGRESS, continuing."); break; case FPMisc.QUERY_RESULT_CODE_END: FPLogger.ConsoleMessage("\nEnd of query."); break; case FPMisc.QUERY_RESULT_CODE_ABORT: // server side issue or start time is later than server time. FPLogger.ConsoleMessage("\nQuery ended abnormally - FP_QUERY_RESULT_CODE_ABORT error."); break; default: // Unknown error, stop running query FPLogger.ConsoleMessage("\nAborting - received unkown error: " + queryStatus); break; } } while (queryStatus != FPMisc.QUERY_RESULT_CODE_END && queryStatus != FPMisc.QUERY_RESULT_CODE_ABORT); FPLogger.ConsoleMessage("\nTotal number of clips \t" + count); foreach (FPQueryResult q in resultsCollection) { FPLogger.ConsoleMessage("\n" + q.ToString()); } myQuery.Close(); // Always close the Pool connection when finished. Not a // good practice to open and close for each transaction. FPLogger.ConsoleMessage("\nClosing connection to Centera cluster (" + thePool.ClusterName + ")"); thePool.Close(); } catch (FPLibraryException e) { ErrorInfo err = e.errorInfo; FPLogger.ConsoleMessage("\nException thrown in FP Library: Error " + err.error + " " + err.message); } }
/* For Writing, the only non-default callback we need to implement is PrepareBuffer. * In this case, we will check the stream the user has supllied for more data that * must be written to the cluster. We'll also send zero length packets as keep alives. */ unsafe public override long PrepareBuffer(ref FPStreamInfo info) { long userStreamLen = 0, userStreamPos = 0; bool streamClosed = false; int dataSize = 0; byte[] localBuffer = new byte[bufferSize]; if (userStream == null || !userStream.CanRead) { return(0); } // We allocate the buffer if this is the first time through if (info.mBuffer == null) { // Create a heap memory buffer that the stream can use info.mBuffer = Marshal.AllocHGlobal(bufferSize).ToPointer(); } // Check for data every 10ms, send keepalives every 50 seconds for (int keepAlive = 0; keepAlive < 50 * 100; keepAlive++) { //FPLogger.ConsoleMessage("\nSeek to position " + info.mStreamPos + " "); lock (userStream) { userStream.Seek(info.mStreamPos, SeekOrigin.Begin); dataSize = userStream.Read(localBuffer, 0, bufferSize); //if (dataSize > 0) FPLogger.ConsoleMessage("\nCallback " + this.GetHashCode() + " Block of " + dataSize); userStreamLen = userStream.Length; userStreamPos = userStream.Position; // Check if user has signalled completion by removing this object from openStreams via Close streamClosed = !openStreams.Contains(((IntPtr)info.mUserData).GetHashCode()); } // If no data ready and stream not closed if (dataSize == 0 && !streamClosed) { Thread.Sleep(10); } else // We have real data ready to send { break; } } //if (dataSize != 0) FPLogger.ConsoleMessage("\n read and sent to SDK\tTotal ack'ed by SDK so far " + info.mStreamPos); //else FPLogger.ConsoleMessage("\n*** Keepalive sent *** Stream closed " + streamClosed + " Position " + userStreamPos + " Length " + userStreamLen); // Copy the localBuffer into the Heap Allocated mBuffer for transfer. Marshal.Copy(localBuffer, 0, (IntPtr)info.mBuffer, dataSize); // Update the stream position and the amount transferred info.mStreamPos += dataSize; info.mTransferLen = dataSize; if (userStreamLen == userStreamPos) { if (info.mStreamLen != -1 || streamClosed) { FPLogger.ConsoleMessage("\n\t *** Thread finished - streamLen: " + info.mStreamLen + " Closed by user: "******"\n" + this.GetHashCode() + " ******* Stream exhausted - closed: " + streamClosed + " StreamInfo.mStreamLen " + info.mStreamLen + " ***********"); } } else { //FPLogger.ConsoleMessage("\n\tNot exhausted " + userStreamPos + "/" + userStreamLen); } return(0); }
static void Main(string[] args) { IntPtr userData = new IntPtr(0); string clipID; BinaryReader myReader; BinaryWriter myWriter; BlobStream myStream; // For thsi test we are using a file as the input. *Any* stream could be used. // This would be your test PDF - in a file or memory stream. FileStream inputStream = new FileStream("e:\\testfile", FileMode.Open); FPLogger.ConsoleMessage("\nInput file length " + inputStream.Length); try { FPLogger log = new FPLogger(); log.LogPath = "C:\\GenStreamsLog.txt"; log.Start(); // Create a test clip demonstrating how to write a blob using a stream FPPool myPool = new FPPool("cse1.centera.lab.emc.com"); FPClip myClip = myPool.ClipCreate("GenericStreamWrite_testClip"); FPTag myTag = myClip.AddTag("testTag"); // Simple test of the BlobWriteStream - write contents of a local file // to Centera using a StreamReader and StreamWriter // We are using a temporary MemoryStream for our staging area myStream = new BlobWriteStream(myTag); myReader = new BinaryReader(inputStream); myWriter = new BinaryWriter(myStream); long writeTime1 = DateTime.Now.Ticks; myWriter.Write(myReader.ReadBytes((int)inputStream.Length)); myWriter.Flush(); ((BlobWriteStream)myStream).Close(); // If we don't do this it will stay open forever with keep alives! writeTime1 = DateTime.Now.Ticks - writeTime1; // If we assign values to existing FP objects we must explicitly close // them first to avoid potential "Object In Use" errors on future closure myTag.Close(); myTag = myClip.AddTag("SlicedBlob"); inputStream.Seek(0, SeekOrigin.Begin); long writeTime = DateTime.Now.Ticks; SlicedBlobWriter.Instance(inputStream, myTag, 8); writeTime = DateTime.Now.Ticks - writeTime; myTag.Close(); clipID = myClip.Write(); myClip.Close(); FPLogger.ConsoleMessage("\nGenericStreamWrite test succeeded " + clipID); // Now we will test reading it back from the Centera { myClip = myPool.ClipOpen(clipID, FPMisc.OPEN_ASTREE); myTag = myClip.NextTag; // Here we create a stream to read back the blob long readTime1 = DateTime.Now.Ticks; myStream = new BlobReadStream(myTag); // This is only to test to verify when we read the content back it is the same as the // input file i.e. we are going to store it on the file system and then use file system tools // to compare the files myReader = new BinaryReader(myStream); myWriter = new BinaryWriter(new FileStream("c:\\testfile2.out", FileMode.Create)); ((BlobReadStream)myStream).Join(); myWriter.Write(myReader.ReadBytes((int)myTag.BlobSize)); myWriter.Flush(); myStream.Close(); readTime1 = DateTime.Now.Ticks - readTime1; myTag.Close(); // This shows how to read content back using multiple threads myTag = myClip.NextTag; long readTime = DateTime.Now.Ticks; SlicedBlobReader.Instance(new FileStream("c:\\testfile2.out.sliced", FileMode.Create), myTag, 8); readTime = DateTime.Now.Ticks - readTime; myTag.Close(); myClip.Close(); myPool.Close(); FPLogger.ConsoleMessage("\nSerial tests - Write time: " + TimeSpan.FromTicks(writeTime1) + " Read time " + TimeSpan.FromTicks(readTime1)); FPLogger.ConsoleMessage("\nMulti threaded tests - Write time: " + TimeSpan.FromTicks(writeTime) + " Read time " + TimeSpan.FromTicks(readTime)); } catch (FPLibraryException e) { ErrorInfo err = e.errorInfo; FPLogger.ConsoleMessage("\nException thrown in FP Library: Error " + err.error + " " + err.message); } }
static void Main(string[] args) { try { FPLogger.ConsoleMessage("\nCluster to connect to [" + defaultCluster + "] :"); String clusterAddress = System.Console.ReadLine(); if ("" == clusterAddress) { clusterAddress = defaultCluster; } FPLogger.ConsoleMessage("\nEnter the CA of the content to be restored: "); String clipID = System.Console.ReadLine(); FPPool thePool = new FPPool(clusterAddress); FPClip clipRef = new FPClip(thePool, clipID, FPMisc.OPEN_ASTREE); FPLogger.ConsoleMessage("\nThe clip retention expires on " + clipRef.RetentionExpiry); // Iterate across the clip metadata foreach (FPAttribute attr in clipRef.Attributes) { FPLogger.ConsoleMessage(attr.ToString() + "\n"); } // Iterate across the Tag (and their Attr) collections foreach (FPTag tg in clipRef.Tags) { FPLogger.ConsoleMessage(tg.ToString() + "\n"); foreach (FPAttribute a in tg.Attributes) { FPLogger.ConsoleMessage(a.ToString() + "\n"); } } FPTag t = (FPTag)clipRef.Tags[0]; if (t.ToString() == "StoreContentObject") { String outfile = clipRef.ClipID + ".Tag." + 0; FPStream streamRef = new FPStream(outfile, "wb"); t.BlobRead(streamRef, FPMisc.OPTION_DEFAULT_OPTIONS); streamRef.Close(); FPLogger.ConsoleMessage("\nThe Blob has been stored into " + outfile); t.Close(); t = (FPTag)clipRef.Tags[1]; //Do the same for the second tag outfile = clipRef.ClipID + ".Tag." + 1; streamRef = new FPStream(outfile, "wb"); t.BlobRead(streamRef, FPMisc.OPTION_DEFAULT_OPTIONS); streamRef.Close(); FPLogger.ConsoleMessage("\nThe Blob has been stored into " + outfile); FPLogger.ConsoleMessage("\nThe CDF has been saved to " + clipRef.ClipID + ".xml"); streamRef = new FPStream(clipRef.ClipID + ".xml", "wb"); clipRef.RawRead(streamRef); // We could retrieve the blob into a buffer - we know we stored // a string in the StoreContent sample so let's get it back.. int blobSize = (int)t.BlobSize; UTF8Encoding converter = new UTF8Encoding(); byte[] buffer = new byte[blobSize]; IntPtr source = Marshal.AllocHGlobal(blobSize); streamRef = new FPStream(source, blobSize, FPStream.StreamDirection.OutputFromCentera); t.BlobRead(streamRef); Marshal.Copy(source, buffer, 0, blobSize); Marshal.FreeHGlobal(source); FPLogger.ConsoleMessage("\n" + converter.GetString(buffer)); streamRef.Close(); } else { FPLogger.ConsoleMessage("\nApplication Error: Not A C-Clip Created By StoreContent Example"); } } catch (FPLibraryException e) { ErrorInfo err = e.errorInfo; FPLogger.ConsoleMessage("\nException thrown in FP Library: Error " + err.error + " " + err.message); } }