/*
* (C) Copyright 2015-2016 the original author or authors.
*
* Licensed 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.
*
* Contributors:
* ohun@live.cn (夜色)
*/
package com.mpush.client.gateway.connection;
import com.google.common.collect.Maps;
import com.mpush.api.connection.Connection;
import com.mpush.api.service.Listener;
import com.mpush.api.spi.common.ServiceDiscoveryFactory;
import com.mpush.api.srd.ServiceDiscovery;
import com.mpush.api.srd.ServiceNode;
import com.mpush.client.gateway.GatewayUDPConnector;
import com.mpush.common.message.BaseMessage;
import com.mpush.tools.thread.pool.ThreadPoolManager;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.net.InetSocketAddress;
import java.util.Map;
import java.util.function.Consumer;
import java.util.function.Function;
import static com.mpush.api.srd.ServiceNames.GATEWAY_SERVER;
import static com.mpush.tools.config.CC.mp.net.gateway_server_multicast;
import static com.mpush.tools.config.CC.mp.net.gateway_server_port;
/**
* Created by yxx on 2016/5/17.
*
* @author ohun@live.cn
*/
public class GatewayUDPConnectionFactory extends GatewayConnectionFactory {
private final Logger logger = LoggerFactory.getLogger(GatewayUDPConnectionFactory.class);
private final Map<String, InetSocketAddress> ip_address = Maps.newConcurrentMap();
private final GatewayUDPConnector connector = GatewayUDPConnector.I();
private final InetSocketAddress multicastRecipient = new InetSocketAddress(gateway_server_multicast, gateway_server_port);
@Override
protected void doStart(Listener listener) throws Throwable {
ThreadPoolManager.I.newThread("udp-client", () -> connector.start(listener)).start();
ServiceDiscovery discovery = ServiceDiscoveryFactory.create();
discovery.subscribe(GATEWAY_SERVER, this);
discovery.lookup(GATEWAY_SERVER).forEach(this::addConnection);
}
@Override
public void onServiceAdded(String path, ServiceNode node) {
addConnection(node);
}
@Override
public void onServiceUpdated(String path, ServiceNode node) {
addConnection(node);
}
@Override
public void onServiceRemoved(String path, ServiceNode node) {
ip_address.remove(node.hostAndPort());
logger.warn("Gateway Server zkNode={} was removed.", node);
}
private void addConnection(ServiceNode node) {
ip_address.put(node.hostAndPort(), new InetSocketAddress(node.getHost(), node.getPort()));
}
@Override
public void doStop(Listener listener) throws Throwable {
ip_address.clear();
connector.stop();
}
@Override
public Connection getConnection(String hostAndPort) {
return connector.getConnection();
}
@SuppressWarnings("unchecked")
@Override
public <M extends BaseMessage> boolean send(String hostAndPort, Function<Connection, M> creator, Consumer<M> sender) {
InetSocketAddress recipient = ip_address.get(hostAndPort);
if (recipient == null) return false;// gateway server 找不到,直接返回推送失败
M message = creator.apply(connector.getConnection());
message.setRecipient(recipient);
sender.accept(message);
return true;
}
@Override
public <M extends BaseMessage> boolean broadcast(Function<Connection, M> creator, Consumer<M> sender) {
M message = creator.apply(connector.getConnection());
message.setRecipient(multicastRecipient);
sender.accept(message);
return true;
}
}