/**
* Copyright (c) 2002-2012 "Neo Technology,"
* Network Engine for Objects in Lund AB [http://neotechnology.com]
*
* This file is part of Neo4j.
*
* Neo4j is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.neo4j.cluster.protocol.cluster;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.neo4j.helpers.Function;
import org.neo4j.helpers.Specification;
import org.neo4j.helpers.collection.Iterables;
/**
* Cluster configuration. Includes name of cluster, list of nodes, and role mappings
*/
public class ClusterConfiguration
{
public static final String COORDINATOR = "coordinator";
public static final String SLAVE = "slave";
private final String name;
private List<URI> members;
private Map<String, URI> roles = new HashMap<String, URI>();
private int allowedFailures = 1;
public ClusterConfiguration( String name, String... members )
{
this.name = name;
this.members = new ArrayList<URI>();
for ( String node : members )
{
try
{
this.members.add( new URI( node ) );
}
catch ( URISyntaxException e )
{
e.printStackTrace();
}
}
}
public ClusterConfiguration( String name, Collection<URI> members )
{
this.name = name;
this.members = new ArrayList<URI>( members );
}
public ClusterConfiguration( ClusterConfiguration copy )
{
this.name = copy.name;
this.members = new ArrayList<URI>( copy.members );
this.roles = new HashMap<String, URI>( copy.roles );
}
public void joined( URI nodeUrl )
{
if ( members.contains( nodeUrl ) )
{
return;
}
this.members = new ArrayList<URI>( members );
members.add( nodeUrl );
}
public void left( URI nodeUrl )
{
this.members = new ArrayList<URI>( members );
members.remove( nodeUrl );
// Remove any roles that this node had
Iterator<Map.Entry<String, URI>> entries = roles.entrySet().iterator();
while ( entries.hasNext() )
{
Map.Entry<String, URI> roleEntry = entries.next();
if ( roleEntry.getValue().equals( nodeUrl ) )
{
entries.remove();
}
}
}
public void elected( String name, URI node )
{
assert members.contains( node );
roles = new HashMap<String, URI>( roles );
roles.put( name, node );
}
public void setMembers( Iterable<URI> members )
{
this.members = new ArrayList<URI>();
for ( URI node : members )
{
this.members.add( node );
}
}
public void setRoles( Map<String, URI> roles )
{
for ( URI uri : roles.values() )
{
assert members.contains( uri );
}
this.roles.clear();
this.roles.putAll( roles );
}
public List<URI> getMembers()
{
return members;
}
public String getName()
{
return name;
}
public Map<String, URI> getRoles()
{
return roles;
}
public int getAllowedFailures()
{
return allowedFailures;
}
public void left()
{
this.members = new ArrayList<URI>();
roles = new HashMap<String, URI>();
}
public void removeElected( String roleName )
{
roles = new HashMap<String, URI>( roles );
roles.remove( roleName );
}
public URI getElected( String roleName )
{
return roles.get( roleName );
}
public Iterable<String> getRolesOf( final URI node )
{
return Iterables.map( new Function<Map.Entry<String, URI>, String>()
{
@Override
public String map( Map.Entry<String, URI> stringURIEntry )
{
return stringURIEntry.getKey();
}
}, Iterables.filter( new Specification<Map.Entry<String, URI>>()
{
@Override
public boolean satisfiedBy( Map.Entry<String, URI> item )
{
return item.getValue().equals( node );
}
}, roles.entrySet() ) );
}
@Override
public String toString()
{
return "Name:" + name + " Nodes:" + members + " Roles:" + roles;
}
}