I get an error when using redirectAction with struts2 and portlets inside jboss portal - redirect

I have the following struts.xml:
<struts>
<package name="default" namespace="/view" extends="struts-portlet-default">
<action name="index" class="com.gigi.LoginAction">
<result type="redirectAction">
<param name="actionName">showAlerts</param>
<param name="namespace">/view</param>
<param name="portletMode">view</param>
</result>
<result name="error">/includes/error.jsp</result>
</action>
<action name="showAlerts" class="com.gigi.AlertsAction">
<result>/jsp/view/Alerts.jsp</result>
</action>
</package>
<package name="edit" namespace="/edit" extends="struts-portlet-default">
<action name="index" class="com.gigi.UpdateNameAction">
<result type="redirectAction">
<param name="actionName">index</param>
<param name="portletMode">view</param>
</result>
<result name="input">/jsp/edit/index.jsp</result>
</action>
</package>
</struts>
and LoginAction has the following execute method:
public String execute() throws Exception {
boolean loggedIn = checkLogin();
System.out.println("LoggedIn = " + loggedIn);
if (loggedIn) {
return SUCCESS;
}
return ERROR;
}
I am trying a redirect from LoginAction to AlertsAction. Every time I open the portlet in jboss portal 2.7.1, I get the following error:
The requested resource (/portlet/view/showAlerts) is not available
Can anyone tell me what I am doing wrong?
I tried writing the redirect in different ways, but the result is the same...
Thanks.

Where exactly is Alerts.jsp? Is it in /jsp or /WEB-INF/jsp? Can you log something out of the execute() method of AlertsAction?

Related

Dynamic Servicefabric Settings and Overrides

Is there a way to not tell the service about the settings at all and just provide them at the application level?
I am still unhappy with how servicefabric configuration seems to work.
Near as I can tell I have to specify in the service’s settings.xml all of the possible configuration values. Then I can override those in the application’s ApplicationParameters. Per documentation this looks like it holds true for environment variables also.
The complication that creates is that our configuration is used to hydrate options in many cases with arrays.
For example consider the json:
{
"AuthorizationOptions": {
"Policies": [
{
"Name": "User",
"Groups": [ "Domain Users" ]
}
]
}
}
There are 2 arrays; that are necessary and useful. To express this in the service fabric configuration it translates to:
<Section Name="AuthorizationOptions">
<Parameter Name="Policies:0:Name" Value="User"/>
<Parameter Name="Policies:0:Groups:0" Value="Domain Users"/>
</Section>
While the translation is not pleasant in comparison to the structured object it is completely usable.
However, If I don’t specify the section and parameters in the service, I can’t seem to override them in the application. So in this case I would have to define the exact number of policies and groups per policy in the service and the application could modify the policy name, or the group values, but not the number of policies total or number of groups total.
Is there a way to not tell the service about the settings at all and just provide them at the application level?
If not what alternatives exist to make the service reusable across applications that I may want to use to provide this type of dynamic configuration differently?
The last part of the puzzle that may assist in answering this question is I am using some pre-release code to translate the service fabric settings into Microsoft.Extensions.Configuration.IConfiguration. However, that is just taking the settings it finds; it isn't the cause of the override issue I am running into.
Example Service Settings.xml:
<?xml version="1.0" encoding="utf-8" ?>
<Settings xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.microsoft.com/2011/01/fabric">
<Section Name="AuthorizationOptions">
<!-- I should not have to provide these at the application level!
However, it fails to deploy if I don't. -->
<Parameter Name="Policies:0:Name" Value="User"/>
<Parameter Name="Policies:0:Groups:0" Value="Domain Users"/>
</Section>
</Settings>
Example Application ApplicationManifest.xml:
<?xml version="1.0" encoding="utf-8"?>
<ApplicationManifest xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" ApplicationTypeName="ServiceFabric.ExampleType" ApplicationTypeVersion="1.0.0" xmlns="http://schemas.microsoft.com/2011/01/fabric">
<Parameters>
<Parameter Name="Service.Example_ASPNETCORE_ENVIRONMENT" DefaultValue="" />
<Parameter Name="Service.Example_InstanceCount" DefaultValue="-1" />
<Parameter Name="Service.Example_AuthorizationOptions_Policies_0_Name" DefaultValue="Users" />
<Parameter Name="Service.Example_AuthorizationOptions_Policies_0_Groups_0" DefaultValue="Domain Users" />
</Parameters>
<ServiceManifestImport>
<ServiceManifestImport>
<ServiceManifestRef ServiceManifestName="Service.ExamplePkg" ServiceManifestVersion="1.0.0" />
<ConfigOverrides>
<ConfigOverride Name="Config">
<Settings>
<Section Name="AuthorizationOptions">
<Parameter Name="Policies:0:Name" Value="[Service.Example_AuthorizationOptions_Policies_0_Name]" />
<Parameter Name="Policies:0:Groups:0" Value="[Service.Example_AuthorizationOptions_Policies_0_Groups_0]" />
</Section>
</Settings>
</ConfigOverride>
</ConfigOverrides>
<EnvironmentOverrides CodePackageRef="code">
<EnvironmentVariable Name="ASPNETCORE_ENVIRONMENT" Value="[Service.Example_ASPNETCORE_ENVIRONMENT]" />
</EnvironmentOverrides>
</ServiceManifestImport>
<DefaultServices>
<Service Name="Service.Example" ServicePackageActivationMode="ExclusiveProcess">
<StatelessService ServiceTypeName="Service.ExampleType" InstanceCount="[Service.Example_InstanceCount]">
<SingletonPartition />
</StatelessService>
</Service>
</DefaultServices>
</ApplicationManifest>
Example Application ApplicationParameters (Local.1Node.xml):
<?xml version="1.0" encoding="utf-8"?>
<Application xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" Name="fabric:/ServiceFabric.Example" xmlns="http://schemas.microsoft.com/2011/01/fabric">
<Parameters>
<Parameter Name="Service.Example_ASPNETCORE_ENVIRONMENT" Value="Development" />
<Parameter Name="Service.Example_InstanceCount" Value="-1" />
<Parameter Name="Service.Example_AuthorizationOptions_Policies_0_Name" Value="Users" />
<Parameter Name="Service.Example_AuthorizationOptions_Policies_0_Groups_0" Value="Domain Users" />
</Parameters>
</Application>
Example Application PublishProfiles (Local.1Node.xml):
<?xml version="1.0" encoding="utf-8"?>
<PublishProfile xmlns="http://schemas.microsoft.com/2015/05/fabrictools">
<ClusterConnectionParameters />
<ApplicationParameterFile Path="..\ApplicationParameters\Local.1Node.xml" />
</PublishProfile>
Should be unrelated, but example consumption of the settings:
internal sealed class Example : StatelessService
{
public Example(StatelessServiceContext context)
: base(context)
{ }
protected override IEnumerable<ServiceInstanceListener> CreateServiceInstanceListeners()
{
return new ServiceInstanceListener[]
{
new ServiceInstanceListener(serviceContext =>
new HttpSysCommunicationListener(serviceContext, "ServiceEndpoint", (url, listener) =>
{
ServiceEventSource.Current.ServiceMessage(serviceContext, $"Starting HttpSys on {url}");
return new WebHostBuilder()
.UseHttpSys(options =>
{
options.Authentication.Schemes = AuthenticationSchemes.Negotiate; // Microsoft.AspNetCore.Server.HttpSys
options.Authentication.AllowAnonymous = false;
}).ConfigureServices(services => services.AddSingleton<StatelessServiceContext>(serviceContext))
.UseContentRoot(Directory.GetCurrentDirectory())
.ConfigureAppConfiguration((hostingContext, config) =>
{
config.SetBasePath(Directory.GetCurrentDirectory());
config.AddServiceFabricConfiguration(FabricRuntime.GetActivationContext(), options => {
options.IncludePackageName=false;
});
})
.UseStartup<Startup>()
.UseServiceFabricIntegration(listener, ServiceFabricIntegrationOptions.None)
.UseUrls(url)
.Build();
}))
};
}
}
From that point forward everything is in the IConfiguration object as expected.
There are many ways to configure a service fabric application, and each approach will bring you to a different challenges.
SF team recommend the approach in the docs, because you can have a better version control of configurations, and makes harder to commit mistakes, as it is explicitly declared in a file, I've used a few different approaches because of limitations like yours, the follwoing approach might solve your problem:
Configure like the original approach, but with complex types stored as JSON values: it is the closest solution to the recommended design and you still can keep control of the configuration versions on source control.
It would be something like:
Settings.xml:
<?xml version="1.0" encoding="utf-8" ?>
<Settings xmlns... namespaces here...>
<Section Name="AuthorizationOptions">
<Parameter Name="Policies"/>
</Section>
</Settings>
ApplicationManifest.xml:
<?xml version="1.0" encoding="utf-8"?>
<ApplicationManifest ApplicationTypeName="ServiceFabric.ExampleType" ApplicationTypeVersion="1.0.0" xmlns:...namespaces....>
<Parameters>
<Parameter Name="Service.Example_ASPNETCORE_ENVIRONMENT" DefaultValue="" />
<Parameter Name="Service.Example_InstanceCount" DefaultValue="-1" />
<Parameter Name="Service.Example_AuthorizationOptions_Policies" DefaultValue="[]" />
</Parameters>
<ServiceManifestImport>
<ServiceManifestImport>
<ServiceManifestRef ServiceManifestName="Service.ExamplePkg" ServiceManifestVersion="1.0.0" />
<ConfigOverrides>
<ConfigOverride Name="Config">
<Settings>
<Section Name="AuthorizationOptions">
<Parameter Name="Policies" Value="[Service.Example_AuthorizationOptions_Policies]" />
</Section>
</Settings>
</ConfigOverride>
</ConfigOverrides>
<EnvironmentOverrides CodePackageRef="code">
<EnvironmentVariable Name="ASPNETCORE_ENVIRONMENT" Value="[Service.Example_ASPNETCORE_ENVIRONMENT]" />
</EnvironmentOverrides>
</ServiceManifestImport>
<DefaultServices>
<Service Name="Service.Example" ServicePackageActivationMode="ExclusiveProcess">
<StatelessService ServiceTypeName="Service.ExampleType" InstanceCount="[Service.Example_InstanceCount]">
<SingletonPartition />
</StatelessService>
</Service>
</DefaultServices>
</ApplicationManifest>
ApplicationParameters.xml
<?xml version="1.0" encoding="utf-8"?>
<Application Name="fabric:/ServiceFabric.Example" xmlns:...namespaces....>
<Parameters>
<Parameter Name="Service.Example_ASPNETCORE_ENVIRONMENT" Value="Development" />
<Parameter Name="Service.Example_InstanceCount" Value="-1" />
<Parameter Name="Service.Example_AuthorizationOptions_Policies" Value="[{'Name': 'User','Groups': ['Domain Users']}, {'Name': 'Admin','Groups': ['Administrators']}]" />
</Parameters>
</Application>
In your service code:
public class Policy
{
public string Name { get; set; }
public string[] Groups { get; set; }
}
var settings = this.Context.CodePackageActivationContext.GetConfigurationPackageObject("Config").Settings;
var authOptions = settings.Sections["AuthorizationOptions"].Parameters["Policies"].Value;
var obj = JsonConvert.DeserializeObject<Policy[]>(authOptions);
You could go a level further and store the entire
AuthorizationOptions as a JSON, but like said previously, more
generic it become, easier will be to commit mistakes and harder to find
configuration issues.

How to return more than 1 record on REST service with WSO2 DSS?

I'm using WSO2 DSS with MySQL database. If I request just 1 record from database, it works correctly. But when I try to select more than 1 registry in a REST service, it doesn't works. The error is:
{
"Fault": {
"faultcode": "soapenv:Server"
"faultstring": "Error while writing to the output stream using JsonWriter"
"detail": ""
}-
}
My data service:
<data name="item" transports="http https local">
<config enableOData="false" id="default">
<property name="carbon_datasource_name">mysql</property>
</config>
<query id="selectActiveItems" useConfig="default">
<sql>SELECT descricao FROM ITEM WHERE ativo = true and id_responsavel = ?</sql>
<result escapeNonPrintableChar="true" outputType="json">{ "_item": { "descricao":$descricao}}</result>
<param name="id_responsavel" ordinal="1" sqlType="INTEGER"/>
</query>
<resource method="POST" path="selectActiveItems">
<call-query href="selectActiveItems">
<with-param name="id_responsavel" query-param="id_responsavel"/>
</call-query>
</resource>
</data>
There is any property to set that I didn't set?
The correct output to response more than 1 record from database is:
<result escapeNonPrintableChar="true" outputType="json">
{"_itens":{"item": [ {"nome":$nome,"descricao":$descricao} ] }}
</result>
I've seen this before and could resolve by changing message builders/formatters.
See my answer here.

Struggling to use Cordova barcodescanner plugin

I'm trying to create an application with Cordova (developing in eclipse, using JBoss Hybrid Mobile Tools + CordovaSim).
I have inspired the code snippet that's giving me problems on this example.
The error I get is:
!JavaScript ERROR: TypeError: 'undefined' is not an object (evaluating 'cordova.plugins.barcodeScanner') on line 6 for http://localhost:54726/js/QRScan.js
QRScan.js only contains the following code (so basically as in the example):
var scanBut = document.getElementById('QRScanButton');
scanBut.onclick = quickScan();
function quickScan(){
cordova.plugins.barcodeScanner.scan(
function (result) {
var s = "Result: " + result.text + "<br/>" +
"Format: " + result.format + "<br/>" +
"Cancelled: " + result.cancelled;
resultDiv.innerHTML = s;
},
function (error) {
alert("Scanning failed: " + error);
}
);
}
And I made sure my index.html contains the following line at the appropriate spot:
<script type="text/javascript" src="cordova.js"></script>
Finally my xml file should be configured correctly, I imported the correct plugin, the file looks like:
<?xml version="1.0" encoding="UTF-8"?>
<widget xmlns="http://www.w3.org/ns/widgets" xmlns:gap="http://phonegap.com/ns/1.0"
id="csam.test" version="1.0.0">
<name>csam test</name>
<description>
A sample Apache Cordova application that responds to the
deviceready
event.
</description>
<author href="http://www.eclipse.org/thym" email="thym-dev#eclipse.org">
Eclipse.org -
Thym
</author>
<content src="index.html" />
<access origin="*" />
<preference name="fullscreen" value="true" />
<preference name="webviewbounce" value="true" />
<feature name="App">
<param name="android-package" value="org.apache.cordova.App" />
</feature>
<feature name="BarcodeScanner">
<param name="android-package" value="com.phonegap.plugins.barcodescanner.BarcodeScanner" />
<param name="ios-package" value="CDVBarcodeScanner" />
<param name="wp-package" value="BarcodeScanner" />
<param name="id" value="cordova-plugin-barcodescanner" />
</feature>
<engine name="android" version="4.0.1" />
</widget>
Plugins must wait for the deviceready event for use. Here is the piece of code from the demo which waits for deviceready added back in.
document.addEventListener("deviceready", init, false);
function init() {
document.querySelector("#startScan").addEventListener("touchend", startScan, false);
var scanBut = document.getElementById('QRScanButton');
scanBut.onclick = quickScan();
}

GWT remote logging going to System.out instead of log file

I have setup gwt remote logging based on the gwt documentation, however my logs are going to System.out instead of being written to a log file.
My gwt module looks like:
<module rename-to='ezdappserver'>
<inherits name="com.google.gwt.logging.Logging"/>
<set-property name="gwt.logging.simpleRemoteHandler" value="ENABLED" />
<set-property name="gwt.logging.logLevel" value="FINEST"/>
<set-property name="gwt.logging.enabled" value="TRUE"/>
<set-property name="gwt.logging.consoleHandler" value="ENABLED" />
<set-property name="gwt.logging.popupHandler" value="DISABLED" />
</module>
My servlet definition is setup like:
<servlet>
<servlet-name>remoteLogging</servlet-name>
<servlet-class>com.google.gwt.logging.server.RemoteLoggingServiceImpl</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>remoteLogging</servlet-name>
<url-pattern>/ezdappserver/remote_logging</url-pattern>
</servlet-mapping>
When an error is logged I see output in my console like so:
Mar 26, 2014 2:10:36 PM com.google.gwt.logging.server.RemoteLoggingServiceUtil logOnServer
SEVERE: Exception caught: (NotFoundError)
....Rest of error....
I was expecting this output to be written to a log file somewhere in my war. Also, I would really like to be able to specify where this file is located, however I haven't been able to find any documentation on that either.
Any help would be much appreciated.
NOTE: I am not running this through dev mode, this is with compiled code.
Thanks!
Try below options also in gwt.xml based on your requirement:
<!-- This handler sends log messages to the server, where they will be logged using the server side logging mechanism. -->
<set-property name="gwt.logging.simpleRemoteHandler" value="ENABLED" />
<!-- Logs by calling method GWT.log. These messages can only be seen in Development Mode in the DevMode window. -->
<set-property name="gwt.logging.developmentModeHandler" value="ENABLED" />
<!-- These messages can only be seen in Development Mode in the DevMode window. -->
<set-property name="gwt.logging.systemHandler" value="ENABLED" />
<!-- Logs to the popup which resides in the upper left hand corner of application when this handler is enabled. -->
<set-property name="gwt.logging.popupHandler" value="DISABLED" />
<!-- Logs to the javascript console, which is used by Firebug Lite (for IE), Safari and Chrome. -->
<set-property name="gwt.logging.consoleHandler" value="DISABLED"/>
<!-- Logs to the firebug console. -->
<set-property name="gwt.logging.firebugHandler" value="DISABLED" />
If above configuration are still not working for you then try below code along with above configuration.
Add log4j.xml file to define the log file location with log level
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">
<appender name="STDOUT" class="org.apache.log4j.ConsoleAppender">
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="DT=> %d [%.4t] %-5p %c{1} - %m%n" />
</layout>
</appender>
<appender name="SERVER_FILE_LOG" class="org.apache.log4j.RollingFileAppender">
<param name="File" value="${jboss.server.log.dir}/logs/DataTools_Server.log" />
<param name="Append" value="true" />
<param name="MaxFileSize" value="5MB" />
<param name="MaxBackupIndex" value="10" />
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%d [%.4t] %-5p [%c] %m%n" />
</layout>
</appender>
<appender name="CLIENT_FILE_LOG" class="org.apache.log4j.RollingFileAppender">
<param name="File" value="${jboss.server.log.dir}/logs/DataTools_Client.log" />
<param name="Append" value="true" />
<param name="MaxFileSize" value="5MB" />
<param name="MaxBackupIndex" value="10" />
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%d [%.4t] %-5p %m%n" />
</layout>
</appender>
<category name="com.x.y.server">
<priority value="DEBUG" />
<appender-ref ref="SERVER_FILE_LOG" />
<appender-ref ref="STDOUT" />
</category>
<category name="gwtRemoteLogging">
<priority value="ERROR" />
<appender-ref ref="CLIENT_FILE_LOG" />
</category>
<root>
<priority value ="ERROR" />
<appender-ref ref="SERVER_FILE_LOG" />
</root>
</log4j:configuration>
Define you own logging servlet by implementing RemoteLoggingService
import java.util.logging.Level;
import java.util.logging.LogRecord;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import com.google.gwt.logging.server.StackTraceDeobfuscator;
import com.google.gwt.logging.shared.RemoteLoggingService;
import com.google.gwt.user.server.rpc.RemoteServiceServlet;
import org.apache.log4j.Logger;
/**
* The Class GwtRemoteLogging.
*/
#SuppressWarnings("serial")
public class GwtRemoteLogging extends RemoteServiceServlet implements RemoteLoggingService {
/** The Constant logger. */
private StackTraceDeobfuscator deobfuscator = null;
private final static Logger logger = Logger.getLogger("gwtRemoteLogging");
#Override
public void init(ServletConfig config) throws ServletException {
super.init(config);
}
/**
* Logs a Log Record which has been serialized using GWT RPC on the server.
*
* #return either an error message, or null if logging is successful.
*/
public final String logOnServer(LogRecord lr) {
try {
if (lr.getLevel().equals(Level.SEVERE)) {
logger.error(lr.getMessage(),lr.getThrown());
} else if (lr.getLevel().equals(Level.INFO)) {
logger.info(lr.getMessage(),lr.getThrown());
} else if (lr.getLevel().equals(Level.WARNING)) {
logger.warn(lr.getMessage(),lr.getThrown());
} else if (lr.getLevel().equals(Level.FINE)) {
logger.debug(lr.getMessage(),lr.getThrown());
} else {
logger.trace(lr.getMessage(),lr.getThrown());
}
} catch (Exception e) {
logger.error("Remote logging failed", e);
return "Remote logging failed, check stack trace for details.";
}
return null;
}
/**
* By default, this service does not do any deobfuscation. In order to do server side
* deobfuscation, you must copy the symbolMaps files to a directory visible to the server and
* set the directory using this method.
*
* #param symbolMapsDir
*/
public void setSymbolMapsDirectory(String symbolMapsDir) {
if (deobfuscator == null) {
deobfuscator = new StackTraceDeobfuscator(symbolMapsDir);
} else {
deobfuscator.setSymbolMapsDirectory(symbolMapsDir);
}
}
}
web.xml
<servlet>
<servlet-name>remoteLogServlet</servlet-name>
<servlet-class>com.x.y.server.servlet.GwtRemoteLogging</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>remoteLogServlet</servlet-name>
<url-pattern>/ezdappserver/remote_logging</url-pattern>
</servlet-mapping>
The RemoteServiceServlet uses java.util.logging to log, and by default it logs to the console (System.err, not System.out BTW).
If you want to log to a file, then you have to configure java.util.logging; either editing your global lib/logging.properties (not recommended), using your own config file that you pass to the JVM using the java.util.logging.config.file system property, or programmatically.
Depending on your servlet container, it can be configured by different means. For instance, Tomcat will read a logging.properties file in your WEB-INF/classes: http://tomcat.apache.org/tomcat-7.0-doc/logging.html#Using_java.util.logging_(default)

Error While integrating Dynamic Jasper with Struts2

This the error i get while integrating struts 2 and dynamic jasper
Caused by: There is no result type defined for type 'dynamicjasper' mapped with name 'success'
it caused because of my report.xml where i have defined the result type dynamic-jasper
<package name="report" extends="struts-default,jasperreports-default">
<result-types>
<result-type name="tiles" class="org.apache.struts2.views.tiles.TilesResult"></result-type>
<result-type name="dynamic-jasper" class="ar.com.fdvs.dj.struts2.DJStruts2Result"/>
</result-types>
<action name="ShowReport" class="hris.report.action.GetReportAction">
<result name="success" type="dynamic-jasper">
<param name="dynamicReport">dr</param>
<param name="layoutManager">classic</param>
<param name="format">PDF</param>
</result>
</action>
</package>