seedstack, how to read the base url from properties file - seedstack

I am using feign client for doing rest call.I kept my base url in application .yaml file.
But I want application.yaml should read the base url from properties file kept in external location.
I am facing this issue when I am trying to do the deployment of my web application.

SeedStack configuration files can contain placeholders (or macros as we call them). Some runtime information is available under the runtime configuration node and can be referenced using macros.
This is the case for the base URL if you run your Web application with the embedded Web server. You can refer to it from your properties files regardless of their location:
someProperty=${runtime.web.baseUrl}/something
Warning: in SeedStack versions older than 18.11, the base URL is available under web.runtime.baseUrl instead. This has been changed in the latest version to regroup all runtime information in the same place. Note that it also had a trailing slash back then.
Relevant docs:
Macros: http://seedstack.org/docs/core/configuration/#macros
Web runtime info: http://seedstack.org/docs/web/#runtime-information
Release notes about the change: http://seedstack.org/posts/18.11-release-notes/#runtime-information-update

Related

Best practice to create .NET Web API using generated Server Stub

b) After generating the .NET C# server stub, the documentation is not very verbose about how to use it:
You need to implement the logic yourself to handle whatever work the
API needs to do. Once the implementation is ready, you can deploy the
API locally or on your server. See the README.md file in the
downloaded archive to get started.
Is there any tutorial about how to use the code? I would like to use inheritance to avoid code changes of the generated code. But the documentation talks about just ignoring some generated files. The swagger support told me to just "migrate" the changes on every change. What is possible, but I hoped to be able to leave generated files untouched. Am I wrong here, is there no parctical need for this? I would like to use the server stub in a continuous integration environment.
One option you have is to customize the templates.
Clone the swagger-codegen repository.
Assuming you are using the latest stable v2 version of the code generation tool, then master branch is fine. Otherwise checkout the tag for the tool version you are using.
In Windows Explorer, open swagger-codegen\modules\swagger-codegen\src\main\resources\ and copy the aspnetcore directory. Paste that into your customer source code repository.
When next you run the codegen tool, provide the -t argument:
java -jar swagger-codegen-cli.jar generate
-i <your Open API spec URL/file>
-l aspnetcore
-o <outputdir>
-t <relative path to your>\aspnetcore
... other args as needed
Now you can modify those templates with custom code. For example, you could have an external library with a new base controller class that provides some generic business logic. Then you could modify the controller.mustache file to reference your base class. Just one of many examples. Add your custom templates to your source control for continuous integration.
Caveats: There is a controller.mustache file directly in aspnetcore and another in aspnetcore\2.1. In studying the source code, I see that the 2.1 folder is used for any version of ASP.NET Core other than 2.0. I'm new to this tool myself and have not fully figured out how to exploit it; the utility generates source code that will not build for me out of the box. It does not generate the security classes, but it does generate code that tries to use those security classes. Thus I'm having to comment out the security code in the templates.

How to make a resource file visible to all bundles in OSGi?

I'd like to include a resource file (e.g. some xml config file) in my bundle and make it visible to all other bundles in the container. Is it possible without using the Fragment-Host manifest header? I'd like this resource file to always be visible in the classpath of all bundles running alongside my bundle, even those that do not exist yet, but will potentially be added in future.
EDIT:
To clarify - that resource must be available passively, i.e. the other bundles should be able to find it in their classpath, and not by refering to any special API or service of my bundle.
Some more background - my environment is a bit messy but I have no control over it and cannot change its existing bundles. The only way I can modify it is by adding my own bundles. That environment includes several copies of the ch.qos.logback.classic bundle. When logback starts up, it looks for specific XML config files in the classpath. If it doesn't find any of them, then its default behaviour is to print everything to stdout with debug level. This environment was previously used to host a GUI application so it didn't matter that much before, but now I am trying to adapt it so I can use some of its functionality in headless mode. So now it becomes important to me to be able to configure it in such a way that only warning and errors are printed to the console.
In general, no you cannot do this. Class-space isolation is at the heart of OSGi, but you want to put a resource in the class loader of one bundle and make it visible to all other bundles. That's not OSGi, it's the global application classpath.
The only thing you can do to add to the internal classpath of a specific bundle is to write a fragment which attaches to that bundle. A fragment can attach to multiple host bundles, but only if those hosts have the same symbolic name, i.e. because they are different versions of the same bundle. See OSGi R6 Core Specification, section 3.14.
You did however state that the bundles you want to attach are all copies of ch.qos.logback.classic. If that means they all have that exact symbolic name then perhaps a fragment will work after all.
You can not change the classpath of other bundles this way.
What you can do is retrieve the classloader of your bundle from your bundleContext. You can give this classloader to another bundle to retrieve your resource.
ClassLoader cl = context.getBundle().adapt(BundleWiring.class).getClassLoader();
Another option is to give the other bundle the URL of the resource.
As long as the resource is on the classpath, any bundle can access the resource if it can get hold of the class loader of the bundle that contains the resource.
For example:
ClassLoader classLoaderOfBundleWithResource = ...
classLoaderOfBundleWithResource.getResourceAsStream("org/example/resource.xml");
From a maintenance and API point of view, I would not recommend exposing a resource that way. Java types are much better suited therefore. Instead, let the resource bundle export a class that gives clients access to the contents of the resource.
For example:
public class XmlDocumentProvider {
public InputStream openDocument() {
return getClass().getResourceAsStream("resource.xml");
}
}
Assuming that both the resource.xml and the XmlDocumentProvider reside in the same package, openDocument will return the resource content just like in the first example.

Dynamically selecting log4j2 configuration in Mule

I have gone through Mule Logging documentation but not clear on how to dynamically load different logging configuration files for each environments. Basically I want to control log verbosity and sync/async feature across environments so looking for similar feature of dynamically selecting property file based on server environment property variable.
2 ways you can load the log4j2 file dynamically in your application either from an external path or from your application classpath:-
setting the log4j2 file path in your application's mule-deploy.properties like :-
log.configFile=E:\common-log4j2.xml
Loading the log4j2.xml in your application programmatically by reconfiguring the log manager via Spring and load our own log4j2.xml file from your defined path:-
ref:- https://dzone.com/articles/getting-own-log4j2-file-for-mule-via-spring
I haven't tried it, but you should be able to set the log4j config file at the command line when launching Mule, using the log4j.configuration system property.
For example (in Windows) by adding -Dlog4j.configuration=c:\some-path\log4j-%MULE-ENV%.xml if your env variable is called MULE-ENV.
Note that there are several places this can be set - directly on the command line if using Mule standalone (in which case I believe you need -M-Dlog4j.configuration=...), in the wrapper.conf file if using standalone, or in the VM params section of the Arguments tab in Run Configurations when running in Studio.
You can have a bean in your application which can call the method to set the configuration. You can pass the environment name as an argument to this bean, it'll pick the configuration file associated with that environment. You can call the method using the invoke component and have this flow executed at the startup.
Till the flow is executed, default logging configuration can be used.

inverse_loading in WASCE 3.0.0.3 / Geronimo 3.0

I am trying to deploy a war onto a IBM Websphere Application Server Community Edition (WASCE) 3.0.0.3. I had some jars conflicting problems between those jars that comes with WASCE 3.0.0.3 and the jars comes from our application dependencies. At the end, I fixed the problem by using below property in geronimo-web.xml to force WASCE to load jars from my application.
<import-package>!the.conflicting.jars</import-package>
However, I would like to force WASCE to always take jars from my application first, i.e. inverse the default classloader behavior to load from application first. What is the correct config to change in this case?
After some searches, WASCE 3.0 is based on Geronimo 3.0 according to link. I found setting <inverse-classloading> in geronimo-web.xml may be helpful. But below two documents on Apache Geronimo 3.0 website mention that this function is no longer available on Geronimo 3.0
in Migrating from G 2.x to G 3.x, it says:
inverse-classloading Geronimo 3.0 does not support the element in the deployment plan.
in geronimo-web.xml,
The <sys:environment> element contains the following elements:
...
The <inverse-classloading> element can be used to specify that standard classloader delegation is to be reversed for this module. The Geronimo classloader delegation follows the Java EE 5 specifications, and the normal behavior is to load classes from a parent classloader (if available) before checking the current classloader. ...... ...... (Not supported in 3.0, use <import-package/> instead)
So if <inverse-classloading> is no longer available, what is the equivalent of this property in WASCE 3.0.0.3? Or how exactly should I do this using <import-package/> for all duplicated jars?
In the link you mentioned you will find the following section
<sys:environment>
The <sys:environment> XML element uses the Geronimo System namespace, which is used to specify the common elements for common libraries and module-scoped services, and is documented here:
http://geronimo.apache.org/schemas-3.0/docs/geronimo-module-1.2.xsd.html
The element contains the following elements:
The <moduleId> element is used to provide the configuration name for the web application as deployed in the Geronimo server. It contains elements for the groupId, artifactId, version and module type. Module IDs are normally printed with slashes between the four components, such as GroupID/ArtifactID/Version/Type.
The <dependencies> element is used to provide the configurations and third party libraries on which the web module is dependent upon. These configurations and libraries are made available to the web module via the Geronimo classloader hierarchy.
The <bundle-activator> element is used to create Bundle-Activator header in the manifest file of the web application. It specifies the entry point of the web application as deployed in the Geronimo server.
The <bundle-classPath> element is used to create Import-Package header in the manifest file of the web application. It contains a list of directories or embedded jar files, which are also called bundle resources and extend the classpath of the web application.
The <import-package> element is used to create Import-Package header in the manifest file of the web application. It specifies a list of packages to be resolved before the web application is started. Use <import-package>!packagename</import-package> to override the specific package in server.
The <export-package> element is used to create Export-Package header in the manifest file of the web application. It specifies a list of packages to be exported.
The <require-bundle> element is used create Require-Bundle header in the manifest file of the web application. It specifies a list of bundles to bind to regardless their packages.
The <dynamic-import-package> element is used to create DynamicImport-Package header in the manifest file of the web application. It specifies a list of packaged to be imported dynamically, especially during class loading.
So basically, you need to add the following directive i.e
<sys:import-package>!package-class-name-here*</sys:import-package> within the <sys:environment> stanza. Typically before the Application Context-Root directive.
As you already know, this is in the geronimo-web.xml embedded in the Application WAR/EAR -- as mentioned in the link
http://geronimo.apache.org/GMOxDOC30/geronimo-webxml.html

Where put an serialized file object on project netbeans

I've an desktop application that implements Serializable class, but now I'm translating it to an web app with servlets, I use Netbeans for this work,I have the following code:
InputStream input = ClassLoader.getSystemResourceAsStream(file_input);
Where file_input is an bytecode fyle from an object serialized before, I don't know where I should put this file because in the desktop application I put it in the same dir where I had my classes.
(I have the file, I don't need to create it).
First of all, don't use ClassLoader#getSystemResourceAsStream() in a Java EE web application, ever. Instead, use ClassLoader#getResourceAsStream(). I would also put big question marks around using ClassLoader#getSystemResourceAsStream() in a Java SE desktop application, for sure if it's intended to be distributable, but that aside.
The ClassLoader ultimately loads resources from the classpath. So all you need to do is to make sure that the file is placed in one of the paths which are by default covered by the webapp's runtime classpath, or to add the new path to the file to the webapp's runtime classpath through a server specific configuration setting, such as shared.loader property of Tomcat's /conf/catalina.properties.
One of the default paths covered by the webapp's runtime classpath is the /WEB-INF/classes folder of the WAR. From IDE project's perspective, just drop the file in the root folder of the "Java Source" (src) folder, there where you have all your Java packages and classes. The IDE will take care that it ultimately ends up in /WEB-INF/classes of the built WAR file.
I by the way still assume that you are not creating the file from inside the webapp, as you explicitly told. That wouldn't work. If you actually need to have write access as well, you're going to need an absolute disk file system path instead. You can always make it configureable by providing it as a VM argument or environment variable, for example.