001/*
002 * Licensed to the Apache Software Foundation (ASF) under one
003 * or more contributor license agreements.  See the NOTICE file
004 * distributed with this work for additional information
005 * regarding copyright ownership.  The ASF licenses this file
006 * to you under the Apache License, Version 2.0 (the
007 * "License"); you may not use this file except in compliance
008 * with the License.  You may obtain a copy of the License at
009 *
010 *   http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing,
013 * software distributed under the License is distributed on an
014 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015 * KIND, either express or implied.  See the License for the
016 * specific language governing permissions and limitations
017 * under the License.
018 */
019package org.apache.reef.wake.remote.transport.netty;
020
021import org.apache.reef.tang.Injector;
022import org.apache.reef.tang.Tang;
023import org.apache.reef.tang.exceptions.InjectionException;
024import org.apache.reef.wake.EStage;
025import org.apache.reef.wake.EventHandler;
026import org.apache.reef.wake.impl.SyncStage;
027import org.apache.reef.wake.remote.RemoteConfiguration;
028import org.apache.reef.wake.remote.address.LocalAddressProvider;
029import org.apache.reef.wake.remote.impl.TransportEvent;
030import org.apache.reef.wake.remote.ports.RangeTcpPortProvider;
031import org.apache.reef.wake.remote.ports.TcpPortProvider;
032import org.apache.reef.wake.remote.transport.Transport;
033import org.apache.reef.wake.remote.transport.TransportFactory;
034
035import javax.inject.Inject;
036
037/**
038 * Factory that creates a messaging transport.
039 */
040public class MessagingTransportFactory implements TransportFactory {
041
042  private final String localAddress;
043
044  /**
045   * @deprecated Have an instance injected instead.
046   */
047  @Deprecated
048  @Inject
049  // TODO[JIRA REEF-703]: change constructor to private
050  public MessagingTransportFactory(final LocalAddressProvider localAddressProvider) {
051    this.localAddress = localAddressProvider.getLocalAddress();
052  }
053
054  /**
055   * Creates a transport.
056   *
057   * @param port          a listening port
058   * @param clientHandler a transport client side handler
059   * @param serverHandler a transport server side handler
060   * @param exHandler     a exception handler
061   */
062  @Override
063  public Transport newInstance(final int port,
064                               final EventHandler<TransportEvent> clientHandler,
065                               final EventHandler<TransportEvent> serverHandler,
066                               final EventHandler<Exception> exHandler) {
067
068    final Injector injector = Tang.Factory.getTang().newInjector();
069    injector.bindVolatileParameter(RemoteConfiguration.HostAddress.class, this.localAddress);
070    injector.bindVolatileParameter(RemoteConfiguration.Port.class, port);
071    injector.bindVolatileParameter(RemoteConfiguration.RemoteClientStage.class, new SyncStage<>(clientHandler));
072    injector.bindVolatileParameter(RemoteConfiguration.RemoteServerStage.class, new SyncStage<>(serverHandler));
073
074    final Transport transport;
075    try {
076      transport = injector.getInstance(NettyMessagingTransport.class);
077      transport.registerErrorHandler(exHandler);
078      return transport;
079    } catch (final InjectionException e) {
080      throw new RuntimeException(e);
081    }
082  }
083
084  // TODO[REEF-547]: This method uses deprecated RangeTcpPortProvider.Default. Must remove usages and deprecate.
085  @Override
086  public Transport newInstance(final String hostAddress, final int port,
087                               final EStage<TransportEvent> clientStage,
088                               final EStage<TransportEvent> serverStage,
089                               final int numberOfTries,
090                               final int retryTimeout) {
091    return newInstance(hostAddress, port, clientStage,
092        serverStage, numberOfTries, retryTimeout, RangeTcpPortProvider.Default);
093  }
094
095  @Override
096  public Transport newInstance(final String hostAddress, final int port,
097                               final EStage<TransportEvent> clientStage,
098                               final EStage<TransportEvent> serverStage,
099                               final int numberOfTries,
100                               final int retryTimeout,
101                               final TcpPortProvider tcpPortProvider) {
102
103    final Injector injector = Tang.Factory.getTang().newInjector();
104    injector.bindVolatileParameter(RemoteConfiguration.HostAddress.class, hostAddress);
105    injector.bindVolatileParameter(RemoteConfiguration.Port.class, port);
106    injector.bindVolatileParameter(RemoteConfiguration.RemoteClientStage.class, clientStage);
107    injector.bindVolatileParameter(RemoteConfiguration.RemoteServerStage.class, serverStage);
108    injector.bindVolatileParameter(RemoteConfiguration.NumberOfTries.class, numberOfTries);
109    injector.bindVolatileParameter(RemoteConfiguration.RetryTimeout.class, retryTimeout);
110    injector.bindVolatileInstance(TcpPortProvider.class, tcpPortProvider);
111    try {
112      return injector.getInstance(NettyMessagingTransport.class);
113    } catch (final InjectionException e) {
114      throw new RuntimeException(e);
115    }
116  }
117}