Author: gnodet
Date: Wed Jul  2 14:28:54 2008
New Revision: 673507

URL: http://svn.apache.org/viewvc?rev=673507&view=rev
Log:
SM-1387: Make servicemix components OSGi friendly

Added:
    
servicemix/components/bindings/servicemix-jms/trunk/src/main/resources/META-INF/spring/
    
servicemix/components/bindings/servicemix-jms/trunk/src/main/resources/META-INF/spring/servicemix-jms.xml
Modified:
    servicemix/components/bindings/servicemix-jms/trunk/pom.xml
    
servicemix/components/bindings/servicemix-jms/trunk/src/main/java/org/apache/servicemix/jms/JmsComponent.java
    
servicemix/components/bindings/servicemix-jms/trunk/src/main/java/org/apache/servicemix/jms/JmsConfiguration.java
    
servicemix/components/bindings/servicemix-jms/trunk/src/main/java/org/apache/servicemix/jms/JmsEndpoint.java
    
servicemix/components/bindings/servicemix-jms/trunk/src/main/java/org/apache/servicemix/jms/endpoints/DefaultConsumerMarshaler.java
    
servicemix/components/bindings/servicemix-jms/trunk/src/main/java/org/apache/servicemix/jms/jca/JcaConsumerProcessor.java
    
servicemix/components/bindings/servicemix-jms/trunk/src/test/java/org/apache/servicemix/jms/JmsConsumerEndpointTest.java
    
servicemix/components/bindings/servicemix-jms/trunk/src/test/java/org/apache/servicemix/jms/JmsMarshalerTest.java
    
servicemix/components/bindings/servicemix-jms/trunk/src/test/java/org/apache/servicemix/jms/JmsURITest.java
    
servicemix/components/bindings/servicemix-jms/trunk/src/test/resources/org/apache/servicemix/jms/spring-jca.xml

Modified: servicemix/components/bindings/servicemix-jms/trunk/pom.xml
URL: 
http://svn.apache.org/viewvc/servicemix/components/bindings/servicemix-jms/trunk/pom.xml?rev=673507&r1=673506&r2=673507&view=diff
==============================================================================
--- servicemix/components/bindings/servicemix-jms/trunk/pom.xml (original)
+++ servicemix/components/bindings/servicemix-jms/trunk/pom.xml Wed Jul  2 
14:28:54 2008
@@ -44,6 +44,19 @@
     <servicemix-version>3.3-SNAPSHOT</servicemix-version>
     <servicemix-shared-version>4.0-SNAPSHOT</servicemix-shared-version>
     <activemq-version>5.1.0</activemq-version>
+
+    <servicemix.osgi.import>
+        org.apache.servicemix.common.osgi,
+        org.apache.woden*;resolution:=optional,
+        org.apache.xbean.spring.context.v2,
+        org.jencks*;resolution:=optional,
+        org.springframework.beans.factory.xml,
+        *
+    </servicemix.osgi.import>
+    <servicemix.osgi.export>
+        org.apache.servicemix*;version=${project.version},
+        
META-INF.services.org.apache.xbean.spring.http.servicemix.apache.org.jms
+    </servicemix.osgi.export>
   </properties>
 
   <dependencies>

Modified: 
servicemix/components/bindings/servicemix-jms/trunk/src/main/java/org/apache/servicemix/jms/JmsComponent.java
URL: 
http://svn.apache.org/viewvc/servicemix/components/bindings/servicemix-jms/trunk/src/main/java/org/apache/servicemix/jms/JmsComponent.java?rev=673507&r1=673506&r2=673507&view=diff
==============================================================================
--- 
servicemix/components/bindings/servicemix-jms/trunk/src/main/java/org/apache/servicemix/jms/JmsComponent.java
 (original)
+++ 
servicemix/components/bindings/servicemix-jms/trunk/src/main/java/org/apache/servicemix/jms/JmsComponent.java
 Wed Jul  2 14:28:54 2008
@@ -28,12 +28,9 @@
 import org.apache.servicemix.common.Deployer;
 import org.apache.servicemix.common.Endpoint;
 import org.apache.servicemix.common.ServiceUnit;
+import org.apache.servicemix.common.util.IntrospectionSupport;
+import org.apache.servicemix.common.util.URISupport;
 import org.apache.servicemix.common.xbean.BaseXBeanDeployer;
-import org.apache.servicemix.jbi.security.auth.AuthenticationService;
-import org.apache.servicemix.jbi.security.auth.impl.JAASAuthenticationService;
-import org.apache.servicemix.jbi.security.keystore.KeystoreManager;
-import org.apache.servicemix.jbi.util.IntrospectionSupport;
-import org.apache.servicemix.jbi.util.URISupport;
 import org.apache.servicemix.jms.endpoints.JmsConsumerEndpoint;
 import org.apache.servicemix.jms.endpoints.JmsProviderEndpoint;
 
@@ -80,28 +77,28 @@
     /**
      * @return the keystoreManager
      */
-    public KeystoreManager getKeystoreManager() {
+    public Object getKeystoreManager() {
         return configuration.getKeystoreManager();
     }
 
     /**
      * @param keystoreManager the keystoreManager to set
      */
-    public void setKeystoreManager(KeystoreManager keystoreManager) {
+    public void setKeystoreManager(Object keystoreManager) {
         this.configuration.setKeystoreManager(keystoreManager);
     }
 
     /**
      * @return the authenticationService
      */
-    public AuthenticationService getAuthenticationService() {
+    public Object getAuthenticationService() {
         return configuration.getAuthenticationService();
     }
 
     /**
      * @param authenticationService the authenticationService to set
      */
-    public void setAuthenticationService(AuthenticationService 
authenticationService) {
+    public void setAuthenticationService(Object authenticationService) {
         this.configuration.setAuthenticationService(authenticationService);
     }
 
@@ -134,7 +131,7 @@
             try {
                 String name = configuration.getKeystoreManagerName();
                 Object km =  context.getNamingContext().lookup(name);
-                configuration.setKeystoreManager((KeystoreManager) km); 
+                configuration.setKeystoreManager(km); 
             } catch (Exception e) {
                 // ignore
             }
@@ -143,9 +140,14 @@
             try {
                 String name = configuration.getAuthenticationServiceName();
                 Object as =  context.getNamingContext().lookup(name);
-                configuration.setAuthenticationService((AuthenticationService) 
as); 
+                configuration.setAuthenticationService(as); 
             } catch (Exception e) {
-                configuration.setAuthenticationService(new 
JAASAuthenticationService());
+                try {
+                    Class cl = 
Class.forName("org.apache.servicemix.jbi.security.auth.impl.JAASAuthenticationService");
+                    configuration.setAuthenticationService(cl.newInstance());
+                } catch (Throwable t) {
+                    logger.warn("Unable to retrieve or create the 
authentication service");
+                }
             }
         }
     }

Modified: 
servicemix/components/bindings/servicemix-jms/trunk/src/main/java/org/apache/servicemix/jms/JmsConfiguration.java
URL: 
http://svn.apache.org/viewvc/servicemix/components/bindings/servicemix-jms/trunk/src/main/java/org/apache/servicemix/jms/JmsConfiguration.java?rev=673507&r1=673506&r2=673507&view=diff
==============================================================================
--- 
servicemix/components/bindings/servicemix-jms/trunk/src/main/java/org/apache/servicemix/jms/JmsConfiguration.java
 (original)
+++ 
servicemix/components/bindings/servicemix-jms/trunk/src/main/java/org/apache/servicemix/jms/JmsConfiguration.java
 Wed Jul  2 14:28:54 2008
@@ -25,9 +25,6 @@
 
 import javax.jms.ConnectionFactory;
 
-import org.apache.servicemix.jbi.security.auth.AuthenticationService;
-import org.apache.servicemix.jbi.security.keystore.KeystoreManager;
-
 /**
  * @author gnodet
  * @org.apache.xbean.XBean element="configuration"
@@ -46,8 +43,8 @@
     private String jndiConnectionFactoryName;
     private String processorName = "multiplexing";
     private transient ConnectionFactory connectionFactory;
-    private transient KeystoreManager keystoreManager;
-    private transient AuthenticationService authenticationService;
+    private transient Object keystoreManager;
+    private transient Object authenticationService;
     
     /**
      * The JNDI name of the AuthenticationService object
@@ -93,13 +90,13 @@
     /**
      * @return the authenticationService
      */
-    public AuthenticationService getAuthenticationService() {
+    public Object getAuthenticationService() {
         return authenticationService;
     }
     /**
      * @param authenticationService the authenticationService to set
      */
-    public void setAuthenticationService(AuthenticationService 
authenticationService) {
+    public void setAuthenticationService(Object authenticationService) {
         this.authenticationService = authenticationService;
     }
     /**
@@ -117,13 +114,13 @@
     /**
      * @return the keystoreManager
      */
-    public KeystoreManager getKeystoreManager() {
+    public Object getKeystoreManager() {
         return keystoreManager;
     }
     /**
      * @param keystoreManager the keystoreManager to set
      */
-    public void setKeystoreManager(KeystoreManager keystoreManager) {
+    public void setKeystoreManager(Object keystoreManager) {
         this.keystoreManager = keystoreManager;
     }
     /**

Modified: 
servicemix/components/bindings/servicemix-jms/trunk/src/main/java/org/apache/servicemix/jms/JmsEndpoint.java
URL: 
http://svn.apache.org/viewvc/servicemix/components/bindings/servicemix-jms/trunk/src/main/java/org/apache/servicemix/jms/JmsEndpoint.java?rev=673507&r1=673506&r2=673507&view=diff
==============================================================================
--- 
servicemix/components/bindings/servicemix-jms/trunk/src/main/java/org/apache/servicemix/jms/JmsEndpoint.java
 (original)
+++ 
servicemix/components/bindings/servicemix-jms/trunk/src/main/java/org/apache/servicemix/jms/JmsEndpoint.java
 Wed Jul  2 14:28:54 2008
@@ -33,8 +33,8 @@
 
 import org.apache.servicemix.common.ExchangeProcessor;
 import org.apache.servicemix.common.ExternalEndpoint;
-import org.apache.servicemix.jbi.security.auth.AuthenticationService;
-import org.apache.servicemix.jbi.security.keystore.KeystoreManager;
+import org.apache.servicemix.common.security.AuthenticationService;
+import org.apache.servicemix.common.security.KeystoreManager;
 import org.apache.servicemix.soap.SoapEndpoint;
 import org.apache.servicemix.store.Store;
 import org.apache.servicemix.store.StoreFactory;
@@ -544,13 +544,13 @@
     }
 
     public AuthenticationService getAuthenticationService() {
-        JmsComponent component = (JmsComponent) 
getServiceUnit().getComponent();
-        return component.getAuthenticationService();
+        JmsComponent comp = (JmsComponent) getServiceUnit().getComponent();
+        return 
AuthenticationService.Proxy.create(comp.getAuthenticationService());
     }
 
     public KeystoreManager getKeystoreManager() {
-        JmsComponent component = (JmsComponent) 
getServiceUnit().getComponent();
-        return component.getKeystoreManager();
+        JmsComponent comp = (JmsComponent) getServiceUnit().getComponent();
+        return KeystoreManager.Proxy.create(comp.getKeystoreManager());
     }
 
     /**

Modified: 
servicemix/components/bindings/servicemix-jms/trunk/src/main/java/org/apache/servicemix/jms/endpoints/DefaultConsumerMarshaler.java
URL: 
http://svn.apache.org/viewvc/servicemix/components/bindings/servicemix-jms/trunk/src/main/java/org/apache/servicemix/jms/endpoints/DefaultConsumerMarshaler.java?rev=673507&r1=673506&r2=673507&view=diff
==============================================================================
--- 
servicemix/components/bindings/servicemix-jms/trunk/src/main/java/org/apache/servicemix/jms/endpoints/DefaultConsumerMarshaler.java
 (original)
+++ 
servicemix/components/bindings/servicemix-jms/trunk/src/main/java/org/apache/servicemix/jms/endpoints/DefaultConsumerMarshaler.java
 Wed Jul  2 14:28:54 2008
@@ -31,16 +31,16 @@
 import javax.jms.TextMessage;
 import javax.xml.transform.Source;
 
+import org.apache.servicemix.common.JbiConstants;
 import org.apache.servicemix.jbi.jaxp.SourceTransformer;
 import org.apache.servicemix.jbi.jaxp.StringSource;
-import org.apache.servicemix.jbi.messaging.MessageExchangeSupport;
 
 public class DefaultConsumerMarshaler implements JmsConsumerMarshaler {
     
     private URI mep;
 
     public DefaultConsumerMarshaler() {
-        this.mep = MessageExchangeSupport.IN_ONLY;
+        this.mep = JbiConstants.IN_ONLY;
     }
     
     public DefaultConsumerMarshaler(URI mep) {

Modified: 
servicemix/components/bindings/servicemix-jms/trunk/src/main/java/org/apache/servicemix/jms/jca/JcaConsumerProcessor.java
URL: 
http://svn.apache.org/viewvc/servicemix/components/bindings/servicemix-jms/trunk/src/main/java/org/apache/servicemix/jms/jca/JcaConsumerProcessor.java?rev=673507&r1=673506&r2=673507&view=diff
==============================================================================
--- 
servicemix/components/bindings/servicemix-jms/trunk/src/main/java/org/apache/servicemix/jms/jca/JcaConsumerProcessor.java
 (original)
+++ 
servicemix/components/bindings/servicemix-jms/trunk/src/main/java/org/apache/servicemix/jms/jca/JcaConsumerProcessor.java
 Wed Jul  2 14:28:54 2008
@@ -16,6 +16,7 @@
  */
 package org.apache.servicemix.jms.jca;
 
+import java.util.concurrent.ConcurrentHashMap;
 import java.util.Map;
 
 import javax.jbi.messaging.ExchangeStatus;
@@ -33,8 +34,6 @@
 import javax.resource.spi.endpoint.MessageEndpointFactory;
 import javax.transaction.TransactionManager;
 
-import edu.emory.mathcs.backport.java.util.concurrent.ConcurrentHashMap;
-
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 import org.apache.servicemix.jms.AbstractJmsProcessor;

Added: 
servicemix/components/bindings/servicemix-jms/trunk/src/main/resources/META-INF/spring/servicemix-jms.xml
URL: 
http://svn.apache.org/viewvc/servicemix/components/bindings/servicemix-jms/trunk/src/main/resources/META-INF/spring/servicemix-jms.xml?rev=673507&view=auto
==============================================================================
--- 
servicemix/components/bindings/servicemix-jms/trunk/src/main/resources/META-INF/spring/servicemix-jms.xml
 (added)
+++ 
servicemix/components/bindings/servicemix-jms/trunk/src/main/resources/META-INF/spring/servicemix-jms.xml
 Wed Jul  2 14:28:54 2008
@@ -0,0 +1,52 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+    Licensed to the Apache Software Foundation (ASF) under one or more
+    contributor license agreements.  See the NOTICE file distributed with
+    this work for additional information regarding copyright ownership.
+    The ASF licenses this file to You under the Apache License, Version 2.0
+    (the "License"); you may not use this file except in compliance with
+    the License.  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+
+-->
+<beans xmlns="http://www.springframework.org/schema/beans";
+       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance";
+       xmlns:osgi="http://www.springframework.org/schema/osgi";
+       xmlns:util="http://www.springframework.org/schema/util";
+       xsi:schemaLocation="
+  http://www.springframework.org/schema/beans
+  http://www.springframework.org/schema/beans/spring-beans.xsd
+  http://www.springframework.org/schema/util
+  http://www.springframework.org/schema/util/spring-util.xsd
+  http://www.springframework.org/schema/osgi
+  http://www.springframework.org/schema/osgi/spring-osgi.xsd";>
+
+    <bean id="servicemix-jms" class="org.apache.servicemix.jms.JmsComponent">
+    </bean>
+
+    <bean id="endpoint-tracker" 
class="org.apache.servicemix.common.osgi.EndpointTracker">
+        <property name="component" ref="servicemix-jms" />
+    </bean>
+
+    <osgi:list id="endpoints"
+               interface="org.apache.servicemix.common.osgi.EndpointWrapper"
+               cardinality="0..N">
+        <osgi:listener ref="endpoint-tracker" bind-method="register" 
unbind-method="unregister" />
+    </osgi:list>
+
+    <osgi:service ref="servicemix-jms" 
interface="javax.jbi.component.Component">
+        <osgi:service-properties>
+            <entry key="NAME" value="servicemix-jms" />
+            <entry key="TYPE" value="binding-component" />
+        </osgi:service-properties>
+    </osgi:service>
+
+</beans>

Modified: 
servicemix/components/bindings/servicemix-jms/trunk/src/test/java/org/apache/servicemix/jms/JmsConsumerEndpointTest.java
URL: 
http://svn.apache.org/viewvc/servicemix/components/bindings/servicemix-jms/trunk/src/test/java/org/apache/servicemix/jms/JmsConsumerEndpointTest.java?rev=673507&r1=673506&r2=673507&view=diff
==============================================================================
--- 
servicemix/components/bindings/servicemix-jms/trunk/src/test/java/org/apache/servicemix/jms/JmsConsumerEndpointTest.java
 (original)
+++ 
servicemix/components/bindings/servicemix-jms/trunk/src/test/java/org/apache/servicemix/jms/JmsConsumerEndpointTest.java
 Wed Jul  2 14:28:54 2008
@@ -26,11 +26,11 @@
 
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
+import org.apache.servicemix.common.JbiConstants;
 import org.apache.servicemix.components.util.EchoComponent;
 import org.apache.servicemix.components.util.MockServiceComponent;
 import org.apache.servicemix.jbi.jaxp.SourceTransformer;
 import org.apache.servicemix.jbi.jaxp.StringSource;
-import org.apache.servicemix.jbi.messaging.MessageExchangeSupport;
 import org.apache.servicemix.jbi.util.FileUtil;
 import org.apache.servicemix.jms.endpoints.DefaultConsumerMarshaler;
 import org.apache.servicemix.jms.endpoints.JmsConsumerEndpoint;
@@ -141,7 +141,7 @@
         endpoint.setConnectionFactory(connectionFactory);
         endpoint.setDestinationName("destination");
         endpoint.setReplyDestinationName("replyDestination");
-        endpoint.setMarshaler(new 
DefaultConsumerMarshaler(MessageExchangeSupport.IN_OUT));
+        endpoint.setMarshaler(new 
DefaultConsumerMarshaler(JbiConstants.IN_OUT));
         component.setEndpoints(new JmsConsumerEndpoint[] {endpoint});
         container.activateComponent(component, "servicemix-jms");
 
@@ -180,7 +180,7 @@
         endpoint.setDestinationName("destination");
         endpoint.setReplyDestinationName("replyDestination");
         endpoint.setTransacted("jms");
-        endpoint.setMarshaler(new 
DefaultConsumerMarshaler(MessageExchangeSupport.IN_OUT));
+        endpoint.setMarshaler(new 
DefaultConsumerMarshaler(JbiConstants.IN_OUT));
         component.setEndpoints(new JmsConsumerEndpoint[] {endpoint});
         container.activateComponent(component, "servicemix-jms");
 

Modified: 
servicemix/components/bindings/servicemix-jms/trunk/src/test/java/org/apache/servicemix/jms/JmsMarshalerTest.java
URL: 
http://svn.apache.org/viewvc/servicemix/components/bindings/servicemix-jms/trunk/src/test/java/org/apache/servicemix/jms/JmsMarshalerTest.java?rev=673507&r1=673506&r2=673507&view=diff
==============================================================================
--- 
servicemix/components/bindings/servicemix-jms/trunk/src/test/java/org/apache/servicemix/jms/JmsMarshalerTest.java
 (original)
+++ 
servicemix/components/bindings/servicemix-jms/trunk/src/test/java/org/apache/servicemix/jms/JmsMarshalerTest.java
 Wed Jul  2 14:28:54 2008
@@ -32,9 +32,9 @@
 import org.apache.activemq.broker.BrokerService;
 import org.apache.activemq.command.ActiveMQQueue;
 import org.apache.activemq.xbean.BrokerFactoryBean;
+import org.apache.servicemix.common.JbiConstants;
 import org.apache.servicemix.jbi.container.JBIContainer;
 import org.apache.servicemix.jbi.jaxp.SourceTransformer;
-import org.apache.servicemix.jbi.messaging.MessageExchangeSupport;
 import org.apache.servicemix.tck.ReceiverComponent;
 import org.springframework.core.io.ClassPathResource;
 
@@ -82,7 +82,7 @@
         ep.setRole(MessageExchange.Role.CONSUMER);
         ep.setDestinationStyle(AbstractJmsProcessor.STYLE_QUEUE);
         ep.setDestination(queue);
-        ep.setDefaultMep(MessageExchangeSupport.IN_ONLY);
+        ep.setDefaultMep(JbiConstants.IN_ONLY);
         ep.setMarshaler(new DefaultJmsMarshaler(ep));
         jms.setEndpoints(new JmsEndpoint[] {ep });
         container.activateComponent(jms, "servicemix-jms");

Modified: 
servicemix/components/bindings/servicemix-jms/trunk/src/test/java/org/apache/servicemix/jms/JmsURITest.java
URL: 
http://svn.apache.org/viewvc/servicemix/components/bindings/servicemix-jms/trunk/src/test/java/org/apache/servicemix/jms/JmsURITest.java?rev=673507&r1=673506&r2=673507&view=diff
==============================================================================
--- 
servicemix/components/bindings/servicemix-jms/trunk/src/test/java/org/apache/servicemix/jms/JmsURITest.java
 (original)
+++ 
servicemix/components/bindings/servicemix-jms/trunk/src/test/java/org/apache/servicemix/jms/JmsURITest.java
 Wed Jul  2 14:28:54 2008
@@ -30,10 +30,10 @@
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 import org.apache.servicemix.client.DefaultServiceMixClient;
+import org.apache.servicemix.common.JbiConstants;
+import org.apache.servicemix.common.util.URIResolver;
 import org.apache.servicemix.jbi.jaxp.SourceTransformer;
 import org.apache.servicemix.jbi.jaxp.StringSource;
-import org.apache.servicemix.jbi.messaging.MessageExchangeSupport;
-import org.apache.servicemix.jbi.resolver.URIResolver;
 import org.apache.servicemix.tck.ReceiverComponent;
 
 public class JmsURITest extends AbstractJmsTestSupport {
@@ -47,7 +47,7 @@
         ep.setRole(MessageExchange.Role.CONSUMER);
         ep.setService(ReceiverComponent.SERVICE);
         ep.setEndpoint(ReceiverComponent.ENDPOINT);
-        ep.setDefaultMep(MessageExchangeSupport.IN_ONLY);
+        ep.setDefaultMep(JbiConstants.IN_ONLY);
         ep.setJmsProviderDestinationName("foo.bar.myqueue");
         ep.setDestinationStyle(AbstractJmsProcessor.STYLE_QUEUE);
         jms.setEndpoints(new JmsEndpoint[] {ep});

Modified: 
servicemix/components/bindings/servicemix-jms/trunk/src/test/resources/org/apache/servicemix/jms/spring-jca.xml
URL: 
http://svn.apache.org/viewvc/servicemix/components/bindings/servicemix-jms/trunk/src/test/resources/org/apache/servicemix/jms/spring-jca.xml?rev=673507&r1=673506&r2=673507&view=diff
==============================================================================
--- 
servicemix/components/bindings/servicemix-jms/trunk/src/test/resources/org/apache/servicemix/jms/spring-jca.xml
 (original)
+++ 
servicemix/components/bindings/servicemix-jms/trunk/src/test/resources/org/apache/servicemix/jms/spring-jca.xml
 Wed Jul  2 14:28:54 2008
@@ -20,7 +20,7 @@
 <beans xmlns:sm="http://servicemix.apache.org/config/1.0"; 
             xmlns:jms="http://servicemix.apache.org/jms/1.0";
             xmlns:amq="http://activemq.org/config/1.0";
-       xmlns:amqra="http://activemq.org/ra/1.0";
+       xmlns:amqra="http://activemq.apache.org/schema/ra";
        xmlns:jencks="http://jencks.org/2.0";
             xmlns:test="http://test";>
 


Reply via email to