Nancy / TinyIoC "works on my machine" issue - windows-7

So I have this webapp that I've been developing over the last half year or so. Recently I discovered that NancyFx had been upgraded to 0.16 on nuget and went to upgrade (from 0.12). Things went fine, or rather seemed to go fine, on my machine.However in on the CI machine, things went spectacularly wrong. I get the following StackTrace:
2013-02-25 14:28:51:145 - OtherApp - ERROR METHOD - Nancy.TinyIoc.TinyIoCContainer.ConstructType
2013-02-25 14:28:51:145 - OtherApp - ERROR MESSAGE - Unable to resolve type: Nancy.Routing.DefaultRouteResolver
2013-02-25 14:28:51:145 - at Nancy.TinyIoc.TinyIoCContainer.ConstructType(Type requestedType, Type implementationType, ConstructorInfo constructor, NamedParameterOverloads parameters, ResolveOptions options)
at Nancy.TinyIoc.TinyIoCContainer.SingletonFactory.GetObject(Type requestedType, TinyIoCContainer container, NamedParameterOverloads parameters, ResolveOptions options)
at Nancy.TinyIoc.TinyIoCContainer.ResolveInternal(TypeRegistration registration, NamedParameterOverloads parameters, ResolveOptions options)
at System.Linq.Enumerable.WhereSelectEnumerableIterator`2.MoveNext()
at System.Linq.Enumerable.<CastIterator>d__b1`1.MoveNext()
at Nancy.Diagnostics.DiagnosticsModuleCatalog.ConfigureContainer(IModuleKeyGenerator moduleKeyGenerator, IEnumerable`1 providers, IRootPathProvider rootPathProvider, IRequestTracing requestTracing, NancyInternalConfiguration configuration, DiagnosticsConfiguration diagnosticsConfiguration)
at Nancy.Diagnostics.DiagnosticsModuleCatalog..ctor(IModuleKeyGenerator keyGenerator, IEnumerable`1 providers, IRootPathProvider rootPathProvider, IRequestTracing requestTracing, NancyInternalConfiguration configuration, DiagnosticsConfiguration diagnosticsConfiguration)
at Nancy.Diagnostics.DiagnosticsHook.Enable(DiagnosticsConfiguration diagnosticsConfiguration, IPipelines pipelines, IEnumerable`1 providers, IRootPathProvider rootPathProvider, IEnumerable`1 serializers, IRequestTracing requestTracing, NancyInternalConfiguration configuration, IModelBinderLocator modelBinderLocator, IEnumerable`1 responseProcessors, ICultureService cultureService)
at Nancy.Diagnostics.DefaultDiagnostics.Initialize(IPipelines pipelines)
at Nancy.Bootstrapper.NancyBootstrapperBase`1.Initialise()
at Nancy.Hosting.Self.NancyHost..ctor(INancyBootstrapper bootstrapper, HostConfiguration configuration, Uri[] baseUris)
at Core.Jobs.HealthMonitorJob.Execute(IJobExecutionContext context)
at Quartz.Core.JobRunShell.Run()
Now I've tracked the issue down to a particular module which takes a lot of parameters which TinyIoC needs to handle creation for, and if I disable that module, Nancy starts fine, but of course without the necessary functionality. On my machine it works flawlessly. The only discernible difference between the two is that my machine is running Windows 7 while the CI is running Windows Server 2008 R2 Enterprise SP1. Does anyone else have any experience with anything like this happening? It's driving me mad.

The exception should have a tree of InnerException exceptions that should point out the specific type that there is an issue with.

Related

Java Spring Boot: How to implement a JCo3 server with different message server

​Hi everyone one,
On my project, we are developing a spring boot application which is using JCo3.
It works fine for calling SAP from JAVA.
Now we are enhancing this application and we want to create a Jco server.
It will have to communicate with 2 different SAP system.
Each system have its own message server.
We customize each message server with several logon group according to our needs.
So we have created 2 classes to build up 2 Jco server one per system.
For server class, we hae base our development upon this blog:
https://blogs.sap.com/2017/08/25/sap-jco-server-example/
So we use a ServerDataProvider to use the parameters below
jco.server.connection_count=2
jco.server.progid=JCO_SERVER_SAP
jco.server.repository_map=SID(020)=S4
jco.server.mshost=myslanaddress.com
j
co.server.msserv=3601
jco.server.system_id=SID
We have 2 files to specify these parameters one per SAP system
The other system wil use a different progid.
When starting our application, everything goes well for the first bean instanciation.
As soon we arrived on the other, when trying to create the new Jco server
with for instance new progid JCO_SERVER_SAP and with new message server info)
with (server = JCoServerFactory.getServer(properties.getProperty(ServerDataProvider.JCO_PROGID));
The Constructor threw this exception; nested exception is com.sap.conn.jco.JCoRuntimeException: (136) JCO_ERROR_ILLEGAL_STATE: JCoServer JCO_SERVER_SAP is currently running. Current server state is STARTED
It is strange because in debug the progId is JCO_SERVER_CAR and not JCO_SERVER_SAP..
I foun this message (https://answers.sap.com/questions/12862862/how-to-implement-a-jco3-server-with-multiple-diffe.html) but I don’t know how to build such solution.
Do you have any clue ?
Thanks in advance for any help.
I tried to create and use
jco.server.repository_map
but it do not work.

SingleInstance() not working only on cluster

I am building a solution that implements a RESTful service for interacting with metadata related to federated identity.
I have a class that is registered with Autofac like this:
builder.RegisterType<ExternalIdpStore>()
.As<IExternalIdpStore>()
.As<IStartable>()
.SingleInstance();
I have a service class (FedApiExtIdpSvc) that implements a service that is a dependency of an ASP.NET controller class. That service class has this IExternalIdpStore as a dependency. When I build and run my application from Visual Studio (which is in Debug mode), I get one instance of ExternalIdpStore injected, it's constructor only executes once. When I initiate a controller action that ends up calling a particular method of my ExternalIdpStore class, it works just fine.
When my application is built via Azure DevOps (which is in Release mode), and deployed to a Kubernetes cluster running under Linux, I initially see one call to the ExternalIdpStore class' constructor right at application startup. When I initiate the same controller action as above, I see another call to the ExternalIdpStore's constructor, and when the same method of the class is called, it fails because the data store hasn't been initialized (it's initialized from calling the class' Start method that implementes IStartable).
I have added a field to the class that gets initialized in the constructor to a GUID so I can confirm that I have two different instances when on cluster. I log this value in the constructor, in the Startup code, and in the method eventually called when the controller action is initiated. Logging is confirming that when I run from Visual Studio under Windows, there is just one instance, and the same GUID is logged in all three places. When it runs on cluster under Linux, logging confirms that the first two log entries reference the same GUID, but the log entry from the method called when the controller action is initiated shows a different GUID, and that a key object reference needed to access the data store is null.
One of my colleagues thought that I might have more than one registration. So I removed the explicit registration I showed above. The dependency failed to resolve when tested.
I am at a loss as to what to try next, or how I might add some additional logging to diagnose what is going on.
So here's what was going on:
The reason for getting two sets of log entries was that we have two Kubernetes clusters sending log entries to Splunk. This service was deployed to both. The sets of log entries were coming from pods in different clusters.
My code was creating a Cosmos DB account client, and was not setting the connection mode, so it was defaulting to direct.
The log entries that showed successful execution were for the cluster running in Azure - in Azure Kubernetes Service (AKS). Accessing the Cosmos DB account from AKS in direct connection mode was succeeding.
The log entries that were failing were running in our on-prem Kubernetes cluster. Attempting to connect to the Cosmos DB account was failing because it's on our corporate network which has security restrictions that were preventing direct connection mode from working.
The exception thrown when attempting to connect from our on-prem cluster was essentially "lost" because it was from a process running on a background thread.
modifying the logic to add a try-catch around the attempt to connect, and passing the exception back to the caller allowed logging the exception related to direct connection mode failing.
Biggest lesson learned: When something "strange" or "odd" or "mysterious" or "unusual" is happening, start looking at your code from the perspective of where it could be throwing an exception that isn't caught - especially if you have background processes!

D365 (DevVM): BestPractise broken after updating to PU28

I have a Dynamics365 DevVM and updated it from 10PU26 to 10PU28 so that i develop on the same platform version as the systems i am developing for. After applying 10pu28 i started my VisualStudio, changed something and tried to save and compile but noticed that BP is broken and so i can't develop further. Visual Studio logs the following but i am not sure what i can do to fix this.
Build started 07/25/2019 06:27.
Build step: Metadata validation started.
Exception occured while performing operation Validate Metadata. Exception details: Path: []:System.ArgumentNullException: Value cannot be null.
Parameter name: source
at System.Linq.Enumerable.Contains[TSource](IEnumerable`1 source, TSource value, IEqualityComparer`1 comparer)
at Microsoft.Dynamics.Framework.Tools.ILGeneratorAgent.CompilationService.ValidateMetadata(String module, String metadataPath, String compilerMetadataPath, IEnumerable`1 referencedAssembliesFolders, IEnumerable`1 elements)
Build step: Metadata validation completed (10 ms).
Build step: X++ compilation, label generation and resource deployment started.
Build step: X++ compilation, label generation and resource deployment completed (670 ms).
Build step: Best practice check started.
Exception occured while performing operation Best practice checks. Exception details: BP Rule: [Exception occured while performing operation Best practice checks. Exception details]:System.ArgumentNullException: Value cannot be null.
Parameter name: referencedAssembliesFolders
at Microsoft.Dynamics.Framework.Tools.ILGeneratorAgent.MetadataProviderExtensions.AddReferenceProvider(IMetadataProvider provider, IEnumerable`1 referencedAssembliesFolders, IDiagnosticSink diagnostics, String modelModule, MetadataProviderFactory factory)
at Microsoft.Dynamics.Framework.Tools.ILGeneratorAgent.CompilationService.RunBestPracticeChecks(String module, String metadataPath, String compilerMetadataPath, IEnumerable`1 referencedAssembliesFolders, IEnumerable`1 elements, String modelName, Boolean isNormalizedCollectionNeeded)
Build step: Best practice check completed (9 ms).
Build completed (716 ms).
I attempted to disable running BP when building as a temporary workaround but that didn't work either. When BP is disabled i still can't compile. Here are the logs:
Build started 07/25/2019 06:40.
Build step: Metadata validation started.
Exception occured while performing operation Validate Metadata. Exception details: Path: []:System.ArgumentNullException: Value cannot be null.
Parameter name: source
at System.Linq.Enumerable.Contains[TSource](IEnumerable`1 source, TSource value, IEqualityComparer`1 comparer)
at Microsoft.Dynamics.Framework.Tools.ILGeneratorAgent.CompilationService.ValidateMetadata(String module, String metadataPath, String compilerMetadataPath, IEnumerable`1 referencedAssembliesFolders, IEnumerable`1 elements)
Build step: Metadata validation completed (8 ms).
Build step: X++ compilation, label generation and resource deployment started.
Build step: X++ compilation, label generation and resource deployment completed (381 ms).
Build completed (409 ms).
This issue can be caused if the update did not successfully update all components. This in turn can be caused if the default topology file is used for the update. The documentation by Microsoft is a bit confusing on this part of the update process (see issue 1137). Make sure to change the topology file according to section Collect topology configuration data in the documentation.
I also recommend to take a look at the d365fo.tools, which include the powershell function Invoke-D365SDPInstall that does a lot of the work in the updgrade process for you (including the update of the topology file).

Trying to convert existing WCF service to Web Role can't deploy without errors

I've converted existing WCF application to web role by adding it with "Add web role project in solution". Convert menu doesn't offer me option to convert. Our application requires .NET 4.6.1
Application runs fine on full emulator. However deployment fails with two scenarios:
osFamily attribute set to "5" in Serviceconfiguration(no .NET 4.6.1 installation script required):
19:15:16 - Instance 0 of role Severa.API is restarting
Details: [11/28T17:15Z]Failed to load role entrypoint. System.Reflection.ReflectionTypeLoadException: Unable to load one or more of the requested types. Retrieve the LoaderExceptions property for more information.
at System.Reflection.RuntimeModule.GetTypes(RuntimeModule module)
at System.Reflection.Assembly.GetTypes()
at Microsoft.WindowsAzure.ServiceRuntime.RoleEnvironment.GetRoleEntryPoint(Assembly entryPointAssembly)
--- End of inner exception stack trace ---
at Microsoft.WindowsAzure.ServiceRuntime.RoleEnvironment.GetRoleEntryPoint(Assembly entryPointAssembly)
at Microsoft.WindowsAzure.ServiceRuntime.RoleEnvironment.CreateRoleEntryPoint(RoleType roleTypeEnum)
at Microsoft.WindowsAzure.ServiceRuntime.RoleEnvironment.InitializeRoleInternal(RoleType roleTypeEnum) Last exit time: [2016/11/28, 17:15:06.916]. Last exit code: 0.
osFamily attribute set to "4" in Serviceconfiguration with .NET 4.6.1 installation:
The feature named NetFx451 that is required by the uploaded package is not available in the OS * chosen for the deployment.
I've used the .NET installation script in other projects with success. Also I have added WebRole.CS class to the project.
Is the issue here that the webrole is not WCF type meaning some setting etc. is missing?
We've managed to identify and fix the issue.
I've enabled Fusion logging and immediately got the missing information.
What would have saved a lot of time and point us to right direction would have been to understand that web role in CS consists of two processes: WAIISHost which runs RoleEntryPoint code in startup and good old W3WP for the Web application itself.
WAIIShost can't read Web.config and requires an empty Web.config file named after name of the project and redeployed successfully. I followed instructions from this article:
Post about the issue

SolrNet in CLR Stored Procedure

Has anyone ever used Solrnet inside CLR Stored Procedures? I would really appreciate pointers to some good tutorials.
One problem I'm facing is that I can't find a way to include the SolrNet library as a reference to the VS (2008) Database (SQL Server) Project.
Update:
So it seems that when you have an SQL Server Project, and you want to add a reference to a library, it has to first exist in SQL Server itself, which makes sense. This is done by creating an assembly in SQL Server from the DLL itself with the following SQL:
CREATE ASSEMBLY SolrNet FROM 'C:\CLR_SP\SolrNet.dll'
WITH PERMISSION_SET = UNSAFE
(Note that UNSAFE might have some repercussions on the security of the database however it is ok for me for now)
However the SolrNet.dll requires other library dependencies such as Castle.Windsor.dll (which in itself requires System.Core.dll) and Ninject.dll. I found the required version of Castle.Windsor.dll (which is 2.5.1.0) and also System.Core.Dll (which was in the .Net folder of Windows), however I cannot find the required version of Ninject.dll (which should be 2.1.0.76). I have attempted to create assembly version 2.2 but, as expected, it did not do the job.
I searched for it on different repositories but could not find it. Does anyone know where I could find this version of DLL?
Update 2:
So after lots of searching over the net, I still didn't manage to find Ninject.dll v2.1.0.76. My next attempt was to use the next version of SolrNet (which is v0.4.0.2002). This version required Ninject.dll v2.2 which I had already found. So my current status is registering all other libraries in SQL Server which are dependencies of SolrNet.dll. I will leave this open to document my process just in case there will be someone having the same problem.
Update 3:
I have managed to register all required libraries (some of which I got from SolrNet source on GitHub). So now, SolrNet is registered as an assembly in SQL Server, and therefore I can reference it from the .NET SQL Server Project (for creating the CLR Stored Procedure). So I have written a very simple CLR SP which connects to SOLR and retrieves a piece of data. Code below:
[Microsoft.SqlServer.Server.SqlProcedure]
public static void PrintToday()
{
SqlPipe p;
p = SqlContext.Pipe;
p.Send("Helloooo");
// Open Solr instance
SolrNet.Startup.Init<ActiveProduct>("http://192.168.2.190:8983/solr");
// Get instance of ActiveProduct
ISolrOperations<ActiveProduct> operations = ActiveProduct.GetActiveProductSolrOperations();
// Prepare QueryOptions. This will be passed as a parameter into the query() method.
SolrNet.Commands.Parameters.QueryOptions qo = new QueryOptions();
qo.Start = 0;
qo.Rows = 20;
// Query Solr
SolrQueryResults<ActiveProduct> results = operations.Query(new SolrQueryByField("SearchDescription", "pants"), qo);
// Read results
String s = "Docs found: " + results.NumFound;
p.Send(s);
}
My next problem is that when I deploy and run the CLR SP, an error is popping stating that Solr is already registered in container. The exact output that I see in SQL Server Management Studio is the following:
Helloooo
Msg 6522, Level 16, State 1, Procedure PrintToday, Line 0
A .NET Framework error occurred during execution of user defined routine or aggregate 'PrintToday':
System.ApplicationException: Key 'SolrNet.Impl.SolrConnection.CLRStoredProcedures2.ActiveProduct.SolrNet.Impl.SolrConnection' already registered in container
System.ApplicationException:
at SolrNet.Utils.Container.Register(String key, Type serviceType, Converter`2 factory)
at SolrNet.Utils.Container.Register[T](String key, Converter`2 factory)
at SolrNet.Startup.Init[T](ISolrConnection connection)
at SolrNet.Startup.Init[T](String serverURL)
at StoredProcedures.PrintToday()
PrintToday is the name of the CLR StoredProcedure
CLRStoredProcedures2 is the name of the .NET SQL Server project and default namespace in VS 2008
ActiveProduct is the name of the document in Solr, and the cs class with Solr annotations
As can be seen from the output, the first Pipe.send("Hellooo") is doing its job therefore the SP works fine until there.
When I searched for the above error, I found out that it will show when one tries to register Solr instance twice in the same application. Now I don't see where I am registering the instance twice. Am I missing something here?
Note that the above cs function worked fine when executed in a cs console application developed on my machine. Another detail which might be important is that the SOLR Server is being hosted on my machine which is on the same network of my SQL Server 2005.
Update 4:
For starters, the error I mentioned above (in update 3) does not fire when the SP is executed the 1st time just after deployment (let's assume that the 1st time works for now since I have another error which I'm currently working on fixing), the error fires when the SP is executed again afterwards. So it seems that whatever SolrNet.Startup.Init<ActiveProduct>("http://192.168.2.190:8983/solr"); is doing (creating some sort of session that has to do with a container I think) when called from the SP it is not releasing the "session" therefore the 2nd time (and each time afterwards) the SP is executed, the error is fired. Is there a way to sort of stop the session or releasing from the container. What I can do as a workaround is to try - catch the SolrNet.Startup.Init part, however this is not clean.
Thanks.
I'll try to summarize the steps / requirements with explanations whenever possible:
For some reason SQL Server seems to trigger the "hidden" dependencies of the merged SolrNet. Usually you can just use the merged SolrNet (which includes all integration modules) and if you ignore the integration classes the dependencies won't trigger. But in this case the unmerged SolrNet is necessary.
SolrNet does HTTP requests to the Solr server, so the DLL must be registered with UNSAFE permissions in SQL-CLR.
SolrNet Initialization (Startup.Init) must happen only once per application, but you don't have a 'root' context in SQL-CLR to place this initialization. A workaround is to use a singleton or a Lazy type. SQL-CLR doesn't run .NET 4 yet, but you can backport the Lazy type or use FSharp.Core.dll's implementation (I blogged about this some time ago)

Resources