github.com/v2fly/v2ray-core/v5@v5.16.2-0.20240507031116-8191faa6e095/app/subscription/subscriptionmanager/subdocapplier.go (about)

     1  package subscriptionmanager
     2  
     3  import (
     4  	"fmt"
     5  
     6  	core "github.com/v2fly/v2ray-core/v5"
     7  	"github.com/v2fly/v2ray-core/v5/app/subscription/specs"
     8  )
     9  
    10  func (s *SubscriptionManagerImpl) applySubscriptionTo(name string, document *specs.SubscriptionDocument) error {
    11  	var trackedSub *trackedSubscription
    12  	if trackedSubFound, found := s.trackedSubscriptions[name]; !found {
    13  		return newError("not found")
    14  	} else {
    15  		trackedSub = trackedSubFound
    16  	}
    17  
    18  	delta, err := trackedSub.diff(document)
    19  	if err != nil {
    20  		return err
    21  	}
    22  
    23  	nameToServerConfig := make(map[string]*specs.SubscriptionServerConfig)
    24  	for _, server := range document.Server {
    25  		nameToServerConfig[server.Id] = server
    26  	}
    27  
    28  	for _, serverName := range delta.removed {
    29  		if err := s.removeManagedServer(name, serverName); err != nil {
    30  			newError("failed to remove managed server: ", err).AtWarning().WriteToLog()
    31  			continue
    32  		}
    33  		trackedSub.recordRemovedServer(serverName)
    34  	}
    35  
    36  	for _, serverName := range delta.modified {
    37  		serverConfig := nameToServerConfig[serverName]
    38  		if err := s.updateManagedServer(name, serverName, serverConfig); err != nil {
    39  			newError("failed to update managed server: ", err).AtWarning().WriteToLog()
    40  			continue
    41  		}
    42  		trackedSub.recordUpdatedServer(serverName, serverConfig.Metadata[ServerMetadataTagName], serverConfig)
    43  	}
    44  
    45  	for _, serverName := range delta.added {
    46  		serverConfig := nameToServerConfig[serverName]
    47  		if err := s.addManagedServer(name, serverName, serverConfig); err != nil {
    48  			newError("failed to add managed server: ", err).AtWarning().WriteToLog()
    49  			continue
    50  		}
    51  		trackedSub.recordUpdatedServer(serverName, serverConfig.Metadata[ServerMetadataTagName], serverConfig)
    52  	}
    53  
    54  	newError("finished applying subscription, ", name, "; ", fmt.Sprintf(
    55  		"%v updated, %v added, %v removed, %v unchanged",
    56  		len(delta.modified), len(delta.added), len(delta.removed), len(delta.unchanged))).AtInfo().WriteToLog()
    57  
    58  	return nil
    59  }
    60  
    61  func (s *SubscriptionManagerImpl) removeManagedServer(subscriptionName, serverName string) error {
    62  	var trackedSub *trackedSubscription
    63  	if trackedSubFound, found := s.trackedSubscriptions[subscriptionName]; !found {
    64  		return newError("not found")
    65  	} else {
    66  		trackedSub = trackedSubFound
    67  	}
    68  
    69  	var trackedServer *materializedServer
    70  	if trackedServerFound, err := trackedSub.getCurrentServer(serverName); err != nil {
    71  		return err
    72  	} else {
    73  		trackedServer = trackedServerFound
    74  	}
    75  
    76  	tagName := fmt.Sprintf("%s_%s", trackedSub.importSource.TagPrefix, trackedServer.tagPostfix)
    77  
    78  	if err := core.RemoveOutboundHandler(s.s, tagName); err != nil {
    79  		return newError("failed to remove handler: ", err)
    80  	}
    81  	trackedSub.recordRemovedServer(serverName)
    82  	return nil
    83  }
    84  
    85  func (s *SubscriptionManagerImpl) addManagedServer(subscriptionName, serverName string,
    86  	serverSpec *specs.SubscriptionServerConfig,
    87  ) error {
    88  	var trackedSub *trackedSubscription
    89  	if trackedSubFound, found := s.trackedSubscriptions[subscriptionName]; !found {
    90  		return newError("not found")
    91  	} else {
    92  		trackedSub = trackedSubFound
    93  	}
    94  	tagPostfix := serverSpec.Metadata[ServerMetadataTagName]
    95  	tagName := fmt.Sprintf("%s_%s", trackedSub.importSource.TagPrefix, tagPostfix)
    96  
    97  	materialized, err := s.materialize(subscriptionName, tagName, serverSpec)
    98  	if err != nil {
    99  		return newError("failed to materialize server: ", err)
   100  	}
   101  
   102  	if err := core.AddOutboundHandler(s.s, materialized); err != nil {
   103  		return newError("failed to add handler: ", err)
   104  	}
   105  
   106  	trackedSub.recordUpdatedServer(serverName, tagPostfix, serverSpec)
   107  
   108  	return nil
   109  }
   110  
   111  func (s *SubscriptionManagerImpl) updateManagedServer(subscriptionName, serverName string,
   112  	serverSpec *specs.SubscriptionServerConfig,
   113  ) error {
   114  	if err := s.removeManagedServer(subscriptionName, serverName); err != nil {
   115  		return newError("failed to update managed server: ", err).AtWarning()
   116  	}
   117  	if err := s.addManagedServer(subscriptionName, serverName, serverSpec); err != nil {
   118  		return newError("failed to update managed server : ", err).AtWarning()
   119  	}
   120  	return nil
   121  }