Has the StackExchange Redis connection config changed? - stackexchange.redis

I have been using the following to connect to Redis without issue until today, now I have to explicitly state provide a database parameter because of this:
ArgumentOutOfRangeException
Specified argument was out of the range of valid values. Parameter name: db at StackExchange.Redis.ConnectionMultiplexer.GetDatabase(Int32 db, Object asyncState) at MyServer.MyClass..cctor()
This is the config I have been using:
private static Lazy<ConnectionMultiplexer> MyConnection = new Lazy<ConnectionMultiplexer>(() =>
{
return ConnectionMultiplexer.Connect(MyRedisConnString);
});
public static ConnectionMultiplexer ConnGer
{
get
{
return MyConnection.Value;
}
}
and at class level:
private static readonly IDatabase RedisDb = RedisConfig.ConnGer.GetDatabase();
Providing the db parameter thus:
RedisConfig.ConnGer.GetDatabase(0);
fixed the error of course; more of a concern is whether there have been any seeming breaking changes recently as my class libraries are littered with Redis!
UPDATE
After thinking I had resolved the issue, for no apparent reason the ConnectionMultiplexer started failing again with the above config. I tried defaultDatabase=0 in the string and also tried as a Configuration.Option and got this error:
Exception type: ArgumentException
Exception message: Keyword 'defaultDatabase' is not supported
at StackExchange.Redis.ConfigurationOptions.OptionKeys.Unknown(String key)
at StackExchange.Redis.ConfigurationOptions.DoParse(String configuration, Boolean ignoreUnknown)
at StackExchange.Redis.ConnectionMultiplexer.CreateMultiplexer(Object configuration)
at StackExchange.Redis.ConnectionMultiplexer.ConnectImpl(Func 1 multiplexerFactory, TextWriter log)
at System.Lazy1.CreateValue()`
and with the ConfigOption mode:
Exception type: TypeInitializationException
Method not found: 'Void StackExchange.Redis.ConfigurationOptions.set_DefaultDatabase(System.Nullable 1<Int32>)'.
I also removed the System.Lazy part of the config too, same errors.
Putting the 0 value in as a GetDatabase() parameter stopped the error for now; the concern remains that this doesn't match the documented implementation.

You are probably specifying a wrong default database in the config?
Try adding defaultDatabase=0 to your connection string.
See the configuration options.

This is a bit of an old one, but I just experienced it out of the nowhere. The server rebooted from a windows update and then the errors began occurring whilst they'd been running fine for a very long time.
To fix it, I just updated to the latest version of the dll.

Related

Why does Sonarqube mark try as a critical issue?

I'm currently facing an issue with some SonarQube's analysis being performed over some Kotlin code I wrote.
I'm trying to implement a method that connects to the database and returns accordingly to the query's result. I'm not sure how related this can be, but I added the following maven dependencies to my project:
Quarkus
Arrow
Ktorm
The code is the following:
#ApplicationScoped
class Repository(private val database: Database) {
override fun get(name: String): Either<Error, Brand> =
try {
database.brands.find { it.name eq name }.rightIfNotNull {
MissingBrandError("Missing brand")
}
} catch (e: Exception) {
Either.Left(DatabaseError(e.message))
}
}
class Error(val message: String)
class MissingUserError(val message: String) : Error(message)
class DatabaseError(val message: String? = null) : Error(message ?: "Some database error")
NOTE: Database object is of type org.ktorm.database.Database and brands is of type org.ktorm.entity.EntitySequence
The code is working and I also wrote unit tests for it that pass and give enough coverage (accordingly to the code coverage analysis tool), but at some point in my pipeline SonarQube marks the try as a critical issue with the following message:
Possible null pointer dereference in (...)Repository(String) due to return value of called method
I checked it online and I could find some related questions, but none of the provided answers worked for me. Amongst the many attempts these are the ones I can remember I tried without any success:
Not inlining any code (pretty much using Java style code)
Extracting the query result to a variable
Check with if/else statements for nullability instead (both with inlined try and without)
I'd also like to highlight that all I can see on Sonar is the generated report and CLI for the running build. I don't have access to any of its configuration or intended to change them (unless of course it comes down to that). The line I mentioned seems to be the only one affected by this problem according to Sonar's report, that's why this is the solo class I provided.
I hope I provided enough info and that any of you can help me with this. Thanks in advance.

Serialize DataTable using protobuf-net-data gives Method Not Found error

I have been using the protobuf-net-data library (Richard Dingwall and Arjen Post) to serialize datatable. This was working fine and I was busy with something else. Recently I got back to this project, but I am getting error:
Method not found: 'Void ProtoBuf.ProtoWriter..ctor(System.IO.Stream, ProtoBuf.Meta.TypeModel, ProtoBuf.SerializationContext)'.
I took the source code and compiled as a separate library and tried to debug. Getting same error. In the DataSerializerEngine class, trying to enter the Writer.Serialize gives error.
public void Serialize(Stream stream, IDataReader reader, ProtoDataWriterOptions options)
{
if (stream == null)
{
throw new ArgumentNullException("stream");
}
if (reader == null)
{
throw new ArgumentNullException("reader");
}
Writer.Serialize(stream, reader, options);
}
I tried using older version of protobuf-net (2.3.2), but same issue. Not sure why I am getting this error. Much appreciate any help.
Latest update - After Marc's comments below: the latest version of protobuf-net-data was still using the ctor. I changed from using new to Create. With that, I am able to serialize. I took the protobuf-net-data src code and am making changes locally.
Now I am getting problem in DeSerialize (below 3065 was length of byte string sent after serialization of data table):
Sub-message not read entirely; expected -3, was 3065
at ProtoBuf.ProtoReader.State.ThrowProtoException(String message) in /_/src/protobuf-net.Core/ProtoReader.State.ReadMethods.cs:line 764
at ProtoBuf.ProtoReader.State.EndSubItem(SubItemToken token) in /_/src/protobuf-net.Core/ProtoReader.State.ReadMethods.cs:line 514
at ProtoBuf.ProtoReader.EndSubItem(SubItemToken token, ProtoReader reader) in /_/src/protobuf-net.Core/ProtoReader.cs:line 288
at ProtoBuf.Data.Internal.ProtoReaderContext.EndSubItem()
When I tried to use latest version of protobuf-net, the Create is deprecated as Marc mentioned. Some methods take writer as a parameter, so I am not sure how to change the code using State APIs.
regards

EF6.1 Upgrade Issues: To SQL Server CE file Location and [NotMapped] Properties

I really appreciate any insight anyone can provide.
I've come back to a project that was using the EF6.0 rc preview. After updating the projects EF to 6.1 and updating the SQL Server CE I have two problems.
[UPDATE]
Problems 1 & 2 solved Problem 3 is not.
PROBLEM 3 -
Now with the path set via a connection string as explained above, migrations called via the package manager are not working as its an invalid path. Any ideas anyone?
When I start up the debug process, I get problem 1 and the exceptions crash; but it does create a .sdf file although in the wrong location as explained in problem 2.
1. NOT MAPPED PROPERTY AND UNSUPPORTED BY LINQ ERROR
During the initial creation process I get an exception
List<Equipment> duplicateTags = db.EquipmentReg
.GroupBy(e => e.TagAndLocation)
.Where(g => g.Count() > 1)
.SelectMany(g => g).ToList<Equipment>();
The exception is related to the TagAndLocation. TagAndLocation is defined in the model by
/// <summary>
/// Creates concatenation object that will not be mapped in the database but will be in the
/// Object Relational Mapping (ORM) of the EF model.
/// </summary>
[NotMapped]
public string TagAndLocation { get { return Tag + " (" + Location.Name + ")"; } }
A first chance exception of type 'System.NotSupportedException' occurred in EntityFramework.dll
Additional information: The specified type member 'TagAndLocation' is
not supported in LINQ to Entities. Only initializers, entity members,
and entity navigation properties are supported.
Why is this happening now?
2. CONNECTION STRING NOT APPLYING LOCATION
My connection isn't applying the path properly anymore.
I have it being done by a DbConfiguration class which auto runs, I guess due to its inherited class type. As shown below
class HAIDbJob_EFConfiguration : DbConfiguration
{
public HAIDbJob_EFConfiguration()
{
SetProviderServices(SqlCeProviderServices.ProviderInvariantName, SqlCeProviderServices.Instance);
// Create the connection string programmatically - Setting the filename and path.
SetDefaultConnectionFactory(new System.Data.Entity.Infrastructure.SqlCeConnectionFactory(
"System.Data.SqlServerCe.4.0",
System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Databases"),
#"Data Source=" + System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Databases") +
#"\Hazardous_Area_Database_Job.sdf"));
}
}
Instead of creating a file in the runtime location ...\bin\Debug\Databases\Hazardous_Area_Database_Job.sdf, it creates it at
..\bin\Debug\HA_Inspector.HAI_Database.HAI_Job_EF_Model.Hazardous_Area_Database_Job.sdf
Which is the full namespace of the database model... I have tried a few solutions found for other people problems of a slightly different nature, but none of it works. Any ideas would be extremely appreciate.
1: The EF provider attempt to translate TagAndLocation to SQL and fails. You must use LINQ to Objects for this grouping.
2: Why not have a named connectionstring in your app.config, or pass it in the DbContext constructor.
SOLUTION 1
I did a string compare in the group by statement since location has a string member Location.Name.
SOLUTION 2
When I originally wrote this I wanted to dynamically name the database all the time and this is why I wrote the initialiser class.
To get around the problem, I just followed Erik's advice and put a XAML connection string in app.config using "Source=./Databases"..... to get the subfolder.

log4net on WebApi 2.1 using ExceptionLogger

How does one properly implement WebApi 2.1's ExceptionLogger so that log4net logs the correct values for method, location and line?
What I'm trying to achieve is a global exception logger to log all unhandled exceptions in a WebAPI 2.1 v5.1.2 app running .NET 4.5.1. I've read quite a few articles including the one linked below explaining how to implement the ExceptionLogger, and it works great, except that I can't get log4net to output the values I really want to record.
For example, if I log an exception from a controller, everything is correct. When I log from the ExceptionLogger, I'm getting the values from the Logger itself, and not the method that initiated the exception. I tried a few things listed in my code below, but they're not quite right. Here's what I get.
I know the text is small, but the table shows the different values log4net writes. The first log is from the controller, everything is great. The 2nd entry is from log.Logger.Log in the code snippet. The last entry is from log.Error in the snippet.
The final method in the snippet attempts to use a limiting type as I've read from other implementations of log4net wrappers, but it just throws an error, as described in the snippet.
So, HOW CAN I GET THE VALUES LIKE THE ONES I WOULD RECEIVE IF CALLING FROM A CONTROLLER, WHEN USING A GLOBAL ExceptionLogger ?
public class GlobalExceptionLogger: ExceptionLogger
{
//private static readonly ILog log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
public override void Log(ExceptionLoggerContext context)
{
StackTrace stackTrace = new StackTrace(context.Exception);
Type methodDeclaringType = stackTrace.GetFrame(2).GetMethod().DeclaringType;
ILog log = LogManager.GetLogger(methodDeclaringType);
string message = context.ExceptionContext.Exception.Message;
//this methods works but writes the location, method name and line from this method, not the caller
//location: System.Web.Http.ExceptionHandling.ExceptionLogger.LogAsync(:0)
//method: LogAsync
//line: 0
log.Logger.Log(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType, log4net.Core.Level.Error, message, context.ExceptionContext.Exception);
//this methods works but writes the location, method name and line from this method, not the caller
//location: Company.AppName.Api.GlobalExceptionLogger.Log(c:\TFS\AppName\AppName.Api\GlobalExceptionLogger.cs:38)
//method: Log
//line: 38
log.Error(message, context.ExceptionContext.Exception);
//this method throws an error in the log4net debug: log4net:ERROR loggingEvent.LocationInformation.StackFrames was null or empty.
log.Logger.Log(methodDeclaringType, log4net.Core.Level.Error, message, context.ExceptionContext.Exception);
}
}
http://weblogs.asp.net/jongalloway//looking-at-asp-net-mvc-5-1-and-web-api-2-1-part-4-web-api-help-pages-bson-and-global-error-handling
Your method of getting the stacktrace is not recommended, because the code will behave differently on debug/release or precessor architecture. The method stackTrace.GetFrame(2).GetMethod() will give you the method on the real stack, with taking into consideration the optimalizations of the runtime for processor architecture, linq rewrites etc.
An alternative method of getting the member name:
public static string LogError(Exception ex, [CallerMemberName] string callerName = "")
You should have a look at this question:
stackframe-behaving-differently-in-release-mode

how do I create a file upload in grails which works with oracle?

got the following problem:
I tried to create a simpel file upload functionality in grails. I just created a domain class with a
byte[] rawFile
as property. Grails did most of the rest for me. It worked fine for the standard hsqldb in the dev environment.
Then I deployed it to the server with an oracle db configured (thin driver). Everything but the file upload works fine with the oracle db. For the file upload I get a (as far as I can remember)
SQLException: ORA-01461: can bind a LONG value only for insert into a LONG
I tried several ways to fix it (including some columnmappings to blobs and using java.sql.blob instead of byte[]) but nothing really worked and I went in a direction where my code wouldn't be db independent anymore.
Google didn't really help me and my grails books don't help too.
Saving the file to the disk isn't a good solution im my opinion.
So here's my question:
how do I create a file upload in grails which works with oracle?
Update: got some additional infos. Managed to reproduce the problem with the XE-Edition of Oracle:
Hibernate creates a VARBINARY(255) column for the rawFile. So I tried to upload a 4 bytes file and it worked.
I then changed the type of the column manually to 'blob' and it worked with bigger files.
I then added
static mapping = {
columns {
rawFile type:'blob'
}
}
to my domain class and it stopped working:
ERROR errors.GrailsExceptionResolver - [B cannot be cast to java.sql.Blob
java.lang.ClassCastException: [B cannot be cast to java.sql.Blob
:-(
Instead of setting the type to blob try to increase the maxSize constraint:
static constraints = {
rawFile(maxSize: 20 * 1024 * 1024) // 20 MBs
// ...
}
If you want to use a Blob field in Oracle then set your domain property to byte[] and set the type to org.hibernate.type.MaterializedBlobType. The MaterializedBlobType handles conversion back and forth between Oracle (presumably other databases, but I've only done this on Oracle) and byte[].
byte[] blobFile
static mapping = {
blobFile type: org.hibernate.type.MaterializedBlobType
}
I'm not sure what you are doing in your controller, try doing it manually to see what happens:
request.fileMap.each { name, file ->
if (!file.empty) {
model.rawFile = file.bytes
}
}
model.save()
Try setting the sqlType.
Using a domain field with type byte[] with sqlType set to "blob" in the mapping block works for me using Grails 2.3.1 and Oracle 11g. Grails handles the type conversion automatically.
class Image {
byte[] image
static mapping = {
image(sqlType: "blob")
}
}

Resources