com.tivoli.mts.PDPrincipal.implies(com.tivoli.mts.PDPermission) deprecated - java

I am using the below code to do the authorizatin checks.
PDPrincipal whoIsit = new PDPrincipal(userId,configURL);
PDPermission whatTheyWant = new PDPermission(objectSpaceName,"TbvA");
boolean haveAccess = whoIsit.implies(whatTheyWant);
However the implies method on com.tivoli.mts.PDPrincipal has been deprecated and has been replaced by implies method from the new PdPrincipal class from different package.
com.tivoli.pd.jazn.PDPrincipal
the new method is as follows.
public boolean implies(javax.security.auth.Subject subject)
the new method takes a Subject.
Can you please let me know how can I change my code to use the new method? How do i construct the Subject or can i get the Subject from somewhere?
Thanks,
Rohit

I was able to work out a solution for this hence sharing it here so that anyone else facing the same issue can use this code.
I found that the new com.tivoli.pd.jazn.PDPermission class has a method implies which takes in a PdAuthorization context and a com.tivoli.pd.jazn.PDPrincipal object which does the same authorization checks that the previous class com.tivoli.mts.PDPrincipal use to do.
Mentioned below is how the same authorization can be done. With this code you need not implement the JAAS code.
First construct the PdAuthorizationContext as shown below. Make sure to define a static PdAuthorizationContext object so that it can be reused untill you close it. Constructing PDAuthorizationContext for every authorization check is resource intensive and not recommended. close the context at the end of your logic
URL configURL = new URL("file:" + String locationToTamConfigFile);
PDAuthorizationContext pdAuthCtx = new PDAuthorizationContext(configURL);
Next Construct the new PDPrincipal and the PdPermission objects as shown below and call the implies method
com.tivoli.pd.jazn.PDPrincipal pdPrincipal = new com.tivoli.pd.jazn.PDPrincipal(pdAuthCtx,userId);
com.tivoli.pd.jazn.PDPermission pdPermission = new com.tivoli.pd.jazn.PDPermission(objectSpaceName,"TbvA");
boolean newimpliesTry = pdPermission.implies(pdAuthCtx,pdPrincipal);

Related

Why can't I cast an object to collection in Java?

I am writing a Unit Test for a class as follows:
#Test
void testCreateStackResources()
{
List<StackResource> stackResourceListExpected = new ArrayList<>();
StackResource stackResource = new StackResource();
stackResource.setLogicalResourceId("Sample-Logical-ID");
stackResourceListExpected.add(stackResource);
ListStackResourcesResult listStackResourcesResult = new ListStackResourcesResult();
StackResourceSummary stackResourceSummary = new StackResourceSummary();
stackResourceSummary.setLogicalResourceId("Sample-Logical-ID");
listStackResourcesResult.setStackResourceSummaries((Collection<StackResourceSummary>) stackResourceSummary); // Problem in this line
Mockito.when(amazonCloudFormation.listStackResources(Mockito.any(ListStackResourcesRequest.class))).thenReturn(listStackResourcesResult);
List<StackResource> stackResourceListResult = cloudFormationManager.createStackResources(Mockito.anyString());
Assert.assertEquals(stackResourceListExpected, stackResourceListResult);
}
Now, when I run this code, it gives me an error that I can't cast StackResourceSummary to a Collection in Java.
java.lang.ClassCastException: com.amazonaws.services.cloudformation.model.StackResourceSummary cannot be cast to java.util.Collection
On the other hand, if I make an array list before, add the object of StackResourceSummary to the list and then run the UT, it gives me the
objc[3648]: Class JavaLaunchHelper is implemented in both /Library/Java/JavaVirtualMachines/jdk1.8.0_121.jdk/Contents/Home/bin/java (0x10d19c4c0) and /Library/Java/JavaVirtualMachines/jdk1.8.0_121.jdk/Contents/Home/jre/lib/libinstrument.dylib (0x10ea194e0). One of the two will be used. Which one is undefined.
This is very weird behaviour. I don't know why can't I cast this to a collection? Please help. Thanks!
PS: There is a seperate class called ListStackResourcesResult which has a setter as follows:
public void setStackResourceSummaries(java.util.Collection<StackResourceSummary> stackResourceSummaries) {
if (stackResourceSummaries == null) {
this.stackResourceSummaries = null;
return;
}
this.stackResourceSummaries = new com.amazonaws.internal.SdkInternalList<StackResourceSummary>(stackResourceSummaries);
}
And I am trying to use this method above.
That is because StackResourceSummary does not extend or implement anything related to a collection.
http://docs.aws.amazon.com/AWSJavaSDK/latest/javadoc/com/amazonaws/services/cloudformation/model/StackResourceSummary.html
What you need to to is create a collection and add your instance of StackResourceSummary to it. For example like so:
List<StackResourceSummary> stackResourceSummaries = new ArrayList<StackResourceSummary>();
stackResourceSummaries.add(stackResourceSummary)
or maybe like so
Arrays.asList(stackResourceSummary)
or use a third party lib like guava collections.
Then you should use that collection as an argument.
listStackResourcesResult.setStackResourceSummaries(stackResourceSummaries); // Problem gone in this line

javassist copy a method with annotation

This is the original method:
#GET
#Produces({"application/json"})
public Response getTermClouds(#Context SecurityContext secCtxt, #Context UriInfo ui)
{
return null
}
I want to copy this method but add a new String parameter,and the annotations of the new method is the same as before,like this:
#GET
#Produces({"application/json"})
public Response getTermClouds(#Context SecurityContext secCtxt, #Context UriInfo ui,String newParam)
{
return null
}
I use javassist to do it,i don`t want to add a "get" annotation and then add a "produces" annotation,because there may be many other annotations which are unkown.How to do it as a common way?
When You try adding a new parameter to a method , Javassist does not allow to add an extra parameter to an existing method,Instead of doing that, a new method receiving the extra parameter as well as the other parameters is added to the same class.
A copy of the the CtMethod object can be obtained by CtNewMethod.copy().
Try this to create a copy of Your previous method. And can you explain exactly what you want to be done with annotations?
I realize this is old now, but I ran into the same problem trying to add parameters to Spring web handler methods, and I've figured it out. You need to copy the attributes of the old class to the new one. You'll also likely want to remove them from the old one to prevent possible conflicts. The code looks like this:
//Create a new method with the same name as the old one
CtMethod mNew = CtNewMethod.copy(mOrig, curClass, null);
//Copy all attributes from the old method to the new one. This includes annotations
for(Object attribute: mOrig.getMethodInfo().getAttributes()) {
m.getMethodInfo().addAttribute((AttributeInfo)attribute);
}
//Remove the method and parameter annotations from the old method
mOrig.getMethodInfo().removeAttribute(AnnotationsAttribute.visibleTag);
mOrig.getMethodInfo().removeAttribute(ParameterAnnotationsAttribute.visibleTag);
//Add the new String parameter to the new method
m.addParameter(cp.getOrNull("java.lang.String"));
//Add a new empty annotation entry for the new parameter (not sure this part is necessary for you.
//In my case, I was adding a new parameter to the beginning, so the old ones needed to be offset.
ParameterAnnotationsAttribute paa = (ParameterAnnotationsAttribute)m.getMethodInfo().getAttribute(ParameterAnnotationsAttribute.visibleTag);
Annotation[][] oldAnnos = paa.getAnnotations();
Annotation[][] newAnnos = new Annotation[oldAnnos.length + 1][];
newAnnos[oldAnnos.length] = new Annotation[] {};
System.arraycopy(oldAnnos, 0, newAnnos, 0, oldAnnos.length);
paa.setAnnotations(newAnnos);
//Rename the old method and add the new one to the class
mOrig.setName(mOrig.getName() + "_replaced");
curClass.addMethod(m);

Test if object was properly created

I'm putting more attention into unit tests these days and I got in a situation for which I'm not sure how to make a good test.
I have a function which creates and returns an object of class X. This X class is part of the framework, so I'm not very familiar with it's implementation and I don't have freedom as in the case of my "regular collaborator classes" (the ones which I have written). Also, when I pass some arguments I cannot check if object X is set to right parameters and I'm not able to pass mock in some cases.
My question is - how to check if this object was properly created, that is, to check which parameters were passed to its constructor? And how to avoid problem when constructor throws an exception when I pass a mock?
Maybe I'm not clear enough, here is a snippet:
public class InputSplitCreator {
Table table;
Scan scan;
RegionLocator regionLocator;
public InputSplitCreator(Table table, Scan scan, RegionLocator regionLocator) {
this.table = table;
this.scan = scan;
this.regionLocator = regionLocator;
}
public InputSplit getInputSplit(String scanStart, String scanStop, Pair<byte[][], byte[][]> startEndKeys, int i) {
String start = Bytes.toString(startEndKeys.getFirst()[i]);
String end = Bytes.toString(startEndKeys.getSecond()[i]);
String startSalt;
if (start.length() == 0)
startSalt = "0";
else
startSalt = start.substring(0, 1);
byte[] startRowKey = Bytes.toBytes(startSalt + "-" + scanStart);
byte[] endRowKey = Bytes.toBytes(startSalt + "-" + scanStop);
TableSplit tableSplit;
try {
HRegionLocation regionLocation = regionLocator.getRegionLocation(startEndKeys.getFirst()[i]);
String hostnamePort = regionLocation.getHostnamePort();
tableSplit = new TableSplit(table.getName(), scan, startRowKey, endRowKey, hostnamePort);
} catch (IOException ex) {
throw new HBaseRetrievalException("Problem while trying to find region location for region " + i, ex);
}
return tableSplit;
}
}
So, this creates an InputSplit. I would like to know whether this split is created with correct parameters. How to do that?
If the class is part of a framework, then you shouldn't test it directly, as the framework has tested it for you. If you still want to test the behaviour of this object, look at the cause-reaction this object would cause. More specifically: mock the object, have it do stuff and check if the affected objects (which you can control) carry out the expected behaviour or are in the correct state.
For more details you should probably update your answer with the framework you're using and the class of said framework you wish to test
This is possibly one of those cases where you shouldn't be testing it directly. This object is supposedly USED for something, yes? If it's not created correctly, some part of your code will break, no?
At some point or another, your application depends on this created object to behave in a certain way, so you can test it implicitly by testing that these procedures that depend on it are working correctly.
This can save you from coupling more abstract use cases from the internal workings and types of the framework.

Activating and Deactivating Entities in Dynamics CRM from Java API

I am using the Microsoft Dynamics CRM, using the Java API generated as per their tutorial and SDK downloads.
I can create, delete, and update entities with no problems.
I am now at the stage where I need to set entities to active or inactive.
I had thought that the right way to do this was roughly
public void doIt(OrganisationServicesStub stub, OptionSetValue stateValue, OptionSetValue statusValue)
{
Guid g = new Guid();
g.setGuid("abc-def-ghijkl");
Entity updateMe = new Entity();
updateMe.setId(g);
updateMe.setLogicalName("ei_teacherdetails");
AttributeCollection updateCollection = new AttributeCollection();
updateCollection.addKeyValuePairOfstringanyType(pair("statecode", stateValue));
updateCollection.addKeyValuePairOfstringanyType(pair("statuscode", statusValue));
updateMe.setAttributes(updateCollection);
update.setEntity(updateMe);
stub.update(update);
}
public static KeyValuePairOfstringanyType pair(String key, Object value)
{
KeyValuePairOfstringanyType attr = new KeyValuePairOfstringanyType();
attr.setKey(key);
attr.setValue(value);
return attr;
}
The above code has been tested and works for updating any attributes except the state/status ones. When I try the above code, however, (i.e. the code that tries to update the state/status), I get the following error (calling with state/status values of 1 and 2 respectively. I got those values by looking at existing Invalid entries in the CRM dumped through the same api, so I am (almost) certain that they are correct.
org.apache.axis2.AxisFault: 2 is not a valid status code for state code ei_teacherdetailsState.Active
I have noticed that in other languages, there is a SetState request, but I don't find a similar one in Java.
If anyone has been down this path before me, I'd greatly appreciate any assistance you could give.
It turns out that the correct answer is as follows, as best I can tell....
private void doIt(OrganizationServiceStub stub, OptionSetValue state, OptionSetValue status)
{
OrganizationRequest request = new OrganizationRequest();
request.setRequestName("SetState");
ParameterCollection collection = new ParameterCollection();
collection.addKeyValuePairOfstringanyType(pair("State", state));
collection.addKeyValuePairOfstringanyType(pair("Status", status));
request.setParameters(collection);
Guid g = new Guid();
g.setGuid("abc0def-ghi");
EntityReference ref = new EntityReference();
ref.setId(g);
ref.setLogicalName("ei_teacherdetails");
collection.addKeyValuePairOfstringanyType(pair("EntityMoniker", ref));
Execute exe = new Execute();
exe.setRequest(request);
stub.execute(exe);
}
Which is pretty obscure, I think. Especially I like that there's a parameter called "EntryMoniker". Anyway, I leave this answer here just in case some other poor soul ends up having to deal with this MS CRM intricacy.

OOP: passing settings to Builder class

In my client I would like to specify strategies to be used in the class produced by builder.
However, I can't pass these strategy objects to builder, because their initialization is partially handled by builder. Yet, I still have to communicate builder which object to use and which additional parameters to pass it.
Here's Builder class
public class MarketGeneratorBuilder {
private MarketGenerator.Parameters parameters;
public MarketGeneratorBuilder(MarketGenerator.Parameters parameters) {
this.parameters = parameters;
}
public MarketGenerator build() {
return new MarketGenerator(
parameters,
new GoodsGenerator(
new UniformDistribution(
new ValueRange(0,parameters.getNumberOfLevels()-1)
)
),
new ITGenerator(),
new OTGenerator(),
new IOTGenerator(
new UniformDistribution(
new ValueRange(1,parameters.getNumberOfLevels()-2)
),
new BundlesGenerator(
new ForwardMarkovDistribution(
new MarkovDistribution.Parameters(
new ValueRange(0,parameters.getNumberOfLevels()-1),
0.1,
0.1
)
),
new UniformDistribution(
new ValueRange(1,parameters.getNumberOfGoodsToCreate()-1)
)
),
new BundlesGenerator(
new BackwardMarkovDistribution(
new MarkovDistribution.Parameters(
new ValueRange(0,parameters.getNumberOfLevels()-1),
0.2,
0.2
)
),
new UniformDistribution(
new ValueRange(1,parameters.getNumberOfGoodsToCreate()-1)
)
)
)
);
}
}
Distributions (UniformDistribution, ForwardMarkovDistribution, ForwardMarkovDistribution and potentially more to come) are hardcoded now, but should be chosen by client. The value range is defined by Builder (the ValueRange objects). Yet, some distributions take additional parameters (ForwardMarkovDistribution takes ValueRange, alpha, beta), which should be defined by client.
The only solution I can see is to pull ValueRange from constructor into setter. But it seems wrong as its an essencial field for the object. Also, I would like client code to not contain internal logic of the builder. More like,
DistributionType levelDistribution = new DistributionType(Distributions.UNIFORM);
DistributionType goodsDistribution = new DistributionsType(Distributions.MARKOV_FORWARD, 0.1,0.1);
But in this case I dont understand how to enforce data integrity. Meaning that when the client chooses Distributions.UNIFORM there are no more parameters to pass. Or in case of Distributions.MARKOV_FORWARD he has to pass alpha and beta.
So, I was hoping you could point me to a better pattern. Thanks!
For full flexibility, add a provider/factory for each of the distributions:
interface DistributionProvider<D extends Distribution> {
D create(ValueRange vr);
}
class UniformDistributionProvider implements DistributionProvider<UniformDistribution> {
UniformDistribution create(ValueRange vr) {
return new UniformDistribution(vr);
}
}
class ForwardMarkovDistributionProvider implements DistributionProvider<ForwardMarkovDistribution> {
private final MarkovDistribution.Parameters params;
ForwardMarkovDistributionProvider(MarkovDistribution.Parameters pParams) {
params = pParams;
}
ForwardMarkovDistribution create(ValueRange vr) {
return new ForwardMarkovDistribution(vr, params);
}
}
// etc.
(Remove the ValueRange from MarkovDistribution.Parameters.)
Basically, each of the providers stores all necessary parameters for the distribution, except the ValueRange.
Then clients can instantiate the provider for the distribution they want, configuring it with the appropriate values.
The builder would get those instances of DistributionProvider and use these to create the distributions, passing a ValueRange.
I see a couple of different patterns here.
You could have a couple of different build methods. buildUniform() and buildMarkov(float alpha, float beta).
You could have a couple of different builder classes: MarketGeneratorMarkovBuilder. They could have a base class with a protected build method. [Not sure I like this one]
You could add the alpha and beta values to the parameters class and throw an exception if they aren't available for the MARKOV_FORWARD and throw exception if they are available for UNIFORM.
If the ValueRange is constant for the entire builder then I see no reason why, as you mention, you couldn't add it to the parameters or put a setter on the builder to inject it.
You might consider using dependency injection (in Spring fashion) for all of the constant sub classes. The builder could have setters for all of them instead of being hard coded.
Hope this helps.

Categories