Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

merged from eee

  • Loading branch information...
commit 2078f587a5e7de18fcd7120dbfa7be9c8ffacbb9 2 parents 13c5ba1 + 0950f43
@dmitrii dmitrii authored
Showing with 1,479 additions and 982 deletions.
  1. +2 −2 clc/.classpath
  2. +41 −20 clc/modules/cloud/src/main/java/com/eucalyptus/cloud/EucalyptusBuilder.java
  3. +3 −3 clc/modules/cluster-manager/src/main/java/com/eucalyptus/blockstorage/SnapshotManager.java
  4. +2 −1  clc/modules/cluster-manager/src/main/java/com/eucalyptus/blockstorage/Snapshots.java
  5. +2 −1  clc/modules/cluster-manager/src/main/java/com/eucalyptus/blockstorage/StorageUtil.java
  6. +16 −11 clc/modules/cluster-manager/src/main/java/com/eucalyptus/blockstorage/VolumeManager.java
  7. +2 −2 clc/modules/cluster-manager/src/main/java/com/eucalyptus/blockstorage/Volumes.java
  8. +3 −3 clc/modules/cluster-manager/src/main/java/com/eucalyptus/cloud/ResourceToken.java
  9. +3 −2 clc/modules/cluster-manager/src/main/java/com/eucalyptus/cloud/run/AdmissionControl.java
  10. +26 −7 clc/modules/cluster-manager/src/main/java/com/eucalyptus/cloud/run/ClusterAllocator.java
  11. +2 −2 clc/modules/cluster-manager/src/main/java/com/eucalyptus/cloud/run/VerifyMetadata.java
  12. +14 −14 clc/modules/cluster-manager/src/main/java/com/eucalyptus/cluster/Cluster.java
  13. +0 −4 clc/modules/cluster-manager/src/main/java/com/eucalyptus/cluster/Clusters.java
  14. +5 −2 clc/modules/cluster-manager/src/main/java/com/eucalyptus/cluster/callback/VolumeAttachCallback.java
  15. +10 −5 clc/modules/cluster-manager/src/main/java/com/eucalyptus/images/ImageManager.java
  16. +46 −37 clc/modules/cluster-manager/src/main/java/com/eucalyptus/network/NetworkGroupManager.java
  17. +6 −2 clc/modules/cluster-manager/src/main/java/com/eucalyptus/util/async/StatefulMessageSet.java
  18. +12 −6 clc/modules/cluster-manager/src/main/java/com/eucalyptus/vm/VmControl.java
  19. +4 −2 clc/modules/cluster-manager/src/main/java/com/eucalyptus/vm/VmInstances.java
  20. +16 −9 clc/modules/configuration/src/main/java/com/eucalyptus/config/Configuration.java
  21. +41 −49 clc/modules/dns/src/main/java/com/eucalyptus/bootstrap/DNSBootstrapper.java
  22. +21 −4 clc/modules/dns/src/main/java/com/eucalyptus/cloud/ws/DNSControl.java
  23. +92 −92 clc/modules/dns/src/main/java/com/eucalyptus/cloud/ws/TCPHandler.java
  24. +70 −59 clc/modules/dns/src/main/java/com/eucalyptus/cloud/ws/TCPListener.java
  25. +7 −0 clc/modules/dns/src/main/java/com/eucalyptus/cloud/ws/UDPListener.java
  26. +6 −2 clc/modules/msgs/conf/scripts/setup_dbpool.groovy
  27. +4 −0 clc/modules/msgs/src/main/java/com/eucalyptus/bootstrap/Bootstrap.java
  28. +749 −48 clc/modules/msgs/src/main/java/com/eucalyptus/bootstrap/Databases.java
  29. +7 −10 clc/modules/msgs/src/main/java/com/eucalyptus/bootstrap/Hosts.java
  30. +0 −3  clc/modules/msgs/src/main/java/com/eucalyptus/component/BasicService.java
  31. +27 −28 clc/modules/msgs/src/main/java/com/eucalyptus/component/Faults.java
  32. +0 −19 clc/modules/msgs/src/main/java/com/eucalyptus/component/Partitions.java
  33. +1 −3 clc/modules/msgs/src/main/java/com/eucalyptus/component/ServiceBuilder.java
  34. +0 −160 clc/modules/msgs/src/main/java/com/eucalyptus/component/ServiceCheckRecord.java
  35. +0 −267 clc/modules/msgs/src/main/java/com/eucalyptus/component/ServiceChecks.java
  36. +1 −1  clc/modules/msgs/src/main/java/com/eucalyptus/component/ServiceState.java
  37. +41 −29 clc/modules/msgs/src/main/java/com/eucalyptus/component/ServiceTransitions.java
  38. +12 −4 clc/modules/msgs/src/main/java/com/eucalyptus/component/Topology.java
  39. +0 −3  clc/modules/msgs/src/main/java/com/eucalyptus/config/ComponentConfiguration.java
  40. +1 −1  clc/modules/msgs/src/main/java/com/eucalyptus/context/ServiceContextManager.java
  41. +1 −0  clc/modules/msgs/src/main/java/com/eucalyptus/entities/Entities.java
  42. +1 −0  clc/modules/msgs/src/main/java/com/eucalyptus/entities/EntityWrapper.java
  43. +7 −1 clc/modules/msgs/src/main/java/com/eucalyptus/entities/PersistenceContexts.java
  44. +2 −2 clc/modules/msgs/src/main/java/com/eucalyptus/event/SystemClock.java
  45. +56 −6 clc/modules/msgs/src/main/java/com/eucalyptus/system/Threads.java
  46. +14 −11 clc/modules/msgs/src/main/java/com/eucalyptus/util/RestrictedTypes.java
  47. +23 −6 clc/modules/msgs/src/main/java/com/eucalyptus/util/async/AsyncRequest.java
  48. +17 −13 clc/modules/msgs/src/main/java/com/eucalyptus/util/fsm/AtomicMarkedState.java
  49. +5 −4 clc/modules/msgs/src/main/java/com/eucalyptus/ws/EmpyreanService.java
  50. +1 −1  clc/modules/msgs/src/main/java/com/eucalyptus/ws/WebServices.java
  51. +30 −0 devel/diffdbs.sh
  52. +7 −21 devel/failover.sh
  53. +20 −0 devel/grabdbs.sh
View
4 clc/.classpath
@@ -157,7 +157,7 @@
<classpathentry kind="lib" path="lib/kahadb-5.4.1.jar"/>
<classpathentry kind="lib" path="lib/log4j-1.2.15.jar"/>
<classpathentry kind="lib" path="lib/manageontap.jar"/>
- <classpathentry kind="lib" path="lib/mule-core-2.0.1.jar"/>
+ <classpathentry kind="lib" path="lib/mule-core-2.0.1.jar" sourcepath="/bzr/third-party/mule-2.0.1.orig"/>
<classpathentry kind="lib" path="lib/mule-module-builders-2.0.1.jar"/>
<classpathentry kind="lib" path="lib/mule-module-client-2.0.1.jar"/>
<classpathentry kind="lib" path="lib/mule-module-management-2.0.1.jar"/>
@@ -170,7 +170,7 @@
<classpathentry kind="lib" path="lib/org.restlet-1.1.5.jar"/>
<classpathentry kind="lib" path="lib/org.restlet.ext.velocity-1.1.5.jar"/>
<classpathentry kind="lib" path="lib/org.simpleframework-3.1.3.jar"/>
- <classpathentry kind="lib" path="lib/proxool-0.9.1.jar"/>
+ <classpathentry kind="lib" path="lib/proxool-0.9.1.jar" sourcepath="/bzr/third-party/proxool-0.9.1"/>
<classpathentry kind="lib" path="lib/proxool-cglib.jar"/>
<classpathentry kind="lib" path="lib/quartz-1.6.5.jar"/>
<classpathentry kind="lib" path="lib/regexp-1.4.jar"/>
View
61 clc/modules/cloud/src/main/java/com/eucalyptus/cloud/EucalyptusBuilder.java
@@ -3,6 +3,7 @@
import java.net.InetAddress;
import java.net.UnknownHostException;
import org.apache.log4j.Logger;
+import com.eucalyptus.bootstrap.Databases;
import com.eucalyptus.bootstrap.Handles;
import com.eucalyptus.bootstrap.Host;
import com.eucalyptus.bootstrap.Hosts;
@@ -18,6 +19,7 @@
import com.eucalyptus.records.EventType;
import com.eucalyptus.util.Exceptions;
import com.eucalyptus.util.Internets;
+import com.google.common.base.Predicate;
@ComponentPart( Eucalyptus.class )
@Handles( { RegisterEucalyptusType.class,
@@ -83,27 +85,46 @@ public void fireCheck( ServiceConfiguration config ) throws ServiceRegistrationE
Host coordinator = Hosts.getCoordinator( );
if ( coordinator == null ) {
throw Faults.failure( config, Exceptions.error( config.getFullName( ) + ":fireCheck(): failed to lookup coordinator (" + coordinator + ")." ) );
- } else if ( coordinator.isLocalHost( ) && !Topology.isEnabledLocally( Eucalyptus.class ) && !config.isVmLocal( ) ) {
- throw Faults.failure( config,
- Exceptions.error( config.getFullName( )
- + ":fireCheck(): cloud controller depends upon ENABLED coordinator service for: "
- + coordinator ) );
- } else if ( !coordinator.isLocalHost( ) && config.isVmLocal( ) ) {
- if ( !Topology.isEnabled( Eucalyptus.class ) ) {
- throw Faults.failure( config,
- Exceptions.error( config.getFullName( )
- + ":fireCheck(): local cloud controller service isn't coordinator and is missing ENABLED cloud controller service: "
- + coordinator ) );
- } else if ( Topology.lookup( Eucalyptus.class ).isVmLocal( ) ) {
- throw Faults.failure( config,
- Exceptions.error( config.getFullName( )
- + ":fireCheck(): local cloud controller service cant be enabled when it is not the coordinator: "
- + coordinator ) );
- } else {
- LOG.debug( config.getFullName( ) + ":fireCheck() completed with coordinator currently: " + coordinator );
- }
-
+ } else if ( coordinator.isLocalHost( ) ) {
+ Check.COORDINATOR.apply( config );
+ } else if ( !coordinator.isLocalHost( ) ) {
+ Check.SECONDARY.apply( config );
}
}
+ enum Check implements Predicate<ServiceConfiguration> {
+ COORDINATOR {
+
+ @Override
+ public boolean apply( ServiceConfiguration config ) {
+//GRZE: No service check makes sense here.
+ return true;
+ }
+ },
+ SECONDARY {
+
+ @Override
+ public boolean apply( ServiceConfiguration config ) {
+ if ( config.isVmLocal( ) ) {
+ if ( !Databases.isSynchronized( ) ) {
+ throw Faults.failure( config,
+ Exceptions.error( config.getFullName( )
+ + ":fireCheck(): eucalyptus service " + config.getFullName( ) + " is currently synchronizing: "
+ + Hosts.getCoordinator( ) ) );
+ } else if ( Topology.isEnabledLocally( Eucalyptus.class ) ) {
+ throw Faults.failure( config,
+ Exceptions.error( config.getFullName( )
+ + ":fireCheck(): eucalyptus service " + config.getFullName( ) + " cant be enabled when it is not the coordinator: "
+ + Hosts.getCoordinator( ) ) );
+ } else {
+ LOG.debug( config.getFullName( ) + ":fireCheck() completed with coordinator currently: " + Hosts.getCoordinator( ) );
+ }
+ }
+ return true;
+ }
+ };
+
+ @Override
+ public abstract boolean apply( ServiceConfiguration input );
+ }
}
View
6 clc/modules/cluster-manager/src/main/java/com/eucalyptus/blockstorage/SnapshotManager.java
@@ -121,7 +121,7 @@ public CreateSnapshotResponseType create( CreateSnapshotType request ) throws Eu
final Context ctx = Contexts.lookup( );
EntityWrapper<Snapshot> db = EntityWrapper.get( Snapshot.class );
Volume vol = Transactions.find( Volume.named( ctx.getUserFullName( ).asAccountFullName( ), request.getVolumeId( ) ) );
- final ServiceConfiguration sc = Partitions.lookupService( Storage.class, vol.getPartition( ) );
+ final ServiceConfiguration sc = Topology.lookup( Storage.class, Partitions.lookupByName( vol.getPartition( ) ) );
final Volume volReady = Volumes.checkVolumeReady( vol );
Supplier<Snapshot> allocator = new Supplier<Snapshot>( ) {
@@ -169,7 +169,7 @@ public boolean apply( Snapshot snap ) {
throw Exceptions.toUndeclared( "Not authorized to delete snapshot " + request.getSnapshotId( ) + " by " + ctx.getUser( ).getName( ),
new EucalyptusCloudException( ) );
} else {
- ServiceConfiguration sc = Partitions.lookupService( Storage.class, snap.getVolumePartition( ) );
+ ServiceConfiguration sc = Topology.lookup( Storage.class, Partitions.lookupByName( snap.getPartition( ) ) );
try {
DeleteStorageSnapshotResponseType scReply = ServiceDispatcher.lookup( sc ).send( new DeleteStorageSnapshotType( snap.getDisplayName( ) ) );
if ( scReply.get_return( ) ) {
@@ -218,7 +218,7 @@ public DescribeSnapshotsResponseType describe( DescribeSnapshotsType request ) t
DescribeStorageSnapshotsType scRequest = new DescribeStorageSnapshotsType( Lists.newArrayList( snap.getDisplayName( ) ) );
if ( request.getSnapshotSet( ).isEmpty( ) || request.getSnapshotSet( ).contains( snap.getDisplayName( ) ) ) {
try {
- ServiceConfiguration sc = Partitions.lookupService( Storage.class, snap.getPartition( ) );
+ ServiceConfiguration sc = Topology.lookup( Storage.class, Partitions.lookupByName( snap.getPartition( ) ) );
DescribeStorageSnapshotsResponseType snapshotInfo = ServiceDispatcher.lookup( sc ).send( scRequest );
for ( StorageSnapshot storageSnapshot : snapshotInfo.getSnapshotSet( ) ) {
snap.setMappedState( storageSnapshot.getStatus( ) );
View
3  clc/modules/cluster-manager/src/main/java/com/eucalyptus/blockstorage/Snapshots.java
@@ -72,6 +72,7 @@
import com.eucalyptus.cloud.util.DuplicateMetadataException;
import com.eucalyptus.component.Partitions;
import com.eucalyptus.component.ServiceConfiguration;
+import com.eucalyptus.component.Topology;
import com.eucalyptus.component.id.Storage;
import com.eucalyptus.crypto.Crypto;
import com.eucalyptus.entities.EntityWrapper;
@@ -130,7 +131,7 @@ static Snapshot initializeSnapshot( UserFullName userFullName, Volume vol, Servi
}
static Snapshot startCreateSnapshot( final Volume vol, final Snapshot snap ) throws EucalyptusCloudException, DuplicateMetadataException {
- final ServiceConfiguration sc = Partitions.lookupService( Storage.class, vol.getPartition( ) );
+ final ServiceConfiguration sc = Topology.lookup( Storage.class, Partitions.lookupByName( vol.getPartition( ) ) );
try {
Snapshot snapState = Transactions.save( snap, new Callback<Snapshot>( ) {
View
3  clc/modules/cluster-manager/src/main/java/com/eucalyptus/blockstorage/StorageUtil.java
@@ -78,6 +78,7 @@
import com.eucalyptus.component.NoSuchServiceException;
import com.eucalyptus.component.Partitions;
import com.eucalyptus.component.ServiceConfiguration;
+import com.eucalyptus.component.Topology;
import com.eucalyptus.component.id.Storage;
import com.eucalyptus.entities.EntityWrapper;
import com.eucalyptus.util.EucalyptusCloudException;
@@ -106,7 +107,7 @@
ArrayList<edu.ucsb.eucalyptus.msgs.Volume> reply = Lists.newArrayList( );
for( String partition : partitionVolumeMap.keySet( ) ) {
try {
- ServiceConfiguration scConfig = Partitions.lookupService( Storage.class, partition );
+ ServiceConfiguration scConfig = Topology.lookup( Storage.class, Partitions.lookupByName( partition ) );
Iterator<String> volumeNames = Iterators.transform( partitionVolumeMap.get( partition ).iterator( ), new Function<Volume,String>() {
@Override
public String apply( Volume arg0 ) {
View
27 clc/modules/cluster-manager/src/main/java/com/eucalyptus/blockstorage/VolumeManager.java
@@ -77,6 +77,7 @@
import com.eucalyptus.cluster.Clusters;
import com.eucalyptus.cluster.callback.VolumeAttachCallback;
import com.eucalyptus.cluster.callback.VolumeDetachCallback;
+import com.eucalyptus.component.Partition;
import com.eucalyptus.component.Partitions;
import com.eucalyptus.component.ServiceConfiguration;
import com.eucalyptus.component.Topology;
@@ -205,7 +206,7 @@ public DeleteVolumeResponseType DeleteVolume( DeleteVolumeType request ) throws
db.commit( );
return reply;
}
- ServiceConfiguration sc = Partitions.lookupService( Storage.class, vol.getPartition( ) );
+ ServiceConfiguration sc = Topology.lookup( Storage.class, Partitions.lookupByName( vol.getPartition( ) ) );
DeleteStorageVolumeResponseType scReply = ServiceDispatcher.lookup( sc ).send( new DeleteStorageVolumeType( vol.getDisplayName( ) ) );
if ( scReply.get_return( ) ) {
vol.setState( State.ANNIHILATING );
@@ -300,10 +301,11 @@ public AttachVolumeResponseType AttachVolume( AttachVolumeType request ) throws
}
Cluster cluster = null;
try {
- cluster = Clusters.lookup( vm.lookupPartition( ) );
+ ServiceConfiguration ccConfig = Topology.lookup( ClusterController.class, vm.lookupPartition( ) );
+ cluster = Clusters.lookup( ccConfig );
} catch ( NoSuchElementException e ) {
LOG.debug( e, e );
- throw new EucalyptusCloudException( "Cluster does not exist: " + Topology.lookup( ClusterController.class, vm.lookupPartition( ) ) );
+ throw new EucalyptusCloudException( "Cluster does not exist in partition: " + vm.getPartition( ) );
}
final String deviceName = request.getDevice( );
final String volumeId = request.getVolumeId( );
@@ -338,8 +340,9 @@ public AttachVolumeResponseType AttachVolume( AttachVolumeType request ) throws
if ( !RestrictedTypes.filterPrivileged( ).apply( volume ) ) {
throw new EucalyptusCloudException( "Not authorized to attach volume " + request.getVolumeId( ) + " by " + ctx.getUser( ).getName( ) );
}
- ServiceConfiguration sc = Partitions.lookupService( Storage.class, volume.getPartition( ) );
- ServiceConfiguration scVm = Partitions.lookupService( Storage.class, cluster.getConfiguration( ).getPartition( ) );
+ Partition volPartition = Partitions.lookupByName( volume.getPartition( ) );
+ ServiceConfiguration sc = Topology.lookup( Storage.class, volPartition );
+ ServiceConfiguration scVm = Topology.lookup( Storage.class, cluster.getConfiguration( ).lookupPartition( ) );
if ( !sc.equals( scVm ) ) {
throw new EucalyptusCloudException( "Can only attach volumes in the same cluster: " + request.getVolumeId( ) );
} else if ( "invalid".equals( volume.getRemoteDevice( ) ) ) {
@@ -364,7 +367,7 @@ public AttachVolumeResponseType AttachVolume( AttachVolumeType request ) throws
EventRecord.here( VolumeManager.class, EventClass.VOLUME, EventType.VOLUME_ATTACH )
.withDetails( volume.getOwner( ).toString( ), volume.getDisplayName( ), "instance", vm.getInstanceId( ) )
- .withDetails( "partition", vm.lookupPartition( ).toString( ) ).info( );
+ .withDetails( "partition", vm.getPartition( ).toString( ) ).info( );
reply.setAttachedVolume( attachVol );
return reply;
}
@@ -411,15 +414,17 @@ public DetachVolumeResponseType detach( DetachVolumeType request ) throws Eucaly
}
Cluster cluster = null;
+ ServiceConfiguration ccConfig = null;
try {
- cluster = Clusters.getInstance( ).lookup( vm.lookupPartition( ) );
+ ccConfig = Topology.lookup( ClusterController.class, vm.lookupPartition( ) );
+ cluster = Clusters.lookup( ccConfig );
} catch ( NoSuchElementException e ) {
LOG.debug( e, e );
- throw new EucalyptusCloudException( "Cluster does not exist: " + Topology.lookup( ClusterController.class, vm.lookupPartition( ) ) );
+ throw new EucalyptusCloudException( "Cluster does not exist in partition: " + vm.getPartition( ) );
}
ServiceConfiguration scVm;
try {
- scVm = Partitions.lookupService( Storage.class, cluster.getConfiguration( ).getPartition( ) );
+ scVm = Topology.lookup( Storage.class, vm.lookupPartition( ) );
} catch ( Exception ex ) {
LOG.error( ex, ex );
throw new EucalyptusCloudException( "Failed to lookup SC for cluster: " + cluster, ex );
@@ -436,8 +441,8 @@ public DetachVolumeResponseType detach( DetachVolumeType request ) throws Eucaly
request.setInstanceId( vm.getInstanceId( ) );
AsyncRequests.newRequest( new VolumeDetachCallback( request ) ).dispatch( cluster.getConfiguration( ) );
EventRecord.here( VolumeManager.class, EventClass.VOLUME, EventType.VOLUME_DETACH )
- .withDetails( vm.getOwner( ).toString( ), volume.getVolumeId( ), "instance", vm.getInstanceId( ) ).withDetails( "cluster",
- Topology.lookup( ClusterController.class, vm.lookupPartition( ) ).toString( ) ).info( );
+ .withDetails( vm.getOwner( ).toString( ), volume.getVolumeId( ), "instance", vm.getInstanceId( ) )
+ .withDetails( "cluster", ccConfig.getFullName( ).toString( ) ).info( );
volume.setStatus( "detaching" );
reply.setDetachedVolume( volume );
return reply;
View
4 clc/modules/cluster-manager/src/main/java/com/eucalyptus/blockstorage/Volumes.java
@@ -63,7 +63,6 @@
package com.eucalyptus.blockstorage;
-import java.lang.reflect.UndeclaredThrowableException;
import java.util.List;
import java.util.concurrent.ExecutionException;
import org.apache.log4j.Logger;
@@ -72,6 +71,7 @@
import com.eucalyptus.cloud.CloudMetadata.VolumeMetadata;
import com.eucalyptus.component.Partitions;
import com.eucalyptus.component.ServiceConfiguration;
+import com.eucalyptus.component.Topology;
import com.eucalyptus.component.id.Storage;
import com.eucalyptus.crypto.Crypto;
import com.eucalyptus.entities.EntityWrapper;
@@ -135,7 +135,7 @@ public static Volume checkVolumeReady( final Volume vol ) throws EucalyptusCloud
return vol;
} else {
//TODO:GRZE:REMOVE temporary workaround to update the volume state.
- final ServiceConfiguration sc = Partitions.lookupService( Storage.class, vol.getPartition( ) );
+ final ServiceConfiguration sc = Topology.lookup( Storage.class, Partitions.lookupByName( vol.getPartition( ) ) );
final DescribeStorageVolumesType descVols = new DescribeStorageVolumesType( Lists.newArrayList( vol.getDisplayName( ) ) );
try {
Transactions.one( Volume.named( null, vol.getDisplayName( ) ), new Callback<Volume>( ) {
View
6 clc/modules/cluster-manager/src/main/java/com/eucalyptus/cloud/ResourceToken.java
@@ -244,15 +244,15 @@ Integer getResourceAllocationSequenceNumber( ) {
}
public void submit( ) throws NoSuchTokenException {
- Clusters.lookup( this.getAllocationInfo( ).getPartition( ) ).getNodeState( ).submitToken( this );
+ Clusters.lookup( Topology.lookup( ClusterController.class, this.getAllocationInfo( ).getPartition( ) ) ).getNodeState( ).submitToken( this );
}
public void redeem( ) throws NoSuchTokenException {
- Clusters.lookup( this.getAllocationInfo( ).getPartition( ) ).getNodeState( ).redeemToken( this );
+ Clusters.lookup( Topology.lookup( ClusterController.class, this.getAllocationInfo( ).getPartition( ) ) ).getNodeState( ).redeemToken( this );
}
public void release( ) throws NoSuchTokenException {
- Clusters.lookup( this.getAllocationInfo( ).getPartition( ) ).getNodeState( ).releaseToken( this );
+ Clusters.lookup( Topology.lookup( ClusterController.class, this.getAllocationInfo( ).getPartition( ) ) ).getNodeState( ).releaseToken( this );
}
public void setNetworkIndex( PrivateNetworkIndex networkIndex ) {
View
5 clc/modules/cluster-manager/src/main/java/com/eucalyptus/cloud/run/AdmissionControl.java
@@ -259,7 +259,7 @@ public String apply( Cluster arg0 ) {
try {
ServiceConfiguration sc = Topology.lookup( Storage.class, partition );
} catch ( Exception ex ) {
- throw new NotEnoughResourcesException( "Not enough resources: " + ex.getMessage( ), ex );
+ throw new NotEnoughResourcesException( "Not enough resources: Cannot run EBS instances in partition w/o a storage controller: " + ex.getMessage( ), ex );
}
}
try {
@@ -307,7 +307,8 @@ private int checkAvailability( String vmTypeName, List<Cluster> authorizedCluste
return Lists.newArrayList( sorted.values( ) );
}
} else {
- Cluster cluster = Clusters.getInstance( ).lookup( Partitions.lookupService( ClusterController.class, partitionName ) );
+ ServiceConfiguration ccConfig = Topology.lookup( ClusterController.class, Partitions.lookupByName( partitionName ) );
+ Cluster cluster = Clusters.lookup( ccConfig );
if ( cluster == null ) {
throw new NotEnoughResourcesException( "Can't find cluster " + partitionName );
}
View
33 clc/modules/cluster-manager/src/main/java/com/eucalyptus/cloud/run/ClusterAllocator.java
@@ -83,8 +83,8 @@
import com.eucalyptus.component.Partitions;
import com.eucalyptus.component.ServiceConfiguration;
import com.eucalyptus.component.ServiceConfigurations;
+import com.eucalyptus.component.Topology;
import com.eucalyptus.component.id.ClusterController;
-import com.eucalyptus.component.id.Eucalyptus;
import com.eucalyptus.component.id.Storage;
import com.eucalyptus.entities.Entities;
import com.eucalyptus.images.BlockStorageImageInfo;
@@ -125,7 +125,16 @@
private static Logger LOG = Logger.getLogger( ClusterAllocator.class );
enum State {
- START, CREATE_VOLS, CREATE_IGROUPS, CREATE_NETWORK, CREATE_NETWORK_RULES, CREATE_VMS, ATTACH_VOLS, ASSIGN_ADDRESSES, FINISHED, ROLLBACK;
+ START,
+ CREATE_VOLS,
+ CREATE_IGROUPS,
+ CREATE_NETWORK,
+ CREATE_NETWORK_RULES,
+ CREATE_VMS,
+ ATTACH_VOLS,
+ ASSIGN_ADDRESSES,
+ FINISHED,
+ ROLLBACK;
}
public static Boolean SPLIT_REQUESTS = true; //TODO:GRZE:@Configurable
@@ -137,10 +146,20 @@
INSTANCE;
@Override
- public boolean apply( Allocation allocInfo ) {
+ public boolean apply( final Allocation allocInfo ) {
try {
EventRecord.here( ClusterAllocator.class, EventType.VM_PREPARE, LogUtil.dumpObject( allocInfo ) ).trace( );
- Threads.enqueue( ServiceConfigurations.createEphemeral( ClusterController.INSTANCE ), new ClusterAllocator( allocInfo ) );
+ ServiceConfiguration config = Topology.lookup( ClusterController.class, allocInfo.getPartition( ) );
+ Runnable runnable = new Runnable( ) {
+ public void run( ) {
+ try {
+ new ClusterAllocator( allocInfo ).run( );
+ } catch ( Exception ex ) {
+ LOG.error( ex , ex );
+ }
+ }
+ };
+ Threads.enqueue( config, 32, runnable );
return true;
} catch ( Exception ex ) {
throw Exceptions.toUndeclared( ex );
@@ -157,7 +176,7 @@ private ClusterAllocator( final Allocation allocInfo ) {
this.allocInfo = allocInfo;
EntityTransaction db = Entities.get( VmInstance.class );
try {
- this.cluster = Clusters.lookup( allocInfo.getPartition( ) );
+ this.cluster = Clusters.lookup( Topology.lookup( ClusterController.class, allocInfo.getPartition( ) ) );
this.messages = new StatefulMessageSet<State>( this.cluster, State.values( ) );
this.setupVolumeMessages( );
this.setupNetworkMessages( );
@@ -182,7 +201,7 @@ private ClusterAllocator( final Allocation allocInfo ) {
private void setupVolumeMessages( ) throws NoSuchElementException, MetadataException, ExecutionException {
if ( this.allocInfo.getBootSet( ).getMachine( ) instanceof BlockStorageImageInfo ) {
- final ServiceConfiguration sc = Partitions.lookupService( Storage.class, this.cluster.getPartition( ) );
+ final ServiceConfiguration sc = Topology.lookup( Storage.class, this.cluster.getConfiguration( ).lookupPartition( ) );
final VirtualBootRecord root = this.allocInfo.getVmTypeInfo( ).lookupRoot( );
if ( root.isBlockStorage( ) ) {
for ( int i = 0; i < this.allocInfo.getAllocationTokens( ).size( ); i++ ) {
@@ -234,7 +253,7 @@ private VmTypeInfo makeVmTypeInfo( final VmTypeInfo vmInfo, final int index, fin
if ( root.isBlockStorage( ) ) {
childVmInfo = vmInfo.child( );
final Volume vol = this.allocInfo.getPersistentVolumes( ).get( index );
- final Dispatcher sc = ServiceDispatcher.lookup( Partitions.lookupService( Storage.class, vol.getPartition( ) ) );
+ final Dispatcher sc = ServiceDispatcher.lookup( Topology.lookup( Storage.class, Partitions.lookupByName( vol.getPartition( ) ) ) );
for ( int i = 0; i < 60; i++ ) {
try {
final DescribeStorageVolumesResponseType volState = sc.send( new DescribeStorageVolumesType( Lists.newArrayList( vol.getDisplayName( ) ) ) );
View
4 clc/modules/cluster-manager/src/main/java/com/eucalyptus/cloud/run/VerifyMetadata.java
@@ -163,11 +163,11 @@ public boolean apply( Allocation allocInfo ) throws MetadataException {
LOG.debug( "disabled values: " + Joiner.on( "\n" ).join( Clusters.getInstance( ).listValues( ) ) );
throw new VerificationException( "Not enough resources: no cluster controller is currently available to run instances." );
} else if ( Partitions.exists( zoneName ) ) {
- Partition partition = Partitions.lookupService( ClusterController.class, zoneName ).lookupPartition( );
+ Partition partition = Partitions.lookupByName( zoneName );
allocInfo.setPartition( partition );
} else if ( "default".equals( zoneName ) ) {
String defaultZone = Clusters.getInstance( ).listValues( ).get( 0 ).getPartition( );
- Partition partition = Partitions.lookupService( ClusterController.class, defaultZone ).lookupPartition( );
+ Partition partition = Partitions.lookupByName( defaultZone );
allocInfo.setPartition( partition );
} else {
throw new VerificationException( "Not enough resources: no cluster controller is currently available to run instances." );
View
28 clc/modules/cluster-manager/src/main/java/com/eucalyptus/cluster/Cluster.java
@@ -358,18 +358,22 @@ private Refresh( final Class refresh ) {
@Override
public final void leave( final Cluster parent, final Callback.Completion transitionCallback ) {
- try {
- AsyncRequests.newRequest( factory.newInstance( ) ).then( transitionCallback ).sendSync( parent.getConfiguration( ) );
- } catch ( final InterruptedException ex ) {
- Thread.currentThread( ).interrupt( );
- Exceptions.trace( ex );
- transitionCallback.fire( );
- } catch ( final Exception t ) {
- if ( !parent.swallowException( t ) ) {
- transitionCallback.fireException( t );
- } else {
+ if ( Hosts.isCoordinator( ) ) {
+ try {
+ AsyncRequests.newRequest( factory.newInstance( ) ).then( transitionCallback ).sendSync( parent.getConfiguration( ) );
+ } catch ( final InterruptedException ex ) {
+ Thread.currentThread( ).interrupt( );
+ Exceptions.trace( ex );
transitionCallback.fire( );
+ } catch ( final Exception t ) {
+ if ( !parent.swallowException( t ) ) {
+ transitionCallback.fireException( t );
+ } else {
+ transitionCallback.fire( );
+ }
}
+ } else {
+ transitionCallback.fire( );
}
}
};
@@ -1100,10 +1104,6 @@ public P getSubject( ) {
? t.getCause( )
: t;
}
- /// Ill-formed responses to DescribeNetworks are OK
- if( Exceptions.isCausedBy(t, org.jibx.runtime.JiBXException.class) || t instanceof org.jibx.runtime.JiBXException)
- return true;
-
LOG.error( t );
if ( Exceptions.isCausedBy( t, InterruptedException.class ) ) {
Thread.currentThread( ).interrupt( );
View
4 clc/modules/cluster-manager/src/main/java/com/eucalyptus/cluster/Clusters.java
@@ -106,10 +106,6 @@ public static Clusters getInstance( ) {
return Lists.newArrayList( hostOrdered );
}
- public static Cluster lookup( final Partition partition ) {
- return Clusters.lookup( Topology.lookup( ClusterController.class, partition ) );
- }
-
public static Cluster lookup( final ServiceConfiguration clusterConfig ) {
try {
return Clusters.getInstance( ).lookup( clusterConfig.getName( ) );
View
7 clc/modules/cluster-manager/src/main/java/com/eucalyptus/cluster/callback/VolumeAttachCallback.java
@@ -68,6 +68,7 @@
import com.eucalyptus.cluster.Cluster;
import com.eucalyptus.cluster.Clusters;
import com.eucalyptus.component.Dispatcher;
+import com.eucalyptus.component.Partition;
import com.eucalyptus.component.Partitions;
import com.eucalyptus.component.ServiceConfiguration;
import com.eucalyptus.component.Topology;
@@ -128,8 +129,10 @@ public void fireException( Throwable e ) {
LOG.debug( "Trying to remove invalid volume attachment " + this.getRequest( ).getVolumeId( ) + " from instance " + this.getRequest( ).getInstanceId( ) );
try {
VmInstance vm = VmInstances.lookup( this.getRequest( ).getInstanceId( ) );
- Cluster cluster = Clusters.lookup( Topology.lookup( ClusterController.class, vm.lookupPartition( ) ) );
- ServiceConfiguration sc = Partitions.lookupService( Storage.class, cluster.getConfiguration( ).getPartition( ) );
+ Partition partition = vm.lookupPartition( );
+ ServiceConfiguration cc = Topology.lookup( ClusterController.class, partition );
+ Cluster cluster = Clusters.lookup( cc );
+ ServiceConfiguration sc = Topology.lookup( Storage.class, partition );
/** clean up SC session state **/
try {
Dispatcher dispatcher = ServiceDispatcher.lookup( sc );
View
15 clc/modules/cluster-manager/src/main/java/com/eucalyptus/images/ImageManager.java
@@ -80,6 +80,7 @@
import com.eucalyptus.cloud.ImageMetadata;
import com.eucalyptus.cluster.Cluster;
import com.eucalyptus.cluster.Clusters;
+import com.eucalyptus.component.ServiceConfiguration;
import com.eucalyptus.component.Topology;
import com.eucalyptus.component.id.ClusterController;
import com.eucalyptus.context.Context;
@@ -89,7 +90,9 @@
import com.eucalyptus.entities.TransactionException;
import com.eucalyptus.entities.Transactions;
import com.eucalyptus.images.ImageManifests.ImageManifest;
+import com.eucalyptus.records.Logs;
import com.eucalyptus.util.EucalyptusCloudException;
+import com.eucalyptus.util.Exceptions;
import com.eucalyptus.util.RestrictedTypes;
import com.eucalyptus.vm.VmInstance;
import com.eucalyptus.vm.VmInstance.VmState;
@@ -165,8 +168,10 @@ public RegisterImageResponseType register( final RegisterImageType request ) thr
public ImageInfo get( ) {
try {
return Images.createFromManifest( ctx.getUserFullName( ), request.getName( ), request.getDescription( ), arch, eki, eri, manifest );
- } catch ( EucalyptusCloudException ex ) {
- throw new RuntimeException( ex );
+ } catch ( Exception ex ) {
+ LOG.error( ex );
+ Logs.extreme( ).error( ex, ex );
+ throw Exceptions.toUndeclared( ex );
}
}
};
@@ -421,11 +426,11 @@ public CreateImageResponseType createImage( CreateImageType request ) throws Euc
} else {
Cluster cluster = null;
try {
- cluster = Clusters.getInstance( ).lookup( vm.lookupPartition( ) );
-
+ ServiceConfiguration ccConfig = Topology.lookup( ClusterController.class, vm.lookupPartition( ) );
+ cluster = Clusters.lookup( ccConfig );
} catch ( NoSuchElementException e ) {
LOG.debug( e );
- throw new EucalyptusCloudException( "Cluster does not exist: " + Topology.lookup( ClusterController.class, vm.lookupPartition( ) ) );
+ throw new EucalyptusCloudException( "Cluster does not exist: " + vm.getPartition( ) );
}
}
} catch ( AuthException ex ) {
View
83 clc/modules/cluster-manager/src/main/java/com/eucalyptus/network/NetworkGroupManager.java
@@ -1,6 +1,9 @@
package com.eucalyptus.network;
+import java.util.Iterator;
import java.util.List;
+import java.util.Set;
+
import javax.persistence.EntityTransaction;
import org.apache.log4j.Logger;
import com.eucalyptus.auth.principal.AccountFullName;
@@ -73,7 +76,7 @@ public DescribeSecurityGroupsResponseType describe( final DescribeSecurityGroups
final DescribeSecurityGroupsResponseType reply = request.getReply( );
final Context ctx = Contexts.lookup( );
NetworkGroups.createDefault( ctx.getUserFullName( ) );//ensure the default group exists to cover some old broken installs
-
+
final List<String> groupNames = request.getSecurityGroupSet( );
final Predicate<NetworkGroup> argListFilter = new Predicate<NetworkGroup>( ) {
@Override
@@ -104,44 +107,50 @@ public boolean apply( final NetworkGroup arg0 ) {
}
public RevokeSecurityGroupIngressResponseType revoke( final RevokeSecurityGroupIngressType request ) throws EucalyptusCloudException, MetadataException {
- final Context ctx = Contexts.lookup( );
- final RevokeSecurityGroupIngressResponseType reply = request.getReply( );
- reply.markFailed( );
- final List<IpPermissionType> ipPermissions = request.getIpPermissions( );
- final List<NetworkRule> ruleList = NetworkGroups.ipPermissionsAsNetworkRules( ipPermissions );
- final Predicate<NetworkRule> filterContainsRule = new Predicate<NetworkRule>( ) {
- @Override
- public boolean apply( final NetworkRule rule ) {
- return ruleList.contains( rule );
- }
- };
- EntityTransaction db = Entities.get( NetworkGroup.class );
- try {
- final NetworkGroup ruleGroup = NetworkGroups.lookup( ctx.getUserFullName( ).asAccountFullName( ), request.getGroupName( ) );
- Predicate<NetworkRule> removeFailedPredicate = new Predicate<NetworkRule>( ) {
-
- @Override
- public boolean apply( NetworkRule rule ) {
- return !ruleGroup.getNetworkRules( ).remove( rule );
- }
- };
- if ( !RestrictedTypes.filterPrivileged( ).apply( ruleGroup ) ) {
- throw new EucalyptusCloudException( "Not authorized to revoke network group " + request.getGroupName( ) + " for " + ctx.getUser( ) );
- }
- final List<NetworkRule> filtered = Lists.newArrayList( Iterables.filter( ruleGroup.getNetworkRules( ), filterContainsRule ) );
- if ( filtered.size( ) == ruleList.size( ) ) {
- reply.set_return( !Iterables.all( filtered, removeFailedPredicate ) );
- } else if ( ( ipPermissions.size( ) == 1 ) && ( ipPermissions.get( 0 ).getIpProtocol( ) == null ) ) {
- reply.set_return( !Iterables.all( ruleList, removeFailedPredicate ) );
+
+ final Context ctx = Contexts.lookup( );
+ final RevokeSecurityGroupIngressResponseType reply = request.getReply( );
+ reply.markFailed( );
+ final List<IpPermissionType> ipPermissions = request.getIpPermissions( );
+ final List<NetworkRule> revokedRuleList = NetworkGroups.ipPermissionsAsNetworkRules( ipPermissions );
+
+ EntityTransaction db = Entities.get( NetworkGroup.class );
+
+ try {
+
+ final List<NetworkGroup> networkGroupList = NetworkGroups
+ .lookupAll(ctx.getUserFullName().asAccountFullName(),
+ request.getGroupName());
+
+ for (NetworkGroup networkGroup : networkGroupList) {
+
+ if (RestrictedTypes.filterPrivileged().apply(networkGroup)) {
+
+ for (Iterator< NetworkRule > it = networkGroup.getNetworkRules().iterator(); it.hasNext() ;) {
+
+ NetworkRule rule = it.next();
+ if (revokedRuleList.contains(rule)) {
+ it.remove();
+ }
+ }
+
+ } else {
+ throw new EucalyptusCloudException(
+ "Not authorized to revoke" + "network group "
+ + request.getGroupName() + " for "
+ + ctx.getUser());
+
+ }
+ }
+ reply.set_return(true);
+ db.commit( );
+ } catch ( Exception ex ) {
+ Logs.exhaust( ).error( ex, ex );
+ db.rollback( );
+ throw new EucalyptusCloudException( "RevokeSecurityGroupIngress failed because: " + ex.getMessage( ), ex );
}
- db.commit( );
- } catch ( Exception ex ) {
- Logs.exhaust( ).error( ex, ex );
- db.rollback( );
- throw new EucalyptusCloudException( "RevokeSecurityGroupIngress failed because: " + ex.getMessage( ), ex );
+ return reply;
}
- return reply;
- }
public AuthorizeSecurityGroupIngressResponseType authorize( final AuthorizeSecurityGroupIngressType request ) throws Exception {
final Context ctx = Contexts.lookup( );
View
8 clc/modules/cluster-manager/src/main/java/com/eucalyptus/util/async/StatefulMessageSet.java
@@ -113,8 +113,12 @@ private boolean isFinished( ) {
public void run( ) {
do {
- this.queueEvents( this.state );
- this.state = this.transition( this.state );
+ try {
+ this.queueEvents( this.state );
+ this.state = this.transition( this.state );
+ } catch ( Exception ex ) {
+ LOG.error( ex , ex );
+ }
} while ( !this.isFinished( ) );
LOG.info( EventRecord.here( StatefulMessageSet.class, this.isSuccessful( )
? EventType.VM_START_COMPLETED
View
18 clc/modules/cluster-manager/src/main/java/com/eucalyptus/vm/VmControl.java
@@ -90,6 +90,7 @@
import com.eucalyptus.cluster.callback.ConsoleOutputCallback;
import com.eucalyptus.cluster.callback.PasswordDataCallback;
import com.eucalyptus.cluster.callback.RebootCallback;
+import com.eucalyptus.component.ServiceConfiguration;
import com.eucalyptus.component.Topology;
import com.eucalyptus.component.id.ClusterController;
import com.eucalyptus.context.Context;
@@ -331,7 +332,8 @@ public boolean apply( final String instanceId ) {
if ( RestrictedTypes.filterPrivileged( ).apply( v ) ) {
final Request<RebootInstancesType, RebootInstancesResponseType> req = AsyncRequests.newRequest( new RebootCallback( v.getInstanceId( ) ) );
req.getRequest( ).regarding( request );
- req.dispatch( Topology.lookup( ClusterController.class, v.lookupPartition( ) ) );
+ ServiceConfiguration ccConfig = Topology.lookup( ClusterController.class, v.lookupPartition( ) );
+ req.dispatch( ccConfig );
return true;
} else {
return false;
@@ -377,9 +379,10 @@ public void getConsoleOutput( final GetConsoleOutputType request ) throws Eucaly
} else {
Cluster cluster = null;
try {
- cluster = Clusters.getInstance( ).lookup( v.lookupPartition( ) );
+ ServiceConfiguration ccConfig = Topology.lookup( ClusterController.class, v.lookupPartition( ) );
+ cluster = Clusters.lookup( ccConfig );
} catch ( final NoSuchElementException e1 ) {
- throw new EucalyptusCloudException( "Failed to find cluster info for '" + v.lookupPartition( ) + "' related to vm: " + request.getInstanceId( ) );
+ throw new EucalyptusCloudException( "Failed to find cluster info for '" + v.getPartition( ) + "' related to vm: " + request.getInstanceId( ) );
}
RequestContext.getEventContext( ).setStopFurtherProcessing( true );
AsyncRequests.newRequest( new ConsoleOutputCallback( request ) ).dispatch( cluster.getConfiguration( ) );
@@ -565,7 +568,8 @@ public CancelBundleTaskResponseType cancelBundleTask( final CancelBundleTaskType
v.getRuntimeState( ).getBundleTask( ).getBundleId( ),
v.getInstanceId( ) ) );
- final Cluster cluster = Clusters.lookup( v.lookupPartition( ) );
+ ServiceConfiguration ccConfig = Topology.lookup( ClusterController.class, v.lookupPartition( ) );
+ final Cluster cluster = Clusters.lookup( ccConfig );
request.setInstanceId( v.getInstanceId( ) );
reply.setTask( Bundles.transform( v.getRuntimeState( ).getBundleTask( ) ) );
@@ -614,7 +618,8 @@ public BundleInstanceResponseType bundleInstance( final BundleInstanceType reque
ctx.getUserFullName( ).toString( ),
v.getRuntimeState( ).getBundleTask( ).getBundleId( ),
v.getInstanceId( ) ).debug( );
- AsyncRequests.newRequest( Bundles.createCallback( request ) ).dispatch( Topology.lookup( ClusterController.class, v.lookupPartition( ) ) );
+ ServiceConfiguration cluster = Topology.lookup( ClusterController.class, v.lookupPartition( ) );
+ AsyncRequests.newRequest( Bundles.createCallback( request ) ).dispatch( cluster );
} else {
throw new EucalyptusCloudException( "Failed to find instance: " + request.getInstanceId( ) );
}
@@ -641,7 +646,8 @@ public void getPasswordData( final GetPasswordDataType request ) throws Exceptio
throw new NoSuchElementException( "Instance " + request.getInstanceId( ) + " is not in a running state." );
}
if ( RestrictedTypes.filterPrivileged( ).apply( v ) ) {
- cluster = Clusters.lookup( Topology.lookup( ClusterController.class, v.lookupPartition( ) ) );
+ ServiceConfiguration ccConfig = Topology.lookup( ClusterController.class, v.lookupPartition( ) );
+ cluster = Clusters.lookup( ccConfig );
} else {
throw new NoSuchElementException( "Instance " + request.getInstanceId( ) + " does not exist." );
}
View
6 clc/modules/cluster-manager/src/main/java/com/eucalyptus/vm/VmInstances.java
@@ -83,6 +83,7 @@
import com.eucalyptus.component.Dispatcher;
import com.eucalyptus.component.ServiceConfiguration;
import com.eucalyptus.component.Topology;
+import com.eucalyptus.component.id.ClusterController;
import com.eucalyptus.component.id.Storage;
import com.eucalyptus.configurable.ConfigurableClass;
import com.eucalyptus.configurable.ConfigurableField;
@@ -360,7 +361,7 @@ public static void cleanUp( final VmInstance vm ) {
LOG.trace( Logs.dump( vm ) );
LOG.trace( Threads.currentStackString( ) );
try {
- final Cluster cluster = Clusters.getInstance( ).lookup( vm.lookupPartition( ) );
+ final Cluster cluster = Clusters.lookup( Topology.lookup( ClusterController.class, vm.lookupPartition( ) ) );
VmInstances.cleanUpAttachedVolumes( vm );
Address address = null;
@@ -388,7 +389,8 @@ public boolean apply( final AttachedVolume arg0 ) {
private static void cleanUpAttachedVolumes( final VmInstance vm ) {
try {
- final Cluster cluster = Clusters.getInstance( ).lookup( vm.lookupPartition( ) );
+ ServiceConfiguration ccConfig = Topology.lookup( ClusterController.class, vm.lookupPartition( ) );
+ final Cluster cluster = Clusters.lookup( ccConfig );
vm.eachVolumeAttachment( new Predicate<AttachedVolume>( ) {
@Override
public boolean apply( final AttachedVolume arg0 ) {
View
25 clc/modules/configuration/src/main/java/com/eucalyptus/config/Configuration.java
@@ -64,7 +64,6 @@
package com.eucalyptus.config;
import java.util.ArrayList;
-import java.util.Collection;
import java.util.List;
import java.util.Set;
import org.apache.log4j.Logger;
@@ -72,10 +71,8 @@
import com.eucalyptus.component.ComponentId;
import com.eucalyptus.component.ComponentRegistrationHandler;
import com.eucalyptus.component.Components;
-import com.eucalyptus.component.Faults;
import com.eucalyptus.component.ServiceBuilder;
import com.eucalyptus.component.ServiceBuilders;
-import com.eucalyptus.component.ServiceCheckRecord;
import com.eucalyptus.component.ServiceConfiguration;
import com.eucalyptus.component.ServiceConfigurations;
import com.eucalyptus.scripting.Groovyness;
@@ -99,6 +96,11 @@
@Override
public ComponentInfoType apply( final ServiceConfiguration input ) {
return new ComponentInfoType( ) {
+ /**
+ *
+ */
+ private static final long serialVersionUID = 1L;
+
{
this.setType( input.getComponentId( ).name( ) );
this.setPartition( input.getPartition( ) );
@@ -107,7 +109,7 @@ public ComponentInfoType apply( final ServiceConfiguration input ) {
this.setFullName( input.getFullName( ).toString( ) );
try {
this.setState( input.lookupState( ).toString( ) );
- } catch ( Exception ex ) {
+ } catch ( final Exception ex ) {
this.setState( "n/a: " + ex.getMessage( ) );
}
this.setDetail( "" );
@@ -118,7 +120,7 @@ public ComponentInfoType apply( final ServiceConfiguration input ) {
}
public static RegisterComponentResponseType registerComponent( final RegisterComponentType request ) throws EucalyptusCloudException {
- ServiceBuilder<? extends ServiceConfiguration> builder = ServiceBuilders.handles( request.getClass( ) );
+ final ServiceBuilder<? extends ServiceConfiguration> builder = ServiceBuilders.handles( request.getClass( ) );
final ComponentId componentId = builder.getComponentId( );
final RegisterComponentResponseType reply = request.getReply( );
final String name = request.getName( );
@@ -154,7 +156,7 @@ public static RegisterComponentResponseType registerComponent( final RegisterCom
}
public static DeregisterComponentResponseType deregisterComponent( final DeregisterComponentType request ) throws EucalyptusCloudException {
- ServiceBuilder<? extends ServiceConfiguration> builder = ServiceBuilders.handles( request.getClass( ) );
+ final ServiceBuilder<? extends ServiceConfiguration> builder = ServiceBuilders.handles( request.getClass( ) );
final ComponentId componentId = builder.getComponentId( );
final DeregisterComponentResponseType reply = ( DeregisterComponentResponseType ) request.getReply( );
try {
@@ -193,6 +195,11 @@ public DescribeComponentsResponseType listComponents( final DescribeComponentsTy
for ( final Component c : Components.list( ) ) {
if ( !c.hasLocalService( ) ) {
listConfigs.add( new ComponentInfoType( ) {
+ /**
+ *
+ */
+ private static final long serialVersionUID = 1L;
+
{
this.setType( c.getComponentId( ).name( ) );
this.setPartition( c.getComponentId( ).getPartition( ) );
@@ -205,7 +212,7 @@ public DescribeComponentsResponseType listComponents( final DescribeComponentsTy
} );
} else {
final ServiceConfiguration config = c.getLocalServiceConfiguration( );
- ComponentInfoType info = TypeMappers.transform( config, ComponentInfoType.class );
+ final ComponentInfoType info = TypeMappers.transform( config, ComponentInfoType.class );
if ( !Boolean.TRUE.equals( request.getVerbose( ) ) ) {
info.setDetail( "" );
}
@@ -213,9 +220,9 @@ public DescribeComponentsResponseType listComponents( final DescribeComponentsTy
}
}
} else {
- ServiceBuilder<? extends ServiceConfiguration> compId = ServiceBuilders.handles( request.getClass( ) );
+ final ServiceBuilder<? extends ServiceConfiguration> compId = ServiceBuilders.handles( request.getClass( ) );
for ( final ServiceConfiguration config : ServiceConfigurations.list( compId.getComponentId( ).getClass( ) ) ) {
- ComponentInfoType info = TypeMappers.transform( config, ComponentInfoType.class );
+ final ComponentInfoType info = TypeMappers.transform( config, ComponentInfoType.class );
if ( !Boolean.TRUE.equals( request.getVerbose( ) ) ) {
info.setDetail( "" );
}
View
90 clc/modules/dns/src/main/java/com/eucalyptus/bootstrap/DNSBootstrapper.java
@@ -63,56 +63,48 @@
import org.apache.log4j.Logger;
import com.eucalyptus.cloud.ws.DNSControl;
import com.eucalyptus.component.id.Dns;
-import com.eucalyptus.empyrean.Empyrean;
-@Provides( Empyrean.class )
-@RunDuring( Bootstrap.Stage.PrivilegedConfiguration )
+@Provides( Dns.class )
+@RunDuring( Bootstrap.Stage.CloudServiceInit )
@DependsLocal( Dns.class )
public class DNSBootstrapper extends Bootstrapper.Simple {
- private static Logger LOG = Logger.getLogger( DNSBootstrapper.class );
- private static DNSBootstrapper singleton;
-
- public static Bootstrapper getInstance( ) {
- synchronized ( DNSBootstrapper.class ) {
- if ( singleton == null ) {
- singleton = new DNSBootstrapper( );
- LOG.info( "Creating DNS Bootstrapper instance." );
- } else {
- LOG.info( "Returning DNS Bootstrapper instance." );
- }
- }
- return singleton;
- }
-
- @Override
- public boolean load( ) throws Exception {
- LOG.info( "Initializing DNS" );
- //The following call binds DNS ports. Must be in a privileged context.
- DNSControl.initialize( );
- return true;
- }
-
- @Provides( Dns.class )
- @RunDuring( Bootstrap.Stage.CloudServiceInit )
- @DependsLocal( Dns.class )
- public static class DNSRecordsBootstrapper extends Bootstrapper.Simple {
-
- @Override
- public boolean start( ) throws Exception {
- LOG.info( "Loading DNS records" );
- //populateRecords must be idempotent.
- DNSControl.populateRecords( );
- return true;
- }
-
- /**
- * @see com.eucalyptus.bootstrap.Bootstrapper#disable()
- */
- @Override
- public boolean disable( ) throws Exception {
- //Don't bring down service but don't process requests.
- return true;
- }
- }
-
+ private static Logger LOG = Logger.getLogger( DNSBootstrapper.class );
+ private static DNSBootstrapper singleton;
+
+ public static Bootstrapper getInstance( ) {
+ synchronized ( DNSBootstrapper.class ) {
+ if ( singleton == null ) {
+ singleton = new DNSBootstrapper( );
+ LOG.info( "Creating DNS Bootstrapper instance." );
+ } else {
+ LOG.info( "Returning DNS Bootstrapper instance." );
+ }
+ }
+ return singleton;
+ }
+
+ @Override
+ public boolean load( ) throws Exception {
+ return true;
+ }
+
+ @Override
+ public boolean start( ) throws Exception {
+ LOG.info( "Initializing DNS" );
+ //The following call binds DNS ports.
+ DNSControl.initialize( );
+ return true;
+ }
+
+ @Override
+ public boolean disable( ) throws Exception {
+ return true;
+ }
+
+ @Override
+ public boolean stop( ) throws Exception {
+ LOG.info("Stopping DNS");
+ DNSControl.stop();
+ return true;
+ }
}
View
25 clc/modules/dns/src/main/java/com/eucalyptus/cloud/ws/DNSControl.java
@@ -85,10 +85,14 @@
private static Logger LOG = Logger.getLogger( DNSControl.class );
+ static UDPListener udpListener;
+ static TCPListener tcpListener;
private static void initializeUDP() throws Exception {
try {
- UDPListener udpListener = new UDPListener(Address.getByAddress(DNSProperties.ADDRESS), DNSProperties.PORT);
- udpListener.start();
+ if (udpListener == null) {
+ udpListener = new UDPListener(Address.getByAddress(DNSProperties.ADDRESS), DNSProperties.PORT);
+ udpListener.start();
+ }
} catch(UnknownHostException ex) {
LOG.error(ex);
throw ex;
@@ -97,8 +101,10 @@ private static void initializeUDP() throws Exception {
private static void initializeTCP() throws Exception {
try {
- TCPListener tcpListener = new TCPListener(Address.getByAddress(DNSProperties.ADDRESS), DNSProperties.PORT);
- tcpListener.start();
+ if (tcpListener == null) {
+ tcpListener = new TCPListener(Address.getByAddress(DNSProperties.ADDRESS), DNSProperties.PORT);
+ tcpListener.start();
+ }
} catch(UnknownHostException ex) {
LOG.error(ex);
throw ex;
@@ -149,6 +155,17 @@ public static void initialize() throws Exception {
}
}
+ public static void stop() throws Exception {
+ if (udpListener != null) {
+ udpListener.close();
+ udpListener = null;
+ }
+ if (tcpListener != null) {
+ tcpListener.close();
+ tcpListener = null;
+ }
+ }
+
public DNSControl() {}
public UpdateARecordResponseType UpdateARecord(UpdateARecordType request) throws EucalyptusCloudException {
View
184 clc/modules/dns/src/main/java/com/eucalyptus/cloud/ws/TCPHandler.java
@@ -1,63 +1,63 @@
/*******************************************************************************
-*Copyright (c) 2009 Eucalyptus Systems, Inc.
-*
-* This program is free software: you can redistribute it and/or modify
-* it under the terms of the GNU General Public License as published by
-* the Free Software Foundation, only version 3 of the License.
-*
-*
-* This file 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 General Public License
-* for more details.
-*
-* You should have received a copy of the GNU General Public License along
-* with this program. If not, see <http://www.gnu.org/licenses/>.
-*
-* Please contact Eucalyptus Systems, Inc., 130 Castilian
-* Dr., Goleta, CA 93101 USA or visit <http://www.eucalyptus.com/licenses/>
-* if you need additional information or have any questions.
-*
-* This file may incorporate work covered under the following copyright and
-* permission notice:
-*
-* Software License Agreement (BSD License)
-*
-* Copyright (c) 2008, Regents of the University of California
-* All rights reserved.
-*
-* Redistribution and use of this software in source and binary forms, with
-* or without modification, are permitted provided that the following
-* conditions are met:
-*
-* Redistributions of source code must retain the above copyright notice,
-* this list of conditions and the following disclaimer.
-*
-* Redistributions in binary form must reproduce the above copyright
-* notice, this list of conditions and the following disclaimer in the
-* documentation and/or other materials provided with the distribution.
-*
-* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
-* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
-* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
-* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
-* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
-* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
-* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
-* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
-* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. USERS OF
-* THIS SOFTWARE ACKNOWLEDGE THE POSSIBLE PRESENCE OF OTHER OPEN SOURCE
-* LICENSED MATERIAL, COPYRIGHTED MATERIAL OR PATENTED MATERIAL IN THIS
-* SOFTWARE, AND IF ANY SUCH MATERIAL IS DISCOVERED THE PARTY DISCOVERING
-* IT MAY INFORM DR. RICH WOLSKI AT THE UNIVERSITY OF CALIFORNIA, SANTA
-* BARBARA WHO WILL THEN ASCERTAIN THE MOST APPROPRIATE REMEDY, WHICH IN
-* THE REGENTS' DISCRETION MAY INCLUDE, WITHOUT LIMITATION, REPLACEMENT
-* OF THE CODE SO IDENTIFIED, LICENSING OF THE CODE SO IDENTIFIED, OR
-* WITHDRAWAL OF THE CODE CAPABILITY TO THE EXTENT NEEDED TO COMPLY WITH
-* ANY SUCH LICENSES OR RIGHTS.
-*******************************************************************************/
+ *Copyright (c) 2009 Eucalyptus Systems, Inc.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, only version 3 of the License.
+ *
+ *
+ * This file 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 General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Please contact Eucalyptus Systems, Inc., 130 Castilian
+ * Dr., Goleta, CA 93101 USA or visit <http://www.eucalyptus.com/licenses/>
+ * if you need additional information or have any questions.
+ *
+ * This file may incorporate work covered under the following copyright and
+ * permission notice:
+ *
+ * Software License Agreement (BSD License)
+ *
+ * Copyright (c) 2008, Regents of the University of California
+ * All rights reserved.
+ *
+ * Redistribution and use of this software in source and binary forms, with
+ * or without modification, are permitted provided that the following
+ * conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. USERS OF
+ * THIS SOFTWARE ACKNOWLEDGE THE POSSIBLE PRESENCE OF OTHER OPEN SOURCE
+ * LICENSED MATERIAL, COPYRIGHTED MATERIAL OR PATENTED MATERIAL IN THIS
+ * SOFTWARE, AND IF ANY SUCH MATERIAL IS DISCOVERED THE PARTY DISCOVERING
+ * IT MAY INFORM DR. RICH WOLSKI AT THE UNIVERSITY OF CALIFORNIA, SANTA
+ * BARBARA WHO WILL THEN ASCERTAIN THE MOST APPROPRIATE REMEDY, WHICH IN
+ * THE REGENTS' DISCRETION MAY INCLUDE, WITHOUT LIMITATION, REPLACEMENT
+ * OF THE CODE SO IDENTIFIED, LICENSING OF THE CODE SO IDENTIFIED, OR
+ * WITHDRAWAL OF THE CODE CAPABILITY TO THE EXTENT NEEDED TO COMPLY WITH
+ * ANY SUCH LICENSES OR RIGHTS.
+ *******************************************************************************/
/*
*
* Author: Neil Soman neil@eucalyptus.com
@@ -76,40 +76,40 @@
public class TCPHandler extends ConnectionHandler {
- private static Logger LOG = Logger.getLogger( TCPHandler.class );
- Socket socket;
- public TCPHandler(Socket s) {
- this.socket = s;
- }
+ private static Logger LOG = Logger.getLogger( TCPHandler.class );
+ Socket socket;
+ public TCPHandler(Socket s) {
+ this.socket = s;
+ }
- public void run() {
- try {
- int inputLength;
- DataInputStream inStream = new DataInputStream(socket.getInputStream());
- DataOutputStream outStream = new DataOutputStream(socket.getOutputStream());
- inputLength = inStream.readUnsignedShort();
- if(inputLength > DNSProperties.MAX_MESSAGE_SIZE) {
- LOG.error("Maximum message size exceeded. Ignoring request.");
- }
- byte[] inBytes = new byte[inputLength];
- inStream.readFully(inBytes);
- Message query;
- byte [] response = null;
- try {
- query = new Message(inBytes);
- response = generateReply(query, inBytes, inBytes.length, socket);
- if (response == null)
- return;
- }
- catch (IOException exception) {
- LOG.error(exception);
- }
- outStream.writeShort(response.length);
- outStream.write(response);
- } catch(IOException ex) {
- LOG.error(ex);
- }
- }
+ public void run() {
+ try {
+ int inputLength;
+ DataInputStream inStream = new DataInputStream(socket.getInputStream());
+ DataOutputStream outStream = new DataOutputStream(socket.getOutputStream());
+ inputLength = inStream.readUnsignedShort();
+ if(inputLength > DNSProperties.MAX_MESSAGE_SIZE) {
+ LOG.error("Maximum message size exceeded. Ignoring request.");
+ }
+ byte[] inBytes = new byte[inputLength];
+ inStream.readFully(inBytes);
+ Message query;
+ byte [] response = null;
+ try {
+ query = new Message(inBytes);
+ response = generateReply(query, inBytes, inBytes.length, socket);
+ if (response == null)
+ return;
+ }
+ catch (IOException exception) {
+ LOG.error(exception);
+ }
+ outStream.writeShort(response.length);
+ outStream.write(response);
+ } catch(IOException ex) {
+ LOG.error(ex);
+ }
+ }
}
View
129 clc/modules/dns/src/main/java/com/eucalyptus/cloud/ws/TCPListener.java
@@ -1,63 +1,63 @@
/*******************************************************************************
-*Copyright (c) 2009 Eucalyptus Systems, Inc.
-*
-* This program is free software: you can redistribute it and/or modify
-* it under the terms of the GNU General Public License as published by
-* the Free Software Foundation, only version 3 of the License.
-*
-*
-* This file 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 General Public License
-* for more details.
-*
-* You should have received a copy of the GNU General Public License along
-* with this program. If not, see <http://www.gnu.org/licenses/>.
-*
-* Please contact Eucalyptus Systems, Inc., 130 Castilian
-* Dr., Goleta, CA 93101 USA or visit <http://www.eucalyptus.com/licenses/>
-* if you need additional information or have any questions.
-*
-* This file may incorporate work covered under the following copyright and
-* permission notice:
-*
-* Software License Agreement (BSD License)
-*
-* Copyright (c) 2008, Regents of the University of California
-* All rights reserved.
-*
-* Redistribution and use of this software in source and binary forms, with
-* or without modification, are permitted provided that the following
-* conditions are met:
-*
-* Redistributions of source code must retain the above copyright notice,
-* this list of conditions and the following disclaimer.
-*
-* Redistributions in binary form must reproduce the above copyright
-* notice, this list of conditions and the following disclaimer in the
-* documentation and/or other materials provided with the distribution.
-*
-* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
-* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
-* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
-* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
-* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
-* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
-* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
-* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
-* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. USERS OF
-* THIS SOFTWARE ACKNOWLEDGE THE POSSIBLE PRESENCE OF OTHER OPEN SOURCE
-* LICENSED MATERIAL, COPYRIGHTED MATERIAL OR PATENTED MATERIAL IN THIS
-* SOFTWARE, AND IF ANY SUCH MATERIAL IS DISCOVERED THE PARTY DISCOVERING
-* IT MAY INFORM DR. RICH WOLSKI AT THE UNIVERSITY OF CALIFORNIA, SANTA
-* BARBARA WHO WILL THEN ASCERTAIN THE MOST APPROPRIATE REMEDY, WHICH IN
-* THE REGENTS' DISCRETION MAY INCLUDE, WITHOUT LIMITATION, REPLACEMENT
-* OF THE CODE SO IDENTIFIED, LICENSING OF THE CODE SO IDENTIFIED, OR
-* WITHDRAWAL OF THE CODE CAPABILITY TO THE EXTENT NEEDED TO COMPLY WITH
-* ANY SUCH LICENSES OR RIGHTS.
-*******************************************************************************/
+ *Copyright (c) 2009 Eucalyptus Systems, Inc.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, only version 3 of the License.
+ *
+ *
+ * This file 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 General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Please contact Eucalyptus Systems, Inc., 130 Castilian
+ * Dr., Goleta, CA 93101 USA or visit <http://www.eucalyptus.com/licenses/>
+ * if you need additional information or have any questions.
+ *
+ * This file may incorporate work covered under the following copyright and
+ * permission notice:
+ *
+ * Software License Agreement (BSD License)
+ *
+ * Copyright (c) 2008, Regents of the University of California
+ * All rights reserved.
+ *
+ * Redistribution and use of this software in source and binary forms, with
+ * or without modification, are permitted provided that the following
+ * conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. USERS OF
+ * THIS SOFTWARE ACKNOWLEDGE THE POSSIBLE PRESENCE OF OTHER OPEN SOURCE
+ * LICENSED MATERIAL, COPYRIGHTED MATERIAL OR PATENTED MATERIAL IN THIS
+ * SOFTWARE, AND IF ANY SUCH MATERIAL IS DISCOVERED THE PARTY DISCOVERING
+ * IT MAY INFORM DR. RICH WOLSKI AT THE UNIVERSITY OF CALIFORNIA, SANTA
+ * BARBARA WHO WILL THEN ASCERTAIN THE MOST APPROPRIATE REMEDY, WHICH IN
+ * THE REGENTS' DISCRETION MAY INCLUDE, WITHOUT LIMITATION, REPLACEMENT
+ * OF THE CODE SO IDENTIFIED, LICENSING OF THE CODE SO IDENTIFIED, OR
+ * WITHDRAWAL OF THE CODE CAPABILITY TO THE EXTENT NEEDED TO COMPLY WITH
+ * ANY SUCH LICENSES OR RIGHTS.
+ *******************************************************************************/
/*
*
* Author: Neil Soman neil@eucalyptus.com
@@ -107,4 +107,15 @@ public void run() {
}
}
}
+
+ public void close() {
+ if (socket != null) {
+ try {
+ socket.close();
+ socket = null;
+ } catch (IOException e) {
+ LOG.error(e, e);
+ }
+ }
+ }
}
View
7 clc/modules/dns/src/main/java/com/eucalyptus/cloud/ws/UDPListener.java
@@ -94,4 +94,11 @@ public void run() {
else
LOG.error("Cannot start service. Invalid socket.");
}
+
+ public void close() {
+ if (socket != null) {
+ socket.close();
+ socket = null;
+ }
+ }
}
View
8 clc/modules/msgs/conf/scripts/setup_dbpool.groovy
@@ -110,11 +110,15 @@ PersistenceContexts.list( ).each { String ctx_simplename ->
new File( ha_jdbc_config_file_name ).withWriter{ writer ->
def xml = new MarkupBuilder(writer);
xml.'ha-jdbc'() {
- sync('class':'net.sf.hajdbc.sync.FullSynchronizationStrategy', id:'full') {
+ sync('class':'com.eucalyptus.bootstrap.Databases\$FullSynchronizationStrategy', id:'full') {
'property'(name:'fetchSize', '1000')
'property'(name:'maxBatchSize', '1000')
}
- sync('class':'net.sf.hajdbc.sync.PassiveSynchronizationStrategy', id:'passive');
+ sync('class':'com.eucalyptus.bootstrap.Databases\$DifferentialSynchronizationStrategy', id:'diff') {
+ 'property'(name:'fetchSize', '1000')
+ 'property'(name:'maxBatchSize', '1000')
+ }
+ sync('class':'com.eucalyptus.bootstrap.Databases\$PassiveSynchronizationStrategy', id:'passive');
cluster(id:context_pool_alias,
// 'auto-activate-schedule':'0 * * ? * *',
balancer:'simple', //(simple|random|round-robin|load)
View
4 clc/modules/msgs/src/main/java/com/eucalyptus/bootstrap/Bootstrap.java
@@ -452,6 +452,10 @@ public static synchronized Stage transition( ) {
return currentStage;
}
+ public static Boolean isLoaded( ) {
+ return starting;
+ }
+
public static Boolean isOperational( ) {
return isFinished( ) && !isShuttingDown( );
}
View
797 clc/modules/msgs/src/main/java/com/eucalyptus/bootstrap/Databases.java
@@ -57,6 +57,28 @@
* OF THE CODE SO IDENTIFIED, LICENSING OF THE CODE SO IDENTIFIED, OR
* WITHDRAWAL OF THE CODE CAPABILITY TO THE EXTENT NEEDED TO COMPLY WITH
* ANY SUCH LICENSES OR RIGHTS.
+ * File also includes source under the following license:
+ *
+ * HA-JDBC: High-Availability JDBC
+ * Copyright (c) 2004-2007 Paul Ferraro
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by the
+ * Free Software Foundation; either version 2.1 of the License, or (at your
+ * option) any later version.
+ *
+ * This library 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 Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Contact: ferraro@users.sourceforge.net
+ * @author Paul Ferraro
+ *
*******************************************************************************
* @author chris grzegorczyk <grze@eucalyptus.com>
*/
@@ -64,22 +86,45 @@
package com.eucalyptus.bootstrap;
import java.sql.Connection;
-import java.sql.Driver;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Statement;
+import java.sql.Types;
+import java.text.MessageFormat;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
import java.util.Map;
import java.util.NoSuchElementException;
+import java.util.Set;
+import java.util.concurrent.Callable;
+import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicReference;
import java.util.concurrent.locks.ReentrantReadWriteLock;
-import java.util.concurrent.locks.ReentrantReadWriteLock.ReadLock;
+import net.sf.hajdbc.Dialect;
+import net.sf.hajdbc.ForeignKeyConstraint;
import net.sf.hajdbc.InactiveDatabaseMBean;
+import net.sf.hajdbc.Messages;
+import net.sf.hajdbc.SequenceProperties;
+import net.sf.hajdbc.SynchronizationContext;
+import net.sf.hajdbc.SynchronizationStrategy;
+import net.sf.hajdbc.TableProperties;
+import net.sf.hajdbc.UniqueConstraint;
import net.sf.hajdbc.sql.DriverDatabaseClusterMBean;
+import net.sf.hajdbc.util.SQLExceptionFactory;
+import net.sf.hajdbc.util.Strings;
import org.apache.log4j.Logger;
+import com.eucalyptus.bootstrap.Hosts.DbFilter;
+import com.eucalyptus.bootstrap.Hosts.SyncedDbFilter;
import com.eucalyptus.component.ServiceUris;
import com.eucalyptus.component.id.Eucalyptus;
import com.eucalyptus.component.id.Eucalyptus.Database;
@@ -88,25 +133,41 @@
import com.eucalyptus.records.Logs;
import com.eucalyptus.scripting.Groovyness;
import com.eucalyptus.scripting.ScriptExecutionFailedException;
+import com.eucalyptus.system.Threads;
import com.eucalyptus.util.Exceptions;
import com.eucalyptus.util.Internets;
import com.eucalyptus.util.Mbeans;
import com.eucalyptus.util.async.Futures;
import com.google.common.base.Function;
import com.google.common.base.Joiner;
+import com.google.common.base.Predicate;
+import com.google.common.base.Predicates;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.MapDifference;
import com.google.common.collect.Maps;
public class Databases {
- private static final ScriptedDbBootstrapper singleton = new ScriptedDbBootstrapper( );
- private static Logger LOG = Logger.getLogger( Databases.class );
- private static final String DB_NAME = "eucalyptus";
- private static final String DB_USERNAME = DB_NAME;
- private static final String jdbcJmxDomain = "net.sf.hajdbc";
- private static final ExecutorService dbSyncExecutors = Executors.newCachedThreadPool( ); //NOTE:GRZE:special case thread handling.
- private static final AtomicReference<SyncState> syncState = new AtomicReference<SyncState>( SyncState.NOTSYNCED );
- private static final ReentrantReadWriteLock canHas = new ReentrantReadWriteLock( );
+ public static class DatabaseStateException extends IllegalStateException {
+
+ /**
+ * @param string
+ */
+ public DatabaseStateException( String string ) {
+ super( string );
+ }
+
+ }
+
+ private static final int MAX_TX_START_SYNC_RETRIES = 120;
+ private static final Predicate<Host> FILTER_SYNCING_DBS = Predicates.and( DbFilter.INSTANCE, Predicates.not( SyncedDbFilter.INSTANCE ) );
+ private static final ScriptedDbBootstrapper singleton = new ScriptedDbBootstrapper( );
+ private static Logger LOG = Logger.getLogger( Databases.class );
+ private static final String DB_NAME = "eucalyptus";
+ private static final String DB_USERNAME = DB_NAME;
+ private static final String jdbcJmxDomain = "net.sf.hajdbc";
+ private static final ExecutorService dbSyncExecutors = Executors.newCachedThreadPool( ); //NOTE:GRZE:special case thread handling.
+ private static final AtomicReference<SyncState> syncState = new AtomicReference<SyncState>( SyncState.NOTSYNCED );
+ private static final ReentrantReadWriteLock canHas = new ReentrantReadWriteLock( );
enum SyncState {
NOTSYNCED,
@@ -117,7 +178,6 @@
enum ExecuteRunnable implements Function<Runnable, Future<Runnable>> {
INSTANCE;
-
@Override
public Future<Runnable> apply( Runnable input ) {
Logs.extreme( ).debug( "SUBMIT: " + input );
@@ -128,11 +188,33 @@
@Provides( Empyrean.class )
@RunDuring( Bootstrap.Stage.PoolInit )
public static class DatabasePoolBootstrapper extends Bootstrapper.Simple {
-
@Override
public boolean load( ) throws Exception {
Hosts.awaitDatabases( );
Groovyness.run( "setup_dbpool.groovy" );
+ OrderedShutdown.registerShutdownHook( Empyrean.class, new Runnable( ) {
+
+ @Override
+ public void run( ) {
+ try {
+ for ( String ctx : PersistenceContexts.list( ) ) {
+ try {
+ DriverDatabaseClusterMBean db = Databases.lookup( ctx );
+ for ( String host : db.getInactiveDatabases( ) ) {
+ Databases.disable( host );
+ }
+ for ( String host : db.getActiveDatabases( ) ) {
+ Databases.disable( host );
+ }
+ } catch ( Exception ex ) {
+ LOG.error( ex );
+ }
+ }
+ } catch ( NoSuchElementException ex ) {
+ LOG.error( ex );
+ }
+ }
+ } );
return true;
}
@@ -140,7 +222,6 @@ public boolean load( ) throws Exception {
public boolean check( ) throws Exception {
return super.check( );
}
-
}
static DriverDatabaseClusterMBean lookup( final String ctx ) throws NoSuchElementException {
@@ -151,9 +232,9 @@ static DriverDatabaseClusterMBean lookup( final String ctx ) throws NoSuchElemen
}
private static void runDbStateChange( Function<String, Runnable> runnableFunction ) {
- LOG.debug( "DB STATE CHANGE: " + runnableFunction );
+ LOG.info( "DB STATE CHANGE: " + runnableFunction );
try {
- if ( canHas.writeLock( ).tryLock( 30000L, TimeUnit.MILLISECONDS ) ) {
+ if ( canHas.writeLock( ).tryLock( ) ) {
try {
Map<Runnable, Future<Runnable>> runnables = Maps.newHashMap( );
for ( final String ctx : PersistenceContexts.list( ) ) {
@@ -175,8 +256,6 @@ private static void runDbStateChange( Function<String, Runnable> runnableFunctio
} else {
throw Exceptions.toUndeclared( "DB STATE CHANGE ABORTED (failed to get lock): " + runnableFunction );
}
- } catch ( InterruptedException ex ) {
- Exceptions.maybeInterrupted( ex );
} catch ( RuntimeException ex ) {
LOG.error( ex );
Logs.extreme( ).error( ex, ex );
@@ -186,17 +265,14 @@ private static void runDbStateChange( Function<String, Runnable> runnableFunctio
enum LivenessCheckHostFunction implements Function<String, Function<String, Runnable>> {
INSTANCE;
-
public Function<String, Runnable> apply( final String hostName ) {
return new Function<String, Runnable>( ) {
-
@Override
public Runnable apply( final String ctx ) {
final String contextName = ctx.startsWith( "eucalyptus_" )
? ctx
: "eucalyptus_" + ctx;
Runnable removeRunner = new Runnable( ) {
-
@Override
public void run( ) {
DriverDatabaseClusterMBean cluster = lookup( ctx );
@@ -224,46 +300,44 @@ public String toString( ) {
@Override
public Function<String, Runnable> apply( final String hostName ) {
return new Function<String, Runnable>( ) {
-
@Override
public Runnable apply( final String ctx ) {
final String contextName = ctx.startsWith( "eucalyptus_" )
? ctx
: "eucalyptus_" + ctx;
Runnable removeRunner = new Runnable( ) {
-
@Override
public void run( ) {
try {
final DriverDatabaseClusterMBean cluster = lookup( contextName );
- LOG.debug( "Tearing down database connections for: " + hostName + " to context: " + contextName );
+ LOG.info( "Tearing down database connections for: " + hostName + " to context: " + contextName );
cluster.getDatabase( hostName );
try {
- LOG.debug( "Removing database connections for: " + hostName + " to context: " + contextName );
+ LOG.info( "Removing database connections for: " + hostName + " to context: " + contextName );
cluster.remove( hostName );
- LOG.debug( "Removed database connections for: " + hostName + " to context: " + contextName );
+ LOG.info( "Removed database connections for: " + hostName + " to context: " + contextName );
} catch ( IllegalStateException ex ) {
- LOG.debug( ex );
+ LOG.info( ex );
Logs.extreme( ).debug( ex, ex );
}
try {
- LOG.debug( "Deactivating database connections for: " + hostName + " to context: " + contextName );
+ LOG.info( "Deactivating database connections for: " + hostName + " to context: " + contextName );
cluster.deactivate( hostName );
- LOG.debug( "Deactived database connections for: " + hostName + " to context: " + contextName );
+ LOG.info( "Deactived database connections for: " + hostName + " to context: " + contextName );
} catch ( Exception ex ) {
- LOG.debug( ex );
+ LOG.info( ex );
Logs.extreme( ).debug( ex, ex );
}
try {
- LOG.debug( "Removing database connections for: " + hostName + " to context: " + contextName );
+ LOG.info( "Removing database connections for: " + hostName + " to context: " + contextName );
cluster.remove( hostName );
- LOG.debug( "Removed database connections for: " + hostName + " to context: " + contextName );
+ LOG.info( "Removed database connections for: " + hostName + " to context: " + contextName );
} catch ( Exception ex ) {
- LOG.debug( ex );
+ LOG.info( ex );
Logs.extreme( ).debug( ex, ex );
}
} catch ( final Exception ex1 ) {
- LOG.debug( ex1 );
+ LOG.info( ex1 );
Logs.extreme( ).debug( ex1, ex1 );
}
}
@@ -272,13 +346,17 @@ public void run( ) {
public String toString( ) {
return "Databases.disable(): " + hostName + " " + contextName;
}
-
};
return removeRunner;
}
+
+ @Override
+ public String toString( ) {
+ return "Databases.disable(): " + hostName;
+ }
};
}
-
+
@Override
public String toString( ) {
return "Databases.disable()";
@@ -287,7 +365,6 @@ public String toString( ) {
enum ActivateHostFunction implements Function<Host, Function<String, Runnable>> {
INSTANCE;
-
private static void prepareConnections( final Host host, final String contextName ) throws NoSuchElementException {
final String hostName = host.getDisplayName( );
final String dbPass = SystemIds.databasePassword( );
@@ -301,7 +378,6 @@ private static void prepareConnections( final Host host, final String contextNam
@Override
public Function<String, Runnable> apply( final Host host ) {
return new Function<String, Runnable>( ) {
-
@Override
public Runnable apply( final String ctx ) {
final String hostName = host.getBindAddress( ).getHostAddress( );
@@ -309,7 +385,6 @@ public Runnable apply( final String ctx ) {
? ctx
: "eucalyptus_" + ctx;
Runnable removeRunner = new Runnable( ) {
-
@Override
public void run( ) {
try {
@@ -321,7 +396,6 @@ public void run( ) {
DriverDatabaseClusterMBean cluster = LookupPersistenceContextDatabaseCluster.INSTANCE.apply( contextName );
final String dbUrl = "jdbc:" + ServiceUris.remote( Database.class, host.getBindAddress( ), contextName );
final String realJdbcDriver = Databases.getDriverName( );
-
try {
if ( fullSync ) {
if ( cluster.getActiveDatabases( ).contains( hostName ) ) {
@@ -357,11 +431,11 @@ public void run( ) {
}
}
} catch ( final NoSuchElementException ex1 ) {
- LOG.debug( ex1 );
+ LOG.info( ex1 );
Logs.extreme( ).debug( ex1, ex1 );
return;
} catch ( final IllegalStateException ex1 ) {
- LOG.debug( ex1 );
+ LOG.info( ex1 );
Logs.extreme( ).debug( ex1, ex1 );
return;
} catch ( final Exception ex1 ) {
@@ -374,13 +448,18 @@ public void run( ) {
public String toString( ) {
return "Databases.enable(): " + host.getDisplayName( ) + " " + contextName;
}
-
};
return removeRunner;
}
+
+ @Override
+ public String toString( ) {
+ return "Databases.enable(): " + host;
+ }
+
};
}
-
+
@Override
public String toString( ) {
return "Databases.enable()";
@@ -446,7 +525,7 @@ static boolean disable( final String hostName ) {
}
static boolean enable( final Host host ) {
- if ( !host.hasBootstrapped( ) || !host.hasDatabase( ) || !Bootstrap.isFinished( ) ) {
+ if ( !host.hasDatabase( ) || !Bootstrap.isLoaded( ) ) {
return false;
} else {
if ( host.isLocalHost( ) ) {
@@ -456,8 +535,14 @@ static boolean enable( final Host host ) {
syncState.set( SyncState.SYNCED );
return true;
} catch ( Exception ex ) {
- runDbStateChange( DeactivateHostFunction.INSTANCE.apply( host.getDisplayName( ) ) );
- syncState.set( SyncState.NOTSYNCED );
+ try {
+ runDbStateChange( DeactivateHostFunction.INSTANCE.apply( host.getDisplayName( ) ) );
+ } catch ( Exception ex1 ) {
+ LOG.error( "Databases.enable(): failed because of: " + ex.getMessage( ) );
+ Logs.extreme( ).error( ex, ex );
+ } finally {
+ syncState.set( SyncState.NOTSYNCED );
+ }
return false;
}
} else {
@@ -525,6 +610,45 @@ public static Boolean isSynchronized( ) {
return SyncState.SYNCED.equals( syncState.get( ) );
}
+ public static Boolean isSynchronizing( ) {
+ if ( !Bootstrap.isFinished( ) || BootstrapArgs.isInitializeSystem( ) ) {
+ return false;
+ } else if ( !Hosts.isCoordinator( ) && BootstrapArgs.isCloudController( ) ) {
+ return !isSynchronized( );
+ } else {
+ return !Hosts.list( FILTER_SYNCING_DBS ).isEmpty( );
+ }
+ }
+
+ private static Predicate<StackTraceElement> notStackFilterYouAreLookingFor = Predicates.or( Threads.filterStackByQualifiedName( "com\\.eucalyptus\\.entities\\..*" ),
+ Threads.filterStackByQualifiedName( "java\\.lang\\.Thread.*" ),
+ Threads.filterStackByQualifiedName( "com\\.eucalyptus\\.system\\.Threads.*" ),
+ Threads.filterStackByQualifiedName( "com\\.eucalyptus\\.bootstrap\\.Databases.*" ) );
+ private static Predicate<StackTraceElement> stackFilter = Predicates.not( notStackFilterYouAreLookingFor );
+
+ public static void awaitSynchronized( ) {
+ if ( !isSynchronizing( ) ) {
+ return;
+ } else {
+ Collection<StackTraceElement> stack = Threads.filteredStack( stackFilter );
+ String caller = ( stack.isEmpty( ) ? "" : stack.iterator( ).next( ).toString( ) );
+ for ( int i = 0; i < MAX_TX_START_SYNC_RETRIES && isSynchronizing( ); i++ ) {
+ try {
+ TimeUnit.MILLISECONDS.sleep( 1000 );
+ LOG.debug( "Transaction blocked on sync: " + caller );
+ } catch ( InterruptedException ex ) {
+ Exceptions.maybeInterrupted( ex );
+ return;
+ }
+ }
+ if ( !isSynchronized( ) ) {
+ throw new DatabaseStateException( "Transaction begin failed due to concurrent database synchronization: " + Hosts.listDatabases( )
+ + " for caller:\n"
+ + Joiner.on( "\n\tat " ).join( stack ) );
+ }
+ }
+ }
+
public static String getUserName( ) {
return DB_USERNAME;
}
@@ -658,7 +782,7 @@ public static String getServicePath( String... pathParts ) {
public static String getJdbcScheme( ) {
return singleton.getJdbcScheme( );
}
-
+
public static void check( ) {
for ( String ctx : PersistenceContexts.list( ) ) {
try {
@@ -669,10 +793,587 @@ public static void check( ) {
}
}
} catch ( NoSuchElementException ex ) {
- LOG.error( ex , ex );
+ LOG.error( ex, ex );
}
return;
}
}
+ public static final class SynchronizationSupport {
+ private SynchronizationSupport( ) {
+ // Hide
+ }
+
+ /**
+ * Drop all foreign key constraints on the target database
+ * * @param <D>
+ *
+ * @param context a synchronization context
+ * @throws SQLException if database error occurs
+ */
+ public static <D> void dropForeignKeys( SynchronizationContext<D> context ) throws SQLException {
+ Dialect dialect = context.getDialect( );
+ Connection connection = context.getConnection( context.getTargetDatabase( ) );
+ Statement statement = connection.createStatement( );
+ for ( TableProperties table : context.getTargetDatabaseProperties( ).getTables( ) ) {
+ for ( ForeignKeyConstraint constraint : table.getForeignKeyConstraints( ) ) {
+ String sql = dialect.getDropForeignKeyConstraintSQL( constraint );
+ LOG.info( sql );
+ statement.addBatch( sql );
+ }
+ }
+ statement.executeBatch( );
+ statement.close( );
+ }
+
+ /**
+ * Restores all foreign key constraints on the target database
+ * * @param <D>
+ *
+ * @param context a synchronization context
+ * @throws SQLException if database error occurs
+ */
+ public static <D> void restoreForeignKeys( SynchronizationContext<D> context ) throws SQLException {
+ Dialect dialect = context.getDialect( );
+ Connection connection = context.getConnection( context.getTargetDatabase( ) );
+ Statement statement = connection.createStatement( );
+ for ( TableProperties table : context.getSourceDatabaseProperties( ).getTables( ) ) {
+ for ( ForeignKeyConstraint constraint : table.getForeignKeyConstraints( ) ) {
+ String sql = dialect.getCreateForeignKeyConstraintSQL( constraint );
+ LOG.info( sql );
+ statement.addBatch( sql );
+ }
+ }
+ statement.executeBatch( );
+ statement.close( );
+ }
+
+ /**
+ * Synchronizes the sequences on the target database with the source database.
+ * * @param <D>
+ *
+ * @param context a synchronization context
+ * @throws SQLException if database error occurs
+ */
+ public static <D> void synchronizeSequences( final SynchronizationContext<D> context ) throws SQLException {
+ Collection<SequenceProperties> sequences = context.getSourceDatabaseProperties( ).getSequences( );
+ if ( !sequences.isEmpty( ) ) {
+ net.sf.hajdbc.Database<D> sourceDatabase = context.getSourceDatabase( );
+ Set<net.sf.hajdbc.Database<D>> databases = context.getActiveDatabaseSet( );
+ ExecutorService executor = context.getExecutor( );
+ Dialect dialect = context.getDialect( );
+ Map<SequenceProperties, Long> sequenceMap = new HashMap<SequenceProperties, Long>( );
+ Map<net.sf.hajdbc.Database<D>, Future<Long>> futureMap = new HashMap<net.sf.hajdbc.Database<D>, Future<Long>>( );
+ for ( SequenceProperties sequence : sequences ) {
+ final String sql = dialect.getNextSequenceValueSQL( sequence );
+ LOG.info( sql );
+ for ( final net.sf.hajdbc.Database<D> database : databases ) {
+ Callable<Long> task = new Callable<Long>( )
+ {
+ public Long call( ) throws SQLException
+ {
+ Statement statement = context.getConnection( database ).createStatement( );
+ ResultSet resultSet = statement.executeQuery( sql );
+ resultSet.next( );
+ long value = resultSet.getLong( 1 );
+ statement.close( );
+ return value;
+ }
+ };
+ futureMap.put( database, executor.submit( task ) );
+ }
+ try {
+ Long sourceValue = futureMap.get( sourceDatabase ).get( );
+ sequenceMap.put( sequence, sourceValue );
+ for ( net.sf.hajdbc.Database<D> database : databases ) {
+ if ( !database.equals( sourceDatabase ) ) {
+ Long value = futureMap.get( database ).get( );
+ if ( !value.equals( sourceValue ) ) {
+ throw new SQLException( Messages.getMessage( Messages.SEQUENCE_OUT_OF_SYNC, sequence, database, value, sourceDatabase, sourceValue ) );
+ }
+ }
+ }
+ } catch ( InterruptedException e ) {
+ throw SQLExceptionFactory.createSQLException( e );
+ } catch ( ExecutionException e ) {
+ throw SQLExceptionFactory.createSQLException( e.getCause( ) );
+ }
+ }
+ Connection targetConnection = context.getConnection( context.getTargetDatabase( ) );
+ Statement targetStatement = targetConnection.createStatement( );
+ for ( SequenceProperties sequence : sequences ) {
+ String sql = dialect.getAlterSequenceSQL( sequence, sequenceMap.get( sequence ) + 1 );
+ LOG.info( sql );
+ targetStatement.addBatch( sql );
+ }
+ targetStatement.executeBatch( );
+ targetStatement.close( );
+ }