Committed by
Gerrit Code Review
[ONOS-2548]
1.refactor serverDetected and serverVanished implementation 2.Use TrafficTreatment.transition to judge which table is used instead of ether_type Change-Id: I5a2dfae1fa6f6ddca94dc5fea024f7430ce37532
Showing
1 changed file
with
69 additions
and
77 deletions
... | @@ -81,6 +81,8 @@ import org.onosproject.store.service.WallClockTimestamp; | ... | @@ -81,6 +81,8 @@ import org.onosproject.store.service.WallClockTimestamp; |
81 | import org.onosproject.vtn.VTNService; | 81 | import org.onosproject.vtn.VTNService; |
82 | import org.slf4j.Logger; | 82 | import org.slf4j.Logger; |
83 | 83 | ||
84 | +import com.google.common.collect.Sets; | ||
85 | + | ||
84 | /** | 86 | /** |
85 | * Provides implementation of VTNService. | 87 | * Provides implementation of VTNService. |
86 | */ | 88 | */ |
... | @@ -116,8 +118,6 @@ public class VTNManager implements VTNService { | ... | @@ -116,8 +118,6 @@ public class VTNManager implements VTNService { |
116 | private static final String IFACEID = "ifaceid"; | 118 | private static final String IFACEID = "ifaceid"; |
117 | private static final String PORT_HEAD = "vxlan"; | 119 | private static final String PORT_HEAD = "vxlan"; |
118 | private static final int MAC_TABLE = 40; | 120 | private static final int MAC_TABLE = 40; |
119 | - private static final short ETH_TYPE_MAC = 40; | ||
120 | - private static final short ETH_TYPE_PORT = 0; | ||
121 | private static final String DEFAULT_BRIDGE_NAME = "br-int"; | 121 | private static final String DEFAULT_BRIDGE_NAME = "br-int"; |
122 | private static final String CONTROLLER_IP_KEY = "ipaddress"; | 122 | private static final String CONTROLLER_IP_KEY = "ipaddress"; |
123 | 123 | ||
... | @@ -149,70 +149,68 @@ public class VTNManager implements VTNService { | ... | @@ -149,70 +149,68 @@ public class VTNManager implements VTNService { |
149 | public void onServerDetected(Device device) { | 149 | public void onServerDetected(Device device) { |
150 | Iterable<Device> devices = deviceService.getAvailableDevices(); | 150 | Iterable<Device> devices = deviceService.getAvailableDevices(); |
151 | DriverHandler handler = driverService.createHandler(device.id()); | 151 | DriverHandler handler = driverService.createHandler(device.id()); |
152 | - TunnelConfig config = handler.behaviour(TunnelConfig.class); | ||
153 | BridgeConfig bridgeConfig = handler.behaviour(BridgeConfig.class); | 152 | BridgeConfig bridgeConfig = handler.behaviour(BridgeConfig.class); |
154 | bridgeConfig.addBridge(BridgeName.bridgeName(DEFAULT_BRIDGE_NAME)); | 153 | bridgeConfig.addBridge(BridgeName.bridgeName(DEFAULT_BRIDGE_NAME)); |
155 | String ipAddress = device.annotations().value(CONTROLLER_IP_KEY); | 154 | String ipAddress = device.annotations().value(CONTROLLER_IP_KEY); |
156 | IpAddress ip = IpAddress.valueOf(ipAddress); | 155 | IpAddress ip = IpAddress.valueOf(ipAddress); |
157 | - TunnelEndPoint tunnelAsSrcSrc = IpTunnelEndPoint.ipTunnelPoint(ip); | 156 | + Sets.newHashSet(devices) |
158 | - TunnelEndPoint tunnelAsDstDst = IpTunnelEndPoint.ipTunnelPoint(ip); | 157 | + .stream() |
159 | - devices.forEach(d -> { | 158 | + .filter(d -> d.type() == Device.Type.CONTROLLER) |
160 | - if (!device.id().equals(d.id())) { | 159 | + .filter(d -> !device.id().equals(d.id())) |
161 | - String ipAddress1 = d.annotations().value(CONTROLLER_IP_KEY); | 160 | + .forEach(d -> { |
161 | + String ipAddress1 = d.annotations() | ||
162 | + .value(CONTROLLER_IP_KEY); | ||
162 | IpAddress ip1 = IpAddress.valueOf(ipAddress1); | 163 | IpAddress ip1 = IpAddress.valueOf(ipAddress1); |
163 | - TunnelEndPoint tunnelAsSrcDst = IpTunnelEndPoint | 164 | + applyTunnelConfig(ip, ip1, handler); |
164 | - .ipTunnelPoint(ip1); | 165 | + DriverHandler handler1 = driverService |
165 | - TunnelEndPoint tunnelAsDstSrc = IpTunnelEndPoint | 166 | + .createHandler(d.id()); |
166 | - .ipTunnelPoint(ip1); | 167 | + applyTunnelConfig(ip1, ip, handler1); |
167 | - TunnelDescription tunnelAsSrc = new DefaultTunnelDescription( | ||
168 | - tunnelAsSrcSrc, | ||
169 | - tunnelAsSrcDst, | ||
170 | - TunnelDescription.Type.VXLAN, | ||
171 | - null); | ||
172 | - TunnelDescription tunnelAsDst = new DefaultTunnelDescription( | ||
173 | - tunnelAsDstDst, | ||
174 | - tunnelAsDstSrc, | ||
175 | - TunnelDescription.Type.VXLAN, | ||
176 | - null); | ||
177 | - config.createTunnel(tunnelAsSrc); | ||
178 | - config.createTunnel(tunnelAsDst); | ||
179 | - } | ||
180 | }); | 168 | }); |
181 | } | 169 | } |
182 | 170 | ||
183 | @Override | 171 | @Override |
184 | public void onServerVanished(Device device) { | 172 | public void onServerVanished(Device device) { |
185 | Iterable<Device> devices = deviceService.getAvailableDevices(); | 173 | Iterable<Device> devices = deviceService.getAvailableDevices(); |
186 | - DriverHandler handler = driverService.createHandler(device.id()); | ||
187 | - TunnelConfig config = handler.behaviour(TunnelConfig.class); | ||
188 | - BridgeConfig bridgeConfig = handler.behaviour(BridgeConfig.class); | ||
189 | - bridgeConfig.deleteBridge(BridgeName.bridgeName(DEFAULT_BRIDGE_NAME)); | ||
190 | String ipAddress = device.annotations().value(CONTROLLER_IP_KEY); | 174 | String ipAddress = device.annotations().value(CONTROLLER_IP_KEY); |
191 | - IpAddress ip = IpAddress.valueOf(ipAddress); | 175 | + IpAddress dst = IpAddress.valueOf(ipAddress); |
192 | - TunnelEndPoint tunnelAsSrcSrc = IpTunnelEndPoint.ipTunnelPoint(ip); | 176 | + Sets.newHashSet(devices) |
193 | - TunnelEndPoint tunnelAsDstDst = IpTunnelEndPoint.ipTunnelPoint(ip); | 177 | + .stream() |
194 | - devices.forEach(d -> { | 178 | + .filter(d -> d.type() == Device.Type.CONTROLLER) |
195 | - if (!device.id().equals(d.id())) { | 179 | + .filter(d -> !device.id().equals(d.id())) |
196 | - String ipAddress1 = d.annotations().value(CONTROLLER_IP_KEY); | 180 | + .forEach(d -> { |
197 | - IpAddress ip1 = IpAddress.valueOf(ipAddress1); | 181 | + String ipAddress1 = d.annotations() |
198 | - TunnelEndPoint tunnelAsSrcDst = IpTunnelEndPoint | 182 | + .value(CONTROLLER_IP_KEY); |
199 | - .ipTunnelPoint(ip1); | 183 | + DriverHandler handler = driverService |
200 | - TunnelEndPoint tunnelAsDstSrc = IpTunnelEndPoint | 184 | + .createHandler(d.id()); |
201 | - .ipTunnelPoint(ip1); | 185 | + IpAddress src = IpAddress.valueOf(ipAddress1); |
202 | - TunnelDescription tunnelAsSrc = new DefaultTunnelDescription( | 186 | + removeTunnelConfig(src, dst, handler); |
203 | - tunnelAsSrcSrc, | 187 | + }); |
204 | - tunnelAsSrcDst, | 188 | + } |
189 | + | ||
190 | + private void applyTunnelConfig(IpAddress src, IpAddress dst, | ||
191 | + DriverHandler handler) { | ||
192 | + TunnelEndPoint tunnelAsSrc = IpTunnelEndPoint.ipTunnelPoint(src); | ||
193 | + TunnelEndPoint tunnelAsDst = IpTunnelEndPoint.ipTunnelPoint(dst); | ||
194 | + TunnelDescription tunnel = new DefaultTunnelDescription( | ||
195 | + tunnelAsSrc, | ||
196 | + tunnelAsDst, | ||
205 | TunnelDescription.Type.VXLAN, | 197 | TunnelDescription.Type.VXLAN, |
206 | null); | 198 | null); |
207 | - TunnelDescription tunnelAsDst = new DefaultTunnelDescription( | 199 | + TunnelConfig config = handler.behaviour(TunnelConfig.class); |
208 | - tunnelAsDstDst, | 200 | + config.createTunnel(tunnel); |
209 | - tunnelAsDstSrc, | 201 | + } |
202 | + | ||
203 | + private void removeTunnelConfig(IpAddress src, IpAddress dst, | ||
204 | + DriverHandler handler) { | ||
205 | + TunnelEndPoint tunnelAsSrc = IpTunnelEndPoint.ipTunnelPoint(src); | ||
206 | + TunnelEndPoint tunnelAsDst = IpTunnelEndPoint.ipTunnelPoint(dst); | ||
207 | + TunnelDescription tunnel = new DefaultTunnelDescription( | ||
208 | + tunnelAsSrc, | ||
209 | + tunnelAsDst, | ||
210 | TunnelDescription.Type.VXLAN, | 210 | TunnelDescription.Type.VXLAN, |
211 | null); | 211 | null); |
212 | - config.removeTunnel(tunnelAsSrc); | 212 | + TunnelConfig config = handler.behaviour(TunnelConfig.class); |
213 | - config.removeTunnel(tunnelAsDst); | 213 | + config.removeTunnel(tunnel); |
214 | - } | ||
215 | - }); | ||
216 | } | 214 | } |
217 | 215 | ||
218 | @Override | 216 | @Override |
... | @@ -295,7 +293,8 @@ public class VTNManager implements VTNService { | ... | @@ -295,7 +293,8 @@ public class VTNManager implements VTNService { |
295 | onServerDetected(device); | 293 | onServerDetected(device); |
296 | }); | 294 | }); |
297 | } else if (Device.Type.CONTROLLER == device.type() | 295 | } else if (Device.Type.CONTROLLER == device.type() |
298 | - && DeviceEvent.Type.DEVICE_REMOVED == event.type()) { | 296 | + && DeviceEvent.Type.DEVICE_AVAILABILITY_CHANGED == event |
297 | + .type()) { | ||
299 | backgroundService.execute(() -> { | 298 | backgroundService.execute(() -> { |
300 | onServerVanished(device); | 299 | onServerVanished(device); |
301 | }); | 300 | }); |
... | @@ -305,7 +304,8 @@ public class VTNManager implements VTNService { | ... | @@ -305,7 +304,8 @@ public class VTNManager implements VTNService { |
305 | onOvsDetected(device); | 304 | onOvsDetected(device); |
306 | }); | 305 | }); |
307 | } else if (Device.Type.SWITCH == device.type() | 306 | } else if (Device.Type.SWITCH == device.type() |
308 | - && DeviceEvent.Type.DEVICE_REMOVED == event.type()) { | 307 | + && DeviceEvent.Type.DEVICE_AVAILABILITY_CHANGED == event |
308 | + .type()) { | ||
309 | backgroundService.execute(() -> { | 309 | backgroundService.execute(() -> { |
310 | onOvsVanished(device); | 310 | onOvsVanished(device); |
311 | }); | 311 | }); |
... | @@ -336,12 +336,12 @@ public class VTNManager implements VTNService { | ... | @@ -336,12 +336,12 @@ public class VTNManager implements VTNService { |
336 | 336 | ||
337 | } | 337 | } |
338 | 338 | ||
339 | - //Used to forward the flows to the local VM. | 339 | + // Used to forward the flows to the local VM. |
340 | private void programLocalOut(DeviceId dpid, SegmentationId segmentationId, | 340 | private void programLocalOut(DeviceId dpid, SegmentationId segmentationId, |
341 | PortNumber outPort, MacAddress sourceMac, | 341 | PortNumber outPort, MacAddress sourceMac, |
342 | ApplicationId appid, Objective.Operation type) { | 342 | ApplicationId appid, Objective.Operation type) { |
343 | TrafficSelector selector = DefaultTrafficSelector.builder() | 343 | TrafficSelector selector = DefaultTrafficSelector.builder() |
344 | - .matchEthDst(sourceMac).matchEthType(ETH_TYPE_MAC).build(); | 344 | + .matchEthDst(sourceMac).build(); |
345 | TrafficTreatment treatment = DefaultTrafficTreatment | 345 | TrafficTreatment treatment = DefaultTrafficTreatment |
346 | .builder() | 346 | .builder() |
347 | .add(Instructions.modTunnelId(Long.parseLong(segmentationId | 347 | .add(Instructions.modTunnelId(Long.parseLong(segmentationId |
... | @@ -357,12 +357,12 @@ public class VTNManager implements VTNService { | ... | @@ -357,12 +357,12 @@ public class VTNManager implements VTNService { |
357 | 357 | ||
358 | } | 358 | } |
359 | 359 | ||
360 | - //Used to forward the flows to the remote VM via VXLAN tunnel. | 360 | + // Used to forward the flows to the remote VM via VXLAN tunnel. |
361 | private void programTunnelOut(DeviceId dpid, SegmentationId segmentationId, | 361 | private void programTunnelOut(DeviceId dpid, SegmentationId segmentationId, |
362 | PortNumber outPort, MacAddress sourceMac, | 362 | PortNumber outPort, MacAddress sourceMac, |
363 | ApplicationId appid, Objective.Operation type) { | 363 | ApplicationId appid, Objective.Operation type) { |
364 | TrafficSelector selector = DefaultTrafficSelector.builder() | 364 | TrafficSelector selector = DefaultTrafficSelector.builder() |
365 | - .matchEthDst(sourceMac).matchEthType(ETH_TYPE_MAC).build(); | 365 | + .matchEthDst(sourceMac).build(); |
366 | TrafficTreatment treatment = DefaultTrafficTreatment | 366 | TrafficTreatment treatment = DefaultTrafficTreatment |
367 | .builder() | 367 | .builder() |
368 | .add(Instructions.modTunnelId(Long.parseLong(segmentationId | 368 | .add(Instructions.modTunnelId(Long.parseLong(segmentationId |
... | @@ -377,7 +377,8 @@ public class VTNManager implements VTNService { | ... | @@ -377,7 +377,8 @@ public class VTNManager implements VTNService { |
377 | } | 377 | } |
378 | } | 378 | } |
379 | 379 | ||
380 | - //Used to forward multicast flows to remote VMs of the same tenant via VXLAN tunnel. | 380 | + // Used to forward multicast flows to remote VMs of the same tenant via |
381 | + // VXLAN tunnel. | ||
381 | private void programTunnelFloodOut(DeviceId dpid, | 382 | private void programTunnelFloodOut(DeviceId dpid, |
382 | SegmentationId segmentationId, | 383 | SegmentationId segmentationId, |
383 | PortNumber ofPortOut, | 384 | PortNumber ofPortOut, |
... | @@ -387,21 +388,19 @@ public class VTNManager implements VTNService { | ... | @@ -387,21 +388,19 @@ public class VTNManager implements VTNService { |
387 | TrafficSelector selector = DefaultTrafficSelector | 388 | TrafficSelector selector = DefaultTrafficSelector |
388 | .builder() | 389 | .builder() |
389 | .matchInPort(ofPortOut) | 390 | .matchInPort(ofPortOut) |
390 | - .matchEthType(ETH_TYPE_MAC) | 391 | + |
391 | .add(Criteria.matchTunnelId(Long.parseLong(segmentationId | 392 | .add(Criteria.matchTunnelId(Long.parseLong(segmentationId |
392 | .toString()))).matchEthDst(MacAddress.BROADCAST) | 393 | .toString()))).matchEthDst(MacAddress.BROADCAST) |
393 | .build(); | 394 | .build(); |
394 | TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder(); | 395 | TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder(); |
395 | - | ||
396 | for (Port outport : localports) { | 396 | for (Port outport : localports) { |
397 | treatment.setOutput(outport.number()); | 397 | treatment.setOutput(outport.number()); |
398 | } | 398 | } |
399 | 399 | ||
400 | ForwardingObjective.Builder objective = DefaultForwardingObjective | 400 | ForwardingObjective.Builder objective = DefaultForwardingObjective |
401 | .builder().withTreatment(treatment.build()) | 401 | .builder().withTreatment(treatment.build()) |
402 | - .withSelector(selector).fromApp(appId) | 402 | + .withSelector(selector).fromApp(appId).makePermanent() |
403 | - | 403 | + .withFlag(Flag.SPECIFIC); |
404 | - .makePermanent().withFlag(Flag.SPECIFIC); | ||
405 | if (type.equals(Objective.Operation.ADD)) { | 404 | if (type.equals(Objective.Operation.ADD)) { |
406 | flowObjectiveService.forward(dpid, objective.add()); | 405 | flowObjectiveService.forward(dpid, objective.add()); |
407 | } else { | 406 | } else { |
... | @@ -409,14 +408,12 @@ public class VTNManager implements VTNService { | ... | @@ -409,14 +408,12 @@ public class VTNManager implements VTNService { |
409 | } | 408 | } |
410 | } | 409 | } |
411 | 410 | ||
412 | - //Applies default flows to mac table. | 411 | + // Applies default flows to mac table. |
413 | private void programMacDefaultRules(DeviceId dpid, ApplicationId appid, | 412 | private void programMacDefaultRules(DeviceId dpid, ApplicationId appid, |
414 | Objective.Operation type) { | 413 | Objective.Operation type) { |
415 | - TrafficSelector selector = DefaultTrafficSelector.builder() | 414 | + TrafficSelector selector = DefaultTrafficSelector.builder().build(); |
416 | - .matchEthType(ETH_TYPE_MAC).build(); | ||
417 | TrafficTreatment treatment = DefaultTrafficTreatment.builder().drop() | 415 | TrafficTreatment treatment = DefaultTrafficTreatment.builder().drop() |
418 | .build(); | 416 | .build(); |
419 | - | ||
420 | ForwardingObjective.Builder objective = DefaultForwardingObjective | 417 | ForwardingObjective.Builder objective = DefaultForwardingObjective |
421 | .builder().withTreatment(treatment).withSelector(selector) | 418 | .builder().withTreatment(treatment).withSelector(selector) |
422 | .fromApp(appId).makePermanent().withFlag(Flag.SPECIFIC); | 419 | .fromApp(appId).makePermanent().withFlag(Flag.SPECIFIC); |
... | @@ -427,7 +424,7 @@ public class VTNManager implements VTNService { | ... | @@ -427,7 +424,7 @@ public class VTNManager implements VTNService { |
427 | } | 424 | } |
428 | } | 425 | } |
429 | 426 | ||
430 | - //Used to forward the flows to the local VMs with the same tenant. | 427 | + // Used to forward the flows to the local VMs with the same tenant. |
431 | private void programLocalBcastRules(DeviceId dpid, | 428 | private void programLocalBcastRules(DeviceId dpid, |
432 | SegmentationId segmentationId, | 429 | SegmentationId segmentationId, |
433 | PortNumber inPort, List<Port> allports, | 430 | PortNumber inPort, List<Port> allports, |
... | @@ -436,7 +433,6 @@ public class VTNManager implements VTNService { | ... | @@ -436,7 +433,6 @@ public class VTNManager implements VTNService { |
436 | TrafficSelector selector = DefaultTrafficSelector | 433 | TrafficSelector selector = DefaultTrafficSelector |
437 | .builder() | 434 | .builder() |
438 | .matchInPort(inPort) | 435 | .matchInPort(inPort) |
439 | - .matchEthType(ETH_TYPE_MAC) | ||
440 | .matchEthDst(MacAddress.BROADCAST) | 436 | .matchEthDst(MacAddress.BROADCAST) |
441 | .add(Criteria.matchTunnelId(Long.parseLong(segmentationId | 437 | .add(Criteria.matchTunnelId(Long.parseLong(segmentationId |
442 | .toString()))).build(); | 438 | .toString()))).build(); |
... | @@ -458,15 +454,13 @@ public class VTNManager implements VTNService { | ... | @@ -458,15 +454,13 @@ public class VTNManager implements VTNService { |
458 | } | 454 | } |
459 | } | 455 | } |
460 | 456 | ||
461 | - //Used to apply local entry flow. | 457 | + // Used to apply local entry flow. |
462 | private void programLocalIn(DeviceId dpid, SegmentationId segmentationId, | 458 | private void programLocalIn(DeviceId dpid, SegmentationId segmentationId, |
463 | PortNumber inPort, MacAddress srcMac, | 459 | PortNumber inPort, MacAddress srcMac, |
464 | ApplicationId appid, Objective.Operation type) { | 460 | ApplicationId appid, Objective.Operation type) { |
465 | TrafficSelector selector = DefaultTrafficSelector.builder() | 461 | TrafficSelector selector = DefaultTrafficSelector.builder() |
466 | - .matchInPort(inPort).matchEthSrc(srcMac) | 462 | + .matchInPort(inPort).matchEthSrc(srcMac).build(); |
467 | - .matchEthType(ETH_TYPE_PORT).build(); | ||
468 | TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder(); | 463 | TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder(); |
469 | - | ||
470 | treatment.add(Instructions.modTunnelId(Long.parseLong(segmentationId | 464 | treatment.add(Instructions.modTunnelId(Long.parseLong(segmentationId |
471 | .toString()))); | 465 | .toString()))); |
472 | treatment.transition(MAC_TABLE); | 466 | treatment.transition(MAC_TABLE); |
... | @@ -481,14 +475,13 @@ public class VTNManager implements VTNService { | ... | @@ -481,14 +475,13 @@ public class VTNManager implements VTNService { |
481 | } | 475 | } |
482 | } | 476 | } |
483 | 477 | ||
484 | - //Used to forward the flows from the egress tunnel to the VM. | 478 | + // Used to forward the flows from the egress tunnel to the VM. |
485 | private void programTunnelIn(DeviceId dpid, SegmentationId segmentationId, | 479 | private void programTunnelIn(DeviceId dpid, SegmentationId segmentationId, |
486 | PortNumber inPort, MacAddress sourceMac, | 480 | PortNumber inPort, MacAddress sourceMac, |
487 | ApplicationId appid, Objective.Operation type) { | 481 | ApplicationId appid, Objective.Operation type) { |
488 | TrafficSelector selector = DefaultTrafficSelector | 482 | TrafficSelector selector = DefaultTrafficSelector |
489 | .builder() | 483 | .builder() |
490 | .matchInPort(inPort) | 484 | .matchInPort(inPort) |
491 | - .matchEthType(ETH_TYPE_PORT) | ||
492 | .add(Criteria.matchTunnelId(Long.parseLong(segmentationId | 485 | .add(Criteria.matchTunnelId(Long.parseLong(segmentationId |
493 | .toString()))).build(); | 486 | .toString()))).build(); |
494 | TrafficTreatment treatment = DefaultTrafficTreatment.builder() | 487 | TrafficTreatment treatment = DefaultTrafficTreatment.builder() |
... | @@ -504,11 +497,10 @@ public class VTNManager implements VTNService { | ... | @@ -504,11 +497,10 @@ public class VTNManager implements VTNService { |
504 | } | 497 | } |
505 | } | 498 | } |
506 | 499 | ||
507 | - //Applies the default flows to port table. | 500 | + // Applies the default flows to port table. |
508 | private void programPortDefaultRules(DeviceId dpid, ApplicationId appid, | 501 | private void programPortDefaultRules(DeviceId dpid, ApplicationId appid, |
509 | Objective.Operation type) { | 502 | Objective.Operation type) { |
510 | - TrafficSelector selector = DefaultTrafficSelector.builder() | 503 | + TrafficSelector selector = DefaultTrafficSelector.builder().build(); |
511 | - .matchEthType(ETH_TYPE_PORT).build(); | ||
512 | TrafficTreatment treatment = DefaultTrafficTreatment.builder() | 504 | TrafficTreatment treatment = DefaultTrafficTreatment.builder() |
513 | .transition(MAC_TABLE).build(); | 505 | .transition(MAC_TABLE).build(); |
514 | ForwardingObjective.Builder objective = DefaultForwardingObjective | 506 | ForwardingObjective.Builder objective = DefaultForwardingObjective | ... | ... |
-
Please register or login to post a comment