How to use a singleton for storing the RedisConnection with Booksleeve? - booksleeve

I'm using Booksleeve 1.1.0.6 (the latest nuget package).
I want so use a single connection for my whole Web Application so I'm storing it in a singleton:
public static RedisConnection Conn = RedisConfig.GetUnsecuredConnection(waitForOpen: true);
The RedisConfig.GetUnsecuredConnection method is the same as used in BookSleeve tests.
When I try to do an operation I get an InvalidOperationException: The queue is closed exception:
[InvalidOperationException: The queue is closed]
BookSleeve.MessageQueue.Enqueue(RedisMessage item, Boolean highPri) in C:\Dev\BookSleeve\BookSleeve\MessageQueue.cs:73
BookSleeve.RedisConnectionBase.ExecuteVoid(RedisMessage message, Boolean queueJump) in C:\Dev\BookSleeve\BookSleeve\RedisConnectionBase.cs:794
ASP.welisten_booksleevetests_aspx.SaveDictionaryToRedis(Dictionary`2 dictionary) +173
ASP.welisten_booksleevetests_aspx.Page_Load(Object sender, EventArgs e) +67
System.Web.Util.CalliHelper.EventArgFunctionCaller(IntPtr fp, Object o, Object t, EventArgs e) +25
System.Web.UI.Control.LoadRecursive() +71
System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +3064
I tried this with the waitForOpen parameter set to true and false
Here is the code I'm trying to execute:
private void SaveDictionaryToRedis(Dictionary<string, string> dictionary)
{
using (Mp.Step("Saving Data to Redis"))
{
using (RedisConfig.Conn)
{
RedisConfig.Conn.Strings.Set(DB, dictionary);
}
}
}

Depending on what was copied, it could be that there is a missing call to:
theConnection.Open();
which will open the connection and perform various handshakes. Thin the case of a singleton, this would be reasonable to do during the initializer.
However! Perhaps the problem here is that your second example is simply wrong. If Conn is, as described, a singleton - then it does not belong to that code, and you should not be using using. That would mean it is only usable once, and all subsequent access would fail. Just access the connection; no using here.

Related

How to make a valid test using the mockito library?

The context
I have a simple method that I'm testing using the mockito library.
The problem
I have a error:
"[MockitoHint] ReceiveServiceTest.testGetFileDto (see javadoc for MockitoHint):
[MockitoHint] 1. Unused... -> at .ReceiveServiceTest.testGetFileDto(ReceiveServiceTest.java:46)
[MockitoHint] ...args ok? -> at ReceiveService.getFileDto(ReceiveService.java:28)
I dont understand way.
The code
#RunWith(MockitoJUnitRunner.class)
public class ReceiveServiceTest {
private List<File> filePaths = new ArrayList<>();
#InjectMocks
private ReceiveService receiveService;
#Mock
private FindFiles findfiles;
#Mock
private ReadByte readByte;
#Before
public void before() {
filePaths.add(new File("d://folder//test1_message_received"));
filePaths.add(new File("d://folder//test2_message_received"));
filePaths.add(new File("d://folder//test3_message_received"));
}
#Test
public void testGetFileDto() throws IOException {
// Given
byte[] resultByteArr = new byte[1028];
when(findfiles.getPathFiles()).thenReturn(filePaths);
when(readByte.readByteArrFromFile(new File("d://folder//test3_message_received"))).thenReturn(resultByteArr);
List<MessageDTO> result = receiveService.getFileDto();
//some assert
}
method
#Autowired
private FindFiles findFiles;
#Autowired
private ReadByte readByte;
public List<MessageDTO> getFileDto() throws IOException {
List<MessageDTO> fileDtos = new ArrayList<>();
for (File file : findFiles.getPathFiles()) {
fileDtos.add(new MessageDTO(Base64.getEncoder().encode(readByte.readByteArrFromFile(new File(file.getPath()))),
file.getName(), "zip", null));
}
return fileDtos;
}
I think mocks are not being initialized. Please initialize the mocks in the #Before method.
#Before
public void init() {
initMocks(this);
}
This should solve the problem I guess.
Here is solution for my problem. I added foreach loop. Now the mock works, but byte [] is different than what it should return.
// Given
byte[] mockByteArr = new byte [2048];
when(findfiles.getPathFiles()).thenReturn(filePaths);
for (File filePath : filePaths) {
when(readByte.readByteArrFromFile(new File(filePath.getPath()))).thenReturn(mockByteArr);
}
//When
List<MessageDTO> result = receiveService.getFileDto();
//Then
assertEquals(3, result.size());
assertEquals(mockByteArr, result.get(1).getContent());
Your problem is, that you create a new object in the following line:
when(readByte.readByteArrFromFile(new File("d://folder//test3_message_received"))).thenReturn(resultByteArr);
Mockito needs to know which real object is passed to the method so that it can return the appropriate thenReturn-value. So if you pass the actual reference into it, your code will work, but also only if you specify all the values which are listed. Otherwise you may get a NullPointerException.
By the way, calling new File(file.getPath()) seems redundant to me. You can just use file instead.
So with the following your code might work better:
when(readByte.readByteArrFromFile(filePaths.get(0)).thenReturn(resultByteArray);
but then you need to specify it for all entries.
Alternatively, use a Matcher instead:
when(readByte.readByteArrFromFile(ArgumentMatchers.any(File.class))).thenReturn(resultByteArr);
or specify the actual argument matching you require as matchers can be very powerful in that regard.
Previously the answer contained the following, which is still true, but not as concise as the answer above:
It's been a long time since I last used mocks (and I am even proud of it ;-)).
The message already states that one should consult the javadoc and there I found the following:
Those are hints - they not necessarily indicate real problems 100% of the time.
Nonetheless, I believe the problem is with the following statement:
when(readByte.readByteArrFromFile(new File("d://folder//test3_message_received"))).thenReturn(resultByteArr);
I think you need to specify a return for every entry in the filePaths or make the call more generic using Matchers.any() (or any other appropriate Matcher).

WP8 Custom Contact Store

I tried to create custom contact store at WP8. My code (from msdn):
async public void AddContact(string remoteId, string givenName, string familyName, string email, string codeName)
{
ContactStore store = await ContactStore.CreateOrOpenAsync();
}
private void Button_Click_1(object sender, RoutedEventArgs e)
{
AddContact("0", "Sample", "Sample", "sample#tut.by", "32");
}
When I click on button it occurs System.UnauthorizedAccessException: Access is denied. .
I don't understand, what happens?
Try add ID_CAP_CONTACTS capability into WMAppManifest.xml file in your project.
UnauthorizedAccessException is a common exception type which is thrown when a certain capability is missing from manifest. We can only wonder why MS guys forgot to add such an important tip into MSDN docs.

hibernate: com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException

When saving an object to database using hibernate, it sometimes fails because of certain fields in the object exceeding the maximum varchar length defined in the database.
Therefore I am using the following approach:
Attempt to save
If getting an DataException, I then truncate the fields in the object to the max length specified in the db definition, then try to save again.
However, in the second save after truncation, I'm getting the following exception:
hibernate: com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Cannot add or update a child row: a foreign key constraint fails
Here's the relevant code, do you notice anything wrong with it?
public static void saveLenientObject(Object obj){
try {
save2(rec);
} catch (org.hibernate.exception.DataException e) {
// TODO Auto-generated catch block
e.printStackTrace();
saveLenientObject(rec, e);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
private static void saveLenientObject(Object rec, DataException e) {
Util.truncateObject(rec);
System.out.println("after truncation ");
save2(rec);
}
public static void save2(Object obj) throws Exception{
try{
beginTransaction();
getSession().save(obj);
commitTransaction();
}catch(Exception e){
e.printStackTrace();
rollbackTransaction();
//closeSession();
throw e;
}finally{
closeSession();
}
}
All Hibernate exceptions (except for NonUniqueResultException) are irrecoverable. If you get an exception you should close the session and open another one for further operations.
See also:
13.2.3. Exception handling
The hibernate documentaiton is quite clear that once an exception is thrown the session will be left in an inconsistent state so is not safe to use for further operations. I suspect that what you're getting here is that the session is left half saving your first attempt so bad things happen.
Fundamentally you should not rely on database errors to check the length of your fields, instead you should pre-validate this in java code. If you know the lengths enough to truncate, then I suggest you simply call your trucate util every time.
Alternatively use Hibernate Validator to declaratively validate the objects before saving.

Operation not permitted on IsolatedStorageFileStream

I'm building this WP7 app that uses a video game API to get the statistics of someone's character (just to help learn silverlight). It grabs the players details from the web service and stores them on isolated storage on the phone to relieve strain from the server.
Originally I had a class which had both the cache writing and reading function, but now i've had to seperate it out into two seperate classes. The cache writing class doesn't matter at the moment, just the cache reading class.
On line 7, it throws an exception saying "Operation not permitted on IsolatedStorageFileStream.", but only during the second time it instantiates the class. I've done some checking with debug and it says the file definately exists, but it stops after the second using clause.
Can anyone help me with this please? I feel like I'm missing something really obvious.
public class CacheReader
{
public PlayerData GetPlayerData(string gamertagIn)
{
using (IsolatedStorageFile CachedReachData = IsolatedStorageFile.GetUserStoreForApplication())
{
using (IsolatedStorageFileStream stream = CachedReachData.OpenFile(gamertagIn + ".xml", FileMode.Open))
{
Debug.WriteLine("Data Retrieved from cache");
XmlSerializer serializer = new XmlSerializer(typeof(PlayerData));
PlayerData loadedPlayer = (PlayerData)serializer.Deserialize(stream);
return loadedPlayer;
}
}
}
}
[EDIT 1]
This is the stack trace i get:
at System.IO.IsolatedStorage.IsolatedStorageFileStream..ctor(String path, FileMode mode, FileAccess access, FileShare share, Int32 bufferSize, IsolatedStorageFile isf)
at System.IO.IsolatedStorage.IsolatedStorageFileStream..ctor(String path, FileMode mode, FileAccess access, IsolatedStorageFile isf)
at System.IO.IsolatedStorage.IsolatedStorageFile.OpenFile(String path, FileMode mode, FileAccess access)
at ReachPhoneApp.CacheReader.GetPlayerFromCache(String gamertagIn)
at ReachPhoneApp.Page2.GetPlayerData()
at ReachPhoneApp.Page2.cacheWriter_UpdateComplete()
at ReachPhoneApp.CacheWriter.WritePlayerDataToCache(String fileNameIn, Object objectIn)
at ReachPhoneApp.CacheWriter.client_GetGameHistoryCompleted(Object sender, GetGameHistoryCompletedEventArgs e)
at ReachPhoneApp.ReachAPI.ReachApiSoapClient.OnGetGameHistoryCompleted(Object state)
at System.Reflection.RuntimeMethodInfo.InternalInvoke(RuntimeMethodInfo rtmi, Object obj, BindingFlags invokeAttr, Binder binder, Object parameters, CultureInfo culture, Boolean isBinderDefault, Assembly caller, Boolean verifyAccess, StackCrawlMark& stackMark)
at System.Reflection.RuntimeMethodInfo.InternalInvoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture, StackCrawlMark& stackMark)
at System.Reflection.MethodBase.Invoke(Object obj, Object[] parameters)
at System.Delegate.DynamicInvokeOne(Object[] args)
at System.MulticastDelegate.DynamicInvokeImpl(Object[] args)
at System.Delegate.DynamicInvoke(Object[] args)
at System.Windows.Threading.DispatcherOperation.Invoke()
at System.Windows.Threading.Dispatcher.Dispatch(DispatcherPriority priority)
at System.Windows.Threading.Dispatcher.OnInvoke(Object context)
at System.Windows.Hosting.CallbackCookie.Invoke(Object[] args)
at System.Windows.Hosting.DelegateWrapper.InternalInvoke(Object[] args)
at System.Windows.RuntimeHost.ManagedHost.InvokeDelegate(IntPtr pHandle, Int32 nParamCount, ScriptParam[] pParams, ScriptParam& pResult)
Check that you don't somehow have two threads accessing IsolatedStorage at the same time (ie. in VS Debug.View.Threads and verify that at the time of the exception you don't have multiple paths through the same IsoStore code).
This happened in my WP7 code once every few days and was tricky to find, as it seemed to occur only when not connectected to the debugger.
You need to call:
stream.Close();
before
return loadedPlayer;
I think the problem is that you didn't specify that multiple threads could read/write at the same time by specifying a System.IO.FileShare.ReadWrite or whatever access you need as the last parameter of OpenFile.
See the discussion here on the Microsoft Forums.
I ran into this issue as well, but for completely different reasons as mentioned above. I hadn't created the directory that I was saving into.
private void SaveStringDataToStorage(string sDirectory, string sFileName, string sFileContent)
{
string sPath;
//
using (IsolatedStorageFile oFile = solatedStorageFile.GetUserStoreForApplication())
{
if (!oFile.DirectoryExists(sDirectory))
oFile.CreateDirectory(sDirectory);
//
sPath = Path.Combine(sDirectory, sFileName);
//
using (var oWriter = new StreamWriter(new IsolatedStorageFileStream(sPath, FileMode.Create, oFile)))
oWriter.Write(sFileContent);
}
}
Using this code will work if you had the same problem as me, plus it's pretty simple so you can adapt it to whatever you need. I was using this code before I had issues, but I'd forgotten the ! so the directory was never created haha. Just typical. Hope this helps :)
EDIT
Looking closer at the original question, it may be that the file didn't exist. I think it's always best to do IsolatedStorageFile.DirectoryExists() and IsolatedStorageFile.FileExists() before trying to access either location, whether you are reading or writing.
By default when you use IsolatedStorageFile.OpenFile("filename", FileMode.Open) your file gets locked by this thread and no other thread would be able to access this file until 1st thread close it. But if you like to share your file in multiple threads for read purpose only then I would recommend you to use following override
IsolatedStorageFile.OpenFile("filename", FileMode.Open, FileAccess.Read, FileShare.Read)
see details here

Convert.ChangeType() on EntityObject

I'm working on MySQL using .Net Connector 6.3.6 and created Entity models on VS 2010. I'm planning to write a generic method that would add an EntityObject to its corresponding table. Here is how it looks:
public void AddToTable(ObjectContext dataContext, string tableName, EntityObject tableObj)
{
try
{
Type type = dataContext.GetType();
string methodName = "AddTo" + tableName;
MethodInfo methodInfo = type.GetMethod(methodName);
PropertyInfo propInfo = dataContext.GetType().GetProperty(tableName);
Object[] parameters = new Object[] { Convert.ChangeType(tableObj, propInfo.PropertyType) };
methodInfo.Invoke(dataContext, parameters);
}
catch (Exception e)
{
edit://gonna handle it appropriately here!
}
}
ObjectContext will be the actual ObjectContext class.
But I'm getting exception saying "object must implement IConvertible" when I use Covert.ChangeType() on an EntityObject.
How to overcome this problem?
Edit: FYI, my main intention is to make write a method which is as generic as possible so that no casting to a particular table type would be required.
Thanks,
Alerter
You're reinventing the wheel.
public void AddToTable<TEntity>(ObjectContext dataContext, TEntity tableObj)
{
dataContext.CreateObjectSet<TEntity>().AddObject(tableObj);
}
And please don't eat exceptions.
Followed the following generalized repository pattern:
[link]http://www.codeproject.com/Articles/37155/Implementing-Repository-Pattern-With-Entity-Framew[link] It is very intuitive and fits my requirement :)