Changing Location of Velocity.Log File - apache

Seems pretty straight forward. Documentation at http://velocity.apache.org/engine/devel/developer-guide.html#Configuring_Logging
says to set the runtime.log property. Here's what I got for all my properties.
velocityEngine.setProperty(RuntimeConstants.FILE_RESOURCE_LOADER_PATH, templatesPath);
velocityEngine.setProperty("runtime.log", "/path/to/my/file/velocity.log");
velocityEngine.setProperty("resource.loader", "string");
velocityEngine.setProperty("string.resource.loader.class", "org.apache.velocity.runtime.resource.loader.StringResourceLoader");
velocityEngine.setProperty("string.resource.loader.repository.class", "org.apache.velocity.runtime.resource.util.StringResourceRepositoryImpl");
Not finding any log file where I told it to place it and instead finding the new errors placed into old (folder of initialization) location. Any ideas? :D

i had similar problem when setting at runtime some options. I figured out those problem whit a custom VelocityBuilder and an external velocity.properties file where you can put all the runtime properties.
Here is the code:
public class BaseVelocityBuilder implements VelocityBuilder {
private VelocityEngine engine;
private Log logger = LogFactory.getLog(getClass());
#Autowired
private WebApplicationContext webApplicationContext;
public VelocityEngine engine() {
if(engine == null) {
engine = new VelocityEngine();
Properties properties = new Properties();
InputStream in = null;
try {
in = webApplicationContext.getServletContext().getResourceAsStream("/WEB-INF/velocity.properties");
properties.load(in);
engine.init(properties);
} catch (IOException e) {
e.printStackTrace();
logger.error("Error loading velocity engine properties");
throw new ProgramException("Cannot load velocity engine properties");
}
IOUtils.closeQuietly(in);
}
return engine;
}
}
See this line:
in = webApplicationContext.getServletContext().getResourceAsStream("/WEB-INF/velocity.properties");
properties.load(in);
engine.init(properties);
So i have a velocity.properties file in /WEB-INF where i put some configuration:
resource.loader = webinf, class
webinf.resource.loader.description = Framework Templates Resource Loader
webinf.resource.loader.class = applica.framework.library.velocity.WEBINFResourceLoader
webapp.resource.loader.class = org.apache.velocity.tools.view.servlet.WebappLoader
webapp.resource.loader.path =
file.resource.loader.description = Velocity File Resource Loader
file.resource.loader.class = org.apache.velocity.runtime.resource.loader.FileResourceLoader
file.resource.loader.path =
class.resource.loader.description = Velocity Classpath Resource Loader
class.resource.loader.class = org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader
runtime.log='/pathYouWant/velocity.log'
In the end in your application.xml :
<bean class="applica.framework.library.velocity.BaseVelocityBuilder" />
In this way you can have for example different file log for different application and when you give the war in production, the sysadm can change the properties due to env configuration of the production server.

Related

Arquillian ShrinkWrap how to add an asset to the file system path

I am importing a library that reads from the file system instead of my web archive's resource folder. I want to be able to essentially mock that file by adding an asset with that path using ShrinkWrap, so I can run tests on my build server without guaranteeing the file system has all these files. I tried to add a String Asset in the appropriate path, but the code can't find that asset. Here's an example of what I'm trying to achieve.
Rest Resource
#Path("/hello-world")
public class HelloWorldResource {
#GET
public Response getHelloWorld(){
return Response.ok(getFileContent()).build();
}
private String getFileContent() {
StringBuilder builder = new StringBuilder();
try {
BufferedReader bufferedReader = new BufferedReader(
new FileReader(
"/usr/myFile.txt"));
String line = bufferedReader.readLine();
while (line != null) {
builder.append(line);
line = bufferedReader.readLine();
}
}
catch (Exception e) {
e.printStackTrace();
}
return builder.toString();
}
}
Test
#RunWith(Arquillian.class)
public class HelloWorldResourceTest {
#Deployment
public static WebArchive createDeployment()
{
WebArchive webArchive = ShrinkWrap
.create(WebArchive.class)
.addPackages(true,
HelloWorldApplication.class.getPackage(),
HelloWorldResource.class.getPackage(),
Hello.class.getPackage())
.add(new StringAsset("Blah"),"/usr/myFile.txt")
.addAsWebInfResource(EmptyAsset.INSTANCE, "beans.xml");
System.out.println("WebArchive: " + webArchive.toString(true));
return webArchive;
}
#Test
#RunAsClient
public void testHello(
#ArquillianResteasyResource("hello-world") final WebTarget webTarget)
{
final Response response = webTarget
.request(MediaType.APPLICATION_JSON)
.get();
String hello = response.readEntity(String.class);
System.err.println("Hello: " + hello);
Assert.assertEquals("Status is not OK", response.getStatus(), 200);
}
}
Web Archive toString
/WEB-INF/
/WEB-INF/classes/
/WEB-INF/classes/com/
/WEB-INF/classes/com/
/WEB-INF/classes/com/
/WEB-INF/classes/com/helloworld/
/WEB-INF/classes/com/helloworld/application/
/WEB-INF/classes/com/helloworld/application/HelloWorldApplication.class
/WEB-INF/classes/com/helloworld/resource/
/WEB-INF/classes/com/helloworld/resource/HelloWorldResourceTest.class
/WEB-INF/classes/com/helloworld/resource/HelloWorldResource.class
/WEB-INF/classes/com/helloworld/dataobjects/
/WEB-INF/classes/com/helloworld/dataobjects/Hello.class
/WEB-INF/beans.xml
/usr/
/usr/myFile.txt
I get the following error:
java.io.FileNotFoundException: /usr/myFile.txt (No such file or
directory)
Seems like ShrinkWrap is adding /usr/myFile.txt as a relative path within the archive instead of making it seem like /usr/myFile.txt is at the root directory of my file system. Is there any way I can get ShrinkWrap to do what I want?
Shrinkwrap is intended to create archives, so the API is scoped to create assets within the archive you are creating. If you want to have resources created in the regular filesystem simply use JDK, there is nothing Shrinkwrap could help you with.
Alternatively, if possible, change your resource to read resources from the classpath, not filesystem path. With this approach, you can easily swap content for the test using Shrinkwrap as you are trying now with your example.

Different project settings for user Intellij Idea

How can I do different project settings for users in the same project. I have a project with some .properties file like email.properties which contains user-specific settings.I need something like user-specific enviroment settings, something like this: email..properties, and variable contains in OS enviroment or, maybe, in project file
Here's how I've done this in some projects. I create a System Property to the path of the property file. The path is outside of the project so the properties file is never committed. But to help others who are running the project for the first time, I commit a template properties file with default options.
In intellij, I start the project with a different -D option than my coworkers do and the startup options don't get committed (because we don't commit the .idea folder).
As a result a do the same: at first I created properties folder in propject root, add there file env.properties which contains current environment name (or user can add it as JVM start paramenter -Denv=<env name>. I add static class and method Properties getProperty(String fileName) which receive property file name as parameter and return all records in file as java.util.Properties.
public static Properties loadProperties(String fileName)
{
Properties properties = null;
if (propertiesMap.containsKey(fileName)) {
properties = (Properties)properties.get(fileName);
} else {
String environment = getEnvironment();
try {
properties = (new PropertiesLoaderImpl()).LoadAllPropertiesForUtilAndEnv(environment, fileName);
} catch (FileNotFoundException exception) {}
}
return properties;
}
private static String getEnvironment() {
// Проверка на наличие параметра при запуске java-машины
String environment = System.getProperty("env");
if (environment == null) {
try {
// Попытка найти файл env.properties
ResourceBundle bundle = ResourceBundle.getBundle("properties/env");
environment = bundle.getString("env");
} catch (MissingResourceException exception) {
environment = "";
}
}
return environment;
}
Property search implements that way:
1. look in ..proeprties;
2. if there is no suitable property, then look in .property;
3. else return empy.

How to list JBoss AS 7 datasource properties in Java code?

I'm running JBoss AS 7.1.0.CR1b. I've got several datasources defined in my standalone.xml e.g.
<subsystem xmlns="urn:jboss:domain:datasources:1.0">
<datasources>
<datasource jndi-name="java:/MyDS" pool-name="MyDS_Pool" enabled="true" use-java-context="true" use-ccm="true">
<connection-url>some-url</connection-url>
<driver>the-driver</driver>
[etc]
Everything works fine.
I'm trying to access the information contained here within my code - specifically the connection-url and driver properties.
I've tried getting the Datasource from JNDI, as normal, but it doesn't appear to provide access to these properties:
// catches removed
InitialContext context;
DataSource dataSource = null;
context = new InitialContext();
dataSource = (DataSource) context.lookup(jndi);
ClientInfo and DatabaseMetadata from a Connection object from this Datasource also don't contain these granular, JBoss properties either.
My code will be running inside the container with the datasource specfied, so all should be available. I've looked at the IronJacamar interface org.jboss.jca.common.api.metadata.ds.DataSource, and its implementing class, and these seem to have accessible hooks to the information I require, but I can't find any information on how to create such objects with these already deployed resources within the container (only constructor on impl involves inputting all properties manually).
JBoss AS 7's Command-Line Interface allows you to navigate and list the datasources as a directory system. http://www.paykin.info/java/add-datasource-programaticaly-cli-jboss-7/ provides an excellent post on how to use what I believe is the Java Management API to interact with the subsystem, but this appears to involve connecting to the target JBoss server. My code is already running within that server, so surely there must be an easier way to do this?
Hope somebody can help. Many thanks.
What you're really trying to do is a management action. The best way to is to use the management API's that are available.
Here is a simple standalone example:
public class Main {
public static void main(final String[] args) throws Exception {
final List<ModelNode> dataSources = getDataSources();
for (ModelNode dataSource : dataSources) {
System.out.printf("Datasource: %s%n", dataSource.asString());
}
}
public static List<ModelNode> getDataSources() throws IOException {
final ModelNode request = new ModelNode();
request.get(ClientConstants.OP).set("read-resource");
request.get("recursive").set(true);
request.get(ClientConstants.OP_ADDR).add("subsystem", "datasources");
ModelControllerClient client = null;
try {
client = ModelControllerClient.Factory.create(InetAddress.getByName("127.0.0.1"), 9999);
final ModelNode response = client.execute(new OperationBuilder(request).build());
reportFailure(response);
return response.get(ClientConstants.RESULT).get("data-source").asList();
} finally {
safeClose(client);
}
}
public static void safeClose(final Closeable closeable) {
if (closeable != null) try {
closeable.close();
} catch (Exception e) {
// no-op
}
}
private static void reportFailure(final ModelNode node) {
if (!node.get(ClientConstants.OUTCOME).asString().equals(ClientConstants.SUCCESS)) {
final String msg;
if (node.hasDefined(ClientConstants.FAILURE_DESCRIPTION)) {
if (node.hasDefined(ClientConstants.OP)) {
msg = String.format("Operation '%s' at address '%s' failed: %s", node.get(ClientConstants.OP), node.get(ClientConstants.OP_ADDR), node.get(ClientConstants.FAILURE_DESCRIPTION));
} else {
msg = String.format("Operation failed: %s", node.get(ClientConstants.FAILURE_DESCRIPTION));
}
} else {
msg = String.format("Operation failed: %s", node);
}
throw new RuntimeException(msg);
}
}
}
The only other way I can think of is to add module that relies on servers internals. It could be done, but I would probably use the management API first.

How do I use Sitecore.Data.Serialization.Manager.LoadItem(path,LoadOptions) to restore a item to Sitecore?

I am trying to use the sitecore API to serialize and restore sitecore items. I have created a WCF app to retrieve an Item name given a ID or sitecore path (/sitecore/content/home), retrieve a list of the names of the items children give an id or path. I can also Serialize the content tree.
public void BackupItemTree(string id)
{
Database db = Sitecore.Configuration.Factory.GetDatabase("master");
Item itm = db.GetItem(id);
Sitecore.Data.Serialization.Manager.DumpTree(itm);
}
The above code works great. After running it can see that the content tree has been serialized.
However when I try to restore the serialized items useing the following:
public void RestoreItemTree(string path)
{
try
{
using (new Sitecore.SecurityModel.SecurityDisabler())
{
Database db = Sitecore.Configuration.Factory.GetDatabase("master");
Data.Serialization.LoadOptions opt = new Data.Serialization.LoadOptions(db);
opt.ForceUpdate = true;
Sitecore.Data.Serialization.Manager.LoadItem(path, opt);
//Sitecore.Data.Serialization.Manager.LoadTree(path, opt);
}
}
catch (Exception ex)
{
throw ex;
}
}
With this code I get no errors. It runs, but if I check SiteCore it didn't do anything. I have tested using the Office Core example. The path I sent in, which might be the issue is:
C:\inetpub\wwwroot\sitecoretest\Data\serialization\master\sitecore\content\Home\Standard-Items\Teasers\Our-Clients.item
and
C:\inetpub\wwwroot\sitecorebfahnestockinet\Data\serialization\master\sitecore\content\Home\Standard-Items\Teasers\Our-Clients
Neither seems to do anything. I changed the teaser title of the item and am trying to restore to before the but every time the change is still present.
Any help would be appreciated as the SiteCore documentation is very limited.
You can always check how the Sitecore code works using Reflector, the following method is called when you click "Revert Item" in back-end:
protected virtual Item LoadItem(Item item, LoadOptions options)
{
Assert.ArgumentNotNull(item, "item");
return Manager.LoadItem(PathUtils.GetFilePath(new ItemReference(item).ToString()), options);
}
In LoadOptions you can specify whether you want to overwrite ("Revert Item") or just update ("Update Item") it.
See Sitecore.Shell.Framework.Commands.Serialization.LoadItemCommand for more info.
You have the correct LoadOptions for forcing an overwrite (aka Revert).
I suspect that the path you are using for the .item file wrong. I would suggest modifying your method to take a path to a Sitecore item. Using that path, you should leverage other serialization APIs to determine where the file should be.
public void RestoreItemTree(string itemPath)
{
Sitecore.Data.Database db = Sitecore.Configuration.Factory.GetDatabase("master");
Sitecore.Data.Serialization.ItemReference itemReference = new Sitecore.Data.Serialization.ItemReference(db.Name, itemPath);
string path = Sitecore.Data.Serialization.PathUtils.GetFilePath(itemReference.ToString());
Sitecore.Data.Serialization.LoadOptions opt = new Sitecore.Data.Serialization.LoadOptions(db);
opt.ForceUpdate = true;
using (new Sitecore.SecurityModel.SecurityDisabler())
{
Sitecore.Data.Serialization.Manager.LoadItem(path, opt);
}
}
Took me a while to work out, but you have to remove .item when restoring the tree
try this
public void RestoreItemTree(string itemPath)
{
var db = Factory.GetDatabase("master");
var itemReference = new ItemReference(db.Name, itemPath);
var path = PathUtils.GetFilePath(itemReference.ToString());
if (!System.IO.File.Exists(path))
{
throw new Exception("File not found " + path);
}
var opt = new LoadOptions(db);
opt.ForceUpdate = true;
using (new SecurityDisabler())
{
Manager.LoadItem(path, opt);
Manager.LoadTree(path.Replace(".item", ""), opt);
}
}

Glassfish Custom Properties Resource Not Loading From File

I've deployed a webapp (war) to Glassfish v3 and I am trying to get it to read from properties defined in a custom resource.
In my app, I've defined the properties as:
#Resource(mappedName = "TestServletProperties")
private Properties properties;
and make use of it like this:
protected void doGet(final HttpServletRequest request,
final HttpServletResponse response) throws ServletException,
java.io.IOException
{
String propertyOne = properties.getProperty("testServlet.propertyOne");
String propertyTwo = properties.getProperty("propertyTwo");
StringBuffer buffer = new StringBuffer("Properties Retrieved\n");
buffer.append("Property One: " + propertyOne + "\n");
buffer.append("Property Two: " + propertyTwo + "\n");
try
{
response.getWriter().write(buffer.toString());
}
catch (Exception ex)
{
try
{
log.warn("Exception thrown", ex);
response.getWriter().write(ex.getStackTrace().toString());
}
catch (IOException io)
{
log.warn("IOException thrown", io);
}
}
}
In Glassfish, I've created a JNDI Custom Resource called TestServletProperties of type java.util.Properties and using factory class org.glassfish.resources.custom.factory.PropertiesFactory. In the resource there is one property "fileName" with its value set to the absolute path of the properties file:
/Program Files/glassfishv3/glassfish/domains/domain1/applications/Test/WEB-INF/classes/TestServlet_lab.properties
I've also tried
c:\Program Files\glassfishv3\glassfish\domains\domain1\applications\Test\WEB-INF\classes\TestServlet_lab.properties
I have confirmed that the file exists and contains the referenced properties. Unfortunately, I'm getting back "null" for both values in my response.
Any thoughts?
The solution is that you have to use the fully qualified "org.glassfish.resources.custom.factory.PropertiesFactory.fileName" versus just "fileName".
The reason might be that you have a web.xml file with the header of a 2.4 (or older) servlet version.
#Resource and other annotations are only processed if you have at least version 2.5 in the header of web.xml. Be sure that you do not simply change the version but copy and paste the new header from somewhere as the namespace is different.
Hope this helps