Java EE 6 and JAXRPCSecurity - osgi

I'am trying convert my Java EE 5 (GlassFish v2, Metro 2.1.1) application to Java EE 6 (GlassFish 3.1.2, Metro 2.2.1-1). I have problem with webservice client, which security is based on JAXRPCSecuirty. JAXRPCSecurity configuration:
private final static String SECURITY_CONFIG =
"<?xml version=\"1.0\" encoding=\"UTF-8\"?> "+
"<xwss:JAXRPCSecurity xmlns:xwss=\"http://java.sun.com/xml/ns/xwss/config\"> " +
" <xwss:Service> " +
" <xwss:SecurityConfiguration dumpMessages=\"true\"> " +
" <xwss:Sign includeTimestamp=\"false\"> " +
" <xwss:X509Token certificateAlias=\"certificate_alias\" /> " +
" <xwss:CanonicalizationMethod disableInclusivePrefix=\"true\" /> " +
" <xwss:SignatureTarget type=\"xpath\" value=\"//SOAP-ENV:Body\"> " +
" <xwss:Transform algorithm=\"http://www.w3.org/2001/10/xml-exc-c14n#\" " +
" disableInclusivePrefix=\"true\" /> " +
" </xwss:SignatureTarget> " +
" </xwss:Sign> " +
" </xwss:SecurityConfiguration> " +
" </xwss:Service> " +
" <xwss:SecurityEnvironmentHandler> " +
" SecurityCallbackHandler " +
" </xwss:SecurityEnvironmentHandler> " +
"</xwss:JAXRPCSecurity>";
And how I set this configuration to webservice client:
public void configureSecurity() throws SITAWebServiceException {
String JAXRPCSecurityXML = completeJAXRPCSecurityXML(alias, keyStore, callbackHandler, dumpMessage);
byte[] JAXRPCSecurityXMLBytes = convertJAXRPSecurityXMLToBytes(JAXRPCSecurityXML);
XWSSecurityConfiguration sc = createXWSSecurityConfiguration(JAXRPCSecurityXMLBytes);
((BindingProvider) port).getRequestContext().put(XWSSecurityConfiguration.MESSAGE_SECURITY_CONFIGURATION, sc);
}
private XWSSecurityConfiguration createXWSSecurityConfiguration(final byte[] JAXRPCSecurityXML) throws SITAWebServiceException {
InputStream is = new ByteArrayInputStream(JAXRPCSecurityXML);
try {
return new SecurityConfiguration(is);
} catch (XWSSecurityException e) {
throw new SITAWebServiceException("XWSSecurityConfiguration problem.", e);
} finally {
closeInputStream(is);
}
}
With GlassFish v2 and Metro 2.1.1, everything works fine. But GlassFish 3 uses OSGi based Metro (webservices-api-osgi and webservice-osgi) and classes from package com.sun.xml.xwss are no longer visible (isn't exproted) so I constantly get this Exception:
java.lang.NoClassDefFoundError: com/sun/xml/xwss/XWSSecurityConfiguration
Is there some solution how export package com.sun.xml.xwss or way how to change JAXRPCSecurity to something other/better?
Thanks.

Related

Spring Data MongoDb - Criteria equivalent to a given query that uses $expr

I have a collection with documents like this:
{
"_id" : ObjectId("5a8ec4620cd3c2a4062548ec"),
"start" : 20,
"end" : 80
}
and I want to show the documents that overlap a given percentage (50%) with an interval (startInterval = 10, endInterval = 90).
I calculate the overlaping section with the following formula:
min(end , endInterval) - max(start, startInterval ) / (endInterval - startInterval)
In this example:
min(80,90) - max(20,10) / (90-10) = (80-20)/80 = 0.75 --> 75%
Then this document will be shown, as 75% is greater than 50%
I expressed this formula in mongo shell as:
db.getCollection('variants').find(
{
$expr: {
$gt: [
{
$divide: [
{
$subtract: [
{ $min: [ "$end", endInterval ] }
,
{ $max: [ "$start", startInterval ] }
]
}
,
{ $subtract: [ endInterval, startInterval ] }
]
}
,
overlap
]
}
}
)
where
overlap = 0.5, startInterval = 10 and endInterval= 90
It works fine in mongo shell.
I'm asking for an equivalent way to calculate this using Spring Data Criteria, since the $expr functionality I used in mongo shell is still to be implemented in Spring Data Mongo.
Currently I'm using Spring Boot 2.0.0, Spring Data MongoDb 2.0.5 and mongodb 3.6.
Thanks a lot for your time.
There is an open issue to add support for $expr : https://github.com/spring-projects/spring-data-mongodb/issues/2750
In the meantime, you can use an BasicQuery:
BasicQuery query = new BasicQuery("{ $expr: {'$gt': ['$results.cache.lastHit', '$results.cache.expiration']}}");
return ofNullable(mongoTemplate.findAndModify(query, updateDefinition, XXXX.class));
You can even concatenate your existing Criteria with BasicQuery, keeping it exclusive to the $expr:
Criteria criteria = Criteria.where("results.cache.cacheUpdateRetriesLeft").gt(4);
BasicQuery query = new BasicQuery("{ $expr: {'$gt': ['$results.cache.lastHit', '$results.cache.expiration']}}");
query.addCriteria(criteria);
return ofNullable(mongoTemplate.findAndModify(query, updateDefinition, XXXX.class));
Just in case it is helpful for somebody, I finally solved my problem using $redact.
String redact = "{\n" +
" \"$redact\": {\n" +
" \"$cond\": [\n" +
" {\n" +
" \"$gte\": [\n" +
" {\n" +
" \"$divide\": [\n" +
" {\n" +
" \"$subtract\": [\n" +
" {\n" +
" \"$min\": [\n" +
" \"$end\",\n" +
" " + endInterval + "\n" +
" ]\n" +
" },\n" +
" {\n" +
" \"$max\": [\n" +
" \"$start\",\n" +
" " + startInterval + "\n" +
" ]\n" +
" }\n" +
" ]\n" +
" },\n" +
" {\n" +
" \"$subtract\": [\n" +
" " + endInterval + "\n" +
" " + startInterval + "\n" +
" ]\n" +
" }\n" +
" ]\n" +
" },\n" +
" " + overlap + "\n" +
" ]\n" +
" },\n" +
" \"$$KEEP\",\n" +
" \"$$PRUNE\"\n" +
" ]\n" +
" }\n" +
" }";
RedactAggregationOperation redactOperation = new RedactAggregationOperation(
Document.parse(redact)
);
where RedactAggregationOperation is
public class RedactAggregationOperation implements AggregationOperation {
private Document operation;
public RedactAggregationOperation (Document operation) {
this.operation = operation;
}
#Override
public Document toDocument(AggregationOperationContext context) {
return context.getMappedObject(operation);
}
}
As you mentioned, Spring Data Mongo currently does not support $expr, so I have to use custom BSON document, and reflection of MongoTemplate.
public List<Variant> listTest() throws Exception {
double overlap = 0.5;
int startInterval = 10;
int endInterval= 90;
String jsonQuery = "{$expr:{$gt:[{$divide:[{$subtract:[{$min:[\"$end\","+endInterval+"]},{$max:[\"$start\","+startInterval+"]}]},{$subtract:["+endInterval+","+startInterval+"]}]},"+overlap+"]}}";
Document query = Document.parse(jsonQuery);
Method doFind = MongoTemplate.class.getDeclaredMethod("doFind", String.class, Document.class,Document.class,Class.class);
doFind.setAccessible(true);
return (List<Variant>) doFind.invoke(mongoTemplate, "variants", query, new Document(), Variant.class);
}
#NoArgsConstructor #Getter #Setter #ToString
public static class Variant{
int start;
int end;
}
As you may see, field mapping works OK.
Used Spring Data Mongo artifact is org.springframework:data.spring-data-mongodb:2.1.5.RELEASE
Support for $expr operator in spring-data-mongodb library is still non-existent. However there is a work around solution using MongoTemplate to solve this problem -
Aggregation.match() provides an overloaded method that accepts AggregationExpression as a parameter. This method can be used to create the query for $match aggregation pipeline with $expr operator as below -
Example usage of AggregationExpression for $match operator -
Aggregation aggregationQuery = Aggregation.newAggregation(Aggregation.match(AggregationExpression.from(MongoExpression.create("'$expr': { '$gte': [ '$foo', '$bar'] }"))));
mongoTemplate.aggregate(aggregationQuery, Entity.class);
Above code is the equivalent of query -
db.collection.aggregate([{"$match": {"$expr": {"$gte: ["$foo", "$bar"]}}}]);

Oracle: FROM keyword not found where expected error in select statment

I am getting below error in my function.
Error: FROM keyword not found where expected
And here is my Function:
private int BauteilLieferzeit(string Materianummer)
{
try
{
OracleCommand cmd = new OracleCommand(
" Select MATNR, AVG_DAUER" +
" AVG " +
" (DATEDIFF " +
" (mi, Z.APL_ANFDATUM, " +
" Z.STA_LIEFERDATUM)) " +
" as AVG_DAUER " +
" from ZDATA AS Z " +
" where MATNR = '" + Materianummer + "'"
, OraVerbindung._conn);
OracleDataReader r = cmd.ExecuteReader();
if (r.HasRows)
{
int Restminuten = OraVerbindung.Lieferzeit;
while (r.Read())
{
Restminuten = r.GetInt32(1);
}
return Restminuten;
}
else
{
return OraVerbindung.Lieferzeit;
}
}
catch
{
return OraVerbindung.Lieferzeit;
}
}
In Oracle this is not a valid syntax
from ZDATA AS Z
use
from ZDATA Z
instead (remove "AS")
Additionally consider the use of bind variables instead of string concatenation:
" where MATNR = '" + Materianummer + "'"
search for "SQL Injection".
Use this. Included the issue highlighted by Marmite also. But the error FROM keyword not found where expected would be due to missing comma in select statement.
Edit: Removed AVG_DAUER column as it is getting derived later.
private int BauteilLieferzeit(string Materianummer)
{
try
{
OracleCommand cmd = new OracleCommand(
" Select MATNR," +
" AVG " +
" (DATEDIFF " +
" (mi, Z.APL_ANFDATUM, " +
" Z.STA_LIEFERDATUM)) " +
" as AVG_DAUER " +
" from ZDATA Z " +
" where MATNR = '" + Materianummer + "'"
, OraVerbindung._conn);
OracleDataReader r = cmd.ExecuteReader();
if (r.HasRows)
{
int Restminuten = OraVerbindung.Lieferzeit;
while (r.Read())
{
Restminuten = r.GetInt32(1);
}
return Restminuten;
}
else
{
return OraVerbindung.Lieferzeit;
}
}
catch
{
return OraVerbindung.Lieferzeit;
}
}

What's the most appropriate way to compare dates in this hibernate query?

I have a Spring MVC REST service that accepts two #RequestParams called from and to. These are parsed as java.util.Date and passed to the following method in my DAO class.
#Override
public List<ErrorsDTOEntity> getAllErrors(Date from, Date to) {
try {
Query query = getSession().createQuery(
"SELECT NEW com.mydomain.esb.jpa.dto.ErrorsDTOEntity(ee, ec.message) "
+ "FROM ErrorsEntity ee, EventCodeEntity ec "
+ "WHERE ee.responseTime > " + from.getTime() + " "
+ "AND ee.responseTime < " + to.getTime() + " "
+ "AND ee.serviceResponseCode = ec.code "
+ "GROUP BY ee.domainName, ee.serviceName, ec.message, ee.serviceErrorCount, ee.errorTimestamp, "
+ "ee.deviceName, ee.servErrId, ee.serviceResponseCode, ee.elapsedTime, ee.forwardTime, "
+ "ee.responseCompletionTime, ee.responseSizeAverage, ee.requestSizeAverage, ee.responseTime "
+ "ORDER BY ee.domainName, ee.serviceName, ec.message, ee.errorTimestamp");
#SuppressWarnings("unchecked")
List<ErrorsDTOEntity> services = (List<ErrorsDTOEntity>) query.list();
return services;
} catch (HibernateException hex) {
hex.printStackTrace();
}
return null;
}
This is throwing the following SQL error:
org.hibernate.exception.SQLGrammarException: ORA-00932: inconsistent datatypes: expected TIMESTAMP got NUMBER
What's the proper way to structure this query so I can only fetch results between the from and to dates?
I figured it out, this works:
#Override
public List<ErrorsDTOEntity> getAllErrors(Date from, Date to) {
try {
Query query = getSession().createQuery(
"SELECT NEW com.mydomain.esb.jpa.dto.ErrorsDTOEntity(ee, ec.message) "
+ "FROM ErrorsEntity ee, EventCodeEntity ec "
+ "WHERE ee.responseTime > :from "
+ "AND ee.responseTime < :to "
+ "AND ee.serviceResponseCode = ec.code "
+ "GROUP BY ee.domainName, ee.serviceName, ec.message, ee.serviceErrorCount, ee.errorTimestamp, "
+ "ee.deviceName, ee.servErrId, ee.serviceResponseCode, ee.elapsedTime, ee.forwardTime, "
+ "ee.responseCompletionTime, ee.responseSizeAverage, ee.requestSizeAverage, ee.responseTime "
+ "ORDER BY ee.domainName, ee.serviceName, ec.message, ee.errorTimestamp");
query.setTimestamp("from", from);
query.setTimestamp("to", to);
#SuppressWarnings("unchecked")
List<ErrorsDTOEntity> services = (List<ErrorsDTOEntity>) query.list();
return services;
} catch (HibernateException hex) {
hex.printStackTrace();
}
return null;
}

List domain users with wmi

I want to list all users of a Windows domain with WMI in C#.
Can someone help me?
Here is my code:
try
{
ConnectionOptions connection = new ConnectionOptions();
connection.Username = user;
connection.Authority = "ntlmdomain:" + domain;
connection.Password = pwd;
SelectQuery query = new SelectQuery("SELECT * FROM Win32_UserAccount");
ManagementScope scope = new ManagementScope(#"\\FullComputerName\\root\\CIMV2", connection);
scope.Connect();
ManagementObjectSearcher searcher = new ManagementObjectSearcher(scope, query);
foreach (ManagementObject queryObj in searcher.Get())
{
Console.WriteLine("Account Type: " + queryObj["AccountType"]);
Console.WriteLine("Caption: " + queryObj["Caption"]);
Console.WriteLine("Description: " + queryObj["Description"]);
Console.WriteLine("Disabled: " + queryObj["Disabled"]);
Console.WriteLine("Domain: " + queryObj["Domain"]);
Console.WriteLine("Full Name: " + queryObj["FullName"]);
Console.WriteLine("Local Account: " + queryObj["LocalAccount"]);
Console.WriteLine("Lockout: " + queryObj["Lockout"]);
Console.WriteLine("Name: " + queryObj["Name"].ToString());
Console.WriteLine("Password Changeable: " + queryObj["PasswordChangeable"]);
Console.WriteLine("Password Expires: " + queryObj["PasswordExpires"]);
Console.WriteLine("Password Required: " + queryObj["PasswordRequired"]);
Console.WriteLine("SID: " + queryObj["SID"]);
Console.WriteLine("SID Type: " + queryObj["SIDType"]);
Console.WriteLine("Status: " + queryObj["Status"]);
Console.WriteLine("");
}
}
catch (ManagementException err)
{
Console.WriteLine("An error occured while querying for WMI data: " + err.Message);
}
catch (System.UnauthorizedAccessException unauthorizedErr)
{
Console.WriteLine("Connection error " + "(user name or password might be incorrect): " + unauthorizedErr.Message);
}
There's a typo in the namespace path in your ManagementScope constructor:
ManagementScope scope = new ManagementScope(#"\\FullComputerName\\root\\CIMV2", connection);
The string should be either #"\\FullComputerName\root\CIMV2" or "\\\\FullComputerName\\root\\CIMV2".
Note that you cannot specify the user account for local connections. So if FullComputerName is a local computer, use this instead:
ManagementScope scope = new ManagementScope("root\\CIMV2");

What is the Xpath expression to select all nodes that have text when using the Firefox WebDriver?

I would like to select all nodes, that have text in them.
In this example the outer shouldBeIgnored tag, should not be selected:
<shouldBeIgnored>
<span>
the outer Span should be selected
</span>
</shouldBeIgnored>
Some other posts suggest something like this: //*/text().
However, this doesn't work in firefox.
This is a small UnitTest to reproduce the problem:
public class XpathTest {
final WebDriver webDriver = new FirefoxDriver();
#Test
public void shouldNotSelectIgnoredTag() {
this.webDriver.get("http://www.s2server.de/stackoverflow/11773593.html");
System.out.println(this.webDriver.getPageSource());
final List<WebElement> elements = this.webDriver.findElements(By.xpath("//*/text()"));
for (final WebElement webElement : elements) {
assertEquals("span", webElement.getTagName());
}
}
#After
public void tearDown() {
this.webDriver.quit();
}
}
If you want to select all nodes that contain text then you can use
//*[text()]
Above xpath will look for any element which contains text. Notice the text() function which is used to determine if current node has text or not.
In your case it will select <span> tag as it contains text.
You can call a javascript function, which shall return you text nodes:
function GetTextNodes(){
var lastNodes = new Array();
$("*").each(function(){
if($(this).children().length == 0)
lastNodes.push($(this));
});
return lastNodes;
}
Selenium WebDriver code:
IJavaScriptExecutor jscript = driver as IJavaScriptExecutor;
List<IWebElement> listTextNodes = jscript.ExecuteScript("return GetTextNodes();");
FYI: Something like might work for you.
I see no reason why this wouldn't work
(by java)
text = driver.findElement(By.xpath("//span")).getText()
If in the odd case that doesnt work:
text = driver.findElement(By.xpath("//span")).getAttribute("innerHTML")
Finally i found out that there is no way to do it with xpath (because XPaths text() selects also the innerText of a node). As workaround i have to inject Java Script that returns all elements, selected by an XPath, that has some text.
Like this:
public class XpathTest
{
//#formatter:off
final static String JS_SCRIPT_GET_TEXT = "function trim(str) { " +
" return str.replace(/^\s+|\s+$/g,''); " +
"} " +
" " +
"function extractText(element) { " +
" var text = ''; " +
" for ( var i = 0; i < element.childNodes.length; i++) { " +
" if (element.childNodes[i].nodeType === Node.TEXT_NODE) { " +
" nodeText = trim(element.childNodes[i].textContent); " +
" " +
" if (nodeText) { " +
" text += element.childNodes[i].textContent + ' '; " +
" } " +
" } " +
" } " +
" " +
" return trim(text); " +
"} " +
" " +
"function selectElementsHavingTextByXPath(expression) { " +
" " +
" result = document.evaluate(\".\" + expression, document.body, null, " +
" XPathResult.ANY_TYPE, null); " +
" " +
" var nodesWithText = new Array(); " +
" " +
" var node = result.iterateNext(); " +
" while (node) { " +
" if (extractText(node)) { " +
" nodesWithText.push(node) " +
" } " +
" " +
" node = result.iterateNext(); " +
" } " +
" " +
" return nodesWithText; " +
"} " +
"return selectElementsHavingTextByXPath(arguments[0]);";
//#formatter:on
final WebDriver webDriver = new FirefoxDriver();
#Test
public void shouldNotSelectIgnoredTag()
{
this.webDriver.get("http://www.s2server.de/stackoverflow/11773593.html");
final List<WebElement> elements = (List<WebElement>) ((JavascriptExecutor) this.webDriver).executeScript(JS_SCRIPT_GET_TEXT, "//*");
assertFalse(elements.isEmpty());
for (final WebElement webElement : elements)
{
assertEquals("span", webElement.getTagName());
}
}
#After
public void tearDown()
{
this.webDriver.quit();
}
}
I modified the UnitTest that the example testable.
One problem with locating text nodes is that even empty strings are considered as valid text nodes (e.g
<tag1><tag2/></tag1>
has no text nodes but
<tag1> <tag2/> </tag1>
has 2 text nodes, one with 2 spaces and another with 4 spaces )
If you want only the text nodes that have non-empty text, here is one way to do it:
//text()[string-length(normalize-space(.))>0]
or to get their parent elements
//*[text()[string-length(normalize-space(.))>0]]

Resources