I am currently able to connect to a IBM MQ using IBMXMSDotnetClient by specifying the connection properties directly in the c# code like below.
XMSFactoryFactory factory = XMSFactoryFactory.GetInstance(XMSC.CT_WMQ);
IConnectionFactory connFactory = factory.CreateConnectionFactory();
connFactory.SetStringProperty(XMSC.WMQ_HOST_NAME, "xxx");
connFactory.SetIntProperty(XMSC.WMQ_PORT, 1414);
connFactory.SetStringProperty(XMSC.WMQ_CHANNEL, "xxx");
connFactory.SetIntProperty(XMSC.WMQ_CONNECTION_MODE, XMSC.WMQ_CM_CLIENT);
connFactory.SetStringProperty(XMSC.WMQ_QUEUE_MANAGER, "xxx");
But in Java, it seems that it can be done by JNDI bindings file.
From what I can see, it looks like that JNDI is something like TNS file (which specifies the connection details such host, port, SID, etc.) used by the client to connect to server in Oracle. Is my understanding correct?
If it is the case, is it possible to connect to the IBM MQ by JNDI bindings files using IBMXMSDotnetClient? All examples I can find is to set the connection properties (connFactory.SetXXXProperty) directly.
I have this snippet to create initial context and use it to create connection factory and sessions. Hope it will get you started.
InitialContext ic = null;
IConnectionFactory confac = null;
IConnection conn = null;
ISession sess = null;
IMessageConsumer cons = null;
IDestination dest = null;
try
{
System.Collections.Hashtable env = new System.Collections.Hashtable();
// Set the URL or PATH where the bindings file is located
env[XMSC.IC_URL] = "file://c:/mqbindings/.bindings";
// Initialize the context
ic = new InitialContext(env);
// Lookup for the connection factory name
confac = (IConnectionFactory)ic.Lookup("myconfactoryname");
// Create connection using the details from connection factory
conn = (IConnection)confac.CreateConnection();
// Create an auto ack session
sess = conn.CreateSession(false, AcknowledgeMode.AutoAcknowledge);
// Lookup for the destination
dest = (IDestination)ic.Lookup("myqueue");
// ... rest of the code - create consumer or producer
}
catch (XMSException xmsE)
{
// Handle exception
}
Related
In package MainPackage.dtsx I have 10 connected Connection managers in that package. 9 are "OLE DB\Oracle Provider for OLE DB" and 1 is "OLE DB\SQL Server Native Client 11.0". In project, I have one C# Script, that create package NewPackageThatNotWillSaved.dtsx with dataFlow that take rows from table A, add column with datetime, copy to table B and count copied rows. And execute package NewPackageThatNotWillSaved.dtsx. In order for the package to be executed, I add 2 connection managers to the package(Source and Destination are connection managers from package MainPackage.dtsx by Dts.Connections) by connection string.
Here the problem. Connection string from SQL Server work fine, but connection string from Oracle throw error DTS_E_CAN NOT ACQUIRE CONNECTION FROM CONNECTION MANAGER every time, when I srcDesignTimeComponent.AcquireConnections(null); (IDTSDesigntimeComponent100 srcDesignTimeComponent). I can`t use password for oracle connection string because 9 different oracle servers have 9 different passwords and password in connection sting sounds bad.
Some C# code that I use:
// Create package
Application app = new Application();
Package package = new Package();
// Get connection manager
ConnectionManager sourceConnection = null;
ConnectionManager destinationConnection = null;
foreach (ConnectionManager conn in Dts.Connections)
{
if (conn.Name.Equals(sourceConnectionName))
{
sourceConnection = conn;
}
if (conn.Name.Equals(destinationConnectionName))
{
destinationConnection = conn;
}
}
// Create dataFlow
Executable e = package.Executables.Add("STOCK:PipelineTask");
TaskHost thMainPipe = e as TaskHost;
MainPipe dataFlowTask = thMainPipe.InnerObject as MainPipe;
thMainPipe.Name = dataFlowName;
// Add connection manager for OLE DB Source
ConnectionManager sourceConn = package.Connections.Add("OLEDB");
sourceConn.Name = sourceConnection.Name + "_src";
sourceConn.ConnectionString = sourceConnection.ConnectionString;
// Add OLE DB Source
IDTSComponentMetaData100 source = dataFlowTask.ComponentMetaDataCollection.New();
source.ComponentClassID = "DTSAdapter.OleDbSource";
source.ValidateExternalMetadata = true;
IDTSDesigntimeComponent100 srcDesignTimeComponent = source.Instantiate();
srcDesignTimeComponent.ProvideComponentProperties();
// Set connetcion manager for OLE DB Source
source.RuntimeConnectionCollection[0].ConnectionManager = DtsConvert.GetExtendedInterface(sourceConn); ;
source.RuntimeConnectionCollection[0].ConnectionManagerID = sourceConn.ID;
// Setting propreties
srcDesignTimeComponent.SetComponentProperty("AccessMode", 2);
srcDesignTimeComponent.SetComponentProperty("SqlCommand", sqlQuery);
srcDesignTimeComponent.AcquireConnections(null); // Throw ERROR -1071611876
srcDesignTimeComponent.ReinitializeMetaData();
srcDesignTimeComponent.ReleaseConnections();
Edit 1: Maybe exist better way to AcquireConnections from exist connected connection manager from MainPackage.dtsx?
I am currently able to connect to the IBM MQ server based on jndi binding file with the following c# code
InitialContext ic = null;
IConnectionFactory confac = null;
IConnection conn = null;
ISession sess = null;
IMessageConsumer cons = null;
IDestination dest = null;
try
{
System.Collections.Hashtable env = new System.Collections.Hashtable();
// Set the URL or PATH where the bindings file is located
env[XMSC.IC_URL] = "file://c:/mqbindings/.bindings";
// Initialize the context
ic = new InitialContext(env);
// Lookup for the connection factory name
confac = (IConnectionFactory)ic.Lookup("myconfactoryname");
// Create connection using the details from connection factory
conn = (IConnection)confac.CreateConnection();
// Create an auto ack session
sess = conn.CreateSession(false, AcknowledgeMode.AutoAcknowledge);
// Lookup for the destination
dest = (IDestination)ic.Lookup("myqueue");
// ... rest of the code - create consumer or producer
}
catch (XMSException xmsE)
{
// Handle exception
}
However, when the SSL enabled in the IBM MQ Server, it fails to connect. Tried setting different properties (like setting XMSC.IC_PROVIDER_URL to the keystores directory/.jp12 file), but does not seem working.
Exception I got:
IBM.XMS.XMSException: 'CWSMQ0006E: An exception was received during the call to the method ConnectionFactory.CreateConnection: CompCode: 2, Reason: 2059.
I also cannot find any sample code on the official site on how this is working.
Any idea or sample code on this (not necessary in great details, at least, give me some ideas how what I need to set)?
I am trying to connect to an AMQP version server running AMQP 1.0 (Not RabbitMQ).
I am trying to use the package Apache.NMS.AMQP with the example code below
Uri connecturi = new Uri($"amqp://my-server-host:5672");
IConnectionFactory factory = new NMSConnectionFactory(connecturi);
using (IConnection connection = factory.CreateConnection("UserName", "Password}"))
{
using (ISession session = connection.CreateSession())
{
IDestination destination = session.GetQueue("QueueToListenFor");
using (IMessageConsumer consumer = session.CreateConsumer(destination))
{
connection.Start();
consumer.Listener += new MessageListener(OnMessage);
}
}
}
The issue I am having is that the application hangs on this line
ISession session = connection.CreateSession()
Any ideas or recommendations on why this is happening or for another .NET library (With working examples) highly appreciated!
Thanks
I am Trying to Connect MY Sap B1 HANA on C# Web Based Application using DI API but my connection is giving me error. Here is Error Screenshot Failed to Connect SLD,make Sure Your SLD Server is Available and Connected. Any Relevant Help would be Appreciated.
try{
oCompany.CompanyDB = "***";
oCompany.Server = "***";
oCompany.LicenseServer = "***:30015";
oCompany.SLDServer = "***:40000"; //
oCompany.DbUserName = "****"; //
oCompany.DbPassword = "****"; //
oCompany.UserName = "****"; //
oCompany.Password = "****"; //
oCompany.DbServerType = SAPbobsCOM.BoDataServerTypes.dst_HANADB;
oCompany.UseTrusted = false;
int res = oCompany.Connect();
string errMsg = oCompany.GetLastErrorDescription();
int ErrNo = oCompany.GetLastErrorCode();
if (ErrNo != 0)
{
value1 = errMsg;
return errMsg;
}
else {
value1 = "Succes Connection To Sap B1 Hana";
return value1;
}
You must include the port number in the server. Usually, the port number is 30015.
you can also use below mention code.
SAPbobsCOM.Company oCompany = new SAPbobsCOM.Company();
oCompany = (SAPbobsCOM.Company)Application.SBO_Application.Company.GetDICompany();
The following connection code should get you a step further:
// The actual database host
// With HANA the single-tenancy port 30015 needs to be provided together with the host (not so with MSSQL)
// When using HANA multi-tenancy the instance is prefixed and the port changed: INSTANCE#DB-HOST:30013
// OR the correct instance port needs to be provided, eg. DB-HOST:30017
sboCompany.Server = "DB-HOST:30015";
// The company database/schema name
// With MSSQL the instance is provided here like: INSTANCE\DB_NAME
sboCompany.CompanyDB = "SCHEMA";
// SLDServer is the new LicenseServer, don't forget the port with HANA
// Be aware: use either hostname or IP of SLD everywhere
sboCompany.SLDServer = "SLD-HOST:40000";
// Hell knows why the version needs to be provided for MSSQL...
sboCompany.DbServerType = SAPbobsCOM.BoDataServerTypes.dst_HANADB;
// DB credentials when using MSSQL authentication or HANA
sboCompany.UseTrusted = false;
sboCompany.DbUserName = "SYSTEM";
sboCompany.DbPassword = "password";
// SBO credentials
sboCompany.UserName = "manager";
sboCompany.Password = "password";
The next problems might be missing or wrong HANA drivers... your journey just began ;-)
I am writing an SQL Server application in C# built in Visual Studio. It is a Windows Forms Application. The program will be installed on the network where users will run it.
The problem I am struggling with is how to manage the configuration file. It has the server username and password there for all to see. I tried Click Once and an encryption scheme but they both required the programs to run on the computer the program was running from. It failed when I tried to run it from a workstation. This is different from How do I avoid having the database password stored in plaintext in sourcecode? because all of those solutions either suggested using integrated security or machine based encryption. Neither of those options would work for me.
Any help would be deeply appreciated.
Don't store passwords in plain text. Period. Full stop.
You should take a cue from SQL Server. Yes, you can store usernames in passwords in plain text in a web/app.config. But for Production servers you never should. Instead for Production deployments you should have a config that uses Integrated Security. That allows for elevated access by accessing credentials which are handled securely by Windows rather than insecurely in a config file.
Similarly, you should use something like WindowsIdentity, or OpenId. Then you can pass around auth tokens in your code rather than storing credentials in plain text.
This is why software developers created multi-tier designs that include middleware services like web services. Web services can be hosted in IIS and the windows account and password can be configured into the Application Identity section of the application connection pool. Then the web.config connection string can be configured with trusted_connection=true. Configuring it this way uses the Windows Data Protection API to protect the identities.
If you mean data at app.config it is simple! You have to use these two classes:
EntityConnectionStringBuilder
https://msdn.microsoft.com/en-us/library/system.data.entityclient.entityconnectionstringbuilder(v=vs.110).aspx
And
SqlConnectionStringBuilder
https://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqlconnectionstringbuilder(v=vs.110).aspx
I learn it from this page: Programmatic Connection Strings in Entity Framework 6 It is very good guide. In any cases, That link didn't help you!? Just Google something like this:
C# define connection string at runtime
After you put all connection string inside your code, you can go and delete any sensitive data from connectionStrings tag of app.config file because your app will not use it anymore! Then compile your code again.
If you are using DB First in EF, then you can check this Guide too: How to set Connection String with Entity Framework
UPDATED:
I added two of my Classes that I manage and create connection string with them programmatic (Dynamic), One is belong to my Entity Framework project that I used SQL Server Compact Edition (SQL Server CE) and the second one belong to another Entity Framework Project That I used SQL Server Express 2014 with SQL Server authentication (used sa username). I will leave both method here in case anyone need them:
This belong to my SQL Server CE project:
public static string GetDBConnectionString(string dataParentPath = "")
{
EntityConnectionStringBuilder entityBuilder = new EntityConnectionStringBuilder();
SqlCeConnectionStringBuilder sqlCEBuilder = new SqlCeConnectionStringBuilder();
if (string.IsNullOrEmpty(dataParentPath) == true)
dataParentPath = #"C:\MyDBFolder\CMS.sdf";
sqlCEBuilder.DataSource = dataParentPath;
sqlCEBuilder.Password = "12345687";
sqlCEBuilder.MaxDatabaseSize = 4090;
entityBuilder.Metadata = "res://*/CMS.csdl|res://*/CMS.ssdl|res://*/CMS.msl";
entityBuilder.ProviderConnectionString = sqlCEBuilder.ToString();
entityBuilder.Provider = "System.Data.SqlServerCe.4.0";
return entityBuilder.ToString();
}
This belongs to my SQL Server Express project with SQL Server authentication:
using System;
using System.Collections.Generic;
using System.Data.Entity.Core.EntityClient;
using System.Data.SqlClient;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace CMS
{
class mySettings
{
public static string GetDBConnectionString()
{
// **************************************************
// This is my "ConnectionString" from App.config file.
// <connectionStrings>
// <add name="CMSEntities"
// connectionString=
// "metadata=res://*/CMS.csdl|res://*/CMS.ssdl|res://*/CMS.msl
// ;provider=System.Data.SqlClient
// ;provider connection string="
// ;data source=MY-PC\SQLEXPRESS
// ;initial catalog=CMS
// ;user id=sa
// ;password=12345687
// ;MultipleActiveResultSets=True
// ;App=EntityFramework
// ""
// providerName="System.Data.EntityClient" />
//</connectionStrings>
// **************************************************
string metaData = "res://*/CMS.csdl|res://*/CMS.ssdl|res://*/CMS.msl";
string providerName = "System.Data.SqlClient";
string dataSource = #"MY-PC\SQLEXPRESS";
string databaseName = "CMS"; // = InitialCatalog
string userID = "sa";
string password = "12345687";
string appName = "EntityFramework";
EntityConnectionStringBuilder entityBuilder = new EntityConnectionStringBuilder();
SqlConnectionStringBuilder sqlBuilder = new SqlConnectionStringBuilder();
// = = = = = = = = = = = = = = = =
sqlBuilder.DataSource = dataSource;
sqlBuilder.InitialCatalog = databaseName;
sqlBuilder.MultipleActiveResultSets = true;
sqlBuilder.UserID = userID;
sqlBuilder.Password = password;
sqlBuilder.ApplicationName = appName;
// = = = = = = = = = = = = = = = =
entityBuilder.Provider = providerName;
entityBuilder.Metadata = metaData;
entityBuilder.ProviderConnectionString = sqlBuilder.ConnectionString;
return entityBuilder.ToString();
}
}
}
As you can see, My database in both project have same name "CMS" so its Entities will be named "CMSEntities". Now! you have to override its DbContext constructor. It is Important but easiest part! Better description than mine is from this page "http://www.cosairus.com/Blog/2015/3/10/programmatic-connection-strings-in-entity-framework-6":
Now your Entity Model extends from DbContext and DbContext provides a
constructor to pass in a Connection String, but your Entity Model does
not overload those constructors for you. In order to access the
constructor overload, you will need to create a new class partial for
your Entity Model database context in the same namespace as your
Entity Model with the required constructor signature. Pro Tip: be sure
to name the filename of the cs file a different name than the Entity
Model database context in the event that future generated code does
not overwrite your changes.
So I build a class at root of my Project, The class must be partial:
using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace CMS // Your Project Namespace
{
public partial class CMSEntities : DbContext
{
public CMSEntities(string connectionString)
: base(connectionString)
{
}
}
}
and Anytime I wanna access to my Database I will use this code:
using (CMSEntities db = new CMSEntities(CMSSettings.GetDBConnectionString()))
{
// Do your DB stuff here...
}
I hope It help you or others which I learn all of that from this site "stackoverflow" and users.
Good Luck