Yeah, that works fine.

I've created a test that reproduces the problem. I think it can only occur
when an Object has a Map as a field. This is the only way we can get a
period into something Mongo uses as a key (I'm guesstimating here) since
fields names themselves obviously can't use a period.

I can think of a few solutions. Two had problems though. Editing the actual
object passed into the converter via reflection or editing the map produced
by the current converter[1] mean you need to recursively check every map
for another map, probably all the way up the object hierarchy too. It's a
bit messy and in what's likely to be the majority of the use cases a
pointless overhead!

Given this I created a converter that maps the object to a string. This
lets Jackson take care of the details and leaves us to simply edit a string
before creating the DBObject.

String json = MongoDbBasicConverters.objectMapper.writeValueAsString(value);
json = json.replace(".", ",");
answer = (DBObject) JSON.parse(json);

This works in all the tests (including the new period key test) except
those that pass a String array of Json. The object to json string object
mapper ends up creating some kind of weird json of json, I suppose that's
to be expected. If I leave the original converter [1] in but change the
signature to the following:
public static DBObject fromAnyArrayToDBObject(final Object[] value).
all the tests pass (since array objects use the mapper conversion
strategy[1]).
This does leave a use case open where somebody could have an array of maps,
so perhaps some kind of check would be required on the elements...if it's
worth worrying about for now.

I can't figure out how to get the type conversion to trigger on the way
back out of the database though, e.g. in a find operation. Any help would
be appreciated there.

Perhaps offline so as to avoid spamming the user list.

Thanks!

P.S. I guess there could be a property in the endpoint uri to allow users
to configure the period replacement character(s) if they didn't want to use
a comma for some reason.


[1] Line 67 in
https://fisheye6.atlassian.com/browse/camel/trunk/components/camel-mongodb/src/main/java/org/apache/camel/component/mongodb/converters/MongoDbBasicConverters.java?hb=true

On 6 October 2012 02:19, Raul Kripalani <r...@evosent.com> wrote:

> Hi Mark,
>
> I just committed a fix for the tests in r1394865. It turns out that the
> PropertiesComponent was being added too late in the route lifecycle, which
> worked before r1373402, but not after.
>
> You should now be able to run the tests locally simply by starting MongoDB.
> The tests are prepared to connect to the default Mongo port @ localhost. If
> your config is different, just adjust mongodb.test.properties accordingly.
>
> Thanks in advance for your contribution ;)
>
> Regards,
>
> *Raúl Kripalani*
> Apache Camel Committer
> Enterprise Architect, Program Manager, Open Source Integration specialist
> http://about.me/raulkripalani | http://www.linkedin.com/in/raulkripalani
> http://blog.raulkr.net | twitter: @raulvk <http://twitter.com/raulvk>
>
> On Fri, Oct 5, 2012 at 6:08 PM, Raul Kripalani <r...@evosent.com> wrote:
>
> > Apologies for not being able to look at this yesterday. Thanks for all
> the
> > feedback from your side.
> >
> > Unfortunately the unit tests of this component are disabled on our
> Jenkins
> > because MongoDB is not embeddable and our unit tests are really
> > "integration tests" from the purist point of view, because they target a
> > real MongoDB instance. Probably some framework change between 2.10.0 and
> > now have introduced this regression.
> >
> > I'll try and take a look at this during the weekend.
> >
> > Sometime ago I was in talks with a MongoDB cloud-hosting company about a
> > free MongoDB cloud instance for the Camel project just for our automated
> > testing. I have to pick up that conversation again.
> >
> > Regards,
> >
> > *Raúl Kripalani*
> > Apache Camel Committer
> > Enterprise Architect, Program Manager, Open Source Integration specialist
> > http://about.me/raulkripalani | http://www.linkedin.com/in/raulkripalani
> > http://blog.raulkr.net | twitter: @raulvk <http://twitter.com/raulvk>
> >
> > On Fri, Oct 5, 2012 at 5:53 PM, Mark Doyle <markjohndo...@gmail.com
> >wrote:
> >
> >> I have a little more info.
> >>
> >> The properties issue is evident on both the command line (mvn install)
> and
> >> running the junit test directly in elipse.
> >>
> >> I tried the spring 3.1 profile on the command line (mvn clean install -P
> >> spring3.1) and got the same problem.
> >>
> >> What is weird is it suddenly stopped finding the latest
> camel-test-spring
> >> dependency, no version is specified in the POM so unless it's managed
> in a
> >> parent I guess it will go for the latest snapshot. I had to
> >> explicitly specify <version>2.11-SNAPSHOT</version> in the pom to get it
> >> to
> >> compile again. Having said all that, I still get the Properties issue :)
> >>
> >> On 4 October 2012 14:20, Raul Kripalani <r...@evosent.com> wrote:
> >>
> >> > Strange, will check this evening and will send you a direct email with
> >> my
> >> > findings.
> >> > Thanks for your collaboration ;)
> >> >
> >> > Regards,
> >> >
> >> > *Raúl Kripalani*
> >> > Apache Camel Committer
> >> > Enterprise Architect, Program Manager, Open Source Integration
> >> specialist
> >> > http://about.me/raulkripalani |
> >> http://www.linkedin.com/in/raulkripalani
> >> > http://blog.raulkr.net | twitter: @raulvk <http://twitter.com/raulvk>
> >> >
> >> > On Wed, Oct 3, 2012 at 10:23 PM, Mark Doyle <markjohndo...@gmail.com>
> >> > wrote:
> >> >
> >> > > Hi Raul,
> >> > >
> >> > > I'm getting the trace below when I try to run the unit tests. Looks
> >> like
> >> > a
> >> > > problem adding the Properties component (using
> >> mongdb.test.properties) to
> >> > > the camel spring context. Any ideas?
> >> > >
> >> > > java.lang.IllegalArgumentException: Cannot add component as its
> >> already
> >> > > previously added: properties
> >> > > at
> >> > >
> >> > >
> >> >
> >>
> org.apache.camel.impl.DefaultCamelContext.addComponent(DefaultCamelContext.java:291)
> >> > > at
> >> > >
> >> > >
> >> >
> >>
> org.apache.camel.component.mongodb.MongoDbOperationsTest$1.configure(MongoDbOperationsTest.java:227)
> >> > > at
> >> > >
> >> > >
> >> >
> >>
> org.apache.camel.builder.RouteBuilder.checkInitialized(RouteBuilder.java:322)
> >> > > at
> >> > >
> >> > >
> >> >
> >>
> org.apache.camel.builder.RouteBuilder.configureRoutes(RouteBuilder.java:276)
> >> > > at
> >> > >
> >> > >
> >> >
> >>
> org.apache.camel.builder.RouteBuilder.addRoutesToCamelContext(RouteBuilder.java:262)
> >> > > at
> >> > >
> >> > >
> >> >
> >>
> org.apache.camel.impl.DefaultCamelContext.addRoutes(DefaultCamelContext.java:633)
> >> > > at
> >> > >
> >> > >
> >> >
> >>
> org.apache.camel.test.junit4.CamelTestSupport.doSetUp(CamelTestSupport.java:293)
> >> > > at
> >> > >
> >> > >
> >> >
> >>
> org.apache.camel.test.junit4.CamelTestSupport.setUp(CamelTestSupport.java:213)
> >> > > at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
> >> > > at
> >> > >
> >> > >
> >> >
> >>
> sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
> >> > > at
> >> > >
> >> > >
> >> >
> >>
> sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
> >> > > at java.lang.reflect.Method.invoke(Method.java:597)
> >> > > at
> >> > >
> >> > >
> >> >
> >>
> org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:45)
> >> > > at
> >> > >
> >> > >
> >> >
> >>
> org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
> >> > > at
> >> > >
> >> > >
> >> >
> >>
> org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:42)
> >> > > at
> >> > >
> >> > >
> >> >
> >>
> org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:27)
> >> > > at
> >> > >
> >> >
> >>
> org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:30)
> >> > > at org.junit.rules.TestWatcher$1.evaluate(TestWatcher.java:47)
> >> > > at org.junit.rules.RunRules.evaluate(RunRules.java:18)
> >> > > at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:263)
> >> > > at
> >> > >
> >> > >
> >> >
> >>
> org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:68)
> >> > > at
> >> > >
> >> > >
> >> >
> >>
> org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:47)
> >> > > at org.junit.runners.ParentRunner$3.run(ParentRunner.java:231)
> >> > > at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:60)
> >> > > at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:229)
> >> > > at org.junit.runners.ParentRunner.access$000(ParentRunner.java:50)
> >> > > at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:222)
> >> > > at
> >> > >
> >> > >
> >> >
> >>
> org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:28)
> >> > > at
> >> > >
> >> >
> >>
> org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:30)
> >> > > at org.junit.runners.ParentRunner.run(ParentRunner.java:300)
> >> > > at
> >> > >
> >> > >
> >> >
> >>
> org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
> >> > > at
> >> > >
> >> > >
> >> >
> >>
> org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
> >> > > at
> >> > >
> >> > >
> >> >
> >>
> org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
> >> > > at
> >> > >
> >> > >
> >> >
> >>
> org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
> >> > > at
> >> > >
> >> > >
> >> >
> >>
> org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
> >> > > at
> >> > >
> >> > >
> >> >
> >>
> org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
> >> > >
> >> > > java.lang.NullPointerException
> >> > > at
> >> > >
> >> > >
> >> >
> >>
> org.apache.camel.component.mongodb.AbstractMongoDbTest.cleanup(AbstractMongoDbTest.java:96)
> >> > > at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
> >> > > at
> >> > >
> >> > >
> >> >
> >>
> sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
> >> > > at
> >> > >
> >> > >
> >> >
> >>
> sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
> >> > > at java.lang.reflect.Method.invoke(Method.java:597)
> >> > > at
> >> > >
> >> > >
> >> >
> >>
> org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:45)
> >> > > at
> >> > >
> >> > >
> >> >
> >>
> org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
> >> > > at
> >> > >
> >> > >
> >> >
> >>
> org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:42)
> >> > > at
> >> > >
> >> >
> >>
> org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:36)
> >> > > at org.junit.rules.TestWatcher$1.evaluate(TestWatcher.java:47)
> >> > > at org.junit.rules.RunRules.evaluate(RunRules.java:18)
> >> > > at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:263)
> >> > > at
> >> > >
> >> > >
> >> >
> >>
> org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:68)
> >> > > at
> >> > >
> >> > >
> >> >
> >>
> org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:47)
> >> > > at org.junit.runners.ParentRunner$3.run(ParentRunner.java:231)
> >> > > at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:60)
> >> > > at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:229)
> >> > > at org.junit.runners.ParentRunner.access$000(ParentRunner.java:50)
> >> > > at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:222)
> >> > > at
> >> > >
> >> > >
> >> >
> >>
> org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:28)
> >> > > at
> >> > >
> >> >
> >>
> org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:30)
> >> > > at org.junit.runners.ParentRunner.run(ParentRunner.java:300)
> >> > > at
> >> > >
> >> > >
> >> >
> >>
> org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
> >> > > at
> >> > >
> >> > >
> >> >
> >>
> org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
> >> > > at
> >> > >
> >> > >
> >> >
> >>
> org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
> >> > > at
> >> > >
> >> > >
> >> >
> >>
> org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
> >> > > at
> >> > >
> >> > >
> >> >
> >>
> org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
> >> > > at
> >> > >
> >> > >
> >> >
> >>
> org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
> >> > >
> >> > >
> >> > > On 2 October 2012 21:26, Mark Doyle <markjohndo...@gmail.com>
> wrote:
> >> > >
> >> > > > Indeed I would; first job is to figure out how to create a JIRA...
> >> > > >
> >> > > > as for your question, yes, you assume correctly. It's the
> following
> >> > > simple
> >> > > > model object:
> >> > > >
> >> > > >
> >> > > >
> >> > >
> >> >
> >>
> https://github.com/JohannesKlug/hbird/blob/master/src/core/commons/src/main/java/org/hbird/core/commons/tmtcgroups/HummingbirdParameter.java
> >> > > >
> >> > > > Which I assume triggers the fromAnyObjectToDBObject method in the
> >> > > > MongoDbBasicConverters class? The qualified name field always
> >> contains
> >> > > > periods.
> >> > > >
> >> > > >
> >> > > > On 2 October 2012 20:11, Raul Kripalani <r...@evosent.com> wrote:
> >> > > >
> >> > > >> Hi Mark,
> >> > > >>
> >> > > >> Correct. Mongo doesn't accept dot characters in field naming
> >> because
> >> > it
> >> > > >> serves as a separator for nested fields, so it's reserved.
> >> > > >>
> >> > > >> It seems like a great idea. Please feel free to create a JIRA.
> >> Would
> >> > you
> >> > > >> be
> >> > > >> happy to work on a patch? If you want I can provide you with some
> >> > > guidance
> >> > > >> since I know this component inside out because I created it ;)
> >> > > >>
> >> > > >> There are a number of type converters that MongoDB provides...
> >> What's
> >> > > the
> >> > > >> original payload type before it hits the MongoDB endpoint?
> (Object,
> >> > > >> HashMap, etc.). I assume it's an Object but please confirm.
> >> > > >>
> >> > > >> Thanks,
> >> > > >>
> >> > > >> --
> >> > > >> *Raúl Kripalani*
> >> > > >> Apache Camel Committer
> >> > > >> Enterprise Architect, Program Manager, Open Source Integration
> >> > > specialist
> >> > > >> http://about.me/raulkripalani |
> >> > > http://www.linkedin.com/in/raulkripalani
> >> > > >> http://blog.raulkr.net | twitter: @raulvk <
> >> http://twitter.com/raulvk>
> >> > > >>
> >> > > >>
> >> > > >> On Tue, Oct 2, 2012 at 4:22 PM, Mark Doyle <
> >> markjohndo...@gmail.com>
> >> > > >> wrote:
> >> > > >>
> >> > > >> > I have a problem where a String field contains a period. This
> >> causes
> >> > > the
> >> > > >> > following exception:
> >> > > >> >
> >> > > >> > Caused by: java.lang.IllegalArgumentException: fields stored in
> >> the
> >> > db
> >> > > >> > can't have . in them. (Bad Key: 'Stock6.tm.Azimuth')
> >> > > >> >
> >> > > >> > which I believe stems from restrictions in the depths of the
> >> mongo!
> >> > > >> >
> >> > > >> > The solution seems to be to convert the character to something
> >> else
> >> > > >> (e.g. a
> >> > > >> > comma) before inserting and back again after finding. Does this
> >> seem
> >> > > >> like
> >> > > >> > something the camel-mongo component should offer as an option,
> or
> >> > even
> >> > > >> > silently deal with by default? Could it be a change in the type
> >> > > >> converters?
> >> > > >> > I think that uses Jackson to build the DB object and therefore
> >> could
> >> > > >> filter
> >> > > >> > out and replace periods. I suppose a user could run into
> >> problems if
> >> > > >> they
> >> > > >> > overrode the converters with their own.
> >> > > >> >
> >> > > >> > I don't know how camel works under the covers so this might not
> >> > work,
> >> > > >> > especially if the converters aren't used to create a real
> object
> >> > from
> >> > > >> > the DBObject returned by Mongo.
> >> > > >> >
> >> > > >>
> >> > > >
> >> > > >
> >> > >
> >> >
> >>
> >
> >
>

Reply via email to