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 }