camel-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Claus Ibsen" ...@silverbullet.dk>
Subject RE: Trying to understand how to deal with process() errors and creating an exceptionChannel for bad messages.
Date Fri, 26 Sep 2008 07:19:59 GMT
Hi Mick

I wont have time to look at this before this weekend. I will be out the office all day wrestling
with a deadly WebSphere ESB platform. 


Med venlig hilsen
 
Claus Ibsen
......................................
Silverbullet
Skovsgårdsvænget 21
8362 Hørning
Tlf. +45 2962 7576
Web: www.silverbullet.dk

-----Original Message-----
From: Mick Knutson [mailto:mknutson@baselogic.com] 
Sent: 25. september 2008 21:41
To: camel-user@activemq.apache.org
Subject: Re: Trying to understand how to deal with process() errors and creating an exceptionChannel
for bad messages.

I sent you my code. Now I have continued to try to solve this as I have a
demo of this later this afternoon.

So here is what else I have found:

*
When I have this test Method, I get 0 Error messages on my Mock Error queue:
*

        *//resultEndpoint.reset();
        resultEndpoint = MockEndpoint.resolve(camelContext,
MOCK_OUTPUT_DESTINATION_URI);
        //resultErrorEndpoint.reset();
        resultErrorEndpoint = MockEndpoint.resolve(camelContext,
MOCK_OUTPUT_ERROR_DESTINATION_URI);

        // setup RouteBuilder...
        setRoutes(inputDestinationURI, changeRequestControllerImpl);


        resultEndpoint.expectedMessageCount(0);
        resultErrorEndpoint.expectedMessageCount(1);

        // Create and Send message to input queue
        createMessage(producerTemplate, messageInputBody);

        //MockEndpoint.assertIsSatisfied(resultErrorEndpoint);
        MockEndpoint.assertIsSatisfied(resultEndpoint, resultErrorEndpoint);
*

<![CDATA[mock:*outputDestinationURI *Received message count. Expected: <0>
but was: <1>]]>
*
*Then, when I change to this test method to anything else now, I get this
result no matter what:

        *  <exception class="java.lang.AssertionError">
            <message>
              <![CDATA[mock:outputErrorDestinationURI Received message
count. Expected: <1> but was: <0>]]>
            </message>
*




On Thu, Sep 25, 2008 at 10:56 AM, Claus Ibsen <ci@silverbullet.dk> wrote:

> Hi Mick
>
> Sorry you lost me a bit there. Could you try it out some more. If you still
> have problems you could zip your source code and email it to me at:
> davsclaus@apache.org. Then I will be in a better position to take a look
> than these user forums.
>
> About the logging. Check your classpath. Maybe log4j pickup antother
> log4j.properties or log4j.xml in the classpath before your file. So try
> changing something different so you know its reading your log4j.xml file.
>
>
> Med venlig hilsen
>
> Claus Ibsen
> ......................................
> Silverbullet
> Skovsgårdsvænget 21
> 8362 Hørning
> Tlf. +45 2962 7576
> Web: www.silverbullet.dk
>
> -----Original Message-----
> From: Mick Knutson [mailto:mknutson@baselogic.com]
> Sent: 25. september 2008 19:46
> To: camel-user@activemq.apache.org
> Subject: Re: Trying to understand how to deal with process() errors and
> creating an exceptionChannel for bad messages.
>
> 1st off, I changed my src/test/resources/log4j.xml to be INFO, and I alos
> changed my route logging to INFO:
>
>               * from(inputUri).errorHandler(
>                        deadLetterChannel(MOCK_OUTPUT_ERROR_DESTINATION_URI)
> //.maximumRedeliveries(2)
>                                //.initialRedeliveryDelay(1)
>                                .loggingLevel(LoggingLevel.INFO)*
>
>
> *But I still get debug messages.*
>
> Next: I changed one of my logs to ERROR in my Processor:
>
>       * } catch (Exception e) {
>
> log.error("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX");
>            throw new RuntimeException(e);
>        }*
>
>
> So my Processor throws a new RuntimeException in my console:
>
> *[myproject] INFO [DefaultMessageListenerContainer-1]
> ChangeRequestControllerImpl.process(33) |
> ChangeRequestControllerImpl.process(Exchange)
> [myproject] ERROR [DefaultMessageListenerContainer-1]
> ChangeRequestControllerImpl.process(78) |
> XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
> XXX
> [myproject] DEBUG [DefaultMessageListenerContainer-1] Pipeline.process(67)
> |
> Message exchange has failed so breaking out of pipeline: Exchange[JmsMess
> age: ActiveMQTextMessage {commandId = 5, responseRequired = true, messageId
> = ID:mickknutson-3641-1222364470527-2:5:1:1:1, originalDestination = null,
>  originalTransactionId = null, producerId =
> ID:mickknutson-3641-1222364470527-2:5:1:1, destination =
> queue://channel/changerequest/add, transactionId
> = null, expiration = 0, timestamp = 1222364474277, arrival = 0,
> brokerInTime
> = 1222364474293, brokerOutTime = 1222364474293, correlationId = null, rep
> lyTo = null, persistent = true, type = null, priority = 4, groupID = null,
> groupSequence = 0, targetConsumerId = null, compressed = false, userID = nu
> ll, content = null, marshalledProperties = null, dataStructure = null,
> redeliveryCounter = 0, size = 1024, properties = null, readOnlyProperties =
> tru
> e, readOnlyBody = true, droppable = false, text =
> {"customerId":"abcd","changeRequestType":"BADREQUEST","quota":"xyz"}}]
> exception: java.lang.RuntimeE
> xception: org.codehaus.jettison.json.JSONException:
> JSONObject["customerId"]
> is not a number. fault: null
> [myproject] WARN [DefaultMessageListenerContainer-1]
> EndpointMessageListener.onMessage(80) |
> Endpoint[activemq:queue:channel/changerequest/add] consum
> er caught an exception while processing JMS message: ActiveMQTextMessage
> {commandId = 5, responseRequired = true, messageId =
> ID:mickknutson-3641-1222
> 364470527-2:5:1:1:1, originalDestination = null, originalTransactionId =
> null, producerId = ID:mickknutson-3641-1222364470527-2:5:1:1, destination =
> q
> ueue://channel/changerequest/add, transactionId = null, expiration = 0,
> timestamp = 1222364474277, arrival = 0, brokerInTime = 1222364474293,
> brokerOu
> tTime = 1222364474293, correlationId = null, replyTo = null, persistent =
> true, type = null, priority = 4, groupID = null, groupSequence = 0,
> targetCo
> nsumerId = null, compressed = false, userID = null, content = null,
> marshalledProperties = null, dataStructure = null, redeliveryCounter = 0,
> size = 1
> 024, properties = null, readOnlyProperties = true, readOnlyBody = true,
> droppable = false, text =
> {"customerId":"abcd","changeRequestType":"BADREQUEST
> ","quota":"xyz"}}
> org.apache.camel.RuntimeCamelException: java.lang.RuntimeException:
> org.codehaus.jettison.json.JSONException: JSONObject["customerId"] is not a
> number
> .
> *
>
>
> But for some reason, the stack above talks about not being able to break
> the
> pipline:
>
> *[myproject] DEBUG [DefaultMessageListenerContainer-1] Pipeline.process(67)
> | Message exchange has failed so breaking out of pipeline:
> Exchange[JmsMess*
>
> There is a valid error as Camel seems to have it nested:
>
> *org.apache.camel.RuntimeCamelException: java.lang.RuntimeException:
> org.codehaus.jettison.json.JSONException: JSONObject["customerId"] is not a
> number
>
>
>
> *
>
> On Thu, Sep 25, 2008 at 10:33 AM, Claus Ibsen <ci@silverbullet.dk> wrote:
>
> > I can not se any ERROR in the console. They are all DEBUG, WARN etc. but
> no
> > ERROR.
> >
> > Try setting log4j loglevel to INFO to get rid of DEBUG logging.
> >
> > Med venlig hilsen
> >
> > Claus Ibsen
> > ......................................
> > Silverbullet
> > Skovsgårdsvænget 21
> > 8362 Hørning
> > Tlf. +45 2962 7576
> > Web: www.silverbullet.dk
> > -----Original Message-----
> > From: Mick Knutson [mailto:mknutson@baselogic.com]
> > Sent: 25. september 2008 19:19
> > To: camel-user@activemq.apache.org
> > Subject: Re: Trying to understand how to deal with process() errors and
> > creating an exceptionChannel for bad messages.
> >
> > I looked at the test example again:
> >
> >
> https://svn.apache.org/repos/asf/activemq/camel/trunk/camel-core/src/test/java/org/apache/camel/processor/DeadLetterChannelTest.java
> > *
> > So then I changed my test routing to:*
> >
> >        *camelContext.addRoutes(new RouteBuilder() {
> >            public void configure() {
> >
> >                from(inputUri).errorHandler(
> >
>  deadLetterChannel(MOCK_OUTPUT_ERROR_DESTINATION_URI)
> > //.maximumRedeliveries(2)
> >                                //.initialRedeliveryDelay(1)
> >                                .loggingLevel(LoggingLevel.DEBUG)
> >
> >                ).process(processor).to(MOCK_OUTPUT_DESTINATION_URI);
> >            }
> >        });
> > *
> > *
> > But I still have an error thrown in my console:*
> >
> > *[myproject] DEBUG [ActiveMQ Transport Stopper: vm://localhost#10]
> > TransportConnection.doStop(927) | Stopping connection: vm://localhost#10
> > [myproject] DEBUG [DefaultMessageListenerContainer-1]
> > EndpointMessageListener.onMessage(61) |
> > Endpoint[activemq:queue:channel/changerequest/add] consumer receiving JMS
> > message: ActiveMQTextMessage {commandId = 5, responseRequired = true,
> > messageId = ID:mickknutson-2702-1222362317888-2:5:1:1:1, origi
> > nalDestination = null, originalTransactionId = null, producerId =
> > ID:mickknutson-2702-1222362317888-2:5:1:1, destination =
> > queue://channel/changerequest/add, transactionId = null, expiration = 0,
> > timestamp = 1222362321716, arrival = 0, brokerInTime = 1222362321716,
> > brokerOutTime = 1222362321716, cor
> > relationId = null, replyTo = null, persistent = true, type = null,
> priority
> > = 4, groupID = null, groupSequence = 0, targetConsumerId = null,
> compressed
> > = false, userID = null, content = null, marshalledProperties = null,
> > dataStructure = null, redeliveryCounter = 0, size = 1024, properties =
> > null,
> > readOnlyProperties = true, readOnlyBody = true, droppable = false, text =
> > {"customerId":"abcd","changeRequestType":"BADREQUEST","quota":"xyz"}}
> > [myproject] INFO [DefaultMessageListenerContainer-1]
> > ChangeRequestControllerImpl.process(32) |
> *********************************
> > [myproject] INFO [DefaultMessageListenerContainer-1]
> > ChangeRequestControllerImpl.process(33) |
> > ChangeRequestControllerImpl.process(Exchange)
> > [myproject] INFO [DefaultMessageListenerContainer-1]
> > ChangeRequestControllerImpl.process(78) |
> > XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
> > XX
> > [myproject] DEBUG [DefaultMessageListenerContainer-1]
> Pipeline.process(67)
> > |
> > Message exchange has failed so breaking out of pipeline:
> > Exchange[JmsMessage: ActiveMQTextMessage {commandId = 5, responseRequired
> =
> > true, messageId = ID:mickknutson-2702-1222362317888-2:5:1:1:1,
> > originalDestination = null,  originalTransactionId = null, producerId =
> > ID:mickknutson-2702-1222362317888-2:5:1:1, destination =
> > queue://channel/changerequest/add, transactionId = null, expiration = 0,
> > timestamp = 1222362321716, arrival = 0, brokerInTime = 1222362321716,
> > brokerOutTime = 1222362321716, correlationId = null, replyTo = null,
> > persistent = true, type = null, priority = 4, groupID = null,
> groupSequence
> > = 0, targetConsumerId = null, compressed = false, userID = null, content
> =
> > null, marshalledProperties = null, dataStructure = null,
> redeliveryCounter
> > =
> > 0, size = 1024, properties = null, readOnlyProperties = true,
> readOnlyBody
> > =
> > true, droppable = false, text =
> > {"customerId":"abcd","changeRequestType":"BADREQUEST","quota":"xyz"}}]
> > exception: java.lang.RuntimeE
> > xception: org.codehaus.jettison.json.JSONException:
> > JSONObject["customerId"]
> > is not a number. fault: null
> > [myproject] WARN [DefaultMessageListenerContainer-1]
> > EndpointMessageListener.onMessage(80) |
> > Endpoint[activemq:queue:channel/changerequest/add] consumer caught an
> > exception while processing JMS message: ActiveMQTextMessage {commandId =
> 5,
> > responseRequired = true, messageId =
> > ID:mickknutson-2702-1222362317888-2:5:1:1:1, originalDestination = null,
> > originalTransactionId = null, producerId =
> > ID:mickknutson-2702-1222362317888-2:5:1:1, destination =
> > queue://channel/changerequest/add, transactionId = null, expiration = 0,
> > timestamp = 1222362321716, arrival = 0, brokerInTime = 1222362321716,
> > brokerOu
> > tTime = 1222362321716, correlationId = null, replyTo = null, persistent =
> > true, type = null, priority = 4, groupID = null, groupSequence = 0,
> > targetConsumerId = null, compressed = false, userID = null, content =
> null,
> > marshalledProperties = null, dataStructure = null, redeliveryCounter = 0,
> > size = 1024, properties = null, readOnlyProperties = true, readOnlyBody =
> > true, droppable = false, text =
> > {"customerId":"abcd","changeRequestType":"BADREQUEST
> > ","quota":"xyz"}} org.apache.camel.RuntimeCamelException:
> > java.lang.RuntimeException: org.codehaus.jettison.json.JSONException:
> > JSONObject["customerId"] is not a number.
> >
> >
> > *
> > 1st issue, is why does my MOCK_OUTPUT_DESTINATION_URI get the message
> when
> > a
> > RuntimeException is thrown.
> >
> > 2nd issue is why does my MOCK_OUTPUT_ERROR_DESTINATION_URI not get any
> > messages at all.
> >
> >
> > *Here is my TestNG results:*
> >          *<exception class="java.lang.AssertionError">
> >            <message>
> >              <![CDATA[mock:outputDestinationURI Received message
> > count. Expected:
> > <0> but was: <1>]]>
> >            </message>
> > *
> >
> > *So I also added this to my test as per the Unit Test listed above:*
> >
> > *Throwable t =
> >
> >
> resultErrorEndpoint.getExchanges().get(0).getProperty(DeadLetterChannel.EXCEPTION_CAUSE_PROPERTY,
> > Throwable.class);
> > *
> >
> > *Then I started getting:*
> >
> > *<full-stacktrace>
> >              <![CDATA[java.lang.ArrayIndexOutOfBoundsException: 0
> >    at
> >
> >
> java.util.concurrent.CopyOnWriteArrayList.get(CopyOnWriteArrayList.java:343)
> >    at
> >
> >
> com.servepath.changerequest.ChangeRequestTest.testCreateInvalidChangeRequest(ChangeRequestTest.java:138)
> > *
> >
> >
> >
> >
> >
> >
> > On Wed, Sep 24, 2008 at 11:13 PM, Willem Jiang <willem.jiang@gmail.com
> > >wrote:
> >
> > > The "mock:fail" is just for the testing, you can use your endpoint URI
> > for
> > > the error message receiving.
> > > I just went through the codes in your mail, can you remove the below
> can
> > > from router configure and try again?
> > >
> > >
> > >
> >
> exception(Exception.class).process(changeRequestInputExceptionProcessor).to(MOCK_OUTPUT_ERROR_DESTINATION_URI);
> > >
> > >
> > > Willem.
> > >
> > >
> > > Mick Knutson wrote:
> > >
> > >> But my test throws an exception, and created
> > >> a*MOCK_OUTPUT_ERROR_DESTINATION_URI
> > >> * Mock instead of the name used "mock:fail" or is there some reason I
> > have
> > >> to use "mock:fail" instead of my endpoint?
> > >>
> > >>
> > >>
> > >>
> > >> On Wed, Sep 24, 2008 at 10:34 PM, Mick Knutson <
> mknutson@baselogic.com
> > >> >wrote:
> > >>
> > >>
> > >>
> > >>> But my test throws an exception, and created
> > >>>
> > >>> On Wed, Sep 24, 2008 at 8:23 PM, Willem Jiang <
> willem.jiang@gmail.com
> > >>> >wrote:
> > >>>
> > >>>
> > >>>
> > >>>> Can you take a look at the below unit test, the message is only
sent
> > to
> > >>>> the "mock:fail" endpoint when the exception is thrown.
> > >>>>
> > >>>>
> > >>>> Willem Jiang wrote:
> > >>>>
> > >>>>
> > >>>>
> > >>>>> Hi
> > >>>>>
> > >>>>> You don't need to call the exchange.isFailed(),  it just check
if
> the
> > >>>>> exchange's  fault message  or exception  is set.
> > >>>>> Here is a Unit test of DeadLetterChannel[1],  which shows what
you
> > >>>>> want.
> > >>>>> Please check it out.
> > >>>>>
> > >>>>> [1]
> > >>>>>
> > >>>>>
> >
> https://svn.apache.org/repos/asf/activemq/camel/trunk/camel-core/src/test/java/org/apache/camel/processor/DeadLetterChannelTest.java
> > >>>>>
> > >>>>> Willem
> > >>>>>
> > >>>>> Mick Knutson wrote:
> > >>>>>
> > >>>>>
> > >>>>>
> > >>>>>> To give some background here is my process:
> > >>>>>>
> > >>>>>>   *public void process(Exchange exchange)
> > >>>>>>           throws Exception {
> > >>>>>>       log.info("process ChangeRequestInputTransformer request");
> > >>>>>>
> > >>>>>>       String body = (String) exchange.getIn().getBody();
> > >>>>>>
> > >>>>>>       // Get a Map of Items from the input message
> > >>>>>>       JSONObject jsonIn = new JSONObject(body);
> > >>>>>>
> > >>>>>>       // validate input message, route to verifyErrorEndpoint
if
> > there
> > >>>>>> are
> > >>>>>> errors.
> > >>>>>>       String customerId = jsonIn.getString(Constants.CUSTOMER_ID);
> > >>>>>>       String type = jsonIn.getString(Constants.CHANGEREQUST_TYPE);
> > >>>>>>       String quota = jsonIn.getString(Constants.QUOTA);
> > >>>>>>
> > >>>>>>       ChangeRequest changeRequest = null;
> > >>>>>>
> > >>>>>>       try {
> > >>>>>>
> > >>>>>>           if (type.equalsIgnoreCase(Constants.PROVISION))
{
> > >>>>>>               log.info("***** PROVISION *****");
> > >>>>>>               changeRequest =
> > createProvisionChangeRequest(customerId,
> > >>>>>> quota); // can throw Exception
> > >>>>>>
> > >>>>>>  exchange.getOut().setHeader(Constants.REQUEST_DESTINATION,
> > >>>>>> Constants.REQUEST_OUTPUT_CHANNEL);
> > >>>>>>
> > >>>>>>           } else if (type.equalsIgnoreCase(Constants.DEPROVISION))
> {
> > >>>>>>               log.info("DEPROVISION");
> > >>>>>>           } else {
> > >>>>>>               log.error("Invalid Change Request");
> > >>>>>>
> > >>>>>>  exchange.getOut().setHeader(Constants.REQUEST_DESTINATION,
> > >>>>>> Constants.REQUEST_INPUT_ERROR_CHANNEL);
> > >>>>>>           }
> > >>>>>>
> > >>>>>>           String jsonOut = toJSON(body);
> > >>>>>>
> > >>>>>>
> > >>>>>>  exchange.getOut().setMessageId(changeRequest.getChangeRequestId()
> > >>>>>> + "");
> > >>>>>>           exchange.getOut().setHeader(Constants.CORRELATION_ID,
> > >>>>>> changeRequest.getChangeRequestId());
> > >>>>>>           exchange.getOut().setHeader(Constants.TIMEOUT,
new
> > >>>>>> Integer(5000)); // fixme: 5 seconds....
> > >>>>>>           exchange.getOut().setHeader(Constants.CUSTOMER_ID,
> > >>>>>> changeRequest.getCustomerId());
> > >>>>>>
> > >>>>>>           exchange.getOut().setBody(jsonOut);
> > >>>>>>
> > >>>>>>           //todo need to rout to CR_INPUT_ERROR_CHANNEL
if there
> is
> > an
> > >>>>>> error.
> > >>>>>>
> > >>>>>>           log.info("*********************************");
> > >>>>>>       } catch (Exception e) {
> > >>>>>>           exchange.isFailed();
> > >>>>>>           throw new Exception("Error creating Change Request");
> > >>>>>>       }
> > >>>>>>   }
> > >>>>>> *
> > >>>>>>
> > >>>>>> Now, I get an exception with
> > >>>>>> *exchange.getOut().setMessageId(changeRequest.getChangeRequestId()
> > >>>>>> + ""); *but my mock still gets the expected number of messages.
> > >>>>>>
> > >>>>>> so I need to understand how to stop the current message,
and
> > redirect
> > >>>>>> this
> > >>>>>> to an error channel instead.
> > >>>>>>
> > >>>>>>
> > >>>>>>
> > >>>>>>
> > >>>>>> On Tue, Sep 23, 2008 at 1:50 PM, Mick Knutson <
> > mknutson@baselogic.com
> > >>>>>>
> > >>>>>>
> > >>>>>>> wrote:
> > >>>>>>>
> > >>>>>>>
> > >>>>>>
> > >>>>>>
> > >>>>>>
> > >>>>>>> I have input messages that I am trying to process,
and when there
> > is
> > >>>>>>> an
> > >>>>>>> error, I want to create a new exceptionMessage and
put it onto an
> > >>>>>>> inputErrorChannel .
> > >>>>>>>
> > >>>>>>>
> > >>>>>>>
> > >>>>>>> --
> > >>>>>>> ---
> > >>>>>>> Thank You...
> > >>>>>>>
> > >>>>>>> Mick Knutson
> > >>>>>>> BASE Logic, inc.
> > >>>>>>> (415) 354-4215
> > >>>>>>>
> > >>>>>>> Website: http://baselogic.com
> > >>>>>>> Blog: http://baselogic.com/blog
> > >>>>>>> BLiNC Magazine: http://blincmagazine.com
> > >>>>>>> Linked IN: http://linkedin.com/in/mickknutson
> > >>>>>>> DJ Mick: http://djmick.com
> > >>>>>>> MySpace: http://myspace.com/mickknutson
> > >>>>>>> Vacation Rental: http://tahoe.baselogic.com
> > >>>>>>>
> > >>>>>>>
> > >>>>>>>
> > >>>>>>>
> > >>>>>>>
> > >>>>>>>
> > >>>>>>
> > >>>>>>
> > >>>>>>
> > >>>>>>
> > >>>>>
> > >>>>>
> > >>>>>
> > >>>> --
> > >>> ---
> > >>> Thank You...
> > >>>
> > >>> Mick Knutson
> > >>> BASE Logic, inc.
> > >>> (415) 354-4215
> > >>>
> > >>> Website: http://baselogic.com
> > >>> Blog: http://baselogic.com/blog
> > >>> BLiNC Magazine: http://blincmagazine.com
> > >>> Linked IN: http://linkedin.com/in/mickknutson
> > >>> DJ Mick: http://djmick.com
> > >>> MySpace: http://myspace.com/mickknutson
> > >>> Vacation Rental: http://tahoe.baselogic.com
> > >>>
> > >>>
> > >>>
> > >>>
> > >>
> > >>
> > >>
> > >>
> > >
> > >
> >
> >
> > --
> > ---
> > Thank You...
> >
> > Mick Knutson
> > BASE Logic, inc.
> > (415) 354-4215
> >
> > Website: http://baselogic.com
> > Blog: http://baselogic.com/blog
> > BLiNC Magazine: http://blincmagazine.com
> > Linked IN: http://linkedin.com/in/mickknutson
> > DJ Mick: http://djmick.com
> > MySpace: http://myspace.com/mickknutson
> > Vacation Rental: http://tahoe.baselogic.com
> >
>
>
>
> --
> ---
> Thank You...
>
> Mick Knutson
> BASE Logic, inc.
> (415) 354-4215
>
> Website: http://baselogic.com
> Blog: http://baselogic.com/blog
> BLiNC Magazine: http://blincmagazine.com
> Linked IN: http://linkedin.com/in/mickknutson
> DJ Mick: http://djmick.com
> MySpace: http://myspace.com/mickknutson
> Vacation Rental: http://tahoe.baselogic.com
>



-- 
---
Thank You...

Mick Knutson
BASE Logic, inc.
(415) 354-4215

Website: http://baselogic.com
Blog: http://baselogic.com/blog
BLiNC Magazine: http://blincmagazine.com
Linked IN: http://linkedin.com/in/mickknutson
DJ Mick: http://djmick.com
MySpace: http://myspace.com/mickknutson
Vacation Rental: http://tahoe.baselogic.com

Mime
View raw message