Struts 1.0.2 to 1.2.9 - struts-1

i am trying to update my application from struts 1.01 to struts 1.29 and I am facing issues with digester class and ActionFormBeans as they are not available in struts package. Can someone please help me on how can I resolve it
// Initialize a new Digester instance
Digester digester = new Digester();
digester.push(configBean);
digester.setDebug(detail);
digester.setValidating(validating);
// Register our local copy of the DTDs that we can find
for (int i = 0; i < registrations.length; i += 2) {
URL url = this.getClass().getResource(registrations[i + 1]);
if (url != null) {
digester.register(registrations[i], url.toString());
}
}
// Configure the processing rules
digester.addObjectCreate("struts-config/action-mappings/action",
mappingClass, "className");
digester.addSetProperties("struts-config/action-mappings/action");
digester.addSetNext("struts-config/action-mappings/action",
"addMapping",
"org.apache.struts.action.ActionMapping");
digester.addSetProperty(
"struts-config/action-mappings/action/set-property",
"property", "value");
digester.addObjectCreate(
"struts-config/action-mappings/action/forward", forwardClass,
"className");
digester.addSetProperties("struts-config/action-mappings/action/forward");
digester.addSetNext("struts-config/action-mappings/action/forward",
"addForward",
"org.apache.struts.action.ActionForward");
digester.addSetProperty(
"struts-config/action-mappings/action/forward/set-property",
"property", "value");
digester.addObjectCreate("struts-config/form-beans/form-bean",
formBeanClass, "className");
digester.addSetProperties("struts-config/form-beans/form-bean");
digester.addSetNext("struts-config/form-beans/form-bean",
"addFormBean",
"org.apache.struts.action.ActionFormBean");
digester.addSetProperty(
"struts-config/form-beans/form-bean/set-property", "property",
"value");
digester.addObjectCreate("struts-config/global-forwards/forward",
forwardClass, "className");
digester.addSetProperties("struts-config/global-forwards/forward");
digester.addSetNext("struts-config/global-forwards/forward",
"addForward",
"org.apache.struts.action.ActionForward");
digester.addSetProperty(
"struts-config/global-forwards/forward/set-property",
"property", "value");
return digester;

Related

Concurrent transaction issue in keycloak user attribute (java spring boot)

I managed our customer's point as keycloak user attribute.
I set 'point' as user attribute, and I handled it with keycloak api in Java Spring boot.
So, flow of update point is..
point = getPointByUserEmail(userEmail); // get point to update.
point -= 10; // minus point
updatePointByUserEmail(userEmail, point); // update point
public Long getPointByUserEmail(String userEmail) {
UserRepresentation userRepresentation = usersResource.search(userEmail, true).get(0);
Map<String, List<String>> attributes = userRepresentation.getAttributes();
if (attributes == null || attributes.get("point") == null)
return null;
return Long.parseLong(attributes.get("point").get(0));
}
public void updatePointByUserEmail(String userEmail, Long point) {
UserRepresentation userRepresentation = usersResource.search(userEmail, true).get(0);
UserResource userResource = usersResource.get(userRepresentation.getId());
Map<String, List<String>> attributes = userRepresentation.getAttributes();
attributes.put("point", Arrays.asList(point.toString()));
userRepresentation.setAttributes(attributes);
userResource.update(userRepresentation);
}
It works well.
But my problem is when user requests simultaneously at almost same time to update point,
It doesn't work well.
For example, there are 2 requests at once. (initial point = 100, minus point per request = 10)
I expected it would be 80 point, because 100 - (10 * 2) = 80
But it was 90 point.
So I think I need to set isolation level to transaction in point.
In JPA, there is #Lock annotation... but,, how can I do it in keycloak ?
Is there any way that I can set isolation level in keycloak api so that my function will work well ?
This is code when I handle point,
public class someController {
public ResponseEntity<String> methodToHandleRequest(#RequestBody Dto param, HttpServletRequest request) {
...
Long point = null;
try {
point = userAttributesService.getPoint();
if (point == null)
throw new NullPointerException();
} catch (Exception e) {
e.printStackTrace();
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("error");
}
if (point < 10)
return ResponseEntity.status(HttpStatus.PAYMENT_REQUIRED).body("you have at least 10 points " + "(current: " + point + ")");
userAttributesService.updatePoint(point - 10);
...
}
I tried managing point to use JPA, it would handle user attribute using DB.
But, when I updated user attribute data in DB.
I tried managing point to connect JPA with keycloak DB.
And I found DB table for user attribute, and there is point value !
But it doesn't update in keycloak when I updated point in DB.... :'(

ASP.NET Web API - Swagger , create multiple views

I am using Swagger with ASP.NET Web API application. If I visit URL http://localhost:5000/swagger
Swagger list all the controllers and actions defined in these controllers. Lets say I have five controllers and each controller has one action. I want to create multiple views such that when
user says http://localhost:5000/swagger/v1 he gets to see all controllers
when user says http://localhost:5000/swagger/v2 he gets to see only one controller
when user says http://localhost:5000/swagger/v3 he gets to see only two controller
Basically I am trying to restrict access to controller via swagger. Based on user requirement, I will share specific URL with them.
Is it possible to achieve this with Swagger?
Yes, you can do exactly what you want.
You should do the following steps:
Create a class that inherits from IDocumentFilter and register it in SwaggerConfig.cs as follows c.DocumentFilter<HideSwaggerEndpointsDocumentFilter>();
Example:
public class HideSwaggerEndpointsDocumentFilter : IDocumentFilter
{
public void Apply(SwaggerDocument swaggerDoc, SchemaRegistry schemaRegistry, IApiExplorer apiExplorer)
{
//enter code here
}
}
This filter is loaded once you load the swagger page. Inside it, you have control over each and every controller action. You can delete some actions based on any criteria decided by you.
Deleting them is a bit tricky, I do it as follows:
foreach (var apiDescription in apiExplorer.ApiDescriptions)
{
var route = "/" + apiDescription.RelativePath.Substring(0, (apiDescription.RelativePath.IndexOf('?') != -1) ? apiDescription.RelativePath.IndexOf('?') : apiDescription.RelativePath.Length).TrimEnd('/');
var path = swaggerDoc.paths[route];
switch (apiDescription.HttpMethod.Method)
{
case "DELETE": path.delete = null; break;
case "GET": path.get = null; break;
case "HEAD": path.head = null; break;
case "OPTIONS": path.options = null; break;
case "PATCH": path.patch = null; break;
case "POST": path.post = null; break;
case "PUT": path.put = null; break;
default: throw new ArgumentOutOfRangeException("Method name not mapped to operation");
}
if (path.delete == null && path.get == null &&
path.head == null && path.options == null &&
path.patch == null && path.post == null && path.put == null)
{
swaggerDoc.paths.Remove(route);
}
}
Disclaimer:
If you put the above code in your DocumentFilter class it will delete all actions regardless of the given URL.
So we are in the final step, where you basically do your desired logic.
Inside the (foreach (var apiDescription in apiExplorer.ApiDescriptions)) you can play and do your custom logic. You have access to HttpContext.Current, so you can get the current URL.
If you don't want to delete the current action have something like this, before the swaggerDoc.paths.Remove(route);.
bool forDelete = false; // your custom logic when it should be deleted
if (!forDelete)
{
return;
}
Hope this helps you.

CrmServiceClient.GetEntityMetadata returns wrong information

Using the Microsoft.CrmSdk assembly to generate entities in Dynamics 365 for Customer Engagement (version 9), I found out that the method GetEntityMetadata from CrmServiceClient does not get the most uptodate information from entities.
Here the code to show you:
using (var svc = new CrmServiceClient(strConn))
{
EntityMetadata em = svc.GetEntityMetadata(PREFIX + TABLE_NAME_D, EntityFilters.Attributes);
if (em == null)
{
Console.WriteLine($"Create entity [{PREFIX + TABLE_NAME_D}]");
CreateEntityRequest createRequest = new CreateEntityRequest
{
Entity = new EntityMetadata
{
SchemaName = PREFIX + TABLE_NAME_D,
LogicalName = PREFIX + TABLE_NAME_D,
DisplayName = new Label(TABLE_LABEL, 1036),
DisplayCollectionName = new Label(TABLE_LABEL_P, 1036),
OwnershipType = OwnershipTypes.UserOwned,
},
PrimaryAttribute = new StringAttributeMetadata
{
SchemaName = PREFIX + "name",
MaxLength = 30,
FormatName = StringFormatName.Text,
DisplayName = new Label("Residence", 1036),
}
};
CreateEntityResponse resp = (CreateEntityResponse)svc.Execute(createRequest);
em = svc.GetEntityMetadata(PREFIX + TABLE_NAME_D, EntityFilters.All);
// At this point, em is null!!!
}
}
After the createResponse is received, the entity is well created in Dynamics, but still the GetEntityMetadata called just after is still null. If I wait a few seconds and make another call, the response is now correct. But that's horrible!
Is there any way to "force" the refresh of the response?
Thanks.
Ok I found it! It's linked to a caching mechanism.
One must use the function ResetLocalMetadataCache to clean the cache, but there seems to be an issue with this function.
It will only works by passing the entity name in parameter (if you call it without parameter, it is supposed to clean the entire cache but that does not work for me).
EntityMetadata em = svc.GetEntityMetadata(TABLE_NAME_D, EntityFilters.All); // Request sent
em = svc.GetEntityMetadata(TABLE_NAME_D, EntityFilters.All); // Cache used
svc.ResetLocalMetadataCache(); // No effect?!
em = svc.GetEntityMetadata(TABLE_NAME_D, EntityFilters.All); // Cache used
em = svc.GetEntityMetadata(TABLE_NAME_D, EntityFilters.All); // Cache used
svc.ResetLocalMetadataCache(TABLE_NAME_D); // Cache cleaned for this entity
em = svc.GetEntityMetadata(TABLE_NAME_D, EntityFilters.All); // Request sent!

eclipse scout image change

I am trying to change image inside Image view.
I know that getTestImageField().setImageId(Icons.Logo); would not work, because it would not refresh renderer.
Because I need to use setImage(), I need a way to get Image from Icons class.
As Patrick suggested I try
final IconProviderService provider = SERVICES.getService(IconProviderService.class);
final IconSpec ic = provider.getIconSpec(AbstractIcons.StatusError);
final byte[] content = ic.getContent();
but my problem is that ic is always null.
While I debug this I notice that inside IconProviderService.class in line 57 :
#Override
protected URL findResource(String fullPath) {
URL[] entries = FileLocator.findEntries(m_hostBundle, new Path(fullPath));
if (entries != null && entries.length > 0) {
URL url = entries[entries.length - 1];
if (LOG.isDebugEnabled()) {
LOG.debug("find image " + fullPath + " in bundle " + m_hostBundle.getSymbolicName() + "->" + url);
}
return url;
}
return null;
}
URL[] entries is always empty no matter witch icon I try to present.
After further debugging I found out that FileLocator tries to find fragments from bundle, and then look for the path inside this fragments. (line 242)
Bundle[] fragments = activator.getFragments(b);
but Bundle[] fragments is always null.
Normally my bundle b is (Bundle) EquinoxBundle : org.eclipse.scout.rt.ui.rap.mobile_4.0.100.20140829-1424.
I want to try with different bundle so I do :
final BundleContext context = Activator.getDefault().getBundle().getBundleContext();
for (final Bundle b : context.getBundles()) {
final IconProviderService provider = SERVICES.getService(IconProviderService.class);
provider.setHostBundle(b);
final IconSpec ic = provider.getIconSpec(AbstractIcons.StatusError);
if (ic != null) {
final byte[] content = ic.getContent();
imageField().setImage(content);
}
}
but fragments (from above code) is always null.
You can obtain the image content (byte[]) that you can set on the image field as follows:
IconProviderService provider = SERVICES.getService(IconProviderService.class);
byte[] content = provider.getIconSpec(Icons.YourIconName).getContent();
getImageField().setImage(content);
I quickly checked it and it works for me.
Please ensure that the icon is available and you set up the icon provider service as explained in this Wiki Article

OrientDB POJO Method proxy not working properly

I am using the OObjectDatabaseTx implementation of OrientDB to store my POJOs in the database. When I try to retrieve some POJOs with a SQL commant, I get the result set but the attributes of the POJOs seem to be empty (getters regurning null).
I register my classes properly with
db.getEntityManager().registerEntityClass(MyUser.class);
The following code describes my problem:
Map<String, String> params = new HashMap<String, String>();
params.put("name", username);
List<MyUser> users = db.command(
new OSQLSynchQuery<MyUser>(
"select * from MyUser where "
+ "name = :name"))
.execute(params);
for (MyUser founduser : users) {
ODocument doc = db.getRecordByUserObject(founduser, false);
String pass = doc.field("pwd");
assertEquals(pass != null, true); // passes
assertEquals(founduser.getPwd() != null, true); // fails
}
How can I get the method getPwd to return the proper value?
I am now using Version 1.3.0 and this has worked before (afaik in 1.1.0).
Can you see if the POJO has the "pwd" field set inside of it?

Resources