Implement event notification of resource event

When a resource is registered or unregistered, a resource event is notified

Change-Id: I40e66761966ef2126366424a14bb3193fc850e5a
This commit is contained in:
Sho SHIMIZU 2015-11-02 17:35:46 -08:00
parent 28ab3915de
commit fa62b475da
8 changed files with 168 additions and 6 deletions

View File

@ -0,0 +1,54 @@
/*
* Copyright 2015 Open Networking Laboratory
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.onosproject.net.newresource;
import com.google.common.annotations.Beta;
import org.onosproject.event.AbstractEvent;
import static com.google.common.base.Preconditions.checkNotNull;
/**
* Describes an event related to a resource.
*/
@Beta
public final class ResourceEvent extends AbstractEvent<ResourceEvent.Type, ResourcePath> {
/**
* Type of resource events.
*/
@Beta
public enum Type {
/**
* Signifies that a new resource has been detected.
*/
RESOURCE_ADDED,
/**
* Signifies that a resource has been removed.
*/
RESOURCE_REMOVED
}
/**
* Create a resource event.
*
* @param type type of resource event
* @param subject subject of resource event
*/
public ResourceEvent(Type type, ResourcePath subject) {
super(checkNotNull(type), checkNotNull(subject));
}
}

View File

@ -0,0 +1,26 @@
/*
* Copyright 2015 Open Networking Laboratory
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.onosproject.net.newresource;
import com.google.common.annotations.Beta;
import org.onosproject.event.EventListener;
/**
* Entity capable of receiving resource related events.
*/
@Beta
public interface ResourceListener extends EventListener<ResourceEvent> {
}

View File

@ -17,6 +17,7 @@ package org.onosproject.net.newresource;
import com.google.common.annotations.Beta; import com.google.common.annotations.Beta;
import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableList;
import org.onosproject.event.ListenerService;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collection; import java.util.Collection;
@ -29,7 +30,7 @@ import static com.google.common.base.Preconditions.checkNotNull;
* Service for allocating/releasing resource(s) and retrieving allocation(s) and availability. * Service for allocating/releasing resource(s) and retrieving allocation(s) and availability.
*/ */
@Beta @Beta
public interface ResourceService { public interface ResourceService extends ListenerService<ResourceEvent, ResourceListener> {
/** /**
* Allocates the specified resource to the specified user. * Allocates the specified resource to the specified user.
* *

View File

@ -16,6 +16,7 @@
package org.onosproject.net.newresource; package org.onosproject.net.newresource;
import com.google.common.annotations.Beta; import com.google.common.annotations.Beta;
import org.onosproject.store.Store;
import java.util.Collection; import java.util.Collection;
import java.util.List; import java.util.List;
@ -25,7 +26,7 @@ import java.util.Optional;
* Service for storing resource and consumer information. * Service for storing resource and consumer information.
*/ */
@Beta @Beta
public interface ResourceStore { public interface ResourceStore extends Store<ResourceEvent, ResourceStoreDelegate> {
/** /**
* Registers the resources in transactional way. * Registers the resources in transactional way.

View File

@ -0,0 +1,24 @@
/*
* Copyright 2015 Open Networking Laboratory
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.onosproject.net.newresource;
import org.onosproject.store.StoreDelegate;
/**
* Resource store delegate abstraction.
*/
public interface ResourceStoreDelegate extends StoreDelegate<ResourceEvent> {
}

View File

@ -18,16 +18,22 @@ package org.onosproject.net.newresource.impl;
import com.google.common.annotations.Beta; import com.google.common.annotations.Beta;
import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableList;
import com.google.common.collect.Lists; import com.google.common.collect.Lists;
import org.apache.felix.scr.annotations.Activate;
import org.apache.felix.scr.annotations.Component; import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Deactivate;
import org.apache.felix.scr.annotations.Reference; import org.apache.felix.scr.annotations.Reference;
import org.apache.felix.scr.annotations.ReferenceCardinality; import org.apache.felix.scr.annotations.ReferenceCardinality;
import org.apache.felix.scr.annotations.Service; import org.apache.felix.scr.annotations.Service;
import org.onosproject.event.AbstractListenerManager;
import org.onosproject.net.newresource.ResourceAdminService; import org.onosproject.net.newresource.ResourceAdminService;
import org.onosproject.net.newresource.ResourceAllocation; import org.onosproject.net.newresource.ResourceAllocation;
import org.onosproject.net.newresource.ResourceConsumer; import org.onosproject.net.newresource.ResourceConsumer;
import org.onosproject.net.newresource.ResourceEvent;
import org.onosproject.net.newresource.ResourceListener;
import org.onosproject.net.newresource.ResourceService; import org.onosproject.net.newresource.ResourceService;
import org.onosproject.net.newresource.ResourcePath; import org.onosproject.net.newresource.ResourcePath;
import org.onosproject.net.newresource.ResourceStore; import org.onosproject.net.newresource.ResourceStore;
import org.onosproject.net.newresource.ResourceStoreDelegate;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
@ -44,11 +50,26 @@ import static com.google.common.base.Preconditions.checkNotNull;
@Component(immediate = true) @Component(immediate = true)
@Service @Service
@Beta @Beta
public final class ResourceManager implements ResourceService, ResourceAdminService { public final class ResourceManager extends AbstractListenerManager<ResourceEvent, ResourceListener>
implements ResourceService, ResourceAdminService {
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected ResourceStore store; protected ResourceStore store;
private final ResourceStoreDelegate delegate = new InternalStoreDelegate();
@Activate
public void activate() {
store.setDelegate(delegate);
eventDispatcher.addSink(ResourceEvent.class, listenerRegistry);
}
@Deactivate
public void deactivate() {
store.unsetDelegate(delegate);
eventDispatcher.addSink(ResourceEvent.class, listenerRegistry);
}
@Override @Override
public List<ResourceAllocation> allocate(ResourceConsumer consumer, public List<ResourceAllocation> allocate(ResourceConsumer consumer,
List<ResourcePath> resources) { List<ResourcePath> resources) {
@ -161,4 +182,11 @@ public final class ResourceManager implements ResourceService, ResourceAdminServ
List<ResourcePath> resources = Lists.transform(children, x -> ResourcePath.child(parent, x)); List<ResourcePath> resources = Lists.transform(children, x -> ResourcePath.child(parent, x));
return store.unregister(resources); return store.unregister(resources);
} }
private class InternalStoreDelegate implements ResourceStoreDelegate {
@Override
public void notify(ResourceEvent event) {
post(event);
}
}
} }

View File

@ -19,6 +19,7 @@ import com.google.common.collect.ImmutableList;
import org.onlab.packet.MplsLabel; import org.onlab.packet.MplsLabel;
import org.onosproject.net.newresource.ResourceAllocation; import org.onosproject.net.newresource.ResourceAllocation;
import org.onosproject.net.newresource.ResourceConsumer; import org.onosproject.net.newresource.ResourceConsumer;
import org.onosproject.net.newresource.ResourceListener;
import org.onosproject.net.newresource.ResourcePath; import org.onosproject.net.newresource.ResourcePath;
import org.onosproject.net.newresource.ResourceService; import org.onosproject.net.newresource.ResourceService;
@ -97,4 +98,10 @@ class MockResourceService implements ResourceService {
public boolean isAvailable(ResourcePath resource) { public boolean isAvailable(ResourcePath resource) {
return true; return true;
} }
@Override
public void addListener(ResourceListener listener) {}
@Override
public void removeListener(ResourceListener listener) {}
} }

View File

@ -22,8 +22,11 @@ import org.apache.felix.scr.annotations.Reference;
import org.apache.felix.scr.annotations.ReferenceCardinality; import org.apache.felix.scr.annotations.ReferenceCardinality;
import org.apache.felix.scr.annotations.Service; import org.apache.felix.scr.annotations.Service;
import org.onosproject.net.newresource.ResourceConsumer; import org.onosproject.net.newresource.ResourceConsumer;
import org.onosproject.net.newresource.ResourceEvent;
import org.onosproject.net.newresource.ResourcePath; import org.onosproject.net.newresource.ResourcePath;
import org.onosproject.net.newresource.ResourceStore; import org.onosproject.net.newresource.ResourceStore;
import org.onosproject.net.newresource.ResourceStoreDelegate;
import org.onosproject.store.AbstractStore;
import org.onosproject.store.serializers.KryoNamespaces; import org.onosproject.store.serializers.KryoNamespaces;
import org.onosproject.store.service.ConsistentMap; import org.onosproject.store.service.ConsistentMap;
import org.onosproject.store.service.Serializer; import org.onosproject.store.service.Serializer;
@ -47,6 +50,7 @@ import java.util.stream.Collectors;
import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.base.Preconditions.checkNotNull;
import static org.onosproject.net.newresource.ResourceEvent.Type.*;
/** /**
* Implementation of ResourceStore using TransactionalMap. * Implementation of ResourceStore using TransactionalMap.
@ -54,7 +58,8 @@ import static com.google.common.base.Preconditions.checkNotNull;
@Component(immediate = true) @Component(immediate = true)
@Service @Service
@Beta @Beta
public class ConsistentResourceStore implements ResourceStore { public class ConsistentResourceStore extends AbstractStore<ResourceEvent, ResourceStoreDelegate>
implements ResourceStore {
private static final Logger log = LoggerFactory.getLogger(ConsistentResourceStore.class); private static final Logger log = LoggerFactory.getLogger(ConsistentResourceStore.class);
private static final String CONSUMER_MAP = "onos-resource-consumers"; private static final String CONSUMER_MAP = "onos-resource-consumers";
@ -116,7 +121,15 @@ public class ConsistentResourceStore implements ResourceStore {
} }
} }
return tx.commit(); boolean success = tx.commit();
if (success) {
List<ResourceEvent> events = resources.stream()
.filter(x -> x.parent().isPresent())
.map(x -> new ResourceEvent(RESOURCE_ADDED, x))
.collect(Collectors.toList());
notifyDelegate(events);
}
return success;
} }
@Override @Override
@ -147,7 +160,15 @@ public class ConsistentResourceStore implements ResourceStore {
} }
} }
return tx.commit(); boolean success = tx.commit();
if (success) {
List<ResourceEvent> events = resources.stream()
.filter(x -> x.parent().isPresent())
.map(x -> new ResourceEvent(RESOURCE_REMOVED, x))
.collect(Collectors.toList());
notifyDelegate(events);
}
return success;
} }
@Override @Override