Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,7 @@
import com.yashdotdev.distributed_traffic_control.lease.LeaseStore;
import com.yashdotdev.distributed_traffic_control.lease.RedisLeaseCoordinator;
import com.yashdotdev.distributed_traffic_control.monitoring.TrafficControlMetrics;
import com.yashdotdev.distributed_traffic_control.policy.DefaultPolicyManagementService;
import com.yashdotdev.distributed_traffic_control.policy.InMemoryPolicyProvider;
import com.yashdotdev.distributed_traffic_control.policy.PolicyManagementService;
import com.yashdotdev.distributed_traffic_control.policy.PolicyProvider;
import com.yashdotdev.distributed_traffic_control.policy.TrafficPolicy;
import com.yashdotdev.distributed_traffic_control.policy.TrafficPolicyType;
import com.yashdotdev.distributed_traffic_control.policy.PolicyStatus;
import com.yashdotdev.distributed_traffic_control.policy.*;
import com.yashdotdev.distributed_traffic_control.quota.InMemoryQuotaCoordinator;
import com.yashdotdev.distributed_traffic_control.quota.QuotaCoordinator;
import com.yashdotdev.distributed_traffic_control.traffic.DefaultTrafficControlService;
Expand Down Expand Up @@ -47,13 +41,19 @@ public TrafficPolicy defaultTrafficPolicy(Clock clock) {
}

@Bean
public InMemoryPolicyProvider policyProvider(TrafficPolicy defaultTrafficPolicy) {
return new InMemoryPolicyProvider(defaultTrafficPolicy);
public RedisPolicyStore policyStore(
StringRedisTemplate redisTemplate,
TrafficPolicy defaultTrafficPolicy) {

RedisPolicyStore policyStore = new RedisPolicyStore(redisTemplate);
policyStore.initializeDefaultPolicy(defaultTrafficPolicy);

return policyStore;
}

@Bean
public PolicyManagementService policyManagementService(InMemoryPolicyProvider policyProvider) {
return new DefaultPolicyManagementService(policyProvider);
public PolicyManagementService policyManagementService(PolicyStore policyStore) {
return new DefaultPolicyManagementService(policyStore);
}


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,34 +6,42 @@

public class DefaultPolicyManagementService implements PolicyManagementService {

private final InMemoryPolicyProvider policyProvider;
private final PolicyStore policyStore;

public DefaultPolicyManagementService(InMemoryPolicyProvider policyProvider) {
this.policyProvider = Objects.requireNonNull(policyProvider, "policyProvider must not be null");
public DefaultPolicyManagementService(PolicyStore policyStore) {
this.policyStore = Objects.requireNonNull(
policyStore,
"policyStore must not be null"
);
}

@Override
public TrafficPolicy registerPolicy(String resource, TrafficPolicy policy) {
policyProvider.registerPolicy(resource, policy);
policyStore.registerPolicy(resource, policy);
return policy;
}

@Override
public Optional<TrafficPolicy> findPolicy(String resource) {
return policyProvider.findPolicy(resource);
return policyStore.findPolicy(resource);
}

@Override
public List<PolicyRegistration> findAllPolicies() {
return policyProvider.findAllPolicies().stream().map(entry -> new PolicyRegistration(entry.getKey(), entry.getValue())).toList();
return policyStore.findAllPolicies();
}

@Override
public TrafficPolicy updatePolicy(String resource, TrafficPolicy policy) {
Optional<TrafficPolicy> existingPolicy = policyProvider.findPolicy(resource);
Optional<TrafficPolicy> existingPolicy = policyStore.findPolicy(resource);

if (existingPolicy.isEmpty()) {
throw new IllegalArgumentException("No policy registered for resource: " + resource);
throw new IllegalArgumentException(
"No policy registered for resource: " + resource
);
}
policyProvider.registerPolicy(resource, policy);

policyStore.registerPolicy(resource, policy);
return policy;
}

Expand All @@ -48,22 +56,22 @@ public TrafficPolicy deactivatePolicy(String resource) {
}

private TrafficPolicy changePolicyStatus(String resource, PolicyStatus status) {
TrafficPolicy policy = policyProvider.findPolicy(resource)
TrafficPolicy policy = policyStore.findPolicy(resource)
.orElseThrow(() -> new PolicyNotFoundException(resource));

TrafficPolicy updatedPolicy = policy.withStatus(status);
policyProvider.registerPolicy(resource, updatedPolicy);
policyStore.registerPolicy(resource, updatedPolicy);

return updatedPolicy;
}

@Override
public void removePolicy(String resource) {
policyProvider.removePolicy(resource);
policyStore.removePolicy(resource);
}

@Override
public void setDefaultPolicy(TrafficPolicy policy) {
policyProvider.setDefaultPolicy(policy);
policyStore.setDefaultPolicy(policy);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,61 +9,91 @@
import java.util.Optional;
import java.util.concurrent.ConcurrentHashMap;

public class InMemoryPolicyProvider implements PolicyProvider {
public class InMemoryPolicyProvider implements PolicyProvider, PolicyStore {

private final Map<String, TrafficPolicy> policiesByResource = new ConcurrentHashMap<>();
private final Map<PolicyMatchKey, TrafficPolicy> policiesBySubjectAndResource = new ConcurrentHashMap<>();

private volatile TrafficPolicy defaultPolicy;

public InMemoryPolicyProvider() {
}

public InMemoryPolicyProvider(TrafficPolicy defaultPolicy) {
this.defaultPolicy = Objects.requireNonNull(defaultPolicy, "defaultPolicy must not be null");
this.defaultPolicy = Objects.requireNonNull(
defaultPolicy,
"defaultPolicy must not be null"
);
}
public void registerPolicy(String resource, TrafficPolicy policy) {

@Override
public void registerPolicy(String resource, TrafficPolicy policy) {
validateResource(resource);
Objects.requireNonNull(policy, "policy must not be null");

policiesByResource.put(resource, policy);
}

public void registerPolicy(TrafficSubject subject, String resource, TrafficPolicy policy) {
Objects.requireNonNull(subject, "subject must not be null");
validateResource(resource);
Objects.requireNonNull(policy, "policy must not be null");
policiesBySubjectAndResource.put(new PolicyMatchKey(subject, resource), policy);

policiesBySubjectAndResource.put(
new PolicyMatchKey(subject, resource),
policy
);
}

public Optional<TrafficPolicy> findPolicy(String resource) {
validateResource(resource);

return Optional.ofNullable(policiesByResource.get(resource));
}

public List<Map.Entry<String, TrafficPolicy>> findAllPolicies() {
return List.copyOf(policiesByResource.entrySet());
@Override
public List<PolicyRegistration> findAllPolicies() {
return policiesByResource.entrySet()
.stream()
.map(entry -> new PolicyRegistration(entry.getKey(), entry.getValue()))
.toList();
}

@Override
public void removePolicy(String resource) {
validateResource(resource);

policiesByResource.remove(resource);
}

public void removePolicy(TrafficSubject subject, String resource) {
Objects.requireNonNull(subject, "subject must not be null");

validateResource(resource);

policiesBySubjectAndResource.remove(new PolicyMatchKey(subject, resource));
}

@Override
public void setDefaultPolicy(TrafficPolicy policy) {
this.defaultPolicy = Objects.requireNonNull(policy, "policy must not be null");
this.defaultPolicy = Objects.requireNonNull(
policy,
"policy must not be null"
);
}

@Override
public Optional<TrafficPolicy> findDefaultPolicy() {
return Optional.ofNullable(defaultPolicy);
}

@Override
public Optional<TrafficPolicy> findPolicy(TrafficRequest request) {
Objects.requireNonNull(request, "request must not be null");

TrafficPolicy subjectPolicy = policiesBySubjectAndResource.get(new PolicyMatchKey(request.getSubject(), request.getResource()));
TrafficPolicy subjectPolicy = policiesBySubjectAndResource.get(
new PolicyMatchKey(request.getSubject(), request.getResource())
);

if (subjectPolicy != null) {
return Optional.of(subjectPolicy);
}
Expand All @@ -73,6 +103,7 @@ public Optional<TrafficPolicy> findPolicy(TrafficRequest request) {
if (resourcePolicy != null) {
return Optional.of(resourcePolicy);
}

return Optional.ofNullable(defaultPolicy);
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package com.yashdotdev.distributed_traffic_control.policy;

import java.util.List;
import java.util.Optional;

/**
* Defines storage operations for traffic policies.
*
* Implementations may use in-memory or persistent storage.
*/
public interface PolicyStore {

void registerPolicy(String resource, TrafficPolicy policy);

Optional<TrafficPolicy> findPolicy(String resource);

List<PolicyRegistration> findAllPolicies();

void removePolicy(String resource);

void setDefaultPolicy(TrafficPolicy policy);

Optional<TrafficPolicy> findDefaultPolicy();
}
Loading
Loading