diff --git a/schema/proto3/goalstateprovisioner.proto b/schema/proto3/goalstateprovisioner.proto index 4bb16c36c..751736b3f 100644 --- a/schema/proto3/goalstateprovisioner.proto +++ b/schema/proto3/goalstateprovisioner.proto @@ -23,6 +23,8 @@ option java_package = "com.futurewei.alcor.schema"; import "common.proto"; import "goalstate.proto"; import "neighbor.proto"; +import "securitygroup.proto"; +import "port.proto"; service GoalStateProvisioner { @@ -50,7 +52,10 @@ service GoalStateProvisioner { rpc RequestGoalStates (HostRequest) returns (HostRequestReply) { } - rpc PushGoalstates (NeighborRulesRequest) returns (GoalStateOperationReply) { + rpc PushGoalstates (ArionGoalStateRequest) returns (GoalStateOperationReply) { + } + + rpc PushSecurityGroupGoalState (SecurityGroupState) returns (GoalStateOperationReply) { } } @@ -86,11 +91,12 @@ message HostRequestReply { uint32 total_operation_time = 3; } -message NeighborRulesRequest { +message ArionGoalStateRequest { uint32 format_version = 1; string request_id = 2; repeated NeighborState neigborstates = 3; + repeated PortState portstates = 4; } message GoalStateOperationReply { diff --git a/services/data_plane_manager/src/main/java/com/futurewei/alcor/dataplane/cache/PortBindingSecurityGroupRepository.java b/services/data_plane_manager/src/main/java/com/futurewei/alcor/dataplane/cache/PortBindingSecurityGroupRepository.java new file mode 100644 index 000000000..341b01059 --- /dev/null +++ b/services/data_plane_manager/src/main/java/com/futurewei/alcor/dataplane/cache/PortBindingSecurityGroupRepository.java @@ -0,0 +1,82 @@ +/* +MIT License +Copyright(c) 2020 Futurewei Cloud + + Permission is hereby granted, + free of charge, to any person obtaining a copy of this software and associated documentation files(the "Software"), to deal in the Software without restriction, + including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and / or sell copies of the Software, and to permit persons + to whom the Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ +package com.futurewei.alcor.dataplane.cache; + +import com.futurewei.alcor.common.db.CacheException; +import com.futurewei.alcor.common.db.CacheFactory; +import com.futurewei.alcor.common.db.ICache; +import com.futurewei.alcor.common.stats.DurationStatistics; +import com.futurewei.alcor.web.entity.securitygroup.PortBindingSecurityGroup; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.stereotype.Repository; +import javax.annotation.PostConstruct; +import java.util.*; +import java.util.function.Function; +import java.util.stream.Collectors; + +@Repository +@ComponentScan(value="com.futurewei.alcor.common.db") +public class PortBindingSecurityGroupRepository { + private static final Logger LOG = LoggerFactory.getLogger(PortBindingSecurityGroupRepository.class); + + private ICache bindingCache; + + @Autowired + public PortBindingSecurityGroupRepository(CacheFactory cacheFactory) { + bindingCache = cacheFactory.getCache(PortBindingSecurityGroup.class); + } + + @PostConstruct + private void init() { + LOG.info("PortBindingSecurityGroupRepository init done"); + } + + @DurationStatistics + public Collection getPortBindingSecurityGroupBySecurityGroupId(String securityGroupId) throws CacheException { + Map filterParams = new HashMap<>(); + filterParams.put("securityGroupId", new String[] {securityGroupId}); + + Map portBindingSecurityGroupMap = bindingCache.getAll(filterParams); + return portBindingSecurityGroupMap.values(); + } + + @DurationStatistics + public Collection getPortBindingSecurityGroupByPortId(String portId) throws CacheException { + Map filterParams = new HashMap<>(); + filterParams.put("portId", new String[] {portId}); + + Map portBindingSecurityGroupMap = bindingCache.getAll(filterParams); + return portBindingSecurityGroupMap.values(); + } + + @DurationStatistics + public synchronized void addPortBindingSecurityGroup(List portBindingSecurityGroups) throws Exception { + Map portBindingSecurityGroupMap = portBindingSecurityGroups + .stream() + .collect(Collectors.toMap(PortBindingSecurityGroup::getId, Function.identity())); + bindingCache.putAll(portBindingSecurityGroupMap); + } + + @DurationStatistics + public synchronized void deleteSecurityGroupBinding(List portBindingSecurityGroups) throws Exception { + for (PortBindingSecurityGroup portBindingSecurityGroup: portBindingSecurityGroups) { + bindingCache.remove(portBindingSecurityGroup.getId()); + } + } +} diff --git a/services/data_plane_manager/src/main/java/com/futurewei/alcor/dataplane/cache/SecurityGroupRepository.java b/services/data_plane_manager/src/main/java/com/futurewei/alcor/dataplane/cache/SecurityGroupRepository.java new file mode 100644 index 000000000..d33075036 --- /dev/null +++ b/services/data_plane_manager/src/main/java/com/futurewei/alcor/dataplane/cache/SecurityGroupRepository.java @@ -0,0 +1,94 @@ +/* +MIT License +Copyright(c) 2020 Futurewei Cloud + + Permission is hereby granted, + free of charge, to any person obtaining a copy of this software and associated documentation files(the "Software"), to deal in the Software without restriction, + including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and / or sell copies of the Software, and to permit persons + to whom the Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ +package com.futurewei.alcor.dataplane.cache; + +import com.futurewei.alcor.common.db.CacheException; +import com.futurewei.alcor.common.db.CacheFactory; +import com.futurewei.alcor.common.db.ICache; +import com.futurewei.alcor.common.stats.DurationStatistics; +import com.futurewei.alcor.web.entity.securitygroup.SecurityGroupRule; +import com.futurewei.alcor.web.entity.securitygroup.SecurityGroupRuleBulkJson; +import com.futurewei.alcor.web.entity.securitygroup.SecurityGroupRuleJson; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Repository; +import javax.annotation.PostConstruct; +import java.util.*; +import java.util.function.Function; +import java.util.stream.Collectors; + +@Repository +public class SecurityGroupRepository { + private static final Logger LOG = LoggerFactory.getLogger(SecurityGroupRepository.class); + + private ICache securityGroupRuleCache; + + @Autowired + public SecurityGroupRepository(CacheFactory cacheFactory) { + securityGroupRuleCache = cacheFactory.getCache(SecurityGroupRule.class); + } + + @PostConstruct + private void init() { + LOG.info("SecurityGroupRepository init done"); + } + + @DurationStatistics + public synchronized void addSecurityGroupRule(SecurityGroupRuleJson securityGroupRuleJson) throws Exception { + securityGroupRuleCache.put(securityGroupRuleJson.getSecurityGroupRule().getId(), securityGroupRuleJson.getSecurityGroupRule()); + } + @DurationStatistics + public synchronized void addSecurityGroupRules(SecurityGroupRuleBulkJson securityGroupRuleBulkJson) throws Exception { + var securityGroupRules = securityGroupRuleBulkJson.getSecurityGroupRules().stream().collect(Collectors.toMap(SecurityGroupRule::getId, Function.identity())); + securityGroupRuleCache.putAll(securityGroupRules); + } + + @DurationStatistics + public synchronized void deleteSecurityGroupRules(List securityGroupIds) throws Exception { + securityGroupIds.forEach(securityGroupId -> { + try { + securityGroupRuleCache.remove(securityGroupId); + } catch (CacheException e) { + e.printStackTrace(); + } + }); + } + + @DurationStatistics + public SecurityGroupRule getSecurityGroupRule(String securityGroupRuleId) throws CacheException { + return securityGroupRuleCache.get(securityGroupRuleId); + } + + @DurationStatistics + public List getSecurityGroupRules(List securityGroupRuleIds) throws CacheException { + List securityGroupRules = new ArrayList<>(); + for (String securityGroupId : securityGroupRuleIds) { + SecurityGroupRule securityGroupRule = securityGroupRuleCache.get(securityGroupId); + securityGroupRules.add(securityGroupRule); + } + return securityGroupRules; + } + + @DurationStatistics + public Collection getSecurityGroupRules(String scurityGroupId) throws CacheException { + Map queryParams = new HashMap<>(); + Object[] value = new Object[1]; + value[0] = scurityGroupId; + queryParams.put("securityGroupId", value); + return securityGroupRuleCache.getAll(queryParams).values(); + } +} diff --git a/services/data_plane_manager/src/main/java/com/futurewei/alcor/dataplane/client/DataPlaneClient.java b/services/data_plane_manager/src/main/java/com/futurewei/alcor/dataplane/client/DataPlaneClient.java index 6e81e70d3..dff1be25b 100644 --- a/services/data_plane_manager/src/main/java/com/futurewei/alcor/dataplane/client/DataPlaneClient.java +++ b/services/data_plane_manager/src/main/java/com/futurewei/alcor/dataplane/client/DataPlaneClient.java @@ -21,6 +21,7 @@ free of charge, to any person obtaining a copy of this software and associated d import com.futurewei.alcor.dataplane.entity.UnicastGoalStateV2; import com.futurewei.alcor.schema.Goalstate.GoalState; import com.futurewei.alcor.schema.Goalstateprovisioner.GoalStateOperationReply.GoalStateOperationStatus; +import com.futurewei.alcor.schema.SecurityGroup; import org.springframework.stereotype.Component; import java.util.List; @@ -31,4 +32,5 @@ public interface DataPlaneClient { List sendGoalStates(List unicastGoalStates) throws Exception; List sendGoalStates(List unicastGoalStates, T multicastGoalState) throws Exception; + List sendGoalStates(SecurityGroup.SecurityGroupState securityGroupState) throws Exception; } diff --git a/services/data_plane_manager/src/main/java/com/futurewei/alcor/dataplane/client/grpc/DataPlaneClientImpl.java b/services/data_plane_manager/src/main/java/com/futurewei/alcor/dataplane/client/grpc/DataPlaneClientImpl.java index 5312b1723..0d65c257f 100644 --- a/services/data_plane_manager/src/main/java/com/futurewei/alcor/dataplane/client/grpc/DataPlaneClientImpl.java +++ b/services/data_plane_manager/src/main/java/com/futurewei/alcor/dataplane/client/grpc/DataPlaneClientImpl.java @@ -23,6 +23,7 @@ free of charge, to any person obtaining a copy of this software and associated d import com.futurewei.alcor.schema.Goalstate; import com.futurewei.alcor.schema.Goalstateprovisioner.GoalStateOperationReply.GoalStateOperationStatus; import com.futurewei.alcor.schema.Goalstateprovisioner.GoalStateOperationReply; +import com.futurewei.alcor.schema.SecurityGroup; import io.grpc.ManagedChannel; import io.grpc.ManagedChannelBuilder; import io.grpc.stub.StreamObserver; @@ -89,6 +90,11 @@ public List sendGoalStates( return null; } + @Override + public List sendGoalStates(SecurityGroup.SecurityGroupState securityGroupState) throws Exception { + return null; + } + private List doSendGoalStates(List unicastGoalStates) { List> futures = new ArrayList<>(unicastGoalStates.size()); diff --git a/services/data_plane_manager/src/main/java/com/futurewei/alcor/dataplane/client/grpc/DataPlaneClientImplV2.java b/services/data_plane_manager/src/main/java/com/futurewei/alcor/dataplane/client/grpc/DataPlaneClientImplV2.java index f285d03b6..59ea62fcb 100644 --- a/services/data_plane_manager/src/main/java/com/futurewei/alcor/dataplane/client/grpc/DataPlaneClientImplV2.java +++ b/services/data_plane_manager/src/main/java/com/futurewei/alcor/dataplane/client/grpc/DataPlaneClientImplV2.java @@ -164,6 +164,12 @@ public List sendGoalStates(List unicastGoalStates, M return null; } + @Override + public List sendGoalStates(SecurityGroup.SecurityGroupState securityGroupState) throws Exception { + doSendGoalStateToArionMaster(securityGroupState); + return new ArrayList<>(); + } + private GrpcChannelStub createGrpcChannelStub(String hostIp, int port) { ManagedChannel channel = ManagedChannelBuilder.forAddress(hostIp, port) .usePlaintext() @@ -251,9 +257,33 @@ public void onCompleted() { private String doSendGoalStateToArionMaster (Goalstate.GoalStateV2.Builder goalStateV2) { GrpcChannelStub channelStub = getOrCreateGrpcChannel(arionMasterServer, arionMasterPort); GoalStateProvisionerGrpc.GoalStateProvisionerStub asyncStub = channelStub.stub; - var neighborStateRequestBuilder = Goalstateprovisioner.NeighborRulesRequest.newBuilder(); - neighborStateRequestBuilder.addAllNeigborstates(goalStateV2.getNeighborStatesMap().values()); - asyncStub.pushGoalstates(neighborStateRequestBuilder.build(), new StreamObserver() { + var arionGoalStateBuilder = Goalstateprovisioner.ArionGoalStateRequest.newBuilder(); + arionGoalStateBuilder.addAllNeigborstates(goalStateV2.getNeighborStatesMap().values()); + arionGoalStateBuilder.addAllPortstates(goalStateV2.getPortStatesMap().values()); + + asyncStub.pushGoalstates(arionGoalStateBuilder.build(), new StreamObserver() { + @Override + public void onNext(Goalstateprovisioner.GoalStateOperationReply goalStateOperationReply) { + LOG.info("Get response: " + goalStateOperationReply.toString()); + } + + @Override + public void onError(Throwable throwable) { + LOG.info(throwable.getMessage()); + } + + @Override + public void onCompleted() { + + } + }); + return null; + } + + private String doSendGoalStateToArionMaster (SecurityGroup.SecurityGroupState securityGroupState) { + GrpcChannelStub channelStub = getOrCreateGrpcChannel(arionMasterServer, arionMasterPort); + GoalStateProvisionerGrpc.GoalStateProvisionerStub asyncStub = channelStub.stub; + asyncStub.pushSecurityGroupGoalState(securityGroupState, new StreamObserver() { @Override public void onNext(Goalstateprovisioner.GoalStateOperationReply goalStateOperationReply) { LOG.info("Get response: " + goalStateOperationReply.toString()); diff --git a/services/data_plane_manager/src/main/java/com/futurewei/alcor/dataplane/client/kafka/DataPlaneClientImpl.java b/services/data_plane_manager/src/main/java/com/futurewei/alcor/dataplane/client/kafka/DataPlaneClientImpl.java index dd49a0646..358f099a2 100644 --- a/services/data_plane_manager/src/main/java/com/futurewei/alcor/dataplane/client/kafka/DataPlaneClientImpl.java +++ b/services/data_plane_manager/src/main/java/com/futurewei/alcor/dataplane/client/kafka/DataPlaneClientImpl.java @@ -22,6 +22,7 @@ free of charge, to any person obtaining a copy of this software and associated d import com.futurewei.alcor.dataplane.entity.UnicastGoalStateV2; import com.futurewei.alcor.schema.Goalstate; import com.futurewei.alcor.schema.Goalstateprovisioner; +import com.futurewei.alcor.schema.SecurityGroup; import java.util.List; import java.util.Map; @@ -37,4 +38,9 @@ public List sendGoalStates(List unicastGoalStates) thr public List sendGoalStates(List unicastGoalStates, MulticastGoalState multicastGoalState) throws Exception { return null; } + + @Override + public List sendGoalStates(SecurityGroup.SecurityGroupState securityGroupState) throws Exception { + return null; + } } diff --git a/services/data_plane_manager/src/main/java/com/futurewei/alcor/dataplane/client/kafka/DataPlaneClientImplV2.java b/services/data_plane_manager/src/main/java/com/futurewei/alcor/dataplane/client/kafka/DataPlaneClientImplV2.java index 33cb09267..bcc959eb5 100644 --- a/services/data_plane_manager/src/main/java/com/futurewei/alcor/dataplane/client/kafka/DataPlaneClientImplV2.java +++ b/services/data_plane_manager/src/main/java/com/futurewei/alcor/dataplane/client/kafka/DataPlaneClientImplV2.java @@ -21,6 +21,7 @@ import com.futurewei.alcor.dataplane.client.DataPlaneClient; import com.futurewei.alcor.dataplane.entity.MulticastGoalStateV2; import com.futurewei.alcor.dataplane.entity.UnicastGoalStateV2; +import com.futurewei.alcor.schema.SecurityGroup; import java.util.List; @@ -34,4 +35,9 @@ public List sendGoalStates(List unicastGoalStates) t public List sendGoalStates(List unicastGoalStates, MulticastGoalStateV2 multicastGoalState) throws Exception { return null; } + + @Override + public List sendGoalStates(SecurityGroup.SecurityGroupState securityGroupState) throws Exception { + return null; + } } diff --git a/services/data_plane_manager/src/main/java/com/futurewei/alcor/dataplane/client/pulsar/group_node_mode/DataPlaneClientImpl.java b/services/data_plane_manager/src/main/java/com/futurewei/alcor/dataplane/client/pulsar/group_node_mode/DataPlaneClientImpl.java index fa762a124..f65579c26 100644 --- a/services/data_plane_manager/src/main/java/com/futurewei/alcor/dataplane/client/pulsar/group_node_mode/DataPlaneClientImpl.java +++ b/services/data_plane_manager/src/main/java/com/futurewei/alcor/dataplane/client/pulsar/group_node_mode/DataPlaneClientImpl.java @@ -21,6 +21,7 @@ free of charge, to any person obtaining a copy of this software and associated d import com.futurewei.alcor.dataplane.entity.UnicastGoalState; import com.futurewei.alcor.dataplane.exception.GroupTopicNotFound; import com.futurewei.alcor.dataplane.exception.MulticastTopicNotFound; +import com.futurewei.alcor.schema.SecurityGroup; import com.futurewei.alcor.web.entity.dataplane.MulticastGoalStateByte; import com.futurewei.alcor.web.entity.dataplane.UnicastGoalStateByte; import org.apache.pulsar.client.api.Producer; @@ -152,4 +153,9 @@ public List sendGoalStates(List unicastGoalStates, Mul return failedHosts; } + + @Override + public List sendGoalStates(SecurityGroup.SecurityGroupState securityGroupState) throws Exception { + return null; + } } diff --git a/services/data_plane_manager/src/main/java/com/futurewei/alcor/dataplane/client/pulsar/group_node_mode/DataPlaneClientImplV2.java b/services/data_plane_manager/src/main/java/com/futurewei/alcor/dataplane/client/pulsar/group_node_mode/DataPlaneClientImplV2.java index 946788659..700eab0c8 100644 --- a/services/data_plane_manager/src/main/java/com/futurewei/alcor/dataplane/client/pulsar/group_node_mode/DataPlaneClientImplV2.java +++ b/services/data_plane_manager/src/main/java/com/futurewei/alcor/dataplane/client/pulsar/group_node_mode/DataPlaneClientImplV2.java @@ -20,6 +20,7 @@ free of charge, to any person obtaining a copy of this software and associated d import com.futurewei.alcor.dataplane.entity.*; import com.futurewei.alcor.dataplane.exception.GroupTopicNotFound; import com.futurewei.alcor.dataplane.exception.MulticastTopicNotFound; +import com.futurewei.alcor.schema.SecurityGroup; import com.futurewei.alcor.web.entity.dataplane.MulticastGoalStateByte; import com.futurewei.alcor.web.entity.dataplane.UnicastGoalStateByte; import org.apache.pulsar.client.api.Producer; @@ -159,4 +160,9 @@ public List sendGoalStates(List unicastGoalStates, M return failedHosts; } + + @Override + public List sendGoalStates(SecurityGroup.SecurityGroupState securityGroupState) throws Exception { + return null; + } } diff --git a/services/data_plane_manager/src/main/java/com/futurewei/alcor/dataplane/client/pulsar/vpc_mode/DataPlaneClientImpl.java b/services/data_plane_manager/src/main/java/com/futurewei/alcor/dataplane/client/pulsar/vpc_mode/DataPlaneClientImpl.java index 99c493d92..b577076da 100644 --- a/services/data_plane_manager/src/main/java/com/futurewei/alcor/dataplane/client/pulsar/vpc_mode/DataPlaneClientImpl.java +++ b/services/data_plane_manager/src/main/java/com/futurewei/alcor/dataplane/client/pulsar/vpc_mode/DataPlaneClientImpl.java @@ -19,6 +19,7 @@ free of charge, to any person obtaining a copy of this software and associated d import com.futurewei.alcor.dataplane.client.DataPlaneClient; import com.futurewei.alcor.dataplane.entity.MulticastGoalState; import com.futurewei.alcor.dataplane.entity.UnicastGoalState; +import com.futurewei.alcor.schema.SecurityGroup; import com.futurewei.alcor.web.entity.dataplane.MulticastGoalStateByte; import com.futurewei.alcor.web.entity.dataplane.UnicastGoalStateByte; import com.futurewei.alcor.web.entity.topic.VpcTopicInfo; @@ -129,4 +130,9 @@ public List sendGoalStates(List unicastGoalStates, Mul return failedHosts; } + + @Override + public List sendGoalStates(SecurityGroup.SecurityGroupState securityGroupState) throws Exception { + return null; + } } \ No newline at end of file diff --git a/services/data_plane_manager/src/main/java/com/futurewei/alcor/dataplane/client/pulsar/vpc_mode/DataPlaneClientImplV2.java b/services/data_plane_manager/src/main/java/com/futurewei/alcor/dataplane/client/pulsar/vpc_mode/DataPlaneClientImplV2.java index a287f3e33..a3f7fbe4a 100644 --- a/services/data_plane_manager/src/main/java/com/futurewei/alcor/dataplane/client/pulsar/vpc_mode/DataPlaneClientImplV2.java +++ b/services/data_plane_manager/src/main/java/com/futurewei/alcor/dataplane/client/pulsar/vpc_mode/DataPlaneClientImplV2.java @@ -21,6 +21,7 @@ import com.futurewei.alcor.dataplane.client.DataPlaneClient; import com.futurewei.alcor.dataplane.entity.MulticastGoalStateV2; import com.futurewei.alcor.dataplane.entity.UnicastGoalStateV2; +import com.futurewei.alcor.schema.SecurityGroup; import com.futurewei.alcor.schema.Subscribeinfoprovisioner.NodeSubscribeInfo; import com.futurewei.alcor.web.entity.dataplane.MulticastGoalStateByte; import com.futurewei.alcor.web.entity.topic.VpcTopicInfo; @@ -137,4 +138,9 @@ public List sendGoalStates(List unicastGoalStates, M return failedHosts; } + + @Override + public List sendGoalStates(SecurityGroup.SecurityGroupState securityGroupState) throws Exception { + return null; + } } diff --git a/services/data_plane_manager/src/main/java/com/futurewei/alcor/dataplane/controller/SecurityGroupController.java b/services/data_plane_manager/src/main/java/com/futurewei/alcor/dataplane/controller/SecurityGroupController.java new file mode 100644 index 000000000..df3669675 --- /dev/null +++ b/services/data_plane_manager/src/main/java/com/futurewei/alcor/dataplane/controller/SecurityGroupController.java @@ -0,0 +1,87 @@ +/* +MIT License +Copyright(c) 2020 Futurewei Cloud + + Permission is hereby granted, + free of charge, to any person obtaining a copy of this software and associated documentation files(the "Software"), to deal in the Software without restriction, + including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and / or sell copies of the Software, and to permit persons + to whom the Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ +package com.futurewei.alcor.dataplane.controller; + +import com.futurewei.alcor.common.exception.ParameterNullOrEmptyException; +import com.futurewei.alcor.common.stats.DurationStatistics; +import com.futurewei.alcor.dataplane.entity.ArionWing; +import com.futurewei.alcor.dataplane.service.SecurityGroupService; +import com.futurewei.alcor.dataplane.service.impl.ArionWingService; +import com.futurewei.alcor.web.entity.gateway.ArionWingInfo; +import com.futurewei.alcor.web.entity.route.RouteTable; +import com.futurewei.alcor.web.entity.route.RouteTableWebJson; +import com.futurewei.alcor.web.entity.securitygroup.SecurityGroupRule; +import com.futurewei.alcor.web.entity.securitygroup.SecurityGroupRuleBulkJson; +import com.futurewei.alcor.web.entity.securitygroup.SecurityGroupRuleJson; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.http.HttpStatus; +import org.springframework.web.bind.annotation.*; + +import javax.ws.rs.QueryParam; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +import static org.springframework.web.bind.annotation.RequestMethod.GET; + + +@Slf4j +@RestController +@ComponentScan(value = "com.futurewei.alcor.common.stats") +public class SecurityGroupController { + + @Autowired + private SecurityGroupService securityGroupService; + + @PostMapping({"/securitygrouprules"}) + @ResponseStatus(HttpStatus.CREATED) + @DurationStatistics + public String createSecurityGroupRule(@RequestBody SecurityGroupRuleJson securityGroupRuleJson) throws Exception { + securityGroupService.updateSecurityGroupRule(securityGroupRuleJson); + return "Success created"; + } + + @PostMapping({"/securitygrouprules/bulk"}) + @ResponseStatus(HttpStatus.CREATED) + @DurationStatistics + public String createSecurityGroupRules(@RequestBody SecurityGroupRuleBulkJson securityGroupRuleBulkJson) throws Exception { + securityGroupService.updateSecurityGroupRules(securityGroupRuleBulkJson); + return "Success created"; + } + + @PutMapping({"/securitygrouprules"}) + @DurationStatistics + public String updateSecurityGroupRules(@PathVariable SecurityGroupRuleJson securityGroupRuleJson) throws Exception { + securityGroupService.updateSecurityGroupRule(securityGroupRuleJson); + return "Success updated"; + } + + @DeleteMapping({"/securitygrouprules/{resource_id}"}) + @DurationStatistics + public void deleteSecurityGroupRule(@RequestParam String resource_id) throws Exception { + securityGroupService.deleteSecurityGroupRules(new ArrayList<>(){{add(resource_id);}}); + } + + @RequestMapping( + method = GET, + value = {"/securitygrouprules/{security_group_id}"}) + @DurationStatistics + public Collection getSecurityGroupRules(@PathVariable String security_group_id) throws Exception { + return securityGroupService.getSecurityGroupRules(security_group_id); + } +} diff --git a/services/data_plane_manager/src/main/java/com/futurewei/alcor/dataplane/service/SecurityGroupService.java b/services/data_plane_manager/src/main/java/com/futurewei/alcor/dataplane/service/SecurityGroupService.java new file mode 100644 index 000000000..7610b3f5b --- /dev/null +++ b/services/data_plane_manager/src/main/java/com/futurewei/alcor/dataplane/service/SecurityGroupService.java @@ -0,0 +1,30 @@ +package com.futurewei.alcor.dataplane.service; + +import com.futurewei.alcor.common.db.CacheException; +import com.futurewei.alcor.web.entity.securitygroup.PortBindingSecurityGroup; +import com.futurewei.alcor.web.entity.securitygroup.SecurityGroupRule; +import com.futurewei.alcor.web.entity.securitygroup.SecurityGroupRuleBulkJson; +import com.futurewei.alcor.web.entity.securitygroup.SecurityGroupRuleJson; + +import java.util.Collection; +import java.util.List; + +public interface SecurityGroupService { + void updateSecurityGroupRule(SecurityGroupRuleJson securityGroupRuleJson) throws Exception; + + void updateSecurityGroupRules(SecurityGroupRuleBulkJson securityGroupRuleBulkJson) throws Exception; + + void deleteSecurityGroupRules(List securityGroupIds) throws Exception; + + List getSecurityGroupRules(List securityGroupRuleIds) throws CacheException; + + Collection getSecurityGroupRules(String securityGroupId) throws CacheException; + + void addPortBindingSecurityGroup(List portBindingSecurityGroups) throws Exception; + + void deletePortBindingSecurityGroup (List portBindingSecurityGroups) throws Exception; + + Collection getPortBindingSecurityGroupBySecurityGroupId(String securityGroupId) throws CacheException; + + Collection getPortBindingSecurityGroupByPortId(String portId) throws CacheException; +} diff --git a/services/data_plane_manager/src/main/java/com/futurewei/alcor/dataplane/service/impl/DpmServiceImplV2.java b/services/data_plane_manager/src/main/java/com/futurewei/alcor/dataplane/service/impl/DpmServiceImplV2.java index c46a42098..2e0b2a8a2 100644 --- a/services/data_plane_manager/src/main/java/com/futurewei/alcor/dataplane/service/impl/DpmServiceImplV2.java +++ b/services/data_plane_manager/src/main/java/com/futurewei/alcor/dataplane/service/impl/DpmServiceImplV2.java @@ -30,6 +30,7 @@ free of charge, to any person obtaining a copy of this software and associated d import com.futurewei.alcor.web.entity.port.PortHostInfo; import com.futurewei.alcor.web.entity.route.InternalRouterInfo; import com.futurewei.alcor.web.entity.route.InternalSubnetRoutingTable; +import com.futurewei.alcor.web.entity.securitygroup.SecurityGroupRuleJson; import com.futurewei.alcor.web.entity.subnet.InternalSubnetPorts; import com.futurewei.alcor.web.restclient.DataPlaneManagerRestClient; import org.slf4j.Logger; @@ -293,6 +294,12 @@ private List processSecurityGroupConfiguration(NetworkConfiguration netw return new ArrayList<>(); } + private List processSecurityGroupConfiguration(SecurityGroupRuleJson securityGroupRuleJson) throws Exception { + + return new ArrayList<>(); + } + + /** * This method get the subnet routing configuration from the NetworkConfiguration, * then find the host information of all the virtual machines under the subnet from diff --git a/services/data_plane_manager/src/main/java/com/futurewei/alcor/dataplane/service/impl/SecurityGroupService.java b/services/data_plane_manager/src/main/java/com/futurewei/alcor/dataplane/service/impl/SecurityGroupService.java index 61483757f..1ef361e2c 100644 --- a/services/data_plane_manager/src/main/java/com/futurewei/alcor/dataplane/service/impl/SecurityGroupService.java +++ b/services/data_plane_manager/src/main/java/com/futurewei/alcor/dataplane/service/impl/SecurityGroupService.java @@ -15,6 +15,7 @@ free of charge, to any person obtaining a copy of this software and associated d */ package com.futurewei.alcor.dataplane.service.impl; +import com.futurewei.alcor.dataplane.cache.PortBindingSecurityGroupRepository; import com.futurewei.alcor.dataplane.entity.UnicastGoalState; import com.futurewei.alcor.dataplane.entity.UnicastGoalStateV2; import com.futurewei.alcor.dataplane.exception.*; @@ -25,8 +26,10 @@ free of charge, to any person obtaining a copy of this software and associated d import com.futurewei.alcor.schema.Port; import com.futurewei.alcor.schema.SecurityGroup.SecurityGroupConfiguration.Direction; import com.futurewei.alcor.web.entity.dataplane.v2.NetworkConfiguration; +import com.futurewei.alcor.web.entity.securitygroup.PortBindingSecurityGroup; import com.futurewei.alcor.web.entity.securitygroup.SecurityGroup; import com.futurewei.alcor.web.entity.securitygroup.SecurityGroupRule; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.util.StringUtils; @@ -38,6 +41,11 @@ free of charge, to any person obtaining a copy of this software and associated d @Service public class SecurityGroupService extends ResourceService { + + + @Autowired + private PortBindingSecurityGroupRepository portBindingSecurityGroupRepository; + private SecurityGroup getSecurityGroup(NetworkConfiguration networkConfig, String securityGroupId) throws Exception { SecurityGroup result = null; for (SecurityGroup securityGroup: networkConfig.getSecurityGroups()) { @@ -183,6 +191,12 @@ public void buildSecurityGroupStates(NetworkConfiguration networkConfig, Unicast .map(Port.PortConfiguration.SecurityGroupId::getId) .collect(Collectors.toList())); } + var portBindingSecurityGroupList = securityGroupIdList.stream().map(securityGroupId -> { + PortBindingSecurityGroup portBindingSecurityGroup = new PortBindingSecurityGroup(portState.getConfiguration().getId(), securityGroupId.getId()); + portBindingSecurityGroup.setId(portState.getConfiguration().getId() + securityGroupId.getId()); + return portBindingSecurityGroup; + }).collect(Collectors.toList()); + portBindingSecurityGroupRepository.addPortBindingSecurityGroup(portBindingSecurityGroupList); } for (String securityGroupId: securityGroupIds) { diff --git a/services/data_plane_manager/src/main/java/com/futurewei/alcor/dataplane/service/impl/SecurityGroupServiceImpl.java b/services/data_plane_manager/src/main/java/com/futurewei/alcor/dataplane/service/impl/SecurityGroupServiceImpl.java new file mode 100644 index 000000000..ce66f07e6 --- /dev/null +++ b/services/data_plane_manager/src/main/java/com/futurewei/alcor/dataplane/service/impl/SecurityGroupServiceImpl.java @@ -0,0 +1,190 @@ +package com.futurewei.alcor.dataplane.service.impl; + +import com.futurewei.alcor.common.db.CacheException; +import com.futurewei.alcor.dataplane.cache.PortBindingSecurityGroupRepository; +import com.futurewei.alcor.dataplane.cache.SecurityGroupRepository; +import com.futurewei.alcor.dataplane.client.DataPlaneClient; +import com.futurewei.alcor.dataplane.entity.MulticastGoalStateV2; +import com.futurewei.alcor.dataplane.entity.UnicastGoalStateV2; +import com.futurewei.alcor.dataplane.exception.SecurityGroupDirectionInvalid; +import com.futurewei.alcor.dataplane.exception.SecurityGroupEtherTypeInvalid; +import com.futurewei.alcor.dataplane.exception.SecurityGroupProtocolInvalid; +import com.futurewei.alcor.dataplane.service.SecurityGroupService; +import com.futurewei.alcor.schema.Common; +import com.futurewei.alcor.schema.SecurityGroup; +import com.futurewei.alcor.web.entity.securitygroup.PortBindingSecurityGroup; +import com.futurewei.alcor.web.entity.securitygroup.SecurityGroupRule; +import com.futurewei.alcor.web.entity.securitygroup.SecurityGroupRuleBulkJson; +import com.futurewei.alcor.web.entity.securitygroup.SecurityGroupRuleJson; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.util.StringUtils; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.Map; +import java.util.function.Function; +import java.util.stream.Collectors; + +@Service +public class SecurityGroupServiceImpl implements SecurityGroupService { + private static final Logger LOG = LoggerFactory.getLogger(SecurityGroupServiceImpl.class); + + @Autowired + private PortBindingSecurityGroupRepository portBindingSecurityGroupRepository; + + @Autowired + private SecurityGroupRepository securityGroupRepository; + + @Autowired + private DataPlaneClient grpcDataPlaneClient; + + + private SecurityGroup.SecurityGroupConfiguration.Direction transformDirection(String direction) throws Exception { + if (StringUtils.isEmpty(direction)) { + throw new SecurityGroupDirectionInvalid(); + } + + switch (direction) { + case "ingress": + return SecurityGroup.SecurityGroupConfiguration.Direction.INGRESS; + case "egress": + return SecurityGroup.SecurityGroupConfiguration.Direction.EGRESS; + } + + throw new SecurityGroupDirectionInvalid(); + } + + private Common.EtherType transformEtherType(String etherType) throws Exception { + if (StringUtils.isEmpty(etherType)) { + return Common.EtherType.IPV4; + } + + switch (etherType) { + case "IPv4": + return Common.EtherType.IPV4; + case "IPv6": + return Common.EtherType.IPV6; + } + + throw new SecurityGroupEtherTypeInvalid(); + } + + private Common.Protocol transformProtocol(String protocol) throws Exception { + if (StringUtils.isEmpty(protocol)) { + throw new SecurityGroupProtocolInvalid(); + } + + switch (protocol) { + case "tcp": + return Common.Protocol.TCP; + case "udp": + return Common.Protocol.UDP; + case "icmp": + return Common.Protocol.ICMP; + case "http": + return Common.Protocol.HTTP; + } + + throw new SecurityGroupProtocolInvalid(); + } + + public SecurityGroup.SecurityGroupConfiguration.SecurityGroupRule buildSecurityGroupGoalState(SecurityGroupRule securityGroupRule) throws Exception { + SecurityGroup.SecurityGroupConfiguration.SecurityGroupRule.Builder securityGroupRuleBuilder = SecurityGroup.SecurityGroupConfiguration.SecurityGroupRule.newBuilder(); + + securityGroupRuleBuilder.setSecurityGroupId(securityGroupRule.getId()); + securityGroupRuleBuilder.setOperationType(Common.OperationType.CREATE); + securityGroupRuleBuilder.setId(securityGroupRule.getId()); + securityGroupRuleBuilder.setDirection(transformDirection(securityGroupRule.getDirection())); + securityGroupRuleBuilder.setEthertype(transformEtherType(securityGroupRule.getEtherType())); + + if (securityGroupRule.getProtocol() != null) { + securityGroupRuleBuilder.setProtocol(transformProtocol(securityGroupRule.getProtocol())); + } + + if (securityGroupRule.getPortRangeMin() != null) { + securityGroupRuleBuilder.setPortRangeMin(securityGroupRule.getPortRangeMin()); + } + + if (securityGroupRule.getPortRangeMax() != null) { + securityGroupRuleBuilder.setPortRangeMax(securityGroupRule.getPortRangeMax()); + } + + if (securityGroupRule.getRemoteIpPrefix() != null) { + securityGroupRuleBuilder.setRemoteIpPrefix(securityGroupRule.getRemoteIpPrefix()); + } + + if (securityGroupRule.getRemoteGroupId() != null) { + securityGroupRuleBuilder.setRemoteGroupId(securityGroupRule.getRemoteGroupId()); + } + return securityGroupRuleBuilder.build(); + } + + + @Override + public void updateSecurityGroupRule(SecurityGroupRuleJson securityGroupRuleJson) throws Exception { + SecurityGroup.SecurityGroupState.Builder securityGroupStateBuilder = SecurityGroup.SecurityGroupState.newBuilder(); + SecurityGroup.SecurityGroupConfiguration.Builder securityGroupConfigurationBuilder = SecurityGroup.SecurityGroupConfiguration.newBuilder(); + List securityGroupRules = new ArrayList<>(); + securityGroupRules.add(buildSecurityGroupGoalState(securityGroupRuleJson.getSecurityGroupRule())); + securityGroupConfigurationBuilder.addAllSecurityGroupRules(securityGroupRules); + securityGroupStateBuilder.setConfiguration(securityGroupConfigurationBuilder); + + grpcDataPlaneClient.sendGoalStates(securityGroupStateBuilder.build()); + securityGroupRepository.addSecurityGroupRule(securityGroupRuleJson); + + } + + @Override + public void updateSecurityGroupRules(SecurityGroupRuleBulkJson securityGroupRuleBulkJson) throws Exception { + SecurityGroup.SecurityGroupState.Builder securityGroupStateBuilder = SecurityGroup.SecurityGroupState.newBuilder(); + SecurityGroup.SecurityGroupConfiguration.Builder securityGroupConfigurationBuilder = SecurityGroup.SecurityGroupConfiguration.newBuilder(); + List securityGroupRules = new ArrayList<>(); + for (var securityGroupRule : securityGroupRuleBulkJson.getSecurityGroupRules()) { + securityGroupRules.add(buildSecurityGroupGoalState(securityGroupRule)); + } + securityGroupConfigurationBuilder.addAllSecurityGroupRules(securityGroupRules); + securityGroupStateBuilder.setConfiguration(securityGroupConfigurationBuilder); + + grpcDataPlaneClient.sendGoalStates(securityGroupStateBuilder.build()); + securityGroupRepository.addSecurityGroupRules(securityGroupRuleBulkJson); + } + + @Override + public void deleteSecurityGroupRules(List securityGroupIds) throws Exception { + securityGroupRepository.deleteSecurityGroupRules(securityGroupIds); + } + + @Override + public List getSecurityGroupRules(List securityGroupRuleIds) throws CacheException { + return securityGroupRepository.getSecurityGroupRules(securityGroupRuleIds); + } + + @Override + public Collection getSecurityGroupRules(String securityGroupId) throws CacheException { + return securityGroupRepository.getSecurityGroupRules(securityGroupId); + } + + @Override + public void addPortBindingSecurityGroup(List portBindingSecurityGroups) throws Exception { + portBindingSecurityGroupRepository.addPortBindingSecurityGroup(portBindingSecurityGroups); + } + + @Override + public void deletePortBindingSecurityGroup(List portBindingSecurityGroups) throws Exception { + portBindingSecurityGroupRepository.deleteSecurityGroupBinding(portBindingSecurityGroups); + } + + @Override + public Collection getPortBindingSecurityGroupBySecurityGroupId(String securityGroupId) throws CacheException { + return portBindingSecurityGroupRepository.getPortBindingSecurityGroupBySecurityGroupId(securityGroupId); + } + + @Override + public Collection getPortBindingSecurityGroupByPortId(String portId) throws CacheException { + return portBindingSecurityGroupRepository.getPortBindingSecurityGroupByPortId(portId); + } +} diff --git a/services/port_manager/src/main/java/com/futurewei/alcor/portmanager/processor/DataPlaneProcessor.java b/services/port_manager/src/main/java/com/futurewei/alcor/portmanager/processor/DataPlaneProcessor.java index 21b69198d..03be4f4d6 100644 --- a/services/port_manager/src/main/java/com/futurewei/alcor/portmanager/processor/DataPlaneProcessor.java +++ b/services/port_manager/src/main/java/com/futurewei/alcor/portmanager/processor/DataPlaneProcessor.java @@ -16,6 +16,7 @@ free of charge, to any person obtaining a copy of this software and associated d package com.futurewei.alcor.portmanager.processor; import com.futurewei.alcor.common.enumClass.StatusEnum; +import com.futurewei.alcor.common.stats.DurationStatistics; import com.futurewei.alcor.common.utils.CommonUtil; import com.futurewei.alcor.common.utils.SpringContextUtil; import com.futurewei.alcor.portmanager.exception.GetNodeInfoException; @@ -34,6 +35,7 @@ free of charge, to any person obtaining a copy of this software and associated d import com.futurewei.alcor.web.entity.route.InternalRouterInfo; import com.futurewei.alcor.web.entity.subnet.SubnetEntity; import com.futurewei.alcor.web.entity.vpc.VpcEntity; +import lombok.Data; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -307,6 +309,7 @@ private void createNetworkConfig(PortContext context, NetworkConfiguration netwo } } + @DurationStatistics private void updateNetworkConfig(PortContext context, NetworkConfiguration networkConfig) throws Exception { PortService portService = SpringContextUtil.getBean(PortService.class); if (networkConfig != null) { diff --git a/services/pseudo_controller/src/main/java/com/futurewei/alcor/pseudo_controller/ncm_test/ncm_test.java b/services/pseudo_controller/src/main/java/com/futurewei/alcor/pseudo_controller/ncm_test/ncm_test.java index fe5f23902..935db6d8a 100644 --- a/services/pseudo_controller/src/main/java/com/futurewei/alcor/pseudo_controller/ncm_test/ncm_test.java +++ b/services/pseudo_controller/src/main/java/com/futurewei/alcor/pseudo_controller/ncm_test/ncm_test.java @@ -242,7 +242,7 @@ public void run_test_against_ncm() { ); // a new Goalstate and its builder for Arion master; should have only neigbhor states. - Goalstateprovisioner.NeighborRulesRequest.Builder arion_neighbor_rule_request_builder = Goalstateprovisioner.NeighborRulesRequest.newBuilder(); + Goalstateprovisioner.ArionGoalStateRequest.Builder arion_neighbor_rule_request_builder = Goalstateprovisioner.ArionGoalStateRequest.newBuilder(); arion_neighbor_rule_request_builder.setFormatVersion(1); arion_neighbor_rule_request_builder.setRequestId("arion_routing_rule-" + (System.currentTimeMillis() / 1000L)); @@ -458,7 +458,7 @@ public void run_test_against_ncm() { } // build the GroutingRuleRequest, to be sent to Arion Master - Goalstateprovisioner.NeighborRulesRequest arion_neighbor_state_request = arion_neighbor_rule_request_builder.build(); + Goalstateprovisioner.ArionGoalStateRequest arion_neighbor_state_request = arion_neighbor_rule_request_builder.build(); compute_node_ips.forEach(ip -> { diff --git a/services/security_group_manager/pom.xml b/services/security_group_manager/pom.xml index 6ad41ec06..5ff914b08 100644 --- a/services/security_group_manager/pom.xml +++ b/services/security_group_manager/pom.xml @@ -107,6 +107,11 @@ Copyright(c) 2020 Futurewei Cloud 0.1.0-SNAPSHOT compile + + org.asynchttpclient + async-http-client + 2.12.3 + diff --git a/services/security_group_manager/src/main/java/com/futurewei/alcor/securitygroup/service/implement/SecurityGroupRuleServiceImpl.java b/services/security_group_manager/src/main/java/com/futurewei/alcor/securitygroup/service/implement/SecurityGroupRuleServiceImpl.java index b35508991..e553ced54 100644 --- a/services/security_group_manager/src/main/java/com/futurewei/alcor/securitygroup/service/implement/SecurityGroupRuleServiceImpl.java +++ b/services/security_group_manager/src/main/java/com/futurewei/alcor/securitygroup/service/implement/SecurityGroupRuleServiceImpl.java @@ -15,6 +15,7 @@ free of charge, to any person obtaining a copy of this software and associated d */ package com.futurewei.alcor.securitygroup.service.implement; +import com.fasterxml.jackson.databind.ObjectMapper; import com.futurewei.alcor.common.stats.DurationStatistics; import com.futurewei.alcor.securitygroup.exception.RemoteSecurityGroupNotFound; import com.futurewei.alcor.securitygroup.exception.SecurityGroupNotFound; @@ -22,15 +23,19 @@ free of charge, to any person obtaining a copy of this software and associated d import com.futurewei.alcor.securitygroup.repo.SecurityGroupRepository; import com.futurewei.alcor.securitygroup.service.SecurityGroupRuleService; import com.futurewei.alcor.web.entity.securitygroup.*; +import org.asynchttpclient.*; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; +import javax.servlet.http.HttpServletResponse; import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.UUID; +import java.util.concurrent.Executors; @Service public class SecurityGroupRuleServiceImpl implements SecurityGroupRuleService { @@ -39,6 +44,14 @@ public class SecurityGroupRuleServiceImpl implements SecurityGroupRuleService { @Autowired SecurityGroupRepository securityGroupRepository; + @Autowired + ObjectMapper objectMapper; + + @Value("${microservices.dataplane.service.url:#{\"\"}}") + private String dataplaneManagerUrl; + + + @Override @DurationStatistics public SecurityGroupRuleJson createSecurityGroupRule(SecurityGroupRuleJson securityGroupRuleJson) throws Exception { @@ -61,8 +74,24 @@ public SecurityGroupRuleJson createSecurityGroupRule(SecurityGroupRuleJson secur securityGroupRule.setId(UUID.randomUUID().toString()); } - securityGroupRepository.addSecurityGroupRule(securityGroup, securityGroupRule); + AsyncHttpClient client = Dsl.asyncHttpClient(); + var request = Dsl.post(dataplaneManagerUrl).setBody(objectMapper.writeValueAsString(securityGroupRuleJson)).setHeader("Content-Type", "application/json"); + + ListenableFuture listenableFuture = client + .executeRequest(request); + listenableFuture.addListener(() -> { + Response response = null; + try { + response = listenableFuture.get(); + if (response.getStatusCode() == HttpServletResponse.SC_CREATED) { + securityGroupRepository.addSecurityGroupRule(securityGroup, securityGroupRule); + } + + } catch (Exception e) { + e.printStackTrace(); + } + }, Executors.newCachedThreadPool()); LOG.info("Create security group rule success, securityGroupRuleJson: {}", securityGroupRuleJson); return securityGroupRuleJson; @@ -86,7 +115,24 @@ public SecurityGroupRuleBulkJson createSecurityGroupRuleBulk(SecurityGroupRuleBu } } - securityGroupRepository.addSecurityGroupRuleBulk(securityGroupRules); + AsyncHttpClient client = Dsl.asyncHttpClient(); + + var request = Dsl.post(dataplaneManagerUrl).setBody(objectMapper.writeValueAsString(securityGroupRuleBulkJson)).setHeader("Content-Type", "application/json"); + + ListenableFuture listenableFuture = client + .executeRequest(request); + listenableFuture.addListener(() -> { + Response response = null; + try { + response = listenableFuture.get(); + if (response.getStatusCode() == HttpServletResponse.SC_CREATED) { + securityGroupRepository.addSecurityGroupRuleBulk(securityGroupRules); + } + + } catch (Exception e) { + e.printStackTrace(); + } + }, Executors.newCachedThreadPool()); LOG.info("Create security group rule bulk success, securityGroupRuleBulkJson: {}", securityGroupRuleBulkJson); @@ -107,7 +153,26 @@ public void deleteSecurityGroupRule(String securityGroupRuleId) throws Exception throw new SecurityGroupRuleNotFound(); } - securityGroupRepository.deleteSecurityGroupRule(securityGroupRule); + AsyncHttpClient client = Dsl.asyncHttpClient(); + Param param = new Param("resource_id", securityGroupRuleId); + List params = new ArrayList<>(); + params.add(param); + var request = Dsl.delete(dataplaneManagerUrl).setQueryParams(params).setHeader("Content-Type", "application/json"); + + ListenableFuture listenableFuture = client + .executeRequest(request); + listenableFuture.addListener(() -> { + Response response = null; + try { + response = listenableFuture.get(); + if (response.getStatusCode() == HttpServletResponse.SC_CREATED) { + securityGroupRepository.deleteSecurityGroupRule(securityGroupRule); + } + + } catch (Exception e) { + e.printStackTrace(); + } + }, Executors.newCachedThreadPool()); LOG.info("Delete security group rule success, securityGroupRuleId: {}", securityGroupRuleId); } diff --git a/services/security_group_manager/src/main/java/com/futurewei/alcor/securitygroup/service/implement/SecurityGroupServiceImpl.java b/services/security_group_manager/src/main/java/com/futurewei/alcor/securitygroup/service/implement/SecurityGroupServiceImpl.java index 1d527a93b..f7c944b15 100644 --- a/services/security_group_manager/src/main/java/com/futurewei/alcor/securitygroup/service/implement/SecurityGroupServiceImpl.java +++ b/services/security_group_manager/src/main/java/com/futurewei/alcor/securitygroup/service/implement/SecurityGroupServiceImpl.java @@ -15,6 +15,8 @@ free of charge, to any person obtaining a copy of this software and associated d */ package com.futurewei.alcor.securitygroup.service.implement; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; import com.futurewei.alcor.common.stats.DurationStatistics; import com.futurewei.alcor.securitygroup.exception.*; import com.futurewei.alcor.securitygroup.repo.PortBindingSecurityGroupRepository; @@ -23,12 +25,19 @@ free of charge, to any person obtaining a copy of this software and associated d import com.futurewei.alcor.securitygroup.utils.TimeUtil; import com.futurewei.alcor.web.entity.securitygroup.PortBindingSecurityGroupsJson; import com.futurewei.alcor.web.entity.securitygroup.*; +import org.asynchttpclient.AsyncHttpClient; +import org.asynchttpclient.Dsl; +import org.asynchttpclient.ListenableFuture; +import org.asynchttpclient.Response; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; +import javax.servlet.http.HttpServletResponse; import java.util.*; +import java.util.concurrent.Executors; @Service public class SecurityGroupServiceImpl implements SecurityGroupService { @@ -40,11 +49,17 @@ public class SecurityGroupServiceImpl implements SecurityGroupService { @Autowired private PortBindingSecurityGroupRepository portBindingSecurityGroupRepository; + @Autowired + ObjectMapper objectMapper; + + @Value("${microservices.dataplane.service.url:#{\"\"}}") + private String dataplaneManagerUrl; + private boolean isDefaultSecurityGroup(SecurityGroup securityGroup) { return "default".equals(securityGroup.getName()); } - private void createDefaultSecurityGroupRules(SecurityGroup securityGroup, SecurityGroupRule.Direction direction) { + private void createDefaultSecurityGroupRules(SecurityGroup securityGroup, SecurityGroupRule.Direction direction) throws JsonProcessingException { List securityGroupRules = new ArrayList<>(); List etherTypes = Arrays.asList(SecurityGroupRule.EtherType.IPV4, SecurityGroupRule.EtherType.IPV6); @@ -60,7 +75,28 @@ private void createDefaultSecurityGroupRules(SecurityGroup securityGroup, Securi securityGroupRules.add(securityGroupRule); } - securityGroup.setSecurityGroupRules(securityGroupRules); + SecurityGroupRuleBulkJson securityGroupRuleJson = new SecurityGroupRuleBulkJson(securityGroupRules); + + AsyncHttpClient client = Dsl.asyncHttpClient(); + + var request = Dsl.post(dataplaneManagerUrl).setBody(objectMapper.writeValueAsString(securityGroupRuleJson)).setHeader("Content-Type", "application/json"); + + ListenableFuture listenableFuture = client + .executeRequest(request); + listenableFuture.addListener(() -> { + Response response = null; + try { + response = listenableFuture.get(); + if (response.getStatusCode() == HttpServletResponse.SC_CREATED) { + securityGroup.getSecurityGroupRules().addAll(securityGroupRules); + } + + } catch (Exception e) { + e.printStackTrace(); + } + }, Executors.newCachedThreadPool()); + + } private void createDefaultSecurityGroup(String tenantId, String projectId, String description) throws Exception { @@ -70,6 +106,7 @@ private void createDefaultSecurityGroup(String tenantId, String projectId, Strin defaultSecurityGroup.setProjectId(projectId); defaultSecurityGroup.setDescription(description); defaultSecurityGroup.setName("default"); + defaultSecurityGroup.setSecurityGroupRules(new ArrayList<>()); //Create default security group rules createDefaultSecurityGroupRules(defaultSecurityGroup, SecurityGroupRule.Direction.INGRESS); @@ -96,7 +133,6 @@ public SecurityGroupJson createSecurityGroup(SecurityGroupJson securityGroupJson if (isDefaultSecurityGroup(securityGroup) && defaultSecurityGroup != null) { throw new DefaultSecurityGroupExists(); } - if (!isDefaultSecurityGroup(securityGroup)) { //Default security group not exists, create it if (defaultSecurityGroup == null) { diff --git a/services/security_group_manager/src/main/resources/application.properties b/services/security_group_manager/src/main/resources/application.properties index 8f393b36a..5dc22ec9d 100644 --- a/services/security_group_manager/src/main/resources/application.properties +++ b/services/security_group_manager/src/main/resources/application.properties @@ -34,6 +34,7 @@ ignite.thin.client.enable=true #####Spring health##### management.health.redis.enabled=false +microservices.dataplane.service.url=http://localhost:9010/securitygrouprules #####Rbac##### rbac.policy.type=Enforced diff --git a/services/security_group_manager/src/test/java/com/futurewei/alcor/securitygroup/controller/SecurityGroupTest.java b/services/security_group_manager/src/test/java/com/futurewei/alcor/securitygroup/controller/SecurityGroupTest.java index 5245e65b2..7cdaf67ce 100644 --- a/services/security_group_manager/src/test/java/com/futurewei/alcor/securitygroup/controller/SecurityGroupTest.java +++ b/services/security_group_manager/src/test/java/com/futurewei/alcor/securitygroup/controller/SecurityGroupTest.java @@ -76,6 +76,8 @@ public void Test02_createSecurityGroupTest() throws Exception { securityGroup.setProjectId(UnitTestConfig.projectId); securityGroup.setTenantId(UnitTestConfig.tenantId); securityGroup.setDescription(UnitTestConfig.securityGroupDescription); + List securityGroupRules = new ArrayList<>(); + securityGroup.setSecurityGroupRules(securityGroupRules); SecurityGroupJson securityGroupJson = new SecurityGroupJson(securityGroup); @@ -97,6 +99,8 @@ public void Test03_createSecurityGroupBulkTest() throws Exception { securityGroup1.setProjectId(UnitTestConfig.projectId); securityGroup1.setTenantId(UnitTestConfig.tenantId); securityGroup1.setDescription(UnitTestConfig.securityGroupDescription); + List securityGroupRules = new ArrayList<>(); + securityGroup1.setSecurityGroupRules(securityGroupRules); SecurityGroup securityGroup2 = new SecurityGroup(); securityGroup2.setId(UnitTestConfig.securityGroupId2); @@ -104,6 +108,7 @@ public void Test03_createSecurityGroupBulkTest() throws Exception { securityGroup2.setProjectId(UnitTestConfig.projectId); securityGroup2.setTenantId(UnitTestConfig.tenantId); securityGroup2.setDescription(UnitTestConfig.securityGroupDescription2); + securityGroup2.setSecurityGroupRules(securityGroupRules); List securityGroups = new ArrayList<>(); securityGroups.add(securityGroup1); diff --git a/web/src/main/java/com/futurewei/alcor/web/entity/securitygroup/SecurityGroupRuleJson.java b/web/src/main/java/com/futurewei/alcor/web/entity/securitygroup/SecurityGroupRuleJson.java index 793a1a9dc..ab217b988 100644 --- a/web/src/main/java/com/futurewei/alcor/web/entity/securitygroup/SecurityGroupRuleJson.java +++ b/web/src/main/java/com/futurewei/alcor/web/entity/securitygroup/SecurityGroupRuleJson.java @@ -17,7 +17,11 @@ free of charge, to any person obtaining a copy of this software and associated d import com.fasterxml.jackson.annotation.JsonProperty; -public class SecurityGroupRuleJson { +import java.io.Serializable; + +public class SecurityGroupRuleJson implements Serializable { + private static final long serialVersionUID = 1234567L; + @JsonProperty("security_group_rule") private SecurityGroupRule securityGroupRule;