Any Java API in Azure to get existing ServiceBusContract? - java

I am using the tutorial here for pushing data and consuming, data from Azure Service Bus. When I run the example the second time, I get back an error PUT https://asbtest.servicebus.windows.net/TestQueue?api-version=2012-08 returned a response status of 409 Conflict, which is way of saying you have already a configuration with that name, so do not create it another time. Most probably, this is the guilty code
Configuration config =
ServiceBusConfiguration.configureWithWrapAuthentication(
"HowToSample",
"your_service_bus_owner",
"your_service_bus_key",
".servicebus.windows.net",
"-sb.accesscontrol.windows.net/WRAPv0.9");
ServiceBusContract service = ServiceBusService.create(config);
QueueInfo queueInfo = new QueueInfo("TestQueue");
That is recalling create() is causing the problem, I would guess. But all methods in com.microsoft.windowsazure.services.serviceBus.ServiceBusService from http://dl.windowsazure.com/javadoc/ are only create, and I am unable to find a method like
ServiceBusContract service = A_class_that_finds_existing_bus_contract.find(config);
Am I thinking the wrong way, or is there another way out. Any pointers are appreciated.
EDIT:
I realized my code example for what I was asking was config, not service bus contract. Updated it, to reflect so.

Turns out I was wrong. The create() function in ServiceBusService does not throw any exception, as I gathered from Javadocs. Also, you can create the service bus contracts multiple times, as it being only a connection. The exception arises, when you attempt to create a queue with a name that already exists. That is this line.
String path = "TestQueue";
QueueInfo queueInfo = new QueueInfo(path);
To overcome this, you can go this way.
import com.microsoft.windowsazure.services.serviceBus.Util;
...
...
Iterable<QueueInfo> iqnf = Util.iterateQueues(service);
boolean queue_created = false;
for( QueueInfo qi : iqnf )
{
if( path.toLowerCase().equals( qi.getPath() ))
{
System.out.println(" Queue already exists. Do not create one.");
queue_created = true;
}
}
if ( !queue_created ) {
service.createQueue(queueInfo);
}
Hope, this helps anybody who may be stuck on create conflicts for queue on Azure.
EDIT: Even after I got the path code, my code refused to work. Turns out there is another caveat. Azure makes all queue names in lower case. I have edited the code to use toLower() for this work around.

I upvoted Soham's Question and Answer. I did not know about lowercase though I have not verified it. It did confirm the problem I am having right now as well.
The way #Soham has addressed it is good but not good for large ServicebUs where we may have tons of Queues it's added overhead to iterate it. The only way is to catch the ServiceException which is very generic and ignore that Exception.
Example:
QueueInfo queueInfo = new QueueInfo(queName);
try {
CreateQueueResult qr = service.createQueue(queueInfo);
} catch (ServiceException e) {
//Silently ignore for now.
}
The right way would be for the Azure library to extend the ServiceException and throw "ConcflictException" for e.g. which is present in httpStatusCode of ServiceException but unfortunately it's set to Private.
Since it is not We would have to extend the ServiceException and override the httpStatusCode setter.
Again, not the best way but the library can improve if we list as feedback on their Github issues.
Note: ServiceBus is still in preview phase.

Related

How to get the current substate and the parent state out of the Spring Statemachine?

I am running a hierachical Spring Statemachine and - after walking through the inital transitions into state UP with the default substate STOPPED - want to use statemachine.getState(). Trouble is, it gives me only the parent state UP, and I cannot find an obvious way to retrieve both the parent state and the sub state.
The machine has states constructed like so:
StateMachineBuilder.Builder<ToolStates, ToolEvents> builder = StateMachineBuilder.builder();
builder.configureStates()
.withStates()
.initial(ToolStates.UP)
.state(ToolStates.UP, new ToolUpEventAction(), null)
.state(ToolStates.DOWN
.and()
.withStates()
.parent(ToolStates.UP)
.initial(ToolStates.STOPPED)
.state(ToolStates.STOPPED,new ToolStoppedEventAction(), null )
.state(ToolStates.IDLE)
.state(ToolStates.PROCESSING,
new ToolBeginProcessingPartAction(),
new ToolDoneProcessingPartAction());
...
builder.build();
ToolStates and ToolEvents are just enums. In the client class, after running the builder code above, the statemachine is started with statemachine.start(); When I subsequently call statemachine.getState().getId(); it gives me UP. No events sent to statemachine before that call.
I have been up and down the Spring statemachine docs and examples. I know from debugging that the entry actions of both states UP and STOPPED have been invoked, so I am assuming they are both "active" and would want to have both states presented when querying the statemachine. Is there a clean way to achieve this ? I want to avoid storing the substate somewhere from inside the Action classes, since I believe I have delegated all state management issues to the freakin Statemachine in the first place and I would rather like to learn how to use its API for this purpose.
Hopefully this is something embarrasingly obvious...
Any advice most welcome!
The documentation describes getStates():
https://docs.spring.io/spring-statemachine/docs/current/api/org/springframework/statemachine/state/State.html
java.util.Collection<State<S,E>> getStates()
Gets all possible states this state knows about including itself and substates.
stateMachine.getState().getStates();
to wrap it up after SMA's most helpful advice: turns out the stateMachine.getState().getStates(); does in my case return a list of four elements:
a StateMachineState instance containing UP and STOPPED
three ObjectState instances containing IDLE, STOPPED and PROCESSING,
respectively.
this leads me to go forward for the time being with the following solution:
public List<ToolStates> getStates() {
List<ToolStates> result = new ArrayList<>();
Collection<State<ToolStates, ToolEvents>> states = this.stateMachine.getState().getStates();
Iterator<State<ToolStates, ToolEvents>> iter = states.iterator();
while (iter.hasNext()) {
State<ToolStates, ToolEvents> candidate = iter.next();
if (!candidate.isSimple()) {
Collection<ToolStates> ids = candidate.getIds();
Iterator<ToolStates> i = ids.iterator();
while (i.hasNext()) {
result.add(i.next());
}
}
}
return result;
}
This maybe would be more elegant with some streaming and filtering, but does the trick for now. I don't like it much, though. It's a lot of error-prone logic and I'll have to see if it holds in the future - I wonder why there isn't a function in the Spring Statemachine that gives me a list of the enum values of all the currently active states, rather than giving me everything possible and forcing me to poke around in it with external logic...

How to prevent "NucleusDataStoreException: Concurrent Modification"?

Our app suddenly got a lot of traffic and there were some design flaws in the system (or rather we never thought it would get this much traffic so we just skipped it by choice).
As the topic states I'm looking for a way to prevent the error: org.datanucleus.exceptions.NucleusDataStoreException: Concurrent Modification
Currently I have an entity called Group that looks like this:
#PersistenceCapable
public class Group extends PersistableString {
private static final long serialVersionUID = 6215353466976945628L;
#Persistent
private int yesCount;
#Persistent
private int noCount;
public void increaseYesCount()
{
yesCount++;
}
public void increaseNoCount()
{
noCount++;
}
}
The following code is how the update of the entity is done:
int answer = Integer.parseInt(req.getParameter("answer"))
try {
PersistenceManager pm = PMF.getPersistenceManager();
for(String groupId : allGroupsToBeUpdated)
{
Group group = pm.getObjectById(Group.class, groupId);
if(answer == 0)
group.increaseNoCount();
else
group.increaseYesCount();
}
pm.close();
} catch (Exception e) {
e.printStackTrace();
}
allGroupsToBeUpdated is a list that contains around 30 string-ids. Is there some way I can avoid the Concurrent Modification-error? Can I check if the entity that I retrieve is being updated and then just discard(/ignore) the update? It's not SUPER important that the write actually succeeds, I just wanna make sure I don't get the error (or that it keeps trying to succeed with the write), because it's causing the request to take between 10-30seconds.
Should I maybe open (get new PM-instance) and close the connection (pm.close()) between each update instead of waiting for all of the 30ish updates to go through?
I know of sharded counters and should have (obviously) used them, but right now I'm looking for a "quick-fix" to this problem.
EDIT:
I'm using:
App Engine SDK 1.8.9
JDO 3.0
Stacktrace can be found at:
http://pastebin.com/TWnmkpPU
Posting as an answer due to length.
Transactions probably aren't good in your case since you are really just looking to hide the issue from the user which is manifesting itself in slow request times. Perhaps kicking off an async push task to do the writes in the background outside of the request would be your best bet.
I really would not recommend design based on hiding errors and swallowing exceptions though. Looking to "prevent" an exception that is doing what it is supposed to (signaling a failed write due to contention), means you should avoid the condition which caused it in the first place.
I totally understand needing to get things working fast early on, but it may be a good idea to start adopting best practices now once the bad design decisions just start making their mark. Continuing to rely on "quick-fixes" and hiding problems can land you in a real mess later on.

Java InvocationTargetException

I have used EMC Documentum Foundation Classes to perform some actions in documentum repository. The code was working fine. I exported the project as a runnable JAR and then tried to run it. However I got following error and I am not able to understand it.
And here is the code for DocMovementHandler.getSession()
Actually this is no new code but regular code for obtaining documentum session
public IDfSession getSession(String userName, String password)
{
DfClientX clientx = null;
IDfClient client = null;
IDfSession session = null;
try {
// create a client object using a factory method in DfClientX
clientx = new DfClientX();
client = clientx.getLocalClient(); //takes time
// call a factory method to create the session manager
IDfSessionManager sessionMgr = client.newSessionManager();
// create an IDfLoginInfo object and set its fields
IDfLoginInfo loginInfo = clientx.getLoginInfo();
loginInfo.setUser(userName);
loginInfo.setPassword(password);
// set single identity for all docbases
sessionMgr.setIdentity("xyz_repo", loginInfo);
session = sessionMgr.getSession("xyz_repo"); //takes time
//sessionMgr.beginTransaction();
System.out.println("Session obtaied.");
}
catch (DfServiceException dse)
{
DfLogger.debug(this, "Error while beginning transaction. ", null, dse);
dse.printStackTrace();
}
catch (Exception e)
{
DfLogger.debug(this, "Error while creating a new session. ", null, e);
e.printStackTrace();
}
return session;
}
And that line 38 is client = clientx.getLocalClient();
InvocationTargetException is a wrapper. It says, "an exception occurred behind this reflection call", and you use getCause() to get at the inner exception.
The stack trace contains the inner exception. It's an ExceptionInInitializerError. That's another wrapper. It says, "whatever you did caused a new class to be loaded, and that class's static initializer threw an exception".
The final exception in this chain is the NullPointerException. That's the one you need to solve. Which means you need to debug this com.documentum thing. As the comments pointed out, that's not going to be easy.
Here is the most likely problem:
The static initializer in one of the classes whose names you have struck is adding an entry with either a null key or a null value to a Hashtable, which does not allow null keys or values.
It is using the Hashtable as a place to store a bunch of persistent properties and all that, and my guess is that the value for one of the entries was the null (which is a perfectly reasonable way to indicate that some feature is unavailable or something like that).
The now deprecated Hashtable needs to be replaced with the more modern HashMap.
If it is a library, that you can't just modify, you should replace the whole library with an updated version.
Here are some clues may be helpful.
The NullPointerException is thrown by Hashtable#put, and this is normally because either the key or the value is null.
Hashtable#put is called by PreferenceManager.readPersistenceProperties, so most likely it's because something is missing in a properties file so the value is null.
This NPE caused the DfClient class could not be loaded.
DfPreferences is the class loading the DFC configuration file dfc.properties. There must be something wrong with it.
Ohkay I did not pin pointed the root cause, but found the solution that will definitely work everytime.
EMC provides a flavor of Eclipse called Documentum Composer to work with Documentum Projects. Since Eclipse variation we can create other types of projects like normal Java project, dynamic web project, web services in this. So I recreated my project in Documetnum Composer and exported it as JAR and whoaaaa it worked.
I tried this many times and this worked all time.
Some points to note:
You have to replace dfc.properties file in Composer installation folder with one in Content Server
The Export to JAR wizard in Composer is a bit different than one in Eclipse
This is usually caused by dfc.properties being incorrect.
Preferences are stored on the global registry repository and the connection details should be specified in dfc.properties. If not, this (or a similar error can occur).
Also, always try to clear cache and use the correct version of the dfc jar's (v6.7 content server requires 6.7 jars, etc...).

Is there a way to change state of workitem with java sdk for TFS?

I'm at a point where I cannot figure out how to change the state of a bug from "New" to anything I'v tried "Approved,Done,Closed" every time I get the following exception shown below. I have looked all over the internet and have found that the System.State field is a bit different than other fields. I thought okay well maybe there is a method to move the transition state but couldn't find that. I also saw a few posts in the .NET api where switching the state caused other fields in particular the reason field to become invalid. I don't think this is the issue though because as soon as I try to call field.setValue("Closed") it throws the exception.I looked with power tools and the System.State does show to be editable? It can't be a transition state issue because I'v tried states that should be valid as a next step. As an example the workitem is new so Approved is a valid next step.
Please if anyone has any idea what is the problem I'd be very grateful.
Example Code:
WorkItem workItem = s.get(0);
Map<String, String> fieldValueMap = settings.getFieldValues();
String status_field_text = settings.getFieldMap().get(SettingsParser.STATUS);
Field statusField = workItem.getFields().getField(status_field_text);
String currentFieldValue = fieldValueMap.get(SettingsParser.CLOSED_STATE);
if(currentFieldValue != null)
{
statusField.setValue("Approved");//<=========== no matter what i add there i get exception
}
else
{
System.out.println("pp");
}
Exception in thread "main
Error:
" java.lang.IllegalArgumentException: field id [10013] does not exist in this collection (wi=16,size=13)
at com.microsoft.tfs.core.clients.workitem.internal.fields.FieldCollectionImpl.newIllegalFieldIDException(FieldCollectionImpl.java:119)
at com.microsoft.tfs.core.clients.workitem.internal.fields.FieldCollectionImpl.getFieldInternal(FieldCollectionImpl.java:459)
at com.microsoft.tfs.core.clients.workitem.internal.WorkItemImpl.getRuleTargetField(WorkItemImpl.java:769)
at com.microsoft.tfs.core.clients.workitem.internal.rules.RuleEngine.preProcessFields(RuleEngine.java:224)
at com.microsoft.tfs.core.clients.workitem.internal.rules.RuleEngine.fieldChanged(RuleEngine.java:196)
at com.microsoft.tfs.core.clients.workitem.internal.rules.RuleEngine.fieldChanged(RuleEngine.java:167)
at com.microsoft.tfs.core.clients.workitem.internal.fields.FieldImpl.fireRules(FieldImpl.java:795)
at com.microsoft.tfs.core.clients.workitem.internal.fields.FieldImpl.setValue(FieldImpl.java:765)
at com.microsoft.tfs.core.clients.workitem.internal.fields.FieldImpl.setValue(FieldImpl.java:457)
at com.microsoft.tfs.core.clients.workitem.internal.fields.FieldImpl.setValue(FieldImpl.java:389)
at Test.main(Test.java:54)
There is no SettingsParser in the TEE SDK. I'm not sure what this class is, but it is not helpful to updating a bug. By using it, it appears that you're trying to update the field named "10013", which does not exist.
The state field is called System.State, or better, you can simply use a constant, CoreFieldReferenceNames.STATE to refer to it.
If you look at the samples included with the SDK, you will find one (EditWorkItemByID) that should illustrate editing a work item for you. Adapting that snippet and the code you've posted above, you should try something like:
WorkItem workItem = s.get(0);
workItem.getFields().getField(CoreFieldReferenceNames.STATE).setValue("Approved");

Why is my Com4J interface hanging during iteration?

I have to interface a third party COM API into an Java application. So I decided to use Com4j, and so far I've been satisfied, but now I've run into a problem.
After running the tlbgen I have an object called IAddressCollection which according to the original API documentation conforms to the IEnum interface definition. The object provides an iterator() function that returns a java.util.Iterator<Com4jObject>. The object comes from another object called IMessage when I want to find all the addresses for the message. So I would expect the code to work like this:
IAddressCollection adrCol = IMessage.getAddressees();
Iterator<Com4jObject> adrItr = adrCol.iterator();
while(adrItr.hasNext()){
Com4jObject adrC4j = adrItr.next();
// normally here I would handle the queryInterface
// and work with the rest of the API
}
My problem is that when I attempt the adrItr.next() nothing happens, the code stops working but hangs. No exception is thrown and I usually have to kill it through the task manager. So I'm wondering is this a problem that is common with Com4j, or am I handling this wrong, or is it possibly a problem with the API?
Ok, I hate answering my own question but in this case I found the problem. The issue was the underlying API. The IAddressCollection uses a 1 based indexing instead of a 0 based as I would have expected. It didn't provide this information in the API documentation. There is an item function where I can pull the object this way and so I can handle this with
IAddressCollection adrCol = IMessage.getAddressees();
for(int i = 1; i <= adrCol.count(); i++){
IAddress adr = adrCol.item(i);
// IAddress is the actual interface that I wanted and this works
}
So sorry for the annoyance on this.

Categories