@@ -191,6 +191,8 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag
191191 SearchBuilder <IPAddressVO > IpAddressSearch ;
192192
193193 private Map <String , String > _configs ;
194+
195+ HashMap <Long , Long > _lastNetworkIdsToFree = new HashMap <Long , Long >();
194196
195197 @ Override @ DB
196198 public PublicIp fetchNewPublicIp (long dcId , VlanType vlanUse , Account owner , Long networkId , boolean sourceNat ) throws InsufficientAddressCapacityException {
@@ -761,7 +763,6 @@ public boolean configure(final String name, final Map<String, Object> params) th
761763 NetworkOfferingVO defaultGuestDirectPodBasedNetworkOffering = new NetworkOfferingVO (NetworkOffering .DefaultDirectPodBasedNetworkOffering , "DirectPodBased" , TrafficType .Public , GuestIpType .DirectPodBased , true , false , rateMbps , multicastRateMbps , null , true );
762764 defaultGuestNetworkOffering = _networkOfferingDao .persistDefaultNetworkOffering (defaultGuestDirectPodBasedNetworkOffering );
763765
764-
765766 AccountsUsingNetworkSearch = _accountDao .createSearchBuilder ();
766767 SearchBuilder <NetworkAccountVO > networkAccountSearch = _networksDao .createSearchBuilderForAccount ();
767768 AccountsUsingNetworkSearch .join ("nc" , networkAccountSearch , AccountsUsingNetworkSearch .entity ().getId (), networkAccountSearch .entity ().getAccountId (), JoinType .INNER );
@@ -1944,6 +1945,55 @@ public boolean deleteNetwork(DeleteNetworkCmd cmd) throws InvalidParameterValueE
19441945
19451946 }
19461947
1948+ @ DB
1949+ public void shutdownNetwork (long networkId ) {
1950+ Transaction txn = Transaction .currentTxn ();
1951+ txn .start ();
1952+ NetworkVO network = _networksDao .lockRow (networkId , true );
1953+ if (network == null ) {
1954+ s_logger .debug ("Unable to find network with id: " + networkId );
1955+ return ;
1956+ }
1957+ if (network .getState () != Network .State .Implemented && network .getState () != Network .State .Destroying ) {
1958+ s_logger .debug ("Network is not implemented: " + network );
1959+ return ;
1960+ }
1961+ network .setState (Network .State .Destroying );
1962+ _networksDao .update (network .getId (), network );
1963+ txn .commit ();
1964+
1965+ boolean success = true ;
1966+ for (NetworkElement element : _networkElements ) {
1967+ try {
1968+ if (s_logger .isDebugEnabled ()) {
1969+ s_logger .debug ("Sending network shutdown to " + element );
1970+ }
1971+ element .shutdown (network , null );
1972+ } catch (ResourceUnavailableException e ) {
1973+ s_logger .warn ("Unable to complete shutdown of the network due to element: " + element .getName (), e );
1974+ success = false ;
1975+ } catch (ConcurrentOperationException e ) {
1976+ s_logger .warn ("Unable to complete shutdown of the network due to element: " + element .getName (), e );
1977+ success = false ;
1978+ } catch (Exception e ) {
1979+ s_logger .warn ("Unable to complete shutdown of the network due to element: " + element .getName (), e );
1980+ success = false ;
1981+ }
1982+ }
1983+
1984+ if (success ) {
1985+ NetworkGuru guru = _networkGurus .get (network .getGuruName ());
1986+ guru .destroy (network , _networkOfferingDao .findById (network .getNetworkOfferingId ()));
1987+ network .setState (Network .State .Allocated );
1988+ _networksDao .update (network .getId (), network );
1989+ } else {
1990+ network .setState (Network .State .Implemented );
1991+ _networksDao .update (network .getId (), network );
1992+ }
1993+
1994+
1995+ }
1996+
19471997 @ Override
19481998 public boolean applyRules (Ip ip , List <? extends FirewallRule > rules , boolean continueOnError ) throws ResourceUnavailableException {
19491999 if (rules .size () == 0 ) {
@@ -1968,4 +2018,39 @@ public boolean applyRules(Ip ip, List<? extends FirewallRule> rules, boolean con
19682018
19692019 return success ;
19702020 }
2021+
2022+ public class NetworkGarbageCollector implements Runnable {
2023+
2024+ @ Override
2025+ public void run () {
2026+ List <Long > shutdownList = new ArrayList <Long >();
2027+ long currentTime = System .currentTimeMillis () >> 10 ;
2028+ HashMap <Long , Long > stillFree = new HashMap <Long , Long >();
2029+
2030+ List <Long > networkIds = _nicDao .listNetworksWithNoActiveNics ();
2031+ for (Long networkId : networkIds ) {
2032+ Long time = _lastNetworkIdsToFree .remove (networkId );
2033+ if (time == null ) {
2034+ if (s_logger .isDebugEnabled ()) {
2035+ s_logger .debug ("We found network " + networkId + " to be free for the first time. Adding it to the list: " + currentTime );
2036+ }
2037+ stillFree .put (networkId , currentTime );
2038+ } else if (time < (currentTime + 600 )) {
2039+ if (s_logger .isDebugEnabled ()) {
2040+ s_logger .debug ("Network " + networkId + " is still free but it's not time to shutdown yet: " + time );
2041+ }
2042+ stillFree .put (networkId , time );
2043+ } else {
2044+ shutdownList .add (networkId );
2045+ }
2046+ }
2047+
2048+ _lastNetworkIdsToFree = stillFree ;
2049+
2050+ for (Long networkId : shutdownList ) {
2051+ shutdownNetwork (networkId );
2052+ }
2053+ }
2054+
2055+ }
19712056}
0 commit comments