Environment: WebSphere Network Deployment edition v6.1 (on Linux)
We have 2 applications "Main" and "Dynamic" that each run on a server cluster. Each of these applications is set to run from its unique domain name. So www.main.com/ is serviced by the Main application while www.dynamic.com/ is serviced by the Dynamic application.
The configurations required for this have been pretty simple. So no problem so far.
Dynamic application is related to Main and going forward, we want to be able to do the following:
We want to be able to serve the Dynamic application from:
www.dynamic.com/ as well as
www.main.com/d/
In order to achieve this, we have the following configuration specified in plugin-cfg.xml.
<URIGroup Name="MainURIs">
<URI Name="/*" />
</URIGroup>
<URIGroup Name="DynamicURIs">
<URI Name="/*" />
</URIGroup>
<URIGroup Name="Main_DynamicURIs">
<URI Name="/d/*" />
</URIGroup>
2 server clusters namely "MainCluster" and "DynamicCluster" have already been defined in plugin-cfg.xml. Similarly we have virtual host groups defined for www.main.com (virtual host name) and www.dynamic.com as "MainVH" and "DynamicVH" respectively. We have the routing rules specified as follows:
<Route UriGroup="MainURIs" VirtualHostGroup="MainVH" ServerCluster="MainCluster"/>
<Route UriGroup="DynamicURIs" VirtualHostGroup="DynamicVH" ServerCluster="DynamicCluster"/>
<Route UriGroup="Main_DynamicURIs" ServerCluster="DynamicCluster"/>
Please note that we don't specify a virtual host group for the third route rule.
This seems to work fine for our purpose. However, we had to make the above change to plugin-cfg.xml by hand. Every time the plugin-cfg.xml file in regenerated, the changes are lost and we have to make them again. This is frowned upon by our clients and they don't want that to be the case going forward.
Is there a way we can overcome this problem of hand-editing the plugin-cfg.xml file?
Some vague ways I was thinking of:
1) Some how making this change using the admin console of WebSphere so that even if the xml file is regenerated, it would have the relevant routing rules automatically.
2) Writing a wsadmin JACL/Jython script that could be run each time after the plugin file is regenerated. This script should be able to update the above routing rules in the configuration. I have searched quite a lot for this approach but haven't found an encouraging reply to this approach.
Any helpful tips are highly appreciated.
Related
I'm new to OFBiz and having trouble making it work on production. I'd appreciate it very much if you could help me to narrow down or even better solve the problem :-)
I was able to able to run OFbiz successfully at localhost and access data that came with the project (ex: https://localhost:8443/webtools/control/entitymaint)
I went through the steps setting up SSL for the project on production site on my Windows Server (I was able to access https://www.mywebsitedomain.com)
I created a folder called ROOT and put the OFBiz folder(same folder on my localhost) in the ROOT folder
I also have set up an SSL Certificate, then added the following to server.xml under Tomcat 9.
(Connector port="8443" maxThreads="150"
scheme="https" secure="true" SSLEnabled="true"
keystoreFile="C:\Program Files\Apache Software Foundation\Tomcat 9.0\webapps\apache-ofbiz-17.12.03\keystore.jks" keystorePass="Password"
clientAuth="false" sslProtocol="TLS")
(/Connector)
When running https://www.mywebsitedomain/webtools/control/entitymaint(same URL except for localhost), I got the message.
"404 - File or directory not found.
The resource you are looking for might have been removed, had its name changed, or is temporarily unavailable."
Edit: Add some additional information
I found the following information on the OFBiz Production SetUP page:
"Configure the ofbiz-containers.xml file to point to your new keystore and password:
If using Tomcat (Catalina), which is the default, find the "catalina-container" -> "https-connector" -> "keystoreFile" and "keystorePass" properties and set them."
I go to apache-ofbiz-17.12.03\framework\base\config\ofbiz-containers.xml
All the entries I have are below. I don't know where I can add "keystoreFile" and "keystorePass" properties
<ofbiz-containers xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="http://ofbiz.apache.org/dtds/ofbiz-containers.xsd">
<!-- load the ofbiz component container (always first) -->
<container name="component-container" loaders="main,rmi,load-data,test" class="org.apache.ofbiz.base.container.ComponentContainer"/>
Thanks in advance.
Jessie
As you found, OFBiz uses an embedded Tomcat (9.0.31). So server.xml is of no help. This wiki page needed update, done. The file you are looking for is framework\catalina\ofbiz-component.xml.
But I'm not sure you are going the right way doing this. Most of the time, it's easier to use Apache HTTPD, even on Windows. You may refer to https://s.apache.org/vmemj. Also for certificates Let's encrypt is what we use for our demos. It's free and, apart the renewal every 3 months, it's great. With their cerbot that's even not a big deal.
By and large, you should better ask questions in the OFBiz user Mailing List.You need to subscribe, please see https://ofbiz.apache.org/mailing-lists.html
HTH
In point 4 you speak about the following, but I see nothing, do I miss something?
You could also ditch OFBiz and migrate to the awesome Scipio ERP (based on the same foundation): www.scipioerp.com
We have a documentation on exactly your question right here: https://www.scipioerp.com/community/developer/installation-configuration/clustering/webserver-configuration/
OK, so I did the dumb thing and released production code (C#, VS2010) that targeted our development database (SQL Server 2008 R2). Luckily we are not using the production database yet so I didn't have the pain of trying to recover and synchronize everything...
But, I want to prevent this from happening again when it could be much more painful. My idea is to add a table I can query at startup and determine what database I am connected to by the value returned. Production would return "PROD" and dev and test would return other values, for example.
If it makes any difference, the application talks to a WCF service to access the database so I have endpoints in the config file, not actual connection strings.
Does this make sense? How have others addressed this problem?
Thanks,
Dave
The easiest way to solve this is to not have access to production accounts. Those are stored in the Machine.config file for our .net applications. In non-.net applications this is easily duplicated, by having a config file in a common location, or (dare I say) a registry entry which holds the account information.
Most of our servers are accessed through aliases too, so no one really needs to change the connection string from environment to environment. Just grab the user from the config and the server alias in the hosts file points you to the correct server. This also removes the headache from us having to update all our config files when we switch db instances (change hardware etc.)
So even with the click once deployment and the end points. You can publish the a new endpoint URI in a machine config on the end users desktop (I'm assuming this is an internal application), and then reference that in the code.
If you absolutely can't do this, as this might be a lot of work (last place I worked had 2000 call center people, so this push was a lot more difficult, but still possible). You can always have an automated build server setup which modifies the app.config file for you as a last step of building the application for you. You then ALWAYS publish the compiled code from the automated build server. Never have the change in the app.config for something like this be a manual step in the developer's process. This will always lead to problems at some point.
Now if none of this works, your final option (done this one too), which I hated, but it worked is to look up the value off of a mapped drive. Essentially, everyone in the company has a mapped drive to say R:. This is where you have your production configuration files etc. The prod account people map to one drive location with the production values, and the devs etc. map to another with the development values. I hate this option compared to the others, but it works, and it can save you in a pinch with others become tedious and difficult (due to say office politics, setting up a build server etc.).
I'm assuming your production server has a different name than your development server, so you could simply SELECT ##SERVERNAME AS ServerName.
Not sure if this answer helps you in a assumed .net environment, but within a *nix/PHP environment, this is how I handle the same situation.
OK, so I did the dumb thing and released production code
There are a times where some app behavior is environment dependent, as you eluded to. In order to provide this ability to check between development and production environments I added the following line to global /etc/profile/profile.d/custom.sh config (CentOS):
SERVICE_ENV=dev
And in code I have a wrapper method which will grab an environment variable based on name and localize it's value making it accessible to my application code. Below is a snippet demonstrating how to check the current environment and react accordingly (in PHP):
public function __call($method, $params)
{
// Reduce chatter on production envs
// Only display debug messages if override told us to
if (($method === 'debug') &&
(CoreLib_Api_Environment_Package::getValue(CoreLib_Api_Environment::VAR_LABEL_SERVICE) === CoreLib_Api_Environment::PROD) &&
(!in_array(CoreLib_Api_Log::DEBUG_ON_PROD_OVERRIDE, $params))) {
return;
}
}
Remember, you don't want to pepper your application logic with environment checks, save for a few extreme use cases as demonstrated with snippet. Rather you should be controlling access to your production databases using DNS. For example, within your development environment the following db hostname mydatabase-db would resolve to a local server instead of your actual production server. And when you push your code to the production environment, your DNS will correctly resolve the hostname, so your code should "just work" without any environment checks.
After hours of wading through textbooks and tutorials on MSBuild and app.config manipulation, I stumbled across something called SlowCheetah - XML Transforms http://visualstudiogallery.msdn.microsoft.com/69023d00-a4f9-4a34-a6cd-7e854ba318b5 that did what I needed it to do in less than hour after first stumbling across it. Definitely recommended! From the article:
This package enables you to transform your app.config or any other XML file based on the build configuration. It also adds additional tooling to help you create XML transforms.
This package is created by Sayed Ibrahim Hashimi, Chuck England and Bill Heibert, the same Hashimi who authored THE book on MSBuild. If you're looking for a simple ubiquitous way to transform your app.config, web.config or any other XML fie based on the build configuration, look no further -- this VS package will do the job.
Yeah I know I answered my own question but I already gave points to the answer that eventually pointed me to the real answer. Now I need to go back and edit the question based on my new understanding of the problem...
Dave
I' assuming yout production serveur has a different ip address. You can simply use
SELECT CONNECTIONPROPERTY('local_net_address') AS local_net_address
I need multiple sites to all point to a common application, varying by host-header.
While the code / content for each each site is identicial each site does need a unique config, for things like connection strings.
What would be the best approach to set this up?
(The site is actually a Silverlight / WCF application, although I don't think that should matter.)
Either use msi installation package and allow set up all these values in installation wizard or use new web.config transformation syntax introduced in .NET 4.0 (you will have separate config and build target for each host header).
Edit - I didn't understand your question first:
You will have to install the application multiple times. You can't have single site with multiple different configs. But you don't have to copy libraries multiple times - you can use links (mklink.exe). It means you will have one central directory holding your shared content like bin directory and you will have separate directory for each site. Each of sites' directories will contain its own web.config and some content placed to root of your site + links to central directory. You will create create separate application for each site in IIS and map single host header to each application.
Other possiblity is handling this in your code and having everything in single web.config but IMO it is pretty bad and dangerous solution.
I need to change database and settings when my customers load the application (xap) on different URLs.
Examples:
client A connects on URL: www.clienteA.com/system
client B connects on URL: www.clienteB.com/system
The two urls above call the same xap file, but I need to change database and settings;
how I do that?
Do those URLs actually resolve to the same site/server? IMO, the easiest way to do this is to do it as part of your build process. When you publish the app for "client A", you use the web.config (etc) for that client - and ditto "client B". May SCM systems allow this type of per-client configuration, or it is pretty easy to do it with a few build scripts.
The alternative (if they absolutely must be the same physical code files on the same server) is to move this into the machine's web.config - much more complicated, but you can use the "location" node in web.config to specify connection-strings per IIS site, even if they resolve to the same files. I stress that this is risky, hard to verify, and easy to get wrong - the build process is my preferred option!
I ran across a new problem in the last week. Due to the nature of my project and available budget a small intranet web application I've been working on is both the testing and live server, as well as serves up the pages and is the sql server. This will last at least until the project is out of the major development cycle. Now that the project has real users but I am continuing development I duplicated the database to have a safe copy to mess with that won't cause havoc to live business data and a development copy of the website.
All was well until I discovered an anomoly on the test copy of the site, anything that uses a sql datasource was properly pulling it's data from the test database, but anything that gets it's data from a stored procedure triggered in the code behind was pulling it's data from the live databse.
My confusion comes from the fact that all stored procedures and sql datasources ultimately point back to the same connectionstring setting in the web.config file to know where to connect to. I just rename the database name depending on if I'm uploading the latest changes to the test or live site.
My question comes down to, why would with one connection string in each site would my test site accessing data one way get it from one database and accessing the other get it's data from the other database?
Here's my connection string they all point back to, names/passwords of course change for obvious reasons, but the structure is intact.
<add name="db_Connection" connectionString="Data Source=SERVERNAME;Initial Catalog=DATABASE_live;Persist Security Info=False;User ID=USERID;Password=password" providerName="System.Data.SqlClient"/>
I added a key to the appsettings to reference the name of the database connection so I could easily change it's name if need be without having to edit dozens of pages for the code behind SProc calls.
<add key="defaultDB" value="db_Connection" />
Am I violating some rule I'm unaware of or is there something else going on that I need to be aware of and change so I can have a true test environment as I continue to develop an active site?
EDIT This project is in ASP.NET 2.0 VB, fixed the code display.
solution found I have tracked down the solution, thanks for the pointers, they got me looking elsewhere. When I copied the site to a different location for testing I forgot to update my appsetting key for the site's location, this caused the following part of the call for stored procedures to grab data from the live site's web.config aparently.
System.Web.Configuration.WebConfigurationManager.OpenWebConfiguration(pubvar_webConfig)
Change the username and password on the dev database. If your problem persists then you might have a connection string set somewhere else that you don't know about.
I would search all of the files in your solution to make sure you don't have one of the database names hard coded some place. Maybe in the designer files?
It may be worth running the two applications in different app pools via IIS (if you aren't already or course!). This should eliminate any concurrency issues between the test and production sites at the application level.
IMHO with a shared test / production environment seperate app pools is good practice at any time.